	var chartMax = parseFloat("10");
	var slotMax = parseFloat("10");
	var rollsMin = parseFloat("3");
	var rollsMax = parseFloat("10");
	var phenotypeMax = parseFloat("12");
	var rareAdjust = parseFloat("2");
	var rareAbilityMsg = '<tr><td class=\'cell\' colspan=\'2\'>* This is an extremely rare and unusual near-metability.</td></tr>';
	var figuredMsg = '<tr><td class=\'cell\' colspan=\'2\'># Note the lack of the No Figured Characteristic Limitation.</td></tr>';
	var tableStart = '<table border="0" width="100%" valign="top" style="width:148mm; border-collapse:collapse;" background="MetaCyberband.jpg">';
	var tableEnd = '</table>';
	var rowSpan = '<tr><td class=\'cell\' colspan=\'2\'><b>@MSG</b></td></tr>';
	var rowContentSpan = '<tr><td class=\'content\' colspan=\'2\'>@MSG</td></tr>';
	var rowNoteSpan = '<tr><td class=\'note\' colspan=\'2\'>@MSG</td></tr>';
	var rowInformativeSpan = '<tr><td class=\'informative\' colspan=\'2\'>@MSG</td></tr>';
	var consecutiveRolls = 0;
	var amphib = false;
	
	function init()
	{
	    consecutiveRolls++;
	    clearAreas();
	    SlotRerollTracker = getSlotArray();
	    SlotRerollRules = getRerollArray(); 
	}
	function clearAreas()
	{
		document.getElementById("wildcardArea").innerHTML = '';
		document.getElementById("rerollsArea").innerHTML = '';
		document.getElementById("rollsArea").innerHTML = '';
		document.getElementById("resultsArea").innerHTML = '';
	}
	function roll1dx(x)
	{

	var total = Math.ceil(Math.random() * x);
	return total;
	}
	
	function getPhenotypePackage(roll)
	{
		if (roll > phenotypeMax)
		{
			return 'Invalid Option';
		}
		var packageDeal;
		var randomizer;
		
		
		if (roll == 1)
		{
			//EXTRA SMART
			packageDeal = rowSpan.replace('@MSG','Extra Smart Package');
			packageDeal += getPackageRow('Genius','+15 INT',1); //15
			packageDeal += getPackageRow('Savant','+2 Overall Levels',1); //20
			packageDeal += getPackageRow('Mental Acuity','Absolute Time Sense<br>Absolute Range Sense<br>Speed Reading (x10)',1); //10
			packageDeal += getPackageRow('Good Memory','Eidetic Memory',1); //5
			packageDeal += getPackageRow('Intuitive','Find Weakness 11- with All Attacks',1); //30
			packageDeal += getSlotManaged(7 , roll1dx(4)+2); //10
			packageDeal += getSlotManaged(roll1dx(2)+3 , roll1dx(slotMax)); //10

		}
		if (roll == 2)
		{
			//EXTRA STRONG
			packageDeal = rowSpan.replace('@MSG','Extra Strong Package');
			packageDeal += getPackageRow('Stupendous','+30 STR; No Figured Characteristics (-1/2)',1); //20
			packageDeal += getPackageRow('Effortless','+50 STR Reduced Endurance (0 END, +1/2); No Figured Characteristics (-1/2), Only To Determine Casual Strength (-1)',1); //30
			packageDeal += getPackageRow('Iron Jawed','+20 PD',1); //20
			packageDeal += getPackageRow('Stamina','+20 END',1); //10
			
			randomizer = roll1dx(3);
			switch(randomizer)
			{
			 	case 1:
					packageDeal += getPackageRow('Strong Grip and Stance','Clinging (STR)',3); //10
					break;
				case 2:
					packageDeal += getPackageRow('Stable','+25 STR; No Figured Characteristics (-1/2), Only To Resist Shoving / Knockdown / Knockback (-1)',3); //10
					break;
				case 3:
					randomizer = roll1dx(4)+2;
					packageDeal += getSlot(roll1dx(2)+6 , randomizer); //10
					break;
			}
			//slightly increasing the odds of doubling up on Razor Nails
			randomizer = (randomizer == 5) ? randomizer : roll1dx(4)+2;
			packageDeal += getSlotManaged((randomizer == 5) ? 8 : roll1dx(2)+6 , randomizer); //10
		
		}
		if (roll == 3)
		{
			//EXTRA RUGGED
			packageDeal = rowSpan.replace('@MSG','Extra Rugged Package');
			packageDeal += getPackageRow('Partial Invulnerability','Physical Damage Reduction, Resistant, 50%',1); //30
			packageDeal += getPackageRow('Partial Invulnerability','Energy Damage Reduction, Resistant, 50%',1); //30
			randomizer = roll1dx(2);
			if (randomizer == 1)
			{
				packageDeal += getPackageRow('Painless','+15 CON; No Figured Characteristics (-1/2)',3); //30
			}
			else
			{
				packageDeal += getPackageRow('Robust','+15 BODY; No Figured Characteristics (-1/2)',3); //30
			}
			packageDeal += getSlotManaged(roll1dx(chartMax-rareAdjust) , roll1dx(slotMax)); //10
			
		}
		if (roll == 4)
		{
			//EXTRA QUICK
			packageDeal = rowSpan.replace('@MSG','Extra Quick Package');
			packageDeal += getPackageRow('Blindingly Quick','+2 SPEED',1); //20
			packageDeal += getPackageRow('Inhumanely Dexterous','+20 DEX, No Figured Characteristics',1); //40
			packageDeal += getPackageRow('Shifty','Defense Manuever IV',1); //10
			
			randomizer = roll1dx(2);
			if (randomizer == 1)
			{
				packageDeal += getPackageRow('Charger','+5" Running, Reduced Endurance (0 END; +1/2)',3); //15
			}
			else
			{
			    packageDeal += getSlotManaged(1,7,3); // naturally Acrobatic 10
				//packageDeal += getPackageRow('Acrobatic','Acrobatics + 1',3); //5
				//packageDeal += getPackageRow('Cat-feet','Breakfall + 1',3); //5
				packageDeal += getPackageRow('Blistering Draw','Fast Draw + 1',3); //5
			}
			randomizer = roll1dx(2);
			if (randomizer == 1)
			{
				packageDeal += getPackageRow('Flurry','Rapid Attack (HtH)',3); //5
			}
			else
			{
				packageDeal += getPackageRow('Fan','Rapid Attack (Ranged)',3); //5
			}
			packageDeal += getSlotManaged(roll1dx(chartMax-rareAdjust) , roll1dx(slotMax)); //10
					
		}
		if (roll == 5)
		{
			//EXTRA CAPABLE
			packageDeal = rowSpan.replace('@MSG','Extra Capable Package');
			
			//Athletic
			packageDeal += getSlotManaged(7 , 1 , 1); //10
			
			//Fit
			packageDeal += getSlotManaged(7 , 4 , 1); //10
			
			//Tenacious
			packageDeal += getSlotManaged(7 , 3 , 1); //10
			
			//Flinty
			packageDeal += getSlotManaged(7 , 6 , 1); //10
			
			//Accelerated
			packageDeal += getSlotManaged(2 , 4 , 1); //10
			
			//Hyper-Competant
			packageDeal += getSlotManaged(8 , 6 , 1); //10
			
			//Visual Acuity
			packageDeal += getSlotManaged(4 , 1 , 1); //10
			
			//Tough
			packageDeal += getSlotManaged(5 , 4 , 1); //10
			
			//Healing Factor
			packageDeal += getSlotManaged(4 , 5 , 1); //10
			
			randomizer = roll1dx(2);
			if (randomizer == 1) 
			{
				//Clever
				packageDeal += getSlotManaged(7 , 2 , 3); //10

			}
			else
			{
				//Social
				packageDeal += getSlotManaged(7 , 5 , 3); //10
			}

							
		}
		if (roll == 6)
		{
			//EXTRA PERCEPTIVE
			packageDeal = rowSpan.replace('@MSG','Extra Perceptive Package');
			
			randomizer = roll1dx(6);
			if(randomizer == 1 || randomizer == 2 || randomizer == 4)
			{
				packageDeal += getPackageRow('Sentinel','+5 All PER',3); //15
				if(randomizer == 1)
				{
					packageDeal += getPackageRow('Acute Senses','+5 versus Range Modifier for Sight Group, Normal Hearing, Normal Smell and Spatial Awareness',3); //15
				}
				else
				{
					packageDeal += getPackageRow('Acute Senses','+6 versus Range Modifier for Sight Group, Normal Hearing, and Normal Smell',3); //15
				}
				packageDeal += getPackageRow('Hyper-dialation','Flash Defense (Sight): 5',3); //5
				packageDeal += getPackageRow('Aural Filtering','Flash Defense (Hearing): 5',3); //5
			}
			if(randomizer == 1 || randomizer == 3 || randomizer == 5)
			{
				packageDeal += getPackageRow('Hyper-Aware','Spatial Awareness (no Sense Group), Discriminatory, Increased Arc Of Perception (360 Degrees), Range, Rapid:  x10',3); //40
			}
			if(randomizer == 2 || randomizer == 3 || randomizer == 6)
			{
				packageDeal += getPackageRow('Discerning','Find Weakness 13- with All Attacks',3); //40
				
			}
			if(randomizer == 4 || randomizer == 5 || randomizer == 6)
			{
				packageDeal += getPackageRow('Sensitive','Danger Sense (immediate vicinity, any danger, Discriminatory, Function as a Sense) 14-',3); //40
			}

			randomizer = roll1dx(8);
			if(randomizer == 2  || randomizer == 3 || randomizer == 4 || randomizer == 8)
			{
				packageDeal += getPackageRow('Low-Light Vision','Nightvision',3); //5
			}
			if(randomizer == 2  || randomizer == 5 || randomizer == 6 || randomizer == 8)
			{
				packageDeal += getPackageRow('Heat Vision','Infravision',3); //5
			}
			if(randomizer == 3  || randomizer == 5 || randomizer == 7 || randomizer == 8)
			{
				packageDeal += getPackageRow('Ultra-violet Vision','UV Vision',3); //5
			}
			if(randomizer == 4  || randomizer == 6 || randomizer == 7 || randomizer == 8)
			{
				packageDeal += getPackageRow('Bloodhound','Tracking with Normal Smell',3); //5			
			}
			if(randomizer == 1)
			{
				randomizer = roll1dx(10);
				switch(randomizer)
				{
					case 1:
						//Mental Acuity
						packageDeal += getSlotManaged(1 , 1 , 3); //10
						break;
					case 2:
						//Good Brain
						packageDeal += getSlotManaged(2 , 1 , 3); //10
						break;
					case 3:
						//Aural Acuity
						packageDeal += getSlotManaged(6 , 5 , 3); //10
						break;
					case 4:
						//Hyper-Competant
						packageDeal += getSlotManaged(8 , 6 , 3); //10
						break;
					case 5:
						//Empath
						packageDeal += getSlotManaged(9 , 1 , 3); //10
						break;
					case 6:
						//Deja Vu
						packageDeal += getSlotManaged(9 , 5 , 3); //10
						break;
					default:
						packageDeal += getSlot(roll1dx(chartMax-rareAdjust) , roll1dx(slotMax-4)+1); //10
						break;
				}
				randomizer = 1; //RESET Randomizer to 1
			}
			if(randomizer < 8)
			{
				packageDeal += getSlotManaged(roll1dx(chartMax-rareAdjust) , roll1dx(slotMax-4)+1); //10
			}
		}
		if (roll == 7)
		{
			//EXTRA PERSONABLE
			packageDeal = rowSpan.replace('@MSG','Extra Personable Package');
			packageDeal += getPackageRow('Personable','+30 PRE',1); //30
			packageDeal += getPackageRow('Attractive','+10 COM',1); //5
			
			randomizer = roll1dx(3);
			switch(randomizer)
			{
				case 1:
					packageDeal += getPackageRow('Arresting Gaze','Entangle 3d6, 3 DEF, Takes No Damage From Attacks Physical Attacks (+1/4), Works Against EGO, Not STR (+1/4), Reduced Endurance (0 END; +1/2), Based On EGO Combat Value (Mental Defense applies; +1); Eye Contact Required (Constant Power requires eye contact throughout use; -1), Cannot Form Barriers (-1/4)',3); //40
					packageDeal += getPackageRow('Imperious','Intimidation +1',3); //5
					break;
				case 2:
					packageDeal += getPackageRow('Convincing','Drain PRE & EGO 1d6, Personal Immunity (+1/4), PRE and EGO simultaneously (+1/2), Reduced Endurance (0 END; +1/2), Delayed Return Rate (points return at the rate of 5 per 20 Minutes; +3/4), Area Of Effect (4" Radius; +1), Invisible Power Effects (Fully Invisible; +1); Requires A Conversation Skill Roll  (Active Point penalty to Skill Roll is -1 per 20 Active Points; -1/4)',3); //40			
					packageDeal += getPackageRow('Glib','Conversation +1',3); //5					
					break;
				case 3:
					packageDeal += getPackageRow('Commanding','Mind Control 8d6 (Human class of minds), Reduced Endurance (0 END; +1/2), Invisible Power Effects (Fully Invisible; +1/2); Does Not Provide Mental Awareness (-1/4), Requires A Persuasion Skill Roll  (Active Point penalty to Skill Roll is -1 per 20 Active Points; -1/4), Only Lasts For One Action (-1/2)',3); //40			
					packageDeal += getPackageRow('Persuasive','Persuasion +1',3); //5					
					break;
			}
			
			packageDeal += getSlotManaged(roll1dx(2) , roll1dx(slotMax)); //10
			packageDeal += getSlotManaged(roll1dx(2)+4 , roll1dx(slotMax)); //10
					
		}
		if (roll == 8)
		{
			//EXTRA EVOLVED
			
			packageDeal = rowSpan.replace('@MSG','Extra Evolved Package');
			packageDeal += getPackageRow('Evolved Physiology','Life Support  (Eating: Character only has to eat once per week; Extended Breathing: 1 END per 20 Minutes; Immunity All terrestrial poisons and chemical warfare agents; Immunity: All terrestrial diseases and biowarfare agents; Longevity: 400 Years; Safe Environment: Zero Gravity; Safe in High Pressure; Safe in High Radiation; Safe in Intense Cold; Safe in Intense Heat; Safe in Low Pressure/Vacuum; Sleeping: Character does not sleep)',1); //40
			packageDeal += getPackageRow('Evolved Regeneration','Regeneration 3 BODY, Can Heal Limbs, Reduced Endurance (0 END; +1/2), Persistent (+1/2) (70 Active Points); Extra Time (Regeneration-Only) 1 Turn (Post-Segment 12) (-1 1/4), Self Only (-1/2)',1); //25
			
			randomizer = roll1dx(5);
			switch(randomizer)
			{
				case 1:
					//Resilience
					packageDeal += getSlotManaged(2 , 2 , 3); //10
					//Resolute
					packageDeal += getSlotManaged(3 , 2 , 3); //10

					packageDeal += getPackageRow('Evolved Resistance','Damage Resistance (5 PD/5 ED/10 Mental Def/10 Power Def)',3); //15
					break;
				case 2:
					packageDeal += getPackageRow('Unbreakable','Armor (5 PD/5 ED)',3); //15
					packageDeal += getPackageRow('Resistant','Damage Resistance (5 PD/5 ED)',3); //5
					packageDeal += getPackageRow('Flawless','Lack Of Weakness (-5) for Resistant Defense',3); //5
					packageDeal += getSlotManaged(7 , roll1dx(slotMax)); //10
					break;
				case 3:
					packageDeal += getPackageRow('Low-Light Vision','Nightvision',3); //5
					packageDeal += getSlotManaged(7 , roll1dx(slotMax)); //10
					packageDeal += getSlotManaged(7 , roll1dx(slotMax)); //10
					packageDeal += getSlotManaged(7 , roll1dx(slotMax)); //10
					break;
					
				case 4:
					packageDeal += getPackageRow('Energetic','+10 END',3); //5
					packageDeal += getSlotManaged(roll1dx(4)+4, roll1dx(slotMax)); //10
					packageDeal += getSlotManaged(roll1dx(4)+4 , roll1dx(slotMax)); //10
					packageDeal += getSlotManaged(roll1dx(4)+4 , roll1dx(slotMax)); //10
					break;
					
				case 5:
					packageDeal += getPackageRow('Tireless','+30 END',3); //15
					packageDeal += getSlotManaged(8, roll1dx(3)); //10
					packageDeal += getSlotManaged(8 , roll1dx(3)); //10
					break;					
			}
							
		}
		if (roll == 9)
		{
			//EXTRA LUCKY
			packageDeal = rowSpan.replace('@MSG','Extra Lucky Package');
			packageDeal += getPackageRow('Favored','Luck 6d6; At the beginning of a game session the player rolls his Luck dice and counts the total. That total represents a number of points the player may add to or subtract from rolls throughout that game to get better results.',1); //30
			packageDeal += getPackageRow('Lucky Miss','Combat Luck (15 PD/15 ED); <i><br />Note: These levels of Combat Luck do not count against the character\'s Super Skill limit.</i>',1); //30
			packageDeal += getPackageRow('Lucky Shift','Defense Manuever IV',1); //10
			randomizer = roll1dx(2);
			switch(randomizer) //20
			{
			    case 1:
			        packageDeal += getPackageRow('Lucky Outcome','+2 Overall Levels',3); //20
			        break;
			    case 2:
			        packageDeal += getSlotManaged(roll1dx(chartMax) , roll1dx(slotMax),3); //10
			        packageDeal += getSlotManaged(roll1dx(chartMax-rareAdjust) , roll1dx(slotMax),3); //10
			        break;
			        
			}
			packageDeal += getSlotManaged(roll1dx(chartMax-rareAdjust) , roll1dx(slotMax),2); //10
					
		}
		if (roll == 10)
		{
			//EXTRA ADAPTABLE
			var ImprovedCramming = '<i><b>Improved Cramming:</b> As Cramming, but a (CHAR/5) Skill Roll is granted rather than the usual 8- Familiarity and the character can use any relevant Skill Levels with the Crammed Skill. Alternately, up to 3 points of fluency in a Language can be learned instead</i>';
			var MartialCramming = '<i><b>Martial Cramming:</b> As Cramming, but instead of the usual Skills available to Cramming any Combat Skill or Martial Maneuver with a cost of 5 points or less can be learned. Further the character can use any relevant Skill Levels or Damage Classes with the Crammed Skill or Maneuver as applicable</i>';
			var MartialCramStack = '<i>At the GM\'s discretion, a character with two Martial Cramming Skills could pool them together to learn a 10 point Combat Skill such as Two Weapon Fighting or Defensive Manuever IV.</i>';
			var CrammingExperience = '<i>As with Cramming, Skills learned via Improved and Martial Cramming fade after a period of time as determined by the GM (at least a week of game time is recommended), but once a character has learned a Skill via Cramming they can opt to spend Experience Points to gain the Skill in the normal fashion, and thus this process can greatly expedite the acquisition of new Skills.</i>';

			packageDeal = rowSpan.replace('@MSG','Extra Adaptable Package');
			randomizer = roll1dx(3);
			switch(randomizer) //40
			{
				case 1:
					packageDeal += getPackageRow('Rapid Assimilation','Improved Cramming x 4',3); //40
					break;
				case 2:
					packageDeal += getPackageRow('Reflexive Assimilation','Martial Cramming x 5',3); //40
					break;
				case 3:
					packageDeal += getPackageRow('Rapid Assimilation','Improved Cramming x 2',3); //20
					packageDeal += getPackageRow('Reflexive Assimilation','Martial Cramming x 2',3); //16
					//placeholder packageDeal += getPackageRow('Bright','+4 INT',3); //4
					break;
			}
			if(randomizer == 3) 
			{
				packageDeal += getPackageRow('Bright','+9 INT',1); //9
			}
			else
			{
				packageDeal += getPackageRow('Sharp','+5 INT',1); //5
			}
			packageDeal += getPackageRow('Savant','+2 Overall Levels',1); //20
			packageDeal += getPackageRow('Good Brain','Eidetic Memory',1); //5
			
			packageDeal += getSlotManaged(roll1dx(7) , roll1dx(slotMax)); //10
			packageDeal += getSlotManaged(roll1dx(7) , roll1dx(slotMax)); //10
			packageDeal += getSlotManaged(roll1dx(7) , roll1dx(slotMax)); //10
			
			if(packageDeal.indexOf('Improved Cramming') > 0)
			{
				packageDeal += rowNoteSpan.replace('@MSG', ImprovedCramming);
			}
			if(packageDeal.indexOf('Martial Cramming') > 0)
			{
				packageDeal += rowNoteSpan.replace('@MSG', MartialCramming);
				packageDeal += rowNoteSpan.replace('@MSG', MartialCramStack);
			}
			packageDeal += rowNoteSpan.replace('@MSG',CrammingExperience);
		}
		if(roll == 11)
		{
		    //ESPER
		    packageDeal = rowSpan.replace('@MSG','Esper Package');
		    //RESOLUTE (Mental Defense)
			packageDeal += getSlot(3 , 2 , 1); //10
			        
		    randomizer = roll1dx(5); 
			switch(randomizer)
			{//30 point combo set
			    case 1:
			        packageDeal += getPackageRow('Egotist','+10 EGO',3); //20
			        packageDeal += getPackageRow('Force of Will','+20 END',3); //10
			        break;
			    case 2:
			        randomizer = roll1dx(2);
			        switch(randomizer)
			        {//20 point combo set
			            case 1:
			                packageDeal += getPackageRow('Egotist','+10 EGO',3); //20
			                break;
			            case 2:
			                packageDeal += getPackageRow('Force of Will','+20 END',3); //10
			                packageDeal += getSlotManaged(roll1dx(chartMax-rareAdjust) , roll1dx(slotMax), 2); //10
			                break;
			        }
			        packageDeal += getSlotManaged(roll1dx(chartMax-rareAdjust) , roll1dx(slotMax), 2); //10
			        
			        break;  
			   case 3:
			   case 4:
			        packageDeal += getPackageRow('Egotist','+5 EGO',3); //10
			        packageDeal += getPackageRow('Force of Will','+20 END',3); //10
			        randomizer = roll1dx(3);
			        switch(randomizer)
			        {//10 point combo set
			            case 1:
			                packageDeal += getPackageRow('Probing','+2 ECV',3); //10
			                break;
			            case 2:
			            case 3:
			                packageDeal += getPackageRow('Ego Driven','+5 REC',3); //10
			                break;
			        }
			        break;
			   case 5: //Lots of Endurance
			        packageDeal += getPackageRow('Tireless','+40 END',3); //20
			        packageDeal += getPackageRow('Ego Driven','+5 REC',3); //10
			        break;			        
			}		
			
			randomizer = roll1dx(8);
			switch(randomizer)
			{//60 point combo slot
				case 1: //Firestarter
					packageDeal += getPackageRow('*Pyrokinesis','RKA 2d6-1 (vs. ED), Costs END Only To Activate (+1/4), Personal Immunity (+1/4), Uncontrolled (Extinguished as normal for Fire, +1/2), Sticky (+1/2), Penetrating (+1/2), Continuous (+1) (100 Active Points); Extra Time (Full Phase, -1/2), Concentration (1/2 DCV; -1/4), No Knockback (-1/4); 9 END',3); //50
					//Fire Proof
					packageDeal += getSlot(10 , 1 , 3); //10
					break;
				case 2: //Mind Lash
					packageDeal += getPackageRow('*Mind Lash','Ego Attack 6d6 (Human class of minds); 6 END',3); //60
					break;
				case 3: //TK
					packageDeal += getPackageRow('*Telekinetic','TK (30 STR), Fine Manipulation; 6 END',3); //55	
					packageDeal += getPackageRow('Mental Fortitude','+10 END',3); //5					
					break;
				case 4: //Mind Reader
				    packageDeal += getPackageRow('*Telepathic','Telepathy 12d6 (Human class of minds); 6 END',3); //60
		            break;
				case 5: //Puppeteer
				    packageDeal += getPackageRow('*Puppeteer','Mind Control 12d6 (Human class of minds); 6 END',3); //60
		            break;
				case 6: //Mental Illusions
				    packageDeal += getPackageRow('*Imagineer','Mental Illusions 12d6 (Human class of minds); 6 END',3); //60
		            break;
				case 7: //Remote Viewing
				    packageDeal += getPackageRow('*Remote Viewing','Clairsentience (Sight Group), Analyze, Discriminatory, Increased Arc Of Perception (360 Degrees), Mobile Perception Point (can move up to 6" per Phase); 4 END',3); //40
				    //Deja Vu
					packageDeal += getSlotManaged(9 , 5 , 3); //10
					packageDeal += getSlotManaged(roll1dx(chartMax) , roll1dx(slotMax), 2); //10
					break;
				case 8: //Psychometry
				    packageDeal += getPackageRow('*Psychometry','Retrocognitive Clairsentience (Sight And Hearing Groups And Mental Awareness), Discriminatory, Increased Arc Of Perception (360 Degrees), Rapid:  x1,000 (74 Active Points); Precognition/Retrocognition Only (-1), Only To See Past As It Has Occured Around An Inanimate Object, On Touch (-1/2); 7 END',3); //30
				    //One shot at a rare:
				    packageDeal += getSlotManaged(roll1dx(chartMax) , roll1dx(slotMax), 2); //10
				    packageDeal += getSlotManaged(roll1dx(chartMax-rareAdjust) , roll1dx(slotMax), 2); //10
				    packageDeal += getSlotManaged(roll1dx(chartMax-rareAdjust) , roll1dx(slotMax), 2); //10
		            break;
			}
				
		}
		if (roll == 12)
		{
			//EXTRA ENHANCED (Stat God)
			packageDeal = rowSpan.replace('@MSG','Extra Enhanced Package');
			randomizer = roll1dx(3);
			switch(randomizer)
			{
			    case 1:
			        packageDeal += getPackageRow('#Uber-Enhanced', " +10 STR<br>+10 DEX<br>+10 CON<br>+10 INT<br>+10 EGO<br>+10 PRE",4);//100
			        break;
			    case 2:
			        packageDeal += getPackageRow('#Elite', " +8 STR<br>+8 DEX<br>+8 CON<br>+8 INT<br>+8 EGO<br>+8 PRE",3);//80
			        
			        packageDeal += getSlotManaged(roll1dx(chartMax) , roll1dx(slotMax)); //10 Two shots at a rare
				    packageDeal += getSlotManaged(roll1dx(chartMax) , roll1dx(slotMax)); //10
				    break;
			    case 3: 
			        packageDeal += getPackageRow('#Impressive', " +5 STR<br>+5 DEX<br>+5 CON<br>+5 INT<br>+5 EGO<br>+5 PRE",3);//50
			        packageDeal += getSlotManaged(roll1dx(chartMax) , roll1dx(7)); //10 Two shots at a rare
				    packageDeal += getSlotManaged(roll1dx(chartMax) , roll1dx(7)); //10
				    packageDeal += getSlotManaged(roll1dx(chartMax-rareAdjust) , roll1dx(7)); //10
		            packageDeal += getSlotManaged(roll1dx(chartMax-rareAdjust) , roll1dx(7)); //10
				    packageDeal += getSlotManaged(roll1dx(chartMax-rareAdjust) , roll1dx(7)); //10
			        break;
			}
			
					
		}
		packageDeal += handleFiguredFootnote(packageDeal.indexOf('#'));
		packageDeal += handleRareFootnote(packageDeal.indexOf('*'));
		
		return packageDeal;
	}
	function getPackageRow(name,ability,emphasis)
	{
		
		var cellName = '<td class=\'cell\' valign=\'top\' width=\'25%\'><@e>@NAME</@e></td>';
		cellName = (emphasis == 1 || emphasis == 4) ? cellName.replace(/@e/g,'b') : cellName;
		cellName = (emphasis == 2) ? cellName.replace(/@e/g,'i') : cellName;
		cellName = (emphasis == 3) ? cellName.replace(/@e/g,'u') : cellName;
		cellName = (emphasis == 4) ? cellName.replace('<b>','<b><i>') : cellName;
		cellName = (emphasis == 4) ? cellName.replace('</b>','</b></i>') : cellName;
		cellName = cellName.replace(/<@e>/g,'');
		cellName = cellName.replace(/<\/@e>/g,'');

		var cellSlot = '<td class=\'cell\' valign=\'top\'>@ABILITY</td>';;
		return '<tr>' + cellName.replace('@NAME',name) + cellSlot.replace('@ABILITY',ability) + '</tr>';
		
	}
	
	function getSlotManaged(chart,slot,emphasis)
	{
	    //init chartSlotIndex from passed chart slot
	    var chartSlotIndex = getChartSlotIndex(chart,slot);
	    
	    //make sure chart / slot combo doesnt require a reroll
	    while(getRerollRequired(chartSlotIndex))
	        chartSlotIndex = getRandomChartSlotIndex();
	    
	    //mark current slot has having been rolled
	    SlotRerollTracker[chartSlotIndex] = true;
	    
	    //redetermine chart and slot
	    var chartSlotArray = getChartSlotArrayByIndex(chartSlotIndex);
	    
	    //Turn off slots that aren't compatible with rolled slot
		handleInterrelatedSlots(chartSlotArray[0],chartSlotArray[1]);
	    
	    //defer to getSlot
	    return getSlot(chartSlotArray[0],chartSlotArray[1],emphasis)
	}
	function getSlot(chart,slot,emphasis)
	{
		
		if ((chart < 1 || chart > chartMax) || (slot < 1 || slot > slotMax))
		{
			return 'Invalid Option';
		}
		var sTmp;
		var enhancement = new Array();
		var emp = emphasis == null ? 2 : parseFloat(emphasis);
		
		if (chart == 1)
		{
			//GENETIC ENHANCEMENT I

			enhancement[1] = getPackageRow('Mental Acuity','Absolute Time Sense<br>Absolute Range Sense,<br>Speed Reading (x10)',emp);
			enhancement[2] = getPackageRow('Combat Alertness','Danger Sense (self only, in combat, Intuitional) 11-',emp);

			sTmp = 'Life Support';
			sTmp += '<br>Eating: Character only has to eat once per week';
			sTmp += '<br>Extended Breathing: 1 END per Minute';
			sTmp += '<br>Longevity: 200 Years';
			sTmp += '<br>Safe in High Pressure';
			sTmp += '<br>Safe in Intense Cold';
			sTmp += '<br>Safe in Intense Heat';
			sTmp += '<br>Sleeping: Character only has to sleep 8 hours per week</td>';
			enhancement[3] = getPackageRow('Advanced Physiology',sTmp,emp);

			sTmp = 'Rapid Healing';
			sTmp += '<br>Resistance (5)';
			enhancement[4] = getPackageRow('Rapid Recovery',sTmp,emp);

			sTmp = '+2 PD';
			sTmp += '<br>+2 ED';
			sTmp += '<br>Damage Resistance (4/4)';
			sTmp += '<br>+1 REC</td>';
			enhancement[5] = getPackageRow('Rugged',sTmp,emp);
			enhancement[6] = getPackageRow('Strong','+10 STR; 0 END (+1/2), No Figured Characteristics(-1/2)',emp);
            enhancement[7] = getPackageRow('Naturally Acrobatic', 'Acrobatics +1<br>Breakfall + 1',emp);
            enhancement[8] = getPackageRow('#Enhanced','+1 STR<br>+1 CON<br>+1 DEX<br>+1 INT<br>+1 EGO<br>+1 PRE',emp);
            enhancement[9] = getPackageRow('#Swift','+1 DEX<br>+2" Running<br>+2" Swimming<br>+1" Leaping',emp);
            
            enhancement[10] = getPackageRow('#Beefcake','+10 STR',emp);
		}
		
		if (chart == 2)
		{
			//GENETIC ENHANCEMENT II

			sTmp = 'Eidetic Memory';
			sTmp += '<br>+5 INT';
			enhancement[1] = getPackageRow('Good Brain',sTmp,emp);
			enhancement[2] = getPackageRow('Resilient','Power Defense: 10',emp);
			enhancement[3] = getPackageRow('Immune to Disease','Life Support (Immunity: All terrestrial diseases and biowarfare agents)',emp);
			enhancement[4] = getPackageRow('Accelerated','+1 SPEED',emp);
			enhancement[5] = getPackageRow('Willful','+5 EGO',emp);

			sTmp = '+7 CON; No Figured Characteristics (-1/2)';
			sTmp += '<br>+1 ED';
			enhancement[6] = getPackageRow('Durable',sTmp,emp);
            enhancement[7] = getPackageRow('Naturally Sneaky','Stealth +1<br>Concealment +1',emp);
            enhancement[8] = getPackageRow('#Enhanced','+1 STR<br>+1 CON<br>+1 DEX<br>+1 INT<br>+1 EGO<br>+1 PRE',emp);
            enhancement[9] = getPackageRow('#Swift','+1 DEX<br>+2" Running<br>+2" Swimming<br>+1" Leaping',emp);
            enhancement[10] = getPackageRow('#Brawny','+5 CON',emp);
		}
		if (chart == 3)
		{
			//GENETIC ENHANCEMENT III
		
			sTmp = 'Ambidexterity (-1)';
			sTmp += '<br>Double Jointed';
			enhancement[1] = getPackageRow('Adroit',sTmp,emp);
			enhancement[2] = getPackageRow('Resolute','Mental Defense: +10',emp);
			enhancement[3] = getPackageRow('Immune to Poisons','Life Support (Immunity: All terrestrial poisons and chemical warfare agents)',emp);
			enhancement[4] = getPackageRow('Impressive','+10 PRE',emp);
			enhancement[5] = getPackageRow('Agile','+5 DEX; No Figured Characteristics (-1/2)',emp);
			
			sTmp = '+7 BODY; No Figured Characteristics (-1/2)';
			sTmp += '<br>+1 PD';
			enhancement[6] = getPackageRow('Stalwart',sTmp,emp);
            enhancement[7] = getPackageRow('Natural Tactician','Tactics +1<br>Teamwork +1',emp);
            enhancement[8] = getPackageRow('#Enhanced','+1 STR<br>+1 CON<br>+1 DEX<br>+1 INT<br>+1 EGO<br>+1 PRE',emp);
            enhancement[9] = getPackageRow('Superior Eye-Hand','+2 all DEX Skills',emp);
            enhancement[10] = getPackageRow('#Crusty','+5 BODY',emp);
		}
		if (chart == 4)
		{
			//GENETIC ENHANCEMENT IV
			
			sTmp = 'Nightvision';
			sTmp += '<br>+1 PER Sight';
			sTmp += '<br>+1 vs Range Penalty (All Attacks)';
			enhancement[1] = getPackageRow('Visual Acuity',sTmp,emp);
			enhancement[2] = getPackageRow('Trooper','+5 REC',emp);
			
			sTmp = 'Life Support';
			sTmp += '<br>Safe Environment: Zero Gravity';
			sTmp += '<br>Safe in High Pressure';
			sTmp += '<br>Safe in High Radiation';
			sTmp += '<br>Safe in Intense Cold';
			sTmp += '<br>Safe in Intense Heat';
			sTmp += '<br>Safe in Low Pressure/Vacuum';
			
			enhancement[3] = getPackageRow('Adaptable',sTmp,emp);
			enhancement[4] = getPackageRow('Sturdy','+10 STUN',emp);
			enhancement[5] = getPackageRow('Healing Factor','Healing 1 BODY, Can Heal Limbs, Reduced Endurance (0 END; +1/2), Persistent (+1/2); <br>Extra Time (Regeneration-Only) 1 Minute (-1 1/2), Self Only (-1/2)',emp);
			enhancement[6] = getPackageRow('Beautiful','+20 COM',emp);
			enhancement[7] = getPackageRow('Naturally Social','High Society +1<br>Streetwise +1',emp);
			enhancement[8] = getPackageRow('#Enhanced','+1 STR<br>+1 CON<br>+1 DEX<br>+1 INT<br>+1 EGO<br>+1 PRE',emp);
		    enhancement[9] = getPackageRow('Intuitive Thinker','+2 all INT Skills',emp);
		    enhancement[10] = getPackageRow('#Bruiser','+5 STR<br>+5 PD',emp);
		    
		}
		
		if (chart == 5)
		{
			//GENETIC ENHANCEMENT V
			
			sTmp = 'Infravision';
			sTmp += '<br>Flash Defense (Sight): 5';
			enhancement[1] = getPackageRow('Corneal Acuity',sTmp,emp);
			enhancement[2] = getPackageRow('Tireless','Reduced Endurance (0 END) on up to 20 STR',emp);
			enhancement[3] = getPackageRow('Fleet','+5" Running',emp);
			enhancement[4] = getPackageRow('Tough','Damage Resistance (8 PD / 8 ED); Hardened (+1/4)',emp);
			
			sTmp = 'Clinging (+10 STR); Requires A Climbing Skill Roll  (-1/2), Cannot Resist Knockback (-1/4)';
			sTmp += '<br>Climbing Skill (DEX)';
			enhancement[5] = getPackageRow('Brachiator',sTmp,emp);
			enhancement[6] = getPackageRow('Brutish','+10 PD',emp);
			enhancement[7] = getPackageRow('Naturally Officious','Bureaucratics +1<br>Bribery +1',emp);
			enhancement[8] = getPackageRow('#Enhanced','+1 STR<br>+1 CON<br>+1 DEX<br>+1 INT<br>+1 EGO<br>+1 PRE',emp);
            enhancement[9] = getPackageRow('Melodic Voice','+2 all PRE Skills',emp);
            enhancement[10] = getPackageRow('Tireless','+20 END',emp);
		}
		if (chart == 6)
		{
			//GENETIC ENHANCEMENT VI
			
			sTmp = '+2 All PER';
			sTmp += '<br>+4 INT';
			enhancement[1] = getPackageRow('Hyper-Alert',sTmp,emp);
			enhancement[2] = getPackageRow('Mighty','+15 STR; No Figured Characteristics (-1/2)',emp);
			enhancement[3] = getPackageRow('Strong-legged','Leaping +5" (Accurate)',emp);
			enhancement[4] = getPackageRow('Dense','Armor (2 PD/2 ED), Inherent (+1/4), Hardened (x2; +1/2)',emp);
			enhancement[5] = getPackageRow('Aural Acuity','Targeting with Normal Hearing',emp);
			enhancement[6] = getPackageRow('Brilliant','+10 INT',emp);
			enhancement[7] = getPackageRow('Naturally Personable','Converation +1<br>Persuasion +1',emp);
			enhancement[8] = getPackageRow('#Enhanced','+1 STR<br>+1 CON<br>+1 DEX<br>+1 INT<br>+1 EGO<br>+1 PRE',emp);
			enhancement[9] = getPackageRow('#Swift','+1 DEX<br>+2" Running<br>+2" Swimming<br>+1" Leaping',emp);
			enhancement[10] = getPackageRow('Steady','+10 END<br>+5 STUN',emp);
			
		}
		
		if (chart == 7)
		{
			//GENETIC ENHANCEMENT VII -- a composite stat set
			
			sTmp = '+5 STR; No Figured Characteristics (-1/2)';
			sTmp += '<br>+5 CON; No Figured Characteristics (-1/2)';
			enhancement[1] = getPackageRow('Athletic',sTmp,emp);

			sTmp = '+5 INT';
			sTmp += '<br>+5 PRE';
			enhancement[2] = getPackageRow('Clever',sTmp,emp);
			
			sTmp = '+3 EGO';
			sTmp += '<br>+2 REC';
			enhancement[3] = getPackageRow('Tenacious',sTmp,emp);
			
			sTmp = '+3 DEX; No Figured Characteristics (-1/2)';
			sTmp += '<br>+3 BODY; No Figured Characteristics (-1/2)';
			enhancement[4] = getPackageRow('Fit',sTmp,emp);
			
			sTmp = '+5 PRE';
			sTmp += '<br>+10 COM';
			enhancement[5] = getPackageRow('Social',sTmp,emp);
			
			sTmp = '+5 PD';
			sTmp += '<br>+5 ED';
			enhancement[6] = getPackageRow('Flinty',sTmp,emp);
			enhancement[7] = getPackageRow('Naturally Shrewd','Deduction +1<br>Interrogation +1',emp);
			enhancement[8] = getPackageRow('#Enhanced','+1 STR<br>+1 CON<br>+1 DEX<br>+1 INT<br>+1 EGO<br>+1 PRE',emp);
		    enhancement[9] = getPackageRow('*Unbreakable Bones','Limbs Immune To Severing and Disabling',4);
			enhancement[10] = getPackageRow('Dodgy','+2 DCV',emp);
			
		}

		if (chart == 8)
		{
			//GENETIC ENHANCEMENT VIII -- some extreme abilities
			
			enhancement[1] = getPackageRow('Boosted','+2 SPD; Costs Endurance (-1/2), Increased Endurance Cost (x2 END; -1/2)',emp);
			enhancement[2] = getPackageRow('Explosive','+20 STR; No Figured Characteristics (-1/2), Increased Endurance Cost (x2 END; -1/2)',emp);
			enhancement[3] = getPackageRow('Manic','+10 DEX; No Figured Characteristics (-1/2), Costs Endurance (-1/2), Increased Endurance Cost (x3 END; -1)',emp);
			enhancement[4] = getPackageRow('Brutal','Hand-To-Hand Attack +3d6; Hand-To-Hand Attack (-1/2)',emp);
			enhancement[5] = getPackageRow('Razor Nails','Killing Attack - Hand-To-Hand +1d6 (vs. PD); Reduced Penetration (-1/4), No Knockback (-1/4)',emp);
			enhancement[6] = getPackageRow('Hyper-Competant','+1 Overall Skill Level',emp);
			enhancement[7] = getPackageRow('Natural Engineer','Inventor +1<br>Mechanics +1',emp);
			enhancement[8] = getPackageRow('#Enhanced','+1 STR<br>+1 CON<br>+1 DEX<br>+1 INT<br>+1 EGO<br>+1 PRE',emp);
			enhancement[9] = getPackageRow('Martial Savant','Basic Strike:  1/2 Phase, +1 OCV, +0 DCV, STR +2d6 Strike<br>Martial Block:  1/2 Phase, +2 OCV, +2 DCV, Block, Abort<br>Takedown:  1/2 Phase, +1 OCV, +1 DCV, STR Strike; Target Falls',emp);
			enhancement[10] = getPackageRow('*Aura Vision','Detect Aura 11- (Unusual Group), Discriminatory',4);
		
		}
		
		if (chart == 9)
		{
			//GENETIC ENHANCEMENT IX -- very rare abilities verging on metabilities
			amphib = (chart == 9 && slot == 4);
			
			enhancement[1] = getPackageRow('*Empath','Telepathy 3d6, Reduced Endurance (0 END; +1/2), Persistent (+1/2); Empathy All Emotions (-1/2), Receive Only (-1/2), Always On (-1/2), Does Not Provide Mental Awareness (-1/4), Normal Range (-1/4)',4);
			enhancement[2] = getPackageRow('*Aenerobe','Life Support  (Self-Contained Breathing)',4);
			
			sTmp = 'Life Support';
			sTmp += '<br>Eating: Character does not eat';
			sTmp += '<br>Sleeping: Character only has to sleep 8 hours per year';
			sTmp += '<br>Longevity: Immortal';
			enhancement[3] = getPackageRow('*Eternal Phsyiology',sTmp,4);
			
			sTmp = 'Swimming +3"';
			sTmp += '<br>Reduced Endurance (0 END; +1/2) on Swimming 5"';
			sTmp += '<br>Sleeping: Character only has to sleep 8 hours per year';
			sTmp += '<br>Expanded Breathing (under water)';
			enhancement[4] = getPackageRow('*Amphibious',sTmp,4);
		
			enhancement[5] = getPackageRow('*Deja Vu','Precognitive Clairsentience (Sight Group), Reduced Endurance (0 END; +1/2); No Conscious Control (-2), Only Through Dreams (-1), Precognition Only (-1), Vague and Unclear (-1/2), Sense Affected As More Than One Sense Mental & Sight (-1/4)',4);
			
			enhancement[6] = getPackageRow('*Corrosive Secretions','Drain DEF 1 point, Uncontrolled (+1/2), Continuous (+1), Delayed Return Rate (points return at the rate of 5 per Century; +3 1/4) (17 Active Points); Extra Time (1 Turn (Post-Segment 12), Only to Activate, -3/4)',4);
			
			enhancement[7] = getPackageRow('*Sonar','Active Sonar (Hearing Group), Discriminatory (20 Active Points); Only Works Under Water (-1)',4);
	        
	        enhancement[8] = getPackageRow('*Psionic Defense Reflex','Ego Attack 1 point (Human class of minds), Invisible Power Effects, SFX Only (Fully Invisible; +1/4), Penetrating (+1/2), Reduced Endurance (0 END; +1/2), Persistent (+1/2), Continuous (+1), Damage Shield (Affects Mental And Physical Attackers; Offensive; +1 1/4) (15 Active Points); Always On (-1/2)',4);
	        
	        enhancement[9] = getPackageRow('*Fangs','Killing Attack - Hand-To-Hand 1d6 (1 1/2d6 w/STR) (vs. PD) (15 Active Points); Restrainable (Mouth, -1/2)',4);
	        
	        enhancement[10] = getPackageRow('*Disrupting Touch','Dispel Electronic 5d6, any Electrical Gadget one at a time (+1/4), EMP Premium (+1) (34 Active Points); Increased Endurance Cost (x3 END; -1), No Range (-1/2), Extra Time (Full Phase, -1/2), Concentration (1/2 DCV; -1/4)',4);

		}
		
		if (chart == 10)
		{
			//GENETIC ENHANCEMENT X -- very rare abilities verging on metabilities
			
			sTmp = 'Armor (0 PD/9 ED), Hardened (+1/4) (17 Active Points); Only Works Against Very Limited Type of Attack (Fire; -1)';
			sTmp += '<br>LS  (Safe in Intense Heat)';
			enhancement[1] = getPackageRow('*Fire Proof',sTmp,4);
			
			enhancement[2] = getPackageRow('*Doughty','Armor (8 PD/0 ED), Hardened (x3; +3/4) (21 Active Points); Only Works Against Very Limited Type of Attack (Only To Mitigate Damage That Would Be Taken Due To Armor Piercing / Penetrating Attacks; Applied After Halving / Penetrating Effect Calculated; -1)',4);
			
			enhancement[3] = getPackageRow('*Natural Scaler','Clinging (normal STR)',4);

			enhancement[4] = getPackageRow('*Vitality Leech','Transfer 1 point (END to END), Can Transfer Maximum Of 10 Points, Delayed Return Rate (Points Gained) points return at the rate of 5 per Minute (+1/4), Delayed Return Rate (Points Lost) (points return at the rate of 5 per Hour; +1) (21 Active Points); Extra Time (Full Phase, -1/2), Concentration (1/2 DCV; -1/4), Requires Skin On Skin Contact (-1/4)',4);
		
			enhancement[5] = getPackageRow('*Digger','Tunneling 1" through 6 DEF material (20 Active Points); Restrainable (Digging Claws; -1/2), Concentration, Must Concentrate throughout use of Constant Power (1/2 DCV; -1/2)',4);
			
			enhancement[6] = getPackageRow('*Radar Hearing','Radar (Radio Group), Increased Arc Of Perception (360 Degrees) (20 Active Points); Sense Affected As More Than One Sense [very common Sense] (Hearing; -1/2), Side Effects, Side Effect occurs automatically whenever Power is used (Character Suffers x1.5 Effect From Hearing Flash When Effect Is Active; -1/2)',4);
			
			sTmp = 'Knockback Resistance -3" (6 Active Points); Nonpersistent (-1/4)';
			sTmp += '<br>Breakfall +1';
			enhancement[7] = getPackageRow('*Great Balance',sTmp,4);
			
	
	        enhancement[8] = getPackageRow('*Human Antennae','Radio Perception, +2 to PER Roll, Discriminatory, Analyze (20 Active Points); Concentration, Must Concentrate throughout use of Constant Power (0 DCV; -1)',4);
	          
	        enhancement[9] = getPackageRow('*Wings','Flight 8", Reduced Endurance (1/2 END; +1/4) (20 Active Points); Restrainable (Wings, -1/2), Concentration, Must Concentrate throughout use of Constant Power (1/2 DCV; -1/2)',4);
	        
	        enhancement[10] = getPackageRow('*Machine Manipulation','Telekinesis (3 STR), Fine Manipulation, IPE, SFX Only (Fully Invisible; +1/2), Cyberkinesis Premium (+1) (36 Active Points); Only To Control Machines And Machine Parts (-1), Concentration (0 DCV; -1/2), Extra Time (Full Phase, -1/2), Increased Endurance Cost (x2 END; -1/2)',4);

		}

		return enhancement[slot];
		

	}
	function reduceRareAbilities(matchVal)
	{
		//Some Charts have extremely rare abilities
		// to reduce the probability of getting them, this
		// function rolls three more times. Only if all extra rolls
		// are matches will the rare chart be available
		var retVal = parseFloat("0");
		for (var p = 0; p < 3; p++)
		{
		   retVal = roll1dx(chartMax);
		   if(retVal != matchVal)
		   {
			break;
		   }
		}
		return parseFloat(retVal);
	}
	
	function makePackage()
	{
        
		var perSpecial = roll1dx(100);
		var rolls = getRolls();
			
		if(perSpecial < 10 && rolls == 10)
		{
			makeSpecialPackage(roll1dx(phenotypeMax));
			document.getElementById("rollsArea").innerHTML = '<b>Selected: </b><i>Randomly</i>';
		}
		else
		{
			makeRandomPackage(rolls);
		}
		
	}
	
	function makeSpecialPackage(phenotypeId)
	{
	    init();  //always reset 
		//parse input
		var packageRoll =  parseFloat(phenotypeId);
		packageRoll =  parseFloat((isNaN(packageRoll) || (packageRoll=="")) ? "0": packageRoll);
		packageRoll = (packageRoll < 1) ? 0 : packageRoll;
		packageRoll = (packageRoll > phenotypeMax) ? 0 : packageRoll;
		packageRoll = (packageRoll == 0) ? roll1dx(phenotypeMax) : packageRoll;

		var packageDeal = tableStart;
		packageDeal += getPhenotypePackage(packageRoll);
		packageDeal += tableEnd;

		//output
		document.getElementById("resultsArea").innerHTML = packageDeal;
		document.getElementById("costArea").innerHTML = '<b>TOTAL REAL COST: 100 points</b>';
		document.getElementById("rollsArea").innerHTML = '<b>Selected: </b><i>By Link</i>';
	}
	function makeRandomPackage(rolls)
	{
	    init(); //always reset 
		handleWildcardDetermination();
		var packageDeal = tableStart;
		var chartSlotArray;
		//slots
		for (var i = 0; i < rolls; i++)
		{
		    chartSlotArray = getChartSlotArray();
			//Rubber meets the road here:
			packageDeal += getSlotManaged(chartSlotArray[0] ,chartSlotArray[1]);
		}
		//footers
		packageDeal += handleFiguredFootnote(packageDeal.indexOf('#'));
		packageDeal += handleRareFootnote(packageDeal.indexOf('*'));
		packageDeal += tableEnd;
		
		//output
		document.getElementById("costArea").innerHTML = '<b>TOTAL REAL COST: ' + (rolls * 10) + ' points</b>';
		document.getElementById("resultsArea").innerHTML = packageDeal;
		document.getElementById("rerollsArea").innerHTML += '<b>Total Consecutive Rolls:</b> ' + consecutiveRolls;
	}
	
	
	
	function handleWildcardDetermination()
	{
	    //defines which slots should be rerolled if rolled more than once
		var perSpecial = roll1dx(100); //WildCard chance

		//every now and then randomly turn off all the
		// non aggregating abilities
		if(perSpecial >= 90)
		{
			for (var i = 0; i < (SlotRerollTracker.length); i++)
			{
			  SlotRerollTracker[i] = SlotRerollRules[i];
			}
			document.getElementById("wildcardArea").innerHTML = '<b>Wildcard:</b> ' + 'No non-aggregating abilities';
		
		}
		
		//every now and then randomly turn off all the
		// aggregating abilities
		if(perSpecial >= 85 && perSpecial < 90)
		{
			for (var i = 0; i < (SlotRerollTracker.length); i++)
			{
			  SlotRerollTracker[i] = (SlotRerollRules[i] == false);
			  SlotRerollRules[i] = true;
			}
			document.getElementById("wildcardArea").innerHTML = '<b>Wildcard:</b> ' + 'No aggregating abilities';
		}
	}
	
	function handleFiguredFootnote(index)
	{
	    if(index > 0)
	        return figuredMsg;
	    return '';
	}
	function handleRareFootnote(index)
	{
	    if(index > 0)
	        return rareAbilityMsg;
	    return '';
	}    
	    
	function getRerollRequired(chartSlotIndex)
	{
	    return (
	        SlotRerollTracker[chartSlotIndex] == true 
	        && SlotRerollRules[chartSlotIndex] == true
	        );
	}
	function getChartSlotIndex(chart,slot)
	{
		return (((chart-1) * slotMax)-1) + slot;
	}
	function getRandomChartSlotIndex()
	{
	    chartSlotArray = getChartSlotArray();
        chart = chartSlotArray[0];
        slot = chartSlotArray[1];
	    return getChartSlotIndex(chart,slot);
	}
	function getChartSlotArrayByIndex(chartSlotIndex)
	{
	   
	    var chart = parseFloat("0");
	    var slot = parseFloat("-1");
	    var iMod = chartSlotIndex;
	    while(slot < 0)
	    {
	        if (iMod >= slotMax)
	            iMod = (iMod - slotMax)
	        if(iMod < slotMax)
	            slot = iMod;
	            
	        chart++   
	    }
	    return new Array(chart+1,slot+1); //adjust up from 0 based array
	    
	}
	function getChartSlotArray()
	{
	    var chart = roll1dx(chartMax);
	    var slot = roll1dx(slotMax);
	    if(amphib && roll1dx(2) == 2)
	    {//if amphib, give a 50% chance of picking sonar
	        chart = 9;
	        slot = 7;
	    }
	    else
	    {
	        //lower probability for rare abilities
		    if(chart > 8)
		        chart = reduceRareAbilities(chart);
	    }
	    amphib = false;
	    return new Array(chart,slot);
	}
	
	
	
	function handleInterrelatedSlots(chart, slot)
	{//TODO: This works but its realy fugly. Need to refactor
	
		//Handle some mutually exclusive slots; this returns the target slot to be turned off
		
		//Extra Healing and Healing Factor are incompatible
		if ((chart == 4 && slot == 5) || (chart == 1 && slot == 4))
		{
			handleSlotRolledFlagging(
			    chart,
			    slot,
			    getChartSlotIndex(
			        (chart == 4) ? 1 : 4,
			        (chart == 4) ? 4 : 5
			        )
			    );
		}
		//Advanced Physiology and Adaptible overlap too much
		if ((chart == 1 && slot == 3) || (chart == 4 && slot == 3))
		{
			handleSlotRolledFlagging(
			    chart,
			    slot,
			    getChartSlotIndex(
			        (chart == 1) ? 4 : 1,
			        3
			        )
			    );
		}
		//Mighty and Explosive stack too much
		if ((chart == 6 && slot == 2) || (chart == 8 && slot == 2))
		{
			handleSlotRolledFlagging(
			    chart,
			    slot,
			    getChartSlotIndex(
			        (chart == 6) ? 8 : 6,
			        2
			        )
			    );
		}
		//Mighty & Beefcake stack too much
		if ((chart == 6 && slot == 2) || (chart == 1 && slot == 10))
		{
		    handleSlotRolledFlagging(
		        chart,
			    slot,
			    getChartSlotIndex(
			        (chart == 6) ? 8 : 6,
		            (chart == 6) ? 10 : 2
		            )
		        );
	    }
		//Accelerated and Boosted stack too much
		if ((chart == 2 && slot == 4) || (chart == 8 && slot == 1))
		{
			handleSlotRolledFlagging(
		        chart,
			    slot,
			    getChartSlotIndex(
			        (chart == 2) ? 8 : 2,
		            (chart == 2) ? 1 : 4
		            )
		        );
		}
		//Manic and Agile stack too much
		if ((chart == 3 && slot == 5) || (chart == 8 && slot == 3))
		{
			handleSlotRolledFlagging(
		        chart,
			    slot,
			    getChartSlotIndex(
			        (chart == 3) ? 8 : 3,
		            (chart == 3) ? 3 : 5
		            )
		        );
		}
		//Scaler and Brachiator don't mix
		if ((chart == 5 && slot == 5) || (chart == 10 && slot == 3))
		{
			handleSlotRolledFlagging(
		        chart,
			    slot,
			    getChartSlotIndex(
			        (chart == 5) ? 10 : 5,
		            (chart == 5) ? 3 : 5
		            )
		        );
		}
		//Great Balance and Naturally Acrobatic both offer Breakfall, which is not stackable
		if ((chart == 10 && slot == 6) || (chart == 1 && slot == 7))
		{
			handleSlotRolledFlagging(
		        chart,
			    slot,
			    getChartSlotIndex(
			        (chart == 10) ? 1 : 10,
		            (chart == 10) ? 7 : 6
		            )
		        );
		}
		
	}
	
	function handleSlotRolledFlagging(chart,slot,targetChartSlotIndex)
	{
        //flag target slot as having been rolled
		SlotRerollTracker[targetChartSlotIndex] = true; 
		SlotRerollRules[targetChartSlotIndex] = (handleExclusiveAggregateSlots(chart,slot,targetChartSlotIndex) == true) ? true : SlotRerollRules[targetChartSlotIndex];
		
	}
	
	function handleExclusiveAggregateSlots(chart,slot,chartSlotIndex)
	{
	
		//Extra handling for mutually exclusive slots that normally aggregate (allow multiple hits)
		
		//Mighty & Explosive stack too much
		if (
		    (chart == 6 && slot == 2) && (chartSlotIndex == getChartSlotIndex(8,2)) 
		    || (chart == 8 && slot == 2) && (chartSlotIndex == getChartSlotIndex(6,2))
		)
		{
			return true;
		}
		//Mighty & Beefcake stack too much
		if (
		    (chart == 6 && slot == 2) && (chartSlotIndex == getChartSlotIndex(1,10)) 
		    || (chart == 1 && slot == 10) && (chartSlotIndex == getChartSlotIndex(6,2))
		)
		{
			return true;
		}
		//Accelerated and Boosted stack too much
		if (
		    (chart == 2 && slot == 4) && (chartSlotIndex == getChartSlotIndex(8,1)) 
		    || (chart == 8 && slot == 1) && (chartSlotIndex == getChartSlotIndex(2,4))
		)
		{
			return true;
		}
		//Manic and Agile stack too much
		if (
		    (chart == 3 && slot == 5) && (chartSlotIndex == getChartSlotIndex(8,3)) 
		    || (chart == 8 && slot == 3) && (chartSlotIndex == getChartSlotIndex(3,5))
		)
		{
			return true;
		}			
		
		
		return false;		
		
	}
	
	//tracks which slots have been rolled 
    var SlotRerollTracker;
    //returns a clean array of slots init'd to FALSE
    // indicating that no slots have been rolled yet
	function getSlotArray()
	{
		var retArr = new Array(
			false,false,false,false,false,false,false,false,false,false,
			false,false,false,false,false,false,false,false,false,false,
			false,false,false,false,false,false,false,false,false,false,
			false,false,false,false,false,false,false,false,false,false,
			false,false,false,false,false,false,false,false,false,false,
			false,false,false,false,false,false,false,false,false,false,
			false,false,false,false,false,false,false,false,false,false,			
			false,false,false,false,false,false,false,false,false,false,			
			false,false,false,false,false,false,false,false,false,false,			
			false,false,false,false,false,false,false,false,false,false
		);
		return retArr;
	}
    
    //defines which slots can be rolled more than once (false) or only once and force a reroll(true)
    var SlotRerollRules;
	//returns a clean master definition of what allows a reroll and what doesnt. 
	// this method drives behavior; alter at risk 
	// true = slot can only be rolled once
	// false = slot can be rolled any number of times
	function getRerollArray()
	{
		var retArr = new Array(
			true,true,true,true,false,false,true,false,false,false, 
			true,false,true,false,false,false,true,false,false,false,
			true,false,true,false,false,false,true,false,true,false,
			true,false,true,false,true,true,true,false,true,false,
			true,true,false,true,true,false,true,false,true,false,
			false,true,true,false,true,false,true,false,false,false,
			false,false,false,false,false,false,true,false,true,false,			
			true,true,true,false,false,false,true,false,true,true,
			false,true,true,true,true,false,true,false,false,false,
			true,true,true,false,true,true,false,true,false,false			
		);
		return retArr;
	}
	function getRolls()
	{
	    //validates / controls user input field for number of rolls
		var rolls = parseFloat("0");
		//parse input
		rolls = document.forms[0].roll.value.replace(/\$|\,/g,'');
		rolls =  parseFloat((isNaN(rolls) || (rolls=="")) ? "0": rolls);
		rolls = (rolls < rollsMin) ? rollsMin : rolls;
		rolls = (rolls > rollsMax) ? rollsMax : rolls;
		document.forms[0].roll.value = rolls;

		return parseFloat(rolls);
}