| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -57,11 +57,18 @@ class Board { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    this.SCREEN_PAD = 20; | 
					 | 
					 | 
					 | 
					    this.SCREEN_PAD = 20; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    // Orb grid
 | 
					 | 
					 | 
					 | 
					    // Orb grid
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    this.grid = {}; | 
					 | 
					 | 
					 | 
					    this.grid = []; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    this.tiles = {}; | 
					 | 
					 | 
					 | 
					    this.tiles = []; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    this.onOrbClick = (index, orb) => {}; | 
					 | 
					 | 
					 | 
					    for(let i=0; i<120;i++) { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    this.onTileClick = (index) => {}; | 
					 | 
					 | 
					 | 
					      this.grid[i] = null; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      this.tiles[i] = null; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    this.onOrbClick = (index, orb) => { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    }; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    this.onTileClick = (index) => { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    }; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    this.initOrb(); | 
					 | 
					 | 
					 | 
					    this.initOrb(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    this.initGlyphs(); | 
					 | 
					 | 
					 | 
					    this.initGlyphs(); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -163,7 +170,7 @@ class Board { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					   * @returns {{x: Number, y: Number}} | 
					 | 
					 | 
					 | 
					   * @returns {{x: Number, y: Number}} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					   */ | 
					 | 
					 | 
					 | 
					   */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  gridIndexToXy(index) { | 
					 | 
					 | 
					 | 
					  gridIndexToXy(index) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return { x : index % 11, y: Math.floor(index/11) }; | 
					 | 
					 | 
					 | 
					    return {x: index % 11, y: Math.floor(index / 11)}; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  } | 
					 | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  /** | 
					 | 
					 | 
					 | 
					  /** | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -199,7 +206,7 @@ class Board { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  removeOrbByIndex(index, errorIfEmpty = false) { | 
					 | 
					 | 
					 | 
					  removeOrbByIndex(index, errorIfEmpty = false) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if (this.grid[index]) { | 
					 | 
					 | 
					 | 
					    if (this.grid[index]) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      this.$orbs.removeChild(this.grid[index].node); | 
					 | 
					 | 
					 | 
					      this.$orbs.removeChild(this.grid[index].node); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      delete this.grid[index]; | 
					 | 
					 | 
					 | 
					      this.grid[index] = null; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } else { | 
					 | 
					 | 
					 | 
					    } else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      if (errorIfEmpty) { | 
					 | 
					 | 
					 | 
					      if (errorIfEmpty) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        throw new Error(`Position ${index} is already empty.`); | 
					 | 
					 | 
					 | 
					        throw new Error(`Position ${index} is already empty.`); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -437,7 +444,7 @@ class Board { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					           cx="13.229166" | 
					 | 
					 | 
					 | 
					           cx="13.229166" | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					           fill="url(#radGradSlotBg)" /> | 
					 | 
					 | 
					 | 
					           fill="url(#radGradSlotBg)" /> | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      </g> | 
					 | 
					 | 
					 | 
					      </g> | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    `, { class: 'tile' });
 | 
					 | 
					 | 
					 | 
					    `, {class: 'tile'});
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  } | 
					 | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  /** | 
					 | 
					 | 
					 | 
					  /** | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -576,7 +583,7 @@ class Rng { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					   * | 
					 | 
					 | 
					 | 
					   * | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					   * @param {Number|null} seed | 
					 | 
					 | 
					 | 
					   * @param {Number|null} seed | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					   */ | 
					 | 
					 | 
					 | 
					   */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  constructor(seed=null) { | 
					 | 
					 | 
					 | 
					  constructor(seed = null) { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if (seed === null) { | 
					 | 
					 | 
					 | 
					    if (seed === null) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      seed = +new Date; | 
					 | 
					 | 
					 | 
					      seed = +new Date; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -603,44 +610,58 @@ class Rng { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    t ^= t + Math.imul(t ^ t >>> 7, t | 61); | 
					 | 
					 | 
					 | 
					    t ^= t + Math.imul(t ^ t >>> 7, t | 61); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return ((t ^ t >>> 14) >>> 0) / 4294967296; | 
					 | 
					 | 
					 | 
					    return ((t ^ t >>> 14) >>> 0) / 4294967296; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  } | 
					 | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  /** | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					   * Get next int, inclusive | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					   * | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					   * @param {Number} max | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					   * @return {Number} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					   */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  nextInt(max) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    return Math.floor((max + 1) * this.next()); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					class Game { | 
					 | 
					 | 
					 | 
					class Game { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  /** | 
					 | 
					 | 
					 | 
					  /** | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					   * Init the game | 
					 | 
					 | 
					 | 
					   * Init the game | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					   */ | 
					 | 
					 | 
					 | 
					   */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  constructor() { | 
					 | 
					 | 
					 | 
					  constructor(seed=null) { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    this.board = new Board(); | 
					 | 
					 | 
					 | 
					    this.board = new Board(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    this.rng = new Rng(1); | 
					 | 
					 | 
					 | 
					    if (seed === null) { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      seed = +new Date(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    this.rng = new Rng(seed); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    this.layoutTemplates = { | 
					 | 
					 | 
					 | 
					    this.layoutTemplates = { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      // templates apparently all have 55 items
 | 
					 | 
					 | 
					 | 
					      // templates apparently all have 55 items
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      //'wheel':     [0,1,2,3,4,5,11,12,13,14,15,16,17,22,23,24,27,28,29,33,34,36,38,40,41,44,45,48,49,52,53,55,56,57,58,59,60,61,62,63,64,65,67,68,71,72,75,76,79,80,82,84,86,87,91,92,93,96,97,98,103,104,105,106,107,108,109,115,116,117,118,119,120],
 | 
					 | 
					 | 
					 | 
					      //'wheel':     [0,1,2,3,4,5,11,12,13,14,15,16,17,22,23,24,27,28,29,33,34,36,38,40,41,44,45,48,49,52,53,55,56,57,58,59,60,61,62,63,64,65,67,68,71,72,75,76,79,80,82,84,86,87,91,92,93,96,97,98,103,104,105,106,107,108,109,115,116,117,118,119,120],
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      'beyblade':  [0,1,2,3,4,5,12,14,15,23,26,34,35,37,38,39,40,46,47,48,50,51,52,55,58,60,61,64,65,67,68,69,70,71,73,76,79,80,83,84,85,86,87,91,94,95,97,98,103,104,105,106,109,115,120], | 
					 | 
					 | 
					 | 
					      'beyblade': [0, 1, 2, 3, 4, 5, 12, 14, 15, 23, 26, 34, 35, 37, 38, 39, 40, 46, 47, 48, 50, 51, 52, 55, 58, 60, 61, 64, 65, 67, 68, 69, 70, 71, 73, 76, 79, 80, 83, 84, 85, 86, 87, 91, 94, 95, 97, 98, 103, 104, 105, 106, 109, 115, 120], | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      'tulip':     [4,14,15,16,23,24,25,26,27,28,34,35,36,37,39,40,45,46,47,48,49,50,51,52,56,57,59,60,61,62,63,67,68,69,70,71,72,73,74,80,81,82,83,85,86,93,94,95,96,97,105,106,107,108,109], | 
					 | 
					 | 
					 | 
					      'tulip': [4, 14, 15, 16, 23, 24, 25, 26, 27, 28, 34, 35, 36, 37, 39, 40, 45, 46, 47, 48, 49, 50, 51, 52, 56, 57, 59, 60, 61, 62, 63, 67, 68, 69, 70, 71, 72, 73, 74, 80, 81, 82, 83, 85, 86, 93, 94, 95, 96, 97, 105, 106, 107, 108, 109], | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      'alien':     [3,4,14,15,16,22,25,26,27,28,34,35,36,37,38,39,40,41,45,46,48,49,51,56,57,58,59,60,61,62,67,68,69,70,71,72,73,74,79,80,81,82,84,85,86,94,95,96,97,98,106,107,108,109,117], | 
					 | 
					 | 
					 | 
					      'alien': [3, 4, 14, 15, 16, 22, 25, 26, 27, 28, 34, 35, 36, 37, 38, 39, 40, 41, 45, 46, 48, 49, 51, 56, 57, 58, 59, 60, 61, 62, 67, 68, 69, 70, 71, 72, 73, 74, 79, 80, 81, 82, 84, 85, 86, 94, 95, 96, 97, 98, 106, 107, 108, 109, 117], | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      'cube':      [1,5,12,13,14,15,16,17,23,27,29,33,34,35,36,37,38,40,44,48,49,51,52,55,56,57,58,59,60,61,62,64,68,70,71,72,73,75,76,80,82,84,86,92,94,96,97,103,104,105,106,108,118,119,120], | 
					 | 
					 | 
					 | 
					      'cube': [1, 5, 12, 13, 14, 15, 16, 17, 23, 27, 29, 33, 34, 35, 36, 37, 38, 40, 44, 48, 49, 51, 52, 55, 56, 57, 58, 59, 60, 61, 62, 64, 68, 70, 71, 72, 73, 75, 76, 80, 82, 84, 86, 92, 94, 96, 97, 103, 104, 105, 106, 108, 118, 119, 120], | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      'star':      [3,14,15,22,23,24,25,26,27,34,35,36,37,38,39,40,41,46,47,48,49,50,51,52,57,58,59,60,61,62,63,68,69,70,71,72,73,74,79,80,81,82,83,84,85,86,93,94,95,96,97,98,105,106,117], | 
					 | 
					 | 
					 | 
					      'star': [3, 14, 15, 22, 23, 24, 25, 26, 27, 34, 35, 36, 37, 38, 39, 40, 41, 46, 47, 48, 49, 50, 51, 52, 57, 58, 59, 60, 61, 62, 63, 68, 69, 70, 71, 72, 73, 74, 79, 80, 81, 82, 83, 84, 85, 86, 93, 94, 95, 96, 97, 98, 105, 106, 117], | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      'flower':    [3,11,12,13,14,15,23,25,27,28,34,36,37,38,39,40,45,46,47,48,49,50,52,53,57,58,59,60,61,62,64,68,70,71,72,73,74,75,79,80,81,82,83,84,86,92,95,96,97,98,104,105,106,107,116], | 
					 | 
					 | 
					 | 
					      'flower': [3, 11, 12, 13, 14, 15, 23, 25, 27, 28, 34, 36, 37, 38, 39, 40, 45, 46, 47, 48, 49, 50, 52, 53, 57, 58, 59, 60, 61, 62, 64, 68, 70, 71, 72, 73, 74, 75, 79, 80, 81, 82, 83, 84, 86, 92, 95, 96, 97, 98, 104, 105, 106, 107, 116], | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      'windmill':  [4,11,12,13,14,15,16,23,24,25,27,28,34,37,39,40,45,46,47,48,49,50,52,53,56,57,59,60,61,63,64,67,68,70,71,72,73,74,75,80,81,83,86,92,93,95,96,97,104,105,106,107,108,109,116], | 
					 | 
					 | 
					 | 
					      'windmill': [4, 11, 12, 13, 14, 15, 16, 23, 24, 25, 27, 28, 34, 37, 39, 40, 45, 46, 47, 48, 49, 50, 52, 53, 56, 57, 59, 60, 61, 63, 64, 67, 68, 70, 71, 72, 73, 74, 75, 80, 81, 83, 86, 92, 93, 95, 96, 97, 104, 105, 106, 107, 108, 109, 116], | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      'propeller': [1,2,3,4,13,14,15,16,22,25,28,34,36,37,38,39,40,41,45,46,47,48,50,56,58,60,61,62,67,68,70,71,73,74,75,76,79,80,81,82,83,84,86,87,91,92,95,97,98,103,106,107,108,109,117], | 
					 | 
					 | 
					 | 
					      'propeller': [1, 2, 3, 4, 13, 14, 15, 16, 22, 25, 28, 34, 36, 37, 38, 39, 40, 41, 45, 46, 47, 48, 50, 56, 58, 60, 61, 62, 67, 68, 70, 71, 73, 74, 75, 76, 79, 80, 81, 82, 83, 84, 86, 87, 91, 92, 95, 97, 98, 103, 106, 107, 108, 109, 117], | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      'garden':    [0,1,2,3,4,5,11,12,13,14,15,16,17,22,23,28,29,33,34,40,41,44,45,52,53,55,56,60,64,65,67,68,75,76,79,80,86,87,91,92,97,98,103,104,105,106,107,108,109,115,116,117,118,119,120], | 
					 | 
					 | 
					 | 
					      'garden': [0, 1, 2, 3, 4, 5, 11, 12, 13, 14, 15, 16, 17, 22, 23, 28, 29, 33, 34, 40, 41, 44, 45, 52, 53, 55, 56, 60, 64, 65, 67, 68, 75, 76, 79, 80, 86, 87, 91, 92, 97, 98, 103, 104, 105, 106, 107, 108, 109, 115, 116, 117, 118, 119, 120], | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      'windmill2': [1,12,13,14,15,16,17,23,24,26,27,28,34,35,36,37,38,40,44,45,47,50,51,52,56,57,58,60,62,63,64,68,69,70,73,75,76,80,82,83,84,85,86,92,93,94,96,97,103,104,105,106,107,108,119], | 
					 | 
					 | 
					 | 
					      'windmill2': [1, 12, 13, 14, 15, 16, 17, 23, 24, 26, 27, 28, 34, 35, 36, 37, 38, 40, 44, 45, 47, 50, 51, 52, 56, 57, 58, 60, 62, 63, 64, 68, 69, 70, 73, 75, 76, 80, 82, 83, 84, 85, 86, 92, 93, 94, 96, 97, 103, 104, 105, 106, 107, 108, 119], | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      'bird':      [2,3,4,14,15,25,27,28,29,33,34,35,36,37,38,39,40,45,46,47,48,49,50,51,57,58,59,60,61,62,67,68,70,71,72,73,74,79,80,81,82,83,84,86,87,91,94,95,96,97,98,106,107,109,118], | 
					 | 
					 | 
					 | 
					      'bird': [2, 3, 4, 14, 15, 25, 27, 28, 29, 33, 34, 35, 36, 37, 38, 39, 40, 45, 46, 47, 48, 49, 50, 51, 57, 58, 59, 60, 61, 62, 67, 68, 70, 71, 72, 73, 74, 79, 80, 81, 82, 83, 84, 86, 87, 91, 94, 95, 96, 97, 98, 106, 107, 109, 118], | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      'strider':   [1,2,3,4,11,12,13,14,15,24,25,26,36,37,38,47,48,49,50,53,58,59,60,61,62,63,64,67,68,69,70,71,72,73,74,75,76,79,80,81,82,83,84,85,86,87,91,92,93,97,98,103,104,109,116], | 
					 | 
					 | 
					 | 
					      'strider': [1, 2, 3, 4, 11, 12, 13, 14, 15, 24, 25, 26, 36, 37, 38, 47, 48, 49, 50, 53, 58, 59, 60, 61, 62, 63, 64, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 79, 80, 81, 82, 83, 84, 85, 86, 87, 91, 92, 93, 97, 98, 103, 104, 109, 116], | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      'campfire':  [0,1,2,3,4,5,11,15,17,22,23,24,25,26,27,29,33,35,39,41,44,46,51,52,53,55,57,60,63,65,67,68,69,74,76,79,81,85,87,91,93,94,95,96,97,98,103,105,109,115,116,117,118,119,120], | 
					 | 
					 | 
					 | 
					      'campfire': [0, 1, 2, 3, 4, 5, 11, 15, 17, 22, 23, 24, 25, 26, 27, 29, 33, 35, 39, 41, 44, 46, 51, 52, 53, 55, 57, 60, 63, 65, 67, 68, 69, 74, 76, 79, 81, 85, 87, 91, 93, 94, 95, 96, 97, 98, 103, 105, 109, 115, 116, 117, 118, 119, 120], | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      'skillet':   [0,1,2,5,11,13,17,22,25,26,27,28,29,33,37,39,41,44,45,46,47,48,49,50,53,55,57,59,60,61,65,69,70,71,72,73,74,75,76,81,83,85,87,91,92,95,96,103,107,115,116,117,118,119,120], | 
					 | 
					 | 
					 | 
					      'skillet': [0, 1, 2, 5, 11, 13, 17, 22, 25, 26, 27, 28, 29, 33, 37, 39, 41, 44, 45, 46, 47, 48, 49, 50, 53, 55, 57, 59, 60, 61, 65, 69, 70, 71, 72, 73, 74, 75, 76, 81, 83, 85, 87, 91, 92, 95, 96, 103, 107, 115, 116, 117, 118, 119, 120], | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      'digger':    [2,3,4,5,16,17,22,27,28,29,33,34,35,36,37,38,39,40,41,44,45,46,47,48,50,51,55,56,57,58,60,61,62,67,70,71,73,79,82,83,84,87,91,94,95,96,98,106,107,108,109,117,118,119,120], | 
					 | 
					 | 
					 | 
					      'digger': [2, 3, 4, 5, 16, 17, 22, 27, 28, 29, 33, 34, 35, 36, 37, 38, 39, 40, 41, 44, 45, 46, 47, 48, 50, 51, 55, 56, 57, 58, 60, 61, 62, 67, 70, 71, 73, 79, 82, 83, 84, 87, 91, 94, 95, 96, 98, 106, 107, 108, 109, 117, 118, 119, 120], | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      'chestnut':  [3,4,12,13,14,15,16,23,25,27,28,34,36,38,39,40,45,46,47,48,49,50,52,56,57,58,59,60,61,62,64,67,68,71,72,74,75,79,80,81,82,83,84,86,92,95,96,97,98,104,105,106,107,108,109], | 
					 | 
					 | 
					 | 
					      'chestnut': [3, 4, 12, 13, 14, 15, 16, 23, 25, 27, 28, 34, 36, 38, 39, 40, 45, 46, 47, 48, 49, 50, 52, 56, 57, 58, 59, 60, 61, 62, 64, 67, 68, 71, 72, 74, 75, 79, 80, 81, 82, 83, 84, 86, 92, 95, 96, 97, 98, 104, 105, 106, 107, 108, 109], | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      'manta':     [0,5,11,16,22,23,24,25,26,27,28,29,33,34,35,39,40,44,45,46,47,51,52,56,57,58,59,60,61,62,63,64,68,69,73,74,75,76,80,81,85,86,87,91,92,93,94,95,96,97,98,104,109,115,120], | 
					 | 
					 | 
					 | 
					      'manta': [0, 5, 11, 16, 22, 23, 24, 25, 26, 27, 28, 29, 33, 34, 35, 39, 40, 44, 45, 46, 47, 51, 52, 56, 57, 58, 59, 60, 61, 62, 63, 64, 68, 69, 73, 74, 75, 76, 80, 81, 85, 86, 87, 91, 92, 93, 94, 95, 96, 97, 98, 104, 109, 115, 120], | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      'pyramids':  [3,4,14,15,16,23,25,26,28,34,35,36,37,38,39,40,45,46,47,48,49,50,51,52,56,58,59,60,61,62,67,68,69,70,71,72,73,74,79,80,81,82,83,84,85,86,94,95,97,98,105,106,107,108,109], | 
					 | 
					 | 
					 | 
					      'pyramids': [3, 4, 14, 15, 16, 23, 25, 26, 28, 34, 35, 36, 37, 38, 39, 40, 45, 46, 47, 48, 49, 50, 51, 52, 56, 58, 59, 60, 61, 62, 67, 68, 69, 70, 71, 72, 73, 74, 79, 80, 81, 82, 83, 84, 85, 86, 94, 95, 97, 98, 105, 106, 107, 108, 109], | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      'bigwheel':  [0,1,2,3,4,5,11,13,17,22,25,28,29,33,36,37,38,39,41,44,45,46,47,50,53,55,58,60,62,65,67,70,73,74,75,76,79,81,82,83,84,87,91,92,95,98,103,107,109,115,116,117,118,119,120], | 
					 | 
					 | 
					 | 
					      'bigwheel': [0, 1, 2, 3, 4, 5, 11, 13, 17, 22, 25, 28, 29, 33, 36, 37, 38, 39, 41, 44, 45, 46, 47, 50, 53, 55, 58, 60, 62, 65, 67, 70, 73, 74, 75, 76, 79, 81, 82, 83, 84, 87, 91, 92, 95, 98, 103, 107, 109, 115, 116, 117, 118, 119, 120], | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      'handshake': [0,1,2,3,4,5,11,12,13,15,16,22,23,24,25,27,33,34,35,36,38,46,48,49,50,58,59,60,61,62,70,71,72,74,82,84,85,86,87,93,95,96,97,98,104,105,107,108,109,115,116,117,118,119,120], | 
					 | 
					 | 
					 | 
					      'handshake': [0, 1, 2, 3, 4, 5, 11, 12, 13, 15, 16, 22, 23, 24, 25, 27, 33, 34, 35, 36, 38, 46, 48, 49, 50, 58, 59, 60, 61, 62, 70, 71, 72, 74, 82, 84, 85, 86, 87, 93, 95, 96, 97, 98, 104, 105, 107, 108, 109, 115, 116, 117, 118, 119, 120], | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      'thinwheel': [0,1,2,3,4,5,11,12,16,17,22,24,27,29,33,36,38,41,44,48,49,53,55,56,57,58,59,60,61,62,63,64,65,67,71,72,76,79,82,84,87,91,93,96,98,103,104,108,109,115,116,117,118,119,120], | 
					 | 
					 | 
					 | 
					      'thinwheel': [0, 1, 2, 3, 4, 5, 11, 12, 16, 17, 22, 24, 27, 29, 33, 36, 38, 41, 44, 48, 49, 53, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 67, 71, 72, 76, 79, 82, 84, 87, 91, 93, 96, 98, 103, 104, 108, 109, 115, 116, 117, 118, 119, 120], | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      'heavywheel':[12,13,14,15,16,23,24,25,27,28,34,36,37,38,39,40,45,46,47,48,49,50,52,56,57,58,59,60,61,62,63,64,68,70,71,72,73,74,75,80,81,82,83,84,86,92,93,95,96,97,104,105,106,107,108], | 
					 | 
					 | 
					 | 
					      'heavywheel': [12, 13, 14, 15, 16, 23, 24, 25, 27, 28, 34, 36, 37, 38, 39, 40, 45, 46, 47, 48, 49, 50, 52, 56, 57, 58, 59, 60, 61, 62, 63, 64, 68, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 84, 86, 92, 93, 95, 96, 97, 104, 105, 106, 107, 108], | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      'virus':     [2,3,13,14,15,22,24,26,27,34,35,36,37,38,39,40,41,46,47,48,49,50,51,57,58,59,60,61,62,63,68,69,70,71,72,73,75,79,80,82,83,84,85,86,87,91,92,93,94,95,96,97,98,106,117], | 
					 | 
					 | 
					 | 
					      'virus': [2, 3, 13, 14, 15, 22, 24, 26, 27, 34, 35, 36, 37, 38, 39, 40, 41, 46, 47, 48, 49, 50, 51, 57, 58, 59, 60, 61, 62, 63, 68, 69, 70, 71, 72, 73, 75, 79, 80, 82, 83, 84, 85, 86, 87, 91, 92, 93, 94, 95, 96, 97, 98, 106, 117], | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      'frisbee':   [0,11,12,13,14,15,22,25,26,27,28,29,33,34,36,38,39,40,41,45,46,47,49,50,53,57,58,59,60,62,64,65,68,69,72,74,75,80,81,82,83,84,85,86,92,95,96,97,104,106,107,115,116,117,118], | 
					 | 
					 | 
					 | 
					      'frisbee': [0, 11, 12, 13, 14, 15, 22, 25, 26, 27, 28, 29, 33, 34, 36, 38, 39, 40, 41, 45, 46, 47, 49, 50, 53, 57, 58, 59, 60, 62, 64, 65, 68, 69, 72, 74, 75, 80, 81, 82, 83, 84, 85, 86, 92, 95, 96, 97, 104, 106, 107, 115, 116, 117, 118], | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }; | 
					 | 
					 | 
					 | 
					    }; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    this.newGame() | 
					 | 
					 | 
					 | 
					    this.newGame() | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -720,7 +741,7 @@ class Game { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return tpl | 
					 | 
					 | 
					 | 
					    return tpl | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .sort((a, b) => a - b) | 
					 | 
					 | 
					 | 
					      .sort((a, b) => a - b) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .map((n) => { | 
					 | 
					 | 
					 | 
					      .map((n) => { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        let { x, y } = this.board.gridIndexToXy(n); | 
					 | 
					 | 
					 | 
					        let {x, y} = this.board.gridIndexToXy(n); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        return this.board.xyToGridIndex(5 + y - x, y); | 
					 | 
					 | 
					 | 
					        return this.board.xyToGridIndex(5 + y - x, y); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      }) | 
					 | 
					 | 
					 | 
					      }) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .sort((a, b) => a - b); | 
					 | 
					 | 
					 | 
					      .sort((a, b) => a - b); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -767,9 +788,13 @@ class Game { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  } | 
					 | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  isAvailable(n) { | 
					 | 
					 | 
					 | 
					  isAvailable(n) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    return this.getNeighbours(n).freeSequence >= 3; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  getNeighbours(n) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    let {x, y} = this.board.gridIndexToXy(n); | 
					 | 
					 | 
					 | 
					    let {x, y} = this.board.gridIndexToXy(n); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    let neighbors = [ | 
					 | 
					 | 
					 | 
					    let freeSpaces = [ | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      this.isOutside(x - 1, y) || !this.board.grid[n - 1], | 
					 | 
					 | 
					 | 
					      this.isOutside(x - 1, y) || !this.board.grid[n - 1], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      this.isOutside(x - 1, y - 1) || !this.board.grid[n - 12], | 
					 | 
					 | 
					 | 
					      this.isOutside(x - 1, y - 1) || !this.board.grid[n - 12], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      this.isOutside(x, y - 1) || !this.board.grid[n - 11], | 
					 | 
					 | 
					 | 
					      this.isOutside(x, y - 1) || !this.board.grid[n - 11], | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -778,235 +803,246 @@ class Game { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      this.isOutside(x, y + 1) || !this.board.grid[n + 11], | 
					 | 
					 | 
					 | 
					      this.isOutside(x, y + 1) || !this.board.grid[n + 11], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    ]; | 
					 | 
					 | 
					 | 
					    ]; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    neighbors.push(neighbors[0]); | 
					 | 
					 | 
					 | 
					    let nOccupied = 0; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    neighbors.push(neighbors[1]); | 
					 | 
					 | 
					 | 
					    for (let i = 0; i < 6; i++) { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      if (!freeSpaces[i]) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        nOccupied++; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    // if(this.debuggetneigh) console.log(`${x}×${y} #${n}, nocc ${nOccupied} `+JSON.stringify(freeSpaces));
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    let conseq = 0; | 
					 | 
					 | 
					 | 
					    let freeSequence = 0; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    for (let i = 0; i < neighbors.length; i++) { | 
					 | 
					 | 
					 | 
					    let maxFreeSequence = 0; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      if (neighbors[i]) { | 
					 | 
					 | 
					 | 
					    for (let i = 0; i < 12; i++) { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        conseq++; | 
					 | 
					 | 
					 | 
					      if (freeSpaces[i % 6]) { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        if (conseq === 3) { | 
					 | 
					 | 
					 | 
					        freeSequence++; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          return true; | 
					 | 
					 | 
					 | 
					        if (freeSequence >= 6) { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          maxFreeSequence = freeSequence; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          break; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        if (freeSequence > maxFreeSequence) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          maxFreeSequence = freeSequence; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        } | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      } else { | 
					 | 
					 | 
					 | 
					      } else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        conseq = 0; | 
					 | 
					 | 
					 | 
					        freeSequence = 0; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      } | 
					 | 
					 | 
					 | 
					      } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return false; | 
					 | 
					 | 
					 | 
					    return {neighbours: nOccupied, freeSequence: maxFreeSequence}; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  } | 
					 | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  placeOrbs() { | 
					 | 
					 | 
					 | 
					  placeOrbs(template) { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    this.board.removeAllOrbs(); | 
					 | 
					 | 
					 | 
					    this.board.removeAllOrbs(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    let template = this.getRandomTemplate(); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    let allowed = []; | 
					 | 
					 | 
					 | 
					    let allowed = []; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    for(let i = 0; i <= 120; i++) { | 
					 | 
					 | 
					 | 
					    for (let i = 0; i <= 120; i++) { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      allowed.push(template.includes(i)); | 
					 | 
					 | 
					 | 
					      let allo = template.includes(i); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      if (!template.includes(i)) { | 
					 | 
					 | 
					 | 
					      allowed.push(allo); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        if (this.board.tiles[i]) { | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          this.board.$bg.removeChild(this.board.tiles[i]) | 
					 | 
					 | 
					 | 
					      // Highlight pattern shape
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      if (this.board.tiles[i]) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        if (allo) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          this.board.tiles[i].setAttribute('opacity', 1) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        } else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          this.board.tiles[i].setAttribute('opacity', 0.6) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        } | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      } | 
					 | 
					 | 
					 | 
					      } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    let place = (n, symbol) => { | 
					 | 
					 | 
					 | 
					    const place = (n, symbol) => { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      if (!allowed[n]) throw Error(`Position ${n} not allowed by template`); | 
					 | 
					 | 
					 | 
					      if (!allowed[n]) throw Error(`Position ${n} not allowed by template`); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      if (this.board.grid[n]) throw Error(`Position ${n} is occupied`); | 
					 | 
					 | 
					 | 
					      if (this.board.grid[n]) throw Error(`Position ${n} is occupied`); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      this.board.placeOrbByIndex(n, symbol); | 
					 | 
					 | 
					 | 
					      this.board.placeOrbByIndex(n, symbol); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }; | 
					 | 
					 | 
					 | 
					    }; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    let findAvailableIndex = () => { | 
					 | 
					 | 
					 | 
					    const findAvailableIndexWithNeighbours = (count) => { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      let candidates = []; | 
					 | 
					 | 
					 | 
					      let candidates = []; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      for(let i=0; i<template.length;i++) { | 
					 | 
					 | 
					 | 
					      for (let i = 0; i < template.length; i++) { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        let n = template[i]; | 
					 | 
					 | 
					 | 
					        const n = template[i]; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        if (!this.board.grid[n] && this.isAvailable(n)) { | 
					 | 
					 | 
					 | 
					        const neigh = this.getNeighbours(n); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        // console.log(neigh);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        if (!this.board.grid[n] && neigh.neighbours === count && neigh.freeSequence >= 3) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          candidates.push(n); | 
					 | 
					 | 
					 | 
					          candidates.push(n); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        } | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      } | 
					 | 
					 | 
					 | 
					      } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      if (candidates.length) { | 
					 | 
					 | 
					 | 
					      if (candidates.length) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        return candidates[Math.floor(this.rng.next()*candidates.length)] | 
					 | 
					 | 
					 | 
					        return candidates[Math.floor(this.rng.next() * candidates.length)] | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      } else { | 
					 | 
					 | 
					 | 
					      } else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        throw Error("Failed to find available tile"); | 
					 | 
					 | 
					 | 
					        return false; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      } | 
					 | 
					 | 
					 | 
					      } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }; | 
					 | 
					 | 
					 | 
					    }; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    try { | 
					 | 
					 | 
					 | 
					    const findAvailableIndex = () => { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					      for (let i = 6; i >= 0; i--) { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      place(60, 'gold'); | 
					 | 
					 | 
					 | 
					        const n = findAvailableIndexWithNeighbours(i); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					        if (n !== false) return n; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      let toPlace = [ | 
					 | 
					 | 
					 | 
					      } | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        // gold is placed always to 60 (5x5)
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        ['salt', 'salt'], | 
					 | 
					 | 
					 | 
					      throw Error("Failed to find available tile"); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        ['salt', 'salt'], | 
					 | 
					 | 
					 | 
					    }; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        ['mors', 'vitae'], | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        ['mors', 'vitae'], | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        ['mors', 'vitae'], | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        ['mors', 'vitae'], | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        ['air', 'air'], | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        ['air', 'air'], | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        ['air', 'air'], | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        ['air', 'air'], | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        ['fire', 'fire'], | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        ['fire', 'fire'], | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        ['fire', 'fire'], | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        ['fire', 'fire'], | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        ['water', 'water'], | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        ['water', 'water'], | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        ['water', 'water'], | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        ['water', 'water'], | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        ['earth', 'earth'], | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        ['earth', 'earth'], | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        ['earth', 'earth'], | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        ['earth', 'earth'], | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        ['lead', 'mercury'], | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        ['tin', 'mercury'], | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        ['iron', 'mercury'], | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        ['copper', 'mercury'], | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        ['silver', 'mercury'], | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      ]; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      let shuffle = (a) => { | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        let j, x, i; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        for (i = a.length - 1; i > 0; i--) { | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          j = Math.floor(this.rng.next() * (i + 1)); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          x = a[i]; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          a[i] = a[j]; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          a[j] = x; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        } | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        return a; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      }; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      shuffle(toPlace); | 
					 | 
					 | 
					 | 
					    place(60, 'gold'); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      toPlace = toPlace.reduce((a,c) => { | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        a.push(c[0]); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        a.push(c[1]); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        return a; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      }, []); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      console.log(toPlace); | 
					 | 
					 | 
					 | 
					    const toPlace = this.buildPlacementList(); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      let history = []; | 
					 | 
					 | 
					 | 
					    // unpack the pairs
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    let toPlace_stack = toPlace.reduce((a, c) => { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      a.push(c[0]); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      a.push(c[1]); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      return a; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    }, []); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      const maxiter = 1000; | 
					 | 
					 | 
					 | 
					    while (toPlace_stack.length > 0) { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      for (let itern = 0; itern < maxiter && toPlace.length > 0; itern++) { | 
					 | 
					 | 
					 | 
					      place(findAvailableIndex(), toPlace_stack.pop()) | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        console.log('--- main iteration -----------'); | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    console.info("Found a valid board!"); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    console.log('Solution: ', toPlace); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        let symbol = toPlace.pop(); | 
					 | 
					 | 
					 | 
					  updateOrbDisabledStatus() { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        console.log('take ' + symbol); | 
					 | 
					 | 
					 | 
					    for (let n = 0; n < 120; n++) { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      if (this.board.grid[n]) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        this.board.grid[n].node.classList.toggle('disabled', !this.isAvailable(n)); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  newGame() { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    // this.board.onTileClick = (n) => {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    //   console.log(n, this.board.gridIndexToXy(n));
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    // };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    const RETRY_IN_TEMPLATE = 100; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    const RETRY_NEW_TEMPLATE = 15; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    // retry loop, should not be needed if everything is correct
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    let suc = false; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    let numretries = 0; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    const alertOnError = false; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    for (let i = 0; i < RETRY_NEW_TEMPLATE && !suc; i++) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      console.log('RNG seed is: ' + this.rng.state); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      const template = this.getRandomTemplate(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      for (let j = 0; j < RETRY_IN_TEMPLATE; j++) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        try { | 
					 | 
					 | 
					 | 
					        try { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          console.log('?place ' + symbol); | 
					 | 
					 | 
					 | 
					          this.placeOrbs(template); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          let index = findAvailableIndex(); | 
					 | 
					 | 
					 | 
					          suc = true; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          place(index, symbol); | 
					 | 
					 | 
					 | 
					          break; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          console.log('placed ' + symbol + ' to ' + index); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          history.push({symbol, index}); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        } catch (e) { | 
					 | 
					 | 
					 | 
					        } catch (e) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          toPlace.push(symbol); | 
					 | 
					 | 
					 | 
					          if (alertOnError) alert('welp'); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          console.log('*return unplaced ' + symbol); | 
					 | 
					 | 
					 | 
					          numretries++; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					          console.warn(e.message); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          console.log('BACKTRACK----------- failed to place ' + symbol); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          console.log('toPlace=',toPlace); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          console.log('history=',history); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          let depth = Math.min(1, history.length); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          let backtracking = true; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          // let retryAtThisLevel=0;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          while (backtracking) { | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            // if (retryAtThisLevel > 0) {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            //   retryAtThisLevel = 0;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            //   depth++;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            //   console.log(`DEEPER`);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            // } else {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            //   retryAtThisLevel++;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            // }
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            console.log('>>> Attempt backtrack of depth ' + depth); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            for (let j = 0; j < depth; j++) { | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					              let hist = history.pop(); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					              this.board.removeOrbByIndex(hist.index, true); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					              toPlace.push(hist.symbol); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					              console.log('undo & return (hist) ' + hist.symbol + ' at ' + hist.index) | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            } | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            console.log(`try getting back ${depth + 1} steps`); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            let successes = 0; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            for (let j = 0; j <= depth; j++) { | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					              let symbol = toPlace.pop(); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					              console.log('take ' + symbol); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					              itern++; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					              if (itern > maxiter) { | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                throw Error("Exceeded max iteration depth"); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					              } | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					              try { | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                console.log('?place ' + symbol); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                let index = findAvailableIndex(); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                place(index, symbol); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                history.push({symbol, index}); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                console.log('placed ' + symbol + ' to ' + index); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                if (j === depth) { | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                  console.log('Backtracking success'); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                  backtracking = false; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                  break; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                } | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                successes++; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					              } catch (e) { | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                console.log(`backtrack of depth ${depth} fail`); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                toPlace.push(symbol); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                console.log('return unplaced ' + symbol); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                // for(let k = 0; k < successes; k++) {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                //   let hist = history.pop();
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                //   this.board.removeOrbByIndex(hist.index, true);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                //   toPlace.push(hist.symbol);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                //   console.log('undo & return (hist) ' + hist.symbol + ' at ' + hist.index);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                // }
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                console.log(`DEEPER`); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                depth++; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                break; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					              } | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            } | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          } | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          console.log('end of backtrack loop, toPlace=', toPlace); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          console.log('history=',history); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        } | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      } | 
					 | 
					 | 
					 | 
					      } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					      if (!suc) { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      if (toPlace.length > 0) { | 
					 | 
					 | 
					 | 
					        console.warn("Exhausted all retries for the template, getting a new one"); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        throw Error("Failed to place some symbols: " + JSON.stringify(toPlace)); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      } | 
					 | 
					 | 
					 | 
					      } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      //place(findAvailableIndex(), metals.pop());
 | 
					 | 
					 | 
					 | 
					    if (!suc) { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      alert(`Sorry, could not find a valid board setup after ${numretries} retries.`); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      return; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    } else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      console.info(`Found valid solution (with ${numretries} retries)`); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } catch (e) { | 
					 | 
					 | 
					 | 
					    this.updateOrbDisabledStatus() | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      console.error(e) | 
					 | 
					 | 
					 | 
					  } | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      for(let i=0;i<120;i++) { | 
					 | 
					 | 
					 | 
					  shuffleArray(a) { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        if (!this.board.grid[i] && allowed[i]) { | 
					 | 
					 | 
					 | 
					    let j, x, i; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          console.log('Free cell '+i+' -> isAvail? '+this.isAvailable(i), this.board.gridIndexToXy(i)); | 
					 | 
					 | 
					 | 
					    for (i = a.length - 1; i > 0; i--) { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        } | 
					 | 
					 | 
					 | 
					      j = this.rng.nextInt(i); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      } | 
					 | 
					 | 
					 | 
					      x = a[i]; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      a[i] = a[j]; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      a[j] = x; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    return a; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  } | 
					 | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  newGame() { | 
					 | 
					 | 
					 | 
					  buildPlacementList() { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    //
 | 
					 | 
					 | 
					 | 
					    let toPlace = [ | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      ['air', 'air'], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      ['air', 'air'], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      ['air', 'air'], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      ['air', 'air'], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      ['fire', 'fire'], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      ['fire', 'fire'], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      ['fire', 'fire'], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      ['fire', 'fire'], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      ['water', 'water'], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      ['water', 'water'], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      ['water', 'water'], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      ['water', 'water'], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      ['earth', 'earth'], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      ['earth', 'earth'], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      ['earth', 'earth'], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      ['earth', 'earth'], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    ]; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    this.board.onTileClick = (n) => { | 
					 | 
					 | 
					 | 
					    let newSaltedPairs = []; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      console.log(n, this.board.gridIndexToXy(n)); | 
					 | 
					 | 
					 | 
					    const nsalted = this.rng.nextInt(2); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }; | 
					 | 
					 | 
					 | 
					    for (let i = 0; i < nsalted; i++) { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      while (true) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        const n = this.rng.nextInt(toPlace.length-1); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        if (toPlace[n][1] !== 'salt') { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          // console.log(`Pairing ${toPlace[n][1]} with salt.`);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          newSaltedPairs.push([toPlace[n][1], 'salt']); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          toPlace[n][1] = 'salt'; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          break; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    toPlace = toPlace.concat(newSaltedPairs); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    // if we have some salt pairs left
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    for (let i = 0; i < 2 - nsalted; i++) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      toPlace.push(['salt', 'salt']); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    // these are always paired like this, and don't support salt
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    toPlace = toPlace.concat([ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      ['mors', 'vitae'], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      ['mors', 'vitae'], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      ['mors', 'vitae'], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      ['mors', 'vitae'], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    ]); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    // shuffle the pairs that have random order (i.e. not metals)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    this.shuffleArray(toPlace); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    // the order here is actually significant, so let's pay attention...
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    const metals = [ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      ['lead', 'mercury'], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      ['tin', 'mercury'], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      ['iron', 'mercury'], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      ['copper', 'mercury'], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      ['silver', 'mercury'], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    ]; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    let mPos = []; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    for (let i = 0; i < metals.length; i++) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      let x; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      // find a unique position
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      do { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        x = this.rng.nextInt(toPlace.length + i); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      } while (mPos.includes(x)); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      mPos.push(x) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    mPos.sort((a, b) => a - b); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    // console.log('Metal positions ', mPos);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    // inject them into the array
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    metals.forEach((pair, i) => { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      toPlace.splice(mPos[i] + i, 0, pair); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    }); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    this.placeOrbs() | 
					 | 
					 | 
					 | 
					    return toPlace; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  } | 
					 | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					 | 
					
  |