@scrabble-solver/scrabble-solver 2.8.8 → 2.8.10

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 (111) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +12 -12
  3. package/.next/cache/.tsbuildinfo +1 -1
  4. package/.next/cache/eslint/.cache_8dgz12 +1 -1
  5. package/.next/cache/next-server.js.nft.json +1 -1
  6. package/.next/cache/webpack/client-production/0.pack +0 -0
  7. package/.next/cache/webpack/client-production/index.pack +0 -0
  8. package/.next/cache/webpack/server-production/0.pack +0 -0
  9. package/.next/cache/webpack/server-production/index.pack +0 -0
  10. package/.next/next-server.js.nft.json +1 -1
  11. package/.next/prerender-manifest.json +1 -1
  12. package/.next/routes-manifest.json +1 -1
  13. package/.next/server/chunks/413.js +350 -73
  14. package/.next/server/chunks/429.js +2 -13
  15. package/.next/server/chunks/44.js +802 -0
  16. package/.next/server/chunks/515.js +767 -322
  17. package/.next/server/chunks/911.js +77 -25
  18. package/.next/server/middleware-build-manifest.js +1 -1
  19. package/.next/server/pages/404.html +2 -2
  20. package/.next/server/pages/404.js.nft.json +1 -1
  21. package/.next/server/pages/500.html +2 -2
  22. package/.next/server/pages/_app.js.nft.json +1 -1
  23. package/.next/server/pages/_document.js.nft.json +1 -1
  24. package/.next/server/pages/_error.js.nft.json +1 -1
  25. package/.next/server/pages/api/solve.js +226 -927
  26. package/.next/server/pages/api/solve.js.nft.json +1 -1
  27. package/.next/server/pages/api/verify.js +217 -0
  28. package/.next/server/pages/api/verify.js.nft.json +1 -0
  29. package/.next/server/pages/index.html +3 -3
  30. package/.next/server/pages/index.js +8 -2
  31. package/.next/server/pages/index.js.nft.json +1 -1
  32. package/.next/server/pages/index.json +1 -1
  33. package/.next/server/pages-manifest.json +1 -0
  34. package/.next/static/A8A_Lmg8cM-Bkf-Jo1CLh/_buildManifest.js +1 -0
  35. package/.next/static/{z3J3qmq1nazbDv_ENIkCo → A8A_Lmg8cM-Bkf-Jo1CLh}/_ssgManifest.js +0 -0
  36. package/.next/static/chunks/317-95ab9051449362fa.js +1 -0
  37. package/.next/static/chunks/758-eff80059a1365d5d.js +1 -0
  38. package/.next/static/chunks/pages/{404-8eb3ba4f0ba17e08.js → 404-90c624da3c83fd17.js} +1 -1
  39. package/.next/static/chunks/pages/_app-0e358b5622cf9e66.js +1 -0
  40. package/.next/static/chunks/pages/index-0cc5e6eda5adac73.js +1 -0
  41. package/.next/static/css/9ac903004135f4b1.css +1 -0
  42. package/.next/static/css/{cdbc9e0afcff5473.css → ad2a08918868cad8.css} +1 -1
  43. package/.next/trace +42 -41
  44. package/package.json +12 -12
  45. package/src/components/Badge/Badge.module.scss +13 -0
  46. package/src/components/Badge/Badge.tsx +15 -0
  47. package/src/components/Badge/index.ts +1 -0
  48. package/src/components/Board/Board.tsx +4 -2
  49. package/src/components/Board/BoardPure.tsx +25 -5
  50. package/src/components/Board/hooks/useGrid.ts +212 -91
  51. package/src/components/Dictionary/Dictionary.tsx +8 -1
  52. package/src/components/NavButtons/NavButtons.tsx +33 -14
  53. package/src/components/Rack/Rack.tsx +51 -11
  54. package/src/components/Rack/RackTile.tsx +33 -16
  55. package/src/components/RemainingTiles/RemainingTiles.module.scss +8 -7
  56. package/src/components/RemainingTiles/RemainingTiles.tsx +13 -4
  57. package/src/components/Results/Results.tsx +19 -3
  58. package/src/components/Sidebar/Sidebar.tsx +2 -2
  59. package/src/components/Sidebar/components/Section/Section.module.scss +0 -1
  60. package/src/components/Sidebar/components/Section/Section.tsx +1 -1
  61. package/src/components/SquareButton/Link.tsx +1 -1
  62. package/src/components/SquareButton/SquareButton.module.scss +5 -0
  63. package/src/components/Tile/Tile.module.scss +4 -0
  64. package/src/components/Tile/Tile.tsx +13 -4
  65. package/src/components/Tile/TilePure.tsx +3 -4
  66. package/src/components/Words/Words.module.scss +35 -0
  67. package/src/components/Words/Words.tsx +57 -0
  68. package/src/components/Words/index.ts +1 -0
  69. package/src/components/index.ts +2 -0
  70. package/src/i18n/de.json +4 -1
  71. package/src/i18n/en.json +4 -1
  72. package/src/i18n/es.json +4 -1
  73. package/src/i18n/fr.json +4 -1
  74. package/src/i18n/pl.json +4 -1
  75. package/src/icons/BookHalf.svg +4 -0
  76. package/src/icons/Check.svg +4 -0
  77. package/src/icons/Cross.svg +2 -2
  78. package/src/icons/CrossFill.svg +4 -0
  79. package/src/icons/index.ts +3 -0
  80. package/src/lib/extractCharacters.ts +26 -0
  81. package/src/lib/extractInputValue.ts +17 -0
  82. package/src/lib/index.ts +2 -0
  83. package/src/lib/isCtrl.ts +1 -1
  84. package/src/lib/memoize.ts +15 -1
  85. package/src/pages/api/solve.ts +3 -4
  86. package/src/pages/api/verify.ts +71 -0
  87. package/src/pages/index.tsx +5 -0
  88. package/src/sdk/fetchJson.ts +36 -0
  89. package/src/sdk/findWordDefinitions.ts +4 -3
  90. package/src/sdk/index.ts +1 -0
  91. package/src/sdk/solve.ts +8 -7
  92. package/src/sdk/verify.ts +23 -0
  93. package/src/state/rootReducer.ts +2 -0
  94. package/src/state/sagas.ts +35 -8
  95. package/src/state/selectors.ts +17 -1
  96. package/src/state/slices/dictionaryInitialState.ts +10 -2
  97. package/src/state/slices/dictionarySlice.ts +10 -16
  98. package/src/state/slices/index.ts +2 -0
  99. package/src/state/slices/rackSlice.ts +7 -0
  100. package/src/state/slices/solveInitialState.ts +14 -2
  101. package/src/state/slices/solveSlice.ts +7 -4
  102. package/src/state/slices/verifyInitialState.ts +12 -0
  103. package/src/state/slices/verifySlice.ts +31 -0
  104. package/src/styles/variables.scss +2 -1
  105. package/src/types/index.ts +6 -1
  106. package/.next/static/chunks/615-d258f6c528c18622.js +0 -1
  107. package/.next/static/chunks/758-f333b1dcdb941547.js +0 -1
  108. package/.next/static/chunks/pages/_app-4a663fd3d5ca4524.js +0 -1
  109. package/.next/static/chunks/pages/index-1a9826d740cc8830.js +0 -1
  110. package/.next/static/css/180c6c26317ac90f.css +0 -1
  111. package/.next/static/z3J3qmq1nazbDv_ENIkCo/_buildManifest.js +0 -1
@@ -124,383 +124,7 @@ module.exports = require("zlib");
124
124
 
125
125
  /***/ }),
126
126
 
127
- /***/ 21285:
128
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
129
-
130
-
131
- var __importDefault = (this && this.__importDefault) || function (mod) {
132
- return (mod && mod.__esModule) ? mod : { "default": mod };
133
- };
134
- Object.defineProperty(exports, "__esModule", ({ value: true }));
135
- const logger_1 = __importDefault(__webpack_require__(52954));
136
- const types_1 = __webpack_require__(46452);
137
- const fs_1 = __importDefault(__webpack_require__(57147));
138
- const constants_1 = __webpack_require__(75823);
139
- const lib_1 = __webpack_require__(26137);
140
- class Dictionaries {
141
- constructor() {
142
- this.cache = new lib_1.LayeredCache();
143
- this.downloadDictionaryProxies = Object.fromEntries(Object.values(types_1.Locale).map((locale) => [locale, (0, lib_1.createAsyncProxy)(() => (0, lib_1.downloadDictionary)(locale))]));
144
- }
145
- async get(locale) {
146
- if (this.cache.has(locale)) {
147
- const trie = await this.cache.get(locale);
148
- if (trie) {
149
- return trie;
150
- }
151
- }
152
- logger_1.default.info('Dictionaries - cache miss', { locale });
153
- return this.updateDictionary(locale);
154
- }
155
- remove() {
156
- fs_1.default.rmdirSync(constants_1.OUTPUT_DIRECTORY, { recursive: true });
157
- }
158
- async update(force) {
159
- const locales = force ? Object.values(types_1.Locale) : this.getLocalesToUpdate();
160
- logger_1.default.info('Dictionaries - update', { force, locales });
161
- await Promise.all(locales.map((locale) => this.updateDictionary(locale)));
162
- }
163
- getLocalesToUpdate() {
164
- return Object.values(types_1.Locale).filter((locale) => this.cache.isStale(locale) !== false);
165
- }
166
- async updateDictionary(locale) {
167
- logger_1.default.info('Dictionaries - updateDictionary', { locale });
168
- fs_1.default.mkdirSync(constants_1.OUTPUT_DIRECTORY, { recursive: true });
169
- const downloadDictionaryProxy = this.downloadDictionaryProxies[locale];
170
- const trie = await downloadDictionaryProxy();
171
- await this.cache.set(locale, trie);
172
- return trie;
173
- }
174
- }
175
- exports["default"] = Dictionaries;
176
-
177
-
178
- /***/ }),
179
-
180
- /***/ 75823:
181
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
182
-
183
-
184
- var __importDefault = (this && this.__importDefault) || function (mod) {
185
- return (mod && mod.__esModule) ? mod : { "default": mod };
186
- };
187
- Object.defineProperty(exports, "__esModule", ({ value: true }));
188
- exports.OUTPUT_DIRECTORY = exports.CACHE_STALE_THRESHOLD = exports.DAY = void 0;
189
- const os_1 = __importDefault(__webpack_require__(22037));
190
- const path_1 = __importDefault(__webpack_require__(71017));
191
- exports.DAY = 24 * 60 * 60 * 1000;
192
- exports.CACHE_STALE_THRESHOLD = 30 * exports.DAY;
193
- exports.OUTPUT_DIRECTORY = path_1.default.resolve(os_1.default.homedir(), '.scrabble-solver', 'dictionaries');
194
-
195
-
196
- /***/ }),
197
-
198
- /***/ 89044:
199
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
200
-
201
-
202
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
203
- if (k2 === undefined) k2 = k;
204
- var desc = Object.getOwnPropertyDescriptor(m, k);
205
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
206
- desc = { enumerable: true, get: function() { return m[k]; } };
207
- }
208
- Object.defineProperty(o, k2, desc);
209
- }) : (function(o, m, k, k2) {
210
- if (k2 === undefined) k2 = k;
211
- o[k2] = m[k];
212
- }));
213
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
214
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
215
- };
216
- var __importDefault = (this && this.__importDefault) || function (mod) {
217
- return (mod && mod.__esModule) ? mod : { "default": mod };
218
- };
219
- Object.defineProperty(exports, "__esModule", ({ value: true }));
220
- exports.dictionaries = void 0;
221
- const Dictionaries_1 = __importDefault(__webpack_require__(21285));
222
- __exportStar(__webpack_require__(26137), exports);
223
- exports.dictionaries = new Dictionaries_1.default();
224
-
225
-
226
- /***/ }),
227
-
228
- /***/ 2812:
229
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
230
-
231
-
232
- var __importDefault = (this && this.__importDefault) || function (mod) {
233
- return (mod && mod.__esModule) ? mod : { "default": mod };
234
- };
235
- Object.defineProperty(exports, "__esModule", ({ value: true }));
236
- const trie_1 = __webpack_require__(83140);
237
- const fs_1 = __importDefault(__webpack_require__(57147));
238
- const constants_1 = __webpack_require__(75823);
239
- const getDictionaryFilepath_1 = __importDefault(__webpack_require__(68638));
240
- class DiskCache {
241
- async get(locale) {
242
- if (!this.has(locale)) {
243
- return undefined;
244
- }
245
- const filepath = (0, getDictionaryFilepath_1.default)(locale);
246
- const serialized = await fs_1.default.promises.readFile(filepath, 'utf-8');
247
- const trie = trie_1.Trie.deserialize(serialized);
248
- return trie;
249
- }
250
- getLastModifiedTimestamp(locale) {
251
- const filepath = (0, getDictionaryFilepath_1.default)(locale);
252
- if (!fs_1.default.existsSync(filepath)) {
253
- return undefined;
254
- }
255
- const stats = fs_1.default.statSync(filepath);
256
- return stats.mtimeMs;
257
- }
258
- has(locale) {
259
- const filepath = (0, getDictionaryFilepath_1.default)(locale);
260
- return fs_1.default.existsSync(filepath);
261
- }
262
- isStale(locale) {
263
- if (!this.has(locale)) {
264
- return undefined;
265
- }
266
- const lastModifiedTimestamp = this.getLastModifiedTimestamp(locale);
267
- if (typeof lastModifiedTimestamp === 'undefined') {
268
- return undefined;
269
- }
270
- const timeSinceModification = Math.abs(lastModifiedTimestamp - Date.now());
271
- return timeSinceModification > constants_1.CACHE_STALE_THRESHOLD;
272
- }
273
- async set(locale, trie) {
274
- const filepath = (0, getDictionaryFilepath_1.default)(locale);
275
- await fs_1.default.promises.writeFile(filepath, trie.serialize());
276
- }
277
- }
278
- exports["default"] = DiskCache;
279
-
280
-
281
- /***/ }),
282
-
283
- /***/ 70287:
284
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
285
-
286
-
287
- var __importDefault = (this && this.__importDefault) || function (mod) {
288
- return (mod && mod.__esModule) ? mod : { "default": mod };
289
- };
290
- Object.defineProperty(exports, "__esModule", ({ value: true }));
291
- const createCacheTimestampComparator_1 = __importDefault(__webpack_require__(20494));
292
- const DiskCache_1 = __importDefault(__webpack_require__(2812));
293
- const MemoryCache_1 = __importDefault(__webpack_require__(50192));
294
- class LayeredCache {
295
- constructor() {
296
- this.layers = [new MemoryCache_1.default(), new DiskCache_1.default()];
297
- }
298
- async get(locale) {
299
- const cache = this.getLastModifiedLayer(locale);
300
- if (!cache) {
301
- return Promise.resolve(undefined);
302
- }
303
- const [memoryCache, diskCache] = this.layers;
304
- const value = await cache.get(locale);
305
- if (cache === diskCache && typeof value !== 'undefined') {
306
- await memoryCache.set(locale, value);
307
- }
308
- return value;
309
- }
310
- getLastModifiedTimestamp(locale) {
311
- const cache = this.getLastModifiedLayer(locale);
312
- if (!cache) {
313
- return undefined;
314
- }
315
- return cache.getLastModifiedTimestamp(locale);
316
- }
317
- has(locale) {
318
- return this.layers.some((cache) => cache.has(locale));
319
- }
320
- isStale(locale) {
321
- if (this.layers.some((cache) => cache.isStale(locale))) {
322
- return true;
323
- }
324
- if (this.layers.every((cache) => typeof cache.isStale(locale) === 'undefined')) {
325
- return undefined;
326
- }
327
- return false;
328
- }
329
- async set(locale, trie) {
330
- const [memoryCache, diskCache] = this.layers;
331
- await diskCache.set(locale, trie);
332
- await memoryCache.set(locale, trie);
333
- }
334
- getLastModifiedLayer(locale) {
335
- const layers = this.layers.filter((cache) => cache.has(locale));
336
- const [cached] = [...layers].sort((0, createCacheTimestampComparator_1.default)(locale));
337
- return cached;
338
- }
339
- }
340
- exports["default"] = LayeredCache;
341
-
342
-
343
- /***/ }),
344
-
345
- /***/ 50192:
346
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
347
-
348
-
349
- Object.defineProperty(exports, "__esModule", ({ value: true }));
350
- const constants_1 = __webpack_require__(75823);
351
- class MemoryCache {
352
- constructor() {
353
- this.cache = {};
354
- this.cacheTimestamps = {};
355
- }
356
- get(locale) {
357
- return Promise.resolve(this.cache[locale]);
358
- }
359
- getLastModifiedTimestamp(locale) {
360
- return this.cacheTimestamps[locale];
361
- }
362
- has(locale) {
363
- return typeof this.cache[locale] !== 'undefined';
364
- }
365
- isStale(locale) {
366
- const timestamp = this.getLastModifiedTimestamp(locale);
367
- if (!this.has(locale) || typeof timestamp === 'undefined') {
368
- return undefined;
369
- }
370
- const timeSinceModification = Math.abs(timestamp - Date.now());
371
- return timeSinceModification > constants_1.CACHE_STALE_THRESHOLD;
372
- }
373
- set(locale, trie) {
374
- this.cacheTimestamps[locale] = Date.now();
375
- this.cache[locale] = trie;
376
- return Promise.resolve();
377
- }
378
- }
379
- exports["default"] = MemoryCache;
380
-
381
-
382
- /***/ }),
383
-
384
- /***/ 26554:
385
- /***/ ((__unused_webpack_module, exports) => {
386
-
387
-
388
- Object.defineProperty(exports, "__esModule", ({ value: true }));
389
- const createAsyncProxy = (asyncCallback) => {
390
- let promise = null;
391
- return async () => {
392
- if (promise) {
393
- return promise;
394
- }
395
- try {
396
- promise = asyncCallback();
397
- return await promise;
398
- }
399
- finally {
400
- promise = null;
401
- }
402
- };
403
- };
404
- exports["default"] = createAsyncProxy;
405
-
406
-
407
- /***/ }),
408
-
409
- /***/ 20494:
410
- /***/ ((__unused_webpack_module, exports) => {
411
-
412
-
413
- Object.defineProperty(exports, "__esModule", ({ value: true }));
414
- const createCacheTimestampComparator = (locale) => {
415
- return (a, b) => {
416
- const aTimestamp = a.getLastModifiedTimestamp(locale);
417
- const bTimestamp = b.getLastModifiedTimestamp(locale);
418
- if (aTimestamp === bTimestamp) {
419
- return 0;
420
- }
421
- if (typeof aTimestamp === 'undefined') {
422
- return 1;
423
- }
424
- if (typeof bTimestamp === 'undefined') {
425
- return -1;
426
- }
427
- return bTimestamp - aTimestamp;
428
- };
429
- };
430
- exports["default"] = createCacheTimestampComparator;
431
-
432
-
433
- /***/ }),
434
-
435
- /***/ 41281:
436
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
437
-
438
-
439
- var __importDefault = (this && this.__importDefault) || function (mod) {
440
- return (mod && mod.__esModule) ? mod : { "default": mod };
441
- };
442
- Object.defineProperty(exports, "__esModule", ({ value: true }));
443
- const trie_1 = __webpack_require__(83140);
444
- const logger_1 = __importDefault(__webpack_require__(52954));
445
- const word_lists_1 = __webpack_require__(51585);
446
- const downloadDictionary = async (locale) => {
447
- logger_1.default.info('downloadDictionary', { locale });
448
- const words = await (0, word_lists_1.getWordList)(locale);
449
- logger_1.default.info('downloadDictionary - success', { locale });
450
- const trie = trie_1.Trie.fromArray(words);
451
- return trie;
452
- };
453
- exports["default"] = downloadDictionary;
454
-
455
-
456
- /***/ }),
457
-
458
- /***/ 68638:
459
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
460
-
461
-
462
- var __importDefault = (this && this.__importDefault) || function (mod) {
463
- return (mod && mod.__esModule) ? mod : { "default": mod };
464
- };
465
- Object.defineProperty(exports, "__esModule", ({ value: true }));
466
- const path_1 = __importDefault(__webpack_require__(71017));
467
- const constants_1 = __webpack_require__(75823);
468
- const getDictionaryFilepath = (locale) => {
469
- return path_1.default.resolve(constants_1.OUTPUT_DIRECTORY, `${locale}.txt`);
470
- };
471
- exports["default"] = getDictionaryFilepath;
472
-
473
-
474
- /***/ }),
475
-
476
- /***/ 26137:
477
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
478
-
479
-
480
- var __importDefault = (this && this.__importDefault) || function (mod) {
481
- return (mod && mod.__esModule) ? mod : { "default": mod };
482
- };
483
- Object.defineProperty(exports, "__esModule", ({ value: true }));
484
- exports.MemoryCache = exports.LayeredCache = exports.getDictionaryFilepath = exports.downloadDictionary = exports.DiskCache = exports.createCacheTimestampComparator = exports.createAsyncProxy = void 0;
485
- var createAsyncProxy_1 = __webpack_require__(26554);
486
- Object.defineProperty(exports, "createAsyncProxy", ({ enumerable: true, get: function () { return __importDefault(createAsyncProxy_1).default; } }));
487
- var createCacheTimestampComparator_1 = __webpack_require__(20494);
488
- Object.defineProperty(exports, "createCacheTimestampComparator", ({ enumerable: true, get: function () { return __importDefault(createCacheTimestampComparator_1).default; } }));
489
- var DiskCache_1 = __webpack_require__(2812);
490
- Object.defineProperty(exports, "DiskCache", ({ enumerable: true, get: function () { return __importDefault(DiskCache_1).default; } }));
491
- var downloadDictionary_1 = __webpack_require__(41281);
492
- Object.defineProperty(exports, "downloadDictionary", ({ enumerable: true, get: function () { return __importDefault(downloadDictionary_1).default; } }));
493
- var getDictionaryFilepath_1 = __webpack_require__(68638);
494
- Object.defineProperty(exports, "getDictionaryFilepath", ({ enumerable: true, get: function () { return __importDefault(getDictionaryFilepath_1).default; } }));
495
- var LayeredCache_1 = __webpack_require__(70287);
496
- Object.defineProperty(exports, "LayeredCache", ({ enumerable: true, get: function () { return __importDefault(LayeredCache_1).default; } }));
497
- var MemoryCache_1 = __webpack_require__(50192);
498
- Object.defineProperty(exports, "MemoryCache", ({ enumerable: true, get: function () { return __importDefault(MemoryCache_1).default; } }));
499
-
500
-
501
- /***/ }),
502
-
503
- /***/ 207:
127
+ /***/ 62316:
504
128
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
505
129
 
506
130
  // ESM COMPAT FLAG
@@ -522,7 +146,6 @@ var logger_build = __webpack_require__(52954);
522
146
  var logger_build_default = /*#__PURE__*/__webpack_require__.n(logger_build);
523
147
  // EXTERNAL MODULE: ../solver/build/index.js
524
148
  var solver_build = __webpack_require__(40368);
525
- var solver_build_default = /*#__PURE__*/__webpack_require__.n(solver_build);
526
149
  // EXTERNAL MODULE: ../types/build/index.js
527
150
  var types_build = __webpack_require__(46452);
528
151
  // EXTERNAL MODULE: ./src/api/index.ts + 4 modules
@@ -547,6 +170,27 @@ const detectLocale = ()=>{
547
170
  };
548
171
  /* harmony default export */ const lib_detectLocale = ((/* unused pure expression or super */ null && (detectLocale)));
549
172
 
173
+ ;// CONCATENATED MODULE: ./src/lib/extractCharacters.ts
174
+
175
+ const extractCharacters = (config, value)=>{
176
+ let index = 0;
177
+ const characters = [];
178
+ while(index < value.length){
179
+ const character = value[index];
180
+ const nextCharacter = value[index + 1];
181
+ const twoCharacterTileCandidate = `${character}${nextCharacter}`;
182
+ if (config.twoCharacterTiles.includes(twoCharacterTileCandidate)) {
183
+ characters.push(twoCharacterTileCandidate);
184
+ ++index;
185
+ } else if (config.hasCharacter(character) || character === BLANK) {
186
+ characters.push(character);
187
+ }
188
+ ++index;
189
+ }
190
+ return characters;
191
+ };
192
+ /* harmony default export */ const lib_extractCharacters = ((/* unused pure expression or super */ null && (extractCharacters)));
193
+
550
194
  ;// CONCATENATED MODULE: ./src/parameters/index.ts
551
195
  const GITHUB_PROJECT_URL = "https://github.com/kamilmielnik/scrabble-solver";
552
196
  const TRANSITION_DURATION = 100;
@@ -818,6 +462,8 @@ const zipCharactersAndTiles = (characters, tiles)=>{
818
462
 
819
463
 
820
464
 
465
+
466
+
821
467
 
822
468
 
823
469
 
@@ -850,9 +496,8 @@ const solve = async (request, response)=>{
850
496
  character,
851
497
  isBlank: character === constants_build.BLANK
852
498
  }));
853
- const solver = new (solver_build_default())(config, trie);
854
- const results = solver.solve(board, tiles);
855
- response.status(200).send(results.map((result)=>result.toJson()));
499
+ const results = (0,solver_build.solve)(trie, config, board, tiles);
500
+ response.status(200).send(results);
856
501
  } catch (error) {
857
502
  const message = error instanceof Error ? error.message : "Unknown error";
858
503
  logger_build_default().error("solve - error", {
@@ -904,201 +549,89 @@ const parseRequest = (request)=>{
904
549
 
905
550
  /***/ }),
906
551
 
907
- /***/ 6700:
552
+ /***/ 83594:
908
553
  /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
909
554
 
910
555
 
911
556
  Object.defineProperty(exports, "__esModule", ({ value: true }));
557
+ exports.fillPatternRecursive = void 0;
912
558
  const constants_1 = __webpack_require__(38436);
913
559
  const types_1 = __webpack_require__(46452);
914
- class PatternsFiller {
915
- constructor(config, trie) {
916
- this.config = config;
917
- this.trie = trie;
918
- }
919
- fill(pattern, tiles) {
920
- const patterns = [];
921
- if (pattern.getEmptyCellsCount() > tiles.length) {
922
- return [];
923
- }
924
- const onPatternFound = (newPattern) => patterns.push(newPattern);
925
- const tilesPermutations = this.generateBlankTilesPermutations(tiles);
926
- for (let index = 0; index < tilesPermutations.length; ++index) {
927
- const tilesPermutation = tilesPermutations[index];
928
- this.fillPattern(pattern, pattern.toString(), tilesPermutation, onPatternFound);
560
+ const fillPattern = (trie, config, pattern, tiles) => {
561
+ if (pattern.getEmptyCellsCount() > tiles.length) {
562
+ return [];
563
+ }
564
+ const results = [];
565
+ (0, exports.fillPatternRecursive)(results, trie, config, pattern, pattern.toString(), tiles);
566
+ return results;
567
+ };
568
+ const fillPatternRecursive = (
569
+ /** gets mutated when this function is called */
570
+ results, trie, config, pattern, word, tiles) => {
571
+ const indexOfFirstCellWithoutTile = pattern.getIndexOfFirstCellWithoutTile();
572
+ if (indexOfFirstCellWithoutTile === -1) {
573
+ if (trie.has(word) && pattern.getCollisions().every((collision) => trie.has(collision.toString()))) {
574
+ results.push(new types_1.FinalPattern(pattern.clone()));
929
575
  }
930
- return patterns;
931
- }
932
- fillPattern(pattern, word, tiles, onPatternFound) {
933
- const indexOfFirstCellWithoutTile = pattern.getIndexOfFirstCellWithoutTile();
934
- if (indexOfFirstCellWithoutTile === -1) {
935
- if (this.canAddPattern(pattern, word)) {
936
- onPatternFound(pattern.clone());
937
- }
938
- }
939
- else {
940
- for (let index = 0; index < tiles.length; ++index) {
941
- const tile = tiles[index];
942
- const previousTile = pattern.cells[indexOfFirstCellWithoutTile].tile;
943
- pattern.cells[indexOfFirstCellWithoutTile].tile = tile;
944
- const indexOfNextCellWithoutTile = pattern.getIndexOfFirstCellWithoutTile();
945
- const indexOfFirstEmptyLetter = word.indexOf(constants_1.EMPTY_CELL);
946
- const newWordPrefix = word.substring(0, indexOfFirstEmptyLetter) + tile.character;
947
- const newWord = newWordPrefix + word.substring(indexOfFirstEmptyLetter + 1);
948
- if (indexOfNextCellWithoutTile === -1) {
949
- if (this.canAddPattern(pattern, newWord)) {
950
- onPatternFound(pattern.clone());
951
- }
952
- }
953
- else if (this.trie.hasPrefix(newWordPrefix)) {
954
- tiles.splice(index, 1);
955
- this.fillPattern(pattern, newWord, tiles, onPatternFound);
956
- tiles.splice(index, 0, tile);
576
+ return;
577
+ }
578
+ for (let index = 0; index < tiles.length; ++index) {
579
+ const tile = tiles[index];
580
+ const previousTile = pattern.cells[indexOfFirstCellWithoutTile].tile;
581
+ pattern.cells[indexOfFirstCellWithoutTile].tile = tile;
582
+ const indexOfNextCellWithoutTile = pattern.getIndexOfFirstCellWithoutTile();
583
+ const indexOfFirstEmptyLetter = word.indexOf(constants_1.EMPTY_CELL);
584
+ const prefix = word.substring(0, indexOfFirstEmptyLetter);
585
+ const suffix = word.substring(indexOfFirstEmptyLetter + 1);
586
+ const characters = tile.isBlank ? config.alphabet : [tile.character];
587
+ for (const character of characters) {
588
+ const newWordPrefix = prefix + character;
589
+ const newWord = newWordPrefix + suffix;
590
+ tile.character = character;
591
+ if (indexOfNextCellWithoutTile === -1) {
592
+ if (trie.has(newWord) && pattern.getCollisions().every((collision) => trie.has(collision.toString()))) {
593
+ results.push(new types_1.FinalPattern(pattern.clone()));
957
594
  }
958
- pattern.cells[indexOfFirstCellWithoutTile].tile = previousTile;
959
595
  }
960
- }
961
- }
962
- canAddPattern(pattern, word) {
963
- return this.trie.has(word) && pattern.getCollisions().every((collision) => this.trie.has(collision.toString()));
964
- }
965
- generateBlankTilesPermutations(tiles) {
966
- const { alphabet } = this.config;
967
- const firstBlankIndex = tiles.findIndex(({ character, isBlank }) => isBlank && !alphabet.includes(character));
968
- if (firstBlankIndex === -1) {
969
- return [tiles];
970
- }
971
- const remainingTiles = tiles.slice(0, firstBlankIndex).concat(tiles.slice(firstBlankIndex + 1));
972
- return this.config.alphabet.reduce((permutations, character) => {
973
- const newTile = new types_1.Tile({ character, isBlank: true });
974
- const newTiles = [...remainingTiles, newTile];
975
- return permutations.concat(this.generateBlankTilesPermutations(newTiles));
976
- }, []);
977
- }
978
- }
979
- exports["default"] = PatternsFiller;
980
-
981
-
982
- /***/ }),
983
-
984
- /***/ 34196:
985
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
986
-
987
-
988
- Object.defineProperty(exports, "__esModule", ({ value: true }));
989
- const types_1 = __webpack_require__(46452);
990
- class PatternsGenerator {
991
- constructor(config) {
992
- this.config = config;
993
- }
994
- generate(board) {
995
- return [...this.generateHorizontal(board), ...this.generateVertical(board)];
996
- }
997
- generateHorizontal(board) {
998
- return this.generatePatterns({
999
- board,
1000
- getNthVector: (index) => board.getRow(index),
1001
- PatternModel: types_1.HorizontalPattern,
1002
- vectorsCount: this.config.boardHeight,
1003
- });
1004
- }
1005
- generateVertical(board) {
1006
- return this.generatePatterns({
1007
- board,
1008
- getNthVector: (index) => board.getColumn(index),
1009
- PatternModel: types_1.VerticalPattern,
1010
- vectorsCount: this.config.boardWidth,
1011
- });
1012
- }
1013
- generatePatterns({ board, getNthVector, vectorsCount, PatternModel, }) {
1014
- return this.generateVectors({ getNthVector, vectorsCount }).reduce((patterns, cells) => {
1015
- return patterns.concat(this.generateCellsPatterns({ board, PatternModel, cells }));
1016
- }, []);
1017
- }
1018
- generateVectors({ getNthVector, vectorsCount, }) {
1019
- return Array(vectorsCount)
1020
- .fill(0)
1021
- .map((_, index) => getNthVector(index));
1022
- }
1023
- generateCellsPatterns({ board, cells, PatternModel, }) {
1024
- return this.generateStartIndices(cells).flatMap((startIndex) => {
1025
- const endIndices = this.generateEndIndices(cells, startIndex);
1026
- const patterns = [];
1027
- for (const endIndex of endIndices) {
1028
- const pattern = new PatternModel({
1029
- board,
1030
- cells: cells.slice(startIndex, endIndex + 1),
1031
- });
1032
- if (pattern.canBePlaced(this.config)) {
1033
- patterns.push(pattern);
1034
- }
596
+ else if (trie.hasPrefix(newWordPrefix)) {
597
+ tiles.splice(index, 1);
598
+ (0, exports.fillPatternRecursive)(results, trie, config, pattern, newWord, tiles);
599
+ tiles.splice(index, 0, tile);
1035
600
  }
1036
- return patterns;
1037
- });
1038
- }
1039
- generateStartIndices(cells) {
1040
- return Array(cells.length - 1)
1041
- .fill(0)
1042
- .map((_, startIndex) => startIndex)
1043
- .filter((startIndex) => startIndex === 0 || !cells[startIndex - 1].hasTile());
1044
- }
1045
- generateEndIndices(cells, startIndex) {
1046
- return Array(cells.length - startIndex - 1)
1047
- .fill(0)
1048
- .map((_, endIndex) => endIndex + startIndex + 1)
1049
- .filter((endIndex) => endIndex >= cells.length - 1 || !cells[endIndex + 1].hasTile());
601
+ }
602
+ pattern.cells[indexOfFirstCellWithoutTile].tile = previousTile;
1050
603
  }
1051
- }
1052
- exports["default"] = PatternsGenerator;
604
+ };
605
+ exports.fillPatternRecursive = fillPatternRecursive;
606
+ exports["default"] = fillPattern;
1053
607
 
1054
608
 
1055
609
  /***/ }),
1056
610
 
1057
- /***/ 19368:
1058
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
611
+ /***/ 50856:
612
+ /***/ ((__unused_webpack_module, exports) => {
1059
613
 
1060
614
 
1061
615
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1062
- const constants_1 = __webpack_require__(38436);
1063
- class ScoresCalculator {
1064
- constructor(config) {
1065
- this.reduceCellScore = ({ multiplier, score }, cell) => {
1066
- const bonus = this.config.getCellBonus(cell);
1067
- const { characterMultiplier, wordMultiplier } = bonus && bonus.canApply(this.config, cell) ? bonus.value : constants_1.NO_BONUS;
1068
- const characterScore = cell.tile.isBlank ? this.config.blankScore : this.config.pointsMap[cell.tile.character];
1069
- return {
1070
- multiplier: multiplier * wordMultiplier,
1071
- score: score + characterScore * characterMultiplier,
1072
- };
1073
- };
1074
- this.config = config;
1075
- }
1076
- calculate(pattern) {
1077
- return this.calculatePatternScoreWithCollisions(pattern) + this.calculateBonusScore(pattern);
1078
- }
1079
- calculateBonusScore(pattern) {
1080
- const areAllTilesUsed = pattern.getEmptyCellsCount() === this.config.maximumCharactersCount;
1081
- return areAllTilesUsed ? this.config.allTilesBonusScore : 0;
616
+ const generateEndIndices = (cells, startIndex) => {
617
+ if (cells.length === 0) {
618
+ return [];
1082
619
  }
1083
- calculatePatternScoreWithCollisions(pattern) {
1084
- return pattern
1085
- .getCollisions()
1086
- .reduce((patternsScore, collisionPattern) => patternsScore + this.calculatePatternScore(collisionPattern), this.calculatePatternScore(pattern));
1087
- }
1088
- calculatePatternScore(pattern) {
1089
- const { multiplier, score } = pattern.cells.reduce(this.reduceCellScore, {
1090
- multiplier: 1,
1091
- score: 0,
1092
- });
1093
- return score * multiplier;
620
+ const endIndices = [];
621
+ for (let endIndex = startIndex + 1; endIndex < cells.length - 1; ++endIndex) {
622
+ if (!cells[endIndex + 1].hasTile()) {
623
+ endIndices.push(endIndex);
624
+ }
1094
625
  }
1095
- }
1096
- exports["default"] = ScoresCalculator;
626
+ endIndices.push(cells.length - 1);
627
+ return endIndices;
628
+ };
629
+ exports["default"] = generateEndIndices;
1097
630
 
1098
631
 
1099
632
  /***/ }),
1100
633
 
1101
- /***/ 66650:
634
+ /***/ 41331:
1102
635
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
1103
636
 
1104
637
 
@@ -1107,67 +640,23 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
1107
640
  };
1108
641
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1109
642
  const types_1 = __webpack_require__(46452);
1110
- const getUniquePatterns_1 = __importDefault(__webpack_require__(55555));
1111
- const PatternsFiller_1 = __importDefault(__webpack_require__(6700));
1112
- const PatternsGenerator_1 = __importDefault(__webpack_require__(34196));
1113
- const ScoresCalculator_1 = __importDefault(__webpack_require__(19368));
1114
- class Solver {
1115
- constructor(config, trie) {
1116
- this.patternsFiller = new PatternsFiller_1.default(config, trie);
1117
- this.patternsGenerator = new PatternsGenerator_1.default(config);
1118
- this.scoresCalculator = new ScoresCalculator_1.default(config);
1119
- }
1120
- solve(board, tiles) {
1121
- const patterns = this.patternsGenerator.generate(board);
1122
- const filledPatterns = patterns.flatMap((pattern) => this.patternsFiller.fill(pattern, tiles));
1123
- const uniquePatterns = (0, getUniquePatterns_1.default)(filledPatterns);
1124
- const results = uniquePatterns.map((pattern, index) => new types_1.Result({
1125
- cells: pattern.cells,
1126
- collisions: pattern.getCollisions().map((collision) => collision.cells),
1127
- id: index,
1128
- points: this.scoresCalculator.calculate(pattern),
1129
- }));
1130
- return results;
1131
- }
1132
- }
1133
- exports["default"] = Solver;
1134
-
1135
-
1136
- /***/ }),
1137
-
1138
- /***/ 55555:
1139
- /***/ ((__unused_webpack_module, exports) => {
1140
-
1141
-
1142
- Object.defineProperty(exports, "__esModule", ({ value: true }));
1143
- const getPatternHash = (pattern) => {
1144
- return pattern.cells
1145
- .map((cell) => {
1146
- const blank = cell.tile.isBlank ? '!' : '';
1147
- const tile = cell.tile.character + blank;
1148
- // eslint-disable-next-line prefer-template
1149
- return cell.x + ',' + cell.y + ',' + tile;
1150
- })
1151
- .join('-');
1152
- };
1153
- const getUniquePatterns = (patterns) => {
1154
- const hashes = new Set();
1155
- const uniquePatterns = [];
1156
- for (const pattern of patterns) {
1157
- const hash = getPatternHash(pattern);
1158
- if (!hashes.has(hash)) {
1159
- hashes.add(hash);
1160
- uniquePatterns.push(pattern);
1161
- }
1162
- }
1163
- return uniquePatterns;
643
+ const generatePattern_1 = __importDefault(__webpack_require__(87984));
644
+ const generateVectors_1 = __importDefault(__webpack_require__(18618));
645
+ const generateHorizontalPatterns = (config, board) => {
646
+ const getNthVector = (index) => board.getRow(index);
647
+ const vectorsCount = config.boardHeight;
648
+ const horizontalVectors = (0, generateVectors_1.default)({ getNthVector, vectorsCount });
649
+ const horizontalPatterns = horizontalVectors.flatMap((cells) => {
650
+ return (0, generatePattern_1.default)({ board, config, PatternModel: types_1.HorizontalPattern, cells });
651
+ });
652
+ return horizontalPatterns;
1164
653
  };
1165
- exports["default"] = getUniquePatterns;
654
+ exports["default"] = generateHorizontalPatterns;
1166
655
 
1167
656
 
1168
657
  /***/ }),
1169
658
 
1170
- /***/ 40368:
659
+ /***/ 87984:
1171
660
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
1172
661
 
1173
662
 
@@ -1175,101 +664,28 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
1175
664
  return (mod && mod.__esModule) ? mod : { "default": mod };
1176
665
  };
1177
666
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1178
- exports["default"] = void 0;
1179
- var Solver_1 = __webpack_require__(66650);
1180
- Object.defineProperty(exports, "default", ({ enumerable: true, get: function () { return __importDefault(Solver_1).default; } }));
1181
-
1182
-
1183
- /***/ }),
1184
-
1185
- /***/ 61704:
1186
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
1187
-
1188
-
1189
- Object.defineProperty(exports, "__esModule", ({ value: true }));
1190
- const lib_1 = __webpack_require__(60337);
1191
- const FILE_URL = 'https://raw.githubusercontent.com/enz/german-wordlist/master/words';
1192
- const getDeDeWordList = async () => {
1193
- return (0, lib_1.getTxtWordList)(FILE_URL);
1194
- };
1195
- exports["default"] = getDeDeWordList;
1196
-
1197
-
1198
- /***/ }),
1199
-
1200
- /***/ 3284:
1201
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
1202
-
1203
-
1204
- Object.defineProperty(exports, "__esModule", ({ value: true }));
1205
- const lib_1 = __webpack_require__(60337);
1206
- const FILE_URL = 'https://www.wordgamedictionary.com/sowpods/download/sowpods.txt';
1207
- const getEnGbWordList = async () => {
1208
- return (0, lib_1.getTxtWordList)(FILE_URL);
1209
- };
1210
- exports["default"] = getEnGbWordList;
1211
-
1212
-
1213
- /***/ }),
1214
-
1215
- /***/ 163:
1216
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
1217
-
1218
-
1219
- Object.defineProperty(exports, "__esModule", ({ value: true }));
1220
- const lib_1 = __webpack_require__(60337);
1221
- const FILE_URL = 'https://www.wordgamedictionary.com/twl06/download/twl06.txt';
1222
- const getEnUsWordList = async () => {
1223
- return (0, lib_1.getTxtWordList)(FILE_URL);
1224
- };
1225
- exports["default"] = getEnUsWordList;
1226
-
1227
-
1228
- /***/ }),
1229
-
1230
- /***/ 87537:
1231
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
1232
-
1233
-
1234
- Object.defineProperty(exports, "__esModule", ({ value: true }));
1235
- const lib_1 = __webpack_require__(60337);
1236
- const FILE_URL = 'https://raw.githubusercontent.com/kamilmielnik/fise-2/master/fise-2.txt';
1237
- const getEsEsWordList = async () => {
1238
- const words = await (0, lib_1.getTxtWordList)(FILE_URL);
1239
- return words.map(normalizeWord);
1240
- };
1241
- const normalizeWord = (word) => {
1242
- // normalization from https://stackoverflow.com/a/37511463
1243
- return word.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
1244
- };
1245
- exports["default"] = getEsEsWordList;
1246
-
1247
-
1248
- /***/ }),
1249
-
1250
- /***/ 27098:
1251
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
1252
-
1253
-
1254
- Object.defineProperty(exports, "__esModule", ({ value: true }));
1255
- const lib_1 = __webpack_require__(60337);
1256
- const FILE_URL =
1257
- // eslint-disable-next-line max-len
1258
- 'https://raw.githubusercontent.com/hbenbel/French-Dictionary/a573eab10cc798d7d5da7daab4d2ac0259bb46a3/dictionary/dictionary.txt';
1259
- const getFrFrWordList = async () => {
1260
- const words = await (0, lib_1.getTxtWordList)(FILE_URL);
1261
- return words.map(normalizeWord);
1262
- };
1263
- const normalizeWord = (word) => {
1264
- // normalization from https://stackoverflow.com/a/37511463
1265
- return word.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
667
+ const generateEndIndices_1 = __importDefault(__webpack_require__(50856));
668
+ const generateStartIndices_1 = __importDefault(__webpack_require__(78182));
669
+ const generatePattern = ({ board, cells, config, PatternModel, }) => {
670
+ const startIndices = (0, generateStartIndices_1.default)(cells);
671
+ return startIndices.flatMap((startIndex) => {
672
+ const endIndices = (0, generateEndIndices_1.default)(cells, startIndex);
673
+ const patterns = [];
674
+ for (const endIndex of endIndices) {
675
+ const pattern = new PatternModel(board, cells.slice(startIndex, endIndex + 1));
676
+ if (pattern.canBePlaced(config)) {
677
+ patterns.push(pattern);
678
+ }
679
+ }
680
+ return patterns;
681
+ });
1266
682
  };
1267
- exports["default"] = getFrFrWordList;
683
+ exports["default"] = generatePattern;
1268
684
 
1269
685
 
1270
686
  /***/ }),
1271
687
 
1272
- /***/ 81848:
688
+ /***/ 29480:
1273
689
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
1274
690
 
1275
691
 
@@ -1277,132 +693,54 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
1277
693
  return (mod && mod.__esModule) ? mod : { "default": mod };
1278
694
  };
1279
695
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1280
- const cheerio_1 = __importDefault(__webpack_require__(55473));
1281
- const memfs_1 = __webpack_require__(28098);
1282
- const unzipper_1 = __importDefault(__webpack_require__(23428));
1283
- const url_1 = __webpack_require__(57310);
1284
- const lib_1 = __webpack_require__(60337);
1285
- const PAGE_URL = 'https://sjp.pl/sl/growy/';
1286
- const FILE_TO_EXTRACT_FROM_ZIP = 'slowa.txt';
1287
- const getPlPlWordList = async () => {
1288
- const tempFilename = (0, lib_1.getTempFilename)();
1289
- const zipUrl = await fetchZipUrl(PAGE_URL);
1290
- const zipTempFilename = await (0, lib_1.downloadFile)(zipUrl);
1291
- await unzip(zipTempFilename, tempFilename);
1292
- memfs_1.fs.unlinkSync(zipTempFilename);
1293
- const file = memfs_1.fs.readFileSync(tempFilename, 'utf-8');
1294
- memfs_1.fs.unlinkSync(tempFilename);
1295
- const words = (0, lib_1.extractWords)(file.toLocaleString());
1296
- return words;
1297
- };
1298
- const fetchZipUrl = async (url) => {
1299
- const html = await (0, lib_1.downloadHtml)(url);
1300
- const filename = await parseZipContainingPage(html);
1301
- const { href } = new url_1.URL(filename, url);
1302
- return href;
1303
- };
1304
- const parseZipContainingPage = (html) => {
1305
- const $ = cheerio_1.default.load(html);
1306
- const $links = $('a');
1307
- const links = Array.from($links)
1308
- .map((link) => $(link).attr('href'))
1309
- .filter(Boolean);
1310
- const zipFilename = links.find((link) => link.endsWith('.zip'));
1311
- if (typeof zipFilename === 'undefined') {
1312
- throw new Error('Cannot find link to zip file on the page');
1313
- }
1314
- return zipFilename;
696
+ const generateHorizontalPatterns_1 = __importDefault(__webpack_require__(41331));
697
+ const generateVerticalPatterns_1 = __importDefault(__webpack_require__(75069));
698
+ const generatePatterns = (config, board) => {
699
+ const horizontalPatterns = (0, generateHorizontalPatterns_1.default)(config, board);
700
+ const verticalPatterns = (0, generateVerticalPatterns_1.default)(config, board);
701
+ return horizontalPatterns.concat(verticalPatterns);
1315
702
  };
1316
- const unzip = (zipFilename, outputFilename) => {
1317
- return memfs_1.fs
1318
- .createReadStream(zipFilename)
1319
- .pipe(unzipper_1.default.Parse())
1320
- .on('entry', (entry) => {
1321
- const fileName = entry.path;
1322
- if (fileName === FILE_TO_EXTRACT_FROM_ZIP) {
1323
- entry.pipe(memfs_1.fs.createWriteStream(outputFilename));
1324
- }
1325
- else {
1326
- entry.autodrain();
1327
- }
1328
- })
1329
- .promise();
1330
- };
1331
- exports["default"] = getPlPlWordList;
703
+ exports["default"] = generatePatterns;
1332
704
 
1333
705
 
1334
706
  /***/ }),
1335
707
 
1336
- /***/ 8769:
1337
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
708
+ /***/ 78182:
709
+ /***/ ((__unused_webpack_module, exports) => {
1338
710
 
1339
711
 
1340
- var __importDefault = (this && this.__importDefault) || function (mod) {
1341
- return (mod && mod.__esModule) ? mod : { "default": mod };
1342
- };
1343
712
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1344
- const types_1 = __webpack_require__(46452);
1345
- const getDeDeWordList_1 = __importDefault(__webpack_require__(61704));
1346
- const getEnGbWordList_1 = __importDefault(__webpack_require__(3284));
1347
- const getEnUsWordList_1 = __importDefault(__webpack_require__(163));
1348
- const getEsEsWordList_1 = __importDefault(__webpack_require__(87537));
1349
- const getFrFrWordList_1 = __importDefault(__webpack_require__(27098));
1350
- const getPlPlWordList_1 = __importDefault(__webpack_require__(81848));
1351
- const localeMap = {
1352
- [types_1.Locale.DE_DE]: getDeDeWordList_1.default,
1353
- [types_1.Locale.EN_GB]: getEnGbWordList_1.default,
1354
- [types_1.Locale.EN_US]: getEnUsWordList_1.default,
1355
- [types_1.Locale.ES_ES]: getEsEsWordList_1.default,
1356
- [types_1.Locale.FR_FR]: getFrFrWordList_1.default,
1357
- [types_1.Locale.PL_PL]: getPlPlWordList_1.default,
713
+ const generateStartIndices = (cells) => {
714
+ if (cells.length === 0) {
715
+ return [];
716
+ }
717
+ const startIndices = [0];
718
+ for (let startIndex = 1; startIndex < cells.length - 1; ++startIndex) {
719
+ if (!cells[startIndex - 1].hasTile()) {
720
+ startIndices.push(startIndex);
721
+ }
722
+ }
723
+ return startIndices;
1358
724
  };
1359
- const getWordList = (locale) => localeMap[locale]();
1360
- exports["default"] = getWordList;
725
+ exports["default"] = generateStartIndices;
1361
726
 
1362
727
 
1363
728
  /***/ }),
1364
729
 
1365
- /***/ 51585:
1366
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
730
+ /***/ 18618:
731
+ /***/ ((__unused_webpack_module, exports) => {
1367
732
 
1368
733
 
1369
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
1370
- if (k2 === undefined) k2 = k;
1371
- var desc = Object.getOwnPropertyDescriptor(m, k);
1372
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
1373
- desc = { enumerable: true, get: function() { return m[k]; } };
1374
- }
1375
- Object.defineProperty(o, k2, desc);
1376
- }) : (function(o, m, k, k2) {
1377
- if (k2 === undefined) k2 = k;
1378
- o[k2] = m[k];
1379
- }));
1380
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
1381
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
1382
- };
1383
- var __importDefault = (this && this.__importDefault) || function (mod) {
1384
- return (mod && mod.__esModule) ? mod : { "default": mod };
1385
- };
1386
734
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1387
- exports.getWordList = exports.getDeDeWordList = exports.getPlPlWordList = exports.getFrFrWordList = exports.getEnGbWordList = exports.getEnUsWordList = void 0;
1388
- var getEnUsWordList_1 = __webpack_require__(163);
1389
- Object.defineProperty(exports, "getEnUsWordList", ({ enumerable: true, get: function () { return __importDefault(getEnUsWordList_1).default; } }));
1390
- var getEnGbWordList_1 = __webpack_require__(3284);
1391
- Object.defineProperty(exports, "getEnGbWordList", ({ enumerable: true, get: function () { return __importDefault(getEnGbWordList_1).default; } }));
1392
- var getFrFrWordList_1 = __webpack_require__(27098);
1393
- Object.defineProperty(exports, "getFrFrWordList", ({ enumerable: true, get: function () { return __importDefault(getFrFrWordList_1).default; } }));
1394
- var getPlPlWordList_1 = __webpack_require__(81848);
1395
- Object.defineProperty(exports, "getPlPlWordList", ({ enumerable: true, get: function () { return __importDefault(getPlPlWordList_1).default; } }));
1396
- var getDeDeWordList_1 = __webpack_require__(61704);
1397
- Object.defineProperty(exports, "getDeDeWordList", ({ enumerable: true, get: function () { return __importDefault(getDeDeWordList_1).default; } }));
1398
- var getWordList_1 = __webpack_require__(8769);
1399
- Object.defineProperty(exports, "getWordList", ({ enumerable: true, get: function () { return __importDefault(getWordList_1).default; } }));
1400
- __exportStar(__webpack_require__(60337), exports);
735
+ const generateVectors = ({ getNthVector, vectorsCount }) => {
736
+ return Array.from({ length: vectorsCount }, (_, index) => getNthVector(index));
737
+ };
738
+ exports["default"] = generateVectors;
1401
739
 
1402
740
 
1403
741
  /***/ }),
1404
742
 
1405
- /***/ 920:
743
+ /***/ 75069:
1406
744
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
1407
745
 
1408
746
 
@@ -1410,116 +748,67 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
1410
748
  return (mod && mod.__esModule) ? mod : { "default": mod };
1411
749
  };
1412
750
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1413
- const follow_redirects_1 = __webpack_require__(24396);
1414
- const memfs_1 = __webpack_require__(28098);
1415
- const getTempFilename_1 = __importDefault(__webpack_require__(52688));
1416
- const downloadFile = (url) => {
1417
- return new Promise((resolve, reject) => {
1418
- const tempFilename = (0, getTempFilename_1.default)();
1419
- const protocol = url.startsWith('https') ? follow_redirects_1.https : follow_redirects_1.http;
1420
- const writeStream = memfs_1.fs.createWriteStream(tempFilename);
1421
- const request = protocol.get(url, (response) => {
1422
- if (typeof response.statusCode === 'undefined' || response.statusCode >= 400) {
1423
- reject(new Error(`Cannot download file: ${url}`));
1424
- return;
1425
- }
1426
- response.on('error', (error) => {
1427
- writeStream.close();
1428
- reject(error);
1429
- });
1430
- response.on('end', () => {
1431
- writeStream.on('finish', () => {
1432
- writeStream.close();
1433
- resolve(tempFilename);
1434
- });
1435
- });
1436
- response.pipe(writeStream);
1437
- });
1438
- request.on('error', (error) => {
1439
- writeStream.close();
1440
- reject(error);
1441
- });
751
+ const types_1 = __webpack_require__(46452);
752
+ const generatePattern_1 = __importDefault(__webpack_require__(87984));
753
+ const generateVectors_1 = __importDefault(__webpack_require__(18618));
754
+ const generateVerticalPatterns = (config, board) => {
755
+ const getNthVector = (index) => board.getColumn(index);
756
+ const vectorsCount = config.boardWidth;
757
+ const verticalVectors = (0, generateVectors_1.default)({ getNthVector, vectorsCount });
758
+ const verticalPatterns = verticalVectors.flatMap((cells) => {
759
+ return (0, generatePattern_1.default)({ board, config, PatternModel: types_1.VerticalPattern, cells });
1442
760
  });
761
+ return verticalPatterns;
1443
762
  };
1444
- exports["default"] = downloadFile;
763
+ exports["default"] = generateVerticalPatterns;
1445
764
 
1446
765
 
1447
766
  /***/ }),
1448
767
 
1449
- /***/ 78015:
768
+ /***/ 56628:
1450
769
  /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
1451
770
 
1452
771
 
1453
772
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1454
- const follow_redirects_1 = __webpack_require__(24396);
1455
- const downloadHtml = (url) => {
1456
- return new Promise((resolve, reject) => {
1457
- const protocol = url.startsWith('https') ? follow_redirects_1.https : follow_redirects_1.http;
1458
- protocol.get(url, (response) => {
1459
- let data = '';
1460
- response.setEncoding('utf8');
1461
- response.on('data', (chunk) => {
1462
- data += chunk;
1463
- });
1464
- response.on('end', () => {
1465
- resolve(data);
1466
- });
1467
- response.on('error', reject);
1468
- });
1469
- });
1470
- };
1471
- exports["default"] = downloadHtml;
1472
-
1473
-
1474
- /***/ }),
1475
-
1476
- /***/ 39759:
1477
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
1478
-
1479
-
1480
- var __importDefault = (this && this.__importDefault) || function (mod) {
1481
- return (mod && mod.__esModule) ? mod : { "default": mod };
1482
- };
1483
- Object.defineProperty(exports, "__esModule", ({ value: true }));
1484
- const findFirstWordIndex_1 = __importDefault(__webpack_require__(47669));
1485
- const extractWords = (file) => {
1486
- const lines = file.replace(/\r/g, '').split('\n');
1487
- const firstWordIndex = (0, findFirstWordIndex_1.default)(lines);
1488
- const words = lines
1489
- .slice(firstWordIndex)
1490
- .filter((word) => word.trim().length > 0)
1491
- .map((word) => word.toLocaleLowerCase());
1492
- return words;
773
+ const constants_1 = __webpack_require__(38436);
774
+ const getCellsScore = (config, cells) => {
775
+ const total = cells.reduce(({ multiplier, score }, cell) => {
776
+ const bonus = config.getCellBonus(cell);
777
+ const { characterMultiplier, wordMultiplier } = bonus && bonus.canApply(config, cell) ? bonus.value : constants_1.NO_BONUS;
778
+ const characterScore = cell.tile.isBlank ? config.blankScore : config.pointsMap[cell.tile.character];
779
+ return {
780
+ multiplier: multiplier * wordMultiplier,
781
+ score: score + characterScore * characterMultiplier,
782
+ };
783
+ }, { multiplier: 1, score: 0 });
784
+ return total.score * total.multiplier;
1493
785
  };
1494
- exports["default"] = extractWords;
786
+ exports["default"] = getCellsScore;
1495
787
 
1496
788
 
1497
789
  /***/ }),
1498
790
 
1499
- /***/ 47669:
791
+ /***/ 22352:
1500
792
  /***/ ((__unused_webpack_module, exports) => {
1501
793
 
1502
794
 
1503
795
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1504
- const findFirstWordIndex = (lines) => {
1505
- const firstWordIndex = lines.findIndex((line, index) => {
1506
- const nextLine = line[index + 1] || '';
1507
- const isNextLineInOrder = line.localeCompare(nextLine) === 1;
1508
- const hasWhitespace = Boolean(line.match(/\s/));
1509
- const isEmpty = line.trim().length === 0;
1510
- return !isEmpty && !hasWhitespace && isNextLineInOrder;
1511
- });
1512
- if (typeof firstWordIndex === 'undefined') {
1513
- throw new Error('Cannot find index of the first word in the file');
1514
- }
1515
- return firstWordIndex;
796
+ const getPatternHash = (pattern) => {
797
+ return pattern.cells
798
+ .map((cell) => {
799
+ const blank = cell.tile.isBlank ? '!' : '';
800
+ const tile = cell.tile.character + blank;
801
+ // eslint-disable-next-line prefer-template
802
+ return cell.x + ',' + cell.y + ',' + tile;
803
+ })
804
+ .join('-');
1516
805
  };
1517
- exports["default"] = findFirstWordIndex;
806
+ exports["default"] = getPatternHash;
1518
807
 
1519
808
 
1520
809
  /***/ }),
1521
810
 
1522
- /***/ 93938:
811
+ /***/ 94808:
1523
812
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
1524
813
 
1525
814
 
@@ -1527,14 +816,21 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
1527
816
  return (mod && mod.__esModule) ? mod : { "default": mod };
1528
817
  };
1529
818
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1530
- const crypto_1 = __importDefault(__webpack_require__(6113));
1531
- const getHash = (bytes = 8) => crypto_1.default.randomBytes(bytes).toString('hex');
1532
- exports["default"] = getHash;
819
+ const getCellsScore_1 = __importDefault(__webpack_require__(56628));
820
+ const getPatternScore = (config, pattern) => {
821
+ const areAllTilesUsed = pattern.getEmptyCellsCount() === config.maximumCharactersCount;
822
+ const bonusScore = areAllTilesUsed ? config.allTilesBonusScore : 0;
823
+ const score = pattern
824
+ .getCollisions()
825
+ .reduce((sum, collision) => sum + (0, getCellsScore_1.default)(config, collision.cells), (0, getCellsScore_1.default)(config, pattern.cells));
826
+ return score + bonusScore;
827
+ };
828
+ exports["default"] = getPatternScore;
1533
829
 
1534
830
 
1535
831
  /***/ }),
1536
832
 
1537
- /***/ 52688:
833
+ /***/ 55555:
1538
834
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
1539
835
 
1540
836
 
@@ -1542,16 +838,25 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
1542
838
  return (mod && mod.__esModule) ? mod : { "default": mod };
1543
839
  };
1544
840
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1545
- const getHash_1 = __importDefault(__webpack_require__(93938));
1546
- const getTempFilename = () => {
1547
- return `/${(0, getHash_1.default)()}.txt`;
841
+ const getPatternHash_1 = __importDefault(__webpack_require__(22352));
842
+ const getUniquePatterns = (patterns) => {
843
+ const hashes = new Set();
844
+ const uniquePatterns = [];
845
+ for (const pattern of patterns) {
846
+ const hash = (0, getPatternHash_1.default)(pattern);
847
+ if (!hashes.has(hash)) {
848
+ hashes.add(hash);
849
+ uniquePatterns.push(pattern);
850
+ }
851
+ }
852
+ return uniquePatterns;
1548
853
  };
1549
- exports["default"] = getTempFilename;
854
+ exports["default"] = getUniquePatterns;
1550
855
 
1551
856
 
1552
857
  /***/ }),
1553
858
 
1554
- /***/ 78029:
859
+ /***/ 40368:
1555
860
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
1556
861
 
1557
862
 
@@ -1559,22 +864,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
1559
864
  return (mod && mod.__esModule) ? mod : { "default": mod };
1560
865
  };
1561
866
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1562
- const memfs_1 = __webpack_require__(28098);
1563
- const downloadFile_1 = __importDefault(__webpack_require__(920));
1564
- const extractWords_1 = __importDefault(__webpack_require__(39759));
1565
- const getTxtWordList = async (url) => {
1566
- const tempFilename = await (0, downloadFile_1.default)(url);
1567
- const file = memfs_1.fs.readFileSync(tempFilename, 'utf-8');
1568
- const words = (0, extractWords_1.default)(file.toLocaleString());
1569
- memfs_1.fs.unlinkSync(tempFilename);
1570
- return words;
1571
- };
1572
- exports["default"] = getTxtWordList;
867
+ exports.solve = void 0;
868
+ var solve_1 = __webpack_require__(46243);
869
+ Object.defineProperty(exports, "solve", ({ enumerable: true, get: function () { return __importDefault(solve_1).default; } }));
1573
870
 
1574
871
 
1575
872
  /***/ }),
1576
873
 
1577
- /***/ 60337:
874
+ /***/ 46243:
1578
875
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
1579
876
 
1580
877
 
@@ -1582,21 +879,23 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
1582
879
  return (mod && mod.__esModule) ? mod : { "default": mod };
1583
880
  };
1584
881
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1585
- exports.getTxtWordList = exports.getTempFilename = exports.getHash = exports.findFirstWordIndex = exports.extractWords = exports.downloadHtml = exports.downloadFile = void 0;
1586
- var downloadFile_1 = __webpack_require__(920);
1587
- Object.defineProperty(exports, "downloadFile", ({ enumerable: true, get: function () { return __importDefault(downloadFile_1).default; } }));
1588
- var downloadHtml_1 = __webpack_require__(78015);
1589
- Object.defineProperty(exports, "downloadHtml", ({ enumerable: true, get: function () { return __importDefault(downloadHtml_1).default; } }));
1590
- var extractWords_1 = __webpack_require__(39759);
1591
- Object.defineProperty(exports, "extractWords", ({ enumerable: true, get: function () { return __importDefault(extractWords_1).default; } }));
1592
- var findFirstWordIndex_1 = __webpack_require__(47669);
1593
- Object.defineProperty(exports, "findFirstWordIndex", ({ enumerable: true, get: function () { return __importDefault(findFirstWordIndex_1).default; } }));
1594
- var getHash_1 = __webpack_require__(93938);
1595
- Object.defineProperty(exports, "getHash", ({ enumerable: true, get: function () { return __importDefault(getHash_1).default; } }));
1596
- var getTempFilename_1 = __webpack_require__(52688);
1597
- Object.defineProperty(exports, "getTempFilename", ({ enumerable: true, get: function () { return __importDefault(getTempFilename_1).default; } }));
1598
- var getTxtWordList_1 = __webpack_require__(78029);
1599
- Object.defineProperty(exports, "getTxtWordList", ({ enumerable: true, get: function () { return __importDefault(getTxtWordList_1).default; } }));
882
+ const fillPattern_1 = __importDefault(__webpack_require__(83594));
883
+ const generatePatterns_1 = __importDefault(__webpack_require__(29480));
884
+ const getPatternScore_1 = __importDefault(__webpack_require__(94808));
885
+ const getUniquePatterns_1 = __importDefault(__webpack_require__(55555));
886
+ const solve = (trie, config, board, tiles) => {
887
+ const patterns = (0, generatePatterns_1.default)(config, board);
888
+ const filledPatterns = patterns.flatMap((pattern) => (0, fillPattern_1.default)(trie, config, pattern, tiles));
889
+ const uniquePatterns = (0, getUniquePatterns_1.default)(filledPatterns);
890
+ const results = uniquePatterns.map((pattern, index) => ({
891
+ cells: pattern.cells.map((cell) => cell.toJson()),
892
+ collisions: pattern.getCollisions().map((collision) => collision.cells.map((cell) => cell.toJson())),
893
+ id: index,
894
+ points: (0, getPatternScore_1.default)(config, pattern),
895
+ }));
896
+ return results;
897
+ };
898
+ exports["default"] = solve;
1600
899
 
1601
900
 
1602
901
  /***/ })
@@ -1608,7 +907,7 @@ Object.defineProperty(exports, "getTxtWordList", ({ enumerable: true, get: funct
1608
907
  var __webpack_require__ = require("../../webpack-api-runtime.js");
1609
908
  __webpack_require__.C(exports);
1610
909
  var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId))
1611
- var __webpack_exports__ = __webpack_require__.X(0, [50,429,939,911], () => (__webpack_exec__(207)));
910
+ var __webpack_exports__ = __webpack_require__.X(0, [50,429,939,911,44], () => (__webpack_exec__(62316)));
1612
911
  module.exports = __webpack_exports__;
1613
912
 
1614
913
  })();