text: var __extends = (this && this.__extends) || (function () {
      var extendStatics = Object.setPrototypeOf ||
          ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
          function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
      return function (d, b) {
          extendStatics(d, b);
          function __() { this.constructor = d; }
          d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
      };
  })();
  var RawData;
  (function (RawData) {
      RawData.pieces = {
          "p": "\n<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<svg\n   xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n   xmlns:cc=\"http://creativecommons.org/ns#\"\n   xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n   xmlns:svg=\"http://www.w3.org/2000/svg\"\n   xmlns=\"http://www.w3.org/2000/svg\"\n   xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"\n   xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"\n   viewBox=\"0 0 2048 2048\"\n   id=\"svg3044\"\n   version=\"1.1\"\n   inkscape:version=\"0.48.4 r9939\"\n   width=\"100%\"\n   height=\"100%\"\n   sodipodi:docname=\"bP.svg\">\n  <metadata\n     id=\"metadata3054\">\n    <rdf:RDF>\n      <cc:Work\n         rdf:about=\"\">\n        <dc:format>image/svg+xml</dc:format>\n        <dc:type\n           rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" />\n        <dc:title></dc:title>\n      </cc:Work>\n    </rdf:RDF>\n  </metadata>\n  <defs\n     id=\"defs3052\" />\n  <sodipodi:namedview\n     pagecolor=\"#ffffff\"\n     bordercolor=\"#666666\"\n     borderopacity=\"1\"\n     objecttolerance=\"10\"\n     gridtolerance=\"10\"\n     guidetolerance=\"10\"\n     inkscape:pageopacity=\"0\"\n     inkscape:pageshadow=\"2\"\n     inkscape:window-width=\"2880\"\n     inkscape:window-height=\"1800\"\n     id=\"namedview3050\"\n     showgrid=\"false\"\n     inkscape:zoom=\"0.75195312\"\n     inkscape:cx=\"1024\"\n     inkscape:cy=\"1024\"\n     inkscape:window-x=\"0\"\n     inkscape:window-y=\"0\"\n     inkscape:window-maximized=\"0\"\n     inkscape:current-layer=\"svg3044\" />\n  <g\n     transform=\"matrix(1 0 0 -1 0 2048)\"\n     id=\"g3046\">\n    <path\n       fill=\"#101010\"\n       d=\"M1024 205h-578v74q-4 80 41.5 137t125.5 108q117 91 171.5 217.5t78.5 267.5h-287l284 239q-86 74 -86 188q0 103 73 177t177 74q103 0 176.5 -74t73.5 -177q0 -114 -86 -188l284 -239h-287q23 -141 78 -267.5t172 -217.5q79 -51 124.5 -108t42.5 -137v-74h-578z\"\n       id=\"path3048\" />\n  </g>\n</svg>\n",
          "n": "\n<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<svg\n   xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n   xmlns:cc=\"http://creativecommons.org/ns#\"\n   xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n   xmlns:svg=\"http://www.w3.org/2000/svg\"\n   xmlns=\"http://www.w3.org/2000/svg\"\n   xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"\n   xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"\n   viewBox=\"0 0 2048 2048\"\n   id=\"svg2\"\n   version=\"1.1\"\n   inkscape:version=\"0.48.2 r9819\"\n   width=\"100%\"\n   height=\"100%\"\n   sodipodi:docname=\"bn.svg\">\n  <metadata\n     id=\"metadata12\">\n    <rdf:RDF>\n      <cc:Work\n         rdf:about=\"\">\n        <dc:format>image/svg+xml</dc:format>\n        <dc:type\n           rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" />\n      </cc:Work>\n    </rdf:RDF>\n  </metadata>\n  <defs\n     id=\"defs10\" />\n  <sodipodi:namedview\n     pagecolor=\"#ffffff\"\n     bordercolor=\"#666666\"\n     borderopacity=\"1\"\n     objecttolerance=\"10\"\n     gridtolerance=\"10\"\n     guidetolerance=\"10\"\n     inkscape:pageopacity=\"0\"\n     inkscape:pageshadow=\"2\"\n     inkscape:window-width=\"640\"\n     inkscape:window-height=\"678\"\n     id=\"namedview8\"\n     showgrid=\"false\"\n     inkscape:zoom=\"0.11523438\"\n     inkscape:cx=\"1024\"\n     inkscape:cy=\"1024\"\n     inkscape:window-x=\"0\"\n     inkscape:window-y=\"0\"\n     inkscape:window-maximized=\"0\"\n     inkscape:current-layer=\"svg2\" />\n  <g\n     transform=\"matrix(1 0 0 -1 0 2048)\"\n     id=\"g4\">\n    <path\n       fill=\"#101010\"\n       d=\"M502 1180l-52 -1l-26 -64l69 -21l46 55zM1038 1367q34 -1 -16 68t-80 42l-116 -109zM700 1465q6 39 115.5 107.5t220.5 143.5l115 154l96 -217q342 -172 432.5 -417.5t47.5 -603.5q-18 -128 4.5 -236t57.5 -190l-1242 -1q-9 178 39 301.5t183 237.5q50 11 82.5 39.5 t53.5 58.5l62.5 1t138 29t139 97t66.5 207q0 17 -8.5 34t-11.5 37q-62 -228 -161 -288.5t-191 -58.5q-236 42 -292 -60l-56 -102l-217 121l115 82l-51 50l-122 -86l-12 297zM1681 273q-102 130 -85 308.5t27 362.5t-50 351.5t-316 275.5q220 -164 252.5 -342t16.5 -350.5 t-12 -329t167 -276.5z\"\n       id=\"path6\" />\n  </g>\n  <path\n     style=\"fill:#ececec;fill-opacity:1;stroke:#101010;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:3.79999995;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0\"\n     d=\"m 1601.3052,1693.0403 c -81.081,-89.747 -91.5841,-156.5414 -74.2276,-472.0505 20.3789,-370.45059 -8.7512,-495.11834 -150.5575,-644.33895 -28.3483,-29.83051 -47.8136,-54.23729 -43.2562,-54.23729 17.0173,0 100.1093,58.43477 144.6504,101.72598 57.0521,55.45106 86.1396,107.89196 109.6386,197.66385 34.9938,133.6852 37.5437,201.94031 17.3275,463.81811 -19.9909,258.9589 -17.5419,312.6196 18.0578,395.6705 9.6985,22.6255 16.1305,42.6404 14.2935,44.4774 -1.8371,1.8371 -18.004,-12.891 -35.9265,-32.7291 l 0,0 z\"\n     id=\"path2989\"\n     inkscape:connector-curvature=\"0\" />\n  <path\n     style=\"fill:#ececec;fill-opacity:1;stroke:#101010;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:3.79999995;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0\"\n     d=\"m 896.70344,621.33017 c 55.68259,-53.26842 60.42184,-55.96132 78.1017,-44.37838 26.06806,17.07847 76.40326,84.06615 70.43026,93.73076 -2.6971,4.36392 -50.55804,7.80453 -106.35772,7.6458 l -101.45395,-0.2886 59.27971,-56.70958 z\"\n     id=\"path2991\"\n     inkscape:connector-curvature=\"0\" />\n  <path\n     style=\"fill:#ececec;fill-opacity:1;stroke:#101010;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:3.79999995;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0\"\n     d=\"m 464.27119,941.44594 c -27.44127,-6.6005 -31.26949,-14.68402 -20.9599,-44.25815 7.68249,-22.038 14.48333,-27.65559 33.48079,-27.65559 13.112,0 30.36269,7.20749 38.33486,16.01664 13.59229,15.01931 13.36664,17.45094 -3.62386,39.05085 -9.96529,12.66881 -20.76409,22.58121 -23.99733,22.02755 -3.23325,-0.55366 -13.6888,-2.88525 -23.23456,-5.1813 z\"\n     id=\"path2993\"\n     inkscape:connector-curvature=\"0\" />\n</svg>\n",
          "b": "\n<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<svg\n   xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n   xmlns:cc=\"http://creativecommons.org/ns#\"\n   xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n   xmlns:svg=\"http://www.w3.org/2000/svg\"\n   xmlns=\"http://www.w3.org/2000/svg\"\n   xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"\n   xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"\n   viewBox=\"0 0 2048 2048\"\n   id=\"svg2\"\n   version=\"1.1\"\n   inkscape:version=\"0.48.2 r9819\"\n   width=\"100%\"\n   height=\"100%\"\n   sodipodi:docname=\"bb.svg\">\n  <metadata\n     id=\"metadata12\">\n    <rdf:RDF>\n      <cc:Work\n         rdf:about=\"\">\n        <dc:format>image/svg+xml</dc:format>\n        <dc:type\n           rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" />\n      </cc:Work>\n    </rdf:RDF>\n  </metadata>\n  <defs\n     id=\"defs10\" />\n  <sodipodi:namedview\n     pagecolor=\"#ffffff\"\n     bordercolor=\"#666666\"\n     borderopacity=\"1\"\n     objecttolerance=\"10\"\n     gridtolerance=\"10\"\n     guidetolerance=\"10\"\n     inkscape:pageopacity=\"0\"\n     inkscape:pageshadow=\"2\"\n     inkscape:window-width=\"640\"\n     inkscape:window-height=\"700\"\n     id=\"namedview8\"\n     showgrid=\"false\"\n     inkscape:zoom=\"0.11523438\"\n     inkscape:cx=\"1024\"\n     inkscape:cy=\"1024\"\n     inkscape:window-x=\"0\"\n     inkscape:window-y=\"0\"\n     inkscape:window-maximized=\"0\"\n     inkscape:current-layer=\"svg2\" />\n  <g\n     transform=\"matrix(1 0 0 -1 0 2048)\"\n     id=\"g4\">\n    <path\n       fill=\"#101010\"\n       d=\"M768 683q-5 -39 -26 -82h564q-18 36 -26 82h-512zM1263 756l46 73q-142 49 -285 47q-144 2 -285 -47l46 -73q118 40 239 38q120 2 239 -38zM831 529h-207q67 116 72 229q-114 119 -162 223.5t-6 223.5q33 96 118 189.5t312 246.5q-17 11 -46 36t-29 79q0 58 41 96t100 38 q58 0 99.5 -38t41.5 -96q0 -54 -29.5 -79t-45.5 -36q226 -153 311 -246.5t119 -189.5q42 -119 -6 -223.5t-162 -223.5q4 -113 72 -229h-207q-2 4 10 -16q33 -53 70 -60t89 -7h250q76 0 141.5 -62t65.5 -179h-495q-123 0 -223.5 84.5t-100.5 198.5q0 -114 -101 -198.5 t-223 -84.5h-495q0 117 65 179t142 62h250q51 0 88 7t71 60q12 20 10 16zM977 1230h-95v-89h95v-165h94v165h95v89h-95v104h-94v-104z\"\n       id=\"path6\" />\n  </g>\n  <path\n     style=\"fill:#ececec;fill-opacity:1;stroke:#101010;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:3.79999995;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0\"\n     d=\"m 761.54028,1406.6983 12.85605,-39.0508 249.60367,0 249.6037,0 12.856,39.0508 12.8561,39.0509 -275.3158,0 -275.31577,0 12.85605,-39.0509 z\"\n     id=\"path2989\"\n     inkscape:connector-curvature=\"0\" />\n  <path\n     style=\"fill:#ececec;fill-opacity:1;stroke:#101010;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:3.79999995;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0\"\n     d=\"m 765.07813,1250.9479 -17.65316,-29.9199 44.99938,-13.0677 c 84.66507,-24.5867 172.41074,-33.5953 274.96545,-28.2302 54.8882,2.8715 113.4644,8.9793 130.1695,13.5729 16.7051,4.5936 46.7792,12.6064 66.8314,17.8062 l 36.4585,9.4541 -17.7902,30.1522 c -20.3271,34.4518 -23.3108,34.9921 -91.5848,16.5858 -68.72,-18.5267 -266.2284,-18.5267 -334.94845,0 -68.23049,18.3946 -71.26607,17.8518 -91.44762,-16.3534 z\"\n     id=\"path2991\"\n     inkscape:connector-curvature=\"0\" />\n  <path\n     style=\"fill:#ececec;fill-opacity:1;stroke:#101010;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:3.79999995;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0\"\n     d=\"m 980.61017,981.47797 0,-82.44068 -47.72881,0 -47.72882,0 0,-39.05085 0,-39.05085 47.72882,0 47.72881,0 0,-52.06779 0,-52.0678 43.38983,0 43.3898,0 0,52.0678 0,52.06779 47.7288,0 47.7289,0 0,39.05085 0,39.05085 -47.7289,0 -47.7288,0 0,82.44068 0,82.44063 -43.3898,0 -43.38983,0 0,-82.44063 z\"\n     id=\"path2993\"\n     inkscape:connector-curvature=\"0\" />\n</svg>\t\n",
          "r": "\n<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<svg\n   xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n   xmlns:cc=\"http://creativecommons.org/ns#\"\n   xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n   xmlns:svg=\"http://www.w3.org/2000/svg\"\n   xmlns=\"http://www.w3.org/2000/svg\"\n   xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"\n   xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"\n   viewBox=\"0 0 2048 2048\"\n   id=\"svg2\"\n   version=\"1.1\"\n   inkscape:version=\"0.48.2 r9819\"\n   width=\"100%\"\n   height=\"100%\"\n   sodipodi:docname=\"br.svg\">\n  <metadata\n     id=\"metadata12\">\n    <rdf:RDF>\n      <cc:Work\n         rdf:about=\"\">\n        <dc:format>image/svg+xml</dc:format>\n        <dc:type\n           rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" />\n      </cc:Work>\n    </rdf:RDF>\n  </metadata>\n  <defs\n     id=\"defs10\" />\n  <sodipodi:namedview\n     pagecolor=\"#ffffff\"\n     bordercolor=\"#666666\"\n     borderopacity=\"1\"\n     objecttolerance=\"10\"\n     gridtolerance=\"10\"\n     guidetolerance=\"10\"\n     inkscape:pageopacity=\"0\"\n     inkscape:pageshadow=\"2\"\n     inkscape:window-width=\"640\"\n     inkscape:window-height=\"709\"\n     id=\"namedview8\"\n     showgrid=\"false\"\n     inkscape:zoom=\"0.11523438\"\n     inkscape:cx=\"1024\"\n     inkscape:cy=\"1024\"\n     inkscape:window-x=\"0\"\n     inkscape:window-y=\"0\"\n     inkscape:window-maximized=\"0\"\n     inkscape:current-layer=\"svg2\" />\n  <g\n     transform=\"matrix(1 0 0 -1 0 2048)\"\n     id=\"g4\">\n    <path\n       fill=\"#101010\"\n       d=\"M1024 205h-641l29 264l159 118l50 659l-149 107l-17 341h289v-147h137v147h143h143v-147h137v147h289l-17 -341l-149 -107l50 -659l159 -118l29 -264h-641zM1024 1194h333l-6 88h-327h-327l-6 -88h333zM1024 547h381l-6 87h-375h-375l-6 -87h381z\"\n       id=\"path6\" />\n  </g>\n  <path\n     style=\"fill:#ececec;fill-opacity:1;stroke:#101010;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:3.79999995;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0\"\n     d=\"m 650.84746,1457.0305 0,-39.0508 373.15254,0 373.1525,0 0,39.0508 0,39.0509 -373.1525,0 -373.15254,0 0,-39.0509 z\"\n     id=\"path2989\"\n     inkscape:connector-curvature=\"0\" />\n  <path\n     style=\"fill:#ececec;fill-opacity:1;stroke:#101010;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:3.79999995;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0\"\n     d=\"m 694.23729,837.64068 c 0,-8.94915 2.44068,-28.47458 5.42373,-43.38983 l 5.42373,-27.11865 318.91525,0 318.9153,0 5.4237,27.11865 c 13.0658,65.32909 43.8795,59.66101 -324.339,59.66101 -316.64934,0 -329.76271,-0.64703 -329.76271,-16.27118 z\"\n     id=\"path2991\"\n     inkscape:connector-curvature=\"0\" />\n</svg>\n",
          "q": "\n<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<svg\n   xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n   xmlns:cc=\"http://creativecommons.org/ns#\"\n   xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n   xmlns:svg=\"http://www.w3.org/2000/svg\"\n   xmlns=\"http://www.w3.org/2000/svg\"\n   xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"\n   xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"\n   viewBox=\"0 0 2048 2048\"\n   id=\"svg2\"\n   version=\"1.1\"\n   inkscape:version=\"0.48.2 r9819\"\n   width=\"100%\"\n   height=\"100%\"\n   sodipodi:docname=\"bq.svg\">\n  <metadata\n     id=\"metadata12\">\n    <rdf:RDF>\n      <cc:Work\n         rdf:about=\"\">\n        <dc:format>image/svg+xml</dc:format>\n        <dc:type\n           rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" />\n      </cc:Work>\n    </rdf:RDF>\n  </metadata>\n  <defs\n     id=\"defs10\" />\n  <sodipodi:namedview\n     pagecolor=\"#ffffff\"\n     bordercolor=\"#666666\"\n     borderopacity=\"1\"\n     objecttolerance=\"10\"\n     gridtolerance=\"10\"\n     guidetolerance=\"10\"\n     inkscape:pageopacity=\"0\"\n     inkscape:pageshadow=\"2\"\n     inkscape:window-width=\"640\"\n     inkscape:window-height=\"667\"\n     id=\"namedview8\"\n     showgrid=\"false\"\n     inkscape:zoom=\"0.11523438\"\n     inkscape:cx=\"1024\"\n     inkscape:cy=\"1024\"\n     inkscape:window-x=\"0\"\n     inkscape:window-y=\"0\"\n     inkscape:window-maximized=\"0\"\n     inkscape:current-layer=\"svg2\" />\n  <g\n     transform=\"matrix(1 0 0 -1 0 2048)\"\n     id=\"g4\">\n    <path\n       fill=\"#101010\"\n       d=\"M590 529q4 -72 -15 -158l134 86zM1024 205h-583q114 231 57.5 456.5t-202.5 449.5q-12 -2 -19 -2q-54 0 -92.5 38.5t-38.5 92.5t38.5 92.5t92.5 38.5t92.5 -38.5t38.5 -92.5q0 -20 -6 -38q-4 -14 -15 -33l196 -139l100 486q-64 31 -72 103q-5 44 29 91t88 53q54 5 96 -29 t48 -88q7 -68 -46 -114l198 -412l198 412q-54 46 -46 114q6 54 48 88t96 29q54 -6 87.5 -53t29.5 -91q-9 -72 -72 -103l100 -486l196 139q-12 19 -15 33q-6 18 -6 38q0 54 38.5 92.5t92.5 38.5t92.5 -38.5t38.5 -92.5t-38.5 -92.5t-92.5 -38.5q-7 0 -19 2 q-147 -224 -203 -449.5t58 -456.5h-583zM1024 655q109 0 222 -28.5t213 -67.5q2 41 11 89q-108 42 -221.5 68t-224.5 26t-225 -26t-221 -68q8 -48 11 -89q99 39 212 67.5t223 28.5zM1024 279h478q-15 34 -24 73h-454h-454q-10 -39 -24 -73h478zM1458 529l-119 -72l134 -86 q-20 86 -15 158zM885 482l139 -87l139 84l-139 86z\"\n       id=\"path6\" />\n  </g>\n  <path\n     style=\"fill:#ececec;fill-opacity:1;stroke:#101010;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:3.79999995;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0\"\n     d=\"m 555.38983,1758.5831 c 0,-1.6742 4.2871,-15.342 9.52689,-30.3729 l 9.52689,-27.3288 449.55639,0 449.5564,0 9.5268,27.3288 c 5.2399,15.0309 9.527,28.6987 9.527,30.3729 0,1.6742 -210.8746,3.044 -468.6102,3.044 -257.73559,0 -468.61017,-1.3698 -468.61017,-3.044 z\"\n     id=\"path2989\"\n     inkscape:connector-curvature=\"0\" />\n  <path\n     style=\"fill:#ececec;fill-opacity:1;stroke:#101010;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:3.79999995;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0\"\n     d=\"m 952.36273,1602.4318 -58.62033,-37.2523 65.13723,-37.2686 65.13727,-37.2687 60.7373,36.0834 c 33.4055,19.8459 60.6625,38.8378 60.5711,42.2043 -0.2311,8.5096 -108.8863,71.2569 -122.911,70.98 -6.2872,-0.1242 -37.81039,-16.9893 -70.05157,-37.4781 l 0,0 z\"\n     id=\"path2991\"\n     inkscape:connector-curvature=\"0\" />\n  <path\n     style=\"fill:#ececec;fill-opacity:1;stroke:#101010;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:3.79999995;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0\"\n     d=\"m 1412.923,1632.6676 c -27.1228,-17.3706 -49.3851,-35.4879 -49.4716,-40.2608 -0.086,-4.7729 20.1524,-21.5067 44.9753,-37.1863 l 45.1326,-28.5082 5.2025,67.5591 c 2.8614,37.1575 4.8139,68.1036 4.339,68.7691 -0.475,0.6655 -23.0549,-13.0023 -50.1778,-30.3729 z\"\n     id=\"path2993\"\n     inkscape:connector-curvature=\"0\" />\n  <path\n     style=\"fill:#ececec;fill-opacity:1;stroke:#101010;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:3.79999995;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0\"\n     d=\"m 588.8,1452.531 c -0.71593,-16.1395 -1.6922,-33.6413 -2.16949,-38.8928 -2.09522,-23.0535 203.92127,-80.7864 343.77351,-96.3372 72.02368,-8.0087 114.68708,-8.0855 184.07668,-0.3314 140.5733,15.7087 348.9687,73.7829 346.8888,96.6686 -0.4773,5.2515 -1.4536,22.7533 -2.1695,38.8928 l -1.3017,29.3445 -101.9661,-32.592 c -133.917,-42.8047 -210.8059,-55.7092 -331.9322,-55.7092 -121.12634,0 -198.01519,12.9045 -331.9322,55.7092 L 590.10169,1481.8755 588.8,1452.531 z\"\n     id=\"path2995\"\n     inkscape:connector-curvature=\"0\" />\n  <path\n     style=\"fill:#ececec;fill-opacity:1;stroke:#101010;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:3.79999995;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0\"\n     d=\"m 587.65069,1602.7569 c 2.11115,-34.3298 4.52362,-65.41 5.36106,-69.0669 0.83744,-3.657 24.25108,7.5677 52.03032,24.9437 27.77924,17.3761 47.28358,34.5936 43.34299,38.2611 -3.9406,3.6676 -29.08154,20.531 -55.86876,37.4742 l -48.70404,30.8059 3.83843,-62.418 z\"\n     id=\"path2997\"\n     inkscape:connector-curvature=\"0\" />\n</svg>\n",
          "k": "\n<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<svg\n   xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n   xmlns:cc=\"http://creativecommons.org/ns#\"\n   xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n   xmlns:svg=\"http://www.w3.org/2000/svg\"\n   xmlns=\"http://www.w3.org/2000/svg\"\n   xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"\n   xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"\n   viewBox=\"0 0 2048 2048\"\n   id=\"svg2\"\n   version=\"1.1\"\n   inkscape:version=\"0.48.2 r9819\"\n   width=\"100%\"\n   height=\"100%\"\n   sodipodi:docname=\"bk.svg\">\n  <metadata\n     id=\"metadata12\">\n    <rdf:RDF>\n      <cc:Work\n         rdf:about=\"\">\n        <dc:format>image/svg+xml</dc:format>\n        <dc:type\n           rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" />\n      </cc:Work>\n    </rdf:RDF>\n  </metadata>\n  <defs\n     id=\"defs10\" />\n  <sodipodi:namedview\n     pagecolor=\"#ffffff\"\n     bordercolor=\"#666666\"\n     borderopacity=\"1\"\n     objecttolerance=\"10\"\n     gridtolerance=\"10\"\n     guidetolerance=\"10\"\n     inkscape:pageopacity=\"0\"\n     inkscape:pageshadow=\"2\"\n     inkscape:window-width=\"640\"\n     inkscape:window-height=\"673\"\n     id=\"namedview8\"\n     showgrid=\"false\"\n     inkscape:zoom=\"0.11523438\"\n     inkscape:cx=\"1024\"\n     inkscape:cy=\"1024\"\n     inkscape:window-x=\"0\"\n     inkscape:window-y=\"0\"\n     inkscape:window-maximized=\"0\"\n     inkscape:current-layer=\"svg2\" />\n  <g\n     transform=\"matrix(1 0 0 -1 0 2048)\"\n     id=\"g4\">\n    <path\n       fill=\"#101010\"\n       d=\"M1024 279h489l-12 73h-477h-477l-12 -73h489zM1024 1200q-25 60 -62 111q31 48 62 65q30 -17 62 -65q-38 -51 -62 -111zM927 746q-154 -11 -303 -58q-123 108 -200 213.5t-77 201.5q0 89 73.5 159t148.5 70q67 0 134.5 -62.5t102.5 -130.5q30 -54 75 -175t46 -218z M577 529l-26 -156l145 84zM1024 1436q-47 0 -136 -121q-31 36 -50 55q93 140 186 140q92 0 186 -140q-20 -19 -50 -55q-90 121 -136 121zM1024 661q-1 126 -42 267.5t-84 226.5q-8 14 -14 27t-12 23q-28 43 -48 69q-51 63 -120 105t-134 42q-103 0 -208 -93t-105 -229 q0 -120 99 -254.5t249 -259.5q201 74 419 76zM1024 205h-576l61 365q-325 280 -326 535q-1 159 125 274.5t267 115.5q78 0 158.5 -47t142.5 -119q61 -74 98.5 -164.5t49.5 -150.5q12 60 49 150.5t99 164.5q61 72 142 119t159 47q140 0 266 -115.5t126 -274.5 q-2 -255 -326 -535l61 -365h-576zM1121 746q0 97 45 218t76 175q34 68 101.5 130.5t135.5 62.5q74 0 147.5 -70t74.5 -159q0 -96 -77 -201.5t-200 -213.5q-150 47 -303 58zM1471 529l-119 -72l145 -84zM1024 661q217 -2 419 -76q150 125 249 259.5t99 254.5 q0 136 -105.5 229t-207.5 93q-66 0 -135 -42t-119 -105q-21 -26 -48 -69q-6 -10 -12.5 -23l-13.5 -27q-44 -85 -85 -226.5t-41 -267.5zM885 502l139 -86l139 84l-139 86zM977 1750v95h94v-95h107v-95h-107v-153q-48 16 -94 0v153h-107v95h107z\"\n       id=\"path6\" />\n  </g>\n  <path\n     style=\"fill:#ececec;fill-opacity:1;stroke:#101010;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:3.79999995;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0\"\n     d=\"m 1401.4915,1445.0218 c -78.8657,-27.9719 -280.8492,-63.4896 -361.055,-63.4896 -13.5729,0 -8.3701,-92.9378 9.9317,-177.4108 46.5412,-214.81404 134.473,-397.65875 231.4791,-481.3361 104.2876,-89.95837 202.4256,-110.29259 301.8815,-62.54996 101.7059,48.82269 168.8559,126.47534 192.6106,222.736 11.9521,48.43347 12.5067,65.83472 3.6329,113.99457 -20.0474,108.80099 -81.3793,205.35889 -221.2364,348.30369 -109.9971,112.4256 -114.1265,115.0451 -157.2444,99.7522 z m 122.8177,-179.6594 c 134.7609,-141.4644 175.4829,-214.4621 176.1913,-315.83774 0.4683,-67.03663 -13.4333,-101.83522 -61.5242,-154.00777 -143.4095,-155.58091 -315.1045,-83.45215 -434.3981,182.48989 -42.6209,95.01492 -76.4874,206.09722 -82.5156,270.65102 -5.7063,61.108 -10.2312,57.4923 84.8046,67.7654 26.5972,2.875 83.221,14.3756 125.8305,25.5568 42.6095,11.1812 81.9736,20.7494 87.4759,21.2628 5.5022,0.5134 52.3632,-43.5328 104.1356,-97.8804 l 0,0 z\"\n     id=\"path2989\"\n     inkscape:connector-curvature=\"0\" />\n  <path\n     style=\"fill:#ececec;fill-opacity:1;stroke:#101010;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:3.79999995;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0\"\n     d=\"M 522.69348,1378.7619 C 282.85431,1147.8294 214.58388,976.10591 297.00399,811.07562 307.70836,789.64221 338.00727,752.40497 364.33493,728.3262 467.72145,633.77083 573.50641,610.75174 673.3258,661.08895 778.26588,714.00843 850.6748,798.31641 911.25199,938.11388 969.78,1073.1823 1015.322,1248.2704 1015.322,1338.215 l 0,41.9358 -58.57624,5.339 c -104.0056,9.4797 -214.78092,29.5868 -283.86381,51.5246 l -67.44533,21.4179 -82.74314,-79.6704 z m 186.38255,-35.874 c 46.72683,-11.7086 106.43583,-23.6599 132.68668,-26.5583 95.0231,-10.4919 89.91439,-6.2064 83.92014,-70.3974 -6.61695,-70.8594 -56.45658,-218.8281 -106.45317,-316.0484 -88.352,-171.80383 -210.06736,-249.01461 -320.08376,-203.04682 -44.15978,18.45113 -116.43706,87.49453 -135.7522,129.67827 -19.05108,41.60706 -20.9871,132.18468 -3.85178,180.20755 22.6552,63.4927 71.07585,130.9368 164.1489,228.6396 51.77234,54.3476 95.54808,98.8139 97.27942,98.8139 1.73135,0 41.37895,-9.5798 88.10577,-21.2884 z\"\n     id=\"path2991\"\n     inkscape:connector-curvature=\"0\" />\n  <path\n     style=\"fill:#ececec;fill-opacity:1;stroke:#101010;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:3.79999995;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0\"\n     d=\"M 1003.3744,949.74058 C 986.85194,899.18356 931.32063,785.54395 906.05991,750.5957 c -13.35176,-18.4722 -11.90128,-21.12111 41.57869,-75.93221 38.00403,-38.94995 61.9944,-56.7923 76.3614,-56.7923 14.367,0 38.3574,17.84235 76.3614,56.7923 53.717,55.05403 54.9805,57.37814 41.2802,75.93221 -24.0218,32.53209 -99.7443,191.12876 -105.4708,220.90261 -2.9834,15.51186 -7.9186,28.17512 -10.9671,28.14057 -3.0485,-0.0347 -12.8717,-22.48878 -21.8293,-49.8983 l 0,0 z m 56.6668,-157.68022 31.7022,-59.81846 -28.5336,-31.15146 c -15.6935,-17.1333 -33.3379,-31.15146 -39.2098,-31.15146 -5.8719,0 -23.5163,14.01816 -39.20978,31.15146 l -28.53362,31.15146 31.70221,59.81846 c 17.43619,32.90016 33.65479,59.81847 36.04119,59.81847 2.3864,0 18.605,-26.91831 36.0412,-59.81847 z\"\n     id=\"path2993\"\n     inkscape:connector-curvature=\"0\" />\n  <path\n     style=\"fill:#ececec;fill-opacity:1;stroke:#101010;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:3.79999995;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0\"\n     d=\"m 961.08475,1587.5558 c -32.21695,-20.136 -58.54284,-38.6067 -58.50197,-41.046 0.0409,-2.4394 27.06664,-21.0865 60.05728,-41.4381 l 59.98294,-37.003 61.4343,36.958 c 33.7888,20.3268 61.4342,39.4619 61.4342,42.5224 0,4.9152 -115.8443,77.2345 -123.0087,76.7918 -1.552,-0.096 -29.18111,-16.6492 -61.39805,-36.7851 z\"\n     id=\"path2995\"\n     inkscape:connector-curvature=\"0\" />\n  <path\n     style=\"fill:#ececec;fill-opacity:1;stroke:#101010;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:3.79999995;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0\"\n     d=\"m 558.77664,1652.3188 c 2.3664,-8.1326 6.96336,-34.312 10.21546,-58.1764 8.99418,-66.0007 11.04011,-67.1917 62.32993,-36.2864 25.05763,15.0988 45.55933,29.9113 45.55933,32.9166 0,3.0053 -27.54164,21.4096 -61.20364,40.8985 -45.11665,26.1206 -60.07274,31.5477 -56.90108,20.6477 z\"\n     id=\"path2997\"\n     inkscape:connector-curvature=\"0\" />\n  <path\n     style=\"fill:#ececec;fill-opacity:1;stroke:#101010;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:3.79999995;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0\"\n     d=\"m 1431.8644,1631.7223 c -31.0237,-18.3043 -57.3928,-36.2297 -58.5979,-39.8342 -2.4479,-7.3215 86.9459,-63.409 92.3885,-57.9665 3.4172,3.4172 26.4635,128.9748 23.9283,130.3629 -0.7217,0.3952 -26.6952,-14.2578 -57.7189,-32.5622 z\"\n     id=\"path2999\"\n     inkscape:connector-curvature=\"0\" />\n  <path\n     style=\"fill:#ececec;fill-opacity:1;stroke:#101010;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:3.79999995;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0\"\n     d=\"m 545.06485,1732.9898 3.54586,-30.3729 475.38929,0 475.3893,0 3.5458,30.3729 3.5459,30.3729 -482.481,0 -482.48102,0 3.54587,-30.3729 z\"\n     id=\"path3001\"\n     inkscape:connector-curvature=\"0\" />\n</svg>\n"
      };
  })(RawData || (RawData = {}));
  var TextEncodingUtils;
  (function (TextEncodingUtils) {
      var TEnc = /** @class */ (function () {
          function TEnc(label, options) {
              this.tenc = new TextEncoder(label, options);
          }
          TEnc.prototype.encode = function (input, options) {
              return this.tenc.encode(input, options);
          };
          return TEnc;
      }());
      TextEncodingUtils.TEnc = TEnc;
      var TDec = /** @class */ (function () {
          function TDec(label, options) {
              this.tdec = new TextDecoder(label, options);
          }
          TDec.prototype.decode = function (input, options) {
              return this.tdec.decode(input, options);
          };
          return TDec;
      }());
      TextEncodingUtils.TDec = TDec;
      var tdec = new TDec();
      var tenc = new TEnc();
      function encode(input) {
          return tenc.encode(input);
      }
      TextEncodingUtils.encode = encode;
      function decode(input) {
          return tdec.decode(input);
      }
      TextEncodingUtils.decode = decode;
  })(TextEncodingUtils || (TextEncodingUtils = {}));
  var WasmLoader;
  (function (WasmLoader_1) {
      ///////////////////////////////////////////////////////
      // from: https://stackoverflow.com/questions/33702838/how-to-append-bytes-multi-bytes-and-buffer-to-arraybuffer-in-javascript
      function concatTypedArrays(a, b) {
          var c = new (a.constructor)(a.length + b.length);
          c.set(a, 0);
          c.set(b, a.length);
          return c;
      }
      ///////////////////////////////////////////////////////
      var MemView = /** @class */ (function () {
          function MemView(_view) {
              this.view = _view;
          }
          MemView.prototype.toString = function () {
              var term = this.view.indexOf(0);
              if (term < 0)
                  return null; // not a C terminated string
              return TextEncodingUtils.decode(this.view.slice(0, term));
          };
          MemView.prototype.strCpy = function (str) {
              var view = TextEncodingUtils.encode(str);
              var viewt = concatTypedArrays(view, new Uint8Array([0]));
              this.view.set(viewt);
          };
          return MemView;
      }());
      WasmLoader_1.MemView = MemView;
      var WasmLoader = /** @class */ (function () {
          function WasmLoader(_url, params) {
              this.importObject = {
                  env: {
                      memoryBase: 0,
                      tableBase: 0,
                      memory: new WebAssembly.Memory({ initial: 256 }),
                      table: new WebAssembly.Table({ initial: 0, element: 'anyfunc' })
                  }
              };
              this.url = _url;
              for (var key in params) {
                  var value = params[key];
                  this.importObject.env[key] = value;
              }
          }
          WasmLoader.prototype.env = function () { return this.importObject.env; };
          WasmLoader.prototype.memory = function () { return this.env().memory; };
          WasmLoader.prototype.membuff = function () { return this.memory().buffer; };
          WasmLoader.prototype.memview = function (from, size) {
              return new MemView(new Uint8Array(this.membuff(), from, size));
          };
          WasmLoader.prototype.fetchThen = function (callback) {
              var _this = this;
              if (callback === void 0) { callback = null; }
              fetch(this.url).then(function (response) { return response.arrayBuffer(); }).then(function (bytes) { return WebAssembly.instantiate(bytes, _this.importObject); }).then(function (results) {
                  _this.module = results.instance;
                  _this.exports = _this.module.exports;
                  if (callback != null)
                      callback();
              });
          };
          return WasmLoader;
      }());
      WasmLoader_1.WasmLoader = WasmLoader;
  })(WasmLoader || (WasmLoader = {}));
  var TextAsset = /** @class */ (function () {
      function TextAsset(_url) {
          this.isready = false;
          this.url = _url;
      }
      TextAsset.prototype.load = function () {
          var _this = this;
          fetch(this.url).then(function (response) { return response.arrayBuffer(); }).then(function (bytes) { return _this.onload(bytes); });
      };
      TextAsset.prototype.onload = function (bytes) {
          var view = new Uint8Array(bytes);
          this.text = TextEncodingUtils.decode(view);
          this.isready = true;
      };
      TextAsset.prototype.ready = function () {
          return this.isready;
      };
      TextAsset.prototype.asJson = function () {
          return JSON.parse(this.text);
      };
      return TextAsset;
  }());
  var AjaxAsset = /** @class */ (function () {
      function AjaxAsset(_reqjson) {
          this.url = "/ajax";
          this.isready = false;
          this.reqjson = _reqjson;
      }
      AjaxAsset.prototype.load = function () {
          var _this = this;
          var body = JSON.stringify(this.reqjson);
          var headers = new Headers();
          headers.append("Content-Type", "application/json");
          fetch(this.url, {
              method: 'post',
              headers: headers,
              body: body
          }).then(function (response) {
              if (response.ok)
                  return response.json();
              return {};
          }).then(function (data) { return _this.onload(data); });
      };
      AjaxAsset.prototype.onload = function (data) {
          this.resjson = data;
          this.isready = true;
      };
      AjaxAsset.prototype.ready = function () {
          return this.isready;
      };
      return AjaxAsset;
  }());
  var AssetLoader = /** @class */ (function () {
      function AssetLoader() {
          this.WAIT = 250;
          this.RETRIES = 40;
          this.items = [];
          this.errorcallback = function () {
              //console.log("loading assets failed");
          };
      }
      AssetLoader.prototype.add = function (l) {
          this.items.push(l);
          return this;
      };
      AssetLoader.prototype.setcallback = function (_callback) {
          this.callback = _callback;
          return this;
      };
      AssetLoader.prototype.seterrorcallback = function (_errorcallback) {
          this.errorcallback = _errorcallback;
          return this;
      };
      AssetLoader.prototype.load = function () {
          this.items.map(function (item) { return item.load(); });
          //console.log("loading assets...")
          this.retries = 0;
          setTimeout(this.loadwait.bind(this), this.WAIT);
      };
      AssetLoader.prototype.loadwait = function () {
          for (var i in this.items) {
              if (!this.items[i].ready()) {
                  this.retries++;
                  if (this.retries <= this.RETRIES) {
                      //console.log("waiting for assets to load... try "+this.retries)
                      setTimeout(this.loadwait.bind(this), this.WAIT);
                      return;
                  }
                  else {
                      this.errorcallback();
                      return;
                  }
              }
          }
          //console.log("assets loaded ok")
          if (this.callback != undefined)
              this.callback();
      };
      return AssetLoader;
  }());
  var AjaxRequest = /** @class */ (function () {
      function AjaxRequest(json) {
          this.ajaxasset = new AjaxAsset(json);
          new AssetLoader().
              add(this.ajaxasset).
              load();
      }
      return AjaxRequest;
  }());
  var Vectors;
  (function (Vectors) {
      var ScreenVector = /** @class */ (function () {
          function ScreenVector(_x, _y) {
              this.x = _x;
              this.y = _y;
          }
          ScreenVector.prototype.Plus = function (sv) {
              return new ScreenVector(this.x + sv.x, this.y + sv.y);
          };
          ScreenVector.prototype.Minus = function (sv) {
              return new ScreenVector(this.x - sv.x, this.y - sv.y);
          };
          return ScreenVector;
      }());
      Vectors.ScreenVector = ScreenVector;
      var Square = /** @class */ (function () {
          function Square(_file, _rank) {
              this.file = _file;
              this.rank = _rank;
          }
          Square.prototype.Plus = function (sq) {
              return new Square(this.file + sq.file, this.rank + sq.rank);
          };
          Square.prototype.Minus = function (sq) {
              return new Square(this.file - sq.file, this.rank - sq.rank);
          };
          return Square;
      }());
      Vectors.Square = Square;
      var Piece = /** @class */ (function () {
          function Piece() {
              this.kind = "-";
              this.color = 0;
          }
          return Piece;
      }());
      Vectors.Piece = Piece;
      var Move = /** @class */ (function () {
          function Move(_fsq, _tsq, _prompiece) {
              if (_prompiece === void 0) { _prompiece = new Piece(); }
              this.prompiece = new Piece();
              this.fsq = _fsq;
              this.tsq = _tsq;
              this.prompiece = _prompiece;
          }
          return Move;
      }());
      Vectors.Move = Move;
      var Vect = /** @class */ (function () {
          function Vect(_x, _y) {
              this.x = _x;
              this.y = _y;
          }
          Vect.prototype.calctrig = function (r, multrby) {
              if (multrby === void 0) { multrby = Math.PI; }
              this.sin = Math.sin(r * multrby);
              this.cos = Math.cos(r * multrby);
          };
          Vect.prototype.r = function (r) {
              this.calctrig(r);
              return new Vect(this.x * this.cos - this.y * this.sin, this.x * this.sin + this.y * this.cos);
          };
          Vect.prototype.n = function (l) {
              var c = (l / this.l());
              return new Vect(this.x * c, this.y * c);
          };
          Vect.prototype.u = function () { return this.n(1); };
          Vect.prototype.p = function (v) {
              return new Vect(this.x + v.x, this.y + v.y);
          };
          Vect.prototype.m = function (v) {
              return new Vect(this.x - v.x, this.y - v.y);
          };
          Vect.prototype.i = function () {
              return new Vect(-this.x, -this.y);
          };
          Vect.prototype.s = function (s) {
              return new Vect(this.x * s, this.y * s);
          };
          Vect.prototype.l = function () {
              return Math.sqrt(this.x * this.x + this.y * this.y);
          };
          return Vect;
      }());
      Vectors.Vect = Vect;
      var INFINITE_COORD = 1E6;
      var Polygon = /** @class */ (function () {
          function Polygon() {
              this.vects = [];
          }
          Polygon.prototype.a = function (v) {
              this.vects.push(v);
              return this;
          };
          Polygon.prototype.normalize = function (overwrite) {
              var _this = this;
              if (overwrite === void 0) { overwrite = true; }
              var minx = INFINITE_COORD;
              var miny = INFINITE_COORD;
              var maxx = -INFINITE_COORD;
              var maxy = -INFINITE_COORD;
              this.vects.map(function (v) {
                  if (v.x < minx)
                      minx = v.x;
                  if (v.y < miny)
                      miny = v.y;
                  if (v.x > maxx)
                      maxx = v.x;
                  if (v.y > maxy)
                      maxy = v.y;
              });
              var min = new Vect(minx, miny);
              var max = new Vect(maxx, maxy);
              this.shift = min.i();
              this.size = max.m(min);
              if (overwrite) {
                  this.vects = this.vects.map(function (v) {
                      return v.p(_this.shift);
                  });
              }
              return this;
          };
          // should only be called on a normalized polygon
          Polygon.prototype.reportSvg = function (bcol) {
              if (bcol === void 0) { bcol = "#dfdf3f"; }
              var points = this.vects.map(function (v) { return (v.x + "," + v.y); }).join(" ");
              return "\n<svg width=\"" + this.size.x + "\" height=\"" + this.size.y + "\" style=\"position:absolute;top:0px;left:0px;\">\n<polygon points=\"" + points + "\" style=\"fill:" + bcol + ";stroke-width:0px;\">\n</svg>\n";
          };
          return Polygon;
      }());
      Vectors.Polygon = Polygon;
      var Arrow = /** @class */ (function () {
          function Arrow(from, to, params) {
              var widthfactor = params["widthfactor"] || 0.1;
              var handlelength = params["handlelength"] || 0.7;
              var headfactor = params["headfactor"] || 0.2;
              var constantwidth = params["constantwidth"] || 0.0;
              var cw = (constantwidth != 0.0);
              var diff = to.m(from);
              var width = cw ? constantwidth : diff.l() * widthfactor;
              var bottomright = cw ? diff.n(constantwidth / 2.0).r(0.5) : diff.n(width / 2.0).r(0.5);
              var bottomleft = bottomright.i();
              var handle = cw ? diff.n(diff.l() - 3.0 * constantwidth) : diff.n(diff.l() * handlelength);
              var headfromright = bottomright.p(handle);
              var headfromleft = bottomleft.p(handle);
              var headtoright = headfromright.p(cw ? bottomright.s(2.0) : bottomright.n(diff.l() * headfactor));
              var headtoleft = headfromleft.p(cw ? bottomleft.s(2.0) : bottomleft.n(diff.l() * headfactor));
              var pg = new Polygon().
                  a(bottomright).
                  a(headfromright).
                  a(headtoright).
                  a(diff).
                  a(headtoleft).
                  a(headfromleft).
                  a(bottomleft).
                  normalize();
              this.svgorig = to.m(pg.vects[3]);
              this.svg = pg.reportSvg(params["color"]);
          }
          return Arrow;
      }());
      Vectors.Arrow = Arrow;
  })(Vectors || (Vectors = {}));
  var Misc;
  (function (Misc) {
      function isDefined(x) {
          return ((x != undefined) && (x != null) && (x != "null"));
      }
      Misc.isDefined = isDefined;
      function nbr(content) {
          return content.
              replace(new RegExp(" ", "g"), "&nbsp;").
              replace(new RegExp("\\-", "g"), "&#8209;");
      }
      Misc.nbr = nbr;
      // from: https://stackoverflow.com/questions/6312993/javascript-seconds-to-time-string-with-format-hhmmss
      function formatDurationSeconds(sec_num) {
          sec_num = Math.round(sec_num);
          var hours = Math.floor(sec_num / 3600);
          var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
          var seconds = sec_num - (hours * 3600) - (minutes * 60);
          if (hours < 10) {
              hours = "0" + hours;
          }
          if (minutes < 10) {
              minutes = "0" + minutes;
          }
          if (seconds < 10) {
              seconds = "0" + seconds;
          }
          return hours + ':' + minutes + ':' + seconds;
      }
      Misc.formatDurationSeconds = formatDurationSeconds;
      function formatDurationMilliSeconds(millisec_num) {
          return formatDurationSeconds(millisec_num / 1000);
      }
      Misc.formatDurationMilliSeconds = formatDurationMilliSeconds;
      var Logitem = /** @class */ (function () {
          function Logitem(content) {
              this.isinfo = false;
              this.isok = false;
              this.iserror = false;
              this.content = content;
          }
          Logitem.prototype.info = function () {
              this.isinfo = true;
              return this;
          };
          Logitem.prototype.ok = function () {
              this.isok = true;
              return this;
          };
          Logitem.prototype.error = function () {
              this.iserror = true;
              return this;
          };
          return Logitem;
      }());
      Misc.Logitem = Logitem;
      var Logger = /** @class */ (function () {
          function Logger() {
              this.MAX_ITEMS = 50;
              this.items = [];
          }
          Logger.prototype.log = function (li) {
              this.items.push(li);
              if (this.items.length > this.MAX_ITEMS) {
                  this.items = this.items.slice(1);
              }
          };
          Logger.prototype.reportText = function () {
              return this.items.slice().reverse().map(function (x) { return x.content; }).join("\n");
          };
          Logger.prototype.reportHtml = function () {
              return this.items.slice().reverse().map(function (x) {
                  var content = x.content.replace(new RegExp("\\n", "g"), "<br>");
                  if (x.isinfo)
                      content = "<font color=\"blue\">" + content + "</font>";
                  if (x.isok)
                      content = "<font color=\"green\">" + content + "</font>";
                  if (x.iserror)
                      content = "<font color=\"red\">" + content + "</font>";
                  return content;
              }).join("<br>").replace(/ /g, "&nbsp;");
          };
          return Logger;
      }());
      Misc.Logger = Logger;
      var Timer = /** @class */ (function () {
          function Timer(_caption, _log) {
              this.caption = _caption;
              this.log = _log;
              this.now = performance.now();
          }
          Timer.prototype.report = function () {
              var elapsed = performance.now() - this.now;
              this.log(new Logitem(this.caption + " took " + elapsed.toLocaleString()));
          };
          return Timer;
      }());
      Misc.Timer = Timer;
      var JsonSerializableState = /** @class */ (function () {
          function JsonSerializableState() {
          }
          JsonSerializableState.prototype.fromJsonText = function (jsontext) {
              this.fromJson(JSON.parse(jsontext));
          };
          return JsonSerializableState;
      }());
      Misc.JsonSerializableState = JsonSerializableState;
      function roughlyEqualStrings(a, b) {
          return a.toLowerCase() == b.toLowerCase();
      }
      Misc.roughlyEqualStrings = roughlyEqualStrings;
      function updateObjectWith(obj, update) {
          for (var property in update) {
              if (obj[property] == undefined) {
                  obj[property] = update[property];
              }
          }
          return obj;
      }
      Misc.updateObjectWith = updateObjectWith;
      function limit(x, min, max) {
          if (x < min)
              return min;
          if (x > max)
              return max;
          return x;
      }
      Misc.limit = limit;
      function scoreColor(score) {
          if (score < -1000)
              return "#f00";
          if (score < -500)
              return "#a00";
          if (score < 0)
              return "#700";
          if (score < 500)
              return "#070";
          return ("#0f0");
      }
      Misc.scoreColor = scoreColor;
  })(Misc || (Misc = {}));
  var Analysis;
  (function (Analysis) {
      var ThinkingOutput = /** @class */ (function () {
          function ThinkingOutput(_prot, _variant) {
              if (_prot === void 0) { _prot = "uci"; }
              if (_variant === void 0) { _variant = "standard"; }
              this.bestmove = "";
              this.scorecp = true;
              this.scoremate = false;
              this.score = 0;
              this.depth = 0;
              this.bestmovereceived = false;
              this.prot = _prot;
              this.variant = _variant;
          }
          ThinkingOutput.prototype.scoreFormatted = function () {
              return (this.scoremate ? "#" : "") + this.score;
          };
          ThinkingOutput.prototype.scoreNumerical = function () {
              return (this.scoremate ? (this.score > 0 ? Config.MATE_SCORE : -Config.MATE_SCORE) : this.score);
          };
          ThinkingOutput.prototype.parseuci = function (buffer) {
              var preparts = buffer.split(" ");
              if (preparts[0] == "bestmove") {
                  this.bestmove = preparts[1];
                  this.bestmovereceived = true;
                  return;
              }
              var parts = buffer.split(new RegExp("^info "));
              if (parts.length < 2) {
                  //console.log("uci string without info "+buffer)
                  return;
              }
              var infoparts = parts[1].split(" ");
              var parsekey = true;
              var key;
              var pvitems = [];
              for (var i in infoparts) {
                  if (parsekey) {
                      key = infoparts[i];
                      parsekey = false;
                  }
                  else {
                      var value = infoparts[i];
                      if (key == "score") {
                          if (value == "cp") {
                              this.scorecp = true;
                              this.scoremate = false;
                          }
                          else if (value == "mate") {
                              this.scoremate = true;
                              this.scorecp = false;
                          }
                          else {
                              this.score = parseInt(value);
                              parsekey = true;
                          }
                      }
                      else if (key == "depth") {
                          this.depth = parseInt(value);
                          parsekey = true;
                      }
                      else if (key == "pv") {
                          pvitems.push(value);
                      }
                      else {
                          parsekey = true;
                      }
                  }
              }
              if (pvitems.length > 0) {
                  this.bestmove = pvitems[0];
              }
          };
          ThinkingOutput.prototype.parse = function (buffer) {
              var buffercleaned = buffer.replace(new RegExp("\\r", "g"), "");
              if (this.prot == "uci") {
                  this.parseuci(buffercleaned);
              }
          };
          return ThinkingOutput;
      }());
      Analysis.ThinkingOutput = ThinkingOutput;
      var EngineMessage = /** @class */ (function () {
          function EngineMessage() {
          }
          EngineMessage.prototype._action = function (_action) { this.action = _action; return this; };
          EngineMessage.prototype._command = function (_command) { this.command = _command; return this; };
          EngineMessage.prototype._name = function (_name) { this.name = _name; return this; };
          EngineMessage.prototype.parseJson = function (data) {
              var pd = JSON.parse(data);
              this.action = pd.action;
              this.available = pd.available;
              this.buffer = pd.buffer;
              return this;
          };
          return EngineMessage;
      }());
      var Analyzer = /** @class */ (function () {
          function Analyzer() {
              this.connectid = 0;
              this.tolog = new Misc.Logger();
              this.thinkingoutput = new ThinkingOutput();
              this.available = [];
              this.enginerunning = false;
          }
          Analyzer.prototype.logws = function (msg, connectid, details) {
              if (details === void 0) { details = ""; }
              this.log(new Misc.Logitem("[ " + connectid + " ] " + msg + (details != "" ? " : " : "") + details));
          };
          Analyzer.prototype.sendem = function (em, connectid) {
              if (!Misc.isDefined(this.ws))
                  return;
              var json = JSON.stringify(em);
              this.logws("sending message", connectid, json);
              /////////////////////////////////////////////
              this.ws.send(json);
              /////////////////////////////////////////////        
          };
          Analyzer.prototype.startengine = function (name) {
              var em = new EngineMessage().
                  _action("start").
                  _name(name);
              this.connect(em, null);
          };
          Analyzer.prototype.getenginecolor = function () {
              return (this.thinkingoutput.score > 0 ? Analyzer.POS_EVAL_MOVE_COL : Analyzer.NEG_EVAL_MOVE_COL);
          };
          Analyzer.prototype.displayenginescore = function () {
              var ecol = this.getenginecolor();
              this.depthdiv.
                  position("absolute").
                  topPx(Config.PREFERRED_BOARD_SIZE / 5.0).
                  leftPx(Config.PREFERRED_BOARD_SIZE / 5.0).
                  zIndexNumber(wBoard.ARROW_Z_INDEX + 1).
                  fontSizePx(Globals.wboard.SQUARE_SIZE()).
                  color(Analyzer.ENGINE_DEPTH_COL).
                  html("" + this.thinkingoutput.depth);
              this.scorediv.
                  position("absolute").
                  topPx(Config.PREFERRED_BOARD_SIZE / 3.0).
                  leftPx(Config.PREFERRED_BOARD_SIZE / 3.0).
                  zIndexNumber(wBoard.ARROW_Z_INDEX + 1).
                  fontSizePx(Globals.wboard.SQUARE_SIZE() * 2.0).
                  color(ecol).
                  html(this.thinkingoutput.scoreFormatted());
          };
          Analyzer.prototype.onmessage = function (connectid, e) {
              //this.logws("connection sent",connectid,e.data)
              var em = new EngineMessage().parseJson(e.data);
              if (em.action == "available") {
                  this.available = em.available;
                  this.logws("available", connectid, em.available.join(", "));
                  Globals.gui.startDefaultEngine();
                  Globals.gui.setup.onanalyzerconnect();
              }
              if (em.action == "neuraloutput") {
                  try {
                      var json = JSON.parse(em.buffer);
                      if (json.action == "makesan") {
                          Globals.gui.makeneuralsan(json);
                      }
                      else {
                          Globals.gui.nlog(new Misc.Logitem(em.buffer));
                      }
                  }
                  catch (err) {
                      Globals.gui.nlog(new Misc.Logitem(em.buffer));
                  }
              }
              if (em.action == "thinkingoutput") {
                  this.tolog.log(new Misc.Logitem(em.buffer));
                  Globals.gui.enginediv.html("<pre>" +
                      this.tolog.items.slice().reverse().map(function (x) { return x.content; }).join("\n") +
                      "</pre>");
                  var to = this.thinkingoutput;
                  to.parse(em.buffer);
                  if (this.enginerunning) {
                      var algeb = this.thinkingoutput.bestmove;
                      if (algeb != "") {
                          var m = Globals.wboard.algebToMove(algeb);
                          var color = this.getenginecolor();
                          var params = { "color": color, "scale": 1.5 };
                          Globals.wboard.drawMoveArrow(m, this.enginearrow, params);
                          this.displayenginescore();
                      }
                  }
              }
          };
          Analyzer.prototype.wsopen = function (connectid, em, e) {
              if (em === void 0) { em = null; }
              this.logws("connection opened", connectid);
              if (em != null)
                  this.sendem(em, connectid);
          };
          Analyzer.prototype.connect = function (em, tabid) {
              if (em === void 0) { em = new EngineMessage()._action("sendavailable"); }
              if (tabid === void 0) { tabid = "log"; }
              if (tabid != null)
                  Globals.gui.tabs.setSelected(tabid);
              this.connectid++;
              this.logws("connecting to server...", this.connectid);
              this.ws = new WebSocket("ws://localhost:9000/ws");
              this.ws.onopen = this.wsopen.bind(this, this.connectid, em);
              this.ws.onmessage = this.onmessage.bind(this, this.connectid);
          };
          Analyzer.prototype.waitbestmove = function (callback) {
              if (this.thinkingoutput.bestmovereceived) {
                  callback();
                  return;
              }
              setTimeout(this.waitbestmove.bind(this), 100);
          };
          Analyzer.prototype.analyze = function (switchenabled) {
              if (switchenabled === void 0) { switchenabled = true; }
              this.thinkingoutput.bestmovereceived = false;
              if (Globals.gui.appconfig.switchToEngineTab && switchenabled)
                  Globals.gui.tabs.setSelected("engine");
              this.thinkingoutput = new ThinkingOutput();
              this.stopanalysis();
              var fen = Globals.wboard.reportFen();
              var em = new EngineMessage().
                  _action("issue").
                  _command("position fen " + fen + "\ngo infinite\n");
              this.sendem(em, this.connectid);
              this.enginerunning = true;
          };
          Analyzer.prototype.stopanalysis = function () {
              this.enginerunning = false;
              var em = new EngineMessage().
                  _action("issue").
                  _command("stop");
              this.sendem(em, this.connectid);
          };
          Analyzer.prototype.makeanalyzedmove = function () {
              if (this.thinkingoutput == undefined) {
                  this.log(new Misc.Logitem("no thinking output"));
                  return "";
              }
              var algeb = this.thinkingoutput.bestmove;
              if (algeb != "") {
                  var m = Globals.wboard.algebToMove(algeb);
                  var fenbefore = Globals.wboard.reportFen();
                  Globals.wboard.makeMove(m);
                  var fenafter = Globals.wboard.reportFen();
                  if (fenafter == fenbefore) {
                      var truealgeb = {
                          "e1g1": "e1h1",
                          "e1c1": "e1a1",
                          "e8g8": "e8h8",
                          "e8c8": "e8a8"
                      }[algeb];
                      var truem = Globals.wboard.algebToMove(truealgeb);
                      Globals.wboard.makeMove(truem);
                  }
                  Globals.wboard.draw();
              }
              return Globals.wboard.reportLastMoveSan();
          };
          Analyzer.prototype.issueneural = function (command) {
              var em = new EngineMessage().
                  _action("issueneural").
                  _command(command);
              this.sendem(em, this.connectid);
          };
          Analyzer.prototype.issueneuralJson = function (commandjson) {
              this.issueneural(JSON.stringify(commandjson));
          };
          Analyzer.POS_EVAL_MOVE_COL = "#00ff00";
          Analyzer.NEG_EVAL_MOVE_COL = "#ff0000";
          Analyzer.ENGINE_DEPTH_COL = "#0000ff";
          return Analyzer;
      }());
      Analysis.Analyzer = Analyzer;
  })(Analysis || (Analysis = {}));
  var Annotation = /** @class */ (function () {
      function Annotation(_annotkey) {
          if (_annotkey === void 0) { _annotkey = "-"; }
          this.annotkey = "-";
          this.color = "#000000";
          this.bcol = "#ffffff";
          this.priority = 0;
          this.annotkey = _annotkey;
      }
      Annotation.prototype.empty = function () {
          return this.annotkey == "-";
      };
      Annotation.prototype.setColor = function (_color) {
          this.color = _color;
          return this;
      };
      Annotation.prototype.setBcol = function (_bcol) {
          this.bcol = _bcol;
          return this;
      };
      Annotation.prototype.setPriority = function (_priority) {
          this.priority = _priority;
          return this;
      };
      Annotation.prototype.parseObj = function (obj) {
          this.annotkey = obj.annotkey;
          this.color = obj.color;
          this.bcol = obj.bcol;
          this.priority = obj.priority;
          return this;
      };
      Annotation.prototype.getAnnotStr = function () {
          if (this.annotkey == "-")
              return "";
          return this.annotkey;
      };
      return Annotation;
  }());
  var BookUtils;
  (function (BookUtils) {
      BookUtils.annotations = {
          "!!": new Annotation("!!").setColor("#00ff00").setBcol("#7fff7f").setPriority(10),
          "!": new Annotation("!").setColor("#007f00").setBcol("#afffaf").setPriority(9),
          "!?": new Annotation("!?").setColor("#0000ff").setBcol("#7f7fff").setPriority(5),
          "?!": new Annotation("?!").setColor("#00007f").setBcol("#afafff").setPriority(4),
          "?": new Annotation("?").setColor("#7f0000").setBcol("#ffafaf").setPriority(2),
          "??": new Annotation("??").setColor("#ff0000").setBcol("#ff7f7f").setPriority(1),
          "-": new Annotation("-").setColor("#000000").setBcol("#ffffff").setPriority(0)
      };
  })(BookUtils || (BookUtils = {}));
  var BookMove = /** @class */ (function () {
      function BookMove(_san) {
          this.annot = new Annotation();
          this.san = _san;
      }
      BookMove.prototype.parseObj = function (obj) {
          this.san = obj.san;
          this.annot = new Annotation().parseObj(obj.annot);
          return this;
      };
      BookMove.prototype.setAnnot = function (annot) {
          this.annot.annotkey = annot.annotkey;
          this.annot.color = annot.color;
          this.annot.bcol = annot.bcol;
          this.annot.priority = annot.priority;
          return this;
      };
      return BookMove;
  }());
  var BookPosition = /** @class */ (function () {
      function BookPosition(_fen) {
          this.moves = {};
          this.fen = _fen;
      }
      BookPosition.prototype.parseObj = function (obj) {
          this.fen = obj.fen;
          for (var san in obj.moves) {
              this.moves[san] = new BookMove(san).parseObj(obj.moves[san]);
          }
          return this;
      };
      BookPosition.prototype.getMove = function (san) {
          if (!Misc.isDefined(this.moves[san])) {
              this.moves[san] = new BookMove(san);
          }
          return this.moves[san];
      };
      BookPosition.prototype.delMove = function (san) {
          delete this.moves[san];
      };
      BookPosition.prototype.sortedSans = function () {
          var _this = this;
          var keys = Object.keys(this.moves);
          var sorted = keys.sort(function (a, b) {
              var movea = _this.moves[a];
              var moveb = _this.moves[b];
              var ma = movea.annot;
              var mb = moveb.annot;
              if (ma.priority != mb.priority)
                  return mb.priority - ma.priority;
              var msa = movea.ms || 0;
              var msb = moveb.ms || 0;
              return msb - msa;
          });
          return sorted;
      };
      return BookPosition;
  }());
  var Book = /** @class */ (function () {
      function Book(_variant, _name) {
          this.positions = {};
          this.variant = _variant;
          this.name = _name;
          var stored = localStorage.getItem(this.storeid());
          if (Misc.isDefined(stored)) {
              this.fromJsonText(stored);
          }
          this.store();
      }
      Book.prototype.storeid = function () {
          return "book_" + this.variant + "_" + this.name;
      };
      Book.prototype.truncfen = function (fen) {
          var parts = fen.split(" ");
          return (parts[0] + " " + parts[1] + " " + parts[2] + " " + parts[3]);
      };
      Book.prototype.fromJsonText = function (jsontext) {
          this.parseObj(JSON.parse(jsontext));
      };
      Book.prototype.src = function () {
          return JSON.stringify(this);
      };
      Book.prototype.store = function () {
          var storeid = this.storeid();
          localStorage.setItem(storeid, this.src());
      };
      Book.prototype.parseObj = function (obj) {
          this.variant = obj.variant;
          this.name = obj.name;
          for (var fen in obj.positions) {
              this.positions[fen] = new BookPosition(fen).parseObj(obj.positions[fen]);
          }
          return this;
      };
      Book.prototype.getPosition = function (fen) {
          var tfen = this.truncfen(fen);
          if (!Misc.isDefined(this.positions[tfen])) {
              this.positions[tfen] = new BookPosition(tfen);
          }
          return this.positions[tfen];
      };
      Book.prototype.delPosition = function (fen) {
          var tfen = this.truncfen(fen);
          delete this.positions[tfen];
      };
      return Book;
  }());
  var LichessGame = /** @class */ (function () {
      function LichessGame(_gameid) {
          if (_gameid === void 0) { _gameid = ""; }
          this.pgnHeaders = {};
          this.moves = "";
          this.result = "result";
          this.gameid = _gameid;
      }
      LichessGame.prototype.url = function () {
          var url = "https://lichess.org/api/game/" + this.gameid + "?with_moves=1";
          return url;
      };
      LichessGame.prototype.onLoad = function () {
          this.fromTextAsset(this.textasset);
          this.callback();
      };
      LichessGame.prototype.errorLogitem = function () {
          return new Misc.Logitem("error loading game: " + this.url() + " timed out").error();
      };
      LichessGame.prototype.infoLogitem = function () {
          return new Misc.Logitem("loading game " + this.url()).info();
      };
      LichessGame.prototype.okLogitem = function () {
          return new Misc.Logitem("game loaded " + this.url()).ok();
      };
      LichessGame.prototype.localAvailableLogitem = function () {
          return new Misc.Logitem("local version is available for " + this.url()).info();
      };
      LichessGame.prototype.loadThen = function (_callback, errorcallback) {
          this.callback = _callback;
          this.textasset = new TextAsset(this.url());
          new AssetLoader().
              add(this.textasset).
              setcallback(this.onLoad.bind(this)).
              seterrorcallback(errorcallback).
              load();
      };
      LichessGame.prototype.fromSerializedJson = function (json) {
          this.gameid = json.gameid;
          this.pgnHeaders = json.pgnHeaders;
          this.moves = json.moves;
          this.result = json.result;
          return this;
      };
      LichessGame.prototype.toSerializedJson = function () {
          var json = {};
          json.gameid = this.gameid;
          json.pgnHeaders = this.pgnHeaders;
          json.moves = this.moves;
          json.result = this.result;
          return json;
      };
      LichessGame.prototype.fromJson = function (json) {
          this.pgnHeaders = {};
          var moves = json.moves;
          this.moves = moves;
          var variant = json.variant;
          this.pgnHeaders["GameVariant"] = variant;
          var players = json.players;
          var white = players.white;
          var black = players.black;
          this.pgnHeaders["White"] = white.userId;
          this.pgnHeaders["Black"] = black.userId;
          var gameid = json.id;
          this.gameid = gameid;
          this.pgnHeaders["GameId"] = gameid;
          var gameurl = json.url;
          this.pgnHeaders["Url"] = gameurl;
          var rated = json.rated;
          this.pgnHeaders["Rated"] = "" + rated;
          var speed = json.speed;
          this.pgnHeaders["Speed"] = speed;
          var createdat = json.createdAt;
          this.pgnHeaders["CreatedAt"] = new Date(createdat).toLocaleString();
          var lastmoveat = json.lastMoveAt;
          this.pgnHeaders["LastMoveAt"] = new Date(lastmoveat).toLocaleString();
          var duration = lastmoveat - createdat;
          this.pgnHeaders["Duration"] = Misc.formatDurationMilliSeconds(duration);
          var status = json.status;
          this.pgnHeaders["Status"] = status;
          var turns = json.turns;
          this.pgnHeaders["Turns"] = turns;
          var winner = json.winner;
          this.pgnHeaders["Winner"] = winner;
          this.result = "draw";
          if (winner == "white") {
              this.pgnHeaders["WinnerName"] = white.userId;
              this.result = "1-0";
          }
          if (winner == "black") {
              this.pgnHeaders["WinnerName"] = black.userId;
              this.result = "0-1";
          }
          return this;
      };
      LichessGame.prototype.fromTextAsset = function (textasset) {
          this.fromJson(textasset.asJson());
          return this;
      };
      LichessGame.prototype.getHeader = function (key) {
          var value = this.pgnHeaders[key];
          return value;
      };
      return LichessGame;
  }());
  var Config;
  (function (Config) {
      Config.appConfig = {
          handle: "myhandle",
          switchToEngineTab: true,
          onGameLoad: {
              autoStartEngine: false,
              autoStartEngineTimeout: 3000,
              forwardMoves: 0
          }
      };
      Config.MATE_SCORE = 10000;
      Config.PREFERRED_BOARD_SIZE = 400;
      Config.BOARD_INFO_HEIGHT = 50;
      Config.TOTAL_BOARD_HEIGHT = Config.PREFERRED_BOARD_SIZE + 2 * Config.BOARD_INFO_HEIGHT;
      Config.PREFERRED_TAB_SIZE = 900;
      Config.STANDARD_START_RAW_FEN = "r0n0b0q0k0b0n0r0" +
          "p0p0p0p0p0p0p0p0" +
          "-0-0-0-0-0-0-0-0" +
          "-0-0-0-0-0-0-0-0" +
          "-0-0-0-0-0-0-0-0" +
          "-0-0-0-0-0-0-0-0" +
          "p1p1p1p1p1p1p1p1" +
          "r1n1b1q1k1b1n1r1";
      var FOUR_PLAYER_START_RAW_FEN = "-0-0-0r0n0b0q0k0b0n0r0-0-0-0" +
          "-0-0-0p0p0p0p0p0p0p0p0-0-0-0" +
          "-0-0-0-0-0-0-0-0-0-0-0-0-0-0" +
          "r3p3-0-0-0-0-0-0-0-0-0-0p2r2" +
          "n3p3-0-0-0-0-0-0-0-0-0-0p2n2" +
          "b3p3-0-0-0-0-0-0-0-0-0-0p2b2" +
          "k3p3-0-0-0-0-0-0-0-0-0-0p2q2" +
          "q3p3-0-0-0-0-0-0-0-0-0-0p2k2" +
          "b3p3-0-0-0-0-0-0-0-0-0-0p2b2" +
          "n3p3-0-0-0-0-0-0-0-0-0-0p2n2" +
          "r3p3-0-0-0-0-0-0-0-0-0-0p2r2" +
          "-0-0-0-0-0-0-0-0-0-0-0-0-0-0" +
          "-0-0-0p1p1p1p1p1p1p1p1-0-0-0" +
          "-0-0-0r1n1b1k1q1b1n1r1-0-0-0";
      Config.variantToDisplayName = {
          "standard": "Standard",
          "atomic": "Atomic",
          "fourplayer": "Four Player"
      };
      Config.variantToVariantCode = {
          "standard": 201,
          "atomic": 202,
          "fourplayer": 401
      };
      Config.startRawFens = {
          "standard": Config.STANDARD_START_RAW_FEN,
          "atomic": Config.STANDARD_START_RAW_FEN,
          "fourplayer": FOUR_PLAYER_START_RAW_FEN
      };
      function isSupportedVariant(variant) {
          return Config.variantToVariantCode[variant] != undefined;
      }
      Config.isSupportedVariant = isSupportedVariant;
      function supportedVariants() {
          return Object.keys(Config.variantToVariantCode);
      }
      Config.supportedVariants = supportedVariants;
  })(Config || (Config = {}));
  // custom wrapper for the DOM
  var DomConfigElement = /** @class */ (function () {
      function DomConfigElement() {
      }
      return DomConfigElement;
  }());
  var SizePx = /** @class */ (function (_super) {
      __extends(SizePx, _super);
      function SizePx(_px) {
          var _this = _super.call(this) || this;
          _this.px = _px;
          return _this;
      }
      return SizePx;
  }(DomConfigElement));
  var DomConfig = /** @class */ (function () {
      function DomConfig() {
          this.elements = {};
      }
      DomConfig.prototype.add = function (id, e) {
          this.elements[id] = e;
          return this;
      };
      DomConfig.prototype.getPx = function (id) {
          return this.elements[id].px;
      };
      return DomConfig;
  }());
  var HTMLElement_ = /** @class */ (function () {
      function HTMLElement_(_kind) {
          this.kind = _kind;
          this.e = document.createElement(_kind);
      }
      HTMLElement_.prototype.setAttribute = function (name, value) {
          this.e.setAttribute(name, value);
          return this;
      };
      HTMLElement_.prototype.removeAttribute = function (name) {
          this.e.removeAttribute(name);
          return this;
      };
      HTMLElement_.prototype.appendChild = function (child) {
          this.e.appendChild(child.e);
          return this;
      };
      HTMLElement_.prototype.appendChilds = function (childs) {
          var _this = this;
          childs.map(function (child) { return _this.appendChild(child); });
          return this;
      };
      HTMLElement_.prototype.addEventListener = function (type, listener) {
          this.e.addEventListener(type, listener);
          return this;
      };
      Object.defineProperty(HTMLElement_.prototype, "innerHTML", {
          get: function () {
              return this.e.innerHTML;
          },
          set: function (content) {
              this.e.innerHTML = content;
          },
          enumerable: true,
          configurable: true
      });
      HTMLElement_.prototype.html = function (content) {
          this.innerHTML = content;
          return this;
      };
      HTMLElement_.prototype.getComputedStyle = function () {
          return getComputedStyle(this.e);
      };
      HTMLElement_.prototype.getComputedHeightPx = function () {
          return this.getPx(this.getComputedStyle().height);
      };
      HTMLElement_.prototype.getComputedWidthPx = function () {
          return this.getPx(this.getComputedStyle().width);
      };
      HTMLElement_.prototype.getComputedTopPx = function () {
          return this.getPx(this.getComputedStyle().top);
      };
      HTMLElement_.prototype.getComputedLeftPx = function () {
          return this.getPx(this.getComputedStyle().left);
      };
      HTMLElement_.prototype.getComputedBottomPx = function () {
          return this.getComputedTopPx() + this.getComputedHeightPx();
      };
      HTMLElement_.prototype.getComputedRightPx = function () {
          return this.getComputedLeftPx() + this.getComputedWidthPx();
      };
      HTMLElement_.prototype.scrollTop = function (scrolltop) {
          this.e.scrollTop = scrolltop;
          return this;
      };
      HTMLElement_.prototype.getScrollTop = function () {
          return this.e.scrollTop;
      };
      HTMLElement_.prototype.scrollLeft = function (scrollleft) {
          this.e.scrollLeft = scrollleft;
          return this;
      };
      HTMLElement_.prototype.getScrollLeft = function () {
          return this.e.scrollLeft;
      };
      HTMLElement_.prototype.focus = function () {
          this.e.focus();
      };
      HTMLElement_.prototype.blur = function () {
          this.e.blur();
      };
      HTMLElement_.prototype.fontSize = function (fontsize) {
          this.e.style.fontSize = fontsize;
          return this;
      };
      HTMLElement_.prototype.fontSizePx = function (fontsizepx) {
          return this.fontSize(fontsizepx + "px");
      };
      HTMLElement_.prototype.fontFamily = function (fontfamily) {
          this.e.style.fontFamily = fontfamily;
          return this;
      };
      HTMLElement_.prototype.fontWeight = function (fontweight) {
          this.e.style.fontWeight = fontweight;
          return this;
      };
      HTMLElement_.prototype.borderCollapse = function (bordercollapse) {
          this.e.style.borderCollapse = bordercollapse;
          return this;
      };
      HTMLElement_.prototype.border = function (border) {
          this.e.style.border = border;
          return this;
      };
      HTMLElement_.prototype.borderPx = function (borderpx) {
          return this.border(borderpx + "px");
      };
      HTMLElement_.prototype.borderTopStyle = function (bordertopstyle) {
          this.e.style.borderTopStyle = bordertopstyle;
          return this;
      };
      HTMLElement_.prototype.borderLeftStyle = function (borderleftstyle) {
          this.e.style.borderLeftStyle = borderleftstyle;
          return this;
      };
      HTMLElement_.prototype.borderBottomStyle = function (borderbottomstyle) {
          this.e.style.borderBottomStyle = borderbottomstyle;
          return this;
      };
      HTMLElement_.prototype.borderRightStyle = function (borderrightstyle) {
          this.e.style.borderBottomStyle = borderrightstyle;
          return this;
      };
      HTMLElement_.prototype.borderStyle = function (borderstyle) {
          this.e.style.borderTopStyle = borderstyle;
          this.e.style.borderLeftStyle = borderstyle;
          this.e.style.borderBottomStyle = borderstyle;
          this.e.style.borderRightStyle = borderstyle;
          return this;
      };
      HTMLElement_.prototype.borderTopColor = function (bordertopcolor) {
          this.e.style.borderTopColor = bordertopcolor;
          return this;
      };
      HTMLElement_.prototype.borderLeftColor = function (borderleftcolor) {
          this.e.style.borderLeftColor = borderleftcolor;
          return this;
      };
      HTMLElement_.prototype.borderBottomColor = function (borderbottomcolor) {
          this.e.style.borderBottomColor = borderbottomcolor;
          return this;
      };
      HTMLElement_.prototype.borderRightColor = function (borderrightcolor) {
          this.e.style.borderBottomColor = borderrightcolor;
          return this;
      };
      HTMLElement_.prototype.borderColor = function (bordercolor) {
          this.e.style.borderTopColor = bordercolor;
          this.e.style.borderLeftColor = bordercolor;
          this.e.style.borderBottomColor = bordercolor;
          this.e.style.borderRightColor = bordercolor;
          return this;
      };
      HTMLElement_.prototype.borderSpacing = function (borderspacing) {
          this.e.style.borderSpacing = borderspacing;
          return this;
      };
      HTMLElement_.prototype.borderSpacingPx = function (borderspacingpx) {
          return this.borderSpacing(borderspacingpx + "px");
      };
      HTMLElement_.prototype.verticalAlign = function (verticalalign) {
          this.e.style.verticalAlign = verticalalign;
          return this;
      };
      HTMLElement_.prototype.padding = function (padding) {
          this.e.style.padding = padding;
          return this;
      };
      HTMLElement_.prototype.paddingPx = function (paddingpx) {
          return this.padding(paddingpx + "px");
      };
      HTMLElement_.prototype.paddingBottom = function (paddingbottom) {
          this.e.style.paddingBottom = paddingbottom;
          return this;
      };
      HTMLElement_.prototype.paddingBottomPx = function (paddingbottompx) {
          return this.paddingBottom(paddingbottompx + "px");
      };
      HTMLElement_.prototype.paddingLeft = function (paddingleft) {
          this.e.style.paddingLeft = paddingleft;
          return this;
      };
      HTMLElement_.prototype.paddingLeftPx = function (paddingleftpx) {
          return this.paddingLeft(paddingleftpx + "px");
      };
      HTMLElement_.prototype.paddingRight = function (paddingright) {
          this.e.style.paddingRight = paddingright;
          return this;
      };
      HTMLElement_.prototype.paddingRightPx = function (paddingrightpx) {
          return this.paddingRight(paddingrightpx + "px");
      };
      HTMLElement_.prototype.paddingTop = function (paddingtop) {
          this.e.style.paddingTop = paddingtop;
          return this;
      };
      HTMLElement_.prototype.paddingTopPx = function (paddingtoppx) {
          return this.paddingTop(paddingtoppx + "px");
      };
      HTMLElement_.prototype.margin = function (margin) {
          this.e.style.margin = margin;
          return this;
      };
      HTMLElement_.prototype.marginPx = function (marginpx) {
          return this.margin(marginpx + "px");
      };
      HTMLElement_.prototype.marginTop = function (margintop) {
          this.e.style.marginTop = margintop;
          return this;
      };
      HTMLElement_.prototype.marginTopPx = function (margintoppx) {
          return this.marginTop(margintoppx + "px");
      };
      HTMLElement_.prototype.marginBottom = function (marginbottom) {
          this.e.style.marginBottom = marginbottom;
          return this;
      };
      HTMLElement_.prototype.marginBottomPx = function (marginbottompx) {
          return this.marginTop(marginbottompx + "px");
      };
      HTMLElement_.prototype.marginLeft = function (marginleft) {
          this.e.style.marginLeft = marginleft;
          return this;
      };
      HTMLElement_.prototype.marginLeftPx = function (marginleftpx) {
          return this.marginLeft(marginleftpx + "px");
      };
      HTMLElement_.prototype.marginRight = function (marginright) {
          this.e.style.marginRight = marginright;
          return this;
      };
      HTMLElement_.prototype.marginRightPx = function (marginrightpx) {
          return this.marginRight(marginrightpx + "px");
      };
      HTMLElement_.prototype.visibility = function (visibility) {
          this.e.style.visibility = visibility;
          return this;
      };
      HTMLElement_.prototype.visibilityBoolean = function (visibilityboolean) {
          return this.visibility(visibilityboolean ? "visible" : "hidden");
      };
      HTMLElement_.prototype.cursor = function (cursor) {
          this.e.style.cursor = cursor;
          return this;
      };
      HTMLElement_.prototype.overflow = function (overflow) {
          this.e.style.overflow = overflow;
          return this;
      };
      HTMLElement_.prototype.draggable = function (draggable) {
          this.setAttribute("draggable", draggable);
          return this;
      };
      HTMLElement_.prototype.draggableBoolean = function (draggableboolean) {
          this.setAttribute("draggable", "" + draggableboolean);
          return this;
      };
      HTMLElement_.prototype.color = function (color) {
          this.e.style.color = color;
          return this;
      };
      HTMLElement_.prototype.backgroundColor = function (color) {
          this.e.style.backgroundColor = color;
          return this;
      };
      HTMLElement_.prototype.position = function (position) {
          this.e.style.position = position;
          return this;
      };
      HTMLElement_.prototype.width = function (width) {
          this.e.style.width = width;
          return this;
      };
      HTMLElement_.prototype.widthPx = function (widthpx) {
          return (this.width(widthpx + "px"));
      };
      HTMLElement_.prototype.height = function (height) {
          this.e.style.height = height;
          return this;
      };
      HTMLElement_.prototype.heightPx = function (heightpx) {
          return (this.height(heightpx + "px"));
      };
      HTMLElement_.prototype.top = function (top) {
          this.e.style.top = top;
          return this;
      };
      HTMLElement_.prototype.topPx = function (toppx) {
          return (this.top(toppx + "px"));
      };
      HTMLElement_.prototype.left = function (left) {
          this.e.style.left = left;
          return this;
      };
      HTMLElement_.prototype.leftPx = function (leftpx) {
          return (this.left(leftpx + "px"));
      };
      HTMLElement_.prototype.getPx = function (css) {
          var cssnum = css.replace("px", "");
          return parseFloat(css);
      };
      HTMLElement_.prototype.getTop = function () {
          return this.e.style.top;
      };
      HTMLElement_.prototype.getTopPx = function () {
          return this.getPx(this.getTop());
      };
      HTMLElement_.prototype.getLeft = function () {
          return this.e.style.left;
      };
      HTMLElement_.prototype.getLeftPx = function () {
          return this.getPx(this.getLeft());
      };
      HTMLElement_.prototype.getWidth = function () {
          return this.e.style.width;
      };
      HTMLElement_.prototype.getWidthPx = function () {
          return this.getPx(this.getWidth());
      };
      HTMLElement_.prototype.getHeight = function () {
          return this.e.style.height;
      };
      HTMLElement_.prototype.getHeightPx = function () {
          return this.getPx(this.getHeight());
      };
      HTMLElement_.prototype.getBottomPx = function () {
          return this.getTopPx() + this.getHeightPx();
      };
      HTMLElement_.prototype.getRightPx = function () {
          return this.getLeftPx() + this.getWidthPx();
      };
      HTMLElement_.prototype.zIndex = function (zindex) {
          this.e.style.zIndex = zindex;
          return this;
      };
      HTMLElement_.prototype.zIndexNumber = function (zindexnumber) {
          return (this.zIndex("" + zindexnumber));
      };
      HTMLElement_.prototype.background = function (background) {
          this.e.style.background = background;
          return this;
      };
      HTMLElement_.prototype.opacity = function (opacity) {
          this.e.style.opacity = opacity;
          return this;
      };
      HTMLElement_.prototype.opacityNumber = function (opacitynumber) {
          return (this.opacity("" + opacitynumber));
      };
      return HTMLElement_;
  }());
  var HTMLDivElement_ = /** @class */ (function (_super) {
      __extends(HTMLDivElement_, _super);
      function HTMLDivElement_() {
          return _super.call(this, "div") || this;
      }
      return HTMLDivElement_;
  }(HTMLElement_));
  var HTMLButtonElement_ = /** @class */ (function (_super) {
      __extends(HTMLButtonElement_, _super);
      function HTMLButtonElement_() {
          var _this = _super.call(this, "input") || this;
          _this.setAttribute("type", "button");
          return _this;
      }
      HTMLButtonElement_.prototype.value = function (value) {
          this.setAttribute("value", value);
          return this;
      };
      HTMLButtonElement_.prototype.onmousedown = function (listener) {
          this.addEventListener("mousedown", listener);
          return this;
      };
      return HTMLButtonElement_;
  }(HTMLElement_));
  var HTMLTableElement_ = /** @class */ (function (_super) {
      __extends(HTMLTableElement_, _super);
      function HTMLTableElement_() {
          return _super.call(this, "table") || this;
      }
      HTMLTableElement_.prototype.borderAttribute = function (border) {
          this.setAttribute("border", "" + border);
          return this;
      };
      HTMLTableElement_.prototype.cellpaddingAttribute = function (cellpadding) {
          this.setAttribute("cellpadding", "" + cellpadding);
          return this;
      };
      HTMLTableElement_.prototype.cellspacingAttribute = function (cellspacing) {
          this.setAttribute("cellspacing", "" + cellspacing);
          return this;
      };
      return HTMLTableElement_;
  }(HTMLElement_));
  var HTMLTableRowElement_ = /** @class */ (function (_super) {
      __extends(HTMLTableRowElement_, _super);
      function HTMLTableRowElement_() {
          return _super.call(this, "tr") || this;
      }
      return HTMLTableRowElement_;
  }(HTMLElement_));
  var HTMLTableColElement_ = /** @class */ (function (_super) {
      __extends(HTMLTableColElement_, _super);
      function HTMLTableColElement_() {
          return _super.call(this, "td") || this;
      }
      return HTMLTableColElement_;
  }(HTMLElement_));
  var HTMLSelectElement_ = /** @class */ (function (_super) {
      __extends(HTMLSelectElement_, _super);
      function HTMLSelectElement_() {
          return _super.call(this, "select") || this;
      }
      return HTMLSelectElement_;
  }(HTMLElement_));
  var HTMLOptionElement_ = /** @class */ (function (_super) {
      __extends(HTMLOptionElement_, _super);
      function HTMLOptionElement_() {
          return _super.call(this, "option") || this;
      }
      return HTMLOptionElement_;
  }(HTMLElement_));
  var ComboBox_ = /** @class */ (function (_super) {
      __extends(ComboBox_, _super);
      function ComboBox_() {
          var _this = _super !== null && _super.apply(this, arguments) || this;
          _this.options = {};
          return _this;
      }
      ComboBox_.prototype.setOptions = function (options) {
          this.html("");
          for (var id in options) {
              var o = new HTMLOptionElement_();
              o.setAttribute("value", id);
              o.innerHTML = options[id];
              this.options[id] = o;
              this.appendChild(o);
          }
          return this;
      };
      ComboBox_.prototype.setOptionsFromList = function (optionlist) {
          var options = {};
          optionlist.map(function (o) { return options[o] = o; });
          return this.setOptions(options);
      };
      ComboBox_.prototype.setSelected = function (id) {
          var _this = this;
          Object.keys(this.options).map(function (key) {
              if (id == key)
                  _this.options[key].setAttribute("selected", "true");
              else
                  _this.options[key].removeAttribute("selected");
          });
          return this;
      };
      ComboBox_.prototype.onChange = function (handler) {
          this.addEventListener("change", handler);
          return this;
      };
      return ComboBox_;
  }(HTMLSelectElement_));
  var HTMLInputElement_ = /** @class */ (function (_super) {
      __extends(HTMLInputElement_, _super);
      function HTMLInputElement_() {
          var _this = _super.call(this, "input") || this;
          _this.editCur = 0;
          _this.editlist = [];
          _this.setAttribute("type", "text");
          _this.addEventListener("keyup", _this.keyup.bind(_this));
          return _this;
      }
      HTMLInputElement_.prototype.getText = function () {
          var v = this.e.value;
          return v;
      };
      HTMLInputElement_.prototype.setText = function (value) {
          this.e.value = value;
          return this;
      };
      HTMLInputElement_.prototype.setEnterCallback = function (entercallback) {
          this.entercallback = entercallback;
          return this;
      };
      HTMLInputElement_.prototype.moveEditCur = function (dir) {
          if (this.editlist.length <= 0)
              return;
          if (this.getText() == "") {
              this.setText(this.editlist[this.editCur]);
              return;
          }
          this.editCur += dir;
          if (this.editCur >= this.editlist.length)
              this.editCur = 0;
          else if (this.editCur < 0)
              this.editCur = this.editlist.length - 1;
          this.setText(this.editlist[this.editCur]);
      };
      HTMLInputElement_.prototype.keyup = function (e) {
          //console.log(e.code)
          if (e.code == "Enter") {
              var text = this.getText();
              if ((this.editlist.length <= 0) || (this.editlist[this.editCur] != text))
                  this.editlist.splice(this.editCur, 0, text);
              if (this.entercallback != undefined) {
                  this.entercallback();
                  this.setText("");
              }
          }
          if (e.code == "ArrowUp") {
              this.moveEditCur(-1);
          }
          if (e.code == "ArrowDown") {
              this.moveEditCur(1);
          }
          if (e.code == "Escape") {
              this.setText("");
          }
      };
      return HTMLInputElement_;
  }(HTMLElement_));
  var HTMLTextAreaElement_ = /** @class */ (function (_super) {
      __extends(HTMLTextAreaElement_, _super);
      function HTMLTextAreaElement_() {
          return _super.call(this, "textarea") || this;
      }
      HTMLTextAreaElement_.prototype.getText = function () {
          var v = this.e.value;
          return v;
      };
      HTMLTextAreaElement_.prototype.setText = function (value) {
          this.e.value = value;
          return this;
      };
      return HTMLTextAreaElement_;
  }(HTMLElement_));
  var Tab = /** @class */ (function () {
      function Tab(_id, _caption) {
          this.id = _id;
          this.caption = _caption;
      }
      return Tab;
  }());
  var TabPane_ = /** @class */ (function (_super) {
      __extends(TabPane_, _super);
      function TabPane_(id, width, height, _tabs, _selid) {
          if (_selid === void 0) { _selid = null; }
          var _this = _super.call(this, "div") || this;
          _this.H_MARGIN = 4;
          _this.V_MARGIN = 24;
          _this.PADDING = 2;
          _this.UNSELECTED_TAB_BCOL = "#dfdfdf";
          _this.TABHTMLDivElement_BCOL = "#afffff";
          _this.SELECTED_TAB_BCOL = _this.TABHTMLDivElement_BCOL;
          _this.selid = null;
          _this.id = id;
          _this.selid = _selid;
          _this.tabs = _tabs;
          _this.tabtds = [];
          _this.tabdivs = [];
          _this.
              widthPx(width - 2 * _this.PADDING).
              heightPx(height - 2 * _this.PADDING).
              backgroundColor("#cfcfcf").
              overflow("hidden").
              paddingPx(_this.PADDING);
          _this.table = new HTMLTableElement_();
          _this.tr1 = new HTMLTableRowElement_();
          _this.tr2 = new HTMLTableRowElement_();
          var ctd = new HTMLTableColElement_();
          var ctddiv = new HTMLDivElement_().position("relative");
          for (var tabi in _tabs) {
              var tab = _tabs[tabi];
              var ttd = new HTMLTableColElement_().
                  backgroundColor(_this.UNSELECTED_TAB_BCOL).
                  cursor("pointer").
                  paddingPx(_this.PADDING).
                  html(tab.caption);
              ttd.addEventListener("mousedown", _this.tabhandler.bind(_this, _this.tabtdId(tab.id), tab.id));
              _this.tabtds.push(ttd);
              _this.tr1.appendChild(ttd);
              var div = new HTMLDivElement_().
                  widthPx(width - _this.H_MARGIN).
                  heightPx(height - _this.V_MARGIN).
                  position("absolute").
                  topPx(0).
                  leftPx(0).
                  backgroundColor(_this.TABHTMLDivElement_BCOL).
                  overflow("scroll").
                  visibilityBoolean(false);
              ctddiv.appendChild(div);
              _this.tabdivs.push(div);
          }
          ctd.appendChild(ctddiv);
          _this.tr2.appendChild(ctd);
          _this.table.appendChild(_this.tr1);
          _this.table.appendChild(_this.tr2);
          _this.appendChild(_this.table);
          _this.setSelected(_this.selid);
          return _this;
      }
      TabPane_.prototype.setSelected = function (tabid) {
          if (tabid === void 0) { tabid = null; }
          var scrollorig = false;
          if (tabid == null) {
              var storedselid = localStorage.getItem(this.id);
              if (storedselid != undefined)
                  this.selid = storedselid;
              else
                  this.selid = this.tabs[0].id;
          }
          else {
              if (this.selid == tabid)
                  scrollorig = true;
              this.selid = tabid;
          }
          for (var tabdivi in this.tabdivs) {
              var tabdiv = this.tabdivs[tabdivi];
              var tab = this.tabs[tabdivi];
              var tabtd = this.tabtds[tabdivi];
              var v = (tab.id == this.selid);
              tabdiv.visibilityBoolean(v);
              tabtd.backgroundColor(v ? this.SELECTED_TAB_BCOL : this.UNSELECTED_TAB_BCOL);
              if (v && scrollorig) {
                  tabdiv.scrollTop(0).scrollLeft(0);
              }
          }
          localStorage.setItem(this.id, this.selid);
      };
      TabPane_.prototype.tabhandler = function (tabtdid, tabid, e) {
          this.setSelected(tabid);
      };
      TabPane_.prototype.tabtdId = function (tabid) { return tabid + "_tabtd"; };
      TabPane_.prototype.contentId = function (tabid) { return tabid + "_content"; };
      TabPane_.prototype.getTabIndexById = function (tabid) {
          for (var ti in this.tabs) {
              var tab = this.tabs[ti];
              if (tab.id == tabid)
                  return parseInt(ti);
          }
          return 0;
      };
      TabPane_.prototype.getTabDivById = function (tabid) {
          return this.tabdivs[this.getTabIndexById(tabid)];
      };
      TabPane_.prototype.setContent = function (tabid, content) {
          var ti = this.getTabIndexById(tabid);
          var tabdiv = this.tabdivs[ti];
          tabdiv.html(content);
      };
      TabPane_.prototype.setElement_ = function (tabid, element_) {
          var ti = this.getTabIndexById(tabid);
          var tabdiv = this.tabdivs[ti];
          tabdiv.html("").appendChild(element_);
      };
      return TabPane_;
  }(HTMLElement_));
  var HTMLAnchorElement_ = /** @class */ (function (_super) {
      __extends(HTMLAnchorElement_, _super);
      function HTMLAnchorElement_() {
          return _super.call(this, "a") || this;
      }
      HTMLAnchorElement_.prototype.href = function (href) {
          this.setAttribute("href", href);
          return this;
      };
      return HTMLAnchorElement_;
  }(HTMLElement_));
  var HTMLBRElement_ = /** @class */ (function (_super) {
      __extends(HTMLBRElement_, _super);
      function HTMLBRElement_() {
          return _super.call(this, "br") || this;
      }
      return HTMLBRElement_;
  }(HTMLElement_));
  var HTMLLabelElement_ = /** @class */ (function (_super) {
      __extends(HTMLLabelElement_, _super);
      function HTMLLabelElement_() {
          return _super.call(this, "label") || this;
      }
      HTMLLabelElement_.prototype.setText = function (value) {
          this.e.innerHTML = value;
          return this;
      };
      return HTMLLabelElement_;
  }(HTMLElement_));
  var HTMLSpanElement_ = /** @class */ (function (_super) {
      __extends(HTMLSpanElement_, _super);
      function HTMLSpanElement_() {
          return _super.call(this, "span") || this;
      }
      return HTMLSpanElement_;
  }(HTMLElement_));
  var PaddedTd = /** @class */ (function (_super) {
      __extends(PaddedTd, _super);
      function PaddedTd(paddingpx) {
          if (paddingpx === void 0) { paddingpx = 3; }
          var _this = _super.call(this) || this;
          _this.paddingPx(paddingpx);
          return _this;
      }
      return PaddedTd;
  }(HTMLTableColElement_));
  var FileChooserState = /** @class */ (function (_super) {
      __extends(FileChooserState, _super);
      function FileChooserState() {
          var _this = _super !== null && _super.apply(this, arguments) || this;
          _this.dirpathl = ["C:"];
          _this.name = "default";
          _this.action = "";
          return _this;
      }
      FileChooserState.prototype.dirpath = function () {
          return this.dirpathl.join("/") + "/";
      };
      FileChooserState.prototype.fullpath = function () {
          return this.dirpath() + this.name;
      };
      FileChooserState.prototype.pathInfo = function (MAX) {
          if (MAX === void 0) { MAX = 50; }
          var path = this.dirpath();
          if (path.length < MAX)
              return path;
          return "..." + path.substr(path.length - MAX);
      };
      FileChooserState.prototype.fromJson = function (json) {
          this.dirpathl = json.dirpathl;
          this.name = json.name;
          return this;
      };
      FileChooserState.prototype.clone = function () {
          var fc = new FileChooserState();
          fc.fromJsonText(JSON.stringify(this));
          return fc;
      };
      return FileChooserState;
  }(Misc.JsonSerializableState));
  var FileChooser = /** @class */ (function (_super) {
      __extends(FileChooser, _super);
      function FileChooser(_id, _dialogroot) {
          var _this = _super.call(this) || this;
          _this.opendialog = null;
          _this.state = new FileChooserState();
          _this.savecallback = null;
          _this.loadcallback = null;
          _this.deletecallback = null;
          _this.id = _id;
          FileChooser.registry[_id] = _this;
          _this.dialogroot = _dialogroot;
          _this.load();
          return _this;
      }
      FileChooser.prototype.hide = function () {
          if (this.opendialog != null)
              this.opendialog.hide();
          this.opendialog = null;
      };
      FileChooser.prototype.hideAll = function () {
          for (var id in FileChooser.registry) {
              var fc = FileChooser.registry[id];
              fc.hide();
          }
      };
      FileChooser.prototype.dirSelected = function (fcstate) {
          this.hideAll();
          if ((fcstate.action == "select") || (fcstate.action == "selectfile"))
              this.state.dirpathl = fcstate.dirpathl;
          if (fcstate.action == "selectfile")
              this.state.name = fcstate.name;
          this.save();
          this.build();
      };
      FileChooser.prototype.choosedrivebuttonpressed = function (e) {
          var drivename = prompt("Enter drive name !");
          if ((drivename == "undefined") || (drivename == null) || (drivename == "")) { }
          else {
              this.state.dirpathl = [drivename];
              this.save();
              this.build();
          }
      };
      FileChooser.prototype.choosedirbuttonpressed = function (e) {
          var shouldopen = this.opendialog == null;
          this.hideAll();
          if (shouldopen) {
              this.opendialog = new FileDialogWindow(this.id + "_dirdialog").
                  setTitle("File").
                  setFileChooserState(this.state.clone()).
                  setDirSelectedCallback(this.dirSelected.bind(this)).
                  build();
              this.dialogroot.html("").appendChild(this.opendialog);
          }
      };
      FileChooser.prototype.actualize = function () {
          this.state.name = this.nameinput.getText();
          this.save();
      };
      FileChooser.prototype.savebuttonpressed = function (e) {
          this.actualize();
          this.savecallback(this.state);
      };
      FileChooser.prototype.setSaveCallback = function (_savecallback) {
          this.savecallback = _savecallback;
          return this;
      };
      FileChooser.prototype.loadbuttonpressed = function (e) {
          this.actualize();
          this.loadcallback(this.state);
      };
      FileChooser.prototype.setLoadCallback = function (_loadcallback) {
          this.loadcallback = _loadcallback;
          return this;
      };
      FileChooser.prototype.deletebuttonpressed = function (e) {
          this.actualize();
          this.deletecallback(this.state);
      };
      FileChooser.prototype.setDeleteCallback = function (_deletecallback) {
          this.deletecallback = _deletecallback;
          return this;
      };
      FileChooser.prototype.load = function () {
          var stored = localStorage.getItem(this.id);
          if (Misc.isDefined(stored)) {
              this.state.fromJsonText(stored);
          }
      };
      FileChooser.prototype.save = function () {
          localStorage.setItem(this.id, JSON.stringify(this.state));
      };
      FileChooser.prototype.build = function () {
          this.
              borderCollapse("separate").
              borderSpacingPx(3).
              borderPx(1).
              borderStyle("solid").
              borderColor("#dfdfdf").
              backgroundColor("#efefef").
              html("");
          this.dirinput = new HTMLLabelElement_();
          this.dirinput.
              fontFamily("monospace");
          this.nameinput = new HTMLInputElement_();
          var tr = new HTMLTableRowElement_();
          var choosedrivebutton = new HTMLButtonElement_().
              value(this.state.dirpathl[0]).
              onmousedown(this.choosedrivebuttonpressed.bind(this)).
              widthPx(50);
          var choosedirbutton = new HTMLButtonElement_().
              value("...").
              onmousedown(this.choosedirbuttonpressed.bind(this));
          var savebutton = new HTMLButtonElement_().
              value("Save").
              onmousedown(this.savebuttonpressed.bind(this));
          var loadbutton = new HTMLButtonElement_().
              value("Load").
              onmousedown(this.loadbuttonpressed.bind(this));
          var deletebutton = new HTMLButtonElement_().
              value("Delete").
              onmousedown(this.deletebuttonpressed.bind(this));
          tr.appendChilds([
              new PaddedTd().appendChild(choosedrivebutton),
              new PaddedTd().widthPx(400).appendChild(this.dirinput),
              new PaddedTd().appendChild(choosedirbutton),
              new PaddedTd().appendChild(this.nameinput)
          ]);
          if (this.savecallback != null)
              tr.appendChild(new PaddedTd().appendChild(savebutton));
          if (this.loadcallback != null)
              tr.appendChild(new PaddedTd().appendChild(loadbutton));
          if (this.deletecallback != null)
              tr.appendChild(new PaddedTd().appendChild(deletebutton));
          this.appendChild(tr);
          this.dirinput.setText(this.state.pathInfo());
          this.nameinput.setText(this.state.name);
          return this;
      };
      FileChooser.registry = {};
      return FileChooser;
  }(HTMLTableElement_));
  var FileDialogWindowState = /** @class */ (function () {
      function FileDialogWindowState() {
          this.x = 0;
          this.y = 0;
      }
      return FileDialogWindowState;
  }());
  var FileDialogWindow = /** @class */ (function (_super) {
      __extends(FileDialogWindow, _super);
      function FileDialogWindow(_id) {
          var _this = _super.call(this) || this;
          _this.title = "";
          _this.state = new FileDialogWindowState();
          _this.fcstate = new FileChooserState();
          _this.w = 400;
          _this.h = 400;
          _this.dragunderway = false;
          _this.id = _id;
          _this.position("absolute").zIndexNumber(10000);
          _this.topbardiv = new HTMLDivElement_().position("absolute");
          _this.contentdiv = new HTMLDivElement_().position("absolute");
          _this.bottombardiv = new HTMLDivElement_().position("absolute");
          return _this;
      }
      FileDialogWindow.prototype.windowdragstart = function (e) {
          e.preventDefault();
          var me = e;
          this.dragstart = new Vectors.ScreenVector(me.clientX, me.clientY);
          this.dragunderway = true;
      };
      FileDialogWindow.prototype.windowmouseout = function (e) {
          this.windowmousemove(e);
          this.windowmouseup(null);
          this.dragunderway = false;
      };
      FileDialogWindow.prototype.windowmousemove = function (e) {
          var me = e;
          if (this.dragunderway) {
              this.dragd = new Vectors.ScreenVector(me.clientX, me.clientY).Minus(this.dragstart);
              this.
                  topPx(Misc.limit(this.state.y + this.dragd.y, 0, FileDialogWindow.MAX_WINDOW_Y)).
                  leftPx(Misc.limit(this.state.x + this.dragd.x, 0, FileDialogWindow.MAX_WINDOW_X));
          }
      };
      FileDialogWindow.prototype.windowmouseup = function (e) {
          if (this.dragunderway) {
              this.dragunderway = false;
              this.state.y = Misc.limit(this.state.y + this.dragd.y, 0, FileDialogWindow.MAX_WINDOW_Y);
              this.state.x = Misc.limit(this.state.x + this.dragd.x, 0, FileDialogWindow.MAX_WINDOW_X);
              this.save();
          }
      };
      FileDialogWindow.prototype.load = function () {
          var stored = localStorage.getItem(this.id);
          if (Misc.isDefined(stored))
              this.state = JSON.parse(stored);
      };
      FileDialogWindow.prototype.save = function () {
          localStorage.setItem(this.id, JSON.stringify(this.state));
      };
      FileDialogWindow.prototype.onDirectorySelected = function () {
      };
      FileDialogWindow.prototype.onDirectoryError = function () {
      };
      FileDialogWindow.prototype.selectbuttonpressed = function (e) {
          this.fcstate.action = "select";
          this.dirselectedcallback(this.fcstate);
      };
      FileDialogWindow.prototype.cancelbuttonpressed = function (e) {
          this.fcstate.action = "cancel";
          this.dirselectedcallback(this.fcstate);
      };
      FileDialogWindow.prototype.onCreateDir = function () {
          var r = this.createdirajaxasset.resjson;
          this.contentdiv.
              html("").
              appendChild(this.createListContent(r.files));
      };
      FileDialogWindow.prototype.onCreateDirError = function () {
      };
      FileDialogWindow.prototype.createbuttonpressed = function (e) {
          var dirname = prompt("Enter directory name !");
          if ((dirname == "undefined") || (dirname == null) || (dirname == "")) { }
          else {
              this.createdirajaxasset = new AjaxAsset({
                  action: "createdir",
                  path: this.fcstate.dirpath(),
                  name: dirname
              });
              new AssetLoader().
                  add(this.createdirajaxasset).
                  setcallback(this.onCreateDir.bind(this)).
                  seterrorcallback(this.onCreateDirError.bind(this)).
                  load();
          }
      };
      FileDialogWindow.prototype.totalHeight = function () {
          return this.h + FileDialogWindow.BAR_WIDTH + FileDialogWindow.BOTTOM_BAR_WIDTH;
      };
      FileDialogWindow.prototype.build = function () {
          this.load();
          this.
              html("").
              topPx(this.state.y).
              leftPx(this.state.x).
              widthPx(this.w + 2 * FileDialogWindow.OUTER_MARGIN).
              heightPx(this.totalHeight() + 2 * FileDialogWindow.OUTER_MARGIN).
              background("url(assets/images/backgrounds/wood.jpg)").
              addEventListener("mousemove", this.windowmousemove.bind(this)).
              addEventListener("mouseup", this.windowmouseup.bind(this)).
              opacityNumber(0.9);
          var pathinfo = this.fcstate.pathInfo();
          this.topbardiv.
              html("<span style=\"opacity:0.6;\">" + this.title + "</span> <span style=\"font-family:monospace;font-size:11px;color:#00f;\">" + pathinfo + "</span>").
              draggableBoolean(true).
              topPx(FileDialogWindow.OUTER_MARGIN).
              leftPx(FileDialogWindow.OUTER_MARGIN).
              paddingPx(FileDialogWindow.PADDING).
              fontSizePx(FileDialogWindow.BAR_WIDTH - 3 * FileDialogWindow.PADDING).
              widthPx(this.w - 2 * FileDialogWindow.PADDING).
              heightPx(FileDialogWindow.BAR_WIDTH - 2 * FileDialogWindow.PADDING).
              cursor("move").
              backgroundColor("#ccc").
              addEventListener("dragstart", this.windowdragstart.bind(this)).
              addEventListener("mouseout", this.windowmouseout.bind(this)).
              opacityNumber(0.7);
          this.contentdiv.
              html("").
              topPx(FileDialogWindow.BAR_WIDTH + FileDialogWindow.OUTER_MARGIN).
              leftPx(FileDialogWindow.OUTER_MARGIN).
              widthPx(this.w).
              heightPx(this.h).
              overflow("scroll").
              backgroundColor("#ffffff");
          this.bottombardiv.
              html(this.title).
              draggableBoolean(true).
              topPx(FileDialogWindow.BAR_WIDTH + this.h + FileDialogWindow.OUTER_MARGIN).
              leftPx(FileDialogWindow.OUTER_MARGIN).
              paddingPx(FileDialogWindow.PADDING).
              fontSizePx(FileDialogWindow.BAR_WIDTH - 3 * FileDialogWindow.PADDING).
              widthPx(this.w - 2 * FileDialogWindow.PADDING).
              heightPx(FileDialogWindow.BOTTOM_BAR_WIDTH - 2 * FileDialogWindow.PADDING).
              backgroundColor("#afafaf").
              opacityNumber(0.7);
          var selectbutton = new HTMLButtonElement_().
              value("Select Directory").
              onmousedown(this.selectbuttonpressed.bind(this)).
              heightPx(FileDialogWindow.BOTTOM_BAR_WIDTH - 2 * FileDialogWindow.PADDING).
              marginRightPx(FileDialogWindow.PADDING);
          var cancelbutton = new HTMLButtonElement_().
              value("Cancel").
              onmousedown(this.cancelbuttonpressed.bind(this)).
              heightPx(FileDialogWindow.BOTTOM_BAR_WIDTH - 2 * FileDialogWindow.PADDING).
              marginRightPx(FileDialogWindow.PADDING);
          var createbutton = new HTMLButtonElement_().
              value("Create").
              onmousedown(this.createbuttonpressed.bind(this)).
              heightPx(FileDialogWindow.BOTTOM_BAR_WIDTH - 2 * FileDialogWindow.PADDING).
              marginRightPx(FileDialogWindow.PADDING);
          this.bottombardiv.html("").appendChilds([
              selectbutton,
              cancelbutton,
              createbutton
          ]);
          this.appendChilds([
              this.topbardiv,
              this.contentdiv,
              this.bottombardiv
          ]);
          this.loadDir();
          return this;
      };
      FileDialogWindow.prototype.loadDir = function () {
          this.listdirajaxasset = new AjaxAsset({
              action: "listdir",
              path: this.fcstate.dirpath()
          });
          new AssetLoader().
              add(this.listdirajaxasset).
              setcallback(this.onListDir.bind(this)).
              seterrorcallback(this.onListDirError.bind(this)).
              load();
      };
      FileDialogWindow.prototype.createListContent = function (dirlist) {
          var _this = this;
          var list = new HTMLDivElement_();
          var dirlistarray = dirlist;
          dirlistarray.sort(function (a, b) {
              if (a.isdir && !b.isdir)
                  return -1;
              if (!a.isdir && b.isdir)
                  return 1;
              return a.name.localeCompare(b.name);
          });
          var fstatsroot = {
              ok: true,
              name: "..",
              isfile: false,
              isdir: true,
              stats: {}
          };
          dirlistarray.unshift(fstatsroot);
          var i = 0;
          dirlistarray.map(function (fstats) {
              var stats = fstats.stats;
              var bcol = "#efefef";
              if (fstats.isdir)
                  bcol = ((i % 2) == 0) ? "#ffffcf" : "#ffffbf";
              if (fstats.isfile)
                  bcol = ((i % 2) == 0) ? "#efefef" : "#dfdfdf";
              if (!fstats.ok)
                  bcol = ((i % 2) == 0) ? "#ffdfdf" : "#ffcfcf";
              var itemdiv = new HTMLDivElement_().
                  paddingPx(FileDialogWindow.PADDING).
                  cursor("pointer").
                  html("<span style=\"color:" + (fstats.isdir ? "#00f" : "#000") + ";font-family:monospace;\">" + fstats.name + "</span>" +
                  (stats.mtime != undefined ? " " + ("<font size=\"1\">" + stats.mtime + "</font>") : "")).
                  backgroundColor(bcol).
                  addEventListener("mousedown", _this.dirItemClicked.bind(_this, fstats));
              list.appendChild(itemdiv);
              i++;
          });
          return list;
      };
      FileDialogWindow.prototype.dirItemClicked = function (fstats, e) {
          if (fstats.ok && fstats.isdir) {
              if (fstats.name == "..") {
                  if (this.fcstate.dirpathl.length > 1) {
                      this.fcstate.dirpathl.pop();
                  }
              }
              else {
                  this.fcstate.dirpathl.push(fstats.name);
              }
              this.build();
              return;
          }
          if (fstats.ok && fstats.isfile) {
              this.fcstate.name = fstats.name;
              this.fcstate.action = "selectfile";
              this.dirselectedcallback(this.fcstate);
          }
      };
      FileDialogWindow.prototype.onListDir = function () {
          var r = this.listdirajaxasset.resjson;
          this.contentdiv.
              html("").
              appendChild(this.createListContent(r.files));
      };
      FileDialogWindow.prototype.onListDirError = function () {
      };
      FileDialogWindow.prototype.hide = function () {
          this.html("").widthPx(0).heightPx(0);
          return this;
      };
      FileDialogWindow.prototype.setTitle = function (_title) {
          this.title = _title;
          return this;
      };
      FileDialogWindow.prototype.setFileChooserState = function (_fcstate) {
          this.fcstate = _fcstate;
          return this;
      };
      FileDialogWindow.prototype.setDirSelectedCallback = function (_dirselectedcallback) {
          this.dirselectedcallback = _dirselectedcallback;
          return this;
      };
      FileDialogWindow.BAR_WIDTH = 36;
      FileDialogWindow.BOTTOM_BAR_WIDTH = 40;
      FileDialogWindow.PADDING = 3;
      FileDialogWindow.OUTER_MARGIN = 5;
      FileDialogWindow.MAX_WINDOW_Y = 300;
      FileDialogWindow.MAX_WINDOW_X = 1000;
      return FileDialogWindow;
  }(HTMLDivElement_));
  var LichessUserData = /** @class */ (function () {
      function LichessUserData() {
          this.atomicrating = 1500;
          this.atomicgames = 0;
      }
      return LichessUserData;
  }());
  var LichessUser = /** @class */ (function () {
      function LichessUser(_handle) {
          this.handle = "Anonymous";
          this.data = new LichessUserData();
          this.handle = _handle;
      }
      LichessUser.prototype.url = function () {
          var url = "https://lichess.org/api/user/" + this.handle;
          return url;
      };
      LichessUser.prototype.loadThen = function (_callback, errorcallback) {
          this.callback = _callback;
          this.textasset = new TextAsset(this.url());
          new AssetLoader().
              add(this.textasset).
              setcallback(this.onLoad.bind(this)).
              seterrorcallback(errorcallback).
              load();
      };
      LichessUser.prototype.onLoad = function () {
          this.fromTextAsset(this.textasset);
          this.callback();
      };
      LichessUser.prototype.errorLogitem = function () {
          return new Misc.Logitem("error loading user: " + this.url() + " timed out").error();
      };
      LichessUser.prototype.infoLogitem = function () {
          return new Misc.Logitem("loading user " + this.url()).info();
      };
      LichessUser.prototype.okLogitem = function () {
          return new Misc.Logitem("user loaded " + this.url()).ok();
      };
      LichessUser.prototype.fromTextAsset = function (textasset) {
          return this.fromJsonText(textasset.text);
      };
      LichessUser.prototype.fromJsonText = function (storedjsontext) {
          return this.fromJson(JSON.parse(storedjsontext));
      };
      LichessUser.prototype.fromJson = function (json) {
          var perfs = json.perfs;
          if (Misc.isDefined(perfs)) {
              var atomic = perfs.atomic;
              if (Misc.isDefined(atomic)) {
                  this.data.atomicrating = atomic.rating;
                  this.data.atomicgames = atomic.games;
              }
          }
          //console.log(json)
          this.data.membersince = json.createdAt;
          this.data.followers = json.nbFollowers;
          return this;
      };
      return LichessUser;
  }());
  var PlayerUtils;
  (function (PlayerUtils) {
      var paddedTd = /** @class */ (function (_super) {
          __extends(paddedTd, _super);
          function paddedTd() {
              var _this = _super.call(this) || this;
              _this.paddingPx(3);
              _this.backgroundColor("#afffaf");
              return _this;
          }
          return paddedTd;
      }(HTMLTableColElement_));
      PlayerUtils.paddedTd = paddedTd;
  })(PlayerUtils || (PlayerUtils = {}));
  var paddedTd = PlayerUtils.paddedTd;
  var LichessUsers = /** @class */ (function () {
      function LichessUsers() {
          this.users = {};
          this.name = "players";
          var storedjsontext = localStorage.getItem(this.storeid());
          if (Misc.isDefined(storedjsontext)) {
              this.fromJsonText(storedjsontext);
          }
          this.maindiv = new HTMLDivElement_().
              backgroundColor("#ffffaf");
      }
      LichessUsers.prototype.storeid = function () {
          return "lichessusers_" + this.name;
      };
      LichessUsers.prototype.fromJsonText = function (storedjsontext) {
          this.users = JSON.parse(storedjsontext);
          return this;
      };
      LichessUsers.prototype.sortedHandles = function () {
          var _this = this;
          var keys = Object.keys(this.users);
          var sorted = keys.sort(function (a, b) {
              var ua = _this.users[a];
              var ub = _this.users[b];
              return ub.atomicrating - ua.atomicrating;
          });
          return sorted;
      };
      LichessUsers.prototype.createElement = function () {
          var _this = this;
          this.maindiv.html("");
          this.table = new HTMLTableElement_().
              borderCollapse("separate").
              borderSpacingPx(3);
          var htr = new HTMLTableRowElement_();
          htr.appendChilds([
              new paddedTd().html("Rank"),
              new paddedTd().html("Player"),
              new paddedTd().html("Rating"),
              new paddedTd().html("Games"),
              new paddedTd().html("Followers"),
              new paddedTd().html("Member since"),
              new paddedTd().html("Load")
          ]);
          this.table.appendChild(htr);
          var i = 1;
          this.sortedHandles().map(function (handle) {
              var tr = new HTMLTableRowElement_();
              var data = _this.users[handle];
              tr.appendChilds([
                  new paddedTd().html("" + i + "."),
                  new paddedTd().html(handle),
                  new paddedTd().html("" + data.atomicrating),
                  new paddedTd().html("" + data.atomicgames),
                  new paddedTd().html("" + data.followers),
                  new paddedTd().html("" + new Date(data.membersince).toLocaleString()),
                  new paddedTd().appendChild(new HTMLButtonElement_().
                      value("Load").
                      onmousedown(_this.loade.bind(_this, handle)))
              ]);
              _this.table.appendChild(tr);
              i++;
          });
          this.maindiv.appendChild(this.table);
          return this.maindiv;
      };
      LichessUsers.prototype.onplayerload = function (lu) {
          Globals.gui.log(lu.okLogitem());
          Globals.gui.tabs.setSelected("players");
          this.addSaveDraw(lu);
      };
      LichessUsers.prototype.onplayererror = function (lu) {
          Globals.gui.log(lu.errorLogitem());
      };
      LichessUsers.prototype.load = function (handle) {
          var lu = new LichessUser(handle);
          Globals.gui.tabs.setSelected("log");
          Globals.gui.log(lu.infoLogitem());
          lu.loadThen(this.onplayerload.bind(this, lu), this.onplayererror.bind(this, lu));
      };
      LichessUsers.prototype.loade = function (handle, e) {
          this.load(handle);
      };
      LichessUsers.prototype.save = function () {
          var jsontext = JSON.stringify(this.users);
          localStorage.setItem(this.storeid(), jsontext);
      };
      LichessUsers.prototype.add = function (lu) {
          this.users[lu.handle] = lu.data;
      };
      LichessUsers.prototype.addSave = function (lu) {
          this.add(lu);
          this.save();
      };
      LichessUsers.prototype.addSaveDraw = function (lu) {
          this.addSave(lu);
          this.createElement();
      };
      return LichessUsers;
  }());
  var Player = /** @class */ (function () {
      function Player() {
          this.name = "?";
          this.score = "0";
      }
      Player.prototype.fromJson = function (json) {
          this.name = json.name;
          this.score = json.score;
      };
      return Player;
  }());
  var Game = /** @class */ (function () {
      function Game() {
          this.result = "result";
          this.id = "gameid";
          this.lgsjson = null;
      }
      Game.prototype.fromJson = function (json) {
          this.i = json.i;
          this.result = json.result;
          this.id = json.id;
          this.lgsjson = json.lgsjson;
          return this;
      };
      return Game;
  }());
  var PairingState = /** @class */ (function () {
      function PairingState() {
          this.players = [new Player(), new Player()];
          this.games = [];
          this.forfeit = false;
      }
      PairingState.prototype.pairingLabel = function (i) {
          return this.players[i].name + " - " + this.players[1 - i].name;
      };
      PairingState.prototype.resultColors = function (result) {
          var wcolor = PairingState.RESULT_BLUE;
          var bcolor = PairingState.RESULT_BLUE;
          if (result == "1-0") {
              wcolor = PairingState.RESULT_GREEN;
              bcolor = PairingState.RESULT_RED;
          }
          if (result == "0-1") {
              wcolor = PairingState.RESULT_RED;
              bcolor = PairingState.RESULT_GREEN;
          }
          return { "wcolor": wcolor, "bcolor": bcolor };
      };
      PairingState.prototype.pairingLabelHtml = function (i, result) {
          if (result === void 0) { result = "draw"; }
          var rc = this.resultColors(result);
          return "<span style=\"color:" + rc["wcolor"] + ";\">" + this.players[i].name + "</span>" + Misc.nbr(" - ") + "<span style=\"color:" + rc["bcolor"] + ";\">" + this.players[1 - i].name + "</span>";
      };
      PairingState.RESULT_BLUE = "#0000ff";
      PairingState.RESULT_GREEN = "#007f00";
      PairingState.RESULT_RED = "#ff0000";
      return PairingState;
  }());
  var Pairing = /** @class */ (function () {
      function Pairing(_parentbracket) {
          this.HEIGHT = 60;
          this.BUTTON_HEIGHT = 20;
          this.LABEL_HEIGHT = 24;
          this.GAME_HEIGHT = 30;
          this.TOTAL_HEIGHT = this.HEIGHT + 40;
          this.WIDTH = 220;
          this.EDIT_SEPARATION = 10;
          this.LABEL_WIDTH = 150;
          this.LABEL_PADDING = 4;
          this.TABLE_SPACING = 10;
          this.SCORE_WIDTH = 30;
          this.RESULT_WIDTH = 100;
          this.TOTAL_WIDTH = this.WIDTH + 110;
          this.SHOW_GAMES_WIDTH = 600;
          this.BAR_WIDTH = 8;
          this.BAR_COLOR = "#7f7f7f";
          this.SELECTED_GAME_BCOL = "#afffaf";
          this.CONTROL_BUTTON_PADDING = 5;
          this.state = new PairingState();
          this.selectedgame = null;
          this.parentbracket = null;
          this.parents = [null, null];
          this.depth = 0;
          this.index = 0;
          this.child = null;
          this.absindex = 0;
          this.labels = [null, null];
          this.scores = [null, null];
          this.gamescores = [];
          this.gameids = [];
          this.parentbracket = _parentbracket;
      }
      Pairing.prototype.fromJson = function (json) {
          for (var i in json.players) {
              var playerjson = json.players[i];
              this.state.players[i].fromJson(playerjson);
          }
          this.state.games = [];
          for (var i in json.games) {
              var gamejson = json.games[i];
              this.state.games.push(new Game().fromJson(gamejson));
              if (gamejson.lgsjson != null) {
                  var lg = new LichessGame().fromSerializedJson(gamejson.lgsjson);
                  this.parentbracket.lichessgameregistry[lg.gameid] = lg;
              }
          }
          this.state.forfeit = json.forfeit;
      };
      Pairing.prototype.createParents = function (currentchild, currentdepth, maxdepth, depthcounts) {
          if (this.parentbracket.pairingregistry[this.depth] == undefined)
              this.parentbracket.pairingregistry[this.depth] = {};
          this.parentbracket.pairingregistry[this.depth][this.index] = this;
          if (this.parentbracket.pairingstateregistry[this.depth] == undefined)
              this.parentbracket.pairingstateregistry[this.depth] = {};
          this.parentbracket.pairingstateregistry[this.depth][this.index] = this.state;
          if (currentdepth > maxdepth)
              return;
          if (depthcounts[currentdepth] == undefined) {
              depthcounts[currentdepth] = 0;
          }
          for (var i = 0; i < 2; i++) {
              this.parents[i] = new Pairing(this.parentbracket);
              this.parents[i].depth = currentdepth;
              this.parents[i].index = depthcounts[currentdepth];
              this.parents[i].child = currentchild;
              this.parents[i].createParents(this.parents[i], currentdepth + 1, maxdepth, depthcounts);
              depthcounts[currentdepth]++;
          }
      };
      Pairing.prototype.middleIndex = function () {
          return (Math.pow(2, this.depth) - 1) / 2;
      };
      Pairing.prototype.distFromMiddle = function () {
          return this.index - this.middleIndex();
      };
      Pairing.prototype.distFromMiddleMagnified = function () {
          return this.distFromMiddle() * Math.pow(2, (this.parentbracket.rounds - 1) - this.depth);
      };
      Pairing.prototype.totalHeigtMagnified = function () {
          return this.TOTAL_HEIGHT * Math.pow(2, (this.parentbracket.rounds - 2) - this.depth);
      };
      Pairing.prototype.distFromMiddlePx = function () {
          return this.distFromMiddleMagnified() * this.TOTAL_HEIGHT;
      };
      Pairing.prototype.maxMiddleIndex = function () {
          return (Math.pow(2, this.parentbracket.rounds - 1) - 1) / 2;
      };
      Pairing.prototype.middlePx = function () {
          return this.maxMiddleIndex() * this.TOTAL_HEIGHT;
      };
      Pairing.prototype.topPx = function () {
          return this.middlePx() + this.distFromMiddlePx();
      };
      Pairing.prototype.leftPx = function () {
          return (this.parentbracket.rounds - 1 - this.depth) * this.TOTAL_WIDTH;
      };
      Pairing.prototype.barMiddlePx = function () {
          return this.topPx() + this.HEIGHT / 2;
      };
      Pairing.prototype.barMiddleTopPx = function () {
          return this.barMiddlePx() - this.BAR_WIDTH / 2;
      };
      Pairing.prototype.barWidthPx = function () {
          return (this.TOTAL_WIDTH - this.WIDTH) / 2;
      };
      Pairing.prototype.hasParent = function () {
          return this.parents[0] != null;
      };
      Pairing.prototype.playerpressed = function (handle, e) {
          Globals.gui.players.load(handle);
      };
      Pairing.prototype.createElement = function () {
          this.div = new HTMLDivElement_().
              position("absolute").
              topPx(this.topPx()).
              leftPx(this.leftPx()).
              widthPx(this.WIDTH).
              heightPx(this.HEIGHT).
              backgroundColor("#00ff00");
          this.parentbracket.bracketdiv.appendChild(this.div);
          if (this.child != null) {
              var childbar = new HTMLDivElement_().
                  position("absolute").
                  topPx(this.barMiddleTopPx()).
                  leftPx(this.leftPx() + this.WIDTH).
                  widthPx(this.barWidthPx()).
                  heightPx(this.BAR_WIDTH).
                  backgroundColor(this.BAR_COLOR);
              this.parentbracket.bracketdiv.appendChild(childbar);
          }
          if (this.hasParent()) {
              var parentbar = new HTMLDivElement_().
                  position("absolute").
                  topPx(this.barMiddleTopPx()).
                  leftPx(this.leftPx() - this.barWidthPx()).
                  widthPx(this.barWidthPx()).
                  heightPx(this.BAR_WIDTH).
                  backgroundColor(this.BAR_COLOR);
              this.parentbracket.bracketdiv.appendChild(parentbar);
              var joinbar = new HTMLDivElement_().
                  position("absolute").
                  topPx(this.barMiddlePx() - this.totalHeigtMagnified() / 2 - this.BAR_WIDTH / 2).
                  leftPx(this.leftPx() - this.barWidthPx() - this.BAR_WIDTH).
                  widthPx(this.BAR_WIDTH).
                  heightPx(this.totalHeigtMagnified()).
                  backgroundColor(this.BAR_COLOR);
              this.parentbracket.bracketdiv.appendChild(joinbar);
          }
          this.parents.map(function (p) {
              if (p != null)
                  p.createElement();
          });
          for (var i = 0; i < 2; i++) {
              var player = this.state.players[i];
              this.labels[i] = (this.parentbracket.editmode ?
                  new HTMLInputElement_().
                      setText(player.name).
                      backgroundColor("#efefef")
                  :
                      new HTMLLabelElement_().
                          setText(player.name).
                          paddingTopPx(this.LABEL_PADDING).
                          paddingLeftPx(this.LABEL_PADDING).
                          cursor("pointer").
                          addEventListener("mousedown", this.playerpressed.bind(this, player.name)));
              this.labels[i].position("absolute").
                  topPx((i * 2 + 1) * this.HEIGHT / 4 - this.LABEL_HEIGHT / 2).
                  leftPx(3).
                  widthPx(this.LABEL_WIDTH).
                  heightPx(this.LABEL_HEIGHT);
              this.div.appendChild(this.labels[i]);
              this.scores[i] = (this.parentbracket.editmode ?
                  new HTMLInputElement_().
                      setText(player.score).
                      backgroundColor("#efefef")
                  :
                      new HTMLLabelElement_().
                          setText(player.score).
                          paddingTopPx(this.LABEL_PADDING).
                          paddingLeftPx(this.LABEL_PADDING));
              this.scores[i].position("absolute").
                  topPx((i * 2 + 1) * this.HEIGHT / 4 - this.LABEL_HEIGHT / 2).
                  leftPx(8 + this.LABEL_WIDTH).
                  widthPx(this.SCORE_WIDTH).
                  heightPx(this.LABEL_HEIGHT);
              this.div.appendChild(this.scores[i]);
          }
          this.showgamesbutton = new HTMLButtonElement_().
              value(this.state.forfeit ? "Forfeit" : ">").
              onmousedown(this.showgamesbuttonpressed.bind(this)).
              position("absolute").
              topPx(this.HEIGHT / 2 - this.BUTTON_HEIGHT / 2).
              leftPx(this.LABEL_WIDTH + this.SCORE_WIDTH + 15).
              heightPx(this.BUTTON_HEIGHT).
              zIndexNumber(100);
          this.div.appendChild(this.showgamesbutton);
      };
      Pairing.prototype.newgamebuttonpressed = function (i, e) {
          var game = new Game();
          game.i = i;
          this.savegames();
          this.state.games.push(game);
          this.parentbracket.save();
          this.showgames();
      };
      Pairing.prototype.gameScoreForPlayer = function (g, i) {
          var scorewhite = 0.5;
          var scoreblack = 0.5;
          if (g.result == "1-0") {
              scorewhite = 1;
              scoreblack = 0;
          }
          if (g.result == "0-1") {
              scorewhite = 0;
              scoreblack = 1;
          }
          var truei = g.i == 0 ? i : 1 - i;
          return truei == 0 ? scorewhite : scoreblack;
      };
      Pairing.prototype.updateMatchScore = function () {
          for (var i = 0; i < 2; i++) {
              this.state.players[i].score = "0";
              for (var gi = 0; gi < this.state.games.length; gi++) {
                  var score = this.gameScoreForPlayer(this.state.games[gi], i);
                  this.state.players[i].score = "" + (parseFloat(this.state.players[i].score) + score);
              }
          }
      };
      Pairing.prototype.updateMatchScoreGui = function () {
          this.updateMatchScore();
          for (var i = 0; i < 2; i++)
              this.scores[i].setText(this.state.players[i].score);
      };
      Pairing.prototype.checkgameloaded = function (gi, lg, li) {
          this.selectedgame = gi;
          Globals.gui.log(li);
          Globals.gui.tabs.setSelected("bracket");
          var lgsjson = lg.toSerializedJson();
          this.state.games[gi].lgsjson = lgsjson;
          this.state.games[gi].id = lg.gameid;
          this.state.games[gi].result = lg.result;
          this.parentbracket.lichessgameregistry[lg.gameid] = lg;
          this.updateMatchScoreGui();
          this.showgames();
      };
      Pairing.prototype.loadgameerror = function (gi, lg) {
          Globals.gui.log(lg.errorLogitem());
          var lgsjson = this.state.games[gi].lgsjson;
          if (lgsjson != null) {
              lg.fromSerializedJson(lgsjson);
              this.checkgameloaded(gi, lg, lg.localAvailableLogitem());
          }
      };
      Pairing.prototype.checkgamebuttonpressed = function (gi, e) {
          var gameid = this.gameids[gi].getText();
          var lg = new LichessGame(gameid);
          Globals.gui.tabs.setSelected("log");
          Globals.gui.log(lg.infoLogitem());
          lg.loadThen(this.checkgameloaded.bind(this, gi, lg, lg.okLogitem()), this.loadgameerror.bind(this, gi, lg));
      };
      Pairing.prototype.deletegamebuttonpressed = function (gi, e) {
          this.selectedgame = null;
          var newgames = [];
          for (var i = 0; i < this.state.games.length; i++) {
              if (i != gi)
                  newgames.push(this.state.games[i]);
          }
          this.state.games = newgames;
          this.updateMatchScoreGui();
          this.showgames();
      };
      Pairing.prototype.showgames = function () {
          this.parentbracket.showngames = null;
          this.showgamesbuttonpressed.bind(this)();
      };
      Pairing.prototype.opengamebuttonpressed = function (gi, e) {
          this.selectedgame = gi;
          this.showgames();
          var id = this.state.games[gi].id;
          var gui = Globals.gui;
          gui.gameidtext.setText(id);
          gui.gameloadbuttonpressed(null);
      };
      Pairing.prototype.savegames = function () {
          for (var gi = 0; gi < this.state.games.length; gi++) {
              this.state.games[gi].result = this.gamescores[gi].getText();
              this.state.games[gi].id = this.gameids[gi].getText();
          }
      };
      Pairing.prototype.savegamesbuttonpressed = function (e) {
          this.savegames();
          this.updateMatchScoreGui();
          this.showgamesbuttonpressed.bind(this)();
      };
      Pairing.prototype.forfeitbuttonpressed = function (e) {
          this.state.forfeit = !this.state.forfeit;
          this.parentbracket.showngames = null;
          this.parentbracket.save();
          this.parentbracket.createElement();
      };
      Pairing.prototype.createEditTable = function () {
          var edittable;
          edittable = new HTMLTableElement_().
              borderCollapse("separate").
              borderSpacingPx(this.TABLE_SPACING).
              backgroundColor("#ffff7f");
          var et_tr1 = new HTMLTableRowElement_();
          var et_td11 = new HTMLTableColElement_();
          var et_td12 = new HTMLTableColElement_();
          et_tr1.appendChilds([et_td11, et_td12]);
          var et_tr2 = new HTMLTableRowElement_();
          var savegamesbutton = new HTMLButtonElement_().
              value("Save games").
              onmousedown(this.savegamesbuttonpressed.bind(this));
          et_td11.appendChilds([savegamesbutton]);
          this.forfeitbutton = new HTMLButtonElement_().
              value(this.state.forfeit ? "Unforfeit" : "Forfeit").
              onmousedown(this.forfeitbuttonpressed.bind(this));
          et_td12.appendChilds([this.forfeitbutton]);
          for (var i = 0; i < 2; i++) {
              var newgamebutton = new HTMLButtonElement_().
                  value("New " + this.state.pairingLabel(i)).
                  onmousedown(this.newgamebuttonpressed.bind(this, i));
              var et_td2_ = new HTMLTableColElement_();
              et_tr2.appendChild(et_td2_);
              et_td2_.appendChilds([
                  newgamebutton
              ]);
          }
          edittable.appendChilds([et_tr1, et_tr2]);
          return edittable;
      };
      Pairing.prototype.createGameTable = function () {
          var numgames = this.state.games.length;
          var gamepanel = new HTMLTableElement_().
              position("absolute").topPx(this.topPx() + this.showgamesbutton.getComputedBottomPx() + this.EDIT_SEPARATION / 2 +
              (this.parentbracket.editmode ? this.edittabletop.getComputedHeightPx() + this.EDIT_SEPARATION : 0)).
              leftPx(this.leftPx() + this.showgamesbutton.getComputedLeftPx() - this.EDIT_SEPARATION).
              borderCollapse("separate").
              borderSpacingPx(this.TABLE_SPACING).
              backgroundColor("#ffff7f");
          this.gamescores = [];
          this.gameids = [];
          for (var gi = 0; gi < numgames; gi++) {
              var tr = new HTMLTableRowElement_();
              var game = this.state.games[gi];
              var checkgamebutton = new HTMLButtonElement_().
                  value("Check").
                  onmousedown(this.checkgamebuttonpressed.bind(this, gi));
              var deletegamebutton = new HTMLButtonElement_().
                  value("Delete").
                  onmousedown(this.deletegamebuttonpressed.bind(this, gi));
              var opengamebutton = new HTMLButtonElement_().
                  value("Open").
                  onmousedown(this.opengamebuttonpressed.bind(this, gi));
              var gamescoreinput = this.parentbracket.editmode ?
                  new HTMLInputElement_().
                      setText(game.result).
                      widthPx(this.RESULT_WIDTH)
                  :
                      new HTMLDivElement_().
                          html(Misc.nbr(game.result)).
                          paddingLeftPx(8).
                          paddingRightPx(8);
              this.gamescores.push(gamescoreinput);
              var gameidinput = new HTMLInputElement_().
                  setText(game.id).
                  widthPx(this.RESULT_WIDTH);
              this.gameids.push(gameidinput);
              var pairinglabel = new HTMLDivElement_().
                  paddingTopPx(this.CONTROL_BUTTON_PADDING).
                  paddingBottomPx(this.CONTROL_BUTTON_PADDING).
                  html(this.state.pairingLabelHtml(game.i, game.result));
              tr.appendChilds([
                  new HTMLTableColElement_().
                      paddingLeftPx(this.CONTROL_BUTTON_PADDING).
                      paddingRightPx(this.CONTROL_BUTTON_PADDING).
                      appendChild(opengamebutton),
                  new HTMLTableColElement_().
                      paddingLeftPx(this.CONTROL_BUTTON_PADDING).
                      paddingRightPx(this.CONTROL_BUTTON_PADDING).
                      appendChild(pairinglabel),
                  new HTMLTableColElement_().
                      paddingLeftPx(this.CONTROL_BUTTON_PADDING).
                      paddingRightPx(this.CONTROL_BUTTON_PADDING).
                      appendChild(gamescoreinput)
              ]);
              if (this.parentbracket.editmode)
                  tr.appendChilds([
                      new HTMLTableColElement_().
                          paddingLeftPx(this.CONTROL_BUTTON_PADDING).
                          paddingRightPx(this.CONTROL_BUTTON_PADDING).
                          appendChild(gameidinput),
                      new HTMLTableColElement_().
                          paddingLeftPx(this.CONTROL_BUTTON_PADDING).
                          paddingRightPx(this.CONTROL_BUTTON_PADDING).
                          appendChild(checkgamebutton),
                      new HTMLTableColElement_().
                          paddingLeftPx(this.CONTROL_BUTTON_PADDING).
                          paddingRightPx(this.CONTROL_BUTTON_PADDING).
                          appendChild(deletegamebutton)
                  ]);
              if (this.selectedgame != null) {
                  if (gi == this.selectedgame) {
                      tr.backgroundColor(this.SELECTED_GAME_BCOL);
                  }
              }
              gamepanel.appendChild(tr);
          }
          return gamepanel;
      };
      Pairing.prototype.showgamesbuttonpressed = function (e) {
          this.parentbracket.save();
          if ((e != undefined) && (e == null))
              this.parentbracket.showngames = null;
          var show = this.parentbracket.showngames != this;
          this.parentbracket.showngames = show ? this : null;
          var sgd = this.parentbracket.showgamediv;
          sgd.html("").widthPx(0).heightPx(0).leftPx(0).topPx(0).zIndexNumber(200);
          if (!show)
              return;
          var etdivtop = new HTMLDivElement_().
              position("absolute").
              topPx(this.topPx() + this.showgamesbutton.getComputedBottomPx() + this.EDIT_SEPARATION / 2).
              leftPx(this.leftPx() + this.showgamesbutton.getComputedLeftPx() - this.EDIT_SEPARATION);
          var etdivbottom = new HTMLDivElement_().
              position("absolute").
              leftPx(this.leftPx() + this.showgamesbutton.getComputedLeftPx() - this.EDIT_SEPARATION);
          if (this.parentbracket.editmode) {
              this.edittabletop = this.createEditTable();
              this.edittablebottom = this.createEditTable();
              etdivtop.appendChild(this.edittabletop);
              etdivbottom.appendChild(this.edittablebottom);
              sgd.appendChild(etdivtop);
              sgd.appendChild(etdivbottom);
          }
          var gamepanel = this.createGameTable();
          sgd.appendChild(gamepanel);
          if (this.parentbracket.editmode) {
              etdivbottom.
                  topPx(gamepanel.getComputedBottomPx() + this.EDIT_SEPARATION);
          }
      };
      return Pairing;
  }());
  var Bracket = /** @class */ (function () {
      function Bracket(_rounds) {
          if (_rounds === void 0) { _rounds = 5; }
          this.DIV_BUFFER_SIZE = 1200;
          this.showngames = null;
          this.pairingstateregistry = {};
          this.pairingregistry = {};
          this.lichessgameregistry = {};
          this.name = "default";
          this.dragunderway = false;
          this.editmode = true;
          this.hidecontrols = false;
          this.rounds = _rounds;
          this.root = new Pairing(this);
          this.root.createParents(this.root, 1, this.rounds - 1, {});
          this.maindiv = new HTMLDivElement_();
          this.tabroot = Globals.gui.tabs.getTabDivById("bracket");
          this.tabroot.draggableBoolean(true).
              addEventListener("dragstart", this.tabdragstart.bind(this)).
              addEventListener("mousemove", this.tabmousemove.bind(this)).
              addEventListener("mouseup", this.tabmouseup.bind(this));
      }
      Bracket.prototype.tabdragstart = function (e) {
          e.preventDefault();
          var me = e;
          this.dragstart = new Vectors.ScreenVector(me.clientX, me.clientY);
          this.scrollstart = new Vectors.ScreenVector(this.tabroot.getScrollLeft(), this.tabroot.getScrollTop());
          this.dragunderway = true;
      };
      Bracket.prototype.tabmousemove = function (e) {
          var me = e;
          if (this.dragunderway) {
              var dragd = new Vectors.ScreenVector(me.clientX, me.clientY).Minus(this.dragstart);
              var scrollcurrent = this.scrollstart.Minus(dragd);
              this.tabroot.scrollTop(scrollcurrent.y);
              this.tabroot.scrollLeft(scrollcurrent.x);
          }
      };
      Bracket.prototype.tabmouseup = function (e) {
          if (this.dragunderway) {
              this.dragunderway = false;
          }
      };
      Bracket.prototype.savebracketcallback = function (fcstate) {
          var fullpath = fcstate.fullpath();
          var src = this.src();
          var ajaxasset = new AjaxAsset({
              action: "writetextfile",
              path: fullpath,
              content: src
          });
          new AssetLoader().
              add(ajaxasset).
              load();
      };
      Bracket.prototype.bracketloadedcallback = function (ajaxasset) {
          var result = ajaxasset.resjson;
          if (!result.error) {
              Globals.gui.srctext.setText(result.content);
              Globals.gui.tabs.setSelected("src");
          }
      };
      Bracket.prototype.loadbracketcallback = function (fcstate) {
          var fullpath = fcstate.fullpath();
          var ajaxasset = new AjaxAsset({
              action: "readtextfile",
              path: fullpath
          });
          new AssetLoader().
              add(ajaxasset).
              setcallback(this.bracketloadedcallback.bind(this, ajaxasset)).
              load();
      };
      Bracket.prototype.createElement = function () {
          //localStorage.setItem(this.storeid(),"null")
          this.maindiv.html("");
          var savebutton = new HTMLButtonElement_().
              value("Save").
              onmousedown(this.savebuttonpressed.bind(this));
          var loadbutton;
          loadbutton = new HTMLButtonElement_().
              value("Load").
              onmousedown(this.loadbuttonpressed.bind(this));
          var importbutton = new HTMLButtonElement_().
              value("Import").
              onmousedown(this.importbuttonpressed.bind(this));
          var filechooser = new FileChooser("bracketfilechooser", Globals.gui.dialogroot).
              setSaveCallback(this.savebracketcallback.bind(this)).
              setLoadCallback(this.loadbracketcallback.bind(this)).
              build();
          if (this.storedjson() == null) {
              loadbutton = new HTMLLabelElement_().setText("Nothing saved yet");
          }
          var freezebutton = new HTMLButtonElement_().
              value("Freeze").
              onmousedown(this.freezebuttonpressed.bind(this));
          var editbutton = new HTMLButtonElement_().
              value("Edit").
              onmousedown(this.editbuttonpressed.bind(this));
          if (!this.hidecontrols) {
              if (this.editmode) {
                  this.maindiv.appendChilds([
                      freezebutton,
                      savebutton,
                      loadbutton,
                      importbutton,
                      filechooser
                  ]);
              }
              else {
                  this.maindiv.appendChilds([
                      editbutton,
                      loadbutton
                  ]);
              }
          }
          this.bracketdiv = new HTMLDivElement_().position("relative");
          this.root.createElement();
          this.showgamediv = new HTMLDivElement_().
              position("absolute");
          this.bracketdiv.appendChild(this.showgamediv);
          this.maindiv.appendChild(this.bracketdiv);
          this.maindiv.widthPx(this.root.TOTAL_WIDTH * this.rounds + this.DIV_BUFFER_SIZE);
          this.maindiv.heightPx(this.root.TOTAL_HEIGHT * Math.pow(2, this.rounds - 1) + this.DIV_BUFFER_SIZE);
          return this.maindiv;
      };
      Bracket.prototype.storedjson = function () {
          var item = localStorage.getItem(this.storeid());
          if ((item == undefined) || (item == null) || (item == "null"))
              return null;
          return item;
      };
      Bracket.prototype.storeid = function () {
          return "bracket_" + this.name;
      };
      Bracket.prototype.src = function () {
          return JSON.stringify(this.pairingstateregistry, null, 1);
      };
      Bracket.prototype.save = function () {
          if (!this.editmode)
              return;
          for (var ditem in this.pairingregistry)
              for (var iitem in this.pairingregistry[ditem]) {
                  var pairing = this.pairingregistry[ditem][iitem];
                  for (var i = 0; i < 2; i++) {
                      var player = this.pairingstateregistry[ditem][iitem].players[i];
                      player.name = pairing.labels[i].getText();
                      player.score = pairing.scores[i].getText();
                  }
              }
          this.json = this.src();
          localStorage.setItem(this.storeid(), this.json);
          Globals.gui.srctext.setText(this.json);
      };
      Bracket.prototype.savebuttonpressed = function (e) {
          this.save();
          Globals.gui.tabs.setSelected("src");
      };
      Bracket.prototype.load = function (setjson) {
          if (setjson === void 0) { setjson = null; }
          var storedjson = setjson != null ? setjson : this.storedjson();
          if (storedjson != null) {
              var json = JSON.parse(storedjson);
              for (var ditem in json)
                  for (var iitem in json[ditem]) {
                      var pairingjson = json[ditem][iitem];
                      this.pairingregistry[ditem][iitem].fromJson(pairingjson);
                  }
              Globals.gui.srctext.setText(storedjson);
          }
          this.createElement();
      };
      Bracket.prototype.loadbuttonpressed = function (e) {
          this.load();
          this.createElement();
      };
      Bracket.prototype.importbuttonpressed = function (e) {
          this.load(Globals.gui.srctext.getText());
          this.save();
          this.createElement();
      };
      Bracket.prototype.freezebuttonpressed = function (e) {
          this.save();
          this.showngames = null;
          this.editmode = false;
          this.createElement();
      };
      Bracket.prototype.editbuttonpressed = function (e) {
          this.editmode = true;
          this.showngames = null;
          this.createElement();
      };
      return Bracket;
  }());
  var SetupUtils;
  (function (SetupUtils) {
      var paddedTd = /** @class */ (function (_super) {
          __extends(paddedTd, _super);
          function paddedTd() {
              var _this = _super.call(this) || this;
              _this.paddingPx(3).
                  backgroundColor("#ffffaf");
              return _this;
          }
          return paddedTd;
      }(HTMLTableColElement_));
      SetupUtils.paddedTd = paddedTd;
      function createPaddedHeadTd() {
          return new paddedTd().backgroundColor("#afffaf");
      }
      SetupUtils.createPaddedHeadTd = createPaddedHeadTd;
  })(SetupUtils || (SetupUtils = {}));
  var ptd = SetupUtils.paddedTd;
  var phtd = SetupUtils.createPaddedHeadTd;
  var Setup = /** @class */ (function () {
      function Setup() {
          var _this = this;
          this.defaultengines = {};
          this.availableengines = ["[None]"];
          this.maindiv = new HTMLDivElement_();
          var stored = localStorage.getItem("setup");
          Config.supportedVariants().map(function (variant) {
              _this.defaultengines[variant] = "[None]";
          });
          if (Misc.isDefined(stored)) {
              var storedjson = JSON.parse(stored);
              this.defaultengines = storedjson.defaultengines;
              this.availableengines = storedjson.availableengines;
          }
      }
      Setup.prototype.onanalyzerconnect = function () {
          Globals.gui.tabs.setSelected("setup");
          this.availableengines = Globals.gui.analyzer.available;
          this.availableengines.unshift("[None]");
          this.save();
          this.createElement();
      };
      Setup.prototype.connectbuttonpressed = function (e) {
          Globals.gui.analyzer.connect();
      };
      Setup.prototype.save = function () {
          localStorage.setItem("setup", JSON.stringify(this));
      };
      Setup.prototype.defaultEngineChanged = function (variant, e) {
          var t = e.target;
          var selectedengine = t.selectedOptions[0].value;
          this.defaultengines[variant] = selectedengine;
          this.save();
          this.createElement();
      };
      Setup.prototype.createElement = function () {
          var _this = this;
          this.maindiv.html("");
          var connectbutton = new HTMLButtonElement_().
              value("Connect to engine server").
              onmousedown(this.connectbuttonpressed.bind(this));
          this.maindiv.appendChilds([
              connectbutton
          ]);
          var variantenginetable = new HTMLTableElement_().
              borderCollapse("separate").
              borderSpacingPx(3);
          variantenginetable.appendChild(new HTMLTableRowElement_().appendChilds([
              phtd().html("Variant"),
              phtd().html("Select default engine"),
              phtd().html("Current default engine")
          ]));
          Config.supportedVariants().map(function (variant) {
              var tr = new HTMLTableRowElement_();
              var defaultengine = _this.defaultengines[variant];
              var selectdefaultcombo = new ComboBox_().
                  setOptionsFromList(_this.availableengines).
                  setSelected(defaultengine).
                  onChange(_this.defaultEngineChanged.bind(_this, variant));
              tr.appendChilds([
                  new ptd().html(Config.variantToDisplayName[variant]),
                  new ptd().appendChild(selectdefaultcombo),
                  new ptd().html(defaultengine)
              ]);
              variantenginetable.appendChild(tr);
          });
          this.maindiv.appendChilds([
              variantenginetable
          ]);
          return this.maindiv;
      };
      return Setup;
  }());
  var Config;
  (function (Config) {
      Config.GuiConfig = new DomConfig().
          add("CONTROL_BUTTON_WIDTH", new SizePx(24)).
          add("PADDING", new SizePx(3)).
          add("CONTROL_BUTTON_PADDING_LEFT", new SizePx(3));
  })(Config || (Config = {}));
  var GUIState = /** @class */ (function () {
      function GUIState() {
          this.variant = localStorage.getItem("guistate_variant");
      }
      GUIState.prototype.variantid = function () {
          return "guistate_variant";
      };
      GUIState.prototype.pgnid = function () {
          return "guistate_" + this._variant + "_pgn";
      };
      Object.defineProperty(GUIState.prototype, "variant", {
          set: function (variant) {
              this._variant = variant;
              localStorage.setItem(this.variantid(), variant);
              this.pgn = localStorage.getItem(this.pgnid());
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(GUIState.prototype, "pgn", {
          set: function (pgn) {
              this._pgn = pgn;
              localStorage.setItem(this.pgnid(), pgn);
          },
          enumerable: true,
          configurable: true
      });
      GUIState.prototype.hasVariant = function () {
          return ((this._variant != undefined) && (this._variant != null) && (this._variant != "null"));
      };
      GUIState.prototype.hasPgn = function () {
          return ((this._pgn != undefined) && (this._pgn != null) && (this._pgn != "null"));
      };
      return GUIState;
  }());
  var GUI = /** @class */ (function () {
      function GUI() {
          this.config = Config.GuiConfig;
          this.LABEL_BCOL = "#efefef";
          this.book = null;
          this.bracket = null;
          this.players = new LichessUsers();
          this.setup = new Setup();
          this.appconfig = {};
          this.state = new GUIState();
          this.doAtomicBook = false;
          this.startupdone = false;
          this.evals = {};
          this.bracketjsonasset = new TextAsset("bracket.json");
          this.oldtabid = null;
          this.rndon = false;
          this.trainon = false;
          this.moveonceon = false;
          this.gameonceon = false;
          this.root = new HTMLDivElement_().position("relative");
          this.dialogroot = new HTMLDivElement_();
          document.body.appendChild(this.root.e);
      }
      GUI.prototype.log = function (li) {
          this.logger.log(li);
          //let text="<pre>"+this.logger.reportText()+"</pre>"        
          var html = this.logger.reportHtml();
          this.tabs.getTabDivById("log").fontFamily("monospace");
          this.tabs.setContent("log", html);
      };
      GUI.prototype.nlog = function (li) {
          this.nlogger.log(li);
          var html = this.nlogger.reportHtml();
          this.neurallogdiv.html(html);
      };
      GUI.prototype.logstr = function (str) {
          this.log(new Misc.Logitem(str));
      };
      // create elements
      GUI.prototype.createEngineControlPanel = function () {
          this.econtrolpanel = new HTMLDivElement_();
          var startenginebutton = new HTMLButtonElement_().
              value(">").
              onmousedown(this.startenginebuttonpressed.bind(this)).
              widthPx(this.config.getPx("CONTROL_BUTTON_WIDTH")).
              paddingLeftPx(this.config.getPx("CONTROL_BUTTON_PADDING_LEFT"));
          var makeanalyzedmovebutton = new HTMLButtonElement_().
              value("*").
              onmousedown(this.makeanalyzedmovebuttonpressed.bind(this, false)).
              widthPx(this.config.getPx("CONTROL_BUTTON_WIDTH")).
              paddingLeftPx(this.config.getPx("CONTROL_BUTTON_PADDING_LEFT"));
          var makeandstoreanalyzedmovebutton = new HTMLButtonElement_().
              value("*!").
              onmousedown(this.makeanalyzedmovebuttonpressed.bind(this, true)).
              widthPx(this.config.getPx("CONTROL_BUTTON_WIDTH")).
              paddingLeftPx(this.config.getPx("CONTROL_BUTTON_PADDING_LEFT"));
          var stopenginebutton = new HTMLButtonElement_().
              value("_").
              onmousedown(this.stopenginebuttonpressed.bind(this)).
              widthPx(this.config.getPx("CONTROL_BUTTON_WIDTH")).
              paddingLeftPx(this.config.getPx("CONTROL_BUTTON_PADDING_LEFT"));
          var restartenginebutton = new HTMLButtonElement_().
              value("!").
              onmousedown(this.restartenginebuttonpressed.bind(this)).
              widthPx(this.config.getPx("CONTROL_BUTTON_WIDTH")).
              paddingLeftPx(this.config.getPx("CONTROL_BUTTON_PADDING_LEFT"));
          var connectenginebutton = new HTMLButtonElement_().
              value("Connect").
              onmousedown(this.connectenginebuttonpressed.bind(this));
          var rndbutton = new HTMLButtonElement_().
              value("Rnd").
              onmousedown(this.rndbuttonpressed.bind(this));
          var anchorbutton = new HTMLButtonElement_().
              value("A").
              onmousedown(this.anchorbuttonpressed.bind(this));
          var restorebutton = new HTMLButtonElement_().
              value("<-").
              onmousedown(this.restorebuttonpressed.bind(this));
          this.pastetext = new HTMLInputElement_();
          this.pastetext.widthPx(40);
          this.econtrolpanel.appendChilds([
              startenginebutton,
              makeanalyzedmovebutton,
              makeandstoreanalyzedmovebutton,
              stopenginebutton,
              restartenginebutton,
              connectenginebutton,
              rndbutton,
              anchorbutton,
              restorebutton,
              this.pastetext
          ]);
      };
      GUI.prototype.createControlPanel = function () {
          this.controlpanel = new HTMLDivElement_();
          this.variantcombo = new ComboBox_().
              setOptions(Config.variantToDisplayName).
              setSelected(this.state.hasVariant() ? this.state._variant : "standard").
              onChange(this.variantChanged.bind(this));
          var flipbutton = new HTMLButtonElement_().
              value("F").
              onmousedown(this.flipbuttonpressed.bind(this)).
              widthPx(this.config.getPx("CONTROL_BUTTON_WIDTH"));
          var resetbutton = new HTMLButtonElement_().
              value("R").
              onmousedown(this.resetbuttonpressed.bind(this)).
              widthPx(this.config.getPx("CONTROL_BUTTON_WIDTH"));
          var tobeginbutton = new HTMLButtonElement_().
              value("|<").
              onmousedown(this.tobeginbuttonpressed.bind(this)).
              widthPx(this.config.getPx("CONTROL_BUTTON_WIDTH")).
              paddingLeftPx(this.config.getPx("CONTROL_BUTTON_PADDING_LEFT"));
          var backbutton = new HTMLButtonElement_().
              value("<").
              onmousedown(this.backbuttonpressed.bind(this)).
              widthPx(this.config.getPx("CONTROL_BUTTON_WIDTH")).
              paddingLeftPx(this.config.getPx("CONTROL_BUTTON_PADDING_LEFT"));
          var forwardbutton = new HTMLButtonElement_().
              value(">").
              onmousedown(this.forwardbuttonpressed.bind(this)).
              widthPx(this.config.getPx("CONTROL_BUTTON_WIDTH"));
          var toendbutton = new HTMLButtonElement_().
              value(">|").
              onmousedown(this.toendbuttonpressed.bind(this)).
              widthPx(this.config.getPx("CONTROL_BUTTON_WIDTH")).
              paddingLeftPx(this.config.getPx("CONTROL_BUTTON_PADDING_LEFT"));
          var deletebutton = new HTMLButtonElement_().
              value("X").
              onmousedown(this.deletebuttonpressed.bind(this)).
              widthPx(this.config.getPx("CONTROL_BUTTON_WIDTH")).
              paddingLeftPx(this.config.getPx("CONTROL_BUTTON_PADDING_LEFT"));
          this.saninputtext = new HTMLInputElement_();
          this.saninputtext.widthPx(50);
          var makesanbutton = new HTMLButtonElement_().
              value("M").
              onmousedown(this.makesanbuttonpressed.bind(this));
          var setfromfenbutton = new HTMLButtonElement_().
              value("F").
              onmousedown(this.setfromfenbuttonpressed.bind(this));
          var setfrompgnbutton = new HTMLButtonElement_().
              value("P").
              onmousedown(this.setfrompgnbuttonpressed.bind(this));
          this.controlpanel.appendChilds([
              this.variantcombo,
              flipbutton,
              resetbutton,
              tobeginbutton,
              backbutton,
              forwardbutton,
              toendbutton,
              deletebutton,
              this.saninputtext,
              makesanbutton,
              setfromfenbutton,
              setfrompgnbutton
          ]);
      };
      GUI.prototype.createTabs = function () {
          this.tabs = new TabPane_("tabs", Config.PREFERRED_TAB_SIZE, Config.TOTAL_BOARD_HEIGHT, [
              new Tab("pgn", "Pgn"),
              new Tab("book", "Book"),
              new Tab("neural", "Neural"),
              new Tab("moves", "Moves"),
              new Tab("engine", "Engine"),
              new Tab("game", "Game"),
              new Tab("bracket", "Bracket"),
              new Tab("players", "Players"),
              new Tab("setup", "Setup"),
              new Tab("config", "Config"),
              new Tab("src", "Src"),
              new Tab("log", "Log")
          ]);
          this.createPgnDiv();
          this.tabs.setElement_("pgn", this.pgndiv);
          this.createEngineDiv();
          this.tabs.setElement_("engine", this.enginediv);
          this.createBookDiv();
          this.tabs.setElement_("book", this.bookdiv);
          this.createNcontrolDiv();
          this.tabs.setElement_("neural", this.ncontroldiv);
          this.createGameDiv();
          this.tabs.setElement_("game", this.gamediv);
          this.tabs.setElement_("players", this.players.createElement());
          this.tabs.setElement_("setup", this.setup.createElement());
          this.createConfigDiv();
          this.tabs.setElement_("config", this.configdiv);
          this.createBracketDiv();
          this.tabs.setElement_("bracket", this.bracketdiv);
          this.createSrcDiv();
          this.tabs.setElement_("src", this.srcdiv);
      };
      GUI.prototype.createEngineDiv = function () {
          this.enginediv = new HTMLDivElement_;
          this.enginediv.fontFamily("monospace");
      };
      GUI.prototype.createPgnDiv = function () {
          this.pgndiv = new HTMLDivElement_;
          this.pgntext = new HTMLTextAreaElement_();
          this.pgntext.
              widthPx(Config.PREFERRED_TAB_SIZE - 25).
              heightPx(Config.TOTAL_BOARD_HEIGHT - 65);
          this.pgnkeytext = new HTMLInputElement_;
          this.pgnvaluetext = new HTMLInputElement_;
          this.pgnvaluetext.widthPx(465);
          var pgneditbutton = new HTMLButtonElement_().
              value("Edit").
              onmousedown(this.pgneditbuttonpressed.bind(this));
          this.pgndiv.appendChild(new HTMLLabelElement_().setText("Header name:").
              backgroundColor(this.LABEL_BCOL).
              paddingPx(this.config.getPx("PADDING")));
          this.pgndiv.appendChild(this.pgnkeytext);
          this.pgndiv.appendChild(new HTMLLabelElement_().setText("Header value:").
              backgroundColor(this.LABEL_BCOL).
              paddingPx(this.config.getPx("PADDING")));
          this.pgndiv.appendChild(this.pgnvaluetext);
          this.pgndiv.appendChild(pgneditbutton);
          this.pgndiv.appendChild(this.pgntext);
      };
      GUI.prototype.appConfigText = function () {
          return JSON.stringify(this.appconfig, null, 1);
      };
      GUI.prototype.createConfigDiv = function () {
          var stored = localStorage.getItem("appconfig");
          if (Misc.isDefined(stored)) {
              this.appconfig = JSON.parse(stored);
          }
          this.appconfig = Misc.updateObjectWith(this.appconfig, Config.appConfig);
          this.configdiv = new HTMLDivElement_();
          this.configtext = new HTMLTextAreaElement_().setText(this.appConfigText());
          this.configtext.
              widthPx(Config.PREFERRED_TAB_SIZE - 25).
              heightPx(Config.TOTAL_BOARD_HEIGHT - 65);
          var configapplybutton = new HTMLButtonElement_().
              value("Apply").
              onmousedown(this.configapplybuttonpressed.bind(this));
          this.configdiv.appendChilds([
              configapplybutton,
              this.configtext
          ]);
      };
      GUI.prototype.createBookDiv = function () {
          this.bookdiv = new HTMLDivElement_();
          var addmovebutton = new HTMLButtonElement_().
              value("+ M").
              onmousedown(this.addmovebuttonpressed.bind(this, false, false, null));
          var addmovebackbutton = new HTMLButtonElement_().
              value("+ M <").
              onmousedown(this.addmovebuttonpressed.bind(this, true, false, null));
          var delbookmovebutton = new HTMLButtonElement_().
              value("- M <").
              onmousedown(this.addmovebuttonpressed.bind(this, true, true, null));
          var delallmovesbutton = new HTMLButtonElement_().
              value("- P").
              onmousedown(this.delallmovesbuttonpressed.bind(this));
          var exportbookbutton = new HTMLButtonElement_().
              value("Export").
              onmousedown(this.exportbookbuttonpressed.bind(this));
          var importbookbutton = new HTMLButtonElement_().
              value("Import").
              onmousedown(this.importbookbuttonpressed.bind(this));
          var filechooser = new FileChooser("bookfilechooser_" + this.state._variant, this.dialogroot).
              setSaveCallback(this.savebookcallback.bind(this)).
              setLoadCallback(this.loadbookcallback.bind(this)).
              build();
          this.bookdiv.appendChilds([
              addmovebutton,
              addmovebackbutton,
              delbookmovebutton,
              delallmovesbutton,
              exportbookbutton,
              importbookbutton,
              filechooser
          ]);
          this.bookcontentdiv = new HTMLDivElement_();
          this.bookdiv.appendChild(this.bookcontentdiv);
      };
      GUI.prototype.createNcontrolDiv = function () {
          this.ncontroldiv = new HTMLDivElement_();
          var issuelabel = new HTMLLabelElement_().setText("Enter neural command : ");
          this.nissuetext = new HTMLInputElement_();
          this.nissuetext.
              setEnterCallback(this.neuralissuebuttonpressed.bind(this)).
              widthPx(100);
          var neuralissuebutton = new HTMLButtonElement_().
              value("Issue").
              onmousedown(this.neuralissuebuttonpressed.bind(this));
          var moveoncebutton = new HTMLButtonElement_().
              value("Move once").
              onmousedown(this.moveonce.bind(this));
          var gameoncebutton = new HTMLButtonElement_().
              value("Game once").
              onmousedown(this.gameonce.bind(this));
          var trainbutton = new HTMLButtonElement_().
              value("Train").
              onmousedown(this.train.bind(this));
          var stoptrainbutton = new HTMLButtonElement_().
              value("Stop").
              onmousedown(this.stoptrain.bind(this));
          var testneuralbutton = new HTMLButtonElement_().
              value("Test").
              onmousedown(this.testneural.bind(this));
          var reloadneuralbutton = new HTMLButtonElement_().
              value("Reload").
              onmousedown(this.reloadneural.bind(this));
          this.neurallogdiv = new HTMLDivElement_().
              widthPx(Config.PREFERRED_TAB_SIZE - 35).
              heightPx(Config.TOTAL_BOARD_HEIGHT - 70).
              overflow("scroll").
              fontFamily("monospace").
              backgroundColor("#fef");
          this.ncontroldiv.appendChilds([
              issuelabel,
              this.nissuetext,
              neuralissuebutton,
              moveoncebutton,
              gameoncebutton,
              trainbutton,
              stoptrainbutton,
              testneuralbutton,
              reloadneuralbutton,
              this.neurallogdiv
          ]);
      };
      GUI.prototype.createGameDiv = function () {
          this.gamediv = new HTMLDivElement_();
          var gameidlabel = new HTMLLabelElement_().setText("Lichess game id : ");
          this.gameidtext = new HTMLInputElement_();
          this.gameidtext.widthPx(300);
          var gameloadbutton = new HTMLButtonElement_().
              value("Load").
              onmousedown(this.gameloadbuttonpressed.bind(this));
          this.gamediv.appendChilds([
              gameidlabel,
              this.gameidtext,
              gameloadbutton
          ]);
      };
      GUI.prototype.createBracketDiv = function () {
          this.bracketdiv = new HTMLDivElement_();
      };
      GUI.prototype.createSrcDiv = function () {
          this.srcdiv = new HTMLDivElement_;
          this.srctext = new HTMLTextAreaElement_();
          this.srctext.
              widthPx(Config.PREFERRED_TAB_SIZE - 25).
              heightPx(Config.TOTAL_BOARD_HEIGHT - 45);
          this.srcdiv.appendChild(this.srctext);
      };
      GUI.prototype.draw = function () {
          //////////////////////////////////////////////////////////
          var _this = this;
          this.root.html("");
          //////////////////////////////////////////////////////////
          this.logger = new Misc.Logger();
          this.nlogger = new Misc.Logger();
          //////////////////////////////////////////////////////////
          this.root.
              html("");
          //////////////////////////////////////////////////////////
          // table
          var table = new HTMLTableElement_().
              borderCollapse("separate").
              borderSpacingPx(6).
              borderPx(3).
              borderStyle("solid").
              borderColor("#dfdfdf").
              marginPx(5).
              backgroundColor("#efefef");
          var tr1 = new HTMLTableRowElement_();
          var tr2 = new HTMLTableRowElement_();
          var tr3 = new HTMLTableRowElement_();
          table.appendChilds([tr1, tr2, tr3]);
          var td11 = new HTMLTableColElement_();
          var td12 = new HTMLTableColElement_().verticalAlign("top");
          tr1.appendChilds([td11, td12]);
          var td21 = new HTMLTableColElement_();
          var td22 = new HTMLTableColElement_();
          tr2.appendChilds([td21, td22]);
          var td31 = new HTMLTableColElement_();
          tr3.appendChilds([td31]);
          //////////////////////////////////////////////////////////
          this.wboardroot = new HTMLDivElement_();
          td11.appendChild(this.wboardroot);
          this.createTabs();
          td12.appendChild(this.tabs);
          this.createControlPanel();
          td21.appendChild(this.controlpanel);
          this.fentext = new HTMLInputElement_();
          this.fentext.widthPx(Config.PREFERRED_TAB_SIZE).fontFamily("monospace");
          td22.appendChild(this.fentext);
          this.createEngineControlPanel();
          td31.appendChild(this.econtrolpanel);
          //////////////////////////////////////////////////////////
          this.analyzer = new Analysis.Analyzer();
          this.analyzer.log = this.log.bind(this);
          //////////////////////////////////////////////////////////
          this.bracket = new Bracket();
          this.bracket.load();
          //////////////////////////////////////////////////////////
          this.loadEvals();
          //////////////////////////////////////////////////////////
          setTimeout((function (e) {
              wboard.setRoot(gui.wboardroot);
              _this.setVariant();
              wboard.draw();
              _this.bracketdiv.appendChild(_this.bracket.createElement());
              _this.root.appendChild(table);
              _this.root.appendChild(_this.dialogroot);
              Globals.log = _this.log.bind(_this);
              if (!_this.startupdone) {
                  _this.startupdone = true;
                  new AssetLoader().
                      add(Globals.startup).
                      setcallback(_this.doStartup.bind(_this)).
                      load();
              }
              setTimeout(_this.systemWatch.bind(_this), 1000);
          }).bind(this), 0);
          //////////////////////////////////////////////////////////
      };
      GUI.prototype.systemWatch = function (e) {
          var pastetext = this.pastetext.getText();
          if (pastetext != "") {
              this.pastetext.setText("");
              this.loadLichessGameById(pastetext);
          }
          setTimeout(this.systemWatch.bind(this), 1000);
      };
      GUI.prototype.brackeJsonLoaded = function () {
          this.bracket.hidecontrols = true;
          this.bracket.editmode = false;
          this.bracket.load(this.bracketjsonasset.text);
      };
      GUI.prototype.doStartup = function () {
          try {
              this.startup = Globals.startup.asJson();
          }
          catch (e) {
              console.log("info: no special startup instructions were detected");
              return;
          }
          var su = this.startup;
          if (Misc.isDefined(su.selectedTab)) {
              this.tabs.setSelected(su.selectedTab);
          }
          if (Misc.isDefined(su.setBracketJson)) {
              if (su.setBracketJson) {
                  new AssetLoader().
                      add(this.bracketjsonasset).
                      setcallback(this.brackeJsonLoaded.bind(this)).
                      load();
              }
          }
          if (Misc.isDefined(su.atomicbook)) {
              console.log("atomicbook detected", su.atomicbook);
              this.doAtomicBook = true;
              this.tabs.setSelected("book");
              Globals.wboard.showBookPage();
          }
      };
      GUI.prototype.startDefaultEngine = function () {
          var defaultengine = this.setup.defaultengines[this.state._variant];
          if (defaultengine != "[None]") {
              this.analyzer.startengine(defaultengine);
          }
      };
      GUI.prototype.setVariant = function (variant) {
          if (variant === void 0) { variant = this.state._variant; }
          if (!Misc.isDefined(variant))
              variant = "standard";
          if (!Config.isSupportedVariant(variant))
              return false;
          this.analyzer.stopanalysis();
          this.variantcombo.setSelected(variant);
          this.state.variant = variant;
          Globals.wboard.dosetVariant(variant, false);
          if (this.state.hasPgn()) {
              Globals.wboard.dosetFromPgn(this.state._pgn);
          }
          this.book = new Book(this.state._variant, "default");
          Globals.wboard.draw();
          this.startDefaultEngine();
          this.createBookDiv();
          this.tabs.setElement_("book", this.bookdiv);
          return true;
      };
      GUI.prototype.variantChanged = function (e) {
          var t = e.target;
          var variant = t.selectedOptions[0].value;
          this.setVariant(variant);
      };
      GUI.prototype.flipbuttonpressed = function (e) {
          Globals.wboard.doflip();
      };
      GUI.prototype.resetbuttonpressed = function (e) {
          Globals.wboard.doreset();
      };
      GUI.prototype.tobeginbuttonpressed = function (e) {
          Globals.wboard.dotobegin();
      };
      GUI.prototype.backbuttonpressed = function (e) {
          Globals.wboard.doback();
      };
      GUI.prototype.forwardbuttonpressed = function (e) {
          Globals.wboard.doforward();
      };
      GUI.prototype.toendbuttonpressed = function (e) {
          Globals.wboard.dotoend();
      };
      GUI.prototype.deletebuttonpressed = function (e) {
          Globals.wboard.dodelete();
      };
      GUI.prototype.makesanbuttonpressed = function (e) {
          var san = this.saninputtext.getText();
          this.saninputtext.setText("");
          Globals.wboard.domakeSanMove(san);
      };
      GUI.prototype.setfromfenbuttonpressed = function (e) {
          var fen = this.fentext.getText();
          Globals.wboard.dosetFromFen(fen);
      };
      GUI.prototype.setfrompgnbuttonpressed = function (e) {
          var pgn = this.pgntext.getText();
          Globals.wboard.dosetFromPgn(pgn);
      };
      GUI.prototype.pgneditbuttonpressed = function (e) {
          var key = this.pgnkeytext.getText();
          this.pgnkeytext.setText("");
          var value = this.pgnvaluetext.getText();
          this.pgnvaluetext.setText("");
          Globals.wboard.doeditPgn(key, value);
      };
      GUI.prototype.startenginebuttonpressed = function (e) {
          this.oldtabid = this.tabs.selid;
          this.analyzer.analyze();
      };
      GUI.prototype.positionChanged = function () {
          if (this.analyzer.enginerunning) {
              this.analyzer.stopanalysis();
              this.analyzer.analyze();
          }
      };
      GUI.prototype.makeanalyzedmovebuttonpressed = function (store, e) {
          this.analyzer.makeanalyzedmove();
          if (store) {
              this.addmovebuttonpressed.bind(this, false, false, "!")();
          }
          this.positionChanged();
      };
      GUI.prototype.stopenginebuttonpressed = function (e) {
          this.analyzer.stopanalysis();
          if (this.oldtabid != null)
              Globals.gui.tabs.setSelected(this.oldtabid);
      };
      GUI.prototype.restartenginebuttonpressed = function (e) {
          this.startDefaultEngine();
      };
      GUI.prototype.connectenginebuttonpressed = function (e) {
          this.analyzer.connect();
      };
      GUI.prototype.addmovebuttonpressed = function (back, del, annotkey, e) {
          var san = Globals.wboard.reportLastMoveSan();
          if (san != "") {
              if (back)
                  Globals.wboard.doback();
              else
                  Globals.wboard.back();
              var fen = Globals.wboard.reportFen();
              if (!back)
                  Globals.wboard.forward();
              var pos = this.book.getPosition(fen);
              var move = pos.getMove(san);
              if (annotkey != null)
                  move.setAnnot(BookUtils.annotations[annotkey]);
              if (del)
                  pos.delMove(san);
              this.book.store();
              Globals.wboard.draw();
          }
      };
      GUI.prototype.delallmovesbuttonpressed = function (e) {
          var fen = Globals.wboard.reportFen();
          this.book.delPosition(fen);
          this.book.store();
          Globals.wboard.draw();
      };
      GUI.prototype.importbookbuttonpressed = function (e) {
          var src = this.srctext.getText();
          this.book.fromJsonText(src);
          this.book.store();
          Globals.wboard.showBookPage();
      };
      GUI.prototype.exportbookbuttonpressed = function (e) {
          this.srctext.setText(this.book.src());
          this.tabs.setSelected("src");
      };
      GUI.prototype.makerandom = function () {
          if (this.rndon) {
              if (Globals.wboard.makeRandomMove())
                  setTimeout(this.makerandom.bind(this), 100);
              else
                  this.rndon = false;
          }
      };
      GUI.prototype.rndbuttonpressed = function (e) {
          if (this.rndon) {
              this.rndon = false;
          }
          else {
              this.rndon = true;
              this.makerandom();
          }
      };
      GUI.prototype.anchorbuttonpressed = function (e) {
          Globals.wboard.latestpgn = Globals.wboard.reportPgn();
      };
      GUI.prototype.restorebuttonpressed = function (e) {
          Globals.wboard.dosetFromPgn(Globals.wboard.latestpgn);
      };
      GUI.prototype.ongameload = function (lg) {
          var _this = this;
          this.log(lg.okLogitem());
          var variant = lg.getHeader("GameVariant");
          if (!this.setVariant(variant)) {
              this.log(new Misc.Logitem("error setting up game: unsupported variant " + variant).error());
              return;
          }
          var moves = lg.moves;
          this.logstr(moves);
          Globals.wboard.setFromPgn(moves);
          for (var key in lg.pgnHeaders) {
              var value = lg.getHeader(key);
              Globals.wboard.editPgn(key, value);
          }
          Globals.wboard.setUpGame();
          Globals.wboard.draw();
          this.pastetext.blur();
          this.tabs.setSelected("pgn");
          var ogl = this.appconfig.onGameLoad;
          var fw = ogl.forwardMoves;
          if (fw) {
              for (var i = 0; i < fw; i++)
                  Globals.wboard.doforward();
          }
          if (ogl.autoStartEngine) {
              setTimeout(function (e) { return _this.analyzer.analyze(); }, ogl.autoStartEngineTimeout);
          }
      };
      GUI.prototype.gameloaderror = function (lg) {
          this.log(lg.errorLogitem());
          var storedlg = this.bracket.lichessgameregistry[lg.gameid];
          if (storedlg != undefined) {
              this.log(lg.localAvailableLogitem());
              this.ongameload(storedlg);
          }
      };
      GUI.prototype.loadLichessGameById = function (gameid) {
          var lg = new LichessGame(gameid);
          this.tabs.setSelected("log");
          this.log(lg.infoLogitem());
          lg.loadThen(this.ongameload.bind(this, lg), this.gameloaderror.bind(this, lg));
      };
      GUI.prototype.gameloadbuttonpressed = function (e) {
          var gameid = this.gameidtext.getText();
          this.gameidtext.setText("");
          this.loadLichessGameById(gameid);
      };
      GUI.prototype.savebookcallback = function (fcstate) {
          var fullpath = fcstate.fullpath();
          var src = this.book.src();
          var ajaxasset = new AjaxAsset({
              action: "writetextfile",
              path: fullpath,
              content: src
          });
          new AssetLoader().
              add(ajaxasset).
              load();
      };
      GUI.prototype.bookloadedcallback = function (ajaxasset) {
          var result = ajaxasset.resjson;
          if (!result.error) {
              this.srctext.setText(result.content);
              this.tabs.setSelected("src");
          }
      };
      GUI.prototype.loadbookcallback = function (fcstate) {
          var fullpath = fcstate.fullpath();
          var ajaxasset = new AjaxAsset({
              action: "readtextfile",
              path: fullpath
          });
          new AssetLoader().
              add(ajaxasset).
              setcallback(this.bookloadedcallback.bind(this, ajaxasset)).
              load();
      };
      GUI.prototype.configapplybuttonpressed = function (e) {
          var jsontext = this.configtext.getText();
          try {
              this.appconfig = JSON.parse(jsontext);
              localStorage.setItem("appconfig", jsontext);
              this.createConfigDiv();
              this.tabs.setElement_("config", this.configdiv);
          }
          catch (e) {
          }
      };
      GUI.prototype.neuralissuebuttonpressed = function (e) {
          var command = this.nissuetext.getText();
          this.nissuetext.setText("");
          this.analyzer.issueneural(command);
      };
      GUI.prototype.sendfens = function (e) {
          var fens = Globals.wboard.legalFens();
          if (fens.length < 1)
              return false;
          var json = { action: "playmove", fens: fens };
          var jsonstr = JSON.stringify(json);
          this.analyzer.issueneural(jsonstr);
          return true;
      };
      GUI.prototype.maketrainmove = function () {
          this.analyzer.stopanalysis();
          var evals = this.getEvals();
          var fen = Globals.wboard.reportFen();
          var to = this.analyzer.thinkingoutput;
          var score = to.scoreNumerical();
          var san = this.analyzer.makeanalyzedmove();
          evals[fen] = {
              san: san,
              score: score,
              depth: to.depth
          };
          if (!this.trainon)
              return;
          if (!this.sendfens(null)) {
              if (this.gameonceon || this.moveonceon) {
                  this.gameonceon = false;
                  this.moveonceon = false;
                  this.stoptrain(null);
              }
              else {
                  this.saveEvals();
                  setTimeout(this.train.bind(this, null), 1000);
              }
          }
      };
      GUI.prototype.starttrainmove = function () {
          if (!this.trainon)
              return;
          this.analyzer.analyze(false);
          setTimeout(this.maketrainmove.bind(this), 500);
      };
      GUI.prototype.train = function (e) {
          Globals.wboard.doreset();
          this.trainon = true;
          this.starttrainmove();
      };
      GUI.prototype.stoptrain = function (e) {
          this.trainon = false;
          this.saveEvals();
      };
      GUI.prototype.makeneuralsan = function (json) {
          var san = json.san;
          Globals.wboard.domakeSanMove(san);
          if (this.moveonceon) {
              this.moveonceon = false;
              this.stoptrain(null);
          }
          else {
              this.analyzer.waitbestmove(this.starttrainmove.bind(this));
          }
      };
      GUI.prototype.evalsLoaded = function () {
          var res = this.evalsasset.resjson;
          if (!res.error) {
              try {
                  this.evals = JSON.parse(res.content);
              }
              catch (err) {
                  console.log("could not parse evals");
              }
              for (var fen in this.evals) {
                  if (fen.lastIndexOf(" b") > 0) {
                      delete this.evals[fen];
                  }
              }
          }
      };
      GUI.prototype.loadEvals = function () {
          this.evalsasset = new AjaxAsset({
              action: "readtextfile",
              path: "evals.json"
          });
          new AssetLoader().
              add(this.evalsasset).
              setcallback(this.evalsLoaded.bind(this)).
              load();
      };
      GUI.prototype.getEvals = function () {
          if (this.evals == undefined)
              this.evals = {};
          return this.evals;
      };
      GUI.prototype.saveEvalsDone = function () {
          this.analyzer.issueneural(JSON.stringify({
              action: "epoch",
              n: 3
          }));
      };
      GUI.prototype.saveEvals = function () {
          var saveevalsasset = new AjaxAsset({
              action: "writetextfile",
              path: "evals.json",
              content: JSON.stringify(this.evals, null, 1)
          });
          new AssetLoader().
              add(saveevalsasset).
              setcallback(this.saveEvalsDone.bind(this)).
              load();
      };
      GUI.prototype.moveonce = function (e) {
          this.trainon = true;
          this.moveonceon = true;
          this.starttrainmove();
      };
      GUI.prototype.gameonce = function (e) {
          this.trainon = true;
          this.gameonceon = true;
          this.train(null);
      };
      GUI.prototype.testneural = function (e) {
          this.analyzer.issueneuralJson({ action: "test" });
      };
      GUI.prototype.reloadneural = function (e) {
          this.analyzer.issueneural("reloadneural");
      };
      return GUI;
  }());
  var wBoard = /** @class */ (function (_super) {
      __extends(wBoard, _super);
      function wBoard() {
          var _this = _super.call(this, "assets/wasm/wboard/wboard.wasm", {
              "setTempRet0": function (x) { },
              "getTempRet0": function (x) { },
              "_i64Add": function (x) { }
          }) || this;
          _this.isready = false;
          _this.latestpgn = null;
          _this.infodivs = [new HTMLDivElement_(), new HTMLDivElement_()];
          _this.flip = 0;
          _this.importObject.env["_conslog"] = function () {
              if (Globals.gui.logger == undefined) {
                  //console.log(this.logbuff.toString())
              }
              else {
                  Globals.gui.log(new Misc.Logitem(_this.logbuff.toString()));
              }
          };
          return _this;
      }
      wBoard.prototype.MARGIN = function () { return Config.PREFERRED_BOARD_SIZE / 50; };
      wBoard.prototype.SQUARE_SIZE = function () { return (Config.PREFERRED_BOARD_SIZE - 2 * this.MARGIN()) / this.getNumFiles(); };
      wBoard.prototype.SQUARE_PADDING = function () { return this.SQUARE_SIZE() / 10; };
      wBoard.prototype.PIECE_SIZE = function () { return this.SQUARE_SIZE() - 2 * this.SQUARE_PADDING(); };
      wBoard.prototype.onload = function () {
          this.logbuff = this.memview(this.exports._logbuffaddr(), this.exports._logbuffsize());
          this.inbuff = this.memview(this.exports._inbuffaddr(), this.exports._inbuffsize());
          this.inbuff2 = this.memview(this.exports._inbuff2addr(), this.exports._inbuffsize());
          this.outbuff = this.memview(this.exports._outbuffaddr(), this.exports._outbuffsize());
          this.exports._initModule();
          this.setVariant("standard");
          this.isready = true;
      };
      wBoard.prototype.setRoot = function (root) {
          this.root = root;
      };
      wBoard.prototype.load = function () {
          this.fetchThen(this.onload.bind(this));
      };
      wBoard.prototype.ready = function () {
          return this.isready;
      };
      wBoard.prototype.setFromRawFen = function (rawfen) {
          this.inbuff.strCpy(rawfen);
          this.exports._setFromRawFenMain();
      };
      wBoard.prototype.reportBoardRep = function () {
          this.exports._reportBoardRepMain();
          return this.outbuff.toString();
      };
      wBoard.prototype.getNumFiles = function () {
          return this.exports._getNumFiles();
      };
      wBoard.prototype.getNumRanks = function () {
          return this.exports._getNumRanks();
      };
      wBoard.prototype.createRegistries = function () {
          this.exports._createRegistries();
      };
      wBoard.prototype.reset = function () {
          this.exports._resetMain();
      };
      wBoard.prototype.doreset = function () {
          Globals.gui.analyzer.stopanalysis();
          this.reset();
          this.draw();
      };
      wBoard.prototype.initVariant = function (variant) {
          var vc = Config.variantToVariantCode[variant];
          this.exports._initVariant(vc);
      };
      wBoard.prototype.initVariantManual = function (variant) {
          var rawfen = Config.startRawFens[variant];
          var vc = Config.variantToVariantCode[variant];
          this.exports._setVariant(vc);
          this.setFromRawFen(rawfen);
          this.createRegistries();
          this.reset();
      };
      wBoard.prototype.setVariant = function (variant) {
          this.initVariant(variant);
          //this.initVariantManual(variant)                
          this.flip = 0;
      };
      wBoard.prototype.dosetVariant = function (variant, storepgn) {
          if (storepgn === void 0) { storepgn = true; }
          this.setVariant(variant);
          this.draw(storepgn);
      };
      wBoard.prototype.reportBoardState = function () {
          this.exports._reportBoardState();
          return this.outbuff.toString();
      };
      wBoard.prototype.getLastRank = function () { return this.getNumRanks() - 1; };
      wBoard.prototype.getLastFile = function () { return this.getNumFiles() - 1; };
      wBoard.prototype.rotateSquare = function (sq, rot) {
          if (rot == 0) {
              return sq;
          }
          if (rot < 0) {
              rot = 4 + rot;
          }
          if (rot == 1) {
              return new Vectors.Square(this.getLastRank() - sq.rank, sq.file);
          }
          if (rot == 2) {
              return new Vectors.Square(this.getLastFile() - sq.file, this.getLastRank() - sq.rank);
          }
          return new Vectors.Square(sq.rank, this.getLastFile() - sq.file);
      };
      wBoard.prototype.sortedLegalSanList = function () {
          var t = new Misc.Timer("sorted legal sans", Globals.log);
          this.exports._sortedLegalSanListMain();
          //t.report()
          return this.outbuff.toString();
      };
      wBoard.prototype.sanclicked = function (san, e) {
          this.domakeSanMove(san);
      };
      wBoard.prototype.movecontent = function () {
          var _this = this;
          var mcdiv = new HTMLDivElement_().fontFamily("monospace");
          var sans = this.sortedLegalSanList().split("\n");
          sans.map(function (san) {
              var a = new HTMLAnchorElement_().
                  href("#").
                  html(san).
                  addEventListener("mousedown", _this.sanclicked.bind(_this, san));
              mcdiv.appendChild(a);
              mcdiv.appendChild(new HTMLBRElement_());
          });
          return mcdiv;
      };
      wBoard.prototype.reportFen = function () {
          this.exports._reportFenMain();
          return this.outbuff.toString();
      };
      wBoard.prototype.legalFens = function () {
          var _this = this;
          var sans = this.sortedLegalSanList().split("\n");
          if (sans[0] == "")
              return [];
          var fens = sans.map(function (san) {
              _this.makeSanMove(san);
              var result = { san: san, fen: _this.reportFen() };
              _this.back();
              return result;
          });
          return fens;
      };
      wBoard.prototype.setFromFen = function (fen) {
          this.inbuff.strCpy(fen);
          this.exports._setFromFenMain();
      };
      wBoard.prototype.dosetFromFen = function (fen) {
          this.setFromFen(fen);
          this.draw();
      };
      wBoard.prototype.reportPgn = function () {
          this.exports._reportPgnMain();
          return this.outbuff.toString();
      };
      wBoard.prototype.setFromPgn = function (pgn) {
          var t = new Misc.Timer("set from pgn", Globals.log);
          this.inbuff.strCpy(pgn);
          this.exports._setFromPgnMain();
          //t.report()
      };
      wBoard.prototype.makeRandomMove = function () {
          var sanlist = this.sortedLegalSanList();
          if (sanlist.length > 0) {
              var sans = sanlist.split("\n");
              var r = Math.floor(Math.random() * sans.length);
              if (r >= sans.length)
                  r = 0;
              this.makeSanMove(sans[r]);
              this.draw();
              return true;
          }
          return false;
      };
      wBoard.prototype.flipByHandle = function () {
          var appconfig = Globals.gui.appconfig;
          var handle = appconfig.handle;
          var white = this.getPgnHeader("White");
          var black = this.getPgnHeader("Black");
          if (handle != undefined) {
              if (Misc.roughlyEqualStrings(handle, white))
                  this.flip = 0;
              if (Misc.roughlyEqualStrings(handle, black))
                  this.flip = 2;
          }
      };
      wBoard.prototype.setUpGame = function () {
          this.latestpgn = this.reportPgn();
          this.flipByHandle();
      };
      wBoard.prototype.dosetFromPgn = function (pgn) {
          this.setFromPgn(pgn);
          this.setUpGame();
          this.draw();
          Globals.gui.positionChanged();
      };
      wBoard.prototype.isSquareValid = function (sq) {
          return this.exports._fileRankOkMain(sq.file, sq.rank) > 0;
      };
      wBoard.prototype.editPgn = function (key, value) {
          this.inbuff.strCpy(key);
          this.inbuff2.strCpy(value);
          this.exports._editPgn();
      };
      wBoard.prototype.getPgnHeader = function (key) {
          this.inbuff.strCpy(key);
          this.exports._getPgnHeader();
          return this.outbuff.toString();
      };
      wBoard.prototype.doeditPgn = function (key, value) {
          this.editPgn(key, value);
          this.draw();
      };
      wBoard.prototype.reportLastMove = function () {
          this.exports._reportLastMove();
          if (this.outbuff.view[0] == 0)
              return null;
          return new Vectors.Move(new Vectors.Square(this.outbuff.view[1], this.outbuff.view[2]), new Vectors.Square(this.outbuff.view[3], this.outbuff.view[4]));
      };
      wBoard.prototype.reportLastMoveSan = function () {
          this.exports._reportLastMoveSan();
          return this.outbuff.toString();
      };
      wBoard.prototype.drawMoveArrow = function (m, div, params) {
          if (div === void 0) { div = null; }
          if (params === void 0) { params = {}; }
          var fromsq = this.rotateSquare(m.fsq, this.flip);
          var tosq = this.rotateSquare(m.tsq, this.flip);
          var fromv = new Vectors.Vect(fromsq.file + 0.5, fromsq.rank + 0.5).s(this.SQUARE_SIZE());
          var tov = new Vectors.Vect(tosq.file + 0.5, tosq.rank + 0.5).s(this.SQUARE_SIZE());
          if (params["scale"] == undefined) {
              params["scale"] = 1.0;
          }
          if (params["constantwidth"] == undefined) {
              params["constantwidth"] = this.SQUARE_SIZE() / 7.5 * params["scale"];
          }
          var arrow = new Vectors.Arrow(fromv, tov, params);
          var adiv = (div == null ? new HTMLDivElement_() : div);
          adiv.
              position("absolute").
              topPx(arrow.svgorig.y).
              leftPx(arrow.svgorig.x).
              zIndexNumber(wBoard.ARROW_Z_INDEX).
              html(arrow.svg);
          if (div == null)
              this.boardcontainer.appendChild(adiv);
      };
      wBoard.prototype.letterToFile = function (letter) {
          return letter.charCodeAt(0) - "a".charCodeAt(0);
      };
      wBoard.prototype.algebToMove = function (algeb) {
          var letterparts = algeb.split(new RegExp("[0-9]+", "g"));
          var ff = this.letterToFile(letterparts[0]);
          var tf = this.letterToFile(letterparts[1]);
          var numranks = this.getNumRanks();
          var numberparts = algeb.split(new RegExp("[a-z]+", "g"));
          var fr = numranks - parseInt(numberparts[1]);
          var tr = numranks - parseInt(numberparts[2]);
          var promkind = "-";
          if (letterparts.length > 2)
              promkind = letterparts[2];
          var prompiece = new Vectors.Piece();
          prompiece.kind = promkind;
          return new Vectors.Move(new Vectors.Square(ff, fr), new Vectors.Square(tf, tr), prompiece);
      };
      wBoard.prototype.bookMoveClicked = function (san, e) {
          this.domakeSanMove(san);
      };
      wBoard.prototype.annotateMove = function (san, akey, e) {
          var bpos = Globals.gui.book.getPosition(this.reportFen());
          if (akey == "delete") {
              bpos.delMove(san);
          }
          else {
              var move = bpos.getMove(san);
              move.setAnnot(BookUtils.annotations[akey]);
          }
          Globals.gui.book.store();
          this.draw();
      };
      wBoard.prototype.tryFetchBookPage = function (fen, tfen, callback) {
          var _this = this;
          console.log("looking up page in database " + tfen);
          var ab = gui.startup.atomicbook;
          var apiurl = ab.databaseUrl + "/databases/" + ab.dbName + "/collections/" + ab.collName + "?q={\"tfen\":\"" + tfen + "\"}&apiKey=" + ab.databaseAccessToken;
          fetch(apiurl).then(function (response) { return response.text(); }).then(function (content) {
              try {
                  console.log("page loaded");
                  var json = JSON.parse(content);
                  var doc = json[0];
                  if (doc != undefined) {
                      var movestext = doc.movestext;
                      var moves = JSON.parse(movestext);
                      var pos = Globals.gui.book.getPosition(fen);
                      for (var san in moves) {
                          var ms = moves[san]["ms"];
                          var bm = pos.getMove(san);
                          bm.ms = ms;
                      }
                      _this.showBookPageInner();
                  }
                  else {
                      console.log("doc undefined");
                      callback();
                  }
              }
              catch (err) {
                  console.log(err);
                  callback();
              }
          });
      };
      wBoard.prototype.showBookPage = function () {
          var gui = Globals.gui;
          var book = gui.book;
          if (book == null)
              return;
          if (gui.doAtomicBook) {
              var fen_1 = this.reportFen();
              var tfen_1 = gui.book.truncfen(fen_1);
              this.tryFetchBookPage(fen_1, tfen_1, (function () {
                  var parts = tfen_1.split(" ");
                  parts[3] = "-";
                  var tfen2 = parts.join(" ");
                  console.log("retry");
                  this.tryFetchBookPage(fen_1, tfen2, (function () {
                      this.showBookPageInner();
                  }).bind(this));
              }).bind(this));
          }
          else {
              this.showBookPageInner();
          }
      };
      wBoard.prototype.showBookPageInner = function () {
          var pos = Globals.gui.book.getPosition(this.reportFen());
          var bcd = Globals.gui.bookcontentdiv;
          bcd.html("");
          var bt = new HTMLTableElement_();
          var sorted = pos.sortedSans();
          for (var sani in sorted) {
              var san = sorted[sani];
              var tr = new HTMLTableRowElement_();
              var bm = pos.getMove(san);
              var annot = bm.annot;
              var ms = bm.ms;
              var full = san + " " + annot.getAnnotStr();
              var a = new HTMLLabelElement_().
                  html(full).
                  fontSizePx(25).
                  cursor("pointer").
                  fontWeight(annot.empty() ? (gui.doAtomicBook ? "bold" : "normal") : "bold").
                  opacityNumber(annot.empty() ? (gui.doAtomicBook ? 1 : 0.5) : 1.0).
                  color(annot.color).
                  addEventListener("mousedown", this.bookMoveClicked.bind(this, san));
              tr.appendChild(new HTMLTableColElement_().
                  paddingPx(5).
                  widthPx(100).
                  appendChild(a));
              tr.appendChild(new HTMLTableColElement_().
                  paddingPx(5).
                  widthPx(100).
                  fontSizePx(22).
                  fontWeight("bold").
                  color(Misc.scoreColor(ms)).
                  appendChild(new HTMLDivElement_().html("" + ms)));
              var cspan = new HTMLSpanElement_().opacityNumber(0.8);
              for (var akey in BookUtils.annotations) {
                  var annot_1 = BookUtils.annotations[akey];
                  var ab_1 = new HTMLButtonElement_().
                      onmousedown(this.annotateMove.bind(this, san, akey)).
                      value(akey).
                      backgroundColor(annot_1.bcol);
                  cspan.appendChild(ab_1);
              }
              var ab = new HTMLButtonElement_().
                  onmousedown(this.annotateMove.bind(this, san, "delete")).
                  value("X").
                  backgroundColor("#ffefef");
              cspan.appendChild(ab);
              tr.appendChild(new HTMLTableColElement_().
                  verticalAlign("middle").
                  appendChild(cspan));
              bt.appendChild(tr);
          }
          bcd.appendChild(bt);
      };
      wBoard.prototype.trueIndexTwoPlayer = function (i) {
          return this.flip == 0 ? i : 1 - i;
      };
      wBoard.prototype.getPlayerNameByIndexTwoPlayer = function (i) {
          return this.getPgnHeader(i == 0 ? "Black" : "White");
      };
      wBoard.prototype.draw = function (storepgn) {
          if (storepgn === void 0) { storepgn = true; }
          var t = new Misc.Timer("wboard draw", Globals.log);
          //Globals.gui.log(new Misc.Logitem(this.reportBoardState()))                
          Globals.gui.fentext.setText(this.reportFen());
          var pgn = this.reportPgn();
          Globals.gui.pgntext.setText(pgn);
          if (storepgn)
              Globals.gui.state.pgn = pgn;
          Globals.gui.tabs.setElement_("moves", this.movecontent());
          this.root.html("");
          var numranks = this.getNumRanks();
          var numfiles = this.getNumFiles();
          var infoboardcontainer = new HTMLDivElement_().
              backgroundColor(wBoard.INFO_BCOL).
              widthPx(numfiles * this.SQUARE_SIZE() + 2 * this.MARGIN()).
              heightPx(numranks * this.SQUARE_SIZE() + 2 * this.MARGIN() + 2 * Config.BOARD_INFO_HEIGHT).
              position("relative");
          var outerboardcontainer = new HTMLDivElement_().
              background("url(assets/images/backgrounds/wood.jpg)").
              widthPx(numfiles * this.SQUARE_SIZE() + 2 * this.MARGIN()).
              heightPx(numranks * this.SQUARE_SIZE() + 2 * this.MARGIN()).
              topPx(Config.BOARD_INFO_HEIGHT).
              position("relative");
          var boardcontainer = new HTMLDivElement_().
              background("url(assets/images/backgrounds/wood.jpg)").
              widthPx(numfiles * this.SQUARE_SIZE()).
              heightPx(numranks * this.SQUARE_SIZE()).
              position("relative").
              leftPx(this.MARGIN()).
              topPx(this.MARGIN());
          var rep = this.reportBoardRep().split("");
          for (var r = 0; r < numranks; r++) {
              for (var f = 0; f < numfiles; f++) {
                  var sq = new Vectors.Square(f, r);
                  var rotsq = this.rotateSquare(sq, this.flip);
                  var index = (r * numfiles + f) * 2 + r;
                  var kind = rep[index];
                  var color = rep[index + 1];
                  if (this.isSquareValid(sq)) {
                      var sqdiv = new HTMLDivElement_().
                          position("absolute").
                          widthPx(this.SQUARE_SIZE()).
                          heightPx(this.SQUARE_SIZE()).
                          topPx(rotsq.rank * this.SQUARE_SIZE()).
                          leftPx(rotsq.file * this.SQUARE_SIZE()).
                          backgroundColor((f + r) % 2 == 0 ? wBoard.LIGHT_SQUARE_COLOR : wBoard.DARK_SQUARE_COLOR).
                          opacityNumber(wBoard.SQUARE_OPACITY).
                          zIndexNumber(wBoard.SQUARE_Z_INDEX);
                      boardcontainer.appendChild(sqdiv);
                  }
                  if (kind != "-") {
                      var svg = RawData.pieces[kind];
                      var colori = parseInt(color);
                      var fillcol = wBoard.PIECE_FILL_COLORS[colori];
                      var strokecol = wBoard.PIECE_STROKE_COLORS[colori];
                      svg = svg.replace("fill=\"#101010\"", "fill=\"" + fillcol + "\"");
                      svg = svg.replace("fill:#ececec", "fill:" + strokecol);
                      svg = svg.replace("stroke:#101010", "stroke:" + fillcol);
                      var pdiv = new HTMLDivElement_().
                          position("absolute").
                          widthPx(this.PIECE_SIZE()).
                          heightPx(this.PIECE_SIZE()).
                          topPx(rotsq.rank * this.SQUARE_SIZE() + this.SQUARE_PADDING()).
                          leftPx(rotsq.file * this.SQUARE_SIZE() + this.SQUARE_PADDING()).
                          zIndexNumber(wBoard.PIECE_Z_INDEX).
                          draggableBoolean(true).
                          html(svg);
                      pdiv.addEventListener("dragstart", this.piecedragstart.bind(this, sq, pdiv));
                      boardcontainer.appendChild(pdiv);
                  }
              }
          }
          boardcontainer.addEventListener("mousemove", this.boardmousemove.bind(this));
          boardcontainer.addEventListener("mouseup", this.boardmouseup.bind(this));
          outerboardcontainer.appendChild(boardcontainer);
          var scorediv = new HTMLDivElement_();
          boardcontainer.appendChild(scorediv);
          Globals.gui.analyzer.scorediv = scorediv;
          var depthdiv = new HTMLDivElement_();
          boardcontainer.appendChild(depthdiv);
          Globals.gui.analyzer.depthdiv = depthdiv;
          var enginearrow = new HTMLDivElement_();
          boardcontainer.appendChild(enginearrow);
          Globals.gui.analyzer.enginearrow = enginearrow;
          infoboardcontainer.appendChild(outerboardcontainer);
          this.root.appendChild(infoboardcontainer);
          this.boardcontainer = boardcontainer;
          var lastmove = this.reportLastMove();
          if (lastmove != null) {
              this.drawMoveArrow(lastmove);
          }
          this.dragz = wBoard.PIECE_Z_INDEX + 1;
          this.showBookPage();
          for (var i = 0; i < 2; i++) {
              var leftpx = wBoard.INFO_DIV_MARGIN;
              var toppx = i == 0 ?
                  wBoard.INFO_DIV_MARGIN
                  :
                      outerboardcontainer.getBottomPx() + wBoard.INFO_DIV_MARGIN;
              var widthpx = outerboardcontainer.getWidthPx() - 2 * wBoard.INFO_DIV_MARGIN;
              var heightpx = Config.BOARD_INFO_HEIGHT - 2 * wBoard.INFO_DIV_MARGIN;
              this.infodivs[i].
                  position("absolute").
                  topPx(toppx).
                  leftPx(leftpx).
                  widthPx(widthpx).
                  heightPx(heightpx).
                  backgroundColor(wBoard.INFO_DIV_BCOL).
                  html("");
              infoboardcontainer.appendChild(this.infodivs[i]);
              if (this.getNumPlayers() == 2) {
                  var playerlabel = new HTMLDivElement_().
                      html(this.getPlayerNameByIndexTwoPlayer(this.trueIndexTwoPlayer(i))).
                      fontSizePx(Config.BOARD_INFO_HEIGHT / 2).
                      marginLeftPx(10).
                      marginTopPx(5);
                  this.infodivs[i].appendChild(playerlabel);
              }
          }
          //t.report()        
      };
      wBoard.prototype.piecedragstart = function (sq, pdiv, e) {
          var me = e;
          me.preventDefault();
          this.draggedsq = sq;
          this.dragstart = new Vectors.ScreenVector(me.clientX, me.clientY);
          this.dragz += 1;
          this.draggedpdiv = pdiv;
          this.dragstartst = new Vectors.ScreenVector(pdiv.getLeftPx(), pdiv.getTopPx());
          this.dragunderway = true;
      };
      wBoard.prototype.boardmousemove = function (e) {
          var me = e;
          if (this.dragunderway) {
              var client = new Vectors.ScreenVector(me.clientX, me.clientY);
              this.dragd = client.Minus(this.dragstart);
              var nsv = this.dragstartst.Plus(this.dragd);
              this.draggedpdiv.
                  leftPx(nsv.x).
                  topPx(nsv.y).
                  zIndexNumber(this.dragz);
          }
      };
      wBoard.prototype.HALF_SQUARE_SIZE_SCREENVECTOR = function () { return new Vectors.ScreenVector(this.SQUARE_SIZE() / 2, this.SQUARE_SIZE() / 2); };
      wBoard.prototype.screenvectortosquare = function (sv) {
          var f = Math.floor(sv.x / this.SQUARE_SIZE());
          var r = Math.floor(sv.y / this.SQUARE_SIZE());
          return new Vectors.Square(f, r);
      };
      wBoard.prototype.squaretoscreenvector = function (sq) {
          var x = sq.file * this.SQUARE_SIZE();
          var y = sq.rank * this.SQUARE_SIZE();
          return new Vectors.ScreenVector(x, y);
      };
      wBoard.prototype.kindToNumber = function (kind) {
          switch (kind) {
              case 'n': return 110;
              case 'b': return 98;
              case 'r': return 114;
              case 'q': return 113;
              case 'k': return 107;
              default: return 45;
          }
      };
      wBoard.prototype.makeMove = function (m) {
          this.exports._makeMoveMain(m.fsq.file, m.fsq.rank, m.tsq.file, m.tsq.rank, this.kindToNumber(m.prompiece.kind));
          Globals.gui.positionChanged();
      };
      wBoard.prototype.isMovePromotion = function (m) {
          return this.exports._isMovePromotionMain(m.fsq.file, m.fsq.rank, m.tsq.file, m.tsq.rank) > 0;
      };
      wBoard.prototype.boardmouseup = function (e) {
          var me = e;
          if (this.dragunderway) {
              this.dragunderway = false;
              var dragdcorr = this.dragd.Plus(this.HALF_SQUARE_SIZE_SCREENVECTOR());
              var dragdnom = dragdcorr;
              var dsq = this.screenvectortosquare(dragdnom);
              var dsv = this.squaretoscreenvector(dsq);
              var nsv = this.dragstartst.Plus(dsv);
              this.draggedpdiv.
                  leftPx(nsv.x).
                  topPx(nsv.y);
              var fromsqorig = this.rotateSquare(this.draggedsq, this.flip);
              var tosq = this.rotateSquare(fromsqorig.Plus(dsq), -this.flip);
              var m = new Vectors.Move(this.draggedsq, tosq);
              if (this.isMovePromotion(m)) {
                  var kind = prompt("Enter promotion piece letter [ n / b / r / q ] !");
                  if ((kind == "undefined") || (kind == null) || (kind == "")) { }
                  else {
                      m.prompiece.kind = kind;
                      this.makeMove(m);
                  }
              }
              else {
                  this.makeMove(m);
              }
              this.draw();
          }
      };
      wBoard.prototype.getNumPlayers = function () {
          return this.exports._getNumPlayers();
      };
      wBoard.prototype.doflip = function () {
          this.flip += (this.getNumPlayers() == 4 ? 1 : 2);
          if (this.flip >= 4) {
              this.flip = 0;
          }
          this.draw();
      };
      wBoard.prototype.tobegin = function () { this.exports._tobegin(); };
      wBoard.prototype.back = function () { this.exports._back(); };
      wBoard.prototype.forward = function () { this.exports._forward(); };
      wBoard.prototype.toend = function () { this.exports._toend(); };
      wBoard.prototype.delete = function () { this.exports._delete(); };
      wBoard.prototype.dotobegin = function () { this.exports._tobegin(); this.draw(); Globals.gui.positionChanged(); };
      wBoard.prototype.doback = function () { this.exports._back(); this.draw(); Globals.gui.positionChanged(); };
      wBoard.prototype.doforward = function () { this.exports._forward(); this.draw(); Globals.gui.positionChanged(); };
      wBoard.prototype.dotoend = function () { this.exports._toend(); this.draw(); Globals.gui.positionChanged(); };
      wBoard.prototype.dodelete = function () { this.exports._delete(); this.draw(); Globals.gui.positionChanged(); };
      wBoard.prototype.makeSanMove = function (san) {
          this.inbuff.strCpy(san);
          this.exports._makeSanMoveMain();
      };
      wBoard.prototype.domakeSanMove = function (san) {
          this.makeSanMove(san);
          this.draw();
          Globals.gui.positionChanged();
      };
      wBoard.SQUARE_Z_INDEX = 10;
      wBoard.ARROW_Z_INDEX = 50;
      wBoard.SQUARE_OPACITY = 0.2;
      wBoard.PIECE_Z_INDEX = 500;
      wBoard.LIGHT_SQUARE_COLOR = "#efefef";
      wBoard.DARK_SQUARE_COLOR = "#afafaf";
      wBoard.PIECE_FILL_COLORS = ["#000000", "#ffffff", "#ffff00", "#ff0000"];
      wBoard.PIECE_STROKE_COLORS = ["#ffffff", "#dfdfdf", "#afafaf", "#afafaf"];
      wBoard.INFO_BCOL = "#cfcfaf";
      wBoard.INFO_DIV_MARGIN = 8;
      wBoard.INFO_DIV_BCOL = "#dfdfaf";
      return wBoard;
  }(WasmLoader.WasmLoader));
  var Globals;
  (function (Globals) {
      Globals.gui = new GUI();
      Globals.wboard = new wBoard();
      Globals.startup = new TextAsset("startup.json");
      Globals.log = function (li) { };
  })(Globals || (Globals = {}));
  var gui = Globals.gui;
  var wboard = Globals.wboard;
  function main() {
      gui.draw();
      window.onbeforeunload = function (e) {
          new AjaxRequest({
              action: "shutdown"
          });
      };
  }
  function mainloader() {
      //localStorage.clear()
      new AssetLoader().
          add(wboard).
          setcallback(main).
          load();
  }
  mainloader();
  