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>chess games</title> 14 15<!-- use viewport settings when body.onresize adapts the chessboard to the available space --> 16<meta name="viewport" content="initial-scale=1, maximum-scale=1"> 17 18<!-- AppCheck: meta --> 19 20<link rel="icon" sizes="16x16" href="pawn.ico" /> 21 22<style type="text/css"> 23 24</style> 25 26<style id="dynamicStyle" type="text/css"></style> 27 28<!-- AppCheck: fonts --> 29 30<script src="pgn4web.js" type="text/javascript"></script> 31<script src="engine.js" type="text/javascript"></script> 32 33<script src="fide-lookup.js" type="text/javascript"></script> 34 35<script type="text/javascript"> 36"use strict"; 37 38SetHighlightOption(true); 39SetGameSelectorOptions("···", true, 30, 0, 8, 15, 15, 3, 0); // (head, num, chEvent, chSite, chRound, chWhite, chBlack, chResult, chDate); 40SetAutoplayDelay(2000); // milliseconds 41SetAutostartAutoplay(false); 42SetAutoplayNextGame(false); 43SetShortcutKeysEnabled(true); 44 45var pgnData_default = ""; 46var refreshMinutes_default = 0; 47var initialGame_default = "first"; 48var pieceBaseSize_default = 96; 49var pieceFont_default = "uscf"; 50var theme = new Array(); // font background light dark highlight 51theme[theme.length] = new Array("black", "FFFFFF", "000000", "999999", "777777", "000000"); 52theme[theme.length] = new Array("blue", "000000", "80B0E0", "E6EDF3", "A0BED8", "596978"); 53theme[theme.length] = new Array("braun", "221100", "FFCE9E", "FFCE9E", "D18B47", "663300"); 54theme[theme.length] = new Array("dark", "FFFFFF", "000000", "FFCE9E", "D18B47", "663300"); 55theme[theme.length] = new Array("gray", "666666", "F4F4F4", "F4F4F4", "E0E0E0", "AAAAAA"); 56theme[theme.length] = new Array("green", "333333", "EFF4EC", "EFF4EC", "C6CEC3", "999999"); 57theme[theme.length] = new Array("light", "000000", "FFFFFF", "FFCE9E", "D18B47", "663300"); 58theme[theme.length] = new Array("pink", "615F54", "EDE8D5", "EDE8D5", "CFCBB3", "F8CCA0"); 59theme[theme.length] = new Array("white", "000000", "FFFFFF", "FFFFFF", "E4E4E4", "000000"); 60theme[theme.length] = new Array("wood", "663300", "FFFFFF", "FFCC99", "CC9966", "663300"); 61theme[theme.length] = new Array("yellow", "54110C", "F2D798", "F2D798", "C9AD6F", "54110C"); 62var colorTheme_indexDefault = 2; 63var colorThemeOptions = ""; 64for (var ii = 0; ii < theme.length; ii++) { colorThemeOptions += "'" + theme[ii][0] + "' | "; } 65colorThemeOptions += "'random' "; 66 67var fontSizeRatio_default = 0.8; 68var pieceSizeRatio_default = 0.8; 69var sizeRatio_min = 0.3; 70var sizeRatio_max = 1; 71var framePaddingRatio_default = 0; 72 73var thisParamString = window.location.search; 74 75var thisRegExp; 76 77thisRegExp = /(&|\?)(help|h)=(true|t)(&|$)/i; 78if (thisParamString.match(thisRegExp) !== null) { 79 document.write("<pre style='font-size: smaller;'>pgn4web dynamic-frame.html parameters" + "\n" + 80 " - pgnData = file.pgn (no default)" + "\n" + 81 " - initialGame = initial game (default " + initialGame_default + ")" + "\n" + 82 " - live = if set true enables live broadcast with default values (default false)" + "\n" + 83 " - refreshMinutes = live broadcast delay (default " + refreshMinutes_default + ")" + "\n" + 84 " - refreshDemo = if set true sets live demo mode (default false)" + "\n" + 85// " - pieceBaseSize = size of baseline piece bitmap (default " + pieceBaseSize_default + ")" + "\n" + 86 " - pieceFont = 'alpha' | 'merida' | 'uscf' | 'random' (default " + pieceFont_default + ")" + "\n" + 87 " - colorTheme = " + colorThemeOptions + "(default '" + theme[colorTheme_indexDefault][0] + "')" + "\n" + 88 " - fontColorHex = font color hex code, like FF0000 (default according to the selected color theme)" + "\n" + 89 " - backgroundColorHex = page background color hex code, like FF0000 (default according to the selected color theme)" + "\n" + 90 " - lightColorHex = light square color hex code, like FF0000 (default according to the selected color theme)" + "\n" + 91 " - darkColorHex = dark square color hex code, like FF0000 (default according to the selected color theme)" + "\n" + 92 " - highlightColorHex = highlight square color hex code, like FF0000, or 'transparent' for no highlight (default according to the selected color theme)" + "\n" + 93 " - showColorFlag = if set true shows a color flag for the side to move (default false)" + "\n" + 94 " - showEco = if set true shows the ECO code if available (default false)" + "\n" + 95// " - fontSizeRatio = font size ratio, from " + sizeRatio_min + " to " + sizeRatio_max + " (default " + fontSizeRatio_default + ")" + "\n" + 96// " - pieceSizeRatio = piece size ratio, from " + sizeRatio_min + " to " + sizeRatio_max + " (default " + pieceSizeRatio_default + ")" + "\n" + 97// " - framePaddingRatio = frame padding as a square ratio (default " + framePaddingRatio_default + ")" + "\n" + 98// " - horizontalCentered = if set true centers vertically the chessboard when in horizontal layout (default false)" + "\n" + 99 " - bare = if set true shows chessboard only (default false)" + "\n" + 100// " - engineWinPrepareIdle = if set true preloads the analysis board with an empty board; use only for embedded analysis boards 101// " - debug = true | false (default false)" + "\n" + 102 " - help = true" + "\n" + 103 "</pre>"); 104} 105 106// undocumented feature 107thisRegExp = /(&|\?)(engineWinPrepareIdle|ewpi)=(true|t)(&|$)/i; 108var engineWinPrepareIdle = (thisParamString.match(thisRegExp) !== null); 109 110// undocumented feature 111thisRegExp = /(&|\?)(debug|d)=(true|t)(&|$)/i; 112var debug = (thisParamString.match(thisRegExp) !== null); 113var dynamicFrameDebugString = ""; 114 115var liveString = ""; 116thisRegExp = /(&|\?)(live|l)=([^&]*)(&|$)/i; 117if (thisParamString.match(thisRegExp) !== null) { 118 liveString = unescape(thisParamString.match(thisRegExp)[3]); 119} 120if ((liveString == "true") || (liveString == "t")) { 121 refreshMinutes_default = 1; 122} 123 124var alertFlag = false; 125var demoFlag = false; 126thisRegExp = /(&|\?)(refreshDemo|rd)=([^&]*)(&|$)/i; 127if (thisParamString.match(thisRegExp) !== null) { 128 var refreshDemo = unescape(thisParamString.match(thisRegExp)[3]); 129 if ((refreshDemo == "true") || (refreshDemo == "t")) { alertFlag = demoFlag = true; } 130} 131 132var refreshMinutes = refreshMinutes_default; 133var stepFlag = true; 134thisRegExp = /(&|\?)(refreshMinutes|rm)=([^&]*)(&|$)/i; 135if (thisParamString.match(thisRegExp) !== null) { 136 refreshMinutes = parseFloat(unescape(thisParamString.match(thisRegExp)[3])); 137 if (isNaN(refreshMinutes)) { refreshMinutes = refreshMinutes_default; } 138 if (refreshMinutes <= 0) { refreshMinutes = refreshMinutes_default; } 139} 140if (refreshMinutes) { 141 pgnData_default = "live/live.pgn"; 142 initialGame_default = "\\[\\s*Result\\s*\"\\*\"\\s*\\]"; 143} 144 145SetInitialHalfmove(refreshMinutes ? "end" : "start", true); 146 147SetLiveBroadcast(refreshMinutes, alertFlag, demoFlag, stepFlag); 148 149var pgnData = pgnData_default; 150thisRegExp = /(&|\?)(pgnData|pd)=([^&]*)(&|$)/i; 151if (thisParamString.match(thisRegExp) !== null) { 152 pgnData = unescape(thisParamString.match(thisRegExp)[3]); 153} 154SetPgnUrl(pgnData); 155 156var iniGame = initialGame_default; 157thisRegExp = /(&|\?)(initialGame|ig)=([^&]*)(&|$)/i; 158if (thisParamString.match(thisRegExp) !== null) { 159 iniGame = unescape(thisParamString.match(thisRegExp)[3]); 160} 161SetInitialGame(iniGame); 162 163// undocumented feature 164var allowedPieceBaseSize = 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); 165var pieceBaseSize = pieceBaseSize_default; 166thisRegExp = /(&|\?)(pieceBaseSize|pbs)=([^&]*)(&|$)/i; 167if (thisParamString.match(thisRegExp) !== null) { 168 var pieceBaseSize_input = unescape(thisParamString.match(thisRegExp)[3]); 169 pieceBaseSize = parseInt(pieceBaseSize_input, 10); 170 var validPieceBaseSize = false; 171 for (var pieceBaseIndex in allowedPieceBaseSize) { 172 if (pieceBaseSize === allowedPieceBaseSize[pieceBaseIndex]) { 173 validPieceBaseSize = true; 174 break; 175 } 176 } 177 if (!validPieceBaseSize) { 178 myAlert("warning: invalid pieceBaseSize=" + pieceBaseSize_input + ", reverting to " + pieceBaseSize_default + " as default"); 179 pieceBaseSize = pieceBaseSize_default; 180 } 181} 182 183var pieceFont = pieceFont_default; 184thisRegExp = /(&|\?)(pieceFont|pf)=([^&]*)(&|$)/i; 185if (thisParamString.match(thisRegExp) !== null) { 186 pieceFont = unescape(thisParamString.match(thisRegExp)[3]); 187} 188if (pieceFont == "a") { pieceFont = "alpha"; } 189if (pieceFont == "m") { pieceFont = "merida"; } 190if (pieceFont == "u") { pieceFont = "uscf"; } 191if (pieceFont == "i") { pieceFont = "igorsvg"; } 192if (pieceFont == "s") { pieceFont = "svgchess"; } 193if (pieceFont == "t") { pieceFont = "tilesvg"; } 194if ((pieceFont == "random") || (pieceFont == "r")) { 195 pieceFont = ["alpha", "merida", "uscf"][Math.floor(3 * Math.random())]; 196} 197if ((pieceFont != "alpha") && (pieceFont != "merida") && (pieceFont != "uscf") && (pieceFont != "igorsvg") && (pieceFont != "svgchess") && (pieceFont != "tilesvg")) { pieceFont = pieceFont_default; } 198if ((pieceFont == "igorsvg") || (pieceFont == "svgchess") || (pieceFont == "tilesvg")) { 199 SetImagePath("images/" + pieceFont); 200 SetImageType("svg"); 201} else { 202 SetImagePath("images/" + pieceFont + "/" + pieceBaseSize); 203 SetImageType("png"); 204} 205 206var colorTheme = theme[colorTheme_indexDefault][0]; 207thisRegExp = /(&|\?)(colorTheme|ct)=([\w]*|[\d]+)(&|$)/i; 208if (thisParamString.match(thisRegExp) !== null) { 209 colorTheme = unescape(thisParamString.match(thisRegExp)[3]); 210} 211var colorTheme_index = colorTheme_indexDefault; 212if (colorTheme == "random") { colorTheme_index = Math.floor(theme.length * Math.random()); } 213else if (colorTheme.match(/^\d+$/)) { colorTheme_index = parseInt(colorTheme, 10) % theme.length; colorTheme = theme[colorTheme_index][0]; } 214else { for (ii = 0; ii < theme.length; ii++) { if (theme[ii][0] === colorTheme) { colorTheme_index = ii; break; } } } 215 216var fontColorHex_default = theme[colorTheme_index][1]; 217var backgroundColorHex_default = theme[colorTheme_index][2]; 218var lightColorHex_default = theme[colorTheme_index][3]; 219var darkColorHex_default = theme[colorTheme_index][4]; 220var highlightColorHex_default = theme[colorTheme_index][5]; 221 222var fontColorHex = fontColorHex_default; 223thisRegExp = /(&|\?)(fontColorHex|fch)=([A-F0-9]*)(&|$)/i; 224if (thisParamString.match(thisRegExp) !== null) { 225 fontColorHex = unescape(thisParamString.match(thisRegExp)[3]); 226} 227 228var backgroundColorHex = backgroundColorHex_default; 229thisRegExp = /(&|\?)(backgroundColorHex|bch)=([A-F0-9]*)(&|$)/i; 230if (thisParamString.match(thisRegExp) !== null) { 231 backgroundColorHex = unescape(thisParamString.match(thisRegExp)[3]); 232} 233 234var lightColorHex = lightColorHex_default; 235thisRegExp = /(&|\?)(lightColorHex|lch)=([A-F0-9]*)(&|$)/i; 236if (thisParamString.match(thisRegExp) !== null) { 237 lightColorHex = unescape(thisParamString.match(thisRegExp)[3]); 238} 239 240var darkColorHex = darkColorHex_default; 241thisRegExp = /(&|\?)(darkColorHex|dch)=([A-F0-9]*)(&|$)/i; 242if (thisParamString.match(thisRegExp) !== null) { 243 darkColorHex = unescape(thisParamString.match(thisRegExp)[3]); 244} 245 246var highlightColorHex = highlightColorHex_default; 247thisRegExp = /(&|\?)(highlightColorHex|hch)=(t|transparent)(&|$)/i; 248if (thisParamString.match(thisRegExp) !== null) { 249 highlightColorHex = ""; 250 clearShortcutSquares("D", "7"); 251} else { 252 thisRegExp = /(&|\?)(highlightColorHex|hch)=([A-F0-9]*)(&|$)/i; 253 if (thisParamString.match(thisRegExp) !== null) { 254 highlightColorHex = unescape(thisParamString.match(thisRegExp)[3]); 255 } 256} 257 258var showColorFlagString = "false"; 259thisRegExp = /(&|\?)(showColorFlag|scf)=([^&]*)(&|$)/i; 260if (thisParamString.match(thisRegExp) !== null) { 261 showColorFlagString = unescape(thisParamString.match(thisRegExp)[3]); 262} 263var showColorFlag = ((showColorFlagString == "true") || (showColorFlagString == "t")); 264 265var showEcoString = "false"; 266thisRegExp = /(&|\?)(showEco|se)=([^&]*)(&|$)/i; 267if (thisParamString.match(thisRegExp) !== null) { 268 showEcoString = unescape(thisParamString.match(thisRegExp)[3]); 269} 270var showEco = ((showEcoString == "true") || (showEcoString == "t")); 271 272// undocumented feature 273var fontSizeRatio = fontSizeRatio_default; 274thisRegExp = /(&|\?)(fontSizeRatio|fsr)=([0-9.]*)(&|$)/i; 275if (thisParamString.match(thisRegExp) !== null) { 276 fontSizeRatio = parseFloat(unescape(thisParamString.match(thisRegExp)[3])); 277 if (isNaN(fontSizeRatio) || (fontSizeRatio < sizeRatio_min) || (fontSizeRatio > sizeRatio_max)) { fontSizeRatio = fontSizeRatio_default; } 278} 279 280// undocumented feature 281var pieceSizeRatio = pieceSizeRatio_default; 282thisRegExp = /(&|\?)(pieceSizeRatio|psr)=([0-9.]*)(&|$)/i; 283if (thisParamString.match(thisRegExp) !== null) { 284 pieceSizeRatio = parseFloat(unescape(thisParamString.match(thisRegExp)[3])); 285 if (isNaN(pieceSizeRatio) || (pieceSizeRatio < sizeRatio_min) || (pieceSizeRatio > sizeRatio_max)) { pieceSizeRatio = pieceSizeRatio_default; } 286} 287 288// undocumented feature 289var framePaddingRatio = framePaddingRatio_default; 290thisRegExp = /(&|\?)(framePaddingRatio|fpr)=([0-9.]*)(&|$)/i; 291if (thisParamString.match(thisRegExp) !== null) { 292 framePaddingRatio = parseFloat(unescape(thisParamString.match(thisRegExp)[3])); 293 if (isNaN(framePaddingRatio)) { framePaddingRatio = framePaddingRatio_default; } 294} 295 296// undocumented feature 297var horizontalCenteredString = ""; 298thisRegExp = /(&|\?)(horizontalCentered|hc)=([^&]*)(&|$)/i; 299if (thisParamString.match(thisRegExp) !== null) { 300 horizontalCenteredString = unescape(thisParamString.match(thisRegExp)[3]); 301} 302var horizontalCentered = ((horizontalCenteredString == "true") || (horizontalCenteredString == "t")); 303 304var bareString = ""; 305thisRegExp = /(&|\?)(bare|b)=([^&]*)(&|$)/i; 306if (thisParamString.match(thisRegExp) !== null) { 307 bareString = unescape(thisParamString.match(thisRegExp)[3]); 308} 309var bare = ((bareString == "true") || (bareString == "t")); 310 311 312function myRulesLength(sheet) { 313 if (sheet.cssRules) { return sheet.cssRules.length; } 314 if (sheet.rules) { return sheet.rules.length; } 315 return null; 316} 317 318function myInsertRule(sheet, selector, declaration) { 319 if (sheet.insertRule) { sheet.insertRule(selector + "{ " + declaration + " }", myRulesLength(sheet)); } 320 else if (sheet.addRule) { sheet.addRule(selector, declaration); } 321} 322 323function myDeleteRule(sheet, index) { 324 if (sheet.deleteRule) { sheet.deleteRule(index); } 325 else if (sheet.removeRule) { sheet.removeRule(index); } 326} 327 328function toggleColorFlag() { 329 var theObj; 330 showColorFlag = !showColorFlag; 331 if (!showColorFlag) { 332 if (theObj = document.getElementById("whiteColorFlag")) { theObj.style.display = "none"; } 333 if (theObj = document.getElementById("whiteColorFlagFiller")) { theObj.style.display = "none"; } 334 if (theObj = document.getElementById("blackColorFlag")) { theObj.style.display = "none"; } 335 if (theObj = document.getElementById("blackColorFlagFiller")) { theObj.style.display = "none"; } 336 } 337 myOnResize(); 338} 339 340function toggleShowEco() { 341 if (showEco = !showEco) { 342 fixHeaderItem("ECO", "GameECO", "ECO"); 343 fixHeaderItem("ECO", "GameECOFiller", "ECO"); 344 } else { 345 var theObj; 346 if (theObj = document.getElementById("GameECO")) { theObj.innerHTML = theObj.title = ""; } 347 if (theObj = document.getElementById("GameECOFiller")) { theObj.innerHTML = theObj.title = ""; } 348 } 349} 350 351var horizontalLayout; 352function myOnResize() { 353 var ww, wh; 354 if (window.innerWidth && window.innerHeight) { ww = window.innerWidth; wh = window.innerHeight; } 355 else if (document.documentElement && document.documentElement.clientWidth) { ww = document.documentElement.clientWidth; wh = document.documentElement.clientHeight; } 356 else if (document.body && document.body.clientWidth) { ww = document.body.clientWidth; wh = document.body.clientHeight; } 357 else { return false; } 358 359 var squareSize; 360 if (bare) { 361 horizontalLayout = (ww >= wh); 362 squareSize = Math.min(ww / (8 + 2 * framePaddingRatio), wh / (8 + 2 * framePaddingRatio)); 363 } else { 364 var squareSize_H = Math.min(ww / (16 / 9), wh) / (8 + 2 * framePaddingRatio); 365 var squareSize_V = Math.min(ww, wh / (16 / 9)) / (8 + 2 * framePaddingRatio); 366 horizontalLayout = (squareSize_H >= squareSize_V); 367 squareSize = horizontalLayout ? squareSize_H : squareSize_V; 368 } 369 var framePadding = Math.floor(framePaddingRatio * squareSize); 370 squareSize = Math.floor(squareSize); 371 var bodyHeight = wh - 2 * framePadding; 372 var lineHeight; 373 if (horizontalLayout) { 374 lineHeight = Math.floor(squareSize * 8 / 16.5); 375 } else { 376 lineHeight = Math.floor(Math.min((wh - framePadding * 2 - squareSize * 8) / (11 + 6/2), squareSize * 8 / 16.5)); 377 } 378 var fontSize = Math.floor(lineHeight * fontSizeRatio); 379 if (fontSize > lineHeight) { fontSize = lineHeight; } 380 var squareBorderWidth = Math.min(Math.ceil(squareSize / 50), 3); 381 var bareSquareSize = squareSize - 2 * squareBorderWidth; 382 var pieceSize = Math.floor(squareSize * pieceSizeRatio); 383 if (pieceSize > bareSquareSize) { pieceSize = Math.floor(bareSquareSize); } 384 var headerContainerWidth = horizontalLayout ? ww - 2 * framePadding - 9 * squareSize + Math.floor(3 * lineHeight / 4) : ww - 2 * framePadding; 385 386 if (document.styleSheets.length === 0) { return false; } 387 388 var sheet = document.styleSheets[0]; 389 var oldRules = myRulesLength(sheet); 390 391 myInsertRule(sheet, "html", "overflow: hidden;"); 392 myInsertRule(sheet, "body", "-webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -o-user-select: none; user-select: none; -webkit-text-size-adjust: none; -moz-text-size-adjust: none; -ms-text-size-adjust: none; -o-text-size-adjust: none; text-size-adjust: none; -webkit-touch-callout: none; height: " + bodyHeight + "px; padding: 0px; margin: " + framePadding + "px; white-space: nowrap; overflow: hidden; color: #" + fontColorHex + "; background-color: #" + backgroundColorHex + "; font-family: sans-serif; line-height: " + lineHeight + "px; font-size: " + fontSize + "px;"); 393 myInsertRule(sheet, "a", "text-decoration: none; color: #" + fontColorHex + ";"); 394 if (bare) { 395 myInsertRule(sheet, ".boardTable", "margin-left: " + Math.floor((ww - 2 * framePadding - 8 * squareSize) / 2) + "px; margin-top: " + Math.floor((wh - 2 * framePadding - 8 * squareSize) / 2) + "px;"); 396 } else { 397 if (horizontalLayout) { myInsertRule(sheet, ".boardTable", "float: left;" + (horizontalCentered ? " margin-top: " + Math.floor((wh - 2 * framePadding - 8 * squareSize) / 2) + "px;" : "")); } 398 else { myInsertRule(sheet, ".boardTable", "margin-left: " + Math.floor((ww - 2 * framePadding - 8 * squareSize) / 2) + "px;"); } 399 } 400 myInsertRule(sheet, ".pieceImage", "cursor: pointer; width: " + pieceSize + "px; height: " + pieceSize + "px;"); 401 myInsertRule(sheet, ".whiteSquare", "width: " + bareSquareSize + "px; height: " + bareSquareSize + "px; border-style: solid; border-width: " + squareBorderWidth + "px;" + "background-color: #" + lightColorHex + "; border-color: #" + lightColorHex + ";"); 402 myInsertRule(sheet, ".blackSquare", "width: " + bareSquareSize + "px; height: " + bareSquareSize + "px; border-style: solid; border-width: " + squareBorderWidth + "px;" + "background-color: #" + darkColorHex + "; border-color: #" + darkColorHex + ";"); 403 myInsertRule(sheet, ".highlightWhiteSquare", "width: " + bareSquareSize + "px; height: " + bareSquareSize + "px; border-style: solid; border-width: " + squareBorderWidth + "px;" + "background-color: #" + lightColorHex + "; border-color: #" + (highlightColorHex ? highlightColorHex : lightColorHex) + ";"); 404 myInsertRule(sheet, ".highlightBlackSquare", "width: " + bareSquareSize + "px; height: " + bareSquareSize + "px; border-style: solid; border-width: " + squareBorderWidth + "px;" + "background-color: #" + darkColorHex + "; border-color: #" + (highlightColorHex ? highlightColorHex : darkColorHex) + ";"); 405 myInsertRule(sheet, ".headerContainer", "width: " + headerContainerWidth + "px; white-space: nowrap; overflow: hidden;" + (horizontalLayout ? " float: right; text-align: left;" + (horizontalCentered ? " margin-top: " + Math.floor((wh - 2 * framePadding - 8 * squareSize) / 2) + "px;" : "") : " text-align: center;")); 406 if (LiveBroadcastDelay > 0) { 407 myInsertRule(sheet, ".gameButtons", "display: none;"); 408 } else { 409 myInsertRule(sheet, ".liveStatusLine", "display: none;"); 410 if (horizontalLayout) { myInsertRule(sheet, ".gameButtons", "width: " + (headerContainerWidth - lineHeight) + "px; " + "text-align: left;"); } 411 var buttonCss = "cursor: pointer; margin: 0px; padding: 0px; width: " + Math.floor(3 * lineHeight / 2) + "px !important; height: " + lineHeight + "px; color: #" + fontColorHex + "; border-style: none; -moz-appearance: none; -webkit-appearance: none; background-color: #" + backgroundColorHex + "; font-family: sans-serif; line-height: " + lineHeight + "px; font-size: " + fontSize + "px;"; 412 myInsertRule(sheet, ".buttonControl", buttonCss); 413 myInsertRule(sheet, ".buttonControlPlay", buttonCss); 414 myInsertRule(sheet, ".buttonControlStop", buttonCss); 415 myInsertRule(sheet, ".buttonControlSpace", "margin: 0px; padding: 0px; width: " + Math.floor(lineHeight / 4) + "px !important;"); 416 } 417 myInsertRule(sheet, ".colorFlag", "height: " + Math.floor(0.45 * fontSize) + "px; width: " + Math.floor(0.45 * fontSize) + "px; border-width: 1px; border-color: #" + fontColorHex + "; border-style: solid; margin-bottom: " + Math.floor(0.1 * fontSize) + "px; margin-left: " + Math.floor(5 * lineHeight / 9) + "px; margin-right: " + Math.floor(5 * lineHeight / 9) + "px;"); 418 myInsertRule(sheet, ".leftRightSpacing", "margin-left: " + Math.floor(lineHeight / 2) + "px; margin-right: " + Math.floor(lineHeight / 2) + "px;"); 419 if (!horizontalLayout) { 420 var variableSpacerLineHeight = Math.floor(Math.min((wh - framePadding * 2 - squareSize * 8 - lineHeight * 11) / 6, lineHeight / 2)); 421 var variableSpacerFontSize = Math.floor(variableSpacerLineHeight * 0.8); 422 myInsertRule(sheet, ".variableSpacer", "line-height: " + variableSpacerLineHeight + "px; font-size: " + variableSpacerFontSize + "px;"); 423 } 424 myInsertRule(sheet, ".gameLiveStatusExtraInfoLeft", horizontalLayout ? "display: none;" : ""); 425 myInsertRule(sheet, ".showGameListLink", "padding-right: " + squareSize + "px; padding-left: " + (horizontalLayout ? 0 : squareSize) + "px;"); 426 var gameListFontHorizontalRatio = 28; 427 var gameListFontVerticalRatio = 24; 428 var gameListFontSize = Math.floor(Math.min((ww - framePadding * 2) / gameListFontHorizontalRatio, (wh - framePadding * 2) / gameListFontVerticalRatio)); 429 gameListLineHeight = Math.floor(1.9 * gameListFontSize); 430 var gameListPadding = Math.floor(gameListLineHeight / 2); 431 gameListBodyHeight = gameListLineHeight * Math.floor((wh - 2 * framePadding - gameListLineHeight - 2.5 * gameListPadding) / gameListLineHeight); 432 gameListNumGames = Math.round(gameListBodyHeight / gameListLineHeight); 433 myInsertRule(sheet, ".gameList", "display: none; position: absolute; overflow: hidden; font-size: " + gameListFontSize + "px; line-height: " + gameListLineHeight + "px;"); 434 myInsertRule(sheet, ".gameListHeader", "overflow: hidden; height: " + gameListLineHeight + "px; width: " + (ww - 2 * framePadding) + "px; padding-top: " + gameListPadding + "px; padding-bottom: " + gameListPadding + "px;"); 435 myInsertRule(sheet, ".gameListHeaderItem", "display: inline-block; overflow: hidden; text-align: center; width: " + ((ww - 2 * framePadding) / 7) + "px;"); 436 myInsertRule(sheet, ".gameListHeaderButton", "cursor: pointer; display: inline-block; min-width: " + ((ww - 2 * framePadding) / 14) + "px;"); 437 myInsertRule(sheet, ".gameListBody", "height: " + gameListBodyHeight + "px; width: " + (ww - 2 * framePadding) + "px; overflow-x: hidden; overflow-y: auto; scrollbar-base-color: #" + backgroundColorHex + "; -webkit-overflow-scrolling: touch; overflow-scrolling: touch;"); 438 myInsertRule(sheet, ".gameListBodyItems", ""); 439 var gameListMarginSpacing = Math.floor((gameListFontSize * gameListFontHorizontalRatio) * (6 / 32) / 5); 440 var gameListPlayerSpacing = Math.floor((gameListFontSize * gameListFontHorizontalRatio) * (9 / 32)); 441 myInsertRule(sheet, ".gameListRow", "cursor: pointer;"); 442 myInsertRule(sheet, ".gameListRowSelected", "color: #" + backgroundColorHex + "; background-color: #" + fontColorHex + ";"); 443 myInsertRule(sheet, ".gameListBodyItemsPlayer", "overflow: hidden; width: " + gameListPlayerSpacing + "px; margin-left: " + gameListMarginSpacing + "px; margin-right: " + gameListMarginSpacing + "px;"); 444 myInsertRule(sheet, ".gameListBodyItemsPlayerWhite", "text-align: right; margin-left: " + (2 * gameListMarginSpacing) + "px;"); 445 myInsertRule(sheet, ".gameListBodyItemsPlayerBlack", ""); 446 myInsertRule(sheet, ".gameListBodyItemsResult", "text-align: center; min-width: 5ex; margin-left: 0px; margin-right: 0px;"); 447 myInsertRule(sheet, ".gameListBodyItemsEventRound", "margin-left: " + (2 * gameListMarginSpacing) + "px; margin-right: " + (2 * gameListMarginSpacing) + "px;"); 448 449 for (var ii = 0; ii < oldRules; ii++) { myDeleteRule(sheet, 0); } 450 451 var theObj; 452 453 if (theObj = document.getElementById("boardTable")) { 454 theObj.style.height = (squareSize * 8) + "px"; 455 theObj.style.width = (squareSize * 8) + "px"; 456 } 457 458 if (theObj = document.getElementById("HeaderContainer")) { theObj.style.display = bare ? "none" : document.getElementById("GameBoard").style.display; } 459 460 if (!firstStart) { 461 fixColorFlag(); 462 fixECO(); 463 } 464 465 dynamicFrameDebugString = "fw=" + ww + " fh=" + wh + " fp=" + framePadding + " fs=" + fontSize + " ss=" + squareSize + " sb=" + squareBorderWidth + " ps=" + pieceSize + " pbs=" + pieceBaseSize; 466 467 return pieceSize; 468} 469 470 471function customFunctionOnCheckLiveBroadcastStatus() { 472 updateBareShortcut(); 473} 474 475function customDebugInfo() { 476 var dbg = ""; 477 if (highlightColorHex) { dbg += "highlightOption=" + highlightOption + " "; } 478 if (LiveBroadcastDelay === 0) { dbg += "initialHalfmove=" + initialHalfmove + " "; } 479 dbg += "showColorFlag=" + showColorFlag + " " + "showEco=" + showEco; 480 if (debug) { dbg += " " + dynamicFrameDebugString; } 481 return dbg; 482} 483 484var textSelectOptionsLast = "none"; 485var currentGameLast = -1; 486var gameListBodyHeight = -1; 487var gameListLineHeight = -1; 488var gameListNumGames = -1; 489function fillGameList(force) { 490 var theObj; 491 if (theObj = document.getElementById("GameSelSelect")) { textSelectOptions = theObj.innerHTML; } 492 if ((currentGame !== currentGameLast) || (textSelectOptions !== textSelectOptionsLast) || (numberOfGames == 1)) { // textSelectOptions not updated when there's only one game 493 currentGameLast = currentGame; 494 textSelectOptionsLast = textSelectOptions; 495 force = true; 496 if (theObj = document.getElementById("GameListBodyItems")) { 497 var thisNum, thisResult, thisGameTitle1, thisGameTitle2; 498 var text = "<table width='100%' cellspacing='0' cellpadding='0' border='0'>"; 499 for (thisNum = 0; thisNum < numberOfGames; thisNum++) { 500 thisGameTitle1 = gameWhite[thisNum] || ""; 501 thisGameTitle1 += (thisGameTitle1 && gameBlack[thisNum]) ? " " : ""; 502 thisGameTitle1 += gameBlack[thisNum] || ""; 503 thisGameTitle1 += (thisGameTitle1 && gameResult[thisNum]) ? " " : ""; 504 thisGameTitle1 += gameResult[thisNum] || ""; 505 thisGameTitle2 = gameEvent[thisNum] || ""; 506 thisGameTitle2 += (thisGameTitle2 && gameRound[thisNum]) ? " " : ""; 507 thisGameTitle2 += gameRound[thisNum] || ""; 508 text += "<tr class='gameListRow" + (currentGame === thisNum ? " gameListRowSelected" : "") + "' onclick='selectGameList(" + thisNum + ");' title='" + thisGameTitle1 + (thisGameTitle1 && thisGameTitle2 ? "\n" : "") + thisGameTitle2 + "'>"; 509 text += "<td><div class='gameListBodyItemsPlayer gameListBodyItemsPlayerWhite'>" + gameWhite[thisNum] + "</div></td>"; 510 if ((gameWhite[thisNum] !== "") || (gameBlack[thisNum] !== "") || (gameResult[thisNum] != "*")) { 511 thisResult = gameResult[thisNum]; 512 if (thisResult == "1/2-1/2") { thisResult = "1/2"; } 513 else if (thisResult.length > 3) { thisResult = "?"; } 514 else if (thisResult == "*") { thisResult = "∗"; } 515 } else { 516 thisResult = ""; 517 } 518 text += "<td><div class='gameListBodyItemsResult'>" + thisResult + "</div></td>"; 519 text += "<td><div class='gameListBodyItemsPlayer gameListBodyItemsPlayerBlack'>" + gameBlack[thisNum] + "</div></td>"; 520 text += "<td width='100%'>"; 521 if (gameEvent[thisNum] || gameRound[thisNum]) { 522 text += "<div class='gameListBodyItemsEventRound'>" + gameEvent[thisNum] + ((gameEvent[thisNum] && gameRound[thisNum]) ? " " : "") + gameRound[thisNum] + "</div>"; 523 } 524 text += "</td></tr>"; 525 } 526 text += "</table>"; 527 theObj.innerHTML = text; 528 } 529 } 530 if (force) { 531 setTimeout("autoscrollGameListBody(-1);", 111); 532 } 533} 534 535function autoscrollGameListBody(thisGame) { 536 var theObj = document.getElementById("GameListBody"); 537 if (theObj) { 538 if (thisGame == -1) { 539 thisGame = currentGame + 1 - Math.ceil(gameListNumGames / 2); 540 } 541 theObj.scrollLeft = 0; 542 theObj.scrollTop = thisGame * gameListLineHeight; 543 } 544} 545 546var oldHeaderContainerDisplay; 547function showGameList() { 548 if (numberOfGames < 2) { return; } 549 var theObj = document.getElementById("GameList"); 550 if ((theObj) && (theObj.style.display == "block")) { return; } 551 disableShortcutKeysAndStoreStatus(); 552 fillGameList(true); 553 if (theObj = document.getElementById("HeaderContainer")) { 554 oldHeaderContainerDisplay = theObj.style.display; 555 theObj.style.display = "none"; 556 } 557 if (theObj = document.getElementById("GameBoard")) { theObj.style.display = "none"; } 558 if (theObj = document.getElementById("GameList")) { theObj.style.display = "block"; } 559} 560 561function selectGameList(gameNum) { 562 var theObj = document.getElementById("GameList"); 563 if ((theObj) && (theObj.style.display === "")) { return; } 564 if (gameNum != -1) { Init(gameNum); } 565 if (theObj = document.getElementById("GameList")) { theObj.style.display = ""; } 566 if (theObj = document.getElementById("GameBoard")) { theObj.style.display = ""; } 567 if (theObj = document.getElementById("HeaderContainer")) { theObj.style.display = oldHeaderContainerDisplay; } 568 restoreShortcutKeysStatus(); 569} 570 571function toggleGameListHorizontalScroll() { 572 var theObj = document.getElementById("GameListBody"); 573 if (theObj) { theObj.scrollLeft = theObj.scrollLeft ? 0 : theObj.offsetWidth; } 574} 575 576var liveBroadcastUpdateTicker = 0; 577var previousPlyNumber = -1; 578function customFunctionOnPgnTextLoad() { 579 var noGamesLoaded = (numberOfGames == 1) && (PlyNumber === 0) && (StartPly === 0) && (!gameWhite[0]) && (!gameBlack[0]) && (!gameResult[0]) && (!gameFEN[0]); 580 if (LiveBroadcastDelay > 0) { 581 if (previousPlyNumber !== PlyNumber) { 582 previousPlyNumber = PlyNumber; 583 liveBroadcastUpdateTicker++; 584 } 585 document.title = liveBroadcastUpdateTicker + "." + LiveBroadcastGamesRunning + "." + numberOfGames + " live broadcast" + (demoFlag ? " demo" : ""); 586 } else { 587 if (noGamesLoaded) { document.title = alertNum ? "PGN data error" : "chess games"; } 588 else { document.title = numberOfGames + " game" + (numberOfGames == 1 ? "" : "s"); } 589 } 590 591 fillGameList(false); 592 if (theObj = document.getElementById("ShowGameListLink")) { 593 theObj.title = "select from " + numberOfGames + " games"; 594 var text = "", ii; 595 for (ii = 0; ii <= 4 + Math.log(numberOfGames)/Math.LN2; ii++) { text += "· "; } 596 text += "·"; 597 theObj.innerHTML = text; 598 } 599 if (theObj = document.getElementById("ShowGameList")) { 600 theObj.style.visibility = numberOfGames > 1 ? "visible" : "hidden"; 601 } 602 if (numberOfGames > 1) { 603 boardShortcut("F5", "show games list", function(t,e){ showGameList(); }); 604 } else { 605 boardShortcut("F5", "", function(t,e){}); 606 } 607 if (engineWinPrepareIdle) { 608 showEngineAnalysisBoard(true, true); 609 engineWinPrepareIdle = false; 610 } 611 612<!-- AppCheck: customFunctionOnPgnTextLoad --> 613 614} 615 616function fixHeaderItem(tag, objectId, label) { 617 var theObj = document.getElementById(objectId); 618 if (theObj) { 619 var tagValue = simpleHtmlentitiesDecode(tag ? customPgnHeaderTag(tag, objectId) : theObj.innerHTML); 620 if (tagValue) { 621 theObj.title = label + ": " + tagValue; 622 theObj.className = "leftRightSpacing"; 623 } else { 624 theObj.title = label; 625 theObj.className = ""; 626 } 627 } 628} 629 630function customFunctionOnPgnGameLoad() { 631 myOnResize(); 632 fixHeaderItem(null, "GameEvent", "event"); 633 fixHeaderItem(null, "GameSite", "site"); 634 fixHeaderItem(null, "GameDate", "date"); 635 fixHeaderItem(null, "GameRound", "round"); 636 fixHeaderItem(null, "GameWhite", "white player"); 637 fixHeaderItem(null, "GameBlack", "black player"); 638 fixHeaderItem(null, "GameResult", "result"); 639 fixHeaderItem("Section", "GameSection", "section"); 640 fixHeaderItem("Stage", "GameStage", "stage"); 641 fixHeaderItem("WhiteTitle", "GameWhiteTitle", "white title"); 642 fixHeaderItem("WhiteElo", "GameWhiteElo", "white elo"); 643 fixHeaderItem("WhiteTeam", "GameWhiteTeam", "white team"); 644 fixHeaderItem("BlackTitle", "GameBlackTitle", "black title"); 645 fixHeaderItem("BlackElo", "GameBlackElo", "black elo"); 646 fixHeaderItem("BlackTeam", "GameBlackTeam", "black team"); 647 if (showEco) { 648 fixHeaderItem("ECO", "GameECO", "ECO"); 649 fixHeaderItem("ECO", "GameECOFiller", "ECO"); 650 } 651 updateBareShortcut(); 652 var theObj = document.getElementById("GameResult"); 653 if (theObj) { theObj.innerHTML = theObj.innerHTML.replace(/\*/g, "∗").replace(/(\d)-(\d)/g, "$1<span style='font-weight:normal;'> - </span>$2"); } 654 655 var livePlaceholderDetected = (LiveBroadcastDelay > 0) && (PlyNumber === 0) && (StartPly === 0) && (!gameWhite[currentGame]) && (!gameBlack[currentGame]) && (!gameFEN[currentGame]); 656 if (theObj = document.getElementById("GameResultLine")) { theObj.style.display = livePlaceholderDetected ? "none" : ""; } 657 if (theObj = document.getElementById("GameWhiteClockLine")) { theObj.style.display = livePlaceholderDetected ? "none" : ""; } 658 if (theObj = document.getElementById("GameBlackClockLine")) { theObj.style.display = livePlaceholderDetected ? "none" : ""; } 659 660<!-- AppCheck: customFunctionOnPgnGameLoad --> 661 662} 663 664function customFunctionOnMove() { 665 var extraMoves = 2; 666 667 document.getElementById("GamePrevMoves").innerHTML = ""; 668 document.getElementById("GameCurrMove").innerHTML = ""; 669 document.getElementById("GameNextMoves").innerHTML = ""; 670 var theObj = document.getElementById("GamePrevMoves"); 671 var thisPly = Math.max(CurrentPly - extraMoves - 1, StartPly); 672 if (thisPly > StartPly) { theObj.innerHTML += "... "; } 673 for (; thisPly < Math.min(CurrentPly + extraMoves, StartPly + PlyNumber); thisPly++) { 674 if (thisPly == CurrentPly) { 675 theObj = document.getElementById("GameNextMoves"); 676 } 677 if (thisPly % 2 === 0) { theObj.innerHTML += Math.floor(1 + thisPly / 2) + ". "; } 678 if (thisPly == CurrentPly - 1) { 679 theObj = document.getElementById("GameCurrMove"); 680 } 681 theObj.innerHTML += Moves[thisPly] + " "; 682 } 683 if (thisPly < StartPly + PlyNumber) { theObj.innerHTML += "..."; } 684 685 fixHeaderItem(null, "GameWhiteClock", "white clock"); 686 fixHeaderItem(null, "GameBlackClock", "black clock"); 687 fixColorFlag(); 688 fixECO(); 689 690<!-- AppCheck: customFunctionOnMove --> 691 692} 693 694 695function fixColorFlag() { 696 var theObj; 697 698 if (showColorFlag) { 699 var whiteFlagPadding = (horizontalLayout || ((theObj = document.getElementById("GameWhiteClock")) && (theObj.innerHTML))); 700 if (theObj = document.getElementById("whiteColorFlag")) { 701 theObj.style.display = "inline-block"; 702 theObj.style.visibility = CurrentPly % 2 ? "hidden" : "visible"; 703 } 704 if (theObj = document.getElementById("whiteColorFlagFiller")) { 705 theObj.style.display = whiteFlagPadding ? "inline-block" : "none"; 706 theObj.style.visibility = "hidden"; 707 } 708 var blackFlagPadding = (horizontalLayout || ((theObj = document.getElementById("GameBlackClock")) && (theObj.innerHTML))); 709 if (theObj = document.getElementById("blackColorFlag")) { 710 theObj.style.display = "inline-block"; 711 theObj.style.visibility = CurrentPly % 2 ? "visible" : "hidden"; 712 } 713 if (theObj = document.getElementById("blackColorFlagFiller")) { 714 theObj.style.display = blackFlagPadding ? "inline-block" : "none"; 715 theObj.style.visibility = "hidden"; 716 } 717 } 718} 719 720function fixECO() { 721 var theObj = document.getElementById("GameECOFiller"); 722 if (theObj) { 723 theObj.style.display = horizontalLayout ? "none" : ""; 724 } 725} 726 727function searchPlayer(name, FideId) { 728 if (typeof(openFidePlayerUrl) == "function") { openFidePlayerUrl(name, FideId); } 729} 730 731function customShortcutKey_Shift_1() { 732 searchPlayer(gameWhite[currentGame], customPgnHeaderTag('WhiteFideId')); 733} 734 735function customShortcutKey_Shift_2() { 736 searchPlayer(gameBlack[currentGame], customPgnHeaderTag('BlackFideId')); 737} 738 739function customShortcutKey_Shift_3() { 740 toggleBareChessboard(); 741} 742 743var showFullscreenChessboardTimeout = null; 744function customShortcutKey_Shift_4() { 745 if (showFullscreenChessboardTimeout) { 746 clearTimeout(showFullscreenChessboardTimeout); 747 showFullscreenChessboardTimeout = null; 748 showFullscreenChessboard(true); 749 } else { 750 showFullscreenChessboardTimeout = setTimeout("showFullscreenChessboardTimeout = false; showFullscreenChessboard(false);", 333); 751 } 752} 753 754function customShortcutKey_Shift_5() { 755 SetHighlight(!highlightOption); 756} 757 758function customShortcutKey_Shift_6() { 759 toggleShowEco(); 760} 761 762function customShortcutKey_Shift_7() { 763 toggleColorFlag(); 764} 765 766// customShortcutKey_Shift_8 defined by engine.js 767// customShortcutKey_Shift_9 defined by engine.js 768// customShortcutKey_Shift_0 defined by engine.js 769 770function toggleBareChessboard() { 771 bare = !bare; 772 myOnResize(); 773 updateBareShortcut(); 774} 775 776function showFullscreenChessboard(newWin) { 777 var win = window; 778 if (newWin) { win.open(location.href.replace(/(pieceBaseSize|pbs)=[^&]*/gi, ""), "_blank"); } 779 else { 780 while (win.parent !== win) { win = win.parent; } 781 win.location.href = location.href.replace(/(pieceBaseSize|pbs)=[^&]*/gi, ""); 782 } 783} 784 785function toggleInitialHalfmove(reset2default) { 786 SetInitialHalfmove(reset2default ? 'start' : (initialHalfmove == 'end' ? 'start' : 'end'), true); 787 GoToMove(initialHalfmove == 'end' ? StartPlyVar[0] + PlyNumberVar[0] : StartPlyVar[0], 0); 788} 789 790 791boardShortcut("E7", "toggle ECO code", function(t,e){ toggleShowEco(); }); 792 793// disable FlipBoard functionality, otherwise remember to redefine FlipBoard() to include myOnResize() 794var warnedFlipBoard = false; 795function FlipBoard() { if (!warnedFlipBoard) { myAlert("warning: flip board functionality disabled", false, true); warnedFlipBoard = true; } } 796 797 798boardShortcut("F7", "toggle side to move flag", function(t,e){ toggleColorFlag(); }); 799 800if (LiveBroadcastDelay === 0) { 801 boardShortcut("G6", "toggle initial halfmove", function(t,e){ toggleInitialHalfmove(e.shiftKey); }); 802} 803 804if ((window.parent !== window) && (!engineWinPrepareIdle)) { 805 boardShortcut("H5", "show fullscreen chessboard", function(t,e){ showFullscreenChessboard(e.shiftKey); }); 806} 807 808function updateBareShortcut() { 809 boardShortcut("G5", bare ? "unhide game info\n\n" + gameTooltipInfo() : "maximize chessboard and hide game info", function(t,e){ toggleBareChessboard(); }); 810} 811 812function meaningfulHeader(tagValue) { 813 return ((typeof(tagValue) == "string") && (tagValue.match(/[^\s?.-]/))); 814} 815 816function gameTooltipInfo() { 817 var headerValue; 818 var str = "game " + (currentGame+1) + " of " + numberOfGames; 819 if (LiveBroadcastDelay > 0) { str += ", " + LiveBroadcastGamesRunning + " live"; } 820 if (meaningfulHeader(gameEvent[currentGame])) { str+= "\nevent: " + gameEvent[currentGame]; 821 if (meaningfulHeader(headerValue = customPgnHeaderTag("Section"))) { str+= " " + headerValue; } 822 if (meaningfulHeader(headerValue = customPgnHeaderTag("Stage"))) { str+= " " + headerValue; } 823 } 824 if (meaningfulHeader(gameSite[currentGame])) { str+= "\nsite: " + gameSite[currentGame]; } 825 if (meaningfulHeader(gameDate[currentGame])) { str+= "\ndate: " + gameDate[currentGame]; } 826 if (meaningfulHeader(gameRound[currentGame])) { str+= "\nround: " + gameRound[currentGame]; } 827 if (meaningfulHeader(gameWhite[currentGame])) { str+= "\nwhite: " + gameWhite[currentGame]; 828 if (meaningfulHeader(headerValue = customPgnHeaderTag("WhiteTitle"))) { str+= " " + headerValue; } 829 if (meaningfulHeader(headerValue = customPgnHeaderTag("WhiteElo"))) { str+= " " + headerValue; } 830 if (meaningfulHeader(headerValue = customPgnHeaderTag("WhiteTeam"))) { str+= " " + headerValue; } 831 } 832 if (meaningfulHeader(gameBlack[currentGame])) { str+= "\nblack: " + gameBlack[currentGame]; 833 if (meaningfulHeader(headerValue = customPgnHeaderTag("BlackTitle"))) { str+= " " + headerValue; } 834 if (meaningfulHeader(headerValue = customPgnHeaderTag("BlackElo"))) { str+= " " + headerValue; } 835 if (meaningfulHeader(headerValue = customPgnHeaderTag("BlackTeam"))) { str+= " " + headerValue; } 836 } 837 if (meaningfulHeader(gameResult[currentGame])) { str+= "\nresult: " + gameResult[currentGame]; } 838 return str; 839} 840 841function searchNextEventRound(backward) { 842 searchPgnGame('\\[\\s*Event\\s*"(?!' + fixRegExp(gameEvent[currentGame]) + '"\\s*\\])|\\[\\s*Section\\s*"(?!' + fixRegExp(customPgnHeaderTag("Section")) + '"\\s*\\])|\\[\\s*Stage\\s*"(?!' + fixRegExp(customPgnHeaderTag("Stage")) + '"\\s*\\])|\\[\\s*Round\\s*"(?!' + fixRegExp(gameRound[currentGame]) + '"\\s*\\])', backward); 843} 844 845var lastOrientation; 846var lastOrientationTimeout = null; 847simpleAddEvent(window, "orientationchange", function() { 848 var theObj; 849 if (typeof(window.orientation) == "undefined") { return; } 850 if (window.orientation === lastOrientation) { return; } 851 var lastOrientationTimeoutString = "lastOrientationTimeout = null;"; 852 if (lastOrientationTimeout) { 853 clearTimeout(lastOrientationTimeout); 854 if ((theObj = document.getElementById("GameList")) && (theObj.style.display)) { selectGameList(-1); } 855 lastOrientationTimeoutString += " refreshPgnSource();"; 856 } else { 857 setTimeout("autoscrollGameListBody(-1);", 111); 858 } 859 lastOrientationTimeout = setTimeout(lastOrientationTimeoutString, 1800); 860 lastOrientation = window.orientation; 861}); 862 863</script> 864 865</head> 866 867<body onResize="myOnResize();" onLoad="myOnResize();"> 868 869<!-- paste your PGN below and make sure you dont specify an external source with SetPgnUrl() --> 870<form style="display:none;"><textarea style="display:none;" id="pgnText"> 871 872</textarea></form> 873<!-- paste your PGN above and make sure you dont specify an external source with SetPgnUrl() --> 874 875<div style="display:none;" id="GameSelector"></div> 876 877<div class="gameList" style="display:none;" id="GameList"> 878<div class="gameListHeader" id="GameListHeader"><div class="gameListHeaderItem"><span class="gameListHeaderButton" onclick="selectGameList(-1);" title="back to chessboard"><=</span></div><div class="gameListHeaderItem"><span class="gameListHeaderButton" onclick="autoscrollGameListBody(0); this.blur();" title="scroll to first page"><<</span></div><div class="gameListHeaderItem"><span class="gameListHeaderButton" onclick="if (theObj = document.getElementById('GameListBody')) { autoscrollGameListBody(Math.floor(theObj.scrollTop / gameListLineHeight) - gameListNumGames); } this.blur();" title="scroll to previous page"><</span></div><div class="gameListHeaderItem"><span class="gameListHeaderButton" onclick="autoscrollGameListBody(-1); this.blur();" title="scroll to current game">><</span></div><div class="gameListHeaderItem"><span class="gameListHeaderButton" onclick="if (theObj = document.getElementById('GameListBody')) { autoscrollGameListBody(Math.floor(theObj.scrollTop / gameListLineHeight) + gameListNumGames); } this.blur();" title="scroll to next page">></span></div><div class="gameListHeaderItem"><span class="gameListHeaderButton" onclick="autoscrollGameListBody(numberOfGames); this.blur();" title="scroll to last page">>></span></div><div class="gameListHeaderItem"><span class="gameListHeaderButton" onclick="toggleGameListHorizontalScroll(); this.blur();" title="horizontal scroll"><></span></div></div> 879<div class="gameListBody" id="GameListBody"><div class="gameListBodyItems" id="GameListBodyItems"></div></div> 880</div> 881 882<div id="GameBoard"></div> 883 884<div id="HeaderContainer" class="headerContainer"> 885<div class="firstVariableSpacer"> </div> 886<div> <span id="GameSite" title="site"></span><span id="GameDate" title="date"></span> </div> 887<div> <span style="cursor:pointer;" onclick="searchNextEventRound(event.shiftKey); this.blur();"><span id="GameEvent" title="event"></span><span id="GameSection" title="section"></span><span id="GameStage" title="stage"></span><span id="GameRound" title="round"></span></span> </div> 888<div class="variableSpacer"> </div> 889<div> <span id="GameWhiteClockLine"><span style="display:inline-block;" title="white to move"><span class="colorFlag" style="background:white; display:none;" id="whiteColorFlag"></span></span><span id="GameWhiteClock" style="cursor:pointer;" onclick="if (!showColorFlag) { toggleColorFlag(); setTimeout('if (showColorFlag) { toggleColorFlag(); }', 1111); } this.blur();" title="white clock"></span><span style="display:inline-block;"><span class="colorFlag" style="background:white; display:none;" id="whiteColorFlagFiller"></span></span></span> </div> 890<div> <span id="GameWhite" style="font-weight:bold; cursor:pointer;" onclick="searchPlayer(this.innerHTML, customPgnHeaderTag('WhiteFideId')); this.blur();" title="white player"></span><span id="GameWhiteTitle" title="white title"></span><span id="GameWhiteElo" title="white elo"></span><span id="GameWhiteTeam" title="white team"></span><span style="font-weight:bold;"> </span></div> 891<div> <span id="GameBlack" style="font-weight:bold; cursor:pointer;" onclick="searchPlayer(this.innerHTML, customPgnHeaderTag('BlackFideId')); this.blur();" title="black player"></span><span id="GameBlackTitle" title="black title"></span><span id="GameBlackElo" title="black elo"></span><span id="GameBlackTeam" title="black team"></span><span style="font-weight:bold;"> </span></div> 892<div> <span id="GameBlackClockLine"><span style="display:inline-block;" title="black to move"><span class="colorFlag" style="background:black; display:none;" id="blackColorFlag"></span></span><span id="GameBlackClock" style="cursor:pointer;" onclick="if (!showColorFlag) { toggleColorFlag(); setTimeout('if (showColorFlag) { toggleColorFlag(); }', 1111); } this.blur();" title="black clock"></span><span style="display:inline-block;"><span class="colorFlag" style="background:black; display:none;" id="blackColorFlagFiller"></span></span></span> </div> 893<div class="variableSpacer"> </div> 894<div> <span id="GameResultLine"><span id="GameECOFiller" style="visibility:hidden; padding-right:2.5em;"></span><span id="GameResult" style="font-weight:bold; cursor:pointer;" onclick="if (!showEco) { toggleShowEco(); setTimeout('if (showEco) { toggleShowEco(); }', 1111); } this.blur();" title="result"></span><span style="padding-left:2.5em;" id="GameECO"></span></span><span style="font-weight:bold;"> </span></div> 895<div class="variableSpacer"> </div> 896<div class="leftRightSpacing"> <span id="GamePrevMoves" style="cursor:pointer;" onclick="GoToMove(CurrentPly - 1); this.blur();" title="previous moves"></span><span id="GameCurrMove" style="font-weight:bold; cursor:pointer;" onclick="if (!highlightOption) { SetHighlight(!highlightOption); setTimeout('if (highlightOption) { SetHighlight(!highlightOption); }', 1111); } this.blur();" title="current move as shown on chessboard"></span><span id="GameNextMoves" style="cursor:pointer;" onclick="GoToMove(CurrentPly + 1); this.blur();" title="next moves"></span><span style="font-weight:bold;"> </span></div> 897<div class="variableSpacer"> </div> 898<center><div id="GameButtons" class="leftRightSpacing gameButtons"></div></center> 899<div class="liveStatusLine"> <span id="GameLiveStatusExtraInfoLeft" class="leftRightSpacing gameLiveStatusExtraInfoLeft" style="visibility:hidden;"></span><span id="GameLiveStatus" class="leftRightSpacing" style="cursor:pointer;"></span><span id="GameLiveStatusExtraInfoRight" class="leftRightSpacing" style="visibility:hidden;"></span> </div> 900<div class="variableSpacer"> </div> 901<div id="ShowGameList" class="leftRightSpacing" style="visibility:hidden;"> <span id="ShowGameListLink" class="showGameListLink" style="cursor:pointer;" onclick="showGameList();"></span> </div> 902</div> 903 904<script type="text/javascript"> 905"use strict"; 906 907var theObj; 908 909if (LiveBroadcastDelay && LiveBroadcastDemo) { 910 if (theObj = document.getElementById("GameLiveStatusExtraInfoRight")) { 911 theObj.innerHTML = "demo"; 912 theObj.title = "this is a broadcast simulation"; 913 theObj.style.visibility = "visible"; 914 } 915 if (theObj = document.getElementById("GameLiveStatusExtraInfoLeft")) { 916 theObj.innerHTML = "demo"; 917 } 918} 919 920<!-- AppCheck: footer --> 921 922</script> 923 924</body> 925 926</html> 927