@rednaxela101/cubing 0.63.5
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.
- package/README.md +120 -0
- package/alg/index.d.ts +1 -0
- package/bluetooth/index.d.ts +1 -0
- package/dist/bin/chunks/chunk-22VWCGBC.js +13 -0
- package/dist/bin/chunks/chunk-22VWCGBC.js.map +7 -0
- package/dist/bin/order.js +59 -0
- package/dist/bin/order.js.map +7 -0
- package/dist/bin/puzzle-geometry-bin.js +407 -0
- package/dist/bin/puzzle-geometry-bin.js.map +7 -0
- package/dist/bin/scramble.js +188 -0
- package/dist/bin/scramble.js.map +7 -0
- package/dist/bin/svg.js +56 -0
- package/dist/bin/svg.js.map +7 -0
- package/dist/lib/cubing/alg/index.d.ts +2 -0
- package/dist/lib/cubing/alg/index.js +43 -0
- package/dist/lib/cubing/alg/index.js.map +7 -0
- package/dist/lib/cubing/bluetooth/index.d.ts +189 -0
- package/dist/lib/cubing/bluetooth/index.js +2271 -0
- package/dist/lib/cubing/bluetooth/index.js.map +7 -0
- package/dist/lib/cubing/chunks/big-puzzle-orientation-BA6QHO5C.js +68 -0
- package/dist/lib/cubing/chunks/big-puzzle-orientation-BA6QHO5C.js.map +7 -0
- package/dist/lib/cubing/chunks/chunk-2VJB4TMH.js +1774 -0
- package/dist/lib/cubing/chunks/chunk-2VJB4TMH.js.map +7 -0
- package/dist/lib/cubing/chunks/chunk-52ZXJEUO.js +665 -0
- package/dist/lib/cubing/chunks/chunk-52ZXJEUO.js.map +7 -0
- package/dist/lib/cubing/chunks/chunk-56VZAEPF.js +274 -0
- package/dist/lib/cubing/chunks/chunk-56VZAEPF.js.map +7 -0
- package/dist/lib/cubing/chunks/chunk-7GUL3OBQ.js +9 -0
- package/dist/lib/cubing/chunks/chunk-7GUL3OBQ.js.map +7 -0
- package/dist/lib/cubing/chunks/chunk-7L7BJSIM.js +21 -0
- package/dist/lib/cubing/chunks/chunk-7L7BJSIM.js.map +7 -0
- package/dist/lib/cubing/chunks/chunk-AESPJKN6.js +265 -0
- package/dist/lib/cubing/chunks/chunk-AESPJKN6.js.map +7 -0
- package/dist/lib/cubing/chunks/chunk-C2Q347XS.js +89 -0
- package/dist/lib/cubing/chunks/chunk-C2Q347XS.js.map +7 -0
- package/dist/lib/cubing/chunks/chunk-CGBMJBU3.js +1195 -0
- package/dist/lib/cubing/chunks/chunk-CGBMJBU3.js.map +7 -0
- package/dist/lib/cubing/chunks/chunk-HZQONEMD.js +249 -0
- package/dist/lib/cubing/chunks/chunk-HZQONEMD.js.map +7 -0
- package/dist/lib/cubing/chunks/chunk-IAGCVPL3.js +1069 -0
- package/dist/lib/cubing/chunks/chunk-IAGCVPL3.js.map +7 -0
- package/dist/lib/cubing/chunks/chunk-NAPITA3L.js +1 -0
- package/dist/lib/cubing/chunks/chunk-NAPITA3L.js.map +7 -0
- package/dist/lib/cubing/chunks/chunk-XPDJUSZ7.js +1876 -0
- package/dist/lib/cubing/chunks/chunk-XPDJUSZ7.js.map +7 -0
- package/dist/lib/cubing/chunks/chunk-YSI6PF35.js +619 -0
- package/dist/lib/cubing/chunks/chunk-YSI6PF35.js.map +7 -0
- package/dist/lib/cubing/chunks/inside-LG2EAKCL.js +557 -0
- package/dist/lib/cubing/chunks/inside-LG2EAKCL.js.map +7 -0
- package/dist/lib/cubing/chunks/puzzles-dynamic-2x2x2-JYJJXB4V.js +142 -0
- package/dist/lib/cubing/chunks/puzzles-dynamic-2x2x2-JYJJXB4V.js.map +7 -0
- package/dist/lib/cubing/chunks/puzzles-dynamic-3x3x3-FYXD7SIU.js +365 -0
- package/dist/lib/cubing/chunks/puzzles-dynamic-3x3x3-FYXD7SIU.js.map +7 -0
- package/dist/lib/cubing/chunks/puzzles-dynamic-4x4x4-AIGABOAR.js +132 -0
- package/dist/lib/cubing/chunks/puzzles-dynamic-4x4x4-AIGABOAR.js.map +7 -0
- package/dist/lib/cubing/chunks/puzzles-dynamic-5x5x5-JUNRX27W.js +277 -0
- package/dist/lib/cubing/chunks/puzzles-dynamic-5x5x5-JUNRX27W.js.map +7 -0
- package/dist/lib/cubing/chunks/puzzles-dynamic-clock-USGQTDPO.js +836 -0
- package/dist/lib/cubing/chunks/puzzles-dynamic-clock-USGQTDPO.js.map +7 -0
- package/dist/lib/cubing/chunks/puzzles-dynamic-fto-WJHMLYCJ.js +100 -0
- package/dist/lib/cubing/chunks/puzzles-dynamic-fto-WJHMLYCJ.js.map +7 -0
- package/dist/lib/cubing/chunks/puzzles-dynamic-megaminx-2LVHIDL4.js +224 -0
- package/dist/lib/cubing/chunks/puzzles-dynamic-megaminx-2LVHIDL4.js.map +7 -0
- package/dist/lib/cubing/chunks/puzzles-dynamic-pyraminx-7UWX4HHI.js +93 -0
- package/dist/lib/cubing/chunks/puzzles-dynamic-pyraminx-7UWX4HHI.js.map +7 -0
- package/dist/lib/cubing/chunks/puzzles-dynamic-square1-PQEKBPFN.js +842 -0
- package/dist/lib/cubing/chunks/puzzles-dynamic-square1-PQEKBPFN.js.map +7 -0
- package/dist/lib/cubing/chunks/search-dynamic-sgs-2x2x2-XFKQ4VJS.js +125 -0
- package/dist/lib/cubing/chunks/search-dynamic-sgs-2x2x2-XFKQ4VJS.js.map +7 -0
- package/dist/lib/cubing/chunks/search-dynamic-sgs-megaminx-ZDOOLEDW.js +1564 -0
- package/dist/lib/cubing/chunks/search-dynamic-sgs-megaminx-ZDOOLEDW.js.map +7 -0
- package/dist/lib/cubing/chunks/search-dynamic-sgs-pyraminx-W6UJWBYY.js +108 -0
- package/dist/lib/cubing/chunks/search-dynamic-sgs-pyraminx-W6UJWBYY.js.map +7 -0
- package/dist/lib/cubing/chunks/search-dynamic-sgs-skewb-FXGKV4KD.js +125 -0
- package/dist/lib/cubing/chunks/search-dynamic-sgs-skewb-FXGKV4KD.js.map +7 -0
- package/dist/lib/cubing/chunks/search-dynamic-sgs-unofficial-YK6HA7BK.js +644 -0
- package/dist/lib/cubing/chunks/search-dynamic-sgs-unofficial-YK6HA7BK.js.map +7 -0
- package/dist/lib/cubing/chunks/search-dynamic-solve-3x3x3-DLMAGPXS.js +2549 -0
- package/dist/lib/cubing/chunks/search-dynamic-solve-3x3x3-DLMAGPXS.js.map +7 -0
- package/dist/lib/cubing/chunks/search-dynamic-solve-4x4x4-NONXQHOJ.js +2923 -0
- package/dist/lib/cubing/chunks/search-dynamic-solve-4x4x4-NONXQHOJ.js.map +7 -0
- package/dist/lib/cubing/chunks/search-dynamic-solve-fto-3GQ2HLSW.js +1405 -0
- package/dist/lib/cubing/chunks/search-dynamic-solve-fto-3GQ2HLSW.js.map +7 -0
- package/dist/lib/cubing/chunks/search-worker-entry.js +19 -0
- package/dist/lib/cubing/chunks/search-worker-entry.js.map +7 -0
- package/dist/lib/cubing/chunks/square1-stickerings-W2ZLZWIN.js +73 -0
- package/dist/lib/cubing/chunks/square1-stickerings-W2ZLZWIN.js.map +7 -0
- package/dist/lib/cubing/chunks/twips-2RNTWYNZ.js +433 -0
- package/dist/lib/cubing/chunks/twips-2RNTWYNZ.js.map +7 -0
- package/dist/lib/cubing/chunks/twips_wasm_bg-TJNYGA2C-23XTPLIK.js +10 -0
- package/dist/lib/cubing/chunks/twips_wasm_bg-TJNYGA2C-23XTPLIK.js.map +7 -0
- package/dist/lib/cubing/chunks/twisty-dynamic-3d-JO6OGKOF.js +2424 -0
- package/dist/lib/cubing/chunks/twisty-dynamic-3d-JO6OGKOF.js.map +7 -0
- package/dist/lib/cubing/index-BX6f56uo.d.ts +76 -0
- package/dist/lib/cubing/index-CcRu94bx.d.ts +2622 -0
- package/dist/lib/cubing/kpuzzle/index.d.ts +2 -0
- package/dist/lib/cubing/kpuzzle/index.js +12 -0
- package/dist/lib/cubing/kpuzzle/index.js.map +7 -0
- package/dist/lib/cubing/notation/index.d.ts +32 -0
- package/dist/lib/cubing/notation/index.js +20 -0
- package/dist/lib/cubing/notation/index.js.map +7 -0
- package/dist/lib/cubing/outside-BCzgSYQ_.d.ts +38 -0
- package/dist/lib/cubing/protocol/index.d.ts +28 -0
- package/dist/lib/cubing/protocol/index.js +20 -0
- package/dist/lib/cubing/protocol/index.js.map +7 -0
- package/dist/lib/cubing/puzzle-geometry/index.d.ts +2 -0
- package/dist/lib/cubing/puzzle-geometry/index.js +5024 -0
- package/dist/lib/cubing/puzzle-geometry/index.js.map +7 -0
- package/dist/lib/cubing/puzzles/index.d.ts +2 -0
- package/dist/lib/cubing/puzzles/index.js +23 -0
- package/dist/lib/cubing/puzzles/index.js.map +7 -0
- package/dist/lib/cubing/scramble/index.d.ts +2 -0
- package/dist/lib/cubing/scramble/index.js +16 -0
- package/dist/lib/cubing/scramble/index.js.map +7 -0
- package/dist/lib/cubing/search/index.d.ts +7 -0
- package/dist/lib/cubing/search/index.js +37 -0
- package/dist/lib/cubing/search/index.js.map +7 -0
- package/dist/lib/cubing/stream/index.d.ts +2 -0
- package/dist/lib/cubing/stream/index.js +111 -0
- package/dist/lib/cubing/stream/index.js.map +7 -0
- package/dist/lib/cubing/twisty/index.d.ts +2 -0
- package/dist/lib/cubing/twisty/index.js +6236 -0
- package/dist/lib/cubing/twisty/index.js.map +7 -0
- package/experimental-json-schema/kpuzzle/KPatternData.schema.json +34 -0
- package/experimental-json-schema/kpuzzle/KPuzzleDefinition.schema.json +97 -0
- package/experimental-json-schema/kpuzzle/KTransformationData.schema.json +27 -0
- package/kpuzzle/index.d.ts +1 -0
- package/notation/index.d.ts +1 -0
- package/package.json +146 -0
- package/protocol/index.d.ts +1 -0
- package/puzzle-geometry/index.d.ts +1 -0
- package/puzzles/index.d.ts +1 -0
- package/scramble/index.d.ts +1 -0
- package/search/index.d.ts +1 -0
- package/stream/index.d.ts +1 -0
- package/twisty/index.d.ts +1 -0
|
@@ -0,0 +1,665 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Alg,
|
|
3
|
+
Move,
|
|
4
|
+
TraversalDownUp,
|
|
5
|
+
functionFromTraversal
|
|
6
|
+
} from "./chunk-XPDJUSZ7.js";
|
|
7
|
+
|
|
8
|
+
// src/cubing/kpuzzle/combine.ts
|
|
9
|
+
function combineTransformationData(definition, transformationData1, transformationData2) {
|
|
10
|
+
const newTransformationData = {};
|
|
11
|
+
for (const orbitDefinition of definition.orbits) {
|
|
12
|
+
const orbit1 = transformationData1[orbitDefinition.orbitName];
|
|
13
|
+
const orbit2 = transformationData2[orbitDefinition.orbitName];
|
|
14
|
+
if (isOrbitTransformationDataIdentityUncached(
|
|
15
|
+
orbitDefinition.numOrientations,
|
|
16
|
+
orbit2
|
|
17
|
+
)) {
|
|
18
|
+
newTransformationData[orbitDefinition.orbitName] = orbit1;
|
|
19
|
+
} else if (isOrbitTransformationDataIdentityUncached(
|
|
20
|
+
orbitDefinition.numOrientations,
|
|
21
|
+
orbit1
|
|
22
|
+
)) {
|
|
23
|
+
newTransformationData[orbitDefinition.orbitName] = orbit2;
|
|
24
|
+
} else {
|
|
25
|
+
const newPerm = new Array(orbitDefinition.numPieces);
|
|
26
|
+
if (orbitDefinition.numOrientations === 1) {
|
|
27
|
+
for (let idx = 0; idx < orbitDefinition.numPieces; idx++) {
|
|
28
|
+
newPerm[idx] = orbit1.permutation[orbit2.permutation[idx]];
|
|
29
|
+
}
|
|
30
|
+
newTransformationData[orbitDefinition.orbitName] = {
|
|
31
|
+
permutation: newPerm,
|
|
32
|
+
orientationDelta: orbit1.orientationDelta
|
|
33
|
+
};
|
|
34
|
+
} else {
|
|
35
|
+
const newOri = new Array(orbitDefinition.numPieces);
|
|
36
|
+
for (let idx = 0; idx < orbitDefinition.numPieces; idx++) {
|
|
37
|
+
newOri[idx] = (orbit1.orientationDelta[orbit2.permutation[idx]] + orbit2.orientationDelta[idx]) % orbitDefinition.numOrientations;
|
|
38
|
+
newPerm[idx] = orbit1.permutation[orbit2.permutation[idx]];
|
|
39
|
+
}
|
|
40
|
+
newTransformationData[orbitDefinition.orbitName] = {
|
|
41
|
+
permutation: newPerm,
|
|
42
|
+
orientationDelta: newOri
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return newTransformationData;
|
|
48
|
+
}
|
|
49
|
+
function applyTransformationDataToKPatternData(definition, patternData, transformationData) {
|
|
50
|
+
const newPatternData = {};
|
|
51
|
+
for (const orbitDefinition of definition.orbits) {
|
|
52
|
+
const patternOrbit = patternData[orbitDefinition.orbitName];
|
|
53
|
+
const transformationOrbit = transformationData[orbitDefinition.orbitName];
|
|
54
|
+
if (isOrbitTransformationDataIdentityUncached(
|
|
55
|
+
orbitDefinition.numOrientations,
|
|
56
|
+
transformationOrbit
|
|
57
|
+
)) {
|
|
58
|
+
newPatternData[orbitDefinition.orbitName] = patternOrbit;
|
|
59
|
+
} else {
|
|
60
|
+
const newPieces = new Array(orbitDefinition.numPieces);
|
|
61
|
+
if (orbitDefinition.numOrientations === 1) {
|
|
62
|
+
for (let idx = 0; idx < orbitDefinition.numPieces; idx++) {
|
|
63
|
+
newPieces[idx] = patternOrbit.pieces[transformationOrbit.permutation[idx]];
|
|
64
|
+
}
|
|
65
|
+
const newOrbitData = {
|
|
66
|
+
pieces: newPieces,
|
|
67
|
+
orientation: patternOrbit.orientation
|
|
68
|
+
// copy all 0
|
|
69
|
+
};
|
|
70
|
+
newPatternData[orbitDefinition.orbitName] = newOrbitData;
|
|
71
|
+
} else {
|
|
72
|
+
const newOrientation = new Array(orbitDefinition.numPieces);
|
|
73
|
+
const newOrientationMod = patternOrbit.orientationMod ? new Array(orbitDefinition.numPieces) : void 0;
|
|
74
|
+
for (let idx = 0; idx < orbitDefinition.numPieces; idx++) {
|
|
75
|
+
const transformationIdx = transformationOrbit.permutation[idx];
|
|
76
|
+
let mod = orbitDefinition.numOrientations;
|
|
77
|
+
if (patternOrbit.orientationMod) {
|
|
78
|
+
const orientationMod = patternOrbit.orientationMod[transformationIdx];
|
|
79
|
+
newOrientationMod[idx] = orientationMod;
|
|
80
|
+
mod = orientationMod || orbitDefinition.numOrientations;
|
|
81
|
+
}
|
|
82
|
+
newOrientation[idx] = (patternOrbit.orientation[transformationIdx] + transformationOrbit.orientationDelta[idx]) % mod;
|
|
83
|
+
newPieces[idx] = patternOrbit.pieces[transformationIdx];
|
|
84
|
+
}
|
|
85
|
+
const newOrbitData = {
|
|
86
|
+
pieces: newPieces,
|
|
87
|
+
orientation: newOrientation
|
|
88
|
+
};
|
|
89
|
+
if (newOrientationMod) {
|
|
90
|
+
newOrbitData.orientationMod = newOrientationMod;
|
|
91
|
+
}
|
|
92
|
+
newPatternData[orbitDefinition.orbitName] = newOrbitData;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return newPatternData;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// src/cubing/kpuzzle/construct.ts
|
|
100
|
+
var FREEZE = false;
|
|
101
|
+
var identityOrbitCache = /* @__PURE__ */ new Map();
|
|
102
|
+
function constructIdentityOrbitTransformation(numPieces) {
|
|
103
|
+
const cached = identityOrbitCache.get(numPieces);
|
|
104
|
+
if (cached) {
|
|
105
|
+
return cached;
|
|
106
|
+
}
|
|
107
|
+
const newPermutation = new Array(numPieces);
|
|
108
|
+
const newOrientation = new Array(numPieces);
|
|
109
|
+
for (let i = 0; i < numPieces; i++) {
|
|
110
|
+
newPermutation[i] = i;
|
|
111
|
+
newOrientation[i] = 0;
|
|
112
|
+
}
|
|
113
|
+
const orbitTransformation = {
|
|
114
|
+
permutation: newPermutation,
|
|
115
|
+
orientationDelta: newOrientation
|
|
116
|
+
};
|
|
117
|
+
if (FREEZE) {
|
|
118
|
+
Object.freeze(newPermutation);
|
|
119
|
+
Object.freeze(newOrientation);
|
|
120
|
+
Object.freeze(orbitTransformation);
|
|
121
|
+
}
|
|
122
|
+
identityOrbitCache.set(numPieces, orbitTransformation);
|
|
123
|
+
return orbitTransformation;
|
|
124
|
+
}
|
|
125
|
+
function constructIdentityTransformationDataUncached(definition) {
|
|
126
|
+
const transformation = {};
|
|
127
|
+
for (const orbitDefinition of definition.orbits) {
|
|
128
|
+
transformation[orbitDefinition.orbitName] = constructIdentityOrbitTransformation(orbitDefinition.numPieces);
|
|
129
|
+
}
|
|
130
|
+
if (FREEZE) {
|
|
131
|
+
Object.freeze(transformation);
|
|
132
|
+
}
|
|
133
|
+
return transformation;
|
|
134
|
+
}
|
|
135
|
+
function moveToTransformationUncached(kpuzzle, move) {
|
|
136
|
+
function getTransformationData(key, multiplyAmount) {
|
|
137
|
+
const s = key.toString();
|
|
138
|
+
const movesDef = kpuzzle.definition.moves[s];
|
|
139
|
+
if (movesDef) {
|
|
140
|
+
return repeatTransformationUncached(kpuzzle, movesDef, multiplyAmount);
|
|
141
|
+
}
|
|
142
|
+
const derivedDef = kpuzzle.definition.derivedMoves?.[s];
|
|
143
|
+
if (derivedDef) {
|
|
144
|
+
return repeatTransformationUncached(
|
|
145
|
+
kpuzzle,
|
|
146
|
+
kpuzzle.algToTransformation(derivedDef).transformationData,
|
|
147
|
+
multiplyAmount
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
return void 0;
|
|
151
|
+
}
|
|
152
|
+
const data = getTransformationData(move.quantum, move.amount) ?? // Handle e.g. `y2` if `y2` is defined.
|
|
153
|
+
// Note: this doesn't handle multiples.
|
|
154
|
+
getTransformationData(move, 1) ?? // Handle e.g. `y2'` if `y2` is defined.
|
|
155
|
+
// Note: this doesn't handle multiples.
|
|
156
|
+
getTransformationData(move.invert, -1);
|
|
157
|
+
if (data) {
|
|
158
|
+
return data;
|
|
159
|
+
}
|
|
160
|
+
throw new Error(`Invalid move for KPuzzle (${kpuzzle.name()}): ${move}`);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// src/cubing/kpuzzle/KTransformation.ts
|
|
164
|
+
var KTransformation = class _KTransformation {
|
|
165
|
+
constructor(kpuzzle, transformationData) {
|
|
166
|
+
this.kpuzzle = kpuzzle;
|
|
167
|
+
this.transformationData = transformationData;
|
|
168
|
+
}
|
|
169
|
+
kpuzzle;
|
|
170
|
+
transformationData;
|
|
171
|
+
toJSON() {
|
|
172
|
+
return {
|
|
173
|
+
experimentalPuzzleName: this.kpuzzle.name(),
|
|
174
|
+
transformationData: this.transformationData
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
invert() {
|
|
178
|
+
return new _KTransformation(
|
|
179
|
+
this.kpuzzle,
|
|
180
|
+
invertTransformation(this.kpuzzle, this.transformationData)
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
// For optimizations, we want to make it cheap to rely on optimizations when a
|
|
184
|
+
// transformation is an identity. Here, we try to make it cheaper by:
|
|
185
|
+
// - only calculating when needed, and
|
|
186
|
+
// - caching the result.
|
|
187
|
+
#cachedIsIdentity;
|
|
188
|
+
// TODO: is `null` worse here?
|
|
189
|
+
isIdentityTransformation() {
|
|
190
|
+
return this.#cachedIsIdentity ??= this.isIdentical(
|
|
191
|
+
this.kpuzzle.identityTransformation()
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
/** @deprecated */
|
|
195
|
+
static experimentalConstructIdentity(kpuzzle) {
|
|
196
|
+
const transformation = new _KTransformation(
|
|
197
|
+
kpuzzle,
|
|
198
|
+
constructIdentityTransformationDataUncached(kpuzzle.definition)
|
|
199
|
+
);
|
|
200
|
+
transformation.#cachedIsIdentity = true;
|
|
201
|
+
return transformation;
|
|
202
|
+
}
|
|
203
|
+
isIdentical(t2) {
|
|
204
|
+
return isTransformationDataIdentical(
|
|
205
|
+
this.kpuzzle,
|
|
206
|
+
this.transformationData,
|
|
207
|
+
t2.transformationData
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
// Convenience function
|
|
211
|
+
/** @deprecated */
|
|
212
|
+
apply(source) {
|
|
213
|
+
return this.applyTransformation(this.kpuzzle.toTransformation(source));
|
|
214
|
+
}
|
|
215
|
+
applyTransformation(t2) {
|
|
216
|
+
if (this.kpuzzle !== t2.kpuzzle) {
|
|
217
|
+
throw new Error(
|
|
218
|
+
`Tried to apply a transformation for a KPuzzle (${t2.kpuzzle.name()}) to a different KPuzzle (${this.kpuzzle.name()}).`
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
if (this.#cachedIsIdentity) {
|
|
222
|
+
return new _KTransformation(this.kpuzzle, t2.transformationData);
|
|
223
|
+
}
|
|
224
|
+
if (t2.#cachedIsIdentity) {
|
|
225
|
+
return new _KTransformation(this.kpuzzle, this.transformationData);
|
|
226
|
+
}
|
|
227
|
+
return new _KTransformation(
|
|
228
|
+
this.kpuzzle,
|
|
229
|
+
combineTransformationData(
|
|
230
|
+
this.kpuzzle.definition,
|
|
231
|
+
this.transformationData,
|
|
232
|
+
t2.transformationData
|
|
233
|
+
)
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
applyMove(move) {
|
|
237
|
+
return this.applyTransformation(this.kpuzzle.moveToTransformation(move));
|
|
238
|
+
}
|
|
239
|
+
applyAlg(alg) {
|
|
240
|
+
return this.applyTransformation(this.kpuzzle.algToTransformation(alg));
|
|
241
|
+
}
|
|
242
|
+
// Convenience. Useful for chaining.
|
|
243
|
+
toKPattern() {
|
|
244
|
+
return KPattern.fromTransformation(this);
|
|
245
|
+
}
|
|
246
|
+
// TODO: support calculating this for a given start state. (For `R U R' U` on 3x3x3, should this default to 5 or 10?)
|
|
247
|
+
repetitionOrder() {
|
|
248
|
+
return transformationRepetitionOrder(this.kpuzzle.definition, this);
|
|
249
|
+
}
|
|
250
|
+
selfMultiply(amount) {
|
|
251
|
+
return new _KTransformation(
|
|
252
|
+
this.kpuzzle,
|
|
253
|
+
repeatTransformationUncached(
|
|
254
|
+
this.kpuzzle,
|
|
255
|
+
this.transformationData,
|
|
256
|
+
amount
|
|
257
|
+
)
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
// src/cubing/kpuzzle/calculate.ts
|
|
263
|
+
function isOrbitTransformationDataIdentityUncached(numOrientations, orbitTransformationData) {
|
|
264
|
+
if (!orbitTransformationData.permutation) {
|
|
265
|
+
console.log(orbitTransformationData);
|
|
266
|
+
}
|
|
267
|
+
const { permutation } = orbitTransformationData;
|
|
268
|
+
const numPieces = permutation.length;
|
|
269
|
+
for (let idx = 0; idx < numPieces; idx++) {
|
|
270
|
+
if (permutation[idx] !== idx) {
|
|
271
|
+
return false;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
if (numOrientations > 1) {
|
|
275
|
+
const { orientationDelta: orientation } = orbitTransformationData;
|
|
276
|
+
for (let idx = 0; idx < numPieces; idx++) {
|
|
277
|
+
if (orientation[idx] !== 0) {
|
|
278
|
+
return false;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
return true;
|
|
283
|
+
}
|
|
284
|
+
function isOrbitTransformationDataIdentical(orbitDefinition, orbitTransformationData1, orbitTransformationData2, options = {}) {
|
|
285
|
+
for (let idx = 0; idx < orbitDefinition.numPieces; idx++) {
|
|
286
|
+
if (!options?.ignorePieceOrientations && orbitTransformationData1.orientationDelta[idx] !== orbitTransformationData2.orientationDelta[idx]) {
|
|
287
|
+
return false;
|
|
288
|
+
}
|
|
289
|
+
if (!options?.ignorePiecePermutation && orbitTransformationData1.permutation[idx] !== orbitTransformationData2.permutation[idx]) {
|
|
290
|
+
return false;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return true;
|
|
294
|
+
}
|
|
295
|
+
function isTransformationDataIdentical(kpuzzle, transformationData1, transformationData2) {
|
|
296
|
+
for (const orbitDefinition of kpuzzle.definition.orbits) {
|
|
297
|
+
if (!isOrbitTransformationDataIdentical(
|
|
298
|
+
orbitDefinition,
|
|
299
|
+
transformationData1[orbitDefinition.orbitName],
|
|
300
|
+
transformationData2[orbitDefinition.orbitName]
|
|
301
|
+
)) {
|
|
302
|
+
return false;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
return true;
|
|
306
|
+
}
|
|
307
|
+
function isOrbitPatternDataIdentical(orbitDefinition, orbitPatternData1, orbitPatternData2, options = {}) {
|
|
308
|
+
for (let idx = 0; idx < orbitDefinition.numPieces; idx++) {
|
|
309
|
+
if (!options?.ignorePieceOrientations && (orbitPatternData1.orientation[idx] !== orbitPatternData2.orientation[idx] || (orbitPatternData1.orientationMod?.[idx] ?? 0) !== (orbitPatternData2.orientationMod?.[idx] ?? 0))) {
|
|
310
|
+
return false;
|
|
311
|
+
}
|
|
312
|
+
if (!options?.ignorePieceIndices && orbitPatternData1.pieces[idx] !== orbitPatternData2.pieces[idx]) {
|
|
313
|
+
return false;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return true;
|
|
317
|
+
}
|
|
318
|
+
function isPatternDataIdentical(kpuzzle, patternData1, patternData2) {
|
|
319
|
+
for (const orbitDefinition of kpuzzle.definition.orbits) {
|
|
320
|
+
if (!isOrbitPatternDataIdentical(
|
|
321
|
+
orbitDefinition,
|
|
322
|
+
patternData1[orbitDefinition.orbitName],
|
|
323
|
+
patternData2[orbitDefinition.orbitName]
|
|
324
|
+
)) {
|
|
325
|
+
return false;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
return true;
|
|
329
|
+
}
|
|
330
|
+
function invertTransformation(kpuzzle, transformationData) {
|
|
331
|
+
const newTransformationData = {};
|
|
332
|
+
for (const orbitDefinition of kpuzzle.definition.orbits) {
|
|
333
|
+
const orbitTransformationData = transformationData[orbitDefinition.orbitName];
|
|
334
|
+
if (isOrbitTransformationDataIdentityUncached(
|
|
335
|
+
orbitDefinition.numOrientations,
|
|
336
|
+
orbitTransformationData
|
|
337
|
+
)) {
|
|
338
|
+
newTransformationData[orbitDefinition.orbitName] = orbitTransformationData;
|
|
339
|
+
} else if (orbitDefinition.numOrientations === 1) {
|
|
340
|
+
const newPerm = new Array(orbitDefinition.numPieces);
|
|
341
|
+
for (let idx = 0; idx < orbitDefinition.numPieces; idx++) {
|
|
342
|
+
newPerm[orbitTransformationData.permutation[idx]] = idx;
|
|
343
|
+
}
|
|
344
|
+
newTransformationData[orbitDefinition.orbitName] = {
|
|
345
|
+
permutation: newPerm,
|
|
346
|
+
orientationDelta: orbitTransformationData.orientationDelta
|
|
347
|
+
};
|
|
348
|
+
} else {
|
|
349
|
+
const newPerm = new Array(orbitDefinition.numPieces);
|
|
350
|
+
const newOri = new Array(orbitDefinition.numPieces);
|
|
351
|
+
for (let idx = 0; idx < orbitDefinition.numPieces; idx++) {
|
|
352
|
+
const fromIdx = orbitTransformationData.permutation[idx];
|
|
353
|
+
newPerm[fromIdx] = idx;
|
|
354
|
+
newOri[fromIdx] = (orbitDefinition.numOrientations - orbitTransformationData.orientationDelta[idx] + orbitDefinition.numOrientations) % orbitDefinition.numOrientations;
|
|
355
|
+
}
|
|
356
|
+
newTransformationData[orbitDefinition.orbitName] = {
|
|
357
|
+
permutation: newPerm,
|
|
358
|
+
orientationDelta: newOri
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
return newTransformationData;
|
|
363
|
+
}
|
|
364
|
+
function repeatTransformationUncached(kpuzzle, transformationData, amount) {
|
|
365
|
+
if (amount === 1) {
|
|
366
|
+
return transformationData;
|
|
367
|
+
}
|
|
368
|
+
if (amount < 0) {
|
|
369
|
+
return repeatTransformationUncached(
|
|
370
|
+
kpuzzle,
|
|
371
|
+
invertTransformation(kpuzzle, transformationData),
|
|
372
|
+
-amount
|
|
373
|
+
);
|
|
374
|
+
}
|
|
375
|
+
if (amount === 0) {
|
|
376
|
+
const { transformationData: transformationData2 } = kpuzzle.identityTransformation();
|
|
377
|
+
return transformationData2;
|
|
378
|
+
}
|
|
379
|
+
let halfish = transformationData;
|
|
380
|
+
if (amount !== 2) {
|
|
381
|
+
halfish = repeatTransformationUncached(
|
|
382
|
+
kpuzzle,
|
|
383
|
+
transformationData,
|
|
384
|
+
Math.floor(amount / 2)
|
|
385
|
+
);
|
|
386
|
+
}
|
|
387
|
+
const twiceHalfish = combineTransformationData(
|
|
388
|
+
kpuzzle.definition,
|
|
389
|
+
halfish,
|
|
390
|
+
halfish
|
|
391
|
+
);
|
|
392
|
+
if (amount % 2 === 0) {
|
|
393
|
+
return twiceHalfish;
|
|
394
|
+
} else {
|
|
395
|
+
return combineTransformationData(
|
|
396
|
+
kpuzzle.definition,
|
|
397
|
+
transformationData,
|
|
398
|
+
twiceHalfish
|
|
399
|
+
);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
var AlgToTransformationTraversal = class extends TraversalDownUp {
|
|
403
|
+
traverseAlg(alg, kpuzzle) {
|
|
404
|
+
let transformation = null;
|
|
405
|
+
for (const algNode of alg.childAlgNodes()) {
|
|
406
|
+
if (transformation) {
|
|
407
|
+
transformation = transformation.applyTransformation(
|
|
408
|
+
this.traverseAlgNode(algNode, kpuzzle)
|
|
409
|
+
);
|
|
410
|
+
} else {
|
|
411
|
+
transformation = this.traverseAlgNode(algNode, kpuzzle);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
return transformation ?? kpuzzle.identityTransformation();
|
|
415
|
+
}
|
|
416
|
+
traverseGrouping(grouping, kpuzzle) {
|
|
417
|
+
const algTransformation = this.traverseAlg(grouping.alg, kpuzzle);
|
|
418
|
+
return new KTransformation(
|
|
419
|
+
kpuzzle,
|
|
420
|
+
repeatTransformationUncached(
|
|
421
|
+
kpuzzle,
|
|
422
|
+
algTransformation.transformationData,
|
|
423
|
+
grouping.amount
|
|
424
|
+
)
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
traverseMove(move, kpuzzle) {
|
|
428
|
+
return kpuzzle.moveToTransformation(move);
|
|
429
|
+
}
|
|
430
|
+
traverseCommutator(commutator, kpuzzle) {
|
|
431
|
+
const aTransformation = this.traverseAlg(commutator.A, kpuzzle);
|
|
432
|
+
const bTransformation = this.traverseAlg(commutator.B, kpuzzle);
|
|
433
|
+
return aTransformation.applyTransformation(bTransformation).applyTransformation(aTransformation.invert()).applyTransformation(bTransformation.invert());
|
|
434
|
+
}
|
|
435
|
+
traverseConjugate(conjugate, kpuzzle) {
|
|
436
|
+
const aTransformation = this.traverseAlg(conjugate.A, kpuzzle);
|
|
437
|
+
const bTransformation = this.traverseAlg(conjugate.B, kpuzzle);
|
|
438
|
+
return aTransformation.applyTransformation(bTransformation).applyTransformation(aTransformation.invert());
|
|
439
|
+
}
|
|
440
|
+
traversePause(_, kpuzzle) {
|
|
441
|
+
return kpuzzle.identityTransformation();
|
|
442
|
+
}
|
|
443
|
+
traverseNewline(_, kpuzzle) {
|
|
444
|
+
return kpuzzle.identityTransformation();
|
|
445
|
+
}
|
|
446
|
+
traverseLineComment(_, kpuzzle) {
|
|
447
|
+
return kpuzzle.identityTransformation();
|
|
448
|
+
}
|
|
449
|
+
};
|
|
450
|
+
var algToTransformation = functionFromTraversal(
|
|
451
|
+
AlgToTransformationTraversal
|
|
452
|
+
);
|
|
453
|
+
function gcd(a, b) {
|
|
454
|
+
if (b) {
|
|
455
|
+
return gcd(b, a % b);
|
|
456
|
+
}
|
|
457
|
+
return a;
|
|
458
|
+
}
|
|
459
|
+
function transformationRepetitionOrder(definition, transformation) {
|
|
460
|
+
let order = 1;
|
|
461
|
+
for (const orbitDefinition of definition.orbits) {
|
|
462
|
+
const transformationOrbit = transformation.transformationData[orbitDefinition.orbitName];
|
|
463
|
+
const orbitPieces = new Array(orbitDefinition.numPieces);
|
|
464
|
+
for (let startIdx = 0; startIdx < orbitDefinition.numPieces; startIdx++) {
|
|
465
|
+
if (!orbitPieces[startIdx]) {
|
|
466
|
+
let currentIdx = startIdx;
|
|
467
|
+
let orientationSum = 0;
|
|
468
|
+
let cycleLength = 0;
|
|
469
|
+
for (; ; ) {
|
|
470
|
+
orbitPieces[currentIdx] = true;
|
|
471
|
+
orientationSum = orientationSum + transformationOrbit.orientationDelta[currentIdx];
|
|
472
|
+
cycleLength = cycleLength + 1;
|
|
473
|
+
currentIdx = transformationOrbit.permutation[currentIdx];
|
|
474
|
+
if (currentIdx === startIdx) {
|
|
475
|
+
break;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
if (orientationSum !== 0) {
|
|
479
|
+
cycleLength = cycleLength * orbitDefinition.numOrientations / gcd(orbitDefinition.numOrientations, Math.abs(orientationSum));
|
|
480
|
+
}
|
|
481
|
+
order = order * cycleLength / gcd(order, cycleLength);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
return order;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
// src/cubing/kpuzzle/KPattern.ts
|
|
489
|
+
var KPattern = class _KPattern {
|
|
490
|
+
constructor(kpuzzle, patternData) {
|
|
491
|
+
this.kpuzzle = kpuzzle;
|
|
492
|
+
this.patternData = patternData;
|
|
493
|
+
}
|
|
494
|
+
kpuzzle;
|
|
495
|
+
patternData;
|
|
496
|
+
toJSON() {
|
|
497
|
+
return {
|
|
498
|
+
experimentalPuzzleName: this.kpuzzle.name(),
|
|
499
|
+
patternData: this.patternData
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
static fromTransformation(transformation) {
|
|
503
|
+
const newPatternData = applyTransformationDataToKPatternData(
|
|
504
|
+
transformation.kpuzzle.definition,
|
|
505
|
+
transformation.kpuzzle.definition.defaultPattern,
|
|
506
|
+
transformation.transformationData
|
|
507
|
+
);
|
|
508
|
+
return new _KPattern(transformation.kpuzzle, newPatternData);
|
|
509
|
+
}
|
|
510
|
+
// Convenience function
|
|
511
|
+
/** @deprecated */
|
|
512
|
+
apply(source) {
|
|
513
|
+
return this.applyTransformation(this.kpuzzle.toTransformation(source));
|
|
514
|
+
}
|
|
515
|
+
applyTransformation(transformation) {
|
|
516
|
+
if (transformation.isIdentityTransformation()) {
|
|
517
|
+
return new _KPattern(this.kpuzzle, this.patternData);
|
|
518
|
+
}
|
|
519
|
+
const newPatternData = applyTransformationDataToKPatternData(
|
|
520
|
+
this.kpuzzle.definition,
|
|
521
|
+
this.patternData,
|
|
522
|
+
transformation.transformationData
|
|
523
|
+
);
|
|
524
|
+
return new _KPattern(this.kpuzzle, newPatternData);
|
|
525
|
+
}
|
|
526
|
+
applyMove(move) {
|
|
527
|
+
return this.applyTransformation(this.kpuzzle.moveToTransformation(move));
|
|
528
|
+
}
|
|
529
|
+
applyAlg(alg) {
|
|
530
|
+
return this.applyTransformation(this.kpuzzle.algToTransformation(alg));
|
|
531
|
+
}
|
|
532
|
+
isIdentical(other) {
|
|
533
|
+
return isPatternDataIdentical(
|
|
534
|
+
this.kpuzzle,
|
|
535
|
+
this.patternData,
|
|
536
|
+
other.patternData
|
|
537
|
+
);
|
|
538
|
+
}
|
|
539
|
+
/** @deprecated */
|
|
540
|
+
experimentalToTransformation() {
|
|
541
|
+
if (!this.kpuzzle.canConvertDefaultPatternToUniqueTransformation()) {
|
|
542
|
+
return null;
|
|
543
|
+
}
|
|
544
|
+
const transformationData = {};
|
|
545
|
+
for (const [orbitName, patternOrbitData] of Object.entries(
|
|
546
|
+
this.patternData
|
|
547
|
+
)) {
|
|
548
|
+
const transformationOrbit = {
|
|
549
|
+
permutation: patternOrbitData.pieces,
|
|
550
|
+
orientationDelta: patternOrbitData.orientation
|
|
551
|
+
};
|
|
552
|
+
transformationData[orbitName] = transformationOrbit;
|
|
553
|
+
}
|
|
554
|
+
return new KTransformation(this.kpuzzle, transformationData);
|
|
555
|
+
}
|
|
556
|
+
experimentalIsSolved(options) {
|
|
557
|
+
if (!this.kpuzzle.definition.experimentalIsPatternSolved) {
|
|
558
|
+
throw new Error(
|
|
559
|
+
"`KPattern.experimentalIsPatternSolved()` is not supported for this puzzle at the moment."
|
|
560
|
+
);
|
|
561
|
+
}
|
|
562
|
+
return this.kpuzzle.definition.experimentalIsPatternSolved(this, options);
|
|
563
|
+
}
|
|
564
|
+
};
|
|
565
|
+
|
|
566
|
+
// src/cubing/kpuzzle/KPuzzle.ts
|
|
567
|
+
var KPuzzle = class {
|
|
568
|
+
constructor(definition, options) {
|
|
569
|
+
this.definition = definition;
|
|
570
|
+
this.experimentalPGNotation = options?.experimentalPGNotation;
|
|
571
|
+
}
|
|
572
|
+
definition;
|
|
573
|
+
experimentalPGNotation;
|
|
574
|
+
#indexedOrbits;
|
|
575
|
+
// Note: this function is needed much more rarely than you might think. Most
|
|
576
|
+
// operations related to orbits require iterating through all of them, for
|
|
577
|
+
// which the following is better:
|
|
578
|
+
//
|
|
579
|
+
// for (const orbitDefinition of kpuzzle.definition.orbits) { // …
|
|
580
|
+
// }
|
|
581
|
+
lookupOrbitDefinition(orbitName) {
|
|
582
|
+
this.#indexedOrbits ||= (() => {
|
|
583
|
+
const indexedOrbits = {};
|
|
584
|
+
for (const orbitDefinition of this.definition.orbits) {
|
|
585
|
+
indexedOrbits[orbitDefinition.orbitName] = orbitDefinition;
|
|
586
|
+
}
|
|
587
|
+
return indexedOrbits;
|
|
588
|
+
})();
|
|
589
|
+
return this.#indexedOrbits[orbitName];
|
|
590
|
+
}
|
|
591
|
+
name() {
|
|
592
|
+
return this.definition.name;
|
|
593
|
+
}
|
|
594
|
+
identityTransformation() {
|
|
595
|
+
return KTransformation.experimentalConstructIdentity(this);
|
|
596
|
+
}
|
|
597
|
+
#moveToTransformationDataCache = /* @__PURE__ */ new Map();
|
|
598
|
+
moveToTransformation(move) {
|
|
599
|
+
if (typeof move === "string") {
|
|
600
|
+
move = new Move(move);
|
|
601
|
+
}
|
|
602
|
+
const cacheKey = move.toString();
|
|
603
|
+
const cachedTransformationData = this.#moveToTransformationDataCache.get(cacheKey);
|
|
604
|
+
if (cachedTransformationData) {
|
|
605
|
+
return new KTransformation(this, cachedTransformationData);
|
|
606
|
+
}
|
|
607
|
+
if (this.experimentalPGNotation) {
|
|
608
|
+
const transformationData2 = this.experimentalPGNotation.lookupMove(move);
|
|
609
|
+
if (!transformationData2) {
|
|
610
|
+
throw new Error(`could not map to internal move: ${move}`);
|
|
611
|
+
}
|
|
612
|
+
this.#moveToTransformationDataCache.set(cacheKey, transformationData2);
|
|
613
|
+
return new KTransformation(this, transformationData2);
|
|
614
|
+
}
|
|
615
|
+
const transformationData = moveToTransformationUncached(this, move);
|
|
616
|
+
this.#moveToTransformationDataCache.set(cacheKey, transformationData);
|
|
617
|
+
return new KTransformation(this, transformationData);
|
|
618
|
+
}
|
|
619
|
+
algToTransformation(alg) {
|
|
620
|
+
if (typeof alg === "string") {
|
|
621
|
+
alg = new Alg(alg);
|
|
622
|
+
}
|
|
623
|
+
return algToTransformation(alg, this);
|
|
624
|
+
}
|
|
625
|
+
/** @deprecated */
|
|
626
|
+
toTransformation(source) {
|
|
627
|
+
if (typeof source === "string") {
|
|
628
|
+
return this.algToTransformation(source);
|
|
629
|
+
} else if (source?.is?.(Alg)) {
|
|
630
|
+
return this.algToTransformation(source);
|
|
631
|
+
} else if (source?.is?.(Move)) {
|
|
632
|
+
return this.moveToTransformation(source);
|
|
633
|
+
} else {
|
|
634
|
+
return source;
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
defaultPattern() {
|
|
638
|
+
return new KPattern(this, this.definition.defaultPattern);
|
|
639
|
+
}
|
|
640
|
+
#cachedCanConvertDefaultPatternToUniqueTransformation;
|
|
641
|
+
// TODO: Handle incomplete default pattern data
|
|
642
|
+
canConvertDefaultPatternToUniqueTransformation() {
|
|
643
|
+
return this.#cachedCanConvertDefaultPatternToUniqueTransformation ??= (() => {
|
|
644
|
+
for (const orbitDefinition of this.definition.orbits) {
|
|
645
|
+
const pieces = new Array(orbitDefinition.numPieces).fill(false);
|
|
646
|
+
for (const piece of this.definition.defaultPattern[orbitDefinition.orbitName].pieces) {
|
|
647
|
+
pieces[piece] = true;
|
|
648
|
+
}
|
|
649
|
+
for (const piece of pieces) {
|
|
650
|
+
if (!piece) {
|
|
651
|
+
return false;
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
return true;
|
|
656
|
+
})();
|
|
657
|
+
}
|
|
658
|
+
};
|
|
659
|
+
|
|
660
|
+
export {
|
|
661
|
+
KTransformation,
|
|
662
|
+
KPattern,
|
|
663
|
+
KPuzzle
|
|
664
|
+
};
|
|
665
|
+
//# sourceMappingURL=chunk-52ZXJEUO.js.map
|