Raw Source
Sauvegarde / PoQR

// ==UserScript==
// @name		PoQR
// @namespace	about:blank
// @description	PokemonForAll request parser
// @include		https://www.reddit.com/r/PokemonForAll/comments/*
// @include		http://bulbapedia.bulbagarden.net/wiki/*
// @icon		https://cdn0.iconfinder.com/data/icons/activities-1/24/233-48.png
// @version		1.00
// @grant		none
// ==/UserScript==

"use strict";

////////////////
// Util class //
////////////////

var Util = {};

{
	// return true if the system use little endian bit priority
	Util.littleEndian = function()
	{
		var buffer = new ArrayBuffer(2);
		new DataView(buffer).setInt16(0, 256, true);
		return new Int16Array(buffer)[0] === 256;
	}
	
	const LE = Util.littleEndian();
	
	// quick and dirty unoptimized Array.Copy portage, not even sorry
	Util.arrayCopy = function(srcArr, srcIdx, dstArr, dstIdx, len)
	{
		for(var i = 0 ; i < len ; ++i)
		{
			dstArr[dstIdx + i] = srcArr[srcIdx + i];
		}
	}
	
	// convert an array's data into a string (beware of null chars)
	Util.arrayToString = function(arr)
	{
		var str = "";
		for(var i = 0 ; i < arr.length ; ++i)
		{
			str += String.fromCharCode(arr[i]);
		}
		return str;
	}
	
	// levenshtein distance
	// http://stackoverflow.com/a/11958496/6355515 --thanks guys
	Util.levenshtein = function(s, t)
	{
		var d = [];
		var n = s.length;
		var m = t.length;
		if(n == 0) return m; // Step 1
		if(m == 0) return n;
		for(var i = n ; i >= 0 ; --i) d[i] = []; // Step 2
		for(var i = n ; i >= 0 ; --i) d[i][0] = i;
		for(var j = m ; j >= 0 ; --j) d[0][j] = j;
		for(var i = 1; i <= n; ++i) // Step 3
		{
			var s_i = s.charAt(i - 1);
			for(var j = 1; j <= m; ++j) // Step 4
			{
				//Check the jagged ld total so far
				if(i == j && d[i][j] > 4) return n;
				var t_j = t.charAt(j - 1);
				var cost = (s_i == t_j) ? 0 : 1; // Step 5
				//Calculate the minimum
				var mi = d[i - 1][j] + 1;
				var b = d[i][j - 1] + 1;
				var c = d[i - 1][j - 1] + cost;
				if(b < mi) mi = b;
				if(c < mi) mi = c;
				d[i][j] = mi; // Step 6
				//Damerau transposition
				if(i > 1 && j > 1 && s_i == t.charAt(j - 2) && s.charAt(i - 2) == t_j)
				{
					d[i][j] = Math.min(d[i][j], d[i - 2][j - 2] + cost);
				}
			}
		}
		return d[n][m]; // Step 7
	}

	// search for an approximate occurence in a sring array using levenshtein distance
	Util.arraySearch = function(arr, str)
	{
		var ret = -1;
		var raw = -1;
		var prev = 100;
		str = str.toLowerCase().replace(/é/g, "e").replace(/è/g, "e");
		raw = arr.indexOf(str);
		if(raw > -1)
		{
			return raw;
		}
		for(var i = 0 ; i < arr.length ; ++i)
		{
			if(arr[i])
			{
				var score = Util.levenshtein(arr[i], str);
				if(score < prev)
				{
					prev = score;
					ret = i;
				}
			}
		}
		return ret;
	}
	
	// used to generate random PID and EC
	Util.random32 = function()
	{
		return parseInt(Math.random()*(1 << 30)) << 2 | parseInt(Math.random()*(1 << 2));
	}
}

///////////////
// PKM class //
///////////////

// constant tables
// accentued letters has been replaced by their ASCII equivalent for better comparison with user input
var PKM = {};

{
	// 721 english named species
	// regex to put 10 per lines : /((?:"[^"]*",){10})/
	PKM.species = 
	[
		"","bulbasaur","ivysaur","venusaur","charmander","charmeleon","charizard","squirtle","wartortle","blastoise",
		"caterpie","metapod","butterfree","weedle","kakuna","beedrill","pidgey","pidgeotto","pidgeot","rattata",
		"raticate","spearow","fearow","ekans","arbok","pikachu","raichu","sandshrew","sandslash","nidoran♀",
		"nidorina","nidoqueen","nidoran♂","nidorino","nidoking","clefairy","clefable","vulpix","ninetales","jigglypuff",
		"wigglytuff","zubat","golbat","oddish","gloom","vileplume","paras","parasect","venonat","venomoth",
		"diglett","dugtrio","meowth","persian","psyduck","golduck","mankey","primeape","growlithe","arcanine",
		"poliwag","poliwhirl","poliwrath","abra","kadabra","alakazam","machop","machoke","machamp","bellsprout",
		"weepinbell","victreebel","tentacool","tentacruel","geodude","graveler","golem","ponyta","rapidash","slowpoke",
		"slowbro","magnemite","magneton","farfetch'd","doduo","dodrio","seel","dewgong","grimer","muk",
		"shellder","cloyster","gastly","haunter","gengar","onix","drowzee","hypno","krabby","kingler",
		"voltorb","electrode","exeggcute","exeggutor","cubone","marowak","hitmonlee","hitmonchan","lickitung","koffing",
		"weezing","rhyhorn","rhydon","chansey","tangela","kangaskhan","horsea","seadra","goldeen","seaking",
		"staryu","starmie","mr. mime","scyther","jynx","electabuzz","magmar","pinsir","tauros","magikarp",
		"gyarados","lapras","ditto","eevee","vaporeon","jolteon","flareon","porygon","omanyte","omastar",
		"kabuto","kabutops","aerodactyl","snorlax","articuno","zapdos","moltres","dratini","dragonair","dragonite",
		"mewtwo","mew","chikorita","bayleef","meganium","cyndaquil","quilava","typhlosion","totodile","croconaw",
		"feraligatr","sentret","furret","hoothoot","noctowl","ledyba","ledian","spinarak","ariados","crobat",
		"chinchou","lanturn","pichu","cleffa","igglybuff","togepi","togetic","natu","xatu","mareep",
		"flaaffy","ampharos","bellossom","marill","azumarill","sudowoodo","politoed","hoppip","skiploom","jumpluff",
		"aipom","sunkern","sunflora","yanma","wooper","quagsire","espeon","umbreon","murkrow","slowking",
		"misdreavus","unown","wobbuffet","girafarig","pineco","forretress","dunsparce","gligar","steelix","snubbull",
		"granbull","qwilfish","scizor","shuckle","heracross","sneasel","teddiursa","ursaring","slugma","magcargo",
		"swinub","piloswine","corsola","remoraid","octillery","delibird","mantine","skarmory","houndour","houndoom",
		"kingdra","phanpy","donphan","porygon2","stantler","smeargle","tyrogue","hitmontop","smoochum","elekid",
		"magby","miltank","blissey","raikou","entei","suicune","larvitar","pupitar","tyranitar","lugia",
		"ho-oh","celebi","treecko","grovyle","sceptile","torchic","combusken","blaziken","mudkip","marshtomp",
		"swampert","poochyena","mightyena","zigzagoon","linoone","wurmple","silcoon","beautifly","cascoon","dustox",
		"lotad","lombre","ludicolo","seedot","nuzleaf","shiftry","taillow","swellow","wingull","pelipper",
		"ralts","kirlia","gardevoir","surskit","masquerain","shroomish","breloom","slakoth","vigoroth","slaking",
		"nincada","ninjask","shedinja","whismur","loudred","exploud","makuhita","hariyama","azurill","nosepass",
		"skitty","delcatty","sableye","mawile","aron","lairon","aggron","meditite","medicham","electrike",
		"manectric","plusle","minun","volbeat","illumise","roselia","gulpin","swalot","carvanha","sharpedo",
		"wailmer","wailord","numel","camerupt","torkoal","spoink","grumpig","spinda","trapinch","vibrava",
		"flygon","cacnea","cacturne","swablu","altaria","zangoose","seviper","lunatone","solrock","barboach",
		"whiscash","corphish","crawdaunt","baltoy","claydol","lileep","cradily","anorith","armaldo","feebas",
		"milotic","castform","kecleon","shuppet","banette","duskull","dusclops","tropius","chimecho","absol",
		"wynaut","snorunt","glalie","spheal","sealeo","walrein","clamperl","huntail","gorebyss","relicanth",
		"luvdisc","bagon","shelgon","salamence","beldum","metang","metagross","regirock","regice","registeel",
		"latias","latios","kyogre","groudon","rayquaza","jirachi","deoxys","turtwig","grotle","torterra",
		"chimchar","monferno","infernape","piplup","prinplup","empoleon","starly","staravia","staraptor","bidoof",
		"bibarel","kricketot","kricketune","shinx","luxio","luxray","budew","roserade","cranidos","rampardos",
		"shieldon","bastiodon","burmy","wormadam","mothim","combee","vespiquen","pachirisu","buizel","floatzel",
		"cherubi","cherrim","shellos","gastrodon","ambipom","drifloon","drifblim","buneary","lopunny","mismagius",
		"honchkrow","glameow","purugly","chingling","stunky","skuntank","bronzor","bronzong","bonsly","mime jr.",
		"happiny","chatot","spiritomb","gible","gabite","garchomp","munchlax","riolu","lucario","hippopotas",
		"hippowdon","skorupi","drapion","croagunk","toxicroak","carnivine","finneon","lumineon","mantyke","snover",
		"abomasnow","weavile","magnezone","lickilicky","rhyperior","tangrowth","electivire","magmortar","togekiss","yanmega",
		"leafeon","glaceon","gliscor","mamoswine","porygon-z","gallade","probopass","dusknoir","froslass","rotom",
		"uxie","mesprit","azelf","dialga","palkia","heatran","regigigas","giratina","cresselia","phione",
		"manaphy","darkrai","shaymin","arceus","victini","snivy","servine","serperior","tepig","pignite",
		"emboar","oshawott","dewott","samurott","patrat","watchog","lillipup","herdier","stoutland","purrloin",
		"liepard","pansage","simisage","pansear","simisear","panpour","simipour","munna","musharna","pidove",
		"tranquill","unfezant","blitzle","zebstrika","roggenrola","boldore","gigalith","woobat","swoobat","drilbur",
		"excadrill","audino","timburr","gurdurr","conkeldurr","tympole","palpitoad","seismitoad","throh","sawk",
		"sewaddle","swadloon","leavanny","venipede","whirlipede","scolipede","cottonee","whimsicott","petilil","lilligant",
		"basculin","sandile","krokorok","krookodile","darumaka","darmanitan","maractus","dwebble","crustle","scraggy",
		"scrafty","sigilyph","yamask","cofagrigus","tirtouga","carracosta","archen","archeops","trubbish","garbodor",
		"zorua","zoroark","minccino","cinccino","gothita","gothorita","gothitelle","solosis","duosion","reuniclus",
		"ducklett","swanna","vanillite","vanillish","vanilluxe","deerling","sawsbuck","emolga","karrablast","escavalier",
		"foongus","amoonguss","frillish","jellicent","alomomola","joltik","galvantula","ferroseed","ferrothorn","klink",
		"klang","klinklang","tynamo","eelektrik","eelektross","elgyem","beheeyem","litwick","lampent","chandelure",
		"axew","fraxure","haxorus","cubchoo","beartic","cryogonal","shelmet","accelgor","stunfisk","mienfoo",
		"mienshao","druddigon","golett","golurk","pawniard","bisharp","bouffalant","rufflet","braviary","vullaby",
		"mandibuzz","heatmor","durant","deino","zweilous","hydreigon","larvesta","volcarona","cobalion","terrakion",
		"virizion","tornadus","thundurus","reshiram","zekrom","landorus","kyurem","keldeo","meloetta","genesect",
		"chespin","quilladin","chesnaught","fennekin","braixen","delphox","froakie","frogadier","greninja","bunnelby",
		"diggersby","fletchling","fletchinder","talonflame","scatterbug","spewpa","vivillon","litleo","pyroar","flabebe",
		"floette","florges","skiddo","gogoat","pancham","pangoro","furfrou","espurr","meowstic","honedge",
		"doublade","aegislash","spritzee","aromatisse","swirlix","slurpuff","inkay","malamar","binacle","barbaracle",
		"skrelp","dragalge","clauncher","clawitzer","helioptile","heliolisk","tyrunt","tyrantrum","amaura","aurorus",
		"sylveon","hawlucha","dedenne","carbink","goomy","sliggoo","goodra","klefki","phantump","trevenant",
		"pumpkaboo","gourgeist","bergmite","avalugg","noibat","noivern","xerneas","yveltal","zygarde","diancie",
		"hoopa","volcanion"
	];
	
	// species can hatch from an egg
	PKM.breedable =
	[
		0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
		1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
		1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,
		0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
		1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,0,
		0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
		1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
		1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,
		1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
		1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,1,1,
		1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
		1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
		1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,
		1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
		1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
	];
	
	// Experience group for each pokemon (# is the index, starting at 0 : "egg")
	// 0 == medium fast
	// 1 == erratic
	// 2 == fluctuating
	// 3 == medium slow
	// 4 == fast
	// 5 == slow
	PKM.expGroup =
	[
		0,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,3,3,3,0,0,0,0,0,0,0,0,0,0,3,3,3,3,3,3,4,4,0,0,4,4,0,0,3,3,3,0,0,0,0,
		0,0,0,0,0,0,0,0,5,5,3,3,3,3,3,3,3,3,3,3,3,3,5,5,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,3,3,3,0,0,0,0,0,
		0,0,5,5,0,0,0,0,0,0,0,5,5,4,0,0,0,0,0,0,5,5,0,0,0,0,0,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,
		5,3,3,3,3,3,3,3,3,3,3,0,0,0,0,4,4,4,4,0,5,5,0,4,4,4,4,0,0,3,3,3,3,4,4,0,3,3,3,3,4,3,3,0,0,0,0,0,3,0,
		4,0,0,0,0,0,0,3,0,4,4,0,0,3,5,3,0,0,0,0,5,5,4,0,0,4,5,5,5,5,0,0,0,0,5,4,0,0,0,0,0,5,4,5,5,5,5,5,5,5,
		5,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,5,5,5,0,0,2,2,5,5,5,1,1,1,3,3,3,2,2,4,0,
		4,4,3,4,5,5,5,0,0,5,5,0,0,1,2,3,2,2,5,5,2,2,0,0,0,4,4,4,3,3,3,3,3,1,1,1,2,4,4,0,0,2,2,0,0,1,1,1,1,1,
		1,0,3,4,4,4,4,5,4,3,0,0,0,3,3,3,1,1,1,5,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,3,3,3,3,3,3,3,3,3,3,3,3,0,
		0,3,3,3,3,3,3,3,1,1,1,1,0,0,0,3,3,0,0,0,0,0,0,0,4,2,2,0,0,4,3,4,4,4,0,0,0,0,0,0,4,3,0,5,5,5,5,3,3,5,
		5,5,5,0,0,5,1,1,5,5,5,3,0,0,5,0,0,0,4,0,0,0,3,5,0,5,0,4,0,0,5,5,5,5,5,5,5,5,5,5,5,5,3,5,5,3,3,3,3,3,
		3,3,3,3,0,0,3,3,3,0,0,0,0,0,0,0,0,4,4,3,3,3,0,0,3,3,3,0,0,0,0,4,3,3,3,3,3,3,0,0,3,3,3,3,3,3,0,0,0,0,
		0,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,4,4,3,3,3,3,3,3,0,0,5,5,5,0,0,0,0,0,0,0,0,0,4,0,0,0,0,3,
		3,3,5,5,5,0,0,3,3,3,5,5,5,0,0,0,0,0,0,3,3,0,0,0,0,0,0,5,5,5,5,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
		3,3,3,3,3,3,3,3,3,0,0,3,3,3,0,0,0,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,
		0,0,0,5,5,5,5,4,0,0,0,0,0,0,0,0,5,5,5,5,5,5
	];
	
	// experience required to be at a level [index][expGroup]
	// http://bulbapedia.bulbagarden.net/wiki/Experience
	PKM.expTable =
	[
		[0,0,0,0,0,0],
		[0,0,0,0,0,0],
		[8,15,4,9,6,10],
		[27,52,13,57,21,33],
		[64,122,32,96,51,80],
		[125,237,65,135,100,156],
		[216,406,112,179,172,270],
		[343,637,178,236,274,428],
		[512,942,276,314,409,640],
		[729,1326,393,419,583,911],
		[1000,1800,540,560,800,1250],
		[1331,2369,745,742,1064,1663],
		[1728,3041,967,973,1382,2160],
		[2197,3822,1230,1261,1757,2746],
		[2744,4719,1591,1612,2195,3430],
		[3375,5737,1957,2035,2700,4218],
		[4096,6881,2457,2535,3276,5120],
		[4913,8155,3046,3120,3930,6141],
		[5832,9564,3732,3798,4665,7290],
		[6859,11111,4526,4575,5487,8573],
		[8000,12800,5440,5460,6400,10000],
		[9261,14632,6482,6458,7408,11576],
		[10648,16610,7666,7577,8518,13310],
		[12167,18737,9003,8825,9733,15208],
		[13824,21012,10506,10208,11059,17280],
		[15625,23437,12187,11735,12500,19531],
		[17576,26012,14060,13411,14060,21970],
		[19683,28737,16140,15244,15746,24603],
		[21952,31610,18439,17242,17561,27440],
		[24389,34632,20974,19411,19511,30486],
		[27000,37800,23760,21760,21600,33750],
		[29791,41111,26811,24294,23832,37238],
		[32768,44564,30146,27021,26214,40960],
		[35937,48155,33780,29949,28749,44921],
		[39304,51881,37731,33084,31443,49130],
		[42875,55737,42017,36435,34300,53593],
		[46656,59719,46656,40007,37324,58320],
		[50653,63822,50653,43808,40522,63316],
		[54872,68041,55969,47846,43897,68590],
		[59319,72369,60505,52127,47455,74148],
		[64000,76800,66560,56660,51200,80000],
		[68921,81326,71677,61450,55136,86151],
		[74088,85942,78533,66505,59270,92610],
		[79507,90637,84277,71833,63605,99383],
		[85184,95406,91998,77440,68147,106480],
		[91125,100237,98415,83335,72900,113906],
		[97336,105122,107069,89523,77868,121670],
		[103823,110052,114205,96012,83058,129778],
		[110592,115015,123863,102810,88473,138240],
		[117649,120001,131766,109923,94119,147061],
		[125000,125000,142500,117360,100000,156250],
		[132651,131324,151222,125126,106120,165813],
		[140608,137795,163105,133229,112486,175760],
		[148877,144410,172697,141677,119101,186096],
		[157464,151165,185807,150476,125971,196830],
		[166375,158056,196322,159635,133100,207968],
		[175616,165079,210739,169159,140492,219520],
		[185193,172229,222231,179056,148154,231491],
		[195112,179503,238036,189334,156089,243890],
		[205379,186894,250562,199999,164303,256723],
		[216000,194400,267840,211060,172800,270000],
		[226981,202013,281456,222522,181584,283726],
		[238328,209728,300293,234393,190662,297910],
		[250047,217540,315059,246681,200037,312558],
		[262144,225443,335544,259392,209715,327680],
		[274625,233431,351520,272535,219700,343281],
		[287496,241496,373744,286115,229996,359370],
		[300763,249633,390991,300140,240610,375953],
		[314432,257834,415050,314618,251545,393040],
		[328509,267406,433631,329555,262807,410636],
		[343000,276458,459620,344960,274400,428750],
		[357911,286328,479600,360838,286328,447388],
		[373248,296358,507617,377197,298598,466560],
		[389017,305767,529063,394045,311213,486271],
		[405224,316074,559209,411388,324179,506530],
		[421875,326531,582187,429235,337500,527343],
		[438976,336255,614566,447591,351180,548720],
		[456533,346965,639146,466464,365226,570666],
		[474552,357812,673863,485862,379641,593190],
		[493039,367807,700115,505791,394431,616298],
		[512000,378880,737280,526260,409600,640000],
		[531441,390077,765275,547274,425152,664301],
		[551368,400293,804997,568841,441094,689210],
		[571787,411686,834809,590969,457429,714733],
		[592704,423190,877201,613664,474163,740880],
		[614125,433572,908905,636935,491300,767656],
		[636056,445239,954084,660787,508844,795070],
		[658503,457001,987754,685228,526802,823128],
		[681472,467489,1035837,710266,545177,851840],
		[704969,479378,1071552,735907,563975,881211],
		[729000,491346,1122660,762160,583200,911250],
		[753571,501878,1160499,789030,602856,941963],
		[778688,513934,1214753,816525,622950,973360],
		[804357,526049,1254796,844653,643485,1005446],
		[830584,536557,1312322,873420,664467,1038230],
		[857375,548720,1354652,902835,685900,1071718],
		[884736,560922,1415577,932903,707788,1105920],
		[912673,571333,1460276,963632,730138,1140841],
		[941192,583539,1524731,995030,752953,1176490],
		[970299,591882,1571884,1027103,776239,1212873],
		[1000000,600000,1640000,1059860,800000,1250000]
	];
	
	PKM.natures =
	[
		"hardy","lonely","brave","adamant","naughty","bold",
		"docile","relaxed","impish","lax","timid","hasty",
		"serious","jolly","naive","modest","mild","quiet",
		"bashful","rash","calm","gentle","sassy","careful",
		"quirky"
	];
	
	// all the moves up to 6th gen
	// http://bulbapedia.bulbagarden.net/wiki/List_of_moves
	PKM.moves =
	[
		"","pound","karate chop","double slap","comet punch","mega punch","pay day","fire punch","ice punch","thunder punch",
		"scratch","vice grip","guillotine","razor wind","swords dance","cut","gust","wing attack","whirlwind","fly",
		"bind","slam","vine whip","stomp","double kick","mega kick","jump kick","rolling kick","sand attack","headbutt",
		"horn attack","fury attack","horn drill","tackle","body slam","wrap","take down","thrash","double-edge","tail whip",
		"poison sting","twineedle","pin missile","leer","bite","growl","roar","sing","supersonic","sonic boom",
		"disable","acid","ember","flamethrower","mist","water gun","hydro pump","surf","ice beam","blizzard",
		"psybeam","bubble beam","aurora beam","hyper beam","peck","drill peck","submission","low kick","counter","seismic toss",
		"strength","absorb","mega drain","leech seed","growth","razor leaf","solar beam","poison powder","stun spore","sleep powder",
		"petal dance","string shot","dragon rage","fire spin","thunder shock","thunderbolt","thunder wave","thunder","rock throw","earthquake",
		"fissure","dig","toxic","confusion","psychic","hypnosis","meditate","agility","quick attack","rage",
		"teleport","night shade","mimic","screech","double team","recover","harden","minimize","smokescreen","confuse ray",
		"withdraw","defense curl","barrier","light screen","haze","reflect","focus energy","bide","metronome","mirror move",
		"self-destruct","egg bomb","lick","smog","sludge","bone club","fire blast","waterfall","clamp","swift",
		"skull bash","spike cannon","constrict","amnesia","kinesis","soft-boiled","high jump kick","glare","dream eater","poison gas",
		"barrage","leech life","lovely kiss","sky attack","transform","bubble","dizzy punch","spore","flash","psywave",
		"splash","acid armor","crabhammer","explosion","fury swipes","bonemerang","rest","rock slide","hyper fang","sharpen",
		"conversion","tri attack","super fang","slash","substitute","struggle","sketch","triple kick","thief","spider web",
		"mind reader","nightmare","flame wheel","snore","curse","flail","conversion 2","aeroblast","cotton spore","reversal",
		"spite","powder snow","protect","mach punch","scary face","feint attack","sweet kiss","belly drum","sludge bomb","mud-slap",
		"octazooka","spikes","zap cannon","foresight","destiny bond","perish song","icy wind","detect","bone rush","lock-on",
		"outrage","sandstorm","giga drain","endure","charm","rollout","false swipe","swagger","milk drink","spark",
		"fury cutter","steel wing","mean look","attract","sleep talk","heal bell","return","present","frustration","safeguard",
		"pain split","sacred fire","magnitude","dynamic punch","megahorn","dragon breath","baton pass","encore","pursuit","rapid spin",
		"sweet scent","iron tail","metal claw","vital throw","morning sun","synthesis","moonlight","hidden power","cross chop","twister",
		"rain dance","sunny day","crunch","mirror coat","psych up","extreme speed","ancient power","shadow ball","future sight","rock smash",
		"whirlpool","beat up","fake out","uproar","stockpile","spit up","swallow","heat wave","hail","torment",
		"flatter","will-o-wisp","memento","facade","focus punch","smelling salts","follow me","nature power","charge","taunt",
		"helping hand","trick","role play","wish","assist","ingrain","superpower","magic coat","recycle","revenge",
		"brick break","yawn","knock off","endeavor","eruption","skill swap","imprison","refresh","grudge","snatch",
		"secret power","dive","arm thrust","camouflage","tail glow","luster purge","mist ball","feather dance","teeter dance","blaze kick",
		"mud sport","ice ball","needle arm","slack off","hyper voice","poison fang","crush claw","blast burn","hydro cannon","meteor mash",
		"astonish","weather ball","aromatherapy","fake tears","air cutter","overheat","odor sleuth","rock tomb","silver wind","metal sound",
		"grass whistle","tickle","cosmic power","water spout","signal beam","shadow punch","extrasensory","sky uppercut","sand tomb","sheer cold",
		"muddy water","bullet seed","aerial ace","icicle spear","iron defense","block","howl","dragon claw","frenzy plant","bulk up",
		"bounce","mud shot","poison tail","covet","volt tackle","magical leaf","water sport","calm mind","leaf blade","dragon dance",
		"rock blast","shock wave","water pulse","doom desire","psycho boost","roost","gravity","miracle eye","wake-up slap","hammer arm",
		"gyro ball","healing wish","brine","natural gift","feint","pluck","tailwind","acupressure","metal burst","u-turn",
		"close combat","payback","assurance","embargo","fling","psycho shift","trump card","heal block","wring out","power trick",
		"gastro acid","lucky chant","me first","copycat","power swap","guard swap","punishment","last resort","worry seed","sucker punch",
		"toxic spikes","heart swap","aqua ring","magnet rise","flare blitz","force palm","aura sphere","rock polish","poison jab","dark pulse",
		"night slash","aqua tail","seed bomb","air slash","x-scissor","bug buzz","dragon pulse","dragon rush","power gem","drain punch",
		"vacuum wave","focus blast","energy ball","brave bird","earth power","switcheroo","giga impact","nasty plot","bullet punch","avalanche",
		"ice shard","shadow claw","thunder fang","ice fang","fire fang","shadow sneak","mud bomb","psycho cut","zen headbutt","mirror shot",
		"flash cannon","rock climb","defog","trick room","draco meteor","discharge","lava plume","leaf storm","power whip","rock wrecker",
		"cross poison","gunk shot","iron head","magnet bomb","stone edge","captivate","stealth rock","grass knot","chatter","judgment",
		"bug bite","charge beam","wood hammer","aqua jet","attack order","defend order","heal order","head smash","double hit","roar of time",
		"spacial rend","lunar dance","crush grip","magma storm","dark void","seed flare","ominous wind","shadow force","hone claws","wide guard",
		"guard split","power split","wonder room","psyshock","venoshock","autotomize","rage powder","telekinesis","magic room","smack down",
		"storm throw","flame burst","sludge wave","quiver dance","heavy slam","synchronoise","electro ball","soak","flame charge","coil",
		"low sweep","acid spray","foul play","simple beam","entrainment","after you","round","echoed voice","chip away","clear smog",
		"stored power","quick guard","ally switch","scald","shell smash","heal pulse","hex","sky drop","shift gear","circle throw",
		"incinerate","quash","acrobatics","reflect type","retaliate","final gambit","bestow","inferno","water pledge","fire pledge",
		"grass pledge","volt switch","struggle bug","bulldoze","frost breath","dragon tail","work up","electroweb","wild charge","drill run",
		"dual chop","heart stamp","horn leech","sacred sword","razor shell","heat crash","leaf tornado","steamroller","cotton guard","night daze",
		"psystrike","tail slap","hurricane","head charge","gear grind","searing shot","techno blast","relic song","secret sword","glaciate",
		"bolt strike","blue flare","fiery dance","freeze shock","ice burn","snarl","icicle crash","v-create","fusion flare","fusion bolt",
		"flying press","mat block","belch","rototiller","sticky web","fell stinger","phantom force","trick-or-treat","noble roar","ion deluge",
		"parabolic charge","forest's curse","petal blizzard","freeze-dry","disarming voice","parting shot","topsy-turvy","draining kiss","crafty shield","flower shield",
		"grassy terrain","misty terrain","electrify","play rough","fairy wind","moonblast","boomburst","fairy lock","king's shield","play nice",
		"confide","diamond storm","steam eruption","hyperspace hole","water shuriken","mystical fire","spiky shield","aromatic mist","eerie impulse","venom drench",
		"powder","geomancy","magnetic flux","happy hour","electric terrain","dazzling gleam","celebrate","hold hands","baby-doll eyes","nuzzle",
		"hold back","infestation","power-up punch","oblivion wing","thousand arrows","thousand waves","land's wrath","light of ruin","origin pulse","precipice blades",
		"dragon ascent","hyperspace fury"
	];
	
	// base PP of each move in 6th gen (50 per line)
	PKM.movesBasePP =
	[
		 0,35,25,10,15,20,20,15,15,15,35,30, 5,10,20,30,35,35,20,15,20,20,25,20,30, 5,10,15,15,15,25,20, 5,35,15,20,20,10,15,30,35,20,20,30,25,40,20,15,20,20,
		20,30,25,15,30,25, 5,15,10, 5,20,20,20, 5,35,20,25,20,20,20,15,25,15,10,20,25,10,35,30,15,10,40,10,15,30,15,20,10,15,10, 5,10,10,25,10,20,40,30,30,20,
		20,15,10,40,15,10,30,10,20,10,40,40,20,30,30,20,30,10,10,20, 5,10,30,20,20,20, 5,15,15,20,10,15,35,20,15,10,10,30,15,40,20,15,10, 5,10,30,10,15,20,15,
		40,20,10, 5,15,10,10,10,15,30,30,10,10,20,10, 1, 1,10,25,10, 5,15,25,15,10,15,30, 5,40,15,10,25,10,30,10,20,10,10,10,10,10,20, 5,40, 5, 5,15, 5,10, 5,
		10,10,10,10,20,20,40,15,10,20,20,25, 5,15,10, 5,20,15,20,25,20, 5,30, 5,10,20,40, 5,20,40,20,15,35,10, 5, 5, 5,15, 5,20, 5, 5,15,20,10, 5, 5,15,10,15,
		15,10,10,10,20,10,10,10,10,15,15,15,10,20,20,10,20,20,20,20,20,10,10,10,20,20, 5,15,10,10,15,10,20, 5, 5,10,10,20, 5,10,20,10,20,20,20, 5, 5,15,20,10,
		15,20,15,10,10,15,10, 5, 5,10,15,10, 5,20,25, 5,40,15, 5,40,15,20,20, 5,15,20,20,15,15, 5,10,30,20,30,15, 5,40,15, 5,20, 5,15,25,25,15,20,15,20,15,20,
		10,20,20, 5, 5,10, 5,40,10,10, 5,10,10,15,10,20,15,30,10,20, 5,10,10,15,10,10, 5,15, 5,10,10,30,20,20,10,10, 5, 5,10, 5,20,10,20,10,15,10,20,20,20,15,
		15,10,15,15,15,10,10,10,20,10,30, 5,10,15,10,10, 5,20,30,10,30,15,15,15,15,30,10,20,15,10,10,20,15, 5, 5,15,15, 5,10, 5,20, 5,15,20, 5,20,20,20,20,10,
		20,10,15,20,15,10,10, 5,10, 5, 5,10, 5, 5,10, 5, 5, 5,15,10,10,10,10,10,10,15,20,15,10,15,10,15,10,20,10,15,10,20,20,20,20,20,15,15,15,15,15,15,20,15,
		10,15,15,15,15,10,10,10,10,10,15,15,15,15, 5, 5,15, 5,10,10,10,20,20,20,10,10,30,15,15,10,15,25,10,15,10,10,10,20,10,10,10,10,10,15,15, 5, 5,10,10,10,
		 5, 5,10, 5, 5,15,10, 5, 5, 5,10,10,10,10,20,25,10,20,30,25,20,20,15,20,15,20,20,10,10,10,10,10,20,10,30,15,10,10,10,20,20, 5, 5, 5,20,10,10,20,15,20,
		20,10,20,30,10,10,40,40,30,20,40,20,20,10,10,10,10, 5,10,10, 5, 5
	];
	
	// abilities available for 6th gen pokemon
	PKM.abilities =
	[
		"","stench","drizzle","speed boost","battle armor","sturdy","damp","limber","sand veil","static",
		"volt absorb","water absorb","oblivious","cloud nine","compound eyes","insomnia","color change","immunity","flash fire","shield dust",
		"own tempo","suction cups","intimidate","shadow tag","rough skin","wonder guard","levitate","effect spore","synchronize","clear body",
		"natural cure","lightning rod","serene grace","swift swim","chlorophyll","illuminate","trace","huge power","poison point","inner focus",
		"magma armor","water veil","magnet pull","soundproof","rain dish","sand stream","pressure","thick fat","early bird","flame body",
		"run away","keen eye","hyper cutter","pickup","truant","hustle","cute charm","plus","minus","forecast",
		"sticky hold","shed skin","guts","marvel scale","liquid ooze","overgrow","blaze","torrent","swarm","rock head",
		"drought","arena trap","vital spirit","white smoke","pure power","shell armor","air lock","tangled feet","motor drive","rivalry",
		"steadfast","snow cloak","gluttony","anger point","unburden","heatproof","simple","dry skin","download","iron fist",
		"poison heal","adaptability","skill link","hydration","solar power","quick feet","normalize","sniper","magic guard","no guard",
		"stall","technician","leaf guard","klutz","mold breaker","super luck","aftermath","anticipation","forewarn","unaware",
		"tinted lens","filter","slow start","scrappy","storm drain","ice body","solid rock","snow warning","honey gather","frisk",
		"reckless","multitype","flower gift","bad dreams","pickpocket","sheer force","contrary","unnerve","defiant","defeatist",
		"cursed body","healer","friend guard","weak armor","heavy metal","light metal","multiscale","toxic boost","flare boost","harvest",
		"telepathy","moody","overcoat","poison touch","regenerator","big pecks","sand rush","wonder skin","analytic","illusion",
		"imposter","infiltrator","mummy","moxie","justified","rattled","magic bounce","sap sipper","prankster","sand force",
		"iron barbs","zen mode","victory star","turboblaze","teravolt","aroma veil","flower veil","cheek pouch","protean","fur coat",
		"magician","bulletproof","competitive","strong jaw","refrigerate","sweet veil","stance change","gale wings","mega launcher","grass pelt",
		"symbiosis","tough claws","pixilate","gooey","aerilate","parental bond","dark aura","fairy aura","aura break","primordial sea",
		"desolate land","delta stream"
	];
	
	// abilities available (by code) for each species
	// index of this table is pokemon species number
	PKM.speciesAbilities = 
	[
		[0,0,0],[65,0,34],[65,0,34],[65,0,34],[66,0,94],[66,0,94],[66,0,94],[67,0,44],[67,0,44],[67,0,44],
		[19,0,50],[61,0,0],[14,0,110],[19,0,50],[61,0,0],[68,0,97],[51,77,145],[51,77,145],[51,77,145],[50,62,55],
		[50,62,55],[51,0,97],[51,0,97],[22,61,127],[22,61,127],[9,0,31],[9,0,31],[8,0,146],[8,0,146],[38,79,55],
		[38,79,55],[38,79,125],[38,79,55],[38,79,55],[38,79,125],[56,98,132],[56,98,109],[18,0,70],[18,0,70],[56,172,132],
		[56,172,119],[39,0,151],[39,0,151],[34,0,50],[34,0,1],[34,0,27],[27,87,6],[27,87,6],[14,110,50],[19,110,147],
		[8,71,159],[8,71,159],[53,101,127],[7,101,127],[6,13,33],[6,13,33],[72,83,128],[72,83,128],[22,18,154],[22,18,154],
		[11,6,33],[11,6,33],[11,6,33],[28,39,98],[28,39,98],[28,39,98],[62,99,80],[62,99,80],[62,99,80],[34,0,82],
		[34,0,82],[34,0,82],[29,64,44],[29,64,44],[69,5,8],[69,5,8],[69,5,8],[50,18,49],[50,18,49],[12,20,144],
		[12,20,144],[42,5,148],[42,5,148],[51,39,128],[50,48,77],[50,48,77],[47,93,115],[47,93,115],[1,60,143],[1,60,143],
		[75,92,142],[75,92,142],[26,0,0],[26,0,0],[26,0,0],[69,5,133],[15,108,39],[15,108,39],[52,75,125],[52,75,125],
		[43,9,106],[43,9,106],[34,0,139],[34,0,139],[69,31,4],[69,31,4],[7,120,84],[51,89,39],[20,12,13],[26,0,0],
		[26,0,0],[31,69,120],[31,69,120],[30,32,131],[34,102,144],[48,113,39],[33,97,6],[38,97,6],[33,41,31],[33,41,31],
		[35,30,148],[35,30,148],[43,111,101],[68,101,80],[12,108,87],[9,0,72],[49,0,72],[52,104,153],[22,83,125],[33,0,155],
		[22,0,153],[11,75,93],[7,0,150],[50,91,107],[11,0,93],[10,0,95],[18,0,62],[36,88,148],[33,75,133],[33,75,133],
		[33,4,133],[33,4,133],[69,46,127],[17,47,82],[46,0,81],[46,0,9],[46,0,49],[61,0,63],[61,0,63],[39,0,136],
		[46,0,127],[28,0,0],[65,0,102],[65,0,102],[65,0,102],[66,0,18],[66,0,18],[66,0,18],[67,0,125],[67,0,125],
		[67,0,125],[50,51,119],[50,51,119],[15,51,110],[15,51,110],[68,48,155],[68,48,89],[68,15,97],[68,15,97],[39,0,151],
		[10,35,11],[10,35,11],[9,0,31],[56,98,132],[56,172,132],[55,32,105],[55,32,105],[28,48,156],[28,48,156],[9,0,57],
		[9,0,57],[9,0,57],[34,0,131],[47,37,157],[47,37,157],[5,69,155],[11,6,2],[34,102,151],[34,102,151],[34,102,151],
		[50,53,92],[34,94,48],[34,94,48],[3,14,119],[6,11,109],[6,11,109],[28,0,156],[28,0,39],[15,105,158],[12,20,144],
		[26,0,0],[26,0,0],[23,0,140],[39,48,157],[5,0,142],[5,0,142],[32,50,155],[52,8,17],[69,5,125],[22,50,155],
		[22,95,155],[38,33,22],[68,101,135],[5,82,126],[68,62,153],[39,51,124],[53,95,118],[62,95,127],[40,49,133],[40,49,133],
		[12,81,47],[12,81,47],[55,30,144],[55,97,141],[21,97,141],[72,55,15],[33,11,41],[51,5,133],[48,18,127],[48,18,127],
		[33,97,6],[53,0,8],[5,0,8],[36,88,148],[22,119,157],[20,101,141],[62,80,72],[22,101,80],[12,108,93],[9,0,72],
		[49,0,72],[47,113,157],[30,32,131],[46,0,10],[46,0,18],[46,0,11],[62,0,8],[61,0,0],[45,0,127],[46,0,136],
		[46,0,144],[30,0,0],[65,0,84],[65,0,84],[65,0,84],[66,0,3],[66,0,3],[66,0,3],[67,0,6],[67,0,6],
		[67,0,6],[50,95,155],[22,95,153],[53,82,95],[53,82,95],[19,0,50],[61,0,0],[68,0,79],[61,0,0],[19,0,14],
		[33,44,20],[33,44,20],[33,44,20],[34,48,124],[34,48,124],[34,48,124],[62,0,113],[62,0,113],[51,0,44],[51,0,44],
		[28,36,140],[28,36,140],[28,36,140],[33,0,44],[22,0,127],[27,90,95],[27,90,101],[54,0,0],[72,0,0],[54,0,0],
		[14,0,50],[3,0,151],[25,0,0],[43,0,155],[43,0,113],[43,0,113],[47,62,125],[47,62,125],[47,37,157],[5,42,159],
		[56,96,147],[56,96,147],[51,100,158],[52,22,125],[5,69,134],[5,69,134],[5,69,134],[74,0,140],[74,0,140],[9,31,58],
		[9,31,58],[57,0,31],[58,0,10],[35,68,158],[12,110,158],[30,38,102],[64,60,82],[64,60,82],[24,0,3],[24,0,3],
		[41,12,46],[41,12,46],[12,86,20],[40,116,83],[73,0,75],[47,20,82],[47,20,82],[20,77,126],[52,71,125],[26,0,0],
		[26,0,0],[8,0,11],[8,0,11],[30,0,13],[30,0,13],[17,0,137],[61,0,151],[26,0,0],[26,0,0],[12,107,93],
		[12,107,93],[52,75,91],[52,75,91],[26,0,0],[26,0,0],[21,0,114],[21,0,114],[4,0,33],[4,0,33],[33,12,91],
		[63,172,56],[59,0,0],[16,0,168],[15,119,130],[15,119,130],[26,0,119],[46,0,119],[34,94,139],[26,0,0],[46,105,154],
		[23,0,140],[39,115,141],[39,115,141],[47,115,12],[47,115,12],[47,115,12],[75,0,155],[33,0,41],[33,0,93],[33,69,5],
		[33,0,93],[69,0,125],[69,0,142],[22,0,153],[29,0,135],[29,0,135],[29,0,135],[29,0,5],[29,0,115],[29,0,135],
		[26,0,0],[26,0,0],[2,0,0],[70,0,0],[76,0,0],[32,0,0],[46,0,0],[65,0,75],[65,0,75],[65,0,75],
		[66,0,89],[66,0,89],[66,0,89],[67,0,128],[67,0,128],[67,0,128],[51,0,120],[22,0,120],[22,0,120],[86,109,141],
		[86,109,141],[61,0,50],[68,0,101],[79,22,62],[79,22,62],[79,22,62],[30,38,102],[30,38,101],[104,0,125],[104,0,125],
		[5,0,43],[5,0,43],[61,0,142],[107,0,142],[68,0,110],[118,0,55],[46,0,127],[50,53,10],[33,0,41],[33,0,41],
		[34,0,0],[122,0,0],[60,114,159],[60,114,159],[101,53,92],[106,84,138],[106,84,138],[50,103,7],[56,103,7],[26,0,0],
		[15,105,153],[7,20,51],[47,20,128],[26,0,0],[1,106,51],[1,106,51],[26,85,134],[26,85,134],[5,69,155],[43,111,101],
		[30,32,132],[51,77,145],[46,0,151],[8,0,24],[8,0,24],[8,0,24],[53,47,82],[80,39,158],[80,39,154],[45,0,159],
		[45,0,159],[4,97,51],[4,97,51],[107,87,143],[107,87,143],[26,0,0],[33,114,41],[33,114,41],[33,11,41],[117,0,43],
		[117,0,43],[46,0,124],[42,5,148],[20,12,13],[31,116,120],[34,102,144],[78,0,72],[49,0,72],[55,32,105],[3,110,119],
		[102,0,34],[81,0,115],[52,8,90],[12,81,47],[91,88,148],[80,0,154],[5,42,159],[46,0,119],[81,0,130],[26,0,0],
		[26,0,0],[26,0,0],[26,0,0],[46,0,140],[46,0,140],[18,0,49],[112,0,0],[46,0,140],[26,0,0],[93,0,0],
		[93,0,0],[123,0,0],[30,0,0],[121,0,0],[162,0,0],[65,0,126],[65,0,126],[65,0,126],[66,0,47],[66,0,47],
		[66,0,120],[67,0,75],[67,0,75],[67,0,75],[50,51,148],[35,51,148],[72,53,50],[22,146,113],[22,146,113],[7,84,158],
		[7,84,158],[82,0,65],[82,0,65],[82,0,66],[82,0,66],[82,0,67],[82,0,67],[108,28,140],[108,28,140],[145,105,79],
		[145,105,79],[145,105,79],[31,78,157],[31,78,157],[5,0,159],[5,0,159],[5,0,159],[109,103,86],[109,103,86],[146,159,104],
		[146,159,104],[131,144,103],[62,125,89],[62,125,89],[62,125,89],[33,93,11],[33,93,11],[33,143,11],[62,39,104],[5,39,104],
		[68,34,142],[102,34,142],[68,34,142],[38,68,3],[38,68,3],[38,68,3],[158,151,34],[158,151,34],[34,20,102],[34,20,102],
		[120,91,104],[22,153,83],[22,153,83],[22,153,83],[55,0,39],[125,0,161],[11,34,114],[5,75,133],[5,75,133],[61,153,22],
		[61,153,22],[147,98,110],[152,0,0],[152,0,0],[116,5,33],[116,5,33],[129,0,0],[129,0,0],[1,60,106],[1,133,106],
		[149,0,0],[149,0,0],[56,101,92],[56,101,92],[119,172,23],[119,172,23],[119,172,23],[142,98,144],[142,98,144],[142,98,144],
		[51,145,93],[51,145,93],[115,0,133],[115,0,133],[115,0,133],[34,157,32],[34,157,32],[9,0,78],[68,61,99],[68,75,142],
		[27,0,144],[27,0,144],[11,130,6],[11,130,6],[131,93,144],[14,127,68],[14,127,68],[160,0,0],[160,0,107],[57,58,29],
		[57,58,29],[57,58,29],[26,0,0],[26,0,0],[26,0,0],[140,28,148],[140,28,148],[18,49,151],[18,49,151],[18,49,151],
		[79,104,127],[79,104,127],[79,104,127],[81,0,155],[81,0,33],[26,0,0],[93,75,142],[93,60,84],[9,7,8],[39,144,120],
		[39,144,120],[24,125,104],[89,103,99],[89,103,99],[128,39,46],[128,39,46],[120,157,43],[51,125,55],[51,125,128],[145,142,133],
		[145,142,133],[82,18,73],[68,55,54],[55,0,0],[55,0,0],[26,0,0],[49,0,68],[49,0,68],[154,0,0],[154,0,0],
		[154,0,0],[158,0,128],[158,0,128],[163,0,0],[164,0,0],[159,0,125],[46,0,0],[154,0,0],[32,0,0],[88,0,0],
		[65,0,171],[65,0,171],[65,0,171],[66,0,170],[66,0,170],[66,0,170],[67,0,168],[67,0,168],[67,0,168],[53,167,37],
		[53,167,37],[145,0,177],[49,0,177],[49,0,177],[19,14,132],[61,0,132],[19,14,132],[79,127,153],[79,127,153],[166,0,180],
		[166,0,180],[166,0,180],[157,0,179],[157,0,179],[89,104,113],[89,104,113],[169,0,0],[51,151,20],[51,151,158],[99,0,0],
		[99,0,0],[176,0,0],[131,0,165],[131,0,165],[175,0,84],[175,0,84],[126,21,151],[126,21,151],[97,181,124],[97,181,124],
		[38,143,91],[38,143,91],[178,0,0],[178,0,0],[87,8,94],[87,8,94],[173,0,5],[173,0,69],[174,0,117],[174,0,117],
		[56,0,182],[7,84,104],[167,53,57],[29,0,5],[157,93,183],[157,93,183],[157,93,183],[158,0,170],[30,119,139],[30,119,139],
		[53,119,15],[53,119,15],[20,115,5],[20,115,5],[119,151,140],[119,151,140],[187,0,0],[186,0,0],[188,0,0],[29,0,0],
		[170,0,0],[11,0,0]
	];
	
	PKM.locations_gen5 =
	[
		"","mystery zone","faraway place",,"nuvema town","accumula town","striaton city","nacrene city","castelia city",
		"nimbasa city","driftveil city","mistralton city","icirrus city","opelucid city","route 1","route 2","route 3","route 4","route 5",
		"route 6","route 7","route 8","route 9","route 10","route 11","route 12","route 13","route 14","route 15",
		"route 16","route 17","route 18","dreamyard","pinwheel forest","desert resort","relic castle","pwt","chargestone cave","twist mountain",
		"dragonspiral tower","victory road","lacunosa town","undella town","anville town","pokémon league","n's castle","royal unova","gear station","battle subway",
		"musical theater","black city","white forest","unity tower","wellspring cave","mistralton cave","rumination field","celestial tower","moor of icirrus","shopping mall",
		"challenger's cave","poké transfer lab","giant chasm","liberty garden","p2 laboratory","skyarrow bridge","driftveil drawbridge","tubeline bridge","village bridge","marvelous bridge",
		"entralink","abundant shrine","undella bay","lostlorn forest","trial chamber","guidance chamber","entree forest","nimbasa city","driftveil city","mistralton city",
		"icirrus city","opelucid city","nuvema town","white forest","black city","cold storage","chargestone cave","twist mountain","dragonspiral tower","giant chasm",
		"driftveil drawbridge","tubeline bridge","village bridge","marvelous bridge","route 5","route 6","route 7","route 8","route 9","route 11",
		"route 12","route 13","route 14","route 15","route 16","lacunosa town","undella town","accumula gate","undella gate","nacrene gate",
		"castelia gate","nimbasa gate","opelucid gate","black gate","white gate","bridge gate","route gate","abyssal ruins","aspertia city","virbank city",
		"humilau city","pokéstar studios","join avenue","floccesy town","lentimas town","route 19","route 20","route 21","route 22","route 23",
		"castelia sewers","floccesy ranch","virbank complex","reversal mountain","strange house","victory road","plasma frigate","relic passage","clay tunnel",,
		"white treehollow","black tower","seaside cave","cave of being","hidden grotto","marine tube","virbank gate","aspertia gate","nature preserve","medal office",
		"underground ruins","rock peak chamber","iceberg chamber","iron chamber","pledge grove"
	];
	{
		var locs_30000 =
		[
			"","link trade","link trade","kanto","johto","hoenn","sinnoh","distant land",,,,,,"entralink","pokémon dream radar"
		];
		var locs_40000 =
		[
			"","lovely place","faraway place","pokémon movie","pokémon movie 10","pokémon movie 11","pokémon movie 12","pokémon movie 13","pokémon movie 14","pokémon movie 15",
			"pokémon movie 16","pokémon movie 17","pokémon movie 18","pokémon movie 19","pokémon movie 20","pokémon center","pokémon cartoon","pc tokyo","pc osaka","pc fukuoka",
			"pc nagoya","pc sapporo","pc yokohama","wcs","wcs 2010","wcs 2011","wcs 2012","wcs 2013","wcs 2014","wcs 2015",
			"wcs 2016","wcs 2017","wcs 2018","wcs 2019","wcs 2020","worlds","worlds 2010","worlds 2011","worlds 2012","worlds 2013",
			"worlds 2014","worlds 2015","worlds 2016","worlds 2017","worlds 2018","worlds 2019","worlds 2020","vge","vge 2010","vge 2011",
			"vge 2012","vge 2013","vge 2014","vge 2015","vge 2016","vge 2017","vge 2018","vge 2019","vge 2020","pokémon event",
			"battle competition","game event","pokémon fan club","pokémon sunday","challenge plaza","battle challenge","trainers' court","battle tour","concert","wi-fi gift",
			"pokémon ranger","ranger union","pbr","pokémon dw","pokémon event 10","pokémon event 11","pokémon event 12","pokémon event 13","pokémon event 14","pokémon event 15",
			"pokémon event 16","pokémon event 17","pokémon event 18","pokémon event 19","pokémon event 20","pokémon festa","pokémon festa 10","pokémon festa 11","pokémon festa 12","pokémon festa 13",
			"pokémon festa 14","pokémon festa 15","pokémon festa 16","pokémon festa 17","pokémon festa 18","pokémon festa 19","pokémon festa 20","pokÉpark","pokÉpark","pokÉpark",
			"pokepark","pokepark","pokepark","pokepark","pokepark","pokepark","pokepark","pokepark","pokepark","event site"
		];
		var locs_60000 =
		[
			"","stranger","day-care couple","pkmn breeder"
		];
		for(var i = 0 ; i < locs_30000.length ; ++i) PKM.locations_gen5[30000 + i] = locs_30000[i];
		for(var i = 0 ; i < locs_40000.length ; ++i) PKM.locations_gen5[40000 + i] = locs_40000[i];
		for(var i = 0 ; i < locs_60000.length ; ++i) PKM.locations_gen5[60000 + i] = locs_60000[i];
	}
	
	PKM.locations_gen6 =
	[
		"",,"mystery zone",,"faraway place",,"vaniville town",,"route 1","vaniville pathway",
		"aquacorde town",,"route 2","avance trail","santalune forest",,"route 3","ouvert way","santalune city",,
		"route 4","parterre way","lumiose city",,"prism tower",,"lysandre labs",,"route 5","versant road",
		"camphrier town",,"shabboneau castle",,"route 6","palais lane","parfum palace",,"route 7","riviere walk",
		"cyllage city",,"route 8","muraille coast","ambrette town",,"route 9","spikes passage","battle chateau",,
		"route 10","menhir trail","geosenge town",,"route 11","miroir way","reflection cave",,"shalour city",,
		"tower of mastery",,"route 12","fourrage road","coumarine city",,"route 13","lumiose badlands","route 14","laverre nature trail",
		"laverre city",,"poke ball factory",,"route 15","brun way","dendemille town",,"route 16","melancolie path",
		,,"frost cavern",,"route 17","mamoswine road","anistar city",,"route 18","vallee etroite way",
		"couriway town",,"route 19","grande vallee way","snowbelle city",,"route 20","winding woods","pokemon village",,
		"route 21","derniere way","route 22","detourner way","victory road",,"pokemon league",,"kiloude city",,
		"battle maison",,"azure bay",,"dendemille gate",,"couriway gate",,"ambrette gate",,
		"lumiose gate",,"shalour gate",,"coumarine gate",,"laverre gate",,"anistar gate",,
		"snowbelle gate",,"glittering cave",,"connecting cave","zubat roost","kalos power plant",,"team flare secret hq",,
		"terminus cave",,"lost hotel",,"chamber of emptiness",,"sea spirit's den",,"friend safari",,
		"blazing chamber",,"flood chamber",,"ironworks chamber",,"dragonmark chamber",,"radiant chamber",,
		"pokemon league gate",,"lumiose station",,"kiloude station",,"ambrette aquarium",,"unknown dungeon",,
		"littleroot town",,"oldale town",,"dewford town",,"lavaridge town",,"fallarbor town",,
		"verdanturf town",,"pacifidlog town",,"petalburg city",,"slateport city",,"mauville city",,
		"rustboro city",,"fortree city",,"lilycove city",,"mossdeep city",,"sootopolis city",,
		"ever grande city",,"pokemon league",,"route 101",,"route 102",,"route 103",,
		"route 104",,"route 105",,"route 106",,"route 107",,"route 108",,
		"route 109",,"route 110",,"route 111",,"route 112",,"route 113",,
		"route 114",,"route 115",,"route 116",,"route 117",,"route 118",,
		"route 119",,"route 120",,"route 121",,"route 122",,"route 123",,
		"route 124",,"route 125",,"route 126",,"route 127",,"route 128",,
		"route 129",,"route 130",,"route 131",,"route 132",,"route 133",,
		"route 134",,"meteor falls",,"rusturf tunnel",,"???",,"desert ruins",,
		"granite cave",,"petalburg woods",,"mt. chimney",,"jagged pass",,"fiery path",,
		"mt. pyre",,"team aqua hideout",,"seafloor cavern",,"cave of origin",,"victory road",,
		"shoal cave",,"new mauville",,"sea mauville",,"island cave",,"ancient tomb",,
		"sealed chamber",,"scorched slab",,"team magma hideout",,"sky pillar",,"battle resort",,
		"southern island",,"s.s. tidal",,"safari zone",,"mirage forest",,"mirage cave",,
		"mirage island",,"mirage mountain",,"trackless forest",,"pathless plain",,"nameless cavern",,
		"fabled cave",,"gnarled den",,"crescent isle",,"secret islet",,"soaring in the sky",,
		"secret shore",,"secret meadow",,"secret base"
	];
	{
		// locations starting at index 30 000
		var locs_30000 =
		[
			"","poke transfer","a link trade","kanto region","johto region","hoenn region","sinnoh region","a distant land",,"unova region",
			"kalos region","pokemon link"
		];
		// you get it
		var locs_40000 =
		[
			"","a lovely place","a faraway place","a pokemon movie","pokemon movie 13","pokemon movie 14","pokemon movie 15","pokemon movie 16","pokemon movie 17","pokemon movie 18",
			"a pokemon center","the pokemon cartoon","pc tokyo","pc osaka","pc fukuoka","pc nagoya","pc sapporo","pc yokohama","pc tohoku","pc tokyo bay",
			"a pokemon store","a wcs","wcs 2013","wcs 2014","wcs 2015","wcs 2016","wcs 2017","wcs 2018","worlds","worlds 2013",
			"worlds 2014","worlds 2015","worlds 2016","worlds 2017","worlds 2018","a vge","vge 2013","vge 2014","vge 2015","vge 2016",
			"vge 2017","vge 2018","a pokemon event","a battle competition","a game event","the pokemon fan club","a pokemon tv program","a concert","an online present","the pgl",
			"pokemon event 13","pokemon event 14","pokemon event 15","pokemon event 16","pokemon event 17","pokemon event 18","pokemon festa","pokemon festa 13","pokemon festa 14","pokemon festa 15",
			"pokemon festa 16","pokemon festa 17","pokemon festa 18","pokepark","pokepark","pokepark","pokepark","pokepark","pokepark","pokepark",
			"an event site","game freak","a stadium","a vgc","the vgc 2013","the vgc 2014","the vgc 2015","the vgc 2016","the vgc 2017","the vgc 2018"
		];
		var locs_60000 =
		[
			"","a stranger","day care helpers","a treasure hunter","an old hot-springs visitor"
		];
		for(var i = 0 ; i < locs_30000.length ; ++i) PKM.locations_gen6[30000 + i] = locs_30000[i];
		for(var i = 0 ; i < locs_40000.length ; ++i) PKM.locations_gen6[40000 + i] = locs_40000[i];
		for(var i = 0 ; i < locs_60000.length ; ++i) PKM.locations_gen6[60000 + i] = locs_60000[i];
	}
	
	// ball used to capture the mon
	PKM.balls =
	[
		"","master","ultra","great","poke","safari","net","dive","nest","repeat",
		"timer","luxury","premier","dusk","heal","quick","cherish","fast","level","lure",
		"heavy","love","friend","moon","sport","dream"
	];
	
	PKM.items = 
	[
		"none","master ball","ultra ball","great ball","poke ball","safari ball","net ball","dive ball","nest ball","repeat ball",
		"timer ball","luxury ball","premier ball","dusk ball","heal ball","quick ball","cherish ball","potion","antidote","burn heal",
		"ice heal","awakening","paralyze heal","full restore","max potion","hyper potion","super potion","full heal","revive","max revive",
		"fresh water","soda pop","lemonade","moomoo milk","energy powder","energy root","heal powder","revival herb","ether","max ether",
		"elixir","max elixir","lava cookie","berry juice","sacred ash","hp up","protein","iron","carbos","calcium",
		"rare candy","pp up","zinc","pp max","old gateau","guard spec.","dire hit","x attack","x defense","x speed",
		"x accuracy","x sp. atk","x sp. def","poke doll","fluffy tail","blue flute","yellow flute","red flute","black flute","white flute",
		"shoal salt","shoal shell","red shard","blue shard","yellow shard","green shard","super repel","max repel","escape rope","repel",
		"sun stone","moon stone","fire stone","thunder stone","water stone","leaf stone","tiny mushroom","big mushroom","pearl","big pearl",
		"stardust","star piece","nugget","heart scale","honey","growth mulch","damp mulch","stable mulch","gooey mulch","root fossil",
		"claw fossil","helix fossil","dome fossil","old amber","armor fossil","skull fossil","rare bone","shiny stone","dusk stone","dawn stone",
		"oval stone","odd keystone","griseous orb","???","???","???","douse drive","shock drive","burn drive","chill drive",
		"???","???","???","???","???","???","???","???","???","???",
		"???","???","???","???","sweet heart","adamant orb","lustrous orb","greet mail","favored mail","rsvp mail",
		"thanks mail","inquiry mail","like mail","reply mail","bridge mail s","bridge mail d","bridge mail t","bridge mail v","bridge mail m","cheri berry",
		"chesto berry","pecha berry","rawst berry","aspear berry","leppa berry","oran berry","persim berry","lum berry","sitrus berry","figy berry",
		"wiki berry","mago berry","aguav berry","iapapa berry","razz berry","bluk berry","nanab berry","wepear berry","pinap berry","pomeg berry",
		"kelpsy berry","qualot berry","hondew berry","grepa berry","tamato berry","cornn berry","magost berry","rabuta berry","nomel berry","spelon berry",
		"pamtre berry","watmel berry","durin berry","belue berry","occa berry","passho berry","wacan berry","rindo berry","yache berry","chople berry",
		"kebia berry","shuca berry","coba berry","payapa berry","tanga berry","charti berry","kasib berry","haban berry","colbur berry","babiri berry",
		"chilan berry","liechi berry","ganlon berry","salac berry","petaya berry","apicot berry","lansat berry","starf berry","enigma berry","micle berry",
		"custap berry","jaboca berry","rowap berry","bright powder","white herb","macho brace","exp. share","quick claw","soothe bell","mental herb",
		"choice band","king's rock","silver powder","amulet coin","cleanse tag","soul dew","deep sea tooth","deep sea scale","smoke ball","everstone",
		"focus band","lucky egg","scope lens","metal coat","leftovers","dragon scale","light ball","soft sand","hard stone","miracle seed",
		"black glasses","black belt","magnet","mystic water","sharp beak","poison barb","never-melt ice","spell tag","twisted spoon","charcoal",
		"dragon fang","silk scarf","up-grade","shell bell","sea incense","lax incense","lucky punch","metal powder","thick club","stick",
		"red scarf","blue scarf","pink scarf","green scarf","yellow scarf","wide lens","muscle band","wise glasses","expert belt","light clay",
		"life orb","power herb","toxic orb","flame orb","quick powder","focus sash","zoom lens","metronome","iron ball","lagging tail",
		"destiny knot","black sludge","icy rock","smooth rock","heat rock","damp rock","grip claw","choice scarf","sticky barb","power bracer",
		"power belt","power lens","power band","power anklet","power weight","shed shell","big root","choice specs","flame plate","splash plate",
		"zap plate","meadow plate","icicle plate","fist plate","toxic plate","earth plate","sky plate","mind plate","insect plate","stone plate",
		"spooky plate","draco plate","dread plate","iron plate","odd incense","rock incense","full incense","wave incense","rose incense","luck incense",
		"pure incense","protector","electirizer","magmarizer","dubious disc","reaper cloth","razor claw","razor fang","tm01","tm02",
		"tm03","tm04","tm05","tm06","tm07","tm08","tm09","tm10","tm11","tm12",
		"tm13","tm14","tm15","tm16","tm17","tm18","tm19","tm20","tm21","tm22",
		"tm23","tm24","tm25","tm26","tm27","tm28","tm29","tm30","tm31","tm32",
		"tm33","tm34","tm35","tm36","tm37","tm38","tm39","tm40","tm41","tm42",
		"tm43","tm44","tm45","tm46","tm47","tm48","tm49","tm50","tm51","tm52",
		"tm53","tm54","tm55","tm56","tm57","tm58","tm59","tm60","tm61","tm62",
		"tm63","tm64","tm65","tm66","tm67","tm68","tm69","tm70","tm71","tm72",
		"tm73","tm74","tm75","tm76","tm77","tm78","tm79","tm80","tm81","tm82",
		"tm83","tm84","tm85","tm86","tm87","tm88","tm89","tm90","tm91","tm92",
		"hm01","hm02","hm03","hm04","hm05","hm06","???","???","explorer kit","loot sack",
		"rule book","poke radar","point card","journal","seal case","fashion case","seal bag","pal pad","works key","old charm",
		"galactic key","red chain","town map","vs. seeker","coin case","old rod","good rod","super rod","sprayduck","poffin case",
		"bike","suite key","oak's letter","lunar wing","member card","azure flute","s.s. ticket","contest pass","magma stone","parcel",
		"coupon 1","coupon 2","coupon 3","storage key","secret potion","vs. recorder","gracidea","secret key","apricorn box","unown report",
		"berry pots","dowsing machine","blue card","slowpoke tail","clear bell","card key","basement key","squirt bottle","red scale","lost item",
		"pass","machine part","silver wing","rainbow wing","mystery egg","red apricorn","blue apricorn","yellow apricorn","green apricorn","pink apricorn",
		"white apricorn","black apricorn","fast ball","level ball","lure ball","heavy ball","love ball","friend ball","moon ball","sport ball",
		"park ball","photo album","gb sounds","tidal bell","rage candy bar","data card 01","data card 02","data card 03","data card 04","data card 05",
		"data card 06","data card 07","data card 08","data card 09","data card 10","data card 11","data card 12","data card 13","data card 14","data card 15",
		"data card 16","data card 17","data card 18","data card 19","data card 20","data card 21","data card 22","data card 23","data card 24","data card 25",
		"data card 26","data card 27","jade orb","lock capsule","red orb","blue orb","enigma stone","prism scale","eviolite","float stone",
		"rocky helmet","air balloon","red card","ring target","binding band","absorb bulb","cell battery","eject button","fire gem","water gem",
		"electric gem","grass gem","ice gem","fighting gem","poison gem","ground gem","flying gem","psychic gem","bug gem","rock gem",
		"ghost gem","dragon gem","dark gem","steel gem","normal gem","health wing","muscle wing","resist wing","genius wing","clever wing",
		"swift wing","pretty wing","cover fossil","plume fossil","liberty pass","pass orb","dream ball","poke toy","prop case","dragon skull",
		"balm mushroom","big nugget","pearl string","comet shard","relic copper","relic silver","relic gold","relic vase","relic band","relic statue",
		"relic crown","casteliacone","dire hit 2","x speed 2","x sp. atk 2","x sp. def 2","x defense 2","x attack 2","x accuracy 2","x speed 3",
		"x sp. atk 3","x sp. def 3","x defense 3","x attack 3","x accuracy 3","x speed 6","x sp. atk 6","x sp. def 6","x defense 6","x attack 6",
		"x accuracy 6","ability urge","item drop","item urge","reset urge","dire hit 3","light stone","dark stone","tm93","tm94",
		"tm95","xtransceiver","???","gram 1","gram 2","gram 3","xtransceiver","medal box","dna splicers","dna splicers",
		"permit","oval charm","shiny charm","plasma card","grubby hanky","colress machine","dropped item","dropped item","reveal glass","weakness policy",
		"assault vest","holo caster","prof's letter","roller skates","pixie plate","ability capsule","whipped dream","sachet","luminous moss","snowball",
		"safety goggles","poke flute","rich mulch","surprise mulch","boost mulch","amaze mulch","gengarite","gardevoirite","ampharosite","venusaurite",
		"charizardite x","blastoisinite","mewtwonite x","mewtwonite y","blazikenite","medichamite","houndoominite","aggronite","banettite","tyranitarite",
		"scizorite","pinsirite","aerodactylite","lucarionite","abomasite","kangaskhanite","gyaradosite","absolite","charizardite y","alakazite",
		"heracronite","mawilite","manectite","garchompite","latiasite","latiosite","roseli berry","kee berry","maranga berry","sprinklotad",
		"tm96","tm97","tm98","tm99","tm100","power plant pass","mega ring","intriguing stone","common stone","discount coupon",
		"elevator key","tmv pass","honor of kalos","adventure rules","strange souvenir","lens case","travel trunk","travel trunk","lumiose galette","shalour sable",
		"jaw fossil","sail fossil","looker ticket","bike","holo caster","fairy gem","mega charm","mega glove","mach bike","acro bike",
		"wailmer pail","devon parts","soot sack","basement key","pokeblock kit","letter","eon ticket","scanner","go-goggles","meteorite",
		"key to room 1","key to room 2","key to room 4","key to room 6","storage key","devon scope","s.s. ticket","hm07","devon scuba gear","contest costume",
		"contest costume","magma suit","aqua suit","pair of tickets","mega bracelet","mega pendant","mega glasses","mega anchor","mega stickpin","mega tiara",
		"mega anklet","meteorite","swampertite","sceptilite","sablenite","altarianite","galladite","audinite","metagrossite","sharpedonite",
		"slowbronite","steelixite","pidgeotite","glalitite","diancite","prison bottle","mega cuff","cameruptite","lopunnite","salamencite",
		"beedrillite","meteorite","meteorite","key stone","meteorite shard","eon flute"
	];

	PKM.versions =
	[
		"","sapphire","ruby","emerald","firered","leafgreen",,"hearthgold","soulsilver",,
		"diamond","pearl","platinum",,,,,,,,
		"white","black","white2","black2","x","y","alphasapphire","omegaruby"
	];

	PKM.countries = [];
	PKM.countries[  1] = "japan";
	PKM.countries[ 18] = "canada";
	PKM.countries[ 49] = "usa";
	PKM.countries[ 65] = "australia";
	PKM.countries[ 77] = "france";
	PKM.countries[ 78] = "germany";
	PKM.countries[ 83] = "italy";
	PKM.countries[100] = "russia";
	PKM.countries[105] = "spain";
	PKM.countries[110] = "uk";
	PKM.countries[128] = "taiwan";
	PKM.countries[136] = "korea";
	PKM.countries[160] = "china";

	PKM.regions =
	[
		"japan","america","europe",,"china","korea","taiwan"
	];

	PKM.languages =
	[
		"","jpn","eng","fre","ita","ger","","esp","kor"
	];
	
	PKM.events =
	[
		// event_name, species#, friendship, [nature], [regions], [versions],
		// [date_range], met_location, met_level, ball, fatefull, [moves], 
		// ot, otgender, tid, sid, shiny, [ribbons]
		[
			"Pokémon 20th Anniversary Mew",
			151,100,[],[1,2],[24,25,26,27],["2016-01-27","2016-05-31"],400001,100,16,true,
			["pound"],
			"GF",0,"02016","00557",false,"classic"
		],
		[
			"Game Freak Mew",
			151,100,[],[0,6],[24,25,26,27],["2016-07-16","2016-12-18"],400071,5,16,true,
			["pound"],
			"GF",0,"22796","00175",false,"premier"
		],
		[
			"Pokémon 20th Anniversary Celebi",
			251,100,[],[1,2],[24,25,26,27],["2016-03-01","2016-03-24"],400001,100,16,true,
			["confusion","recover","heal bell","safeguard"],
			"GF",0,"03016","00558",false,"classic"
		],
		[
			"2014 Tanabata Jirachi",
			385,100,[],[0],[24,25],["2014-08-01","2014-08-31"],40018,10,16,true,
			["wish","swift","healing wish","moonblast"],
			"たなばた",0,"08014","00034",true,"classic"
		],
		[
			"Wishing Star Jirachi",
			385,100,[],[5],[24,25],["2014-08-05","2014-09-14"],40003,5,16,true,
			["wish","confusion","rest","healing wish"],
			"소원의별",0,"08144","01015",false,"classic"
		],
		[
			"Pokémon Center Jirachi",
			385,100,[],[0],[24,25,26,27],["2014-12-01","2015-05-28"],40010,15,16,true,
			["Wish","confusion","helping hand","return"],
			"ポケセン",0,"12014","00061",true,"classic"
		],
		[
			"2015 Tanabata Jirachi",
			385,100,[],[0],[24,25],["2015-07-18","2015-08-16"],40018,100,16,true,
			["heart stamp","play rough","wish","cosmic power"],
			"おりひめ",1,"07185","00108",false,"classic"
		],
		[
			"2015 Tanabata Jirachi",
			385,100,[],[0],[26,27],["2015-07-18","2015-08-16"],40018,100,16,true,
			["heart stamp","play rough","wish","cosmic power"],
			"ひこぼし",0,"07185","00108",false,"classic"
		],
		[
			"Nintendo Hong Kong Jirachi",
			385,100,[],[0,2,6],[24,25,26,27],["2015-12-12","2016-01-31"],40001,25,16,true,
			["wish","confusion","swift","happy hour"],
			"Nintendo HK",0,"12015","00145",true,"classic"
		],
		[
			"Pokémon 20th Anniversary Jirachi",
			385,100,[],[1,2],[24,25,26,27],["2016-08-01", "2016-08-240"],40001,100,16,true,
			["wish","confusion","rest"],
			"GF",0,"04016","00559",false,"classic"
		],
		[
			"2016 Tanabata Jirachi",
			385,100,[],[0],[24,25],["2016-08-01","2016-08-31"],40018,100,16,true,
			["wish","cosmic power","swift","meteor mash"],
			"ひこぼし",0,"08076","00174",false,"classic"
		],
		[
			"2016 Tanabata Jirachi",
			385,100,[],[0],[26,27],["2016-08-01","2016-08-31"],40018,100,16,true,
			["wish","cosmic power","swift","meteor mash"],
			"おりひめ",1,"08076","00174",false,"classic"
		],
		[
			"Water Tribe Manaphy",
			490,70,[],[5],[26,27],["2015-07-18", "2015-08-31"],40003,1,16,true,
			["tail glow","bubble","water sport","heart swap"],
			"물의일족",0,"07235","01041",false,"wishing"
		],
		[
			"Pokémon 20th Anniversary Manaphy",
			490,70,[],[1,2],[24,25,26,27],["2016-06-01","2016-06-24"],40001,100,16,true,
			["tail glow","bubble","water sport"],
			"GF",0,"06016","00561",false,"classic"
		],
		[
			"Mysterious World Darkrai",
			491,0,[],[5],[24,25,26,27],["2014-12-20","2015-01-25"],40003,50,16,true,
			["dark void","dream eater","dark pulse","phantom force"],
			"신비한세계",0,"12204","01017",false,"wishing"
		],
		[
			"February 2015 Darkrai",
			491,0,[],[2],[24,25,26,27],["2015-02-13","2015-05-05"],40001,50,16,true,
			["dark void","dream eater","dark pulse","phantom force"],
			"FEB2015",0,"02135","00536",false,"classic"
		],
		[
			"Pokémon 20th Anniversary Darkrai",
			491,0,[],[1,2],[24,25,26,27],["2016-05-01","2016-10-31"],40001,100,16,true,
			["dark void","ominous wind","nightmare","feint attack"],
			"GF",0,"05016","00560",false,"classic"
		],
		[
			"Shaymin",
			492,100,[],[0],[24,25,26,27],["2014-12-01","2015-05-15"],40001,15,16,true,
			["growth","magical leaf","seed flare","air slash"],
			"Pスクラップ",0,"12014","00050",false,"classic"
		],
		[
			"Full Story Shaymin",
			492,100,[],[5],[26,27],["2015-07-17","2016-01-31"],40001,15,16,true,
			["growth","magical leaf","seed flare","air slash"],
			"완전스토리",0,"04155","01024",false,"classic"
		],
		[
			"Pokémon 20th Anniversary Shaymin",
			492,100,[],[1,2],[24,25,26,27],["2016-07-01","2016-07-24"],40001,100,16,true,
			["seed flare","aromatherapy","substitute","energy ball"],
			"GF",0,"07016","00562",false,"classic"
		],
		[
			"Dahara City Arceus",
			493,0,[],[0,6],[24,25,26,27],["2015-03-07","2015-12-17"],40006,100,16,true,
			["judgment","blast burn","hydro cannon","earth power"],
			"デセルシティ",0,"03075","00081",[true,false],"wishing"
		],
		[
			"Dahara City Arceus",
			493,0,[],[5],[24,25,26,27],["2015-12-15","2016-02-29"],40003,100,16,true,
			["judgment","blast burn","hydro cannon","earth power"],
			"데세르시티",0,"12235","01053",false,"wishing"
		]
	];
}

///////////////
// PK6 class //
///////////////

// handler for a sixth generation pokémon data
var PK6 = function()
{
	this._data = new Uint8Array(0xe8); // 232 as we are not including battle stats
	this._view = new DataView(this._data.buffer);
	this.shiny = false; // will be used in pid calculation
};

{
	const LE = Util.littleEndian();
	
	/////////////////////////
	// Property generators //
	/////////////////////////
	
	// when we need simple setters / getters with none of those bit-wise operations
	function simpleProperty(adr, size, name)
	{
		switch(size)
		{
			case 32: Object.defineProperty(PK6.prototype, name,
			{
				get: function()		{return this._view.getUint32(adr, LE);},
				set: function(nv)	{this._view.setUint32(adr, nv, LE);}
			});
			break;
			case 16: Object.defineProperty(PK6.prototype, name,
			{
				get: function()		{return this._view.getUint16(adr, LE);},
				set: function(nv)	{this._view.setUint16(adr, nv, LE);}
			});
			break;
			case 8: Object.defineProperty(PK6.prototype, name,
			{
				get: function()		{return this._view.getUint8(adr);},
				set: function(nv)	{this._view.setUint8(adr, nv);}
			});
			break;
		}
	}
	
	// many ribbons are stored on a single byte
	function ribbonProperty(adr, shift, name)
	{
		Object.defineProperty(PK6.prototype, name,
		{
			get: function()
			{
				return (this._view.getUint8(adr) & (1 << shift)) == 1 << shift;
			},
			set: function(nv)
			{
				var prev = this._view.getUint8(adr);
				this._view.setUint8(adr, (prev & ~(1 << shift)) | (nv ? 1 << shift : 0));
			}
		});
	}
	
	// iv are all stored on a 32 bit integer
	function ivProperty(adr, shift, name)
	{
		Object.defineProperty(PK6.prototype, name,
		{
			get: function()
			{
				return (this._view.getUint32(adr, LE) >> shift) & 0x1f;
			},
			set: function(nv)
			{
				var prev = this._view.getUint32(adr, LE);
				this._view.setUint32(adr, (prev & ~(0x1f << shift)) | (nv > 31 ? 31 : nv) << shift, LE);
			}
		});
	}
	
	// names must handle special chars
	function nameProperty(adr, name)
	{
		Object.defineProperty(PK6.prototype, name,
		{
			get: function()
			{
				var nick = "";
				var bound = adr + 0x1a; // 13 chars (26 bytes)
				for(var i = adr ; i < bound ; i += 0x2)
				{
					nick += String.fromCharCode(this._view.getUint16(i, LE));
				}
				nick = nick.replace(/\x00/g, "");	// trim the null chars
				nick = nick.replace("\ue08f", "\u2640"); // decode ♂ char as in nidoran♂
				nick = nick.replace("\ue08e", "\u2642"); // decode ♀ char as in nidoran♀
				nick = nick.replace("\u2019", "\u0027"); // decode ' char as in farfetch'd
				return nick;
			},
			set: function(nv)
			{
				var c = adr;
				var bound = adr + 0x1a;
				nv = nv.slice(0, 12); // 12 chars max
				nv = nv.replace("\u2640", "\ue08f"); // encode ♂ char
				nv = nv.replace("\u2642", "\ue08e"); // encode ♀ char
				nv = nv.replace("\u0027", "\u2019"); // encode ' char
				for(var i = 0 ; i < nv.length ; ++i)
				{
					this._view.setUint16(c, nv.codePointAt(i), LE);
					c += 0x2;
				}
				while(c < bound) // right padding with \0
				{
					this._view.setUint8(c, 0);
					c += 0x1;
				}
			}
		});
	}
	
	// properties related to PKM tables
	function tableProperty(adr, size, table, name)
	{
		function searchTable(nv)
		{
			if(typeof nv === "string")
			{
				nv = Util.arraySearch(table, nv);
			}
			return nv >= 0 ? nv : 0;
		}
		switch(size)
		{
			case 32: Object.defineProperty(PK6.prototype, name,
			{
				get: function()		{return this._view.getUint32(adr, LE);},
				set: function(nv)	{this._view.setUint32(adr, searchTable(nv), LE);}
			});
			break;
			case 16: Object.defineProperty(PK6.prototype, name,
			{
				get: function()		{return this._view.getUint16(adr, LE);},
				set: function(nv)	{this._view.setUint16(adr, searchTable(nv), LE);}
			});
			break;
			case 8: Object.defineProperty(PK6.prototype, name,
			{
				get: function()		{return this._view.getUint8(adr);},
				set: function(nv)	{this._view.setUint8(adr, searchTable(nv));}
			});
			break;
		}
	}
	
	// also table related but we need to be more specific here as it depends on gen
	function locationProperty(adr, name)
	{
		function searchTable(nv, v)
		{
			if(typeof nv === "string")
			{
				if     (v >= 20 && v <= 23)	nv = Util.arraySearch(PKM.locations_gen5, nv);
				else if(v >= 24 && v <= 27)	nv = Util.arraySearch(PKM.locations_gen6, nv);
				else						nv = 0;
			}
			return nv >= 0 ? nv : 0;
		}
		Object.defineProperty(PK6.prototype, name,
		{
			get: function()		{return this._view.getUint16(adr, LE);},
			set: function(nv)	{this._view.setUint16(adr, searchTable(nv, this.version), LE);}
		});
	}
	
	/////////////
	// Methods //
	/////////////
	
	PK6.prototype.correctValues = function()
	{
		var speciesName = PKM.species[this.species];
		if(!this.isNicknamed || this.nickname.toLowerCase() == speciesName)
		{
			this.isNicknamed = false;
			this.nickname = speciesName[0].toUpperCase() + speciesName.slice(1); // nickname is species name by default
		}
		if(!PKM.breedable[this.species] || this.met_level != 1)
		{
			this.egg_location = 0;
			this.egg_year = 0;
			this.egg_month = 0;
			this.egg_day = 0;
		}
		else if(this.met_location == 318 && (this.version == 24 || this.version == 25))
		{
			// pokemon has hatched on battle resort in version x or y ? I don't think so
			// put route 7 instead (this is the long one just in front of day care building
			this.met_location = 38;
		}
		if(this.version < 20) // before 5th gen
		{
			// https://www.reddit.com/r/PokemonForAll/wiki/guidetogenningevents
			this.met_location = "poke transfer";
		}
	}
	
	PK6.prototype.generateEC = function()
	{
		if(this.version >= 20)
		{
			return this.ec = Util.random32();
		}
		return this.ec = 0;
	}
	
	// http://bulbapedia.bulbagarden.net/wiki/Personality_value
	PK6.prototype.generatePID = function()
	{
		if(this.version >= 20)
		{
			while(1)
			{
				var pid = Util.random32();
				var lid = pid & 0xffff;
				var hid = pid >> 16;
				var xor = this.tid ^ lid ^ this.sid ^ hid;
				if(!this.shiny ^ (xor >> 3 == 1))
				{
					return this.pid = this.shiny ? pid ^ xor : pid;
				}
			}
		}
		return this.pid = 0;
	}
	
	PK6.prototype.generateChecksum = function()
	{
		var chk = 0;
		for(var i = 0x08 ; i < 0xe8 ; i += 2)
		{
			chk += this._view.getUint16(i, LE);
		}
		return this.checksum = chk;
	}
	
	// compute checksum and returns what needs to be converted into a qr code after a btoa()
	PK6.prototype.getDataString = function()
	{
		this.correctValues();
		this.generatePID();
		this.generateChecksum();
		return Util.arrayToString(this._data);
	}
	
	// doesn't work : "Invalid checksum in QR data"
	PK6.prototype.getEncryptedDataString = function()
	{
		const blockPos =
		[
			[0,0,0,0,0,0,1,1,2,3,2,3,1,1,2,3,2,3,1,1,2,3,2,3],
			[1,1,2,3,2,3,0,0,0,0,0,0,2,3,1,1,3,2,2,3,1,1,3,2],
			[2,3,1,1,3,2,2,3,1,1,3,2,0,0,0,0,0,0,3,2,3,2,1,1],
			[3,2,3,2,1,1,3,2,3,2,1,1,3,2,3,2,1,1,0,0,0,0,0,0]
		];
		const blockPosInv = 
		[
			0,1,2,4,3,5,6,7,12,18,13,19,8,10,14,20,16,22,9,11,15,21,17,23
		];
		function shuffleArray(data, sv)
		{
			var sdata = new Uint8Array(data.length);
			Util.arrayCopy(data, 0, sdata, 0, 8);
			for(var block = 0 ; block < 4 ; ++block) // shuffle away!
			{
				Util.arrayCopy(data, 8 + 56*blockPos[block][sv], sdata, 8 + 56*block, 56);
			}
			return sdata;
		}
		function lcrng(seed)
		{
			const a = 0x41c64e6d;
			const c = 0x00006073;
			return seed*a + c;
		}
		this.correctValues();
		this.generateEC();
		this.generatePID();
		this.generateChecksum();
		var pv = this._view.getUint32(0, LE);
		var sv = (pv >> 0xd & 0x1f) % 24;
		var seed = lcrng(pv);
		var ekx = this._data.slice();
		var ekv = new DataView(ekx.buffer);
		ekx = shuffleArray(ekx, blockPosInv[sv]);
		for(var i = 8 ; i < 232 ; i += 2) // encrypt blocks with RNG seed
		{
			seed = lcrng(seed);
			ekv.setUint16(i, ekv.getUint16(i, LE) ^ seed >> 16, LE); // maybe problem here ?
		}
		return Util.arrayToString(ekx);
	}
	
	////////////////
	// Properties //
	////////////////
	
	// Block A
	
	simpleProperty(0x00, 32, "ec"); // encryption constant
	simpleProperty(0x04, 16, "sanity"); // Should always be zero...
	simpleProperty(0x06, 16, "checksum");
	tableProperty(0x08, 16, PKM.species, "species");
	tableProperty(0x0a, 16, PKM.items, "heldItem");
	simpleProperty(0x0c, 16, "tid");
	simpleProperty(0x0e, 16, "sid");
	simpleProperty(0x10, 32, "exp");
	
	Object.defineProperty(PK6.prototype, "ability",
	{
		get: function()
		{
			return this._view.getUint8(0x14);
		},
		set: function(nv)
		{
			var ability = Math.max(0, (typeof nv === "string") ? Util.arraySearch(PKM.abilities, nv) : nv);
			this._view.setUint8(0x14, ability);
			if(this.ability > 0 && this.species > 0)
			{
				// try to calculate the associated "abilityNum" of the pokemon
				var abilityNum = Math.max(0, PKM.speciesAbilities[this.species].indexOf(this.ability)*2); // 0 / 2 / 4
				this._view.setUint8(0x15, abilityNum);
			}
		}
	});
	
	simpleProperty(0x15, 8, "abilityNum");
	simpleProperty(0x16, 8, "trainingBagHits");
	simpleProperty(0x17, 8, "trainingBag");
	simpleProperty(0x18, 32, "pid");
	tableProperty(0x1c, 8, PKM.natures, "nature");
	
	Object.defineProperty(PK6.prototype, "fateful",
	{
		get: function()				{return (this._view.getUint8(0x1d) & 1) == 1;},
		set: function(nv)			{this._view.setUint8(0x1d, this._view.getUint8(0x1d) & ~0x01 | (nv ? 1 : 0));}
	});
	
	Object.defineProperty(PK6.prototype, "gender",
	{
		get: function()				{return (this._view.getUint8(0x1d) >> 1) & 0x3;},
		set: function(nv)			{this._view.setUint8(0x1d, this._view.getUint8(0x1d) & ~0x06 | (nv << 1));}
	});
	
	Object.defineProperty(PK6.prototype, "altForm",
	{
		get: function()				{return this._view.getUint8(0x1d) >> 3;},
		set: function(nv)			{this._view.setUint8(0x1d, this._view.getUint8(0x1d) & 0x07 | (nv << 3));}
	});
	
	// this actually does not exists in the data structure but can be tied to exp width the PKM tables
	Object.defineProperty(PK6.prototype, "level",
	{
		get: function()
		{
			var exp = this.exp;
			var expGroup = PKM.expGroup[this.species];
			for(var i = 1 ; i <= 100 ; ++i)
			{
				var inf = exp >= PKM.expTable[i][expGroup];
				var sup = i == 100 || exp < PKM.expTable[i+1][expGroup];
				if(inf && sup)
				{
					return i;
				}
			}
			return 0;
		},
		set: function(nv)
		{
			this.exp = PKM.expTable[nv][PKM.expGroup[this.species]];
		}
	});
	
	simpleProperty(0x1e, 8, "ev_hp");
	simpleProperty(0x1f, 8, "ev_atk");
	simpleProperty(0x20, 8, "ev_def");
	simpleProperty(0x21, 8, "ev_spe");
	simpleProperty(0x22, 8, "ev_spa");
	simpleProperty(0x23, 8, "ev_spd");
	simpleProperty(0x24, 8, "cnt_cool");
	simpleProperty(0x25, 8, "cnt_beauty");
	simpleProperty(0x26, 8, "cnt_cute");
	simpleProperty(0x27, 8, "cnt_smart");
	simpleProperty(0x28, 8, "cnt_tough");
	simpleProperty(0x29, 8, "cnt_sheen");
	simpleProperty(0x2a, 8, "boxMark"); // box marking (● ▲ ■ ♥ ★ ♦)
	simpleProperty(0x2b, 8, "pkrs");
	
	Object.defineProperty(PK6.prototype, "pkrs_days",
	{
		get: function()				{return this._view.getUint8(0x2b) & 0xf;},
		set: function(nv)			{this._view.setUint8(0x2b, this._view.getUint8(0x2b) & ~0xf | nv);}
	});
	
	Object.defineProperty(PK6.prototype, "pkrs_strain",
	{
		get: function()				{return this._view.getUint8(0x2b) >> 4;},
		set: function(nv)			{this._view.setUint8(0x2b, this._view.getUint8(0x2b) & 0xf | nv << 4);}
	});
	
	// skip super training : 0x2c to 0x2f
	
	simpleProperty(0x30, 8, "rib0");
	simpleProperty(0x31, 8, "rib1");
	simpleProperty(0x32, 8, "rib2");
	simpleProperty(0x33, 8, "rib3");
	simpleProperty(0x34, 8, "rib4");
	simpleProperty(0x35, 8, "rib5");
	
	// skip to rib3 : those who really matter
	
	ribbonProperty(0x33, 0, "rib_earth");
	ribbonProperty(0x33, 1, "rib_world");
	ribbonProperty(0x33, 2, "rib_classic");
	ribbonProperty(0x33, 3, "rib_premier");
	ribbonProperty(0x33, 4, "rib_event");
	ribbonProperty(0x33, 5, "rib_birthday");
	ribbonProperty(0x33, 6, "rib_special"); // i'm special
	ribbonProperty(0x33, 7, "rib_souvenir");
	ribbonProperty(0x34, 0, "rib_wishing");
	
	// skip other ribbons
	
	// we won't be using these
	simpleProperty(0x38, 8, "ribCountMemoryContest");
	simpleProperty(0x39, 8, "ribCountMemoryBattle");
	simpleProperty(0x3a, 8, "distByte"); // related to super train (?)
	
	// Block B
	
	nameProperty(0x40, "nickname");
	
	tableProperty(0x5a, 16, PKM.moves, "move1");
	tableProperty(0x5c, 16, PKM.moves, "move2");
	tableProperty(0x5e, 16, PKM.moves, "move3");
	tableProperty(0x60, 16, PKM.moves, "move4");
	simpleProperty(0x62, 8, "move1_pp");
	simpleProperty(0x63, 8, "move2_pp");
	simpleProperty(0x64, 8, "move3_pp");
	simpleProperty(0x65, 8, "move4_pp");
	simpleProperty(0x66, 8, "move1_pp_up");
	simpleProperty(0x67, 8, "move2_pp_up");
	simpleProperty(0x68, 8, "move3_pp_up");
	simpleProperty(0x69, 8, "move4_pp_up");
	simpleProperty(0x6a, 16, "relearnMove1");
	simpleProperty(0x6c, 16, "relearnMove2");
	simpleProperty(0x6e, 16, "relearnMove3");
	simpleProperty(0x70, 16, "relearnMove4");
	
	simpleProperty(0x74, 32, "iv");
	ivProperty(0x74,  0, "iv_hp");
	ivProperty(0x74,  5, "iv_atk");
	ivProperty(0x74, 10, "iv_def");
	ivProperty(0x74, 15, "iv_spe");
	ivProperty(0x74, 20, "iv_spa");
	ivProperty(0x74, 25, "iv_spd");
	
	Object.defineProperty(PK6.prototype, "isEgg",
	{
		get: function()		{return ((this._view.getUint32(0x74, LE) >> 30) & 1) == 1;},
		set: function(nv)	{this._view.setUint32(0x74, (this._view.getUint32(0x74, LE) & ~0x40000000) | (nv ? 0x40000000 : 0), LE);}
	});
	
	Object.defineProperty(PK6.prototype, "isNicknamed",
	{
		get: function()		{return ((this._view.getUint32(0x74, LE) >> 31) & 1) == 1;},
		set: function(nv)	{this._view.setUint32(0x74, (this._view.getUint32(0x74, LE) & 0x7fffffff) | (nv ? 0x80000000 : 0), LE);}
	});
	
	// Block C
	
	nameProperty(0x78, "ht_name");
	simpleProperty(0x92, 8, "ht_gender");
	simpleProperty(0x93, 8, "currentHandler");
	
	simpleProperty(0x94, 8, "geo1_region");
	simpleProperty(0x95, 8, "geo1_country");
	simpleProperty(0x96, 8, "geo2_region");
	simpleProperty(0x97, 8, "geo2_country");
	simpleProperty(0x98, 8, "geo3_region");
	simpleProperty(0x99, 8, "geo3_country");
	simpleProperty(0x9a, 8, "geo4_region");
	simpleProperty(0x9b, 8, "geo4_country");
	simpleProperty(0x9c, 8, "geo5_region");
	simpleProperty(0x9d, 8, "geo5_country");
	
	simpleProperty(0xa2, 8, "ht_friendship");
	simpleProperty(0xa3, 8, "ht_affection");
	simpleProperty(0xa4, 8, "ht_intensity");
	simpleProperty(0xa5, 8, "ht_memory");
	simpleProperty(0xa6, 8, "ht_feeling");
	
	simpleProperty(0xa8, 16, "ht_textVar");
	
	simpleProperty(0xae, 8, "fullness");
	simpleProperty(0xaf, 8, "enjoyment");
	
	// Block D
	
	nameProperty(0xb0, "ot_name");
	simpleProperty(0xca, 8, "ot_friendship");
	simpleProperty(0xcb, 8, "ot_affection");
	simpleProperty(0xcc, 8, "ot_intensity");
	simpleProperty(0xcd, 8, "ot_memory");
	simpleProperty(0xce, 16, "ot_textVar");
	simpleProperty(0xd0, 8, "ot_feeling");
	
	simpleProperty(0xd1, 8, "egg_year");
	simpleProperty(0xd2, 8, "egg_month");
	simpleProperty(0xd3, 8, "egg_day");
	simpleProperty(0xd4, 8, "met_year");
	simpleProperty(0xd5, 8, "met_month");
	simpleProperty(0xd6, 8, "met_day");
	
	locationProperty(0xd8, "egg_location");
	locationProperty(0xda, "met_location");
	tableProperty(0xdc, 8, PKM.balls, "ball");
	
	Object.defineProperty(PK6.prototype, "met_level",
	{
		get: function()		{return this._view.getUint8(0xdd) & ~0x80;},
		set: function(nv)	{this._view.setUint8(0xdd, (this._view.getUint8(0xdd) & 0x80) | nv);}
	});
	
	Object.defineProperty(PK6.prototype, "ot_gender",
	{
		get: function()		{return this._view.getUint8(0xdd) >> 7;},
		set: function(nv)	{this._view.setUint8(0xdd, (this._view.getUint8(0xdd) & ~0x80) | nv << 7);}
	});
	
	simpleProperty(0xde, 8, "encounterType");
	tableProperty(0xdf, 8, PKM.versions, "version");
	tableProperty(0xe0, 8, PKM.countries, "country");
	simpleProperty(0xe1, 8, "subRegion"); // depends on the country chosen
	tableProperty(0xe2, 8, PKM.regions, "region");
	tableProperty(0xe3, 8, PKM.languages, "language");
}

// standard gen template
function addGenTemplate(pkm)
{
	var ajd = new Date();
	pkm.species = 1; // bulbasaur
	pkm.exp = 1059860; // level 100
	pkm.nature = 12; // serious
	pkm.language = 2; // english
	pkm.country = 49; // usa
	pkm.region = 1; // america
	pkm.version = 26; // alpha sapphire
	pkm.ball = 4; // pokeball
	pkm.met_level = 1;
	pkm.met_location = 318; // battle resort
	pkm.egg_location = 60002; // day care helper
	pkm.met_year  = pkm.egg_year  = ajd.getYear() - 100;
	pkm.met_month = pkm.egg_month = ajd.getMonth() + 1;
	pkm.met_day   = pkm.egg_day   = ajd.getDate();
	pkm.iv_hp = pkm.iv_atk = pkm.iv_def = pkm.iv_spa = pkm.iv_spd = pkm.iv_spe = 31;
	pkm.ot_name = "Askolei"
	pkm.tid = 25691;
	pkm.sid = 19371;
	pkm.ot_memory = 47; // stared by a judge
	pkm.ot_feeling = 9; // got nervous
	return pkm;
}

function addEventTemplate(pkm)
{
	pkm.ot_friendship = 70; // good memory but doesn't seem to remember anything
	pkm.ot_memory = 0;
	pkm.ot_feeling = 0;
	pkm.ht_name = "Askolei";
	pkm.ht_friendship = 70;
	pkm.ht_memory = 3; // met at ...
	pkm.ht_textVar = 9; // a pokémon center...
	pkm.ht_intensity = 0; // the pokemon remembers...
	pkm.ht_feeling = 0; // it was happy
	return pkm;
}

// gotta parse 'em all !
function parseGenRequest(md)
{
	function parseOnlyInt(str)
	{
		return parseInt(str.replace(/[^\d]/g, ""));
	}
	function parseNickname(dom, val)
	{
		if(!val.match(/^$|^\W?(n\/a|no|none)\W?$/i))
		{
			pkm.nickname = val;
			pkm.isNicknamed = true;
		}
	}
	function parseGender(dom, val)
	{
		if     (val.match(/^m/i))	pkm.gender = 0; // male
		else if(val.match(/^f/i))	pkm.gender = 1; // female
		else						pkm.gender = 2; // genderless
	}
	function parseRegion(dom, val)
	{
		if     (val.match(/jpn|japan/i))		{pkm.region = "japan";		pkm.country = "japan";	pkm.language = "jpn";}
		else if(val.match(/usa?|uni|america/i))	{pkm.region = "america";	pkm.country = "usa";	pkm.language = "eng";}
		else if(val.match(/eur?|pal|europe/i))	{pkm.region = "europe";		pkm.country = "uk";		pkm.language = "eng";}
		else if(val.match(/china/i))			{pkm.region = "china";		pkm.country = "china";	pkm.language = "eng";}
		else if(val.match(/kor|korea/i))		{pkm.region = "korea";		pkm.country = "korea";	pkm.language = "kor";}
		else if(val.match(/tw|taiwan/i))		{pkm.region = "taiwan";		pkm.country = "taiwan";	pkm.language = "kor";}
		else
		{
			dom.style.color = "red";
		}
	}
	function parseMetInfos(dom, val)
	{
		var subParts = val.split(/\s*[\/,]\s*/);
		if(subParts.length == 3)
		{
			pkm.version = subParts[0]
				.replace(/pok[eé]mon/i, "")
				.replace(/^hg/i, "hearthgold")
				.replace(/^ss/i, "soulsilver")
				.replace(/^pl|pt/i, "platinum")
				.replace(/^w2/i, "white2")
				.replace(/^b2/i, "black2")
				.replace(/^as/i, "alphasapphire")
				.replace(/^or/i, "omegaruby");
			pkm.met_location = subParts[1].replace(/.*hatch.*/i, "battle resort");
			pkm.met_level = parseOnlyInt(subParts[2]) || 1;
		}
		else
		{
			dom.style.color = "red";
		}
	}
	function parseMetDate(dom, val)
	{
		var subParts = val.split(/\W+/);
		if(subParts.length >= 3)
		{
			var numberParsed = 0;
			for(var i = 0 ; i < 3 ; ++i)
			{
				var n = parseOnlyInt(subParts[i]);
				if(!isNaN(n))
				{
					subParts[i] = n;
					numberParsed++;
				}
			}
			if(numberParsed == 3)
			{
				if(subParts[0] >= 2000 && subParts[1] <= 12 && subParts[2] <= 31)
				{
					// assuming yyyy-mm-dd format
					pkm.met_year  = subParts[0] - 2000;
					pkm.met_month = subParts[1];
					pkm.met_day   = subParts[2];
				}
				else if(subParts[2] >= 2000 && subParts[0] <= 12 && subParts[1] <= 31)
				{
					// assuming mm/dd/yyyy format
					pkm.met_year  = subParts[2] - 2000;
					pkm.met_month = subParts[0];
					pkm.met_day   = subParts[1];
				}
				else
				{
					dom.style.color = "red";
				}
			}
			else if(numberParsed == 2)
			{
				if((subParts[0] <= 31 || subParts[1] <= 31) && subParts[2] >= 2000)
				{
					// assuming "July 4th, 2000" or "4 July 2000" format
					var parsedDate = new Date(subParts.join(" "));
					pkm.met_year  = parsedDate.getYear() - 100;
					pkm.met_month = parsedDate.getMonth() + 1;
					pkm.met_day   = parsedDate.getDate();
				}
				else
				{
					dom.style.color = "red";
				}
			}
			else
			{
				dom.style.color = "red";
			}
		}
	}
	function parseIdValues(dom, type, val)
	{
		var subParts = val.split(/\s*[\/,]\s*/);
		if(subParts.length == 6)
		{
			pkm[type + "_hp" ] = parseOnlyInt(subParts[0]);
			pkm[type + "_atk"] = parseOnlyInt(subParts[1]);
			pkm[type + "_def"] = parseOnlyInt(subParts[2]);
			pkm[type + "_spa"] = parseOnlyInt(subParts[3]);
			pkm[type + "_spd"] = parseOnlyInt(subParts[4]);
			pkm[type + "_spe"] = parseOnlyInt(subParts[5]);
		}
		else if(subParts.length > 0)
		{
			for(var j = 0 ; j < subParts.length ; ++j)
			{
				if     (subParts[j].match(/health|hp|pv/i))					pkm[type + "_hp" ] = parseOnlyInt(subParts[j]);
				else if(subParts[j].match(/sp(ecial|.|) att?(ac|)k|spa/i))	pkm[type + "_spa"] = parseOnlyInt(subParts[j]);
				else if(subParts[j].match(/sp(ecial|.|) def(ence|)|spd/i))	pkm[type + "_spd"] = parseOnlyInt(subParts[j]);
				else if(subParts[j].match(/attack|att?k/i))					pkm[type + "_atk"] = parseOnlyInt(subParts[j]);
				else if(subParts[j].match(/defence|def/i))					pkm[type + "_def"] = parseOnlyInt(subParts[j]);
				else if(subParts[j].match(/speed|spe/i))					pkm[type + "_spe"] = parseOnlyInt(subParts[j]);
				else
				{
					dom.style.color = "orange";
				}
			}
		}
	}
	function parseMove(dom, nb, val)
	{
		if(!val.match(/^$|^\W?(n\/a|no|none)\W*?$/i))
		{
			var moveN = "move" + nb;
			var maxPP = val.match(/\W*max pp\W*/i);
			var ppUps = 0;
			if(maxPP)
			{
				ppUps = 3;
				val = val.replace(maxPP, "");
			}
			pkm[moveN] = val;
			pkm[moveN + "_pp"] = PKM.movesBasePP[pkm[moveN]] * (5 + ppUps) / 5;
			pkm[moveN + "_pp_up"] = ppUps;
		}
	}
	function parseRibbon(dom, val)
	{
		if     (val.match(/earth/i))	pkm.rib_earth = 1;
		else if(val.match(/world/i))	pkm.rib_world = 1;
		else if(val.match(/classic/i))	pkm.rib_classic = 1;
		else if(val.match(/premier/i))	pkm.rib_premier = 1;
		else if(val.match(/event/i))	pkm.rib_event = 1;
		else if(val.match(/birthday/i))	pkm.rib_birthday = 1;
		else if(val.match(/special/i))	pkm.rib_special = 1;
		else if(val.match(/souvenir/i))	pkm.rib_souvenir = 1;
		else if(val.match(/wishing/i))	pkm.rib_wishing = 1;
		else
		{
			dom.style.color = "red";
		}
	}
	// read through lines and alter the pkm object accordingly
	// when it find something it recognize, it color the corresponding domli accordingly
	function parseLines()
	{
		for(var i = 0 ; i < lines.length ; ++i)
		{
			var item = lines[i].split(/\s*:\s*/);
			if(item.length > 1)
			{
				var key = item[0];
				var val = item[1];
				if(keys.indexOf(key) == -1)
				{
					keys.push(key);
					domli[i].style.color = "green";
					if     (key.match(/^pok[eé]mon/i))							pkm.species = val;
					else if(key.match(/^shine?y/i))								pkm.shiny = val.match(/^y/i) ? 1 : 0;
					else if(key.match(/^nickname/i))							parseNickname(domli[i], val);
					else if(key.match(/^gender$/i))								parseGender(domli[i], val);
					else if(key.match(/^level/i))								pkm.level = parseOnlyInt(val);
					else if(key.match(/^nature/i))								pkm.nature = val;
					else if(key.match(/^held|^item/i))							pkm.heldItem = val;
					else if(key.match(/^ability/i))								pkm.ability = val;
					else if(key.match(/^region/i))								parseRegion(domli[i], val);
					else if(key.match(/^game[\W]+location[\W]+(met )?level/i))	parseMetInfos(domli[i], val);
					else if(key.match(/^met date/i))							parseMetDate(domli[i], val);
					else if(key.match(/^(pok[eé])?ball/i))						pkm.ball = val;
					else if(key.match(/^fateful/i))								pkm.fateful = val.match(/^y/i) ? 1 :0;
					else if(key.match(/^IV/))									parseIdValues(domli[i], "iv", val);
					else if(key.match(/^EV/))									parseIdValues(domli[i], "ev", val);
					else if(key.match(/^move 1/i))								parseMove(domli[i], 1, val);
					else if(key.match(/^move 2/i))								parseMove(domli[i], 2, val);
					else if(key.match(/^move 3/i))								parseMove(domli[i], 3, val);
					else if(key.match(/^move 4/i))								parseMove(domli[i], 4, val);
					else if(key.match(/^ot| ot$/i))								pkm.ot_name = val;
					else if(key.match(/^gender of in game character/i))			pkm.ot_gender = val;
					else if(key.match(/.*?tid.*?/i) && val.match(/\d{5}/i))		pkm.tid = val;
					else if(key.match(/.*?sid.*?/i) && val.match(/\d{5}/i))		pkm.sid = val;
					else if(key.match(/^ribbon/i))								parseRibbon(domli[i], val);
					else
					{
						keys.pop();
						domli[i].style.color = "";
					}
				}
			}
		}
	}
	var pkm = addGenTemplate(new PK6());
	var queries = [".entry .md ul li p", ".entry .md p", ".entry .md ul li"];
	var domli = []; // dom container with the text node inside
	var lines = []; // actual text contained inside domli
	var keys = [];
	var sep = /[: -]+/;
	for(var i = 0 ; i < queries.length ; ++i)
	{
		// break post into lines using formatting queries (I have seen all of them used by posters)
		domli = document.querySelectorAll(queries[i]) || [];
		if(domli.length > 3)
		{
			// populate lines with the text inside domli
			for(var j = 0 ; j < domli.length ; ++j)
			{
				lines[j] = domli[j].innerHTML;
			}
			parseLines();
			return pkm;
		}
	}
	return null;
}

// if your username is mentioned in the comment section, create the reference line and append it to the document
function createReference()
{
	// if found returns the date of the post mentionning your name in the comment area
	function searchCompletionDate(qrcoder)
	{
		var mentions = document.querySelectorAll("div[data-type=comment] a[href='" + qrcoder + "']");
		var lastlink = mentions[mentions.length - 1]; // last link mentionning your username
		var ymd = lastlink.closest("div.entry").querySelector("time").dateTime.slice(0, 10); // year-month-day
		return ymd.slice(8, 10) + "/" + ymd.slice(5, 7) + "/" + ymd.slice(2, 4); // day-month-year
	}
	try
	{
		var sitetable = document.querySelector("div#siteTable");
		var title = sitetable.querySelector("p.title");
		var tagline = sitetable.querySelector("p.tagline");
		// post meta infos
		var postname = title.querySelector("a.title").innerHTML;
		var posthref = document.querySelector("input#shortlink-text").value;
		var author = tagline.querySelector("a.author").innerHTML;
		// post type : [gen] ? [event] ?
		var firstline = sitetable.querySelector(".entry .md p").innerHTML;
		var typematch = firstline.match(/\[(\w+)\]/);
		var posttype = (typematch.length > 1) ? typematch[1] : "gen";
		// current user infos
		var username = document.querySelector("span.user a").innerHTML; // It's you !
		var completed = searchCompletionDate("/u/" + username);
		if(completed)
		{
			var refline = "|[" + postname + "](" + posthref + ")|" + posttype + "|" + completed + "|/u/" + author + "|";
			var element = document.createElement("div");
			element.id = "refline";
			element.innerHTML = refline;
			element.style = "font-size: 11pt; color: #0f0;";
			document.querySelector("div.commentarea").appendChild(element);
			return true;
		}
	}
	catch(e)
	{
	}
	return false;
}

// Append the parsed pokemon's QR code to the document
function createQR()
{
	// Highlight the text in the element
	function selectText(element)
	{
		var range = document.createRange();
		var selection = window.getSelection();
		range.selectNodeContents(element);
		selection.removeAllRanges();
		selection.addRange(range);
	}
	const inject = "http://loadcode.projectpokemon.org/b1s1.html#";
	const qrmake = "http://api.qrserver.com/v1/create-qr-code/?data=";
	var pkm = parseGenRequest();
	if(pkm)
	{
		var qrc = document.createElement("div");
		var dat = pkm.getDataString();
		qrc.innerHTML = qrmake + encodeURIComponent(inject + btoa(dat));
		qrc.style.wordWrap = "break-word";
		document.querySelector("div.commentarea").appendChild(qrc);
		// all you need to do now is ctrl+c then alt-click on pokemon icon in PKHeX
		selectText(qrc);
	}
}

addEventListener("load", function()
{
	if(location.href.startsWith("http://bulbapedia.bulbagarden.net/wiki/"))
	{
		function printArray(arr)
		{
			var ret = "[";
			for(var i = 0 ; i < arr.length ; ++i)
			{
				var val = arr[i];
				if(typeof val == "object")
				{
					ret += printArray(val);
				}
				else if(parseInt(val))
				{
					ret += val;
				}
				else
				{
					ret += '"' + val + '"';
				}
				if(i < arr.length - 1)
				{
					ret += ",";
				}
			}
			ret += "]";
			return ret;
		}
		// collect event info from bulbapedia
		// exemple: http://bulbapedia.bulbagarden.net/wiki/List_of_Japanese_event_Pok%C3%A9mon_distributions_in_Generation_III#Pok.C3.A9Park_Mew
		var id = location.href.split("#")[1];
		if(id)
		{
			var title = document.getElementById(id);
			var table = title.parentElement;
			while(table.tagName != "TABLE") table = table.nextElementSibling;
			if(table)
			{
				var evTitle   = title.innerHTML;
				/*var evBall    = table.tBodies[0].rows[1].cells[0].children[0].title;
				var evSpecies = table.tBodies[0].rows[1].cells[3].children[0].innerHTML;
				var evNature  = table.tBodies[0].rows[1].cells[4].children[0].children[0].innerHTML;
				var evMove1   = table.tBodies[0].rows[1].cells[6].children[0].children[0].innerHTML;
				var evRibbon  = table.tBodies[0].rows[1].cells[7].children[0].children[0].innerHTML;
				var evLevel   = table.tBodies[0].rows[2].cells[0].children[1].innerHTML;
				var evMet     = table.tBodies[0].rows[2].cells[2].innerHTML;
				var evMove2   = table.tBodies[0].rows[2].cells[4].children[0].children[0].innerHTML;
				var evMove3   = table.tBodies[0].rows[3].cells[6].children[0].children[0].innerHTML;
				var evTrainer = table.tBodies[0].rows[4].cells[1].children[0].children[0].innerHTML;
				var evMove4   = table.tBodies[0].rows[4].cells[4].children[0].children[0].innerHTML;
				var evId      = table.tBodies[0].rows[5].cells[1].children[0].innerHTML;
				var evRegion  = table.tBodies[0].rows[5].cells[2].children[0].children[0].children[0].innerHTML;
				var evRange   = table.tBodies[0].rows[5].cells[2].children[0].children[0].children[2].innerHTML;
				var evAbility = table.tBodies[0].rows[7].cells[1].children[0].children[0].innerHTML;*/
				
				var evSpecies  = parseInt(table.rows[0].cells[0].children[0].rows[0].cells[0].innerHTML.replace(/\D/g, ""));
				var evLevel    = parseInt(table.rows[0].cells[0].children[0].rows[1].cells[1].innerHTML.replace(/\D/g, ""));
				var evId       = parseInt(table.rows[0].cells[1].children[0].rows[0].cells[1].innerHTML.replace(/\D/g, ""));
				var evTrainer  = table.rows[0].cells[1].children[0].rows[1].cells[1].innerHTML.replace(/\s/g, "");
				var evMet      = table.rows[0].cells[1].children[0].rows[2].cells[1].innerHTML.split("(")[0].replace(/\s/g, "");
				var evFateful  = table.rows[0].cells[1].children[0].rows[2].cells[1].innerHTML.split("(")[1].match("fateful");
				var evNature   = table.rows[0].cells[1].children[0].rows[3].cells[1].children[0].children[0].innerHTML;
				var evRibbon   = table.rows[0].cells[1].children[0].rows[4].cells[1].children[0].children[0].alt.replace(" Ribbon", "");
				var evMove1    = table.rows[1].cells[0].children[0].rows[0].cells[0].children[0].rows[0].cells[0].children[0].children[0].innerHTML.toLowerCase();
				var evMove2    = table.rows[1].cells[0].children[0].rows[0].cells[1].children[0].rows[0].cells[0].children[0].children[0].innerHTML.toLowerCase();
				var evMove3    = table.rows[1].cells[0].children[0].rows[0].cells[2].children[0].rows[0].cells[0].children[0].children[0].innerHTML.toLowerCase();
				var evMove4    = table.rows[1].cells[0].children[0].rows[0].cells[3].children[0].rows[0].cells[0].children[0].children[0].innerHTML.toLowerCase();
				var evVersion  = [];
				var domVersion = table.rows[2].cells[0].children[0].rows[1].cells[0].children[0].children[0].children;
				for(var i = 0 ; i < domVersion.length ; ++i)
				{
					evVersion.push(domVersion[i].innerHTML);
				}
				var evRange    = "";
				try
				{
					evRange = table.rows[2].cells[0].children[0].rows[1].cells[4].innerHTML;
				}
				catch(e) {}
			}
			// [event_name, species#, friendship, [nature], [regions], [versions], [date_range], met_location, met_level, ball, fatefull, [moves], ot, ot gender, tid, sid]
			var res = [evTitle, evSpecies, -1, [evNature], [], evVersion, [evRange], evMet, evLevel, 16, true, [evMove1, evMove2, evMove3, evMove4], evTrainer, "0", evId, "00000", ""];
			var div = document.createElement("div");
			div.innerHTML = printArray(res);
			table.parentElement.insertBefore(div, table.nextElementSibling);
		}
	}
	else
	{
		if(!createReference()) createQR();
	}
});