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 results</title>
14
15<link rel="icon" sizes="16x16" href="pawn.ico" />
16
17<style type="text/css">
18
19html,
20body {
21  margin: 0px;
22  padding: 0px;
23}
24
25body {
26  padding: 40px; /* defined as body.padding */
27  font-family: sans-serif;
28  font-size: 16px; /* defined as body.fontSize */
29  color: black;
30  overflow-x: hidden;
31  overflow-y: scroll;
32
33  -webkit-user-select: none;
34  -moz-user-select: none;
35  -ms-user-select: none;
36  -o-user-select: none;
37  user-select: none;
38  -webkit-text-size-adjust: none;
39  -moz-text-size-adjust: none;
40  -ms-text-size-adjust: none;
41  -o-text-size-adjust: none;
42  text-size-adjust: none;
43  -webkit-touch-callout: none;
44}
45
46a {
47  color: black;
48  text-decoration: none;
49}
50
51.pageHeader {
52  color: red;
53  text-decoration: none;
54}
55
56h1.pageHeader {
57  margin-top: 0px;
58  margin-bottom: 0px;
59  padding-top: 0px;
60  padding-bottom: 10px; /* = 1/4 * body.padding */
61  white-space: nowrap;
62}
63
64.gamesAnchor {
65  display: inline-block;
66  height: 40px; /* = body.padding */
67  width: 99%;
68}
69
70.event, .round, .match, .firstTeam, .secondTeam, .score, .player, .firstPlayer, .secondPlayer, .result, .newMoves, .noNewMoves, .lastMoves {
71  white-space: nowrap;
72  display: inline-block;
73  overflow: hidden;
74  vertical-align: bottom;
75}
76
77.eventRound, .matchScore, .game {
78  white-space: nowrap;
79}
80
81.team, .firstTeam, .secondTeam, .firstTeamScore, .secondTeamScore, .firstPlayer, .secondPlayer, .firstTeamPlayer, .secondTeamPlayer {
82  white-space: nowrap;
83}
84
85.eventRound, .event, .match, .firstTeam, .game, .firstPlayer, .secondPlayer, .firstTeamPlayer, .secondTeamPlayer {
86  margin-left: 0px;
87}
88
89.player {
90  width: 180px; /* defined as player.width */
91  margin-right: 20px; /* defined as player.marginRight */
92}
93
94.event, .firstTeam, .secondTeam, .firstPlayer, .secondPlayer {
95  padding-left: 5px; /* defined as player.paddingLeft */
96  padding-right: 5px; /* = player.paddingLeft */
97}
98
99.round, .secondTeam, .score, .newMoves, .noNewMoves, .lastMoves {
100  margin-left: 20px; /* = player.marginRight */
101}
102
103.event {
104  width: 420px; /* = defined as event.width */
105}
106
107.round {
108  text-align: right;
109  width: 50px; /* defined as round.width */
110}
111
112.match {
113  width: 380px; /* = 2 * player.width + 4 * player.paddingLeft */
114}
115
116.score {
117  width: 70px; /* = defined as score.width */
118}
119
120.result {
121  width: 70px; /* = score.width */
122}
123
124.eventRound {
125  font-size: 20px; /* = 5/4 * body.fontSize */
126  font-weight: normal;
127  margin-top: 48px; /* = 3 * body.fontSize */
128  margin-bottom: 12px; /* = 3/4 * body.fontSize */
129}
130
131.matchScore {
132  font-size: 16px; /* = body.fontSize */
133  font-weight: bold;
134  margin-top: 24px; /* = 3/2 * body.fontSize */
135  margin-bottom: 12px; /* = 3/4 * body.fontSize */
136}
137
138.game {
139  font-size: 14px; /* defined as game.fontSize */
140  font-weight: normal;
141  margin-top: 0px;
142  margin-bottom: 0px;
143  cursor: pointer;
144}
145
146.secondTeam, .secondTeamPlayer {
147  background-color: #F4F4F4;
148  border-radius: 3px; /* = 1/4 * game.fontSize */
149}
150
151.score, .result {
152  text-align: center;
153}
154
155.newMoves, .noNewMoves {
156  font-weight: bold;
157  padding-right: 10px; /* = 1/2 * player.marginRight */
158}
159
160.noNewMoves {
161  visibility: hidden;
162}
163
164.lastMoves {
165  min-width: 180px; /* = player.width */
166}
167
168.gameLiveStatus2 {
169  display: inline-block;
170  margin-top: 48px; /* = 3 * body.fontSize */
171  padding-left: 5px; /* = player.paddingLeft */
172  font-size: 14px; /* defined as game.fontSize */
173  color: gray;
174}
175
176.gameFloatingContainer {
177  position: fixed;
178  right: 0; /* defined as gameFloatingContainer.right */
179  top: 30px; /* defined as gameFloatingContainer.top */
180  white-space: nowrap;
181  background-color: white;
182}
183
184.gameAnalysisContainer {
185  padding-top: 110px; /* = gameBoardContainer.paddingTop + 2 * (header.height + header.paddingBottom) + boardTable.borderWidth + gameBoard.paddingTop = (20 + 2 * (16 + 24) + 2 + 8) */
186  overflow: hidden;
187  width: 40px; /* defined as gameAnalysisContainer.width.closed = body.padding */
188  transition: width 1s linear;
189  -moz-transition: width 1s linear;
190  -webkit-transition: width 1s linear;
191  -o-transition: width 1s linear;
192  opacity: 0.8;
193}
194
195.gameAnalysisButtons {
196  height: 14px; /* = engine.html squareSize / 2 */
197  width: 224px; /* = gameAnalysisFrame.width */
198  margin-left: 40px; /* = body.padding */
199  margin-bottom: 14px; /* = engine.html squareSize / 2 */
200}
201
202.gameAnalysisFrame {
203  width: 224px; /* defined as gameAnalysisFrame.width = engine.html width */
204  height: 280px; /* = engine.html height */
205  margin-left: 40px; /* defined as gameAnalysisFrame.marginLeft = body.padding */
206}
207
208.gameBoardContainer {
209  width: 324px; /* defined as gameBoardContainer.width */
210  padding-top: 20px; /* defined as gameBoardContainer.paddingTop */
211  padding-bottom: 10px; /* defined as gameBoardContainer.paddingBottom */
212  padding-right: 40px; /* = body.padding */
213  padding-left: 0px;
214  margin-bottom: 16px; /* = body.fontSize */
215}
216
217.gameBoard {
218  padding-top: 8px; /* defined as gameBoard.paddingTop = 0.5 * header.height */
219  padding-bottom: 8px; /* = gameBoard.paddingTop */
220}
221
222.whiteSquare,
223.blackSquare,
224.highlightWhiteSquare,
225.highlightBlackSquare {
226  width: 38px; /* defined as whiteSquare.bareWidth */
227  height: 38px; /* = whiteSquare.bareWidth */
228  border-style: solid;
229  border-width: 1px; /* defined as whiteSquare.borderWidth */
230  /* whiteSquare.width = whiteSquare.bareWidth + 2 * whiteSquare.borderWidth */
231}
232
233.boardTable {
234  border-style: solid;
235  border-color: #818780;
236  border-width: 2px; /* defined as boardTable.borderWidth */
237  box-shadow: 0px 0px 20px #B0B8AE;
238  width: 324px; /* = 8 * whiteSquare.width + 2 * boardTable.borderWidth */
239  height: 324px; /* = 8 * whiteSquare.width + 2 * boardTable.borderWidth */
240  background-color: #FFFFFF;
241}
242
243.pieceImage {
244  width: 32px; /* defined as pieceImage.width < whiteSquare.bareWidth */
245  height: 32px; /* = pieceImage.width */
246  cursor: pointer;
247}
248
249.whiteSquare,
250.highlightWhiteSquare {
251  background: #EFF4EC;
252  border-color: #EFF4EC;
253}
254
255.blackSquare,
256.highlightBlackSquare {
257  background: #C6CEC3;
258  border-color: #C6CEC3;
259}
260
261.highlightWhiteSquare,
262.highlightBlackSquare {
263  border-color: #818780;
264}
265
266.selectControl {
267/* a "width" attribute here must use the !important flag to override default settings */
268  font-size: 16px; /* = body.fontSize */
269}
270
271.optionSelectControl {
272}
273
274.buttonControlPlay,
275.buttonControlStop,
276.buttonControl {
277/* a "width" attribute here must use the !important flag to override default settings */
278  font-size: 16px; /* = body.fontSize */
279  border-style: none;
280  background-color: transparent;
281}
282
283.buttonControlSpace {
284/* a "width" attribute here must use the !important flag to override default settings */
285  font-size: 16px; /* = body.fontSize */
286}
287
288.searchPgnButton {
289/* a "width" attribute here must use the !important flag to override default settings */
290  font-size: 16px; /* = body.fontSize */
291}
292
293.searchPgnExpression {
294/* a "width" attribute here must use the !important flag to override default settings */
295  font-size: 16px; /* = body.fontSize */
296}
297
298.move,
299.variation {
300  text-decoration: none;
301}
302
303.move {
304  color: black;
305}
306
307.comment,
308.variation {
309  color: gray !important;
310}
311
312a.variation {
313  color: gray !important;
314}
315
316.moveOn,
317.variationOn {
318  background: #DAF4D7;
319}
320
321.header, .footer {
322  font-size: 11px; /* defined as header.fontSize */
323  height: 16px; /* defined as header.height */
324  white-space: nowrap;
325  margin-left: 2px; /* = boardTable.borderWidth */
326  margin-right: 2px; /* = boardTable.borderWidth */
327  width: 320px; /* = 8 * whiteSquare.width */
328  text-align: center;
329}
330
331.header {
332  margin-bottom: 24px; /* defined as header.marginBottom = 1.5 * header.height */
333}
334
335.footer {
336  margin-top: 24px; /* = 1.5 * header.height */
337}
338
339.gameEvent, .gameDateAdjusted, .gameLiveStatus, .gameWhite, .gameWhiteClock, .gameBlackClock, .gameBlack {
340  display: inline-block;
341  overflow: hidden;
342}
343
344.gameEvent {
345  width: 220px; /* = 5.5 * whiteSquare.width */
346  margin-right: 20px; /* = 1/2 * whiteSquare.width */
347  text-align: left;
348  color: gray;
349}
350
351.gameDateAdjusted {
352  width: 80px; /* = 2 * whiteSquare.width */
353  cursor: pointer;
354}
355
356.gameLiveStatus {
357  width: 80px; /* = 2 * whiteSquare.width */
358  text-align: right;
359  color: gray;
360}
361
362.gameWhite, .gameBlack {
363  width: 80px; /* = 2 * whiteSquare.width */
364  text-decoration: none;
365  color: black;
366  cursor: pointer;
367}
368
369.gameWhiteClock, .gameBlackClock {
370  width: 50px; /* defined as gameWhiteClock.width */
371  margin-left: 15px; /* = 1/2 * (2 * whiteSquare.width - gameWhiteClock.width) */
372  margin-right: 15px; /* = 1/2 * (2 * whiteSquare.width - gameWhiteClock.width) */
373}
374
375.gameWhite, .gameBlackClock {
376  text-align: left;
377}
378
379.gameWhiteClock, .gameBlack {
380  text-align: right;
381}
382
383.gameSideToMove, .gameText, .gameResult {
384  white-space: nowrap;
385  display: inline-block;
386  overflow-x: hidden;
387}
388
389.gameSideToMove, .gameResult {
390  width: 50px; /* = gameWhiteClock.width */
391}
392
393.gameSideToMove {
394  text-align: left;
395}
396
397.gameResult {
398  text-align: right;
399  cursor: pointer;
400}
401
402.gameText {
403  width: 220px; /* = 8 * whiteSquare.width - 2 * gameWhiteClock.width */
404  text-align: center;
405}
406
407.sideToMove {
408  display: inline-block;
409  height: 1ex;
410  width: 1ex;
411  border-style: solid;
412  border-color: black;
413  border-width: 1px;
414  margin-bottom: 1px;
415}
416
417.sideToMoveHidden {
418  visibility: hidden;
419}
420
421</style>
422
423<script src="pgn4web.js" type="text/javascript"></script>
424<script src="engine.js" type="text/javascript"></script>
425
426<script src="fide-lookup.js" type="text/javascript"></script>
427
428<script src="crc32.js" type="text/javascript"></script>
429
430<script type="text/javascript">
431  "use strict";
432
433  var pgn4web_engineWindowUrlParameters = "lch=FFFFFF&dch=E4E4E4&hch=BCDEB4&ctch=888888&ss=28&ps=24&fms=11&fcs=19&fpr=0";
434  var pgn4web_engineWindowTarget = "pgn4webAnalysisBoardForLiveResultsViewer";
435  var pgn4web_engineWindowHeight = "";
436  var pgn4web_engineWindowWidth = "";
437
438  var pgnFile;
439  var pgnFile_default = detectBaseLocation() ?
440    location.protocol + "//" + location.hostname + location.pathname.replace(/\/[^\/]*$/, "/live/live.pgn") :
441    "live/live.pgn";
442  // accepts pgnData as alias for pgnFile for consistency with board.html
443  if ((pgnFile = gup("pgnData")) === "") {
444    if ((pgnFile = gup("pgnFile")) === "") {
445      pgnFile = pgnFile_default;
446    }
447  }
448
449  var demoFlag = false;
450  var alertFlag = false;
451  if ((gup("demo") == "true") || (gup("demo") == "t") ||
452      (gup("refreshDemo") == "true") || (gup("refreshDemo") == "t")) {
453    demoFlag = true; alertFlag = true;
454  }
455
456  var refreshMinutes;
457  if ((refreshMinutes = gup("refreshMinutes")) === "") {
458    refreshMinutes = 1;
459  } else {
460    refreshMinutes = parseFloat(refreshMinutes);
461    if (isNaN(refreshMinutes) || (refreshMinutes < 0)) {
462      if (alertFlag) {
463        alert("ERROR: refreshMinutes parameter must be a positive number: defaulting to 1.\n");
464      }
465      refreshMinutes = 1;
466    }
467  }
468
469  var iniGame;
470  var delayIniGame = false;
471  if ((iniGame = gup("initialGame")) === "") {iniGame = 1; }
472  if (!(isNaN(parseInt(iniGame, 10)))) {
473    iniGame = parseInt(iniGame, 10);
474    delayIniGame = (iniGame > 0);
475  }
476
477  var showBoard = true;
478  if ((gup("showBoard") == "false") || (gup("showBoard") == "f")) { showBoard = false; }
479
480  var adjustBoard = true;
481  if ((gup("adjustBoard") == "false") || (gup("adjustBoard") == "f")) { adjustBoard = false; }
482
483  var showEvent = true;
484  if ((gup("showEvent") == "false") || (gup("showEvent") == "f")) { showEvent = false; }
485
486  var roundReverse = false;
487  if ((gup("roundReverse") == "true") || (gup("roundReverse") == "t")) { roundReverse = true; }
488
489  var showTeams = true;
490  if ((gup("showTeams") == "false") || (gup("showTeams") == "f")) { showTeams = false; }
491
492  var showPlayersInfo = true;
493  if ((gup("showPlayersInfo") == "false") || (gup("showPlayersInfo") == "f")) { showPlayersInfo = false; }
494
495  var showLastMoves = false;
496  if ((gup("showLastMoves") == "true") || (gup("showLastMoves") == "t")) { showLastMoves = true; }
497
498  var highlightMode = false;
499  if ((gup("highlightMode") == "true") || (gup("highlightMoves") == "t") || (gup("highlightMode") == "border") || (gup("highlightMoves") == "b")) { highlightMode = true; }
500
501  var showAnalysis = false; // does not fit the design to allow this as URL parameter
502
503  var disableEngine = true; // does not fit the design to allow this as URL parameter; preset as true to preload the analysis board
504
505  var autoUpdateAnalysis = false;
506  if ((gup("autoUpdateAnalysis") == "true") || (gup("autoUpdateAnalysis") == "t")) { autoUpdateAnalysis = true; }
507
508  var headlessPage = false;
509  if ((gup("headlessPage") == "true") || (gup("headlessPage") == "t")) { headlessPage = true; }
510
511  if ((gup("help") == "true") || (gup("help") == "t")) {
512      document.write("<pre style='font-size:11px;'>" +
513      "pgn4web live-results.html parameters" + "\n\n" +
514      " - pgnData = " + pgnFile + "; PGN file to load (default " + pgnFile_default + ")" + "\n" +
515      " - refreshMinutes = " + refreshMinutes + "; refresh interval in minutes, decimals allowed (default 1)" + "\n" +
516      " - refreshDemo = " + demoFlag + "; sets live demo mode (default false)" + "\n" +
517      " - initialGame = " + iniGame + "; initial game to load, a number or first, last, random or a search string (default 1)" + "\n" +
518      " - showBoard = " + showBoard + "; shows the chessboard (default true)" + "\n" +
519      " - adjustBoard = " + adjustBoard + "; dynamically adjusts the board position (default true)" + "\n" +
520      " - showEvent = " + showEvent + "; shows event information (default true)" + "\n" +
521      " - roundReverse = " + roundReverse + "; reverse round ordering (default false)" + "\n" +
522      " - showTeams = " + showTeams + "; shows teams information (default true)" + "\n" +
523      " - showPlayersInfo = " + showPlayersInfo + "; shows title/elo players information (default true)" + "\n" +
524      " - showLastMoves = " + showLastMoves + "; shows last moves information (default false)" + "\n" +
525      " - highlightMode = " + highlightMode + "; highlight moves (default false)" + "\n" +
526      " - autoUpdateAnalysis = " + autoUpdateAnalysis + "; automatically updates analysis board from main board (default false)" + "\n" +
527      " - headlessPage = " + headlessPage + "; displays a page without heading (default false)" + "\n" +
528      " - help = true" + "\n\n" +
529      "</pre>");
530  }
531
532  SetPgnUrl(pgnFile);
533  SetImagePath ("images/alpha/32");
534  SetImageType("png");
535  SetHighlightOption(highlightMode);
536  SetCommentsIntoMoveText(false);
537  SetCommentsOnSeparateLines(false);
538  SetAutoplayDelay(1000);
539  SetAutostartAutoplay(false);
540  SetAutoplayNextGame(false);
541  SetInitialHalfmove("end", true);
542  SetInitialVariation(0);
543  SetInitialGame(delayIniGame ? "first" : iniGame);
544  SetShortcutKeysEnabled(showBoard);
545  if (refreshMinutes !== 0) { SetLiveBroadcast(refreshMinutes, alertFlag, demoFlag, true); }
546
547  function customFunctionOnCheckLiveBroadcastStatus() {
548    var theObj, theObjFrom, theObjTo;
549    if ((theObjFrom = document.getElementById("GameLiveStatus")) && (theObjTo = document.getElementById("GameLiveStatus2"))) {
550      theObjTo.innerHTML = theObjFrom.innerHTML;
551      theObjTo.title = theObjFrom.title;
552    }
553    for (var gg in gameId) {
554      if (theObj = document.getElementById("newMoves_" + gameId[gg])) {
555        theObj.className = "noNewMoves";
556      }
557    }
558    gameNewMoves = new Array();
559  }
560
561  var gameId;
562  var gameWhiteTeam;
563  var gameBlackTeam;
564  var gameWhiteTitle;
565  var gameBlackTitle;
566  var gameWhiteElo;
567  var gameBlackElo;
568  var gameMatch;
569  var gameBoard;
570  var newGameLengthFromCrc = new Array();
571  var gameLengthFromCrc = new Array();
572  var gameNewMoves = new Array();
573  var firstCustomFunctionOnPgnTextLoad = true;
574  function customFunctionOnPgnTextLoad() {
575    var theObj;
576
577    gameId = new Array();
578
579    gameWhiteTeam = new Array();
580    gameBlackTeam = new Array();
581    gameWhiteTitle = new Array();
582    gameBlackTitle = new Array();
583    gameWhiteElo = new Array();
584    gameBlackElo = new Array();
585    gameMatch = new Array();
586    gameBoard = new Array();
587    gameNewMoves = new Array();
588    for (var gg = 0; gg < numberOfGames; gg++) {
589      gameId[gg] = gg;
590      gameWhiteTeam[gg] = customPgnHeaderTag("WhiteTeam", null, gg);
591      gameBlackTeam[gg] = customPgnHeaderTag("BlackTeam", null, gg);
592      gameWhiteTitle[gg] = customPgnHeaderTag("WhiteTitle", null, gg);
593      gameBlackTitle[gg] = customPgnHeaderTag("BlackTitle", null, gg);
594      gameWhiteElo[gg] = customPgnHeaderTag("WhiteElo", null, gg);
595      gameBlackElo[gg] = customPgnHeaderTag("BlackElo", null, gg);
596      gameMatch[gg] = crc32(gameWhiteTeam[gg]) + crc32(gameBlackTeam[gg]);
597      gameBoard[gg] = customPgnHeaderTag("Board", null, gg);
598      var thisCrc = (typeof(pgnHeader[gg]) == "string") ? (crc32((gameEvent[gg] + "," + gameSite[gg] + "," + gameRound[gg] + "," + gameWhite[gg] + "," + gameBlack[gg] + ";").replace(/(^\s*|\s*$)/g, "")) % 65535) + 65535 : 0;
599      newGameLengthFromCrc[thisCrc] = LiveBroadcastDemo ? gameDemoMaxPly[gg] : pgnGame[gg].replace(/(^\s*|\s*$)/g, "").length;
600      gameNewMoves[gg] = ((newGameLengthFromCrc[thisCrc] !== gameLengthFromCrc[thisCrc]) && (LiveBroadcastStarted) && (!LiveBroadcastEnded));
601    }
602    gameLengthFromCrc = newGameLengthFromCrc.splice(0, newGameLengthFromCrc.length);
603    gameId.sort(sortGameId);
604
605    printGames();
606
607    if ((LiveBroadcastTicker < 2) && delayIniGame) {
608      Init(typeof(gameId[iniGame - 1]) != "undefined" ? gameId[iniGame - 1] : "0");
609    }
610
611    if (firstCustomFunctionOnPgnTextLoad) {
612      firstCustomFunctionOnPgnTextLoad = false;
613      if (theObj = document.getElementById("SideToMove")) { theObj.className = "sideToMove"; }
614      showEngineAnalysisBoard(disableEngine, true); // prepare analysis frame with an idle board
615    }
616  }
617
618  function myCompare(AA, ZZ) {
619    if ((typeof(AA) == "undefined") && (typeof(ZZ) == "undefined")) { return 0; }
620    if (typeof(ZZ) == "undefined") { return 1; }
621    if (typeof(ZZ) == "undefined") { return -1; }
622    if (AA > ZZ) { return 1; }
623    if (AA < ZZ) { return -1; }
624    return 0;
625  }
626
627  function myCompareRound(AA, ZZ) {
628    var AA_A = AA.split(".");
629    var ZZ_Z = ZZ.split(".");
630    var AA_a, ZZ_z;
631    var jm = Math.max(AA_A.length, ZZ_Z.length);
632    for (var jj = 0; jj < jm; jj++) {
633      if (typeof(ZZ_Z[jj]) == "undefined") { return 1; }
634      if (typeof(AA_A[jj]) == "undefined") { return -1; }
635      AA_a = parseInt(AA_A[jj], 10);
636      ZZ_z = parseInt(ZZ_Z[jj], 10);
637      if (isNaN(AA_a) || isNaN(ZZ_z)) {
638        if (!isNaN(ZZ_z)) { return 1; }
639        if (!isNaN(AA_a)) { return -1; }
640        if (AA_A[jj] > ZZ_Z[jj]) { return 1; }
641        if (AA_A[jj] < ZZ_Z[jj]) { return -1; }
642      } else {
643        if (AA_a > ZZ_z) { return 1; }
644        if (AA_a < ZZ_z) { return -1; }
645      }
646    }
647    return 0;
648  }
649
650  function sortGameId(aa, zz) {
651    var res;
652
653    res = myCompare(gameEvent[aa], gameEvent[zz]);
654    if (res !== 0) { return res; }
655
656    res = myCompareRound(fixRound(gameRound[aa]), fixRound(gameRound[zz]));
657    if (res !== 0) { return roundReverse ? -res : res; }
658
659    res = myCompare(gameMatch[aa], gameMatch[zz]);
660    if (res !== 0) { return res; }
661
662    res = myCompareRound(gameRound[aa], gameRound[zz]);
663    if (res !== 0) { return res; }
664
665    res = myCompare(gameBoard[aa], gameBoard[zz]);
666    if (res !== 0) { return res; }
667
668    if (aa > zz) { return 1; }
669    if (aa < zz) { return -1; }
670
671    return 0;
672
673  }
674
675  function fixRound(thisRound) {
676    return thisRound.replace(/\..*$/, ""); // only use the first number of rounds like 1.2.3
677  }
678
679  function printGames() {
680    var firstRow = true;
681    var lastEventRound = "";
682    var lastMatch = 0;
683    var theObj = document.getElementById("results");
684    if (theObj) {
685      var resultTable = "";
686      var ggId, fixedRound, currentEventRound, whitePlayer, whiteTitle, whiteElo, blackPlayer, blackTitle, blackElo, lastMoves;
687      for (var gg in gameId) {
688        ggId = gameId[gg];
689        fixedRound = fixRound(gameRound[ggId]);
690        currentEventRound = gameEvent[ggId] + fixedRound;
691        if (showEvent && currentEventRound && (currentEventRound !== lastEventRound)) {
692          resultTable += '<div class="eventRound"' + (firstRow ? ' style="margin-top:0px;"' : '') + '><span class="event" title="' + gameEvent[ggId] + '">' + gameEvent[ggId] + '</span><span class="round" title="' + 'round ' + fixedRound + '">' + fixedRound + '</span></div>';
693          if (firstRow) { firstRow = false; }
694          lastEventRound = currentEventRound;
695          lastMatch = 0;
696        }
697        if (showTeams && gameMatch[ggId] && (gameMatch[ggId] !== lastMatch)) {
698          resultTable += matchRow(gameEvent[ggId], gameRound[ggId], gameMatch[ggId], firstRow);
699          if (firstRow) { firstRow = false; }
700          lastMatch = gameMatch[ggId];
701        }
702        whiteTitle = gameWhiteTitle[ggId];
703        whiteElo = gameWhiteElo[ggId];
704        whitePlayer = gameWhite[ggId] + (showPlayersInfo ? (whiteTitle ? " &nbsp; " + whiteTitle : "") + (whiteElo ? " &nbsp; " + whiteElo : "") : "");
705        blackTitle = gameBlackTitle[ggId];
706        blackElo = gameBlackElo[ggId];
707        blackPlayer = gameBlack[ggId] + (showPlayersInfo ? (blackTitle ? " &nbsp; " + blackTitle : "") + (blackElo ? " &nbsp; " + blackElo : "") : "");
708        if (showLastMoves) {
709          lastMoves = pgnGame[ggId].replace(/\n/g, " ").replace(/{.*?}|\$\d+/g, " ").replace(/[^\sa-wyzA-WYZ0-9.\/#-]+/g, "").replace(/\d+\.{2,}|1-0|0-1|1\/2-1\/2|\*/g, "").match(/((\b\d+\.?)?(\s*\S+)?(\s*\S+)|(\S+\s*)?(\b\d+\.?)?(\s*\S+))\s*$/);
710          if (lastMoves) { lastMoves = lastMoves[0].replace(/\s\s+/g, " ").replace(/^\s+|\s+$/g, ""); }
711        }
712        resultTable += '<div class="game" id="gameRow_' + ggId + '" style="' + ((showBoard && (ggId === oldSelectedGame)) ? 'font-weight:bold;' : '') + (firstRow ? 'margin-top:0px;' : '') + '"><span onclick="selectGame(' + ggId + ');"><span class="player"><span class="firstPlayer' + ((firstTeam && gameWhiteTeam[ggId] === firstTeam) ? ' firstTeamPlayer' : '') + ((secondTeam && gameWhiteTeam[ggId] === secondTeam) ? ' secondTeamPlayer' : '') + '" title="' + whitePlayer.replace(/&nbsp;/, ' ') + '">' + whitePlayer + '</span></span><span class="player"><span class="secondPlayer' + ((firstTeam && gameWhiteTeam[ggId] === firstTeam) ? ' firstTeamPlayer' : '') + ((secondTeam && gameBlackTeam[ggId] === secondTeam) ? ' secondTeamPlayer' : '') + '" title="' + blackPlayer.replace(/&nbsp;/, ' ') + '">' + blackPlayer + '</span></span><span class="result" title="' + gameResult[ggId] + '">' + gameResult[ggId] + '</span><span id="newMoves_' + ggId + '" class="' + (gameNewMoves[ggId] ? 'newMoves' : 'noNewMoves') + '" title="new moves received">*</span><span class="lastMoves"><span' + (lastMoves ? ' title="last moves">' + lastMoves : '>&nbsp;')  + '</span></span></span></div>';
713        if (firstRow) { firstRow = false; }
714      }
715      theObj.innerHTML = resultTable;
716    }
717  }
718
719  var firstTeam = "";
720  var secondTeam = "";
721  function matchRow(eventStr, roundStr, matchId, firstRow) {
722    firstTeam = "";
723    secondTeam = "";
724    if (matchId === 0) { return ""; }
725    var firstTeamScore = 0;
726    var secondTeamScore = 0;
727    for (var ii in gameId) {
728      if ((gameEvent[gameId[ii]] === eventStr) && (fixRound(gameRound[gameId[ii]]) === fixRound(roundStr)) && (gameMatch[gameId[ii]] === matchId)) {
729        if (!firstTeam || !secondTeam) {
730          firstTeam = gameWhiteTeam[gameId[ii]];
731          secondTeam = gameBlackTeam[gameId[ii]];
732        }
733        switch (gameResult[gameId[ii]]) {
734          case "1-0":
735            if (firstTeam == gameWhiteTeam[gameId[ii]]) { firstTeamScore += 1; }
736            else if (secondTeam == gameWhiteTeam[gameId[ii]]) { secondTeamScore += 1; }
737            break;
738          case "0-1":
739            if (firstTeam == gameBlackTeam[gameId[ii]]) { firstTeamScore += 1; }
740            else if (secondTeam == gameBlackTeam[gameId[ii]]) { secondTeamScore += 1; }
741            break;
742          case "1/2-1/2":
743            firstTeamScore += 0.5;
744            secondTeamScore += 0.5;
745            break;
746          default:
747            break;
748        }
749      }
750    }
751    return '<div class="matchScore"' + (firstRow? ' style="margin-top:0px;"' : '') + '><span class="match" title="' + firstTeam + ' - ' + secondTeam + '"><span class="team"><span class="firstTeam">' + firstTeam + '</span></span><span class="team"><span class="secondTeam">' + secondTeam + '</span></span></span><span class="score" title="' + firstTeamScore + '-' + secondTeamScore + '">' + firstTeamScore + '-' + secondTeamScore + '</span></div>';
752  }
753
754  var oldSelectedGame = -1;
755  function selectGame(gameNum) {
756    if (!showBoard) { return; }
757    Init(gameNum);
758    highlightGame(gameNum);
759  }
760
761  function highlightGame(gameNum) {
762    var theObj;
763    if (!showBoard) { return; }
764    if (theObj = document.getElementById("gameRow_" + oldSelectedGame)) {
765      if (oldSelectedGame !== gameNum) {
766        theObj.style.fontWeight = "";
767      }
768    }
769    if (theObj = document.getElementById("gameRow_" + gameNum)) {
770       theObj.style.fontWeight = "bold";
771    }
772    oldSelectedGame = gameNum;
773  }
774
775  function customFunctionOnPgnGameLoad() {
776    var theObj;
777
778    highlightGame(currentGame);
779
780    if (theObj = document.getElementById("GameWhite")) {
781      var whiteTitle = customPgnHeaderTag("WhiteTitle");
782      var whiteElo = customPgnHeaderTag("WhiteElo");
783      var whiteTeam = customPgnHeaderTag("WhiteTeam");
784      theObj.title = simpleHtmlentitiesDecode("white player:  " + gameWhite[currentGame] + (showPlayersInfo ? (whiteTitle ? "  " + whiteTitle : "") + (whiteElo ? "  " + whiteElo : "") + (whiteTeam ? "  " + whiteTeam : "") : ""));
785      if (theObj.innerHTML === "") { theObj.innerHTML = "&nbsp;"; }
786    }
787    if (theObj = document.getElementById("GameBlack")) {
788      var blackTitle = customPgnHeaderTag("BlackTitle");
789      var blackElo = customPgnHeaderTag("BlackElo");
790      var blackTeam = customPgnHeaderTag("BlackTeam");
791      theObj.title = simpleHtmlentitiesDecode("black player:  " + gameBlack[currentGame] + (showPlayersInfo ? (blackTitle ? "  " + blackTitle : "") + (blackElo ? "  " + blackElo : "") + (blackTeam ? "  " + blackTeam : "") : ""));
792      if (theObj.innerHTML === "") { theObj.innerHTML = "&nbsp;"; }
793    }
794
795    if (theObj = document.getElementById("GameEvent")) {
796      if (theObj.innerHTML == gameEvent[currentGame]) {
797        theObj.innerHTML += " &nbsp; &nbsp; " + gameRound[currentGame];
798        theObj.title = simpleHtmlentitiesDecode("event:  " + gameEvent[currentGame] + (gameSite[currentGame] ? "\nsite:  " + gameSite[currentGame] : "") + (gameDate[currentGame] ? "\ndate:  " + gameDate[currentGame] : "") + (gameRound[currentGame] ? "\nround:  " + gameRound[currentGame] : ""));
799      }
800      if (refreshMinutes === 0) {
801        var theOther = document.getElementById("GameDate");
802        if (theOther) { theOther.title = theObj.title; }
803      }
804    }
805
806    if ((refreshMinutes !== 0) && (theObj = document.getElementById("GameDateAdjusted"))) {
807      theObj.innerHTML = (gameDate[currentGame].match(/live/i)) ? "live" : "&nbsp;";
808      theObj.title = (gameDate[currentGame].match(/live/i)) ? "live event" : "";
809    }
810  }
811
812  function customFunctionOnMove() {
813    var extraMoves = 2;
814
815    document.getElementById("GamePrevMoves").innerHTML = "";
816    document.getElementById("GameCurrMove").innerHTML = "";
817    document.getElementById("GameNextMoves").innerHTML = "";
818    var theObj = document.getElementById("GamePrevMoves");
819    var thisPly = Math.max(CurrentPly - extraMoves - 1, StartPly);
820    if (thisPly > StartPly) { theObj.innerHTML += "... "; }
821    for (; thisPly < Math.min(CurrentPly + extraMoves, StartPly + PlyNumber); thisPly++) {
822      if (thisPly == CurrentPly) {
823        theObj = document.getElementById("GameNextMoves");
824      }
825      if (thisPly % 2 === 0) { theObj.innerHTML += Math.floor(1 + thisPly / 2) + ". "; }
826      if (thisPly == CurrentPly - 1) {
827        theObj = document.getElementById("GameCurrMove");
828      }
829      theObj.innerHTML += Moves[thisPly] + " ";
830    }
831    if (thisPly < StartPly + PlyNumber) { theObj.innerHTML += "..."; }
832
833    if (theObj = document.getElementById("SideToMove")) {
834      theObj.style.backgroundColor = CurrentPly % 2 ? "black" : "white";
835    }
836
837    if (showBoard && showAnalysis && autoUpdateAnalysis) {
838      showAnalysisBoard(disableEngine);
839    }
840  }
841
842  function searchGameWithNewMoves(backward) {
843    if (typeof(gameId) == "undefined") { return; }
844    if (typeof(gameNewMoves) == "undefined") { return; }
845
846    for (var thisGameIndex = 0; thisGameIndex < gameId.length; thisGameIndex++) {
847      if (gameId[thisGameIndex] == currentGame) { break; }
848    }
849    if (thisGameIndex === gameId.length) { return; }
850
851    var indexIncrement = backward ? -1 : 1;
852    for (var thisIndex = (thisGameIndex + indexIncrement + gameId.length) % gameId.length; thisIndex !== thisGameIndex; thisIndex = (thisIndex + indexIncrement + gameId.length) % gameId.length) {
853      if ((typeof(gameNewMoves[gameId[thisIndex]]) != "undefined") && (gameNewMoves[gameId[thisIndex]])) { break; }
854    }
855    if (thisIndex !== thisGameIndex) { Init(gameId[thisIndex]); }
856  }
857
858  function searchLiveGame(backward) {
859    searchPgnGame("\\[\\s*Date\\s*\"[^\"]*live[^\"]*\"\\s*\\]", backward);
860  }
861
862  function customDebugInfo() {
863    return "roundReverse=" + b2s(roundReverse);
864  }
865  function b2s(b) { return b ? "true" : "false"; }
866
867  // customShortcutKey_Shift_1 defined by fide-lookup.js
868  // customShortcutKey_Shift_2 defined by fide-lookup.js
869
870  function customShortcutKey_Shift_3() { searchLiveGame(false); }
871  function customShortcutKey_Shift_4() { searchPgnGame('\\[\\s*Result\\s*"\\*"\\s*\\]', false); }
872  function customShortcutKey_Shift_5() { searchGameWithNewMoves(false); }
873  function customShortcutKey_Shift_6() { toggleAdjustBoard(); }
874  function customShortcutKey_Shift_7() { toggleShowBoard(); }
875
876  // overwriting engine.js definitions of customShortcutKey_Shift_8 9 0
877  function customShortcutKey_Shift_8() { showAnalysisBoard(true); }
878  function customShortcutKey_Shift_9() { showAnalysisBoard(false); }
879  function customShortcutKey_Shift_0() { if (showAnalysis) { hideAnalysisBoard(); } else { showAnalysisBoard(disableEngine); } }
880
881  boardShortcut("F5", "toggle event information", function(t,e){ if (e.shiftKey) { toggleRoundReverse(); } else { toggleShowEvent(); } });
882  boardShortcut("G5", "toggle teams information", function(t,e){ toggleShowTeams(); });
883  boardShortcut("H5", "toggle title/elo players information", function(t,e){ toggleShowPlayersInfo(); });
884  boardShortcut("G6", "toggle last moves information", function(t,e){ toggleShowLastMoves(); });
885
886  if (LiveBroadcastDelay > 0) {
887    boardShortcut("B7", "search previous game with new moves", function(t,e){ searchGameWithNewMoves(true); });
888    boardShortcut("C7", "search next game with new moves", function(t,e){ searchGameWithNewMoves(false); });
889  }
890  clearShortcutSquares("F", "7");
891
892  if (!pgn4web_engineWindowDisableAnalysisBoard) {
893    boardShortcut("E8", "open/update analysis board", function(t,e){ showAnalysisBoard(e.shiftKey); });
894    boardShortcut("F8", "close/pause analysis board", function(t,e){ if (!e.shiftKey) { hideAnalysisBoard(); } });
895  }
896
897
898  function toggleShowEvent() {
899    showEvent = !showEvent;
900    printGames();
901  }
902
903  function toggleRoundReverse() {
904    roundReverse = !roundReverse;
905    gameId.sort(sortGameId);
906    printGames();
907  }
908
909  function toggleShowTeams() {
910    showTeams = !showTeams;
911    printGames();
912  }
913
914  function toggleShowPlayersInfo() {
915    showPlayersInfo = !showPlayersInfo;
916    printGames();
917    customFunctionOnPgnGameLoad();
918  }
919
920  function toggleShowLastMoves() {
921    showLastMoves = !showLastMoves;
922    printGames();
923  }
924
925  function toggleShowBoard() {
926    var theObj;
927    showBoard = !showBoard;
928    if (theObj = document.getElementById("GameFloatingContainer")) {
929      theObj.style.display = showBoard ? "" : "none";
930    }
931    if (theObj = document.getElementById("GameLiveStatus2")) {
932      theObj.style.display = showBoard ? "none" : "";
933    }
934    if (showBoard) { Init(currentGame); }
935    printGames();
936  }
937
938  function toggleAdjustBoard() {
939    var theObj;
940    adjustBoard = !adjustBoard;
941    if (adjustBoard) { myOnResize(); }
942    else {
943      if (theObj = document.getElementById("GameFloatingContainer")) { theObj.style.marginRight = 0; }
944    }
945  }
946
947  var thisEngineWin;
948  function showAnalysisBoard(de) {
949    if (pgn4web_engineWindowDisableAnalysisBoard) { return; }
950    var theObj;
951    if (!showBoard) { return; }
952    thisEngineWin = showEngineAnalysisBoard(de);
953    if (thisEngineWin) {
954      disableEngine = de;
955      if (theObj = document.getElementById('GameAnalysisContainer')) {
956        theObj.style.width = "304px"; // defined as gameAnalysisContainer.width.open = gameAnalysisFrame.width + gameAnalysisFrame.marginLeft + body.padding
957      }
958      showAnalysis = true;
959    }
960  }
961
962  function hideAnalysisBoard() {
963    if (pgn4web_engineWindowDisableAnalysisBoard) { return; }
964    var theObj;
965    if (theObj = document.getElementById('GameAnalysisContainer')) {
966      theObj.style.width = "40px"; // = gameAnalysisContainer.width.closed
967    }
968    if (typeof(thisEngineWin) != "undefined") {
969      if (typeof(thisEngineWin.StopBackgroundEngine) == "function") { thisEngineWin.StopBackgroundEngine(); }
970      if (typeof(thisEngineWin.autoUpdate) != "undefined") { thisEngineWin.autoUpdate = false; }
971    }
972    showAnalysis = false;
973  }
974
975  function gup(name) {
976
977    name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
978    var regexS = "[\\?&]"+name+"=([^&#]*)";
979    // commented below to match first occurrence (to avoid users overruling setting)
980    // regexS = regexS+"(?!.*"+regexS+")"; // matches the LAST occurrence
981    var regex = new RegExp( regexS, "i" );
982    var results = regex.exec( window.location.href );
983    if (results !== null) { return decodeURIComponent(results[1]); }
984
985    // allows for short version of the URL parameters, for instance sC matches squareColor
986    var compact_name = name.charAt(0);
987    for (var i=1; i<name.length; i++) {
988      if (name.charAt(i).match(/[A-Z]/)) { compact_name = compact_name + name.charAt(i).toLowerCase(); }
989    }
990    name = compact_name;
991
992    name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
993    regexS = "[\\?&]"+name+"=([^&#]*)";
994    // commented below to match first occurrence (to avoid users overruling setting)
995    // regexS = regexS+"(?!.*"+regexS+")"; // matches the LAST occurrence
996    regex = new RegExp( regexS, "i" );
997
998    results = regex.exec( window.location.href );
999    if (results !== null) { return decodeURIComponent(results[1]); }
1000
1001    return "";
1002  }
1003
1004</script>
1005
1006</head>
1007
1008<body onResize="myOnResize();" onLoad="myOnResize();">
1009
1010<h1 class="pageHeader" id="pageHeader">pgn4web <a class="pageHeader" href="#games">live chess broadcast</a></h1>
1011
1012<table class="gameFloatingContainer" id="GameFloatingContainer" cellspacing="0" cellpadding="0" border="0"><tr valign="top"><td align="leftt">
1013<div class="gameAnalysisContainer" id="GameAnalysisContainer">
1014<div class="gameAnalysisButtons" id="GameAnalysisButtons" title="analysis board: try moves clicking from/to squares" onclick="hideAnalysisBoard();"></div>
1015<iframe class="gameAnalysisFrame" id="GameAnalysisFrame" name="pgn4webAnalysisBoardForLiveResultsViewer" src="./blank.html" frameborder="0" scrolling="no" marginheight="0" marginwidth="0">your web browser and/or your host do not support iframes as required</iframe>
1016</div>
1017</td><td align="left">
1018<div class="gameBoardContainer" id="GameBoardContainer">
1019<div class="header"><span class="gameEvent" id="GameEvent">&nbsp;</span><span class="gameLiveStatus"><span style="display: none;" id="GameDate"></span><span id="GameLiveStatus" style="cursor:pointer;"></span></span></div>
1020<div class="header"><span class="gameWhite" id="GameWhite" title="white player" onclick="openFidePlayerUrl(this.innerHTML, customPgnHeaderTag('WhiteFideId')); this.blur();"></span><span class="gameWhiteClock" id="GameWhiteClock" title="white clock"></span><span class="gameBlackClock" id="GameBlackClock" title="black clock"></span><span class="gameBlack" id="GameBlack" title="black player" onclick="openFidePlayerUrl(this.innerHTML, customPgnHeaderTag('BlackFideId')); this.blur();"></span></div>
1021<div class="gameBoard" id="GameBoard"></div>
1022<div class="footer"><span class="gameSideToMove"><span class="sideToMove sideToMoveHidden" id="SideToMove" title="side to move"></span>&nbsp;</span><span class="gameText">&nbsp;<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="SetHighlight(!highlightOption); 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;">&nbsp;</span></span><span class="gameResult" id="GameResult" onclick="GoToMove(StartPlyVar[0] + PlyNumberVar[0], 0); this.blur();" title="go to game end"></span></div>
1023<div class="footer"><span class="gameDateAdjusted" id="GameDateAdjusted" onclick="searchLiveGame(event.shiftKey);"></span></div>
1024</div>
1025</td></tr></table>
1026
1027<a name="games" class="gamesAnchor" id="gamesAnchor"></a>
1028
1029<div id="results"></div>
1030<span class="gameLiveStatus2" id="GameLiveStatus2"></span>
1031
1032<script type="text/javascript">
1033  "use strict";
1034
1035  var theObj;
1036
1037  if (theObj = document.getElementById("GameFloatingContainer")) {
1038    theObj.style.display = showBoard ? "" : "none";
1039  }
1040  if (theObj = document.getElementById("GameLiveStatus2")) {
1041      theObj.style.display = showBoard ? "none" : "";
1042  }
1043  if (theObj = document.getElementById("pageHeader")) {
1044    theObj.style.display = headlessPage ? "none" : "";
1045  }
1046  if (theObj = document.getElementById("gamesAnchor")) {
1047    theObj.style.display = headlessPage ? "none" : "";
1048  }
1049  if (theObj = document.getElementById("GameDate")) {
1050    if (refreshMinutes === 0) { theObj.style.display = ""; }
1051  }
1052
1053  function myOnResize() {
1054    if (!adjustBoard) { return false; }
1055    var ww, wh;
1056    if (window.innerWidth && window.innerHeight) { ww = window.innerWidth; wh = window.innerHeight; }
1057    else if (document.documentElement && document.documentElement.clientWidth) { ww = document.documentElement.clientWidth; wh = document.documentElement.clientHeight; }
1058    else if (document.body && document.body.clientWidth) { ww = document.body.clientWidth; wh = document.body.clientHeight; }
1059    else { return false; }
1060
1061    var theObj = document.getElementById("GameFloatingContainer");
1062    if (theObj) {
1063      // targetMargin = 0.5 * (ww - 2 * body.padding - event.width - 2 * player.paddingLeft - round.width - player.marginRight - 12 * game.fontSize - gameBoardContainer.width - gameBoardContainer.paddingRight - gameFloatingContainer.right - extra);
1064      var targetMargin = 0.5 * (ww - 40 - 420 - 2 * 5 - 50 - 20 - 324 - 12 * 14 - 40 - 0 - 40);
1065      theObj.style.marginRight = targetMargin > 0 ? targetMargin + "px" : 0;
1066      return true;
1067    } else { return false; }
1068  }
1069
1070  function pgn4web_handleTouchEnd_FloatingContainer(e) {
1071    e.stopPropagation();
1072    var jj, deltaX, deltaY;
1073    for (var ii = 0; ii < e.changedTouches.length; ii++) {
1074      if ((jj = pgn4webOngoingTouchIndexById(e.changedTouches[ii].identifier)) != -1) {
1075        if (pgn4webOngoingTouches.length == 1) {
1076          deltaX = e.changedTouches[ii].clientX - pgn4webOngoingTouches[jj].clientX;
1077          deltaY = e.changedTouches[ii].clientY - pgn4webOngoingTouches[jj].clientY;
1078          if (Math.max(Math.abs(deltaX), Math.abs(deltaY)) >= 13) {
1079            if (Math.abs(deltaX) > 1.5 * Math.abs(deltaY)) {
1080              if (deltaX > 0) { // horizontal right
1081                hideAnalysisBoard();
1082              } else { // horizontal left
1083                showAnalysisBoard(false);
1084              }
1085            } else if (Math.abs(deltaY) > 1.5 * Math.abs(deltaX)) { // vertical up or down
1086              refreshPgnSource();
1087            }
1088          }
1089          pgn4webMaxTouches = 0;
1090        }
1091        pgn4webOngoingTouches.splice(jj, 1);
1092      }
1093    }
1094    clearSelectedText();
1095  }
1096
1097  if (touchEventEnabled) {
1098    if (theObj = document.getElementById("GameFloatingContainer")) {
1099      simpleAddEvent(theObj, "touchstart", pgn4web_handleTouchStart);
1100      simpleAddEvent(theObj, "touchmove", pgn4web_handleTouchMove);
1101      simpleAddEvent(theObj, "touchend", pgn4web_handleTouchEnd_FloatingContainer);
1102      simpleAddEvent(theObj, "touchleave", pgn4web_handleTouchEnd_FloatingContainer);
1103      simpleAddEvent(theObj, "touchcancel", pgn4web_handleTouchCancel);
1104    }
1105    if ((LiveBroadcastDelay > 0) || (!pgn4web_engineWindowDisableAnalysisBoard)) {
1106      touchGestures_helpActions =  touchGestures_helpActions.concat([ "&nbsp;" ]);
1107      touchGestures_helpText = touchGestures_helpText.concat([ "" ]);
1108    }
1109    if (LiveBroadcastDelay > 0) {
1110      touchGestures_helpActions =  touchGestures_helpActions.concat([ "game header vertical swipe" ]);
1111      touchGestures_helpText = touchGestures_helpText.concat([ "force live broadcast games refresh" ]);
1112    }
1113    if (!pgn4web_engineWindowDisableAnalysisBoard) {
1114      touchGestures_helpActions =  touchGestures_helpActions.concat([ "game header left-right swipe", "game header right-left swipe" ]);
1115      touchGestures_helpText = touchGestures_helpText.concat([ "close/pause analysis board", "open/update analysis board" ]);
1116    }
1117    touchGestures_helpActions =  touchGestures_helpActions.concat([ "&nbsp;", "games list swipe" ]);
1118    touchGestures_helpText = touchGestures_helpText.concat([ "", "scroll the games list" ]);
1119  }
1120
1121</script>
1122
1123</body>
1124
1125</html>
1126