/*-----------------------------------------------------------------------
	This script is NOT freeware. Please email if you want to re-use it.
	Your comments on how it could be improved would be appreciated
	Andrew Stuart, 23 May 2005, andrew@scanraid.com
	Version 1.38, 02-Dec-2006
-----------------------------------------------------------------------*/
var stage=0,laststage=0,prevlaststage=0;
var print_version=false;
var showhints=true;
var steps=0;
var save_dstring='';
var bunched=false;
var some_changes=false;
var firsttime=true;
var some_saved=false;
var cordX;
var cordY;
var rcbname=["Row","Col","Box"];
var abety="ABCDEFGHJ";
var abetx="123456789";
var editmode=false;
var MAX_STRAT = jig_list.length+7;
var coordmode=1;
var cnv, jg;

// Mask is a 2D array of ints which actually store bit arrays of numbers 1 to 9.
var mask=[[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]];
var g   =[[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]];
var jc  =[[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]];
var jb  =[[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]];
var save=[[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]];
var orig=[[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]];
var last=[[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]];
var rcm =[[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]];
var ccm =[[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]];
var show =[[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]];
var offset=[0,0,0,0,0,0,0,0,0,1,1,1,1,1,2,2,2,2,2,2,9,3,3,3,3,3,3,3,3,3,4,4,4];

var examples = [
// Shape 1
"400709020000020000090008000104000300700401002002000103000600010000040000010207045", // 36 IR
"201000904970000056004000000000908000000000000000709100000000200890000071009000305", // 10 LOL
"080300590500000000010000060900400005803000209700006004090000030200000008045009070", // 8 XW
"090000430200080007000000040000001000020000059000206000060000000300070001009010068", // HQ

// Shape 2
"400000001000700000001074930610000040000315000090000017047620100000006000100000003", // easy
"704306200000000000006000040001000980070904000010000000080000630000000000002607108", // 11 LOL
"000000000274000090060040020605004709800000002302900804080050040030000261000000000", // XYZ
"000813900090000000000070030100000003000402000930000007050000000070000010002705800", // hardest

// Shape 3
"105000407007100200000800000002000600070000030000000500000008000009007800304020100", // 7 LOL
"005000000081906420030108090060000000000000000000000050020405010093500100000000700", // 8 XW
"701000602030400000008070200006000000400050001000000800009040700000001000207000500", // 9 XYC
"050040730000106800007469000000000000070905000000000000000604200002308000006010040", // hardest

// Shape 4
"080000090009301000000000000590000037000609000230000061000000000600907208000000040", // 20 IR
"000000008004906300000010000050000060200608005070000090000070000107809400500000000", // LOL
"040900060005209300000000000500601002004090000000307004000000000007503400060008020", // SF
"000650000000406000020000010398000070002000500010007864080000040000100000000920000", // hardest

// Shape 5
"005000600004000020000000000750090063243000896070080031000000000017000300000000700", // LOL
"000216080000000000400060021000000000360000005000097000240050009000000000090824100", // YW
"070000020201000506106200000000090000005103600000030000000000705509000408020000000", // XYZ
"006092000210000089000040000050010800000000600007000020000060000040000016000020500", // hardest

// Shape 6
"602030009800000000000506000080709030100000002090301000000100000000000000900058307", // 43 IR
"004050007000098000008000640050000000000980000060000090021000000000800000500060102", // LOL
"051000040020408160940100058000020000000000000000080000480009016019604070030000780", // XYC
"000070000003000000002809600360504008000000006400097010004105900000000100000040000", // hardest

// Shape 7
"400095030005308900000000000500000008900000001700000003000000000002509300840160000", // LOL
"050000010028304090040050070000000000860040053000000000070080030010705320090000060", // SC
"700050008001300600640807003000000000580000014000000000300609045009005800800070000", // XC
"020030090005090002970820004000000000000000000000080000450062039800000900010000000", // hardest

// Shape 8
"000090000800000004400000100603000005000030001305000807002000706500000003100020000", // LOL
"450010020000705000100000005002500108020000050506008700800000003000309000070030082", // YW
"003400000009020000300809006200605000000000000400507001500104003000060500000000300", // ALS/MC/GXC
"000090000800000004400000100603000005000030001305000807002000706500000003100020000", // hardest

// Shape 9
"000007000060002080003000700008604000940000030000701800007000100080000049000300000", // SC
"700604005100000000680000019000405000000000000000109000560000024030000008400507000", // LOL
"800005004000080000001962000600000005000470000300000007003807000000090000700600001", // SF
"680000900900050000050000000260000031300000006540000070000000060000010003700000010", // hardest

// Shape 10
"004000900057010204000907000000080000100090002000020000000803000400070628000000000", // IR
"006000000000000000001030520402700809200401000807009405023050680000000000000000000", // LOL
"007230000000804000000000170400000008000301000900000006020000860000906000000005000", // YW
"407000009204000000000704000170000060000908000680000010000403000000000900802000700", // hardest

// Shape 11
"000000000060000070009105200070000004308000506500030020003704600020000030000002000", // SC
"000000000010700040200984030000000200000295800004010000000468009030009070000000000", // LOL
"000080000080320000004000100005090210200145003016030900002000800000064030000070000", // XYC
"203000000069050780000009000401000803000000000906000401000500000027060000005000306", // hardest

// Shape 12
"003500600400031008908020006000000000605000802000000000000080901200340005007005000", // IR/YW
"050020094900050001000000000000006009079408250000100000000700000400060002090010060", // LOL
"900000007000030000038000420080657040006000100090184060057000210000040000200000006", // XC
"500107009009600500030050000060000030000000000050000010070040080008002300400008000", // hardest

// Shape 13
"200806904000000000000529001000400000000108000000002005800247000000000000705001003", // IR
"800000001070000040200000507006000700062005980007000400908060002080000000700000006", // LOL
"070002000005000300002000900040503080000030000080301050007000800001040500050900010", // SC
"309600087000000000080010020000000000000020000000000000010040050030000000870035961", // hardest

// Shape 14
"008000060630475001000000000300507009007000300900208007000000000100342070090000200", // LOL
"000659000500080900060020070050000090400010000070000080040060020006040001000072000", // XW
"040000070507000209000000008086703501050000060605108490100000000809000305030000050", // SC
"060173490010000000600000004070000000800000000020000000100000006000000020057926010", // hardest

// Shape 15
"009000708580010069900020005040000000300000007000000080400050001810040092605000800", // LOL
"000603000050040070400000001294000036000000000960000843810000007000090060000802000", // SCOL
"000000000030000070807100602063700900000903001001000860500002703040000020000000000", // XYC
"908070205000000003005009300000506000300000004000008000006400800200000000601030508", // hardest

// Shape 16
"000024080000800000030000090040905720000000000069502010090200030000000000050700000", // HT
"060000000091703400600201004000000000080030040000000000700409001005002710000000000", // LOL
"700000104000000020400020000209508403008000900307409001000000007050000000001000009", // SCOL
"400130507050000000002050000800070001000601000600040000000060000000000020308096000", // hardest

// Shape 17
"001000005500080700000030100032000070009000000000000020007090000408070206100000400", // LOL
"000407001000000800002860500020000700030000260008000000000041600009000000700309000", // IR
"000000000023000190600001000004200800090000030001804900000500009056000210000000000", // XYC
"004000100020010070000605020290007006000000000900300067060504000080060090007000600", // hardest

// Shape 18
"098307620400000003000000000500701000000000000000208000000000000900000000075106380", // LOL
"095000264700000401000000000340000057000030000620000010000000000401000006276000890", // HQ
"010690050300000906070000009000000000032106540000000000200000094106000005090008070", // YW
"031720580005010300000000000000030600000000002003080700000000000008040900092060040", // hardest

// Shape 19
"050419032000007000300060000080002060000603000070800040000090007000900000620504070", // SF
"083040200000403000001009000009050007000702000100000700002600400000308000005080930", // LOL
"006010000000306000201000705800530006900000000600072008102000304000205000000050400", // XC
"000040002000080070506002109000090000809000705000060000005200001040000000200010000", // hardest

// Shape 20
"090247010000000000340080029400600008000000000900008001270050036000000000020463080", // HQ
"000000000003907800070090030040050020000870000010030080080060050004285100000000000", // LOL
"002000600890000057000060002307000826000000000018000705600090000200000073004000200", // SCOL
"060700080009000200000000000810000076204000901090000007000000000056000000030006020"]; // hardest


var jigsaw_maps = [
	"111222333111222333111222333333444111333444111333444111111222333111222333111222333",
	"111222233111222233114412333144411433444111444334114441333214411332222111332222111",
	"111222221111222211111333111444431114444434444422234444222333222221111222211111222",
	"111222233111332233111332233443333233444311113244411144222411444222333334223333444",
	"111122233111222333311222333333444113333444111133444111111222331111222333112223333",
	"111222223311222323331144333331144333333444422223224222222211122444211122444444111",
	"114444444114333334111133332221444422222242222224444122233331111433333411444444411",
	"112221111411222111441122211444114444344213344334223344331122334331112233331111223",
	"122223444112223344111223444131133324333443322333441112332441112222244122222241122",
	"112222211111222111311121113331444133333444333331444133311121113111222111112222211", // moonlotus, moonlotus1016@hotmail.com, 25/01/2006
	"111112222113343322133444332134444432231111132233111331234414431224444411222211111", // Onion, Andrew Smith, andrewgsmith@ntlworld.com, 15/01/2006
	"111132222111333222143333342144111442444111444244111441243333341222333111222231111", // Double Mirror, Fer van Nieuwenhuizen, TeachOffice@Wanadoo.nl
	"111222333111123333311222331334424411333424111333444111111123333111222333112222233", // cyndie.smith@netzero.com
	"111123333111224333122244443123344443223333322144443323144442223111422333111123333", // Tornado, Kathleen R Nicol, kath@nic01.com
	"122222334112223344411233444441133441444113411443322111433342211333444221344444222", // Cross, Andrew Smith, andrewgsmith@ntlworld.com
	"112222333111221333112221233114411223444412222244112244224133344222133444222333344", // Worm, Leonid Kreysin, lkreysin@yahoo.com
	"444411111444431112334233122331223332311222332311122322332112422322214444222224444", // Cabbage, Tim Cieplowski, tjciepl@bgnet.bgsu.edu
	"111222333111222333411322133441332113444333111144233411114223441111222444111222444", // Stripes, leob, leob54321@yahoo.com
	"111223333112223133112224133311424111333444111333434221113433322113133322111133222", // H, Bob & Debbie Scott, krydak@yahoo.com
	"111222223111122233331142333333444133133341113113444111111342211113332222133333222", // Wednesday, Gérard Coteau, coteau41@wanadoo.fr
	"111123333113122333133422231133442231332444211312244113312224113111223133111123333"]; // zigzag, Gérard Coteau, coteau41@wanadoo.fr

var jigsaw_boxes = [
	"111222333111222333111222333444555666444555666444555666777888999777888999777888999", // 0 = SUDOKU
	"111222233111222233114452333144455633444555666774556669777856699778888999778888999",
	"111222223111222233111555333444453336444456666477756666777555999778888999788888999",
	"111222233111442233111442233554444233555466663755566699777566999777888889778888999",
	"111122233111222333411222333444555663444555666744555666777888996777888999778889999",
	"111222223411222323441155333441155333444555599664665999666677799888677799888888777",
	"112222222112333332111133336441555566444456666445555966477779999877777899888888899",
	"115558888411555888441155588444117777944213377994223377996622337996662233996666223",
	"122223444112223344111223444151133384555663388555667778559667778999966788999967788",
	"112222233111222333411123336441555366444555666447555966477789996777888999778888899", //  9, moonlotus, moonlotus1016@hotmail.com, 25/01/2006, and Leonid Kreysin, Rebecca Schwartz
	"111112222113345522133444552134444452637777752633777559638878859668888899666699999", // 10, Onion, Andrew Smith, andrewgsmith@ntlworld.com, 15/01/2006
	"111152222111555222175555582177999882777999888477999883476666683444666333444463333", // 11, Double Mirror, Fer van Nieuwenhuizen, TeachOffice@Wanadoo.nl
	"111222333111123333411222336445525566444525666444555666777789999777888999778888899", // 12, cyndie.smith@netzero.com
	"111123333111224333122244443125544443225555566788885569788886669777866999777769999", // 13, Tornado, Kathleen R Nicol, kath@nic01.com
	"188888996118889966411899666441199667444119677443322777433352277333555227355555222", // 14, Cross, Andrew Smith, andrewgsmith@ntlworld.com
	"112222333111225333112225633114455663444456666744556699774588899777588999777888899", // 15, Worm, Leonid Kreysin, lkreysin@yahoo.com
	"444455555444435556994233566991223336911222336911122366998112766988817777888887777", // 16, Cabbage, Tim Cieplowski, tjciepl@bgnet.bgsu.edu
	"111222333111222333411522633441552663444555666744855966774885996777888999777888999", // 17, Stripes, leob, leob54321@yahoo.com
	"111223333112223633112225633411525666444555666444585996774588899774788899777788999", // 18, H, Bob & Debbie Scott, krydak@yahoo.com
	"111222223111122233441152333444555633744456663774555666777859966778889999788888999", // 19, Wednesday, Gérard Coteau, coteau41@wanadoo.fr
	"111123333114122333144522236144552236447555266487755669487775669888779699888879999"]; // 20 zigzag, Gérard Coteau, coteau41@wanadoo.fr

jig=1;

/*---------------------------------------------------------------------*/
/* Draws the content of a square on the board							*/
/*---------------------------------------------------------------------*/
function set_square( x, y, val, setup )
{
	var t, s;
	var sq_col=['black','#CC0000','blue','blue'];
	var sq_siz=['8pt','14pt','14pt','14pt','8pt','18pt','18pt','18pt'];

	// Get the table cell name out using the coordinates
	t=document.getElementById("a"+y+x);
	if( (setup==0 && showhints) || setup > 0 )
		 t.innerHTML=val;	// Assign the new value to the cell
	else t.innerHTML='&nbsp;';	// Assign the new value to the cell
	t.style.color=(print_version) ? 'black' : sq_col[setup];
	t.style.fontSize=(print_version) ? '20pt' : sq_siz[setup];
	if( !print_version && setup == 3 ) t.style.backgroundColor = '#ff0000';
	if( print_version ) return;
	s="D" + y.toString()+x.toString();
	if( val == "&nbsp;" )
		document.forms.DataEntry.elements[s].value='';
	else if( setup ) document.forms.DataEntry.elements[s].value=val;
}
/*----------------------------------------------------------------------*/
/* Converts the bit array to a string of numbers for display			*/
/*----------------------------------------------------------------------*/
function lable_square( y, x, deduct )
{
	var lable, c, i, modfact=3, cel;
	lable='';
	c=0;
	mask[y][x] -= deduct;
	show[y][x] += deduct;
	if( bunched )
	{
		if( bit_count(mask[y][x]) < 5 ) modfact=2;
		for( i=0;i<9;i++ ) if( mask[y][x] & (1 << i) )	// i=0 to 8 so first shift is 0 bits
		{
			if( lable.length > 0 ) lable=lable + "&nbsp;";

			if( c && (c % modfact) == 0 ) lable=lable + "<br>";
			lable=lable + (i+1);
			c++;	// <br> it every three numbers
		}
	}
	else
	{
		modfact=3;
		lable = '<table id="cl' + y + x + '" class="candtb" cellspacing=0 align=center>';
		for( i=0;i<9;i++ )
		{
			if( (i % modfact) == 0 )
				lable=lable + "<tr>";
			cel = '<td id="w' + y + x + i + '"';
			if( mask[y][x] & (1 << i) )	// i=0 to 8 so first shift is 0 bits
			{
				if( show[y][x] & (1 << i) )
					lable=lable + cel + ' class="fsh">' + (i+1) + '</td>';
				else
					lable=lable + cel + '>' + (i+1) + "</td>";
			}
			else
			{
				if( show[y][x] & (1 << i) )
					lable=lable + cel + ' class="fsh">' + (i+1) + '</td>';
				else lable=lable + cel + '>&nbsp;</td>';
			}
			if( (i % modfact) == 2 )
				lable=lable + "</tr>";
		}
		lable=lable + "</table>";
	}
	some_changes=true;
	set_square(x,y,lable,0);
}
/*---------------------------------------------------------------------*/
/* Sets the board up from scratch and draws it. Called from onLoad */
/*---------------------------------------------------------------------*/
function load_board()
{
	var i,j,t,s,nt,k,p,a,doc,jboard;
	var bd=location.search.split('=');
	var par;
	var content;
	prevlaststage=laststage=stage=0;
	print_version=false;

	cordX=new Array(81);
	cordY=new Array(81);
	APEstack=new Array(81);

/*	if( !document.ifrm )
		 doc = document.getElementById("ifrm").contentDocument;
	else doc = document.ifrm.document;
	doc.body.innerHTML='Results will go here!';*/


	if( bd.length==3 && firsttime )
	{
		tmparr = bd[1]
		tmp2 = tmparr.split('&');
		jig = parseInt(tmp2[0]);
		document.forms.DataEntry.elements["maptype"].selectedIndex = jig;
	}
	for(j=0;j<9;j++)
		for(i=0;i<9;i++)
		{
			g[j][i]=show[j][i]=orig[j][i]=mask[j][i]=0;
			jc[j][i] = jigsaw_maps[jig].charAt(j*9+i);
			jb[j][i] = jigsaw_boxes[jig].charAt(j*9+i)-1;
			document.forms.DataEntry.elements["D"+j+i].className = "DE" + jigsaw_maps[jig].charAt(j*9+i);
			document.forms.DataEntry.elements["D"+j+i].value='';

		}
	jboard = (jig-1)*4+document.forms.DataEntry.elements["Example"].selectedIndex;

	for(j=0;j<9;j++)
		for(i=0;i<9;i++)
		{
			if( bd.length==3 && bd[2].length==81 && firsttime )
			{
				if( IsNumeric(bd[2].charAt((j*9)+i)) )
					g[j][i]=bd[2].charAt((j*9)+i);
			}
			else g[j][i]=examples[jboard].charAt((j*9)+i)*1;

			show[j][i]=orig[j][i]=mask[j][i]=0;
			t=document.getElementById("a" + j + i);
			t.style.border = '1px solid #888888';
			if( j>0 && jc[j][i] != jc[j-1][i] ) t.style.borderTop = "2px solid black";
			if( j<8 && jc[j][i] != jc[j+1][i] ) t.style.borderBottom = "2px solid black";
			if( i>0 && jc[j][i] != jc[j][i-1] ) t.style.borderLeft = "2px solid black";
			if( i<8 && jc[j][i] != jc[j][i+1] ) t.style.borderRight = "2px solid black";

			if( g[j][i] > 0 )
				set_square(i,j,g[j][i],1);
			else
			{
				orig[j][i]=mask[j][i]=511;
				lable_square( j,i,0 );
			}
		}

	reset_yes_no( jig_list,6 );
	document.getElementById("takestep").onclick=take_step;
	document.getElementById("takestep").className = 'SButton';
	if( readCookie('scanraidnewjigsawcookie') )
	{
		document.getElementById("reload").className="SButton";
		some_saved=true;
	}
	some_changes=false;
	firsttime=false;

	if( !document.ifrm )
		 doc = document.getElementById("ifrm").contentDocument;
	else doc = document.ifrm.document;
	doc.body.innerHTML='Results go here';

	cnv = document.getElementById("myCanvas");
	jg = new jsGraphics(cnv);
	jg.clear();
}
function change_jigsaw_board()
{
	jig = document.forms.DataEntry.elements["maptype"].selectedIndex;
	jig++;
	load_board();
}
function load_print_board()
{
	var i,j,k=2,t,s,sss,k,p,a,doc,jboard;
	var par;
	var content;

	cordX=new Array(81);
	cordY=new Array(81);
	APEstack=new Array(81);
	print_version=true;

	sss = location.search.split(",");
	jig = sss[0].substring(1,sss[0].length);
	showhints = (sss[1]==1)?true:false;

	for(j=0;j<9;j++)
		for(i=0;i<9;i++)
		{
			g[j][i]=show[j][i]=orig[j][i]=mask[j][i]=0;
			n = parseInt(sss[k++]);
			if( bit_count(n) == 1 )
				g[j][i] = bit2int(n)+1*1;
			else mask[j][i] = n;
			jc[j][i] = jigsaw_maps[jig].charAt(j*9+i);
			jb[j][i] = jigsaw_boxes[jig].charAt(j*9+i);
		}

	for(j=0;j<9;j++)
		for(i=0;i<9;i++)
		{
			t=document.getElementById("a" + j + i);

			t.style.border = '1px solid #888888';
			if( j>0 && jc[j][i] != jc[j-1][i] ) t.style.borderTop = "3px solid black";
			if( j<8 && jc[j][i] != jc[j+1][i] ) t.style.borderBottom = "2px solid black";
			if( i>0 && jc[j][i] != jc[j][i-1] ) t.style.borderLeft = "2px solid black";
			if( i<8 && jc[j][i] != jc[j][i+1] ) t.style.borderRight = "3px solid black";

			if( g[j][i] > 0 )
				set_square(i,j,g[j][i],1);
			else if( showhints )
			{
				s = "";
				for(n=1;n<10;n++)3
				{
					if( mask[j][i] & (1 << (n-1)) )
						s = s + n + "&nbsp;";
					else s = s + "&nbsp;&nbsp;&nbsp;"
					if( n==3 || n==6 ) s = s + "<br>";
				}
				t.className='innerLittleCenter';
				t.innerHTML=s;
			}
		}
}
function import_sudoku()
{
	var dstring;
	var actualstr='';
	var c,i,j,s,t;

	dstring=window.prompt("Enter a string of 81 numbers (you can express blanks as 0, *, _ or '.')",save_dstring);
	if( dstring == null ) return;
	if( dstring.length == 0 ) return;

	save_dstring=dstring;

	for(i=0;i<dstring.length;i++)
	{
		c=dstring.charAt(i);
		if( IsNumeric(c) || c=='0' )
			actualstr=actualstr + dstring.charAt(i);
		else if( c=='.' || c=='*' || c=='_' )
			actualstr=actualstr + '0';
	}
	if( actualstr.length != 81 )
	{
		okay=false;
		alert("Your submission contained " + actualstr.length + " numbers. Please check it and press 'Import' again");
		return;
	}
	for(j=0;j<9;j++)
		for(i=0;i<9;i++)
		{
			t=document.getElementById("a"+j+i);
			t.style.backgroundColor='#eeeedd';
			t.style.color='black';
			t.style.fontSize='8pt';
			show[j][i]=mask[j][i]=0;
			g[j][i]=parseInt(actualstr.charAt((j*9)+i));
			if( g[j][i] > 0 )
				set_square(i,j,g[j][i],1);
			else
			{
				orig[j][i]=mask[j][i]=511;
				lable_square( j,i,0 );
				s="D" + j.toString()+i.toString();
				document.forms.DataEntry.elements[s].value='';
			}
		}
	reset_yes_no( jig_list,6 );
	some_changes=false;
	firsttime=false;
	prevlaststage=laststage=stage=0;
	jg.clear();
}
function blank_board()
{
	var i,t,x,y,nt;
	prevlaststage=laststage=stage=0;
	t=document.getElementById("TestT");
	for(i=0;i<MAX_STRAT;i++)
		t.rows[i].cells[0].style.backgroundColor="#222222";
	document.getElementById("backstep").className='GButton';
	for(x=0;x<9;x++)
		for(y=0;y<9;y++)
		{
			t=document.getElementById("a"+y+x);
			t.style.backgroundColor='#eeeedd';
			t.style.color='black';
			t.style.fontSize='8pt';
			orig[x][y]=mask[x][y]=511;	// This is the key: numbers 1-9 in bits=511,
			g[x][y]=0;					// .. and there are no picked squares
			set_square(y,x,"&nbsp;",0);		// nbsp it so the borders show up
		}
	reset_yes_no( jig_list,6 );
}
function clear_board()
{
	var i,t,x,y,nt;
	prevlaststage=laststage=stage=0;
	t=document.getElementById("TestT");
	for(i=0;i<MAX_STRAT;i++)
		t.rows[i].cells[0].style.backgroundColor="#222222";
	document.getElementById("backstep").className='GButton';
	for(x=0;x<9;x++)
		for(y=0;y<9;y++)
		{
			t=document.getElementById("a"+y+x);
			t.style.backgroundColor='#eeeedd';
			t.style.color='black';
			t.style.fontSize='8pt';
			orig[x][y]=mask[x][y]=511;	// This is the key: numbers 1-9 in bits=511,
			g[x][y]=0;					// .. and there are no picked squares
		//	set_square(y,x,"&nbsp;",0);		// nbsp it so the borders show up
		}
	reset_yes_no( jig_list,6 );
	jg.clear();
}
function save_board()
{
	var i,j,s=jig.toString();
	for( j in g )
		for( i in g[j] ) {
			if( s.length ) s += ',';
			s = s + (g[j][i]?g[j][i]:-mask[j][i]);
			save[j][i]=g[j][i];
		}
	document.getElementById("reload").className="SButton";
	some_saved=true;

	var date = new Date();
	date.setTime(date.getTime()+(30*24*60*60*1000));

	document.cookie ='scanraidnewjigsawcookie=' + s + '; expires=' + date.toGMTString() + '; path=/'

	alert("Current Board Saved (as a cookie)");
}
function reload_board()
{
	var i,j,x,xarr;

	x = readCookie('scanraidnewjigsawcookie')
	if (!x)
	{
		alert("No saved board found");
		return;
	}

	arr = x.split(',');
	jig = arr[0];
	clear_board();

	for( j=0;j<9;j++ )
		for( i=0;i<9;i++ )
		{
			orig[j][i]=0;
			if( arr[(j*9)+i+1] > 0 ) {
				g[j][i]=parseInt(arr[(j*9)+i+1]);
				orig[j][i]=mask[j][i]=0;
			} else {
				orig[j][i]=mask[j][i]=-parseInt(arr[(j*9)+i+1]);
				g[j][i]=0;
			}

			jc[j][i] = jigsaw_maps[jig].charAt(j*9+i);
			jb[j][i] = jigsaw_boxes[jig].charAt(j*9+i)-1;
			document.forms.DataEntry.elements["D"+j+i].className = "DE" + jigsaw_maps[jig].charAt(j*9+i);
			document.forms.DataEntry.elements["D"+j+i].value='';

		}
	jboard = 0;

	for(j=0;j<9;j++)
		for(i=0;i<9;i++)
		{
			t=document.getElementById("a" + j + i);
			t.style.border = '1px solid #888888';
			if( j>0 && jc[j][i] != jc[j-1][i] ) t.style.borderTop = "2px solid black";
			if( j<8 && jc[j][i] != jc[j+1][i] ) t.style.borderBottom = "2px solid black";
			if( i>0 && jc[j][i] != jc[j][i-1] ) t.style.borderLeft = "2px solid black";
			if( i<8 && jc[j][i] != jc[j][i+1] ) t.style.borderRight = "2px solid black";

			if( g[j][i] > 0 )
				set_square(i,j,g[j][i],1);
			else lable_square( j,i,0 );

		}

	reset_yes_no( jig_list,6 );
	document.getElementById("takestep").onclick=take_step;
	document.getElementById("takestep").className = 'SButton';
	some_changes=false;
	firsttime=false;
	jg.clear();
}
/*----------------------------------------------------------------------*/
/* First of the analyser functions - simply checks for single values	*/
/* which means a number MUST be the solution for that square			*/
/*----------------------------------------------------------------------*/
function check_for_single()
{
	var i,x,y,done=0;
	for( y=0;y<9;y++ )
		for( x=0;x<9;x++ )	// for every square on the board
		{
			for(i=0;i<9;i++)	// if the bit array contains only one bit
				if( mask[y][x] == (1 << i) )
				{
					g[y][x]=i+1;		// we have a single number and a solution
					mask[y][x]=0;		// ...wipe the mask
					set_square(x,y,g[y][x],2);	// and draw the number
					done++;
			//		some_changes=true;
				}
		}
	return done;
}
function check_for_one_single( y,x )
{
	var n;
	for(n=0;n<9;n++)
		if( mask[y][x] == (1 << n) )
		{
			g[y][x]=n+1;		// we have a single number and a solution
			mask[y][x]=0;		// ...wipe the mask
			set_square(x,y,g[y][x],2);	// and draw the number
			some_changes=true;
			return true;
		}
	return false;
}

function show_candidates()
{
	var changes;
	var x,y,i,a,b,j,xx,yy,n,b;

	/*----------------------------------------------------------------------*/
	/* check the rows and columns of each square							*/
	/* and to remove any bits for numbers that are found. Ie,we start with	*/
	/* 123456789 and zero any numbers in the array in each row/column		*/
	/*----------------------------------------------------------------------*/
	for( y=0;y<9;y++ )
		for( x=0;x<9;x++ )	// for every square on the board
			if( !g[y][x] )	// if it is an unknown square...
			{
				changes=false;
				for( i=0;i<9;i++) // for the size of the board
				{
					if( i != x && g[y][i] > 0 ) // check values in row
						if( (mask[y][x] & (1 << (g[y][i]-1))) )
						{
							mask[y][x] -= (1 << (g[y][i]-1));	// remove that bit
							changes=true;
						}
					if( i != y && g[i][x] > 0 ) // check values in column
						if( (mask[y][x] & (1 << (g[i][x]-1))) )
						{
							mask[y][x] -= (1 << (g[i][x]-1));	// remove that bit
							changes=true;
						}
				}
				if( changes ) lable_square( y,x,0 );
			}

	/*----------------------------------------------------------------------*/
	/* check number in each box - which MUST 								*/
	/* contain only 1 to 9. If we have known numbers then they must be		*/
	/* removed from the choices in the bit array found in test_row_col		*/
	/*----------------------------------------------------------------------*/
	for( y=0;y<9;y++ )
		for( x=0;x<9;x++ ) if( g[y][x]>0 ) // for every square on the board
		{
			n=g[y][x]-1;
			b = jb[y][x];
			for( yy=0;yy<9;yy++ )
				for( xx=0;xx<9;xx++ )
					if( b == jb[yy][xx] && mask[yy][xx] & (1 << n) )
					{
						mask[yy][xx] -= (1 << n);
						lable_square( yy,xx,0);
					}
		}
}
function singles_in_row_col( )
{
	var y,x,n,cc,cr,k;

	for(y=0;y<9;y++)
		for(x=0;x<9;x++)	// for every square on the board...
			if( !g[y][x] )	// if it is an unknown square...
			{
				for(n=0;n<9 && !g[y][x];n++) if( mask[y][x] & (1 << n) ) // For all numbers,if the number is a possible
				{
					for( cc=cr=k=0;k<9;k++)
					{
						if( !g[y][k] && (mask[y][k] & (1 << n)) ) cr++;  // check the row
						if( !g[k][x] && (mask[k][x] & (1 << n)) ) cc++;  // check the column
					}
					if( cr==1 || cc==1 )
					{
						if( cr==1 ) strat_add("SINGLE: " + cordit(y,x) + " set to " + abetx.charAt(n) + ", unique in Row<br>");
						if( cc==1 ) strat_add("SINGLE: " + cordit(y,x) + " set to " + abetx.charAt(n) + ", unique in Column<br>");
						show[y][x]=(1 << n);
						lable_square(y,x,0);
						mask[y][x]=(1 << n);
					}
				}
			}
}

function singles_in_box( )
{
	var ax=new Array(12);
	var ay=new Array(12);
	var bb,cc,n,c,y,x;

	/*----------------------------------------------------------------------*/
	/* Point of check_box is that now we have a whole board set up with	*/
	/* a bit array for each square. Lets check that bit array in each		*/
	/* box to see if any of the nine squares have numbers which only occur	*/
	/* once. If so we have a NEW solution for that square.					*/
	/*----------------------------------------------------------------------*/

	for(b=0;b<9;b++)			// for each box (9 of them)
		for(n=0;n<9;n++)	// .. check each number
		{
			c = 0;
			for(y=0;y<9 && c<9;y++)
				for(x=0;x<9 && c<9;x++)
					if( jb[y][x]==b && (mask[y][x] & (1 << n)) ) // if the square is known ...
					{
						ax[c]=x;	// Store the coordinates
						ay[c++]=y; // and count how many times this happens
					}
					else if( jb[y][x]==b && g[y][x]==n+1 ) c=9;	// if that number is known we can ignore it
			if( c == 1 )	// If we only have one occurance...
			{
				strat_add("SINGLE: " + cordit(ay[0],ax[0]) + " set to " + abetx.charAt(n) + ", unique in Box<br>");
				show[ay[0]][ax[0]]=(1 << n);
				lable_square(ay[0],ax[0],0);
				mask[ay[0]][ax[0]]=(1 << n);
				some_changes=true;
			}
		}
}

/*-------------------------------------------------------------------------*/
/* Purpose of hidden_pairs is to look for pairs of numbers, eg 3-7 and 3-7 */
/* mixed up in the same two squares with other numbers - which can be      */
/* eliminated. 															   */
/*-------------------------------------------------------------------------*/
function apply_new_mask( desc,direction,unit,y,x,h )
{
	strat_add(desc + mask2str(h) + direction + abetx.charAt(unit) + ": " + cordit(y,x) + " - " + mask2str(mask[y][x]) + " -> " + mask2str(mask[y][x] & h) + "<br>");
	show[y][x] = mask[y][x] - (mask[y][x] & h);
	mask[y][x] &= h;
	lable_square( y,x,0 );
}
function hidden_pairs()
{
	var x,y,n,m,i,bb,cc,box=0,h;
	var pos=new Array(9);

	for(b=0;b<9;b++)		// Once more, for each box (9 of them 3 by 3 each)
	{
		for(n=0;n<9;n++)
			for(i=y=0;y<9;y++)
				for(x=0;x<9;x++)
					if( jb[y][x]==b && !g[y][x] && (mask[y][x] & (1 << n)) )
						pos[n] += (1 << i++);  // ith position of n

		for(n=0;n<8;n++)
			for(m=n+1;m<9;m++)
				if( bit_count(pos[n])==2 && pos[n] == pos[m] )
				{
					i=0;
					for(y=bb;y<bb+3;y++)	// which means looking in each 3 by 3 box
						for(x=cc;x<cc+3;x++,i++)
							if( pos[n] & (1 << i) && bit_count(mask[y][x]) > 2 )
							{
								h=(1 << n) + (1 << m);
								apply_new_mask( "HIDDEN PAIR: ", " in box ", box,y,x,h );
							}
				}
		box++;
	}

	/*-------------------------------------------------------------------------*/
	/* Checking in the box will get most hidden pairs, but some are aligned    */
	/* over two box but still on the same row or columns				       */
	/*-------------------------------------------------------------------------*/
	for(y=0;y<9;y++)
	{
		for(n=0;n<9;n++)	// .. check each number
			for(pos[n]=x=0;x<9;x++)	// which means looking in each row/col
				if( !g[y][x] && (mask[y][x] & (1 << n)) )
					pos[n] += (1 << x);  // ith position of n

		for(n=0;n<8;n++)
			for(m=n+1;m<9;m++)
				if( bit_count(pos[n])==2 && pos[n] == pos[m] )
					for(x=0;x<9;x++)	// which means looking in each row/col
						if( pos[n] & (1 << x) && bit_count(mask[y][x]) > 2 )
						{
							h=(1 << n) + (1 << m);
							apply_new_mask( "HIDDEN PAIR: ", " in row ",y,y,x,h );
						}
	}
	for(x=0;x<9;x++)
	{
		for(n=0;n<9;n++)	// .. check each number
			for(pos[n]=y=0;y<9;y++)	// which means looking in each row/col
				if( !g[y][x] && (mask[y][x] & (1 << n)) )
					pos[n] += (1 << y);  // ith position of n

		for(n=0;n<8;n++)
			for(m=n+1;m<9;m++)
				if( bit_count(pos[n])==2 && pos[n] == pos[m] )
					for(y=0;y<9;y++)	// which means looking in each row/col
						if( pos[n] & (1 << y) && bit_count(mask[y][x]) > 2 )
						{
							h=(1 << n) + (1 << m);
							apply_new_mask( "HIDDEN PAIR: ", " in col ",x,y,x,h );
						}
	}
}
function hidden_triples()
{
	var x,y,n,m,p,i,bb,cc,a,b,c,h,box=0;
	var pos=new Array(9);


	for(b=0;b<9;b++)		// Once more, for each box (9 of them 3 by 3 each)
	{
		for(n=0;n<9;n++)
			for(i=y=0;y<9;y++)
				for(x=0;x<9;x++)
					if( jb[y][x]==b && !g[y][x] && (mask[y][x] & (1 << n)) )
						pos[n] += (1 << i++);  // ith position of n

		for(n=0;n<7;n++)
			for(m=n+1;m<8;m++)
				for(p=m+1;p<9;p++)
					if( bit_count(pos[n] | pos[m] | pos[p]) == 3 && pos[n] && pos[m] && pos[p] )
					{
						i=0;
						for(y=bb;y<bb+3;y++)	// which means looking in each 3 by 3 box
							for(x=cc;x<cc+3;x++,i++)
							{
								a=pos[n] & (1 << i);
								b=pos[m] & (1 << i);
								c=pos[p] & (1 << i);
								if( (a || b || c)
								  && bit_count(mask[y][x]) > ((a>0)+(b>0)+(c>0)) )
								{
									h=(1 << n) + (1 << m) + (1 << p);
									apply_new_mask( "HIDDEN TRIPLE: ", " in box ",box,y,x,h );
								}
							}
					}
			box++;
		}

	/*-------------------------------------------------------------------------*/
	/* Checking in the box will get most hidden pairs, but some are aligned    */
	/* over two box but still on the same row or columns				       */
	/*-------------------------------------------------------------------------*/
	for(y=0;y<9;y++)
	{
		for(n=0;n<9;n++)	// .. check each number
			for(pos[n]=x=0;x<9;x++)	// which means looking in each row/col
				if( !g[y][x] && (mask[y][x] & (1 << n)) )
					pos[n] += (1 << x);  // ith position of n

		for(n=0;n<7;n++)
			for(m=n+1;m<8;m++)
				for(p=m+1;p<9;p++)
					if( bit_count(pos[n] | pos[m] | pos[p]) == 3 && pos[n] && pos[m] && pos[p] )
					{
						for(x=0;x<9;x++)
						{
							a=pos[n] & (1 << x);
							b=pos[m] & (1 << x);
							c=pos[p] & (1 << x);
						//	if( y==4 ) alert( x + ' abc: ' + a + ' ' + b + ' ' + c + ' nmp: ' + n + ' ' + m + ' ' + p );
							if( (a || b || c)
							  && bit_count(mask[y][x]) > ((a>0)+(b>0)+(c>0)) )
							{
								h=(1 << n) + (1 << m) + (1 << p);
								apply_new_mask( "HIDDEN TRIPLE: ", " in row ",y,y,x,h );
							}
						}
					}
	}
	for(x=0;x<9;x++)
	{
		for(n=0;n<9;n++)	// .. check each number
			for(pos[n]=y=0;y<9;y++)	// which means looking in each row/col
				if( !g[y][x] && (mask[y][x] & (1 << n)) )
					pos[n] += (1 << y);  // ith position of n

		for(n=0;n<7;n++)
			for(m=n+1;m<8;m++)
				for(p=m+1;p<9;p++)
					if( bit_count(pos[n] | pos[m] | pos[p]) == 3 && pos[n] && pos[m] && pos[p] )
					{
						for(y=0;y<9;y++)
						{
							a=pos[n] & (1 << y);
							b=pos[m] & (1 << y);
							c=pos[p] & (1 << y);
							if( (a || b || c)
							  && bit_count(mask[y][x]) > ((a>0)+(b>0)+(c>0)) )
							{
								h=(1 << n) + (1 << m) + (1 << p);
								apply_new_mask( "HIDDEN TRIPLE: ", " in col ",x,y,x,h );
							}
						}
					}
	}
}
function hidden_quads()
{
	var x,y,n,m,p,q,i,bb,cc,a,b,c,d,h,box=0;
	var pos=new Array(9);

	for(b=0;b<9;b++)		// Once more, for each box (9 of them 3 by 3 each)
	{
		for(n=0;n<9;n++)
			for(i=y=0;y<9;y++)
				for(x=0;x<9;x++)
					if( jb[y][x]==b && !g[y][x] && (mask[y][x] & (1 << n)) )
						pos[n] += (1 << i++);  // ith position of n

		for(n=0;n<6;n++)
			for(m=n+1;m<7;m++)
				for(p=m+1;p<8;p++)
					for(q=p+1;q<9;q++)
						if( bit_count(pos[n] | pos[m] | pos[p] | pos[q]) == 4 && pos[n] && pos[m] && pos[p] && pos[q] )
						{
							i=0;
							for(y=bb;y<bb+3;y++)	// which means looking in each 3 by 3 box
								for(x=cc;x<cc+3;x++,i++)
								{
									a=pos[n] & (1 << i);
									b=pos[m] & (1 << i);
									c=pos[p] & (1 << i);
									d=pos[q] & (1 << i);
									if( (a || b || c || d)
									  && bit_count(mask[y][x]) > ((a>0)+(b>0)+(c>0)+(d>0)) )
									{
										h=(1 << n) + (1 << m) + (1 << p) + (1 << q);
										apply_new_mask( "HIDDEN QUAD: ", " in box ",box,y,x,h );
									}
								}
						}
		box++;
	}

	/*-------------------------------------------------------------------------*/
	/* Checking in the box will get most hidden pairs, but some are aligned    */
	/* over two box but still on the same row or columns				       */
	/*-------------------------------------------------------------------------*/
	for(y=0;y<9;y++)
	{

		for(n=0;n<9;n++)	// .. check each number
			for(pos[n]=x=0;x<9;x++)	// which means looking in each row/col
				if( !g[y][x] && (mask[y][x] & (1 << n)) )
					pos[n] += (1 << x);  // ith position of n

		for(n=0;n<6;n++)
			for(m=n+1;m<7;m++)
				for(p=m+1;p<8;p++)
					for(q=p+1;q<9;q++)
						if( bit_count(pos[n] | pos[m] | pos[p] | pos[q]) == 4 && pos[n] && pos[m] && pos[p] && pos[q] )
						{
							for(x=0;x<9;x++)
							{
								a=pos[n] & (1 << x);
								b=pos[m] & (1 << x);
								c=pos[p] & (1 << x);
								d=pos[q] & (1 << x);
								if( (a || b || c || d)
								  && bit_count(mask[y][x]) > ((a>0)+(b>0)+(c>0)+(d>0)) )
								{
									h=(1 << n) + (1 << m) + (1 << p) + (1 << q);
									apply_new_mask( "HIDDEN QUAD: ", " in row ",y,y,x,h );
								}
							}
						}
	}
	for(x=0;x<9;x++)
	{
		for(n=0;n<9;n++)	// .. check each number
			for(pos[n]=y=0;y<9;y++)	// which means looking in each row/col
				if( !g[y][x] && (mask[y][x] & (1 << n)) )
					pos[n] += (1 << y);  // ith position of n

		for(n=0;n<6;n++)
			for(m=n+1;m<7;m++)
				for(p=m+1;p<8;p++)
					for(q=p+1;q<9;q++)
						if( bit_count(pos[n] | pos[m] | pos[p] | pos[q]) == 3 && pos[n] && pos[m] && pos[p] && pos[q] )
						{
							for(y=0;y<9;y++)
							{
								a=pos[n] & (1 << y);
								b=pos[m] & (1 << y);
								c=pos[p] & (1 << y);
								d=pos[q] & (1 << y);
								if( (a || b || c)
								  && bit_count(mask[y][x]) > ((a>0)+(b>0)+(c>0)+(d>0)) )
								  {
									h=(1 << n) + (1 << m) + (1 << p) + (1 << q);
								  	apply_new_mask( "HIDDEN QUAD: ", " in col ",x,y,x,h );
								  }
							}
						}
	}
}

/*----------------------------------------------------------------------*/
/* MAIN PAIR TEST														*/
/*----------------------------------------------------------------------*/
function naked_pairs()
{
	var bb,cc,n,m,i,j,k,a,b,y,x1,x2,x3,h,cn,bx;
	var mbox=new Array(9);
	var cnt=new Array(9);

	/*----------------------------------------------------------------------*/
	/* Purpose of this pair test is to look for pairs of numbers,			*/
	/* eg 3-7 and 3-7 in the same box. Since both numbers MUST be on both   */
	/* cells they can be eliminated from the rest of the box				*/
	/*----------------------------------------------------------------------*/
	for(bx=0;bx<9;bx++)		// Once more, for each box (9 of them 3 by 3 each)
	{
		k=0;
		for(y=0;y<9;y++)	// put the box in a 1D array for ease of use
			for(x=0;x<9;x++) if( jb[y][x]==bx )
			{
				mbox[k]=mask[y][x];
				cnt[k]=bit_count(mask[y][x]);
				cordX[k]=x;
				cordY[k++]=y;
			}
		for(a=0;a<8;a++)	// .. check each pair in the 1D box array
			for(b=a+1;b<9;b++)
			{
				if( cnt[a]==2 && mbox[a] == mbox[b] )  // If same 2 numbers in the same 2 squares
				{
					for(m=0;m<9;m++)	// for all squares in the box
						for(n=0;n<9;n++) // for all numbers
						{
							if( m!=a && m!=b && (mbox[a] & (1 << n)) && (mbox[m] & (1 << n)) )
							{
							//	alert("here n=" + n + " m=" + m + " a=" + a + " mbox[a]=" + mbox[a] + " cnt[m]=" + cnt[m]);
								cn=abetx.charAt(n);
								strat_add("NAKED PAIR (Box): " + cordit(cordY[a],cordX[a]) + "/" + cordit(cordY[b],cordX[b]) + " removes " + cn + " from " + cordit(cordY[m],cordX[m]) + "<br>");
								mbox[m] -= (1 << n); // remove that number
								lable_square( cordY[m],cordX[m],(1 << n) );
							}
						}
				}
			}
	}

	/*----------------------------------------------------------------------*/
	/* Purpose of pair_test2 is to look for pairs of numbers, eg 3-7 and 3-7 */
	/* in the same row/col. Since both numbers MUST be on both cells they 	*/
	/* can be elininated from the rest of the ROW or COLUMN they are		*/
	/* aligned with. How cool is that?										*/
	/*----------------------------------------------------------------------*/

	for(y=0;y<9;y++)
		for(x1=0;x1<8;x1++)	// For every square...
			for(x2=x1+1;x2<9;x2++)
			{
				// This block checks the ROW the pair resides in...
				if( bit_count(mask[y][x1])==2 && mask[y][x1] == mask[y][x2] )
					for(i=0;i<9;i++)
					{
						h=(mask[y][i] & mask[y][x1]);
						if( i!=x1 && i!=x2 && !g[y][i] && h )
						{
							strat_add("NAKED PAIR (Row): " + cordit(y,x1) + "/" + cordit(y,x2) + " removes " + mask2str(mask[y][i] & h) + " from " + cordit(y,i) + "<br>");
							lable_square( y,i,h );
						}
					}

				// This block checks the COLUMN the pair resides in...
				if( bit_count(mask[x1][y])==2 && mask[x1][y] == mask[x2][y] )
					for(i=0;i<9;i++)
					{
						h=(mask[i][y] & mask[x1][y]);
						if( i!=x1 && i!=x2 && !g[i][y] && h )
						{
							strat_add("NAKED PAIR (Col): " + cordit(x1,y) + "/" + cordit(x2,y) + " removes " + mask2str(mask[i][y] & h) + " from " + cordit(i,y) + "<br>");
							lable_square( i,y,h );
						}
					}
			}
}

function naked_triples()
{
	var bb,cc,i,j,k,y,x1,x2,x3,h,off;
	var mbox=new Array(9);
	var cnt=new Array(9);

	// LOOK FOR TRIPLES
	for(y=0;y<9;y++)
		for(x1=0;x1<7;x1++)	// For each triple
			for(x2=x1+1;x2<8;x2++)
				for(x3=x2+1;x3<9;x3++)
				{
					// This block checks the ROW the triple resides in...
					if( bit_count(mask[y][x1])>1 && bit_count(mask[y][x2])>1 && bit_count(mask[y][x3])>1 )
					{
						h=mask[y][x1] | mask[y][x2] | mask[y][x3];
						if( bit_count(h)==3 )
							for(i=0;i<9;i++)
							{
								off=(mask[y][i] & h);
								if( i!=x1 && i!=x2 && i!=x3 && off )
								{
									strat_add("NAKED TRIPLE (Row): " + cordit(y,x1) + "/" + cordit(y,x2) + "/" + cordit(y,x3) + " removes " + mask2str(off) + " from " + cordit(y,i) + "<br>");
									lable_square( y,i,off );
								}
							}
					}
					// This block checks the COLUMN the triple resides in...
					if( bit_count(mask[x1][y])>1 && bit_count(mask[x2][y])>1 && bit_count(mask[x3][y])>1 )
					{
						h=mask[x1][y] | mask[x2][y] | mask[x3][y];
						if( bit_count(h)==3 )
							for(i=0;i<9;i++)
							{
								off=(mask[i][y] & h);
								if( i!=x1 && i!=x2 && i!=x3 && off )
								{
									strat_add("NAKED TRIPLE (Col): " + cordit(x1,y) + "/" + cordit(x2,y) + "/" + cordit(x3,y) + " removes " + mask2str(off) + " from " + cordit(i,y) + "<br>");
									lable_square( i,y,off );
								}
							}
					}
				}
	/*----------------------------------------------------------------------*/
	// This block checks the BOX the triple resides in...
	/*----------------------------------------------------------------------*/
	for(b=0;b<9;b++)		// Once more, for each box (9 of them 3 by 3 each)
	{
		k=0;
		for(y=0;y<9;y++)	// put the box in a 1D array for ease of use
			for(x=0;x<9;x++) if( jb[y][x]==b )
			{
				mbox[k]=mask[y][x];
				cnt[k]=bit_count(mask[y][x]);
				cordX[k]=x;
				cordY[k++]=y;
			}
		for(x1=0;x1<7;x1++)	// For each triple
			for(x2=x1+1;x2<8;x2++)
				for(x3=x2+1;x3<9;x3++)
				{
					if( cnt[x1]>1 && cnt[x2]>1 && cnt[x3]>1 )
					{
						h=mbox[x1] | mbox[x2] | mbox[x3];
						if( bit_count(h)==3 )
							for(i=0;i<9;i++)
							{
								off=(mbox[i] & h);
								if( i!=x1 && i!=x2 && i!=x3 && off )
								{
									strat_add("NAKED TRIPLE (Box): " + cordit(cordY[x1],cordX[x1]) + "/" + cordit(cordY[x2],cordX[x2]) + "/" + cordit(cordY[x3],cordX[x3]) + " removes " + mask2str(off) + " from " + cordit(cordY[i],cordX[i]) + "<br>");
									mbox[i] -= off; // remove that number
									lable_square( cordY[i],cordX[i],off ); // remove that number
								}
							}
					}
				}
	}
}
function naked_quads()
{
	var bb,cc,i,j,k,y,x1,x2,x3,x4,h,off;
	var mbox=new Array(9);
	var cnt=new Array(9);

	// LOOK FOR QUADS
	for(y=0;y<9;y++)
		for(x1=0;x1<6;x1++)	// For each quad
			for(x2=x1+1;x2<7;x2++)
				for(x3=x2+1;x3<8;x3++)
					for(x4=x3+1;x4<9;x4++)
					{
						// This block checks the ROW the quad resides in...
						if( bit_count(mask[y][x1])>1 && bit_count(mask[y][x2])>1 && bit_count(mask[y][x3])>1 && bit_count(mask[y][x4])>1 )
						{
							h=mask[y][x1] | mask[y][x2] | mask[y][x3] | mask[y][x4];
							if( bit_count(h)==4 )
								for(i=0;i<9;i++)
								{
									off=(mask[y][i] & h);
									if( i!=x1 && i!=x2 && i!=x3 && i!=x4 && off )
									{
										strat_add("NAKED QUAD (Row): " + cordit(y,x1) + "/" + cordit(y,x2) + "/" + cordit(y,x3) + "/" + cordit(y,x4) + " removes " + mask2str(off) + " from " + cordit(y,i) + "<br>");
										lable_square( y,i,off );
									}
								}
						}
						// This block checks the COLUMN the triple resides in...
						if( bit_count(mask[x1][y])>1 && bit_count(mask[x2][y])>1 && bit_count(mask[x3][y])>1 && bit_count(mask[x4][y])>1 )
						{
							h=mask[x1][y] | mask[x2][y] | mask[x3][y] | mask[x4][y];
							if( bit_count(h)==4 )
								for(i=0;i<9;i++)
								{
									off=(mask[i][y] & h);
									if( i!=x1 && i!=x2 && i!=x3 && i!=x4 && off )
									{
										strat_add("NAKED QUAD (Col): " + cordit(x1,y) + "/" + cordit(x2,y) + "/" + cordit(x3,y) + "/" + cordit(x4,y) + " removes " + mask2str(off) + " from " + cordit(i,y) + "<br>");
										lable_square( i,y,off );
									}
								}
						}
					}
	/*----------------------------------------------------------------------*/
	// This block checks the BOX the triple resides in...
	/*----------------------------------------------------------------------*/
	for(b=0;b<9;b++)		// Once more, for each box (9 of them 3 by 3 each)
	{
		k=0;
		for(y=0;y<9;y++)	// put the box in a 1D array for ease of use
			for(x=0;x<9;x++) if( jb[y][x]==b )
			{
				mbox[k]=mask[y][x];
				cnt[k]=bit_count(mask[y][x]);
				cordX[k]=x;
				cordY[k++]=y;
			}
		for(x1=0;x1<6;x1++)	// For each triple
			for(x2=x1+1;x2<7;x2++)
				for(x3=x2+1;x3<8;x3++)
					for(x4=x3+1;x4<9;x4++)
					{
						if( cnt[x1]>1 && cnt[x2]>1 && cnt[x3]>1 && cnt[x4]>1 )
						{
							h=mbox[x1] | mbox[x2] | mbox[x3] | mbox[x4];
							if( bit_count(h)==4 )
								for(i=0;i<9;i++)
								{
									off=(mbox[i] & h);
									if( i!=x1 && i!=x2 && i!=x3 && i!=x4 && off )
									{
										strat_add("NAKED QUAD (Box): " + cordit(cordY[x1],cordX[x1]) + "/" + cordit(cordY[x2],cordX[x2]) + "/" + cordit(cordY[x3],cordX[x3])  + "/" + cordit(cordY[x4],cordX[x4]) + " removes " + mask2str(off) + " from " + cordit(cordY[i],cordX[i]) + "<br>");
										mbox[i] -= off; // remove that number
										lable_square( cordY[i],cordX[i],off ); // remove that number
									}
								}
						}
					}
	}
}
function locked_pair( a,b,x,y )
{
	var i,j;
	if( a == x ) return true;
	if( b == y ) return true;
//	alert(a + '-' + b + ' ' + x + '-' + y);
	if( jb[b][a] == jb[y][x] ) return true;
	return false;
}
/*----------------------------------------------------------------------*/
/* See http://www.scanraid.com/remotepairs.htm for a full explanation	*/
/*----------------------------------------------------------------------*/
function remote_pair_test()
{
	var x,xx,y,yy,x1,x2,y1,y2,h,z1,z2,d,i,z;
	var pl=0;
	var sq=0;
	var oddness=new Array(20);

	for(y=0;y<9;y++)
		for(x=0;x<9;x++)	// For every square...
			if( bit_count(mask[y][x])==2 )	// find a pair
			{
				sq=0;
				cordX[sq]=x;
				cordY[sq++]=y;
				for(yy=0;yy<9;yy++)
					for(xx=0;xx<9;xx++)	// Find all other pairs..
						if( !(x==xx && y==yy) && mask[y][x] == mask[yy][xx] )
						{
							cordX[sq]=xx;
							cordY[sq++]=yy;
						}
				if( sq > 1 ) // At least 2 occurances of this pair
				{
					// Start the walk from the point of view of the start square
					for(i=0;i<sq;i++) oddness[i]=99;  // set all to unknown
					oddness[0]=0;  // Home Square
					for(d=0;d<sq;d++)  		// maximum distance is number of pairs - sq
					{
						for(z1=0;z1<sq-1;z1++)
							for(z2=z1+1;z2<sq;z2++)
							{
								if( oddness[z1] == d && oddness[z2] == 99 )
									if( locked_pair(cordX[z1],cordY[z1],cordX[z2],cordY[z2]) )
										oddness[z2]=d+1;  // One locked pair away from other

								if( oddness[z2] == d && oddness[z1] == 99 )
									if( locked_pair(cordX[z1],cordY[z1],cordX[z2],cordY[z2]) )
										oddness[z1]=d+1;  // One locked pair away from other
							}

					}
					for(z=1;z<sq;z++)
						if( oddness[z]!=99 && (oddness[z] % 2) == 1 )
						{
							x1=cordX[0];
							y1=cordY[0];
							x2=cordX[z];
							y2=cordY[z];
						//	alert(mask2str(mask[y][x]) + ' ' + cordit(y1,x1) + ' ' + cordit(y2,x2));

							if( y1!=y2 && x1!=x2 )
								for(yy=0;yy<9;yy++)
									for(xx=0;xx<9;xx++)
									{
										if( g[yy][xx] ) continue;
										if( (xx==x1 && yy==y1) || (xx==x2 && yy==y2)) continue;
										if( !locked_pair(xx,yy,x1,y1) || !locked_pair(xx,yy,x2,y2) ) continue; // Can see each other
										h=(mask[y][x] & mask[yy][xx]);
										if( !h ) continue; // Its unknown .. but one of the numbers is
										lable_square( yy,xx,h );  // remove that number
										strat_add("REMOTE PAIR: " + mask2str(h) + " removed from " + cordit(yy,xx) + ", Chain ends: " + cordit(y1,x1) + ' ' + cordit(y2,x2) + "<br>");
									}
						}
				}
			}
}
/*----------------------------------------------------------------------*/
/* Function to check for conflicts with the rules						*/
/*----------------------------------------------------------------------*/
function sanity_check()
{
	var b,n,i,j,c,x,y,xx,yy,failed=0;

	for( x in g )
		for( y in g[x] )	// for every square on the board...
			if( g[x][y]==0 && mask[x][y]==0 )	// if it is an known square...
			{
				set_square(y,x,g[x][y],3);	// hightlight conflicting squares
				return true;
			}

	for( x in g )
		for( y in g[x] )	// for every square on the board...
			if( g[x][y] )	// if it is an known square...
			{
				for( i=0;i<9;i++ ) // check values in row
				{
					if( i != y && g[x][i] == g[x][y] )
					{
						set_square(i,x,g[x][i],3);	// hightlight conflicting squares
						set_square(y,x,g[x][y],3);	// hightlight conflicting squares
						failed+=2;
					}
					if( i != x && g[i][y] == g[x][y] )
					{
						set_square(y,i,g[i][y],3);	// hightlight conflicting squares
						set_square(y,x,g[x][y],3);	// hightlight conflicting squares
						failed+=2;
					}
				}
			}

	for(b=0;b<9;b++)			// for each box (9 of them 3 by 3 each)
		for(y=0;y<9;y++)
			for(x=0;x<9;x++)
				if( jb[y][x]==b && g[y][x] ) // if the square is known ...
					for(yy=0;yy<9;yy++)	// ..check every other cell
						for(xx=0;xx<9;xx++)
							if( !(y==yy && x==xx) && jb[yy][xx]==b && g[y][x] == g[yy][xx] )	// .. if the number is known
							{
								set_square(yy,xx,g[yy][xx],3);	// hightlight conflicting squares
								set_square(y,x,g[y][x],3);	// hightlight conflicting squares
								failed+=2;
							}
	return failed;
}
/* Function to reset the board to its normal blue background */
function blue_board()
{
	var x,y,done=0;
	for(y=0;y<9;y++)		// Redraw the board to clear any user highlighting
		for(x=0;x<9;x++)
		{
			if( some_changes==false ) t=document.getElementById("a"+y+x);
			if( some_changes==false ) t.style.backgroundColor='#eeeedd';
			if( g[y][x]>0 ) done++;
		}
	return done;
}
function block_board()
{
	var x,y,c,okay=false;
	for(y=0;y<9;y++)		// Redraw the board to clear any user highlighting
		for(x=0;x<9;x++)
		{
			c = g26.charAt((y*9)+x)*1;
			if( c > 0 && g[y][x]!=c ) okay = true;
		}
	if(!okay) alert("Sorry, but a special block has been put on this solver for the Weekly 'Extreme' Sudokus. You will be able to use the solver after the deadline");
	return okay;
}
function post_to_form(cur_strat) {
	var x,y,s='',st='';
	for(y=0;y<9;y++)		// Redraw the board to clear any user highlighting
		for(x=0;x<9;x++)
		{
			if( g[y][x] )
				 s = s + ',' + (1 << (g[y][x]-1));
			else s = s + ',' + mask[y][x];
		}
	for( x=2;x<jig_list.length;x++) if( document.getElementById("CB"+jig_list[x]).checked===false )
	{
		st+=jig_list[x];
	}
/*	var frm;
	var iframeEl = document.getElementById('ifrm');
	if ( iframeEl.contentDocument ) { // DOM
		frm = iframeEl.contentDocument.getElementById('servsolv');
	} else if ( iframeEl.contentWindow ) { // IE win
		frm = iframeEl.contentWindow.document.getElementById('servsolv');
	} else {
		alert("Can't find iframe in DOM");
	} */
	frm = document.forms.servsolv;
	frm.elements['coordmode'].value = coordmode;
	frm.elements['strat'].value = cur_strat;
	frm.elements['stratmask'].value = st;
	frm.elements['mapno'].value = jig;
	frm.elements['board'].value = s.substr(1,s.length-1);
	frm.submit();

}
/*----------------------------------------------------------------------*/
/* Function to run the steps above in one go. Resets the board colors	*/
/*----------------------------------------------------------------------*/
function take_step()
{
	var i,j,done=0,t,found=0,x,y;

	done=blue_board();
//	if( done > 0 && !block_board() ) return;

	if( done == 0 )	// If the number of solutions=81, we're all done
	{
		alert("Put some numbers in the small board first.");
	}
	else if( done == 81 )	// If the number of solutions=81, we're all done
	{
		if( sanity_check()>0 )
			 alert("Opps. Not a valid Sudoku solution");
		else alert("Thats it! All done");
	}
	else
	{
		if( stage == 0 ) some_changes=false;

		if( stage!=0 && !some_changes )
		{
			for( x in g )
				for( y in g[x] ) last[x][y]=mask[x][y];
			prevlaststage=stage;
			laststage=stage;
		}
	//	alert('before: ' + stage + ' ' + some_changes);
		if( some_changes ) stage=0;
		else
		{
			if( stage==MAX_STRAT ) stage=1
			else if( stage<8 ) stage++;
			else stage=9;
		}

		if( stage == 0 )
		{
			found=check_for_single();
			document.getElementById("R0").innerHTML=(found)? '<font color=#00ff00><b>' + found + '</b></font>' : '<font color=#ff0000><b>0</b></font>';
			some_changes=false;
		}
		else
		{
		/*	if( !document.ifrm )
				 doc = document.getElementById("ifrm").contentDocument;
			else doc = document.ifrm.document;
			doc.body.innerHTML=''; */

			if( stage == 1 ) { reset_yes_no( jig_list,6 ); jg.clear(); clear_on_off_color(); }

			if( stage >= 7 )
			{
				document.getElementById("takestep").onclick=null;
				document.getElementById("takestep").className = 'GButton';
			}
			if( sanity_check() )
				alert("Oops - you've got an error on the board");
			clear_results = true;

			if( stage == 1  ) show_candidates();
			if( stage == 2  ) singles_in_row_col();
			if( stage == 3  ) singles_in_box();
			if( stage == 4  ) { naked_pairs(); naked_triples(); }
			if( stage == 5  ) { hidden_pairs(); hidden_triples(); }
			if( stage == 6  ) { naked_quads();  hidden_quads(); }
			if( stage == 7  ) /* pointing_pairs */ 	post_to_form('PPR');
			if( stage == 8  ) /* LBR */				post_to_form('LBR');
			if( stage == 9  ) /* LOL */ 			post_to_form('LOL');


			//	document.getElementById("dump").innerHTML = 'sudoku/SudokuSAPI.dll?GetSudoku?board=' + stage);

			if( stage == 1 )
				for( x in g )
					for( y in g[x] ) if( mask[y][x] && show[y][x] ) { show[y][x]=0; lable_square(y,x,0); }

			if( stage < 7  )
				document.getElementById("R" + stage).innerHTML=(some_changes)? '<font color=#00ff00><b>Yes</b></font>' : '<font color=#ff0000><b>No</b></font>';
			else document.getElementById("R" + jig_list[stage-7]).innerHTML=(some_changes)? '<font color=#00ff00><b>Yes</b></font>' : '<font color=#ffff00><b>Wait</b></font>';

			for( x in g )
				for( y in g[x] ) orig[x][y]=mask[x][y];
		}
		if( sanity_check() )
			alert("Oops - you've got an error on the board");

		t=document.getElementById("TestT");
		for(i=0;i<MAX_STRAT-1;i++)
			t.rows[i*1+offset[i]].cells[1].style.backgroundColor=(stage==i) ? "#777700" : ((((i*1+offset[i])%2)==0 && offset[i]!=9)?"#333333":"#222222");
		document.getElementById("backstep").className='SButton';
		if( stage==MAX_STRAT && some_changes == false )
			alert("No more known logical steps to take - you have to enter a number somewhere and then click 'Take Step'");
	}
}
function back_step()
{
	var i,j,s;
	if( document.getElementById("backstep").className == 'GButton' ) return;
	for( j in g )
		for( i in g[j] )
		{
			if( last[j][i]>0 )
			{
				show[j][i]=g[j][i]=0;
				orig[j][i]=mask[j][i]=last[j][i];
				lable_square( j,i,0 );
				document.forms.DataEntry.elements["D"+j+i].value='';
			}
		}
	some_changes=false;
	stage=(stage==0)?prevlaststage:laststage;
	t=document.getElementById("TestT");
	for(i=0;i<MAX_STRAT;i++)
		t.rows[i*1+offset[i]].cells[1].style.backgroundColor=(stage==i) ? "#777700" : ((((i*1+offset[i])%2)==0)?"#333333":"#222222");
	backup_yes_no( jig_list, stage, 7 );

	document.getElementById("backstep").className='GButton';
	document.getElementById("takestep").onclick=take_step;
	document.getElementById("takestep").className = 'SButton';
	blue_board();
	jg.clear();
}
/* Function to put a number on the board from the data entry form 		 */
function add_data(t)
{
	var x,y;
	some_changes=false;
	blue_board();
	x=t.id.charAt(1);	// Coordinate found in the input field name
	y=t.id.charAt(2);
	if( IsNumeric(t.value) )	// If the value is numeric
	{
	//	if( orig[x][y] & (1 << (t.value-1)) )	// ..Check if its a possible number for that square
	//	{
			g[x][y]=t.value;				// .. it is, so put it on the board
			mask[x][y]=0;
			set_square(y,x,g[x][y],2);
	//	}
	//	else t.value=( g[x][y] && !orig[x][y] ) ? g[x][y] : '';
	}
	else t.value='';
	if( t.value == '' )
	{
		if( orig[x][y]==0 ) orig[x][y]=511;
		mask[x][y]=orig[x][y];
		g[x][y]=0;
		lable_square(x,y,0)
	}
	stage=0;
	sanity_check();
}
function email_board()
{
	var x,y,done=0,SGW;
	var board='shape=' + jig + '&bd=';
	for(y=0;y<9;y++)
		for(x=0;x<9;x++)
		{
			if( g[y][x]>0 ) done++;
			board=board + g[y][x];
		}
	if( !done )
		alert("This board is empty!");
	else
	{
		SGW=window.open('JigsawEmail.htm?' + board,'_blank','resizable=no,scrollbars=no,left=300,top=200,screenX=200,screenY=200,width=750,height=420');
    	if (!SGW.opener) SGW.opener=self;
	}
}
function print_board()
{
	var x,y,done=0,SGW;
	var board=jig;
	board = board + ',' + ((showhints)?1:0);
	for(y=0;y<9;y++)
		for(x=0;x<9;x++)
		{
			if( g[y][x]>0 ) done++;
			if( g[y][x]>0 ) board=board + ',' + (1 << (g[y][x]-1));
			else board=board + ',' + mask[y][x];
		}
	SGW=window.open('JigsawPrintable.htm?' + board,'_blank','resizable=yes,toolbar=1,scrollbars=yes,left=100,top=10,screenX=100,screenY=10,width=670,height=700');
	if (!SGW.opener) SGW.opener=self;
}
function test_solutions(ptype)
{
	var x,y,done=0,SGW;
	var board='';

	done=blue_board();
	if( done < 10  ) { alert('Too few clues/numbers, please enter some more numbers.'); return; }
	if( done == 81  ) { alert('Puzzle is complete.'); return; }

	for(y=0;y<9;y++) for(x=0;x<9;x++)
		board=board + g[y][x];

	SGW=window.open('S/WebSudoku.dll?solutions&' + jig + ',' + board,'_blank','resizable=yes,toolbar=1,scrollbars=yes,left=100,top=10,screenX=100,screenY=10,width=670,height=480');
	if (!SGW.opener) SGW.opener=self;
}
function fired_event()
{
	var s='',c,y,x,n,t,stratname,www;
	var doc;
	if( !document.ifrm )
		 doc = document.getElementById("ifrm").contentDocument;
	else doc = document.ifrm.document;

	if( !doc.getElementById("kbin")) return;
	s = doc.getElementById("kbin").value;
	stratname = doc.getElementById("nstage").value;
	t=document.getElementById("TestT");

	if( stratname!="NO" )
	{
		stage = get_stage(jig_list,stratname);

		d2 = doc.getElementById("cols1");
		if( d2 ) grn_blue_color(d2.value,"fshGrn");
		d2 = doc.getElementById("cols2");
		if( d2 ) grn_blue_color(d2.value,"fshBlu");

		if( jg ) {
			jg.clear();

			d = doc.getElementById("chain1")
			if( d ) parsemychain( d.value, "#0000ff" );

			d = doc.getElementById("chain2")
			if( d ) parsemychain( d.value, "#990099" );

			d = doc.getElementById("chain3")
			if( d ) parsemychain( d.value, "#ff0000" );

			d = doc.getElementById("chain4")
			if( d ) parsemychain( d.value, "#009900" );

			jg.paint();
		}
		for(i=0;i<s.length;i+=3)
		{
			c = s.charAt(i);
			if( c == '{' ) break;
			y = s.charAt(i)-1;
			x = s.charAt(i+1)-1;
			n = s.charAt(i+2)-1;
		//	show[y][x] = mask[y][x] = (1 << n);
			lable_square(y,x,(1 << n));
			some_changes = true;
		}
		for(y=0;y<9;y++)
			for(x=0;x<9;x++)
			{
				switch( s.charAt(y*9+x+i+1) ){
				case '1' : document.getElementById("a"+y+x).style.backgroundColor='#ffff55'; break; // YELLOW
				case '2' : document.getElementById("a"+y+x).style.backgroundColor='#eeaa55'; break; // ORANGE
				case '3' : document.getElementById("a"+y+x).style.backgroundColor='#55ff55'; break; // GREEN
				case '4' : document.getElementById("a"+y+x).style.backgroundColor='#55ffcc'; break; // CYAN
				}
			}
		if( stratname=="PPR" || stratname=="LBR" )
		{
			document.getElementById("R" + stratname).innerHTML=(some_changes)? '<font color=#00ff00><b>Yes</b></font>' : '<font color=#ff0000><b>No</b></font>';
		}
		else
		{
			for(i=0;i<MAX_STRAT-1;i++) {
				www = i*1+offset[i];
				t.rows[www].cells[1].style.backgroundColor=(stage==i) ? "#777700" : (((www%2)==0)?"#333333":"#222222");
			}
			paint_yes_no( jig_list, stratname );
		}
	}
	else
	{
		if( stage==7 || stage==8 )
			document.getElementById("R" + stratname).innerHTML='<font color=#ff0000><b>No</b></font>';
		else
		{
			paint_yes_no( jig_list, stratname );
		}
	}
	document.getElementById("takestep").onclick=take_step;
	document.getElementById("takestep").className = 'SButton';
}
function toggle_strats( whichset )
{
	var i;
	switch( whichset ) {
	case 2 :
		for(i=7;i<=12;i++)
			document.getElementById("CB" + jig_list[i]).checked = !document.getElementById("CB" + jig_list[i]).checked;
		break;
	case 3 :
		for(i=13;i<=22;i++)
			document.getElementById("CB" + jig_list[i]).checked = !document.getElementById("CB" + jig_list[i]).checked;
		break;
	case 4 :
		for(i=23;i<=24;i++)
			document.getElementById("CB" + jig_list[i]).checked = !document.getElementById("CB" + jig_list[i]).checked;
		break;
	case 5 :
		document.getElementById("CBUR").checked = !document.getElementById("CBUR").checked;
//		document.getElementById("CBHUR").checked = !document.getElementById("CBHUR").checked;
		document.getElementById("CBBUG").checked = !document.getElementById("CBBUG").checked;
	}

}
