@ankhorage/zora 21.1.3 → 22.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +4 -1
  3. package/dist/features/authoring/index.d.ts +0 -4
  4. package/dist/features/authoring/index.d.ts.map +1 -1
  5. package/dist/features/authoring/index.js +0 -3
  6. package/dist/features/authoring/index.js.map +1 -1
  7. package/dist/features/chess/adapters/inbound/ChessBoard.d.ts +1 -1
  8. package/dist/features/chess/adapters/inbound/ChessBoard.d.ts.map +1 -1
  9. package/dist/features/chess/adapters/inbound/ChessBoard.js +23 -7
  10. package/dist/features/chess/adapters/inbound/ChessBoard.js.map +1 -1
  11. package/dist/features/chess/meta.d.ts +68 -0
  12. package/dist/features/chess/meta.d.ts.map +1 -1
  13. package/dist/features/chess/meta.js +36 -1
  14. package/dist/features/chess/meta.js.map +1 -1
  15. package/dist/features/chess/public.d.ts +3 -1
  16. package/dist/features/chess/public.d.ts.map +1 -1
  17. package/dist/features/chess/public.js +2 -0
  18. package/dist/features/chess/public.js.map +1 -1
  19. package/dist/features/chess/utils/chessEngine.d.ts +8 -0
  20. package/dist/features/chess/utils/chessEngine.d.ts.map +1 -0
  21. package/dist/features/chess/utils/chessEngine.js +71 -0
  22. package/dist/features/chess/utils/chessEngine.js.map +1 -0
  23. package/dist/features/tabletop/meta.d.ts +32 -0
  24. package/dist/features/tabletop/meta.d.ts.map +1 -1
  25. package/dist/features/tabletop/meta.js +24 -0
  26. package/dist/features/tabletop/meta.js.map +1 -1
  27. package/dist/features/tabletop/public.d.ts +1 -0
  28. package/dist/features/tabletop/public.d.ts.map +1 -1
  29. package/dist/features/tabletop/public.js +1 -0
  30. package/dist/features/tabletop/public.js.map +1 -1
  31. package/dist/index.d.ts +4 -7
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +3 -5
  34. package/dist/index.js.map +1 -1
  35. package/dist/types/chess.d.ts +10 -0
  36. package/dist/types/chess.d.ts.map +1 -1
  37. package/dist/types/chess.js.map +1 -1
  38. package/package.json +7 -6
  39. package/src/features/authoring/featureManifest.test.ts +46 -10
  40. package/src/features/authoring/index.ts +0 -8
  41. package/src/features/chess/adapters/inbound/ChessBoard.tsx +34 -11
  42. package/src/features/chess/meta.ts +36 -1
  43. package/src/features/chess/public.test.tsx +83 -0
  44. package/src/features/chess/public.ts +3 -0
  45. package/src/features/chess/utils/chessEngine.test.ts +35 -0
  46. package/src/features/chess/utils/chessEngine.ts +83 -0
  47. package/src/features/chessTabletopOwnership.test.ts +8 -4
  48. package/src/features/tabletop/meta.ts +24 -0
  49. package/src/features/tabletop/public.test.tsx +12 -0
  50. package/src/features/tabletop/public.ts +1 -0
  51. package/src/index.ts +7 -15
  52. package/src/structureOwnership.test.ts +2 -7
  53. package/src/types/chess.ts +11 -0
  54. package/web-dist/chunks/Accordion-784f23tq.js +3813 -0
  55. package/web-dist/components/card-back/CardBack.js +1 -1
  56. package/web-dist/components/card-hand/CardHand.js +1 -1
  57. package/web-dist/components/chess-board/ChessBoard.js +1 -1
  58. package/web-dist/components/opening-book/OpeningBook.js +1 -1
  59. package/web-dist/components/playing-card/PlayingCard.js +1 -1
  60. package/web-dist/components/poker-training-table/PokerTrainingTable.js +1 -1
  61. package/web-dist/components/tabletop-table/TabletopTable.js +1 -1
  62. package/web-dist/manifest.json +12 -24
  63. package/dist/features/plugin/ZORA_CORE_PLUGIN.d.ts +0 -4
  64. package/dist/features/plugin/ZORA_CORE_PLUGIN.d.ts.map +0 -1
  65. package/dist/features/plugin/ZORA_CORE_PLUGIN.js +0 -8
  66. package/dist/features/plugin/ZORA_CORE_PLUGIN.js.map +0 -1
  67. package/dist/features/plugin/ZORA_CORE_PLUGIN_METADATA.d.ts +0 -3
  68. package/dist/features/plugin/ZORA_CORE_PLUGIN_METADATA.d.ts.map +0 -1
  69. package/dist/features/plugin/ZORA_CORE_PLUGIN_METADATA.js +0 -36
  70. package/dist/features/plugin/ZORA_CORE_PLUGIN_METADATA.js.map +0 -1
  71. package/dist/features/plugin/application/use-cases/composeZoraPluginMetadata.d.ts +0 -4
  72. package/dist/features/plugin/application/use-cases/composeZoraPluginMetadata.d.ts.map +0 -1
  73. package/dist/features/plugin/application/use-cases/composeZoraPluginMetadata.js +0 -106
  74. package/dist/features/plugin/application/use-cases/composeZoraPluginMetadata.js.map +0 -1
  75. package/dist/features/plugin/application/use-cases/composeZoraPlugins.d.ts +0 -4
  76. package/dist/features/plugin/application/use-cases/composeZoraPlugins.d.ts.map +0 -1
  77. package/dist/features/plugin/application/use-cases/composeZoraPlugins.js +0 -41
  78. package/dist/features/plugin/application/use-cases/composeZoraPlugins.js.map +0 -1
  79. package/dist/features/plugin/domain/ZoraPluginCompositionError.d.ts +0 -14
  80. package/dist/features/plugin/domain/ZoraPluginCompositionError.d.ts.map +0 -1
  81. package/dist/features/plugin/domain/ZoraPluginCompositionError.js +0 -14
  82. package/dist/features/plugin/domain/ZoraPluginCompositionError.js.map +0 -1
  83. package/dist/features/plugin/public.d.ts +0 -4
  84. package/dist/features/plugin/public.d.ts.map +0 -1
  85. package/dist/features/plugin/public.js +0 -4
  86. package/dist/features/plugin/public.js.map +0 -1
  87. package/dist/features/plugin/runtime.d.ts +0 -3
  88. package/dist/features/plugin/runtime.d.ts.map +0 -1
  89. package/dist/features/plugin/runtime.js +0 -3
  90. package/dist/features/plugin/runtime.js.map +0 -1
  91. package/dist/types/plugin.d.ts +0 -29
  92. package/dist/types/plugin.d.ts.map +0 -1
  93. package/dist/types/plugin.js +0 -2
  94. package/dist/types/plugin.js.map +0 -1
  95. package/src/features/plugin/ZORA_CORE_PLUGIN.ts +0 -9
  96. package/src/features/plugin/ZORA_CORE_PLUGIN_METADATA.ts +0 -49
  97. package/src/features/plugin/application/use-cases/composeZoraPluginMetadata.ts +0 -166
  98. package/src/features/plugin/application/use-cases/composeZoraPlugins.ts +0 -76
  99. package/src/features/plugin/domain/ZoraPluginCompositionError.ts +0 -21
  100. package/src/features/plugin/pluginComposition.test.ts +0 -139
  101. package/src/features/plugin/public.ts +0 -3
  102. package/src/features/plugin/runtime.ts +0 -2
  103. package/src/types/plugin.ts +0 -43
  104. package/web-dist/chunks/Accordion-86z2tvvz.js +0 -321
  105. package/web-dist/components/zora-plugin-composition-error/ZoraPluginCompositionError.d.ts +0 -3
  106. package/web-dist/components/zora-plugin-composition-error/ZoraPluginCompositionError.js +0 -17
  107. package/web-dist/components/zora-plugin-composition-error/index.d.ts +0 -1
  108. package/web-dist/components/zora-plugin-composition-error/index.js +0 -2
  109. /package/web-dist/chunks/{Accordion-57mn1j9e.js → Accordion-z585n0mr.js} +0 -0
@@ -0,0 +1,3813 @@
1
+ 'use client';
2
+ import {
3
+ require_cjs
4
+ } from "./Accordion-7hn324r1.js";
5
+ import {
6
+ withZoraThemeScope
7
+ } from "./Accordion-k3bc4kad.js";
8
+ import {
9
+ useZoraTheme2
10
+ } from "./Accordion-7zfskq1s.js";
11
+ import {
12
+ __toESM
13
+ } from "./Accordion-9qvmwkxe.js";
14
+
15
+ // src/features/chess/adapters/inbound/ChessBoard.tsx
16
+ var import_react_native = __toESM(require_cjs(), 1);
17
+
18
+ // node_modules/chess.js/dist/esm/chess.js
19
+ function rootNode(comment) {
20
+ return comment !== null ? { comment, variations: [] } : { variations: [] };
21
+ }
22
+ function node(move, suffix, nag, comment, variations) {
23
+ const node = { move, variations };
24
+ if (suffix) {
25
+ node.suffix = suffix;
26
+ }
27
+ if (nag) {
28
+ node.nag = nag;
29
+ }
30
+ if (comment !== null) {
31
+ node.comment = comment;
32
+ }
33
+ return node;
34
+ }
35
+ function lineToTree(...nodes) {
36
+ const [root, ...rest] = nodes;
37
+ let parent = root;
38
+ for (const child of rest) {
39
+ if (child !== null) {
40
+ parent.variations = [child, ...child.variations];
41
+ child.variations = [];
42
+ parent = child;
43
+ }
44
+ }
45
+ return root;
46
+ }
47
+ function pgn(headers, game) {
48
+ if (game.marker && game.marker.comment) {
49
+ let node = game.root;
50
+ while (true) {
51
+ const next = node.variations[0];
52
+ if (!next) {
53
+ node.comment = game.marker.comment;
54
+ break;
55
+ }
56
+ node = next;
57
+ }
58
+ }
59
+ return {
60
+ headers,
61
+ root: game.root,
62
+ result: (game.marker && game.marker.result) ?? undefined
63
+ };
64
+ }
65
+ function peg$subclass(child, parent) {
66
+ function C() {
67
+ this.constructor = child;
68
+ }
69
+ C.prototype = parent.prototype;
70
+ child.prototype = new C;
71
+ }
72
+ function peg$SyntaxError(message, expected, found, location) {
73
+ var self = Error.call(this, message);
74
+ if (Object.setPrototypeOf) {
75
+ Object.setPrototypeOf(self, peg$SyntaxError.prototype);
76
+ }
77
+ self.expected = expected;
78
+ self.found = found;
79
+ self.location = location;
80
+ self.name = "SyntaxError";
81
+ return self;
82
+ }
83
+ peg$subclass(peg$SyntaxError, Error);
84
+ function peg$padEnd(str, targetLength, padString) {
85
+ padString = padString || " ";
86
+ if (str.length > targetLength) {
87
+ return str;
88
+ }
89
+ targetLength -= str.length;
90
+ padString += padString.repeat(targetLength);
91
+ return str + padString.slice(0, targetLength);
92
+ }
93
+ peg$SyntaxError.prototype.format = function(sources) {
94
+ var str = "Error: " + this.message;
95
+ if (this.location) {
96
+ var src = null;
97
+ var k;
98
+ for (k = 0;k < sources.length; k++) {
99
+ if (sources[k].source === this.location.source) {
100
+ src = sources[k].text.split(/\r\n|\n|\r/g);
101
+ break;
102
+ }
103
+ }
104
+ var s = this.location.start;
105
+ var offset_s = this.location.source && typeof this.location.source.offset === "function" ? this.location.source.offset(s) : s;
106
+ var loc = this.location.source + ":" + offset_s.line + ":" + offset_s.column;
107
+ if (src) {
108
+ var e = this.location.end;
109
+ var filler = peg$padEnd("", offset_s.line.toString().length, " ");
110
+ var line = src[s.line - 1];
111
+ var last = s.line === e.line ? e.column : line.length + 1;
112
+ var hatLen = last - s.column || 1;
113
+ str += `
114
+ --> ` + loc + `
115
+ ` + filler + ` |
116
+ ` + offset_s.line + " | " + line + `
117
+ ` + filler + " | " + peg$padEnd("", s.column - 1, " ") + peg$padEnd("", hatLen, "^");
118
+ } else {
119
+ str += `
120
+ at ` + loc;
121
+ }
122
+ }
123
+ return str;
124
+ };
125
+ peg$SyntaxError.buildMessage = function(expected, found) {
126
+ var DESCRIBE_EXPECTATION_FNS = {
127
+ literal: function(expectation) {
128
+ return '"' + literalEscape(expectation.text) + '"';
129
+ },
130
+ class: function(expectation) {
131
+ var escapedParts = expectation.parts.map(function(part) {
132
+ return Array.isArray(part) ? classEscape(part[0]) + "-" + classEscape(part[1]) : classEscape(part);
133
+ });
134
+ return "[" + (expectation.inverted ? "^" : "") + escapedParts.join("") + "]";
135
+ },
136
+ any: function() {
137
+ return "any character";
138
+ },
139
+ end: function() {
140
+ return "end of input";
141
+ },
142
+ other: function(expectation) {
143
+ return expectation.description;
144
+ }
145
+ };
146
+ function hex(ch) {
147
+ return ch.charCodeAt(0).toString(16).toUpperCase();
148
+ }
149
+ function literalEscape(s) {
150
+ return s.replace(/\\/g, "\\\\").replace(/"/g, "\\\"").replace(/\0/g, "\\0").replace(/\t/g, "\\t").replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/[\x00-\x0F]/g, function(ch) {
151
+ return "\\x0" + hex(ch);
152
+ }).replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) {
153
+ return "\\x" + hex(ch);
154
+ });
155
+ }
156
+ function classEscape(s) {
157
+ return s.replace(/\\/g, "\\\\").replace(/\]/g, "\\]").replace(/\^/g, "\\^").replace(/-/g, "\\-").replace(/\0/g, "\\0").replace(/\t/g, "\\t").replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/[\x00-\x0F]/g, function(ch) {
158
+ return "\\x0" + hex(ch);
159
+ }).replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) {
160
+ return "\\x" + hex(ch);
161
+ });
162
+ }
163
+ function describeExpectation(expectation) {
164
+ return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation);
165
+ }
166
+ function describeExpected(expected) {
167
+ var descriptions = expected.map(describeExpectation);
168
+ var i, j;
169
+ descriptions.sort();
170
+ if (descriptions.length > 0) {
171
+ for (i = 1, j = 1;i < descriptions.length; i++) {
172
+ if (descriptions[i - 1] !== descriptions[i]) {
173
+ descriptions[j] = descriptions[i];
174
+ j++;
175
+ }
176
+ }
177
+ descriptions.length = j;
178
+ }
179
+ switch (descriptions.length) {
180
+ case 1:
181
+ return descriptions[0];
182
+ case 2:
183
+ return descriptions[0] + " or " + descriptions[1];
184
+ default:
185
+ return descriptions.slice(0, -1).join(", ") + ", or " + descriptions[descriptions.length - 1];
186
+ }
187
+ }
188
+ function describeFound(found) {
189
+ return found ? '"' + literalEscape(found) + '"' : "end of input";
190
+ }
191
+ return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found.";
192
+ };
193
+ function peg$parse(input, options) {
194
+ options = options !== undefined ? options : {};
195
+ var peg$FAILED = {};
196
+ var peg$source = options.grammarSource;
197
+ var peg$startRuleFunctions = { pgn: peg$parsepgn };
198
+ var peg$startRuleFunction = peg$parsepgn;
199
+ var peg$c0 = "[";
200
+ var peg$c1 = '"';
201
+ var peg$c2 = "]";
202
+ var peg$c3 = ".";
203
+ var peg$c4 = "O-O-O";
204
+ var peg$c5 = "O-O";
205
+ var peg$c6 = "0-0-0";
206
+ var peg$c7 = "0-0";
207
+ var peg$c8 = "$";
208
+ var peg$c9 = "{";
209
+ var peg$c10 = "}";
210
+ var peg$c11 = ";";
211
+ var peg$c12 = "(";
212
+ var peg$c13 = ")";
213
+ var peg$c14 = "1-0";
214
+ var peg$c15 = "0-1";
215
+ var peg$c16 = "1/2-1/2";
216
+ var peg$c17 = "*";
217
+ var peg$r0 = /^[a-zA-Z]/;
218
+ var peg$r1 = /^[^"]/;
219
+ var peg$r2 = /^[0-9]/;
220
+ var peg$r3 = /^[.]/;
221
+ var peg$r4 = /^[a-zA-Z1-8\-=]/;
222
+ var peg$r5 = /^[+#]/;
223
+ var peg$r6 = /^[!?]/;
224
+ var peg$r7 = /^[^}]/;
225
+ var peg$r8 = /^[^\r\n]/;
226
+ var peg$r9 = /^[ \t\r\n]/;
227
+ var peg$e0 = peg$otherExpectation("tag pair");
228
+ var peg$e1 = peg$literalExpectation("[", false);
229
+ var peg$e2 = peg$literalExpectation('"', false);
230
+ var peg$e3 = peg$literalExpectation("]", false);
231
+ var peg$e4 = peg$otherExpectation("tag name");
232
+ var peg$e5 = peg$classExpectation([["a", "z"], ["A", "Z"]], false, false);
233
+ var peg$e6 = peg$otherExpectation("tag value");
234
+ var peg$e7 = peg$classExpectation(['"'], true, false);
235
+ var peg$e8 = peg$otherExpectation("move number");
236
+ var peg$e9 = peg$classExpectation([["0", "9"]], false, false);
237
+ var peg$e10 = peg$literalExpectation(".", false);
238
+ var peg$e11 = peg$classExpectation(["."], false, false);
239
+ var peg$e12 = peg$otherExpectation("standard algebraic notation");
240
+ var peg$e13 = peg$literalExpectation("O-O-O", false);
241
+ var peg$e14 = peg$literalExpectation("O-O", false);
242
+ var peg$e15 = peg$literalExpectation("0-0-0", false);
243
+ var peg$e16 = peg$literalExpectation("0-0", false);
244
+ var peg$e17 = peg$classExpectation([["a", "z"], ["A", "Z"], ["1", "8"], "-", "="], false, false);
245
+ var peg$e18 = peg$classExpectation(["+", "#"], false, false);
246
+ var peg$e19 = peg$otherExpectation("suffix annotation");
247
+ var peg$e20 = peg$classExpectation(["!", "?"], false, false);
248
+ var peg$e21 = peg$otherExpectation("NAG");
249
+ var peg$e22 = peg$literalExpectation("$", false);
250
+ var peg$e23 = peg$otherExpectation("brace comment");
251
+ var peg$e24 = peg$literalExpectation("{", false);
252
+ var peg$e25 = peg$classExpectation(["}"], true, false);
253
+ var peg$e26 = peg$literalExpectation("}", false);
254
+ var peg$e27 = peg$otherExpectation("rest of line comment");
255
+ var peg$e28 = peg$literalExpectation(";", false);
256
+ var peg$e29 = peg$classExpectation(["\r", `
257
+ `], true, false);
258
+ var peg$e30 = peg$otherExpectation("variation");
259
+ var peg$e31 = peg$literalExpectation("(", false);
260
+ var peg$e32 = peg$literalExpectation(")", false);
261
+ var peg$e33 = peg$otherExpectation("game termination marker");
262
+ var peg$e34 = peg$literalExpectation("1-0", false);
263
+ var peg$e35 = peg$literalExpectation("0-1", false);
264
+ var peg$e36 = peg$literalExpectation("1/2-1/2", false);
265
+ var peg$e37 = peg$literalExpectation("*", false);
266
+ var peg$e38 = peg$otherExpectation("whitespace");
267
+ var peg$e39 = peg$classExpectation([" ", "\t", "\r", `
268
+ `], false, false);
269
+ var peg$f0 = function(headers, game) {
270
+ return pgn(headers, game);
271
+ };
272
+ var peg$f1 = function(tagPairs) {
273
+ return Object.fromEntries(tagPairs);
274
+ };
275
+ var peg$f2 = function(tagName, tagValue) {
276
+ return [tagName, tagValue];
277
+ };
278
+ var peg$f3 = function(root, marker) {
279
+ return { root, marker };
280
+ };
281
+ var peg$f4 = function(comment, moves) {
282
+ return lineToTree(rootNode(comment), ...moves.flat());
283
+ };
284
+ var peg$f5 = function(san, suffix, nag, comment, variations) {
285
+ return node(san, suffix, nag, comment, variations);
286
+ };
287
+ var peg$f6 = function(nag) {
288
+ return nag;
289
+ };
290
+ var peg$f7 = function(comment) {
291
+ return comment.replace(/[\r\n]+/g, " ");
292
+ };
293
+ var peg$f8 = function(comment) {
294
+ return comment.trim();
295
+ };
296
+ var peg$f9 = function(line) {
297
+ return line;
298
+ };
299
+ var peg$f10 = function(result, comment) {
300
+ return { result, comment };
301
+ };
302
+ var peg$currPos = options.peg$currPos | 0;
303
+ var peg$posDetailsCache = [{ line: 1, column: 1 }];
304
+ var peg$maxFailPos = peg$currPos;
305
+ var peg$maxFailExpected = options.peg$maxFailExpected || [];
306
+ var peg$silentFails = options.peg$silentFails | 0;
307
+ var peg$result;
308
+ if (options.startRule) {
309
+ if (!(options.startRule in peg$startRuleFunctions)) {
310
+ throw new Error(`Can't start parsing from rule "` + options.startRule + '".');
311
+ }
312
+ peg$startRuleFunction = peg$startRuleFunctions[options.startRule];
313
+ }
314
+ function peg$literalExpectation(text, ignoreCase) {
315
+ return { type: "literal", text, ignoreCase };
316
+ }
317
+ function peg$classExpectation(parts, inverted, ignoreCase) {
318
+ return { type: "class", parts, inverted, ignoreCase };
319
+ }
320
+ function peg$endExpectation() {
321
+ return { type: "end" };
322
+ }
323
+ function peg$otherExpectation(description) {
324
+ return { type: "other", description };
325
+ }
326
+ function peg$computePosDetails(pos) {
327
+ var details = peg$posDetailsCache[pos];
328
+ var p;
329
+ if (details) {
330
+ return details;
331
+ } else {
332
+ if (pos >= peg$posDetailsCache.length) {
333
+ p = peg$posDetailsCache.length - 1;
334
+ } else {
335
+ p = pos;
336
+ while (!peg$posDetailsCache[--p]) {}
337
+ }
338
+ details = peg$posDetailsCache[p];
339
+ details = {
340
+ line: details.line,
341
+ column: details.column
342
+ };
343
+ while (p < pos) {
344
+ if (input.charCodeAt(p) === 10) {
345
+ details.line++;
346
+ details.column = 1;
347
+ } else {
348
+ details.column++;
349
+ }
350
+ p++;
351
+ }
352
+ peg$posDetailsCache[pos] = details;
353
+ return details;
354
+ }
355
+ }
356
+ function peg$computeLocation(startPos, endPos, offset) {
357
+ var startPosDetails = peg$computePosDetails(startPos);
358
+ var endPosDetails = peg$computePosDetails(endPos);
359
+ var res = {
360
+ source: peg$source,
361
+ start: {
362
+ offset: startPos,
363
+ line: startPosDetails.line,
364
+ column: startPosDetails.column
365
+ },
366
+ end: {
367
+ offset: endPos,
368
+ line: endPosDetails.line,
369
+ column: endPosDetails.column
370
+ }
371
+ };
372
+ return res;
373
+ }
374
+ function peg$fail(expected) {
375
+ if (peg$currPos < peg$maxFailPos) {
376
+ return;
377
+ }
378
+ if (peg$currPos > peg$maxFailPos) {
379
+ peg$maxFailPos = peg$currPos;
380
+ peg$maxFailExpected = [];
381
+ }
382
+ peg$maxFailExpected.push(expected);
383
+ }
384
+ function peg$buildStructuredError(expected, found, location) {
385
+ return new peg$SyntaxError(peg$SyntaxError.buildMessage(expected, found), expected, found, location);
386
+ }
387
+ function peg$parsepgn() {
388
+ var s0, s1, s2;
389
+ s0 = peg$currPos;
390
+ s1 = peg$parsetagPairSection();
391
+ s2 = peg$parsemoveTextSection();
392
+ s0 = peg$f0(s1, s2);
393
+ return s0;
394
+ }
395
+ function peg$parsetagPairSection() {
396
+ var s0, s1, s2;
397
+ s0 = peg$currPos;
398
+ s1 = [];
399
+ s2 = peg$parsetagPair();
400
+ while (s2 !== peg$FAILED) {
401
+ s1.push(s2);
402
+ s2 = peg$parsetagPair();
403
+ }
404
+ s2 = peg$parse_();
405
+ s0 = peg$f1(s1);
406
+ return s0;
407
+ }
408
+ function peg$parsetagPair() {
409
+ var s0, s2, s4, s6, s7, s8, s10;
410
+ peg$silentFails++;
411
+ s0 = peg$currPos;
412
+ peg$parse_();
413
+ if (input.charCodeAt(peg$currPos) === 91) {
414
+ s2 = peg$c0;
415
+ peg$currPos++;
416
+ } else {
417
+ s2 = peg$FAILED;
418
+ if (peg$silentFails === 0) {
419
+ peg$fail(peg$e1);
420
+ }
421
+ }
422
+ if (s2 !== peg$FAILED) {
423
+ peg$parse_();
424
+ s4 = peg$parsetagName();
425
+ if (s4 !== peg$FAILED) {
426
+ peg$parse_();
427
+ if (input.charCodeAt(peg$currPos) === 34) {
428
+ s6 = peg$c1;
429
+ peg$currPos++;
430
+ } else {
431
+ s6 = peg$FAILED;
432
+ if (peg$silentFails === 0) {
433
+ peg$fail(peg$e2);
434
+ }
435
+ }
436
+ if (s6 !== peg$FAILED) {
437
+ s7 = peg$parsetagValue();
438
+ if (input.charCodeAt(peg$currPos) === 34) {
439
+ s8 = peg$c1;
440
+ peg$currPos++;
441
+ } else {
442
+ s8 = peg$FAILED;
443
+ if (peg$silentFails === 0) {
444
+ peg$fail(peg$e2);
445
+ }
446
+ }
447
+ if (s8 !== peg$FAILED) {
448
+ peg$parse_();
449
+ if (input.charCodeAt(peg$currPos) === 93) {
450
+ s10 = peg$c2;
451
+ peg$currPos++;
452
+ } else {
453
+ s10 = peg$FAILED;
454
+ if (peg$silentFails === 0) {
455
+ peg$fail(peg$e3);
456
+ }
457
+ }
458
+ if (s10 !== peg$FAILED) {
459
+ s0 = peg$f2(s4, s7);
460
+ } else {
461
+ peg$currPos = s0;
462
+ s0 = peg$FAILED;
463
+ }
464
+ } else {
465
+ peg$currPos = s0;
466
+ s0 = peg$FAILED;
467
+ }
468
+ } else {
469
+ peg$currPos = s0;
470
+ s0 = peg$FAILED;
471
+ }
472
+ } else {
473
+ peg$currPos = s0;
474
+ s0 = peg$FAILED;
475
+ }
476
+ } else {
477
+ peg$currPos = s0;
478
+ s0 = peg$FAILED;
479
+ }
480
+ peg$silentFails--;
481
+ if (s0 === peg$FAILED) {
482
+ if (peg$silentFails === 0) {
483
+ peg$fail(peg$e0);
484
+ }
485
+ }
486
+ return s0;
487
+ }
488
+ function peg$parsetagName() {
489
+ var s0, s1, s2;
490
+ peg$silentFails++;
491
+ s0 = peg$currPos;
492
+ s1 = [];
493
+ s2 = input.charAt(peg$currPos);
494
+ if (peg$r0.test(s2)) {
495
+ peg$currPos++;
496
+ } else {
497
+ s2 = peg$FAILED;
498
+ if (peg$silentFails === 0) {
499
+ peg$fail(peg$e5);
500
+ }
501
+ }
502
+ if (s2 !== peg$FAILED) {
503
+ while (s2 !== peg$FAILED) {
504
+ s1.push(s2);
505
+ s2 = input.charAt(peg$currPos);
506
+ if (peg$r0.test(s2)) {
507
+ peg$currPos++;
508
+ } else {
509
+ s2 = peg$FAILED;
510
+ if (peg$silentFails === 0) {
511
+ peg$fail(peg$e5);
512
+ }
513
+ }
514
+ }
515
+ } else {
516
+ s1 = peg$FAILED;
517
+ }
518
+ if (s1 !== peg$FAILED) {
519
+ s0 = input.substring(s0, peg$currPos);
520
+ } else {
521
+ s0 = s1;
522
+ }
523
+ peg$silentFails--;
524
+ if (s0 === peg$FAILED) {
525
+ s1 = peg$FAILED;
526
+ if (peg$silentFails === 0) {
527
+ peg$fail(peg$e4);
528
+ }
529
+ }
530
+ return s0;
531
+ }
532
+ function peg$parsetagValue() {
533
+ var s0, s1, s2;
534
+ peg$silentFails++;
535
+ s0 = peg$currPos;
536
+ s1 = [];
537
+ s2 = input.charAt(peg$currPos);
538
+ if (peg$r1.test(s2)) {
539
+ peg$currPos++;
540
+ } else {
541
+ s2 = peg$FAILED;
542
+ if (peg$silentFails === 0) {
543
+ peg$fail(peg$e7);
544
+ }
545
+ }
546
+ while (s2 !== peg$FAILED) {
547
+ s1.push(s2);
548
+ s2 = input.charAt(peg$currPos);
549
+ if (peg$r1.test(s2)) {
550
+ peg$currPos++;
551
+ } else {
552
+ s2 = peg$FAILED;
553
+ if (peg$silentFails === 0) {
554
+ peg$fail(peg$e7);
555
+ }
556
+ }
557
+ }
558
+ s0 = input.substring(s0, peg$currPos);
559
+ peg$silentFails--;
560
+ s1 = peg$FAILED;
561
+ if (peg$silentFails === 0) {
562
+ peg$fail(peg$e6);
563
+ }
564
+ return s0;
565
+ }
566
+ function peg$parsemoveTextSection() {
567
+ var s0, s1, s3;
568
+ s0 = peg$currPos;
569
+ s1 = peg$parseline();
570
+ peg$parse_();
571
+ s3 = peg$parsegameTerminationMarker();
572
+ if (s3 === peg$FAILED) {
573
+ s3 = null;
574
+ }
575
+ peg$parse_();
576
+ s0 = peg$f3(s1, s3);
577
+ return s0;
578
+ }
579
+ function peg$parseline() {
580
+ var s0, s1, s2, s3;
581
+ s0 = peg$currPos;
582
+ s1 = peg$parsecomment();
583
+ if (s1 === peg$FAILED) {
584
+ s1 = null;
585
+ }
586
+ s2 = [];
587
+ s3 = peg$parsemove();
588
+ while (s3 !== peg$FAILED) {
589
+ s2.push(s3);
590
+ s3 = peg$parsemove();
591
+ }
592
+ s0 = peg$f4(s1, s2);
593
+ return s0;
594
+ }
595
+ function peg$parsemove() {
596
+ var s0, s4, s5, s6, s7, s8, s9, s10;
597
+ s0 = peg$currPos;
598
+ peg$parse_();
599
+ peg$parsemoveNumber();
600
+ peg$parse_();
601
+ s4 = peg$parsesan();
602
+ if (s4 !== peg$FAILED) {
603
+ s5 = peg$parsesuffixAnnotation();
604
+ if (s5 === peg$FAILED) {
605
+ s5 = null;
606
+ }
607
+ s6 = [];
608
+ s7 = peg$parsenag();
609
+ while (s7 !== peg$FAILED) {
610
+ s6.push(s7);
611
+ s7 = peg$parsenag();
612
+ }
613
+ s7 = peg$parse_();
614
+ s8 = peg$parsecomment();
615
+ if (s8 === peg$FAILED) {
616
+ s8 = null;
617
+ }
618
+ s9 = [];
619
+ s10 = peg$parsevariation();
620
+ while (s10 !== peg$FAILED) {
621
+ s9.push(s10);
622
+ s10 = peg$parsevariation();
623
+ }
624
+ s0 = peg$f5(s4, s5, s6, s8, s9);
625
+ } else {
626
+ peg$currPos = s0;
627
+ s0 = peg$FAILED;
628
+ }
629
+ return s0;
630
+ }
631
+ function peg$parsemoveNumber() {
632
+ var s0, s1, s2, s3, s4, s5;
633
+ peg$silentFails++;
634
+ s0 = peg$currPos;
635
+ s1 = [];
636
+ s2 = input.charAt(peg$currPos);
637
+ if (peg$r2.test(s2)) {
638
+ peg$currPos++;
639
+ } else {
640
+ s2 = peg$FAILED;
641
+ if (peg$silentFails === 0) {
642
+ peg$fail(peg$e9);
643
+ }
644
+ }
645
+ while (s2 !== peg$FAILED) {
646
+ s1.push(s2);
647
+ s2 = input.charAt(peg$currPos);
648
+ if (peg$r2.test(s2)) {
649
+ peg$currPos++;
650
+ } else {
651
+ s2 = peg$FAILED;
652
+ if (peg$silentFails === 0) {
653
+ peg$fail(peg$e9);
654
+ }
655
+ }
656
+ }
657
+ if (input.charCodeAt(peg$currPos) === 46) {
658
+ s2 = peg$c3;
659
+ peg$currPos++;
660
+ } else {
661
+ s2 = peg$FAILED;
662
+ if (peg$silentFails === 0) {
663
+ peg$fail(peg$e10);
664
+ }
665
+ }
666
+ if (s2 !== peg$FAILED) {
667
+ s3 = peg$parse_();
668
+ s4 = [];
669
+ s5 = input.charAt(peg$currPos);
670
+ if (peg$r3.test(s5)) {
671
+ peg$currPos++;
672
+ } else {
673
+ s5 = peg$FAILED;
674
+ if (peg$silentFails === 0) {
675
+ peg$fail(peg$e11);
676
+ }
677
+ }
678
+ while (s5 !== peg$FAILED) {
679
+ s4.push(s5);
680
+ s5 = input.charAt(peg$currPos);
681
+ if (peg$r3.test(s5)) {
682
+ peg$currPos++;
683
+ } else {
684
+ s5 = peg$FAILED;
685
+ if (peg$silentFails === 0) {
686
+ peg$fail(peg$e11);
687
+ }
688
+ }
689
+ }
690
+ s1 = [s1, s2, s3, s4];
691
+ s0 = s1;
692
+ } else {
693
+ peg$currPos = s0;
694
+ s0 = peg$FAILED;
695
+ }
696
+ peg$silentFails--;
697
+ if (s0 === peg$FAILED) {
698
+ s1 = peg$FAILED;
699
+ if (peg$silentFails === 0) {
700
+ peg$fail(peg$e8);
701
+ }
702
+ }
703
+ return s0;
704
+ }
705
+ function peg$parsesan() {
706
+ var s0, s1, s2, s3, s4, s5;
707
+ peg$silentFails++;
708
+ s0 = peg$currPos;
709
+ s1 = peg$currPos;
710
+ if (input.substr(peg$currPos, 5) === peg$c4) {
711
+ s2 = peg$c4;
712
+ peg$currPos += 5;
713
+ } else {
714
+ s2 = peg$FAILED;
715
+ if (peg$silentFails === 0) {
716
+ peg$fail(peg$e13);
717
+ }
718
+ }
719
+ if (s2 === peg$FAILED) {
720
+ if (input.substr(peg$currPos, 3) === peg$c5) {
721
+ s2 = peg$c5;
722
+ peg$currPos += 3;
723
+ } else {
724
+ s2 = peg$FAILED;
725
+ if (peg$silentFails === 0) {
726
+ peg$fail(peg$e14);
727
+ }
728
+ }
729
+ if (s2 === peg$FAILED) {
730
+ if (input.substr(peg$currPos, 5) === peg$c6) {
731
+ s2 = peg$c6;
732
+ peg$currPos += 5;
733
+ } else {
734
+ s2 = peg$FAILED;
735
+ if (peg$silentFails === 0) {
736
+ peg$fail(peg$e15);
737
+ }
738
+ }
739
+ if (s2 === peg$FAILED) {
740
+ if (input.substr(peg$currPos, 3) === peg$c7) {
741
+ s2 = peg$c7;
742
+ peg$currPos += 3;
743
+ } else {
744
+ s2 = peg$FAILED;
745
+ if (peg$silentFails === 0) {
746
+ peg$fail(peg$e16);
747
+ }
748
+ }
749
+ if (s2 === peg$FAILED) {
750
+ s2 = peg$currPos;
751
+ s3 = input.charAt(peg$currPos);
752
+ if (peg$r0.test(s3)) {
753
+ peg$currPos++;
754
+ } else {
755
+ s3 = peg$FAILED;
756
+ if (peg$silentFails === 0) {
757
+ peg$fail(peg$e5);
758
+ }
759
+ }
760
+ if (s3 !== peg$FAILED) {
761
+ s4 = [];
762
+ s5 = input.charAt(peg$currPos);
763
+ if (peg$r4.test(s5)) {
764
+ peg$currPos++;
765
+ } else {
766
+ s5 = peg$FAILED;
767
+ if (peg$silentFails === 0) {
768
+ peg$fail(peg$e17);
769
+ }
770
+ }
771
+ if (s5 !== peg$FAILED) {
772
+ while (s5 !== peg$FAILED) {
773
+ s4.push(s5);
774
+ s5 = input.charAt(peg$currPos);
775
+ if (peg$r4.test(s5)) {
776
+ peg$currPos++;
777
+ } else {
778
+ s5 = peg$FAILED;
779
+ if (peg$silentFails === 0) {
780
+ peg$fail(peg$e17);
781
+ }
782
+ }
783
+ }
784
+ } else {
785
+ s4 = peg$FAILED;
786
+ }
787
+ if (s4 !== peg$FAILED) {
788
+ s3 = [s3, s4];
789
+ s2 = s3;
790
+ } else {
791
+ peg$currPos = s2;
792
+ s2 = peg$FAILED;
793
+ }
794
+ } else {
795
+ peg$currPos = s2;
796
+ s2 = peg$FAILED;
797
+ }
798
+ }
799
+ }
800
+ }
801
+ }
802
+ if (s2 !== peg$FAILED) {
803
+ s3 = input.charAt(peg$currPos);
804
+ if (peg$r5.test(s3)) {
805
+ peg$currPos++;
806
+ } else {
807
+ s3 = peg$FAILED;
808
+ if (peg$silentFails === 0) {
809
+ peg$fail(peg$e18);
810
+ }
811
+ }
812
+ if (s3 === peg$FAILED) {
813
+ s3 = null;
814
+ }
815
+ s2 = [s2, s3];
816
+ s1 = s2;
817
+ } else {
818
+ peg$currPos = s1;
819
+ s1 = peg$FAILED;
820
+ }
821
+ if (s1 !== peg$FAILED) {
822
+ s0 = input.substring(s0, peg$currPos);
823
+ } else {
824
+ s0 = s1;
825
+ }
826
+ peg$silentFails--;
827
+ if (s0 === peg$FAILED) {
828
+ s1 = peg$FAILED;
829
+ if (peg$silentFails === 0) {
830
+ peg$fail(peg$e12);
831
+ }
832
+ }
833
+ return s0;
834
+ }
835
+ function peg$parsesuffixAnnotation() {
836
+ var s0, s1, s2;
837
+ peg$silentFails++;
838
+ s0 = peg$currPos;
839
+ s1 = [];
840
+ s2 = input.charAt(peg$currPos);
841
+ if (peg$r6.test(s2)) {
842
+ peg$currPos++;
843
+ } else {
844
+ s2 = peg$FAILED;
845
+ if (peg$silentFails === 0) {
846
+ peg$fail(peg$e20);
847
+ }
848
+ }
849
+ while (s2 !== peg$FAILED) {
850
+ s1.push(s2);
851
+ if (s1.length >= 2) {
852
+ s2 = peg$FAILED;
853
+ } else {
854
+ s2 = input.charAt(peg$currPos);
855
+ if (peg$r6.test(s2)) {
856
+ peg$currPos++;
857
+ } else {
858
+ s2 = peg$FAILED;
859
+ if (peg$silentFails === 0) {
860
+ peg$fail(peg$e20);
861
+ }
862
+ }
863
+ }
864
+ }
865
+ if (s1.length < 1) {
866
+ peg$currPos = s0;
867
+ s0 = peg$FAILED;
868
+ } else {
869
+ s0 = s1;
870
+ }
871
+ peg$silentFails--;
872
+ if (s0 === peg$FAILED) {
873
+ s1 = peg$FAILED;
874
+ if (peg$silentFails === 0) {
875
+ peg$fail(peg$e19);
876
+ }
877
+ }
878
+ return s0;
879
+ }
880
+ function peg$parsenag() {
881
+ var s0, s2, s3, s4, s5;
882
+ peg$silentFails++;
883
+ s0 = peg$currPos;
884
+ peg$parse_();
885
+ if (input.charCodeAt(peg$currPos) === 36) {
886
+ s2 = peg$c8;
887
+ peg$currPos++;
888
+ } else {
889
+ s2 = peg$FAILED;
890
+ if (peg$silentFails === 0) {
891
+ peg$fail(peg$e22);
892
+ }
893
+ }
894
+ if (s2 !== peg$FAILED) {
895
+ s3 = peg$currPos;
896
+ s4 = [];
897
+ s5 = input.charAt(peg$currPos);
898
+ if (peg$r2.test(s5)) {
899
+ peg$currPos++;
900
+ } else {
901
+ s5 = peg$FAILED;
902
+ if (peg$silentFails === 0) {
903
+ peg$fail(peg$e9);
904
+ }
905
+ }
906
+ if (s5 !== peg$FAILED) {
907
+ while (s5 !== peg$FAILED) {
908
+ s4.push(s5);
909
+ s5 = input.charAt(peg$currPos);
910
+ if (peg$r2.test(s5)) {
911
+ peg$currPos++;
912
+ } else {
913
+ s5 = peg$FAILED;
914
+ if (peg$silentFails === 0) {
915
+ peg$fail(peg$e9);
916
+ }
917
+ }
918
+ }
919
+ } else {
920
+ s4 = peg$FAILED;
921
+ }
922
+ if (s4 !== peg$FAILED) {
923
+ s3 = input.substring(s3, peg$currPos);
924
+ } else {
925
+ s3 = s4;
926
+ }
927
+ if (s3 !== peg$FAILED) {
928
+ s0 = peg$f6(s3);
929
+ } else {
930
+ peg$currPos = s0;
931
+ s0 = peg$FAILED;
932
+ }
933
+ } else {
934
+ peg$currPos = s0;
935
+ s0 = peg$FAILED;
936
+ }
937
+ peg$silentFails--;
938
+ if (s0 === peg$FAILED) {
939
+ if (peg$silentFails === 0) {
940
+ peg$fail(peg$e21);
941
+ }
942
+ }
943
+ return s0;
944
+ }
945
+ function peg$parsecomment() {
946
+ var s0;
947
+ s0 = peg$parsebraceComment();
948
+ if (s0 === peg$FAILED) {
949
+ s0 = peg$parserestOfLineComment();
950
+ }
951
+ return s0;
952
+ }
953
+ function peg$parsebraceComment() {
954
+ var s0, s1, s2, s3, s4;
955
+ peg$silentFails++;
956
+ s0 = peg$currPos;
957
+ if (input.charCodeAt(peg$currPos) === 123) {
958
+ s1 = peg$c9;
959
+ peg$currPos++;
960
+ } else {
961
+ s1 = peg$FAILED;
962
+ if (peg$silentFails === 0) {
963
+ peg$fail(peg$e24);
964
+ }
965
+ }
966
+ if (s1 !== peg$FAILED) {
967
+ s2 = peg$currPos;
968
+ s3 = [];
969
+ s4 = input.charAt(peg$currPos);
970
+ if (peg$r7.test(s4)) {
971
+ peg$currPos++;
972
+ } else {
973
+ s4 = peg$FAILED;
974
+ if (peg$silentFails === 0) {
975
+ peg$fail(peg$e25);
976
+ }
977
+ }
978
+ while (s4 !== peg$FAILED) {
979
+ s3.push(s4);
980
+ s4 = input.charAt(peg$currPos);
981
+ if (peg$r7.test(s4)) {
982
+ peg$currPos++;
983
+ } else {
984
+ s4 = peg$FAILED;
985
+ if (peg$silentFails === 0) {
986
+ peg$fail(peg$e25);
987
+ }
988
+ }
989
+ }
990
+ s2 = input.substring(s2, peg$currPos);
991
+ if (input.charCodeAt(peg$currPos) === 125) {
992
+ s3 = peg$c10;
993
+ peg$currPos++;
994
+ } else {
995
+ s3 = peg$FAILED;
996
+ if (peg$silentFails === 0) {
997
+ peg$fail(peg$e26);
998
+ }
999
+ }
1000
+ if (s3 !== peg$FAILED) {
1001
+ s0 = peg$f7(s2);
1002
+ } else {
1003
+ peg$currPos = s0;
1004
+ s0 = peg$FAILED;
1005
+ }
1006
+ } else {
1007
+ peg$currPos = s0;
1008
+ s0 = peg$FAILED;
1009
+ }
1010
+ peg$silentFails--;
1011
+ if (s0 === peg$FAILED) {
1012
+ s1 = peg$FAILED;
1013
+ if (peg$silentFails === 0) {
1014
+ peg$fail(peg$e23);
1015
+ }
1016
+ }
1017
+ return s0;
1018
+ }
1019
+ function peg$parserestOfLineComment() {
1020
+ var s0, s1, s2, s3, s4;
1021
+ peg$silentFails++;
1022
+ s0 = peg$currPos;
1023
+ if (input.charCodeAt(peg$currPos) === 59) {
1024
+ s1 = peg$c11;
1025
+ peg$currPos++;
1026
+ } else {
1027
+ s1 = peg$FAILED;
1028
+ if (peg$silentFails === 0) {
1029
+ peg$fail(peg$e28);
1030
+ }
1031
+ }
1032
+ if (s1 !== peg$FAILED) {
1033
+ s2 = peg$currPos;
1034
+ s3 = [];
1035
+ s4 = input.charAt(peg$currPos);
1036
+ if (peg$r8.test(s4)) {
1037
+ peg$currPos++;
1038
+ } else {
1039
+ s4 = peg$FAILED;
1040
+ if (peg$silentFails === 0) {
1041
+ peg$fail(peg$e29);
1042
+ }
1043
+ }
1044
+ while (s4 !== peg$FAILED) {
1045
+ s3.push(s4);
1046
+ s4 = input.charAt(peg$currPos);
1047
+ if (peg$r8.test(s4)) {
1048
+ peg$currPos++;
1049
+ } else {
1050
+ s4 = peg$FAILED;
1051
+ if (peg$silentFails === 0) {
1052
+ peg$fail(peg$e29);
1053
+ }
1054
+ }
1055
+ }
1056
+ s2 = input.substring(s2, peg$currPos);
1057
+ s0 = peg$f8(s2);
1058
+ } else {
1059
+ peg$currPos = s0;
1060
+ s0 = peg$FAILED;
1061
+ }
1062
+ peg$silentFails--;
1063
+ if (s0 === peg$FAILED) {
1064
+ s1 = peg$FAILED;
1065
+ if (peg$silentFails === 0) {
1066
+ peg$fail(peg$e27);
1067
+ }
1068
+ }
1069
+ return s0;
1070
+ }
1071
+ function peg$parsevariation() {
1072
+ var s0, s2, s3, s5;
1073
+ peg$silentFails++;
1074
+ s0 = peg$currPos;
1075
+ peg$parse_();
1076
+ if (input.charCodeAt(peg$currPos) === 40) {
1077
+ s2 = peg$c12;
1078
+ peg$currPos++;
1079
+ } else {
1080
+ s2 = peg$FAILED;
1081
+ if (peg$silentFails === 0) {
1082
+ peg$fail(peg$e31);
1083
+ }
1084
+ }
1085
+ if (s2 !== peg$FAILED) {
1086
+ s3 = peg$parseline();
1087
+ if (s3 !== peg$FAILED) {
1088
+ peg$parse_();
1089
+ if (input.charCodeAt(peg$currPos) === 41) {
1090
+ s5 = peg$c13;
1091
+ peg$currPos++;
1092
+ } else {
1093
+ s5 = peg$FAILED;
1094
+ if (peg$silentFails === 0) {
1095
+ peg$fail(peg$e32);
1096
+ }
1097
+ }
1098
+ if (s5 !== peg$FAILED) {
1099
+ s0 = peg$f9(s3);
1100
+ } else {
1101
+ peg$currPos = s0;
1102
+ s0 = peg$FAILED;
1103
+ }
1104
+ } else {
1105
+ peg$currPos = s0;
1106
+ s0 = peg$FAILED;
1107
+ }
1108
+ } else {
1109
+ peg$currPos = s0;
1110
+ s0 = peg$FAILED;
1111
+ }
1112
+ peg$silentFails--;
1113
+ if (s0 === peg$FAILED) {
1114
+ if (peg$silentFails === 0) {
1115
+ peg$fail(peg$e30);
1116
+ }
1117
+ }
1118
+ return s0;
1119
+ }
1120
+ function peg$parsegameTerminationMarker() {
1121
+ var s0, s1, s3;
1122
+ peg$silentFails++;
1123
+ s0 = peg$currPos;
1124
+ if (input.substr(peg$currPos, 3) === peg$c14) {
1125
+ s1 = peg$c14;
1126
+ peg$currPos += 3;
1127
+ } else {
1128
+ s1 = peg$FAILED;
1129
+ if (peg$silentFails === 0) {
1130
+ peg$fail(peg$e34);
1131
+ }
1132
+ }
1133
+ if (s1 === peg$FAILED) {
1134
+ if (input.substr(peg$currPos, 3) === peg$c15) {
1135
+ s1 = peg$c15;
1136
+ peg$currPos += 3;
1137
+ } else {
1138
+ s1 = peg$FAILED;
1139
+ if (peg$silentFails === 0) {
1140
+ peg$fail(peg$e35);
1141
+ }
1142
+ }
1143
+ if (s1 === peg$FAILED) {
1144
+ if (input.substr(peg$currPos, 7) === peg$c16) {
1145
+ s1 = peg$c16;
1146
+ peg$currPos += 7;
1147
+ } else {
1148
+ s1 = peg$FAILED;
1149
+ if (peg$silentFails === 0) {
1150
+ peg$fail(peg$e36);
1151
+ }
1152
+ }
1153
+ if (s1 === peg$FAILED) {
1154
+ if (input.charCodeAt(peg$currPos) === 42) {
1155
+ s1 = peg$c17;
1156
+ peg$currPos++;
1157
+ } else {
1158
+ s1 = peg$FAILED;
1159
+ if (peg$silentFails === 0) {
1160
+ peg$fail(peg$e37);
1161
+ }
1162
+ }
1163
+ }
1164
+ }
1165
+ }
1166
+ if (s1 !== peg$FAILED) {
1167
+ peg$parse_();
1168
+ s3 = peg$parsecomment();
1169
+ if (s3 === peg$FAILED) {
1170
+ s3 = null;
1171
+ }
1172
+ s0 = peg$f10(s1, s3);
1173
+ } else {
1174
+ peg$currPos = s0;
1175
+ s0 = peg$FAILED;
1176
+ }
1177
+ peg$silentFails--;
1178
+ if (s0 === peg$FAILED) {
1179
+ s1 = peg$FAILED;
1180
+ if (peg$silentFails === 0) {
1181
+ peg$fail(peg$e33);
1182
+ }
1183
+ }
1184
+ return s0;
1185
+ }
1186
+ function peg$parse_() {
1187
+ var s0, s1;
1188
+ peg$silentFails++;
1189
+ s0 = [];
1190
+ s1 = input.charAt(peg$currPos);
1191
+ if (peg$r9.test(s1)) {
1192
+ peg$currPos++;
1193
+ } else {
1194
+ s1 = peg$FAILED;
1195
+ if (peg$silentFails === 0) {
1196
+ peg$fail(peg$e39);
1197
+ }
1198
+ }
1199
+ while (s1 !== peg$FAILED) {
1200
+ s0.push(s1);
1201
+ s1 = input.charAt(peg$currPos);
1202
+ if (peg$r9.test(s1)) {
1203
+ peg$currPos++;
1204
+ } else {
1205
+ s1 = peg$FAILED;
1206
+ if (peg$silentFails === 0) {
1207
+ peg$fail(peg$e39);
1208
+ }
1209
+ }
1210
+ }
1211
+ peg$silentFails--;
1212
+ s1 = peg$FAILED;
1213
+ if (peg$silentFails === 0) {
1214
+ peg$fail(peg$e38);
1215
+ }
1216
+ return s0;
1217
+ }
1218
+ peg$result = peg$startRuleFunction();
1219
+ if (options.peg$library) {
1220
+ return {
1221
+ peg$result,
1222
+ peg$currPos,
1223
+ peg$FAILED,
1224
+ peg$maxFailExpected,
1225
+ peg$maxFailPos
1226
+ };
1227
+ }
1228
+ if (peg$result !== peg$FAILED && peg$currPos === input.length) {
1229
+ return peg$result;
1230
+ } else {
1231
+ if (peg$result !== peg$FAILED && peg$currPos < input.length) {
1232
+ peg$fail(peg$endExpectation());
1233
+ }
1234
+ throw peg$buildStructuredError(peg$maxFailExpected, peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null, peg$maxFailPos < input.length ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) : peg$computeLocation(peg$maxFailPos, peg$maxFailPos));
1235
+ }
1236
+ }
1237
+ var MASK64 = 0xffffffffffffffffn;
1238
+ function rotl(x, k) {
1239
+ return (x << k | x >> 64n - k) & 0xffffffffffffffffn;
1240
+ }
1241
+ function wrappingMul(x, y) {
1242
+ return x * y & MASK64;
1243
+ }
1244
+ function xoroshiro128(state) {
1245
+ return function() {
1246
+ let s0 = BigInt(state & MASK64);
1247
+ let s1 = BigInt(state >> 64n & MASK64);
1248
+ const result = wrappingMul(rotl(wrappingMul(s0, 5n), 7n), 9n);
1249
+ s1 ^= s0;
1250
+ s0 = (rotl(s0, 24n) ^ s1 ^ s1 << 16n) & MASK64;
1251
+ s1 = rotl(s1, 37n);
1252
+ state = s1 << 64n | s0;
1253
+ return result;
1254
+ };
1255
+ }
1256
+ var rand = xoroshiro128(0xa187eb39cdcaed8f31c4b365b102e01en);
1257
+ var PIECE_KEYS = Array.from({ length: 2 }, () => Array.from({ length: 6 }, () => Array.from({ length: 128 }, () => rand())));
1258
+ var EP_KEYS = Array.from({ length: 8 }, () => rand());
1259
+ var CASTLING_KEYS = Array.from({ length: 16 }, () => rand());
1260
+ var SIDE_KEY = rand();
1261
+ var WHITE = "w";
1262
+ var BLACK = "b";
1263
+ var PAWN = "p";
1264
+ var KNIGHT = "n";
1265
+ var BISHOP = "b";
1266
+ var ROOK = "r";
1267
+ var QUEEN = "q";
1268
+ var KING = "k";
1269
+ var DEFAULT_POSITION = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
1270
+
1271
+ class Move {
1272
+ color;
1273
+ from;
1274
+ to;
1275
+ piece;
1276
+ captured;
1277
+ promotion;
1278
+ flags;
1279
+ san;
1280
+ lan;
1281
+ before;
1282
+ after;
1283
+ constructor(chess, internal) {
1284
+ const { color, piece, from, to, flags, captured, promotion } = internal;
1285
+ const fromAlgebraic = algebraic(from);
1286
+ const toAlgebraic = algebraic(to);
1287
+ this.color = color;
1288
+ this.piece = piece;
1289
+ this.from = fromAlgebraic;
1290
+ this.to = toAlgebraic;
1291
+ this.san = chess["_moveToSan"](internal, chess["_moves"]({ legal: true }));
1292
+ this.lan = fromAlgebraic + toAlgebraic;
1293
+ this.before = chess.fen();
1294
+ chess["_makeMove"](internal);
1295
+ this.after = chess.fen();
1296
+ chess["_undoMove"]();
1297
+ this.flags = "";
1298
+ for (const flag in BITS) {
1299
+ if (BITS[flag] & flags) {
1300
+ this.flags += FLAGS[flag];
1301
+ }
1302
+ }
1303
+ if (captured) {
1304
+ this.captured = captured;
1305
+ }
1306
+ if (promotion) {
1307
+ this.promotion = promotion;
1308
+ this.lan += promotion;
1309
+ }
1310
+ }
1311
+ isCapture() {
1312
+ return this.flags.indexOf(FLAGS["CAPTURE"]) > -1;
1313
+ }
1314
+ isPromotion() {
1315
+ return this.flags.indexOf(FLAGS["PROMOTION"]) > -1;
1316
+ }
1317
+ isEnPassant() {
1318
+ return this.flags.indexOf(FLAGS["EP_CAPTURE"]) > -1;
1319
+ }
1320
+ isKingsideCastle() {
1321
+ return this.flags.indexOf(FLAGS["KSIDE_CASTLE"]) > -1;
1322
+ }
1323
+ isQueensideCastle() {
1324
+ return this.flags.indexOf(FLAGS["QSIDE_CASTLE"]) > -1;
1325
+ }
1326
+ isBigPawn() {
1327
+ return this.flags.indexOf(FLAGS["BIG_PAWN"]) > -1;
1328
+ }
1329
+ }
1330
+ var EMPTY = -1;
1331
+ var FLAGS = {
1332
+ NORMAL: "n",
1333
+ CAPTURE: "c",
1334
+ BIG_PAWN: "b",
1335
+ EP_CAPTURE: "e",
1336
+ PROMOTION: "p",
1337
+ KSIDE_CASTLE: "k",
1338
+ QSIDE_CASTLE: "q",
1339
+ NULL_MOVE: "-"
1340
+ };
1341
+ var BITS = {
1342
+ NORMAL: 1,
1343
+ CAPTURE: 2,
1344
+ BIG_PAWN: 4,
1345
+ EP_CAPTURE: 8,
1346
+ PROMOTION: 16,
1347
+ KSIDE_CASTLE: 32,
1348
+ QSIDE_CASTLE: 64,
1349
+ NULL_MOVE: 128
1350
+ };
1351
+ var SEVEN_TAG_ROSTER = {
1352
+ Event: "?",
1353
+ Site: "?",
1354
+ Date: "????.??.??",
1355
+ Round: "?",
1356
+ White: "?",
1357
+ Black: "?",
1358
+ Result: "*"
1359
+ };
1360
+ var SUPLEMENTAL_TAGS = {
1361
+ WhiteTitle: null,
1362
+ BlackTitle: null,
1363
+ WhiteElo: null,
1364
+ BlackElo: null,
1365
+ WhiteUSCF: null,
1366
+ BlackUSCF: null,
1367
+ WhiteNA: null,
1368
+ BlackNA: null,
1369
+ WhiteType: null,
1370
+ BlackType: null,
1371
+ EventDate: null,
1372
+ EventSponsor: null,
1373
+ Section: null,
1374
+ Stage: null,
1375
+ Board: null,
1376
+ Opening: null,
1377
+ Variation: null,
1378
+ SubVariation: null,
1379
+ ECO: null,
1380
+ NIC: null,
1381
+ Time: null,
1382
+ UTCTime: null,
1383
+ UTCDate: null,
1384
+ TimeControl: null,
1385
+ SetUp: null,
1386
+ FEN: null,
1387
+ Termination: null,
1388
+ Annotator: null,
1389
+ Mode: null,
1390
+ PlyCount: null
1391
+ };
1392
+ var HEADER_TEMPLATE = {
1393
+ ...SEVEN_TAG_ROSTER,
1394
+ ...SUPLEMENTAL_TAGS
1395
+ };
1396
+ var Ox88 = {
1397
+ a8: 0,
1398
+ b8: 1,
1399
+ c8: 2,
1400
+ d8: 3,
1401
+ e8: 4,
1402
+ f8: 5,
1403
+ g8: 6,
1404
+ h8: 7,
1405
+ a7: 16,
1406
+ b7: 17,
1407
+ c7: 18,
1408
+ d7: 19,
1409
+ e7: 20,
1410
+ f7: 21,
1411
+ g7: 22,
1412
+ h7: 23,
1413
+ a6: 32,
1414
+ b6: 33,
1415
+ c6: 34,
1416
+ d6: 35,
1417
+ e6: 36,
1418
+ f6: 37,
1419
+ g6: 38,
1420
+ h6: 39,
1421
+ a5: 48,
1422
+ b5: 49,
1423
+ c5: 50,
1424
+ d5: 51,
1425
+ e5: 52,
1426
+ f5: 53,
1427
+ g5: 54,
1428
+ h5: 55,
1429
+ a4: 64,
1430
+ b4: 65,
1431
+ c4: 66,
1432
+ d4: 67,
1433
+ e4: 68,
1434
+ f4: 69,
1435
+ g4: 70,
1436
+ h4: 71,
1437
+ a3: 80,
1438
+ b3: 81,
1439
+ c3: 82,
1440
+ d3: 83,
1441
+ e3: 84,
1442
+ f3: 85,
1443
+ g3: 86,
1444
+ h3: 87,
1445
+ a2: 96,
1446
+ b2: 97,
1447
+ c2: 98,
1448
+ d2: 99,
1449
+ e2: 100,
1450
+ f2: 101,
1451
+ g2: 102,
1452
+ h2: 103,
1453
+ a1: 112,
1454
+ b1: 113,
1455
+ c1: 114,
1456
+ d1: 115,
1457
+ e1: 116,
1458
+ f1: 117,
1459
+ g1: 118,
1460
+ h1: 119
1461
+ };
1462
+ var PAWN_OFFSETS = {
1463
+ b: [16, 32, 17, 15],
1464
+ w: [-16, -32, -17, -15]
1465
+ };
1466
+ var PIECE_OFFSETS = {
1467
+ n: [-18, -33, -31, -14, 18, 33, 31, 14],
1468
+ b: [-17, -15, 17, 15],
1469
+ r: [-16, 1, 16, -1],
1470
+ q: [-17, -16, -15, 1, 17, 16, 15, -1],
1471
+ k: [-17, -16, -15, 1, 17, 16, 15, -1]
1472
+ };
1473
+ var ATTACKS = [
1474
+ 20,
1475
+ 0,
1476
+ 0,
1477
+ 0,
1478
+ 0,
1479
+ 0,
1480
+ 0,
1481
+ 24,
1482
+ 0,
1483
+ 0,
1484
+ 0,
1485
+ 0,
1486
+ 0,
1487
+ 0,
1488
+ 20,
1489
+ 0,
1490
+ 0,
1491
+ 20,
1492
+ 0,
1493
+ 0,
1494
+ 0,
1495
+ 0,
1496
+ 0,
1497
+ 24,
1498
+ 0,
1499
+ 0,
1500
+ 0,
1501
+ 0,
1502
+ 0,
1503
+ 20,
1504
+ 0,
1505
+ 0,
1506
+ 0,
1507
+ 0,
1508
+ 20,
1509
+ 0,
1510
+ 0,
1511
+ 0,
1512
+ 0,
1513
+ 24,
1514
+ 0,
1515
+ 0,
1516
+ 0,
1517
+ 0,
1518
+ 20,
1519
+ 0,
1520
+ 0,
1521
+ 0,
1522
+ 0,
1523
+ 0,
1524
+ 0,
1525
+ 20,
1526
+ 0,
1527
+ 0,
1528
+ 0,
1529
+ 24,
1530
+ 0,
1531
+ 0,
1532
+ 0,
1533
+ 20,
1534
+ 0,
1535
+ 0,
1536
+ 0,
1537
+ 0,
1538
+ 0,
1539
+ 0,
1540
+ 0,
1541
+ 0,
1542
+ 20,
1543
+ 0,
1544
+ 0,
1545
+ 24,
1546
+ 0,
1547
+ 0,
1548
+ 20,
1549
+ 0,
1550
+ 0,
1551
+ 0,
1552
+ 0,
1553
+ 0,
1554
+ 0,
1555
+ 0,
1556
+ 0,
1557
+ 0,
1558
+ 0,
1559
+ 20,
1560
+ 2,
1561
+ 24,
1562
+ 2,
1563
+ 20,
1564
+ 0,
1565
+ 0,
1566
+ 0,
1567
+ 0,
1568
+ 0,
1569
+ 0,
1570
+ 0,
1571
+ 0,
1572
+ 0,
1573
+ 0,
1574
+ 0,
1575
+ 2,
1576
+ 53,
1577
+ 56,
1578
+ 53,
1579
+ 2,
1580
+ 0,
1581
+ 0,
1582
+ 0,
1583
+ 0,
1584
+ 0,
1585
+ 0,
1586
+ 24,
1587
+ 24,
1588
+ 24,
1589
+ 24,
1590
+ 24,
1591
+ 24,
1592
+ 56,
1593
+ 0,
1594
+ 56,
1595
+ 24,
1596
+ 24,
1597
+ 24,
1598
+ 24,
1599
+ 24,
1600
+ 24,
1601
+ 0,
1602
+ 0,
1603
+ 0,
1604
+ 0,
1605
+ 0,
1606
+ 0,
1607
+ 2,
1608
+ 53,
1609
+ 56,
1610
+ 53,
1611
+ 2,
1612
+ 0,
1613
+ 0,
1614
+ 0,
1615
+ 0,
1616
+ 0,
1617
+ 0,
1618
+ 0,
1619
+ 0,
1620
+ 0,
1621
+ 0,
1622
+ 0,
1623
+ 20,
1624
+ 2,
1625
+ 24,
1626
+ 2,
1627
+ 20,
1628
+ 0,
1629
+ 0,
1630
+ 0,
1631
+ 0,
1632
+ 0,
1633
+ 0,
1634
+ 0,
1635
+ 0,
1636
+ 0,
1637
+ 0,
1638
+ 20,
1639
+ 0,
1640
+ 0,
1641
+ 24,
1642
+ 0,
1643
+ 0,
1644
+ 20,
1645
+ 0,
1646
+ 0,
1647
+ 0,
1648
+ 0,
1649
+ 0,
1650
+ 0,
1651
+ 0,
1652
+ 0,
1653
+ 20,
1654
+ 0,
1655
+ 0,
1656
+ 0,
1657
+ 24,
1658
+ 0,
1659
+ 0,
1660
+ 0,
1661
+ 20,
1662
+ 0,
1663
+ 0,
1664
+ 0,
1665
+ 0,
1666
+ 0,
1667
+ 0,
1668
+ 20,
1669
+ 0,
1670
+ 0,
1671
+ 0,
1672
+ 0,
1673
+ 24,
1674
+ 0,
1675
+ 0,
1676
+ 0,
1677
+ 0,
1678
+ 20,
1679
+ 0,
1680
+ 0,
1681
+ 0,
1682
+ 0,
1683
+ 20,
1684
+ 0,
1685
+ 0,
1686
+ 0,
1687
+ 0,
1688
+ 0,
1689
+ 24,
1690
+ 0,
1691
+ 0,
1692
+ 0,
1693
+ 0,
1694
+ 0,
1695
+ 20,
1696
+ 0,
1697
+ 0,
1698
+ 20,
1699
+ 0,
1700
+ 0,
1701
+ 0,
1702
+ 0,
1703
+ 0,
1704
+ 0,
1705
+ 24,
1706
+ 0,
1707
+ 0,
1708
+ 0,
1709
+ 0,
1710
+ 0,
1711
+ 0,
1712
+ 20
1713
+ ];
1714
+ var RAYS = [
1715
+ 17,
1716
+ 0,
1717
+ 0,
1718
+ 0,
1719
+ 0,
1720
+ 0,
1721
+ 0,
1722
+ 16,
1723
+ 0,
1724
+ 0,
1725
+ 0,
1726
+ 0,
1727
+ 0,
1728
+ 0,
1729
+ 15,
1730
+ 0,
1731
+ 0,
1732
+ 17,
1733
+ 0,
1734
+ 0,
1735
+ 0,
1736
+ 0,
1737
+ 0,
1738
+ 16,
1739
+ 0,
1740
+ 0,
1741
+ 0,
1742
+ 0,
1743
+ 0,
1744
+ 15,
1745
+ 0,
1746
+ 0,
1747
+ 0,
1748
+ 0,
1749
+ 17,
1750
+ 0,
1751
+ 0,
1752
+ 0,
1753
+ 0,
1754
+ 16,
1755
+ 0,
1756
+ 0,
1757
+ 0,
1758
+ 0,
1759
+ 15,
1760
+ 0,
1761
+ 0,
1762
+ 0,
1763
+ 0,
1764
+ 0,
1765
+ 0,
1766
+ 17,
1767
+ 0,
1768
+ 0,
1769
+ 0,
1770
+ 16,
1771
+ 0,
1772
+ 0,
1773
+ 0,
1774
+ 15,
1775
+ 0,
1776
+ 0,
1777
+ 0,
1778
+ 0,
1779
+ 0,
1780
+ 0,
1781
+ 0,
1782
+ 0,
1783
+ 17,
1784
+ 0,
1785
+ 0,
1786
+ 16,
1787
+ 0,
1788
+ 0,
1789
+ 15,
1790
+ 0,
1791
+ 0,
1792
+ 0,
1793
+ 0,
1794
+ 0,
1795
+ 0,
1796
+ 0,
1797
+ 0,
1798
+ 0,
1799
+ 0,
1800
+ 17,
1801
+ 0,
1802
+ 16,
1803
+ 0,
1804
+ 15,
1805
+ 0,
1806
+ 0,
1807
+ 0,
1808
+ 0,
1809
+ 0,
1810
+ 0,
1811
+ 0,
1812
+ 0,
1813
+ 0,
1814
+ 0,
1815
+ 0,
1816
+ 0,
1817
+ 17,
1818
+ 16,
1819
+ 15,
1820
+ 0,
1821
+ 0,
1822
+ 0,
1823
+ 0,
1824
+ 0,
1825
+ 0,
1826
+ 0,
1827
+ 1,
1828
+ 1,
1829
+ 1,
1830
+ 1,
1831
+ 1,
1832
+ 1,
1833
+ 1,
1834
+ 0,
1835
+ -1,
1836
+ -1,
1837
+ -1,
1838
+ -1,
1839
+ -1,
1840
+ -1,
1841
+ -1,
1842
+ 0,
1843
+ 0,
1844
+ 0,
1845
+ 0,
1846
+ 0,
1847
+ 0,
1848
+ 0,
1849
+ -15,
1850
+ -16,
1851
+ -17,
1852
+ 0,
1853
+ 0,
1854
+ 0,
1855
+ 0,
1856
+ 0,
1857
+ 0,
1858
+ 0,
1859
+ 0,
1860
+ 0,
1861
+ 0,
1862
+ 0,
1863
+ 0,
1864
+ -15,
1865
+ 0,
1866
+ -16,
1867
+ 0,
1868
+ -17,
1869
+ 0,
1870
+ 0,
1871
+ 0,
1872
+ 0,
1873
+ 0,
1874
+ 0,
1875
+ 0,
1876
+ 0,
1877
+ 0,
1878
+ 0,
1879
+ -15,
1880
+ 0,
1881
+ 0,
1882
+ -16,
1883
+ 0,
1884
+ 0,
1885
+ -17,
1886
+ 0,
1887
+ 0,
1888
+ 0,
1889
+ 0,
1890
+ 0,
1891
+ 0,
1892
+ 0,
1893
+ 0,
1894
+ -15,
1895
+ 0,
1896
+ 0,
1897
+ 0,
1898
+ -16,
1899
+ 0,
1900
+ 0,
1901
+ 0,
1902
+ -17,
1903
+ 0,
1904
+ 0,
1905
+ 0,
1906
+ 0,
1907
+ 0,
1908
+ 0,
1909
+ -15,
1910
+ 0,
1911
+ 0,
1912
+ 0,
1913
+ 0,
1914
+ -16,
1915
+ 0,
1916
+ 0,
1917
+ 0,
1918
+ 0,
1919
+ -17,
1920
+ 0,
1921
+ 0,
1922
+ 0,
1923
+ 0,
1924
+ -15,
1925
+ 0,
1926
+ 0,
1927
+ 0,
1928
+ 0,
1929
+ 0,
1930
+ -16,
1931
+ 0,
1932
+ 0,
1933
+ 0,
1934
+ 0,
1935
+ 0,
1936
+ -17,
1937
+ 0,
1938
+ 0,
1939
+ -15,
1940
+ 0,
1941
+ 0,
1942
+ 0,
1943
+ 0,
1944
+ 0,
1945
+ 0,
1946
+ -16,
1947
+ 0,
1948
+ 0,
1949
+ 0,
1950
+ 0,
1951
+ 0,
1952
+ 0,
1953
+ -17
1954
+ ];
1955
+ var PIECE_MASKS = { p: 1, n: 2, b: 4, r: 8, q: 16, k: 32 };
1956
+ var SYMBOLS = "pnbrqkPNBRQK";
1957
+ var PROMOTIONS = [KNIGHT, BISHOP, ROOK, QUEEN];
1958
+ var RANK_1 = 7;
1959
+ var RANK_2 = 6;
1960
+ var RANK_7 = 1;
1961
+ var RANK_8 = 0;
1962
+ var SIDES = {
1963
+ [KING]: BITS.KSIDE_CASTLE,
1964
+ [QUEEN]: BITS.QSIDE_CASTLE
1965
+ };
1966
+ var ROOKS = {
1967
+ w: [
1968
+ { square: Ox88.a1, flag: BITS.QSIDE_CASTLE },
1969
+ { square: Ox88.h1, flag: BITS.KSIDE_CASTLE }
1970
+ ],
1971
+ b: [
1972
+ { square: Ox88.a8, flag: BITS.QSIDE_CASTLE },
1973
+ { square: Ox88.h8, flag: BITS.KSIDE_CASTLE }
1974
+ ]
1975
+ };
1976
+ var SECOND_RANK = { b: RANK_7, w: RANK_2 };
1977
+ var SAN_NULLMOVE = "--";
1978
+ function rank(square) {
1979
+ return square >> 4;
1980
+ }
1981
+ function file(square) {
1982
+ return square & 15;
1983
+ }
1984
+ function isDigit(c) {
1985
+ return "0123456789".indexOf(c) !== -1;
1986
+ }
1987
+ function algebraic(square) {
1988
+ const f = file(square);
1989
+ const r = rank(square);
1990
+ return "abcdefgh".substring(f, f + 1) + "87654321".substring(r, r + 1);
1991
+ }
1992
+ function swapColor(color) {
1993
+ return color === WHITE ? BLACK : WHITE;
1994
+ }
1995
+ function validateFen(fen) {
1996
+ const tokens = fen.split(/\s+/);
1997
+ if (tokens.length !== 6) {
1998
+ return {
1999
+ ok: false,
2000
+ error: "Invalid FEN: must contain six space-delimited fields"
2001
+ };
2002
+ }
2003
+ const moveNumber = parseInt(tokens[5], 10);
2004
+ if (isNaN(moveNumber) || moveNumber <= 0) {
2005
+ return {
2006
+ ok: false,
2007
+ error: "Invalid FEN: move number must be a positive integer"
2008
+ };
2009
+ }
2010
+ const halfMoves = parseInt(tokens[4], 10);
2011
+ if (isNaN(halfMoves) || halfMoves < 0) {
2012
+ return {
2013
+ ok: false,
2014
+ error: "Invalid FEN: half move counter number must be a non-negative integer"
2015
+ };
2016
+ }
2017
+ if (!/^(-|[abcdefgh][36])$/.test(tokens[3])) {
2018
+ return { ok: false, error: "Invalid FEN: en-passant square is invalid" };
2019
+ }
2020
+ if (/[^kKqQ-]/.test(tokens[2])) {
2021
+ return { ok: false, error: "Invalid FEN: castling availability is invalid" };
2022
+ }
2023
+ if (!/^(w|b)$/.test(tokens[1])) {
2024
+ return { ok: false, error: "Invalid FEN: side-to-move is invalid" };
2025
+ }
2026
+ const rows = tokens[0].split("/");
2027
+ if (rows.length !== 8) {
2028
+ return {
2029
+ ok: false,
2030
+ error: "Invalid FEN: piece data does not contain 8 '/'-delimited rows"
2031
+ };
2032
+ }
2033
+ for (let i = 0;i < rows.length; i++) {
2034
+ let sumFields = 0;
2035
+ let previousWasNumber = false;
2036
+ for (let k = 0;k < rows[i].length; k++) {
2037
+ if (isDigit(rows[i][k])) {
2038
+ if (previousWasNumber) {
2039
+ return {
2040
+ ok: false,
2041
+ error: "Invalid FEN: piece data is invalid (consecutive number)"
2042
+ };
2043
+ }
2044
+ sumFields += parseInt(rows[i][k], 10);
2045
+ previousWasNumber = true;
2046
+ } else {
2047
+ if (!/^[prnbqkPRNBQK]$/.test(rows[i][k])) {
2048
+ return {
2049
+ ok: false,
2050
+ error: "Invalid FEN: piece data is invalid (invalid piece)"
2051
+ };
2052
+ }
2053
+ sumFields += 1;
2054
+ previousWasNumber = false;
2055
+ }
2056
+ }
2057
+ if (sumFields !== 8) {
2058
+ return {
2059
+ ok: false,
2060
+ error: "Invalid FEN: piece data is invalid (too many squares in rank)"
2061
+ };
2062
+ }
2063
+ }
2064
+ if (tokens[3][1] == "3" && tokens[1] == "w" || tokens[3][1] == "6" && tokens[1] == "b") {
2065
+ return { ok: false, error: "Invalid FEN: illegal en-passant square" };
2066
+ }
2067
+ const kings = [
2068
+ { color: "white", regex: /K/g },
2069
+ { color: "black", regex: /k/g }
2070
+ ];
2071
+ for (const { color, regex } of kings) {
2072
+ if (!regex.test(tokens[0])) {
2073
+ return { ok: false, error: `Invalid FEN: missing ${color} king` };
2074
+ }
2075
+ if ((tokens[0].match(regex) || []).length > 1) {
2076
+ return { ok: false, error: `Invalid FEN: too many ${color} kings` };
2077
+ }
2078
+ }
2079
+ if (Array.from(rows[0] + rows[7]).some((char) => char.toUpperCase() === "P")) {
2080
+ return {
2081
+ ok: false,
2082
+ error: "Invalid FEN: some pawns are on the edge rows"
2083
+ };
2084
+ }
2085
+ return { ok: true };
2086
+ }
2087
+ function getDisambiguator(move, moves) {
2088
+ const from = move.from;
2089
+ const to = move.to;
2090
+ const piece = move.piece;
2091
+ let ambiguities = 0;
2092
+ let sameRank = 0;
2093
+ let sameFile = 0;
2094
+ for (let i = 0, len = moves.length;i < len; i++) {
2095
+ const ambigFrom = moves[i].from;
2096
+ const ambigTo = moves[i].to;
2097
+ const ambigPiece = moves[i].piece;
2098
+ if (piece === ambigPiece && from !== ambigFrom && to === ambigTo) {
2099
+ ambiguities++;
2100
+ if (rank(from) === rank(ambigFrom)) {
2101
+ sameRank++;
2102
+ }
2103
+ if (file(from) === file(ambigFrom)) {
2104
+ sameFile++;
2105
+ }
2106
+ }
2107
+ }
2108
+ if (ambiguities > 0) {
2109
+ if (sameRank > 0 && sameFile > 0) {
2110
+ return algebraic(from);
2111
+ } else if (sameFile > 0) {
2112
+ return algebraic(from).charAt(1);
2113
+ } else {
2114
+ return algebraic(from).charAt(0);
2115
+ }
2116
+ }
2117
+ return "";
2118
+ }
2119
+ function addMove(moves, color, from, to, piece, captured = undefined, flags = BITS.NORMAL) {
2120
+ const r = rank(to);
2121
+ if (piece === PAWN && (r === RANK_1 || r === RANK_8)) {
2122
+ for (let i = 0;i < PROMOTIONS.length; i++) {
2123
+ const promotion = PROMOTIONS[i];
2124
+ moves.push({
2125
+ color,
2126
+ from,
2127
+ to,
2128
+ piece,
2129
+ captured,
2130
+ promotion,
2131
+ flags: flags | BITS.PROMOTION
2132
+ });
2133
+ }
2134
+ } else {
2135
+ moves.push({
2136
+ color,
2137
+ from,
2138
+ to,
2139
+ piece,
2140
+ captured,
2141
+ flags
2142
+ });
2143
+ }
2144
+ }
2145
+ function inferPieceType(san) {
2146
+ let pieceType = san.charAt(0);
2147
+ if (pieceType >= "a" && pieceType <= "h") {
2148
+ const matches = san.match(/[a-h]\d.*[a-h]\d/);
2149
+ if (matches) {
2150
+ return;
2151
+ }
2152
+ return PAWN;
2153
+ }
2154
+ pieceType = pieceType.toLowerCase();
2155
+ if (pieceType === "o") {
2156
+ return KING;
2157
+ }
2158
+ return pieceType;
2159
+ }
2160
+ function strippedSan(move) {
2161
+ return move.replace(/=/, "").replace(/[+#]?[?!]*$/, "");
2162
+ }
2163
+
2164
+ class Chess {
2165
+ _board = new Array(128);
2166
+ _turn = WHITE;
2167
+ _header = {};
2168
+ _kings = { w: EMPTY, b: EMPTY };
2169
+ _epSquare = -1;
2170
+ _halfMoves = 0;
2171
+ _moveNumber = 0;
2172
+ _history = [];
2173
+ _comments = {};
2174
+ _castling = { w: 0, b: 0 };
2175
+ _hash = 0n;
2176
+ _positionCount = new Map;
2177
+ constructor(fen = DEFAULT_POSITION, { skipValidation = false } = {}) {
2178
+ this.load(fen, { skipValidation });
2179
+ }
2180
+ clear({ preserveHeaders = false } = {}) {
2181
+ this._board = new Array(128);
2182
+ this._kings = { w: EMPTY, b: EMPTY };
2183
+ this._turn = WHITE;
2184
+ this._castling = { w: 0, b: 0 };
2185
+ this._epSquare = EMPTY;
2186
+ this._halfMoves = 0;
2187
+ this._moveNumber = 1;
2188
+ this._history = [];
2189
+ this._comments = {};
2190
+ this._header = preserveHeaders ? this._header : { ...HEADER_TEMPLATE };
2191
+ this._hash = this._computeHash();
2192
+ this._positionCount = new Map;
2193
+ this._header["SetUp"] = null;
2194
+ this._header["FEN"] = null;
2195
+ }
2196
+ load(fen, { skipValidation = false, preserveHeaders = false } = {}) {
2197
+ let tokens = fen.split(/\s+/);
2198
+ if (tokens.length >= 2 && tokens.length < 6) {
2199
+ const adjustments = ["-", "-", "0", "1"];
2200
+ fen = tokens.concat(adjustments.slice(-(6 - tokens.length))).join(" ");
2201
+ }
2202
+ tokens = fen.split(/\s+/);
2203
+ if (!skipValidation) {
2204
+ const { ok, error } = validateFen(fen);
2205
+ if (!ok) {
2206
+ throw new Error(error);
2207
+ }
2208
+ }
2209
+ const position = tokens[0];
2210
+ let square = 0;
2211
+ this.clear({ preserveHeaders });
2212
+ for (let i = 0;i < position.length; i++) {
2213
+ const piece = position.charAt(i);
2214
+ if (piece === "/") {
2215
+ square += 8;
2216
+ } else if (isDigit(piece)) {
2217
+ square += parseInt(piece, 10);
2218
+ } else {
2219
+ const color = piece < "a" ? WHITE : BLACK;
2220
+ this._put({ type: piece.toLowerCase(), color }, algebraic(square));
2221
+ square++;
2222
+ }
2223
+ }
2224
+ this._turn = tokens[1];
2225
+ if (tokens[2].indexOf("K") > -1) {
2226
+ this._castling.w |= BITS.KSIDE_CASTLE;
2227
+ }
2228
+ if (tokens[2].indexOf("Q") > -1) {
2229
+ this._castling.w |= BITS.QSIDE_CASTLE;
2230
+ }
2231
+ if (tokens[2].indexOf("k") > -1) {
2232
+ this._castling.b |= BITS.KSIDE_CASTLE;
2233
+ }
2234
+ if (tokens[2].indexOf("q") > -1) {
2235
+ this._castling.b |= BITS.QSIDE_CASTLE;
2236
+ }
2237
+ this._epSquare = tokens[3] === "-" ? EMPTY : Ox88[tokens[3]];
2238
+ this._halfMoves = parseInt(tokens[4], 10);
2239
+ this._moveNumber = parseInt(tokens[5], 10);
2240
+ this._hash = this._computeHash();
2241
+ this._updateSetup(fen);
2242
+ this._incPositionCount();
2243
+ }
2244
+ fen({ forceEnpassantSquare = false } = {}) {
2245
+ let empty = 0;
2246
+ let fen = "";
2247
+ for (let i = Ox88.a8;i <= Ox88.h1; i++) {
2248
+ if (this._board[i]) {
2249
+ if (empty > 0) {
2250
+ fen += empty;
2251
+ empty = 0;
2252
+ }
2253
+ const { color, type: piece } = this._board[i];
2254
+ fen += color === WHITE ? piece.toUpperCase() : piece.toLowerCase();
2255
+ } else {
2256
+ empty++;
2257
+ }
2258
+ if (i + 1 & 136) {
2259
+ if (empty > 0) {
2260
+ fen += empty;
2261
+ }
2262
+ if (i !== Ox88.h1) {
2263
+ fen += "/";
2264
+ }
2265
+ empty = 0;
2266
+ i += 8;
2267
+ }
2268
+ }
2269
+ let castling = "";
2270
+ if (this._castling[WHITE] & BITS.KSIDE_CASTLE) {
2271
+ castling += "K";
2272
+ }
2273
+ if (this._castling[WHITE] & BITS.QSIDE_CASTLE) {
2274
+ castling += "Q";
2275
+ }
2276
+ if (this._castling[BLACK] & BITS.KSIDE_CASTLE) {
2277
+ castling += "k";
2278
+ }
2279
+ if (this._castling[BLACK] & BITS.QSIDE_CASTLE) {
2280
+ castling += "q";
2281
+ }
2282
+ castling = castling || "-";
2283
+ let epSquare = "-";
2284
+ if (this._epSquare !== EMPTY) {
2285
+ if (forceEnpassantSquare) {
2286
+ epSquare = algebraic(this._epSquare);
2287
+ } else {
2288
+ const bigPawnSquare = this._epSquare + (this._turn === WHITE ? 16 : -16);
2289
+ const squares = [bigPawnSquare + 1, bigPawnSquare - 1];
2290
+ for (const square of squares) {
2291
+ if (square & 136) {
2292
+ continue;
2293
+ }
2294
+ const color = this._turn;
2295
+ if (this._board[square]?.color === color && this._board[square]?.type === PAWN) {
2296
+ this._makeMove({
2297
+ color,
2298
+ from: square,
2299
+ to: this._epSquare,
2300
+ piece: PAWN,
2301
+ captured: PAWN,
2302
+ flags: BITS.EP_CAPTURE
2303
+ });
2304
+ const isLegal = !this._isKingAttacked(color);
2305
+ this._undoMove();
2306
+ if (isLegal) {
2307
+ epSquare = algebraic(this._epSquare);
2308
+ break;
2309
+ }
2310
+ }
2311
+ }
2312
+ }
2313
+ }
2314
+ return [
2315
+ fen,
2316
+ this._turn,
2317
+ castling,
2318
+ epSquare,
2319
+ this._halfMoves,
2320
+ this._moveNumber
2321
+ ].join(" ");
2322
+ }
2323
+ _pieceKey(i) {
2324
+ if (!this._board[i]) {
2325
+ return 0n;
2326
+ }
2327
+ const { color, type } = this._board[i];
2328
+ const colorIndex = {
2329
+ w: 0,
2330
+ b: 1
2331
+ }[color];
2332
+ const typeIndex = {
2333
+ p: 0,
2334
+ n: 1,
2335
+ b: 2,
2336
+ r: 3,
2337
+ q: 4,
2338
+ k: 5
2339
+ }[type];
2340
+ return PIECE_KEYS[colorIndex][typeIndex][i];
2341
+ }
2342
+ _epKey() {
2343
+ return this._epSquare === EMPTY ? 0n : EP_KEYS[this._epSquare & 7];
2344
+ }
2345
+ _castlingKey() {
2346
+ const index = this._castling.w >> 5 | this._castling.b >> 3;
2347
+ return CASTLING_KEYS[index];
2348
+ }
2349
+ _computeHash() {
2350
+ let hash = 0n;
2351
+ for (let i = Ox88.a8;i <= Ox88.h1; i++) {
2352
+ if (i & 136) {
2353
+ i += 7;
2354
+ continue;
2355
+ }
2356
+ if (this._board[i]) {
2357
+ hash ^= this._pieceKey(i);
2358
+ }
2359
+ }
2360
+ hash ^= this._epKey();
2361
+ hash ^= this._castlingKey();
2362
+ if (this._turn === "b") {
2363
+ hash ^= SIDE_KEY;
2364
+ }
2365
+ return hash;
2366
+ }
2367
+ _updateSetup(fen) {
2368
+ if (this._history.length > 0)
2369
+ return;
2370
+ if (fen !== DEFAULT_POSITION) {
2371
+ this._header["SetUp"] = "1";
2372
+ this._header["FEN"] = fen;
2373
+ } else {
2374
+ this._header["SetUp"] = null;
2375
+ this._header["FEN"] = null;
2376
+ }
2377
+ }
2378
+ reset() {
2379
+ this.load(DEFAULT_POSITION);
2380
+ }
2381
+ get(square) {
2382
+ return this._board[Ox88[square]];
2383
+ }
2384
+ findPiece(piece) {
2385
+ const squares = [];
2386
+ for (let i = Ox88.a8;i <= Ox88.h1; i++) {
2387
+ if (i & 136) {
2388
+ i += 7;
2389
+ continue;
2390
+ }
2391
+ if (!this._board[i] || this._board[i]?.color !== piece.color) {
2392
+ continue;
2393
+ }
2394
+ if (this._board[i].color === piece.color && this._board[i].type === piece.type) {
2395
+ squares.push(algebraic(i));
2396
+ }
2397
+ }
2398
+ return squares;
2399
+ }
2400
+ put({ type, color }, square) {
2401
+ if (this._put({ type, color }, square)) {
2402
+ this._updateCastlingRights();
2403
+ this._updateEnPassantSquare();
2404
+ this._updateSetup(this.fen());
2405
+ return true;
2406
+ }
2407
+ return false;
2408
+ }
2409
+ _set(sq, piece) {
2410
+ this._hash ^= this._pieceKey(sq);
2411
+ this._board[sq] = piece;
2412
+ this._hash ^= this._pieceKey(sq);
2413
+ }
2414
+ _put({ type, color }, square) {
2415
+ if (SYMBOLS.indexOf(type.toLowerCase()) === -1) {
2416
+ return false;
2417
+ }
2418
+ if (!(square in Ox88)) {
2419
+ return false;
2420
+ }
2421
+ const sq = Ox88[square];
2422
+ if (type == KING && !(this._kings[color] == EMPTY || this._kings[color] == sq)) {
2423
+ return false;
2424
+ }
2425
+ const currentPieceOnSquare = this._board[sq];
2426
+ if (currentPieceOnSquare && currentPieceOnSquare.type === KING) {
2427
+ this._kings[currentPieceOnSquare.color] = EMPTY;
2428
+ }
2429
+ this._set(sq, { type, color });
2430
+ if (type === KING) {
2431
+ this._kings[color] = sq;
2432
+ }
2433
+ return true;
2434
+ }
2435
+ _clear(sq) {
2436
+ this._hash ^= this._pieceKey(sq);
2437
+ delete this._board[sq];
2438
+ }
2439
+ remove(square) {
2440
+ const piece = this.get(square);
2441
+ this._clear(Ox88[square]);
2442
+ if (piece && piece.type === KING) {
2443
+ this._kings[piece.color] = EMPTY;
2444
+ }
2445
+ this._updateCastlingRights();
2446
+ this._updateEnPassantSquare();
2447
+ this._updateSetup(this.fen());
2448
+ return piece;
2449
+ }
2450
+ _updateCastlingRights() {
2451
+ this._hash ^= this._castlingKey();
2452
+ const whiteKingInPlace = this._board[Ox88.e1]?.type === KING && this._board[Ox88.e1]?.color === WHITE;
2453
+ const blackKingInPlace = this._board[Ox88.e8]?.type === KING && this._board[Ox88.e8]?.color === BLACK;
2454
+ if (!whiteKingInPlace || this._board[Ox88.a1]?.type !== ROOK || this._board[Ox88.a1]?.color !== WHITE) {
2455
+ this._castling.w &= -65;
2456
+ }
2457
+ if (!whiteKingInPlace || this._board[Ox88.h1]?.type !== ROOK || this._board[Ox88.h1]?.color !== WHITE) {
2458
+ this._castling.w &= -33;
2459
+ }
2460
+ if (!blackKingInPlace || this._board[Ox88.a8]?.type !== ROOK || this._board[Ox88.a8]?.color !== BLACK) {
2461
+ this._castling.b &= -65;
2462
+ }
2463
+ if (!blackKingInPlace || this._board[Ox88.h8]?.type !== ROOK || this._board[Ox88.h8]?.color !== BLACK) {
2464
+ this._castling.b &= -33;
2465
+ }
2466
+ this._hash ^= this._castlingKey();
2467
+ }
2468
+ _updateEnPassantSquare() {
2469
+ if (this._epSquare === EMPTY) {
2470
+ return;
2471
+ }
2472
+ const startSquare = this._epSquare + (this._turn === WHITE ? -16 : 16);
2473
+ const currentSquare = this._epSquare + (this._turn === WHITE ? 16 : -16);
2474
+ const attackers = [currentSquare + 1, currentSquare - 1];
2475
+ if (this._board[startSquare] !== null || this._board[this._epSquare] !== null || this._board[currentSquare]?.color !== swapColor(this._turn) || this._board[currentSquare]?.type !== PAWN) {
2476
+ this._hash ^= this._epKey();
2477
+ this._epSquare = EMPTY;
2478
+ return;
2479
+ }
2480
+ const canCapture = (square) => !(square & 136) && this._board[square]?.color === this._turn && this._board[square]?.type === PAWN;
2481
+ if (!attackers.some(canCapture)) {
2482
+ this._hash ^= this._epKey();
2483
+ this._epSquare = EMPTY;
2484
+ }
2485
+ }
2486
+ _attacked(color, square, verbose) {
2487
+ const attackers = [];
2488
+ for (let i = Ox88.a8;i <= Ox88.h1; i++) {
2489
+ if (i & 136) {
2490
+ i += 7;
2491
+ continue;
2492
+ }
2493
+ if (this._board[i] === undefined || this._board[i].color !== color) {
2494
+ continue;
2495
+ }
2496
+ const piece = this._board[i];
2497
+ const difference = i - square;
2498
+ if (difference === 0) {
2499
+ continue;
2500
+ }
2501
+ const index = difference + 119;
2502
+ if (ATTACKS[index] & PIECE_MASKS[piece.type]) {
2503
+ if (piece.type === PAWN) {
2504
+ if (difference > 0 && piece.color === WHITE || difference <= 0 && piece.color === BLACK) {
2505
+ if (!verbose) {
2506
+ return true;
2507
+ } else {
2508
+ attackers.push(algebraic(i));
2509
+ }
2510
+ }
2511
+ continue;
2512
+ }
2513
+ if (piece.type === "n" || piece.type === "k") {
2514
+ if (!verbose) {
2515
+ return true;
2516
+ } else {
2517
+ attackers.push(algebraic(i));
2518
+ continue;
2519
+ }
2520
+ }
2521
+ const offset = RAYS[index];
2522
+ let j = i + offset;
2523
+ let blocked = false;
2524
+ while (j !== square) {
2525
+ if (this._board[j] != null) {
2526
+ blocked = true;
2527
+ break;
2528
+ }
2529
+ j += offset;
2530
+ }
2531
+ if (!blocked) {
2532
+ if (!verbose) {
2533
+ return true;
2534
+ } else {
2535
+ attackers.push(algebraic(i));
2536
+ continue;
2537
+ }
2538
+ }
2539
+ }
2540
+ }
2541
+ if (verbose) {
2542
+ return attackers;
2543
+ } else {
2544
+ return false;
2545
+ }
2546
+ }
2547
+ attackers(square, attackedBy) {
2548
+ if (!attackedBy) {
2549
+ return this._attacked(this._turn, Ox88[square], true);
2550
+ } else {
2551
+ return this._attacked(attackedBy, Ox88[square], true);
2552
+ }
2553
+ }
2554
+ _isKingAttacked(color) {
2555
+ const square = this._kings[color];
2556
+ return square === -1 ? false : this._attacked(swapColor(color), square);
2557
+ }
2558
+ hash() {
2559
+ return this._hash.toString(16);
2560
+ }
2561
+ isAttacked(square, attackedBy) {
2562
+ return this._attacked(attackedBy, Ox88[square]);
2563
+ }
2564
+ isCheck() {
2565
+ return this._isKingAttacked(this._turn);
2566
+ }
2567
+ inCheck() {
2568
+ return this.isCheck();
2569
+ }
2570
+ isCheckmate() {
2571
+ return this.isCheck() && this._moves().length === 0;
2572
+ }
2573
+ isStalemate() {
2574
+ return !this.isCheck() && this._moves().length === 0;
2575
+ }
2576
+ isInsufficientMaterial() {
2577
+ const pieces = {
2578
+ b: 0,
2579
+ n: 0,
2580
+ r: 0,
2581
+ q: 0,
2582
+ k: 0,
2583
+ p: 0
2584
+ };
2585
+ const bishops = [];
2586
+ let numPieces = 0;
2587
+ let squareColor = 0;
2588
+ for (let i = Ox88.a8;i <= Ox88.h1; i++) {
2589
+ squareColor = (squareColor + 1) % 2;
2590
+ if (i & 136) {
2591
+ i += 7;
2592
+ continue;
2593
+ }
2594
+ const piece = this._board[i];
2595
+ if (piece) {
2596
+ pieces[piece.type] = piece.type in pieces ? pieces[piece.type] + 1 : 1;
2597
+ if (piece.type === BISHOP) {
2598
+ bishops.push(squareColor);
2599
+ }
2600
+ numPieces++;
2601
+ }
2602
+ }
2603
+ if (numPieces === 2) {
2604
+ return true;
2605
+ } else if (numPieces === 3 && (pieces[BISHOP] === 1 || pieces[KNIGHT] === 1)) {
2606
+ return true;
2607
+ } else if (numPieces === pieces[BISHOP] + 2) {
2608
+ let sum = 0;
2609
+ const len = bishops.length;
2610
+ for (let i = 0;i < len; i++) {
2611
+ sum += bishops[i];
2612
+ }
2613
+ if (sum === 0 || sum === len) {
2614
+ return true;
2615
+ }
2616
+ }
2617
+ return false;
2618
+ }
2619
+ isThreefoldRepetition() {
2620
+ return this._getPositionCount(this._hash) >= 3;
2621
+ }
2622
+ isDrawByFiftyMoves() {
2623
+ return this._halfMoves >= 100;
2624
+ }
2625
+ isDraw() {
2626
+ return this.isDrawByFiftyMoves() || this.isStalemate() || this.isInsufficientMaterial() || this.isThreefoldRepetition();
2627
+ }
2628
+ isGameOver() {
2629
+ return this.isCheckmate() || this.isDraw();
2630
+ }
2631
+ moves({ verbose = false, square = undefined, piece = undefined } = {}) {
2632
+ const moves = this._moves({ square, piece });
2633
+ if (verbose) {
2634
+ return moves.map((move) => new Move(this, move));
2635
+ } else {
2636
+ return moves.map((move) => this._moveToSan(move, moves));
2637
+ }
2638
+ }
2639
+ _moves({ legal = true, piece = undefined, square = undefined } = {}) {
2640
+ const forSquare = square ? square.toLowerCase() : undefined;
2641
+ const forPiece = piece?.toLowerCase();
2642
+ const moves = [];
2643
+ const us = this._turn;
2644
+ const them = swapColor(us);
2645
+ let firstSquare = Ox88.a8;
2646
+ let lastSquare = Ox88.h1;
2647
+ let singleSquare = false;
2648
+ if (forSquare) {
2649
+ if (!(forSquare in Ox88)) {
2650
+ return [];
2651
+ } else {
2652
+ firstSquare = lastSquare = Ox88[forSquare];
2653
+ singleSquare = true;
2654
+ }
2655
+ }
2656
+ for (let from = firstSquare;from <= lastSquare; from++) {
2657
+ if (from & 136) {
2658
+ from += 7;
2659
+ continue;
2660
+ }
2661
+ if (!this._board[from] || this._board[from].color === them) {
2662
+ continue;
2663
+ }
2664
+ const { type } = this._board[from];
2665
+ let to;
2666
+ if (type === PAWN) {
2667
+ if (forPiece && forPiece !== type)
2668
+ continue;
2669
+ to = from + PAWN_OFFSETS[us][0];
2670
+ if (!this._board[to]) {
2671
+ addMove(moves, us, from, to, PAWN);
2672
+ to = from + PAWN_OFFSETS[us][1];
2673
+ if (SECOND_RANK[us] === rank(from) && !this._board[to]) {
2674
+ addMove(moves, us, from, to, PAWN, undefined, BITS.BIG_PAWN);
2675
+ }
2676
+ }
2677
+ for (let j = 2;j < 4; j++) {
2678
+ to = from + PAWN_OFFSETS[us][j];
2679
+ if (to & 136)
2680
+ continue;
2681
+ if (this._board[to]?.color === them) {
2682
+ addMove(moves, us, from, to, PAWN, this._board[to].type, BITS.CAPTURE);
2683
+ } else if (to === this._epSquare) {
2684
+ addMove(moves, us, from, to, PAWN, PAWN, BITS.EP_CAPTURE);
2685
+ }
2686
+ }
2687
+ } else {
2688
+ if (forPiece && forPiece !== type)
2689
+ continue;
2690
+ for (let j = 0, len = PIECE_OFFSETS[type].length;j < len; j++) {
2691
+ const offset = PIECE_OFFSETS[type][j];
2692
+ to = from;
2693
+ while (true) {
2694
+ to += offset;
2695
+ if (to & 136)
2696
+ break;
2697
+ if (!this._board[to]) {
2698
+ addMove(moves, us, from, to, type);
2699
+ } else {
2700
+ if (this._board[to].color === us)
2701
+ break;
2702
+ addMove(moves, us, from, to, type, this._board[to].type, BITS.CAPTURE);
2703
+ break;
2704
+ }
2705
+ if (type === KNIGHT || type === KING)
2706
+ break;
2707
+ }
2708
+ }
2709
+ }
2710
+ }
2711
+ if (forPiece === undefined || forPiece === KING) {
2712
+ if (!singleSquare || lastSquare === this._kings[us]) {
2713
+ if (this._castling[us] & BITS.KSIDE_CASTLE) {
2714
+ const castlingFrom = this._kings[us];
2715
+ const castlingTo = castlingFrom + 2;
2716
+ if (!this._board[castlingFrom + 1] && !this._board[castlingTo] && !this._attacked(them, this._kings[us]) && !this._attacked(them, castlingFrom + 1) && !this._attacked(them, castlingTo)) {
2717
+ addMove(moves, us, this._kings[us], castlingTo, KING, undefined, BITS.KSIDE_CASTLE);
2718
+ }
2719
+ }
2720
+ if (this._castling[us] & BITS.QSIDE_CASTLE) {
2721
+ const castlingFrom = this._kings[us];
2722
+ const castlingTo = castlingFrom - 2;
2723
+ if (!this._board[castlingFrom - 1] && !this._board[castlingFrom - 2] && !this._board[castlingFrom - 3] && !this._attacked(them, this._kings[us]) && !this._attacked(them, castlingFrom - 1) && !this._attacked(them, castlingTo)) {
2724
+ addMove(moves, us, this._kings[us], castlingTo, KING, undefined, BITS.QSIDE_CASTLE);
2725
+ }
2726
+ }
2727
+ }
2728
+ }
2729
+ if (!legal || this._kings[us] === -1) {
2730
+ return moves;
2731
+ }
2732
+ const legalMoves = [];
2733
+ for (let i = 0, len = moves.length;i < len; i++) {
2734
+ this._makeMove(moves[i]);
2735
+ if (!this._isKingAttacked(us)) {
2736
+ legalMoves.push(moves[i]);
2737
+ }
2738
+ this._undoMove();
2739
+ }
2740
+ return legalMoves;
2741
+ }
2742
+ move(move, { strict = false } = {}) {
2743
+ let moveObj = null;
2744
+ if (typeof move === "string") {
2745
+ moveObj = this._moveFromSan(move, strict);
2746
+ } else if (move === null) {
2747
+ moveObj = this._moveFromSan(SAN_NULLMOVE, strict);
2748
+ } else if (typeof move === "object") {
2749
+ const moves = this._moves();
2750
+ for (let i = 0, len = moves.length;i < len; i++) {
2751
+ if (move.from === algebraic(moves[i].from) && move.to === algebraic(moves[i].to) && (!("promotion" in moves[i]) || move.promotion === moves[i].promotion)) {
2752
+ moveObj = moves[i];
2753
+ break;
2754
+ }
2755
+ }
2756
+ }
2757
+ if (!moveObj) {
2758
+ if (typeof move === "string") {
2759
+ throw new Error(`Invalid move: ${move}`);
2760
+ } else {
2761
+ throw new Error(`Invalid move: ${JSON.stringify(move)}`);
2762
+ }
2763
+ }
2764
+ if (this.isCheck() && moveObj.flags & BITS.NULL_MOVE) {
2765
+ throw new Error("Null move not allowed when in check");
2766
+ }
2767
+ const prettyMove = new Move(this, moveObj);
2768
+ this._makeMove(moveObj);
2769
+ this._incPositionCount();
2770
+ return prettyMove;
2771
+ }
2772
+ _push(move) {
2773
+ this._history.push({
2774
+ move,
2775
+ kings: { b: this._kings.b, w: this._kings.w },
2776
+ turn: this._turn,
2777
+ castling: { b: this._castling.b, w: this._castling.w },
2778
+ epSquare: this._epSquare,
2779
+ halfMoves: this._halfMoves,
2780
+ moveNumber: this._moveNumber
2781
+ });
2782
+ }
2783
+ _movePiece(from, to) {
2784
+ this._hash ^= this._pieceKey(from);
2785
+ this._board[to] = this._board[from];
2786
+ delete this._board[from];
2787
+ this._hash ^= this._pieceKey(to);
2788
+ }
2789
+ _makeMove(move) {
2790
+ const us = this._turn;
2791
+ const them = swapColor(us);
2792
+ this._push(move);
2793
+ if (move.flags & BITS.NULL_MOVE) {
2794
+ if (us === BLACK) {
2795
+ this._moveNumber++;
2796
+ }
2797
+ this._halfMoves++;
2798
+ this._turn = them;
2799
+ this._epSquare = EMPTY;
2800
+ return;
2801
+ }
2802
+ this._hash ^= this._epKey();
2803
+ this._hash ^= this._castlingKey();
2804
+ if (move.captured) {
2805
+ this._hash ^= this._pieceKey(move.to);
2806
+ }
2807
+ this._movePiece(move.from, move.to);
2808
+ if (move.flags & BITS.EP_CAPTURE) {
2809
+ if (this._turn === BLACK) {
2810
+ this._clear(move.to - 16);
2811
+ } else {
2812
+ this._clear(move.to + 16);
2813
+ }
2814
+ }
2815
+ if (move.promotion) {
2816
+ this._clear(move.to);
2817
+ this._set(move.to, { type: move.promotion, color: us });
2818
+ }
2819
+ if (this._board[move.to].type === KING) {
2820
+ this._kings[us] = move.to;
2821
+ if (move.flags & BITS.KSIDE_CASTLE) {
2822
+ const castlingTo = move.to - 1;
2823
+ const castlingFrom = move.to + 1;
2824
+ this._movePiece(castlingFrom, castlingTo);
2825
+ } else if (move.flags & BITS.QSIDE_CASTLE) {
2826
+ const castlingTo = move.to + 1;
2827
+ const castlingFrom = move.to - 2;
2828
+ this._movePiece(castlingFrom, castlingTo);
2829
+ }
2830
+ this._castling[us] = 0;
2831
+ }
2832
+ if (this._castling[us]) {
2833
+ for (let i = 0, len = ROOKS[us].length;i < len; i++) {
2834
+ if (move.from === ROOKS[us][i].square && this._castling[us] & ROOKS[us][i].flag) {
2835
+ this._castling[us] ^= ROOKS[us][i].flag;
2836
+ break;
2837
+ }
2838
+ }
2839
+ }
2840
+ if (this._castling[them]) {
2841
+ for (let i = 0, len = ROOKS[them].length;i < len; i++) {
2842
+ if (move.to === ROOKS[them][i].square && this._castling[them] & ROOKS[them][i].flag) {
2843
+ this._castling[them] ^= ROOKS[them][i].flag;
2844
+ break;
2845
+ }
2846
+ }
2847
+ }
2848
+ this._hash ^= this._castlingKey();
2849
+ if (move.flags & BITS.BIG_PAWN) {
2850
+ let epSquare;
2851
+ if (us === BLACK) {
2852
+ epSquare = move.to - 16;
2853
+ } else {
2854
+ epSquare = move.to + 16;
2855
+ }
2856
+ if (!(move.to - 1 & 136) && this._board[move.to - 1]?.type === PAWN && this._board[move.to - 1]?.color === them || !(move.to + 1 & 136) && this._board[move.to + 1]?.type === PAWN && this._board[move.to + 1]?.color === them) {
2857
+ this._epSquare = epSquare;
2858
+ this._hash ^= this._epKey();
2859
+ } else {
2860
+ this._epSquare = EMPTY;
2861
+ }
2862
+ } else {
2863
+ this._epSquare = EMPTY;
2864
+ }
2865
+ if (move.piece === PAWN) {
2866
+ this._halfMoves = 0;
2867
+ } else if (move.flags & (BITS.CAPTURE | BITS.EP_CAPTURE)) {
2868
+ this._halfMoves = 0;
2869
+ } else {
2870
+ this._halfMoves++;
2871
+ }
2872
+ if (us === BLACK) {
2873
+ this._moveNumber++;
2874
+ }
2875
+ this._turn = them;
2876
+ this._hash ^= SIDE_KEY;
2877
+ }
2878
+ undo() {
2879
+ const hash = this._hash;
2880
+ const move = this._undoMove();
2881
+ if (move) {
2882
+ const prettyMove = new Move(this, move);
2883
+ this._decPositionCount(hash);
2884
+ return prettyMove;
2885
+ }
2886
+ return null;
2887
+ }
2888
+ _undoMove() {
2889
+ const old = this._history.pop();
2890
+ if (old === undefined) {
2891
+ return null;
2892
+ }
2893
+ this._hash ^= this._epKey();
2894
+ this._hash ^= this._castlingKey();
2895
+ const move = old.move;
2896
+ this._kings = old.kings;
2897
+ this._turn = old.turn;
2898
+ this._castling = old.castling;
2899
+ this._epSquare = old.epSquare;
2900
+ this._halfMoves = old.halfMoves;
2901
+ this._moveNumber = old.moveNumber;
2902
+ this._hash ^= this._epKey();
2903
+ this._hash ^= this._castlingKey();
2904
+ this._hash ^= SIDE_KEY;
2905
+ const us = this._turn;
2906
+ const them = swapColor(us);
2907
+ if (move.flags & BITS.NULL_MOVE) {
2908
+ return move;
2909
+ }
2910
+ this._movePiece(move.to, move.from);
2911
+ if (move.piece) {
2912
+ this._clear(move.from);
2913
+ this._set(move.from, { type: move.piece, color: us });
2914
+ }
2915
+ if (move.captured) {
2916
+ if (move.flags & BITS.EP_CAPTURE) {
2917
+ let index;
2918
+ if (us === BLACK) {
2919
+ index = move.to - 16;
2920
+ } else {
2921
+ index = move.to + 16;
2922
+ }
2923
+ this._set(index, { type: PAWN, color: them });
2924
+ } else {
2925
+ this._set(move.to, { type: move.captured, color: them });
2926
+ }
2927
+ }
2928
+ if (move.flags & (BITS.KSIDE_CASTLE | BITS.QSIDE_CASTLE)) {
2929
+ let castlingTo, castlingFrom;
2930
+ if (move.flags & BITS.KSIDE_CASTLE) {
2931
+ castlingTo = move.to + 1;
2932
+ castlingFrom = move.to - 1;
2933
+ } else {
2934
+ castlingTo = move.to - 2;
2935
+ castlingFrom = move.to + 1;
2936
+ }
2937
+ this._movePiece(castlingFrom, castlingTo);
2938
+ }
2939
+ return move;
2940
+ }
2941
+ pgn({ newline = `
2942
+ `, maxWidth = 0 } = {}) {
2943
+ const result = [];
2944
+ let headerExists = false;
2945
+ for (const i in this._header) {
2946
+ const headerTag = this._header[i];
2947
+ if (headerTag)
2948
+ result.push(`[${i} "${this._header[i]}"]` + newline);
2949
+ headerExists = true;
2950
+ }
2951
+ if (headerExists && this._history.length) {
2952
+ result.push(newline);
2953
+ }
2954
+ const appendComment = (moveString) => {
2955
+ const comment = this._comments[this.fen()];
2956
+ if (typeof comment !== "undefined") {
2957
+ const delimiter = moveString.length > 0 ? " " : "";
2958
+ moveString = `${moveString}${delimiter}{${comment}}`;
2959
+ }
2960
+ return moveString;
2961
+ };
2962
+ const reversedHistory = [];
2963
+ while (this._history.length > 0) {
2964
+ reversedHistory.push(this._undoMove());
2965
+ }
2966
+ const moves = [];
2967
+ let moveString = "";
2968
+ if (reversedHistory.length === 0) {
2969
+ moves.push(appendComment(""));
2970
+ }
2971
+ while (reversedHistory.length > 0) {
2972
+ moveString = appendComment(moveString);
2973
+ const move = reversedHistory.pop();
2974
+ if (!move) {
2975
+ break;
2976
+ }
2977
+ if (!this._history.length && move.color === "b") {
2978
+ const prefix = `${this._moveNumber}. ...`;
2979
+ moveString = moveString ? `${moveString} ${prefix}` : prefix;
2980
+ } else if (move.color === "w") {
2981
+ if (moveString.length) {
2982
+ moves.push(moveString);
2983
+ }
2984
+ moveString = this._moveNumber + ".";
2985
+ }
2986
+ moveString = moveString + " " + this._moveToSan(move, this._moves({ legal: true }));
2987
+ this._makeMove(move);
2988
+ }
2989
+ if (moveString.length) {
2990
+ moves.push(appendComment(moveString));
2991
+ }
2992
+ moves.push(this._header.Result || "*");
2993
+ if (maxWidth === 0) {
2994
+ return result.join("") + moves.join(" ");
2995
+ }
2996
+ const strip = function() {
2997
+ if (result.length > 0 && result[result.length - 1] === " ") {
2998
+ result.pop();
2999
+ return true;
3000
+ }
3001
+ return false;
3002
+ };
3003
+ const wrapComment = function(width, move) {
3004
+ for (const token of move.split(" ")) {
3005
+ if (!token) {
3006
+ continue;
3007
+ }
3008
+ if (width + token.length > maxWidth) {
3009
+ while (strip()) {
3010
+ width--;
3011
+ }
3012
+ result.push(newline);
3013
+ width = 0;
3014
+ }
3015
+ result.push(token);
3016
+ width += token.length;
3017
+ result.push(" ");
3018
+ width++;
3019
+ }
3020
+ if (strip()) {
3021
+ width--;
3022
+ }
3023
+ return width;
3024
+ };
3025
+ let currentWidth = 0;
3026
+ for (let i = 0;i < moves.length; i++) {
3027
+ if (currentWidth + moves[i].length > maxWidth) {
3028
+ if (moves[i].includes("{")) {
3029
+ currentWidth = wrapComment(currentWidth, moves[i]);
3030
+ continue;
3031
+ }
3032
+ }
3033
+ if (currentWidth + moves[i].length > maxWidth && i !== 0) {
3034
+ if (result[result.length - 1] === " ") {
3035
+ result.pop();
3036
+ }
3037
+ result.push(newline);
3038
+ currentWidth = 0;
3039
+ } else if (i !== 0) {
3040
+ result.push(" ");
3041
+ currentWidth++;
3042
+ }
3043
+ result.push(moves[i]);
3044
+ currentWidth += moves[i].length;
3045
+ }
3046
+ return result.join("");
3047
+ }
3048
+ header(...args) {
3049
+ for (let i = 0;i < args.length; i += 2) {
3050
+ if (typeof args[i] === "string" && typeof args[i + 1] === "string") {
3051
+ this._header[args[i]] = args[i + 1];
3052
+ }
3053
+ }
3054
+ return this._header;
3055
+ }
3056
+ setHeader(key, value) {
3057
+ this._header[key] = value ?? SEVEN_TAG_ROSTER[key] ?? null;
3058
+ return this.getHeaders();
3059
+ }
3060
+ removeHeader(key) {
3061
+ if (key in this._header) {
3062
+ this._header[key] = SEVEN_TAG_ROSTER[key] || null;
3063
+ return true;
3064
+ }
3065
+ return false;
3066
+ }
3067
+ getHeaders() {
3068
+ const nonNullHeaders = {};
3069
+ for (const [key, value] of Object.entries(this._header)) {
3070
+ if (value !== null) {
3071
+ nonNullHeaders[key] = value;
3072
+ }
3073
+ }
3074
+ return nonNullHeaders;
3075
+ }
3076
+ loadPgn(pgn, { strict = false, newlineChar = `\r?
3077
+ ` } = {}) {
3078
+ if (newlineChar !== `\r?
3079
+ `) {
3080
+ pgn = pgn.replace(new RegExp(newlineChar, "g"), `
3081
+ `);
3082
+ }
3083
+ const parsedPgn = peg$parse(pgn);
3084
+ this.reset();
3085
+ const headers = parsedPgn.headers;
3086
+ let fen = "";
3087
+ for (const key in headers) {
3088
+ if (key.toLowerCase() === "fen") {
3089
+ fen = headers[key];
3090
+ }
3091
+ this.header(key, headers[key]);
3092
+ }
3093
+ if (!strict) {
3094
+ if (fen) {
3095
+ this.load(fen, { preserveHeaders: true });
3096
+ }
3097
+ } else {
3098
+ if (headers["SetUp"] === "1") {
3099
+ if (!("FEN" in headers)) {
3100
+ throw new Error("Invalid PGN: FEN tag must be supplied with SetUp tag");
3101
+ }
3102
+ this.load(headers["FEN"], { preserveHeaders: true });
3103
+ }
3104
+ }
3105
+ let node = parsedPgn.root;
3106
+ while (node) {
3107
+ if (node.move) {
3108
+ const move = this._moveFromSan(node.move, strict);
3109
+ if (move == null) {
3110
+ throw new Error(`Invalid move in PGN: ${node.move}`);
3111
+ } else {
3112
+ this._makeMove(move);
3113
+ this._incPositionCount();
3114
+ }
3115
+ }
3116
+ if (node.comment !== undefined) {
3117
+ this._comments[this.fen()] = node.comment;
3118
+ }
3119
+ node = node.variations[0];
3120
+ }
3121
+ const result = parsedPgn.result;
3122
+ if (result && Object.keys(this._header).length && this._header["Result"] !== result) {
3123
+ this.setHeader("Result", result);
3124
+ }
3125
+ }
3126
+ _moveToSan(move, moves) {
3127
+ let output = "";
3128
+ if (move.flags & BITS.KSIDE_CASTLE) {
3129
+ output = "O-O";
3130
+ } else if (move.flags & BITS.QSIDE_CASTLE) {
3131
+ output = "O-O-O";
3132
+ } else if (move.flags & BITS.NULL_MOVE) {
3133
+ return SAN_NULLMOVE;
3134
+ } else {
3135
+ if (move.piece !== PAWN) {
3136
+ const disambiguator = getDisambiguator(move, moves);
3137
+ output += move.piece.toUpperCase() + disambiguator;
3138
+ }
3139
+ if (move.flags & (BITS.CAPTURE | BITS.EP_CAPTURE)) {
3140
+ if (move.piece === PAWN) {
3141
+ output += algebraic(move.from)[0];
3142
+ }
3143
+ output += "x";
3144
+ }
3145
+ output += algebraic(move.to);
3146
+ if (move.promotion) {
3147
+ output += "=" + move.promotion.toUpperCase();
3148
+ }
3149
+ }
3150
+ this._makeMove(move);
3151
+ if (this.isCheck()) {
3152
+ if (this.isCheckmate()) {
3153
+ output += "#";
3154
+ } else {
3155
+ output += "+";
3156
+ }
3157
+ }
3158
+ this._undoMove();
3159
+ return output;
3160
+ }
3161
+ _moveFromSan(move, strict = false) {
3162
+ let cleanMove = strippedSan(move);
3163
+ if (!strict) {
3164
+ if (cleanMove === "0-0") {
3165
+ cleanMove = "O-O";
3166
+ } else if (cleanMove === "0-0-0") {
3167
+ cleanMove = "O-O-O";
3168
+ }
3169
+ }
3170
+ if (cleanMove == SAN_NULLMOVE) {
3171
+ const res = {
3172
+ color: this._turn,
3173
+ from: 0,
3174
+ to: 0,
3175
+ piece: "k",
3176
+ flags: BITS.NULL_MOVE
3177
+ };
3178
+ return res;
3179
+ }
3180
+ let pieceType = inferPieceType(cleanMove);
3181
+ let moves = this._moves({ legal: true, piece: pieceType });
3182
+ for (let i = 0, len = moves.length;i < len; i++) {
3183
+ if (cleanMove === strippedSan(this._moveToSan(moves[i], moves))) {
3184
+ return moves[i];
3185
+ }
3186
+ }
3187
+ if (strict) {
3188
+ return null;
3189
+ }
3190
+ let piece = undefined;
3191
+ let matches = undefined;
3192
+ let from = undefined;
3193
+ let to = undefined;
3194
+ let promotion = undefined;
3195
+ let overlyDisambiguated = false;
3196
+ matches = cleanMove.match(/([pnbrqkPNBRQK])?([a-h][1-8])x?-?([a-h][1-8])([qrbnQRBN])?/);
3197
+ if (matches) {
3198
+ piece = matches[1];
3199
+ from = matches[2];
3200
+ to = matches[3];
3201
+ promotion = matches[4];
3202
+ if (from.length == 1) {
3203
+ overlyDisambiguated = true;
3204
+ }
3205
+ } else {
3206
+ matches = cleanMove.match(/([pnbrqkPNBRQK])?([a-h]?[1-8]?)x?-?([a-h][1-8])([qrbnQRBN])?/);
3207
+ if (matches) {
3208
+ piece = matches[1];
3209
+ from = matches[2];
3210
+ to = matches[3];
3211
+ promotion = matches[4];
3212
+ if (from.length == 1) {
3213
+ overlyDisambiguated = true;
3214
+ }
3215
+ }
3216
+ }
3217
+ pieceType = inferPieceType(cleanMove);
3218
+ moves = this._moves({
3219
+ legal: true,
3220
+ piece: piece ? piece : pieceType
3221
+ });
3222
+ if (!to) {
3223
+ return null;
3224
+ }
3225
+ for (let i = 0, len = moves.length;i < len; i++) {
3226
+ if (!from) {
3227
+ if (cleanMove === strippedSan(this._moveToSan(moves[i], moves)).replace("x", "")) {
3228
+ return moves[i];
3229
+ }
3230
+ } else if ((!piece || piece.toLowerCase() == moves[i].piece) && Ox88[from] == moves[i].from && Ox88[to] == moves[i].to && (!promotion || promotion.toLowerCase() == moves[i].promotion)) {
3231
+ return moves[i];
3232
+ } else if (overlyDisambiguated) {
3233
+ const square = algebraic(moves[i].from);
3234
+ if ((!piece || piece.toLowerCase() == moves[i].piece) && Ox88[to] == moves[i].to && (from == square[0] || from == square[1]) && (!promotion || promotion.toLowerCase() == moves[i].promotion)) {
3235
+ return moves[i];
3236
+ }
3237
+ }
3238
+ }
3239
+ return null;
3240
+ }
3241
+ ascii() {
3242
+ let s = ` +------------------------+
3243
+ `;
3244
+ for (let i = Ox88.a8;i <= Ox88.h1; i++) {
3245
+ if (file(i) === 0) {
3246
+ s += " " + "87654321"[rank(i)] + " |";
3247
+ }
3248
+ if (this._board[i]) {
3249
+ const piece = this._board[i].type;
3250
+ const color = this._board[i].color;
3251
+ const symbol = color === WHITE ? piece.toUpperCase() : piece.toLowerCase();
3252
+ s += " " + symbol + " ";
3253
+ } else {
3254
+ s += " . ";
3255
+ }
3256
+ if (i + 1 & 136) {
3257
+ s += `|
3258
+ `;
3259
+ i += 8;
3260
+ }
3261
+ }
3262
+ s += ` +------------------------+
3263
+ `;
3264
+ s += " a b c d e f g h";
3265
+ return s;
3266
+ }
3267
+ perft(depth) {
3268
+ const moves = this._moves({ legal: false });
3269
+ let nodes = 0;
3270
+ const color = this._turn;
3271
+ for (let i = 0, len = moves.length;i < len; i++) {
3272
+ this._makeMove(moves[i]);
3273
+ if (!this._isKingAttacked(color)) {
3274
+ if (depth - 1 > 0) {
3275
+ nodes += this.perft(depth - 1);
3276
+ } else {
3277
+ nodes++;
3278
+ }
3279
+ }
3280
+ this._undoMove();
3281
+ }
3282
+ return nodes;
3283
+ }
3284
+ setTurn(color) {
3285
+ if (this._turn == color) {
3286
+ return false;
3287
+ }
3288
+ this.move("--");
3289
+ return true;
3290
+ }
3291
+ turn() {
3292
+ return this._turn;
3293
+ }
3294
+ board() {
3295
+ const output = [];
3296
+ let row = [];
3297
+ for (let i = Ox88.a8;i <= Ox88.h1; i++) {
3298
+ if (this._board[i] == null) {
3299
+ row.push(null);
3300
+ } else {
3301
+ row.push({
3302
+ square: algebraic(i),
3303
+ type: this._board[i].type,
3304
+ color: this._board[i].color
3305
+ });
3306
+ }
3307
+ if (i + 1 & 136) {
3308
+ output.push(row);
3309
+ row = [];
3310
+ i += 8;
3311
+ }
3312
+ }
3313
+ return output;
3314
+ }
3315
+ squareColor(square) {
3316
+ if (square in Ox88) {
3317
+ const sq = Ox88[square];
3318
+ return (rank(sq) + file(sq)) % 2 === 0 ? "light" : "dark";
3319
+ }
3320
+ return null;
3321
+ }
3322
+ history({ verbose = false } = {}) {
3323
+ const reversedHistory = [];
3324
+ const moveHistory = [];
3325
+ while (this._history.length > 0) {
3326
+ reversedHistory.push(this._undoMove());
3327
+ }
3328
+ while (true) {
3329
+ const move = reversedHistory.pop();
3330
+ if (!move) {
3331
+ break;
3332
+ }
3333
+ if (verbose) {
3334
+ moveHistory.push(new Move(this, move));
3335
+ } else {
3336
+ moveHistory.push(this._moveToSan(move, this._moves()));
3337
+ }
3338
+ this._makeMove(move);
3339
+ }
3340
+ return moveHistory;
3341
+ }
3342
+ _getPositionCount(hash) {
3343
+ return this._positionCount.get(hash) ?? 0;
3344
+ }
3345
+ _incPositionCount() {
3346
+ this._positionCount.set(this._hash, (this._positionCount.get(this._hash) ?? 0) + 1);
3347
+ }
3348
+ _decPositionCount(hash) {
3349
+ const currentCount = this._positionCount.get(hash) ?? 0;
3350
+ if (currentCount === 1) {
3351
+ this._positionCount.delete(hash);
3352
+ } else {
3353
+ this._positionCount.set(hash, currentCount - 1);
3354
+ }
3355
+ }
3356
+ _pruneComments() {
3357
+ const reversedHistory = [];
3358
+ const currentComments = {};
3359
+ const copyComment = (fen) => {
3360
+ if (fen in this._comments) {
3361
+ currentComments[fen] = this._comments[fen];
3362
+ }
3363
+ };
3364
+ while (this._history.length > 0) {
3365
+ reversedHistory.push(this._undoMove());
3366
+ }
3367
+ copyComment(this.fen());
3368
+ while (true) {
3369
+ const move = reversedHistory.pop();
3370
+ if (!move) {
3371
+ break;
3372
+ }
3373
+ this._makeMove(move);
3374
+ copyComment(this.fen());
3375
+ }
3376
+ this._comments = currentComments;
3377
+ }
3378
+ getComment() {
3379
+ return this._comments[this.fen()];
3380
+ }
3381
+ setComment(comment) {
3382
+ this._comments[this.fen()] = comment.replace("{", "[").replace("}", "]");
3383
+ }
3384
+ deleteComment() {
3385
+ return this.removeComment();
3386
+ }
3387
+ removeComment() {
3388
+ const comment = this._comments[this.fen()];
3389
+ delete this._comments[this.fen()];
3390
+ return comment;
3391
+ }
3392
+ getComments() {
3393
+ this._pruneComments();
3394
+ return Object.keys(this._comments).map((fen) => {
3395
+ return { fen, comment: this._comments[fen] };
3396
+ });
3397
+ }
3398
+ deleteComments() {
3399
+ return this.removeComments();
3400
+ }
3401
+ removeComments() {
3402
+ this._pruneComments();
3403
+ return Object.keys(this._comments).map((fen) => {
3404
+ const comment = this._comments[fen];
3405
+ delete this._comments[fen];
3406
+ return { fen, comment };
3407
+ });
3408
+ }
3409
+ setCastlingRights(color, rights) {
3410
+ for (const side of [KING, QUEEN]) {
3411
+ if (rights[side] !== undefined) {
3412
+ if (rights[side]) {
3413
+ this._castling[color] |= SIDES[side];
3414
+ } else {
3415
+ this._castling[color] &= ~SIDES[side];
3416
+ }
3417
+ }
3418
+ }
3419
+ this._updateCastlingRights();
3420
+ const result = this.getCastlingRights(color);
3421
+ return (rights[KING] === undefined || rights[KING] === result[KING]) && (rights[QUEEN] === undefined || rights[QUEEN] === result[QUEEN]);
3422
+ }
3423
+ getCastlingRights(color) {
3424
+ return {
3425
+ [KING]: (this._castling[color] & SIDES[KING]) !== 0,
3426
+ [QUEEN]: (this._castling[color] & SIDES[QUEEN]) !== 0
3427
+ };
3428
+ }
3429
+ moveNumber() {
3430
+ return this._moveNumber;
3431
+ }
3432
+ }
3433
+
3434
+ // src/features/chess/utils/chessEngine.ts
3435
+ function createChess(fen) {
3436
+ try {
3437
+ return new Chess(fen);
3438
+ } catch {
3439
+ return null;
3440
+ }
3441
+ }
3442
+ function toPieceCode(piece) {
3443
+ return piece.color === "w" ? piece.type.toUpperCase() : piece.type.toLowerCase();
3444
+ }
3445
+ function toPromotionPiece(piece) {
3446
+ return piece === "q" || piece === "r" || piece === "b" || piece === "n" ? piece : undefined;
3447
+ }
3448
+ function toMoveResult(move, fen) {
3449
+ return {
3450
+ fen,
3451
+ from: move.from,
3452
+ lan: move.lan,
3453
+ promotion: toPromotionPiece(move.promotion),
3454
+ san: move.san,
3455
+ to: move.to
3456
+ };
3457
+ }
3458
+ function readChessPieces(fen) {
3459
+ const chess = createChess(fen);
3460
+ const pieces = new Map;
3461
+ if (!chess)
3462
+ return pieces;
3463
+ for (const rank of chess.board()) {
3464
+ for (const piece of rank) {
3465
+ if (!piece)
3466
+ continue;
3467
+ pieces.set(piece.square, {
3468
+ color: piece.color === "w" ? "white" : "black",
3469
+ piece: toPieceCode(piece),
3470
+ square: piece.square
3471
+ });
3472
+ }
3473
+ }
3474
+ return pieces;
3475
+ }
3476
+ function getLegalTargets(fen, from) {
3477
+ const chess = createChess(fen);
3478
+ return chess ? chess.moves({ square: from, verbose: true }).map((move) => move.to) : [];
3479
+ }
3480
+ function tryMove(fen, attempt) {
3481
+ const chess = createChess(fen);
3482
+ if (!chess)
3483
+ return null;
3484
+ try {
3485
+ const move = chess.move({
3486
+ from: attempt.from,
3487
+ promotion: attempt.promotion,
3488
+ to: attempt.to
3489
+ });
3490
+ return toMoveResult(move, chess.fen());
3491
+ } catch {
3492
+ return null;
3493
+ }
3494
+ }
3495
+
3496
+ // src/features/chess/utils/createBoardSquares.ts
3497
+ var files = ["a", "b", "c", "d", "e", "f", "g", "h"];
3498
+ var ranks = ["1", "2", "3", "4", "5", "6", "7", "8"];
3499
+ function createBoardSquares(orientation) {
3500
+ const displayedRanks = orientation === "white" ? [...ranks].reverse() : [...ranks];
3501
+ const displayedFiles = orientation === "white" ? [...files] : [...files].reverse();
3502
+ return displayedRanks.flatMap((rank) => displayedFiles.map((file) => `${file}${rank}`));
3503
+ }
3504
+
3505
+ // src/features/chess/utils/createChessBoardColorScheme.ts
3506
+ function createChessBoardColorScheme(theme, overrides) {
3507
+ return {
3508
+ border: theme.semantics.neutral.divider,
3509
+ coordinateText: theme.semantics.content.muted,
3510
+ darkPiece: theme.semantics.content.default,
3511
+ darkSquare: theme.semantics.neutral.surfaceHover,
3512
+ darkSquareText: theme.semantics.content.muted,
3513
+ lastMoveFrom: theme.semantics.warning.softBg,
3514
+ lastMoveTo: theme.semantics.warning.softBg,
3515
+ legalTarget: theme.semantics.success.softBg,
3516
+ lightPiece: theme.semantics.content.default,
3517
+ lightSquare: theme.semantics.neutral.surface,
3518
+ lightSquareText: theme.semantics.content.muted,
3519
+ selectedSquare: theme.semantics.action.primary.softBg,
3520
+ ...overrides
3521
+ };
3522
+ }
3523
+
3524
+ // src/features/chess/utils/isLightSquare.ts
3525
+ var files2 = "abcdefgh";
3526
+ function isLightSquare(square) {
3527
+ return (files2.indexOf(square[0] ?? "") + Number(square[1]) - 1) % 2 === 1;
3528
+ }
3529
+
3530
+ // src/features/chess/adapters/inbound/ChessBoard.tsx
3531
+ import { jsx, jsxs } from "react/jsx-runtime";
3532
+ var symbols = new Map([
3533
+ ["white:p", "♙"],
3534
+ ["white:n", "♘"],
3535
+ ["white:b", "♗"],
3536
+ ["white:r", "♖"],
3537
+ ["white:q", "♕"],
3538
+ ["white:k", "♔"],
3539
+ ["black:p", "♟"],
3540
+ ["black:n", "♞"],
3541
+ ["black:b", "♝"],
3542
+ ["black:r", "♜"],
3543
+ ["black:q", "♛"],
3544
+ ["black:k", "♚"]
3545
+ ]);
3546
+ var ChessBoard2 = withZoraThemeScope(ChessBoardInner);
3547
+ function ChessBoardInner({
3548
+ fen,
3549
+ pieces,
3550
+ orientation = "white",
3551
+ selectedSquare = null,
3552
+ legalTargets,
3553
+ lastMove = null,
3554
+ disabled = false,
3555
+ showCoordinates = false,
3556
+ validateMoves = true,
3557
+ colorScheme,
3558
+ onSquarePress,
3559
+ onMoveAttempt,
3560
+ onLegalMove,
3561
+ onInvalidMove,
3562
+ renderPiece,
3563
+ interactionPolicy,
3564
+ testID
3565
+ }) {
3566
+ const { theme } = useZoraTheme2();
3567
+ const colors = createChessBoardColorScheme(theme, colorScheme);
3568
+ const squares = createBoardSquares(orientation);
3569
+ const piecesBySquare = pieces === undefined ? fen === undefined ? new Map : new Map(readChessPieces(fen)) : new Map(pieces.map((piece) => [piece.square, piece]));
3570
+ const resolvedLegalTargets = legalTargets ?? (fen !== undefined && selectedSquare !== null ? getLegalTargets(fen, selectedSquare) : []);
3571
+ const legalTargetSet = new Set(resolvedLegalTargets);
3572
+ const pressSquare = (square) => {
3573
+ if (disabled || interactionPolicy === "passive")
3574
+ return;
3575
+ onSquarePress?.(square);
3576
+ if (selectedSquare === null || selectedSquare === square)
3577
+ return;
3578
+ const attempt = { from: selectedSquare, to: square };
3579
+ onMoveAttempt?.(attempt);
3580
+ if (!validateMoves || fen === undefined)
3581
+ return;
3582
+ const result = tryMove(fen, attempt);
3583
+ if (result)
3584
+ onLegalMove?.(result);
3585
+ else
3586
+ onInvalidMove?.(attempt);
3587
+ };
3588
+ return /* @__PURE__ */ jsx(import_react_native.View, {
3589
+ accessibilityLabel: "Chess board",
3590
+ style: [styles.board, { borderColor: colors.border, opacity: disabled ? 0.56 : 1 }],
3591
+ testID,
3592
+ children: squares.map((square) => {
3593
+ const piece = piecesBySquare.get(square);
3594
+ const light = isLightSquare(square);
3595
+ const isTarget = legalTargetSet.has(square);
3596
+ const backgroundColor = selectedSquare === square ? colors.selectedSquare : isTarget ? colors.legalTarget : lastMove?.from === square ? colors.lastMoveFrom : lastMove?.to === square ? colors.lastMoveTo : light ? colors.lightSquare : colors.darkSquare;
3597
+ const pieceContent = piece === undefined ? null : renderPiece ? renderPiece({
3598
+ color: piece.color === "white" ? colors.lightPiece : colors.darkPiece,
3599
+ piece: piece.piece,
3600
+ square
3601
+ }) : symbols.get(`${piece.color}:${piece.piece.toLowerCase()}`) ?? piece.piece;
3602
+ return /* @__PURE__ */ jsxs(import_react_native.Pressable, {
3603
+ accessibilityLabel: square,
3604
+ accessibilityRole: "button",
3605
+ disabled: disabled || interactionPolicy === "passive",
3606
+ onPress: () => pressSquare(square),
3607
+ style: [styles.square, { backgroundColor }],
3608
+ testID: testID ? `${testID}-square-${square}` : undefined,
3609
+ children: [
3610
+ showCoordinates ? /* @__PURE__ */ jsx(import_react_native.Text, {
3611
+ style: [
3612
+ styles.coordinate,
3613
+ { color: light ? colors.lightSquareText : colors.darkSquareText }
3614
+ ],
3615
+ children: square
3616
+ }) : null,
3617
+ piece === undefined ? null : /* @__PURE__ */ jsx(import_react_native.View, {
3618
+ pointerEvents: "none",
3619
+ style: styles.pieceContainer,
3620
+ children: renderPiece ? pieceContent : /* @__PURE__ */ jsx(import_react_native.Text, {
3621
+ style: [
3622
+ styles.piece,
3623
+ { color: piece.color === "white" ? colors.lightPiece : colors.darkPiece }
3624
+ ],
3625
+ children: pieceContent
3626
+ })
3627
+ })
3628
+ ]
3629
+ }, square);
3630
+ })
3631
+ });
3632
+ }
3633
+ var styles = import_react_native.StyleSheet.create({
3634
+ board: {
3635
+ aspectRatio: 1,
3636
+ borderRadius: 12,
3637
+ borderWidth: import_react_native.StyleSheet.hairlineWidth,
3638
+ flexDirection: "row",
3639
+ flexWrap: "wrap",
3640
+ overflow: "hidden",
3641
+ width: "100%"
3642
+ },
3643
+ coordinate: {
3644
+ fontSize: 9,
3645
+ fontWeight: "600",
3646
+ left: 3,
3647
+ opacity: 0.72,
3648
+ position: "absolute",
3649
+ top: 2,
3650
+ zIndex: 2
3651
+ },
3652
+ piece: { fontSize: 32, fontWeight: "600", lineHeight: 38 },
3653
+ pieceContainer: {
3654
+ alignItems: "center",
3655
+ bottom: 0,
3656
+ justifyContent: "center",
3657
+ left: 0,
3658
+ position: "absolute",
3659
+ right: 0,
3660
+ top: 0
3661
+ },
3662
+ square: {
3663
+ alignItems: "center",
3664
+ aspectRatio: 1,
3665
+ width: "12.5%",
3666
+ justifyContent: "center",
3667
+ position: "relative"
3668
+ }
3669
+ });
3670
+
3671
+ // src/features/chess/adapters/inbound/OpeningBook.tsx
3672
+ var import_react_native2 = __toESM(require_cjs(), 1);
3673
+
3674
+ // src/features/chess/utils/createOpeningBookColorScheme.ts
3675
+ function createOpeningBookColorScheme(theme, overrides) {
3676
+ return {
3677
+ border: theme.semantics.neutral.divider,
3678
+ metricSurface: theme.semantics.neutral.surface,
3679
+ primaryText: theme.semantics.content.default,
3680
+ secondaryText: theme.semantics.content.muted,
3681
+ selectedSurface: theme.semantics.action.primary.softBg,
3682
+ surface: theme.semantics.neutral.surface,
3683
+ surfaceHover: theme.semantics.neutral.surfaceHover,
3684
+ titleText: theme.semantics.content.default,
3685
+ ...overrides
3686
+ };
3687
+ }
3688
+
3689
+ // src/features/chess/adapters/inbound/OpeningBook.tsx
3690
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
3691
+ var OpeningBook2 = withZoraThemeScope(OpeningBookInner);
3692
+ function rate(label, value) {
3693
+ if (value === undefined || !Number.isFinite(value))
3694
+ return;
3695
+ return `${label} ${Math.round(value <= 1 ? value * 100 : value)}%`;
3696
+ }
3697
+ function moveKey(move) {
3698
+ return move.uci ?? move.fen ?? move.san;
3699
+ }
3700
+ function OpeningBookInner({
3701
+ moves = [],
3702
+ title = "Opening book",
3703
+ loading = false,
3704
+ errorText,
3705
+ emptyText = "No book moves for this position.",
3706
+ selectedMove = null,
3707
+ colorScheme,
3708
+ onMovePress,
3709
+ interactionPolicy,
3710
+ testID
3711
+ }) {
3712
+ const { theme } = useZoraTheme2();
3713
+ const colors = createOpeningBookColorScheme(theme, colorScheme);
3714
+ const stateText = loading ? "Loading opening moves…" : errorText ?? emptyText;
3715
+ const showState = loading || errorText !== undefined || moves.length === 0;
3716
+ return /* @__PURE__ */ jsxs2(import_react_native2.View, {
3717
+ accessibilityLabel: title,
3718
+ style: [
3719
+ styles2.root,
3720
+ {
3721
+ borderColor: colors.border,
3722
+ backgroundColor: colors.surface
3723
+ }
3724
+ ],
3725
+ testID,
3726
+ children: [
3727
+ /* @__PURE__ */ jsx2(import_react_native2.Text, {
3728
+ style: [styles2.title, { color: colors.titleText }],
3729
+ children: title
3730
+ }),
3731
+ !showState ? /* @__PURE__ */ jsx2(import_react_native2.View, {
3732
+ style: styles2.moves,
3733
+ children: moves.map((move) => {
3734
+ const selected = selectedMove !== null && (selectedMove === move.san || selectedMove === move.uci || selectedMove === move.fen);
3735
+ const details = [
3736
+ move.eco,
3737
+ move.name,
3738
+ move.games === undefined ? undefined : `${move.games} games`
3739
+ ].filter((part) => typeof part === "string" && part.length > 0);
3740
+ const stats = [
3741
+ rate("W", move.whiteWinRate),
3742
+ rate("D", move.drawRate),
3743
+ rate("B", move.blackWinRate)
3744
+ ].filter((part) => part !== undefined);
3745
+ return /* @__PURE__ */ jsxs2(import_react_native2.Pressable, {
3746
+ accessibilityRole: "button",
3747
+ disabled: onMovePress === undefined || interactionPolicy === "passive",
3748
+ onPress: () => {
3749
+ if (interactionPolicy === "passive")
3750
+ return;
3751
+ onMovePress?.(move);
3752
+ },
3753
+ style: [
3754
+ styles2.move,
3755
+ {
3756
+ backgroundColor: selected ? colors.selectedSurface : colors.surfaceHover,
3757
+ borderColor: colors.border
3758
+ }
3759
+ ],
3760
+ testID: testID ? `${testID}-move-${move.san}` : undefined,
3761
+ children: [
3762
+ /* @__PURE__ */ jsxs2(import_react_native2.View, {
3763
+ style: styles2.moveMain,
3764
+ children: [
3765
+ /* @__PURE__ */ jsx2(import_react_native2.Text, {
3766
+ style: [styles2.san, { color: colors.primaryText }],
3767
+ children: move.san
3768
+ }),
3769
+ /* @__PURE__ */ jsx2(import_react_native2.Text, {
3770
+ style: [styles2.meta, { color: colors.secondaryText }],
3771
+ children: details.length > 0 ? details.join(" · ") : "Book move"
3772
+ })
3773
+ ]
3774
+ }),
3775
+ stats.length > 0 ? /* @__PURE__ */ jsx2(import_react_native2.View, {
3776
+ style: [styles2.metric, { backgroundColor: colors.metricSurface }],
3777
+ children: /* @__PURE__ */ jsx2(import_react_native2.Text, {
3778
+ style: [styles2.metricText, { color: colors.secondaryText }],
3779
+ children: stats.join(" ")
3780
+ })
3781
+ }) : null
3782
+ ]
3783
+ }, moveKey(move));
3784
+ })
3785
+ }) : /* @__PURE__ */ jsx2(import_react_native2.Text, {
3786
+ style: [styles2.stateText, { color: colors.secondaryText }],
3787
+ children: stateText
3788
+ })
3789
+ ]
3790
+ });
3791
+ }
3792
+ var styles2 = import_react_native2.StyleSheet.create({
3793
+ root: { borderRadius: 12, borderWidth: import_react_native2.StyleSheet.hairlineWidth, gap: 10, padding: 12 },
3794
+ title: { fontSize: 15, fontWeight: "700", lineHeight: 20 },
3795
+ stateText: { fontSize: 13, lineHeight: 18 },
3796
+ moves: { gap: 8 },
3797
+ move: {
3798
+ alignItems: "center",
3799
+ borderRadius: 10,
3800
+ borderWidth: import_react_native2.StyleSheet.hairlineWidth,
3801
+ flexDirection: "row",
3802
+ gap: 10,
3803
+ justifyContent: "space-between",
3804
+ paddingHorizontal: 10,
3805
+ paddingVertical: 8
3806
+ },
3807
+ moveMain: { flex: 1, gap: 2 },
3808
+ san: { fontSize: 16, fontWeight: "700", lineHeight: 20 },
3809
+ meta: { fontSize: 12, lineHeight: 16 },
3810
+ metric: { borderRadius: 999, paddingHorizontal: 8, paddingVertical: 4 },
3811
+ metricText: { fontSize: 11, fontWeight: "600" }
3812
+ });
3813
+ export { ChessBoard2, OpeningBook2 };