1<!DOCTYPE HTML>
2<html>
3
4<!--
5  pgn4web javascript chessboard
6  copyright (C) 2009-2015 Paolo Casaschi
7  see README file and http://pgn4web.casaschi.net
8  for credits, license and more details
9-->
10
11<head>
12
13<title>pgn4web chessboard</title>
14
15<!-- use the base tag to host board.html on a different server than pgn4web.js
16
17<base href="http://pgn4web.casaschi.net">
18
19-->
20
21<style type="text/css">
22
23@import url("fonts/pgn4web-font-ChessSansPiratf.css");
24@import url("fonts/pgn4web-font-LiberationSans.css");
25
26html,
27body {
28  margin: 0px;
29  padding: 0px;
30}
31
32body {
33  font-family: sans-serif;
34  color: black;
35}
36
37.boardTable {
38  border-style: double;
39  border-color: black;
40  border-width: 3px;
41}
42
43.pieceImage,
44.whiteSquare,
45.blackSquare,
46.highlightWhiteSquare,
47.highlightBlackSquare {
48}
49
50.selectControl,
51.buttonControlPlay,
52.buttonControlStop,
53.buttonControl,
54.buttonControlSpace {
55/* a "width" attribute here must use the !important flag to override default settings */
56}
57
58.optionSelectControl {
59}
60
61.header {
62  color: black;
63  font-weight: bold;
64  line-height: 1.4em;
65}
66
67.headerLive, .headerVariations {
68  font-weight: normal;
69  overflow: hidden;
70}
71
72.move,
73.variation {
74  line-height: 1.4em;
75  text-decoration: none;
76}
77
78a.move,
79a.variation,
80.commentMove {
81  white-space: nowrap;
82}
83
84.move {
85  color: black;
86}
87
88.comment,
89.variation {
90  color: gray;
91  line-height: 1.4em;
92}
93
94.moveOn,
95.variationOn {
96  background: #DAF4D7;
97}
98
99</style>
100
101<!--[if lt IE 9]>
102<style type="text/css">
103.move, .moveOn { position: relative; /* bugfix: IE offsetTop issue */ }
104</style>
105<![endif]-->
106
107<link rel="icon" sizes="16x16" href="pawn.ico" />
108
109<script type="text/javascript">
110"use strict";
111
112// reads the URL search string and sets parameters
113
114function gup(name) {
115
116  name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
117  var regexS = "[\\?&]"+name+"=([^&#]*)";
118  regexS = regexS+"(?!.*"+regexS+")"; // matches the LAST occurrence
119  var regex = new RegExp( regexS, "i" );
120  var results = regex.exec( window.location.href );
121  if (results !== null) { return decodeURIComponent(results[1]); }
122
123  // allows for short version of the URL parameters, for instance sC matches squareColor
124  var compact_name = name.charAt(0);
125  for (var i=1; i<name.length; i++) {
126    if (name.charAt(i).match(/[A-Z]/)) { compact_name = compact_name + name.charAt(i).toLowerCase(); }
127  }
128  name = compact_name;
129
130  name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
131  regexS = "[\\?&]"+name+"=([^&#]*)";
132  regexS = regexS+"(?!.*"+regexS+")"; // matches the LAST occurrence
133  regex = new RegExp( regexS, "i" );
134
135  results = regex.exec( window.location.href );
136  if (results !== null) { return decodeURIComponent(results[1]); }
137
138  return "";
139}
140
141var oldMovesDisplay = "";
142var showMoves = gup("showMoves");
143if ((showMoves == "true")  || (showMoves == "t")) { oldMovesDisplay = "justified"; }
144if ((showMoves == "false") || (showMoves == "f")) { oldMovesDisplay = "hidden"; }
145var movesDisplay = gup("movesDisplay");
146if (movesDisplay === "") {
147  movesDisplay = oldMovesDisplay === "" ? "hidden" : oldMovesDisplay;
148}
149if (movesDisplay == "f") { movesDisplay = "figurine"; }
150if (movesDisplay == "t") { movesDisplay = "text"; }
151if (movesDisplay == "h") { movesDisplay = "hidden"; }
152if (movesDisplay == "n") { movesDisplay = "nosymbols"; } // "nosymbols" option is undocumented
153if (movesDisplay == "p") { movesDisplay = "puzzle"; }
154if ((movesDisplay == "justified") || (movesDisplay == "j")) { movesDisplay = "figurine"; } // backward compatibility
155if ((movesDisplay != "figurine") && (movesDisplay != "nosymbols") && (movesDisplay != "puzzle") && (movesDisplay != "text") && (movesDisplay != "hidden")) { movesDisplay = "figurine"; }
156
157var blockChessInformantNAGSymbols = ((movesDisplay != "figurine") && ((movesDisplay != "puzzle")));
158
159</script>
160
161<script src="pgn4web.js" type="text/javascript"></script>
162<script src="fonts/chess-informant-NAG-symbols.js" type="text/javascript"></script>
163<script id="engineScript" type="text/javascript"></script>
164
165<script src="pgn-decoder.js" type="text/javascript"></script>
166
167<script src="fide-lookup.js" type="text/javascript"></script>
168
169
170<!-- DeploymentCheck: google analytics code -->
171
172<!-- end DeploymentCheck -->
173
174
175</head>
176
177<body onResize="autoScrollToCurrentMoveIfEnabled();">
178
179<!-- paste your PGN below and make sure you dont specify an external source with SetPgnUrl() -->
180<form style="display: none;"><textarea style="display: none;" id="pgnText">
181
182</textarea></form>
183<!-- paste your PGN above and make sure you dont specify an external source with SetPgnUrl() -->
184
185<script type="text/javascript">
186"use strict";
187
188
189<!-- DeploymentCheck: enableEngine_default -->
190var enableEngine_default = "false";
191<!-- end DeploymentCheck -->
192
193
194// undocumented option
195var enableEngine = gup("enableEngine") || enableEngine_default;
196if ((enableEngine == "true")  || (enableEngine == "t")) {
197  var engineScriptObject = document.getElementById("engineScript");
198  if (engineScriptObject) { engineScriptObject.src = "engine.js"; }
199}
200
201function percentFixFromUrl(text) {
202  text += ''; // makes sure text is a string
203  return text.replace(/pct$/,'%').replace(/p$/,'%'); // 100pct and 100p both mean 100%
204}
205
206var sexEncodingCharSet = "$0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_";
207function sex2hex(sex) {
208  if (sex === "") { return ""; }
209  sex += "";
210  var dec = 0;
211  for (var cnt=0; cnt<sex.length; cnt++) {
212    dec <<= 6;
213    dec += sexEncodingCharSet.indexOf(sex.charAt(cnt));
214  }
215  var hex = dec.toString(16).toUpperCase() + "";
216  while (hex.length < 6) { hex = "0" + hex; }
217  return hex;
218}
219
220var pieceSizeOptions = new Array(20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 52, 56, 60, 64, 72, 80, 88, 96, 112, 128, 144, 300);
221function defaultPieceSize(squareSize) {
222  var targetPieceSize = Math.floor(0.8 * squareSize);
223  for (var ii=(pieceSizeOptions.length-1); ii>=0; ii--) {
224    if (pieceSizeOptions[ii] <= targetPieceSize) { return pieceSizeOptions[ii]; }
225  }
226  return pieceSizeOptions[0];
227}
228
229SetHighlightOption(true);
230SetShortcutKeysEnabled(true);
231
232var squareSize = gup("squareSize");
233if (squareSize === "") { squareSize = 28; }
234else { squareSize = parseInt(squareSize, 10); }
235if (squareSize < 20) { squareSize = 20; }
236
237var highlightMode = gup("highlightMode");
238if (highlightMode === "") { highlightMode = "square"; }
239if (highlightMode == "b") { highlightMode = "border"; }
240if (highlightMode == "n") { highlightMode = "none"; }
241if (highlightMode == "s") { highlightMode = "square"; }
242var borderSize = highlightMode == "border" ? Math.floor(0.05 * squareSize) : 0;
243
244var lightColor = gup("lightColorName");
245if (lightColor === "") {
246  if ((lightColor = "#" + gup("lightColorHex")) == "#") {
247    if ((lightColor = "#" + sex2hex(gup("lightColorSex"))) == "#") { lightColor = "#EFF4EC"; }
248  }
249}
250var darkColor = gup("darkColorName");
251if (darkColor === "") {
252  if ((darkColor = "#" + gup("darkColorHex")) == "#") {
253    if ((darkColor = "#" + sex2hex(gup("darkColorSex"))) == "#") { darkColor = "#C6CEC3"; }
254  }
255}
256var highlightColor = gup("highlightColorName");
257if (highlightColor === "") {
258  if ((highlightColor = "#" + gup("highlightColorHex")) == "#") {
259    if ((highlightColor = "#" + sex2hex(gup("highlightColorSex"))) == "#") { highlightColor = "#DAF4D7"; }
260  }
261}
262var highlightLightColor = highlightColor;
263var highlightDarkColor = highlightColor;
264if ((highlightMode == 'none') || (highlightColor == 'none') || (highlightColor == '#none')) {
265  highlightMode = 'none';
266  borderSize = 0;
267  highlightLightColor = lightColor;
268  highlightDarkColor = darkColor;
269  clearShortcutSquares("D", "7");
270}
271
272var pieceSize = gup("pieceSize");
273if ((pieceSize === "") || (pieceSize == "default") || (pieceSize == "d")) { pieceSize = defaultPieceSize(squareSize); }
274else { pieceSize = parseInt(pieceSize, 10); }
275if (pieceSize > (squareSize - 2 * borderSize)) { pieceSize = defaultPieceSize(squareSize - 2 * borderSize); }
276
277var pieceFont = gup("pieceFont");
278if (pieceFont === "") {
279  if ((pieceFont = gup("font")) === "") // left for compatibility with older version
280    { pieceFont = "default"; }
281}
282if (pieceFont == "a") { pieceFont = "alpha"; }
283if (pieceFont == "m") { pieceFont = "merida"; }
284if (pieceFont == "u") { pieceFont = "uscf"; }
285if (pieceFont == "i") { pieceFont = "igorsvg"; } // undocumented option
286if (pieceFont == "s") { pieceFont = "svgchess"; } // undocumented option
287if (pieceFont == "t") { pieceFont = "tilesvg"; } // undocumented option
288if ((pieceFont == "random") || (pieceFont == "r")) {
289  pieceFont = ["alpha", "merida", "uscf"][Math.floor(3 * Math.random())];
290}
291if ((pieceFont == "default") || (pieceFont == "d")) {
292  if (pieceSize < 28) { pieceFont = "uscf"; }
293  else {
294    if (pieceSize > 39) { pieceFont = "merida"; }
295    else { pieceFont = "alpha"; }
296  }
297}
298
299// undocumented option
300var pieceFontRoot = gup("pieceFontRoot");
301if (pieceFontRoot !== "") {
302  if (pieceFontRoot.charAt(pieceFontRoot.length - 1) != "/") { pieceFontRoot += "/"; }
303}
304
305SetImagePath("" + pieceFontRoot + "images/" + pieceFont + "/" + pieceSize);
306if ((pieceFont == "igorsvg") || (pieceFont == "svgchess") || (pieceFont == "tilesvg")) {
307  SetImagePath("" + pieceFontRoot + "images/" + pieceFont);
308  SetImageType("svg");
309}
310
311var boardBorderColor = gup("boardBorderColorName");
312if (boardBorderColor === "") {
313  if ((boardBorderColor = "#" + gup("boardBorderColorHex")) == "#") {
314    if ((boardBorderColor = "#" + sex2hex(gup("boardBorderColorSex"))) == "#") { boardBorderColor = "#000000"; }
315  }
316}
317
318var boardShadowColor = gup("boardShadowColorName");
319if (boardShadowColor === "") {
320  if ((boardShadowColor = "#" + gup("boardShadowColorHex")) == "#") {
321    var boardShadowColorSex = gup("boardShadowColorSex");
322    if ((boardShadowColorSex == "transparent") || (boardShadowColorSex == "t")) {
323      boardShadowColor = "transparent";
324    } else if ((boardShadowColorSex == "border") || (boardShadowColorSex == "b")) {
325      boardShadowColor = "border";
326    } else {
327      if ((boardShadowColor = "#" + sex2hex(gup("boardShadowColorSex"))) == "#") { boardShadowColor = "transparent"; }
328    }
329  }
330}
331if ((boardShadowColor ==  "border") || (boardShadowColor ==  "b") ||
332    (boardShadowColor == "#border") || (boardShadowColor == "#b")) {
333  boardShadowColor = boardBorderColor;
334}
335if ((boardShadowColor ==  "transparent") || (boardShadowColor ==  "t") ||
336    (boardShadowColor == "#transparent") || (boardShadowColor == "#t")) {
337  boardShadowColor = "transparent";
338}
339
340var backgroundColor = gup("backgroundColorName");
341if (backgroundColor === "") {
342  if ((backgroundColor = "#" + gup("backgroundColorHex")) == "#") {
343    var backgroundColorSex = gup("backgroundColorSex");
344    if ((backgroundColorSex == "transparent") || (backgroundColorSex == "t")) {
345      backgroundColor = "transparent";
346    } else {
347      if ((backgroundColor = "#" + sex2hex(gup("backgroundColorSex"))) == "#") { backgroundColor = "#FFFFFF"; }
348    }
349  }
350}
351if ((backgroundColor ==  "transparent") || (backgroundColor ==  "t") ||
352    (backgroundColor == "#transparent") || (backgroundColor == "#t")) {
353  backgroundColor = "transparent";
354}
355
356var highlightMoveColor = gup("highlightMoveColorName");
357if (highlightMoveColor === "") {
358  if ((highlightMoveColor = "#" + gup("highlightMoveColorHex")) == "#") {
359    var highlightMoveColorSex = gup("highlightMoveColorSex");
360    if ((highlightMoveColorSex == "background") || (highlightMoveColorSex == "b")) {
361      highlightMoveColor = "background";
362    } else {
363      if ((highlightMoveColor = "#" + sex2hex(highlightMoveColorSex)) == "#") { highlightMoveColor = "#DAF4D7"; }
364    }
365  }
366}
367if ((highlightMoveColor ==  "background") || (highlightMoveColor ==  "b") ||
368    (highlightMoveColor == "#background") || (highlightMoveColor == "#b")) {
369  highlightMoveColor = backgroundColor;
370}
371
372var framePadding = gup("framePadding");
373if (framePadding === "") { framePadding = 0;}
374else { framePadding = parseInt(framePadding, 10); }
375
376var fontHeaderSize = percentFixFromUrl(gup("fontHeaderSize"));
377if (fontHeaderSize === "") { fontHeaderSize = "16"; }
378var fontHeaderColor = gup("fontHeaderColorName");
379if (fontHeaderColor === "") {
380  if ((fontHeaderColor = "#" + gup("fontHeaderColorHex")) == "#") {
381    if ((fontHeaderColor = "#" + sex2hex(gup("fontHeaderColorSex"))) == "#") { fontHeaderColor = "#000000"; }
382  }
383}
384
385var fontMovesSize = percentFixFromUrl(gup("fontMovesSize"));
386if (fontMovesSize === "") { fontMovesSize = "16"; }
387var fontMovesColor = gup("fontMovesColorName");
388if (fontMovesColor === "") {
389  if ((fontMovesColor = "#" + gup("fontMovesColorHex")) == "#") {
390    if ((fontMovesColor = "#" + sex2hex(gup("fontMovesColorSex"))) == "#") { fontMovesColor = "#000000";}
391  }
392}
393
394var fontCommentsSize = percentFixFromUrl(gup("fontCommentsSize"));
395if (fontCommentsSize === "") { fontCommentsSize = "moves"; }
396if (fontCommentsSize == "m") { fontCommentsSize = "moves"; }
397var fontCommentsColor = gup("fontCommentsColorName");
398if (fontCommentsColor === "") {
399  if ((fontCommentsColor = "#" + gup("fontCommentsColorHex")) == "#") {
400    if ((fontCommentsColor = "#" + sex2hex(gup("fontCommentsColorSex"))) == "#") { fontCommentsColor = "#808080"; }
401  }
402}
403
404var fontVariationsSize = percentFixFromUrl(gup("fontVariationsSize"));
405if (fontVariationsSize === "") { fontVariationsSize = "comments"; }
406if (fontVariationsSize == "c") { fontVariationsSize = "comments"; }
407var fontVariationsColor = gup("fontVariationsColorName");
408if (fontVariationsColor === "") {
409  if ((fontVariationsColor = "#" + gup("fontVariationsColorHex")) == "#") {
410    if ((fontVariationsColor = "#" + sex2hex(gup("fontVariationsColorSex"))) == "#") { fontVariationsColor = "comments"; }
411  }
412}
413
414var oldAutoplayMode = "";
415var auto = gup("auto");
416if ((auto == "false") || (auto == "f")) { oldAutoplayMode = "none"; }
417var loop = gup("loop");
418if ((loop == "true") || (loop == "t")) { oldAutoplayMode = "loop"; }
419var autoplayMode = gup("autoplayMode");
420if (autoplayMode === "") {
421  autoplayMode = oldAutoplayMode === "" ? "game" : oldAutoplayMode;
422}
423if (autoplayMode == "g") { autoplayMode = "game"; }
424if (autoplayMode == "l") { autoplayMode = "loop"; }
425if (autoplayMode == "n") { autoplayMode = "none"; }
426
427switch (autoplayMode) {
428  case "loop":
429    SetAutostartAutoplay(true);
430    SetAutoplayNextGame(true);
431    break;
432  case "none":
433    SetAutostartAutoplay(false);
434    SetAutoplayNextGame(false);
435    break;
436  case "game":
437  default:
438    SetAutostartAutoplay(true);
439    SetAutoplayNextGame(false);
440    break;
441}
442
443if (gup("delay") === "") { SetAutoplayDelay(1000); }
444else { SetAutoplayDelay(gup("delay")); }
445
446// use init_Game to avoid overlap with existing global var initialGame in pgn4web.js
447var init_Game = gup("initialGame");
448if (init_Game === "") {
449  init_Game = "first";
450} else {
451  if (init_Game == "f") { init_Game = "first"; }
452  if (init_Game == "l") { init_Game = "last"; }
453  if (init_Game == "r") { init_Game = "random"; }
454}
455SetInitialGame(init_Game);
456
457// use init_Variation to avoid overlap with existing global var initialVariation in pgn4web.js
458var init_Variation = gup("initialVariation");
459if (init_Variation !== "") {
460  SetInitialVariation(init_Variation);
461}
462
463// use init_Halfmove to avoid overlap with existing global var initialHalfmove in pgn4web.js
464var always_Halfmove = false;
465var init_Halfmove = gup("initialHalfmove");
466if (init_Halfmove === "") {
467  init_Halfmove = "start";
468} else {
469  if (init_Halfmove == "s") { init_Halfmove = "start"; }
470  if (init_Halfmove == "e") { init_Halfmove = "end"; }
471  if (init_Halfmove == "r") { init_Halfmove = "random"; }
472  if (init_Halfmove == "c") { init_Halfmove = "comment"; }
473  if (init_Halfmove == "v") { init_Halfmove = "variation"; }
474  if ((init_Halfmove == "start")  || (init_Halfmove == "end") ||
475      (init_Halfmove == "random") || (init_Halfmove == "comment") ||
476      (init_Halfmove == "variation")) {
477     always_Halfmove = true;
478  }
479}
480SetInitialHalfmove(init_Halfmove,always_Halfmove);
481
482var oldButtonsDisplay = "";
483var showButtons = gup("showButtons");
484if ((showButtons == "true")  || (showButtons == "t")) { oldButtonsDisplay = "custom"; }
485if ((showButtons == "false") || (showButtons == "f")) { oldButtonsDisplay = "hidden"; }
486var buttonsDisplay = gup("buttonsDisplay");
487if (buttonsDisplay === "") {
488  buttonsDisplay = oldButtonsDisplay === "" ? "hidden" : oldButtonsDisplay;
489}
490if (buttonsDisplay == "c") { buttonsDisplay = "custom"; }
491if (buttonsDisplay == "h") { buttonsDisplay = "hidden"; }
492if (buttonsDisplay == "s") { buttonsDisplay = "standard"; }
493if ((buttonsDisplay != "custom") && (buttonsDisplay != "standard")) { buttonsDisplay = "hidden"; }
494
495// SetGameSelectorOptions(head, num, chEvent, chSite, chRound, chWhite, chBlack, chResult, chDate);
496SetGameSelectorOptions(null, false, 0, 0, 0, 15, 15, 3, 10);
497
498var controlBackgroundColor = "default";
499var controlTextColor = "#000000";
500if (buttonsDisplay == "custom") {
501
502  if ((controlBackgroundColor = gup("controlBackgroundColorName")) === "") {
503    if ((controlBackgroundColor = "#" + gup("controlBackgroundColorHex")) == "#") {
504      var controlBackgroundColorSex = gup("controlBackgroundColorSex");
505      if (controlBackgroundColorSex == "default") {
506          controlBackgroundColor = "#default";
507      } else if (controlBackgroundColorSex == "d") {
508            controlBackgroundColor = "#d";
509      } else {
510        if ((controlBackgroundColor = "#" + sex2hex(controlBackgroundColorSex)) == "#") {
511          controlBackgroundColor = "#default";
512        }
513      }
514    }
515  }
516
517  if ((controlBackgroundColor == "d") || (controlBackgroundColor == "#d")) { controlBackgroundColor = "default"; }
518  if (controlBackgroundColor == "#default") { controlBackgroundColor = "default"; }
519
520  if (controlBackgroundColor == "default") { buttonsDisplay = "standard"; }
521
522  if ((controlTextColor = gup("controlTextColorName")) === "") {
523    if ((controlTextColor = "#" + gup("controlTextColorHex")) == "#") {
524      if ((controlTextColor = "#" + sex2hex(gup("controlTextColorSex"))) == "#") { controlTextColor = "#000000"; }
525    }
526  }
527
528}
529
530var oldCommentsDisplay = "";
531var showCommentsOnSeparateLines = gup("showCommentsOnSeparateLines");
532if ((showCommentsOnSeparateLines == "true") || (showCommentsOnSeparateLines == "t")) { oldCommentsDisplay = "newline"; }
533var showComments = gup("showComments");
534if ((showComments == "false") || (showComments == "f")) { oldCommentsDisplay = "hidden"; }
535var commentsDisplay = gup("commentsDisplay");
536if (commentsDisplay === "") {
537  commentsDisplay = oldCommentsDisplay === "" ? "inline" : oldCommentsDisplay;
538}
539if (commentsDisplay == "h") { commentsDisplay = "hidden"; }
540if (commentsDisplay == "i") { commentsDisplay = "inline"; }
541if (commentsDisplay == "n") { commentsDisplay = "newline"; }
542
543switch (commentsDisplay) {
544  case "hidden":
545    SetCommentsIntoMoveText(false);
546    SetCommentsOnSeparateLines(false);
547    break;
548  case "newline":
549    SetCommentsIntoMoveText(true);
550    SetCommentsOnSeparateLines(true);
551    break;
552  case "inline":
553  default:
554    SetCommentsIntoMoveText(true);
555    SetCommentsOnSeparateLines(false);
556    break;
557}
558
559function cleanPgnInput(pgnInput) {
560  pgnInput += "";
561
562  pgnInput = pgnInput.replace(/\[/g,"\n\n[");
563  pgnInput = pgnInput.replace(/\]/g,"]\n\n");
564  pgnInput = pgnInput.replace(/([012\*])(\s*)(\[)/g,"$1\n\n$3");
565  pgnInput = pgnInput.replace(/\]\s*\[/g,"]\n[");
566  pgnInput = pgnInput.replace(/^\s*\[/g,"[");
567  pgnInput = pgnInput.replace(/\n[\s*\n]+/g,'\n\n');
568
569  return pgnInput;
570}
571
572var newPgnId = gup("pgnId");
573var newPgnIdData;
574if (newPgnId !== "") {
575  try {
576    if (parent && (parent !== window) && parent.document.getElementById(newPgnId)) {
577      var theParentObject = parent.document.getElementById(newPgnId);
578      if (theParentObject.tagName.toLowerCase() == "textarea") {
579        newPgnIdData = theParentObject.value;
580      } else { // backward compatibility with pgn4web older than 1.77 when the <span> technique was used for pgnText
581        newPgnIdData = theParentObject.innerHTML;
582        // fixes issue with some browser removing \n from innerHTML
583        if (newPgnIdData.indexOf('\n') < 0) { newPgnIdData = newPgnIdData.replace(/((\[[^\[\]]*\]\s*)+)/g, "\n$1\n"); }
584        // fixes issue with some browser replacing quotes with &quot;
585        if (newPgnIdData.indexOf('"') < 0) { newPgnIdData = newPgnIdData.replace(/(&quot;)/g, '"'); }
586      }
587      document.getElementById('pgnText').value = newPgnIdData = cleanPgnInput(newPgnIdData);
588    } else {
589      myAlert("error: data not found for pgnId=" + newPgnId, true);
590    }
591  } catch(e) {
592    myAlert("error: data error for pgnId=" + newPgnId, true);
593  }
594}
595
596var fenString = gup("fenString");
597if (fenString !== "") {
598  document.getElementById('pgnText').value = '[FEN "' + fenString + '"]';
599}
600
601var newPgnText = gup("pgnText");
602if (newPgnText !== "") {
603  document.getElementById('pgnText').value = newPgnText = cleanPgnInput(newPgnText);
604}
605
606var newPgnEncoded = gup("pgnEncoded");
607var newPgnDecoded;
608if (newPgnEncoded !== "") {
609  newPgnDecoded = DecodePGN(newPgnEncoded);
610  document.getElementById('pgnText').value = newPgnDecoded = cleanPgnInput(newPgnDecoded);
611}
612
613var pgnData = gup("pgnData");
614if (pgnData !== "") {
615  SetPgnUrl(pgnData);
616  document.getElementById('pgnText').value = "";
617}
618
619if ((pgnData !== "") && ((newPgnEncoded !== "") || (newPgnText !== "") ||
620  (fenString !== "") || (newPgnId !==""))) {
621  myAlert("warning: pgnData value superseeds pgnEncoded, pgnText, pgnId and/or fenString values.", false);
622}
623
624if ((newPgnEncoded !== "") && ((newPgnText !== "") || (fenString !== "") || (newPgnId !==""))) {
625  myAlert("warning: pgnEncoded value superseeds pgnText, pgnId and/or fenString values.", false);
626}
627
628if ((newPgnText !== "") && ((fenString !== "") || (newPgnId !==""))) {
629  myAlert("warning: pgnText value superseeds pgnId and/or fenString value.", false);
630}
631
632if ((fenString !== "") && (newPgnId !=="")) {
633  myAlert("warning: fenString value superseeds pgnId value.", false);
634}
635
636var oldHeaderDisplay = "";
637var showHeader = gup("showHeader");
638if ((showHeader == "true")  || (showHeader == "t")) { oldHeaderDisplay = "justified"; }
639if ((showHeader == "false") || (showHeader == "f")) { oldHeaderDisplay = "hidden"; }
640var headerDisplay = gup("headerDisplay");
641if (headerDisplay === "") {
642  headerDisplay = oldHeaderDisplay === "" ? "hidden" : oldHeaderDisplay;
643}
644if (headerDisplay == "c") { headerDisplay = "centered"; }
645if (headerDisplay == "h") { headerDisplay = "hidden"; }
646if (headerDisplay == "j") { headerDisplay = "justified"; }
647if (headerDisplay == "l") { headerDisplay = "live"; }
648if (headerDisplay == "v") { headerDisplay = "variations"; }
649if ((headerDisplay != "centered") && (headerDisplay != "live") && (headerDisplay != "variations") && (headerDisplay != "hidden")) { headerDisplay = "justified"; }
650
651// movesDisplay is set at the beginning of the script
652
653var textHeight = percentFixFromUrl(gup("textHeight"));
654if (textHeight === "") { textHeight = "100%"; }
655if (!textHeight.match(/[^0-9]/)) { textHeight += "px"; }
656
657var textWidth = percentFixFromUrl(gup("textWidth"));
658if (textWidth === "") { textWidth = "100%"; }
659if (!textWidth.match(/[^0-9]/)) { textWidth += "px"; }
660
661var textMargin = gup("textMargin");
662if (textMargin === "") { textMargin = 0; }
663else { textMargin = parseInt(textMargin, 10); }
664
665var frameHeight = gup("frameHeight");
666var fixFrameHeightToBoard = false;
667switch (frameHeight) {
668  case "b":
669  case "board":
670    frameHeight = "";
671    fixFrameHeightToBoard = true;
672    break;
673  case "p":
674  case "page":
675    if (window.innerHeight) { frameHeight = window.innerHeight; }
676    else if (document.documentElement && document.documentElement.clientHeight) { frameHeight = document.documentElement.clientHeight; }
677    else if (document.body && document.body.clientHeight) { frameHeight = document.body.clientHeight; }
678    else { frameHeight = ""; }
679    break;
680  case "":
681    break;
682  default:
683    frameHeight = parseInt(frameHeight, 10);
684    if (isNaN(frameHeight)) { frameHeight = ""; }
685    break;
686}
687
688var frameWidth = gup("frameWidth");
689var fixFrameWidthToBoard = false;
690switch (frameWidth) {
691  case "b":
692  case "board":
693    frameWidth = "";
694    fixFrameWidthToBoard = true;
695    break;
696  case "p":
697  case "page":
698    frameWidth = "";
699    textWidth = "100%";
700    break;
701  case "":
702    break;
703  default:
704    frameWidth = parseInt(frameWidth, 10);
705    if (isNaN(frameWidth)) { frameWidth = ""; }
706    break;
707}
708
709var horizontalLayout = false;
710if ((gup("horizontalLayout") == "true") || (gup("horizontalLayout") == "t")) { horizontalLayout = true; }
711
712var demoFlag = false;
713var alertFlag = false;
714if ((gup("refreshDemo") == "true") || (gup("refreshDemo") == "t")) { demoFlag = true; alertFlag = true; }
715
716var refreshMinutes = 0;
717if ((refreshMinutes = gup("refreshMinutes")) !== "") {
718  var testMinutes = refreshMinutes + "";
719  if ((testMinutes.match(/[^0-9\.]/)) || (refreshMinutes === 0)) {
720    myAlert("error: refreshMinutes parameter must be a positive number.\n" +
721      "Supplied " + testMinutes + "; live refresh disabled.", true);
722    refreshMinutes = 0;
723  }
724}
725
726if (refreshMinutes > 0) {
727  if (pgnData !== "") { SetLiveBroadcast(refreshMinutes, alertFlag, demoFlag, true); }
728  else {
729    myAlert("error: live broadcast requires using pgnData parameter as PGN source.", true);
730  }
731  if (gup("initialHalfmove") === "") {
732    SetInitialHalfmove(init_Halfmove = "end", always_Halfmove = true);
733  }
734  if (gup("autoplayMode") === "") {
735    autoplayMode = "none";
736    SetAutostartAutoplay(false);
737    SetAutoplayNextGame(false);
738  }
739}
740
741
742if ((gup("help") == "true") || (gup("help") == "t")) {
743  document.write("<PRE>");
744  document.write("URL parameters\n");
745  document.write("\n");
746  document.write(" - pgnText = PGN games to display\n");
747  document.write(" - pgnEncoded = encoded PGN games to display (used only by the board generator tool)\n");
748  document.write(" - fenString = FEN position to display\n");
749  document.write(" - pgnId = id of the parent's textarea containing the PGN games (parent page/frame MUST be in the same domain)\n");
750  document.write(" - pgnData = URL of the file containing the PGN games (file MUST be in the same domain)\n");
751  document.write("\n");
752  document.write(" - refreshMinutes = live broadcast delay (default 0 = live broadcast disabled)\n");
753  document.write(" - refreshDemo = if set true sets live demo mode (default false)\n");
754  document.write("\n");
755  document.write(" - initialGame = first | last | random | a number | a search expression (default first)\n");
756  document.write(" - initialVariation = a number (default 0)\n");
757  document.write(" - initialHalfmove = start | end | random | comment | variation | a number (default start)\n");
758  document.write("\n");
759  document.write(" - autoplayMode = game (autoplay first game once) | loop (loops through games continuously) | none (default game)\n");
760  document.write(" - delay = autoplay delay in ms (default 1000)\n");
761  document.write("\n");
762  document.write(" - squareSize = size of square (default 28)\n");
763  document.write(" - pieceSize = size of pieces | default (default selects piece size based on square size)\n");
764  document.write(" - pieceFont = alpha | merida | uscf | random | default (default selects piece font based on piece size)\n");
765  document.write(" - highlightMode = border | square | none (default square)\n");
766  document.write(" - lightColorHex = light square color hex code, like FF0000 (default EFF4EC)\n");
767  document.write(" - darkColorHex = dark square color hex code, like FF0000 (default C6CEC3)\n");
768  document.write(" - highlightColorHex = highlight color hex code, like FF0000 (default DAF4D7)\n");
769  document.write(" - boardBorderColorHex = board border color hex code, like FF0000 (default 000000)\n");
770  document.write(" - boardShadowColorHex = board shadow color hex code, like FF0000, 'transparent' for no shadow, 'border' for same color as board border (default transparent)\n");
771  document.write("\n");
772  document.write(" - buttonsDisplay = hidden | standard (use browser's standard buttons) | custom (use custom color buttons) (default hidden)\n");
773  document.write(" - controlBackgroundColorHex = control buttons background color hex code, like FF0000 (default reverts to standard buttons)\n");
774  document.write(" - controlTextColorHex = control buttons text color hex code, like FF0000 (default 000000)\n");
775  document.write("\n");
776  document.write(" - headerDisplay = justified | centered | hidden | live | variations (default hidden)\n");
777  document.write(" - movesDisplay = figurine | text | puzzle | hidden (default hidden)\n");
778  document.write(" - textHeight = set height of the textual section, header and/or moves text, might be ignored if frameHeight is set (default 100%)\n");
779  document.write(" - textWidth = set width of the textual section, header and/or moves text, might be ignored if frameWidth is set (default 100%)\n");
780  document.write(" - textMargin = set left/right margin width of the textual section, header and/or moves text (default 0)\n");
781  document.write(" - commentsDisplay = hidden | inline (same line as moves) | newline (new lines) (default inline)\n");
782  document.write(" - fontHeaderColorHex = header color hex code, like FF0000 (default 000000)\n");
783  document.write(" - fontMovesColorHex = moves color hex code, like FF0000 (default 000000)\n");
784  document.write(" - fontCommentsColorHex = comments color hex code, like FF0000 (default 808080)\n");
785  document.write(" - fontVariationsColorHex = variations color hex code, like FF0000; if set as 'comments' fontCommentsColorHex is copied (default comments)\n");
786  document.write(" - highlightMoveColorHex = background color hex code to highlight current move, like FF0000, 'background' for no highlight (default DAF4D7)\n");
787  document.write(" - fontHeaderSize = header font size (default 16)\n");
788  document.write(" - fontMovesSize = moves font size (default 16)\n");
789  document.write(" - fontCommentsSize = comments font size; if set as 'moves' fontMovesSize is copied (default moves)\n");
790  document.write(" - fontVariationsSize = variations font size; if set as 'comments' fontCommentsSize is copied (default comments)\n");
791  document.write("\n");
792  document.write(" - backgroundColorHex = page background color hex code, like FF0000, 'transparent' to use the parent's background color (default FFFFFF)\n");
793  document.write(" - horizontalLayout = if set true, shows header/moves text at the right of the board, below otherwise (default false)\n");
794  document.write(" - frameHeight = set height of the overall frame, as a number, as 'board' or as 'page', overriding textHeight (default not set)\n");
795  document.write(" - frameWidth = set width of the overall frame, as a number, as 'board' or as 'page', overriding textWidth (default not set)\n");
796  document.write(" - framePadding = padding within the frame (default 0)\n");
797  document.write("\n");
798  document.write(" - showHeightWidth = if set true, calculates optimal iframe dimensions (default false)\n");
799  document.write(" - help = true\n");
800  document.write("\n");
801  document.write("URL parameters can be shortened: for example squareSize => sq, autoplayMode => am, highlightMoveColorHex => hmch\n");
802  document.write("Also supplied textual values can be shortened: true => t, false => f\n");
803  document.write("\n");
804  document.write("Every color parameter can by assigned also by name (like 'red') or using a proprietary encoding in base 64.\n");
805  document.write("For instance, the light square color, besides using the lightColorHex parameter can be also assigned using the lightColorName or the lightColorSex parameter.\n");
806  document.write("The latter is proprietary and used by the board generator tool. \n");
807  document.write("\n");
808  document.write("</PRE>\n<HR>\n");
809}
810
811
812// write updated CSS stylesheet with new values overriding the one at the top of the file
813
814var newStyleSheet = '<style type="text/css"> \n';
815
816if ((movesDisplay == "figurine") || (movesDisplay == "nosymbols") || (movesDisplay == "puzzle")) {
817  newStyleSheet += 'body, .header, .comment { font-family: \'pgn4web Liberation Sans\', sans-serif; } \n';
818  newStyleSheet += '.move, .variation, .commentMove { font-family: \'pgn4web ChessSansPiratf\', \'pgn4web Liberation Sans\', sans-serif; } \n';
819}
820
821newStyleSheet += 'body { background: ' + backgroundColor + '; padding: ' + framePadding + 'px; } \n';
822
823newStyleSheet += '.pieceImage { width: ' + pieceSize + 'px; height: ' + pieceSize + 'px; } \n';
824
825if (highlightMode == 'border') {
826
827  newStyleSheet += '.whiteSquare { ' +
828                   'width: ' + (squareSize - 2 * borderSize) + 'px; ' +
829                   'height: ' + (squareSize - 2 * borderSize) + 'px; ' +
830                   'background: ' + lightColor + '; ' +
831                   'border-style: solid; ' +
832                   'border-width: ' + borderSize + 'px; ' +
833                   'border-color: ' + lightColor + '; ' +
834                   '} \n';
835
836  newStyleSheet += '.blackSquare { ' +
837                   'width: ' + (squareSize - 2 * borderSize) + 'px; ' +
838                   'height: ' + (squareSize - 2 * borderSize) + 'px; ' +
839                   'background: ' + darkColor + '; ' +
840                   'border-style: solid; ' +
841                   'border-width: ' + borderSize + 'px; ' +
842                   'border-color: ' + darkColor + '; ' +
843                   '} \n';
844
845  newStyleSheet += '.highlightWhiteSquare { ' +
846                   'width: ' + (squareSize - 2 * borderSize) + 'px; ' +
847                   'height: ' + (squareSize - 2 * borderSize) + 'px; ' +
848                   'background: ' + lightColor + '; ' +
849                   'border-style: solid; ' +
850                   'border-width: ' + borderSize + 'px; ' +
851                   'border-color: ' + highlightLightColor + '; ' +
852                   '} \n';
853
854  newStyleSheet += '.highlightBlackSquare { ' +
855                   'width: ' + (squareSize - 2 * borderSize) + 'px; ' +
856                   'height: ' + (squareSize - 2 * borderSize) + 'px; ' +
857                   'background: ' + darkColor + '; ' +
858                   'border-style: solid; ' +
859                   'border-width: ' + borderSize + 'px; ' +
860                   'border-color: ' + highlightDarkColor + '; ' +
861                   '} \n';
862
863} else {
864
865  newStyleSheet += '.whiteSquare { ' +
866                   'width: ' + (squareSize - 2 * borderSize) + 'px; ' +
867                   'height: ' + (squareSize - 2 * borderSize) + 'px; ' +
868                   'background: ' + lightColor + '; ' +
869                   '} \n';
870
871  newStyleSheet += '.blackSquare { ' +
872                   'width: ' + (squareSize - 2 * borderSize) + 'px; ' +
873                   'height: ' + (squareSize - 2 * borderSize) + 'px; ' +
874                   'background: ' + darkColor + '; ' +
875                   '} \n';
876
877  newStyleSheet += '.highlightWhiteSquare { ' +
878                   'width: ' + (squareSize - 2 * borderSize) + 'px; ' +
879                   'height: ' + (squareSize - 2 * borderSize) + 'px; ' +
880                   'background: ' + highlightLightColor + '; ' +
881                   '} \n';
882
883  newStyleSheet += '.highlightBlackSquare { ' +
884                   'width: ' + (squareSize - 2 * borderSize) + 'px; ' +
885                   'height: ' + (squareSize - 2 * borderSize) + 'px; ' +
886                   'background: ' + highlightDarkColor + '; ' +
887                   '} \n';
888
889}
890
891var boardHeight = squareSize * 8 + 6;
892var boardWidth = boardHeight;
893
894newStyleSheet += '.boardTable { height: ' + boardHeight + 'px; ' +
895  'width: ' + boardHeight + 'px; border-color: ' + boardBorderColor + '; } \n';
896
897if (boardShadowColor != 'transparent') {
898  newStyleSheet += '.boardTable { ' +
899    'box-shadow: 0px 0px ' + Math.ceil(squareSize / 2) + 'px ' + boardShadowColor + '; ' +
900    '} \n';
901}
902
903if (!fontHeaderSize.match(/[^0-9]/)) {
904  fontHeaderSize += 'px';
905  newStyleSheet += 'body, table { font-size: ' + fontHeaderSize + '; } \n';
906}
907newStyleSheet += '.header { color: ' + fontHeaderColor + '; font-size: ' + fontHeaderSize + '; } \n';
908
909if (!fontMovesSize.match(/[^0-9]/)) { fontMovesSize += 'px'; }
910newStyleSheet += '.move { color: ' + fontMovesColor + '; font-size: ' + fontMovesSize + '; } \n';
911
912if (!fontCommentsSize.match(/[^0-9]/)) { fontCommentsSize += 'px'; }
913newStyleSheet += '.comment, .variation { ' +
914                 ' color: ' + fontCommentsColor + ';' +
915                 ' font-size: ' + (fontCommentsSize == 'moves' ? fontMovesSize : fontCommentsSize) + '; ' +
916                 '} \n';
917
918if (!fontVariationsSize.match(/[^0-9]/)) { fontCommentsSize += 'px'; }
919if (fontVariationsColor !== 'comments') {
920  newStyleSheet += '.variation, a.variation { ' +
921                   ' color: ' + fontVariationsColor + '; ' +
922                   '} \n';
923}
924if (fontVariationsSize !== 'comments') {
925  newStyleSheet += '.variation { ' +
926                   ' font-size: ' + fontVariationsSize + '; ' +
927                   '} \n';
928}
929
930//  newStyleSheet += 'a.move:hover, a.variation:hover { ' +
931//                   ' background: ' + (highlightMoveColor == 'none' ? backgroundColor : highlightMoveColor) + '; ' +
932//                   '} \n';
933
934newStyleSheet += '.moveOn, .variationOn { ' +
935                 ' background: ' + (highlightMoveColor == 'none' ? backgroundColor : highlightMoveColor) + '; ' +
936                 '} \n';
937
938if ((controlBackgroundColor != 'default') && (controlBackgroundColor != '#default')) {
939  var controlFontSize = Math.floor(squareSize / 2.5);
940  newStyleSheet += '.buttonControl, .buttonControlPlay, .buttonControlStop { ' +
941                   '-moz-appearance: none; -webkit-appearance: none; ' +
942                   'border-style: solid; ' +
943                   'border-width: 0px; ' +
944                   'border-radius: 0px; ' +
945                   'border-color: ' + backgroundColor + '; ' +
946                   'background-color: ' + controlBackgroundColor + '; ' +
947                   'color: ' + controlTextColor + '; ' +
948                   'font-size: ' + controlFontSize + 'px; ' +
949                   'text-align: center; ' +
950                   'vertical-align: middle; ' +
951                   ' } \n';
952
953  newStyleSheet += '.selectControl { ' +
954                   '-moz-appearance: none; -webkit-appearance: none; ' +
955                   'padding: 3px; ' +
956                   'border-style: solid; ' +
957                   'border-width: 1px; ' +
958                   'border-radius: 0px; ' +
959                   'border-color: ' + backgroundColor + '; ' +
960                   'background-color: ' + controlBackgroundColor + '; ' +
961                   'color: ' + controlTextColor + '; ' +
962                   'font-size: ' + controlFontSize + 'px; ' +
963                   ' } \n';
964
965  newStyleSheet += '.optionSelectControl { ' +
966                   'background-color: ' + controlBackgroundColor + '; ' +
967                   ' } \n';
968}
969
970newStyleSheet += '</style> \n';
971
972document.write(newStyleSheet);
973
974
975// write actual chessboard components
976
977document.write("<center>");
978document.write("<table id='outerFrame' style='width: 100%;' cellspacing=0 cellpadding=0 border=0>");
979document.write("<tr>");
980document.write("<td id='extendedBoard' align=center valign=top>");
981display_board();
982document.write("</td>");
983if (horizontalLayout === true) {
984  document.write("<td id='headerMovesPadding' width='0px' >");
985  document.write("<td id='extendedHeaderMoves' align=left valign=top>");
986} else {
987  document.write("</tr><tr><td id='extendedHeaderMoves' align=center valign=top>");
988}
989display_header_moves();
990document.write("</td>");
991document.write("</tr>");
992document.write("</table>");
993document.write("</center>");
994
995function display_board() {
996  document.write("<table width=100% cellpadding=0 cellspacing=0 border=0>");
997  document.write("<tr><td align=center valign=top>");
998  if (buttonsDisplay != "hidden") { document.write("<div id='GameSelector'></div>"); }
999  document.write("<div id='GameBoard'></div>");
1000  if (buttonsDisplay != "hidden") { document.write("<div id='GameButtons'></div>"); }
1001  document.write("</td></tr></table>");
1002}
1003
1004function display_header_moves() {
1005
1006  if (((headerDisplay != "hidden") || (movesDisplay != "hidden")) && (horizontalLayout === false)) {
1007    if (headerDisplay != "hidden") {
1008      document.write("<div id='boardHeadermovesPadding' class='header' style='text-align: center;'>&nbsp;</div>");
1009    } else {
1010      document.write("<div id='boardHeadermovesPadding' class='moves' style='text-align: center;'>&nbsp;</div>");
1011    }
1012  }
1013  if ((headerDisplay != "hidden") || (movesDisplay != "hidden")) {
1014    document.write("<div id='headerMoves' style='overflow:auto; overflow-x:hidden;" +
1015                   " height: " + textHeight + "; width: " + textWidth +
1016                   "; scrollbar-base-color: " + backgroundColor + ";'>");
1017  }
1018
1019  if (headerDisplay == "variations") {
1020
1021    document.write("<table width=100% cellpadding=0 cellspacing=0 border=0><tr>");
1022    document.write("<td align=left>");
1023    document.write("<div class='header headerVariations' style='white-space: nowrap; margin-left: "  + textMargin +
1024                   "px; margin-right: 3%;' id=GameWhite></div>");
1025    document.write("</td><td align=right>");
1026    document.write("<div class='header headerVariations' style='white-space: nowrap; margin-right: " + textMargin +
1027                   "px; margin-left: 3%;'>&nbsp;<span class='move'>&nbsp;</span>" +
1028                   "<span id='GameLastMove' title='last move'></span>" +
1029                   "<span id='GameLastVariations' title='last move alternatives'></span></div>");
1030    document.write("</td></tr></table>");
1031
1032    document.write("<table width=100% cellpadding=0 cellspacing=0 border=0><tr>");
1033    document.write("<td align=left>");
1034    document.write("<div class='header headerVariations' style='white-space: nowrap; margin-left: "  + textMargin +
1035                   "px; margin-right: 3%;' id=GameBlack></div>");
1036    document.write("</td><td align=right>");
1037    document.write("<div class='header headerVariations' style='white-space: nowrap; margin-right: " + textMargin +
1038                   "px; margin-left: 3%;'>&nbsp;<span class='move'>&nbsp;</span>" +
1039                   "<span id='GameNextMove' title='next move'></span>" +
1040                   "<span id='GameNextVariations' title='next move alternatives'></span></div>");
1041    document.write("</td></tr></table>");
1042
1043    document.write("<table width=100% cellpadding=0 cellspacing=0 border=0><tr>");
1044    document.write("<td align=left>");
1045    document.write("<div class='header headerVariations' style='white-space: nowrap; margin-left: "  + textMargin +
1046                   "px; margin-right: 3%;' id=GameResult></div>");
1047    document.write("</td><td align=right>");
1048    document.write("<div class='header headerVariations' style='white-space: nowrap; margin-right: " + textMargin +
1049                   "px; margin-left: 3%;'></div>");
1050    document.write("</td></tr></table>");
1051  }
1052
1053  if (headerDisplay == "live") {
1054
1055    document.write("<table width=100% cellpadding=0 cellspacing=0 border=0><tr>");
1056    document.write("<td align=left>");
1057    document.write("<div class='header headerLive' style='white-space: nowrap; margin-left: "  + textMargin +
1058                   "px; margin-right: 3%;' id=GameWhite></div>");
1059    document.write("</td><td align=right>");
1060    document.write("<div class='header headerLive' style='white-space: nowrap; margin-right: " + textMargin +
1061                   "px; margin-left: 3%;'>&nbsp;<span id=GameWhiteClock></span></div>");
1062    document.write("</td></tr></table>");
1063
1064    document.write("<table width=100% cellpadding=0 cellspacing=0 border=0><tr>");
1065    document.write("<td align=left>");
1066    document.write("<div class='header headerLive' style='white-space: nowrap; margin-left: "  + textMargin +
1067                   "px; margin-right: 3%;' id=GameBlack></div>");
1068    document.write("</td><td align=right>");
1069    document.write("<div class='header headerLive' style='white-space: nowrap; margin-right: " + textMargin +
1070                   "px; margin-left: 3%;'>&nbsp;<span id=GameBlackClock></span></div>");
1071    document.write("</td></tr></table>");
1072
1073    document.write("<table width=100% cellpadding=0 cellspacing=0 border=0><tr>");
1074    document.write("<td align=left>");
1075    document.write("<div class='header headerLive' style='white-space: nowrap; margin-left: "  + textMargin +
1076                   "px; margin-right: 3%;'><span id=GameNextMove></span><span class='move'>&nbsp;</span></div>");
1077    document.write("</td><td align=right>");
1078    document.write("<div class='header headerLive' style='white-space: nowrap; margin-right: " + textMargin +
1079                   "px; margin-left: 3%;'>&nbsp;<span id=GameLiveStatus></span></div>");
1080    document.write("</td></tr></table>");
1081  }
1082
1083  if (headerDisplay == "justified") {
1084
1085    document.write("<table width=100% cellpadding=0 cellspacing=0 border=0><tr>");
1086    document.write("<td align=left>");
1087    document.write("<div class='header' style='white-space: nowrap; margin-left: "  + textMargin +
1088                   "px; margin-right: 3%;' id=GameWhite></div>");
1089    document.write("</td><td align=right>");
1090    document.write("<div class='header' style='white-space: nowrap; margin-right: " + textMargin +
1091                   "px; margin-left: 3%;'  id=GameDate></div>");
1092    document.write("</td></tr></table>");
1093
1094    document.write("<table width=100% cellpadding=0 cellspacing=0 border=0><tr>");
1095    document.write("<td align=left>");
1096    document.write("<div class='header' style='white-space: nowrap; margin-left: "  + textMargin +
1097                   "px; margin-right: 3%;' id=GameBlack></div>");
1098    document.write("</td><td align=right>");
1099    document.write("<div class='header' style='white-space: nowrap; margin-right: " + textMargin +
1100                   "px; margin-left: 3%;'  id=GameSite></div>");
1101    document.write("</td></tr></table>");
1102
1103    document.write("<table width=100% cellpadding=0 cellspacing=0 border=0><tr>");
1104    document.write("<td align=left>");
1105    document.write("<div class='header' style='white-space: nowrap; margin-left: "  + textMargin +
1106                   "px; margin-right: 3%;' id=GameResult></div>");
1107    document.write("</td><td align=right>");
1108    document.write("<div class='header' style='white-space: nowrap; margin-right: " + textMargin +
1109                   "px; margin-left: 3%;'><span id=GameEvent></span><span id=roundDetails></span></div>");
1110    document.write("</td></tr></table>");
1111  }
1112
1113  if (headerDisplay == "centered") {
1114
1115    document.write("<table width=100% cellpadding=0 cellspacing=0 border=0><tr>");
1116    document.write("<td align=center>");
1117    document.write("<div id=playersDetails class='header' style='white-space: nowrap; margin-left: "  + textMargin +
1118                   "px; margin-right: " + textMargin + "px;'>");
1119    document.write("<span id=GameWhite></span><span id=whiteBlackSpacer></span><span id=GameBlack></span><span id=blackResultSpacer></span><span id=GameResult></span>");
1120    document.write("</div>");
1121    document.write("</td></tr><tr><td align=center>");
1122    document.write("<div class='header' style='white-space: nowrap; margin-left: "  + textMargin +
1123                   "px; margin-right: " + textMargin + "px;'>");
1124    document.write("<span id=GameEvent></span><span id=roundDetails></span>");
1125    document.write("</div>");
1126    document.write("</td></tr><tr><td align=center>");
1127    document.write("<div class='header' style='white-space: nowrap; margin-left: "  + textMargin +
1128                   "px; margin-right: " + textMargin + "px;'>");
1129    document.write("<span id=GameSite></span><span id=siteDateSpacer></span><span id=GameDate></span>");
1130    document.write("</div>");
1131    document.write("</td></tr></table>");
1132
1133  }
1134
1135  if (movesDisplay != "hidden") {
1136    if (headerDisplay != "hidden") {
1137      document.write("<div id='headerMovesSpacer' class='header' style='text-align: center;'>&nbsp;</div>");
1138    }
1139    if (movesDisplay == "puzzle") {
1140      document.write("<div style='margin-left:" + textMargin + "px; margin-right:" + textMargin +
1141                     "px; text-align: justify;' id=GamePuzzleTask></div>");
1142    }
1143    document.write("<div style='margin-left:" + textMargin + "px; margin-right:" + textMargin +
1144                   "px; text-align: justify;' id=GameText></div>");
1145  }
1146
1147  if ((headerDisplay != "hidden") || (movesDisplay != "hidden")) {
1148    document.write("</div>");
1149  }
1150
1151}
1152
1153function customFunctionOnPgnTextLoad() {
1154  var theObj;
1155
1156  var paddingControlHeight = Math.floor(squareSize / 2.5);
1157  var paddingControlWidth = squareSize - textMargin;
1158  if (paddingControlWidth < 0) { paddingControlWidth = 0; }
1159
1160  if (theObj = document.getElementById("GameButtons"))
1161  { theObj.style.paddingTop = paddingControlHeight + "px"; }
1162
1163  if (theObj = document.getElementById("GameSelector")) {
1164    if ((buttonsDisplay != "hidden") && (numberOfGames > 1)) {
1165      theObj.style.paddingBottom = paddingControlHeight + "px";
1166      theObj.style.display = "block";
1167    } else {
1168      theObj.style.paddingBottom = "0px";
1169      theObj.style.display = "inline";
1170    }
1171  }
1172
1173  if (theObj = document.getElementById("headerMovesPadding")) {
1174    if (horizontalLayout === true) { theObj.width = paddingControlWidth + "px"; }
1175    else { theObj.style.minHeight = paddingControlHeight; }
1176  }
1177
1178  var boardHeight = document.getElementById("boardTable").offsetHeight;
1179  var boardWidth = document.getElementById("boardTable").offsetWidth;
1180
1181  if (theObj = document.getElementById("GameButtons")) {
1182    if (buttonsDisplay != "hidden") { boardHeight += document.getElementById("GameButtons").offsetHeight; }
1183  }
1184
1185  if (theObj = document.getElementById("GameSelector")) {
1186    if ((buttonsDisplay != "hidden") && (numberOfGames > 1)) { boardHeight += document.getElementById("GameSelector").offsetHeight; }
1187  }
1188
1189  if (horizontalLayout === true) {
1190    document.getElementById("extendedBoard").width = boardWidth + "px";
1191  }
1192
1193  if (fixFrameWidthToBoard) { frameWidth = boardWidth + 2 * framePadding; }
1194  if (fixFrameHeightToBoard) { frameHeight = boardHeight + 2 * framePadding; }
1195
1196  if (theObj = document.getElementById("headerMoves")) {
1197    if (horizontalLayout === true) {
1198      if (frameWidth === "") { theObj.style.width = textWidth; }
1199      else { document.getElementById("outerFrame").style.width = frameWidth - 2 * framePadding + "px"; }
1200      theObj.style.height = (frameHeight === "" ? textHeight : (frameHeight - 2 * framePadding) + "px");
1201    } else {
1202      theObj.style.width = (frameWidth === "" ? textWidth : (frameWidth - 2 * framePadding) + "px");
1203      if (frameHeight === "") { theObj.style.height = textHeight; }
1204      else {
1205       var boardHeadermovesPaddingHeight = document.getElementById("boardHeadermovesPadding") ? document.getElementById("boardHeadermovesPadding").offsetHeight : 0;
1206       theObj.style.height = (frameHeight - boardHeight - 2 * framePadding - boardHeadermovesPaddingHeight) + "px";
1207      }
1208    }
1209  }
1210
1211  // cope with occasional failures to load the live PGN data
1212  if ((LiveBroadcastDelay !== 0) && (LiveBroadcastTicker > 0) && (!LiveBroadcastFoundOldGame)) {
1213    var thisCurrentGame = currentGame;
1214    SetInitialGame(init_Game);
1215    setCurrentGameFromInitialGame();
1216    if (currentGame != thisCurrentGame) {
1217      SetInitialHalfmove("end",true);
1218      Init();
1219      GoToInitialHalfmove();
1220    }
1221  }
1222
1223  if (firstCurrentGame == -1) { firstCurrentGame = currentGame; }
1224
1225  if (gup("showHeightWidth") !== "") {
1226    myAlert("info: board width=" + boardWidth + " height=" + boardHeight, false);
1227  }
1228}
1229
1230var firstCurrentGame = -1;
1231var objectHiddenPuzzler = ["GameResult", "GameLastMove", "GameLastVariations", "GameNextMove", "GameNextVariations", "GameLastComment"];
1232
1233function customFunctionOnPgnGameLoad() {
1234  var ii, theObj;
1235
1236  if (movesDisplay == "puzzle") {
1237    if ((currentGame === firstCurrentGame) && (!alwaysInitialHalfmove)) { GoToInitialHalfmove(); }
1238    if (firstCurrentGame == -1) { firstCurrentGame = currentGame; }
1239
1240    for (ii = 0; ii < objectHiddenPuzzler.length; ii++) {
1241      if (theObj = document.getElementById(objectHiddenPuzzler[ii])) {
1242        theObj.style.visibility = "hidden";
1243      }
1244    }
1245    if (theObj = document.getElementById("GameText")) {
1246        theObj.style.display = "none";
1247    }
1248    if (theObj = document.getElementById("GamePuzzleTask")) {
1249      theObj.innerHTML = "<A CLASS='move moveOn'" +
1250        "HREF='javascript:void(0);' " + "ONCLICK='GoToMove(CurrentPly + 1);'>" +
1251        Math.floor((CurrentPly / 2) + 1) +
1252        (CurrentPly % 2 ? "..." : ".") + " ?</A>";
1253      theObj.title = (CurrentPly % 2 ? "Black" : "White") +
1254        " to move: find the best move... click the ? for the solution";
1255      theObj.style.display = "block";
1256    }
1257  }
1258
1259  if (theObj = document.getElementById("roundDetails")) {
1260    if ((gameRound[currentGame] !=  undefined) &&
1261        (gameRound[currentGame] !== "") &&
1262        (gameRound[currentGame] !== "*") &&
1263        (gameRound[currentGame] !=  "?")) {
1264      theObj.innerHTML = "&nbsp;(" + gameRound[currentGame] + ")";
1265    } else {
1266      theObj.innerHTML = "";
1267    }
1268  }
1269
1270  if (theObj = document.getElementById("siteDateSpacer")) {
1271    if ((gameSite[currentGame] != undefined) &&
1272        (gameSite[currentGame] !== "") &&
1273        (gameDate[currentGame] != undefined) &&
1274        (gameDate[currentGame] !== "")) {
1275      theObj.innerHTML = "&nbsp; &nbsp;";
1276    } else {
1277      theObj.innerHTML = "";
1278    }
1279  }
1280
1281  if (theObj = document.getElementById("whiteBlackSpacer")) {
1282    if ((gameWhite[currentGame] != undefined) &&
1283        (gameWhite[currentGame] !== "") &&
1284        (gameBlack[currentGame] != undefined) &&
1285        (gameBlack[currentGame] !== "")) {
1286      theObj.innerHTML = "&nbsp;-&nbsp;";
1287    } else {
1288      theObj.innerHTML = "";
1289    }
1290  }
1291
1292  if (theObj = document.getElementById("blackResultSpacer")) {
1293    if ((gameBlack[currentGame] != undefined) &&
1294        (gameBlack[currentGame] !== "") &&
1295        (gameResult[currentGame] != undefined) &&
1296        (gameResult[currentGame] !== "")) {
1297      theObj.innerHTML = "&nbsp; &nbsp;";
1298    } else {
1299      theObj.innerHTML = "";
1300    }
1301  }
1302
1303  if (theObj = document.getElementById("playersDetails")) {
1304    if ( ( ((gameWhite[currentGame] != undefined) && (gameWhite[currentGame] !== ""))   ||
1305           ((gameBlack[currentGame] != undefined) && (gameBlack[currentGame] !== ""))   ||
1306           ((gameResult[currentGame] != undefined) && (gameResult[currentGame] !== "")) )  &&
1307         ( ((gameEvent[currentGame] != undefined) && (gameEvent[currentGame] !== ""))   ||
1308           ((gameRound[currentGame] != undefined) && (gameRound[currentGame] !== "") &&
1309            (gameRound[currentGame] != "?") && (gameRound[currentGame] != "*"))        ||
1310           ((gameSite[currentGame] != undefined) && (gameSite[currentGame] !== ""))     ||
1311           ((gameDate[currentGame] != undefined) && (gameDate[currentGame] !== "")) ) ) {
1312      theObj.style.paddingBottom = "0.33em";
1313    } else {
1314      theObj.style.paddingBottom = "";
1315    }
1316  }
1317
1318  if (theObj = document.getElementById("headerMovesSpacer")) {
1319    if ( (headerDisplay == "live")                                                    ||
1320         (headerDisplay == "variations")                                              ||
1321         ((gameWhite[currentGame] != undefined) && (gameWhite[currentGame] !== ""))   ||
1322         ((gameBlack[currentGame] != undefined) && (gameBlack[currentGame] !== ""))   ||
1323         ((gameResult[currentGame] != undefined) && (gameResult[currentGame] !== "")) ||
1324         ((gameEvent[currentGame] != undefined) && (gameEvent[currentGame] !== ""))   ||
1325         ((gameRound[currentGame] != undefined) && (gameRound[currentGame] !== "") &&
1326          (gameRound[currentGame] != "?") && (gameRound[currentGame] != "*"))         ||
1327         ((gameSite[currentGame] != undefined) && (gameSite[currentGame] !== ""))     ||
1328         ((gameDate[currentGame] != undefined) && (gameDate[currentGame] !== "")) ) {
1329      theObj.style.display = "inline";
1330    } else {
1331      theObj.style.display = "none";
1332    }
1333  }
1334
1335// uncomment this to show the result at the end of the moves text
1336//
1337//   if (theObj = document.getElementById("GameText")) {
1338//     if ( (gameResult[currentGame] == "1-0")     ||
1339//          (gameResult[currentGame] == "0-1")     ||
1340//          (gameResult[currentGame] == "1/2-1/2") ||
1341//          (gameResult[currentGame] == "*") ) {
1342//       theObj.innerHTML += '<span class="move" style="white-space: nowrap;"> ' + gameResult[currentGame] + '</span>';
1343//     }
1344//   }
1345
1346}
1347
1348function customFunctionOnMove() {
1349  var theObj, ii;
1350
1351  if (movesDisplay == "puzzle") {
1352    if (theObj = document.getElementById("GamePuzzleTask")) {
1353      theObj.style.display = "none";
1354      theObj.innerHTML = "";
1355    }
1356    for (ii = 0; ii < objectHiddenPuzzler.length; ii++) {
1357      if (theObj = document.getElementById(objectHiddenPuzzler[ii])) {
1358        theObj.style.visibility = "";
1359      }
1360    }
1361    if (theObj = document.getElementById("GameText")) {
1362      theObj.style.display = "";
1363    }
1364  }
1365  if (theObj = document.getElementById("GameLastVariations")) {
1366    theObj.style.paddingLeft = theObj.innerHTML ? "1ex" : "";
1367  }
1368  if (theObj = document.getElementById("GameNextVariations")) {
1369    theObj.style.paddingLeft = theObj.innerHTML ? "1ex" : "";
1370  }
1371
1372}
1373
1374
1375function customDebugInfo() {
1376  return "autoScroll=" + (autoScrollToCurrentMove_objId !== "");
1377}
1378
1379enableAutoScrollToCurrentMove("headerMoves");
1380
1381// F5
1382if (movesDisplay == "puzzle") { boardShortcut("F5", "reset puzzle", function(t,e){ Init(currentGame); }); }
1383// G5
1384boardShortcut("G5", "toggle auto-scroll moves text to current move", function(t,e){ toggleAutoScrollToCurrentMove('headerMoves'); });
1385// H5
1386boardShortcut("H5", "scroll moves text to current move", function(t,e){ autoScrollToCurrentMove('headerMoves'); });
1387
1388// customShortcutKey_Shift_1 defined by fide-lookup.js
1389// customShortcutKey_Shift_2 defined by fide-lookup.js
1390
1391function customShortcutKey_Shift_5() {
1392  if (movesDisplay == "puzzle") { Init(currentGame); }
1393}
1394
1395var boardGeneratorWin=null;
1396function customShortcutKey_Shift_6() {
1397  if ((newPgnEncoded === "") && (newPgnText === "")) { return; }
1398  if (!window.location.href.match(/board\.html/)) { return; }
1399  if (boardGeneratorWin && !boardGeneratorWin.closed) { boardGeneratorWin.close(); }
1400  boardGeneratorWin = window.open(window.location.href.replace(/board\.html/g, "board-generator.html").replace(window.location.hash, "") + "#preview");
1401  if (boardGeneratorWin && window.focus) { boardGeneratorWin.focus(); }
1402}
1403
1404// customShortcutKey_Shift_8 defined by engine.js
1405// customShortcutKey_Shift_9 defined by engine.js
1406// customShortcutKey_Shift_0 defined by engine.js
1407
1408</script>
1409
1410</body>
1411
1412</html>
1413