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 live broadcast</title> 14 15<link rel="icon" sizes="16x16" href="pawn.ico" /> 16 17<script src="pgn4web.js" type="text/javascript"></script> 18 19<script type="text/javascript"> 20 "use strict"; 21 22 var readyToSendPgn = false; 23 24 var pgnData_default = "live/live.pgn"; 25 var maxBoards_default = 8; 26 var displayGame_default = 1; 27 var refreshMinutes_default = 1; 28 var boardTool_default = "tile"; 29 var flipBoards_default = "none"; 30 31 var thisRegExp = /(&|\?)(help|h)=(true|t)(&|$)/i; 32 if (window.location.search.match(thisRegExp) !== null) { 33 alert("pgn4web live-mosaic.html parameters" + "\n\n" + 34 " - pgnData = file.pgn" + "\n\n" + 35 " - maxBoards = max number of boards to display in a page (default " + maxBoards_default + ")" + "\n\n" + 36 " - displayGame = number of game for display, negative counts backwards (default " + displayGame_default + ")" + "\n\n" + 37 " - refreshMinutes = live broadcast delay (default " + refreshMinutes_default + ")" + "\n\n" + 38 " - refreshDemo = if set true sets live demo mode (default false)" + "\n\n" + 39 // " - demoPly = comma separated list of starting plies for each of the live demo games (default blank)" + "\n\n" + 40 " - boardTool = tile|stone (default " + boardTool_default + ")" + "\n\n" + 41 " - flipBoards = none|even|odd|all (default " + flipBoards_default + ")" + "\n\n" + 42 " - hideFinishedGamesClocks = if set treu hides clocks for finished games (default false)" + "\n\n" + 43 " - headlessPage = if set true displays a page without heading (default false)" + "\n\n" + 44 // " - barePadding = if not null, displays a page with given padding and without header/footer (default null)" + "\n\n" + 45 // " - backgroundColorHex = if not null and barePadding also not null, background color hex code, like FF0000 (default null)" + "\n\n" + 46 " - help = true"); 47 } 48 49 var pgnData = pgnData_default; 50 thisRegExp = /(&|\?)(pgnData|pd)=([^&]*)(&|$)/i; 51 if (window.location.search.match(thisRegExp) !== null) { 52 pgnData = unescape(window.location.search.match(thisRegExp)[3]); 53 } else { 54 // accepts pgnData as alias for pgnFile for consistency with board.html 55 thisRegExp = /(&|\?)(pgnFile|pf)=([^&]*)(&|$)/i; 56 if (window.location.search.match(thisRegExp) !== null) { 57 pgnData = unescape(window.location.search.match(thisRegExp)[3]); 58 } 59 } 60 61 SetPgnUrl(pgnData); // if set, this has precedence over the inline PGN in the HTML file 62 63 var maxBoards = getMaxBoardFromLocalStorage(); 64 thisRegExp = /(&|\?)(maxBoards|mb)=([\d]*)(&|$)/i; 65 if (window.location.search.match(thisRegExp) !== null) { 66 maxBoards = unescape(window.location.search.match(thisRegExp)[3]); 67 } 68 maxBoards = parseInt(maxBoards, 10); 69 if (isNaN(maxBoards) || (maxBoards < 1)) { maxBoards = maxBoards_default; } 70 71 var displayGame = displayGame_default; 72 thisRegExp = /(&|\?)(displayGame|dg)=([+-]?[\d]+)(&|$)/i; 73 if (window.location.search.match(thisRegExp) !== null) { 74 displayGame = unescape(window.location.search.match(thisRegExp)[3]); 75 } 76 displayGame = parseInt(displayGame, 10); 77 if (displayGame === 0) { displayGame = 1; } 78 79 var alertFlag = false; 80 var demoFlag = false; 81 thisRegExp = /(&|\?)(refreshDemo|rd)=([^&]*)(&|$)/i; 82 if (window.location.search.match(thisRegExp) !== null) { 83 var refreshDemo = unescape(window.location.search.match(thisRegExp)[3]); 84 if ((refreshDemo == "true") || (refreshDemo == "t")) { alertFlag = demoFlag = true; } 85 } 86 87 thisRegExp = /(&|\?)(demoPly|dp)=([^&]*)(&|$)/i; 88 if (window.location.search.match(thisRegExp) !== null) { 89 gameDemoMaxPly = unescape(window.location.search.match(thisRegExp)[3]).split(","); 90 var p; 91 for (var g in gameDemoMaxPly) { gameDemoMaxPly[g] = isNaN(p = parseInt(gameDemoMaxPly[g], 10)) ? 0 : p; } 92 } 93 94 var refreshMinutes = refreshMinutes_default; 95 var stepFlag = true; 96 thisRegExp = /(&|\?)(refreshMinutes|rm)=([^&]*)(&|$)/i; 97 if (window.location.search.match(thisRegExp) !== null) { 98 refreshMinutes = parseFloat(unescape(window.location.search.match(thisRegExp)[3])); 99 if (isNaN(refreshMinutes)) { refreshMinutes = refreshMinutes_default; } 100 if (refreshMinutes <= 0) { refreshMinutes = refreshMinutes_default; } 101 } 102 103 SetLiveBroadcast(refreshMinutes, alertFlag, demoFlag, stepFlag); 104 105 function getMaxBoardFromLocalStorage() { 106 var mb; 107 try { mb = localStorage.getItem("pgn4web_chess_live_mosaic_viewer_maxBoards"); } 108 catch(e) { return maxBoards_default; } 109 return mb === null ? maxBoards_default : mb; 110 } 111 112 function setMaxBoardToLocalStorage(mb) { 113 try { localStorage.setItem("pgn4web_chess_live_mosaic_viewer_maxBoards", mb); } 114 catch(e) { return false; } 115 return true; 116 } 117 118 var boardTool = boardTool_default; 119 thisRegExp = /(&|\?)(boardTool|bt)=(tile|t|stone|s)(&|$)/i; 120 if (window.location.search.match(thisRegExp) !== null) { 121 boardTool = unescape(window.location.search.match(thisRegExp)[3]); 122 if (boardTool == "t") { boardTool = "tile"; } 123 if (boardTool == "s") { boardTool = "stone"; } 124 } 125 var boardToolFrameHeight = (boardTool == "tile") ? 306 : 318; 126 var boardToolFrameWidth = 256; 127 128 var flipBoards = flipBoards_default; 129 thisRegExp = /(&|\?)(flipBoards|fb)=(none|n|even|e|odd|o|all|a)(&|$)/i; 130 if (window.location.search.match(thisRegExp) !== null) { 131 flipBoards = unescape(window.location.search.match(thisRegExp)[3]); 132 if (flipBoards == "n") { flipBoards = "none"; } 133 if (flipBoards == "e") { flipBoards = "even"; } 134 if (flipBoards == "o") { flipBoards = "odd"; } 135 if (flipBoards == "a") { flipBoards = "all"; } 136 } 137 138 var hideFinishedGamesClocks = false; 139 thisRegExp = /(&|\?)(hideFinishedGamesClocks|hfgc)=([^&]*)(&|$)/i; 140 if (window.location.search.match(thisRegExp) !== null) { 141 var hideFinishedGamesClocksValue = unescape(window.location.search.match(thisRegExp)[3]); 142 if ((hideFinishedGamesClocksValue == "true") || (hideFinishedGamesClocksValue == "t")) { hideFinishedGamesClocks = true; } 143 } 144 145 var headlessPage = false; 146 thisRegExp = /(&|\?)(headlessPage|hp)=([^&]*)(&|$)/i; 147 if (window.location.search.match(thisRegExp) !== null) { 148 var headlessPageValue = unescape(window.location.search.match(thisRegExp)[3]); 149 if ((headlessPageValue == "true") || (headlessPageValue == "t")) { headlessPage = true; } 150 } 151 152 // undocumented features 153 154 var barePadding = ""; 155 thisRegExp = /(&|\?)(barePadding|bp)=([^&]*)(&|$)/i; 156 if (window.location.search.match(thisRegExp) !== null) { 157 barePadding = unescape(window.location.search.match(thisRegExp)[3]); 158 } 159 barePadding = barePadding.replace(/[^a-zA-Z0-9%\s]/g, ""); 160 161 var backgroundColorHex = ""; 162 thisRegExp = /(&|\?)(backgroundColorHex|bch)=([0-9A-Fa-f]{6})(&|$)/i; 163 if (window.location.search.match(thisRegExp) !== null) { 164 backgroundColorHex = unescape(window.location.search.match(thisRegExp)[3]); 165 } 166 167 SetImagePath("images/alpha/24"); // just to avoid console errors 168 169 // disable FlipBoard function 170 function FlipBoard() { } 171 172</script> 173 174 175<style type="text/css"> 176 177@import url("fonts/pgn4web-font-LiberationSans.css"); 178 179html, 180body { 181 margin: 0px; 182 padding: 0px; 183} 184 185body { 186 color: black; 187 background: white; 188 font-family: sans-serif; 189 padding: 1.75em; 190 overflow-x: hidden; 191 overflow-y: auto; 192 193 -webkit-user-select: none; 194 -moz-user-select: none; 195 -ms-user-select: none; 196 -o-user-select: none; 197 user-select: none; 198 -webkit-text-size-adjust: none; 199 -moz-text-size-adjust: none; 200 -ms-text-size-adjust: none; 201 -o-text-size-adjust: none; 202 text-size-adjust: none; 203 -webkit-touch-callout: none; 204} 205 206a { 207 color: black; 208 text-decoration: none; 209} 210 211a:hover { 212 color: red; 213} 214 215.header { 216 color: red; 217 text-decoration: none; 218} 219 220.beforeBoards { 221 display: inline-block; 222 text-align: right; 223 margin-top: 10px; 224 height: 15px; 225 width: 100%; 226 overflow: hidden; 227} 228 229.afterBoards { 230 display: inline-block; 231 text-align: right; 232 height: 40px; 233 width: 100%; 234 overflow: hidden; 235} 236 237.menuLine { 238 font-size: 12px; 239 font-family: 'pgn4web Liberation Sans', sans-serif; 240 line-height: 20px; 241} 242 243.menuLink { 244 display: inline-block; 245 width: 2em; 246} 247 248.commandLink:hover { 249 text-transform: uppercase; 250} 251 252.hiddenFrame, 253.visibleFrame { 254 margin-left: 20px; 255 margin-right: 20px; 256 margin-top: 15px; 257 margin-bottom: 5px; 258} 259 260.hiddenFrame { 261 display: none; 262} 263 264.visibleFrame { 265 display: inline; 266} 267 268.infoMessage { 269 font-weight: bold; 270 text-align: center; 271} 272 273</style> 274 275</head> 276 277<body id="body"> 278 279<script type="text/javascript"> 280"use strict"; 281 282function fixCSSforBackgroundColorHex() { 283 document.body.style.backgroundColor = "#" + backgroundColorHex; 284} 285 286function fixCSSforHeadelessPage() { 287 document.write("<style type='text/css'> body { color: #AAAAAA; } a { color: #AAAAAA; } a:hover { color: black; } .beforeBoards { margin-top: 15px; } </style>"); 288} 289 290function fixCSSforBarePadding() { 291 document.write("<style type='text/css'> body { padding: " + barePadding + "; } .beforeBoards, .afterBoards { display: none; } .menuLine { height: 0; visibility: hidden; } </style>"); 292} 293 294function printHeader() { 295 document.write("<h1 style='margin-top:0px; padding-top:0px; text-align:right;'><span style='float:left; color:red;'>pgn4web chess live broadcast</span><a href='.' onfocus='this.blur();' style='width:49px; height:29px; background:url(pawns.png) -47px -15px; vertical-align:baseline; display:inline-block;'></a></h1>"); 296} 297 298function printMenu() { 299 document.write("<div id='rightMenu' class='menuLine' style='text-align:right; float:right;'></div><div id='leftMenu' class='menuLine' style='text-align:left; float:left;'><span id='GameLiveStatusDemo' title='this is a simulation of the live broadcast functionality'></span><span id='GameLiveStatus' style='display:none;'></span></div><div id='infoMessage' class='menuLine infoMessage'>...loading PGN data...</div>"); 300} 301 302function replayLastMoves() { 303 var wf, rpmm; 304 for (var thisBoard in boardId) { 305 if ((wf = window.frames["board" + boardId[thisBoard]]) && (rpmm = wf.replayPreviousMovesMosaic)) { 306 rpmm(LiveBroadcastEnded); 307 } 308 } 309} 310 311var nextBoardId = 1000; 312var boardId = new Array(); 313 314function updateBoardFrames(newMaxBoards) { 315 var theObj = document.getElementById("boardFrames"); 316 if (theObj) { 317 theObj.innerHTML = ""; 318 for (var board = 0; board < newMaxBoards; board++) { 319 theObj.innerHTML += "<iframe src='live-mosaic-" + boardTool + ".html?ut=t&rm=" + refreshMinutes + "' class='hiddenFrame' id='board" + nextBoardId + "' name='board" + nextBoardId + "' width='" + boardToolFrameWidth + "' height='" + boardToolFrameHeight + "' frameborder='0' marginheight='0' marginwidth='0' scrolling='no'>your web browser and/or your host do not support iframes as required to display the chessboard</iframe>"; 320 boardId[board] = nextBoardId++; 321 } 322 } 323 maxBoards = newMaxBoards; 324 setMaxBoardToLocalStorage(maxBoards); 325} 326 327if (headlessPage || (barePadding !== "")) { 328 fixCSSforHeadelessPage(); 329 if (barePadding !== "") { 330 fixCSSforBarePadding(); 331 if (backgroundColorHex !== "") { 332 fixCSSforBackgroundColorHex(); 333 } 334 } 335 printMenu(); 336} else { 337 printHeader(); 338} 339 340</script> 341 342<center> 343<a class="beforeBoards" name="boards" href="javascript:void(0);" onclick="goToHash('boards');" onfocus="this.blur();"> </a> 344<div id="boardFrames"></div> 345<a class="afterBoards" name="bottom" href="javascript:void(0);" onclick="goToHash('');" onfocus="this.blur();"> </a> 346</center> 347 348<script type="text/javascript"> 349"use strict"; 350 351 352if (!headlessPage && (barePadding === "")) { printMenu(); } 353 354 355var pgn4webClearShortCutSquaresForChildFrames = [ ["DH", "8"], ["H", "7"], ["ABH", "6"] ]; 356 357var filteredGames = new Array(); 358var unfilteredGames = new Array(); 359var numberOfGamesForDisplay = 0; 360var firstGame; 361var startGame; 362var firstBoardDisplayGame = 0; 363var gamesForHiding; 364 365function firstFromDisplayGame(dGame) { 366 if (dGame > numberOfGames) { dGame = numberOfGames; } 367 else if (dGame < -numberOfGames) { dGame = -numberOfGames; } 368 369 if (dGame > 0) { dGame--; } // positive displayGame starts from +1 as first game 370 371 var dGameAdjustment = 0; 372 if (filteredGames.length > 0) { 373 var g; 374 if (dGame >= 0) { 375 for (g = 0; g < dGame; g++) { 376 if (checkForHiddenGame(gameEvent[g], gameSite[g], gameDate[g], gameRound[g], gameWhite[g], gameBlack[g])) { 377 dGameAdjustment--; 378 } 379 } 380 } else { 381 for (g = numberOfGames - 1; g > numberOfGames + dGame; g--) { 382 if (checkForHiddenGame(gameEvent[g], gameSite[g], gameDate[g], gameRound[g], gameWhite[g], gameBlack[g])) { 383 dGameAdjustment++; 384 } 385 } 386 } 387 } 388 389 return (dGame + dGameAdjustment); 390} 391 392function gameKey(event, site, date, round, white, black) { 393 var key = ""; 394 key += "[" + (typeof(event) == "string" ? event : "") + "]"; 395 key += "[" + (typeof(site) == "string" ? site : "") + "]"; 396 key += "[" + (typeof(round) == "string" ? round : "") + "]"; 397 key += "[" + (typeof(white) == "string" ? white : "") + "]"; 398 key += "[" + (typeof(black) == "string" ? black : "") + "]"; 399 return key; 400} 401 402function pgn4webHideChildFrameGame(event, site, date, round, white, black, test) { 403 var res = false; 404 if (numberOfGamesForDisplay > 1) { 405 res = hideGame(event, site, date, round, white, black, test); 406 if (res && (test !== true)) { 407 firstGame = firstFromDisplayGame(firstBoardDisplayGame); 408 customFunctionOnPgnTextLoad(); 409 } 410 } 411 return res; 412} 413 414function hideGame(event, site, date, round, white, black, test) { 415 var key = gameKey(event, site, date, round, white, black); 416 var meaningful = (key.match(/[A-Za-z0-9]/) !== null); 417 if (meaningful && (test !== true)) { 418 for (var f in filteredGames) { if (key == filteredGames[f]) { return false; } } 419 filteredGames.push(key); 420 } 421 return meaningful; 422} 423 424function checkForHiddenGame(event, site, date, round, white, black) { 425 var key = gameKey(event, site, date, round, white, black); 426 for (var f in filteredGames) { 427 if (key == filteredGames[f]) { return true; } 428 } 429 return false; 430} 431 432function hideEndedGames() { 433 for (var g = 0; g < numberOfGames; g++) { 434 if ((typeof(gameResult[g]) == "undefined") || (gameResult[g].indexOf("*") == -1)) { 435 hideGame(gameEvent[g], gameSite[g], gameDate[g], gameRound[g], gameWhite[g], gameBlack[g]); 436 } 437 } 438 firstGame = firstFromDisplayGame(firstBoardDisplayGame); 439 customFunctionOnPgnTextLoad(); 440} 441 442function restoreHiddenGames() { 443 filteredGames = new Array(); 444 firstGame = firstFromDisplayGame(firstBoardDisplayGame); 445 customFunctionOnPgnTextLoad(); 446} 447 448function pgnGameForBoard(gameNum) { 449 if (!LiveBroadcastDemo) { return fullPgnGame(gameNum); } 450 451 if (gameDemoMaxPly[gameNum] > gameDemoLength[gameNum]) { return fullPgnGame(gameNum); } 452 453 Init(gameNum); 454 455 var localPgnGame = ""; 456 if (gameEvent[gameNum]) { localPgnGame += "[Event \"" + gameEvent[gameNum] + "\"]\n"; } 457 if (gameSite[gameNum]) { localPgnGame += "[Site \"" + gameSite[gameNum] + "\"]\n"; } 458 if (gameDate[gameNum]) { localPgnGame += "[Date \"" + gameDate[gameNum] + "\"]\n"; } 459 if (gameRound[gameNum]) { localPgnGame += "[Round \"" + gameRound[gameNum] + "\"]\n"; } 460 if (gameWhite[gameNum]) { localPgnGame += "[White \"" + gameWhite[gameNum] + "\"]\n"; } 461 if (gameBlack[gameNum]) { localPgnGame += "[Black \"" + gameBlack[gameNum] + "\"]\n"; } 462 if (gameResult[gameNum]) { localPgnGame += "[Result \"" + gameResult[gameNum] + "\"]\n"; } 463 if (gameFEN[gameNum]) { localPgnGame += "[FEN \"" + gameFEN[gameNum] + "\"]\n"; } 464 if (gameSetUp[gameNum]) { localPgnGame += "[SetUp \"" + gameSetUp[gameNum] + "\"]\n"; } 465 if (gameVariant[gameNum]) { localPgnGame += "[Variant \"" + gameVariant[gameNum] + "\"]\n"; } 466 if (gameInitialWhiteClock[gameNum]) { localPgnGame += "[WhiteClock \"" + gameInitialWhiteClock[gameNum] + "\"]\n"; } 467 if (gameInitialBlackClock[gameNum]) { localPgnGame += "[BlackClock \"" + gameInitialBlackClock[gameNum] + "\"]\n"; } 468 var theseTags = ["WhiteTeam", "BlackTeam", "WhiteFideId", "BlackFideId", "TimeControl"]; 469 var thisTagValue; 470 for (var ii in theseTags) { 471 thisTagValue = customPgnHeaderTag(theseTags[ii]); 472 if (thisTagValue) { localPgnGame += "[" + theseTags[ii] + " \"" + thisTagValue + "\"]\n"; } 473 } 474 localPgnGame += "\n"; 475 476 var gameDemoPlyNumber = gameDemoMaxPly[gameNum] <= gameDemoLength[gameNum] ? gameDemoMaxPly[gameNum] : gameDemoLength[gameNum] + 1; 477 for (var thisPly = StartPly; thisPly < StartPly + gameDemoPlyNumber; thisPly++) { 478 if (thisPly % 2) { 479 if (thisComment = MoveComments[thisPly].replace(/{/g, "")) { 480 localPgnGame += "{" + thisComment + "} " + ((thisPly+1)/2) + "... "; 481 } 482 localPgnGame += Moves[thisPly] + " \n"; 483 } else { 484 if (thisComment = MoveComments[thisPly].replace(/{/g, "")) { localPgnGame += "{" + thisComment + "} "; } 485 localPgnGame += (thisPly/2+1) + ". " + Moves[thisPly] + " "; 486 } 487 } 488 var thisComment = MoveComments[thisPly].replace(/{/g, ""); 489 if (thisComment) { localPgnGame += "{" + thisComment + "} "; } 490 localPgnGame += " *"; 491 492 return localPgnGame; 493} 494 495function updateBoard(thisBoardId) { 496 var gameNum = -1; 497 var thisBoard = -1; 498 var thisFrame, gameForBoard, thisPgnGame, thisFlipped, thisFrameClass; 499 for (thisBoard in boardId) { if (thisBoardId === boardId[thisBoard]) { break; } } 500 thisBoard = parseInt(thisBoard, 10); 501 if ((thisBoard < boardId.length) && (thisFrame = document.getElementById("board" + thisBoardId))) { 502 if (thisBoard < numberOfGamesForDisplay) { 503 startGame = startFromFirstGame(firstGame); 504 if (startGame >= 0) { gameForBoard = (startGame + thisBoard) % numberOfGamesForDisplay; } 505 else { gameForBoard = (2 * numberOfGamesForDisplay + startGame - thisBoard) % numberOfGamesForDisplay; } 506 gameNum = unfilteredGames[gameForBoard]; 507 thisPgnGame = simpleHtmlentitiesDecode(pgnGameForBoard(gameNum)); 508 thisFlipped = (((flipBoards == "even") && (gameNum % 2 === 1)) || ((flipBoards == "odd") && (gameNum % 2 === 0)) || (flipBoards == "all")); 509 thisFrameClass = "visibleFrame"; 510 } else { 511 thisPgnGame = ""; 512 thisFlipped = (flipBoards == "all"); 513 thisFrameClass = "hiddenFrame"; 514 } 515 try { 516 if (window.frames["board" + thisBoardId].readyToReceivePgn) { 517 window.frames["board" + thisBoardId].pauseLiveBroadcast(); 518 window.frames["board" + thisBoardId].document.getElementById("pgnText").value = thisPgnGame; 519 if (thisFlipped !== window.frames["board" + thisBoardId].IsRotated) { window.frames["board" + thisBoardId].FlipBoard(); } 520 window.frames["board" + thisBoardId].hideFinishedGamesClocks = hideFinishedGamesClocks; 521 window.frames["board" + thisBoardId].refreshPgnSource(); 522 window.frames["board" + thisBoardId].clearShortcutSquares("A","8"); 523 } // else { myAlert("warning: board #" + thisBoard + " not ready"); } 524 } catch(e) { myAlert("error: failed accessing iframe for board #" + thisBoard, true); } 525 thisFrame.className = thisFrameClass; 526 } 527 return gameNum; 528} 529 530var firstLoadNewBoards = true; 531var firstLoadPgnText = true; 532var liveBroadcastUpdateTicker = 0; 533var previousPgnGameLength = new Array(); 534 535function customFunctionOnPgnTextLoad() { 536 var theObj; 537 538 if (firstLoadNewBoards) { newBoards(maxBoards); } 539 if (firstLoadPgnText) { firstGame = firstFromDisplayGame(displayGame); } 540 541 unfilteredGames = new Array(); 542 var newMovesInShownGames = false; 543 gamesForHiding = 0; 544 for (var g = 0; g < numberOfGames; g++) { 545 if (!checkForHiddenGame(gameEvent[g], gameSite[g], gameDate[g], gameRound[g], gameWhite[g], gameBlack[g])) { 546 unfilteredGames.push(g); 547 if ((typeof(gameResult[g]) == "undefined") || (gameResult[g].indexOf("*") == -1)) { gamesForHiding++; } 548 } 549 } 550 numberOfGamesForDisplay = unfilteredGames.length; 551 552 readyToSendPgn = true; 553 if (!firstLoadNewBoards) { 554 for (var board = 0; board < maxBoards; board++) { 555 if ((g = updateBoard(boardId[board])) != -1) { 556 if (board === 0) { firstBoardDisplayGame = displayGame >=0 ? g + 1 : numberOfGames - g; } 557 var found_g = false; for (var f in unfilteredGames) { if (unfilteredGames[f] === g) { found_g = true; break; } } 558 if (found_g) { 559 var currentPgnGameLength; 560 if (LiveBroadcastDemo) { 561 currentPgnGameLength = gameDemoMaxPly[g] > gameDemoLength[g] ? gameDemoLength[g] + 1 : gameDemoMaxPly[g]; 562 } else { 563 currentPgnGameLength = pgnGame[g].replace(/{[^}]*}/g, " ").replace(/\([^)]*\)/g, " ").length; 564 } 565 newMovesInShownGames = newMovesInShownGames || (typeof(previousPgnGameLength[g]) == "undefined") || (previousPgnGameLength[g] !== currentPgnGameLength); 566 previousPgnGameLength[g] = currentPgnGameLength; 567 } 568 } 569 } 570 } 571 572 if (theObj = document.getElementById("GameLiveStatus")) { 573 if (alertNumSinceReset) { 574 theObj.title += " - " + alertNumSinceReset + " new alert" + (alertNumSinceReset > 1 ? "s" : ""); 575 } 576 if (firstLoadPgnText) { theObj.style.display = "inline"; } 577 } 578 579 if (newMovesInShownGames) { liveBroadcastUpdateTicker++; } 580 document.title = liveBroadcastUpdateTicker + "." + LiveBroadcastGamesRunning + "." + numberOfGames + " live broadcast" + (demoFlag ? " demo" : ""); 581 582 if (theObj = document.getElementById("GameLiveStatusDemo")) { theObj.innerHTML = LiveBroadcastDemo ? "demo " : ""; } 583 584 updateMenu(); 585 586 if (firstLoadNewBoards) { firstLoadNewBoards = false; } 587 if (firstLoadPgnText) { firstLoadPgnText = false; } 588} 589 590function customDebugInfo() { 591 var dbg = "maxBoards=" + maxBoards; 592 dbg += " filtered=" + filteredGames.length; 593 return dbg; 594} 595 596function updateMenu() { 597 var theRightObject, theLeftObject, theInfoObject; 598 599 if (theRightObject = document.getElementById("rightMenu")) { 600 theRightObject.innerHTML = ""; 601 602 theRightObject.innerHTML += "<span class='menuLink'><a class='commandLink' class='commandLink' href='javascript:void(0);' onclick='replayLastMoves();' title='replaY last moves' onfocus='this.blur();'> y </a></span>"; 603 604 if (numberOfGamesForDisplay > maxBoards) { theRightObject.innerHTML += "<span class='menuLink'><a class='commandLink' href='javascript:void(0);' onclick='previousPage();' title='showing from game " + (Math.abs(firstGame)+1) + "/" + numberOfGamesForDisplay + ": view the Earlier games' onfocus='this.blur();'> e </a></span><span class='menuLink'><a class='commandLink' href='javascript:void(0);' onclick='nextPage();' title='showing from game " + (Math.abs(firstGame)+1) + "/" + numberOfGamesForDisplay + ": view the Next games' onfocus='this.blur();'> n </a></span>"; } 605 606 if (maxBoards > 1 && numberOfGamesForDisplay > 1) { theRightObject.innerHTML += "<span class='menuLink'><a class='commandLink' href='javascript:void(0);' onclick='newBoards(" + Math.min(maxBoards - 1, numberOfGamesForDisplay - 1) + ");' title='show one chessboard Less' onfocus='this.blur();'> l </a></span>"; } 607 if (numberOfGamesForDisplay > maxBoards) { theRightObject.innerHTML += "<span class='menuLink'><a class='commandLink' href='javascript:void(0);' onclick='newBoards(" + (maxBoards + 1) + ");' title='show one chessboard More' onfocus='this.blur();'> m </a></span>"; } 608 609 if (LiveBroadcastStarted && !LiveBroadcastEnded && gamesForHiding && numberOfGamesForDisplay > 1) { theRightObject.innerHTML += "<span class='menuLink'><a class='commandLink' href='javascript:void(0);' onclick='hideEndedGames();' title='Hide games finished so far' onfocus='this.blur();'> h </a></span>"; } 610 if (filteredGames.length > 0) { theRightObject.innerHTML += "<span class='menuLink'><a class='commandLink' href='javascript:void(0);' onclick='restoreHiddenGames();' title='Unhide games previously hidden: " + filteredGames.length + "/" + numberOfGames + "' onfocus='this.blur();'> u </a></span>"; } 611 612 if (LiveBroadcastDelay > 0) { 613 if (LiveBroadcastEnded) { theRightObject.innerHTML += "<span class='menuLink'><a class='commandLink' href='javascript:void(0);' onclick='restartLiveBroadcast();' title='Check for the start of a new live broadcast event' onfocus='this.blur();'> c </a></span>"; } 614 else { 615 if (LiveBroadcastPaused && LiveBroadcastStarted) { theRightObject.innerHTML += "<span class='menuLink'><a class='commandLink' href='javascript:void(0);' onclick='restartLiveBroadcast(); updateMenu();' title='Restart live broadcast automatic refresh of games' onfocus='this.blur();'> r </a></span>"; } 616 else if (LiveBroadcastPaused && !LiveBroadcastStarted) { theRightObject.innerHTML += "<span class='menuLink'><a class='commandLink' href='javascript:void(0);' onclick='restartLiveBroadcast(); updateMenu();' title='Restart polling for a new live broadcast' onfocus='this.blur();'> r </a></span>"; } 617 else if (LiveBroadcastStarted) { theRightObject.innerHTML += "<span class='menuLink'><a class='commandLink' href='javascript:void(0);' onclick='pauseLiveBroadcast(); updateMenu();' title='Pause live broadcast automatic refresh of games' onfocus='this.blur();'> p </a></span>"; } 618 else { theRightObject.innerHTML += "<span class='menuLink'><a class='commandLink' href='javascript:void(0);' onclick='pauseLiveBroadcast(); updateMenu();' title='Pause polling for a new live broadcast' onfocus='this.blur();'> p </a></span>"; } 619 theRightObject.innerHTML += "<span class='menuLink'><a class='commandLink' class='commandLink' href='javascript:void(0);' onclick='refreshPgnSource();' title='Force games refresh" + (LiveBroadcastStarted ? ": last moves received on " + LiveBroadcastLastReceivedLocal : "") + "' onfocus='this.blur();'> f </a></span>"; 620 } 621 } 622 623 if (theRightObject && (theLeftObject = document.getElementById("leftMenu"))) { 624 theRightObject.style.minWidth = 0; 625 theLeftObject.style.minWidth = 0; 626 theRightObject.style.minWidth = theLeftObject.offsetWidth + "px"; 627 theLeftObject.style.minWidth = theRightObject.offsetWidth + "px"; 628 } 629 } 630 631 if (theInfoObject = document.getElementById("infoMessage")) { 632 if (numberOfGamesForDisplay < 1) { 633 theInfoObject.innerHTML = "warning: all games hidden: <a href='javascript:void(0);' onclick='restoreHiddenGames();' onfocus='this.blur();'>unhide games</a> or <a href='javascript:void(0);' onclick='refreshPgnSource();' onfocus='this.blur();'>force live refresh</a>"; 634 } else { 635 var theEvent = ""; 636 var theSite = ""; 637 for (var n = 0; n < numberOfGames; n++) { 638 if ((theEvent !== false) && (theEvent !== gameEvent[n])) { 639 if (theEvent) { theEvent = false; } 640 else { theEvent = gameEvent[n]; } 641 } 642 if ((theSite !== false) && (theSite !== gameSite[n])) { 643 if (theSite) { theSite = false; } 644 else { theSite = gameSite[n]; } 645 } 646 } 647 if (theEvent == "?") { theEvent = ""; } 648 if (theSite == "?") { theSite = ""; } 649 if (theEvent) { theEvent = theEvent.replace(/\s/g, " ").replace(/-/g, "‑"); } 650 if (theSite) { theSite = theSite.replace(/\s/g, " ").replace(/-/g, "‑"); } 651 652 if (theEvent || theSite) { 653 var theInfoObjectText = "<span class='notranslate'> "; 654 if (theEvent) { theInfoObjectText += theEvent; } 655 if (theEvent && theSite) { theInfoObjectText += " "; } 656 if (theSite) { theInfoObjectText += theSite; } 657 theInfoObjectText += " </span>"; 658 theInfoObject.innerHTML = theInfoObjectText; 659 theInfoObject.title = "event currently on display: hover the mouse below each chessboard for more details"; 660 } else { 661 theInfoObject.innerHTML = " "; 662 theInfoObject.title = ""; 663 } 664 } 665 } 666 667} 668 669function startFromFirstGame(fGame) { 670 if (fGame >= numberOfGamesForDisplay) { return numberOfGamesForDisplay - 1; } 671 if (fGame < -numberOfGamesForDisplay) { return 0; } 672 if (fGame < 0) { return numberOfGamesForDisplay + fGame; } 673 else { return fGame; } 674} 675 676function nextPage() { 677 firstGame = (startFromFirstGame(firstGame) + maxBoards) % numberOfGamesForDisplay; 678 firstGame -= (firstGame < 0 ? numberOfGamesForDisplay : 0); 679 customFunctionOnPgnTextLoad(); 680} 681 682function previousPage() { 683 firstGame = (startFromFirstGame(firstGame) - maxBoards + numberOfGamesForDisplay) % numberOfGamesForDisplay; 684 firstGame -= (firstGame < 0 ? numberOfGamesForDisplay : 0); 685 customFunctionOnPgnTextLoad(); 686} 687 688function newBoards(newMaxBoards) { 689 updateBoardFrames(newMaxBoards); 690 updateMenu(); 691} 692 693function cycleHash() { 694 switch (location.hash) { 695 case "#boards": goToHash("bottom"); break; 696 case "#bottom": goToHash(""); break; 697 default: goToHash("boards"); break; 698 } 699} 700 701function goToHash(hash) { 702 if (hash) { location.hash = ""; } 703 else { location.hash = "boards"; } 704 location.hash = hash; 705} 706 707function customShortcutKey_Shift_3() { cycleHash(); } 708 709function customShortcutKey_Shift_5() { 710 displayGame = displayGame_default; 711 firstLoadPgnText = true; 712 customFunctionOnPgnTextLoad(); 713} 714 715function customShortcutKey_Shift_6() { 716 firstLoadPgnText = true; 717 customFunctionOnPgnTextLoad(); 718} 719 720function customShortcutKey_Shift_7() { 721 restoreHiddenGames(); 722} 723 724function customShortcutKey_Shift_8() { 725 newBoards(maxBoards_default); 726} 727 728function pgn4web_onload(e) { 729 start_pgn4web(); 730 if (location.hash) { setTimeout("goToHash('" + location.hash + "');", 333 * maxBoards); } 731} 732 733</script> 734 735</body> 736 737</html> 738