squanlib 1.1.3 → 1.2.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.
- package/dist/squanlib.umd.js +62 -33
- package/dist/squanlib.umd.min.js +1 -1
- package/package.json +1 -1
- package/squanlib.js +62 -33
package/dist/squanlib.umd.js
CHANGED
|
@@ -70,7 +70,6 @@
|
|
|
70
70
|
"d2": "-1,5", "d2'": "1,-5",
|
|
71
71
|
"K": "5,2", "K'": "-5,-2",
|
|
72
72
|
"k": "2,5", "k'": "-2,-5",
|
|
73
|
-
"A": "1,0", "A'": "-1,0",
|
|
74
73
|
"G": "5,-4", "G'": "-5,4",
|
|
75
74
|
"g": "4,-5", "g'": "-4,5",
|
|
76
75
|
};
|
|
@@ -277,10 +276,10 @@
|
|
|
277
276
|
* GOOD_FINISHES: moves that are acceptable as the last move
|
|
278
277
|
*/
|
|
279
278
|
static GOOD_FINISHES = new Set([
|
|
280
|
-
"
|
|
281
|
-
"
|
|
282
|
-
"
|
|
283
|
-
"5
|
|
279
|
+
"1,1", "-1,-1", "2,2", "-2,-2", "2,-1", "-2,1", "1,-2", "-1,2",
|
|
280
|
+
"3,0", "-3,0", "0,3", "0,-3", "3,3", "3,-3", "-3,-3", "-3,3",
|
|
281
|
+
"4,1", "-4,-1", "1,4", "-1,-4", "2,-4", "-2,4", "4,-2", "-4,2",
|
|
282
|
+
"5,-1", "-5,1", "-4,5", "-5,4", "6,3",
|
|
284
283
|
]);
|
|
285
284
|
|
|
286
285
|
/**
|
|
@@ -717,14 +716,6 @@
|
|
|
717
716
|
// overrides
|
|
718
717
|
if (alg in this.tempReplacements) return this.tempReplacements[alg];
|
|
719
718
|
|
|
720
|
-
// p scrambles
|
|
721
|
-
let isPScramble = /^p[ /\\|]/.test(alg);
|
|
722
|
-
let startingSlice;
|
|
723
|
-
if (isPScramble) {
|
|
724
|
-
startingSlice = alg.charAt(1) === " " ? "/" : alg.charAt(1);
|
|
725
|
-
alg = alg.slice(2, -3);
|
|
726
|
-
}
|
|
727
|
-
|
|
728
719
|
// legacy character substitutions
|
|
729
720
|
alg = alg
|
|
730
721
|
.replaceAll('&', '-1')
|
|
@@ -733,6 +724,17 @@
|
|
|
733
724
|
.replaceAll('8', '-4')
|
|
734
725
|
.replaceAll('7', '-5');
|
|
735
726
|
|
|
727
|
+
// remove potential move counts, comments
|
|
728
|
+
alg = alg.replaceAll(/\[.*?\]/g, "");
|
|
729
|
+
|
|
730
|
+
// p scrambles
|
|
731
|
+
let isPScramble = /^p[ /\\|]/.test(alg);
|
|
732
|
+
let startingSlice;
|
|
733
|
+
if (isPScramble) {
|
|
734
|
+
startingSlice = alg.charAt(1) === " " ? "/" : alg.charAt(1);
|
|
735
|
+
alg = alg.slice(2, -3);
|
|
736
|
+
}
|
|
737
|
+
|
|
736
738
|
// expand move groups, e.g. "(U U')3" → "U U' U U' U U'"
|
|
737
739
|
for (const group of alg.matchAll(/(\(.*?\))(\d+)/g)) {
|
|
738
740
|
const inner = group[1].replaceAll(/[()]/g, '');
|
|
@@ -1378,16 +1380,32 @@
|
|
|
1378
1380
|
rated = true;
|
|
1379
1381
|
|
|
1380
1382
|
if (rated && ["/", "\\", "|"].includes(sliceStart)) {
|
|
1381
|
-
|
|
1382
|
-
const slashPos = line.indexOf('/');
|
|
1383
|
-
if (slashPos >= 0)
|
|
1384
|
-
result.alg = line.slice(0, slashPos) + sliceStart + line.slice(slashPos + 1);
|
|
1383
|
+
result.alg = this.injectSliceStart(line, sliceStart);
|
|
1385
1384
|
}
|
|
1386
1385
|
|
|
1387
1386
|
return result;
|
|
1388
1387
|
}).sort((a, b) => b.score - a.score);
|
|
1389
1388
|
}
|
|
1390
1389
|
|
|
1390
|
+
/**
|
|
1391
|
+
* injectSliceStart: injects the slice start into an alg
|
|
1392
|
+
*
|
|
1393
|
+
* @param {string} alg the alg. no extra spaces allowed
|
|
1394
|
+
* @param {string} sliceStart " " | "/" | "\\" | "|"
|
|
1395
|
+
* @returns {string} the alg with slice start injected at the first slice
|
|
1396
|
+
*/
|
|
1397
|
+
injectSliceStart(alg, sliceStart) {
|
|
1398
|
+
let moreThan1 = /[/\\| ]/.test(alg); // is there ANY slice chars?
|
|
1399
|
+
let firstMove = moreThan1 ? alg.match(/^([^/\\| ]*)[/\\| ]/)?.[1] : alg;
|
|
1400
|
+
// only tests if it's a karn
|
|
1401
|
+
if (firstMove in SquanLib.karnToWCA) return sliceStart + alg;
|
|
1402
|
+
if (!moreThan1) return alg; // no slice to inject to
|
|
1403
|
+
|
|
1404
|
+
// guaranteed to have a slice
|
|
1405
|
+
const slashPos = alg.search(/[/\\| ]/);
|
|
1406
|
+
return alg.slice(0, slashPos) + sliceStart + alg.slice(slashPos + 1);
|
|
1407
|
+
}
|
|
1408
|
+
|
|
1391
1409
|
// =========================================================================
|
|
1392
1410
|
// SECTION 8: ALG TRANSFORM
|
|
1393
1411
|
// =========================================================================
|
|
@@ -1408,28 +1426,38 @@
|
|
|
1408
1426
|
/**
|
|
1409
1427
|
* compl: get the complement of a move
|
|
1410
1428
|
*
|
|
1411
|
-
* @param {string} a a move
|
|
1412
|
-
* @returns {string} the complement move
|
|
1413
|
-
* @example "-12" → "5-4"
|
|
1429
|
+
* @param {string} a a move
|
|
1430
|
+
* @returns {string} the complement move with commas
|
|
1431
|
+
* @example "-12" → "5,-4"; "-1,2" → "5,-4"
|
|
1414
1432
|
*/
|
|
1415
1433
|
compl(a) {
|
|
1416
1434
|
if (!a) return a;
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1435
|
+
let u, d;
|
|
1436
|
+
if (a.includes(',')) [u, d] = a.split(",");
|
|
1437
|
+
else {
|
|
1438
|
+
const inx = this.sepIndex(a);
|
|
1439
|
+
[u, d] = [a.slice(0, inx), a.slice(inx)];
|
|
1440
|
+
}
|
|
1441
|
+
return String(this.legalMove(6 + parseInt(u, 10))) + "," +
|
|
1442
|
+
String(this.legalMove(6 + parseInt(d, 10)));
|
|
1420
1443
|
}
|
|
1421
1444
|
|
|
1422
1445
|
/**
|
|
1423
1446
|
* lf: get the layer flip of a move
|
|
1424
1447
|
*
|
|
1425
|
-
* @param {string} a a move
|
|
1448
|
+
* @param {string} a a move
|
|
1426
1449
|
* @returns {string} the layer flip move
|
|
1427
|
-
* @example "-12" → "2-1"
|
|
1450
|
+
* @example "-12" → "2,-1"; "-1,2" → "2,-1"
|
|
1428
1451
|
*/
|
|
1429
1452
|
lf(a) {
|
|
1430
1453
|
if (!a) return a;
|
|
1431
|
-
|
|
1432
|
-
|
|
1454
|
+
let u, d;
|
|
1455
|
+
if (a.includes(',')) [u, d] = a.split(",");
|
|
1456
|
+
else {
|
|
1457
|
+
const inx = this.sepIndex(a);
|
|
1458
|
+
[u, d] = [a.slice(0, inx), a.slice(inx)];
|
|
1459
|
+
}
|
|
1460
|
+
return d + "," + u;
|
|
1433
1461
|
}
|
|
1434
1462
|
|
|
1435
1463
|
/**
|
|
@@ -1442,11 +1470,11 @@
|
|
|
1442
1470
|
compact(algIn) {
|
|
1443
1471
|
let alg = algIn
|
|
1444
1472
|
.replace(/\[.*?\]/g, "")
|
|
1445
|
-
.replace(/[()]/g, "")
|
|
1446
|
-
.replaceAll(" ", "").trim();
|
|
1473
|
+
.replace(/[()]/g, "").trim();
|
|
1447
1474
|
if (this.isKarn(alg)) {
|
|
1448
1475
|
const numeric = this.unkarnify(alg);
|
|
1449
|
-
return numeric.split("/").
|
|
1476
|
+
return numeric.split("/").map(m => {
|
|
1477
|
+
if (!m) return m;
|
|
1450
1478
|
if (!m.includes(","))
|
|
1451
1479
|
throw new Error(
|
|
1452
1480
|
`algToInternal: m doesn't have commas post karnifying: ${m}`
|
|
@@ -1456,7 +1484,7 @@
|
|
|
1456
1484
|
String(this.legalMove(parseInt(d, 10)));
|
|
1457
1485
|
}).join(" ");
|
|
1458
1486
|
}
|
|
1459
|
-
alg = alg.
|
|
1487
|
+
alg = alg.replaceAll(" ", "");
|
|
1460
1488
|
if (alg.includes("/")) {
|
|
1461
1489
|
return alg.split("/").filter(Boolean).map(m => {
|
|
1462
1490
|
if (!m.includes(",")) m = this.addCommas(m);
|
|
@@ -1485,7 +1513,8 @@
|
|
|
1485
1513
|
* @returns {number} how many positions the alg can y2 at
|
|
1486
1514
|
*/
|
|
1487
1515
|
countY2Positions(algIn) {
|
|
1488
|
-
|
|
1516
|
+
// spaces ARE slices, cannot trim or do anything like that
|
|
1517
|
+
const segs = this.compact(algIn).split(" ");
|
|
1489
1518
|
return Math.max(0, segs.length - 3);
|
|
1490
1519
|
}
|
|
1491
1520
|
|
|
@@ -1637,7 +1666,7 @@
|
|
|
1637
1666
|
isOBLCase(l, target) {
|
|
1638
1667
|
const targetPattern = Object.entries(SquanLib.OBLToEnglish)
|
|
1639
1668
|
.find(([, v]) => v === target
|
|
1640
|
-
|
|
1669
|
+
)?.[0];
|
|
1641
1670
|
if (!targetPattern) return false;
|
|
1642
1671
|
// to corner first
|
|
1643
1672
|
if (l[0] !== l[0].toUpperCase()) l = this.shift(l, -1);
|
package/dist/squanlib.umd.min.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/*! squanlib | GPL-3.0-or-later | https://github.com/Mattttttttttttttttttttttttttttttt/squan-lib */
|
|
2
|
-
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).squanlib=e()}(this,function(){"use strict";class t{static karnToWCA={U4:"U U' U U'","U4'":"U' U U' U",D4:"D D' D D'","D4'":"D' D D' D",u4:"u u' u u'","u4'":"u' u u' u",d4:"d d' d d'","d4'":"d' d d' d",U3:"U U' U","U3'":"U' U U'",D3:"D D' D","D3'":"D' D D'",u3:"u u' u","u3'":"u' u u'",d3:"d d' d","d3'":"d' d d'",F3:"F F' F","F3'":"F' F F'",f3:"f f' f","f3'":"f' f f'",W:"U U'","W'":"U' U",B:"D D'","B'":"D' D",w:"u u'","w'":"u' u",b:"d d'","b'":"d' d",F2:"F F'","F2'":"F' F",f2:"f f'","f2'":"f' f",UU:"U U","UU'":"U' U'",DD:"D D","DD'":"D' D'",T2:"T T'","T2'":"T' T",t2:"t t'","t2'":"t' t",E2:"E E'","E2'":"E' E","ɇ":"U D","ɇ'":"U' D'","Ɇ":"U D'","Ɇ'":"U' D",U2:"6,0","U2'":"6,0",D2:"0,6",U2D:"6,3","U2D'":"6,-3","U2'D":"6,3","U2'D'":"6,-3",U2D2:"6,6",UD2:"3,6","U'D2":"-3,6",U:"3,0","U'":"-3,0",D:"0,3","D'":"0,-3",E:"3,-3","E'":"-3,3",e:"3,3","e'":"-3,-3",u:"2,-1","u'":"-2,1",d:"-1,2","d'":"1,-2",F:"4,1","F'":"-4,-1",f:"1,4","f'":"-1,-4",T:"2,-4","T'":"-2,4",t:"4,-2","t'":"-4,2",m:"2,2","m'":"-2,-2",M:"1,1","M'":"-1,-1",u2:"5,-1","u2'":"-5,1",d2:"-1,5","d2'":"1,-5",K:"5,2","K'":"-5,-2",k:"2,5","k'":"-2,-5",A:"1,0","A'":"-1,0",G:"5,-4","G'":"-5,4",g:"4,-5","g'":"-4,5"};static shorthandToKarn={bjj:"U' e D'",fjj:"U e' D",e2bjj:"U' e' U'",e2fjj:"U e U",nn:"E E'",jn:"D4'",nj:"U4",jj:"U e' D","bjj+e2":"U' e' U'","-nn":"E' E","-jn":"D4","-nj":"D4'",bpj10:"d m' U","bpj0-1":"u' m D'",fpj10:"u m' D","fpj0-1":"d' m U'",aa10:"u m' u T'","aa0-1":"U m' U t'",fadj10:"D M' d'",dadj10:"D M' d'","fadj0-1":"U' M u","u'adj0-1":"U' M u",badj10:"U M' u'",uadj10:"U M' u'","badj0-1":"D' M d","d'adj0-1":"D' M d",bb10:"T u' e U'","bb0-1":"t d e' D",fdd10:"D e' d t","fdd0-1":"U' e u' T",bdd10:"U e' u T'","bdd0-1":"D' e d' t'",ff10:"d m' d M E","ff0-1":"u' m U' M T",fv10:"d4","fv0-1":"d4'",vf10:"u4","vf0-1":"u4'",y2fv10:"u d' u -5,4",jf10:"w D' u T'","jf0-1":"w' D u' T",fj10:"b U' d t","fj0-1":"b' U d' t'",jr00:"e' w e",jr10:"e' b e","jr0-1":"e' w' e","jr1-1":"e' b' e",rj00:"e b' e'",rj10:"e w e'","rj0-1":"e b' e'","rj1-1":"e w e'",jv10:"b D d d2'","jv0-1":"b' D' d' d2",vj10:"w U u u2'","vj0-1":"w' U' u' u2",kk10:"u m' U E'","kk0-1":"U m' u E'",opp10:"u2 u2'","opp0-1":"u2' u2",pn10:"T T'","pn0-1":"t t'",px10:"f' d3' f'","px0-1":"f d3 f",xp10:"F' u3' F'","xp0-1":"F u3 F",tt10:"d m' F' u2'",fss10:"u M D' E'","fss0-1":"D' M u E'",bss10:"D M' u' E","bss0-1":"U' M d E",vv10:"u M u m' E'",zz10:"u M t' M D'","zz0-1":"D' M t' M u","30adj10":"U M' u'","-30adj0-1":"U' M u","03adj10":"D M' d'",obopp00:"1,0/M' F M' F M'/0,1","oaopp1-1":"0,1/M' u' M' u' M'/0,1",but00:"",also00:"","done!00":"0,0"};static alignmentIndependent=new Set(["bjj","fjj","nn","jn","nj","e2bjj","e2fjj","jj","bjj+e2","-nn","-jn","-nj"]);static wcaToBaseKarn={"6,0":"U2","6,3":"U2D","6,-3":"U2D'","6,6":"U2D2","0,6":"D2","3,6":"UD2","-3,6":"U'D2","3,0":"U","-3,0":"U'","0,3":"D","0,-3":"D'","3,-3":"E","-3,3":"E'","3,3":"e","-3,-3":"e'","2,-1":"u","-2,1":"u'","-1,2":"d","1,-2":"d'","4,1":"F","-4,-1":"F'","1,4":"f","-1,-4":"f'","2,-4":"T","-2,4":"T'","4,-2":"t","-4,2":"t'","2,2":"m","-2,-2":"m'","1,1":"M","-1,-1":"M'","5,-1":"u2","-5,1":"u2'","-1,5":"d2","1,-5":"d2'","5,2":"K","-5,-2":"K'","2,5":"k","-2,-5":"k'"};static baseKarnToHighKarn={"U U' U U'":"U4","U' U U' U":"U4'","D D' D D'":"D4","D' D D' D":"D4'","u u' u u'":"u4","u' u u' u":"u4'","d d' d d'":"d4","d' d d' d":"d4'","U U' U":"U3","U' U U'":"U3'","D D' D":"D3","D' D D'":"D3'","u u' u":"u3","u' u u'":"u3'","d d' d":"d3","d' d d'":"d3'","F F' F":"F3","F' F F'":"F3'","f f' f":"f3","f' f f'":"f3'","U U'":"W","U' U":"W'","D D'":"B","D' D":"B'","u u'":"w","u' u":"w'","d d'":"b","d' d":"b'","F F'":"F2","F' F":"F2'","f f'":"f2","f' f":"f2'","U U":"UU","U' U'":"UU'","D D":"DD","D' D'":"DD'"};static A_MOVES=[[3,0],[-3,0],[0,3],[0,-3],[3,3],[2,-1],[-1,2],[-4,-1],[-1,-4],[2,-4],[2,2],[-1,-1],[5,-1]];static a_MOVES=[[3,0],[-3,0],[0,3],[0,-3],[3,3],[-2,1],[1,-2],[4,1],[1,4],[-2,4],[-2,-2],[1,1],[-5,1]];static OPTIM={"/0,0/":"","/3,3/3,3/":"-3,-3/-3,-3","/-3,-3/-3,-3/":"3,3/3,3","/2,2/-2,-2/":"2,2/-2,-2","/-2,-2/2,2/":"-2,-2/2,2","/1,1/-1,-1/":"1,1/-1,-1","/-1,-1/1,1/":"-1,-1/1,1","/2,-4/-2,4/2,-4/":"2,-4/-2,4/2,-4","/-2,4/2,-4/-2,4/":"-2,4/2,-4/-2,4","/5,-1/-5,1/5,-1/":"5,-1/-5,1/5,-1","/-5,1/5,-1/-5,1/":"-5,1/5,-1/-5,1"};static CLOSEST_MAP=new Map([[-5,-6],[-4,-3],[-3,-3],[-2,-3],[-1,0],[0,0],[1,0],[2,3],[3,3],[4,3],[5,6],[6,6]]);static MOVE_VALUES=new Map([["A/0,3",16],["A/0,6",1],["A/0,-3",18],["A/3,0",16],["A/3,3",12],["A/3,6",0],["A/3,-3",13],["A/6,0",12],["A/6,3",11],["A/6,6",2],["A/6,-3",12],["A/-3,0",9],["A/-3,3",13],["A/-3,6",4],["A/-3,-3",12],["A\\0,3",17],["A\\0,6",1],["A\\0,-3",8],["A\\3,0",6],["A\\3,3",14],["A\\3,6",1],["A\\3,-3",12],["A\\6,0",14],["A\\6,3",11],["A\\6,6",5],["A\\6,-3",8],["A\\-3,0",11],["A\\-3,3",14],["A\\-3,6",6],["A\\-3,-3",9],["a/0,3",5],["a/0,6",5],["a/0,-3",12],["a/3,0",17],["a/3,3",10],["a/3,6",5],["a/3,-3",7],["a/6,0",4],["a/6,3",2],["a/6,6",0],["a/6,-3",3],["a/-3,0",18],["a/-3,3",12],["a/-3,6",7],["a/-3,-3",11],["a\\0,3",5],["a\\0,6",5],["a\\0,-3",5],["a\\3,0",16],["a\\3,3",11],["a\\3,6",4],["a\\3,-3",6],["a\\6,0",4],["a\\6,3",2],["a\\6,6",0],["a\\6,-3",1],["a\\-3,0",15],["a\\-3,3",10],["a\\-3,6",2],["a\\-3,-3",5],["/1,-2",4],["\\1,-2",17],["/-1,2",15],["\\-1,2",14],["/1,-5",3],["\\1,-5",1],["/-1,5",8],["\\-1,5",3],["/1,4",7],["\\1,4",14],["/-1,-4",12],["\\-1,-4",9],["/1,1",11],["\\1,1",20],["/-1,-1",20],["\\-1,-1",10],["/2,-1",20],["\\2,-1",12],["/-2,1",14],["\\-2,1",18],["/2,2",12],["\\2,2",13],["/-2,-2",14],["\\-2,-2",8],["/2,5",5],["\\2,5",3],["/-2,-5",4],["\\-2,-5",3],["/2,-4",14],["\\2,-4",6],["/-2,4",13],["\\-2,4",13],["/4,4",5],["\\4,4",12],["/-4,-4",12],["\\-4,-4",4],["/4,1",6],["\\4,1",13],["/-4,-1",16],["\\-4,-1",6],["/4,-2",12],["\\4,-2",9],["/-4,2",16],["\\-4,2",13],["/4,-5",2],["\\4,-5",5],["/-4,5",13],["\\-4,5",3],["/5,5",1],["\\5,5",4],["/-5,-5",2],["\\-5,-5",0],["/5,2",6],["\\5,2",10],["/-5,-2",12],["\\-5,-2",13],["/5,-1",11],["\\5,-1",7],["/-5,1",14],["\\-5,1",15],["/5,-4",2],["\\5,-4",2],["/-5,4",12],["\\-5,4",14]]);static GOOD_FINISHES=new Set(["11","-1-1","22","-2-2","2-1","-21","1-2","-12","30","-30","03","0-3","33","3-3","-3-3","-33","41","-4-1","14","-1-4","2-4","-24","4-2","-42","5-1","-51","-45","-54","63"]);static OBLToEnglish={BBbBBbBBbBBb:"solved",BBwWWwWWwWWw:"1c",BBwBBwWWwWWw:"cadj",BBwWWwBBwWWw:"copp",BBwBBwBBwWWw:"3c",BBwBBwBBwBBw:"4e",WWbWWbWWbWWw:"3e",WWbWWwWWbWWw:"line",WWbWWbWWwWWw:"L",WWbWWwWWwWWw:"1e",WWbBBwWWwWWw:"left pair",BBbWWwWWwWWw:"right pair",BBwWWwWWbWWw:"left arrow",BBwWWbWWwWWw:"right arrow",WWbBBbWWwWWw:"gem",WWwWWbWWbBBw:"left knight",BBbWWbWWwWWw:"right knight",WWwWWbWWwBBb:"left axe",BBwWWbWWwWWb:"right axe",BBwWWbWWbWWw:"squid",WWwWWbBBbWWb:"left thumb",WWbBBbWWwWWb:"right thumb",WWwBBbWWbWWb:"left bunny",WWbWWbBBwWWb:"right bunny",BBbBBwWWwWWw:"shell",BBwWWwWWbBBw:"left bird",BBwBBbWWwWWw:"right bird",BBwWWbWWwBBw:"hazard",BBbBBbWWwWWw:"left kite",WWwWWbBBbBBw:"right kite",BBwBBwWWbWWb:"left cut",BBwBBbWWbWWw:"right cut",BBbBBwWWbWWw:"black T",WWwWWbBBwBBb:"white T",WWbBBwWWbBBw:"left N",WWwBBbWWwBBb:"right N",WWbBBbWWwBBw:"black tie",BBwWWwBBbWWb:"white tie",BBbWWwBBwWWw:"left yoshi",WWwBBwWWbBBw:"right yoshi"};static OBLToState=Object.fromEntries(Object.entries(this.OBLToEnglish).map(([t,e])=>[e,t]));static NAMING={solved:"O","1c":"D",cadj:"J",copp:"V","3c":"M","4e":"Q","3e":"W",line:"F",L:"L","1e":"E","left pair":"Pw","right pair":"Pc","left arrow":"Aw","right arrow":"Ac",gem:"G","left knight":"Hw","right knight":"Hc","left axe":"Xc","right axe":"Xw",squid:"S","left thumb":"THw","right thumb":"THc","left bunny":"Uc","right bunny":"Uw",shell:"SH","left bird":"Bc","right bird":"Bw",hazard:"Z","left kite":"Kc","right kite":"Kw","left cut":"Cw","right cut":"Cc","black T":"Tu","white T":"Td","left N":"Nw","right N":"Nc","black tie":"Iu","white tie":"Id","left yoshi":"Yc","right yoshi":"Yw"};static OBL_ANGLES={solved:"-","1c":"UR",cadj:"R",copp:"/","3c":"DR","4e":"-","3e":"D",line:"—",L:"DR","1e":"R","left pair":"DR","right pair":"UR","left arrow":"UR","right arrow":"UR",gem:"DR","left knight":"L","right knight":"R","left axe":"L","right axe":"R",squid:"UR","left thumb":"DL","right thumb":"DR","left bunny":"DR","right bunny":"DL",shell:"R","left bird":"R","right bird":"U",hazard:"U","left kite":"R","right kite":"L","left cut":"R","right cut":"R","black T":"R","white T":"R","left N":"\\","right N":"\\","black tie":"DR","white tie":"DR","left yoshi":"UL","right yoshi":"UR"};static nextAngle={"-":"-","/":"\\","\\":"/","—":"|","|":"—",U:"R",R:"D",D:"L",L:"U",UR:"DR",DR:"DL",DL:"UL",UL:"UR"};static get HALF_L(){return 6}static get LAYERL(){return 12}static get THREE_FOUR_L(){return 18}static get CUBEL(){return 24}static get SOLVED(){return"bBBbBBbBBbBBwWWwWWwWWwWW"}static POSSIBLE_OBL=[["","solved","solved"],["","1c","1c"],["","cadj","cadj"],["","cadj","copp"],["","copp","copp"],["","3c","3c"],["","4e","4e"],["","3e","3e"],["","line","line"],["","L","line"],["","L","L"],["","1e","1e"],["good","pair","pair"],["bad","pair","pair"],["good","arrow","pair"],["bad","arrow","pair"],["good","arrow","arrow"],["bad","arrow","arrow"],["","gem","gem"],["","gem","knight"],["","gem","axe"],["","gem","squid"],["good","knight","knight"],["bad","knight","knight"],["good","knight","axe"],["bad","knight","axe"],["same","axe","axe"],["diff","axe","axe"],["","squid","knight"],["","squid","axe"],["","squid","squid"],["good","thumb","thumb"],["bad","thumb","thumb"],["good","thumb","bunny"],["bad","thumb","bunny"],["good","bunny","bunny"],["bad","bunny","bunny"],["","shell","shell"],["","shell","bird"],["","shell","hazard"],["","yoshi","shell"],["good","bird","bird"],["bad","bird","bird"],["","bird","hazard"],["","hazard","hazard"],["good","yoshi","bird"],["bad","yoshi","bird"],["","yoshi","hazard"],["same","yoshi","yoshi"],["diff","yoshi","yoshi"],["good","kite","kite"],["bad","kite","kite"],["good","kite","cut"],["bad","kite","cut"],["","kite","T"],["good","kite","N"],["bad","kite","N"],["","kite","tie"],["","cut","T"],["good","cut","N"],["bad","cut","N"],["","cut","tie"],["good","cut","cut"],["bad","cut","cut"],["good","T","T"],["bad","T","T"],["","T","N"],["good","T","tie"],["bad","T","tie"],["good","N","N"],["bad","N","N"],["","tie","N"],["good","tie","tie"],["bad","tie","tie"]];static OBL_LEN={"solved/solved":0,"1c/1c":5,"cadj/cadj":4,"cadj/copp":5,"copp/copp":2,"3c/3c":5,"4e/4e":4,"3e/3e":5,"line/line":2,"L/line":5,"L/L":4,"1e/1e":5,"good pair/pair":2,"bad pair/pair":4,"good arrow/pair":3,"bad arrow/pair":4,"good arrow/arrow":3,"bad arrow/arrow":4,"gem/gem":4,"gem/knight":4,"gem/axe":3,"gem/squid":4,"good knight/knight":4,"bad knight/knight":5,"good knight/axe":3,"bad knight/axe":4,"same axe/axe":5,"diff axe/axe":5,"squid/knight":4,"squid/axe":4,"squid/squid":5,"good thumb/thumb":2,"bad thumb/thumb":5,"good thumb/bunny":4,"bad thumb/bunny":4,"good bunny/bunny":3,"bad bunny/bunny":5,"shell/shell":4,"shell/bird":4,"shell/hazard":4,"yoshi/shell":3,"good bird/bird":4,"bad bird/bird":5,"bird/hazard":4,"hazard/hazard":5,"good yoshi/bird":3,"bad yoshi/bird":4,"yoshi/hazard":4,"same yoshi/yoshi":5,"diff yoshi/yoshi":5,"good kite/kite":1,"bad kite/kite":5,"good kite/cut":3,"bad kite/cut":6,"kite/T":4,"good kite/N":3,"bad kite/N":4,"kite/tie":4,"cut/T":4,"good cut/N":4,"bad cut/N":5,"cut/tie":4,"good cut/cut":3,"bad cut/cut":6,"good T/T":3,"bad T/T":4,"T/N":5,"good T/tie":3,"bad T/tie":4,"good N/N":2,"bad N/N":4,"tie/N":5,"good tie/tie":3,"bad tie/tie":4};static OBL_TRANSLATION={"solved/solved":["solved/solved"],"1c/1c":["1c/1c"],"cadj/cadj":["cadj/cadj"],"cadj/copp":["cadj/copp"],"copp/copp":["copp/copp"],"3c/3c":["3c/3c"],"4e/4e":["4e/4e"],"3e/3e":["3e/3e"],"line/line":["line/line"],"L/line":["L/line"],"L/L":["L/L"],"1e/1e":["1e/1e"],"good pair/pair":["left pair/left pair","right pair/right pair"],"bad pair/pair":["left pair/right pair"],"good arrow/pair":["left arrow/right pair","right arrow/left pair"],"bad arrow/pair":["left arrow/left pair","right arrow/right pair"],"good arrow/arrow":["left arrow/left arrow","right arrow/right arrow"],"bad arrow/arrow":["left arrow/right arrow"],"gem/gem":["gem/gem"],"gem/knight":["gem/left knight","gem/right knight"],"gem/axe":["gem/left axe","gem/right axe"],"gem/squid":["gem/squid"],"good knight/knight":["left knight/right knight"],"bad knight/knight":["left knight/left knight","right knight/right knight"],"good knight/axe":["left knight/left axe","right knight/right axe"],"bad knight/axe":["left knight/right axe","right knight/left axe"],"same axe/axe":["left axe/left axe","right axe/right axe"],"diff axe/axe":["left axe/right axe"],"squid/knight":["squid/left knight","squid/right knight"],"squid/axe":["squid/left axe","squid/right axe"],"squid/squid":["squid/squid"],"good thumb/thumb":["left thumb/left thumb","right thumb/right thumb"],"bad thumb/thumb":["left thumb/right thumb"],"good thumb/bunny":["left thumb/right bunny","right thumb/left bunny"],"bad thumb/bunny":["left thumb/left bunny","right thumb/right bunny"],"good bunny/bunny":["left bunny/left bunny","right bunny/right bunny"],"bad bunny/bunny":["left bunny/right bunny"],"shell/shell":["shell/shell"],"shell/bird":["shell/left bird","shell/right bird"],"shell/hazard":["shell/hazard"],"yoshi/shell":["left yoshi/shell","right yoshi/shell"],"good bird/bird":["left bird/right bird"],"bad bird/bird":["left bird/left bird","right bird/right bird"],"bird/hazard":["left bird/hazard","right bird/hazard"],"hazard/hazard":["hazard/hazard"],"good yoshi/bird":["left yoshi/left bird","right yoshi/right bird"],"bad yoshi/bird":["left yoshi/right bird","right yoshi/left bird"],"yoshi/hazard":["left yoshi/hazard","right yoshi/hazard"],"same yoshi/yoshi":["left yoshi/left yoshi","right yoshi/right yoshi"],"diff yoshi/yoshi":["left yoshi/right yoshi"],"good kite/kite":["left kite/left kite","right kite/right kite"],"bad kite/kite":["left kite/right kite"],"good kite/cut":["left kite/left cut","right kite/right cut"],"bad kite/cut":["left kite/right cut","right kite/left cut"],"kite/T":["left kite/black T","left kite/white T","right kite/black T","right kite/white T"],"good kite/N":["left kite/right N","right kite/left N"],"bad kite/N":["left kite/left N","right kite/right N"],"kite/tie":["left kite/black tie","left kite/white tie","right kite/black tie","right kite/white tie"],"cut/T":["left cut/black T","left cut/white T","right cut/black T","right cut/white T"],"good cut/N":["left cut/left N","right cut/right N"],"bad cut/N":["left cut/right N","right cut/left N"],"cut/tie":["left cut/black tie","left cut/white tie","right cut/black tie","right cut/white tie"],"good cut/cut":["left cut/left cut","right cut/right cut"],"bad cut/cut":["left cut/right cut"],"good T/T":["black T/black T","white T/white T"],"bad T/T":["black T/white T"],"T/N":["black T/left N","black T/right N","white T/left N","white T/right N"],"good T/tie":["black T/black tie","white T/white tie"],"bad T/tie":["black T/white tie","white T/black tie"],"good N/N":["left N/left N","right N/right N"],"bad N/N":["left N/right N"],"tie/N":["black tie/left N","black tie/right N","white tie/left N","white tie/right N"],"good tie/tie":["black tie/black tie","white tie/white tie"],"bad tie/tie":["black tie/white tie"]};static CORNERS=[[""],["1","3","5","7"],["13","15","17","35","37","57"],["135","137","157","357"],["1357"]];static EDGES=[[""],["2","4","6","8"],["24","26","28","46","48","68"],["246","248","268","468"],["2468"]];static TOTAL_CORNERS=["","1","3","5","7","13","15","17","35","37","57","135","137","157","357","1357"];static TOTAL_EDGES=["","2","4","6","8","24","26","28","46","48","68","246","248","268","468","2468"];constructor(t={"meow :3":"meow :3"}){this.tempReplacements={...t}}setTempReplacements(t){return this.tempReplacements={...t},this}addTempReplacements(t){return Object.assign(this.tempReplacements,t),this}dictReplace(t,e){const i=new RegExp(Object.keys(e).map(t=>t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join("|"),"g");let r;do{r=t,t=t.replace(i,t=>e[t])}while(t!==r);return t}addCommas(t){return t.split(/[/\\| ]/).map(t=>{if(!t||isNaN(Number(t.replaceAll("-","")))||t.includes(","))return t;switch(t.length){case 1:return t+",0";case 2:return"-"===t.charAt(0)?t+",0":t[0]+","+t[1];case 3:return"-"===t.charAt(0)?t.slice(0,2)+","+t[2]:t[0]+","+t.slice(1);case 4:return t.slice(0,2)+","+t.slice(2);default:throw new Error(`"${t}" is not a valid karn numeric move`)}}).join(" ")}isKarn(t){return/[a-zA-Z]/.test(t)}getAlignmentMove(t,e){return(t?"1":"0")+(e?"-1":"0")}getAlignment(t){if(!t)return{topA:!1,bottomA:!1};if(!(t=this.addCommas(t)).includes(","))throw new Error("getAlignment: move is weird: "+t);const[e,i]=t.split(",");return{topA:"0"!==e,bottomA:"0"!==i}}unkarnifyHelp(e){if(e=(e=e.trim().replaceAll(/[()]/g,"")).replaceAll(/ ([\/\\\|]) /g,"$1"),/[\/\\\|]{2,}/.test(e))throw new Error("unkarnifyHelp: Two slices in a row.");if(!this.isKarn(e))return e;let i,r;/[/\\| ]/.test(e)?(i=e.match(/^([^/\\| ]*)[/\\| ]/)?.[1],r=e.match(/[/\\| ]([^/\\| ]*)$/)?.[1]):i=r=e;let a=["/","\\","|"].includes(e.charAt(0))?e.charAt(0):i in t.karnToWCA?"/":"",n="/"===e.at(-1)||r in t.karnToWCA?"/":"";e=e.replaceAll(/[/\\| ]+/g," ");let s=(e=this.addCommas(e)).split(" ").filter(Boolean);for(let e=0;e<s.length;e++)s[e]in t.karnToWCA&&(s[e]=t.karnToWCA[s[e]].split(" "));s=s.flat();for(let e=0;e<s.length;e++)s[e]in t.karnToWCA&&(s[e]=t.karnToWCA[s[e]]);if(e=(e=a+s.join("/")+n).replaceAll(/ +/g,""),/[\/\\\|]{2,}/.test(e))throw new Error("unkarnifyHelp: Two slices in a row post-replacements.");return e}unkarnify(t){if(t in this.tempReplacements)return this.tempReplacements[t];let e,i=/^p[ /\\|]/.test(t);i&&(e=" "===t.charAt(1)?"/":t.charAt(1),t=t.slice(2,-3)),t=t.replaceAll("&","-1").replaceAll("^","-2").replaceAll("9","-3").replaceAll("8","-4").replaceAll("7","-5");for(const e of t.matchAll(/(\(.*?\))(\d+)/g)){const i=e[1].replaceAll(/[()]/g,""),r=parseInt(e[2],10);t=t.replace(e[0],Array(r).fill(i).join(" "))}let r=this.replaceShorthands(this.unkarnifyHelp(t));return i&&(["/","\\","|"].includes(r.charAt(0))&&(r=r.slice(1)),r="p"+e+r+"/p'"),r=r.replaceAll(/\/+/g,"/"),r}replaceShorthands(e){const i=e.split(/[\/\\\|]/);if(i.every(e=>!e||!this.isKarn(e)||" "+e+" "in t.karnToWCA))return this.unkarnifyHelp(e);let r=!1,a=!1;for(const n of i)if(n)if(n.includes(",")){const[t,e]=n.split(",");parseInt(t,10)%3!=0&&(r=!r),parseInt(e,10)%3!=0&&(a=!a)}else{const i=t.alignmentIndependent.has(n.toLowerCase())?n.toLowerCase():n.toLowerCase()+this.getAlignmentMove(r,a),s=t.shorthandToKarn[i];if(void 0===s)throw new Error(`replaceShorthands: "${n}" with alignment ${this.getAlignmentMove(r,a)} is not defined.`);e=e.replace(n,s);for(const t of this.unkarnifyHelp(s).split("/")){if(!t)continue;const[e,i]=t.split(",");parseInt(e,10)%3!=0&&(r=!r),parseInt(i,10)%3!=0&&(a=!a)}}return this.unkarnifyHelp(e)}parseScramble(t){const e=[],i=t.replace(/[\/\\\|]/g," / ").trim().split(/\s+/).filter(Boolean);for(let t of i)if(t.startsWith("p"))e.push({type:"turn",top:0,bottom:0});else if("/"===t)e.push({type:"twist"});else{if(t=this.addCommas(t.replace(/[()]/g,"")),!t.includes(","))throw new Error(`parseScramble: move: ${t} is weird.`);const[i,r]=t.split(",").map(t=>parseInt(t.trim(),10));isNaN(i)||isNaN(r)||e.push({type:"turn",top:i,bottom:r})}return e}twist(t,e){return{tlHex:t.slice(0,6)+e.slice(0,6),blHex:t.slice(6)+e.slice(6)}}doSlice(e){const[i,r,a,n]=[e.slice(0,t.HALF_L),e.slice(t.HALF_L,t.LAYERL),e.slice(t.LAYERL,t.THREE_FOUR_L),e.slice(t.THREE_FOUR_L,t.CUBEL)],s=t=>t===t.toUpperCase();if(![i,r,a,n].map(t=>!s(t.at(0))||s(t.at(1))&&!s(t.at(-1))||s(t.at(-2))).every(Boolean))throw new Error("doSlice: unsliceable position encountered");return a+r+i+n}algToHex(t){let e="011233455677",i="998bbaddcffe";for(const r of this.parseScramble(this.unkarnify(t)))"twist"===r.type?({tlHex:e,blHex:i}=this.twist(e,i)):(e=this.shift(e,-r.top),i=this.shift(i,-r.bottom));return{tlHex:e,blHex:i}}doMoves(e,i){void 0===i&&(i=t.SOLVED);for(const t of this.unkarnify(e).split("/")){const e=t.trim();if(""!==e){const[t,r]=e.split(",").map(Number);i=this.moveCube(i,t,r)}i=this.doSlice(i)}return this.doSlice(i)}moveCube(e,i,r){return this.shift(e.slice(0,t.LAYERL),i)+this.shift(e.slice(t.LAYERL),r)}invertScramble(t){return t?this.unkarnify(t).trim().split("/").reverse().map(t=>{const e=(t=t.trim()).includes("(")?t.match(/\(([^)]+)\)/)?.[1]:t.includes(",")?t:null;if(!e)return t;const i=e.split(",").map(t=>{const e=parseInt(t.trim(),10);return isNaN(e)?t.trim():String(-e)}).join(",");return t.includes("(")?`(${i})`:i}).join("/"):t}isPBL(t){let{tlHex:e,blHex:i}=t,r=[...e],a=[...i];return r[1]===r[2]&&r[4]===r[5]&&r[7]===r[8]&&r[10]===r[11]&&(parseInt(r[0],10)%2==0&&parseInt(r[1],10)%2==1&&parseInt(r[3],10)%2==0&&parseInt(r[4],10)%2==1&&parseInt(r[6],10)%2==0&&parseInt(r[7],10)%2==1&&parseInt(r[9],10)%2==0&&parseInt(r[10],10)%2==1&&(!!(r.includes("0")&&r.includes("1")&&r.includes("2")&&r.includes("3")&&r.includes("4")&&r.includes("5")&&r.includes("6")&&r.includes("7"))&&(a[0]===a[1]&&a[3]===a[4]&&a[6]===a[7]&&a[9]===a[10]&&(parseInt(a[0],16)%2==1&&parseInt(a[2],16)%2==0&&parseInt(a[3],16)%2==1&&parseInt(a[5],16)%2==0&&parseInt(a[6],16)%2==1&&parseInt(a[8],16)%2==0&&parseInt(a[9],16)%2==1&&parseInt(a[11],16)%2==0&&!!(a.includes("8")&&a.includes("9")&&a.includes("a")&&a.includes("b")&&a.includes("c")&&a.includes("d")&&a.includes("e")&&a.includes("f"))))))}karnify(e){if(e=e.trim(),/[\/\\\|]{2,}/.test(e))throw new Error("karnify: Two slices in a row.");if(this.isKarn(e))throw new Error("karnify: Alg has letters. Try unkarnifying first.");let i=["/","\\","|"].includes(e.charAt(0)),r=i?e.charAt(0):"",a="/"===e.at(-1),n=a?"/":"",s=(e=e.replaceAll(/[/\\| ]+/g," ")).split(" ").filter(Boolean);for(let e=0;e<s.length;e++){if(0===e&&!i){s[e]=s[e].replace(",","");continue}if(e===s.length-1&&!a){s[e]=s[e].replace(",","");break}let l=s[e]in t.wcaToBaseKarn;s[e]=l?t.wcaToBaseKarn[s[e]]:s[e].replace(",",""),l&&0===e&&(r=r.replace("/","")),l&&e===s.length-1&&(n="")}return e=r+s.join(" ")+n,e=this.dictReplace(e,t.baseKarnToHighKarn)}legalMove(t){return(t%=12)<-5?t+12:t>6?t-12:t}addMoves(t,e){if(!t&&!e)throw new Error("addMoves: both moves are empty.");if(!t)return e;if(!e)return t;const i={A:"a",a:"A"};if(t in i&&e in i)throw new Error("addMoves: both moves cannot be alignment markers.");if(t in i){const r=parseInt(e.split(",")[0],10);return this.changesAlignment(r)?i[t]:t}if(e in i){const r=parseInt(t.split(",")[0],10);return this.changesAlignment(r)?i[e]:e}const[r,a]=t.split(",").map(Number),[n,s]=e.split(",").map(Number);return`${this.legalMove(r+n)},${this.legalMove(a+s)}`}changesAlignment(t){return t%3!=0}optimize(e){const i=Object.keys(t.OPTIM);for(;this.dictReplace(e,t.OPTIM)!==e;){const r=e.split("/").map(t=>t.trim());let a=0,n=!1;for(let s=0;s<e.length&&!n;s++)if("/"===e[s]){a++;for(const l of i)if(!(e.length-1-s<l.length)&&e.slice(s,s+l.length)===l){if("/0,0/"===l)r[a-1]=this.addMoves(r[a-1],r[a+1]),r.splice(a,2);else{const e=l.split("/").length,i=t.OPTIM[l].split("/"),n=e-2;r[a-1]=this.addMoves(r[a-1],i.shift()),r[a+e-2]=this.addMoves(r[a+e-2],i.pop()),r.splice(a,n,...i)}e=r.join("/"),n=!0;break}}}return e}getMoveValue(e,i,r){let a=r.indexOf(",");if(-1===a&&(a=this.addCommas(r).indexOf(","),-1===a))throw new Error(`getMoveValue: move: ${r} is weird`);const n=i?"/":"\\";let s;return s=parseInt(r.slice(0,a),10)%3==0?(e?"A":"a")+n+r:n+r,t.MOVE_VALUES.get(s)??5}getOverwork(e){const i=[],r=[];for(const t of e){let e=t.indexOf(",");if(-1===e){if(e=this.addCommas(t).indexOf(","),-1===e)throw new Error(`getOverwork: in moves, m: ${t} is weird.`)}i.push(parseInt(t.slice(0,e),10)||0),r.push(parseInt(t.slice(e+1),10)||0)}let a=0,n=0,s=0,l=0,o=0;for(const e of i){if(6===e||e<0){if(s++,!t.CLOSEST_MAP.has(e))throw new Error("getOverwork: top move is weird: "+e);l+=Math.abs(t.CLOSEST_MAP.get(e)),o+=Math.abs(e),s>1&&l>3&&(a+=o,o=0)}else s=0,l=0,o=0}s=0,l=0,o=0;for(const e of r){if(e>0){if(s++,!t.CLOSEST_MAP.has(e))throw new Error("getOverwork: top move is weird: "+e);l+=Math.abs(t.CLOSEST_MAP.get(e)),o+=Math.abs(e),s>1&&l>3&&(a+=o,o=0)}else s=0,l=0,o=0}for(let t=0;t+1<i.length;t++)i[t]+i[t+1]===0&&n++,r[t]+r[t+1]===0&&n++;return{movement:a,bonus:n}}rateAlg(t,e=!1,i={}){const r=i.W1??34,a=i.W2??100,n=i.W3??38,s=i.W4??500,l=i.W5??10;let o=t.replace(/\[.*$/,"").trim();const h=(this.isKarn(o)?this.unkarnify(o):o.replaceAll(" ","")).split("/").filter((t,e)=>0===e||""!==t.trim()).map(t=>t.trim()),d=h.length-1;if(d<=0)return{score:s,sliceStart:" "};let c=0,u=0,g=!1,f=!0;for(let i=0;i<h.length-1;i++){let r=h[i],a=r.indexOf(",");if(-1===a&&(r=r?this.addCommas(r):"0,0",a=r.indexOf(","),-1===a))throw new Error(`rateAlg:\nalg: ${t}\nmove: ${r}\nis weird.`);const n=parseInt(r.slice(0,a),10);if(isNaN(n))throw new Error(`rateAlg:\nalg: ${t}\nmove: ${r}\nis weird.`);0!==i?(c+=this.getMoveValue(g,f,r),u+=this.getMoveValue(g,!f,r),g=g!==(n%3!=0),f=!f):(g=e!==(n%3!=0),f=!0)}const b=r*Math.max(c,u)/d;let p="|";Math.abs(c-u)/d>5&&(p=c>u?"/":"\\");const w=a*d,m=h.slice(1,-1),{movement:W,bonus:B}=this.getOverwork(m);return{score:b-w-n*W/d+B*l/d+s,sliceStart:p}}rateAndSort(t,e=""){let i=!1;if(e){const t=e[0];i=/[A-HU-W]/i.test(t)}return t.map(t=>{const e=t.indexOf("["),r=e>0?t.slice(0,e).trim():t.trim();let a={alg:t,score:500},n=!1,s=" ";const l=this.isKarn(r)?this.unkarnify(r):r;if(({score:a.score,sliceStart:s}=this.rateAlg(l,i)),n=!0,["/","\\","|"].includes(s)){const e=t.indexOf("/");e>=0&&(a.alg=t.slice(0,e)+s+t.slice(e+1))}return a}).sort((t,e)=>e.score-t.score)}sepIndex(t){let e=0;for(const i of t)if(e++,/\d/.test(i))break;return e}compl(t){if(!t)return t;const e=this.sepIndex(t);return String(this.legalMove(6+parseInt(t.slice(0,e),10)))+String(this.legalMove(6+parseInt(t.slice(e),10)))}lf(t){if(!t)return t;const e=this.sepIndex(t);return t.slice(e)+t.slice(0,e)}compact(t){let e=t.replace(/\[.*?\]/g,"").replace(/[()]/g,"").replaceAll(" ","").trim();if(this.isKarn(e)){return this.unkarnify(e).split("/").filter(Boolean).map(t=>{if(!t.includes(","))throw new Error(`algToInternal: m doesn't have commas post karnifying: ${t}`);const[e,i]=t.split(",");return String(this.legalMove(parseInt(e,10)))+String(this.legalMove(parseInt(i,10)))}).join(" ")}return e=e.trim(),e.includes("/")?e.split("/").filter(Boolean).map(t=>{if(t.includes(",")||(t=this.addCommas(t)),!t.includes(","))throw new Error(`algToInternal: m doesn't have commas post addComma: ${t}`);const[e,i]=t.split(",");return String(this.legalMove(parseInt(e,10)))+String(this.legalMove(parseInt(i,10)))}).join(" "):e.split(" ").filter(t=>t).map(t=>{const e=t.includes(",")?t.split(","):[t.slice(0,this.sepIndex(t)),t.slice(this.sepIndex(t))];return String(this.legalMove(parseInt(e[0],10)))+String(this.legalMove(parseInt(e[1],10)))}).join(" ")}countY2Positions(t){const e=this.compact(t).split(" ").filter(t=>t);return Math.max(0,e.length-3)}applyY2s(e,i,r=null){let a=e.replaceAll(/\[.*?\]/g,"").trim();i||(i=[]);const n=this.isKarn(a),s=null===r?n:r;a=this.unkarnify(e);let l=a.split("/");const o=l[0],h=l[l.length-1];let d=!1,c=!1;for(let t=1;t<=l.length-3;t++){let e=l[t];e=c?this.lf(e):e,i.includes(t)&&(e=this.compl(e),d=!d),c=d?!c:c,l[t]=e}const u=l.length-2;c&&(l[u]=this.lf(l[u])),d!==c&&(l[u]=this.compl(l[u]));const g=l[u];for(let t=0;t<l.length;t++)l[t]=this.addCommas(l[t]);a=l.join("/");let f="";g&&!t.GOOD_FINISHES.has(g)&&(f+=" (bad finish)");const{topA:b,bottomA:p}=this.getAlignment(o),{topA:w,bottomA:m}=this.getAlignment(h);return b!==p&&b!==w&&w!==m&&(f+=" (alignment changes in CS)"),s&&(a=this.karnify(a)),a+f}layerFlip(t){const e={b:"w",B:"W",w:"b",W:"B"};return[...t].map(t=>{if(t in e)return e[t];throw new Error("layerFlip: unrecognized character: "+t)}).join("")}shift(t,e){return e=(-e%t.length+t.length)%t.length,t.slice(e)+t.slice(0,e)}oblName(t){return t[0]?`${t[0]} ${t[1]}/${t[2]}`:`${t[1]}/${t[2]}`}layerFlipName(t){const e=(t=t.replace("/"," ")).split(" ");return 2===e.length?e[1]+"/"+e[0]:e[0]+" "+e[2]+"/"+e[1]}speToNonSpe(e){const[i,r]=e.split("/"),a=i.split(" ").pop(),n=r.split(" ").pop(),s=t.POSSIBLE_OBL.filter(t=>t.includes(a)&&t.includes(n)).map(t=>this.oblName(t));for(const i of s){const r=t.OBL_TRANSLATION[i]||[];for(const t of r){if(t===e)return i;const[r,a]=t.split("/");if(`${a}/${r}`===e)return this.layerFlipName(i)}}throw new Error(`speToNonSpe: No non-specific OBL found for: ${e}`)}isOBLCase(e,i){const r=Object.entries(t.OBLToEnglish).find(([,t])=>t===i)?.[0];if(!r)return!1;e[0]!==e[0].toUpperCase()&&(e=this.shift(e,-1));for(let t=0;t<4;t++)if(r===this.shift(e,-3*t))return t;if(!["T","tie"].includes(i.split(" ").pop())){const t=this.layerFlip(e);for(let e=0;e<4;e++)if(r===this.shift(t,-3*e))return e}return!1}layerToOBL(e){for(const i of Object.keys(t.OBLToState))if(this.isOBLCase(e,i))return{obl:i,angleOffset:this.isOBLCase(e,i)};throw new Error("layerToOBL: no OBL matched layer: "+e)}getAngle(e,i,r,a){let n=t.OBL_ANGLES[e],s=t.OBL_ANGLES[i];for(let e=0;e<r%4;e++)n=t.nextAngle[n];for(let e=0;e<a%4;e++)s=t.nextAngle[s];return`${n} ${s}`}cubeToSpe(e){return[this.layerToOBL(e.slice(0,t.LAYERL)),this.layerToOBL(e.slice(t.LAYERL))]}getOBLLen(t){return t in OBL_LEN?OBL_LEN[t]:OBL_LEN[layer_flip_name(t)]}stateToLen(t,e){return this.getOBLLen(this.speToNonSpe(t+"/"+e))}getOBLNaming(e,i){return t.NAMING[e]+"/"+t.NAMING[i]}stateToMatt(e){let i=e.slice(0,t.LAYERL),r=e.slice(t.LAYERL);i=i[0]!==i[0].toLowerCase()?this.shift(i,3):this.shift(i,2),r=r[0]!==r[0].toLowerCase()?this.shift(r,3):this.shift(r,2);let a="",n=1;for(let e=0;e<t.LAYERL;e+=3)"B"===i[e]&&(a+=n),"b"===i[e+2]&&(a+=n+1),n+=2;a=""===a?"- ":a+" ",n=1;for(let e=0;e<t.LAYERL;e+=3)"B"===r[e]&&(a+=n),"b"===r[e+2]&&(a+=n+1),n+=2;return" "===a[a.length-1]?a+"-":a}mattToLayer(t){const e=["W","W","w","W","W","w","W","W","w","W","W","w"];for(const i of t){const t=parseInt(i,10);t%2!=0?(e[3*Math.floor(t/2)]="B",e[3*Math.floor(t/2)+1]="B"):e[3*Math.floor(t/2)-1]="b"}return e.join("")}mattToNonSpe(t){const[e,i]=t.split(" ");return this.speToNonSpe(`${this.layerToOBL(this.mattToLayer(e))}/${this.layerToOBL(this.mattToLayer(i))}`)}sortOblp(t){return[...t].sort().join("")}}return t});
|
|
2
|
+
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).squanlib=e()}(this,function(){"use strict";class t{static karnToWCA={U4:"U U' U U'","U4'":"U' U U' U",D4:"D D' D D'","D4'":"D' D D' D",u4:"u u' u u'","u4'":"u' u u' u",d4:"d d' d d'","d4'":"d' d d' d",U3:"U U' U","U3'":"U' U U'",D3:"D D' D","D3'":"D' D D'",u3:"u u' u","u3'":"u' u u'",d3:"d d' d","d3'":"d' d d'",F3:"F F' F","F3'":"F' F F'",f3:"f f' f","f3'":"f' f f'",W:"U U'","W'":"U' U",B:"D D'","B'":"D' D",w:"u u'","w'":"u' u",b:"d d'","b'":"d' d",F2:"F F'","F2'":"F' F",f2:"f f'","f2'":"f' f",UU:"U U","UU'":"U' U'",DD:"D D","DD'":"D' D'",T2:"T T'","T2'":"T' T",t2:"t t'","t2'":"t' t",E2:"E E'","E2'":"E' E","ɇ":"U D","ɇ'":"U' D'","Ɇ":"U D'","Ɇ'":"U' D",U2:"6,0","U2'":"6,0",D2:"0,6",U2D:"6,3","U2D'":"6,-3","U2'D":"6,3","U2'D'":"6,-3",U2D2:"6,6",UD2:"3,6","U'D2":"-3,6",U:"3,0","U'":"-3,0",D:"0,3","D'":"0,-3",E:"3,-3","E'":"-3,3",e:"3,3","e'":"-3,-3",u:"2,-1","u'":"-2,1",d:"-1,2","d'":"1,-2",F:"4,1","F'":"-4,-1",f:"1,4","f'":"-1,-4",T:"2,-4","T'":"-2,4",t:"4,-2","t'":"-4,2",m:"2,2","m'":"-2,-2",M:"1,1","M'":"-1,-1",u2:"5,-1","u2'":"-5,1",d2:"-1,5","d2'":"1,-5",K:"5,2","K'":"-5,-2",k:"2,5","k'":"-2,-5",G:"5,-4","G'":"-5,4",g:"4,-5","g'":"-4,5"};static shorthandToKarn={bjj:"U' e D'",fjj:"U e' D",e2bjj:"U' e' U'",e2fjj:"U e U",nn:"E E'",jn:"D4'",nj:"U4",jj:"U e' D","bjj+e2":"U' e' U'","-nn":"E' E","-jn":"D4","-nj":"D4'",bpj10:"d m' U","bpj0-1":"u' m D'",fpj10:"u m' D","fpj0-1":"d' m U'",aa10:"u m' u T'","aa0-1":"U m' U t'",fadj10:"D M' d'",dadj10:"D M' d'","fadj0-1":"U' M u","u'adj0-1":"U' M u",badj10:"U M' u'",uadj10:"U M' u'","badj0-1":"D' M d","d'adj0-1":"D' M d",bb10:"T u' e U'","bb0-1":"t d e' D",fdd10:"D e' d t","fdd0-1":"U' e u' T",bdd10:"U e' u T'","bdd0-1":"D' e d' t'",ff10:"d m' d M E","ff0-1":"u' m U' M T",fv10:"d4","fv0-1":"d4'",vf10:"u4","vf0-1":"u4'",y2fv10:"u d' u -5,4",jf10:"w D' u T'","jf0-1":"w' D u' T",fj10:"b U' d t","fj0-1":"b' U d' t'",jr00:"e' w e",jr10:"e' b e","jr0-1":"e' w' e","jr1-1":"e' b' e",rj00:"e b' e'",rj10:"e w e'","rj0-1":"e b' e'","rj1-1":"e w e'",jv10:"b D d d2'","jv0-1":"b' D' d' d2",vj10:"w U u u2'","vj0-1":"w' U' u' u2",kk10:"u m' U E'","kk0-1":"U m' u E'",opp10:"u2 u2'","opp0-1":"u2' u2",pn10:"T T'","pn0-1":"t t'",px10:"f' d3' f'","px0-1":"f d3 f",xp10:"F' u3' F'","xp0-1":"F u3 F",tt10:"d m' F' u2'",fss10:"u M D' E'","fss0-1":"D' M u E'",bss10:"D M' u' E","bss0-1":"U' M d E",vv10:"u M u m' E'",zz10:"u M t' M D'","zz0-1":"D' M t' M u","30adj10":"U M' u'","-30adj0-1":"U' M u","03adj10":"D M' d'",obopp00:"1,0/M' F M' F M'/0,1","oaopp1-1":"0,1/M' u' M' u' M'/0,1",but00:"",also00:"","done!00":"0,0"};static alignmentIndependent=new Set(["bjj","fjj","nn","jn","nj","e2bjj","e2fjj","jj","bjj+e2","-nn","-jn","-nj"]);static wcaToBaseKarn={"6,0":"U2","6,3":"U2D","6,-3":"U2D'","6,6":"U2D2","0,6":"D2","3,6":"UD2","-3,6":"U'D2","3,0":"U","-3,0":"U'","0,3":"D","0,-3":"D'","3,-3":"E","-3,3":"E'","3,3":"e","-3,-3":"e'","2,-1":"u","-2,1":"u'","-1,2":"d","1,-2":"d'","4,1":"F","-4,-1":"F'","1,4":"f","-1,-4":"f'","2,-4":"T","-2,4":"T'","4,-2":"t","-4,2":"t'","2,2":"m","-2,-2":"m'","1,1":"M","-1,-1":"M'","5,-1":"u2","-5,1":"u2'","-1,5":"d2","1,-5":"d2'","5,2":"K","-5,-2":"K'","2,5":"k","-2,-5":"k'"};static baseKarnToHighKarn={"U U' U U'":"U4","U' U U' U":"U4'","D D' D D'":"D4","D' D D' D":"D4'","u u' u u'":"u4","u' u u' u":"u4'","d d' d d'":"d4","d' d d' d":"d4'","U U' U":"U3","U' U U'":"U3'","D D' D":"D3","D' D D'":"D3'","u u' u":"u3","u' u u'":"u3'","d d' d":"d3","d' d d'":"d3'","F F' F":"F3","F' F F'":"F3'","f f' f":"f3","f' f f'":"f3'","U U'":"W","U' U":"W'","D D'":"B","D' D":"B'","u u'":"w","u' u":"w'","d d'":"b","d' d":"b'","F F'":"F2","F' F":"F2'","f f'":"f2","f' f":"f2'","U U":"UU","U' U'":"UU'","D D":"DD","D' D'":"DD'"};static A_MOVES=[[3,0],[-3,0],[0,3],[0,-3],[3,3],[2,-1],[-1,2],[-4,-1],[-1,-4],[2,-4],[2,2],[-1,-1],[5,-1]];static a_MOVES=[[3,0],[-3,0],[0,3],[0,-3],[3,3],[-2,1],[1,-2],[4,1],[1,4],[-2,4],[-2,-2],[1,1],[-5,1]];static OPTIM={"/0,0/":"","/3,3/3,3/":"-3,-3/-3,-3","/-3,-3/-3,-3/":"3,3/3,3","/2,2/-2,-2/":"2,2/-2,-2","/-2,-2/2,2/":"-2,-2/2,2","/1,1/-1,-1/":"1,1/-1,-1","/-1,-1/1,1/":"-1,-1/1,1","/2,-4/-2,4/2,-4/":"2,-4/-2,4/2,-4","/-2,4/2,-4/-2,4/":"-2,4/2,-4/-2,4","/5,-1/-5,1/5,-1/":"5,-1/-5,1/5,-1","/-5,1/5,-1/-5,1/":"-5,1/5,-1/-5,1"};static CLOSEST_MAP=new Map([[-5,-6],[-4,-3],[-3,-3],[-2,-3],[-1,0],[0,0],[1,0],[2,3],[3,3],[4,3],[5,6],[6,6]]);static MOVE_VALUES=new Map([["A/0,3",16],["A/0,6",1],["A/0,-3",18],["A/3,0",16],["A/3,3",12],["A/3,6",0],["A/3,-3",13],["A/6,0",12],["A/6,3",11],["A/6,6",2],["A/6,-3",12],["A/-3,0",9],["A/-3,3",13],["A/-3,6",4],["A/-3,-3",12],["A\\0,3",17],["A\\0,6",1],["A\\0,-3",8],["A\\3,0",6],["A\\3,3",14],["A\\3,6",1],["A\\3,-3",12],["A\\6,0",14],["A\\6,3",11],["A\\6,6",5],["A\\6,-3",8],["A\\-3,0",11],["A\\-3,3",14],["A\\-3,6",6],["A\\-3,-3",9],["a/0,3",5],["a/0,6",5],["a/0,-3",12],["a/3,0",17],["a/3,3",10],["a/3,6",5],["a/3,-3",7],["a/6,0",4],["a/6,3",2],["a/6,6",0],["a/6,-3",3],["a/-3,0",18],["a/-3,3",12],["a/-3,6",7],["a/-3,-3",11],["a\\0,3",5],["a\\0,6",5],["a\\0,-3",5],["a\\3,0",16],["a\\3,3",11],["a\\3,6",4],["a\\3,-3",6],["a\\6,0",4],["a\\6,3",2],["a\\6,6",0],["a\\6,-3",1],["a\\-3,0",15],["a\\-3,3",10],["a\\-3,6",2],["a\\-3,-3",5],["/1,-2",4],["\\1,-2",17],["/-1,2",15],["\\-1,2",14],["/1,-5",3],["\\1,-5",1],["/-1,5",8],["\\-1,5",3],["/1,4",7],["\\1,4",14],["/-1,-4",12],["\\-1,-4",9],["/1,1",11],["\\1,1",20],["/-1,-1",20],["\\-1,-1",10],["/2,-1",20],["\\2,-1",12],["/-2,1",14],["\\-2,1",18],["/2,2",12],["\\2,2",13],["/-2,-2",14],["\\-2,-2",8],["/2,5",5],["\\2,5",3],["/-2,-5",4],["\\-2,-5",3],["/2,-4",14],["\\2,-4",6],["/-2,4",13],["\\-2,4",13],["/4,4",5],["\\4,4",12],["/-4,-4",12],["\\-4,-4",4],["/4,1",6],["\\4,1",13],["/-4,-1",16],["\\-4,-1",6],["/4,-2",12],["\\4,-2",9],["/-4,2",16],["\\-4,2",13],["/4,-5",2],["\\4,-5",5],["/-4,5",13],["\\-4,5",3],["/5,5",1],["\\5,5",4],["/-5,-5",2],["\\-5,-5",0],["/5,2",6],["\\5,2",10],["/-5,-2",12],["\\-5,-2",13],["/5,-1",11],["\\5,-1",7],["/-5,1",14],["\\-5,1",15],["/5,-4",2],["\\5,-4",2],["/-5,4",12],["\\-5,4",14]]);static GOOD_FINISHES=new Set(["1,1","-1,-1","2,2","-2,-2","2,-1","-2,1","1,-2","-1,2","3,0","-3,0","0,3","0,-3","3,3","3,-3","-3,-3","-3,3","4,1","-4,-1","1,4","-1,-4","2,-4","-2,4","4,-2","-4,2","5,-1","-5,1","-4,5","-5,4","6,3"]);static OBLToEnglish={BBbBBbBBbBBb:"solved",BBwWWwWWwWWw:"1c",BBwBBwWWwWWw:"cadj",BBwWWwBBwWWw:"copp",BBwBBwBBwWWw:"3c",BBwBBwBBwBBw:"4e",WWbWWbWWbWWw:"3e",WWbWWwWWbWWw:"line",WWbWWbWWwWWw:"L",WWbWWwWWwWWw:"1e",WWbBBwWWwWWw:"left pair",BBbWWwWWwWWw:"right pair",BBwWWwWWbWWw:"left arrow",BBwWWbWWwWWw:"right arrow",WWbBBbWWwWWw:"gem",WWwWWbWWbBBw:"left knight",BBbWWbWWwWWw:"right knight",WWwWWbWWwBBb:"left axe",BBwWWbWWwWWb:"right axe",BBwWWbWWbWWw:"squid",WWwWWbBBbWWb:"left thumb",WWbBBbWWwWWb:"right thumb",WWwBBbWWbWWb:"left bunny",WWbWWbBBwWWb:"right bunny",BBbBBwWWwWWw:"shell",BBwWWwWWbBBw:"left bird",BBwBBbWWwWWw:"right bird",BBwWWbWWwBBw:"hazard",BBbBBbWWwWWw:"left kite",WWwWWbBBbBBw:"right kite",BBwBBwWWbWWb:"left cut",BBwBBbWWbWWw:"right cut",BBbBBwWWbWWw:"black T",WWwWWbBBwBBb:"white T",WWbBBwWWbBBw:"left N",WWwBBbWWwBBb:"right N",WWbBBbWWwBBw:"black tie",BBwWWwBBbWWb:"white tie",BBbWWwBBwWWw:"left yoshi",WWwBBwWWbBBw:"right yoshi"};static OBLToState=Object.fromEntries(Object.entries(this.OBLToEnglish).map(([t,e])=>[e,t]));static NAMING={solved:"O","1c":"D",cadj:"J",copp:"V","3c":"M","4e":"Q","3e":"W",line:"F",L:"L","1e":"E","left pair":"Pw","right pair":"Pc","left arrow":"Aw","right arrow":"Ac",gem:"G","left knight":"Hw","right knight":"Hc","left axe":"Xc","right axe":"Xw",squid:"S","left thumb":"THw","right thumb":"THc","left bunny":"Uc","right bunny":"Uw",shell:"SH","left bird":"Bc","right bird":"Bw",hazard:"Z","left kite":"Kc","right kite":"Kw","left cut":"Cw","right cut":"Cc","black T":"Tu","white T":"Td","left N":"Nw","right N":"Nc","black tie":"Iu","white tie":"Id","left yoshi":"Yc","right yoshi":"Yw"};static OBL_ANGLES={solved:"-","1c":"UR",cadj:"R",copp:"/","3c":"DR","4e":"-","3e":"D",line:"—",L:"DR","1e":"R","left pair":"DR","right pair":"UR","left arrow":"UR","right arrow":"UR",gem:"DR","left knight":"L","right knight":"R","left axe":"L","right axe":"R",squid:"UR","left thumb":"DL","right thumb":"DR","left bunny":"DR","right bunny":"DL",shell:"R","left bird":"R","right bird":"U",hazard:"U","left kite":"R","right kite":"L","left cut":"R","right cut":"R","black T":"R","white T":"R","left N":"\\","right N":"\\","black tie":"DR","white tie":"DR","left yoshi":"UL","right yoshi":"UR"};static nextAngle={"-":"-","/":"\\","\\":"/","—":"|","|":"—",U:"R",R:"D",D:"L",L:"U",UR:"DR",DR:"DL",DL:"UL",UL:"UR"};static get HALF_L(){return 6}static get LAYERL(){return 12}static get THREE_FOUR_L(){return 18}static get CUBEL(){return 24}static get SOLVED(){return"bBBbBBbBBbBBwWWwWWwWWwWW"}static POSSIBLE_OBL=[["","solved","solved"],["","1c","1c"],["","cadj","cadj"],["","cadj","copp"],["","copp","copp"],["","3c","3c"],["","4e","4e"],["","3e","3e"],["","line","line"],["","L","line"],["","L","L"],["","1e","1e"],["good","pair","pair"],["bad","pair","pair"],["good","arrow","pair"],["bad","arrow","pair"],["good","arrow","arrow"],["bad","arrow","arrow"],["","gem","gem"],["","gem","knight"],["","gem","axe"],["","gem","squid"],["good","knight","knight"],["bad","knight","knight"],["good","knight","axe"],["bad","knight","axe"],["same","axe","axe"],["diff","axe","axe"],["","squid","knight"],["","squid","axe"],["","squid","squid"],["good","thumb","thumb"],["bad","thumb","thumb"],["good","thumb","bunny"],["bad","thumb","bunny"],["good","bunny","bunny"],["bad","bunny","bunny"],["","shell","shell"],["","shell","bird"],["","shell","hazard"],["","yoshi","shell"],["good","bird","bird"],["bad","bird","bird"],["","bird","hazard"],["","hazard","hazard"],["good","yoshi","bird"],["bad","yoshi","bird"],["","yoshi","hazard"],["same","yoshi","yoshi"],["diff","yoshi","yoshi"],["good","kite","kite"],["bad","kite","kite"],["good","kite","cut"],["bad","kite","cut"],["","kite","T"],["good","kite","N"],["bad","kite","N"],["","kite","tie"],["","cut","T"],["good","cut","N"],["bad","cut","N"],["","cut","tie"],["good","cut","cut"],["bad","cut","cut"],["good","T","T"],["bad","T","T"],["","T","N"],["good","T","tie"],["bad","T","tie"],["good","N","N"],["bad","N","N"],["","tie","N"],["good","tie","tie"],["bad","tie","tie"]];static OBL_LEN={"solved/solved":0,"1c/1c":5,"cadj/cadj":4,"cadj/copp":5,"copp/copp":2,"3c/3c":5,"4e/4e":4,"3e/3e":5,"line/line":2,"L/line":5,"L/L":4,"1e/1e":5,"good pair/pair":2,"bad pair/pair":4,"good arrow/pair":3,"bad arrow/pair":4,"good arrow/arrow":3,"bad arrow/arrow":4,"gem/gem":4,"gem/knight":4,"gem/axe":3,"gem/squid":4,"good knight/knight":4,"bad knight/knight":5,"good knight/axe":3,"bad knight/axe":4,"same axe/axe":5,"diff axe/axe":5,"squid/knight":4,"squid/axe":4,"squid/squid":5,"good thumb/thumb":2,"bad thumb/thumb":5,"good thumb/bunny":4,"bad thumb/bunny":4,"good bunny/bunny":3,"bad bunny/bunny":5,"shell/shell":4,"shell/bird":4,"shell/hazard":4,"yoshi/shell":3,"good bird/bird":4,"bad bird/bird":5,"bird/hazard":4,"hazard/hazard":5,"good yoshi/bird":3,"bad yoshi/bird":4,"yoshi/hazard":4,"same yoshi/yoshi":5,"diff yoshi/yoshi":5,"good kite/kite":1,"bad kite/kite":5,"good kite/cut":3,"bad kite/cut":6,"kite/T":4,"good kite/N":3,"bad kite/N":4,"kite/tie":4,"cut/T":4,"good cut/N":4,"bad cut/N":5,"cut/tie":4,"good cut/cut":3,"bad cut/cut":6,"good T/T":3,"bad T/T":4,"T/N":5,"good T/tie":3,"bad T/tie":4,"good N/N":2,"bad N/N":4,"tie/N":5,"good tie/tie":3,"bad tie/tie":4};static OBL_TRANSLATION={"solved/solved":["solved/solved"],"1c/1c":["1c/1c"],"cadj/cadj":["cadj/cadj"],"cadj/copp":["cadj/copp"],"copp/copp":["copp/copp"],"3c/3c":["3c/3c"],"4e/4e":["4e/4e"],"3e/3e":["3e/3e"],"line/line":["line/line"],"L/line":["L/line"],"L/L":["L/L"],"1e/1e":["1e/1e"],"good pair/pair":["left pair/left pair","right pair/right pair"],"bad pair/pair":["left pair/right pair"],"good arrow/pair":["left arrow/right pair","right arrow/left pair"],"bad arrow/pair":["left arrow/left pair","right arrow/right pair"],"good arrow/arrow":["left arrow/left arrow","right arrow/right arrow"],"bad arrow/arrow":["left arrow/right arrow"],"gem/gem":["gem/gem"],"gem/knight":["gem/left knight","gem/right knight"],"gem/axe":["gem/left axe","gem/right axe"],"gem/squid":["gem/squid"],"good knight/knight":["left knight/right knight"],"bad knight/knight":["left knight/left knight","right knight/right knight"],"good knight/axe":["left knight/left axe","right knight/right axe"],"bad knight/axe":["left knight/right axe","right knight/left axe"],"same axe/axe":["left axe/left axe","right axe/right axe"],"diff axe/axe":["left axe/right axe"],"squid/knight":["squid/left knight","squid/right knight"],"squid/axe":["squid/left axe","squid/right axe"],"squid/squid":["squid/squid"],"good thumb/thumb":["left thumb/left thumb","right thumb/right thumb"],"bad thumb/thumb":["left thumb/right thumb"],"good thumb/bunny":["left thumb/right bunny","right thumb/left bunny"],"bad thumb/bunny":["left thumb/left bunny","right thumb/right bunny"],"good bunny/bunny":["left bunny/left bunny","right bunny/right bunny"],"bad bunny/bunny":["left bunny/right bunny"],"shell/shell":["shell/shell"],"shell/bird":["shell/left bird","shell/right bird"],"shell/hazard":["shell/hazard"],"yoshi/shell":["left yoshi/shell","right yoshi/shell"],"good bird/bird":["left bird/right bird"],"bad bird/bird":["left bird/left bird","right bird/right bird"],"bird/hazard":["left bird/hazard","right bird/hazard"],"hazard/hazard":["hazard/hazard"],"good yoshi/bird":["left yoshi/left bird","right yoshi/right bird"],"bad yoshi/bird":["left yoshi/right bird","right yoshi/left bird"],"yoshi/hazard":["left yoshi/hazard","right yoshi/hazard"],"same yoshi/yoshi":["left yoshi/left yoshi","right yoshi/right yoshi"],"diff yoshi/yoshi":["left yoshi/right yoshi"],"good kite/kite":["left kite/left kite","right kite/right kite"],"bad kite/kite":["left kite/right kite"],"good kite/cut":["left kite/left cut","right kite/right cut"],"bad kite/cut":["left kite/right cut","right kite/left cut"],"kite/T":["left kite/black T","left kite/white T","right kite/black T","right kite/white T"],"good kite/N":["left kite/right N","right kite/left N"],"bad kite/N":["left kite/left N","right kite/right N"],"kite/tie":["left kite/black tie","left kite/white tie","right kite/black tie","right kite/white tie"],"cut/T":["left cut/black T","left cut/white T","right cut/black T","right cut/white T"],"good cut/N":["left cut/left N","right cut/right N"],"bad cut/N":["left cut/right N","right cut/left N"],"cut/tie":["left cut/black tie","left cut/white tie","right cut/black tie","right cut/white tie"],"good cut/cut":["left cut/left cut","right cut/right cut"],"bad cut/cut":["left cut/right cut"],"good T/T":["black T/black T","white T/white T"],"bad T/T":["black T/white T"],"T/N":["black T/left N","black T/right N","white T/left N","white T/right N"],"good T/tie":["black T/black tie","white T/white tie"],"bad T/tie":["black T/white tie","white T/black tie"],"good N/N":["left N/left N","right N/right N"],"bad N/N":["left N/right N"],"tie/N":["black tie/left N","black tie/right N","white tie/left N","white tie/right N"],"good tie/tie":["black tie/black tie","white tie/white tie"],"bad tie/tie":["black tie/white tie"]};static CORNERS=[[""],["1","3","5","7"],["13","15","17","35","37","57"],["135","137","157","357"],["1357"]];static EDGES=[[""],["2","4","6","8"],["24","26","28","46","48","68"],["246","248","268","468"],["2468"]];static TOTAL_CORNERS=["","1","3","5","7","13","15","17","35","37","57","135","137","157","357","1357"];static TOTAL_EDGES=["","2","4","6","8","24","26","28","46","48","68","246","248","268","468","2468"];constructor(t={"meow :3":"meow :3"}){this.tempReplacements={...t}}setTempReplacements(t){return this.tempReplacements={...t},this}addTempReplacements(t){return Object.assign(this.tempReplacements,t),this}dictReplace(t,e){const i=new RegExp(Object.keys(e).map(t=>t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join("|"),"g");let r;do{r=t,t=t.replace(i,t=>e[t])}while(t!==r);return t}addCommas(t){return t.split(/[/\\| ]/).map(t=>{if(!t||isNaN(Number(t.replaceAll("-","")))||t.includes(","))return t;switch(t.length){case 1:return t+",0";case 2:return"-"===t.charAt(0)?t+",0":t[0]+","+t[1];case 3:return"-"===t.charAt(0)?t.slice(0,2)+","+t[2]:t[0]+","+t.slice(1);case 4:return t.slice(0,2)+","+t.slice(2);default:throw new Error(`"${t}" is not a valid karn numeric move`)}}).join(" ")}isKarn(t){return/[a-zA-Z]/.test(t)}getAlignmentMove(t,e){return(t?"1":"0")+(e?"-1":"0")}getAlignment(t){if(!t)return{topA:!1,bottomA:!1};if(!(t=this.addCommas(t)).includes(","))throw new Error("getAlignment: move is weird: "+t);const[e,i]=t.split(",");return{topA:"0"!==e,bottomA:"0"!==i}}unkarnifyHelp(e){if(e=(e=e.trim().replaceAll(/[()]/g,"")).replaceAll(/ ([\/\\\|]) /g,"$1"),/[\/\\\|]{2,}/.test(e))throw new Error("unkarnifyHelp: Two slices in a row.");if(!this.isKarn(e))return e;let i,r;/[/\\| ]/.test(e)?(i=e.match(/^([^/\\| ]*)[/\\| ]/)?.[1],r=e.match(/[/\\| ]([^/\\| ]*)$/)?.[1]):i=r=e;let a=["/","\\","|"].includes(e.charAt(0))?e.charAt(0):i in t.karnToWCA?"/":"",n="/"===e.at(-1)||r in t.karnToWCA?"/":"";e=e.replaceAll(/[/\\| ]+/g," ");let s=(e=this.addCommas(e)).split(" ").filter(Boolean);for(let e=0;e<s.length;e++)s[e]in t.karnToWCA&&(s[e]=t.karnToWCA[s[e]].split(" "));s=s.flat();for(let e=0;e<s.length;e++)s[e]in t.karnToWCA&&(s[e]=t.karnToWCA[s[e]]);if(e=(e=a+s.join("/")+n).replaceAll(/ +/g,""),/[\/\\\|]{2,}/.test(e))throw new Error("unkarnifyHelp: Two slices in a row post-replacements.");return e}unkarnify(t){if(t in this.tempReplacements)return this.tempReplacements[t];t=(t=t.replaceAll("&","-1").replaceAll("^","-2").replaceAll("9","-3").replaceAll("8","-4").replaceAll("7","-5")).replaceAll(/\[.*?\]/g,"");let e,i=/^p[ /\\|]/.test(t);i&&(e=" "===t.charAt(1)?"/":t.charAt(1),t=t.slice(2,-3));for(const e of t.matchAll(/(\(.*?\))(\d+)/g)){const i=e[1].replaceAll(/[()]/g,""),r=parseInt(e[2],10);t=t.replace(e[0],Array(r).fill(i).join(" "))}let r=this.replaceShorthands(this.unkarnifyHelp(t));return i&&(["/","\\","|"].includes(r.charAt(0))&&(r=r.slice(1)),r="p"+e+r+"/p'"),r=r.replaceAll(/\/+/g,"/"),r}replaceShorthands(e){const i=e.split(/[\/\\\|]/);if(i.every(e=>!e||!this.isKarn(e)||" "+e+" "in t.karnToWCA))return this.unkarnifyHelp(e);let r=!1,a=!1;for(const n of i)if(n)if(n.includes(",")){const[t,e]=n.split(",");parseInt(t,10)%3!=0&&(r=!r),parseInt(e,10)%3!=0&&(a=!a)}else{const i=t.alignmentIndependent.has(n.toLowerCase())?n.toLowerCase():n.toLowerCase()+this.getAlignmentMove(r,a),s=t.shorthandToKarn[i];if(void 0===s)throw new Error(`replaceShorthands: "${n}" with alignment ${this.getAlignmentMove(r,a)} is not defined.`);e=e.replace(n,s);for(const t of this.unkarnifyHelp(s).split("/")){if(!t)continue;const[e,i]=t.split(",");parseInt(e,10)%3!=0&&(r=!r),parseInt(i,10)%3!=0&&(a=!a)}}return this.unkarnifyHelp(e)}parseScramble(t){const e=[],i=t.replace(/[\/\\\|]/g," / ").trim().split(/\s+/).filter(Boolean);for(let t of i)if(t.startsWith("p"))e.push({type:"turn",top:0,bottom:0});else if("/"===t)e.push({type:"twist"});else{if(t=this.addCommas(t.replace(/[()]/g,"")),!t.includes(","))throw new Error(`parseScramble: move: ${t} is weird.`);const[i,r]=t.split(",").map(t=>parseInt(t.trim(),10));isNaN(i)||isNaN(r)||e.push({type:"turn",top:i,bottom:r})}return e}twist(t,e){return{tlHex:t.slice(0,6)+e.slice(0,6),blHex:t.slice(6)+e.slice(6)}}doSlice(e){const[i,r,a,n]=[e.slice(0,t.HALF_L),e.slice(t.HALF_L,t.LAYERL),e.slice(t.LAYERL,t.THREE_FOUR_L),e.slice(t.THREE_FOUR_L,t.CUBEL)],s=t=>t===t.toUpperCase();if(![i,r,a,n].map(t=>!s(t.at(0))||s(t.at(1))&&!s(t.at(-1))||s(t.at(-2))).every(Boolean))throw new Error("doSlice: unsliceable position encountered");return a+r+i+n}algToHex(t){let e="011233455677",i="998bbaddcffe";for(const r of this.parseScramble(this.unkarnify(t)))"twist"===r.type?({tlHex:e,blHex:i}=this.twist(e,i)):(e=this.shift(e,-r.top),i=this.shift(i,-r.bottom));return{tlHex:e,blHex:i}}doMoves(e,i){void 0===i&&(i=t.SOLVED);for(const t of this.unkarnify(e).split("/")){const e=t.trim();if(""!==e){const[t,r]=e.split(",").map(Number);i=this.moveCube(i,t,r)}i=this.doSlice(i)}return this.doSlice(i)}moveCube(e,i,r){return this.shift(e.slice(0,t.LAYERL),i)+this.shift(e.slice(t.LAYERL),r)}invertScramble(t){return t?this.unkarnify(t).trim().split("/").reverse().map(t=>{const e=(t=t.trim()).includes("(")?t.match(/\(([^)]+)\)/)?.[1]:t.includes(",")?t:null;if(!e)return t;const i=e.split(",").map(t=>{const e=parseInt(t.trim(),10);return isNaN(e)?t.trim():String(-e)}).join(",");return t.includes("(")?`(${i})`:i}).join("/"):t}isPBL(t){let{tlHex:e,blHex:i}=t,r=[...e],a=[...i];return r[1]===r[2]&&r[4]===r[5]&&r[7]===r[8]&&r[10]===r[11]&&(parseInt(r[0],10)%2==0&&parseInt(r[1],10)%2==1&&parseInt(r[3],10)%2==0&&parseInt(r[4],10)%2==1&&parseInt(r[6],10)%2==0&&parseInt(r[7],10)%2==1&&parseInt(r[9],10)%2==0&&parseInt(r[10],10)%2==1&&(!!(r.includes("0")&&r.includes("1")&&r.includes("2")&&r.includes("3")&&r.includes("4")&&r.includes("5")&&r.includes("6")&&r.includes("7"))&&(a[0]===a[1]&&a[3]===a[4]&&a[6]===a[7]&&a[9]===a[10]&&(parseInt(a[0],16)%2==1&&parseInt(a[2],16)%2==0&&parseInt(a[3],16)%2==1&&parseInt(a[5],16)%2==0&&parseInt(a[6],16)%2==1&&parseInt(a[8],16)%2==0&&parseInt(a[9],16)%2==1&&parseInt(a[11],16)%2==0&&!!(a.includes("8")&&a.includes("9")&&a.includes("a")&&a.includes("b")&&a.includes("c")&&a.includes("d")&&a.includes("e")&&a.includes("f"))))))}karnify(e){if(e=e.trim(),/[\/\\\|]{2,}/.test(e))throw new Error("karnify: Two slices in a row.");if(this.isKarn(e))throw new Error("karnify: Alg has letters. Try unkarnifying first.");let i=["/","\\","|"].includes(e.charAt(0)),r=i?e.charAt(0):"",a="/"===e.at(-1),n=a?"/":"",s=(e=e.replaceAll(/[/\\| ]+/g," ")).split(" ").filter(Boolean);for(let e=0;e<s.length;e++){if(0===e&&!i){s[e]=s[e].replace(",","");continue}if(e===s.length-1&&!a){s[e]=s[e].replace(",","");break}let l=s[e]in t.wcaToBaseKarn;s[e]=l?t.wcaToBaseKarn[s[e]]:s[e].replace(",",""),l&&0===e&&(r=r.replace("/","")),l&&e===s.length-1&&(n="")}return e=r+s.join(" ")+n,e=this.dictReplace(e,t.baseKarnToHighKarn)}legalMove(t){return(t%=12)<-5?t+12:t>6?t-12:t}addMoves(t,e){if(!t&&!e)throw new Error("addMoves: both moves are empty.");if(!t)return e;if(!e)return t;const i={A:"a",a:"A"};if(t in i&&e in i)throw new Error("addMoves: both moves cannot be alignment markers.");if(t in i){const r=parseInt(e.split(",")[0],10);return this.changesAlignment(r)?i[t]:t}if(e in i){const r=parseInt(t.split(",")[0],10);return this.changesAlignment(r)?i[e]:e}const[r,a]=t.split(",").map(Number),[n,s]=e.split(",").map(Number);return`${this.legalMove(r+n)},${this.legalMove(a+s)}`}changesAlignment(t){return t%3!=0}optimize(e){const i=Object.keys(t.OPTIM);for(;this.dictReplace(e,t.OPTIM)!==e;){const r=e.split("/").map(t=>t.trim());let a=0,n=!1;for(let s=0;s<e.length&&!n;s++)if("/"===e[s]){a++;for(const l of i)if(!(e.length-1-s<l.length)&&e.slice(s,s+l.length)===l){if("/0,0/"===l)r[a-1]=this.addMoves(r[a-1],r[a+1]),r.splice(a,2);else{const e=l.split("/").length,i=t.OPTIM[l].split("/"),n=e-2;r[a-1]=this.addMoves(r[a-1],i.shift()),r[a+e-2]=this.addMoves(r[a+e-2],i.pop()),r.splice(a,n,...i)}e=r.join("/"),n=!0;break}}}return e}getMoveValue(e,i,r){let a=r.indexOf(",");if(-1===a&&(a=this.addCommas(r).indexOf(","),-1===a))throw new Error(`getMoveValue: move: ${r} is weird`);const n=i?"/":"\\";let s;return s=parseInt(r.slice(0,a),10)%3==0?(e?"A":"a")+n+r:n+r,t.MOVE_VALUES.get(s)??5}getOverwork(e){const i=[],r=[];for(const t of e){let e=t.indexOf(",");if(-1===e){if(e=this.addCommas(t).indexOf(","),-1===e)throw new Error(`getOverwork: in moves, m: ${t} is weird.`)}i.push(parseInt(t.slice(0,e),10)||0),r.push(parseInt(t.slice(e+1),10)||0)}let a=0,n=0,s=0,l=0,o=0;for(const e of i){if(6===e||e<0){if(s++,!t.CLOSEST_MAP.has(e))throw new Error("getOverwork: top move is weird: "+e);l+=Math.abs(t.CLOSEST_MAP.get(e)),o+=Math.abs(e),s>1&&l>3&&(a+=o,o=0)}else s=0,l=0,o=0}s=0,l=0,o=0;for(const e of r){if(e>0){if(s++,!t.CLOSEST_MAP.has(e))throw new Error("getOverwork: top move is weird: "+e);l+=Math.abs(t.CLOSEST_MAP.get(e)),o+=Math.abs(e),s>1&&l>3&&(a+=o,o=0)}else s=0,l=0,o=0}for(let t=0;t+1<i.length;t++)i[t]+i[t+1]===0&&n++,r[t]+r[t+1]===0&&n++;return{movement:a,bonus:n}}rateAlg(t,e=!1,i={}){const r=i.W1??34,a=i.W2??100,n=i.W3??38,s=i.W4??500,l=i.W5??10;let o=t.replace(/\[.*$/,"").trim();const h=(this.isKarn(o)?this.unkarnify(o):o.replaceAll(" ","")).split("/").filter((t,e)=>0===e||""!==t.trim()).map(t=>t.trim()),d=h.length-1;if(d<=0)return{score:s,sliceStart:" "};let c=0,u=0,g=!1,f=!0;for(let i=0;i<h.length-1;i++){let r=h[i],a=r.indexOf(",");if(-1===a&&(r=r?this.addCommas(r):"0,0",a=r.indexOf(","),-1===a))throw new Error(`rateAlg:\nalg: ${t}\nmove: ${r}\nis weird.`);const n=parseInt(r.slice(0,a),10);if(isNaN(n))throw new Error(`rateAlg:\nalg: ${t}\nmove: ${r}\nis weird.`);0!==i?(c+=this.getMoveValue(g,f,r),u+=this.getMoveValue(g,!f,r),g=g!==(n%3!=0),f=!f):(g=e!==(n%3!=0),f=!0)}const b=r*Math.max(c,u)/d;let p="|";Math.abs(c-u)/d>5&&(p=c>u?"/":"\\");const w=a*d,m=h.slice(1,-1),{movement:W,bonus:B}=this.getOverwork(m);return{score:b-w-n*W/d+B*l/d+s,sliceStart:p}}rateAndSort(t,e=""){let i=!1;if(e){const t=e[0];i=/[A-HU-W]/i.test(t)}return t.map(t=>{const e=t.indexOf("["),r=e>0?t.slice(0,e).trim():t.trim();let a={alg:t,score:500},n=!1,s=" ";const l=this.isKarn(r)?this.unkarnify(r):r;return({score:a.score,sliceStart:s}=this.rateAlg(l,i)),n=!0,["/","\\","|"].includes(s)&&(a.alg=this.injectSliceStart(t,s)),a}).sort((t,e)=>e.score-t.score)}injectSliceStart(e,i){let r=/[/\\| ]/.test(e);if((r?e.match(/^([^/\\| ]*)[/\\| ]/)?.[1]:e)in t.karnToWCA)return i+e;if(!r)return e;const a=e.search(/[/\\| ]/);return e.slice(0,a)+i+e.slice(a+1)}sepIndex(t){let e=0;for(const i of t)if(e++,/\d/.test(i))break;return e}compl(t){if(!t)return t;let e,i;if(t.includes(","))[e,i]=t.split(",");else{const r=this.sepIndex(t);[e,i]=[t.slice(0,r),t.slice(r)]}return String(this.legalMove(6+parseInt(e,10)))+","+String(this.legalMove(6+parseInt(i,10)))}lf(t){if(!t)return t;let e,i;if(t.includes(","))[e,i]=t.split(",");else{const r=this.sepIndex(t);[e,i]=[t.slice(0,r),t.slice(r)]}return i+","+e}compact(t){let e=t.replace(/\[.*?\]/g,"").replace(/[()]/g,"").trim();if(this.isKarn(e)){return this.unkarnify(e).split("/").map(t=>{if(!t)return t;if(!t.includes(","))throw new Error(`algToInternal: m doesn't have commas post karnifying: ${t}`);const[e,i]=t.split(",");return String(this.legalMove(parseInt(e,10)))+String(this.legalMove(parseInt(i,10)))}).join(" ")}return e=e.replaceAll(" ",""),e.includes("/")?e.split("/").filter(Boolean).map(t=>{if(t.includes(",")||(t=this.addCommas(t)),!t.includes(","))throw new Error(`algToInternal: m doesn't have commas post addComma: ${t}`);const[e,i]=t.split(",");return String(this.legalMove(parseInt(e,10)))+String(this.legalMove(parseInt(i,10)))}).join(" "):e.split(" ").filter(t=>t).map(t=>{const e=t.includes(",")?t.split(","):[t.slice(0,this.sepIndex(t)),t.slice(this.sepIndex(t))];return String(this.legalMove(parseInt(e[0],10)))+String(this.legalMove(parseInt(e[1],10)))}).join(" ")}countY2Positions(t){const e=this.compact(t).split(" ");return Math.max(0,e.length-3)}applyY2s(e,i,r=null){let a=e.replaceAll(/\[.*?\]/g,"").trim();i||(i=[]);const n=this.isKarn(a),s=null===r?n:r;a=this.unkarnify(e);let l=a.split("/");const o=l[0],h=l[l.length-1];let d=!1,c=!1;for(let t=1;t<=l.length-3;t++){let e=l[t];e=c?this.lf(e):e,i.includes(t)&&(e=this.compl(e),d=!d),c=d?!c:c,l[t]=e}const u=l.length-2;c&&(l[u]=this.lf(l[u])),d!==c&&(l[u]=this.compl(l[u]));const g=l[u];for(let t=0;t<l.length;t++)l[t]=this.addCommas(l[t]);a=l.join("/");let f="";g&&!t.GOOD_FINISHES.has(g)&&(f+=" (bad finish)");const{topA:b,bottomA:p}=this.getAlignment(o),{topA:w,bottomA:m}=this.getAlignment(h);return b!==p&&b!==w&&w!==m&&(f+=" (alignment changes in CS)"),s&&(a=this.karnify(a)),a+f}layerFlip(t){const e={b:"w",B:"W",w:"b",W:"B"};return[...t].map(t=>{if(t in e)return e[t];throw new Error("layerFlip: unrecognized character: "+t)}).join("")}shift(t,e){return e=(-e%t.length+t.length)%t.length,t.slice(e)+t.slice(0,e)}oblName(t){return t[0]?`${t[0]} ${t[1]}/${t[2]}`:`${t[1]}/${t[2]}`}layerFlipName(t){const e=(t=t.replace("/"," ")).split(" ");return 2===e.length?e[1]+"/"+e[0]:e[0]+" "+e[2]+"/"+e[1]}speToNonSpe(e){const[i,r]=e.split("/"),a=i.split(" ").pop(),n=r.split(" ").pop(),s=t.POSSIBLE_OBL.filter(t=>t.includes(a)&&t.includes(n)).map(t=>this.oblName(t));for(const i of s){const r=t.OBL_TRANSLATION[i]||[];for(const t of r){if(t===e)return i;const[r,a]=t.split("/");if(`${a}/${r}`===e)return this.layerFlipName(i)}}throw new Error(`speToNonSpe: No non-specific OBL found for: ${e}`)}isOBLCase(e,i){const r=Object.entries(t.OBLToEnglish).find(([,t])=>t===i)?.[0];if(!r)return!1;e[0]!==e[0].toUpperCase()&&(e=this.shift(e,-1));for(let t=0;t<4;t++)if(r===this.shift(e,-3*t))return t;if(!["T","tie"].includes(i.split(" ").pop())){const t=this.layerFlip(e);for(let e=0;e<4;e++)if(r===this.shift(t,-3*e))return e}return!1}layerToOBL(e){for(const i of Object.keys(t.OBLToState))if(this.isOBLCase(e,i))return{obl:i,angleOffset:this.isOBLCase(e,i)};throw new Error("layerToOBL: no OBL matched layer: "+e)}getAngle(e,i,r,a){let n=t.OBL_ANGLES[e],s=t.OBL_ANGLES[i];for(let e=0;e<r%4;e++)n=t.nextAngle[n];for(let e=0;e<a%4;e++)s=t.nextAngle[s];return`${n} ${s}`}cubeToSpe(e){return[this.layerToOBL(e.slice(0,t.LAYERL)),this.layerToOBL(e.slice(t.LAYERL))]}getOBLLen(t){return t in OBL_LEN?OBL_LEN[t]:OBL_LEN[layer_flip_name(t)]}stateToLen(t,e){return this.getOBLLen(this.speToNonSpe(t+"/"+e))}getOBLNaming(e,i){return t.NAMING[e]+"/"+t.NAMING[i]}stateToMatt(e){let i=e.slice(0,t.LAYERL),r=e.slice(t.LAYERL);i=i[0]!==i[0].toLowerCase()?this.shift(i,3):this.shift(i,2),r=r[0]!==r[0].toLowerCase()?this.shift(r,3):this.shift(r,2);let a="",n=1;for(let e=0;e<t.LAYERL;e+=3)"B"===i[e]&&(a+=n),"b"===i[e+2]&&(a+=n+1),n+=2;a=""===a?"- ":a+" ",n=1;for(let e=0;e<t.LAYERL;e+=3)"B"===r[e]&&(a+=n),"b"===r[e+2]&&(a+=n+1),n+=2;return" "===a[a.length-1]?a+"-":a}mattToLayer(t){const e=["W","W","w","W","W","w","W","W","w","W","W","w"];for(const i of t){const t=parseInt(i,10);t%2!=0?(e[3*Math.floor(t/2)]="B",e[3*Math.floor(t/2)+1]="B"):e[3*Math.floor(t/2)-1]="b"}return e.join("")}mattToNonSpe(t){const[e,i]=t.split(" ");return this.speToNonSpe(`${this.layerToOBL(this.mattToLayer(e))}/${this.layerToOBL(this.mattToLayer(i))}`)}sortOblp(t){return[...t].sort().join("")}}return t});
|
package/package.json
CHANGED
package/squanlib.js
CHANGED
|
@@ -63,7 +63,6 @@ export default class SquanLib {
|
|
|
63
63
|
"d2": "-1,5", "d2'": "1,-5",
|
|
64
64
|
"K": "5,2", "K'": "-5,-2",
|
|
65
65
|
"k": "2,5", "k'": "-2,-5",
|
|
66
|
-
"A": "1,0", "A'": "-1,0",
|
|
67
66
|
"G": "5,-4", "G'": "-5,4",
|
|
68
67
|
"g": "4,-5", "g'": "-4,5",
|
|
69
68
|
};
|
|
@@ -270,10 +269,10 @@ export default class SquanLib {
|
|
|
270
269
|
* GOOD_FINISHES: moves that are acceptable as the last move
|
|
271
270
|
*/
|
|
272
271
|
static GOOD_FINISHES = new Set([
|
|
273
|
-
"
|
|
274
|
-
"
|
|
275
|
-
"
|
|
276
|
-
"5
|
|
272
|
+
"1,1", "-1,-1", "2,2", "-2,-2", "2,-1", "-2,1", "1,-2", "-1,2",
|
|
273
|
+
"3,0", "-3,0", "0,3", "0,-3", "3,3", "3,-3", "-3,-3", "-3,3",
|
|
274
|
+
"4,1", "-4,-1", "1,4", "-1,-4", "2,-4", "-2,4", "4,-2", "-4,2",
|
|
275
|
+
"5,-1", "-5,1", "-4,5", "-5,4", "6,3",
|
|
277
276
|
]);
|
|
278
277
|
|
|
279
278
|
/**
|
|
@@ -710,14 +709,6 @@ export default class SquanLib {
|
|
|
710
709
|
// overrides
|
|
711
710
|
if (alg in this.tempReplacements) return this.tempReplacements[alg];
|
|
712
711
|
|
|
713
|
-
// p scrambles
|
|
714
|
-
let isPScramble = /^p[ /\\|]/.test(alg);
|
|
715
|
-
let startingSlice;
|
|
716
|
-
if (isPScramble) {
|
|
717
|
-
startingSlice = alg.charAt(1) === " " ? "/" : alg.charAt(1);
|
|
718
|
-
alg = alg.slice(2, -3);
|
|
719
|
-
}
|
|
720
|
-
|
|
721
712
|
// legacy character substitutions
|
|
722
713
|
alg = alg
|
|
723
714
|
.replaceAll('&', '-1')
|
|
@@ -726,6 +717,17 @@ export default class SquanLib {
|
|
|
726
717
|
.replaceAll('8', '-4')
|
|
727
718
|
.replaceAll('7', '-5');
|
|
728
719
|
|
|
720
|
+
// remove potential move counts, comments
|
|
721
|
+
alg = alg.replaceAll(/\[.*?\]/g, "");
|
|
722
|
+
|
|
723
|
+
// p scrambles
|
|
724
|
+
let isPScramble = /^p[ /\\|]/.test(alg);
|
|
725
|
+
let startingSlice;
|
|
726
|
+
if (isPScramble) {
|
|
727
|
+
startingSlice = alg.charAt(1) === " " ? "/" : alg.charAt(1);
|
|
728
|
+
alg = alg.slice(2, -3);
|
|
729
|
+
}
|
|
730
|
+
|
|
729
731
|
// expand move groups, e.g. "(U U')3" → "U U' U U' U U'"
|
|
730
732
|
for (const group of alg.matchAll(/(\(.*?\))(\d+)/g)) {
|
|
731
733
|
const inner = group[1].replaceAll(/[()]/g, '');
|
|
@@ -1371,16 +1373,32 @@ export default class SquanLib {
|
|
|
1371
1373
|
rated = true;
|
|
1372
1374
|
|
|
1373
1375
|
if (rated && ["/", "\\", "|"].includes(sliceStart)) {
|
|
1374
|
-
|
|
1375
|
-
const slashPos = line.indexOf('/');
|
|
1376
|
-
if (slashPos >= 0)
|
|
1377
|
-
result.alg = line.slice(0, slashPos) + sliceStart + line.slice(slashPos + 1);
|
|
1376
|
+
result.alg = this.injectSliceStart(line, sliceStart);
|
|
1378
1377
|
}
|
|
1379
1378
|
|
|
1380
1379
|
return result;
|
|
1381
1380
|
}).sort((a, b) => b.score - a.score);
|
|
1382
1381
|
}
|
|
1383
1382
|
|
|
1383
|
+
/**
|
|
1384
|
+
* injectSliceStart: injects the slice start into an alg
|
|
1385
|
+
*
|
|
1386
|
+
* @param {string} alg the alg. no extra spaces allowed
|
|
1387
|
+
* @param {string} sliceStart " " | "/" | "\\" | "|"
|
|
1388
|
+
* @returns {string} the alg with slice start injected at the first slice
|
|
1389
|
+
*/
|
|
1390
|
+
injectSliceStart(alg, sliceStart) {
|
|
1391
|
+
let moreThan1 = /[/\\| ]/.test(alg); // is there ANY slice chars?
|
|
1392
|
+
let firstMove = moreThan1 ? alg.match(/^([^/\\| ]*)[/\\| ]/)?.[1] : alg;
|
|
1393
|
+
// only tests if it's a karn
|
|
1394
|
+
if (firstMove in SquanLib.karnToWCA) return sliceStart + alg;
|
|
1395
|
+
if (!moreThan1) return alg; // no slice to inject to
|
|
1396
|
+
|
|
1397
|
+
// guaranteed to have a slice
|
|
1398
|
+
const slashPos = alg.search(/[/\\| ]/);
|
|
1399
|
+
return alg.slice(0, slashPos) + sliceStart + alg.slice(slashPos + 1);
|
|
1400
|
+
}
|
|
1401
|
+
|
|
1384
1402
|
// =========================================================================
|
|
1385
1403
|
// SECTION 8: ALG TRANSFORM
|
|
1386
1404
|
// =========================================================================
|
|
@@ -1401,28 +1419,38 @@ export default class SquanLib {
|
|
|
1401
1419
|
/**
|
|
1402
1420
|
* compl: get the complement of a move
|
|
1403
1421
|
*
|
|
1404
|
-
* @param {string} a a move
|
|
1405
|
-
* @returns {string} the complement move
|
|
1406
|
-
* @example "-12" → "5-4"
|
|
1422
|
+
* @param {string} a a move
|
|
1423
|
+
* @returns {string} the complement move with commas
|
|
1424
|
+
* @example "-12" → "5,-4"; "-1,2" → "5,-4"
|
|
1407
1425
|
*/
|
|
1408
1426
|
compl(a) {
|
|
1409
1427
|
if (!a) return a;
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1428
|
+
let u, d;
|
|
1429
|
+
if (a.includes(',')) [u, d] = a.split(",");
|
|
1430
|
+
else {
|
|
1431
|
+
const inx = this.sepIndex(a);
|
|
1432
|
+
[u, d] = [a.slice(0, inx), a.slice(inx)];
|
|
1433
|
+
}
|
|
1434
|
+
return String(this.legalMove(6 + parseInt(u, 10))) + "," +
|
|
1435
|
+
String(this.legalMove(6 + parseInt(d, 10)));
|
|
1413
1436
|
}
|
|
1414
1437
|
|
|
1415
1438
|
/**
|
|
1416
1439
|
* lf: get the layer flip of a move
|
|
1417
1440
|
*
|
|
1418
|
-
* @param {string} a a move
|
|
1441
|
+
* @param {string} a a move
|
|
1419
1442
|
* @returns {string} the layer flip move
|
|
1420
|
-
* @example "-12" → "2-1"
|
|
1443
|
+
* @example "-12" → "2,-1"; "-1,2" → "2,-1"
|
|
1421
1444
|
*/
|
|
1422
1445
|
lf(a) {
|
|
1423
1446
|
if (!a) return a;
|
|
1424
|
-
|
|
1425
|
-
|
|
1447
|
+
let u, d;
|
|
1448
|
+
if (a.includes(',')) [u, d] = a.split(",");
|
|
1449
|
+
else {
|
|
1450
|
+
const inx = this.sepIndex(a);
|
|
1451
|
+
[u, d] = [a.slice(0, inx), a.slice(inx)];
|
|
1452
|
+
}
|
|
1453
|
+
return d + "," + u;
|
|
1426
1454
|
}
|
|
1427
1455
|
|
|
1428
1456
|
/**
|
|
@@ -1435,11 +1463,11 @@ export default class SquanLib {
|
|
|
1435
1463
|
compact(algIn) {
|
|
1436
1464
|
let alg = algIn
|
|
1437
1465
|
.replace(/\[.*?\]/g, "")
|
|
1438
|
-
.replace(/[()]/g, "")
|
|
1439
|
-
.replaceAll(" ", "").trim();
|
|
1466
|
+
.replace(/[()]/g, "").trim();
|
|
1440
1467
|
if (this.isKarn(alg)) {
|
|
1441
1468
|
const numeric = this.unkarnify(alg);
|
|
1442
|
-
return numeric.split("/").
|
|
1469
|
+
return numeric.split("/").map(m => {
|
|
1470
|
+
if (!m) return m;
|
|
1443
1471
|
if (!m.includes(","))
|
|
1444
1472
|
throw new Error(
|
|
1445
1473
|
`algToInternal: m doesn't have commas post karnifying: ${m}`
|
|
@@ -1449,7 +1477,7 @@ export default class SquanLib {
|
|
|
1449
1477
|
String(this.legalMove(parseInt(d, 10)));
|
|
1450
1478
|
}).join(" ");
|
|
1451
1479
|
}
|
|
1452
|
-
alg = alg.
|
|
1480
|
+
alg = alg.replaceAll(" ", "");
|
|
1453
1481
|
if (alg.includes("/")) {
|
|
1454
1482
|
return alg.split("/").filter(Boolean).map(m => {
|
|
1455
1483
|
if (!m.includes(",")) m = this.addCommas(m);
|
|
@@ -1478,7 +1506,8 @@ export default class SquanLib {
|
|
|
1478
1506
|
* @returns {number} how many positions the alg can y2 at
|
|
1479
1507
|
*/
|
|
1480
1508
|
countY2Positions(algIn) {
|
|
1481
|
-
|
|
1509
|
+
// spaces ARE slices, cannot trim or do anything like that
|
|
1510
|
+
const segs = this.compact(algIn).split(" ");
|
|
1482
1511
|
return Math.max(0, segs.length - 3);
|
|
1483
1512
|
}
|
|
1484
1513
|
|
|
@@ -1630,7 +1659,7 @@ export default class SquanLib {
|
|
|
1630
1659
|
isOBLCase(l, target) {
|
|
1631
1660
|
const targetPattern = Object.entries(SquanLib.OBLToEnglish)
|
|
1632
1661
|
.find(([, v]) => v === target
|
|
1633
|
-
|
|
1662
|
+
)?.[0];
|
|
1634
1663
|
if (!targetPattern) return false;
|
|
1635
1664
|
// to corner first
|
|
1636
1665
|
if (l[0] !== l[0].toUpperCase()) l = this.shift(l, -1);
|