@cubingcenter/scrambler 0.6.3 → 0.7.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 (115) hide show
  1. package/README.md +2 -0
  2. package/dist/puzzles/cube2/solver/search.d.ts.map +1 -1
  3. package/dist/puzzles/cube2/solver/search.js +3 -3
  4. package/dist/puzzles/cube2/solver/tables.d.ts +6 -0
  5. package/dist/puzzles/cube2/solver/tables.d.ts.map +1 -1
  6. package/dist/puzzles/cube2/solver/tables.js +16 -2
  7. package/dist/puzzles/cube3/index.d.ts +1 -0
  8. package/dist/puzzles/cube3/index.d.ts.map +1 -1
  9. package/dist/puzzles/cube3/moves.d.ts.map +1 -1
  10. package/dist/puzzles/cube3/moves.js +104 -18
  11. package/dist/puzzles/cube3/scrambler.d.ts +16 -1
  12. package/dist/puzzles/cube3/scrambler.d.ts.map +1 -1
  13. package/dist/puzzles/cube3/scrambler.js +1 -1
  14. package/dist/puzzles/cube3/solver/browser-loader.js +6 -2
  15. package/dist/puzzles/cube3/solver/index.d.ts +5 -3
  16. package/dist/puzzles/cube3/solver/index.d.ts.map +1 -1
  17. package/dist/puzzles/cube3/solver/index.js +2 -1
  18. package/dist/puzzles/cube3/solver/node-loader.js +9 -2
  19. package/dist/puzzles/cube3/solver/phase1.d.ts +18 -0
  20. package/dist/puzzles/cube3/solver/phase1.d.ts.map +1 -1
  21. package/dist/puzzles/cube3/solver/phase1.js +132 -14
  22. package/dist/puzzles/cube3/solver/phase2.d.ts +47 -0
  23. package/dist/puzzles/cube3/solver/phase2.d.ts.map +1 -1
  24. package/dist/puzzles/cube3/solver/phase2.js +236 -66
  25. package/dist/puzzles/cube3/solver/search-utils.d.ts +1 -1
  26. package/dist/puzzles/cube3/solver/search-utils.d.ts.map +1 -1
  27. package/dist/puzzles/cube3/solver/symmetry.d.ts +24 -0
  28. package/dist/puzzles/cube3/solver/symmetry.d.ts.map +1 -0
  29. package/dist/puzzles/cube3/solver/symmetry.js +74 -0
  30. package/dist/puzzles/cube3/solver/tables.d.ts +6 -1
  31. package/dist/puzzles/cube3/solver/tables.d.ts.map +1 -1
  32. package/dist/puzzles/cube3/validation.d.ts.map +1 -1
  33. package/dist/puzzles/cube3/validation.js +15 -7
  34. package/dist/puzzles/cube4/index.d.ts +3 -2
  35. package/dist/puzzles/cube4/index.d.ts.map +1 -1
  36. package/dist/puzzles/cube4/index.js +2 -2
  37. package/dist/puzzles/cube4/moves.d.ts +5 -0
  38. package/dist/puzzles/cube4/moves.d.ts.map +1 -1
  39. package/dist/puzzles/cube4/moves.js +120 -11
  40. package/dist/puzzles/cube4/reduction/browser-loader.d.ts +3 -0
  41. package/dist/puzzles/cube4/reduction/browser-loader.d.ts.map +1 -1
  42. package/dist/puzzles/cube4/reduction/browser-loader.js +34 -3
  43. package/dist/puzzles/cube4/reduction/center2.d.ts +20 -3
  44. package/dist/puzzles/cube4/reduction/center2.d.ts.map +1 -1
  45. package/dist/puzzles/cube4/reduction/center2.js +53 -9
  46. package/dist/puzzles/cube4/reduction/edge3.d.ts +4 -0
  47. package/dist/puzzles/cube4/reduction/edge3.d.ts.map +1 -1
  48. package/dist/puzzles/cube4/reduction/edge3.js +23 -3
  49. package/dist/puzzles/cube4/reduction/generated/c3_pair_dist.bin +1 -0
  50. package/dist/puzzles/cube4/reduction/generated/center2-manifest.json +36 -0
  51. package/dist/puzzles/cube4/reduction/generated/center2-pruning-wide.bin +1 -0
  52. package/dist/puzzles/cube4/reduction/generated/hc-distances.bin +1 -0
  53. package/dist/puzzles/cube4/reduction/generated/hc-manifest.json +38 -0
  54. package/dist/puzzles/cube4/reduction/generated/hc-move.bin +0 -0
  55. package/dist/puzzles/cube4/reduction/hc-pdb.d.ts +50 -0
  56. package/dist/puzzles/cube4/reduction/hc-pdb.d.ts.map +1 -0
  57. package/dist/puzzles/cube4/reduction/hc-pdb.js +202 -0
  58. package/dist/puzzles/cube4/reduction/node-loader.d.ts +5 -0
  59. package/dist/puzzles/cube4/reduction/node-loader.d.ts.map +1 -1
  60. package/dist/puzzles/cube4/reduction/node-loader.js +48 -8
  61. package/dist/puzzles/cube4/reduction/pairing-coordinate.js +5 -5
  62. package/dist/puzzles/cube4/reduction/phase3-search.d.ts +111 -5
  63. package/dist/puzzles/cube4/reduction/phase3-search.d.ts.map +1 -1
  64. package/dist/puzzles/cube4/reduction/phase3-search.js +341 -22
  65. package/dist/puzzles/cube4/reduction/solve.d.ts +112 -1
  66. package/dist/puzzles/cube4/reduction/solve.d.ts.map +1 -1
  67. package/dist/puzzles/cube4/reduction/solve.js +920 -181
  68. package/dist/puzzles/cube4/scrambler.d.ts +105 -4
  69. package/dist/puzzles/cube4/scrambler.d.ts.map +1 -1
  70. package/dist/puzzles/cube4/scrambler.js +216 -166
  71. package/dist/puzzles/cube4/state.d.ts.map +1 -1
  72. package/dist/puzzles/cube4/state.js +4 -1
  73. package/dist/puzzles/pyraminx/solver/search.d.ts.map +1 -1
  74. package/dist/puzzles/pyraminx/solver/search.js +3 -6
  75. package/dist/puzzles/pyraminx/solver/tables.d.ts +6 -0
  76. package/dist/puzzles/pyraminx/solver/tables.d.ts.map +1 -1
  77. package/dist/puzzles/pyraminx/solver/tables.js +17 -0
  78. package/dist/puzzles/skewb/solver/search.js +3 -3
  79. package/dist/puzzles/skewb/solver/tables.d.ts +6 -0
  80. package/dist/puzzles/skewb/solver/tables.d.ts.map +1 -1
  81. package/dist/puzzles/skewb/solver/tables.js +17 -0
  82. package/dist-cjs/puzzles/cube2/solver/search.js +2 -2
  83. package/dist-cjs/puzzles/cube2/solver/tables.js +17 -3
  84. package/dist-cjs/puzzles/cube3/moves.js +104 -18
  85. package/dist-cjs/puzzles/cube3/scrambler.js +1 -1
  86. package/dist-cjs/puzzles/cube3/solver/browser-loader.js +6 -2
  87. package/dist-cjs/puzzles/cube3/solver/index.js +8 -1
  88. package/dist-cjs/puzzles/cube3/solver/node-loader.js +9 -2
  89. package/dist-cjs/puzzles/cube3/solver/phase1.js +133 -14
  90. package/dist-cjs/puzzles/cube3/solver/phase2.js +233 -63
  91. package/dist-cjs/puzzles/cube3/solver/symmetry.js +80 -0
  92. package/dist-cjs/puzzles/cube3/validation.js +15 -7
  93. package/dist-cjs/puzzles/cube4/index.js +3 -1
  94. package/dist-cjs/puzzles/cube4/moves.js +121 -11
  95. package/dist-cjs/puzzles/cube4/reduction/browser-loader.js +34 -3
  96. package/dist-cjs/puzzles/cube4/reduction/center2.js +54 -9
  97. package/dist-cjs/puzzles/cube4/reduction/edge3.js +24 -3
  98. package/dist-cjs/puzzles/cube4/reduction/generated/c3_pair_dist.bin +1 -0
  99. package/dist-cjs/puzzles/cube4/reduction/generated/center2-manifest.json +36 -0
  100. package/dist-cjs/puzzles/cube4/reduction/generated/center2-pruning-wide.bin +1 -0
  101. package/dist-cjs/puzzles/cube4/reduction/generated/hc-distances.bin +1 -0
  102. package/dist-cjs/puzzles/cube4/reduction/generated/hc-manifest.json +38 -0
  103. package/dist-cjs/puzzles/cube4/reduction/generated/hc-move.bin +0 -0
  104. package/dist-cjs/puzzles/cube4/reduction/hc-pdb.js +213 -0
  105. package/dist-cjs/puzzles/cube4/reduction/node-loader.js +48 -8
  106. package/dist-cjs/puzzles/cube4/reduction/pairing-coordinate.js +5 -5
  107. package/dist-cjs/puzzles/cube4/reduction/phase3-search.js +343 -23
  108. package/dist-cjs/puzzles/cube4/reduction/solve.js +918 -173
  109. package/dist-cjs/puzzles/cube4/scrambler.js +214 -163
  110. package/dist-cjs/puzzles/cube4/state.js +4 -1
  111. package/dist-cjs/puzzles/pyraminx/solver/search.js +2 -5
  112. package/dist-cjs/puzzles/pyraminx/solver/tables.js +18 -1
  113. package/dist-cjs/puzzles/skewb/solver/search.js +2 -2
  114. package/dist-cjs/puzzles/skewb/solver/tables.js +18 -1
  115. package/package.json +14 -5
@@ -9,6 +9,7 @@ exports.clearCachedCube4Tables = clearCachedCube4Tables;
9
9
  exports.loadCube4ReductionTablesBrowser = loadCube4ReductionTablesBrowser;
10
10
  const edge3_js_1 = require("./edge3.js");
11
11
  const compressed_fetch_js_1 = require("../../shared/compressed-fetch.js");
12
+ const hc_pdb_js_1 = require("./hc-pdb.js");
12
13
  const GENERATED_DIRECTORY = "puzzles/cube4/reduction/generated";
13
14
  const CACHE_NAME = "cubingcenter-scrambler-tables-v1";
14
15
  let cachedTables;
@@ -36,13 +37,16 @@ async function loadCube4ReductionTablesBrowser(baseUrl) {
36
37
  return cachedTables;
37
38
  }
38
39
  const resolved = resolveBaseUrl(baseUrl);
39
- const [center1, center2, center3, edge3] = await Promise.all([
40
+ const [center1, center2, center3, edge3, hc] = await Promise.all([
40
41
  loadCenter1(resolved),
41
42
  loadCenter2(resolved),
42
43
  loadCenter3(resolved),
43
- loadEdge3(resolved)
44
+ loadEdge3(resolved),
45
+ loadHc(resolved)
44
46
  ]);
45
47
  cachedTables = { center1, center2, center3, edge3 };
48
+ if (hc)
49
+ cachedTables.hc = hc;
46
50
  return cachedTables;
47
51
  }
48
52
  async function fetchJson(baseUrl, file) {
@@ -79,7 +83,18 @@ async function loadCenter2(baseUrl) {
79
83
  const byte = pruningPacked[i >> 1];
80
84
  pruning[i] = (i & 1) === 0 ? byte & 0x0f : byte >> 4;
81
85
  }
82
- return { ctMove, rlMove, pruning };
86
+ const tables = { ctMove, rlMove, pruning };
87
+ if (manifest.pruningWideTable) {
88
+ const wideBuffer = await (0, compressed_fetch_js_1.fetchTableBuffer)(baseUrl, GENERATED_DIRECTORY, manifest.pruningWideTable.file, { cacheName: CACHE_NAME, compressed: manifest.pruningWideTable.compressed !== false });
89
+ const widePacked = new Uint8Array(wideBuffer);
90
+ const pruningWide = new Uint8Array(450450);
91
+ for (let i = 0; i < 450450; i++) {
92
+ const byte = widePacked[i >> 1];
93
+ pruningWide[i] = (i & 1) === 0 ? byte & 0x0f : byte >> 4;
94
+ }
95
+ tables.pruningWide = pruningWide;
96
+ }
97
+ return tables;
83
98
  }
84
99
  async function loadCenter3(baseUrl) {
85
100
  const manifest = await fetchJson(baseUrl, "center3-manifest.json");
@@ -95,6 +110,22 @@ async function loadCenter3(baseUrl) {
95
110
  async function loadEdge3(baseUrl) {
96
111
  const manifest = await fetchJson(baseUrl, "edge3-manifest.json");
97
112
  const distancesBuffer = await (0, compressed_fetch_js_1.fetchTableBuffer)(baseUrl, GENERATED_DIRECTORY, manifest.distances.file, { cacheName: CACHE_NAME, compressed: manifest.distances.compressed !== false });
113
+ // Keep nibble-packed (see node-loader.ts): all readers handle both formats.
98
114
  const distances = new Uint8Array(distancesBuffer);
99
115
  return { distances, distanceOfEdge: (0, edge3_js_1.edge3DistanceLookup)(distances) };
100
116
  }
117
+ async function loadHc(baseUrl) {
118
+ try {
119
+ const manifest = await fetchJson(baseUrl, "hc-manifest.json");
120
+ const distancesBuffer = await (0, compressed_fetch_js_1.fetchTableBuffer)(baseUrl, GENERATED_DIRECTORY, manifest.distances.file, { cacheName: CACHE_NAME, compressed: manifest.distances.compressed !== false });
121
+ const dense = (0, hc_pdb_js_1.buildHcDense)(new Uint8Array(distancesBuffer));
122
+ if (manifest.moveTable) {
123
+ const moveBuffer = await (0, compressed_fetch_js_1.fetchTableBuffer)(baseUrl, GENERATED_DIRECTORY, manifest.moveTable.file, { cacheName: CACHE_NAME, compressed: manifest.moveTable.compressed !== false });
124
+ dense.moves = new Int32Array(moveBuffer);
125
+ }
126
+ return dense;
127
+ }
128
+ catch {
129
+ return undefined;
130
+ }
131
+ }
@@ -13,12 +13,14 @@
13
13
  * - goal: ct == 0 and rl in the 6 reference goal patterns (even parity);
14
14
  * - the 28-move set keeps the ct and rl position sets separate, so the move
15
15
  * tables factor: ctmv (6,435×28) and rlmv (70×28);
16
- * - the search explores the first 23 moves (face moves + Uw2/Rw/Rw2/Rw').
16
+ * - the search explores the first 23 moves (face moves + Uw2/Rw/Rw2/Rw')
17
+ * by default; the wide set (`CENTER2_SEARCH_MOVES_WIDE`, all 28, with
18
+ * the `pruningWide` table) additionally tries Dw2/Lw/Lw2/Lw'/Bw2.
17
19
  *
18
20
  * The phase-1 → phase-2 bridge (alignment + encode) is in `reduction.ts`.
19
21
  */
20
22
  Object.defineProperty(exports, "__esModule", { value: true });
21
- exports.CENTER2_STATES = exports.CENTER2_RL_STATES = exports.CENTER2_CT_STATES = exports.CENTER2_GOAL_RL = exports.CENTER2_SEARCH_MOVES = exports.CENTER2_MOVES = void 0;
23
+ exports.ALIGNMENT_ROTATIONS = exports.CENTER2_STATES = exports.CENTER2_RL_STATES = exports.CENTER2_CT_STATES = exports.CENTER2_GOAL_RL = exports.CENTER2_SEARCH_MOVES_WIDE = exports.CENTER2_SEARCH_MOVES = exports.CENTER2_MOVES = void 0;
22
24
  exports.wingPermutationParity = wingPermutationParity;
23
25
  exports.encodeCenter2 = encodeCenter2;
24
26
  exports.isCenter2Goal = isCenter2Goal;
@@ -26,6 +28,7 @@ exports.center2Bridge = center2Bridge;
26
28
  exports.generateCenter2Tables = generateCenter2Tables;
27
29
  exports.solveCenter2 = solveCenter2;
28
30
  exports.solveCenter2All = solveCenter2All;
31
+ exports.getWingMoveMaps = getWingMoveMaps;
29
32
  exports.solveCenter2GatedLength = solveCenter2GatedLength;
30
33
  exports.solveCenter2Gated = solveCenter2Gated;
31
34
  exports.verifyCenter2 = verifyCenter2;
@@ -41,6 +44,12 @@ exports.CENTER2_MOVES = [
41
44
  ];
42
45
  /** The search's exploration set (the first 23 of CENTER2_MOVES). */
43
46
  exports.CENTER2_SEARCH_MOVES = exports.CENTER2_MOVES.slice(0, 23);
47
+ /**
48
+ * The wide exploration set: all 28 moves (adds Dw2/Lw/Lw2/Lw'/Bw2).
49
+ * Searches over this set must use the `pruningWide` table — the
50
+ * 23-move pruning distances are inadmissible here (they overestimate).
51
+ */
52
+ exports.CENTER2_SEARCH_MOVES_WIDE = exports.CENTER2_MOVES;
44
53
  /** The 6 reference goal rl patterns (full 70-space values, even parity). */
45
54
  exports.CENTER2_GOAL_RL = [0, 18, 28, 46, 54, 56];
46
55
  exports.CENTER2_CT_STATES = 6435;
@@ -125,6 +134,11 @@ const ALIGNMENT_CANDIDATES = [
125
134
  ["Uw", "Dw'"]
126
135
  ];
127
136
  function center2InvariantDiffs(centers) {
137
+ const rlAxis = centers[RL_POS[7]] % 3;
138
+ for (let i = 0; i < 7; i++) {
139
+ if (centers[RL_POS[i]] % 3 !== rlAxis)
140
+ return { ctDiff: -1, rlDiff: -1 };
141
+ }
128
142
  let ctDiff = 0;
129
143
  let rlDiff = 0;
130
144
  for (let i = 0; i < 15; i++) {
@@ -137,12 +151,18 @@ function center2InvariantDiffs(centers) {
137
151
  }
138
152
  return { ctDiff, rlDiff };
139
153
  }
154
+ exports.ALIGNMENT_ROTATIONS = [
155
+ [],
156
+ ["z"],
157
+ ["y"]
158
+ ];
140
159
  /**
141
160
  * Phase-1 → phase-2 bridge: apply the shortest alignment candidate that
142
161
  * makes the state coordinate-invariant, then encode.
143
162
  */
144
163
  function center2Bridge(state) {
145
- for (const alignment of ALIGNMENT_CANDIDATES) {
164
+ for (let idx = 0; idx < ALIGNMENT_CANDIDATES.length; idx++) {
165
+ const alignment = ALIGNMENT_CANDIDATES[idx];
146
166
  const aligned = alignment.length === 0
147
167
  ? state
148
168
  : (0, moves_js_1.applyCube4Algorithm)(state, alignment);
@@ -150,6 +170,7 @@ function center2Bridge(state) {
150
170
  if (ctDiff === 8 && rlDiff === 4) {
151
171
  return {
152
172
  alignment: [...alignment],
173
+ rotation: [...exports.ALIGNMENT_ROTATIONS[idx]],
153
174
  state: aligned,
154
175
  encoded: encodeCenter2(aligned)
155
176
  };
@@ -259,7 +280,31 @@ function generateCenter2Tables() {
259
280
  }
260
281
  }
261
282
  }
262
- return { ctMove, rlMove, pruning };
283
+ // Wide pruning BFS: same goals, all 28 moves (exact distances for the
284
+ // wide search; the 23-move table overestimates there).
285
+ const pruningWide = new Uint8Array(exports.CENTER2_STATES).fill(0xff);
286
+ const wideQueue = [];
287
+ for (const rl of exports.CENTER2_GOAL_RL) {
288
+ pruningWide[rl] = 0;
289
+ wideQueue.push(rl);
290
+ }
291
+ let wideHead = 0;
292
+ while (wideHead < wideQueue.length) {
293
+ const idx = wideQueue[wideHead++];
294
+ const ct = Math.floor(idx / exports.CENTER2_RL_STATES);
295
+ const rl = idx % exports.CENTER2_RL_STATES;
296
+ const d = pruningWide[idx];
297
+ for (let m = 0; m < exports.CENTER2_SEARCH_MOVES_WIDE.length; m++) {
298
+ const nextCt = ctMove[ct * exports.CENTER2_MOVES.length + m];
299
+ const nextRl = rlMove[rl * exports.CENTER2_MOVES.length + m];
300
+ const next = nextCt * exports.CENTER2_RL_STATES + nextRl;
301
+ if (pruningWide[next] === 0xff) {
302
+ pruningWide[next] = d + 1;
303
+ wideQueue.push(next);
304
+ }
305
+ }
306
+ }
307
+ return { ctMove, rlMove, pruning, pruningWide };
263
308
  }
264
309
  // The reference's cancellation rule (ckmv over move2std): skip the same base
265
310
  // move, or the same axis-class when the previous move's standard index is
@@ -434,24 +479,24 @@ function buildWingMoveMaps() {
434
479
  // ---------------------------------------------------------------------------
435
480
  // Verification gates
436
481
  // ---------------------------------------------------------------------------
437
- function verifyCenter2(tables) {
482
+ function verifyCenter2(tables, pruning = tables.pruning, moves = exports.CENTER2_SEARCH_MOVES) {
438
483
  const errors = [];
439
484
  for (const rl of exports.CENTER2_GOAL_RL) {
440
- if (tables.pruning[rl] !== 0) {
485
+ if (pruning[rl] !== 0) {
441
486
  errors.push(`Goal rl ${rl} must have pruning 0.`);
442
487
  }
443
488
  }
444
489
  let maxDepth = 0;
445
490
  for (let idx = 0; idx < exports.CENTER2_STATES; idx++) {
446
- const d = tables.pruning[idx];
491
+ const d = pruning[idx];
447
492
  if (d > maxDepth)
448
493
  maxDepth = d;
449
494
  const ct = Math.floor(idx / exports.CENTER2_RL_STATES);
450
495
  const rl = idx % exports.CENTER2_RL_STATES;
451
- for (let m = 0; m < exports.CENTER2_SEARCH_MOVES.length; m++) {
496
+ for (let m = 0; m < moves.length; m++) {
452
497
  const nc = tables.ctMove[ct * exports.CENTER2_MOVES.length + m];
453
498
  const nr = tables.rlMove[rl * exports.CENTER2_MOVES.length + m];
454
- const nd = tables.pruning[nc * exports.CENTER2_RL_STATES + nr];
499
+ const nd = pruning[nc * exports.CENTER2_RL_STATES + nr];
455
500
  if (nd < d - 1 || nd > d + 1) {
456
501
  errors.push(`Pruning inconsistency at ${idx} move ${exports.CENTER2_MOVES[m]}: ${d} -> ${nd}.`);
457
502
  break;
@@ -28,6 +28,7 @@ exports.getSymTables = getSymTables;
28
28
  exports.buildSymTables = buildSymTables;
29
29
  exports.getMvSymFrom = getMvSymFrom;
30
30
  exports.generateEdge3Tables = generateEdge3Tables;
31
+ exports.unpackEdge3Distances = unpackEdge3Distances;
31
32
  exports.edge3DistanceLookup = edge3DistanceLookup;
32
33
  exports.__edge3TestHooks = __edge3TestHooks;
33
34
  exports.verifyEdge3 = verifyEdge3;
@@ -479,8 +480,23 @@ function generateEdge3Tables(maxDepthCap = -1) {
479
480
  frontier = next;
480
481
  depth++;
481
482
  }
482
- const distanceOfEdge = edge3DistanceLookup(distances);
483
- return { distances, distanceOfEdge };
483
+ const unpacked = unpackEdge3Distances(distances);
484
+ const distanceOfEdge = edge3DistanceLookup(unpacked);
485
+ return { distances: unpacked, distanceOfEdge };
486
+ }
487
+ /**
488
+ * Unpack 4-bit nibble-packed distances into a byte-expanded Uint8Array (1 byte per state).
489
+ */
490
+ function unpackEdge3Distances(packed) {
491
+ if (packed.length >= exports.EDGE3_TOTAL)
492
+ return packed;
493
+ const unpacked = new Uint8Array(exports.EDGE3_TOTAL);
494
+ for (let i = 0; i < packed.length; i++) {
495
+ const b = packed[i];
496
+ unpacked[i << 1] = b & 0x0f;
497
+ unpacked[(i << 1) | 1] = b >> 4;
498
+ }
499
+ return unpacked;
484
500
  }
485
501
  /**
486
502
  * The distance lookup over a loaded distances buffer: builds the sym
@@ -491,9 +507,12 @@ function edge3DistanceLookup(distances) {
491
507
  const t = symTables ?? buildSymTables();
492
508
  const { sym2Raw, sym2Mask, raw2Sym, mvrot, mvroto } = t;
493
509
  const identity = Uint8Array.from({ length: 12 }, (_, i) => i);
510
+ const isUnpacked = distances.length >= exports.EDGE3_TOTAL;
494
511
  return (e) => {
495
512
  const std = (0, pairing_coordinate_js_1.normalizePairingState)(e, identity).edge;
496
513
  const idx = getMvSymFrom(std, identity, 20, sym2Raw, sym2Mask, raw2Sym, mvrot, mvroto) >> 3;
514
+ if (isUnpacked)
515
+ return distances[idx];
497
516
  return (distances[idx >> 1] >> ((idx & 1) * 4)) & 0x0f;
498
517
  };
499
518
  }
@@ -511,8 +530,10 @@ function verifyEdge3(tables) {
511
530
  errors.push("Solved state must have distance 0.");
512
531
  }
513
532
  let seen = 0;
533
+ const isUnpacked = tables.distances.length >= exports.EDGE3_TOTAL;
514
534
  for (let i = 0; i < exports.EDGE3_TOTAL; i++) {
515
- if (((tables.distances[i >> 1] >> ((i & 1) * 4)) & 0x0f) !== 0x0f)
535
+ const d = isUnpacked ? tables.distances[i] : ((tables.distances[i >> 1] >> ((i & 1) * 4)) & 0x0f);
536
+ if (d !== 0x0f)
516
537
  seen++;
517
538
  }
518
539
  if (seen !== exports.EDGE3_TOTAL) {