cubing 0.63.2 → 0.63.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/dist/bin/chunks/{chunk-52ODPET6.js → chunk-OI3YIXMQ.js} +2 -2
  2. package/dist/bin/order.js +1 -1
  3. package/dist/bin/puzzle-geometry-bin.js +1 -1
  4. package/dist/bin/scramble.js +1 -1
  5. package/dist/lib/cubing/{PuzzleLoader-R-puDLmC.d.ts → PuzzleLoader-Bp8zngUn.d.ts} +10 -0
  6. package/dist/lib/cubing/alg/index.d.ts +2 -2
  7. package/dist/lib/cubing/bluetooth/index.d.ts +2 -2
  8. package/dist/lib/cubing/chunks/chunk-44CFF24P.js +239 -0
  9. package/dist/lib/cubing/chunks/chunk-44CFF24P.js.map +7 -0
  10. package/dist/lib/cubing/chunks/chunk-DQGYYYHZ.js +1180 -0
  11. package/dist/lib/cubing/chunks/chunk-DQGYYYHZ.js.map +7 -0
  12. package/dist/lib/cubing/chunks/chunk-FTE3QI5X.js +1074 -0
  13. package/dist/lib/cubing/chunks/chunk-FTE3QI5X.js.map +7 -0
  14. package/dist/lib/cubing/chunks/chunk-FZBKZ5ZB.js +265 -0
  15. package/dist/lib/cubing/chunks/chunk-FZBKZ5ZB.js.map +7 -0
  16. package/dist/lib/cubing/chunks/chunk-OUM32GEA.js +239 -0
  17. package/dist/lib/cubing/chunks/chunk-OUM32GEA.js.map +7 -0
  18. package/dist/lib/cubing/chunks/chunk-SGJ5WPE4.js +1074 -0
  19. package/dist/lib/cubing/chunks/chunk-SGJ5WPE4.js.map +7 -0
  20. package/dist/lib/cubing/chunks/chunk-TAVR35KU.js +265 -0
  21. package/dist/lib/cubing/chunks/chunk-TAVR35KU.js.map +7 -0
  22. package/dist/lib/cubing/chunks/chunk-VRTKWZPL.js +10084 -0
  23. package/dist/lib/cubing/chunks/chunk-VRTKWZPL.js.map +7 -0
  24. package/dist/lib/cubing/chunks/chunk-VSMFYTG6.js +10086 -0
  25. package/dist/lib/cubing/chunks/chunk-VSMFYTG6.js.map +7 -0
  26. package/dist/lib/cubing/chunks/inside-IHWQVDVU.js +564 -0
  27. package/dist/lib/cubing/chunks/inside-IHWQVDVU.js.map +7 -0
  28. package/dist/lib/cubing/chunks/inside-L2JI2BEY.js +564 -0
  29. package/dist/lib/cubing/chunks/inside-L2JI2BEY.js.map +7 -0
  30. package/dist/lib/cubing/chunks/search-dynamic-sgs-side-events-MXHP7O4R.js +1890 -0
  31. package/dist/lib/cubing/chunks/search-dynamic-sgs-side-events-MXHP7O4R.js.map +7 -0
  32. package/dist/lib/cubing/chunks/search-dynamic-sgs-side-events-XFECDWOF.js +1890 -0
  33. package/dist/lib/cubing/chunks/search-dynamic-sgs-side-events-XFECDWOF.js.map +7 -0
  34. package/dist/lib/cubing/chunks/search-dynamic-sgs-unofficial-CM33KT7L.js +1267 -0
  35. package/dist/lib/cubing/chunks/search-dynamic-sgs-unofficial-CM33KT7L.js.map +7 -0
  36. package/dist/lib/cubing/chunks/search-dynamic-sgs-unofficial-Q4LLHL2O.js +1267 -0
  37. package/dist/lib/cubing/chunks/search-dynamic-sgs-unofficial-Q4LLHL2O.js.map +7 -0
  38. package/dist/lib/cubing/chunks/search-dynamic-solve-4x4x4-COSEVJBV.js +2922 -0
  39. package/dist/lib/cubing/chunks/search-dynamic-solve-4x4x4-COSEVJBV.js.map +7 -0
  40. package/dist/lib/cubing/chunks/search-dynamic-solve-4x4x4-NANDMURR.js +2922 -0
  41. package/dist/lib/cubing/chunks/search-dynamic-solve-4x4x4-NANDMURR.js.map +7 -0
  42. package/dist/lib/cubing/chunks/twisty-dynamic-3d-5NZRNZ7C.js +1881 -0
  43. package/dist/lib/cubing/chunks/twisty-dynamic-3d-5NZRNZ7C.js.map +7 -0
  44. package/dist/lib/cubing/chunks/twisty-dynamic-3d-VGZIQ64W.js +1927 -0
  45. package/dist/lib/cubing/chunks/twisty-dynamic-3d-VGZIQ64W.js.map +7 -0
  46. package/dist/lib/cubing/chunks/twisty-dynamic-3d-XLUOPCLN.js +1881 -0
  47. package/dist/lib/cubing/chunks/twisty-dynamic-3d-XLUOPCLN.js.map +7 -0
  48. package/dist/lib/cubing/{events-IfSwQLYm.d.ts → events-CewDA1aS.d.ts} +1 -1
  49. package/dist/lib/cubing/{index-btIxbuNp.d.ts → index-DabjED-w.d.ts} +1 -1
  50. package/dist/lib/cubing/kpuzzle/index.d.ts +1 -1
  51. package/dist/lib/cubing/notation/index.d.ts +1 -1
  52. package/dist/lib/cubing/protocol/index.d.ts +1 -1
  53. package/dist/lib/cubing/puzzle-geometry/index.d.ts +2 -2
  54. package/dist/lib/cubing/puzzles/index.d.ts +1 -1
  55. package/dist/lib/cubing/scramble/index.d.ts +2 -2
  56. package/dist/lib/cubing/search/index.d.ts +3 -3
  57. package/dist/lib/cubing/stream/index.d.ts +3 -3
  58. package/dist/lib/cubing/twisty/index.d.ts +2 -2
  59. package/dist/lib/cubing/twisty/index.js +37 -4
  60. package/dist/lib/cubing/twisty/index.js.map +3 -3
  61. package/package.json +1 -1
  62. /package/dist/bin/chunks/{chunk-52ODPET6.js.map → chunk-OI3YIXMQ.js.map} +0 -0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../../../src/cubing/twisty/controllers/indexer/AlgDuration.ts", "../../../../src/cubing/twisty/controllers/indexer/SimpleAlgIndexer.ts", "../../../../src/cubing/twisty/controllers/indexer/tree/AlgWalker.ts", "../../../../src/cubing/twisty/controllers/indexer/tree/chunkAlgs.ts", "../../../../src/cubing/twisty/controllers/indexer/tree/TreeAlgIndexer.ts", "../../../../src/cubing/twisty/model/props/viewer/BackViewProp.ts", "../../../../src/cubing/twisty/views/2D/TwistyAnimatedSVG.ts", "../../../../src/cubing/twisty/views/ClassListManager.ts", "../../../../src/cubing/twisty/model/helpers.ts", "../../../../src/cubing/twisty/controllers/AnimationTypes.ts", "../../../../src/cubing/twisty/controllers/TwistyAnimationController.ts", "../../../../src/cubing/twisty/controllers/TwistyPlayerController.ts", "../../../../src/cubing/twisty/model/props/viewer/ControlPanelProp.ts", "../../../../src/cubing/twisty/views/TwistyViewerWrapper.css.ts", "../../../../src/cubing/twisty/views/2D/Twisty2DPuzzle.css.ts", "../../../../src/cubing/twisty/views/2D/Twisty2DPuzzle.ts", "../../../../src/cubing/twisty/views/2D/Twisty2DPuzzleWrapper.ts", "../../../../src/cubing/twisty/views/2D/Twisty2DSceneWrapper.ts", "../../../../src/cubing/twisty/views/InitialValueTracker.ts", "../../../../src/cubing/twisty/views/3D/Twisty3DPuzzleWrapper.ts", "../../../../src/cubing/twisty/views/3D/Twisty3DSceneWrapper.ts", "../../../../src/cubing/twisty/views/document.ts", "../../../../src/cubing/twisty/views/control-panel/webkit-fullscreen.ts", "../../../../src/cubing/twisty/model/props/viewer/ButtonAppearanceProp.ts", "../../../../src/cubing/twisty/views/control-panel/TwistyButtons.css.ts", "../../../../src/cubing/twisty/views/control-panel/TwistyButtons.ts", "../../../../src/cubing/twisty/views/control-panel/TwistyScrubber.css.ts", "../../../../src/cubing/twisty/views/control-panel/TwistyScrubber.ts", "../../../../src/cubing/twisty/views/screenshot.ts", "../../../../src/cubing/twisty/views/TwistyPlayer.css.ts", "../../../../src/cubing/twisty/model/props/general/ArbitraryStringProp.ts", "../../../../src/cubing/twisty/model/props/general/URLProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/AlgProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/AlgTransformationProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/AnchorTransformationProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/AnimationTimelineLeavesRequestProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/CatchUpMoveProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/CurrentLeavesSimplified.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/CurrentMoveInfoProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/CurrentPatternProp.ts", "../../../../src/cubing/twisty/controllers/indexer/simultaneous-moves/simul-moves.ts", "../../../../src/cubing/twisty/controllers/indexer/simultaneous-moves/SimultaneousMoveIndexer.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/IndexerConstructorProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/IndexerConstructorRequestProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/IndexerProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/LegacyPositionProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/PuzzleAlgProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/SetupAnchorProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/SetupTransformationProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/structure/KPuzzleProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/structure/PuzzleDescriptionProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/structure/PuzzleIDProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/structure/PuzzleIDRequestProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/structure/PuzzleLoaderProp.ts", "../../../../src/cubing/twisty/model/props/timeline/CoarseTimelineInfoProp.ts", "../../../../src/cubing/twisty/model/props/timeline/DetailedTimelineInfoProp.ts", "../../../../src/cubing/twisty/model/props/timeline/PlayingInfoProp.ts", "../../../../src/cubing/twisty/model/props/timeline/TempoScaleProp.ts", "../../../../src/cubing/twisty/model/props/timeline/TimestampRequestProp.ts", "../../../../src/cubing/twisty/model/props/viewer/TimeRangeProp.ts", "../../../../src/cubing/twisty/model/props/viewer/ViewerLinkProp.ts", "../../../../src/cubing/twisty/model/props/viewer/VisualizationProp.ts", "../../../../src/cubing/twisty/model/props/viewer/VisualizationStrategyProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/display/FaceletScaleProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/display/FoundationDisplayProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/display/InitialHintFaceletsAnimationProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/display/SpriteProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/display/StickeringMaskProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/display/parseSerializedStickeringMask.ts", "../../../../src/cubing/twisty/model/props/puzzle/display/StickeringMaskRequestProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/display/StickeringRequestProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/DragInputProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/MovePressCancelOptions.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/MovePressInputProp.ts", "../../../../src/cubing/twisty/model/props/viewer/BackgroundProp.ts", "../../../../src/cubing/twisty/model/props/viewer/ColorSchemeProp.ts", "../../../../src/cubing/twisty/model/props/viewer/ColorSchemeRequestProp.ts", "../../../../src/cubing/twisty/model/props/viewer/DOMElementReferenceProp.ts", "../../../../src/cubing/twisty/model/props/viewer/LatitudeLimit.ts", "../../../../src/cubing/twisty/model/props/viewer/OrbitCoordinatesRequestProp.ts", "../../../../src/cubing/twisty/model/props/viewer/OrbitCoordinatesProp.ts", "../../../../src/cubing/twisty/model/TwistySceneModel.ts", "../../../../src/cubing/twisty/model/UserVisibleErrorTracker.ts", "../../../../src/cubing/twisty/model/TwistyPlayerModel.ts", "../../../../src/cubing/twisty/views/TwistyPlayerSettable.ts", "../../../../src/cubing/twisty/views/TwistyPlayer.ts", "../../../../src/cubing/twisty/views/TwistyAlgEditor/LeafTokens.ts", "../../../../src/cubing/twisty/views/TwistyAlgEditor/model.ts", "../../../../src/cubing/twisty/views/TwistyAlgEditor/paste.ts", "../../../../src/cubing/twisty/views/TwistyAlgEditor/TwistyAlgEditor.css.ts", "../../../../src/cubing/twisty/views/TwistyAlgEditor/TwistyAlgEditor.ts", "../../../../src/cubing/twisty/views/firstElementWithId.ts", "../../../../src/cubing/twisty/views/TwistyAlgViewer.css.ts", "../../../../src/cubing/twisty/views/TwistyAlgViewer.ts", "../../../../src/cubing/twisty/views/twizzle/TwizzleLink.css.ts", "../../../../src/cubing/twisty/views/twizzle/url-params.ts", "../../../../src/cubing/twisty/views/twizzle/TwizzleLink.ts"],
4
- "sourcesContent": ["import {\n type Alg,\n type Commutator,\n type Conjugate,\n type Grouping,\n type LineComment,\n type Move,\n type Newline,\n type Pause,\n TraversalUp,\n} from \"../../../alg\";\nimport type { MillisecondDuration } from \"../AnimationTypes\";\n\nexport function constantDurationForAmount(\n _amount: number,\n): MillisecondDuration {\n return 1000 as MillisecondDuration;\n}\n\nexport function defaultDurationForAmount(amount: number): MillisecondDuration {\n switch (Math.abs(amount)) {\n case 0:\n return 0 as MillisecondDuration;\n case 1:\n return 1000 as MillisecondDuration;\n case 2:\n return 1500 as MillisecondDuration;\n default:\n return 2000 as MillisecondDuration;\n }\n}\nexport function ExperimentalScaledDefaultDurationForAmount(\n scale: number,\n amount: number,\n): MillisecondDuration {\n switch (Math.abs(amount)) {\n case 0:\n return 0 as MillisecondDuration;\n case 1:\n return (scale * 1000) as MillisecondDuration;\n case 2:\n return (scale * 1500) as MillisecondDuration;\n default:\n return (scale * 2000) as MillisecondDuration;\n }\n}\n\nexport class AlgDuration extends TraversalUp<MillisecondDuration> {\n // TODO: Pass durationForAmount as Down type instead?\n constructor(\n public durationForAmount: (\n amount: number,\n ) => MillisecondDuration = defaultDurationForAmount,\n ) {\n super();\n }\n\n public traverseAlg(alg: Alg): MillisecondDuration {\n let total = 0;\n for (const algNode of alg.childAlgNodes()) {\n total += this.traverseAlgNode(algNode);\n }\n return total as MillisecondDuration;\n }\n\n public traverseGrouping(grouping: Grouping): MillisecondDuration {\n return (grouping.amount *\n this.traverseAlg(grouping.alg)) as MillisecondDuration;\n }\n\n public traverseMove(move: Move): MillisecondDuration {\n return this.durationForAmount(move.amount);\n }\n\n public traverseCommutator(commutator: Commutator): MillisecondDuration {\n return (2 *\n (this.traverseAlg(commutator.A) +\n this.traverseAlg(commutator.B))) as MillisecondDuration;\n }\n\n public traverseConjugate(conjugate: Conjugate): MillisecondDuration {\n return (2 * this.traverseAlg(conjugate.A) +\n this.traverseAlg(conjugate.B)) as MillisecondDuration;\n }\n\n public traversePause(_pause: Pause): MillisecondDuration {\n return this.durationForAmount(1);\n }\n\n public traverseNewline(_newline: Newline): MillisecondDuration {\n return this.durationForAmount(1);\n }\n\n public traverseLineComment(_comment: LineComment): MillisecondDuration {\n return this.durationForAmount(0);\n }\n}\n", "import { Alg, type Move, type TraversalUp } from \"../../../alg\";\nimport type { KPuzzle, KTransformation } from \"../../../kpuzzle\";\nimport type { KPattern } from \"../../../kpuzzle/KPattern\";\nimport { experimentalCountAnimatedLeaves } from \"../../../notation\";\nimport type {\n MillisecondDuration,\n MillisecondTimestamp,\n} from \"../AnimationTypes\";\nimport { AlgDuration, defaultDurationForAmount } from \"./AlgDuration\";\nimport type { AlgIndexer, LeafCount, LeafIndex } from \"./AlgIndexer\";\n\nexport class SimpleAlgIndexer implements AlgIndexer {\n private moves: Alg;\n // TODO: Allow custom `durationFn`.\n private durationFn: TraversalUp<MillisecondDuration> = new AlgDuration(\n defaultDurationForAmount,\n );\n\n constructor(\n private kpuzzle: KPuzzle,\n alg: Alg,\n ) {\n // TODO: Avoid assuming all base moves are block moves.\n this.moves = new Alg(alg.experimentalExpand());\n }\n\n public getAnimLeaf(index: number): Move {\n return Array.from(this.moves.childAlgNodes())[index] as Move; // TODO: perf\n }\n\n public indexToMoveStartTimestamp(index: number): MillisecondTimestamp {\n const alg = new Alg(Array.from(this.moves.childAlgNodes()).slice(0, index)); // TODO\n return this.durationFn.traverseAlg(alg) as number as MillisecondTimestamp;\n }\n\n public timestampToIndex(timestamp: MillisecondTimestamp): LeafIndex {\n let cumulativeTime = 0;\n let i: number;\n for (i = 0; i < this.numAnimatedLeaves(); i++) {\n cumulativeTime += this.durationFn.traverseMove(this.getAnimLeaf(i));\n if (cumulativeTime >= timestamp) {\n return i as LeafIndex;\n }\n }\n return i as LeafIndex;\n }\n\n public patternAtIndex(index: number): KPattern {\n return this.kpuzzle\n .defaultPattern()\n .applyTransformation(this.transformationAtIndex(index));\n }\n\n public transformationAtIndex(index: number): KTransformation {\n let pattern = this.kpuzzle.identityTransformation();\n for (const move of Array.from(this.moves.childAlgNodes()).slice(0, index)) {\n // TODO\n pattern = pattern.applyMove(move as Move);\n }\n return pattern;\n }\n\n public algDuration(): MillisecondDuration {\n return this.durationFn.traverseAlg(this.moves);\n }\n\n public numAnimatedLeaves(): LeafCount {\n // TODO: Cache internally once performance matters.\n return experimentalCountAnimatedLeaves(this.moves) as LeafCount;\n }\n\n public moveDuration(index: LeafIndex): MillisecondDuration {\n return this.durationFn.traverseMove(this.getAnimLeaf(index));\n }\n}\n", "import {\n Alg,\n type AlgNode,\n type Commutator,\n type Conjugate,\n type Grouping,\n type LineComment,\n type Move,\n type Newline,\n type Pause,\n TraversalDownUp,\n TraversalUp,\n} from \"../../../../alg\";\nimport {\n ExperimentalIterationDirection,\n experimentalDirectedGenerator,\n} from \"../../../../alg/cubing-private\";\nimport type { KPuzzle, KTransformation } from \"../../../../kpuzzle\";\nimport type { MillisecondDuration } from \"../../AnimationTypes\";\nimport { AlgDuration, defaultDurationForAmount } from \"../AlgDuration\";\nimport type { LeafIndex as LeafCount } from \"../AlgIndexer\";\n\nexport class AlgWalkerDecoration {\n constructor(\n public moveCount: LeafCount,\n public duration: MillisecondDuration,\n public forward: KTransformation,\n public backward: KTransformation,\n public children: AlgWalkerDecoration[] = [],\n ) {}\n}\nexport class DecoratorConstructor extends TraversalUp<AlgWalkerDecoration> {\n private identity: KTransformation;\n private dummyLeaf: AlgWalkerDecoration;\n private durationFn: TraversalUp<MillisecondDuration> = new AlgDuration(\n defaultDurationForAmount,\n );\n\n private cache: { [key: string]: AlgWalkerDecoration } = {};\n\n constructor(private kpuzzle: KPuzzle) {\n super();\n this.identity = kpuzzle.identityTransformation();\n this.dummyLeaf = new AlgWalkerDecoration(\n 0 as LeafCount,\n 0 as MillisecondDuration,\n this.identity,\n this.identity,\n [],\n );\n }\n\n public traverseAlg(alg: Alg): AlgWalkerDecoration {\n let moveCount = 0 as LeafCount;\n let duration = 0 as MillisecondDuration;\n let transformation = this.identity;\n const child: AlgWalkerDecoration[] = [];\n for (const algNode of alg.childAlgNodes()) {\n const apd = this.traverseAlgNode(algNode);\n /** @ts-expect-error: ts(2322) Rewriting this would required duplicating `moveCount`. */\n moveCount += apd.moveCount;\n /** @ts-expect-error: ts(2322) Rewriting this would required duplicating `duration`. */\n duration += apd.duration;\n if (transformation === this.identity) {\n transformation = apd.forward;\n } else {\n transformation = transformation.applyTransformation(apd.forward);\n }\n child.push(apd);\n }\n return new AlgWalkerDecoration(\n moveCount,\n duration,\n transformation,\n transformation.invert(),\n child,\n );\n }\n\n public traverseGrouping(grouping: Grouping): AlgWalkerDecoration {\n const dec = this.traverseAlg(grouping.alg);\n return this.mult(dec, grouping.amount, [dec]);\n }\n\n public traverseMove(move: Move): AlgWalkerDecoration {\n const key = move.toString();\n let r: AlgWalkerDecoration | undefined = this.cache[key];\n if (r) {\n return r;\n }\n const transformation = this.kpuzzle.moveToTransformation(move);\n r = new AlgWalkerDecoration(\n 1 as LeafCount,\n this.durationFn.traverseAlgNode(move),\n transformation,\n transformation.invert(),\n );\n this.cache[key] = r;\n return r;\n }\n\n public traverseCommutator(commutator: Commutator): AlgWalkerDecoration {\n const decA = this.traverseAlg(commutator.A);\n const decB = this.traverseAlg(commutator.B);\n const AB = decA.forward.applyTransformation(decB.forward);\n const ApBp = decA.backward.applyTransformation(decB.backward);\n const ABApBp = AB.applyTransformation(ApBp);\n const dec = new AlgWalkerDecoration(\n (2 * (decA.moveCount + decB.moveCount)) as LeafCount,\n (2 * (decA.duration + decB.duration)) as MillisecondDuration,\n ABApBp,\n ABApBp.invert(),\n [decA, decB],\n );\n return this.mult(dec, 1, [dec, decA, decB]);\n }\n\n public traverseConjugate(conjugate: Conjugate): AlgWalkerDecoration {\n const decA = this.traverseAlg(conjugate.A);\n const decB = this.traverseAlg(conjugate.B);\n const AB = decA.forward.applyTransformation(decB.forward);\n const ABAp = AB.applyTransformation(decA.backward);\n const dec = new AlgWalkerDecoration(\n (2 * decA.moveCount + decB.moveCount) as LeafCount,\n (2 * decA.duration + decB.duration) as MillisecondDuration,\n ABAp,\n ABAp.invert(),\n [decA, decB],\n );\n return this.mult(dec, 1, [dec, decA, decB]);\n }\n\n public traversePause(pause: Pause): AlgWalkerDecoration {\n if (pause.experimentalNISSGrouping) {\n return this.dummyLeaf;\n }\n return new AlgWalkerDecoration(\n 1 as LeafCount,\n this.durationFn.traverseAlgNode(pause),\n this.identity,\n this.identity,\n );\n }\n\n public traverseNewline(_newline: Newline): AlgWalkerDecoration {\n return this.dummyLeaf;\n }\n\n public traverseLineComment(_comment: LineComment): AlgWalkerDecoration {\n return this.dummyLeaf;\n }\n\n private mult(\n apd: AlgWalkerDecoration,\n n: number,\n child: AlgWalkerDecoration[],\n ): AlgWalkerDecoration {\n const absn = Math.abs(n);\n const st = apd.forward.selfMultiply(n);\n return new AlgWalkerDecoration(\n (apd.moveCount * absn) as LeafCount,\n (apd.duration * absn) as MillisecondDuration,\n st,\n st.invert(),\n child,\n );\n }\n}\nclass WalkerDown {\n constructor(\n public apd: AlgWalkerDecoration,\n public back: boolean,\n ) {\n /**/\n }\n}\nexport class AlgWalker extends TraversalDownUp<WalkerDown, boolean> {\n public move?: AlgNode;\n public moveDuration: MillisecondDuration;\n public back: boolean;\n public st: KTransformation;\n public root: WalkerDown;\n public i: LeafCount;\n public dur: MillisecondDuration;\n private goalIndex: LeafCount;\n private goalDuration: MillisecondDuration;\n constructor(\n public kpuzzle: KPuzzle,\n public algOrAlgNode: Alg | AlgNode, // TODO: can we keep these separate?\n public apd: AlgWalkerDecoration,\n ) {\n super();\n this.i = -1 as LeafCount;\n this.dur = -1 as MillisecondDuration;\n this.goalIndex = -1 as LeafCount;\n this.goalDuration = -1 as MillisecondDuration;\n this.move = undefined;\n this.back = false;\n this.moveDuration = 0 as MillisecondDuration;\n this.st = this.kpuzzle.identityTransformation();\n this.root = new WalkerDown(this.apd, false);\n }\n\n public moveByIndex(loc: LeafCount): boolean {\n if (this.i >= 0 && this.i === loc) {\n return this.move !== undefined;\n }\n return this.dosearch(loc, Infinity as MillisecondDuration);\n }\n\n public moveByDuration(dur: MillisecondDuration): boolean {\n if (\n this.dur >= 0 &&\n this.dur < dur &&\n this.dur + this.moveDuration >= dur\n ) {\n return this.move !== undefined;\n }\n return this.dosearch(Infinity as LeafCount, dur);\n }\n\n public dosearch(loc: LeafCount, dur: MillisecondDuration): boolean {\n this.goalIndex = loc;\n this.goalDuration = dur;\n this.i = 0 as LeafCount;\n this.dur = 0 as MillisecondDuration;\n this.move = undefined;\n this.moveDuration = 0 as MillisecondDuration;\n this.back = false;\n this.st = this.kpuzzle.identityTransformation();\n const r = this.algOrAlgNode.is(Alg)\n ? this.traverseAlg(this.algOrAlgNode as Alg, this.root)\n : this.traverseAlgNode(this.algOrAlgNode as AlgNode, this.root); // TODO\n return r;\n }\n\n public traverseAlg(alg: Alg, wd: WalkerDown): boolean {\n if (!this.firstcheck(wd)) {\n return false;\n }\n let i = wd.back ? alg.experimentalNumChildAlgNodes() - 1 : 0;\n for (const algNode of experimentalDirectedGenerator(\n alg.childAlgNodes(),\n wd.back\n ? ExperimentalIterationDirection.Backwards\n : ExperimentalIterationDirection.Forwards,\n )) {\n if (\n this.traverseAlgNode(\n algNode,\n new WalkerDown(wd.apd.children[i], wd.back),\n )\n ) {\n return true;\n }\n i += wd.back ? -1 : 1;\n }\n return false;\n }\n\n public traverseGrouping(grouping: Grouping, wd: WalkerDown): boolean {\n if (!this.firstcheck(wd)) {\n return false;\n }\n const back = this.domult(wd, grouping.amount);\n return this.traverseAlg(\n grouping.alg,\n new WalkerDown(wd.apd.children[0], back),\n );\n }\n\n public traverseMove(move: Move, wd: WalkerDown): boolean {\n if (!this.firstcheck(wd)) {\n return false;\n }\n this.move = move;\n this.moveDuration = wd.apd.duration;\n this.back = wd.back;\n return true;\n }\n\n public traverseCommutator(commutator: Commutator, wd: WalkerDown): boolean {\n if (!this.firstcheck(wd)) {\n return false;\n }\n const back = this.domult(wd, 1);\n if (back) {\n return (\n this.traverseAlg(\n commutator.B,\n new WalkerDown(wd.apd.children[2], !back),\n ) ||\n this.traverseAlg(\n commutator.A,\n new WalkerDown(wd.apd.children[1], !back),\n ) ||\n this.traverseAlg(\n commutator.B,\n new WalkerDown(wd.apd.children[2], back),\n ) ||\n this.traverseAlg(commutator.A, new WalkerDown(wd.apd.children[1], back))\n );\n } else {\n return (\n this.traverseAlg(\n commutator.A,\n new WalkerDown(wd.apd.children[1], back),\n ) ||\n this.traverseAlg(\n commutator.B,\n new WalkerDown(wd.apd.children[2], back),\n ) ||\n this.traverseAlg(\n commutator.A,\n new WalkerDown(wd.apd.children[1], !back),\n ) ||\n this.traverseAlg(\n commutator.B,\n new WalkerDown(wd.apd.children[2], !back),\n )\n );\n }\n }\n\n public traverseConjugate(conjugate: Conjugate, wd: WalkerDown): boolean {\n if (!this.firstcheck(wd)) {\n return false;\n }\n const back = this.domult(wd, 1);\n if (back) {\n return (\n this.traverseAlg(\n conjugate.A,\n new WalkerDown(wd.apd.children[1], !back),\n ) ||\n this.traverseAlg(\n conjugate.B,\n new WalkerDown(wd.apd.children[2], back),\n ) ||\n this.traverseAlg(conjugate.A, new WalkerDown(wd.apd.children[1], back))\n );\n } else {\n return (\n this.traverseAlg(\n conjugate.A,\n new WalkerDown(wd.apd.children[1], back),\n ) ||\n this.traverseAlg(\n conjugate.B,\n new WalkerDown(wd.apd.children[2], back),\n ) ||\n this.traverseAlg(conjugate.A, new WalkerDown(wd.apd.children[1], !back))\n );\n }\n }\n\n public traversePause(pause: Pause, wd: WalkerDown): boolean {\n if (!this.firstcheck(wd)) {\n return false;\n }\n this.move = pause;\n this.moveDuration = wd.apd.duration;\n this.back = wd.back;\n return true;\n }\n\n public traverseNewline(_newline: Newline, _wd: WalkerDown): boolean {\n return false;\n }\n\n public traverseLineComment(\n _lineComment: LineComment,\n _wd: WalkerDown,\n ): boolean {\n return false;\n }\n\n private firstcheck(wd: WalkerDown): boolean {\n if (\n wd.apd.moveCount + this.i <= this.goalIndex &&\n wd.apd.duration + this.dur < this.goalDuration\n ) {\n return this.keepgoing(wd);\n }\n return true;\n }\n\n private domult(wd: WalkerDown, amount: number): boolean {\n let back = wd.back;\n if (amount === 0) {\n // I don't believe this will ever happen\n return back;\n }\n if (amount < 0) {\n back = !back;\n amount = -amount;\n }\n const base = wd.apd.children[0];\n const full = Math.min(\n Math.floor((this.goalIndex - this.i) / base.moveCount),\n Math.ceil((this.goalDuration - this.dur) / base.duration - 1),\n );\n if (full > 0) {\n this.keepgoing(new WalkerDown(base, back), full);\n }\n return back;\n }\n\n private keepgoing(wd: WalkerDown, mul: number = 1): boolean {\n /** @ts-expect-error: ts(2322) Rewriting this would required duplicating `this.i`. */\n this.i += (mul * wd.apd.moveCount) as LeafCount;\n /** @ts-expect-error: ts(2322) Rewriting this would required duplicating `this.dur`. */\n this.dur += (mul * wd.apd.duration) as MillisecondDuration;\n if (mul !== 1) {\n if (wd.back) {\n this.st = this.st.applyTransformation(\n wd.apd.backward.selfMultiply(mul),\n );\n } else {\n this.st = this.st.applyTransformation(wd.apd.forward.selfMultiply(mul));\n }\n } else {\n if (wd.back) {\n this.st = this.st.applyTransformation(wd.apd.backward);\n } else {\n this.st = this.st.applyTransformation(wd.apd.forward);\n }\n }\n return false;\n }\n}\n", "import {\n type Alg,\n AlgBuilder,\n type AlgNode,\n type Commutator,\n Conjugate,\n functionFromTraversal,\n Grouping,\n type LineComment,\n type Move,\n type Newline,\n type Pause,\n TraversalUp,\n} from \"../../../../alg\";\n\nconst MIN_CHUNKING_THRESHOLD = 16;\n\nfunction chunkifyAlg(alg: Alg, chunkMaxLength: number): Alg {\n const mainAlgBuilder = new AlgBuilder();\n const chunkAlgBuilder = new AlgBuilder();\n for (const algNode of alg.childAlgNodes()) {\n chunkAlgBuilder.push(algNode);\n if (chunkAlgBuilder.experimentalNumAlgNodes() >= chunkMaxLength) {\n mainAlgBuilder.push(new Grouping(chunkAlgBuilder.toAlg()));\n chunkAlgBuilder.reset();\n }\n }\n mainAlgBuilder.push(new Grouping(chunkAlgBuilder.toAlg()));\n return mainAlgBuilder.toAlg();\n}\n\nclass ChunkAlgs extends TraversalUp<Alg, AlgNode> {\n traverseAlg(alg: Alg): Alg {\n const algLength = alg.experimentalNumChildAlgNodes();\n if (algLength < MIN_CHUNKING_THRESHOLD) {\n return alg;\n }\n return chunkifyAlg(alg, Math.ceil(Math.sqrt(algLength)));\n }\n\n traverseGrouping(grouping: Grouping): AlgNode {\n return new Grouping(\n this.traverseAlg(grouping.alg),\n grouping.amount, // TODO\n );\n }\n\n traverseMove(move: Move): AlgNode {\n return move;\n }\n\n traverseCommutator(commutator: Commutator): AlgNode {\n return new Conjugate(\n this.traverseAlg(commutator.A),\n this.traverseAlg(commutator.B),\n );\n }\n\n traverseConjugate(conjugate: Conjugate): AlgNode {\n return new Conjugate(\n this.traverseAlg(conjugate.A),\n this.traverseAlg(conjugate.B),\n );\n }\n\n traversePause(pause: Pause): AlgNode {\n return pause;\n }\n\n traverseNewline(newline: Newline): AlgNode {\n return newline;\n }\n\n traverseLineComment(comment: LineComment): AlgNode {\n return comment;\n }\n}\n\nexport const chunkAlgs = functionFromTraversal(ChunkAlgs);\n", "import type { Alg, Move } from \"../../../../alg\";\nimport type { KPuzzle, KTransformation } from \"../../../../kpuzzle\";\nimport type { KPattern } from \"../../../../kpuzzle/KPattern\";\nimport type {\n MillisecondDuration,\n MillisecondTimestamp,\n} from \"../../AnimationTypes\";\nimport type { AlgIndexer, LeafCount, LeafIndex } from \"../AlgIndexer\";\nimport {\n AlgWalker,\n type AlgWalkerDecoration,\n DecoratorConstructor,\n} from \"./AlgWalker\";\nimport { chunkAlgs } from \"./chunkAlgs\";\n\nexport class TreeAlgIndexer implements AlgIndexer {\n private decoration: AlgWalkerDecoration;\n private walker: AlgWalker;\n constructor(\n private kpuzzle: KPuzzle,\n alg: Alg,\n ) {\n const deccon = new DecoratorConstructor(this.kpuzzle);\n\n const chunkedAlg = chunkAlgs(alg);\n\n this.decoration = deccon.traverseAlg(chunkedAlg);\n this.walker = new AlgWalker(this.kpuzzle, chunkedAlg, this.decoration);\n }\n\n public getAnimLeaf(index: LeafIndex): Move | null {\n // FIXME need to support Pause\n if (this.walker.moveByIndex(index)) {\n if (!this.walker.move) {\n throw new Error(\"`this.walker.mv` missing\");\n }\n const move = this.walker.move as Move;\n // TODO: this type of negation needs to be in alg\n if (this.walker.back) {\n return move.invert();\n }\n return move;\n }\n return null;\n }\n\n public indexToMoveStartTimestamp(index: LeafIndex): MillisecondTimestamp {\n if (this.walker.moveByIndex(index) || this.walker.i === index) {\n return this.walker.dur as number as MillisecondTimestamp; // TODO\n }\n throw new Error(`Out of algorithm: index ${index}`);\n }\n\n public indexToMovesInProgress(index: LeafIndex): MillisecondTimestamp {\n if (this.walker.moveByIndex(index) || this.walker.i === index) {\n return this.walker.dur as number as MillisecondTimestamp; // TODO\n }\n throw new Error(`Out of algorithm: index ${index}`);\n }\n\n public patternAtIndex(index: LeafIndex, startPattern?: KPattern): KPattern {\n this.walker.moveByIndex(index);\n return (startPattern ?? this.kpuzzle.defaultPattern()).applyTransformation(\n this.walker.st,\n );\n }\n\n // TransformAtIndex does not reflect the start pattern; it only reflects\n // the change from the start pattern to the current move index. If you\n // want the actual pattern, use patternAtIndex.\n public transformationAtIndex(index: LeafIndex): KTransformation {\n this.walker.moveByIndex(index);\n return this.walker.st;\n }\n\n public numAnimatedLeaves(): LeafCount {\n return this.decoration.moveCount as number as LeafCount; // TODO: This should not need any casting?\n }\n\n public timestampToIndex(timestamp: MillisecondTimestamp): LeafIndex {\n this.walker.moveByDuration(timestamp as number as MillisecondDuration); // TODO\n return this.walker.i;\n }\n\n public algDuration(): MillisecondDuration {\n return this.decoration.duration;\n }\n\n public moveDuration(index: LeafIndex): MillisecondDuration {\n this.walker.moveByIndex(index);\n return this.walker.moveDuration;\n }\n}\n", "import { SimpleTwistyPropSource } from \"../TwistyProp\";\n\nexport const backViewLayouts = {\n none: true, // default\n \"side-by-side\": true,\n \"top-right\": true,\n};\nexport type BackViewLayout = keyof typeof backViewLayouts;\n\nexport type BackViewLayoutWithAuto = BackViewLayout | \"auto\";\n\nexport class BackViewProp extends SimpleTwistyPropSource<BackViewLayoutWithAuto> {\n getDefaultValue(): BackViewLayoutWithAuto {\n return \"auto\";\n }\n}\n", "import type { KPuzzle } from \"../../../kpuzzle\";\nimport type { KPattern } from \"../../../kpuzzle/KPattern\";\nimport type {\n FaceletMeshStickeringMask,\n StickeringMask,\n} from \"../../../puzzles/stickerings/mask\"; // TODO\n\nconst xmlns = \"http://www.w3.org/2000/svg\";\nconst DATA_COPY_ID_ATTRIBUTE = \"data-copy-id\";\n\n// Unique ID mechanism to keep SVG gradient element IDs unique. TODO: Is there\n// something more performant, and that can't be broken by other elements of the\n// page? (And also doesn't break if this library is run in parallel.)\nlet svgCounter = 0;\nfunction nextSVGID(): string {\n svgCounter += 1;\n return `svg${svgCounter.toString()}`;\n}\n\n// TODO: This is hardcoded to 3x3x3 SVGs\nconst colorMaps: Partial<\n Record<FaceletMeshStickeringMask, string | Record<string, string>>\n> = {\n dim: {\n white: \"#dddddd\",\n orange: \"#884400\",\n limegreen: \"#008800\",\n red: \"#660000\",\n \"rgb(34, 102, 255)\": \"#000088\", // TODO\n yellow: \"#888800\",\n \"rgb(102, 0, 153)\": \"rgb(50, 0, 76)\",\n purple: \"#3f003f\",\n },\n oriented: \"#44ddcc\",\n ignored: \"#555555\",\n invisible: \"#00000000\",\n};\n\nexport class TwistyAnimatedSVG {\n public wrapperElement: HTMLElement;\n public svgElement: SVGElement;\n public gradientDefs: SVGDefsElement;\n private originalColors: { [type: string]: string } = {};\n private gradients: { [type: string]: SVGGradientElement } = {};\n private svgID: string;\n constructor(\n public kpuzzle: KPuzzle,\n svgSource: string,\n experimentalStickeringMask?: StickeringMask,\n private showUnknownOrientations: boolean = false,\n ) {\n if (!svgSource) {\n throw new Error(`No SVG definition for puzzle type: ${kpuzzle.name()}`);\n }\n\n this.svgID = nextSVGID();\n\n this.wrapperElement = document.createElement(\"div\");\n this.wrapperElement.classList.add(\"svg-wrapper\");\n // TODO: Sanitization.\n this.wrapperElement.innerHTML = svgSource;\n\n const svgElem = this.wrapperElement.querySelector(\"svg\");\n if (!svgElem) {\n throw new Error(\"Could not get SVG element\");\n }\n this.svgElement = svgElem;\n if (xmlns !== svgElem.namespaceURI) {\n throw new Error(\"Unexpected XML namespace\");\n }\n svgElem.style.maxWidth = \"100%\";\n svgElem.style.maxHeight = \"100%\";\n this.gradientDefs = document.createElementNS(xmlns, \"defs\");\n svgElem.insertBefore(this.gradientDefs, svgElem.firstChild);\n\n for (const orbitDefinition of kpuzzle.definition.orbits) {\n for (let idx = 0; idx < orbitDefinition.numPieces; idx++) {\n for (\n let orientation = 0;\n orientation < orbitDefinition.numOrientations;\n orientation++\n ) {\n const id = this.elementID(\n orbitDefinition.orbitName,\n idx,\n orientation,\n );\n const elem = this.elementByID(id);\n\n let originalColor: string = elem?.style.fill;\n /// TODO: Allow setting stickering mask dynamically.\n if (experimentalStickeringMask) {\n (() => {\n // TODO: dedup with Cube3D,,factor out fallback calculations\n const a = experimentalStickeringMask.orbits;\n if (!a) {\n return;\n }\n const orbitStickeringMask = a[orbitDefinition.orbitName];\n if (!orbitStickeringMask) {\n return;\n }\n const pieceStickeringMask = orbitStickeringMask.pieces[idx];\n if (!pieceStickeringMask) {\n return;\n }\n const faceletStickeringMasks =\n pieceStickeringMask.facelets[orientation];\n if (!faceletStickeringMasks) {\n return;\n }\n const stickeringMask =\n typeof faceletStickeringMasks === \"string\"\n ? faceletStickeringMasks\n : faceletStickeringMasks?.mask;\n const colorMap = colorMaps[stickeringMask];\n if (typeof colorMap === \"string\") {\n originalColor = colorMap;\n } else if (colorMap) {\n originalColor = colorMap[originalColor];\n }\n })();\n } else {\n originalColor = elem?.style.fill;\n }\n this.originalColors[id] = originalColor;\n this.gradients[id] = this.newGradient(id, originalColor);\n this.gradientDefs.appendChild(this.gradients[id]);\n elem?.setAttribute(\"style\", `fill: url(#grad-${this.svgID}-${id})`);\n }\n }\n }\n\n for (const hintElem of Array.from(\n svgElem.querySelectorAll(`[${DATA_COPY_ID_ATTRIBUTE}]`),\n )) {\n const id = hintElem.getAttribute(DATA_COPY_ID_ATTRIBUTE);\n hintElem.setAttribute(\"style\", `fill: url(#grad-${this.svgID}-${id})`);\n }\n\n if (this.showUnknownOrientations) {\n this.drawPattern(this.kpuzzle.defaultPattern());\n }\n }\n\n public drawPattern(\n pattern: KPattern,\n nextPattern?: KPattern,\n fraction?: number,\n ): void {\n this.draw(pattern, nextPattern, fraction);\n }\n\n // TODO: save definition in the constructor?\n public draw(\n pattern: KPattern,\n nextPattern?: KPattern,\n fraction?: number,\n ): void {\n const nextTransformation = nextPattern?.experimentalToTransformation();\n if (!pattern) {\n throw new Error(\"Distinguishable pieces are not handled for SVG yet!\");\n }\n\n for (const orbitDefinition of pattern.kpuzzle.definition.orbits) {\n const currentPatternOrbit =\n pattern.patternData[orbitDefinition.orbitName];\n const nextTransformationOrbit = nextTransformation\n ? nextTransformation.transformationData[orbitDefinition.orbitName]\n : null;\n for (let idx = 0; idx < orbitDefinition.numPieces; idx++) {\n for (\n let orientation = 0;\n orientation < orbitDefinition.numOrientations;\n orientation++\n ) {\n const id = this.elementID(\n orbitDefinition.orbitName,\n idx,\n orientation,\n );\n const fromCur = this.elementID(\n orbitDefinition.orbitName,\n currentPatternOrbit.pieces[idx],\n (orbitDefinition.numOrientations -\n currentPatternOrbit.orientation[idx] +\n orientation) %\n orbitDefinition.numOrientations,\n );\n let singleColor = false;\n if (nextTransformationOrbit) {\n const fromNext = this.elementID(\n orbitDefinition.orbitName,\n nextTransformationOrbit.permutation[idx],\n (orbitDefinition.numOrientations -\n nextTransformationOrbit.orientationDelta[idx] +\n orientation) %\n orbitDefinition.numOrientations,\n );\n if (fromCur === fromNext) {\n singleColor = true; // TODO: Avoid redundant work during move.\n }\n fraction = fraction || 0; // TODO Use the type system to tie this to nextPattern?\n const easedBackwardsPercent =\n 100 * (1 - fraction * fraction * (2 - fraction * fraction)); // TODO: Move easing up the stack.\n this.gradients[id].children[0].setAttribute(\n \"stop-color\",\n this.originalColors[fromCur],\n );\n this.gradients[id].children[0].setAttribute(\n \"offset\",\n `${Math.max(easedBackwardsPercent - 5, 0)}%`,\n );\n this.gradients[id].children[1].setAttribute(\n \"offset\",\n `${Math.max(easedBackwardsPercent - 5, 0)}%`,\n );\n this.gradients[id].children[2].setAttribute(\n \"offset\",\n `${easedBackwardsPercent}%`,\n );\n this.gradients[id].children[3].setAttribute(\n \"offset\",\n `${easedBackwardsPercent}%`,\n );\n this.gradients[id].children[3].setAttribute(\n \"stop-color\",\n this.originalColors[fromNext],\n );\n } else {\n singleColor = true; // TODO: Avoid redundant work during move.\n }\n if (singleColor) {\n if (\n this.showUnknownOrientations &&\n currentPatternOrbit.orientationMod?.[idx] === 1\n ) {\n this.gradients[id].children[0].setAttribute(\"stop-color\", \"#000\");\n this.gradients[id].children[0].setAttribute(\"offset\", \"5%\");\n this.gradients[id].children[1].setAttribute(\"offset\", \"5%\");\n this.gradients[id].children[2].setAttribute(\"offset\", \"20%\");\n this.gradients[id].children[3].setAttribute(\"offset\", \"20%\");\n this.gradients[id].children[3].setAttribute(\n \"stop-color\",\n this.originalColors[fromCur],\n );\n } else {\n this.gradients[id].children[0].setAttribute(\n \"stop-color\",\n this.originalColors[fromCur],\n );\n this.gradients[id].children[0].setAttribute(\"offset\", \"100%\");\n this.gradients[id].children[1].setAttribute(\"offset\", \"100%\");\n this.gradients[id].children[2].setAttribute(\"offset\", \"100%\");\n this.gradients[id].children[3].setAttribute(\"offset\", \"100%\");\n }\n }\n // this.gradients[id]\n // this.elementByID(id).style.fill = this.originalColors[from];\n }\n }\n }\n }\n\n private newGradient(id: string, originalColor: string): SVGGradientElement {\n const grad = document.createElementNS(\n xmlns,\n \"radialGradient\",\n ) as SVGGradientElement;\n grad.setAttribute(\"id\", `grad-${this.svgID}-${id}`);\n grad.setAttribute(\"r\", \"70.7107%\"); // TODO: Adapt to puzzle.\n const stopDefs = [\n { offset: 0, color: originalColor },\n { offset: 0, color: \"black\" },\n { offset: 0, color: \"black\" },\n { offset: 0, color: originalColor },\n ];\n for (const stopDef of stopDefs) {\n const stop = document.createElementNS(xmlns, \"stop\");\n stop.setAttribute(\"offset\", `${stopDef.offset}%`);\n stop.setAttribute(\"stop-color\", stopDef.color);\n stop.setAttribute(\"stop-opacity\", \"1\");\n grad.appendChild(stop);\n }\n return grad;\n }\n\n private elementID(\n orbitName: string,\n idx: number,\n orientation: number,\n ): string {\n return `${orbitName}-l${idx}-o${orientation}`;\n }\n\n private elementByID(id: string): HTMLElement {\n // TODO: Use classes and scope selector to SVG element.\n return this.wrapperElement.querySelector(`#${id}`) as HTMLElement;\n }\n}\n", "import type { ManagedCustomElement } from \"./ManagedCustomElement\";\n\nexport class ClassListManager<SuffixType extends string> {\n #currentClassName: string | null = null;\n // The prefix should ideally end in a dash.\n constructor(\n private elem: ManagedCustomElement,\n private prefix: string,\n private validSuffixes: SuffixType[],\n ) {}\n\n // Does nothing if there was no value.\n clearValue(): void {\n if (this.#currentClassName) {\n this.elem.contentWrapper.classList.remove(this.#currentClassName);\n }\n this.#currentClassName = null; // TODO: add test for this behaviour.\n }\n\n // Returns if the value changed\n setValue(suffix: SuffixType): boolean {\n if (!this.validSuffixes.includes(suffix)) {\n throw new Error(`Invalid suffix: ${suffix}`);\n }\n const newClassName = `${this.prefix}${suffix}`;\n const changed = this.#currentClassName !== newClassName;\n if (changed) {\n this.clearValue();\n this.elem.contentWrapper.classList.add(newClassName);\n this.#currentClassName = newClassName;\n }\n return changed;\n }\n}\n", "import { offsetMod } from \"../../alg/cubing-private\";\n\nexport function arrayEquals<T>(a: readonly T[], b: readonly T[]): boolean {\n if (a === b) {\n return true;\n }\n if (a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) {\n return false;\n }\n }\n return true;\n}\n\nexport function arrayEqualsCompare<T>(\n a: readonly T[],\n b: readonly T[],\n compare: (a: T, b: T) => boolean,\n): boolean {\n if (a === b) {\n return true;\n }\n if (a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i++) {\n if (!compare(a[i], b[i])) {\n return false;\n }\n }\n return true;\n}\n\nexport function modIntoRange(\n v: number,\n rangeMin: number,\n rangeMax: number,\n): number {\n return offsetMod(v, rangeMax - rangeMin, rangeMin);\n}\n", "import type { Tagged } from \"type-fest\";\nimport type { Move } from \"../../alg\";\nimport type { KPattern } from \"../../kpuzzle/KPattern\";\n\nexport type MillisecondTimestamp = Tagged<\n DOMHighResTimeStamp,\n \"MillisecondTimestamp\"\n>;\n\n// TODO: unify duration/timstamp types\nexport type MillisecondDuration = Tagged<number, \"MillisecondDuration\">; // Duration in milliseconds\n// TODO: Extend `number`, introduce MoveSequenceTimestamp vs. EpochTimestamp,\n// force Duration to be a difference.\n\nexport type Fraction = number; // Value from 0 to 1.\n\n// 1, 0, -1 are used as scalars for `directionScalar` below.\nexport enum Direction {\n Forwards = 1,\n Paused = 0,\n Backwards = -1,\n}\n\nexport function directionScalar(direction: Direction): number {\n return direction;\n}\n\nexport interface MoveInProgress {\n move: Move;\n direction: Direction;\n fraction: number;\n}\n\nexport type PuzzlePosition = {\n pattern: KPattern;\n movesInProgress: MoveInProgress[];\n};\n\nexport enum BoundaryType {\n Move = \"move\",\n EntireTimeline = \"entire-timeline\",\n}\n\nexport interface TimeRange {\n start: MillisecondTimestamp;\n end: MillisecondTimestamp;\n}\n\n// export type DurationForAmount = (amount: number) => Duration;\n\nexport interface PositionListener {\n onPositionChange(position: PuzzlePosition): void;\n}\n", "import { modIntoRange } from \"../model/helpers\";\nimport { StaleDropper } from \"../model/PromiseFreshener\";\nimport type { CatchUpMove } from \"../model/props/puzzle/state/CatchUpMoveProp\";\nimport type {\n PlayingInfo,\n SimpleDirection,\n} from \"../model/props/timeline/PlayingInfoProp\";\nimport type { TimestampRequest } from \"../model/props/timeline/TimestampRequestProp\";\nimport type { TwistyPlayerModel } from \"../model/TwistyPlayerModel\";\nimport {\n BoundaryType,\n Direction,\n directionScalar,\n type MillisecondTimestamp,\n type TimeRange,\n} from \"./AnimationTypes\";\nimport type { CurrentMoveInfo } from \"./indexer/AlgIndexer\";\nimport { RenderScheduler } from \"./RenderScheduler\";\n\n// TODO: Figure out a better way for the controller to instruct the player.\nexport interface TwistyAnimationControllerDelegate {\n flash(): void;\n}\n\n// We use a separate helper to separate the anim frame callbacks (and their cancellations).\n// TODO: fold this into the main controller\nclass CatchUpHelper {\n catchingUp: boolean = false;\n pendingFrame = false;\n\n tempoScale: number = 1; // TODO\n constructor(private model: TwistyPlayerModel) {\n model.tempoScale.addFreshListener((tempoScale) => {\n this.tempoScale = tempoScale;\n });\n }\n\n private scheduler: RenderScheduler = new RenderScheduler(\n this.animFrame.bind(this),\n );\n\n start(): void {\n if (!this.catchingUp) {\n this.lastTimestamp = performance.now();\n }\n this.catchingUp = true;\n this.pendingFrame = true;\n this.scheduler.requestAnimFrame();\n }\n\n stop(): void {\n this.catchingUp = false;\n this.scheduler.cancelAnimFrame();\n }\n\n catchUpMs = 500;\n lastTimestamp = 0;\n animFrame(timestamp: MillisecondTimestamp): void {\n this.scheduler.requestAnimFrame();\n const delta =\n (this.tempoScale * (timestamp - this.lastTimestamp)) / this.catchUpMs;\n this.lastTimestamp = timestamp;\n\n this.model.catchUpMove.set(\n (async (): Promise<CatchUpMove> => {\n const previousCatchUpMove = await this.model.catchUpMove.get();\n if (previousCatchUpMove.move === null) {\n return previousCatchUpMove;\n }\n\n const amount = previousCatchUpMove.amount + delta; // TODO: use tempo scale?\n if (amount >= 1) {\n this.pendingFrame = true;\n this.stop();\n this.model.timestampRequest.set(\"end\");\n return {\n move: null,\n amount: 0,\n };\n }\n this.pendingFrame = false;\n return {\n move: previousCatchUpMove.move,\n amount: amount,\n };\n })(),\n );\n }\n}\n\n// This controls the logic for animation, so that the main controller can focus on the right API abstractions.\nexport class TwistyAnimationController {\n // TODO: #private?\n private playing: boolean = false;\n private direction: Direction = Direction.Forwards;\n\n private catchUpHelper: CatchUpHelper;\n\n private model: TwistyPlayerModel;\n\n private lastDatestamp: MillisecondTimestamp = 0 as MillisecondTimestamp;\n private lastTimestampPromise: Promise<MillisecondTimestamp>;\n\n private scheduler: RenderScheduler = new RenderScheduler(\n this.animFrame.bind(this),\n );\n\n constructor(\n model: TwistyPlayerModel,\n private delegate: TwistyAnimationControllerDelegate,\n ) {\n this.model = model;\n this.lastTimestampPromise = this.#effectiveTimestampMilliseconds();\n\n this.model.playingInfo.addFreshListener(this.onPlayingProp.bind(this)); // TODO\n\n this.catchUpHelper = new CatchUpHelper(this.model);\n this.model.catchUpMove.addFreshListener(this.onCatchUpMoveProp.bind(this)); // TODO\n }\n\n // TODO: Do we need this?\n async onPlayingProp(playingInfo: PlayingInfo): Promise<void> {\n if (playingInfo.playing !== this.playing) {\n playingInfo.playing ? this.play(playingInfo) : this.pause();\n }\n }\n\n // TODO: Do we need this?\n async onCatchUpMoveProp(catchUpMove: CatchUpMove): Promise<void> {\n const catchingUp = catchUpMove.move !== null;\n if (catchingUp !== this.catchUpHelper.catchingUp) {\n catchingUp ? this.catchUpHelper.start() : this.catchUpHelper.stop();\n }\n this.scheduler.requestAnimFrame();\n }\n\n async #effectiveTimestampMilliseconds(): Promise<MillisecondTimestamp> {\n return (await this.model.detailedTimelineInfo.get()).timestamp;\n }\n\n // TODO: Return the animation we've switched to.\n jumpToStart(options?: { flash: boolean }): void {\n this.model.timestampRequest.set(\"start\");\n this.pause();\n if (options?.flash) {\n this.delegate.flash();\n }\n }\n\n // TODO: Return the animation we've switched to.\n jumpToEnd(options?: { flash: boolean }): void {\n this.model.timestampRequest.set(\"end\");\n this.pause();\n if (options?.flash) {\n this.delegate.flash();\n }\n }\n\n // TODO: Return the playing info we've switched to.\n playPause(): void {\n if (this.playing) {\n this.pause();\n } else {\n this.play(); // TODO: Resume direction and looping behaviour?\n }\n }\n\n // TODO: bundle playing direction, and boundary into `toggle`.\n play(options?: {\n direction?: SimpleDirection;\n untilBoundary?: BoundaryType;\n autoSkipToOtherEndIfStartingAtBoundary?: boolean; // TODO What's a good short name that doesn't imply a more general looping concept?\n loop?: boolean;\n }): void {\n void (async () => {\n // TODO: We might need to cache all playing info?\n // Or maybe we don't have to worry about short-circuiting, since this is idempotent?\n // if (this.playing) {\n // return;\n // }\n\n const direction = options?.direction ?? Direction.Forwards;\n\n const coarseTimelineInfo = await this.model.coarseTimelineInfo.get(); // TODO: Why do we need to read this if we don't use it?\n if (options?.autoSkipToOtherEndIfStartingAtBoundary ?? true) {\n if (direction === Direction.Forwards && coarseTimelineInfo.atEnd) {\n this.model.timestampRequest.set(\"start\");\n this.delegate.flash();\n }\n if (direction === Direction.Backwards && coarseTimelineInfo.atStart) {\n this.model.timestampRequest.set(\"end\");\n this.delegate.flash();\n }\n }\n this.model.playingInfo.set({\n playing: true,\n direction,\n untilBoundary: options?.untilBoundary ?? BoundaryType.EntireTimeline,\n loop: options?.loop ?? false,\n });\n\n this.playing = true;\n this.lastDatestamp = performance.now() as MillisecondTimestamp; // TODO: Take from event.\n this.lastTimestampPromise = this.#effectiveTimestampMilliseconds();\n\n // TODO: Save timestamp from model?\n this.scheduler.requestAnimFrame();\n })();\n }\n\n pause(): void {\n this.playing = false;\n this.scheduler.cancelAnimFrame();\n this.model.playingInfo.set({\n playing: false,\n untilBoundary: BoundaryType.EntireTimeline,\n });\n }\n\n #animFrameEffectiveTimestampStaleDropper: StaleDropper<\n [PlayingInfo, MillisecondTimestamp, TimeRange, number, CurrentMoveInfo]\n > = new StaleDropper<\n [PlayingInfo, MillisecondTimestamp, TimeRange, number, CurrentMoveInfo]\n >();\n\n async animFrame(frameDatestamp: MillisecondTimestamp): Promise<void> {\n if (this.playing) {\n this.scheduler.requestAnimFrame();\n }\n\n const lastDatestamp = this.lastDatestamp;\n const freshenerResult =\n await this.#animFrameEffectiveTimestampStaleDropper.queue(\n Promise.all([\n this.model.playingInfo.get(),\n this.lastTimestampPromise,\n this.model.timeRange.get(),\n this.model.tempoScale.get(),\n this.model.currentMoveInfo.get(),\n ]),\n );\n\n const [playingInfo, lastTimestamp, timeRange, tempoScale, currentMoveInfo] =\n freshenerResult;\n\n // TODO: Get this without wasting time on the others?\n if (!playingInfo.playing) {\n this.playing = false;\n // TODO: Ideally we'd cancel the anim frame from the top of this method.\n // But `this.scheduler.cancelAnimFrame();` might accidentally cancel a\n // legit freshly scheduled frame. We should modify `RenderScheduler` to\n // either have individually cancellable requests, or to have something\n // like a \"default\" anim frame re-request that can be canceled separately.\n //\n // Note that we can't wait until here to call\n // `this.scheduler.requestAnimFrame();`, because that would slow down the\n // frame rate.\n return;\n }\n\n let end = currentMoveInfo.earliestEnd; // timeRange.end\n if (\n currentMoveInfo.currentMoves.length === 0 ||\n playingInfo.untilBoundary === BoundaryType.EntireTimeline\n ) {\n end = timeRange.end;\n }\n\n let start = currentMoveInfo.latestStart; // timeRange.end\n if (\n currentMoveInfo.currentMoves.length === 0 ||\n playingInfo.untilBoundary === BoundaryType.EntireTimeline\n ) {\n start = timeRange.start;\n }\n // const start = currentMoveInfo.latestStart; // timeRange.start // TODO\n\n let delta =\n (frameDatestamp - lastDatestamp) *\n directionScalar(this.direction) *\n tempoScale;\n delta = Math.max(delta, 1); // TODO: This guards against the timestamp going in the wrong direction by accident. Can we avoid it?\n delta *= playingInfo.direction;\n let newTimestamp = (lastTimestamp + delta) as MillisecondTimestamp; // TODO: Pre-emptively clamp.\n let newSmartTimestampRequest: Exclude<TimestampRequest, number> | null =\n null;\n\n if (newTimestamp >= end) {\n if (playingInfo.loop) {\n newTimestamp = modIntoRange(\n newTimestamp,\n timeRange.start,\n timeRange.end,\n ) as MillisecondTimestamp;\n } else {\n if (newTimestamp === timeRange.end) {\n newSmartTimestampRequest = \"end\";\n } else {\n newTimestamp = end as MillisecondTimestamp;\n }\n this.playing = false;\n this.model.playingInfo.set({\n playing: false,\n });\n }\n } else if (newTimestamp <= start) {\n if (playingInfo.loop) {\n newTimestamp = modIntoRange(\n newTimestamp,\n timeRange.start,\n timeRange.end,\n ) as MillisecondTimestamp;\n } else {\n if (newTimestamp === timeRange.start) {\n newSmartTimestampRequest = \"start\";\n } else {\n newTimestamp = start as MillisecondTimestamp;\n }\n this.playing = false;\n this.model.playingInfo.set({\n playing: false,\n });\n }\n }\n this.lastDatestamp = frameDatestamp;\n this.lastTimestampPromise = Promise.resolve(\n newTimestamp as MillisecondTimestamp,\n ); // TODO: Save this earlier? / Do we need to worry about the effecitve timestamp disagreeing?\n this.model.timestampRequest.set(newSmartTimestampRequest ?? newTimestamp);\n }\n}\n", "import type { TwistyPlayerModel } from \"../model/TwistyPlayerModel\";\nimport {\n TwistyAnimationController,\n type TwistyAnimationControllerDelegate,\n} from \"./TwistyAnimationController\";\n\nexport class TwistyPlayerController {\n animationController: TwistyAnimationController;\n\n constructor(\n private model: TwistyPlayerModel,\n delegate: TwistyAnimationControllerDelegate,\n ) {\n this.animationController = new TwistyAnimationController(model, delegate);\n }\n\n jumpToStart(options?: { flash: boolean }): void {\n this.animationController.jumpToStart(options);\n }\n\n jumpToEnd(options?: { flash: boolean }): void {\n this.animationController.jumpToEnd(options);\n }\n\n togglePlay(play?: boolean) {\n if (typeof play === \"undefined\") {\n this.animationController.playPause();\n }\n play ? this.animationController.play() : this.animationController.pause();\n }\n\n public async visitTwizzleLink(): Promise<void> {\n const a = document.createElement(\"a\");\n a.href = await this.model.twizzleLink();\n a.target = \"_blank\";\n a.click();\n }\n}\n", "import { SimpleTwistyPropSource } from \"../TwistyProp\";\n\nexport const controlsLocations = {\n \"bottom-row\": true, // default\n none: true,\n};\nexport type ControlsLocation = keyof typeof controlsLocations;\nexport type ControlPanelThemeWithAuto = ControlsLocation | \"auto\";\n\nexport class ControlPanelProp extends SimpleTwistyPropSource<ControlPanelThemeWithAuto> {\n getDefaultValue(): ControlPanelThemeWithAuto {\n return \"auto\";\n }\n}\n", "import { cssStyleSheetShim } from \"./node-custom-element-shims\";\n\nexport const twistyViewerWrapperCSS = new cssStyleSheetShim();\ntwistyViewerWrapperCSS.replaceSync(\n `\n:host {\n width: 384px;\n height: 256px;\n display: grid;\n}\n\n.wrapper {\n width: 100%;\n height: 100%;\n display: grid;\n overflow: hidden;\n}\n\n.wrapper > * {\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n\n.wrapper.back-view-side-by-side {\n grid-template-columns: 1fr 1fr;\n}\n\n.wrapper.back-view-top-right {\n grid-template-columns: 3fr 1fr;\n grid-template-rows: 1fr 3fr;\n}\n\n.wrapper.back-view-top-right > :nth-child(1) {\n grid-row: 1 / 3;\n grid-column: 1 / 3;\n}\n\n.wrapper.back-view-top-right > :nth-child(2) {\n grid-row: 1 / 2;\n grid-column: 2 / 3;\n}\n`,\n);\n", "import { cssStyleSheetShim } from \"../node-custom-element-shims\";\n\n// TODO: Can we do this without so much nesting, and styling all the nested elems?\nexport const twisty2DSVGCSS = new cssStyleSheetShim();\ntwisty2DSVGCSS.replaceSync(\n `\n:host {\n width: 384px;\n height: 256px;\n display: grid;\n}\n\n.wrapper {\n width: 100%;\n height: 100%;\n display: grid;\n overflow: hidden;\n}\n\n.svg-wrapper,\ntwisty-2d-svg,\nsvg {\n width: 100%;\n height: 100%;\n display: grid;\n min-height: 0;\n}\n\nsvg {\n animation: fade-in 0.25s ease-in;\n}\n\n@keyframes fade-in {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.hint-facelets-none .hint-facelet {\n display: none;\n}\n`,\n);\n", "import type { KPuzzle } from \"../../../kpuzzle\";\nimport type { ExperimentalStickeringMask } from \"../../../puzzles/cubing-private\";\nimport type { PuzzleLoader } from \"../../../puzzles/PuzzleLoader\";\nimport type { StickeringMask } from \"../../../puzzles/stickerings/mask\";\nimport {\n type HintFaceletStyleWithAuto,\n hintFaceletStyles,\n} from \"../../../twisty/model/props/puzzle/display/HintFaceletProp\";\nimport type { PuzzleID } from \"../..\";\nimport {\n Direction,\n type PositionListener,\n type PuzzlePosition,\n} from \"../../controllers/AnimationTypes\";\nimport { RenderScheduler } from \"../../controllers/RenderScheduler\";\nimport { FreshListenerManager } from \"../../model/props/TwistyProp\";\nimport type { TwistyPlayerModel } from \"../../model/TwistyPlayerModel\";\nimport { ClassListManager } from \"../ClassListManager\";\nimport { ManagedCustomElement } from \"../ManagedCustomElement\";\nimport { customElementsShim } from \"../node-custom-element-shims\";\nimport { twisty2DSVGCSS } from \"./Twisty2DPuzzle.css\";\nimport { TwistyAnimatedSVG } from \"./TwistyAnimatedSVG\";\n\nexport interface Twisty2DPuzzleOptions {\n experimentalStickeringMask?: ExperimentalStickeringMask;\n}\n\n// <twisty-2d-svg>\nexport class Twisty2DPuzzle\n extends ManagedCustomElement\n implements PositionListener\n{\n public svgWrapper?: TwistyAnimatedSVG;\n private scheduler = new RenderScheduler(this.render.bind(this));\n #cachedPosition: PuzzlePosition | null = null; // TODO: pull when needed.\n constructor(\n private model?: TwistyPlayerModel,\n private kpuzzle?: KPuzzle,\n private svgSource?: string,\n private options?: Twisty2DPuzzleOptions,\n private puzzleLoader?: PuzzleLoader,\n ) {\n super();\n this.addCSS(twisty2DSVGCSS);\n\n this.resetSVG(); // TODO: do this in `connectedCallback()`?\n\n this.#freshListenerManager.addListener(\n this.model!.puzzleID,\n (puzzleID: PuzzleID) => {\n if (puzzleLoader?.id !== puzzleID) {\n this.disconnect();\n }\n },\n );\n\n this.#freshListenerManager.addListener(\n this.model!.twistySceneModel.hintFacelet,\n (hintFacelet) => {\n this.setHintFacelet(hintFacelet);\n },\n );\n\n this.#freshListenerManager.addListener(\n this.model!.legacyPosition,\n this.onPositionChange.bind(this),\n );\n\n if (this.options?.experimentalStickeringMask) {\n this.experimentalSetStickeringMask(\n this.options.experimentalStickeringMask,\n );\n }\n }\n\n #freshListenerManager = new FreshListenerManager();\n disconnect(): void {\n this.#freshListenerManager.disconnect();\n }\n\n onPositionChange(position: PuzzlePosition): void {\n try {\n if (position.movesInProgress.length > 0) {\n const move = position.movesInProgress[0].move;\n\n let partialMove = move;\n if (position.movesInProgress[0].direction === Direction.Backwards) {\n partialMove = move.invert();\n }\n const newPattern = position.pattern.applyMove(partialMove);\n // TODO: move to render()\n this.svgWrapper?.draw(\n position.pattern,\n newPattern,\n position.movesInProgress[0].fraction,\n );\n } else {\n this.svgWrapper?.draw(position.pattern);\n this.#cachedPosition = position;\n }\n } catch (e) {\n console.warn(\n \"Bad position (this doesn't necessarily mean something is wrong). Pre-emptively disconnecting:\",\n this.puzzleLoader?.id,\n e,\n );\n this.disconnect();\n }\n }\n\n scheduleRender(): void {\n this.scheduler.requestAnimFrame();\n }\n\n experimentalSetStickeringMask(\n stickeringMask: ExperimentalStickeringMask,\n ): void {\n this.resetSVG(stickeringMask);\n }\n\n // TODO: do this without constructing a new SVG.\n private resetSVG(stickeringMask?: StickeringMask): void {\n if (this.svgWrapper) {\n this.removeElement(this.svgWrapper.wrapperElement);\n }\n if (!this.kpuzzle) {\n return; // TODO\n }\n this.svgWrapper = new TwistyAnimatedSVG(\n this.kpuzzle,\n this.svgSource!,\n stickeringMask,\n ); // TODO\n this.addElement(this.svgWrapper.wrapperElement);\n if (this.#cachedPosition) {\n this.onPositionChange(this.#cachedPosition);\n }\n }\n\n private hintFaceletsClassListManager = new ClassListManager(\n this,\n \"hint-facelets-\",\n Object.keys(hintFaceletStyles),\n );\n setHintFacelet(hintFacelet: HintFaceletStyleWithAuto) {\n this.hintFaceletsClassListManager.setValue(\n hintFacelet === \"auto\" ? \"floating\" : hintFacelet,\n );\n }\n\n private render(): void {\n /*...*/\n }\n}\n\ncustomElementsShim.define(\"twisty-2d-puzzle\", Twisty2DPuzzle);\n", "import type { PuzzleLoader } from \"../../../puzzles\";\nimport type { ExperimentalStickeringMask } from \"../../../puzzles/cubing-private\";\nimport type { Schedulable } from \"../../controllers/RenderScheduler\";\nimport { FreshListenerManager } from \"../../model/props/TwistyProp\";\nimport type { TwistyPlayerModel } from \"../../model/TwistyPlayerModel\";\nimport { Twisty2DPuzzle } from \"./Twisty2DPuzzle\";\n\nexport class Twisty2DPuzzleWrapper implements Schedulable {\n constructor(\n private model: TwistyPlayerModel,\n public schedulable: Schedulable,\n private puzzleLoader: PuzzleLoader,\n private effectiveVisualization:\n | \"2D\"\n | \"experimental-2D-LL\"\n | \"experimental-2D-LL-face\",\n ) {\n void this.twisty2DPuzzle(); // Start constructing.\n\n this.#freshListenerManager.addListener(\n this.model.twistySceneModel.stickeringMask,\n async (stickeringMask: ExperimentalStickeringMask) => {\n (await this.twisty2DPuzzle()).experimentalSetStickeringMask(\n stickeringMask,\n );\n },\n );\n }\n\n #freshListenerManager = new FreshListenerManager();\n disconnect(): void {\n this.#freshListenerManager.disconnect();\n }\n\n // TODO: Hook this up nicely.\n scheduleRender(): void {\n // Nothing\n }\n\n #cachedTwisty2DPuzzle: Promise<Twisty2DPuzzle> | null = null;\n // TODO: Stale dropper?\n async twisty2DPuzzle(): Promise<Twisty2DPuzzle> {\n return (this.#cachedTwisty2DPuzzle ??= (async () => {\n const svgPromise =\n this.effectiveVisualization === \"experimental-2D-LL-face\"\n ? this.puzzleLoader.llFaceSVG!()\n : this.effectiveVisualization === \"experimental-2D-LL\"\n ? this.puzzleLoader.llSVG!()\n : this.puzzleLoader.svg();\n return new Twisty2DPuzzle(\n this.model,\n await this.puzzleLoader.kpuzzle(),\n await svgPromise,\n {},\n this.puzzleLoader,\n );\n })());\n }\n}\n", "import type { Scene as ThreeScene } from \"three/src/Three.js\";\nimport type { PuzzleLoader } from \"../../../puzzles\";\nimport type { Schedulable } from \"../../controllers/RenderScheduler\";\nimport { bulk3DCode } from \"../../heavy-code-imports/3d\";\nimport { FreshListenerManager } from \"../../model/props/TwistyProp\";\nimport type { TwistySceneModel } from \"../../model/TwistySceneModel\";\nimport { ManagedCustomElement } from \"../ManagedCustomElement\";\nimport { customElementsShim } from \"../node-custom-element-shims\";\nimport { twistyViewerWrapperCSS } from \"../TwistyViewerWrapper.css\";\nimport { Twisty2DPuzzleWrapper } from \"./Twisty2DPuzzleWrapper\";\n\nexport class Twisty2DSceneWrapper\n extends ManagedCustomElement\n implements Schedulable\n{\n #freshListenerManager = new FreshListenerManager();\n disconnect(): void {\n this.#freshListenerManager.disconnect();\n }\n\n constructor(\n public model?: TwistySceneModel,\n private effectiveVisualization?:\n | \"2D\"\n | \"experimental-2D-LL\"\n | \"experimental-2D-LL-face\",\n ) {\n super();\n }\n\n async connectedCallback(): Promise<void> {\n this.addCSS(twistyViewerWrapperCSS);\n if (this.model) {\n this.#freshListenerManager.addListener(\n this.model.twistyPlayerModel.puzzleLoader,\n this.onPuzzleLoader.bind(this),\n );\n }\n }\n\n #cachedScene?: Promise<ThreeScene>;\n async scene(): Promise<ThreeScene> {\n return (this.#cachedScene ??= (async () =>\n new (await bulk3DCode()).ThreeScene())());\n }\n\n scheduleRender(): void {\n this.#currentTwisty2DPuzzleWrapper?.scheduleRender();\n }\n\n #currentTwisty2DPuzzleWrapper: Twisty2DPuzzleWrapper | undefined;\n currentTwisty2DPuzzleWrapper(): Twisty2DPuzzleWrapper | undefined {\n return this.#currentTwisty2DPuzzleWrapper;\n }\n\n // #oldTwisty3DPuzzleWrappers: Twisty3DPuzzleWrapper[] = []; // TODO: Animate these out.\n async setCurrentTwisty2DPuzzleWrapper(\n twisty2DPuzzleWrapper: Twisty2DPuzzleWrapper,\n ): Promise<void> {\n const old = this.#currentTwisty2DPuzzleWrapper;\n this.#currentTwisty2DPuzzleWrapper = twisty2DPuzzleWrapper;\n old?.disconnect(); // TODO: Disconnect properly.\n const twisty2DPuzzlePromise = twisty2DPuzzleWrapper.twisty2DPuzzle();\n this.contentWrapper.textContent = \"\"; // Clear existing ones.\n this.addElement(await twisty2DPuzzlePromise);\n }\n\n async onPuzzleLoader(puzzleLoader: PuzzleLoader): Promise<void> {\n this.#currentTwisty2DPuzzleWrapper?.disconnect();\n const twisty2DPuzzleWrapper = new Twisty2DPuzzleWrapper(\n this.model!.twistyPlayerModel,\n this,\n puzzleLoader,\n this.effectiveVisualization!,\n );\n\n void this.setCurrentTwisty2DPuzzleWrapper(twisty2DPuzzleWrapper);\n }\n}\n\ncustomElementsShim.define(\"twisty-2d-scene-wrapper\", Twisty2DSceneWrapper);\n", "export class InitialValueTracker<T> {\n // @ts-expect-error: We do initialize this synchronously (assuming no one has tampered with the `Promise` constructor).\n #resolve: (t: T) => void;\n // @ts-expect-error: We do initialize this synchronously (assuming no one has tampered with the `Promise` constructor).\n reject: (e?: Error) => void; // TODO: AbortController?\n promise: Promise<T>;\n constructor() {\n this.promise = new Promise((resolve, reject) => {\n this.#resolve = resolve;\n this.reject = reject;\n });\n }\n handleNewValue(t: T): void {\n this.#resolve(t);\n }\n}\n", "import type { Raycaster, Texture as ThreeTexture } from \"three/src/Three.js\";\nimport type { PuzzleLoader } from \"../../../puzzles\";\nimport type { ExperimentalStickeringMask } from \"../../../puzzles/cubing-private\";\nimport type { PuzzlePosition } from \"../../controllers/AnimationTypes\";\nimport type { Schedulable } from \"../../controllers/RenderScheduler\";\nimport { bulk3DCode } from \"../../heavy-code-imports/3d\";\nimport type { FoundationDisplay } from \"../../model/props/puzzle/display/FoundationDisplayProp\";\nimport type { HintFaceletStyleWithAuto } from \"../../model/props/puzzle/display/HintFaceletProp\";\nimport { FreshListenerManager } from \"../../model/props/TwistyProp\";\nimport type { VisualizationStrategy } from \"../../model/props/viewer/VisualizationStrategyProp\";\nimport type { TwistyPlayerModel } from \"../../model/TwistyPlayerModel\";\nimport type { Cube3D } from \"./puzzles/Cube3D\";\nimport type { PG3D } from \"./puzzles/PG3D\";\nimport type { Twisty3DPuzzle } from \"./puzzles/Twisty3DPuzzle\";\n\nexport class Twisty3DPuzzleWrapper extends EventTarget implements Schedulable {\n constructor(\n private model: TwistyPlayerModel,\n public schedulable: Schedulable,\n private puzzleLoader: PuzzleLoader,\n private visualizationStrategy: VisualizationStrategy,\n ) {\n super();\n void this.twisty3DPuzzle(); // Start constructing.\n\n // TODO: Hook up listeners before loading the heavy code in the async constructor, so we get any intermediate updates?\n // Repro: Switch to 40x40x40 a fraction of a second before animation finishes. When it's loaded the itmeline is at the end, but the 40x40x40 is rendered with an earlier position.\n\n this.#freshListenerManager.addListener(\n this.model.puzzleLoader,\n (puzzleLoader: PuzzleLoader) => {\n if (this.puzzleLoader.id !== puzzleLoader.id) {\n this.disconnect();\n }\n },\n );\n this.#freshListenerManager.addListener(\n this.model.legacyPosition,\n async (position: PuzzlePosition) => {\n try {\n (await this.twisty3DPuzzle()).onPositionChange(position);\n this.scheduleRender();\n } catch {\n // TODO\n // console.warn(\n // \"Bad position (this doesn't necessarily mean something is wrong). Pre-emptively disconnecting:\",\n // this.puzzleLoader.id,\n // e,\n // );\n this.disconnect();\n }\n },\n );\n\n this.#freshListenerManager.addListener(\n this.model.twistySceneModel.hintFacelet,\n async (hintFaceletStyle: HintFaceletStyleWithAuto) => {\n (\n (await this.twisty3DPuzzle()) as Cube3D | PG3D\n ).experimentalUpdateOptions({\n hintFacelets:\n hintFaceletStyle === \"auto\" ? \"floating\" : hintFaceletStyle,\n });\n this.scheduleRender();\n },\n );\n this.#freshListenerManager.addListener(\n this.model.twistySceneModel.foundationDisplay,\n async (foundationDisplay: FoundationDisplay) => {\n (\n (await this.twisty3DPuzzle()) as Cube3D | PG3D\n ).experimentalUpdateOptions({\n showFoundation: foundationDisplay !== \"none\",\n });\n this.scheduleRender();\n },\n );\n this.#freshListenerManager.addListener(\n this.model.twistySceneModel.stickeringMask,\n async (stickeringMask: ExperimentalStickeringMask) => {\n const twisty3D = await this.twisty3DPuzzle();\n twisty3D.setStickeringMask(stickeringMask);\n this.scheduleRender();\n },\n );\n this.#freshListenerManager.addListener(\n this.model.twistySceneModel.faceletScale,\n async (faceletScale: \"auto\" | number) => {\n (\n (await this.twisty3DPuzzle()) as Cube3D | PG3D\n ).experimentalUpdateOptions({\n faceletScale,\n });\n this.scheduleRender();\n },\n );\n\n this.#freshListenerManager.addMultiListener3(\n [\n this.model.twistySceneModel.stickeringMask,\n this.model.twistySceneModel.foundationStickerSprite,\n this.model.twistySceneModel.hintStickerSprite,\n ],\n async (\n inputs: [\n stickeringMask: ExperimentalStickeringMask,\n foundationSprite: ThreeTexture | null,\n hintSprite: ThreeTexture | null,\n ],\n ) => {\n if (\"experimentalUpdateTexture\" in (await this.twisty3DPuzzle())) {\n ((await this.twisty3DPuzzle()) as PG3D).experimentalUpdateTexture(\n inputs[0].specialBehaviour === \"picture\",\n inputs[1],\n inputs[2],\n );\n this.scheduleRender();\n }\n },\n );\n }\n\n #freshListenerManager = new FreshListenerManager();\n disconnect(): void {\n this.#freshListenerManager.disconnect();\n }\n\n scheduleRender(): void {\n this.schedulable.scheduleRender();\n this.dispatchEvent(new CustomEvent(\"render-scheduled\"));\n }\n\n #cachedTwisty3DPuzzle: Promise<Twisty3DPuzzle> | null = null;\n async twisty3DPuzzle(): Promise<Twisty3DPuzzle> {\n return (this.#cachedTwisty3DPuzzle ??= (async () => {\n const proxyPromise = bulk3DCode();\n if (\n this.puzzleLoader.id === \"3x3x3\" &&\n this.visualizationStrategy === \"Cube3D\"\n ) {\n // TODO: synchronize\n const [\n foundationSprite,\n hintSprite,\n experimentalStickeringMask,\n initialHintFaceletsAnimation,\n ] = await Promise.all([\n this.model.twistySceneModel.foundationStickerSprite.get(),\n this.model.twistySceneModel.hintStickerSprite.get(),\n this.model.twistySceneModel.stickeringMask.get(),\n this.model.twistySceneModel.initialHintFaceletsAnimation.get(),\n ]);\n return (await proxyPromise).cube3DShim(\n () => this.schedulable.scheduleRender(),\n {\n foundationSprite,\n hintSprite,\n experimentalStickeringMask,\n initialHintFaceletsAnimation,\n },\n );\n } else {\n const [hintFacelets, foundationSprite, hintSprite, faceletScale] =\n await Promise.all([\n this.model.twistySceneModel.hintFacelet.get(),\n this.model.twistySceneModel.foundationStickerSprite.get(),\n this.model.twistySceneModel.hintStickerSprite.get(),\n this.model.twistySceneModel.faceletScale.get(),\n ]);\n const pg3d = (await proxyPromise).pg3dShim(\n () => this.schedulable.scheduleRender(),\n this.puzzleLoader,\n hintFacelets === \"auto\" ? \"floating\" : hintFacelets,\n faceletScale,\n this.puzzleLoader.id === \"kilominx\", // TODO: generalize to other puzzles\n );\n // TODO: Figure out how to do this in one place using the listener.\n pg3d.then((p) =>\n p.experimentalUpdateTexture(\n true,\n foundationSprite ?? undefined,\n hintSprite ?? undefined,\n ),\n );\n return pg3d;\n }\n })());\n }\n\n async raycastMove(\n raycasterPromise: Promise<Raycaster>,\n transformations: {\n invert: boolean;\n depth?: \"secondSlice\" | \"rotation\" | \"none\";\n },\n ): Promise<void> {\n const puzzle = (await this.twisty3DPuzzle()) as Cube3D | PG3D;\n // TODO: check this differently.\n if (!(\"experimentalGetControlTargets\" in puzzle)) {\n console.info(\"not PG3D! skipping raycast\");\n return;\n }\n\n const targets = puzzle.experimentalGetControlTargets(); // TODO: sticker targets\n const [raycaster, movePressCancelOptions] = await Promise.all([\n raycasterPromise,\n this.model.twistySceneModel.movePressCancelOptions.get(),\n ]);\n\n const intersects = raycaster.intersectObjects(targets);\n if (intersects.length > 0) {\n const closestMove = puzzle.getClosestMoveToAxis(\n intersects[0].point,\n transformations,\n );\n if (closestMove) {\n this.model.experimentalAddMove(closestMove.move, {\n cancel: movePressCancelOptions,\n });\n } else {\n console.info(\"Skipping move!\");\n }\n }\n }\n}\n", "import type {\n PerspectiveCamera,\n Scene as ThreeScene,\n} from \"three/src/Three.js\";\nimport type { PuzzleLoader } from \"../../../puzzles\";\nimport type { Schedulable } from \"../../controllers/RenderScheduler\";\nimport { bulk3DCode } from \"../../heavy-code-imports/3d\";\nimport { StaleDropper } from \"../../model/PromiseFreshener\";\nimport { FreshListenerManager } from \"../../model/props/TwistyProp\";\nimport type { BackViewLayout as BackViewLayoutWithAuto } from \"../../model/props/viewer/BackViewProp\";\nimport type { VisualizationStrategy } from \"../../model/props/viewer/VisualizationStrategyProp\";\nimport type { TwistyPlayerModel } from \"../../model/TwistyPlayerModel\";\nimport { ClassListManager } from \"../ClassListManager\";\nimport { InitialValueTracker } from \"../InitialValueTracker\";\nimport { ManagedCustomElement } from \"../ManagedCustomElement\";\nimport { customElementsShim } from \"../node-custom-element-shims\";\nimport { twistyViewerWrapperCSS } from \"../TwistyViewerWrapper.css\";\nimport type { PressInfo } from \"./DragTracker\";\nimport { Twisty3DPuzzleWrapper } from \"./Twisty3DPuzzleWrapper\";\nimport { Twisty3DVantage } from \"./Twisty3DVantage\";\n\nexport class Twisty3DSceneWrapper\n extends ManagedCustomElement\n implements Schedulable\n{\n // @ts-expect-error TypeScript type inference appears to be borked: ts(2322)\n #backViewClassListManager: ClassListManager<BackViewLayoutWithAuto> =\n new ClassListManager(this, \"back-view-\", [\n \"auto\",\n \"none\",\n \"side-by-side\",\n \"top-right\",\n ]);\n\n #freshListenerManager = new FreshListenerManager();\n disconnect(): void {\n this.#freshListenerManager.disconnect();\n }\n\n constructor(public model?: TwistyPlayerModel) {\n super();\n }\n\n async connectedCallback(): Promise<void> {\n this.addCSS(twistyViewerWrapperCSS);\n const vantage = new Twisty3DVantage(this.model, this);\n this.addVantage(vantage);\n if (this.model) {\n this.#freshListenerManager.addMultiListener(\n [this.model.puzzleLoader, this.model.visualizationStrategy],\n this.onPuzzle.bind(this),\n );\n this.#freshListenerManager.addListener(\n this.model.backView,\n // @ts-expect-error TypeScript type inference appears to be borked: ts(2322)\n this.setBackView.bind(this),\n );\n }\n this.scheduleRender();\n }\n\n #backViewVantage: Twisty3DVantage | null = null;\n setBackView(backView: BackViewLayoutWithAuto): void {\n const shouldHaveBackView = [\"side-by-side\", \"top-right\"].includes(backView);\n const hasBackView = this.#backViewVantage !== null;\n\n this.#backViewClassListManager.setValue(backView);\n if (shouldHaveBackView) {\n if (!hasBackView) {\n this.#backViewVantage = new Twisty3DVantage(this.model, this, {\n backView: true,\n });\n this.addVantage(this.#backViewVantage);\n this.scheduleRender();\n }\n } else {\n if (this.#backViewVantage) {\n this.removeVantage(this.#backViewVantage);\n this.#backViewVantage = null;\n }\n }\n }\n\n async onPress(\n e: CustomEvent<{\n pressInfo: PressInfo;\n cameraPromise: Promise<PerspectiveCamera>;\n }>,\n ): Promise<void> {\n const twisty3DPuzzleWrapper = this.#currentTwisty3DPuzzleWrapper;\n if (!twisty3DPuzzleWrapper) {\n console.info(\"no wrapper; skipping scene wrapper press!\");\n return;\n }\n\n const raycasterPromise = (async () => {\n const [camera, { ThreeRaycaster, ThreeVector2 }] = await Promise.all([\n e.detail.cameraPromise,\n (async () => {\n const { ThreeRaycaster, ThreeVector2 } = await bulk3DCode();\n return { ThreeRaycaster, ThreeVector2 };\n })(),\n ]);\n\n const raycaster = new ThreeRaycaster();\n const mouse = new ThreeVector2(\n e.detail.pressInfo.normalizedX,\n e.detail.pressInfo.normalizedY,\n );\n raycaster.setFromCamera(mouse, camera);\n return raycaster;\n })();\n\n twisty3DPuzzleWrapper.raycastMove(raycasterPromise, {\n invert: !e.detail.pressInfo.rightClick,\n depth: e.detail.pressInfo.keys.ctrlOrMetaKey\n ? \"rotation\"\n : e.detail.pressInfo.keys.shiftKey\n ? \"secondSlice\"\n : \"none\",\n });\n }\n\n #cachedScene?: Promise<ThreeScene>;\n async scene(): Promise<ThreeScene> {\n return (this.#cachedScene ??= (async () =>\n new (await bulk3DCode()).ThreeScene())());\n }\n\n #vantages: Set<Twisty3DVantage> = new Set();\n addVantage(vantage: Twisty3DVantage) {\n vantage.addEventListener(\n \"press\",\n this.onPress.bind(this) as any as EventListener, // TODO: https://github.com/microsoft/TypeScript/issues/28357\n );\n this.#vantages.add(vantage);\n this.contentWrapper.appendChild(vantage);\n }\n\n removeVantage(vantage: Twisty3DVantage) {\n this.#vantages.delete(vantage);\n vantage.remove();\n vantage.disconnect();\n this.#currentTwisty3DPuzzleWrapper?.disconnect();\n }\n\n experimentalVantages(): Iterable<Twisty3DVantage> {\n return this.#vantages.values();\n }\n\n scheduleRender(): void {\n for (const vantage of this.#vantages) {\n vantage.scheduleRender();\n }\n }\n\n #currentTwisty3DPuzzleWrapper: Twisty3DPuzzleWrapper | null = null;\n // #oldTwisty3DPuzzleWrappers: Twisty3DPuzzleWrapper[] = []; // TODO: Animate these out.\n async setCurrentTwisty3DPuzzleWrapper(\n scene: ThreeScene,\n twisty3DPuzzleWrapper: Twisty3DPuzzleWrapper,\n ): Promise<void> {\n const old = this.#currentTwisty3DPuzzleWrapper;\n try {\n this.#currentTwisty3DPuzzleWrapper = twisty3DPuzzleWrapper;\n old?.disconnect();\n scene.add(await twisty3DPuzzleWrapper.twisty3DPuzzle());\n } finally {\n if (old) {\n // We wait for the new puzzle to be in place before removing the old one.\n scene.remove(await old.twisty3DPuzzle());\n }\n }\n this.#initialWrapperTracker.handleNewValue(twisty3DPuzzleWrapper);\n }\n\n #initialWrapperTracker = new InitialValueTracker<Twisty3DPuzzleWrapper>();\n /** @deprecated */\n async experimentalTwisty3DPuzzleWrapper(): Promise<Twisty3DPuzzleWrapper> {\n return (\n this.#currentTwisty3DPuzzleWrapper || this.#initialWrapperTracker.promise\n );\n }\n\n #twisty3DStaleDropper: StaleDropper<[ThreeScene, Twisty3DPuzzleWrapper]> =\n new StaleDropper<[ThreeScene, Twisty3DPuzzleWrapper]>();\n\n async onPuzzle(\n inputs: [\n puzzleLoader: PuzzleLoader,\n visualizationStrategy: VisualizationStrategy,\n ],\n ): Promise<void> {\n if (inputs[1] === \"2D\") {\n // We are being asked to render with stale info. Ignore.\n return;\n }\n this.#currentTwisty3DPuzzleWrapper?.disconnect();\n const [scene, twisty3DPuzzleWrapper] =\n await this.#twisty3DStaleDropper.queue(\n Promise.all([\n this.scene(),\n new Twisty3DPuzzleWrapper(this.model!, this, inputs[0], inputs[1]), // TODO\n ]),\n );\n\n void this.setCurrentTwisty3DPuzzleWrapper(scene, twisty3DPuzzleWrapper);\n }\n}\n\ncustomElementsShim.define(\"twisty-3d-scene-wrapper\", Twisty3DSceneWrapper);\n", "// Use like this:\n// const enabled = globalSafeDocument?.fullscreenEnabled;\nexport const globalSafeDocument: Document | null =\n typeof document === \"undefined\" ? null : document;\n", "// Ponyfills for prefixing in Safari.\n\nimport { globalSafeDocument } from \"../document\";\n\ndeclare global {\n interface Document {\n webkitFullscreenEnabled?: boolean;\n webkitExitFullscreen?: () => Promise<void>;\n webkitFullscreenElement?: Element | null;\n }\n\n interface Element {\n webkitRequestFullscreen: () => Promise<void>;\n }\n}\n\n// TODO: Can `webkitFullscreenEnabled` change after it's cached at page load?\nexport const fullscreenEnabled: boolean =\n globalSafeDocument?.fullscreenEnabled ||\n !!globalSafeDocument?.webkitFullscreenEnabled;\n\nexport function documentExitFullscreen(): Promise<void> {\n if (document.exitFullscreen) {\n return document.exitFullscreen();\n } else {\n return document.webkitExitFullscreen!(); // YOLO\n }\n}\n\nexport function documentFullscreenElement(): Element | null {\n if (document.fullscreenElement) {\n return document.fullscreenElement;\n } else {\n return document.webkitFullscreenElement ?? null;\n }\n}\n\nexport function requestFullscreen(element: Element): Promise<void> {\n if (element.requestFullscreen) {\n return element.requestFullscreen();\n } else {\n return element.webkitRequestFullscreen();\n }\n}\n", "import type { ButtonCommand } from \"../../../views/control-panel/TwistyButtons\";\nimport { fullscreenEnabled } from \"../../../views/control-panel/webkit-fullscreen\";\nimport { TwistyPropDerived } from \"../TwistyProp\";\nimport type { CoarseTimelineInfo } from \"../timeline/CoarseTimelineInfoProp\";\nimport type { ViewerLinkPageWithAuto } from \"./ViewerLinkProp\";\n\nexport const buttonIcons = [\n \"skip-to-start\",\n \"skip-to-end\",\n \"step-forward\",\n \"step-backward\",\n \"pause\",\n \"play\",\n \"enter-fullscreen\",\n \"exit-fullscreen\",\n \"twizzle-tw\",\n];\nexport type ButtonIcon = (typeof buttonIcons)[number];\n\ninterface ButtonAppearance {\n enabled: boolean;\n icon: ButtonIcon;\n title: string;\n hidden?: boolean;\n}\nexport type ButtonAppearances = Record<ButtonCommand, ButtonAppearance>;\n\n// TODO: reduce inputs to avoid unnecessary updates.\ninterface ButtonAppearancePropInputs {\n coarseTimelineInfo: CoarseTimelineInfo;\n viewerLink: ViewerLinkPageWithAuto;\n}\n\nexport class ButtonAppearanceProp extends TwistyPropDerived<\n ButtonAppearancePropInputs,\n ButtonAppearances\n> {\n // TODO: This still seems to fire twice for play/pause?\n derive(inputs: ButtonAppearancePropInputs): ButtonAppearances {\n const buttonAppearances = {\n fullscreen: {\n // TODO: Cache?// TODO: Cache?\n enabled: fullscreenEnabled,\n icon:\n // TODO: Check against the expected element?\n // TODO: This will *not* update when we enter/leave fullscreen. We need to work more closely with the controller.\n document.fullscreenElement === null\n ? \"enter-fullscreen\"\n : \"exit-fullscreen\",\n title: \"Enter fullscreen\",\n },\n \"jump-to-start\": {\n enabled: !inputs.coarseTimelineInfo.atStart,\n icon: \"skip-to-start\",\n title: \"Restart\",\n },\n \"play-step-backwards\": {\n enabled: !inputs.coarseTimelineInfo.atStart,\n icon: \"step-backward\",\n title: \"Step backward\",\n },\n \"play-pause\": {\n enabled: !(\n inputs.coarseTimelineInfo.atStart && inputs.coarseTimelineInfo.atEnd\n ),\n icon: inputs.coarseTimelineInfo.playing ? \"pause\" : \"play\",\n title: inputs.coarseTimelineInfo.playing ? \"Pause\" : \"Play\",\n },\n \"play-step\": {\n enabled: !inputs.coarseTimelineInfo.atEnd,\n icon: \"step-forward\",\n title: \"Step forward\",\n },\n \"jump-to-end\": {\n enabled: !inputs.coarseTimelineInfo.atEnd,\n icon: \"skip-to-end\",\n title: \"Skip to End\",\n },\n \"twizzle-link\": {\n enabled: true,\n icon: \"twizzle-tw\",\n title: \"View at Twizzle\",\n hidden: inputs.viewerLink === \"none\",\n },\n };\n return buttonAppearances;\n }\n}\n", "import { cssStyleSheetShim } from \"../node-custom-element-shims\";\n\nexport const buttonGridCSS = new cssStyleSheetShim();\nbuttonGridCSS.replaceSync(\n `\n:host {\n width: 384px;\n height: 24px;\n display: grid;\n}\n\n.wrapper {\n width: 100%;\n height: 100%;\n display: grid;\n overflow: hidden;\n backdrop-filter: blur(4px);\n -webkit-backdrop-filter: blur(4px);\n}\n\n.wrapper {\n grid-auto-flow: column;\n}\n\n.viewer-link-none .twizzle-link-button {\n display: none;\n}\n\n.wrapper twisty-button,\n.wrapper twisty-control-button {\n width: inherit;\n height: inherit;\n}\n`,\n);\n\nexport const buttonCSS = new cssStyleSheetShim();\nbuttonCSS.replaceSync(\n `\n:host:not([hidden]) {\n display: grid;\n}\n\n:host {\n width: 48px;\n height: 24px;\n}\n\n.wrapper {\n width: 100%;\n height: 100%;\n}\n\nbutton {\n width: 100%;\n height: 100%;\n border: none;\n \n background-position: center;\n background-repeat: no-repeat;\n background-size: contain;\n\n background-color: rgba(196, 196, 196, 0.75);\n}\n\nbutton:enabled {\n background-color: rgba(196, 196, 196, 0.75)\n}\n\n.dark-mode button:enabled {\n background-color: #88888888;\n}\n\nbutton:disabled {\n background-color: rgba(0, 0, 0, 0.4);\n opacity: 0.25;\n pointer-events: none;\n}\n\n.dark-mode button:disabled {\n background-color: #ffffff44;\n}\n\nbutton:enabled:hover {\n background-color: rgba(255, 255, 255, 0.75);\n box-shadow: 0 0 1em rgba(0, 0, 0, 0.25);\n cursor: pointer;\n}\n\n/* TODO: fullscreen icons have too much padding?? */\n.svg-skip-to-start button,\nbutton.svg-skip-to-start {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNTg0IiBoZWlnaHQ9IjM1ODQiIHZpZXdCb3g9IjAgMCAzNTg0IDM1ODQiPjxwYXRoIGQ9Ik0yNjQzIDEwMzdxMTktMTkgMzItMTN0MTMgMzJ2MTQ3MnEwIDI2LTEzIDMydC0zMi0xM2wtNzEwLTcxMHEtOS05LTEzLTE5djcxMHEwIDI2LTEzIDMydC0zMi0xM2wtNzEwLTcxMHEtOS05LTEzLTE5djY3OHEwIDI2LTE5IDQ1dC00NSAxOUg5NjBxLTI2IDAtNDUtMTl0LTE5LTQ1VjEwODhxMC0yNiAxOS00NXQ0NS0xOWgxMjhxMjYgMCA0NSAxOXQxOSA0NXY2NzhxNC0xMSAxMy0xOWw3MTAtNzEwcTE5LTE5IDMyLTEzdDEzIDMydjcxMHE0LTExIDEzLTE5eiIvPjwvc3ZnPg==\");\n}\n\n.svg-skip-to-end button,\nbutton.svg-skip-to-end {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNTg0IiBoZWlnaHQ9IjM1ODQiIHZpZXdCb3g9IjAgMCAzNTg0IDM1ODQiPjxwYXRoIGQ9Ik05NDEgMjU0N3EtMTkgMTktMzIgMTN0LTEzLTMyVjEwNTZxMC0yNiAxMy0zMnQzMiAxM2w3MTAgNzEwcTggOCAxMyAxOXYtNzEwcTAtMjYgMTMtMzJ0MzIgMTNsNzEwIDcxMHE4IDggMTMgMTl2LTY3OHEwLTI2IDE5LTQ1dDQ1LTE5aDEyOHEyNiAwIDQ1IDE5dDE5IDQ1djE0MDhxMCAyNi0xOSA0NXQtNDUgMTloLTEyOHEtMjYgMC00NS0xOXQtMTktNDV2LTY3OHEtNSAxMC0xMyAxOWwtNzEwIDcxMHEtMTkgMTktMzIgMTN0LTEzLTMydi03MTBxLTUgMTAtMTMgMTl6Ii8+PC9zdmc+\");\n}\n\n.svg-step-forward button,\nbutton.svg-step-forward {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNTg0IiBoZWlnaHQ9IjM1ODQiIHZpZXdCb3g9IjAgMCAzNTg0IDM1ODQiPjxwYXRoIGQ9Ik0yNjg4IDE1NjhxMCAyNi0xOSA0NWwtNTEyIDUxMnEtMTkgMTktNDUgMTl0LTQ1LTE5cS0xOS0xOS0xOS00NXYtMjU2aC0yMjRxLTk4IDAtMTc1LjUgNnQtMTU0IDIxLjVxLTc2LjUgMTUuNS0xMzMgNDIuNXQtMTA1LjUgNjkuNXEtNDkgNDIuNS04MCAxMDF0LTQ4LjUgMTM4LjVxLTE3LjUgODAtMTcuNSAxODEgMCA1NSA1IDEyMyAwIDYgMi41IDIzLjV0Mi41IDI2LjVxMCAxNS04LjUgMjV0LTIzLjUgMTBxLTE2IDAtMjgtMTctNy05LTEzLTIydC0xMy41LTMwcS03LjUtMTctMTAuNS0yNC0xMjctMjg1LTEyNy00NTEgMC0xOTkgNTMtMzMzIDE2Mi00MDMgODc1LTQwM2gyMjR2LTI1NnEwLTI2IDE5LTQ1dDQ1LTE5cTI2IDAgNDUgMTlsNTEyIDUxMnExOSAxOSAxOSA0NXoiLz48L3N2Zz4=\");\n}\n\n.svg-step-backward button,\nbutton.svg-step-backward {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNTg0IiBoZWlnaHQ9IjM1ODQiIHZpZXdCb3g9IjAgMCAzNTg0IDM1ODQiPjxwYXRoIGQ9Ik0yNjg4IDIwNDhxMCAxNjYtMTI3IDQ1MS0zIDctMTAuNSAyNHQtMTMuNSAzMHEtNiAxMy0xMyAyMi0xMiAxNy0yOCAxNy0xNSAwLTIzLjUtMTB0LTguNS0yNXEwLTkgMi41LTI2LjV0Mi41LTIzLjVxNS02OCA1LTEyMyAwLTEwMS0xNy41LTE4MXQtNDguNS0xMzguNXEtMzEtNTguNS04MC0xMDF0LTEwNS41LTY5LjVxLTU2LjUtMjctMTMzLTQyLjV0LTE1NC0yMS41cS03Ny41LTYtMTc1LjUtNmgtMjI0djI1NnEwIDI2LTE5IDQ1dC00NSAxOXEtMjYgMC00NS0xOWwtNTEyLTUxMnEtMTktMTktMTktNDV0MTktNDVsNTEyLTUxMnExOS0xOSA0NS0xOXQ0NSAxOXExOSAxOSAxOSA0NXYyNTZoMjI0cTcxMyAwIDg3NSA0MDMgNTMgMTM0IDUzIDMzM3oiLz48L3N2Zz4=\");\n}\n\n.svg-pause button,\nbutton.svg-pause {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNTg0IiBoZWlnaHQ9IjM1ODQiIHZpZXdCb3g9IjAgMCAzNTg0IDM1ODQiPjxwYXRoIGQ9Ik0yNTYwIDEwODh2MTQwOHEwIDI2LTE5IDQ1dC00NSAxOWgtNTEycS0yNiAwLTQ1LTE5dC0xOS00NVYxMDg4cTAtMjYgMTktNDV0NDUtMTloNTEycTI2IDAgNDUgMTl0MTkgNDV6bS04OTYgMHYxNDA4cTAgMjYtMTkgNDV0LTQ1IDE5aC01MTJxLTI2IDAtNDUtMTl0LTE5LTQ1VjEwODhxMC0yNiAxOS00NXQ0NS0xOWg1MTJxMjYgMCA0NSAxOXQxOSA0NXoiLz48L3N2Zz4=\");\n}\n\n.svg-play button,\nbutton.svg-play {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNTg0IiBoZWlnaHQ9IjM1ODQiIHZpZXdCb3g9IjAgMCAzNTg0IDM1ODQiPjxwYXRoIGQ9Ik0yNDcyLjUgMTgyM2wtMTMyOCA3MzhxLTIzIDEzLTM5LjUgM3QtMTYuNS0zNlYxMDU2cTAtMjYgMTYuNS0zNnQzOS41IDNsMTMyOCA3MzhxMjMgMTMgMjMgMzF0LTIzIDMxeiIvPjwvc3ZnPg==\");\n}\n\n.svg-enter-fullscreen button,\nbutton.svg-enter-fullscreen {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjgiIHZpZXdCb3g9IjAgMCAyOCAyOCIgd2lkdGg9IjI4Ij48cGF0aCBkPSJNMiAyaDI0djI0SDJ6IiBmaWxsPSJub25lIi8+PHBhdGggZD0iTTkgMTZIN3Y1aDV2LTJIOXYtM3ptLTItNGgyVjloM1Y3SDd2NXptMTIgN2gtM3YyaDV2LTVoLTJ2M3pNMTYgN3YyaDN2M2gyVjdoLTV6Ii8+PC9zdmc+\");\n}\n\n.svg-exit-fullscreen button,\nbutton.svg-exit-fullscreen {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjgiIHZpZXdCb3g9IjAgMCAyOCAyOCIgd2lkdGg9IjI4Ij48cGF0aCBkPSJNMiAyaDI0djI0SDJ6IiBmaWxsPSJub25lIi8+PHBhdGggZD0iTTcgMThoM3YzaDJ2LTVIN3Yyem0zLThIN3YyaDVWN2gtMnYzem02IDExaDJ2LTNoM3YtMmgtNXY1em0yLTExVjdoLTJ2NWg1di0yaC0zeiIvPjwvc3ZnPg==\");\n}\n\n.svg-twizzle-tw button,\nbutton.svg-twizzle-tw {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODY0IiBoZWlnaHQ9IjYwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMzk3LjU4MSAxNTEuMTh2NTcuMDg0aC04OS43MDN2MjQwLjM1MmgtNjYuOTU1VjIwOC4yNjRIMTUxLjIydi01Ny4wODNoMjQ2LjM2MXptNTQuMzEgNzEuNjc3bDcuNTEyIDMzLjY5MmMyLjcxOCAxMi4xNiA1LjU4IDI0LjY4IDguNTg0IDM3LjU1NWEyMTgwLjc3NSAyMTgwLjc3NSAwIDAwOS40NDIgMzguODQzIDEyNjYuMyAxMjY2LjMgMCAwMDEwLjA4NiAzNy41NTVjMy43Mi0xMi41OSA3LjM2OC0yNS40NjYgMTAuOTQ1LTM4LjYyOCAzLjU3Ni0xMy4xNjIgNy4wMS0yNi4xMSAxMC4zLTM4Ljg0M2w1Ljc2OS0yMi40NTZjMS4yNDgtNC44ODcgMi40NzItOS43MDUgMy42NzQtMTQuNDU1IDMuMDA0LTExLjg3NSA1LjY1MS0yMi45NjIgNy45NC0zMy4yNjNoNDYuMzU0bDIuMzg0IDEwLjU2M2EyMDAwLjc3IDIwMDAuNzcgMCAwMDMuOTM1IDE2LjgyOGw2LjcxMSAyNy43MWMxLjIxMyA0Ljk1NiAyLjQ1IDkuOTggMy43MDkgMTUuMDczYTMxMTkuNzc3IDMxMTkuNzc3IDAgMDA5Ljg3MSAzOC44NDMgMTI0OS4yMjcgMTI0OS4yMjcgMCAwMDEwLjczIDM4LjYyOCAxOTA3LjYwNSAxOTA3LjYwNSAwIDAwMTAuMzAxLTM3LjU1NSAxMzk3Ljk0IDEzOTcuOTQgMCAwMDkuNjU3LTM4Ljg0M2w0LjQtMTkuMDQ2Yy43MTUtMy4xMyAxLjQyMS02LjIzNiAyLjExOC05LjMyMWw5LjU3Ny00Mi44OGg2Ni41MjZhMjk4OC43MTggMjk4OC43MTggMCAwMS0xOS41MjkgNjYuMzExbC01LjcyOCAxOC40ODJhMzIzNy40NiAzMjM3LjQ2IDAgMDEtMTQuMDE1IDQzLjc1MmMtNi40MzggMTkuNi0xMi43MzMgMzcuNjk4LTE4Ljg4NSA1NC4yOTRsLTMuMzA2IDguODI1Yy00Ljg4NCAxMi44OTgtOS40MzMgMjQuMjYzLTEzLjY0NyAzNC4wOTVoLTQ5Ljc4N2E4NDE3LjI4OSA4NDE3LjI4OSAwIDAxLTIxLjAzMS02NC44MDkgMTI4OC42ODYgMTI4OC42ODYgMCAwMS0xOC44ODUtNjQuODEgMTk3Mi40NDQgMTk3Mi40NDQgMCAwMS0xOC4yNCA2NC44MSAyNTc5LjQxMiAyNTc5LjQxMiAwIDAxLTIwLjM4OCA2NC44MWgtNDkuNzg3Yy00LjY4Mi0xMC45MjYtOS43Mi0yMy43NDMtMTUuMTEtMzguNDUxbC0xLjYyOS00LjQ3Yy01LjI1OC0xNC41MjEtMTAuNjgtMzAuMTkyLTE2LjI2Ni00Ny4wMTRsLTIuNDA0LTcuMjhjLTYuNDM4LTE5LjYtMTMuMDItNDAuMzQ0LTE5Ljc0My02Mi4yMzRhMjk4OC43MDcgMjk4OC43MDcgMCAwMS0xOS41MjktNjYuMzExaDY3LjM4NXoiIGZpbGw9IiM0Mjg1RjQiIGZpbGwtcnVsZT0ibm9uemVybyIvPjwvc3ZnPg==\");\n}\n`,\n);\n// Sized against full-screen dimensions.\n// button.svg-twizzle-tw {\n// background-image: url(\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNzc3IiBoZWlnaHQ9IjUxMyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMzU0LjU4MSAxMDcuMTh2NTcuMDg0aC04OS43MDN2MjQwLjM1MmgtNjYuOTU1VjE2NC4yNjRIMTA4LjIydi01Ny4wODNoMjQ2LjM2MXptNTQuMzEgNzEuNjc3bDcuNTEyIDMzLjY5MmMyLjcxOCAxMi4xNiA1LjU4IDI0LjY4IDguNTg0IDM3LjU1NWEyMTgwLjc3NSAyMTgwLjc3NSAwIDAwOS40NDIgMzguODQzIDEyNjYuMyAxMjY2LjMgMCAwMDEwLjA4NiAzNy41NTVjMy43Mi0xMi41OSA3LjM2OC0yNS40NjYgMTAuOTQ1LTM4LjYyOCAzLjU3Ni0xMy4xNjIgNy4wMS0yNi4xMSAxMC4zLTM4Ljg0M2w1Ljc2OS0yMi40NTZjMS4yNDgtNC44ODcgMi40NzItOS43MDUgMy42NzQtMTQuNDU1IDMuMDA0LTExLjg3NSA1LjY1MS0yMi45NjIgNy45NC0zMy4yNjNoNDYuMzU0bDIuMzg0IDEwLjU2M2EyMDAwLjc3IDIwMDAuNzcgMCAwMDMuOTM1IDE2LjgyOGw2LjcxMSAyNy43MWMxLjIxMyA0Ljk1NiAyLjQ1IDkuOTggMy43MDkgMTUuMDczYTMxMTkuNzc3IDMxMTkuNzc3IDAgMDA5Ljg3MSAzOC44NDMgMTI0OS4yMjcgMTI0OS4yMjcgMCAwMDEwLjczIDM4LjYyOCAxOTA3LjYwNSAxOTA3LjYwNSAwIDAwMTAuMzAxLTM3LjU1NSAxMzk3Ljk0IDEzOTcuOTQgMCAwMDkuNjU3LTM4Ljg0M2w0LjQtMTkuMDQ2Yy43MTUtMy4xMyAxLjQyMS02LjIzNiAyLjExOC05LjMyMWw5LjU3Ny00Mi44OGg2Ni41MjZhMjk4OC43MTggMjk4OC43MTggMCAwMS0xOS41MjkgNjYuMzExbC01LjcyOCAxOC40ODJhMzIzNy40NiAzMjM3LjQ2IDAgMDEtMTQuMDE1IDQzLjc1MmMtNi40MzggMTkuNi0xMi43MzMgMzcuNjk4LTE4Ljg4NSA1NC4yOTRsLTMuMzA2IDguODI1Yy00Ljg4NCAxMi44OTgtOS40MzMgMjQuMjYzLTEzLjY0NyAzNC4wOTVoLTQ5Ljc4N2E4NDE3LjI4OSA4NDE3LjI4OSAwIDAxLTIxLjAzMS02NC44MDkgMTI4OC42ODYgMTI4OC42ODYgMCAwMS0xOC44ODUtNjQuODEgMTk3Mi40NDQgMTk3Mi40NDQgMCAwMS0xOC4yNCA2NC44MSAyNTc5LjQxMiAyNTc5LjQxMiAwIDAxLTIwLjM4OCA2NC44MWgtNDkuNzg3Yy00LjY4Mi0xMC45MjYtOS43Mi0yMy43NDMtMTUuMTEtMzguNDUxbC0xLjYyOS00LjQ3Yy01LjI1OC0xNC41MjEtMTAuNjgtMzAuMTkyLTE2LjI2Ni00Ny4wMTRsLTIuNDA0LTcuMjhjLTYuNDM4LTE5LjYtMTMuMDItNDAuMzQ0LTE5Ljc0My02Mi4yMzRhMjk4OC43MDcgMjk4OC43MDcgMCAwMS0xOS41MjktNjYuMzExaDY3LjM4NXoiIGZpbGw9IiM0Mjg1RjQiIGZpbGwtcnVsZT0ibm9uemVybyIvPjwvc3ZnPg==\");\n// }\n", "import { BoundaryType, Direction } from \"../../controllers/AnimationTypes\";\nimport type { TwistyPlayerController } from \"../../controllers/TwistyPlayerController\";\nimport {\n type ButtonAppearances,\n type ButtonIcon,\n buttonIcons,\n} from \"../../model/props/viewer/ButtonAppearanceProp\";\nimport type { ColorScheme } from \"../../model/props/viewer/ColorSchemeRequestProp\";\nimport type { TwistyPlayerModel } from \"../../model/TwistyPlayerModel\";\nimport { ClassListManager } from \"../ClassListManager\";\nimport { ManagedCustomElement } from \"../ManagedCustomElement\";\nimport { customElementsShim } from \"../node-custom-element-shims\";\nimport { buttonCSS, buttonGridCSS } from \"./TwistyButtons.css\";\nimport {\n documentExitFullscreen,\n documentFullscreenElement,\n requestFullscreen,\n} from \"./webkit-fullscreen\";\n\nconst buttonCommands = {\n fullscreen: true,\n \"jump-to-start\": true,\n \"play-step-backwards\": true,\n \"play-pause\": true,\n \"play-step\": true,\n \"jump-to-end\": true,\n \"twizzle-link\": true,\n};\n\nexport type ButtonCommand = keyof typeof buttonCommands;\n\nexport class TwistyButtons extends ManagedCustomElement {\n buttons: Record<ButtonCommand, TwistyButton> | null = null;\n\n // TODO: Privacy\n constructor(\n public model?: TwistyPlayerModel,\n public controller?: TwistyPlayerController,\n private defaultFullscreenElement?: HTMLElement,\n ) {\n super();\n }\n\n connectedCallback(): void {\n this.addCSS(buttonGridCSS);\n const buttons: Partial<Record<ButtonCommand, TwistyButton>> = {};\n for (const command in buttonCommands) {\n const button = new TwistyButton();\n buttons[command as ButtonCommand] = button;\n button.htmlButton.addEventListener(\"click\", () =>\n this.#onCommand(command as ButtonCommand),\n );\n this.addElement(button);\n }\n this.buttons = buttons as Record<ButtonCommand, TwistyButton>;\n\n this.model?.buttonAppearance.addFreshListener(this.update.bind(this));\n this.model?.twistySceneModel.colorScheme.addFreshListener(\n this.updateColorScheme.bind(this),\n );\n }\n\n #onCommand(command: ButtonCommand) {\n switch (command) {\n case \"fullscreen\": {\n void this.onFullscreenButton();\n break;\n }\n case \"jump-to-start\": {\n this.controller?.jumpToStart({ flash: true });\n break;\n }\n case \"play-step-backwards\": {\n this.controller?.animationController.play({\n direction: Direction.Backwards,\n untilBoundary: BoundaryType.Move,\n });\n break;\n }\n case \"play-pause\": {\n this.controller?.togglePlay();\n break;\n }\n case \"play-step\": {\n this.controller?.animationController.play({\n direction: Direction.Forwards,\n untilBoundary: BoundaryType.Move,\n });\n break;\n }\n case \"jump-to-end\": {\n this.controller?.jumpToEnd({ flash: true });\n break;\n }\n case \"twizzle-link\": {\n void this.controller?.visitTwizzleLink();\n break;\n }\n default:\n throw new Error(\"Missing command\");\n }\n }\n\n // TODO: Should we have a prop, or a way to query if we're fullscreen?\n // https://developer.mozilla.org/en-US/docs/Web/API/Element/requestFullScreen\n async onFullscreenButton(): Promise<void> {\n if (!this.defaultFullscreenElement) {\n throw new Error(\"Attempted to go fullscreen without an element.\");\n }\n\n if (documentFullscreenElement() === this.defaultFullscreenElement) {\n void documentExitFullscreen();\n } else {\n // TODO: Propagate button info to `ButtonAppearanceProp`.\n this.buttons?.fullscreen.setIcon(\"exit-fullscreen\");\n\n void requestFullscreen(\n (await this.model?.twistySceneModel.fullscreenElement.get()) ??\n this.defaultFullscreenElement,\n );\n\n const onFullscreen = (): void => {\n if (documentFullscreenElement() !== this.defaultFullscreenElement) {\n this.buttons?.fullscreen.setIcon(\"enter-fullscreen\");\n globalThis.removeEventListener(\"fullscreenchange\", onFullscreen);\n }\n };\n globalThis.addEventListener(\"fullscreenchange\", onFullscreen);\n }\n }\n\n async update(buttonAppearances: ButtonAppearances): Promise<void> {\n // TODO: Check that we have every command?\n for (const command in buttonCommands) {\n // TODO: Why doesn't `command` have the type `ButtonCommand`?\n const button = this.buttons![command as ButtonCommand];\n // TODO: track individual changes?\n const info = buttonAppearances[command as ButtonCommand];\n button.htmlButton.disabled = !info.enabled;\n button.htmlButton.title = info.title;\n button.setIcon(info.icon);\n button.hidden = !!info.hidden;\n // button.textContent = info.icon;\n }\n }\n\n updateColorScheme(colorScheme: ColorScheme): void {\n for (const button of Object.values(this.buttons ?? {})) {\n button.updateColorScheme(colorScheme);\n }\n }\n}\n\ncustomElementsShim.define(\"twisty-buttons\", TwistyButtons);\n\nclass TwistyButton extends ManagedCustomElement {\n htmlButton: HTMLButtonElement = document.createElement(\"button\"); // TODO: async?\n\n updateColorScheme(colorScheme: ColorScheme): void {\n this.contentWrapper.classList.toggle(\"dark-mode\", colorScheme === \"dark\");\n }\n\n connectedCallback() {\n this.addCSS(buttonCSS);\n this.addElement(this.htmlButton);\n }\n\n #iconManager: ClassListManager<ButtonIcon> = new ClassListManager(\n this,\n \"svg-\",\n buttonIcons,\n );\n\n setIcon(iconName: ButtonIcon): void {\n this.#iconManager.setValue(iconName);\n }\n}\n\ncustomElementsShim.define(\"twisty-button\", TwistyButton);\n", "import { cssStyleSheetShim } from \"../node-custom-element-shims\";\n\nexport const twistyScrubberCSS = new cssStyleSheetShim();\ntwistyScrubberCSS.replaceSync(\n `\n:host {\n width: 384px;\n height: 16px;\n display: grid;\n}\n\n.wrapper {\n width: 100%;\n height: 100%;\n display: grid;\n overflow: hidden;\n backdrop-filter: blur(4px);\n -webkit-backdrop-filter: blur(4px);\n background: rgba(196, 196, 196, 0.75);\n}\n\ninput:not(:disabled) {\n cursor: ew-resize;\n}\n\n.wrapper.dark-mode {\n background: #666666;\n}\n`,\n);\n", "import {\n BoundaryType,\n Direction,\n type MillisecondTimestamp,\n} from \"../../controllers/AnimationTypes\";\nimport type { TwistyPlayerController } from \"../../controllers/TwistyPlayerController\";\nimport type { DetailedTimelineInfo } from \"../../model/props/timeline/DetailedTimelineInfoProp\";\nimport type { ColorScheme } from \"../../model/props/viewer/ColorSchemeRequestProp\";\nimport type { TwistyPlayerModel } from \"../../model/TwistyPlayerModel\";\nimport { globalSafeDocument } from \"../document\";\nimport { ManagedCustomElement } from \"../ManagedCustomElement\";\nimport { customElementsShim } from \"../node-custom-element-shims\";\nimport { twistyScrubberCSS } from \"./TwistyScrubber.css\";\n\nconst SLOW_DOWN_SCRUBBING = false;\n\nlet isMouseDown = false;\n\nglobalSafeDocument?.addEventListener(\n \"mousedown\",\n (event) => {\n if (event.which) {\n isMouseDown = true;\n }\n },\n true,\n);\n\nglobalSafeDocument?.addEventListener(\n \"mouseup\",\n (event) => {\n if (event.which) {\n isMouseDown = false;\n }\n },\n true,\n);\n\n// var x = 0;\nlet y = 0;\nlet clickNum = 0;\n\nglobalSafeDocument?.addEventListener(\n \"mousedown\",\n () => {\n clickNum++;\n },\n false,\n);\n\nglobalSafeDocument?.addEventListener(\"mousemove\", onMouseUpdate, false);\nglobalSafeDocument?.addEventListener(\"mouseenter\", onMouseUpdate, false);\n\nfunction onMouseUpdate(e: MouseEvent) {\n // x = e.pageX;\n y = e.pageY;\n // console.log(x, y);\n}\n\nconst lastVal = 0;\nlet lastPreval = 0;\nlet scaling: boolean = false;\nlet currentClickNum = 0;\n\n// Values are integers.\nexport class TwistyScrubber extends ManagedCustomElement {\n constructor(\n public model?: TwistyPlayerModel,\n public controller?: TwistyPlayerController,\n ) {\n super();\n }\n\n async onDetailedTimelineInfo(\n detailedTimelineInfo: DetailedTimelineInfo,\n ): Promise<void> {\n // TODO: is this efficient enough?\n const inputElem = await this.inputElem();\n inputElem.min = detailedTimelineInfo.timeRange.start.toString();\n inputElem.max = detailedTimelineInfo.timeRange.end.toString();\n inputElem.disabled = inputElem.min === inputElem.max;\n inputElem.value = detailedTimelineInfo.timestamp.toString();\n }\n\n async connectedCallback(): Promise<void> {\n this.addCSS(twistyScrubberCSS);\n this.addElement(await this.inputElem());\n this.model?.twistySceneModel.colorScheme.addFreshListener(\n this.updateColorScheme.bind(this),\n );\n }\n\n updateColorScheme(colorScheme: ColorScheme): void {\n this.contentWrapper.classList.toggle(\"dark-mode\", colorScheme === \"dark\");\n }\n\n #inputElem: Promise<HTMLInputElement> | null = null;\n async inputElem(): Promise<HTMLInputElement> {\n // console.log(\"inputElem\", this.#inputElem);\n return (this.#inputElem ??= (async () => {\n const elem = document.createElement(\"input\");\n elem.type = \"range\";\n elem.disabled = true;\n\n // console.log(\"1\");\n this.model?.detailedTimelineInfo.addFreshListener(\n this.onDetailedTimelineInfo.bind(this),\n );\n // console.log(\"3\");\n elem.addEventListener(\"input\", this.onInput.bind(this));\n elem.addEventListener(\"keydown\", this.onKeypress.bind(this));\n\n return elem;\n })());\n }\n\n async onInput(e: Event): Promise<void> {\n if (scaling) {\n return; // TODO\n }\n const inputElem = await this.inputElem();\n await this.slowDown(e, inputElem); // TODO\n\n const value = parseInt(inputElem.value, 10) as MillisecondTimestamp;\n // console.log(\"on input\", value);\n this.model?.playingInfo.set({ playing: false });\n this.model?.timestampRequest.set(value);\n }\n\n onKeypress(e: KeyboardEvent): void {\n switch (e.key) {\n case \"ArrowLeft\":\n // fallthrough\n case \"ArrowRight\": {\n this.controller?.animationController.play({\n direction:\n e.key === \"ArrowLeft\" ? Direction.Backwards : Direction.Forwards,\n untilBoundary: BoundaryType.Move,\n });\n e.preventDefault();\n break;\n }\n case \" \": {\n this.controller?.togglePlay();\n e.preventDefault();\n break;\n }\n }\n }\n\n async slowDown(e: Event, inputElem: HTMLInputElement): Promise<void> {\n if (!SLOW_DOWN_SCRUBBING) {\n return; // TODO\n }\n\n if (isMouseDown) {\n const rect = inputElem.getBoundingClientRect();\n const sliderY = rect.top + rect.height / 2;\n console.log(sliderY, e, y, isMouseDown);\n\n const yDist = Math.abs(sliderY - y);\n let scale = 1;\n if (yDist > 64) {\n scale = Math.max(2 ** (-(yDist - 64) / 64), 1 / 32);\n }\n const preVal = parseInt(inputElem.value, 10);\n console.log(\"cl\", currentClickNum, clickNum, preVal);\n if (currentClickNum === clickNum) {\n const delta = (preVal - lastPreval) * scale;\n console.log(\"delta\", delta, yDist);\n scaling = true;\n let newVal = preVal;\n newVal =\n lastVal +\n delta * scale +\n (preVal - lastVal) * Math.min(1, (1 / 2) ** ((yDist * yDist) / 64));\n inputElem.value = newVal.toString();\n console.log(scale);\n scaling = false;\n this.contentWrapper.style.opacity = scale.toString();\n } else {\n currentClickNum = clickNum;\n }\n lastPreval = preVal;\n }\n }\n}\n\ncustomElementsShim.define(\"twisty-scrubber\", TwistyScrubber);\n", "import type { PerspectiveCamera } from \"three/src/Three.js\";\nimport { bulk3DCode } from \"../heavy-code-imports/3d\";\nimport type { TwistyPlayerModel } from \"../model/TwistyPlayerModel\";\nimport { rawRenderPooled } from \"./3D/RendererPool\";\nimport { Twisty3DPuzzleWrapper } from \"./3D/Twisty3DPuzzleWrapper\";\nimport { setCameraFromOrbitCoordinates } from \"./3D/Twisty3DVantage\";\n\nexport interface TwistyPlayerScreenshot {\n dataURL: string;\n download: (filename?: string) => Promise<void>;\n}\n\n// TODO: cache\nlet cachedCamera: PerspectiveCamera | null = null;\nexport async function screenshot(\n model: TwistyPlayerModel,\n options?: { width: number; height: number },\n): Promise<TwistyPlayerScreenshot> {\n // TODO: improve async caching\n\n // TODO: Avoid the `_stickering` and `_legacyPosition` calls in favor of proper callbacks.\n const [\n { ThreePerspectiveCamera, ThreeScene },\n puzzleLoader,\n visualizationStrategy,\n _stickering, // TODO\n _stickeringMaskRequest, // TODO\n _legacyPosition,\n orbitCoordinates,\n ] = await Promise.all([\n (async () => {\n const { ThreePerspectiveCamera, ThreeScene } = await bulk3DCode();\n return { ThreePerspectiveCamera, ThreeScene };\n })(),\n await model.puzzleLoader.get(),\n await model.visualizationStrategy.get(),\n await model.twistySceneModel.stickeringRequest.get(),\n await model.twistySceneModel.stickeringMaskRequest.get(),\n await model.legacyPosition.get(),\n await model.twistySceneModel.orbitCoordinates.get(),\n ]);\n\n const width = options?.width ?? 2048;\n const height = options?.height ?? 2048;\n const aspectRatio = width / height;\n const camera = (cachedCamera ??= await (async () => {\n return new ThreePerspectiveCamera(20, aspectRatio, 0.1, 20);\n })());\n\n const scene = new ThreeScene();\n const twisty3DWrapper = new Twisty3DPuzzleWrapper(\n model,\n { scheduleRender: () => {} },\n puzzleLoader,\n visualizationStrategy,\n );\n scene.add(await twisty3DWrapper.twisty3DPuzzle());\n await setCameraFromOrbitCoordinates(camera, orbitCoordinates);\n\n const rendererCanvas = await rawRenderPooled(width, height, scene, camera);\n const dataURL = rendererCanvas.toDataURL();\n\n const defaultFilename = await getDefaultFilename(model);\n\n return {\n dataURL,\n download: async (filename?: string) => {\n downloadURL(dataURL, filename ?? defaultFilename);\n },\n };\n}\n\nexport async function getDefaultFilename(\n model: TwistyPlayerModel,\n): Promise<string> {\n const [puzzleID, algWithIssues] = await Promise.all([\n model.puzzleID.get(),\n model.alg.get(),\n ]);\n return `[${puzzleID}]${\n algWithIssues.alg.experimentalNumChildAlgNodes() === 0\n ? \"\"\n : ` ${algWithIssues.alg.toString()}`\n }`;\n}\n\nexport function downloadURL(\n url: string,\n name: string,\n extension: string = \"png\",\n): void {\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = `${name}.${extension}`;\n a.click();\n}\n", "import { cssStyleSheetShim } from \"./node-custom-element-shims\";\n\n// TODO: figure out why `:host(twisty-player):fullscreen { background-color: white }` doesn't work.\nexport const twistyPlayerCSS = new cssStyleSheetShim();\ntwistyPlayerCSS.replaceSync(\n `\n:host {\n width: 384px;\n height: 256px;\n display: grid;\n\n -webkit-user-select: none;\n user-select: none;\n}\n\n.wrapper {\n display: grid;\n overflow: hidden;\n contain: size;\n grid-template-rows: 7fr minmax(1.5em, 0.5fr) minmax(2em, 1fr);\n}\n\n.wrapper > * {\n width: inherit;\n height: inherit;\n overflow: hidden;\n}\n\n.wrapper.controls-none {\n grid-template-rows: 7fr;\n}\n\n.wrapper.controls-none twisty-scrubber,\n.wrapper.controls-none twisty-control-button-panel ,\n.wrapper.controls-none twisty-scrubber,\n.wrapper.controls-none twisty-buttons {\n display: none;\n}\n\ntwisty-scrubber {\n background: rgba(196, 196, 196, 0.5);\n}\n\n.wrapper.checkered,\n.wrapper.checkered-transparent {\n background-color: #EAEAEA;\n background-image: linear-gradient(45deg, #DDD 25%, transparent 25%, transparent 75%, #DDD 75%, #DDD),\n linear-gradient(45deg, #DDD 25%, transparent 25%, transparent 75%, #DDD 75%, #DDD);\n background-size: 32px 32px;\n background-position: 0 0, 16px 16px;\n}\n\n.wrapper.checkered-transparent {\n background-color: #F4F4F4;\n background-image: linear-gradient(45deg, #DDDDDD88 25%, transparent 25%, transparent 75%, #DDDDDD88 75%, #DDDDDD88),\n linear-gradient(45deg, #DDDDDD88 25%, transparent 25%, transparent 75%, #DDDDDD88 75%, #DDDDDD88);\n}\n\n.wrapper.dark-mode {\n background-color: #444;\n background-image: linear-gradient(45deg, #DDDDDD0b 25%, transparent 25%, transparent 75%, #DDDDDD0b 75%, #DDDDDD0b),\n linear-gradient(45deg, #DDDDDD0b 25%, transparent 25%, transparent 75%, #DDDDDD0b 75%, #DDDDDD0b);\n}\n\n.visualization-wrapper > * {\n width: 100%;\n height: 100%;\n}\n\n.error-elem {\n width: 100%;\n height: 100%;\n display: none;\n place-content: center;\n font-family: sans-serif;\n box-shadow: inset 0 0 2em rgb(255, 0, 0);\n color: red;\n text-shadow: 0 0 0.2em white;\n background: rgba(255, 255, 255, 0.25);\n}\n\n.wrapper.error .visualization-wrapper {\n display: none;\n}\n\n.wrapper.error .error-elem {\n display: grid;\n}\n`,\n);\n", "import { SimpleTwistyPropSource } from \"../TwistyProp\";\n\nexport class ArbitraryStringProp extends SimpleTwistyPropSource<string | null> {\n getDefaultValue(): string | null {\n return null;\n }\n}\n", "import { TwistyPropSource } from \"../TwistyProp\";\n\nexport class URLProp extends TwistyPropSource<URL | null, URL | string | null> {\n getDefaultValue(): URL | null {\n return null;\n }\n\n derive(input: URL | string | null): URL | null {\n if (typeof input === \"string\") {\n return new URL(input, location.href); // TODO\n }\n return input;\n }\n}\n", "import { Alg } from \"../../../../../alg\";\nimport { arrayEquals } from \"../../../helpers\";\nimport { TwistyPropSource } from \"../../TwistyProp\";\n\nexport class AlgIssues {\n // TODO: (string | Error)[]\n\n readonly warnings: readonly string[];\n readonly errors: readonly string[];\n\n constructor(issues?: { warnings?: string[]; errors?: string[] }) {\n // TODO: clone inputs?\n this.warnings = Object.freeze(issues?.warnings ?? []);\n this.errors = Object.freeze(issues?.errors ?? []);\n Object.freeze(this);\n }\n\n add(issues?: { warnings?: string[]; errors?: string[] }) {\n return new AlgIssues({\n warnings: this.warnings.concat(issues?.warnings ?? []),\n errors: this.errors.concat(issues?.errors ?? []),\n });\n }\n\n /** @deprecated */\n log() {\n if (this.errors.length > 0) {\n console.error(`\uD83D\uDEA8 ${this.errors[0]}`);\n } else if (this.warnings.length > 0) {\n console.warn(`\u26A0\uFE0F ${this.warnings[0]}`);\n } else {\n console.info(\"\uD83D\uDE0E No issues!\");\n }\n }\n}\n\nexport interface AlgWithIssues {\n alg: Alg;\n issues: AlgIssues;\n}\n\nexport function algWithIssuesFromString(s: string): AlgWithIssues {\n try {\n const alg = Alg.fromString(s); // TODO: is this safe?\n const warnings = [];\n if (alg.toString() !== s) {\n // TODO: Push this check into the parser and return semantic info (so they can be e.g. highlighted).\n warnings.push(\"Alg is non-canonical!\");\n }\n return {\n alg,\n issues: new AlgIssues({ warnings }),\n };\n } catch (e) {\n return {\n alg: new Alg(),\n issues: new AlgIssues({\n errors: [`Malformed alg: ${(e as Error).toString()}`],\n }),\n };\n }\n}\n\nfunction algWithIssuesEquals(a1: AlgWithIssues, a2: AlgWithIssues): boolean {\n return (\n a1.alg.isIdentical(a2.alg) &&\n arrayEquals(a1.issues.warnings, a2.issues.warnings) &&\n arrayEquals(a1.issues.errors, a2.issues.errors)\n );\n}\n\nexport class AlgProp extends TwistyPropSource<AlgWithIssues, Alg | string> {\n override getDefaultValue(): AlgWithIssues {\n return { alg: new Alg(), issues: new AlgIssues() };\n }\n\n protected override canReuseValue(v1: AlgWithIssues, v2: AlgWithIssues) {\n return algWithIssuesEquals(v1, v2);\n }\n\n protected override async derive(\n newAlg: Alg | string,\n ): Promise<AlgWithIssues> {\n if (typeof newAlg === \"string\") {\n return algWithIssuesFromString(newAlg);\n } else {\n return {\n alg: newAlg,\n issues: new AlgIssues(),\n };\n }\n }\n}\n", "import type { KPuzzle, KTransformation } from \"../../../../../kpuzzle\";\nimport { TwistyPropDerived } from \"../../TwistyProp\";\nimport type { AlgWithIssues } from \"./AlgProp\";\n\ntype AlgTransformationPropInputs = {\n setupAlg: AlgWithIssues;\n kpuzzle: KPuzzle;\n};\n\nexport class AlgTransformationProp extends TwistyPropDerived<\n AlgTransformationPropInputs,\n KTransformation\n> {\n derive(input: AlgTransformationPropInputs): KTransformation {\n return input.kpuzzle.algToTransformation(input.setupAlg.alg);\n }\n}\n", "import type { KTransformation } from \"../../../../../kpuzzle\";\nimport type {\n AlgIndexer,\n LeafIndex,\n} from \"../../../../controllers/indexer/AlgIndexer\";\nimport { TwistyPropDerived } from \"../../TwistyProp\";\nimport type { SetupToLocation } from \"./SetupAnchorProp\";\n\ninterface AnchorTransformationPropInputs {\n setupTransformation: KTransformation | null;\n setupAnchor: SetupToLocation;\n setupAlgTransformation: KTransformation;\n indexer: AlgIndexer;\n}\n\nexport class AnchorTransformationProp extends TwistyPropDerived<\n AnchorTransformationPropInputs,\n KTransformation\n> {\n derive(inputs: AnchorTransformationPropInputs): KTransformation {\n if (inputs.setupTransformation) {\n return inputs.setupTransformation;\n }\n switch (inputs.setupAnchor) {\n case \"start\":\n return inputs.setupAlgTransformation;\n case \"end\": {\n const algTransformation = inputs.indexer.transformationAtIndex(\n inputs.indexer.numAnimatedLeaves() as number as LeafIndex,\n );\n const inverseAlgTransformation = algTransformation.invert();\n return inputs.setupAlgTransformation.applyTransformation(\n inverseAlgTransformation,\n );\n }\n default:\n throw new Error(\"Unimplemented!\");\n }\n }\n}\n", "import type { AlgLeaf } from \"../../../../../alg\";\nimport type { MillisecondTimestamp } from \"../../../../controllers/AnimationTypes\";\nimport { SimpleTwistyPropSource } from \"../../TwistyProp\";\n\nexport interface AnimationTimelineLeaf {\n animLeaf: AlgLeaf;\n start: MillisecondTimestamp;\n end: MillisecondTimestamp;\n}\n\nexport type AnimationTimelineLeaves = AnimationTimelineLeaf[];\n\nexport class AnimationTimelineLeavesRequestProp extends SimpleTwistyPropSource<\n AnimationTimelineLeaf[] | null\n> {\n getDefaultValue(): AnimationTimelineLeaf[] | null {\n return null;\n }\n}\n", "import type { Move } from \"../../../../../alg\";\nimport { SimpleTwistyPropSource } from \"../../TwistyProp\";\n\nexport interface CatchUpMove {\n move: Move | null;\n amount: number;\n}\n\nexport class CatchUpMoveProp extends SimpleTwistyPropSource<CatchUpMove> {\n override getDefaultValue(): CatchUpMove {\n return { move: null, amount: 0 };\n }\n\n protected override canReuseValue(v1: CatchUpMove, v2: CatchUpMove) {\n return v1.move === v2.move && v1.amount === v2.amount;\n }\n}\n", "import type { Move } from \"../../../../../alg\";\nimport type {\n CurrentMoveInfo,\n LeafIndex,\n} from \"../../../../controllers/indexer/AlgIndexer\";\nimport { arrayEqualsCompare } from \"../../../helpers\";\nimport { TwistyPropDerived } from \"../../TwistyProp\";\n\ninterface CurrentLeavesSimplifiedPropInputs {\n currentMoveInfo: CurrentMoveInfo;\n}\n\nexport interface CurrentLeavesSimplified {\n patternIndex: LeafIndex;\n movesFinishing: Move[];\n movesFinished: Move[];\n}\n\n// This started as a version of `CurrentLeaves` without highly timestamp-sensitive info like fractions, to enable easier caching.\nexport class CurrentLeavesSimplifiedProp extends TwistyPropDerived<\n CurrentLeavesSimplifiedPropInputs,\n CurrentLeavesSimplified\n> {\n protected override derive(\n inputs: CurrentLeavesSimplifiedPropInputs,\n ): CurrentLeavesSimplified {\n return {\n patternIndex: inputs.currentMoveInfo.patternIndex as LeafIndex,\n movesFinishing: inputs.currentMoveInfo.movesFinishing.map(\n (currentMoveInfo) => currentMoveInfo.move,\n ),\n movesFinished: inputs.currentMoveInfo.movesFinished.map(\n (currentMoveInfo) => currentMoveInfo.move,\n ),\n };\n }\n\n protected override canReuseValue(\n v1: CurrentLeavesSimplified,\n v2: CurrentLeavesSimplified,\n ): boolean {\n return (\n v1.patternIndex === v2.patternIndex &&\n arrayEqualsCompare(\n v1.movesFinishing,\n v2.movesFinishing,\n (m1: Move, m2: Move) => m1.isIdentical(m2),\n ) &&\n arrayEqualsCompare(\n v1.movesFinished,\n v2.movesFinished,\n (m1: Move, m2: Move) => m1.isIdentical(m2),\n )\n );\n }\n}\n", "import { Move } from \"../../../../../alg\";\nimport {\n Direction,\n type MillisecondTimestamp,\n} from \"../../../../controllers/AnimationTypes\";\nimport type {\n AlgIndexer,\n CurrentMove,\n CurrentMoveInfo,\n} from \"../../../../controllers/indexer/AlgIndexer\";\nimport { TwistyPropDerived } from \"../../TwistyProp\";\nimport type { DetailedTimelineInfo } from \"../../timeline/DetailedTimelineInfoProp\";\nimport type { CatchUpMove } from \"./CatchUpMoveProp\";\n\ninterface PositionPropInputs {\n indexer: AlgIndexer;\n detailedTimelineInfo: DetailedTimelineInfo;\n catchUpMove: CatchUpMove;\n}\n\n// TODO: Rename \"current\" (implies a single one) to \"active\"?\nexport class CurrentMoveInfoProp extends TwistyPropDerived<\n PositionPropInputs,\n CurrentMoveInfo\n> {\n derive(inputs: PositionPropInputs): CurrentMoveInfo {\n function addCatchUpMove(currentMoveInfo: CurrentMoveInfo): CurrentMoveInfo {\n if (\n inputs.detailedTimelineInfo.atEnd &&\n inputs.catchUpMove.move !== null\n ) {\n currentMoveInfo.currentMoves.push({\n move: inputs.catchUpMove.move,\n direction: Direction.Backwards,\n fraction: 1 - inputs.catchUpMove.amount,\n startTimestamp: -1 as MillisecondTimestamp, // TODO\n endTimestamp: -1 as MillisecondTimestamp, // TODO\n });\n }\n return currentMoveInfo;\n }\n\n // Copied from AlgCursor\n if (inputs.indexer.currentMoveInfo) {\n return addCatchUpMove(\n inputs.indexer.currentMoveInfo(inputs.detailedTimelineInfo.timestamp),\n );\n } else {\n const idx = inputs.indexer.timestampToIndex(\n inputs.detailedTimelineInfo.timestamp,\n );\n const currentMoveInfo: CurrentMoveInfo = {\n patternIndex: idx,\n currentMoves: [],\n movesFinishing: [],\n movesFinished: [],\n movesStarting: [],\n latestStart: -Infinity,\n earliestEnd: Infinity,\n };\n\n if (inputs.indexer.numAnimatedLeaves() > 0) {\n const move = inputs.indexer.getAnimLeaf(idx)?.as(Move);\n if (!move) {\n return addCatchUpMove(currentMoveInfo);\n }\n const start = inputs.indexer.indexToMoveStartTimestamp(idx);\n const duration = inputs.indexer.moveDuration(idx);\n const fraction = duration\n ? (inputs.detailedTimelineInfo.timestamp - start) / duration\n : 0;\n const end = (start + duration) as MillisecondTimestamp;\n const currentMove: CurrentMove = {\n move,\n direction: Direction.Forwards,\n fraction,\n startTimestamp: start,\n endTimestamp: end,\n };\n if (fraction === 0) {\n currentMoveInfo.movesStarting.push(currentMove);\n // // TODO: push this into the indexer\n // position.state = combineTransformations(\n // inputs.def,\n // state,\n // transformationForMove(inputs.def, move),\n // ) as Transformation;\n } else if (fraction === 1) {\n currentMoveInfo.movesFinishing.push(currentMove);\n // // TODO: push this into the indexer\n // position.state = combineTransformations(\n // inputs.def,\n // state,\n // transformationForMove(inputs.def, move),\n // ) as Transformation;\n } else {\n // TODO\n currentMoveInfo.currentMoves.push(currentMove);\n currentMoveInfo.latestStart = Math.max(\n currentMoveInfo.latestStart,\n start,\n );\n currentMoveInfo.earliestEnd = Math.min(\n currentMoveInfo.earliestEnd,\n end,\n );\n }\n // }\n // }\n }\n return addCatchUpMove(currentMoveInfo);\n }\n }\n}\n", "import type { KTransformation } from \"../../../../../kpuzzle\";\nimport type { KPattern } from \"../../../../../kpuzzle/KPattern\";\nimport type { AlgIndexer } from \"../../../../controllers/indexer/AlgIndexer\";\nimport { TwistyPropDerived } from \"../../TwistyProp\";\nimport type { CurrentLeavesSimplified } from \"./CurrentLeavesSimplified\";\n\ninterface CurrentTransformationPropInputs {\n anchoredStart: KTransformation; // kpuzzle todo: KPattern?\n currentLeavesSimplified: CurrentLeavesSimplified;\n indexer: AlgIndexer;\n}\n\n// TODO: Make this so we don't have to handle the finishing moves?\nexport class CurrentPatternProp extends TwistyPropDerived<\n CurrentTransformationPropInputs,\n KPattern\n> {\n derive(inputs: CurrentTransformationPropInputs): KPattern {\n let transformation: KTransformation = inputs.indexer.transformationAtIndex(\n inputs.currentLeavesSimplified.patternIndex,\n );\n transformation = inputs.anchoredStart.applyTransformation(transformation);\n\n // TODO: handle non-commutative finished/finishing/current moves.\n for (const finishingMove of inputs.currentLeavesSimplified.movesFinishing) {\n transformation = transformation.applyMove(finishingMove);\n }\n for (const finishedMove of inputs.currentLeavesSimplified.movesFinished) {\n transformation = transformation.applyMove(finishedMove);\n }\n return transformation.toKPattern(); // kpuzzle todo\n }\n}\n", "import {\n type Alg,\n type Commutator,\n type Conjugate,\n functionFromTraversal,\n type Grouping,\n LineComment,\n Move,\n Newline,\n type Pause,\n TraversalUp,\n} from \"../../../../alg\";\nimport type { AnimationTimelineLeaf } from \"../../../model/props/puzzle/state/AnimationTimelineLeavesRequestProp\";\nimport type {\n MillisecondDuration,\n MillisecondTimestamp,\n} from \"../../AnimationTypes\";\nimport { defaultDurationForAmount } from \"../AlgDuration\";\n\nexport type AnimatedLeafAlgNode = Move | Pause;\nexport interface LocalAnimLeavesWithRange {\n animLeafAlgNode: AnimatedLeafAlgNode;\n msUntilNext: MillisecondDuration;\n duration: MillisecondDuration;\n}\n\nconst axisLookup: Record<string, \"x\" | \"y\" | \"z\"> = {\n u: \"y\",\n l: \"x\",\n f: \"z\",\n r: \"x\",\n b: \"z\",\n d: \"y\",\n m: \"x\",\n e: \"y\",\n s: \"z\",\n x: \"x\",\n y: \"y\",\n z: \"z\",\n};\n\nfunction isSameAxis(move1: Move, move2: Move): boolean {\n return (\n axisLookup[move1.family[0].toLowerCase()] ===\n axisLookup[move2.family[0].toLowerCase()]\n );\n}\n\n// TODO: Replace this with an optimized implementation.\n// TODO: Consider `(x U)` and `(U x F)` to be simultaneous.\nexport class LocalSimulMoves extends TraversalUp<LocalAnimLeavesWithRange[]> {\n public traverseAlg(alg: Alg): LocalAnimLeavesWithRange[] {\n const processed: LocalAnimLeavesWithRange[][] = [];\n for (const childAlgNode of alg.childAlgNodes()) {\n processed.push(this.traverseAlgNode(childAlgNode));\n }\n return Array.prototype.concat(...processed) as LocalAnimLeavesWithRange[];\n }\n\n public traverseGroupingOnce(alg: Alg): LocalAnimLeavesWithRange[] {\n if (alg.experimentalIsEmpty()) {\n return [];\n }\n\n const moves: Move[] = [];\n for (const algNode of alg.childAlgNodes()) {\n if (\n !(algNode.is(Move) || algNode.is(LineComment) || algNode.is(Newline))\n ) {\n // TODO: define the type statically on the class?\n return this.traverseAlg(alg);\n }\n const asMove = algNode.as(Move);\n if (asMove) {\n moves.push(asMove);\n }\n }\n\n let maxSimulDur = defaultDurationForAmount(moves[0].amount);\n for (let i = 0; i < moves.length - 1; i++) {\n for (let j = 1; j < moves.length; j++) {\n if (!isSameAxis(moves[i], moves[j])) {\n return this.traverseAlg(alg);\n }\n }\n maxSimulDur = Math.max(\n maxSimulDur,\n defaultDurationForAmount(moves[i].amount),\n ) as MillisecondDuration;\n }\n\n const localMovesWithRange: LocalAnimLeavesWithRange[] = moves.map(\n (blockMove): LocalAnimLeavesWithRange => {\n return {\n animLeafAlgNode: blockMove,\n msUntilNext: 0 as MillisecondDuration,\n duration: maxSimulDur as MillisecondDuration,\n };\n },\n );\n localMovesWithRange[localMovesWithRange.length - 1].msUntilNext =\n maxSimulDur as MillisecondDuration;\n return localMovesWithRange;\n }\n\n public traverseGrouping(grouping: Grouping): LocalAnimLeavesWithRange[] {\n const processed: LocalAnimLeavesWithRange[][] = [];\n\n const segmentOnce: Alg =\n grouping.amount > 0 ? grouping.alg : grouping.alg.invert();\n for (let i = 0; i < Math.abs(grouping.amount); i++) {\n processed.push(this.traverseGroupingOnce(segmentOnce));\n }\n return Array.prototype.concat(...processed) as LocalAnimLeavesWithRange[];\n }\n\n public traverseMove(move: Move): LocalAnimLeavesWithRange[] {\n const duration = defaultDurationForAmount(move.amount);\n return [\n {\n animLeafAlgNode: move,\n msUntilNext: duration,\n duration,\n },\n ];\n }\n\n public traverseCommutator(\n commutator: Commutator,\n ): LocalAnimLeavesWithRange[] {\n const processed: LocalAnimLeavesWithRange[][] = [];\n const segmentsOnce: Alg[] = [\n commutator.A,\n commutator.B,\n commutator.A.invert(),\n commutator.B.invert(),\n ];\n for (const segment of segmentsOnce) {\n processed.push(this.traverseGroupingOnce(segment));\n }\n return Array.prototype.concat(...processed) as LocalAnimLeavesWithRange[];\n }\n\n public traverseConjugate(conjugate: Conjugate): LocalAnimLeavesWithRange[] {\n const processed: LocalAnimLeavesWithRange[][] = [];\n const segmentsOnce: Alg[] = [\n conjugate.A,\n conjugate.B,\n conjugate.A.invert(),\n ];\n for (const segment of segmentsOnce) {\n processed.push(this.traverseGroupingOnce(segment));\n }\n return Array.prototype.concat(...processed) as LocalAnimLeavesWithRange[];\n }\n\n public traversePause(pause: Pause): LocalAnimLeavesWithRange[] {\n if (pause.experimentalNISSGrouping) {\n return [];\n }\n const duration = defaultDurationForAmount(1);\n return [\n {\n animLeafAlgNode: pause,\n msUntilNext: duration, // TODO\n duration,\n },\n ];\n }\n\n public traverseNewline(_newline: Newline): LocalAnimLeavesWithRange[] {\n return [];\n }\n\n public traverseLineComment(\n _comment: LineComment,\n ): LocalAnimLeavesWithRange[] {\n return [];\n }\n}\n\nconst localSimulMoves = functionFromTraversal(LocalSimulMoves);\n\nexport function simulMoves(a: Alg): AnimationTimelineLeaf[] {\n let timestamp = 0;\n const l = localSimulMoves(a).map(\n (localSimulMove: LocalAnimLeavesWithRange): AnimationTimelineLeaf => {\n const leafWithRange = {\n animLeaf: localSimulMove.animLeafAlgNode,\n start: timestamp as MillisecondTimestamp,\n end: (timestamp + localSimulMove.duration) as MillisecondTimestamp,\n };\n timestamp += localSimulMove.msUntilNext;\n return leafWithRange;\n },\n );\n return l;\n}\n", "import { type Alg, Move } from \"../../../../alg\";\nimport type { KPuzzle, KTransformation } from \"../../../../kpuzzle\";\nimport type { KPattern } from \"../../../../kpuzzle/KPattern\";\nimport type {\n AnimationTimelineLeaf,\n AnimationTimelineLeaves,\n} from \"../../../model/props/puzzle/state/AnimationTimelineLeavesRequestProp\";\nimport {\n Direction,\n type MillisecondDuration,\n type MillisecondTimestamp,\n type PuzzlePosition,\n} from \"../../AnimationTypes\";\nimport type {\n CurrentMove,\n CurrentMoveInfo,\n LeafCount,\n LeafIndex,\n} from \"../AlgIndexer\";\nimport { type AnimatedLeafAlgNode, simulMoves } from \"./simul-moves\";\n\nexport class SimultaneousMoveIndexer {\n private animLeaves: AnimationTimelineLeaf[];\n // TODO: Allow custom `durationFn`.\n\n constructor(\n private kpuzzle: KPuzzle,\n alg: Alg,\n options?: { animationTimelineLeaves?: AnimationTimelineLeaves | null },\n ) {\n this.animLeaves = options?.animationTimelineLeaves ?? simulMoves(alg);\n // TODO: Avoid assuming all base moves are block moves.\n }\n\n public getAnimLeaf(index: number): AnimatedLeafAlgNode | null {\n return (\n this.animLeaves[Math.min(index, this.animLeaves.length - 1)]?.animLeaf ??\n null\n );\n }\n\n private getAnimationTimelineLeaf(index: number): AnimationTimelineLeaf {\n return this.animLeaves[Math.min(index, this.animLeaves.length - 1)];\n }\n\n public indexToMoveStartTimestamp(index: number): MillisecondTimestamp {\n let start = 0;\n if (this.animLeaves.length > 0) {\n start =\n this.animLeaves[Math.min(index, this.animLeaves.length - 1)].start;\n }\n return start as MillisecondTimestamp;\n }\n\n public timestampToIndex(timestamp: MillisecondTimestamp): LeafIndex {\n let i = 0;\n for (i = 0; i < this.animLeaves.length; i++) {\n if (this.animLeaves[i].start >= timestamp) {\n return Math.max(0, i - 1) as LeafIndex;\n }\n }\n return Math.max(0, i - 1) as LeafIndex;\n }\n\n public timestampToPosition(\n timestamp: MillisecondTimestamp,\n startPattern?: KPattern,\n ): PuzzlePosition {\n const currentMoveInfo = this.currentMoveInfo(timestamp);\n\n let pattern =\n startPattern ?? this.kpuzzle.identityTransformation().toKPattern();\n for (const leafWithRange of this.animLeaves.slice(\n 0,\n currentMoveInfo.patternIndex,\n )) {\n const move = leafWithRange.animLeaf.as(Move);\n if (move !== null) {\n pattern = pattern.applyMove(move);\n }\n }\n\n return {\n pattern: pattern,\n movesInProgress: currentMoveInfo.currentMoves,\n };\n }\n\n // TODO: Caching\n public currentMoveInfo(timestamp: MillisecondTimestamp): CurrentMoveInfo {\n // The starting timestamp of the earliest active move.\n let windowEarliestTimestamp = Infinity;\n for (const leafWithRange of this.animLeaves) {\n if (leafWithRange.start <= timestamp && leafWithRange.end >= timestamp) {\n windowEarliestTimestamp = Math.min(\n windowEarliestTimestamp,\n leafWithRange.start,\n );\n } else if (leafWithRange.start > timestamp) {\n break;\n }\n }\n\n const currentMoves: CurrentMove[] = [];\n const movesStarting: CurrentMove[] = [];\n const movesFinishing: CurrentMove[] = [];\n const movesFinished: CurrentMove[] = [];\n let latestStart: number = -Infinity; // TODO: is there a better way to accumulate this?\n let earliestEnd: number = Infinity; // TODO: is there a better way to accumulate this?\n\n let patternIndex: number = 0;\n for (const leafWithRange of this.animLeaves) {\n if (leafWithRange.end <= windowEarliestTimestamp) {\n if (\n // biome-ignore lint/suspicious/noGlobalIsFinite: TODO: wait on Biome to remove this check by default\n !isFinite(windowEarliestTimestamp) &&\n leafWithRange.start > timestamp\n ) {\n // Allow for time segments without any active leaf.\n break;\n }\n patternIndex++;\n } else if (leafWithRange.start > timestamp) {\n break;\n } else {\n const move = leafWithRange.animLeaf.as(Move);\n if (move !== null) {\n let fraction =\n (timestamp - leafWithRange.start) /\n (leafWithRange.end - leafWithRange.start);\n let moveFinished = false;\n if (fraction > 1) {\n fraction = 1;\n moveFinished = true;\n }\n const currentMove = {\n move: move,\n direction: Direction.Forwards,\n fraction: fraction,\n startTimestamp: leafWithRange.start,\n endTimestamp: leafWithRange.end,\n };\n switch (fraction) {\n case 0: {\n movesStarting.push(currentMove);\n break;\n }\n case 1: {\n // Generalize this to avoid reordering commuting moves.\n if (moveFinished) {\n movesFinished.push(currentMove);\n } else {\n movesFinishing.push(currentMove);\n }\n break;\n }\n default:\n currentMoves.push(currentMove);\n latestStart = Math.max(latestStart, leafWithRange.start);\n earliestEnd = Math.min(earliestEnd, leafWithRange.end);\n }\n }\n }\n }\n return {\n patternIndex: patternIndex,\n currentMoves,\n latestStart,\n earliestEnd,\n movesStarting,\n movesFinishing,\n movesFinished,\n };\n }\n\n public patternAtIndex(index: number, startPattern?: KPattern): KPattern {\n let pattern = startPattern ?? this.kpuzzle.defaultPattern();\n for (let i = 0; i < this.animLeaves.length && i < index; i++) {\n const leafWithRange = this.animLeaves[i];\n const move = leafWithRange.animLeaf.as(Move);\n if (move !== null) {\n pattern = pattern.applyMove(move);\n }\n }\n return pattern;\n }\n\n public transformationAtIndex(index: number): KTransformation {\n let transformation = this.kpuzzle.identityTransformation();\n for (const leafWithRange of this.animLeaves.slice(0, index)) {\n const move = leafWithRange.animLeaf.as(Move);\n if (move !== null) {\n transformation = transformation.applyMove(move);\n }\n }\n return transformation;\n }\n\n public algDuration(): MillisecondDuration {\n let max = 0;\n for (const leafWithRange of this.animLeaves) {\n max = Math.max(max, leafWithRange.end);\n }\n return max as MillisecondDuration;\n }\n\n public numAnimatedLeaves(): LeafCount {\n // TODO: Cache internally once performance matters.\n return this.animLeaves.length as LeafCount;\n }\n\n public moveDuration(index: LeafIndex): MillisecondDuration {\n const move = this.getAnimationTimelineLeaf(index);\n return (move.end - move.start) as MillisecondDuration;\n }\n}\n", "import type { Alg } from \"../../../../../alg\";\nimport type { KPuzzle } from \"../../../../../kpuzzle\";\nimport { countLeavesInExpansionForSimultaneousMoveIndexer } from \"../../../../../notation/CountMoves\";\nimport type { AlgIndexer } from \"../../../..\";\nimport { SimpleAlgIndexer } from \"../../../../controllers/indexer/SimpleAlgIndexer\";\nimport { SimultaneousMoveIndexer } from \"../../../../controllers/indexer/simultaneous-moves/SimultaneousMoveIndexer\";\nimport { TreeAlgIndexer } from \"../../../../controllers/indexer/tree/TreeAlgIndexer\";\nimport { TwistyPropDerived } from \"../../TwistyProp\";\nimport type { VisualizationStrategy } from \"../../viewer/VisualizationStrategyProp\";\nimport type { PuzzleID } from \"../structure/PuzzleIDRequestProp\";\nimport type { AlgWithIssues } from \"./AlgProp\";\nimport type { AnimationTimelineLeaves } from \"./AnimationTimelineLeavesRequestProp\";\nimport type { IndexerStrategyName } from \"./IndexerConstructorRequestProp\";\n\nexport type IndexerConstructor = new (\n kpuzzle: KPuzzle,\n alg: Alg,\n options?: {\n animationTimelineLeaves?: AnimationTimelineLeaves | null;\n },\n) => AlgIndexer;\n\ninterface IndexerConstructorPropInputs {\n puzzle: PuzzleID;\n alg: AlgWithIssues;\n visualizationStrategy: VisualizationStrategy;\n indexerConstructorRequest: IndexerStrategyName;\n animationTimelineLeaves: AnimationTimelineLeaves | null;\n}\n\n// `SimultaneousMoveIndexer` is currently not optimized and has to expand the alg. This bounds the number of moves in the expanded alg.\nconst SIMULTANEOUS_INDEXER_MAX_EXPANDED_LEAVES = 1024;\n\n// TODO: Also handle PG3D vs. 3D\nexport class IndexerConstructorProp extends TwistyPropDerived<\n IndexerConstructorPropInputs,\n IndexerConstructor\n> {\n derive(inputs: IndexerConstructorPropInputs): IndexerConstructor {\n switch (inputs.indexerConstructorRequest) {\n case \"auto\":\n if (inputs.animationTimelineLeaves !== null) {\n return SimultaneousMoveIndexer;\n }\n if (\n countLeavesInExpansionForSimultaneousMoveIndexer(inputs.alg.alg) <=\n SIMULTANEOUS_INDEXER_MAX_EXPANDED_LEAVES &&\n inputs.puzzle === \"3x3x3\" &&\n inputs.visualizationStrategy === \"Cube3D\"\n ) {\n return SimultaneousMoveIndexer;\n } else {\n return TreeAlgIndexer;\n }\n case \"tree\":\n return TreeAlgIndexer;\n case \"simple\":\n return SimpleAlgIndexer;\n case \"simultaneous\":\n return SimultaneousMoveIndexer;\n default:\n throw new Error(\"Invalid indexer request!\");\n }\n }\n}\n", "import { SimpleTwistyPropSource } from \"../../TwistyProp\";\n\nexport const indexerStrategyNames = {\n auto: true,\n simple: true,\n tree: true,\n simultaneous: true,\n};\nexport type IndexerStrategyName = keyof typeof indexerStrategyNames;\n\nexport class IndexerConstructorRequestProp extends SimpleTwistyPropSource<IndexerStrategyName> {\n getDefaultValue(): IndexerStrategyName {\n return \"auto\";\n }\n}\n", "import type { KPuzzle } from \"../../../../../kpuzzle\";\nimport type { AlgIndexer } from \"../../../../controllers/indexer/AlgIndexer\";\nimport { TwistyPropDerived } from \"../../TwistyProp\";\nimport type { AlgWithIssues } from \"./AlgProp\";\nimport type { AnimationTimelineLeaves } from \"./AnimationTimelineLeavesRequestProp\";\nimport type { IndexerConstructor } from \"./IndexerConstructorProp\";\n\ntype IndexerPropInputs = {\n indexerConstructor: IndexerConstructor;\n algWithIssues: AlgWithIssues;\n kpuzzle: KPuzzle;\n animationTimelineLeaves: AnimationTimelineLeaves | null;\n};\nexport class IndexerProp extends TwistyPropDerived<\n IndexerPropInputs,\n AlgIndexer\n> {\n derive(input: IndexerPropInputs): AlgIndexer {\n return new input.indexerConstructor(\n input.kpuzzle,\n input.algWithIssues.alg,\n { animationTimelineLeaves: input.animationTimelineLeaves },\n );\n }\n}\n", "import type { KPattern } from \"../../../../../kpuzzle/KPattern\";\nimport type { PuzzlePosition } from \"../../../../controllers/AnimationTypes\";\nimport type { CurrentMoveInfo } from \"../../../../controllers/indexer/AlgIndexer\";\nimport { TwistyPropDerived } from \"../../TwistyProp\";\n\nexport interface LegacyPositionPropInputs {\n currentMoveInfo: CurrentMoveInfo;\n currentPattern: KPattern;\n}\n\n// TODO: This exist as a convenience for old `Twisty3D` implementations. Get rid of this.\nexport class LegacyPositionProp extends TwistyPropDerived<\n LegacyPositionPropInputs,\n PuzzlePosition\n> {\n derive(inputs: LegacyPositionPropInputs): PuzzlePosition {\n return {\n pattern: inputs.currentPattern,\n movesInProgress: inputs.currentMoveInfo.currentMoves,\n };\n }\n}\n", "import { Alg } from \"../../../../../alg\";\nimport type { KPuzzle } from \"../../../../../kpuzzle\";\nimport { TwistyPropDerived } from \"../../TwistyProp\";\nimport { AlgIssues, type AlgWithIssues } from \"./AlgProp\";\n\nlet validate: boolean = true;\nexport function experimentalSetPuzzleAlgValidation(newValidate: boolean): void {\n validate = newValidate;\n}\n\nexport class PuzzleAlgProp extends TwistyPropDerived<\n { algWithIssues: AlgWithIssues; kpuzzle: KPuzzle },\n AlgWithIssues\n> {\n async derive(inputs: {\n algWithIssues: AlgWithIssues;\n kpuzzle: KPuzzle;\n }): Promise<AlgWithIssues> {\n try {\n if (validate) {\n inputs.kpuzzle.algToTransformation(inputs.algWithIssues.alg);\n }\n\n // Looks like we could apply the alg!\n return inputs.algWithIssues;\n } catch (e) {\n return {\n alg: new Alg(),\n issues: new AlgIssues({\n errors: [`Invalid alg for puzzle: ${(e as Error).toString()}`],\n }),\n };\n }\n }\n}\n", "import { SimpleTwistyPropSource } from \"../../TwistyProp\";\n\n// TODO: turn these maps into lists?\nexport const setupToLocations = {\n start: true, // default // TODO: \"beginning\"\n end: true,\n};\nexport type SetupToLocation = keyof typeof setupToLocations;\n\nexport class SetupAnchorProp extends SimpleTwistyPropSource<SetupToLocation> {\n getDefaultValue(): SetupToLocation {\n return \"start\";\n }\n}\n", "import type { KTransformation } from \"../../../../../kpuzzle\";\nimport { SimpleTwistyPropSource } from \"../../TwistyProp\";\n\nexport class SetupTransformationProp extends SimpleTwistyPropSource<KTransformation | null> {\n getDefaultValue(): KTransformation | null {\n return null;\n }\n}\n", "import type { KPuzzle } from \"../../../../../kpuzzle\";\nimport type { PuzzleLoader } from \"../../../../../puzzles\";\nimport { TwistyPropDerived } from \"../../TwistyProp\";\n\nexport class KPuzzleProp extends TwistyPropDerived<\n { puzzleLoader: PuzzleLoader },\n KPuzzle\n> {\n async derive(inputs: { puzzleLoader: PuzzleLoader }): Promise<KPuzzle> {\n return inputs.puzzleLoader.kpuzzle();\n }\n}\n", "import type { PuzzleDescriptionString } from \"../../../../../puzzle-geometry/pgPuzzles\";\nimport {\n NO_VALUE,\n type NoValueType,\n SimpleTwistyPropSource,\n} from \"../../TwistyProp\";\n\nexport class PGPuzzleDescriptionStringProp extends SimpleTwistyPropSource<\n PuzzleDescriptionString | NoValueType\n> {\n getDefaultValue(): PuzzleDescriptionString | NoValueType {\n return NO_VALUE;\n }\n}\n", "import type { PuzzleLoader } from \"../../../../../puzzles\";\nimport { TwistyPropDerived } from \"../../TwistyProp\";\nimport type { PuzzleID } from \"./PuzzleIDRequestProp\";\n\nexport class PuzzleIDProp extends TwistyPropDerived<\n { puzzleLoader: PuzzleLoader },\n PuzzleID\n> {\n async derive(inputs: { puzzleLoader: PuzzleLoader }): Promise<PuzzleID> {\n return inputs.puzzleLoader.id as PuzzleID;\n }\n}\n", "import {\n NO_VALUE,\n type NoValueType,\n SimpleTwistyPropSource,\n} from \"../../TwistyProp\";\n\nexport const puzzleIDs = {\n \"3x3x3\": true, // default\n custom: true,\n \"2x2x2\": true,\n \"4x4x4\": true,\n \"5x5x5\": true,\n \"6x6x6\": true,\n \"7x7x7\": true,\n \"40x40x40\": true,\n megaminx: true,\n pyraminx: true,\n square1: true,\n clock: true,\n skewb: true,\n fto: true,\n gigaminx: true,\n master_tetraminx: true,\n kilominx: true,\n redi_cube: true,\n baby_fto: true,\n melindas2x2x2x2: true,\n tri_quad: true,\n loopover: true,\n};\nexport type PuzzleID = keyof typeof puzzleIDs;\n\n// TODO: Ideally we'd use `null` to mean \"no value\", but `null` has a special meaning\n// for `TwistyProp` and might mess with caching.\n// https://github.com/cubing/cubing.js/blob/63b0a55b83963f68410bb117a2e481052a07e086/src/cubing/twisty/model/TwistyProp.ts#L189-L189\nexport class PuzzleIDRequestProp extends SimpleTwistyPropSource<\n PuzzleID | NoValueType\n> {\n getDefaultValue(): PuzzleID | NoValueType {\n return NO_VALUE;\n }\n}\n", "import type { PuzzleDescriptionString } from \"../../../../../puzzle-geometry/pgPuzzles\";\nimport { cube3x3x3, type PuzzleLoader, puzzles } from \"../../../../../puzzles\";\nimport { experimentalCustomPGPuzzleLoader } from \"../../../../../puzzles/cubing-private\";\nimport {\n NO_VALUE,\n type NoValueType,\n TwistyPropDerived,\n} from \"../../TwistyProp\";\nimport type { PuzzleID } from \"./PuzzleIDRequestProp\";\n\n8;\ninterface PuzzleLoaderPropInputs {\n puzzleIDRequest: PuzzleID | NoValueType;\n puzzleDescriptionRequest: PuzzleDescriptionString | NoValueType;\n}\n\nexport class PuzzleLoaderProp extends TwistyPropDerived<\n PuzzleLoaderPropInputs,\n PuzzleLoader\n> {\n derive(inputs: PuzzleLoaderPropInputs): PuzzleLoader {\n if (inputs.puzzleIDRequest && inputs.puzzleIDRequest !== NO_VALUE) {\n const puzzleLoader = puzzles[inputs.puzzleIDRequest];\n if (!puzzleLoader) {\n this.userVisibleErrorTracker!.set({\n errors: [`Invalid puzzle ID: ${inputs.puzzleIDRequest}`],\n });\n }\n return puzzleLoader;\n }\n if (\n inputs.puzzleDescriptionRequest &&\n inputs.puzzleDescriptionRequest !== NO_VALUE\n ) {\n return experimentalCustomPGPuzzleLoader(inputs.puzzleDescriptionRequest);\n }\n return cube3x3x3;\n }\n}\n", "import type { ButtonCommand } from \"../../../views/control-panel/TwistyButtons\";\nimport { TwistyPropDerived } from \"../TwistyProp\";\nimport type { DetailedTimelineInfo } from \"./DetailedTimelineInfoProp\";\nimport type { PlayingInfo } from \"./PlayingInfoProp\";\n\ninterface ButtonAppearance {\n enabled: boolean;\n icon: string;\n title: string;\n}\nexport type ButtonAppearances = Record<ButtonCommand, ButtonAppearance>;\n\ninterface CoarseTimelineInfoInputs {\n playingInfo: PlayingInfo;\n detailedTimelineInfo: DetailedTimelineInfo;\n}\n\nexport interface CoarseTimelineInfo {\n playing: boolean;\n atStart: boolean;\n atEnd: boolean;\n}\n\n// This started as a version of `EffectiveTimestamp` without the actual\n// timestamp, to enable easier caching.\nexport class CoarseTimelineInfoProp extends TwistyPropDerived<\n CoarseTimelineInfoInputs,\n CoarseTimelineInfo\n> {\n protected override derive(\n inputs: CoarseTimelineInfoInputs,\n ): CoarseTimelineInfo {\n return {\n playing: inputs.playingInfo.playing,\n atStart: inputs.detailedTimelineInfo.atStart,\n atEnd: inputs.detailedTimelineInfo.atEnd,\n };\n }\n\n protected override canReuseValue(\n v1: CoarseTimelineInfo,\n v2: CoarseTimelineInfo,\n ): boolean {\n return (\n v1.playing === v2.playing &&\n v1.atStart === v2.atStart &&\n v1.atEnd === v2.atEnd\n );\n }\n}\n", "import type {\n MillisecondTimestamp,\n TimeRange,\n} from \"../../../controllers/AnimationTypes\";\nimport type { AlgWithIssues } from \"../puzzle/state/AlgProp\";\nimport type { SetupToLocation } from \"../puzzle/state/SetupAnchorProp\";\nimport { TwistyPropDerived } from \"../TwistyProp\";\nimport type { TimestampRequest } from \"./TimestampRequestProp\";\n\ninterface DetailedTimelineInfoInputs {\n timestampRequest: TimestampRequest;\n timeRange: TimeRange;\n setupAnchor: SetupToLocation;\n setupAlg: AlgWithIssues;\n}\n\nexport interface DetailedTimelineInfo {\n timestamp: MillisecondTimestamp;\n timeRange: TimeRange; // TODO: Don't incluede this, and let fresh listeners listen to multiple inputs?\n // Note: `atStart` and `atEnd` can both be true. This is the case with the\n // default (empty) alg, which has a duration of 0 ms.\n atStart: boolean;\n atEnd: boolean;\n}\n\nexport class DetailedTimelineInfoProp extends TwistyPropDerived<\n DetailedTimelineInfoInputs,\n DetailedTimelineInfo\n> {\n protected override derive(\n inputs: DetailedTimelineInfoInputs,\n ): DetailedTimelineInfo {\n let timestamp = this.#requestedTimestampToMilliseconds(inputs);\n let atStart: boolean = false;\n let atEnd: boolean = false;\n if (timestamp >= inputs.timeRange.end) {\n atEnd = true;\n timestamp = Math.min(\n inputs.timeRange.end,\n timestamp,\n ) as MillisecondTimestamp;\n }\n if (timestamp <= inputs.timeRange.start) {\n atStart = true;\n timestamp = Math.max(\n inputs.timeRange.start,\n timestamp,\n ) as MillisecondTimestamp;\n }\n return {\n timestamp,\n timeRange: inputs.timeRange,\n atStart,\n atEnd,\n };\n }\n\n #requestedTimestampToMilliseconds(\n inputs: DetailedTimelineInfoInputs,\n ): MillisecondTimestamp {\n switch (inputs.timestampRequest) {\n case \"auto\":\n return inputs.setupAnchor === \"start\" &&\n inputs.setupAlg.alg.experimentalIsEmpty()\n ? inputs.timeRange.end\n : inputs.timeRange.start;\n case \"start\":\n return inputs.timeRange.start;\n case \"end\":\n return inputs.timeRange.end;\n case \"anchor\":\n return inputs.setupAnchor === \"start\"\n ? inputs.timeRange.start\n : inputs.timeRange.end;\n case \"opposite-anchor\":\n return inputs.setupAnchor === \"start\"\n ? inputs.timeRange.end\n : inputs.timeRange.start;\n default:\n return inputs.timestampRequest;\n }\n }\n\n protected override canReuseValue(\n v1: DetailedTimelineInfo,\n v2: DetailedTimelineInfo,\n ) {\n return (\n v1.timestamp === v2.timestamp &&\n v1.timeRange.start === v2.timeRange.start &&\n v1.timeRange.end === v2.timeRange.end &&\n v1.atStart === v2.atStart &&\n v1.atEnd === v2.atEnd\n );\n }\n}\n", "import { BoundaryType, Direction } from \"../../../controllers/AnimationTypes\";\nimport { TwistyPropSource } from \"../TwistyProp\";\n\nexport type SimpleDirection = Direction.Forwards | Direction.Backwards;\n\nexport interface PlayingInfo {\n playing: boolean;\n direction: SimpleDirection;\n untilBoundary: BoundaryType; // TODO: allows this to be optional in the setter?\n // TODO: Is `loop` responsible to add at this point? Maybe we should wait until we've figured out autoplay?\n // TODO: Combine `loop` into something with BoundaryType?\n loop: boolean;\n}\n\n// TODO: direction,\nexport class PlayingInfoProp extends TwistyPropSource<\n PlayingInfo,\n Partial<PlayingInfo>\n> {\n public override async getDefaultValue(): Promise<PlayingInfo> {\n return {\n direction: Direction.Forwards,\n playing: false,\n untilBoundary: BoundaryType.EntireTimeline,\n loop: false,\n };\n }\n\n protected override async derive(\n newInfo: Partial<PlayingInfo>,\n oldValuePromise: Promise<PlayingInfo>,\n ): Promise<PlayingInfo> {\n const oldValue = await oldValuePromise;\n\n const newValue: PlayingInfo = Object.assign({}, oldValue);\n Object.assign(newValue, newInfo);\n return newValue;\n }\n\n protected override canReuseValue(v1: PlayingInfo, v2: PlayingInfo) {\n return (\n v1.direction === v2.direction &&\n v1.playing === v2.playing &&\n v1.untilBoundary === v2.untilBoundary &&\n v1.loop === v2.loop\n );\n }\n}\n", "import { TwistyPropSource } from \"../TwistyProp\";\n\n// TODO: Pick a better name. `speed` is probably good, although that could mean\n// something else (e.g. shorter, faster moves but still with the same spacing).\nexport class TempoScaleProp extends TwistyPropSource<number, number> {\n getDefaultValue(): number {\n return 1;\n }\n\n derive(v: number): number {\n return v < 0 ? 1 : v;\n }\n}\n", "import type { MillisecondTimestamp } from \"../../../controllers/AnimationTypes\";\nimport { type PromiseOrValue, SimpleTwistyPropSource } from \"../TwistyProp\";\n\nconst smartTimestamps = {\n auto: true,\n start: true,\n end: true,\n anchor: true,\n \"opposite-anchor\": true,\n};\n\nexport type TimestampRequest =\n | MillisecondTimestamp\n | keyof typeof smartTimestamps;\n\nexport class TimestampRequestProp extends SimpleTwistyPropSource<TimestampRequest> {\n override getDefaultValue(): TimestampRequest {\n return \"auto\";\n }\n\n public override set(v: PromiseOrValue<TimestampRequest>) {\n const currentValue = this.get();\n super.set(\n (async () => {\n if (!this.validInput(await v)) {\n // TODO: Generalize this to more props. How do we surface this? Throw an error and catch it from sync setters that call into this?\n return currentValue;\n }\n return v;\n })(),\n );\n }\n\n protected validInput(v: TimestampRequest): boolean {\n if (typeof v === \"number\") {\n return true;\n }\n if (smartTimestamps[v]) {\n return true;\n }\n return false;\n }\n}\n", "import type {\n MillisecondTimestamp,\n TimeRange,\n} from \"../../../controllers/AnimationTypes\";\nimport type { AlgIndexer } from \"../../../controllers/indexer/AlgIndexer\";\nimport { TwistyPropDerived } from \"../TwistyProp\";\n\nexport class TimeRangeProp extends TwistyPropDerived<\n { indexer: AlgIndexer },\n TimeRange\n> {\n derive(inputs: { indexer: AlgIndexer }): TimeRange {\n return {\n start: 0 as MillisecondTimestamp,\n end: inputs.indexer.algDuration() as number as MillisecondTimestamp,\n };\n }\n}\n", "import { SimpleTwistyPropSource } from \"../TwistyProp\";\n\nexport const viewerLinkPages = {\n twizzle: true, // default\n \"experimental-twizzle-explorer\": true,\n none: true,\n};\nexport type ViewerLinkPage = keyof typeof viewerLinkPages;\nexport type ViewerLinkPageWithAuto = ViewerLinkPage | \"auto\";\n\nexport class ViewerLinkProp extends SimpleTwistyPropSource<ViewerLinkPageWithAuto> {\n getDefaultValue(): ViewerLinkPageWithAuto {\n return \"auto\";\n }\n}\n", "import { SimpleTwistyPropSource } from \"../TwistyProp\";\n\n// TODO: turn these maps into lists?\nexport const visualizationFormats = {\n \"3D\": true, // default\n \"2D\": true,\n \"experimental-2D-LL\": true, // TODO\n \"experimental-2D-LL-face\": true, // TODO\n PG3D: true,\n} as const;\nexport type VisualizationFormat = keyof typeof visualizationFormats;\nexport type VisualizationFormatWithAuto = VisualizationFormat | \"auto\";\n\nexport class VisualizationFormatProp extends SimpleTwistyPropSource<VisualizationFormatWithAuto> {\n getDefaultValue(): VisualizationFormatWithAuto {\n return \"auto\";\n }\n}\n", "import type { PuzzleID } from \"../../..\";\nimport { TwistyPropDerived } from \"../TwistyProp\";\nimport type { VisualizationFormatWithAuto } from \"./VisualizationProp\";\n\ntype VisualizationStrategyPropInputs = {\n visualizationRequest: VisualizationFormatWithAuto;\n puzzleID: PuzzleID;\n};\n\nexport type VisualizationStrategy =\n | \"Cube3D\"\n | \"2D\"\n | \"experimental-2D-LL\"\n | \"experimental-2D-LL-face\"\n | \"PG3D\";\n\nexport class VisualizationStrategyProp extends TwistyPropDerived<\n VisualizationStrategyPropInputs,\n VisualizationStrategy\n> {\n derive(inputs: VisualizationStrategyPropInputs): VisualizationStrategy {\n // TODO: let the puzzle loader tell us.\n switch (inputs.puzzleID) {\n case \"clock\":\n case \"square1\":\n case \"redi_cube\":\n case \"melindas2x2x2x2\":\n case \"tri_quad\":\n case \"loopover\":\n return \"2D\";\n case \"3x3x3\":\n switch (inputs.visualizationRequest) {\n case \"auto\":\n case \"3D\":\n return \"Cube3D\";\n default:\n return inputs.visualizationRequest;\n }\n default:\n switch (inputs.visualizationRequest) {\n case \"auto\":\n case \"3D\":\n return \"PG3D\";\n case \"experimental-2D-LL\":\n case \"experimental-2D-LL-face\":\n if ([\"2x2x2\", \"4x4x4\", \"megaminx\"].includes(inputs.puzzleID)) {\n // TODO: calculate this based on the `PuzzleLoader`.\n return \"experimental-2D-LL\";\n } else {\n return \"2D\";\n }\n default:\n return inputs.visualizationRequest;\n }\n }\n }\n}\n", "import { SimpleTwistyPropSource } from \"../../TwistyProp\";\n\nexport type FaceletScale = \"auto\" | number;\nexport class FaceletScaleProp extends SimpleTwistyPropSource<FaceletScale> {\n getDefaultValue(): FaceletScale {\n return \"auto\";\n }\n}\n", "import { SimpleTwistyPropSource } from \"../../TwistyProp\";\n\nexport type FoundationDisplay = \"auto\" | \"opaque\" | \"none\";\n\nexport class FoundationDisplayProp extends SimpleTwistyPropSource<FoundationDisplay> {\n getDefaultValue(): FoundationDisplay {\n return \"auto\";\n }\n}\n", "import { SimpleTwistyPropSource } from \"../../TwistyProp\";\n\nexport type InitialHintFaceletsAnimation = \"auto\" | \"always\" | \"none\";\n\nexport class InitialHintFaceletsAnimationProp extends SimpleTwistyPropSource<InitialHintFaceletsAnimation> {\n getDefaultValue(): InitialHintFaceletsAnimation {\n return \"auto\";\n }\n}\n", "import type { Texture, TextureLoader } from \"three/src/Three.js\";\nimport { bulk3DCode } from \"../../../../heavy-code-imports/3d\";\nimport { TwistyPropDerived } from \"../../TwistyProp\";\n\nlet cachedLoader: TextureLoader | null = null;\nasync function loader(): Promise<TextureLoader> {\n return (cachedLoader ??= new (await bulk3DCode()).ThreeTextureLoader());\n}\n\ntype SpritePropInputs = {\n spriteURL: URL | null;\n};\n\n// TODO: Find a way to make the 3D elements own this, instead of the main `TwistyPlayerModel`.\nexport class SpriteProp extends TwistyPropDerived<\n SpritePropInputs,\n Texture | null\n> {\n async derive(inputs: SpritePropInputs): Promise<Texture | null> {\n const { spriteURL: textureURL } = inputs;\n if (textureURL === null) {\n return null;\n }\n // biome-ignore lint/suspicious/noAsyncPromiseExecutor: TODO: Find a different way to handle `onLoadingError`?\n return new Promise(async (resolve, _reject) => {\n const onLoadingError = (): void => {\n console.warn(\"Could not load sprite:\", textureURL.toString());\n resolve(null);\n };\n // TODO: provide a way to listen for errors?\n try {\n (await loader()).load(\n textureURL.toString(),\n resolve,\n onLoadingError,\n onLoadingError,\n );\n } catch {\n onLoadingError();\n }\n });\n }\n}\n", "import type { PuzzleLoader } from \"../../../../../puzzles\";\nimport type {\n ExperimentalPieceStickeringMask,\n ExperimentalStickeringMask,\n} from \"../../../../../puzzles/cubing-private\";\nimport { TwistyPropDerived } from \"../../TwistyProp\";\nimport type { ExperimentalStickering } from \"./StickeringRequestProp\";\n\ninterface StickeringMaskPropInputs {\n stickeringMaskRequest: ExperimentalStickeringMask | null;\n stickeringRequest: ExperimentalStickering | null;\n puzzleLoader: PuzzleLoader;\n}\n\nconst r: ExperimentalPieceStickeringMask = {\n facelets: [\"regular\", \"regular\", \"regular\", \"regular\", \"regular\"],\n};\n\nasync function fullStickeringMask(\n puzzleLoader: PuzzleLoader,\n): Promise<ExperimentalStickeringMask> {\n const { definition } = await puzzleLoader.kpuzzle();\n const fullStickeringMask: ExperimentalStickeringMask = { orbits: {} };\n for (const orbitDefinition of definition.orbits) {\n fullStickeringMask.orbits[orbitDefinition.orbitName] = {\n pieces: new Array(orbitDefinition.numPieces).fill(r),\n };\n }\n return fullStickeringMask;\n}\n\nexport class StickeringMaskProp extends TwistyPropDerived<\n StickeringMaskPropInputs,\n ExperimentalStickeringMask\n> {\n getDefaultValue(): ExperimentalStickeringMask {\n return { orbits: {} }; // TODO: auto\n }\n\n async derive(\n inputs: StickeringMaskPropInputs,\n ): Promise<ExperimentalStickeringMask> {\n if (inputs.stickeringMaskRequest) {\n return inputs.stickeringMaskRequest;\n }\n if (inputs.stickeringRequest === \"picture\") {\n return {\n specialBehaviour: \"picture\",\n orbits: {},\n };\n }\n return (\n inputs.puzzleLoader.stickeringMask?.(\n inputs.stickeringRequest ?? \"full\",\n ) ?? fullStickeringMask(inputs.puzzleLoader)\n );\n }\n // TODO: Implement canReuseValue?\n}\n", "// import type {\n// FaceletMeshStickeringMask,\n// PieceStickeringMask,\n// StickeringMask,\n// } from \"./mask\";\n\nimport {\n ExperimentalPieceStickering,\n type ExperimentalPieceStickeringMask,\n type ExperimentalStickeringMask,\n experimentalGetPieceStickeringMask,\n} from \"../../../../../puzzles/cubing-private\";\n\nconst charMap: Record<string, ExperimentalPieceStickering> = {\n \"-\": ExperimentalPieceStickering.Regular,\n D: ExperimentalPieceStickering.Dim,\n I: ExperimentalPieceStickering.Ignored,\n // o: ExperimentalPieceStickering.OrientationStickers, // TODO: hack for centers\n X: ExperimentalPieceStickering.Invisible,\n O: ExperimentalPieceStickering.IgnoreNonPrimary, // orient color known\n P: ExperimentalPieceStickering.PermuteNonPrimary, // Example: PLL\n o: ExperimentalPieceStickering.Ignoriented, // Example: LL edges during CLS\n \"?\": ExperimentalPieceStickering.OrientationWithoutPermutation, // ACube: ignore position\n M: ExperimentalPieceStickering.Mystery, // This piece needs highlighting, but we know nothing about it.\n \"@\": ExperimentalPieceStickering.Regular, // ACube: ignore orientation // TODO: distinguish from \"regular\"\n};\n\nexport function parseSerializedStickeringMask(\n serializedStickeringMask: string,\n): ExperimentalStickeringMask {\n const stickeringMask: ExperimentalStickeringMask = {\n orbits: {},\n };\n const serializedOrbits = serializedStickeringMask.split(\",\");\n for (const serializedOrbit of serializedOrbits) {\n const [orbitName, serializedOrbitPieces, ...rest] =\n serializedOrbit.split(\":\");\n if (rest.length > 0) {\n throw new Error(\n `Invalid serialized orbit stickering mask (too many colons): \\`${serializedOrbit}\\``,\n );\n }\n const pieces: ExperimentalPieceStickeringMask[] = [];\n stickeringMask.orbits[orbitName] = { pieces };\n for (const char of serializedOrbitPieces) {\n const pieceStickering = charMap[char];\n pieces.push(experimentalGetPieceStickeringMask(pieceStickering));\n }\n }\n return stickeringMask;\n}\n", "import type { ExperimentalStickeringMask } from \"../../../../../puzzles/cubing-private\";\nimport { TwistyPropSource } from \"../../TwistyProp\";\nimport { parseSerializedStickeringMask } from \"./parseSerializedStickeringMask\";\n\nexport class StickeringMaskRequestProp extends TwistyPropSource<\n ExperimentalStickeringMask | null,\n string | ExperimentalStickeringMask | null\n> {\n getDefaultValue(): ExperimentalStickeringMask | null {\n return null; // TODO: auto\n }\n\n derive(\n input: string | ExperimentalStickeringMask | null,\n ): ExperimentalStickeringMask | null {\n if (input === null) {\n return null;\n } else if (typeof input === \"string\") {\n return parseSerializedStickeringMask(input);\n } else {\n return input;\n }\n }\n}\n", "import { experimentalStickerings } from \"../../../../../puzzles/cubing-private\";\nimport { SimpleTwistyPropSource } from \"../../TwistyProp\";\nimport type { PuzzleID } from \"../structure/PuzzleIDRequestProp\";\n\n// TODO: turn these maps into lists?\n// TODO: alg.cubing.net parity\n\nexport type ExperimentalStickering = keyof typeof experimentalStickerings;\n\nexport function getStickeringGroup(\n stickering: ExperimentalStickering,\n puzzleID: PuzzleID,\n): string {\n const groups = experimentalStickerings[stickering]?.groups;\n if (!groups) {\n return \"Stickering\";\n }\n return groups[puzzleID] ?? \"Stickering\";\n}\n\nexport class StickeringRequestProp extends SimpleTwistyPropSource<ExperimentalStickering | null> {\n getDefaultValue(): ExperimentalStickering | null {\n return null;\n }\n}\n", "import { SimpleTwistyPropSource } from \"../../TwistyProp\";\n\nexport const dragInputModes = {\n auto: true,\n none: true,\n};\nexport type DragInputMode = keyof typeof dragInputModes;\n\nexport class DragInputProp extends SimpleTwistyPropSource<DragInputMode> {\n getDefaultValue(): DragInputMode {\n return \"auto\";\n }\n}\n", "import type { AppendCancelOptions } from \"../../../../../alg\";\nimport { SimpleTwistyPropSource } from \"../../TwistyProp\";\n\n// TODO: this should probably be dynamic based on the input, e.g. possibly even controlled using a modifier key.\nexport class MovePressCancelOptions extends SimpleTwistyPropSource<AppendCancelOptions> {\n getDefaultValue(): AppendCancelOptions {\n return {};\n }\n}\n", "import { SimpleTwistyPropSource } from \"../../TwistyProp\";\n\nexport const movePressInputNames = {\n auto: true,\n none: true,\n basic: true,\n};\nexport type MovePressInput = keyof typeof movePressInputNames;\n\nexport class MovePressInputProp extends SimpleTwistyPropSource<MovePressInput> {\n getDefaultValue(): MovePressInput {\n return \"auto\";\n }\n}\n", "import { SimpleTwistyPropSource } from \"../TwistyProp\";\n\nexport const backgroundThemes = {\n checkered: true, // default\n \"checkered-transparent\": true, // default\n none: true,\n};\nexport type BackgroundTheme = keyof typeof backgroundThemes;\n\nexport type BackgroundThemeWithAuto = BackgroundTheme | \"auto\";\n\nexport class BackgroundProp extends SimpleTwistyPropSource<BackgroundThemeWithAuto> {\n getDefaultValue(): BackgroundThemeWithAuto {\n return \"auto\";\n }\n}\n", "import { TwistyPropDerived } from \"../TwistyProp\";\nimport type {\n ColorScheme,\n ColorSchemeWithAuto,\n} from \"./ColorSchemeRequestProp\";\n\ninterface ColorSchemePropInputs {\n colorSchemeRequest: ColorSchemeWithAuto;\n}\n\nexport class ColorSchemeProp extends TwistyPropDerived<\n ColorSchemePropInputs,\n ColorScheme\n> {\n protected derive(inputs: ColorSchemePropInputs): ColorScheme {\n // TODO: Once the theme is ready, use `prefers-color-scheme` for automatic dark mode by default.\n return inputs.colorSchemeRequest === \"dark\" ? \"dark\" : \"light\";\n }\n}\n", "import { SimpleTwistyPropSource } from \"../TwistyProp\";\n\nexport const colorSchemes = {\n light: true,\n dark: true,\n};\nexport type ColorScheme = keyof typeof colorSchemes;\nexport type ColorSchemeWithAuto = ColorScheme | \"auto\";\n\nexport class ColorSchemeRequestProp extends SimpleTwistyPropSource<ColorSchemeWithAuto> {\n getDefaultValue(): ColorSchemeWithAuto {\n return \"auto\";\n }\n}\n", "import { SimpleTwistyPropSource } from \"../TwistyProp\";\n\nexport class DOMElementReferenceProp extends SimpleTwistyPropSource<Element | null> {\n getDefaultValue(): Element | null {\n return null;\n }\n}\n", "import { SimpleTwistyPropSource } from \"../TwistyProp\";\nimport type { CoordinateDegrees } from \"./OrbitCoordinatesRequestProp\";\n\n// Similar to https://alg.cubing.net/\nconst DEFAULT_LATITUDE_LIMIT = 35;\n\nexport class LatitudeLimitProp extends SimpleTwistyPropSource<CoordinateDegrees> {\n getDefaultValue(): CoordinateDegrees {\n return DEFAULT_LATITUDE_LIMIT;\n }\n}\n", "import { modIntoRange } from \"../../helpers\";\nimport { TwistyPropSource } from \"../TwistyProp\";\n\nexport type CoordinateDegrees = number;\n\nexport interface OrbitCoordinates {\n latitude: CoordinateDegrees;\n longitude: CoordinateDegrees;\n distance: number;\n}\n\nexport function orbitCoordinatesEqual(\n c1: OrbitCoordinates,\n c2: OrbitCoordinates,\n): boolean {\n return (\n c1.latitude === c2.latitude &&\n c1.longitude === c2.longitude &&\n c1.distance === c2.distance\n );\n}\n\n// TODO: Check if freezing affects perf.\n// const DEFAULT_COORDINATES = Object.freeze({\n// latitude: 35,\n// longitude: 30,\n// distance: 6,\n// });\n\nexport type OrbitCoordinatesRequest = Partial<OrbitCoordinates> | \"auto\";\n\n// TODO: Put the \"auto\" calculations in a separate place.\nexport class OrbitCoordinatesRequestProp extends TwistyPropSource<\n OrbitCoordinatesRequest,\n Partial<OrbitCoordinates> | \"auto\"\n> {\n override getDefaultValue(): OrbitCoordinatesRequest {\n return \"auto\";\n }\n\n protected override canReuseValue(v1: OrbitCoordinates, v2: OrbitCoordinates) {\n return v1 === v2 || orbitCoordinatesEqual(v1, v2);\n }\n\n protected override async derive(\n newCoordinates: Partial<OrbitCoordinates> | \"auto\",\n oldValuePromise: Promise<OrbitCoordinatesRequest>,\n ): Promise<OrbitCoordinatesRequest> {\n if (newCoordinates === \"auto\") {\n return \"auto\";\n }\n\n let oldValue = await oldValuePromise;\n if (oldValue === \"auto\") {\n oldValue = {};\n }\n\n const newValue: Partial<OrbitCoordinates> = Object.assign({}, oldValue);\n Object.assign(newValue, newCoordinates);\n\n if (typeof newValue.latitude !== \"undefined\") {\n newValue.latitude = Math.min(Math.max(newValue.latitude, -90), 90);\n }\n if (typeof newValue.longitude !== \"undefined\") {\n newValue.longitude = modIntoRange(newValue.longitude, 180, -180);\n }\n return newValue;\n }\n}\n", "import { DEGREES_PER_RADIAN } from \"../../../views/3D/TAU\";\nimport type { PuzzleID } from \"../puzzle/structure/PuzzleIDRequestProp\";\nimport { TwistyPropDerived } from \"../TwistyProp\";\nimport {\n type CoordinateDegrees,\n type OrbitCoordinates,\n type OrbitCoordinatesRequest,\n orbitCoordinatesEqual,\n} from \"./OrbitCoordinatesRequestProp\";\nimport type { VisualizationStrategy } from \"./VisualizationStrategyProp\";\n\ninterface OrbitCoordinatesPropInputs {\n orbitCoordinatesRequest: OrbitCoordinatesRequest;\n latitudeLimit: CoordinateDegrees;\n puzzleID: PuzzleID;\n strategy: VisualizationStrategy;\n}\n\nexport class OrbitCoordinatesProp extends TwistyPropDerived<\n OrbitCoordinatesPropInputs,\n OrbitCoordinates\n> {\n override canReuseValue(v1: OrbitCoordinates, v2: OrbitCoordinates) {\n return orbitCoordinatesEqual(v1, v2);\n }\n\n async derive(inputs: OrbitCoordinatesPropInputs): Promise<OrbitCoordinates> {\n if (inputs.orbitCoordinatesRequest === \"auto\") {\n return defaultCameraOrbitCoordinates(inputs.puzzleID, inputs.strategy);\n }\n\n const req: OrbitCoordinates = Object.assign(\n Object.assign(\n {},\n defaultCameraOrbitCoordinates(inputs.puzzleID, inputs.strategy),\n inputs.orbitCoordinatesRequest,\n ),\n );\n\n if (Math.abs(req.latitude) <= inputs.latitudeLimit) {\n return req;\n } else {\n const { latitude, longitude, distance } = req;\n // TODO: Should we re-normalize the request, so we don't depend on normalization in the input?\n return {\n latitude: inputs.latitudeLimit * Math.sign(latitude),\n longitude,\n distance,\n };\n }\n }\n}\n\n// const DEFAULT_CAMERA_Z = 5;\n// // Golden ratio is perfect for FTO and Megaminx.\n// const DEFAULT_CAMERA_Y = DEFAULT_CAMERA_Z * (2 / (1 + Math.sqrt(5)));\nexport const centeredCameraOrbitCoordinates: OrbitCoordinates = {\n latitude: 31.717474411461005,\n longitude: 0,\n distance: 5.877852522924731,\n};\n\n// This is tuned so that the hint facelets for 3x3x3 always fit in the canvas.\nexport const cubeCube3DCameraOrbitCoordinates: OrbitCoordinates = {\n latitude: 35,\n longitude: 30,\n distance: 6,\n};\n\n// This is tuned so that the hint facelets always fit in the canvas.\nexport const cubePG3DCameraOrbitCoordinates: OrbitCoordinates = {\n latitude: 35,\n longitude: 30,\n distance: 6.25,\n};\n\nexport const megaminxCameraOrbitCoordinates: OrbitCoordinates = {\n latitude: Math.atan(1 / 2) * DEGREES_PER_RADIAN,\n longitude: 0,\n distance: 6.7,\n};\n\nexport const pyraminxCameraOrbitCoordinates: OrbitCoordinates = {\n latitude: 26.56505117707799,\n longitude: 0,\n distance: 6,\n};\n\nexport const cornerCameraOrbitCoordinates: OrbitCoordinates = {\n latitude: 35.264389682754654,\n longitude: 45,\n distance: 6.928203230275509,\n};\n\n// TODO\nexport function defaultCameraOrbitCoordinates(\n puzzleID: PuzzleID,\n strategy: VisualizationStrategy,\n): OrbitCoordinates {\n if (puzzleID[1] === \"x\") {\n if (strategy === \"Cube3D\") {\n return cubeCube3DCameraOrbitCoordinates;\n } else {\n return cubePG3DCameraOrbitCoordinates;\n }\n } else {\n switch (puzzleID) {\n case \"megaminx\":\n case \"gigaminx\":\n return megaminxCameraOrbitCoordinates;\n case \"pyraminx\":\n case \"master_tetraminx\":\n return pyraminxCameraOrbitCoordinates;\n case \"skewb\":\n return cubePG3DCameraOrbitCoordinates;\n default:\n return centeredCameraOrbitCoordinates;\n }\n }\n}\n// TODO: templatize\nexport interface ManagedAttribute<K> {\n string: string;\n value: K;\n setString(s: string): boolean;\n setValue(v: K): boolean;\n}\n", "import { URLProp } from \"./props/general/URLProp\";\nimport { FaceletScaleProp } from \"./props/puzzle/display/FaceletScaleProp\";\nimport { FoundationDisplayProp } from \"./props/puzzle/display/FoundationDisplayProp\";\nimport { HintFaceletProp } from \"./props/puzzle/display/HintFaceletProp\";\nimport { InitialHintFaceletsAnimationProp } from \"./props/puzzle/display/InitialHintFaceletsAnimationProp\";\nimport { SpriteProp } from \"./props/puzzle/display/SpriteProp\";\nimport { StickeringMaskProp } from \"./props/puzzle/display/StickeringMaskProp\";\nimport { StickeringMaskRequestProp } from \"./props/puzzle/display/StickeringMaskRequestProp\";\nimport { StickeringRequestProp } from \"./props/puzzle/display/StickeringRequestProp\";\nimport { DragInputProp } from \"./props/puzzle/state/DragInputProp\";\nimport { MovePressCancelOptions } from \"./props/puzzle/state/MovePressCancelOptions\";\nimport { MovePressInputProp } from \"./props/puzzle/state/MovePressInputProp\";\nimport { BackgroundProp } from \"./props/viewer/BackgroundProp\";\nimport { ColorSchemeProp } from \"./props/viewer/ColorSchemeProp\";\nimport { ColorSchemeRequestProp } from \"./props/viewer/ColorSchemeRequestProp\";\nimport { DOMElementReferenceProp } from \"./props/viewer/DOMElementReferenceProp\";\nimport { LatitudeLimitProp } from \"./props/viewer/LatitudeLimit\";\nimport { OrbitCoordinatesProp } from \"./props/viewer/OrbitCoordinatesProp\";\nimport { OrbitCoordinatesRequestProp } from \"./props/viewer/OrbitCoordinatesRequestProp\";\nimport type { TwistyPlayerModel } from \"./TwistyPlayerModel\";\n\nexport class TwistySceneModel {\n // Depth 0\n background = new BackgroundProp();\n colorSchemeRequest = new ColorSchemeRequestProp();\n dragInput = new DragInputProp();\n foundationDisplay = new FoundationDisplayProp();\n foundationStickerSpriteURL = new URLProp();\n fullscreenElement = new DOMElementReferenceProp();\n hintFacelet = new HintFaceletProp();\n hintStickerSpriteURL = new URLProp();\n initialHintFaceletsAnimation = new InitialHintFaceletsAnimationProp();\n latitudeLimit = new LatitudeLimitProp();\n movePressInput = new MovePressInputProp();\n movePressCancelOptions = new MovePressCancelOptions();\n orbitCoordinatesRequest: OrbitCoordinatesRequestProp =\n new OrbitCoordinatesRequestProp();\n // `stickeringMaskRequest` takes priority over `stickeringRequest`\n stickeringMaskRequest = new StickeringMaskRequestProp();\n stickeringRequest = new StickeringRequestProp();\n faceletScale = new FaceletScaleProp();\n\n // Depth 1\n colorScheme = new ColorSchemeProp({\n colorSchemeRequest: this.colorSchemeRequest,\n });\n foundationStickerSprite = new SpriteProp({\n spriteURL: this.foundationStickerSpriteURL,\n });\n hintStickerSprite = new SpriteProp({\n spriteURL: this.hintStickerSpriteURL,\n });\n\n // Dependence on TwistyPlayerModel\n orbitCoordinates: OrbitCoordinatesProp;\n stickeringMask: StickeringMaskProp;\n\n constructor(public twistyPlayerModel: TwistyPlayerModel) {\n this.orbitCoordinates = new OrbitCoordinatesProp({\n orbitCoordinatesRequest: this.orbitCoordinatesRequest,\n latitudeLimit: this.latitudeLimit,\n puzzleID: twistyPlayerModel.puzzleID,\n strategy: twistyPlayerModel.visualizationStrategy,\n });\n this.stickeringMask = new StickeringMaskProp({\n stickeringMaskRequest: this.stickeringMaskRequest,\n stickeringRequest: this.stickeringRequest,\n puzzleLoader: twistyPlayerModel.puzzleLoader,\n });\n }\n}\n", "import { arrayEquals } from \"./helpers\";\nimport { SimpleTwistyPropSource } from \"./props/TwistyProp\";\n\ninterface UserVisibleError {\n errors: string[];\n}\n\nconst EMPTY_ERRORS = { errors: [] };\n\nexport class UserVisibleErrorTracker extends SimpleTwistyPropSource<UserVisibleError> {\n override getDefaultValue(): UserVisibleError {\n return EMPTY_ERRORS;\n }\n\n public reset() {\n this.set(this.getDefaultValue());\n }\n\n protected override canReuseValue(\n _v1: UserVisibleError,\n _v2: UserVisibleError,\n ): boolean {\n return arrayEquals(_v1.errors, _v2.errors);\n }\n}\n", "import { Alg, experimentalAppendMove, Move } from \"../../alg\";\nimport type { AlgLeaf } from \"../../alg/alg-nodes/AlgNode\";\nimport type { AppendOptions } from \"../../alg/simplify\";\nimport { getPartialAppendOptionsForPuzzleSpecificSimplifyOptions } from \"../../puzzles/cubing-private\";\nimport { ArbitraryStringProp } from \"./props/general/ArbitraryStringProp\";\nimport { URLProp } from \"./props/general/URLProp\";\nimport { AlgProp } from \"./props/puzzle/state/AlgProp\";\nimport { AlgTransformationProp } from \"./props/puzzle/state/AlgTransformationProp\";\nimport { AnchorTransformationProp } from \"./props/puzzle/state/AnchorTransformationProp\";\nimport { AnimationTimelineLeavesRequestProp } from \"./props/puzzle/state/AnimationTimelineLeavesRequestProp\";\nimport { CatchUpMoveProp } from \"./props/puzzle/state/CatchUpMoveProp\";\nimport { CurrentLeavesSimplifiedProp } from \"./props/puzzle/state/CurrentLeavesSimplified\";\nimport { CurrentMoveInfoProp } from \"./props/puzzle/state/CurrentMoveInfoProp\";\nimport { CurrentPatternProp } from \"./props/puzzle/state/CurrentPatternProp\";\nimport { IndexerConstructorProp } from \"./props/puzzle/state/IndexerConstructorProp\";\nimport { IndexerConstructorRequestProp } from \"./props/puzzle/state/IndexerConstructorRequestProp\";\nimport { IndexerProp } from \"./props/puzzle/state/IndexerProp\";\nimport { LegacyPositionProp } from \"./props/puzzle/state/LegacyPositionProp\";\nimport { PuzzleAlgProp } from \"./props/puzzle/state/PuzzleAlgProp\";\nimport { SetupAnchorProp } from \"./props/puzzle/state/SetupAnchorProp\";\nimport { SetupTransformationProp } from \"./props/puzzle/state/SetupTransformationProp\";\nimport { KPuzzleProp } from \"./props/puzzle/structure/KPuzzleProp\";\nimport { PGPuzzleDescriptionStringProp } from \"./props/puzzle/structure/PuzzleDescriptionProp\";\nimport { PuzzleIDProp } from \"./props/puzzle/structure/PuzzleIDProp\";\nimport { PuzzleIDRequestProp } from \"./props/puzzle/structure/PuzzleIDRequestProp\";\nimport { PuzzleLoaderProp } from \"./props/puzzle/structure/PuzzleLoaderProp\";\nimport { NO_VALUE } from \"./props/TwistyProp\";\nimport { CoarseTimelineInfoProp } from \"./props/timeline/CoarseTimelineInfoProp\";\nimport { DetailedTimelineInfoProp } from \"./props/timeline/DetailedTimelineInfoProp\";\nimport { PlayingInfoProp } from \"./props/timeline/PlayingInfoProp\";\nimport { TempoScaleProp } from \"./props/timeline/TempoScaleProp\";\nimport { TimestampRequestProp } from \"./props/timeline/TimestampRequestProp\";\nimport { BackViewProp } from \"./props/viewer/BackViewProp\";\nimport { ButtonAppearanceProp } from \"./props/viewer/ButtonAppearanceProp\";\nimport { ControlPanelProp } from \"./props/viewer/ControlPanelProp\";\nimport { TimeRangeProp } from \"./props/viewer/TimeRangeProp\";\nimport { ViewerLinkProp } from \"./props/viewer/ViewerLinkProp\";\nimport { VisualizationFormatProp } from \"./props/viewer/VisualizationProp\";\nimport { VisualizationStrategyProp } from \"./props/viewer/VisualizationStrategyProp\";\nimport { TwistySceneModel } from \"./TwistySceneModel\";\nimport { UserVisibleErrorTracker } from \"./UserVisibleErrorTracker\";\n\n// From https://stackoverflow.com/a/50918777\ntype Without<T, K extends string[]> = Pick<T, Exclude<keyof T, K[number]>>;\n\nexport class TwistyPlayerModel {\n // TODO: incorporate error handling into the entire prop graph.\n // TODO: Make this something that can't get confused with normal props?\n userVisibleErrorTracker = new UserVisibleErrorTracker();\n\n // TODO: Redistribute and group props with controllers.\n\n /******************************** Depth 0 ********************************/\n\n alg = new AlgProp();\n backView = new BackViewProp();\n controlPanel = new ControlPanelProp();\n catchUpMove = new CatchUpMoveProp();\n indexerConstructorRequest = new IndexerConstructorRequestProp();\n playingInfo = new PlayingInfoProp();\n puzzleDescriptionRequest = new PGPuzzleDescriptionStringProp();\n puzzleIDRequest = new PuzzleIDRequestProp();\n setupAnchor = new SetupAnchorProp();\n setupAlg = new AlgProp();\n setupTransformation = new SetupTransformationProp();\n tempoScale = new TempoScaleProp();\n timestampRequest = new TimestampRequestProp();\n viewerLink = new ViewerLinkProp();\n visualizationFormat = new VisualizationFormatProp();\n // Metadata\n title = new ArbitraryStringProp();\n videoURL = new URLProp();\n competitionID = new ArbitraryStringProp();\n /**\n * `<twisty-player>` interally supports associating custom timing information\n * for this move, but there is not an API for this yet. In order to support\n * exploratory use cases for such a feature in the future, this property\n * allows setting timeline information.\n *\n * Note that this feature may not work as expected when combined with other\n * features. In particular, it will cause sync issues with an associated\n * `<twisty-alg-viewer>` depending on how the alg/moves are constructed.\n *\n * Usage example:\n *\n * ```ts\n * import { Move, Pause } from \"cubing/alg\";\n * import { TwistyPlayer } from \"cubing/twisty\";\n *\n * const player = document.body.appendChild(new TwistyPlayer());\n * player.alg = \"R U' D2 R'\";\n *\n * // Note that:\n * // - The leaves must match those of the alg. (No consistency checks are performed at this time.)\n * // - Leaves may overlap if they can be simultaneously animated.\n * // - There must always be at least one animating leaf at any moment. You can use a `Pause` for this if there is a gap between moves.\n * player.experimentalModel.animationTimelineLeavesRequest.set([\n * { animLeaf: new Move(\"R\", 1), start: 0, end: 200 },\n * { animLeaf: new Pause(), start: 200, end: 218 },\n * { animLeaf: new Move(\"U\", -1), start: 218, end: 370 },\n * { animLeaf: new Move(\"D\", 2), start: 249, end: 520 },\n * { animLeaf: new Pause(), start: 520, end: 530 },\n * { animLeaf: new Move(\"R\", -1), start: 530, end: 790 },\n * ]);\n * ```\n */\n animationTimelineLeavesRequest = new AnimationTimelineLeavesRequestProp();\n\n /******************************** Depth 1 ********************************/\n\n puzzleLoader = new PuzzleLoaderProp(\n {\n puzzleIDRequest: this.puzzleIDRequest,\n puzzleDescriptionRequest: this.puzzleDescriptionRequest,\n },\n this.userVisibleErrorTracker,\n );\n\n /******************************** Depth 2 ********************************/\n\n kpuzzle = new KPuzzleProp({ puzzleLoader: this.puzzleLoader });\n\n puzzleID = new PuzzleIDProp({ puzzleLoader: this.puzzleLoader });\n\n /******************************** Depth 3 ********************************/\n\n puzzleAlg = new PuzzleAlgProp({\n algWithIssues: this.alg,\n kpuzzle: this.kpuzzle,\n });\n\n puzzleSetupAlg = new PuzzleAlgProp({\n algWithIssues: this.setupAlg,\n kpuzzle: this.kpuzzle,\n });\n\n visualizationStrategy = new VisualizationStrategyProp({\n visualizationRequest: this.visualizationFormat,\n puzzleID: this.puzzleID,\n });\n\n /******************************** Depth 4 ********************************/\n\n indexerConstructor = new IndexerConstructorProp({\n alg: this.alg,\n puzzle: this.puzzleID,\n visualizationStrategy: this.visualizationStrategy,\n indexerConstructorRequest: this.indexerConstructorRequest,\n animationTimelineLeaves: this.animationTimelineLeavesRequest,\n });\n\n setupAlgTransformation = new AlgTransformationProp({\n setupAlg: this.puzzleSetupAlg,\n kpuzzle: this.kpuzzle,\n });\n\n /******************************** Depth 5 ********************************/\n\n indexer = new IndexerProp({\n indexerConstructor: this.indexerConstructor,\n algWithIssues: this.puzzleAlg,\n kpuzzle: this.kpuzzle,\n animationTimelineLeaves: this.animationTimelineLeavesRequest,\n });\n\n /******************************** Depth 6 ********************************/\n\n anchorTransformation = new AnchorTransformationProp({\n setupTransformation: this.setupTransformation,\n setupAnchor: this.setupAnchor,\n setupAlgTransformation: this.setupAlgTransformation,\n indexer: this.indexer,\n });\n\n timeRange = new TimeRangeProp({\n indexer: this.indexer,\n });\n\n /******************************** Depth 7 ********************************/\n\n detailedTimelineInfo: DetailedTimelineInfoProp = new DetailedTimelineInfoProp(\n {\n timestampRequest: this.timestampRequest,\n timeRange: this.timeRange,\n setupAnchor: this.setupAnchor,\n setupAlg: this.setupAlg,\n },\n );\n\n /******************************** Depth 8 ********************************/\n\n coarseTimelineInfo = new CoarseTimelineInfoProp({\n detailedTimelineInfo: this.detailedTimelineInfo,\n playingInfo: this.playingInfo,\n });\n\n currentMoveInfo = new CurrentMoveInfoProp({\n indexer: this.indexer,\n detailedTimelineInfo: this.detailedTimelineInfo,\n catchUpMove: this.catchUpMove,\n });\n\n /******************************** Depth 9 ********************************/\n\n // TODO: Inline Twisty3D management.\n buttonAppearance = new ButtonAppearanceProp({\n coarseTimelineInfo: this.coarseTimelineInfo,\n viewerLink: this.viewerLink,\n });\n\n currentLeavesSimplified = new CurrentLeavesSimplifiedProp({\n currentMoveInfo: this.currentMoveInfo,\n });\n\n /******************************** Depth 10 ********************************/\n\n currentPattern = new CurrentPatternProp({\n anchoredStart: this.anchorTransformation,\n currentLeavesSimplified: this.currentLeavesSimplified,\n indexer: this.indexer,\n });\n\n /******************************** Depth 11 ********************************/\n\n legacyPosition = new LegacyPositionProp({\n currentMoveInfo: this.currentMoveInfo,\n currentPattern: this.currentPattern,\n });\n\n twistySceneModel = new TwistySceneModel(this);\n\n public async twizzleLink(): Promise<string> {\n const [\n viewerLink,\n puzzleID,\n puzzleDescription,\n alg,\n setup,\n anchor,\n experimentalStickeringRequest,\n experimentalTitle,\n ] = await Promise.all([\n this.viewerLink.get(),\n this.puzzleID.get(),\n this.puzzleDescriptionRequest.get(),\n this.alg.get(),\n this.setupAlg.get(),\n this.setupAnchor.get(),\n this.twistySceneModel.stickeringRequest.get(),\n this.twistySceneModel.twistyPlayerModel.title.get(),\n ]);\n\n const isExplorer = viewerLink === \"experimental-twizzle-explorer\";\n\n const url = new URL(\n `https://alpha.twizzle.net/${isExplorer ? \"explore\" : \"edit\"}/`,\n );\n\n if (!alg.alg.experimentalIsEmpty()) {\n url.searchParams.set(\"alg\", alg.alg.toString());\n }\n if (!setup.alg.experimentalIsEmpty()) {\n url.searchParams.set(\"setup-alg\", setup.alg.toString());\n }\n if (anchor !== \"start\") {\n url.searchParams.set(\"setup-anchor\", anchor);\n }\n if (\n experimentalStickeringRequest !== \"full\" &&\n experimentalStickeringRequest !== null\n ) {\n url.searchParams.set(\n \"experimental-stickering\",\n experimentalStickeringRequest,\n );\n }\n if (isExplorer && puzzleDescription !== NO_VALUE) {\n url.searchParams.set(\"puzzle-description\", puzzleDescription);\n } else if (puzzleID !== \"3x3x3\") {\n url.searchParams.set(\"puzzle\", puzzleID);\n }\n if (experimentalTitle) {\n url.searchParams.set(\"title\", experimentalTitle);\n }\n return url.toString();\n }\n\n experimentalAddAlgLeaf(algLeaf: AlgLeaf, options?: AppendOptions): void {\n const maybeMove = algLeaf.as(Move);\n if (maybeMove) {\n this.experimentalAddMove(maybeMove, options);\n } else {\n this.alg.set(\n (async () => {\n const alg = (await this.alg.get()).alg;\n const newAlg = alg.concat(new Alg([algLeaf]));\n this.timestampRequest.set(\"end\");\n return newAlg;\n })(),\n );\n }\n }\n\n // TODO: Animate the new move.\n experimentalAddMove(\n flexibleMove: Move | string,\n options?: Without<\n AppendOptions,\n [\"puzzleLoader\", \"puzzleSpecificSimplifyOptions\"] // TODO: figure out how to modify `AppendOptions` to accommodate this (or just accept cancel options for now?)\n >,\n ): void {\n const move =\n typeof flexibleMove === \"string\" ? new Move(flexibleMove) : flexibleMove;\n this.alg.set(\n (async () => {\n const [{ alg }, puzzleLoader] = await Promise.all([\n this.alg.get(),\n this.puzzleLoader.get(),\n ]);\n const newAlg = experimentalAppendMove(alg, move, {\n ...options,\n ...(await getPartialAppendOptionsForPuzzleSpecificSimplifyOptions(\n puzzleLoader,\n )),\n });\n this.timestampRequest.set(\"end\");\n this.catchUpMove.set({\n move: move,\n amount: 0,\n });\n return newAlg;\n })(),\n );\n }\n\n // TODO: allow more than 1?\n experimentalRemoveFinalChild(): void {\n this.alg.set(\n (async () => {\n const alg = (await this.alg.get()).alg;\n const children = Array.from(alg.childAlgNodes());\n const [finalChild] = children.splice(-1);\n if (!finalChild) {\n return alg;\n }\n this.timestampRequest.set(\"end\");\n const finalChildMove = finalChild.as(Move);\n if (finalChildMove) {\n this.catchUpMove.set({\n move: finalChildMove.invert(),\n amount: 0,\n });\n }\n return new Alg(children);\n })(),\n );\n }\n}\n", "import type { Alg, AppendCancelOptions } from \"../../alg\";\nimport type { PuzzleDescriptionString } from \"../../puzzle-geometry/pgPuzzles\";\nimport type { StickeringMask } from \"../../puzzles/stickerings/mask\";\nimport type { ExperimentalStickering, PuzzleID } from \"../../twisty\";\nimport type { MillisecondTimestamp } from \"../controllers/AnimationTypes\";\nimport type { FaceletScale } from \"../model/props/puzzle/display/FaceletScaleProp\";\nimport type { HintFaceletStyleWithAuto } from \"../model/props/puzzle/display/HintFaceletProp\";\nimport type { InitialHintFaceletsAnimation } from \"../model/props/puzzle/display/InitialHintFaceletsAnimationProp\";\nimport type { DragInputMode } from \"../model/props/puzzle/state/DragInputProp\";\nimport type { IndexerStrategyName } from \"../model/props/puzzle/state/IndexerConstructorRequestProp\";\nimport type { MovePressInput } from \"../model/props/puzzle/state/MovePressInputProp\";\nimport type { SetupToLocation } from \"../model/props/puzzle/state/SetupAnchorProp\";\nimport type { TimestampRequest } from \"../model/props/timeline/TimestampRequestProp\";\nimport type { BackgroundThemeWithAuto } from \"../model/props/viewer/BackgroundProp\";\nimport type { BackViewLayoutWithAuto } from \"../model/props/viewer/BackViewProp\";\nimport type { ColorSchemeWithAuto } from \"../model/props/viewer/ColorSchemeRequestProp\";\nimport type { ControlPanelThemeWithAuto } from \"../model/props/viewer/ControlPanelProp\";\nimport type { ViewerLinkPageWithAuto } from \"../model/props/viewer/ViewerLinkProp\";\nimport type { VisualizationFormatWithAuto } from \"../model/props/viewer/VisualizationProp\";\nimport { TwistyPlayerModel } from \"../model/TwistyPlayerModel\";\nimport { ManagedCustomElement } from \"./ManagedCustomElement\";\n\nfunction err(propName: string): Error {\n return new Error(\n `Cannot get \\`.${propName}\\` directly from a \\`TwistyPlayer\\`.`,\n );\n}\n\nexport abstract class TwistyPlayerSettable extends ManagedCustomElement {\n experimentalModel: TwistyPlayerModel = new TwistyPlayerModel();\n\n set alg(newAlg: Alg | string) {\n this.experimentalModel.alg.set(newAlg);\n }\n get alg(): never {\n throw err(\"alg\");\n }\n\n set experimentalSetupAlg(newSetup: Alg | string) {\n this.experimentalModel.setupAlg.set(newSetup);\n }\n get experimentalSetupAlg(): never {\n throw err(\"setup\");\n }\n\n set experimentalSetupAnchor(anchor: SetupToLocation) {\n this.experimentalModel.setupAnchor.set(anchor);\n }\n get experimentalSetupAnchor(): never {\n throw err(\"anchor\");\n }\n\n set puzzle(puzzleID: PuzzleID) {\n this.experimentalModel.puzzleIDRequest.set(puzzleID);\n }\n get puzzle(): never {\n throw err(\"puzzle\");\n }\n\n set experimentalPuzzleDescription(puzzleDescription: PuzzleDescriptionString) {\n this.experimentalModel.puzzleDescriptionRequest.set(puzzleDescription);\n }\n get experimentalPuzzleDescription(): never {\n throw err(\"experimentalPuzzleDescription\");\n }\n\n set timestamp(timestamp: TimestampRequest) {\n this.experimentalModel.timestampRequest.set(timestamp);\n }\n get timestamp(): never {\n throw err(\"timestamp\");\n }\n\n set hintFacelets(hintFaceletStyle: HintFaceletStyleWithAuto) {\n this.experimentalModel.twistySceneModel.hintFacelet.set(hintFaceletStyle);\n }\n get hintFacelets(): never {\n throw err(\"hintFacelets\");\n }\n\n set experimentalStickering(stickering: ExperimentalStickering) {\n this.experimentalModel.twistySceneModel.stickeringRequest.set(stickering);\n }\n get experimentalStickering(): never {\n throw err(\"experimentalStickering\");\n }\n\n set experimentalStickeringMaskOrbits(stickeringMask:\n | string\n | StickeringMask) {\n this.experimentalModel.twistySceneModel.stickeringMaskRequest.set(\n stickeringMask,\n );\n }\n get experimentalStickeringMaskOrbits(): never {\n throw err(\"experimentalStickeringMaskOrbits\");\n }\n\n set experimentalFaceletScale(faceletScale: FaceletScale) {\n this.experimentalModel.twistySceneModel.faceletScale.set(faceletScale);\n }\n\n get experimentalFaceletScale(): never {\n throw err(\"experimentalFaceletScale\");\n }\n\n set backView(backView: BackViewLayoutWithAuto) {\n this.experimentalModel.backView.set(backView);\n }\n get backView(): never {\n throw err(\"backView\");\n }\n\n set background(backgroundTheme: BackgroundThemeWithAuto) {\n this.experimentalModel.twistySceneModel.background.set(backgroundTheme);\n }\n get background(): never {\n throw err(\"background\");\n }\n\n set colorScheme(colorScheme: ColorSchemeWithAuto) {\n this.experimentalModel.twistySceneModel.colorSchemeRequest.set(colorScheme);\n }\n get colorScheme(): never {\n throw err(\"colorScheme\");\n }\n\n set controlPanel(newControlPanel: ControlPanelThemeWithAuto) {\n this.experimentalModel.controlPanel.set(newControlPanel);\n }\n get controlPanel(): never {\n throw err(\"controlPanel\");\n }\n\n set visualization(visualizationFormat: VisualizationFormatWithAuto) {\n this.experimentalModel.visualizationFormat.set(visualizationFormat);\n }\n get visualization(): never {\n throw err(\"visualization\");\n }\n\n set experimentalTitle(title: string | null) {\n this.experimentalModel.title.set(title);\n }\n get experimentalTitle(): never {\n throw err(\"experimentalTitle\");\n }\n\n set experimentalVideoURL(videoURL: string | null) {\n this.experimentalModel.videoURL.set(videoURL);\n }\n get experimentalVideoURL(): never {\n throw err(\"experimentalVideoURL\");\n }\n\n set experimentalCompetitionID(competitionID: string | null) {\n this.experimentalModel.competitionID.set(competitionID);\n }\n get experimentalCompetitionID(): never {\n throw err(\"experimentalCompetitionID\");\n }\n\n set viewerLink(viewerLinkPage: ViewerLinkPageWithAuto) {\n this.experimentalModel.viewerLink.set(viewerLinkPage);\n }\n get viewerLink(): never {\n throw err(\"viewerLink\");\n }\n\n set experimentalMovePressInput(movePressInput: MovePressInput) {\n this.experimentalModel.twistySceneModel.movePressInput.set(movePressInput);\n }\n get experimentalMovePressInput(): never {\n throw err(\"experimentalMovePressInput\");\n }\n\n set experimentalMovePressCancelOptions(movePressCancelOptions: AppendCancelOptions) {\n this.experimentalModel.twistySceneModel.movePressCancelOptions.set(\n movePressCancelOptions,\n );\n }\n get experimentalMovePressCancelOptions(): never {\n throw err(\"experimentalMovePressCancelOptions\");\n }\n\n set cameraLatitude(latitude: number) {\n this.experimentalModel.twistySceneModel.orbitCoordinatesRequest.set({\n latitude,\n });\n }\n get cameraLatitude(): never {\n throw err(\"cameraLatitude\");\n }\n\n set cameraLongitude(longitude: number) {\n this.experimentalModel.twistySceneModel.orbitCoordinatesRequest.set({\n longitude,\n });\n }\n get cameraLongitude(): never {\n throw err(\"cameraLongitude\");\n }\n\n set cameraDistance(distance: number) {\n this.experimentalModel.twistySceneModel.orbitCoordinatesRequest.set({\n distance,\n });\n }\n get cameraDistance(): never {\n throw err(\"cameraDistance\");\n }\n\n set cameraLatitudeLimit(latitudeLimit: number) {\n this.experimentalModel.twistySceneModel.latitudeLimit.set(latitudeLimit);\n }\n get cameraLatitudeLimit(): never {\n throw err(\"cameraLatitudeLimit\");\n }\n\n set indexer(indexer: IndexerStrategyName) {\n this.experimentalModel.indexerConstructorRequest.set(indexer);\n }\n get indexer(): never {\n throw err(\"indexer\");\n }\n\n set tempoScale(newTempoScale: number) {\n this.experimentalModel.tempoScale.set(newTempoScale);\n }\n get tempoScale(): never {\n throw err(\"tempoScale\");\n }\n\n set experimentalSprite(url: string | URL) {\n this.experimentalModel.twistySceneModel.foundationStickerSpriteURL.set(url);\n }\n get experimentalSprite(): never {\n throw err(\"experimentalSprite\");\n }\n\n set experimentalHintSprite(url: string | URL) {\n this.experimentalModel.twistySceneModel.hintStickerSpriteURL.set(url);\n }\n get experimentalHintSprite(): never {\n throw err(\"experimentalHintSprite\");\n }\n\n set fullscreenElement(element: Element | null) {\n this.experimentalModel.twistySceneModel.fullscreenElement.set(element);\n }\n get fullscreenElement(): never {\n throw err(\"fullscreenElement\");\n }\n\n set experimentalInitialHintFaceletsAnimation(anim: InitialHintFaceletsAnimation) {\n this.experimentalModel.twistySceneModel.initialHintFaceletsAnimation.set(\n anim,\n );\n }\n get experimentalInitialHintFaceletsAnimation(): never {\n throw err(\"experimentalInitialHintFaceletsAnimation\");\n }\n\n set experimentalDragInput(dragInputMode: DragInputMode) {\n this.experimentalModel.twistySceneModel.dragInput.set(dragInputMode);\n }\n get experimentalDragInput(): never {\n throw err(\"experimentalDragInput\");\n }\n\n experimentalGet = new ExperimentalGetters(this.experimentalModel);\n}\n\nclass ExperimentalGetters {\n constructor(private model: TwistyPlayerModel) {}\n\n async alg(): Promise<Alg> {\n return (await this.model.alg.get()).alg;\n }\n\n async setupAlg(): Promise<Alg> {\n return (await this.model.setupAlg.get()).alg;\n }\n\n puzzleID(): Promise<PuzzleID> {\n return this.model.puzzleID.get();\n }\n\n async timestamp(): Promise<MillisecondTimestamp> {\n return (await this.model.detailedTimelineInfo.get()).timestamp;\n }\n}\n", "import type { Object3D } from \"three/src/Three.js\";\nimport type { Alg, Move } from \"../../alg\";\nimport type { AlgLeaf } from \"../../alg/alg-nodes/AlgNode\";\nimport type { AppendCancelOptions, AppendOptions } from \"../../alg/simplify\";\nimport type { PuzzleDescriptionString } from \"../../puzzle-geometry/pgPuzzles\";\nimport type { ExperimentalStickeringMask } from \"../../puzzles/cubing-private\";\nimport type { ExperimentalStickering } from \"..\";\nimport { RenderScheduler } from \"../controllers/RenderScheduler\";\nimport type { TwistyAnimationControllerDelegate } from \"../controllers/TwistyAnimationController\";\nimport { TwistyPlayerController } from \"../controllers/TwistyPlayerController\";\nimport type { HintFaceletStyleWithAuto } from \"../model/props/puzzle/display/HintFaceletProp\";\nimport type { InitialHintFaceletsAnimation } from \"../model/props/puzzle/display/InitialHintFaceletsAnimationProp\";\nimport type { DragInputMode } from \"../model/props/puzzle/state/DragInputProp\";\nimport type { MovePressInput } from \"../model/props/puzzle/state/MovePressInputProp\";\nimport type { SetupToLocation } from \"../model/props/puzzle/state/SetupAnchorProp\";\nimport type { PuzzleID } from \"../model/props/puzzle/structure/PuzzleIDRequestProp\";\nimport type { BackgroundThemeWithAuto } from \"../model/props/viewer/BackgroundProp\";\nimport type { BackViewLayoutWithAuto } from \"../model/props/viewer/BackViewProp\";\nimport type {\n ColorScheme,\n ColorSchemeWithAuto,\n} from \"../model/props/viewer/ColorSchemeRequestProp\";\nimport {\n type ControlPanelThemeWithAuto,\n controlsLocations,\n} from \"../model/props/viewer/ControlPanelProp\";\nimport type { ViewerLinkPageWithAuto } from \"../model/props/viewer/ViewerLinkProp\";\nimport type { VisualizationFormatWithAuto } from \"../model/props/viewer/VisualizationProp\";\nimport type { VisualizationStrategy } from \"../model/props/viewer/VisualizationStrategyProp\";\nimport { Twisty2DSceneWrapper } from \"./2D/Twisty2DSceneWrapper\";\nimport type { Twisty3DPuzzle } from \"./3D/puzzles/Twisty3DPuzzle\";\nimport { Twisty3DSceneWrapper } from \"./3D/Twisty3DSceneWrapper\";\nimport type { Twisty3DVantage } from \"./3D/Twisty3DVantage\";\nimport { ClassListManager } from \"./ClassListManager\";\nimport { TwistyButtons } from \"./control-panel/TwistyButtons\";\nimport { TwistyScrubber } from \"./control-panel/TwistyScrubber\";\nimport { InitialValueTracker } from \"./InitialValueTracker\";\nimport { customElementsShim } from \"./node-custom-element-shims\";\nimport { downloadURL, getDefaultFilename, screenshot } from \"./screenshot\";\nimport { twistyPlayerCSS } from \"./TwistyPlayer.css\";\nimport { TwistyPlayerSettable } from \"./TwistyPlayerSettable\";\n\nconst DATA_ATTRIBUTE_PREFIX = \"data-\";\n\n// TODO: I couldn't figure out how to use use more specific types. Ideally, we'd\n// enforce consistency with the model.\nexport const twistyPlayerAttributeMap = {\n // TODO: We assume each of these can be set using a string or will be automatically converted by JS (e.g. numbers). Can we enforce\n // that with types? Do we need to add a translation mechanism for things we\n // don't want to leave settable as strings?\n // TODO: Enum validation.\n\n // Alg\n alg: \"alg\",\n \"experimental-setup-alg\": \"experimentalSetupAlg\",\n\n // String-based\n \"experimental-setup-anchor\": \"experimentalSetupAnchor\",\n puzzle: \"puzzle\",\n \"experimental-puzzle-description\": \"experimentalPuzzleDescription\",\n visualization: \"visualization\",\n \"hint-facelets\": \"hintFacelets\",\n \"experimental-stickering\": \"experimentalStickering\",\n \"experimental-stickering-mask-orbits\": \"experimentalStickeringMaskOrbits\",\n background: \"background\",\n \"color-scheme\": \"colorScheme\",\n \"control-panel\": \"controlPanel\",\n \"back-view\": \"backView\",\n \"experimental-initial-hint-facelets-animation\":\n \"experimentalInitialHintFaceletsAnimation\",\n // \"indexer\": \"indexer\",\n \"viewer-link\": \"viewerLink\",\n \"experimental-move-press-input\": \"experimentalMovePressInput\",\n \"experimental-drag-input\": \"experimentalDragInput\",\n\n // Metadata\n \"experimental-title\": \"experimentalTitle\",\n \"experimental-video-url\": \"experimentalVideoURL\",\n \"experimental-competition-id\": \"experimentalCompetitionID\",\n\n // Number-based\n \"camera-latitude\": \"cameraLatitude\",\n \"camera-longitude\": \"cameraLongitude\",\n \"camera-distance\": \"cameraDistance\",\n \"camera-latitude-limit\": \"cameraLatitudeLimit\",\n \"tempo-scale\": \"tempoScale\",\n\n // URL-based\n \"experimental-sprite\": \"experimentalSprite\",\n \"experimental-hint-sprite\": \"experimentalHintSprite\",\n};\n\nexport type TwistyPlayerAttribute = keyof typeof twistyPlayerAttributeMap;\n\nconst configKeys: Record<TwistyPlayerAttribute, true> = Object.fromEntries(\n Object.values(twistyPlayerAttributeMap).map((s) => [s, true]),\n) as any;\n\n// TODO: Find a way to share this def with `attributeMap`.\n/**\n * The config argument passed to {@link TwistyPlayer} when calling the\n * constructor. This interface type be useful for avoiding bugs when you would\n * like to create a {@link TwistyPlayer} using a dynamic config, or by combining\n * configs.\n *\n * ```js\n * import { TwistyPlayer, type TwistyPlayerConfig } from \"cubing/twisty\";\n *\n * const MY_DEFAULT_CONFIG: TwistyPlayerConfig = {\n * puzzle: \"megaminx\",\n * alg: \"R U R'\"\n * };\n * export function createTwistyPlayer(overrideConfig: TwistyPlayerConfig) {\n * const options = { ...MY_DEFAULT_CONFIG, ...overrideConfig };\n * return new TwistyPlayer(options);\n * }\n *\n * // Example: if the current page is https://alpha.twizzle.net/edit/?alg=M2+E2+S2\n * // then this gives us the \"alg\" param value \"M2 E2 S2\".\n * const myOverrideConfig: TwistyPlayerConfig = {};\n * const algParam = new URL(location.href).searchParams.get(\"alg\");\n * if (algParam) {\n * myOverrideConfig.alg = algParam;\n * }\n * createTwistyPlayer(myOverrideConfig);\n * ```\n *\n * @category TwistyPlayer\n */\nexport interface TwistyPlayerConfig {\n // Alg\n alg?: Alg | string;\n experimentalSetupAlg?: Alg | string;\n // String-based\n experimentalSetupAnchor?: SetupToLocation; // TODO: \"auto\"\n puzzle?: PuzzleID;\n experimentalPuzzleDescription?: PuzzleDescriptionString;\n visualization?: VisualizationFormatWithAuto;\n hintFacelets?: HintFaceletStyleWithAuto;\n experimentalStickering?: ExperimentalStickering | null;\n experimentalStickeringMaskOrbits?: ExperimentalStickeringMask | string;\n background?: BackgroundThemeWithAuto;\n colorScheme?: ColorSchemeWithAuto;\n controlPanel?: ControlPanelThemeWithAuto;\n backView?: BackViewLayoutWithAuto;\n experimentalInitialHintFaceletsAnimation?: InitialHintFaceletsAnimation;\n // \"indexer\"?: \"indexer\";\n viewerLink?: ViewerLinkPageWithAuto;\n experimentalMovePressInput?: MovePressInput;\n experimentalDragInput?: DragInputMode;\n // Metadata\n experimentalTitle?: string | null;\n experimentalVideoURL?: string;\n experimentalCompetitionID?: string;\n // Number-based\n cameraLatitude?: number;\n cameraLongitude?: number;\n cameraDistance?: number;\n cameraLatitudeLimit?: number;\n tempoScale?: number;\n // URL-based\n experimentalSprite?: string | null;\n experimentalHintSprite?: string | null;\n // TODO: Not supported as attributes\n experimentalMovePressCancelOptions?: AppendCancelOptions; // TODO: Support setting via a simplified attribute enum?\n}\n\nconst propOnly: Record<string, boolean> = {\n experimentalMovePressCancelOptions: true,\n};\n\nlet cachedSharedIntersectionObserver: IntersectionObserver | undefined;\nconst intersectedCallback = Symbol(\"intersectedCallback\");\nfunction waitForIntersection(player: TwistyPlayer) {\n cachedSharedIntersectionObserver ??= new IntersectionObserver(\n (entries, observer) => {\n for (const entry of entries) {\n if (entry.isIntersecting && entry.intersectionRect.height > 0) {\n (entry.target as TwistyPlayer)[intersectedCallback]();\n observer.unobserve(entry.target);\n }\n }\n },\n );\n cachedSharedIntersectionObserver.observe(player);\n}\n\n/**\n * TwistyPlayer is the heart of `cubing.js`. It can be used to display a puzzle on a web page like this:\n *\n * <script src=\"path/to/cubing/twisty\" type=\"module\"></script>\n * <twisty-player alg=\"R U R'\"></twisty-player>\n *\n * You can also construct it directly in JavaScript:\n *\n * ```js\n * import { TwistyPlayer } from \"cubing/twisty\";\n * const twistyPlayer = new TwistyPlayer({alg: \"R U R'\"});\n * // Once the page has loaded, you can do this:\n * document.body.appendChild(twistyPlayer);\n * ```\n *\n * See {@link https://js.cubing.net/cubing/} for more examples.\n *\n * @category TwistyPlayer\n */\nexport class TwistyPlayer\n extends TwistyPlayerSettable\n implements TwistyAnimationControllerDelegate\n{\n controller: TwistyPlayerController = new TwistyPlayerController(\n this.experimentalModel,\n this,\n );\n\n buttons?: TwistyButtons;\n\n experimentalCanvasClickCallback: (...args: any) => void = () => {};\n // #onCanvasClick() {\n\n // }\n\n constructor(config: TwistyPlayerConfig = {}) {\n super();\n\n // TODO: double-check that these are all getting set sync without causing extra work.\n for (const [propName, value] of Object.entries(config)) {\n if (\n !(configKeys[propName as TwistyPlayerAttribute] || propOnly[propName])\n ) {\n console.warn(`Invalid config passed to TwistyPlayer: ${propName}`);\n break;\n }\n (this as any)[propName] = value;\n }\n }\n\n #controlsManager: ClassListManager<ControlPanelThemeWithAuto> =\n new ClassListManager<ControlPanelThemeWithAuto>(\n this,\n \"controls-\",\n ([\"auto\"] as ControlPanelThemeWithAuto[]).concat(\n Object.keys(controlsLocations) as ControlPanelThemeWithAuto[],\n ),\n );\n\n #visualizationWrapperElem = document.createElement(\"div\"); // TODO: Better pattern.\n #errorElem = document.createElement(\"div\"); // TODO: Better pattern.\n #alreadyConnected = false; // TODO: support resetting\n connectedCallback(): void {\n this.addCSS(twistyPlayerCSS);\n waitForIntersection(this);\n }\n\n async [intersectedCallback](): Promise<void> {\n if (this.#alreadyConnected) {\n return;\n }\n this.#alreadyConnected = true;\n\n this.addElement(this.#visualizationWrapperElem).classList.add(\n \"visualization-wrapper\",\n );\n this.addElement(this.#errorElem).classList.add(\"error-elem\");\n this.#errorElem.textContent = \"Error\";\n this.experimentalModel.userVisibleErrorTracker.addFreshListener(\n (userVisibleError) => {\n const errorString: string | null = userVisibleError.errors[0] ?? null;\n this.contentWrapper.classList.toggle(\"error\", !!errorString);\n if (errorString) {\n this.#errorElem.textContent = errorString;\n }\n },\n );\n\n const scrubber = new TwistyScrubber(\n this.experimentalModel,\n this.controller,\n );\n this.contentWrapper.appendChild(scrubber);\n\n this.buttons = new TwistyButtons(\n this.experimentalModel,\n this.controller,\n this,\n );\n this.contentWrapper.appendChild(this.buttons);\n\n this.experimentalModel.twistySceneModel.background.addFreshListener(\n (backgroundTheme: BackgroundThemeWithAuto) => {\n this.contentWrapper.classList.toggle(\n \"checkered\",\n [\"auto\", \"checkered\"].includes(backgroundTheme),\n );\n this.contentWrapper.classList.toggle(\n \"checkered-transparent\",\n backgroundTheme === \"checkered-transparent\",\n );\n },\n );\n\n this.experimentalModel.twistySceneModel.colorScheme.addFreshListener(\n (colorScheme: ColorScheme) => {\n this.contentWrapper.classList.toggle(\n \"dark-mode\",\n [\"dark\"].includes(colorScheme),\n );\n },\n );\n\n this.experimentalModel.controlPanel.addFreshListener(\n (controlPanel: ControlPanelThemeWithAuto) => {\n this.#controlsManager.setValue(controlPanel);\n },\n );\n\n this.experimentalModel.visualizationStrategy.addFreshListener(\n this.#setVisualizationWrapper.bind(this),\n );\n\n this.experimentalModel.puzzleID.addFreshListener(this.flash.bind(this));\n }\n\n #flashLevel: \"auto\" | \"none\" = \"auto\";\n /** @deprecated */\n experimentalSetFlashLevel(newLevel: \"auto\" | \"none\"): void {\n this.#flashLevel = newLevel;\n }\n\n flash() {\n if (this.#flashLevel === \"auto\") {\n this.#visualizationWrapper?.animate([{ opacity: 0.25 }, { opacity: 1 }], {\n duration: 250,\n easing: \"ease-out\",\n });\n }\n }\n\n #visualizationWrapper: Twisty2DSceneWrapper | Twisty3DSceneWrapper | null =\n null;\n #initial3DVisualizationWrapper =\n new InitialValueTracker<Twisty3DSceneWrapper>();\n\n #visualizationStrategy: VisualizationStrategy | null = null;\n #setVisualizationWrapper(strategy: VisualizationStrategy): void {\n if (strategy !== this.#visualizationStrategy) {\n this.#visualizationWrapper?.remove();\n this.#visualizationWrapper?.disconnect();\n let newWrapper: Twisty2DSceneWrapper | Twisty3DSceneWrapper;\n switch (strategy) {\n case \"2D\":\n case \"experimental-2D-LL\":\n case \"experimental-2D-LL-face\": {\n newWrapper = new Twisty2DSceneWrapper(\n this.experimentalModel.twistySceneModel,\n strategy,\n );\n break;\n }\n case \"Cube3D\":\n case \"PG3D\": {\n // TODO: Properly wire this up so we can set PG3D for the cube.\n newWrapper = new Twisty3DSceneWrapper(this.experimentalModel);\n this.#initial3DVisualizationWrapper.handleNewValue(newWrapper);\n break;\n }\n default:\n throw new Error(\"Invalid visualization\");\n }\n this.#visualizationWrapperElem.appendChild(newWrapper);\n this.#visualizationWrapper = newWrapper;\n this.#visualizationStrategy = strategy;\n }\n }\n\n async experimentalCurrentVantages(): Promise<Iterable<Twisty3DVantage>> {\n this.connectedCallback();\n const wrapper = this.#visualizationWrapper;\n if (wrapper instanceof Twisty3DSceneWrapper) {\n return wrapper.experimentalVantages();\n }\n return [];\n }\n\n async experimentalCurrentCanvases(): Promise<HTMLCanvasElement[]> {\n const vantages = await this.experimentalCurrentVantages();\n const canvases: HTMLCanvasElement[] = [];\n for (const vantage of vantages) {\n canvases.push((await vantage.canvasInfo()).canvas);\n }\n return canvases;\n }\n\n /**\n * Get the first available puzzle `Object3D`. This can be inserted into\n * another `three.js` scene, essentially \"adopting\" it from the\n * `TwistyPlayer`'s scenes while still allowing the `TwistyPlayer` to animate\n * it. The function returns a `Promise` that returns if and when the\n * `Object3D` is available, and accepts a callback that is called whenever a\n * render is scheduled for the puzzle (essentially, if something about the\n * puzzle has changed, like its appearance or current animated state).\n *\n * Note:\n * - This may never resolve if the player never creates the relevant 3D object\n * under the hood (e.g. if the config is set to 2D, or is not valid for\n * rendering a puzzle)\n * - The architecture of `cubing.js` may change significantly, so it is not\n * guaranteed that a `three.js` `Object3D` will be available from the main\n * thread in the future.\n * - This function only returns the current `three.js` puzzle object (once one\n * exists). If you change e.g. the `puzzle` config for the player, then the\n * object will currently become stale. This may be replaced with more\n * convenient behaviour in the future.\n *\n * @deprecated */\n async experimentalCurrentThreeJSPuzzleObject(\n puzzleRenderScheduledCallback?: () => void,\n ): Promise<Object3D> {\n this.connectedCallback();\n const sceneWrapper = await this.#initial3DVisualizationWrapper.promise;\n const puzzleWrapper =\n await sceneWrapper.experimentalTwisty3DPuzzleWrapper();\n const twisty3DPuzzlePromise: Promise<Twisty3DPuzzle> =\n puzzleWrapper.twisty3DPuzzle();\n const safeToCallback = (async () => {\n await twisty3DPuzzlePromise;\n await new Promise((resolve) => setTimeout(resolve, 0));\n })();\n if (puzzleRenderScheduledCallback) {\n // We want to notify the callback when the render is *scheduled* (once per\n // render), not when it is run. So we have a stub callback for the\n // scheduler itself, and rely on `scheduler.requestIsPending()` to dedup\n // requests below.\n const scheduler = new RenderScheduler(async () => {});\n puzzleWrapper.addEventListener(\"render-scheduled\", async () => {\n if (!scheduler.requestIsPending()) {\n scheduler.requestAnimFrame();\n await safeToCallback;\n puzzleRenderScheduledCallback();\n }\n });\n }\n return twisty3DPuzzlePromise;\n }\n\n jumpToStart(options?: { flash: boolean }): void {\n this.controller.jumpToStart(options);\n }\n\n jumpToEnd(options?: { flash: boolean }): void {\n this.controller.jumpToEnd(options);\n }\n\n play(): void {\n this.controller.togglePlay(true);\n }\n\n pause(): void {\n this.controller.togglePlay(false);\n }\n\n // Inspiration:\n // - https://developer.mozilla.org/en-US/docs/Web/API/Element/toggleAttribute (`force` argument)\n // - https://developer.mozilla.org/en-US/docs/Web/API/DOMTokenList/toggle (`force` argument)\n // We still provide `play()` and `pause()` individually for convenience, though.\n togglePlay(play?: boolean): void {\n this.controller.togglePlay(play);\n }\n\n // TODO: Animate the new move.\n // TODO: Automatically handle puzzle.\n experimentalAddMove(\n flexibleMove: Move | string,\n options?: AppendOptions,\n ): void {\n this.experimentalModel.experimentalAddMove(flexibleMove, options);\n }\n\n // TODO: Animate the new move.\n // TODO: Automatically handle puzzle.\n experimentalAddAlgLeaf(algLeaf: AlgLeaf, options?: AppendOptions): void {\n this.experimentalModel.experimentalAddAlgLeaf(algLeaf, options);\n }\n\n static get observedAttributes(): string[] {\n const observed: string[] = [];\n for (const key of Object.keys(twistyPlayerAttributeMap)) {\n observed.push(key, DATA_ATTRIBUTE_PREFIX + key);\n }\n return observed;\n }\n\n experimentalRemoveFinalChild(): void {\n this.experimentalModel.experimentalRemoveFinalChild();\n }\n\n attributeChangedCallback(\n attributeName: string,\n _oldValue: string,\n newValue: string,\n ): void {\n if (attributeName.startsWith(DATA_ATTRIBUTE_PREFIX)) {\n attributeName = attributeName.slice(DATA_ATTRIBUTE_PREFIX.length);\n }\n const setterName =\n twistyPlayerAttributeMap[attributeName as TwistyPlayerAttribute];\n if (!setterName) {\n return;\n }\n\n (this as any)[setterName] = newValue;\n }\n\n // TODO: Make this more ergonomic and flexible.\n // TODO: dimensions.\n async experimentalScreenshot(options?: {\n width: number;\n height: number;\n }): Promise<string> {\n return (await screenshot(this.experimentalModel, options)).dataURL;\n }\n\n // TODO: Make this more ergonomic and flexible.\n // TODO: dimensions.\n async experimentalDownloadScreenshot(filename?: string): Promise<void> {\n if (\n [\"2D\", \"experimental-2D-LL\", \"experimental-2D-LL-face\"].includes(\n await this.experimentalModel.visualizationStrategy.get(),\n )\n ) {\n // TODO: This has lots of async issues. It should also go into the screenshot impl file.\n const wrapper2D = this.#visualizationWrapper as Twisty2DSceneWrapper;\n const twisty2DPuzzle = await wrapper2D\n .currentTwisty2DPuzzleWrapper()!\n .twisty2DPuzzle();\n const str = new XMLSerializer().serializeToString(\n twisty2DPuzzle.svgWrapper!.svgElement,\n );\n const url = URL.createObjectURL(new Blob([str]));\n downloadURL(\n url,\n filename ?? (await getDefaultFilename(this.experimentalModel)),\n \"svg\",\n );\n } else {\n await (await screenshot(this.experimentalModel)).download(filename);\n }\n }\n}\n\ncustomElementsShim.define(\"twisty-player\", TwistyPlayer);\ndeclare global {\n interface HTMLElementTagNameMap {\n \"twisty-player\": TwistyPlayer;\n }\n}\n", "import {\n type Alg,\n type Commutator,\n type Conjugate,\n functionFromTraversal,\n type Grouping,\n type LineComment,\n type Move,\n type Newline,\n type Pause,\n TraversalDownUp,\n} from \"../../../alg\";\nimport type { Parsed } from \"../../../alg/parseAlg\";\nimport type {\n LeafCount,\n LeafIndex,\n} from \"../../controllers/indexer/AlgIndexer\";\nimport type { AnimatedLeafAlgNode } from \"../../controllers/indexer/simultaneous-moves/simul-moves\";\n\nexport type AnimatedLeafAlgNodeInfo = {\n leaf: Parsed<AnimatedLeafAlgNode>;\n idx: LeafIndex;\n};\nexport type OrderedLeafTokens = AnimatedLeafAlgNodeInfo[];\n\ninterface DataUp {\n tokens: OrderedLeafTokens;\n numLeavesInside: LeafCount;\n}\n\ninterface DataDown {\n numMovesSoFar: LeafCount;\n}\n\nclass LeafTokens extends TraversalDownUp<DataDown, DataUp> {\n public traverseAlg(alg: Alg, dataDown: DataDown): DataUp {\n const algNodeArrays: OrderedLeafTokens[] = [];\n let numMovesInside = 0;\n for (const algNode of alg.childAlgNodes()) {\n const dataUp = this.traverseAlgNode(algNode, {\n numMovesSoFar: (dataDown.numMovesSoFar + numMovesInside) as LeafCount,\n });\n algNodeArrays.push(dataUp.tokens);\n numMovesInside += dataUp.numLeavesInside;\n }\n return {\n tokens: Array.prototype.concat(...algNodeArrays),\n numLeavesInside: numMovesInside as LeafCount,\n };\n }\n\n public traverseGrouping(grouping: Grouping, dataDown: DataDown): DataUp {\n const dataUp = this.traverseAlg(grouping.alg, dataDown);\n return {\n tokens: dataUp.tokens,\n numLeavesInside: (dataUp.numLeavesInside * grouping.amount) as LeafCount,\n };\n }\n\n public traverseMove(move: Move, dataDown: DataDown): DataUp {\n return {\n tokens: [\n {\n leaf: move as Parsed<Move>,\n idx: dataDown.numMovesSoFar as number as LeafIndex,\n },\n ],\n numLeavesInside: 1 as LeafCount,\n }; // TODO: What if not parsed?\n }\n\n public traverseCommutator(\n commutator: Commutator,\n dataDown: DataDown,\n ): DataUp {\n const dataUpA = this.traverseAlg(commutator.A, dataDown);\n const dataUpB = this.traverseAlg(commutator.B, {\n numMovesSoFar: (dataDown.numMovesSoFar +\n dataUpA.numLeavesInside) as LeafCount,\n });\n return {\n tokens: dataUpA.tokens.concat(dataUpB.tokens),\n numLeavesInside: (dataUpA.numLeavesInside * 2 +\n dataUpB.numLeavesInside) as LeafCount,\n };\n }\n\n public traverseConjugate(conjugate: Conjugate, dataDown: DataDown): DataUp {\n const dataUpA = this.traverseAlg(conjugate.A, dataDown);\n const dataUpB = this.traverseAlg(conjugate.B, {\n numMovesSoFar: (dataDown.numMovesSoFar +\n dataUpA.numLeavesInside) as LeafCount,\n });\n return {\n tokens: dataUpA.tokens.concat(dataUpB.tokens),\n numLeavesInside: (dataUpA.numLeavesInside * 2 +\n dataUpB.numLeavesInside * 2) as LeafCount,\n };\n }\n\n public traversePause(pause: Pause, dataDown: DataDown): DataUp {\n return {\n tokens: [\n {\n leaf: pause as Parsed<Pause>,\n idx: dataDown.numMovesSoFar as number as LeafIndex,\n },\n ],\n numLeavesInside: 1 as LeafCount,\n }; // TODO: What if not parsed?\n }\n\n public traverseNewline(_newline: Newline, _dataDown: DataDown): DataUp {\n return {\n tokens: [],\n numLeavesInside: 0 as LeafCount,\n };\n }\n\n public traverseLineComment(\n _comment: LineComment,\n _dataDown: DataDown,\n ): DataUp {\n return {\n tokens: [],\n numLeavesInside: 0 as LeafCount,\n };\n }\n}\n\nexport const leafTokens = functionFromTraversal(LeafTokens);\n", "// TODO: Move this?\n\nimport type { Alg } from \"../../../alg\";\nimport {\n endCharIndexKey,\n type Parsed,\n startCharIndexKey,\n} from \"../../../alg/parseAlg\";\nimport type { LeafCount } from \"../../controllers/indexer/AlgIndexer\";\nimport {\n type AlgWithIssues,\n algWithIssuesFromString,\n} from \"../../model/props/puzzle/state/AlgProp\";\nimport {\n SimpleTwistyPropSource,\n TwistyPropDerived,\n TwistyPropSource,\n} from \"../../model/props/TwistyProp\";\nimport {\n type AnimatedLeafAlgNodeInfo,\n leafTokens,\n type OrderedLeafTokens,\n} from \"./LeafTokens\";\n\nexport class TwistyAlgEditorValueProp extends SimpleTwistyPropSource<string> {\n getDefaultValue(): string {\n return \"\";\n }\n}\n\ninterface AlgEditorAlgWithIssuesPropInput {\n value: string;\n}\nclass AlgEditorAlgWithIssuesProp extends TwistyPropDerived<\n AlgEditorAlgWithIssuesPropInput,\n AlgWithIssues\n> {\n derive(input: AlgEditorAlgWithIssuesPropInput): AlgWithIssues {\n return algWithIssuesFromString(input.value);\n }\n // TODO: canReuse needs to take the source string into account.\n}\n\ninterface SelectionInfoPropInput {\n selectionStart: number;\n selectionEnd: number;\n}\ninterface SelectionInfo extends SelectionInfoPropInput {\n endChangedMostRecently: boolean;\n}\nexport class TwistyAlgEditorSelectionProp extends TwistyPropSource<\n SelectionInfo,\n SelectionInfoPropInput\n> {\n getDefaultValue() {\n return {\n selectionStart: 0,\n selectionEnd: 0,\n endChangedMostRecently: false,\n };\n }\n\n async derive(\n input: SelectionInfoPropInput,\n oldValue: Promise<SelectionInfo>,\n ): Promise<SelectionInfo> {\n const { selectionStart, selectionEnd } = input;\n const lastResult = await oldValue;\n const endChangedMostRecently =\n input.selectionStart === lastResult.selectionStart &&\n input.selectionEnd !== (await oldValue).selectionEnd;\n return {\n selectionStart,\n selectionEnd,\n endChangedMostRecently,\n };\n }\n}\n\ninterface TargetCharPropInputs {\n selectionInfo: SelectionInfo;\n}\n\nexport class TargetCharProp extends TwistyPropDerived<\n TargetCharPropInputs,\n number\n> {\n derive(inputs: TargetCharPropInputs) {\n return inputs.selectionInfo.endChangedMostRecently\n ? inputs.selectionInfo.selectionEnd\n : inputs.selectionInfo.selectionStart;\n }\n}\n\ninterface LeafTokensPropInputs {\n algWithIssues: AlgWithIssues;\n}\nclass LeafTokensProp extends TwistyPropDerived<\n LeafTokensPropInputs,\n OrderedLeafTokens\n> {\n derive(inputs: LeafTokensPropInputs): OrderedLeafTokens {\n return leafTokens(inputs.algWithIssues.alg as Parsed<Alg>, {\n numMovesSoFar: 0 as LeafCount,\n }).tokens;\n }\n}\n\ninterface LeafToHighlightPropInputs {\n targetChar: number;\n leafTokens: OrderedLeafTokens;\n}\ntype HighlightWhere = \"before\" | \"start\" | \"inside\" | \"end\" | \"after\";\nexport interface HighlightInfo {\n leafInfo: AnimatedLeafAlgNodeInfo;\n where: HighlightWhere;\n}\nclass LeafToHighlightProp extends TwistyPropDerived<\n LeafToHighlightPropInputs,\n HighlightInfo | null\n> {\n derive(inputs: LeafToHighlightPropInputs): HighlightInfo | null {\n function withWhere(\n leafInfo: AnimatedLeafAlgNodeInfo | null,\n ): HighlightInfo | null {\n if (leafInfo === null) {\n return null;\n }\n let where: HighlightWhere;\n if (inputs.targetChar < leafInfo.leaf[startCharIndexKey]) {\n where = \"before\";\n } else if (inputs.targetChar === leafInfo.leaf[startCharIndexKey]) {\n where = \"start\";\n } else if (inputs.targetChar < leafInfo.leaf[endCharIndexKey]) {\n where = \"inside\";\n } else if (inputs.targetChar === leafInfo.leaf[endCharIndexKey]) {\n where = \"end\";\n } else {\n where = \"after\";\n }\n return {\n leafInfo,\n where,\n };\n }\n\n let lastLeafInfo: AnimatedLeafAlgNodeInfo | null = null;\n // TODO: binary search\n for (const leafInfo of inputs.leafTokens) {\n if (\n inputs.targetChar < leafInfo.leaf[startCharIndexKey] &&\n lastLeafInfo !== null\n ) {\n return withWhere(lastLeafInfo);\n }\n if (inputs.targetChar <= leafInfo.leaf[endCharIndexKey]) {\n return withWhere(leafInfo);\n }\n lastLeafInfo = leafInfo;\n }\n\n return withWhere(lastLeafInfo);\n }\n}\n\nexport class TwistyAlgEditorModel {\n valueProp = new TwistyAlgEditorValueProp();\n selectionProp = new TwistyAlgEditorSelectionProp();\n targetCharProp = new TargetCharProp({ selectionInfo: this.selectionProp });\n\n algEditorAlgWithIssues = new AlgEditorAlgWithIssuesProp({\n value: this.valueProp,\n });\n\n leafTokensProp = new LeafTokensProp({\n algWithIssues: this.algEditorAlgWithIssues,\n });\n\n leafToHighlight = new LeafToHighlightProp({\n leafTokens: this.leafTokensProp,\n targetChar: this.targetCharProp,\n });\n}\n", "import { Alg } from \"../../../alg\";\nimport { globalSafeDocument } from \"../document\";\n\nconst COMMENT_DELIMITER = \"//\";\n\nfunction maybeParse(str: string): Alg | null {\n try {\n return Alg.fromString(str);\n } catch {\n return null;\n }\n}\n\n// If there is no occurence, the original string is returned in the first entry.\n// If there is, the delimiter is included at the start of the second entry.\nfunction sliceBeforeFirstOccurrence(\n str: string,\n delimiter: string,\n): [before: string, after: string] {\n const idx = str.indexOf(delimiter);\n if (idx === -1) {\n return [str, \"\"];\n }\n return [str.slice(0, idx), str.slice(idx)];\n}\n\nfunction replaceSmartQuotesOutsideComments(str: string): string {\n const linesOut = [];\n for (const line of str.split(\"\\n\")) {\n let [before, after] = sliceBeforeFirstOccurrence(line, COMMENT_DELIMITER);\n before = before.replaceAll(\"\u2019\", \"'\");\n linesOut.push(before + after);\n }\n return linesOut.join(\"\\n\");\n}\n\nexport function pasteIntoTextArea(\n textArea: HTMLTextAreaElement,\n pastedText: string,\n): void {\n const { value: oldValue } = textArea;\n const { selectionStart, selectionEnd } = textArea;\n\n const textPrecedingSelection = oldValue.slice(0, selectionStart);\n const textFollowingSelection = oldValue.slice(selectionEnd);\n\n pastedText = pastedText.replaceAll(\"\\r\\n\", \"\\n\");\n\n // Does the last line end in a comment?\n // Note that we want the match to include \"R U R'\\n//hello there\" but not \"// hello there\\nR U R'\"\n const selectionStartsInExistingComment =\n textPrecedingSelection.match(/\\/\\/[^\\n]*$/);\n const pasteCreatesStartingComment =\n oldValue[selectionStart - 1] === \"/\" && pastedText[0] === \"/\"; // Pasting \"/ This is \u201Cweird\u201D.\" at the end of \"R U R' /\"\n const pasteStartsWithCommentText =\n selectionStartsInExistingComment || pasteCreatesStartingComment;\n\n const pasteEndsWithComment = pastedText.match(/\\/\\/[^\\n]*$/);\n\n // Replace smart quotes that are not in comments.\n let replacement = pastedText;\n if (pasteStartsWithCommentText) {\n const [before, after] = sliceBeforeFirstOccurrence(pastedText, \"\\n\");\n replacement = before + replaceSmartQuotesOutsideComments(after);\n } else {\n replacement = replaceSmartQuotesOutsideComments(pastedText);\n }\n\n /** Note: at this point, we would want to test which of the following produces\n * a valid alg:\n *\n * - No changes to `correctedPastedText`.\n * - Add a space prefix.\n * - Add a space suffix.\n *\n * However, the puzzle is not synchronously available to us, so we can't tell\n * whether pasting \"U\" before \"R\" should create \"UR\" (Megaminx) or \"U R\"\n * (3x3x3). So we optimistically assume the pasted alg is self-contained\n * (which is the case if it's a fully valid alg on its own) and try to perform\n * the latter directly.\n */\n\n const tryAddSpaceBefore =\n !pasteStartsWithCommentText &&\n selectionStart !== 0 && // Not at text start\n ![\"\\n\", \" \"].includes(replacement[0]) &&\n ![\"\\n\", \" \"].includes(oldValue[selectionStart - 1]); // Not at line start, no space before\n const tryAddSpaceAfter =\n !pasteEndsWithComment &&\n selectionEnd !== oldValue.length && // Not at text end\n !([\"\\n\", \" \"] as (string | undefined)[]).includes(replacement.at(-1)) &&\n ![\"\\n\", \" \"].includes(oldValue[selectionEnd]); // Not at line end, no space after\n\n function adoptSpacingIfValid(prefix: string, suffix: string): boolean {\n const candidate = prefix + replacement + suffix;\n const valid = !!maybeParse(\n textPrecedingSelection + candidate + textFollowingSelection,\n );\n if (valid) {\n replacement = candidate;\n }\n return valid;\n }\n\n // Here, we try possible space insertions. We use `||` for short-circuit logic, to adopt the first valid one.\n (tryAddSpaceBefore && tryAddSpaceAfter && adoptSpacingIfValid(\" \", \" \")) || // Paste \"R U R' U'\" over \" \" in \"F F'\" to create \"F R U R' U' F'\"\n (tryAddSpaceBefore && adoptSpacingIfValid(\" \", \"\")) || // Paste \"U\" after \"R'\" in \"R' L'\" to create \"R' U L'\"\n (tryAddSpaceAfter && adoptSpacingIfValid(\"\", \" \")); // Paste \"U\" before \"L'\" in \"R' L'\" to create \"R' U L'\"\n\n // `execCommand` is under-specced and deprecated, but it's more likely to allow undo and preserve history.\n const execCommandSuccess = globalSafeDocument?.execCommand(\n \"insertText\",\n false,\n replacement,\n );\n if (!execCommandSuccess) {\n // TODO: use \"select\" or \"preserve\" (https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setRangeText#selectmode)\n textArea.setRangeText(replacement, selectionStart, selectionEnd, \"end\");\n }\n}\n", "import { cssStyleSheetShim } from \"../node-custom-element-shims\";\n\nexport const twistyAlgEditorCSS = new cssStyleSheetShim();\ntwistyAlgEditorCSS.replaceSync(\n `\n:host {\n width: 384px;\n display: grid;\n}\n\n.wrapper {\n /*overflow: hidden;\n resize: horizontal;*/\n\n background: var(--background, none);\n display: grid;\n}\n\ntextarea, .carbon-copy {\n grid-area: 1 / 1 / 2 / 2;\n\n width: 100%;\n font-family: sans-serif;\n line-height: 1.2em;\n\n font-size: var(--font-size, inherit);\n font-family: var(--font-family, sans-serif);\n\n box-sizing: border-box;\n\n padding: var(--padding, 0.5em);\n /* Prevent horizontal growth. */\n overflow-x: hidden;\n}\n\ntextarea {\n resize: none;\n background: none;\n z-index: 2;\n border: 1px solid var(--border-color, rgba(0, 0, 0, 0.25));\n overflow: hidden;\n}\n\n.carbon-copy {\n white-space: pre-wrap;\n word-wrap: break-word;\n color: transparent;\n user-select: none;\n pointer-events: none;\n\n z-index: 1;\n}\n\n.carbon-copy .highlight {\n background: var(--highlight-color, rgba(255, 128, 0, 0.5));\n padding: 0.1em 0.2em;\n margin: -0.1em -0.2em;\n border-radius: 0.2em;\n}\n\n.wrapper.issue-warning textarea,\n.wrapper.valid-for-puzzle-warning textarea {\n outline: none;\n border: 1px solid rgba(200, 200, 0, 0.5);\n background: rgba(255, 255, 0, 0.1);\n}\n\n.wrapper.issue-error textarea,\n.wrapper.valid-for-puzzle-error textarea {\n outline: none;\n border: 1px solid red;\n background: rgba(255, 0, 0, 0.1);\n}\n`,\n);\n", "/**\n * Warning: the current implementation of <twisty-alg-editor> is *not good*,\n * but it is *good enough*. The important parts is that:\n *\n * - The editor can be used in apps without much effort.\n * - The editor handles alg validation and move highlighting *okay* when not\n * connected to a `<twisty-player>`.\n * - The editor stays in sync if it's connected to a `<twisty-player>`.\n *\n * The current implementation still has some race conditions and edge cases. A\n * proper rewrite with a better model would be very welcome.\n */\n\nimport type { ExperimentalParsed } from \"../../../alg\";\nimport { Alg, type Move, type Pause } from \"../../../alg\";\nimport {\n endCharIndexKey,\n type Parsed,\n startCharIndexKey,\n} from \"../../../alg/parseAlg\";\nimport type { MillisecondTimestamp } from \"../../controllers/AnimationTypes\";\nimport type {\n AlgProp,\n AlgWithIssues,\n} from \"../../model/props/puzzle/state/AlgProp\";\nimport type { CurrentLeavesSimplified } from \"../../model/props/puzzle/state/CurrentLeavesSimplified\";\nimport { ClassListManager } from \"../ClassListManager\";\nimport { ManagedCustomElement } from \"../ManagedCustomElement\";\nimport { customElementsShim } from \"../node-custom-element-shims\";\nimport { TwistyPlayer } from \"../TwistyPlayer\";\nimport { type HighlightInfo, TwistyAlgEditorModel } from \"./model\";\nimport { pasteIntoTextArea } from \"./paste\";\nimport { twistyAlgEditorCSS } from \"./TwistyAlgEditor.css\";\n\nconst ATTRIBUTE_FOR_TWISTY_PLAYER = \"for-twisty-player\";\nconst ATTRIBUTE_PLACEHOLDER = \"placeholder\";\nconst ATTRIBUTE_TWISTY_PLAYER_PROP = \"twisty-player-prop\";\n\ntype TwistyPlayerAlgProp = \"alg\" | \"setupAlg\";\n\n/** @category Other Custom Elements */\nexport class TwistyAlgEditor extends ManagedCustomElement {\n model = new TwistyAlgEditorModel();\n\n // #alg: Alg = new Alg();\n #textarea: HTMLTextAreaElement = document.createElement(\"textarea\");\n #carbonCopy: HTMLDivElement = document.createElement(\"div\");\n #carbonCopyPrefix: HTMLSpanElement = document.createElement(\"span\");\n #carbonCopyHighlight: HTMLSpanElement = document.createElement(\"span\");\n #carbonCopySuffix: HTMLSpanElement = document.createElement(\"span\");\n\n // #textareaClassListManager: ClassListManager<\"none\" | \"warning\" | \"error\"> =\n // new ClassListManager(this, \"issue-\", [\"none\", \"warning\", \"error\"]);\n\n #textareaClassListValidForPuzzleManager: ClassListManager<\n \"none\" | \"warning\" | \"error\"\n > = new ClassListManager(this, \"valid-for-puzzle-\", [\n \"none\",\n \"warning\",\n \"error\",\n ]);\n\n #twistyPlayer: TwistyPlayer | null = null;\n #twistyPlayerProp: TwistyPlayerAlgProp;\n get #algProp(): AlgProp | null {\n if (this.#twistyPlayer === null) {\n return null;\n } else {\n return this.#twistyPlayer.experimentalModel[this.#twistyPlayerProp];\n }\n }\n\n // Temporary Workaround for Twizzle Explorer\n debugNeverRequestTimestamp: boolean = false;\n\n constructor(options?: {\n twistyPlayer?: TwistyPlayer;\n twistyPlayerProp?: TwistyPlayerAlgProp;\n }) {\n super();\n this.#carbonCopy.classList.add(\"carbon-copy\");\n this.addElement(this.#carbonCopy);\n this.#textarea.rows = 1;\n this.addElement(this.#textarea);\n this.#carbonCopyPrefix.classList.add(\"prefix\");\n this.#carbonCopy.appendChild(this.#carbonCopyPrefix);\n this.#carbonCopyHighlight.classList.add(\"highlight\");\n this.#carbonCopy.appendChild(this.#carbonCopyHighlight);\n this.#carbonCopySuffix.classList.add(\"suffix\");\n this.#carbonCopy.appendChild(this.#carbonCopySuffix);\n\n this.#textarea.placeholder = \"Alg\";\n // Prevent iOS from defaulting to smart quotes.\n this.#textarea.setAttribute(\"spellcheck\", \"false\");\n\n this.addCSS(twistyAlgEditorCSS);\n\n // TODO: What set of events should we register? `change`? `keydown`?\n this.#textarea.addEventListener(\"input\", () => {\n this.#onInputHasFired = true;\n this.onInput();\n });\n this.#textarea.addEventListener(\"blur\", () => this.onBlur());\n document.addEventListener(\"selectionchange\", () =>\n this.onSelectionChange(),\n );\n\n if (options?.twistyPlayer) {\n this.twistyPlayer = options.twistyPlayer;\n }\n this.#twistyPlayerProp = options?.twistyPlayerProp ?? \"alg\";\n\n if (options?.twistyPlayerProp === \"alg\") {\n this.model.leafToHighlight.addFreshListener(\n (highlightInfo: HighlightInfo | null) => {\n if (highlightInfo) {\n this.highlightLeaf(highlightInfo.leafInfo.leaf);\n }\n },\n );\n }\n }\n\n connectedCallback(): void {\n this.#textarea.addEventListener(\"paste\", (e) => {\n const text = e.clipboardData?.getData(\"text\");\n if (text) {\n pasteIntoTextArea(this.#textarea, text);\n e.preventDefault();\n this.onInput();\n }\n });\n }\n\n // TODO\n set algString(s: string) {\n this.#textarea.value = s;\n this.onInput();\n }\n\n // TODO: remove?\n get algString(): string {\n return this.#textarea.value;\n }\n\n // To we need a getter?\n set placeholder(placeholderText: string) {\n this.#textarea.placeholder = placeholderText;\n }\n\n #onInputHasFired = false;\n onInput(): void {\n this.#carbonCopyHighlight.hidden = true;\n this.highlightLeaf(null);\n\n // TODO: This is a hack so that the you don't get a warning when the cursor\n // is after the space while typing `R U`. It would be nice to have something\n // cursor-aware that can also ignore whitespace warnings (or other syntax\n // errors due to normal input) adjacent to the cursor when it's in the\n // middle, but this is suffuciently useful for now.\n const endTrimmed = this.#textarea.value.trimEnd();\n this.model.valueProp.set(endTrimmed);\n this.#algProp?.set(endTrimmed);\n }\n\n async onSelectionChange(): Promise<void> {\n if (\n document.activeElement !== this ||\n this.shadow.activeElement !== this.#textarea\n ) {\n return;\n }\n if (this.#twistyPlayerProp !== \"alg\") {\n return;\n }\n\n const { selectionStart, selectionEnd } = this.#textarea;\n this.model.selectionProp.set({\n selectionStart,\n selectionEnd,\n });\n }\n\n async onBlur(): Promise<void> {\n // TODO: Figure out how not to make the cursor jump.\n // const parsed = Alg.fromString(this.algString);\n // this.algString = parsed.toString();\n // const [currentLeavesSimplified, indexer] = await Promise.all([\n // this.#twistyPlayer!.model.currentLeavesSimplifiedProp.get(),\n // this.#twistyPlayer!.model.indexerProp.get(),\n // ]);\n // const leaf = indexer.getAnimLeaf(currentLeavesSimplified.stateIndex);\n // this.highlightLeaf(leaf as Parsed<Move | Pause> | null);\n }\n\n setAlgIssueClassForPuzzle(issues: \"none\" | \"warning\" | \"error\") {\n this.#textareaClassListValidForPuzzleManager.setValue(issues);\n }\n\n // `white-space: pre;` mostly matches the formatting of the `<textarea>`, *except* when we end with a newline.\n // So we add an space to ensure that there is a character on the final line (that is very unlikely to trigger extra line wrapping).\n #padSuffix(s: string): string {\n return s.endsWith(\"\\n\") ? `${s} ` : s;\n }\n\n #highlightedLeaf: ExperimentalParsed<Move | Pause> | null = null;\n // TODO: support a primary highlighted move and secondary ones.\n highlightLeaf(leaf: ExperimentalParsed<Move | Pause> | null): void {\n // if (this.#twistyPlayerProp !== \"alg\") {\n // // TODO: make this configurable\n // return;\n // }\n if (leaf === null) {\n this.#carbonCopyPrefix.textContent = \"\";\n this.#carbonCopyHighlight.textContent = \"\";\n this.#carbonCopySuffix.textContent = this.#padSuffix(\n this.#textarea.value,\n );\n return;\n }\n if (leaf === this.#highlightedLeaf) {\n return;\n }\n this.#highlightedLeaf = leaf;\n this.#carbonCopyPrefix.textContent = this.#textarea.value.slice(\n 0,\n leaf[startCharIndexKey],\n );\n this.#carbonCopyHighlight.textContent = this.#textarea.value.slice(\n leaf[startCharIndexKey],\n leaf[endCharIndexKey],\n );\n this.#carbonCopySuffix.textContent = this.#padSuffix(\n this.#textarea.value.slice(leaf[endCharIndexKey]),\n );\n this.#carbonCopyHighlight.hidden = false;\n }\n\n get twistyPlayer(): TwistyPlayer | null {\n return this.#twistyPlayer;\n }\n\n // TODO: spread out this impl over private methods instead of self-listeners.\n set twistyPlayer(twistyPlayer: TwistyPlayer | null) {\n if (this.#twistyPlayer) {\n // TODO: support reassigment/clearing\n console.warn(\"twisty-player reassignment/clearing is not supported\");\n return;\n }\n this.#twistyPlayer = twistyPlayer;\n if (!twistyPlayer) {\n return;\n }\n void (async () => {\n this.algString = this.#algProp\n ? (await this.#algProp.get()).alg.toString()\n : \"\";\n })();\n\n // if (this.#twistyPlayerProp === \"setupAlg\") {\n // console.log(\"Setupppety!\");\n // this.#twistyPlayer?.experimentalModel.puzzleSetupAlg.addFreshListener(\n // () => {\n // this.highlightLeaf(null);\n // },\n // );\n // }\n if (this.#twistyPlayerProp === \"alg\") {\n // this.model.leafToHighlight.addFreshListener(\n // this.highlightLeaf.bind(this),\n // );\n\n // TODO: listen to puzzle prop?\n this.#twistyPlayer?.experimentalModel.puzzleAlg.addFreshListener(\n (algWithIssues: AlgWithIssues) => {\n // console.log(JSON.stringify(algWithIssues));\n if (algWithIssues.issues.errors.length === 0) {\n this.setAlgIssueClassForPuzzle(\n // TODO: Allow trailing spaces.\n algWithIssues.issues.warnings.length === 0 ? \"none\" : \"warning\",\n );\n const newAlg = algWithIssues.alg;\n const oldAlg = Alg.fromString(this.algString);\n if (!newAlg.isIdentical(oldAlg)) {\n this.algString = newAlg.toString();\n this.onInput();\n } else {\n // this.model.algInputProp.set(oldAlg);\n }\n } else {\n this.setAlgIssueClassForPuzzle(\"error\");\n }\n },\n );\n\n this.model.leafToHighlight.addFreshListener(\n async (highlightInfo: HighlightInfo | null) => {\n if (highlightInfo === null) {\n return;\n }\n // TODO: This indexer can be out of date!\n const [indexer, timestampRequest] = await Promise.all([\n await twistyPlayer.experimentalModel.indexer.get(),\n await twistyPlayer.experimentalModel.timestampRequest.get(),\n ]);\n if (timestampRequest === \"auto\" && !this.#onInputHasFired) {\n return;\n }\n const moveStartTimestamp = indexer.indexToMoveStartTimestamp(\n highlightInfo.leafInfo.idx,\n );\n const duration = indexer.moveDuration(highlightInfo.leafInfo.idx);\n\n let newTimestamp: MillisecondTimestamp;\n switch (highlightInfo.where) {\n case \"before\": {\n newTimestamp = moveStartTimestamp;\n break;\n }\n case \"start\":\n case \"inside\": {\n newTimestamp = (moveStartTimestamp +\n duration / 4) as MillisecondTimestamp;\n break;\n }\n case \"end\":\n case \"after\": {\n newTimestamp = (moveStartTimestamp +\n duration) as MillisecondTimestamp;\n break;\n }\n default:\n console.log(\"invalid where\");\n throw new Error(\"Invalid where!\");\n }\n if (!this.debugNeverRequestTimestamp) {\n twistyPlayer.experimentalModel.timestampRequest.set(newTimestamp);\n }\n },\n );\n\n twistyPlayer.experimentalModel.currentLeavesSimplified.addFreshListener(\n async (currentLeavesSimplified: CurrentLeavesSimplified) => {\n const indexer = await twistyPlayer.experimentalModel.indexer.get();\n const leaf = indexer.getAnimLeaf(\n currentLeavesSimplified.patternIndex,\n );\n this.highlightLeaf(leaf as Parsed<Move | Pause> | null);\n },\n );\n }\n }\n\n protected attributeChangedCallback(\n attributeName: string,\n _oldValue: string,\n newValue: string,\n ): void {\n switch (attributeName) {\n case ATTRIBUTE_FOR_TWISTY_PLAYER: {\n const elem = document.getElementById(newValue);\n if (!elem) {\n console.warn(`${ATTRIBUTE_FOR_TWISTY_PLAYER}= elem does not exist`);\n return;\n }\n if (!(elem instanceof TwistyPlayer)) {\n // TODO: avoid assuming single instance of lib?\n console.warn(`${ATTRIBUTE_FOR_TWISTY_PLAYER}=is not a twisty-player`);\n return;\n }\n this.twistyPlayer = elem;\n return;\n }\n case ATTRIBUTE_PLACEHOLDER: {\n this.placeholder = newValue;\n return;\n }\n case ATTRIBUTE_TWISTY_PLAYER_PROP: {\n if (this.#twistyPlayer) {\n console.log(\"cannot set prop\");\n throw new Error(\"cannot set prop after twisty player\");\n }\n this.#twistyPlayerProp = newValue as TwistyPlayerAlgProp;\n return;\n }\n }\n }\n\n static get observedAttributes(): string[] {\n return [\n ATTRIBUTE_FOR_TWISTY_PLAYER,\n ATTRIBUTE_PLACEHOLDER,\n ATTRIBUTE_TWISTY_PLAYER_PROP,\n ];\n }\n}\n\ncustomElementsShim.define(\"twisty-alg-editor\", TwistyAlgEditor);\ndeclare global {\n interface HTMLElementTagNameMap {\n \"twisty-alg-editor\": TwistyAlgEditor;\n }\n}\n", "// Normally we'd capitalize `ID`, but `Id` matches DOM API function names.\nexport async function firstElementWithId(id: string): Promise<Element> {\n return new Promise((resolve, reject) => {\n try {\n const currentElem = document.getElementById(id);\n if (currentElem) {\n resolve(currentElem);\n }\n const observer = new MutationObserver((mutations: MutationRecord[]) => {\n for (const mutation of mutations) {\n if (\n mutation.attributeName === \"id\" &&\n mutation.target instanceof Element &&\n mutation.target.getAttribute(\"id\") === id\n ) {\n resolve(mutation.target);\n observer.disconnect();\n }\n }\n });\n\n observer.observe(document.body, {\n attributeFilter: [\"id\"],\n subtree: true,\n });\n } catch (e) {\n reject(e);\n }\n });\n}\n", "import { cssStyleSheetShim } from \"./node-custom-element-shims\";\n\nexport const twistyAlgViewerCSS = new cssStyleSheetShim();\ntwistyAlgViewerCSS.replaceSync(\n `\n:host {\n display: inline;\n}\n\n.wrapper {\n display: inline;\n}\n\na:not(:hover) {\n color: inherit;\n text-decoration: none;\n}\n\ntwisty-alg-leaf-elem.twisty-alg-comment {\n color: rgba(0, 0, 0, 0.4);\n}\n\n.wrapper.current-move {\n background: rgba(66, 133, 244, 0.3);\n margin-left: -0.1em;\n margin-right: -0.1em;\n padding-left: 0.1em;\n padding-right: 0.1em;\n border-radius: 0.1em;\n}\n`,\n);\n", "import {\n Alg,\n type AlgNode,\n type Commutator,\n type Conjugate,\n functionFromTraversal,\n Grouping,\n type LineComment,\n type Move,\n type Newline,\n Pause,\n TraversalDownUp,\n} from \"../../alg\";\nimport {\n ExperimentalIterationDirection,\n experimentalDirect,\n} from \"../../alg/cubing-private\";\nimport { type Parsed, startCharIndexKey } from \"../../alg/parseAlg\";\nimport type { MillisecondTimestamp } from \"../controllers/AnimationTypes\";\nimport type {\n CurrentMoveInfo,\n LeafIndex,\n} from \"../controllers/indexer/AlgIndexer\";\nimport type { AlgWithIssues } from \"../model/props/puzzle/state/AlgProp\";\nimport type { DetailedTimelineInfo } from \"../model/props/timeline/DetailedTimelineInfoProp\";\nimport { firstElementWithId } from \"./firstElementWithId\";\nimport { ManagedCustomElement } from \"./ManagedCustomElement\";\nimport {\n customElementsShim,\n HTMLElementShim,\n} from \"./node-custom-element-shims\";\nimport { twistyAlgViewerCSS } from \"./TwistyAlgViewer.css\";\nimport { TwistyPlayer } from \"./TwistyPlayer\";\n\n// TODO: dynamically adjust the fraction to take into account moves that rotate a lot (e.g. `R100`).\nconst DEFAULT_OFFSET_FRACTION = 0.25;\n\ninterface DataDown {\n earliestMoveIndex: LeafIndex;\n twistyAlgViewer: TwistyAlgViewer;\n direction: ExperimentalIterationDirection;\n}\n\ninterface DataUp {\n moveCount: number;\n element: TwistyAlgWrapperElem | TwistyAlgLeafElem;\n}\n\nclass TwistyAlgLeafElem extends ManagedCustomElement {\n constructor(\n className: string,\n text: string,\n dataDown: DataDown,\n public algOrAlgNode: Alg | AlgNode,\n offsetIntoMove: boolean,\n clickable: boolean,\n ) {\n super({ mode: \"open\" });\n this.classList.add(className);\n\n this.addCSS(twistyAlgViewerCSS);\n if (clickable) {\n const anchor = this.contentWrapper.appendChild(\n document.createElement(\"a\"),\n );\n anchor.href = \"#\";\n anchor.textContent = text;\n\n anchor.addEventListener(\"click\", (e) => {\n e.preventDefault();\n void dataDown.twistyAlgViewer.jumpToIndex(\n dataDown.earliestMoveIndex,\n offsetIntoMove,\n );\n });\n } else {\n this.contentWrapper.appendChild(\n document.createElement(\"span\"),\n ).textContent = text;\n }\n }\n\n pathToIndex(_index: number): (TwistyAlgWrapperElem | TwistyAlgLeafElem)[] {\n return [];\n }\n\n setCurrentMove(current: boolean) {\n this.contentWrapper.classList.toggle(\"current-move\", current);\n }\n}\n\ncustomElementsShim.define(\"twisty-alg-leaf-elem\", TwistyAlgLeafElem);\n\nclass TwistyAlgWrapperElem extends HTMLElementShim {\n private queue: (Element | Text)[] = [];\n\n constructor(\n className: string,\n public algOrAlgNode: Alg | AlgNode,\n ) {\n super();\n this.classList.add(className);\n }\n\n addString(str: string) {\n this.queue.push(document.createTextNode(str));\n }\n\n addElem(dataUp: DataUp): number {\n this.queue.push(dataUp.element);\n return dataUp.moveCount;\n }\n\n flushQueue(\n direction: ExperimentalIterationDirection = ExperimentalIterationDirection.Forwards,\n ): void {\n for (const node of maybeReverseList(this.queue, direction)) {\n this.append(node);\n }\n this.queue = [];\n }\n\n pathToIndex(_index: number): (TwistyAlgWrapperElem | TwistyAlgLeafElem)[] {\n return [];\n }\n}\n\ncustomElementsShim.define(\"twisty-alg-wrapper-elem\", TwistyAlgWrapperElem);\n\nfunction oppositeDirection(\n direction: ExperimentalIterationDirection,\n): ExperimentalIterationDirection {\n return direction === ExperimentalIterationDirection.Forwards\n ? ExperimentalIterationDirection.Backwards\n : ExperimentalIterationDirection.Forwards;\n}\n\nfunction updateDirectionByAmount(\n currentDirection: ExperimentalIterationDirection,\n amount: number,\n): ExperimentalIterationDirection {\n return amount < 0 ? oppositeDirection(currentDirection) : currentDirection;\n}\n\nfunction maybeReverseList<T>(\n l: T[],\n direction: ExperimentalIterationDirection,\n): T[] {\n if (direction === ExperimentalIterationDirection.Forwards) {\n return l;\n }\n // console.log(\"rev\", Array.from(l).reverse());\n // return Array.from(l).reverse();\n const copy = Array.from(l);\n copy.reverse();\n return copy;\n}\n\nclass AlgToDOMTree extends TraversalDownUp<DataDown, DataUp, DataUp> {\n public traverseAlg(alg: Alg, dataDown: DataDown): DataUp {\n let moveCount = 0;\n const element = new TwistyAlgWrapperElem(\"twisty-alg-alg\", alg); // TODO: pick a better class name.\n let first = true;\n for (const algNode of experimentalDirect(\n alg.childAlgNodes(),\n dataDown.direction,\n )) {\n if (!first) {\n element.addString(\" \");\n }\n first = false;\n if (algNode.as(Pause)?.experimentalNISSGrouping) {\n element.addString(\"^(\"); // TODO: Handle this lower down.\n }\n // TODO: Handle this check lower down.\n if (!algNode.as(Grouping)?.experimentalNISSPlaceholder) {\n moveCount += element.addElem(\n this.traverseAlgNode(algNode, {\n earliestMoveIndex: (dataDown.earliestMoveIndex +\n moveCount) as LeafIndex,\n twistyAlgViewer: dataDown.twistyAlgViewer,\n direction: dataDown.direction,\n }),\n );\n }\n if (algNode.as(Pause)?.experimentalNISSGrouping) {\n element.addString(\")\"); // TODO: Handle this lower down.\n }\n }\n element.flushQueue(dataDown.direction);\n return {\n moveCount: moveCount,\n element,\n };\n }\n\n public traverseGrouping(grouping: Grouping, dataDown: DataDown): DataUp {\n const square1Tuple = grouping.experimentalAsSquare1Tuple();\n // if (square1Tuplle) {\n\n // }\n\n const direction = updateDirectionByAmount(\n dataDown.direction,\n grouping.amount,\n );\n let moveCount = 0;\n const element = new TwistyAlgWrapperElem(\"twisty-alg-grouping\", grouping);\n element.addString(\"(\");\n\n if (square1Tuple) {\n moveCount += element.addElem({\n moveCount: 1,\n element: new TwistyAlgLeafElem(\n \"twisty-alg-move\", // TODO: Mark the tuple with a special class?\n square1Tuple[0].amount.toString(),\n dataDown,\n square1Tuple[0],\n true,\n true,\n ),\n });\n element.addString(\", \");\n moveCount += element.addElem({\n moveCount: 1,\n element: new TwistyAlgLeafElem(\n \"twisty-alg-move\", // TODO: Mark the tuple with a special class?\n square1Tuple[1].amount.toString(),\n dataDown,\n square1Tuple[1],\n true,\n true,\n ),\n });\n } else {\n moveCount += element.addElem(\n this.traverseAlg(grouping.alg, {\n earliestMoveIndex: (dataDown.earliestMoveIndex +\n moveCount) as LeafIndex,\n twistyAlgViewer: dataDown.twistyAlgViewer,\n direction,\n }),\n );\n }\n\n element.addString(`)${grouping.experimentalRepetitionSuffix}`);\n element.flushQueue();\n return {\n moveCount: moveCount * Math.abs(grouping.amount),\n element,\n };\n }\n\n public traverseMove(move: Move, dataDown: DataDown): DataUp {\n const element = new TwistyAlgLeafElem(\n \"twisty-alg-move\",\n move.toString(),\n dataDown,\n move,\n true,\n true,\n );\n dataDown.twistyAlgViewer.highlighter.addMove(\n (move as Parsed<Move>)[startCharIndexKey],\n element,\n );\n return {\n moveCount: 1,\n element,\n };\n }\n\n public traverseCommutator(\n commutator: Commutator,\n dataDown: DataDown,\n ): DataUp {\n let moveCount = 0;\n const element = new TwistyAlgWrapperElem(\n \"twisty-alg-commutator\",\n commutator,\n );\n element.addString(\"[\");\n element.flushQueue();\n const [first, second]: Alg[] = maybeReverseList(\n [commutator.A, commutator.B],\n dataDown.direction,\n );\n moveCount += element.addElem(\n this.traverseAlg(first, {\n earliestMoveIndex: (dataDown.earliestMoveIndex +\n moveCount) as LeafIndex,\n twistyAlgViewer: dataDown.twistyAlgViewer,\n direction: dataDown.direction,\n }),\n );\n element.addString(\", \");\n moveCount += element.addElem(\n this.traverseAlg(second, {\n earliestMoveIndex: (dataDown.earliestMoveIndex +\n moveCount) as LeafIndex,\n twistyAlgViewer: dataDown.twistyAlgViewer,\n direction: dataDown.direction,\n }),\n );\n element.flushQueue(dataDown.direction);\n element.addString(\"]\");\n element.flushQueue();\n return {\n moveCount: moveCount * 2,\n element,\n };\n }\n\n public traverseConjugate(conjugate: Conjugate, dataDown: DataDown): DataUp {\n let moveCount = 0;\n const element = new TwistyAlgWrapperElem(\"twisty-alg-conjugate\", conjugate);\n element.addString(\"[\");\n const aLen = element.addElem(\n this.traverseAlg(conjugate.A, {\n earliestMoveIndex: (dataDown.earliestMoveIndex +\n moveCount) as LeafIndex,\n twistyAlgViewer: dataDown.twistyAlgViewer,\n direction: dataDown.direction,\n }),\n );\n moveCount += aLen;\n element.addString(\": \");\n moveCount += element.addElem(\n this.traverseAlg(conjugate.B, {\n earliestMoveIndex: (dataDown.earliestMoveIndex +\n moveCount) as LeafIndex,\n twistyAlgViewer: dataDown.twistyAlgViewer,\n direction: dataDown.direction,\n }),\n );\n element.addString(\"]\");\n element.flushQueue();\n return {\n moveCount: moveCount + aLen,\n element,\n };\n }\n\n public traversePause(pause: Pause, dataDown: DataDown): DataUp {\n if (pause.experimentalNISSGrouping) {\n return this.traverseAlg(pause.experimentalNISSGrouping.alg, dataDown);\n }\n return {\n moveCount: 1,\n element: new TwistyAlgLeafElem(\n \"twisty-alg-pause\",\n \".\",\n dataDown,\n pause,\n true,\n true,\n ),\n };\n }\n\n public traverseNewline(newline: Newline, _dataDown: DataDown): DataUp {\n const element = new TwistyAlgWrapperElem(\"twisty-alg-newline\", newline);\n element.append(document.createElement(\"br\"));\n return {\n moveCount: 0,\n element,\n };\n }\n\n public traverseLineComment(\n lineComment: LineComment,\n dataDown: DataDown,\n ): DataUp {\n return {\n moveCount: 0,\n element: new TwistyAlgLeafElem(\n \"twisty-alg-line-comment\",\n `//${lineComment.text}`,\n dataDown,\n lineComment,\n false,\n false,\n ),\n };\n }\n}\n\nconst algToDOMTree = functionFromTraversal(AlgToDOMTree);\n\nclass MoveHighlighter {\n moveCharIndexMap: Map<number, TwistyAlgLeafElem> = new Map();\n currentElem: TwistyAlgLeafElem | null = null;\n\n addMove(charIndex: number, elem: TwistyAlgLeafElem): void {\n this.moveCharIndexMap.set(charIndex, elem);\n }\n\n set(move: Parsed<Move> | null): void {\n const newElem = move\n ? (this.moveCharIndexMap.get(move[startCharIndexKey]) ?? null)\n : null;\n if (this.currentElem === newElem) {\n return;\n }\n this.currentElem?.classList.remove(\"twisty-alg-current-move\");\n this.currentElem?.setCurrentMove(false);\n newElem?.classList.add(\"twisty-alg-current-move\");\n newElem?.setCurrentMove(true);\n this.currentElem = newElem;\n }\n}\n\n/** @category Other Custom Elements */\nexport class TwistyAlgViewer extends HTMLElementShim {\n highlighter: MoveHighlighter = new MoveHighlighter();\n #domTree?: TwistyAlgWrapperElem | TwistyAlgLeafElem;\n #twistyPlayer: TwistyPlayer | null = null;\n lastClickTimestamp: number | null = null;\n constructor(options?: { twistyPlayer?: TwistyPlayer }) {\n super();\n if (options?.twistyPlayer) {\n this.twistyPlayer = options?.twistyPlayer;\n }\n }\n\n protected connectedCallback(): void {\n // nothing to do?\n }\n\n private setAlg(alg: Alg): void {\n this.#domTree = algToDOMTree(alg, {\n earliestMoveIndex: 0 as LeafIndex,\n twistyAlgViewer: this,\n direction: ExperimentalIterationDirection.Forwards,\n }).element;\n this.textContent = \"\";\n this.appendChild(this.#domTree);\n }\n\n get twistyPlayer(): TwistyPlayer | null {\n return this.#twistyPlayer;\n }\n\n set twistyPlayer(twistyPlayer: TwistyPlayer | null) {\n void this.#setTwistyPlayer(twistyPlayer);\n }\n\n async #setTwistyPlayer(twistyPlayer: TwistyPlayer | null) {\n if (this.#twistyPlayer) {\n console.warn(\"twisty-player reassignment is not supported\");\n return;\n }\n if (twistyPlayer === null) {\n throw new Error(\"clearing twistyPlayer is not supported\");\n }\n this.#twistyPlayer = twistyPlayer;\n\n this.#twistyPlayer.experimentalModel.alg.addFreshListener(\n (algWithIssues: AlgWithIssues) => {\n this.setAlg(algWithIssues.alg);\n },\n );\n\n const sourceAlg = (await this.#twistyPlayer.experimentalModel.alg.get())\n .alg;\n // TODO: Use proper architecture instead of a heuristic to ensure we have a parsed alg annotated with char indices.\n const parsedAlg =\n startCharIndexKey in (sourceAlg as Partial<Parsed<Alg>>)\n ? sourceAlg\n : Alg.fromString(sourceAlg.toString());\n this.setAlg(parsedAlg);\n\n twistyPlayer.experimentalModel.currentMoveInfo.addFreshListener(\n (currentMoveInfo: CurrentMoveInfo) => {\n let moveInfo = currentMoveInfo.currentMoves[0];\n moveInfo ??= currentMoveInfo.movesStarting[0];\n moveInfo ??= currentMoveInfo.movesFinishing[0];\n if (!moveInfo) {\n this.highlighter.set(null);\n } else {\n const mainCurrentMove = moveInfo.move; // TODO\n this.highlighter.set(mainCurrentMove as Parsed<Move>);\n }\n },\n );\n\n twistyPlayer.experimentalModel.detailedTimelineInfo.addFreshListener(\n (detailedTimelineInfo: DetailedTimelineInfo) => {\n if (detailedTimelineInfo.timestamp !== this.lastClickTimestamp) {\n this.lastClickTimestamp = null;\n }\n },\n );\n }\n\n async jumpToIndex(index: LeafIndex, offsetIntoMove: boolean): Promise<void> {\n // TODO: Fix async issues.\n const twistyPlayer = this.#twistyPlayer;\n if (twistyPlayer) {\n twistyPlayer.pause();\n const timestampPromise = (async (): Promise<MillisecondTimestamp> => {\n const indexer = await twistyPlayer.experimentalModel.indexer.get();\n const offset = offsetIntoMove\n ? indexer.moveDuration(index) * DEFAULT_OFFSET_FRACTION\n : 0;\n return (indexer.indexToMoveStartTimestamp(index) +\n indexer.moveDuration(index) -\n offset) as MillisecondTimestamp;\n })();\n twistyPlayer.experimentalModel.timestampRequest.set(\n await timestampPromise, // TODO\n );\n if (this.lastClickTimestamp === (await timestampPromise)) {\n twistyPlayer.play();\n this.lastClickTimestamp = null;\n } else {\n this.lastClickTimestamp = await timestampPromise;\n }\n }\n }\n\n protected async attributeChangedCallback(\n attributeName: string,\n _oldValue: string,\n newValue: string,\n ): Promise<void> {\n if (attributeName === \"for\") {\n let elem: Element | null = document.getElementById(newValue);\n if (!elem) {\n console.info(\"for= elem does not exist, waiting for one\");\n }\n await customElements.whenDefined(\"twisty-player\");\n // TODO: handle intermediate attribute changes\n elem = await firstElementWithId(newValue);\n if (!(elem instanceof TwistyPlayer)) {\n console.warn(\"for= elem is not a twisty-player\");\n return;\n }\n this.twistyPlayer = elem;\n }\n }\n\n static get observedAttributes(): string[] {\n return [\"for\"];\n }\n}\n\ncustomElementsShim.define(\"twisty-alg-viewer\", TwistyAlgViewer);\ndeclare global {\n interface HTMLElementTagNameMap {\n \"twisty-alg-viewer\": TwistyAlgViewer;\n }\n}\n", "import { cssStyleSheetShim } from \"../node-custom-element-shims\";\n\nexport const twizzleLinkCSS = new cssStyleSheetShim();\ntwizzleLinkCSS.replaceSync(\n `\n.wrapper {\n background: rgb(255, 245, 235);\n border: 1px solid rgba(0, 0, 0, 0.25);\n\n /* Workaround from https://stackoverflow.com/questions/40010597/how-do-i-apply-opacity-to-a-css-color-variable */\n --text-color: 0, 0, 0;\n --heading-background: 255, 230, 210;\n\n color: rgb(var(--text-color));\n}\n\n.setup-alg, twisty-alg-viewer {\n padding: 0.5em 1em;\n}\n\n.heading {\n background: rgba(var(--heading-background), 1);\n color: rgba(var(--text-color), 1);\n font-weight: bold;\n padding: 0.25em 0.5em;\n display: grid;\n grid-template-columns: auto 1fr;\n\n /* For the move count hover elems. */\n position: sticky;\n}\n\n.heading.title {\n background: rgb(255, 245, 235);\n font-size: 150%;\n white-space: pre-wrap;\n}\n\n.heading .move-count {\n font-weight: initial;\n text-align: right;\n color: rgba(var(--text-color), 0.4);\n}\n\n.wrapper.dark-mode .heading .move-count {\n color: rgba(var(--text-color), 0.7);\n}\n\n.heading a {\n text-decoration: none;\n color: inherit;\n}\n\ntwisty-player {\n width: 100%;\n min-height: 128px;\n height: 288px;\n resize: vertical;\n overflow-y: hidden;\n}\n\ntwisty-player + .heading {\n padding-top: 0.5em;\n}\n\ntwisty-alg-viewer {\n display: inline-block;\n}\n\n.wrapper {\n container-type: inline-size;\n}\n\n.scrollable-region {\n border-top: 1px solid rgba(0, 0, 0, 0.25);\n}\n\n.scrollable-region {\n max-height: 18em;\n overflow-y: auto;\n}\n\n@container (min-width: 512px) {\n .responsive-wrapper {\n display: grid;\n grid-template-columns: 1fr 1fr;\n }\n twisty-player {\n height: 320px\n }\n .scrollable-region {\n border-top: none;\n border-left: 1px solid rgba(0, 0, 0, 0.25);\n contain: strict;\n max-height: 100cqh;\n }\n}\n\n.wrapper:fullscreen,\n.wrapper:fullscreen .responsive-wrapper {\n width: 100%;\n height: 100%;\n}\n\n.wrapper:fullscreen twisty-player,\n.wrapper:fullscreen .scrollable-region {\n height: 50%;\n}\n\n@container (min-width: 512px) {\n .wrapper:fullscreen twisty-player,\n .wrapper:fullscreen .scrollable-region {\n height: 100%;\n }\n}\n\n/* TODO: dedup with Twizzle Editor */\n.move-count > span:hover:before {\n background-color: rgba(var(--heading-background), 1);\n color: rgba(var(--text-color), 1);\n backdrop-filter: blur(4px);\n z-index: 100;\n position: absolute;\n padding: 0.5em;\n top: 1.5em;\n right: 0;\n content: attr(data-before);\n white-space: pre-wrap;\n text-align: left;\n}\n\n.move-count > span:hover {\n color: rgba(var(--text-color), 1);\n cursor: help;\n}\n`,\n);\n\nexport const twizzleLinkForumTweaksCSS = new cssStyleSheetShim();\ntwizzleLinkForumTweaksCSS.replaceSync(`\n.wrapper {\n background: white;\n --heading-background: 232, 239, 253\n}\n\n.wrapper.dark-mode {\n --text-color: 236, 236, 236;\n --heading-background: 29, 29, 29;\n}\n\n.scrollable-region {\n overflow-y: auto;\n}\n\n.wrapper.dark-mode {\n background: #262626;\n --text-color: 142, 142, 142;\n border-color: #FFFFFF44;\n color-scheme: dark;\n}\n\n.wrapper.dark-mode .heading:not(.title) {\n background: #1d1d1d;\n}\n\n.heading.title {\n background: none;\n}\n`);\n", "import { EXPERIMENTAL_PROP_NO_VALUE } from \"../../../../cubing/twisty\";\nimport type {\n AlgProp,\n AlgWithIssues,\n} from \"../../../../cubing/twisty/model/props/puzzle/state/AlgProp\";\nimport type { TwistyPropSource } from \"../../../../cubing/twisty/model/props/TwistyProp\";\nimport type { TwistyPlayerModel } from \"../../../../cubing/twisty/model/TwistyPlayerModel\";\nimport {\n type TwistyPlayerAttribute,\n type TwistyPlayerConfig,\n twistyPlayerAttributeMap,\n} from \"../../../../cubing/twisty/views/TwistyPlayer\";\n\nfunction updateURL(url: URL): void {\n globalThis.history.replaceState(\"\", \"\", url.toString());\n}\n\n// TODO: Find a way to connect this to the `TwistyPlayer` constructor?\n\nexport type URLParamUpdaterOptions = {\n prefix?: string;\n};\n\nexport class URLParamUpdater {\n #prefix: string;\n constructor(model: TwistyPlayerModel, options?: URLParamUpdaterOptions) {\n this.#prefix = options?.prefix ?? \"\";\n\n this.listenToAlgProp(model.alg, \"alg\");\n this.listenToAlgProp(model.setupAlg, \"setup-alg\");\n this.listenToStringOrNullProp(\n model.twistySceneModel.stickeringRequest,\n \"stickering\",\n \"full\",\n );\n this.listenToStringSourceProp(model.setupAnchor, \"setup-anchor\");\n this.listenToStringOrNullProp(model.title, \"title\");\n this.listenToStringOrNoValueProp(\n model.puzzleIDRequest,\n \"puzzle\",\n EXPERIMENTAL_PROP_NO_VALUE,\n );\n this.listenToStringOrNoValueProp(\n model.puzzleDescriptionRequest,\n \"puzzle-description\",\n EXPERIMENTAL_PROP_NO_VALUE,\n );\n }\n\n // TODO: Cache parsed URL?\n setURLParam(\n unprefixedKey: string,\n value: string,\n defaultString: string,\n ): void {\n const prefixedKey = this.#prefix + unprefixedKey;\n const url = new URL(location.href);\n if (value === defaultString) {\n url.searchParams.delete(prefixedKey);\n } else {\n url.searchParams.set(prefixedKey, value);\n }\n updateURL(url);\n }\n\n listenToStringSourceProp<T extends string>(\n prop: TwistyPropSource<T>,\n key: string,\n defaultString?: T,\n ): void {\n void (async () => {\n const actualDefaultString =\n defaultString ?? (await prop.getDefaultValue()) ?? \"\"; // TODO\n prop.addFreshListener((s: string) => {\n this.setURLParam(key, s, actualDefaultString);\n });\n })();\n }\n\n listenToStringOrNullProp(\n prop: TwistyPropSource<string | null>,\n key: string,\n defaultString: string = \"\",\n ): void {\n prop.addFreshListener((s: string | null) => {\n this.setURLParam(key, s ?? defaultString, defaultString);\n });\n }\n\n listenToStringOrNoValueProp<T extends string>(\n prop: TwistyPropSource<T | typeof EXPERIMENTAL_PROP_NO_VALUE>,\n key: string,\n defaultString: T | typeof EXPERIMENTAL_PROP_NO_VALUE,\n ): void {\n prop.addFreshListener((s: string | typeof EXPERIMENTAL_PROP_NO_VALUE) => {\n if (s === EXPERIMENTAL_PROP_NO_VALUE) {\n s = defaultString;\n }\n if (s === EXPERIMENTAL_PROP_NO_VALUE) {\n this.setURLParam(key, \"\", \"\");\n } else {\n this.setURLParam(key, s, \"\"); // TODO\n }\n });\n }\n\n listenToAlgProp(prop: AlgProp, key: string): void {\n prop.addFreshListener((algWithIssues: AlgWithIssues) => {\n this.setURLParam(key, algWithIssues.alg.toString(), \"\");\n });\n }\n}\n\nexport function getConfigFromURL(\n prefix = \"\",\n url: string = location.href,\n): TwistyPlayerConfig {\n // TODO: Why does `Object.entries(paramMapping)` crash if this is defined elswhere?\n const paramMapping: Record<string, TwistyPlayerAttribute> = {\n alg: \"alg\",\n \"setup-alg\": \"experimental-setup-alg\",\n \"setup-anchor\": \"experimental-setup-anchor\",\n puzzle: \"puzzle\",\n stickering: \"experimental-stickering\",\n \"puzzle-description\": \"experimental-puzzle-description\",\n title: \"experimental-title\",\n \"video-url\": \"experimental-video-url\",\n competition: \"experimental-competition-id\",\n };\n\n const params = new URL(url).searchParams;\n const config: TwistyPlayerConfig = {};\n for (const [ourParam, twistyPlayerParam] of Object.entries(paramMapping)) {\n const paramValue = params.get(prefix + ourParam);\n if (paramValue !== null) {\n // TODO: type\n const configKey = twistyPlayerAttributeMap[twistyPlayerParam];\n (config as any)[configKey] = paramValue;\n }\n }\n return config;\n}\n\nexport function remapLegacyURLParams(\n mapping: Record<string, string | null>,\n): void {\n const url = new URL(location.href);\n for (const [oldKey, newKey] of Object.entries(mapping)) {\n // `null` indicates there is no new key, i.e. just drop the old key\n if (newKey !== null) {\n // The new key takes precedents, so we only remap the old key if the new key\n // is not already set.\n if (!url.searchParams.has(newKey)) {\n const value = url.searchParams.get(oldKey);\n if (value !== null) {\n url.searchParams.set(newKey, value);\n }\n }\n }\n url.searchParams.delete(oldKey);\n }\n updateURL(url);\n}\n", "import { Alg } from \"../../../alg\";\nimport {\n ExperimentalCommonMetric,\n experimentalCountMetricMoves,\n} from \"../../../notation\";\nimport { puzzles } from \"../../../puzzles\";\nimport { TwistyPlayer } from \"../..\";\nimport type { ColorSchemeWithAuto } from \"../../model/props/viewer/ColorSchemeRequestProp\";\nimport type { TwistyPlayerModel } from \"../../model/TwistyPlayerModel\";\nimport { ManagedCustomElement } from \"../ManagedCustomElement\";\nimport { customElementsShim } from \"../node-custom-element-shims\";\nimport { TwistyAlgViewer } from \"../TwistyAlgViewer\";\nimport { twizzleLinkCSS, twizzleLinkForumTweaksCSS } from \"./TwizzleLink.css\";\nimport { getConfigFromURL } from \"./url-params\";\n\n/** @category Other Custom Elements */\n\n// Non-breaking space\n// const NBSP = \"\\xa0\";\n\nconst OUTER_BLOCK_MOVES_EXPLANATION = \"outer block moves (e.g. R, Rw, or 4r)\";\nconst INNER_BLOCK_MOVES_EXPLANATION = \"inner block moves (e.g. M or 2-5r)\";\n\n// TODO: calculate descriptions from the cost factors directly.\nconst METRIC_EXPLANATIONS: Partial<Record<ExperimentalCommonMetric, string>> = {\n [ExperimentalCommonMetric.OuterBlockTurnMetric]: `HTM = OBTM (\"Outer Block Turn Metric\"):\n\u2022 ${INNER_BLOCK_MOVES_EXPLANATION} count as 2 turns\n\u2022 ${OUTER_BLOCK_MOVES_EXPLANATION} count as 1 turn\n\u2022 rotations (e.g. x) count as 0 turns`,\n [ExperimentalCommonMetric.OuterBlockQuantumTurnMetric]: `QTM = OBQTM (\"Outer Block Quantum Turn Metric\"):\n\u2022 ${INNER_BLOCK_MOVES_EXPLANATION} count as 2 turns per quantum (e.g. M2 counts as 4)\n\u2022 ${OUTER_BLOCK_MOVES_EXPLANATION} count as 1 turn per quantum (e.g. R2 counts as 2)\n\u2022 rotations (e.g. x) count as 0 turns`,\n [ExperimentalCommonMetric.RangeBlockTurnMetric]: `STM = RBTM (\"Range Block Turn Metric\"):\n\u2022 ${INNER_BLOCK_MOVES_EXPLANATION} count as 1 turn\n\u2022 ${OUTER_BLOCK_MOVES_EXPLANATION} count as 1 turn\n\u2022 rotations (e.g. x) count as 0 turns`,\n [ExperimentalCommonMetric.RangeBlockQuantumTurnMetric]: `SQTM = RBQTM (\"Range Block Quantum Turn Metric\"):\n\u2022 ${INNER_BLOCK_MOVES_EXPLANATION} count as 1 turn per quantum (e.g. M2 counts as 2)\n\u2022 ${OUTER_BLOCK_MOVES_EXPLANATION} count as 1 turn per quantum (e.g. R2 counts as 2)\n\u2022 rotations (e.g. x) count as 0 turns`,\n [ExperimentalCommonMetric.ExecutionTurnMetric]: `ETM (\"Execution Turn Metric\"):\n\u2022 all moves (including rotations) count as 1 turn`,\n};\n// const LEGACY_METRIC_ABBREVIATIONS: Partial<\n// Record<ExperimentalCommonMetric, string>\n// > = {\n// [ExperimentalCommonMetric.OuterBlockTurnMetric]: \"h\",\n// [ExperimentalCommonMetric.OuterBlockQuantumTurnMetric]: \"q\",\n// [ExperimentalCommonMetric.RangeBlockTurnMetric]: \"s\",\n// [ExperimentalCommonMetric.RangeBlockQuantumTurnMetric]: \"sq\",\n// [ExperimentalCommonMetric.ExecutionTurnMetric]: \"e\",\n// };\nconst CONSISTENT_METRIC_ABBREVIATIONS: Partial<\n Record<ExperimentalCommonMetric, string>\n> = {\n [ExperimentalCommonMetric.OuterBlockTurnMetric]: \"OB\",\n [ExperimentalCommonMetric.OuterBlockQuantumTurnMetric]: \"OBQ\",\n [ExperimentalCommonMetric.RangeBlockTurnMetric]: \"RB\",\n [ExperimentalCommonMetric.RangeBlockQuantumTurnMetric]: \"RBQ\",\n [ExperimentalCommonMetric.ExecutionTurnMetric]: \"E\",\n};\n\nexport class TwizzleLink extends ManagedCustomElement {\n twistyPlayer: TwistyPlayer | null = null;\n a: HTMLAnchorElement | null = null;\n constructor(\n private options?: {\n cdnForumTweaks?: boolean;\n colorScheme?: ColorSchemeWithAuto;\n },\n ) {\n super({ mode: \"open\" });\n }\n\n #fallback() {\n this.contentWrapper.textContent = \"\";\n if (this.a) {\n const span = this.contentWrapper.appendChild(\n document.createElement(\"span\"),\n );\n span.textContent = \"\u2757\uFE0F\";\n span.title = \"Could not show a player for link\";\n this.addElement(this.a);\n }\n this.removeCSS(twizzleLinkCSS);\n const cssIndex = this.shadow.adoptedStyleSheets.indexOf(twizzleLinkCSS);\n if (typeof cssIndex !== \"undefined\") {\n this.shadow.adoptedStyleSheets.splice(cssIndex, cssIndex + 1);\n }\n this.#cssCDNForumTweaksElem?.remove();\n }\n\n #cssCDNForumTweaksElem?: HTMLStyleElement;\n #scrollableRegion?: HTMLDivElement;\n #responsiveWrapper?: HTMLDivElement;\n #moveCountElem?: HTMLSpanElement;\n async connectedCallback() {\n this.#responsiveWrapper = this.addElement(document.createElement(\"div\"));\n this.#responsiveWrapper.classList.add(\"responsive-wrapper\");\n if (this.options?.colorScheme === \"dark\") {\n this.contentWrapper.classList.add(\"dark-mode\");\n }\n this.addCSS(twizzleLinkCSS);\n if (this.options?.cdnForumTweaks) {\n this.addCSS(twizzleLinkForumTweaksCSS);\n }\n this.a = this.querySelector(\"a\");\n if (!this.a) {\n return;\n }\n\n const config = getConfigFromURL(\"\", this.a.href);\n\n const href = this.a?.href;\n const { hostname, pathname } = new URL(href);\n\n if (hostname !== \"alpha.twizzle.net\") {\n this.#fallback();\n return;\n }\n if ([\"/edit/\", \"/explore/\"].includes(pathname)) {\n const isExplorer = pathname === \"/explore/\";\n\n if (config.puzzle && !(config.puzzle in puzzles)) {\n const puzzleDescription = (\n await import(\"../../../puzzle-geometry\")\n ).getPuzzleDescriptionString(config.puzzle);\n delete config.puzzle;\n config.experimentalPuzzleDescription = puzzleDescription;\n }\n\n this.twistyPlayer = this.#responsiveWrapper.appendChild(\n new TwistyPlayer({\n background: this.options?.cdnForumTweaks\n ? \"checkered-transparent\"\n : \"checkered\",\n colorScheme: this.options?.colorScheme === \"dark\" ? \"dark\" : \"light\",\n ...config,\n viewerLink: isExplorer ? \"experimental-twizzle-explorer\" : \"auto\",\n }),\n );\n this.twistyPlayer.fullscreenElement = this.contentWrapper;\n if (config.experimentalTitle) {\n this.twistyPlayer.experimentalTitle = config.experimentalTitle;\n }\n\n this.#scrollableRegion = this.#responsiveWrapper.appendChild(\n document.createElement(\"div\"),\n );\n this.#scrollableRegion.classList.add(\"scrollable-region\");\n\n if (config.experimentalTitle) {\n this.#addHeading(config.experimentalTitle).classList.add(\"title\");\n // const setupAlgDiv = this.addElement(document.createElement(\"div\"));\n // setupAlgDiv.classList.add(\"setup-alg\");\n // setupAlgDiv.textContent = puzzles[config.puzzle ?? \"3x3x3\"].fullName;\n }\n\n if (config.experimentalSetupAlg) {\n this.#addHeading(\n \"Setup\",\n async () =>\n (\n await this.twistyPlayer?.experimentalModel.setupAlg.get()\n )?.alg.toString() ?? null,\n );\n\n const setupAlgDiv = this.#scrollableRegion.appendChild(\n document.createElement(\"div\"),\n );\n setupAlgDiv.classList.add(\"setup-alg\");\n setupAlgDiv.textContent = new Alg(\n config.experimentalSetupAlg,\n ).toString();\n }\n const movesHeading = this.#addHeading(\n \"Moves\",\n async () =>\n (\n await this.twistyPlayer?.experimentalModel.alg.get()\n )?.alg.toString() ?? null,\n );\n\n this.#moveCountElem = movesHeading.appendChild(\n constructMoveCountDisplay(this.twistyPlayer.experimentalModel),\n );\n this.#moveCountElem.classList.add(\"move-count\");\n\n const twistyAlgViewer = this.#scrollableRegion.appendChild(\n new TwistyAlgViewer({ twistyPlayer: this.twistyPlayer }),\n );\n twistyAlgViewer.part.add(\"twisty-alg-viewer\");\n } else {\n this.#fallback();\n }\n }\n\n #addHeading(\n text: string,\n getTextToCopy?: () => Promise<string | null>,\n ): HTMLElement {\n const headingDiv = this.#scrollableRegion!.appendChild(\n document.createElement(\"div\"),\n );\n headingDiv.classList.add(\"heading\");\n // Wrapper span for grid layout.\n const wrapperSpan = headingDiv.appendChild(document.createElement(\"span\"));\n wrapperSpan.textContent = text;\n if (getTextToCopy) {\n wrapperSpan.textContent += \" \";\n const a = wrapperSpan.appendChild(document.createElement(\"a\"));\n a.textContent = \"\uD83D\uDCCB\";\n a.href = \"#\";\n a.title = \"Copy to clipboard\";\n async function setAndClear(text: string) {\n a.textContent = text;\n await new Promise((resolve) => setTimeout(resolve, 2000));\n if (a.textContent === text) {\n a.textContent = \"\uD83D\uDCCB\";\n }\n }\n a.addEventListener(\"click\", async (e) => {\n e.preventDefault();\n a.textContent = \"\uD83D\uDCCB\u2026\";\n const textToCopy = await getTextToCopy();\n if (textToCopy) {\n try {\n await navigator.clipboard.writeText(textToCopy);\n void setAndClear(\"\uD83D\uDCCB\u2705\");\n } catch (e) {\n void setAndClear(\"\uD83D\uDCCB\u274C\");\n throw e;\n }\n } else {\n void setAndClear(\"\uD83D\uDCCB\u274C\");\n }\n });\n }\n return headingDiv;\n }\n}\n\ncustomElementsShim.define(\"twizzle-link\", TwizzleLink);\ndeclare global {\n interface HTMLElementTagNameMap {\n \"twizzle-link\": TwizzleLink;\n }\n}\n\nexport function constructMoveCountDisplay(\n model: TwistyPlayerModel,\n elem: HTMLSpanElement = document.createElement(\"span\"),\n): HTMLSpanElement {\n async function update() {\n const [algWithIssues, puzzleLoader] = await Promise.all([\n model.puzzleAlg.get(),\n model.puzzleLoader.get(),\n ]);\n if (algWithIssues.issues.errors.length !== 0) {\n elem.textContent = \"\";\n return;\n }\n let isFirstMetric = true;\n function addMetric(metric: ExperimentalCommonMetric) {\n if (isFirstMetric) {\n isFirstMetric = false;\n } else {\n elem.append(\")(\");\n }\n const span = elem.appendChild(document.createElement(\"span\"));\n const moveCount = experimentalCountMetricMoves(\n puzzleLoader,\n metric,\n algWithIssues.alg,\n );\n span.append(`${CONSISTENT_METRIC_ABBREVIATIONS[metric]}: `);\n const moveNumber = span.appendChild(document.createElement(\"span\"));\n moveNumber.textContent = moveCount.toString();\n moveNumber.classList.add(\"move-number\");\n // span.title = METRIC_EXPLANATIONS[metric] ?? \"\";\n span.setAttribute(\"data-before\", METRIC_EXPLANATIONS[metric] ?? \"\");\n span.setAttribute(\"title\", METRIC_EXPLANATIONS[metric] ?? \"\");\n }\n\n elem.textContent = \"(\";\n if (puzzleLoader.id === \"3x3x3\") {\n addMetric(ExperimentalCommonMetric.OuterBlockTurnMetric);\n addMetric(ExperimentalCommonMetric.OuterBlockQuantumTurnMetric);\n addMetric(ExperimentalCommonMetric.RangeBlockTurnMetric);\n } else if (puzzleLoader.pg) {\n addMetric(ExperimentalCommonMetric.RangeBlockTurnMetric);\n addMetric(ExperimentalCommonMetric.RangeBlockQuantumTurnMetric);\n }\n addMetric(ExperimentalCommonMetric.ExecutionTurnMetric);\n elem.append(\")\");\n }\n model.puzzleAlg.addFreshListener(update);\n model.puzzleID.addFreshListener(update);\n return elem;\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmBO,SAAS,yBAAyB,QAAqC;AAC5E,UAAQ,KAAK,IAAI,MAAM,GAAG;AAAA,IACxB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAiBO,IAAM,cAAN,cAA0B,YAAiC;AAAA;AAAA,EAEhE,YACS,oBAEoB,0BAC3B;AACA,UAAM;AAJC;AAAA,EAKT;AAAA,EAEO,YAAY,KAA+B;AAChD,QAAI,QAAQ;AACZ,eAAW,WAAW,IAAI,cAAc,GAAG;AACzC,eAAS,KAAK,gBAAgB,OAAO;AAAA,IACvC;AACA,WAAO;AAAA,EACT;AAAA,EAEO,iBAAiB,UAAyC;AAC/D,WAAQ,SAAS,SACf,KAAK,YAAY,SAAS,GAAG;AAAA,EACjC;AAAA,EAEO,aAAa,MAAiC;AACnD,WAAO,KAAK,kBAAkB,KAAK,MAAM;AAAA,EAC3C;AAAA,EAEO,mBAAmB,YAA6C;AACrE,WAAQ,KACL,KAAK,YAAY,WAAW,CAAC,IAC5B,KAAK,YAAY,WAAW,CAAC;AAAA,EACnC;AAAA,EAEO,kBAAkB,WAA2C;AAClE,WAAQ,IAAI,KAAK,YAAY,UAAU,CAAC,IACtC,KAAK,YAAY,UAAU,CAAC;AAAA,EAChC;AAAA,EAEO,cAAc,QAAoC;AACvD,WAAO,KAAK,kBAAkB,CAAC;AAAA,EACjC;AAAA,EAEO,gBAAgB,UAAwC;AAC7D,WAAO,KAAK,kBAAkB,CAAC;AAAA,EACjC;AAAA,EAEO,oBAAoB,UAA4C;AACrE,WAAO,KAAK,kBAAkB,CAAC;AAAA,EACjC;AACF;;;ACrFO,IAAM,mBAAN,MAA6C;AAAA,EAOlD,YACU,SACR,KACA;AAFQ;AAIR,SAAK,QAAQ,IAAI,IAAI,IAAI,mBAAmB,CAAC;AAAA,EAC/C;AAAA,EAZQ;AAAA;AAAA,EAEA,aAA+C,IAAI;AAAA,IACzD;AAAA,EACF;AAAA,EAUO,YAAY,OAAqB;AACtC,WAAO,MAAM,KAAK,KAAK,MAAM,cAAc,CAAC,EAAE,KAAK;AAAA,EACrD;AAAA,EAEO,0BAA0B,OAAqC;AACpE,UAAM,MAAM,IAAI,IAAI,MAAM,KAAK,KAAK,MAAM,cAAc,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;AAC1E,WAAO,KAAK,WAAW,YAAY,GAAG;AAAA,EACxC;AAAA,EAEO,iBAAiB,WAA4C;AAClE,QAAI,iBAAiB;AACrB,QAAI;AACJ,SAAK,IAAI,GAAG,IAAI,KAAK,kBAAkB,GAAG,KAAK;AAC7C,wBAAkB,KAAK,WAAW,aAAa,KAAK,YAAY,CAAC,CAAC;AAClE,UAAI,kBAAkB,WAAW;AAC/B,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEO,eAAe,OAAyB;AAC7C,WAAO,KAAK,QACT,eAAe,EACf,oBAAoB,KAAK,sBAAsB,KAAK,CAAC;AAAA,EAC1D;AAAA,EAEO,sBAAsB,OAAgC;AAC3D,QAAI,UAAU,KAAK,QAAQ,uBAAuB;AAClD,eAAW,QAAQ,MAAM,KAAK,KAAK,MAAM,cAAc,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG;AAEzE,gBAAU,QAAQ,UAAU,IAAY;AAAA,IAC1C;AACA,WAAO;AAAA,EACT;AAAA,EAEO,cAAmC;AACxC,WAAO,KAAK,WAAW,YAAY,KAAK,KAAK;AAAA,EAC/C;AAAA,EAEO,oBAA+B;AAEpC,WAAO,oBAAgC,KAAK,KAAK;AAAA,EACnD;AAAA,EAEO,aAAa,OAAuC;AACzD,WAAO,KAAK,WAAW,aAAa,KAAK,YAAY,KAAK,CAAC;AAAA,EAC7D;AACF;;;ACpDO,IAAM,sBAAN,MAA0B;AAAA,EAC/B,YACS,WACA,UACA,SACA,UACA,WAAkC,CAAC,GAC1C;AALO;AACA;AACA;AACA;AACA;AAAA,EACN;AACL;AACO,IAAM,uBAAN,cAAmC,YAAiC;AAAA,EASzE,YAAoB,SAAkB;AACpC,UAAM;AADY;AAElB,SAAK,WAAW,QAAQ,uBAAuB;AAC/C,SAAK,YAAY,IAAI;AAAA,MACnB;AAAA,MACA;AAAA,MACA,KAAK;AAAA,MACL,KAAK;AAAA,MACL,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAlBQ;AAAA,EACA;AAAA,EACA,aAA+C,IAAI;AAAA,IACzD;AAAA,EACF;AAAA,EAEQ,QAAgD,CAAC;AAAA,EAclD,YAAY,KAA+B;AAChD,QAAI,YAAY;AAChB,QAAI,WAAW;AACf,QAAI,iBAAiB,KAAK;AAC1B,UAAM,QAA+B,CAAC;AACtC,eAAW,WAAW,IAAI,cAAc,GAAG;AACzC,YAAM,MAAM,KAAK,gBAAgB,OAAO;AAExC,mBAAa,IAAI;AAEjB,kBAAY,IAAI;AAChB,UAAI,mBAAmB,KAAK,UAAU;AACpC,yBAAiB,IAAI;AAAA,MACvB,OAAO;AACL,yBAAiB,eAAe,oBAAoB,IAAI,OAAO;AAAA,MACjE;AACA,YAAM,KAAK,GAAG;AAAA,IAChB;AACA,WAAO,IAAI;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA,eAAe,OAAO;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AAAA,EAEO,iBAAiB,UAAyC;AAC/D,UAAM,MAAM,KAAK,YAAY,SAAS,GAAG;AACzC,WAAO,KAAK,KAAK,KAAK,SAAS,QAAQ,CAAC,GAAG,CAAC;AAAA,EAC9C;AAAA,EAEO,aAAa,MAAiC;AACnD,UAAM,MAAM,KAAK,SAAS;AAC1B,QAAIA,KAAqC,KAAK,MAAM,GAAG;AACvD,QAAIA,IAAG;AACL,aAAOA;AAAA,IACT;AACA,UAAM,iBAAiB,KAAK,QAAQ,qBAAqB,IAAI;AAC7D,IAAAA,KAAI,IAAI;AAAA,MACN;AAAA,MACA,KAAK,WAAW,gBAAgB,IAAI;AAAA,MACpC;AAAA,MACA,eAAe,OAAO;AAAA,IACxB;AACA,SAAK,MAAM,GAAG,IAAIA;AAClB,WAAOA;AAAA,EACT;AAAA,EAEO,mBAAmB,YAA6C;AACrE,UAAM,OAAO,KAAK,YAAY,WAAW,CAAC;AAC1C,UAAM,OAAO,KAAK,YAAY,WAAW,CAAC;AAC1C,UAAM,KAAK,KAAK,QAAQ,oBAAoB,KAAK,OAAO;AACxD,UAAM,OAAO,KAAK,SAAS,oBAAoB,KAAK,QAAQ;AAC5D,UAAM,SAAS,GAAG,oBAAoB,IAAI;AAC1C,UAAM,MAAM,IAAI;AAAA,MACb,KAAK,KAAK,YAAY,KAAK;AAAA,MAC3B,KAAK,KAAK,WAAW,KAAK;AAAA,MAC3B;AAAA,MACA,OAAO,OAAO;AAAA,MACd,CAAC,MAAM,IAAI;AAAA,IACb;AACA,WAAO,KAAK,KAAK,KAAK,GAAG,CAAC,KAAK,MAAM,IAAI,CAAC;AAAA,EAC5C;AAAA,EAEO,kBAAkB,WAA2C;AAClE,UAAM,OAAO,KAAK,YAAY,UAAU,CAAC;AACzC,UAAM,OAAO,KAAK,YAAY,UAAU,CAAC;AACzC,UAAM,KAAK,KAAK,QAAQ,oBAAoB,KAAK,OAAO;AACxD,UAAM,OAAO,GAAG,oBAAoB,KAAK,QAAQ;AACjD,UAAM,MAAM,IAAI;AAAA,MACb,IAAI,KAAK,YAAY,KAAK;AAAA,MAC1B,IAAI,KAAK,WAAW,KAAK;AAAA,MAC1B;AAAA,MACA,KAAK,OAAO;AAAA,MACZ,CAAC,MAAM,IAAI;AAAA,IACb;AACA,WAAO,KAAK,KAAK,KAAK,GAAG,CAAC,KAAK,MAAM,IAAI,CAAC;AAAA,EAC5C;AAAA,EAEO,cAAc,OAAmC;AACtD,QAAI,MAAM,0BAA0B;AAClC,aAAO,KAAK;AAAA,IACd;AACA,WAAO,IAAI;AAAA,MACT;AAAA,MACA,KAAK,WAAW,gBAAgB,KAAK;AAAA,MACrC,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAAA,EACF;AAAA,EAEO,gBAAgB,UAAwC;AAC7D,WAAO,KAAK;AAAA,EACd;AAAA,EAEO,oBAAoB,UAA4C;AACrE,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,KACN,KACA,GACA,OACqB;AACrB,UAAM,OAAO,KAAK,IAAI,CAAC;AACvB,UAAM,KAAK,IAAI,QAAQ,aAAa,CAAC;AACrC,WAAO,IAAI;AAAA,MACR,IAAI,YAAY;AAAA,MAChB,IAAI,WAAW;AAAA,MAChB;AAAA,MACA,GAAG,OAAO;AAAA,MACV;AAAA,IACF;AAAA,EACF;AACF;AACA,IAAM,aAAN,MAAiB;AAAA,EACf,YACS,KACA,MACP;AAFO;AACA;AAAA,EAGT;AACF;AACO,IAAM,YAAN,cAAwB,gBAAqC;AAAA,EAUlE,YACS,SACA,cACA,KACP;AACA,UAAM;AAJC;AACA;AACA;AAGP,SAAK,IAAI;AACT,SAAK,MAAM;AACX,SAAK,YAAY;AACjB,SAAK,eAAe;AACpB,SAAK,OAAO;AACZ,SAAK,OAAO;AACZ,SAAK,eAAe;AACpB,SAAK,KAAK,KAAK,QAAQ,uBAAuB;AAC9C,SAAK,OAAO,IAAI,WAAW,KAAK,KAAK,KAAK;AAAA,EAC5C;AAAA,EAxBO;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACC;AAAA,EACA;AAAA,EAkBD,YAAY,KAAyB;AAC1C,QAAI,KAAK,KAAK,KAAK,KAAK,MAAM,KAAK;AACjC,aAAO,KAAK,SAAS;AAAA,IACvB;AACA,WAAO,KAAK,SAAS,KAAK,QAA+B;AAAA,EAC3D;AAAA,EAEO,eAAe,KAAmC;AACvD,QACE,KAAK,OAAO,KACZ,KAAK,MAAM,OACX,KAAK,MAAM,KAAK,gBAAgB,KAChC;AACA,aAAO,KAAK,SAAS;AAAA,IACvB;AACA,WAAO,KAAK,SAAS,UAAuB,GAAG;AAAA,EACjD;AAAA,EAEO,SAAS,KAAgB,KAAmC;AACjE,SAAK,YAAY;AACjB,SAAK,eAAe;AACpB,SAAK,IAAI;AACT,SAAK,MAAM;AACX,SAAK,OAAO;AACZ,SAAK,eAAe;AACpB,SAAK,OAAO;AACZ,SAAK,KAAK,KAAK,QAAQ,uBAAuB;AAC9C,UAAMA,KAAI,KAAK,aAAa,GAAG,GAAG,IAC9B,KAAK,YAAY,KAAK,cAAqB,KAAK,IAAI,IACpD,KAAK,gBAAgB,KAAK,cAAyB,KAAK,IAAI;AAChE,WAAOA;AAAA,EACT;AAAA,EAEO,YAAY,KAAU,IAAyB;AACpD,QAAI,CAAC,KAAK,WAAW,EAAE,GAAG;AACxB,aAAO;AAAA,IACT;AACA,QAAI,IAAI,GAAG,OAAO,IAAI,6BAA6B,IAAI,IAAI;AAC3D,eAAW,WAAW;AAAA,MACpB,IAAI,cAAc;AAAA,MAClB,GAAG;AAAA,IAGL,GAAG;AACD,UACE,KAAK;AAAA,QACH;AAAA,QACA,IAAI,WAAW,GAAG,IAAI,SAAS,CAAC,GAAG,GAAG,IAAI;AAAA,MAC5C,GACA;AACA,eAAO;AAAA,MACT;AACA,WAAK,GAAG,OAAO,KAAK;AAAA,IACtB;AACA,WAAO;AAAA,EACT;AAAA,EAEO,iBAAiB,UAAoB,IAAyB;AACnE,QAAI,CAAC,KAAK,WAAW,EAAE,GAAG;AACxB,aAAO;AAAA,IACT;AACA,UAAM,OAAO,KAAK,OAAO,IAAI,SAAS,MAAM;AAC5C,WAAO,KAAK;AAAA,MACV,SAAS;AAAA,MACT,IAAI,WAAW,GAAG,IAAI,SAAS,CAAC,GAAG,IAAI;AAAA,IACzC;AAAA,EACF;AAAA,EAEO,aAAa,MAAY,IAAyB;AACvD,QAAI,CAAC,KAAK,WAAW,EAAE,GAAG;AACxB,aAAO;AAAA,IACT;AACA,SAAK,OAAO;AACZ,SAAK,eAAe,GAAG,IAAI;AAC3B,SAAK,OAAO,GAAG;AACf,WAAO;AAAA,EACT;AAAA,EAEO,mBAAmB,YAAwB,IAAyB;AACzE,QAAI,CAAC,KAAK,WAAW,EAAE,GAAG;AACxB,aAAO;AAAA,IACT;AACA,UAAM,OAAO,KAAK,OAAO,IAAI,CAAC;AAC9B,QAAI,MAAM;AACR,aACE,KAAK;AAAA,QACH,WAAW;AAAA,QACX,IAAI,WAAW,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI;AAAA,MAC1C,KACA,KAAK;AAAA,QACH,WAAW;AAAA,QACX,IAAI,WAAW,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI;AAAA,MAC1C,KACA,KAAK;AAAA,QACH,WAAW;AAAA,QACX,IAAI,WAAW,GAAG,IAAI,SAAS,CAAC,GAAG,IAAI;AAAA,MACzC,KACA,KAAK,YAAY,WAAW,GAAG,IAAI,WAAW,GAAG,IAAI,SAAS,CAAC,GAAG,IAAI,CAAC;AAAA,IAE3E,OAAO;AACL,aACE,KAAK;AAAA,QACH,WAAW;AAAA,QACX,IAAI,WAAW,GAAG,IAAI,SAAS,CAAC,GAAG,IAAI;AAAA,MACzC,KACA,KAAK;AAAA,QACH,WAAW;AAAA,QACX,IAAI,WAAW,GAAG,IAAI,SAAS,CAAC,GAAG,IAAI;AAAA,MACzC,KACA,KAAK;AAAA,QACH,WAAW;AAAA,QACX,IAAI,WAAW,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI;AAAA,MAC1C,KACA,KAAK;AAAA,QACH,WAAW;AAAA,QACX,IAAI,WAAW,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI;AAAA,MAC1C;AAAA,IAEJ;AAAA,EACF;AAAA,EAEO,kBAAkB,WAAsB,IAAyB;AACtE,QAAI,CAAC,KAAK,WAAW,EAAE,GAAG;AACxB,aAAO;AAAA,IACT;AACA,UAAM,OAAO,KAAK,OAAO,IAAI,CAAC;AAC9B,QAAI,MAAM;AACR,aACE,KAAK;AAAA,QACH,UAAU;AAAA,QACV,IAAI,WAAW,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI;AAAA,MAC1C,KACA,KAAK;AAAA,QACH,UAAU;AAAA,QACV,IAAI,WAAW,GAAG,IAAI,SAAS,CAAC,GAAG,IAAI;AAAA,MACzC,KACA,KAAK,YAAY,UAAU,GAAG,IAAI,WAAW,GAAG,IAAI,SAAS,CAAC,GAAG,IAAI,CAAC;AAAA,IAE1E,OAAO;AACL,aACE,KAAK;AAAA,QACH,UAAU;AAAA,QACV,IAAI,WAAW,GAAG,IAAI,SAAS,CAAC,GAAG,IAAI;AAAA,MACzC,KACA,KAAK;AAAA,QACH,UAAU;AAAA,QACV,IAAI,WAAW,GAAG,IAAI,SAAS,CAAC,GAAG,IAAI;AAAA,MACzC,KACA,KAAK,YAAY,UAAU,GAAG,IAAI,WAAW,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;AAAA,IAE3E;AAAA,EACF;AAAA,EAEO,cAAc,OAAc,IAAyB;AAC1D,QAAI,CAAC,KAAK,WAAW,EAAE,GAAG;AACxB,aAAO;AAAA,IACT;AACA,SAAK,OAAO;AACZ,SAAK,eAAe,GAAG,IAAI;AAC3B,SAAK,OAAO,GAAG;AACf,WAAO;AAAA,EACT;AAAA,EAEO,gBAAgB,UAAmB,KAA0B;AAClE,WAAO;AAAA,EACT;AAAA,EAEO,oBACL,cACA,KACS;AACT,WAAO;AAAA,EACT;AAAA,EAEQ,WAAW,IAAyB;AAC1C,QACE,GAAG,IAAI,YAAY,KAAK,KAAK,KAAK,aAClC,GAAG,IAAI,WAAW,KAAK,MAAM,KAAK,cAClC;AACA,aAAO,KAAK,UAAU,EAAE;AAAA,IAC1B;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,OAAO,IAAgB,QAAyB;AACtD,QAAI,OAAO,GAAG;AACd,QAAI,WAAW,GAAG;AAEhB,aAAO;AAAA,IACT;AACA,QAAI,SAAS,GAAG;AACd,aAAO,CAAC;AACR,eAAS,CAAC;AAAA,IACZ;AACA,UAAM,OAAO,GAAG,IAAI,SAAS,CAAC;AAC9B,UAAM,OAAO,KAAK;AAAA,MAChB,KAAK,OAAO,KAAK,YAAY,KAAK,KAAK,KAAK,SAAS;AAAA,MACrD,KAAK,MAAM,KAAK,eAAe,KAAK,OAAO,KAAK,WAAW,CAAC;AAAA,IAC9D;AACA,QAAI,OAAO,GAAG;AACZ,WAAK,UAAU,IAAI,WAAW,MAAM,IAAI,GAAG,IAAI;AAAA,IACjD;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,UAAU,IAAgB,MAAc,GAAY;AAE1D,SAAK,KAAM,MAAM,GAAG,IAAI;AAExB,SAAK,OAAQ,MAAM,GAAG,IAAI;AAC1B,QAAI,QAAQ,GAAG;AACb,UAAI,GAAG,MAAM;AACX,aAAK,KAAK,KAAK,GAAG;AAAA,UAChB,GAAG,IAAI,SAAS,aAAa,GAAG;AAAA,QAClC;AAAA,MACF,OAAO;AACL,aAAK,KAAK,KAAK,GAAG,oBAAoB,GAAG,IAAI,QAAQ,aAAa,GAAG,CAAC;AAAA,MACxE;AAAA,IACF,OAAO;AACL,UAAI,GAAG,MAAM;AACX,aAAK,KAAK,KAAK,GAAG,oBAAoB,GAAG,IAAI,QAAQ;AAAA,MACvD,OAAO;AACL,aAAK,KAAK,KAAK,GAAG,oBAAoB,GAAG,IAAI,OAAO;AAAA,MACtD;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;;;AC/ZA,IAAM,yBAAyB;AAE/B,SAAS,YAAY,KAAU,gBAA6B;AAC1D,QAAM,iBAAiB,IAAI,WAAW;AACtC,QAAM,kBAAkB,IAAI,WAAW;AACvC,aAAW,WAAW,IAAI,cAAc,GAAG;AACzC,oBAAgB,KAAK,OAAO;AAC5B,QAAI,gBAAgB,wBAAwB,KAAK,gBAAgB;AAC/D,qBAAe,KAAK,IAAI,SAAS,gBAAgB,MAAM,CAAC,CAAC;AACzD,sBAAgB,MAAM;AAAA,IACxB;AAAA,EACF;AACA,iBAAe,KAAK,IAAI,SAAS,gBAAgB,MAAM,CAAC,CAAC;AACzD,SAAO,eAAe,MAAM;AAC9B;AAEA,IAAM,YAAN,cAAwB,YAA0B;AAAA,EAChD,YAAY,KAAe;AACzB,UAAM,YAAY,IAAI,6BAA6B;AACnD,QAAI,YAAY,wBAAwB;AACtC,aAAO;AAAA,IACT;AACA,WAAO,YAAY,KAAK,KAAK,KAAK,KAAK,KAAK,SAAS,CAAC,CAAC;AAAA,EACzD;AAAA,EAEA,iBAAiB,UAA6B;AAC5C,WAAO,IAAI;AAAA,MACT,KAAK,YAAY,SAAS,GAAG;AAAA,MAC7B,SAAS;AAAA;AAAA,IACX;AAAA,EACF;AAAA,EAEA,aAAa,MAAqB;AAChC,WAAO;AAAA,EACT;AAAA,EAEA,mBAAmB,YAAiC;AAClD,WAAO,IAAI;AAAA,MACT,KAAK,YAAY,WAAW,CAAC;AAAA,MAC7B,KAAK,YAAY,WAAW,CAAC;AAAA,IAC/B;AAAA,EACF;AAAA,EAEA,kBAAkB,WAA+B;AAC/C,WAAO,IAAI;AAAA,MACT,KAAK,YAAY,UAAU,CAAC;AAAA,MAC5B,KAAK,YAAY,UAAU,CAAC;AAAA,IAC9B;AAAA,EACF;AAAA,EAEA,cAAc,OAAuB;AACnC,WAAO;AAAA,EACT;AAAA,EAEA,gBAAgB,SAA2B;AACzC,WAAO;AAAA,EACT;AAAA,EAEA,oBAAoB,SAA+B;AACjD,WAAO;AAAA,EACT;AACF;AAEO,IAAM,YAAY,sBAAsB,SAAS;;;AC/DjD,IAAM,iBAAN,MAA2C;AAAA,EAGhD,YACU,SACR,KACA;AAFQ;AAGR,UAAM,SAAS,IAAI,qBAAqB,KAAK,OAAO;AAEpD,UAAM,aAAa,UAAU,GAAG;AAEhC,SAAK,aAAa,OAAO,YAAY,UAAU;AAC/C,SAAK,SAAS,IAAI,UAAU,KAAK,SAAS,YAAY,KAAK,UAAU;AAAA,EACvE;AAAA,EAZQ;AAAA,EACA;AAAA,EAaD,YAAY,OAA+B;AAEhD,QAAI,KAAK,OAAO,YAAY,KAAK,GAAG;AAClC,UAAI,CAAC,KAAK,OAAO,MAAM;AACrB,cAAM,IAAI,MAAM,0BAA0B;AAAA,MAC5C;AACA,YAAM,OAAO,KAAK,OAAO;AAEzB,UAAI,KAAK,OAAO,MAAM;AACpB,eAAO,KAAK,OAAO;AAAA,MACrB;AACA,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA,EAEO,0BAA0B,OAAwC;AACvE,QAAI,KAAK,OAAO,YAAY,KAAK,KAAK,KAAK,OAAO,MAAM,OAAO;AAC7D,aAAO,KAAK,OAAO;AAAA,IACrB;AACA,UAAM,IAAI,MAAM,2BAA2B,KAAK,EAAE;AAAA,EACpD;AAAA,EAEO,uBAAuB,OAAwC;AACpE,QAAI,KAAK,OAAO,YAAY,KAAK,KAAK,KAAK,OAAO,MAAM,OAAO;AAC7D,aAAO,KAAK,OAAO;AAAA,IACrB;AACA,UAAM,IAAI,MAAM,2BAA2B,KAAK,EAAE;AAAA,EACpD;AAAA,EAEO,eAAe,OAAkB,cAAmC;AACzE,SAAK,OAAO,YAAY,KAAK;AAC7B,YAAQ,gBAAgB,KAAK,QAAQ,eAAe,GAAG;AAAA,MACrD,KAAK,OAAO;AAAA,IACd;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKO,sBAAsB,OAAmC;AAC9D,SAAK,OAAO,YAAY,KAAK;AAC7B,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEO,oBAA+B;AACpC,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEO,iBAAiB,WAA4C;AAClE,SAAK,OAAO,eAAe,SAA0C;AACrE,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEO,cAAmC;AACxC,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEO,aAAa,OAAuC;AACzD,SAAK,OAAO,YAAY,KAAK;AAC7B,WAAO,KAAK,OAAO;AAAA,EACrB;AACF;;;AC1FO,IAAM,kBAAkB;AAAA,EAC7B,MAAM;AAAA;AAAA,EACN,gBAAgB;AAAA,EAChB,aAAa;AACf;AAKO,IAAM,eAAN,cAA2B,uBAA+C;AAAA,EAC/E,kBAA0C;AACxC,WAAO;AAAA,EACT;AACF;;;ACRA,IAAM,QAAQ;AACd,IAAM,yBAAyB;AAK/B,IAAI,aAAa;AACjB,SAAS,YAAoB;AAC3B,gBAAc;AACd,SAAO,MAAM,WAAW,SAAS,CAAC;AACpC;AAGA,IAAM,YAEF;AAAA,EACF,KAAK;AAAA,IACH,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,KAAK;AAAA,IACL,qBAAqB;AAAA;AAAA,IACrB,QAAQ;AAAA,IACR,oBAAoB;AAAA,IACpB,QAAQ;AAAA,EACV;AAAA,EACA,UAAU;AAAA,EACV,SAAS;AAAA,EACT,WAAW;AACb;AAEO,IAAM,oBAAN,MAAwB;AAAA,EAO7B,YACS,SACP,WACA,4BACQ,0BAAmC,OAC3C;AAJO;AAGC;AAER,QAAI,CAAC,WAAW;AACd,YAAM,IAAI,MAAM,sCAAsC,QAAQ,KAAK,CAAC,EAAE;AAAA,IACxE;AAEA,SAAK,QAAQ,UAAU;AAEvB,SAAK,iBAAiB,SAAS,cAAc,KAAK;AAClD,SAAK,eAAe,UAAU,IAAI,aAAa;AAE/C,SAAK,eAAe,YAAY;AAEhC,UAAM,UAAU,KAAK,eAAe,cAAc,KAAK;AACvD,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,MAAM,2BAA2B;AAAA,IAC7C;AACA,SAAK,aAAa;AAClB,QAAI,UAAU,QAAQ,cAAc;AAClC,YAAM,IAAI,MAAM,0BAA0B;AAAA,IAC5C;AACA,YAAQ,MAAM,WAAW;AACzB,YAAQ,MAAM,YAAY;AAC1B,SAAK,eAAe,SAAS,gBAAgB,OAAO,MAAM;AAC1D,YAAQ,aAAa,KAAK,cAAc,QAAQ,UAAU;AAE1D,eAAW,mBAAmB,QAAQ,WAAW,QAAQ;AACvD,eAAS,MAAM,GAAG,MAAM,gBAAgB,WAAW,OAAO;AACxD,iBACM,cAAc,GAClB,cAAc,gBAAgB,iBAC9B,eACA;AACA,gBAAM,KAAK,KAAK;AAAA,YACd,gBAAgB;AAAA,YAChB;AAAA,YACA;AAAA,UACF;AACA,gBAAM,OAAO,KAAK,YAAY,EAAE;AAEhC,cAAI,gBAAwB,MAAM,MAAM;AAExC,cAAI,4BAA4B;AAC9B,aAAC,MAAM;AAEL,oBAAM,IAAI,2BAA2B;AACrC,kBAAI,CAAC,GAAG;AACN;AAAA,cACF;AACA,oBAAM,sBAAsB,EAAE,gBAAgB,SAAS;AACvD,kBAAI,CAAC,qBAAqB;AACxB;AAAA,cACF;AACA,oBAAM,sBAAsB,oBAAoB,OAAO,GAAG;AAC1D,kBAAI,CAAC,qBAAqB;AACxB;AAAA,cACF;AACA,oBAAM,yBACJ,oBAAoB,SAAS,WAAW;AAC1C,kBAAI,CAAC,wBAAwB;AAC3B;AAAA,cACF;AACA,oBAAM,iBACJ,OAAO,2BAA2B,WAC9B,yBACA,wBAAwB;AAC9B,oBAAM,WAAW,UAAU,cAAc;AACzC,kBAAI,OAAO,aAAa,UAAU;AAChC,gCAAgB;AAAA,cAClB,WAAW,UAAU;AACnB,gCAAgB,SAAS,aAAa;AAAA,cACxC;AAAA,YACF,GAAG;AAAA,UACL,OAAO;AACL,4BAAgB,MAAM,MAAM;AAAA,UAC9B;AACA,eAAK,eAAe,EAAE,IAAI;AAC1B,eAAK,UAAU,EAAE,IAAI,KAAK,YAAY,IAAI,aAAa;AACvD,eAAK,aAAa,YAAY,KAAK,UAAU,EAAE,CAAC;AAChD,gBAAM,aAAa,SAAS,mBAAmB,KAAK,KAAK,IAAI,EAAE,GAAG;AAAA,QACpE;AAAA,MACF;AAAA,IACF;AAEA,eAAW,YAAY,MAAM;AAAA,MAC3B,QAAQ,iBAAiB,IAAI,sBAAsB,GAAG;AAAA,IACxD,GAAG;AACD,YAAM,KAAK,SAAS,aAAa,sBAAsB;AACvD,eAAS,aAAa,SAAS,mBAAmB,KAAK,KAAK,IAAI,EAAE,GAAG;AAAA,IACvE;AAEA,QAAI,KAAK,yBAAyB;AAChC,WAAK,YAAY,KAAK,QAAQ,eAAe,CAAC;AAAA,IAChD;AAAA,EACF;AAAA,EAxGO;AAAA,EACA;AAAA,EACA;AAAA,EACC,iBAA6C,CAAC;AAAA,EAC9C,YAAoD,CAAC;AAAA,EACrD;AAAA,EAqGD,YACL,SACA,aACA,UACM;AACN,SAAK,KAAK,SAAS,aAAa,QAAQ;AAAA,EAC1C;AAAA;AAAA,EAGO,KACL,SACA,aACA,UACM;AACN,UAAM,qBAAqB,aAAa,6BAA6B;AACrE,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,MAAM,qDAAqD;AAAA,IACvE;AAEA,eAAW,mBAAmB,QAAQ,QAAQ,WAAW,QAAQ;AAC/D,YAAM,sBACJ,QAAQ,YAAY,gBAAgB,SAAS;AAC/C,YAAM,0BAA0B,qBAC5B,mBAAmB,mBAAmB,gBAAgB,SAAS,IAC/D;AACJ,eAAS,MAAM,GAAG,MAAM,gBAAgB,WAAW,OAAO;AACxD,iBACM,cAAc,GAClB,cAAc,gBAAgB,iBAC9B,eACA;AACA,gBAAM,KAAK,KAAK;AAAA,YACd,gBAAgB;AAAA,YAChB;AAAA,YACA;AAAA,UACF;AACA,gBAAM,UAAU,KAAK;AAAA,YACnB,gBAAgB;AAAA,YAChB,oBAAoB,OAAO,GAAG;AAAA,aAC7B,gBAAgB,kBACf,oBAAoB,YAAY,GAAG,IACnC,eACA,gBAAgB;AAAA,UACpB;AACA,cAAI,cAAc;AAClB,cAAI,yBAAyB;AAC3B,kBAAM,WAAW,KAAK;AAAA,cACpB,gBAAgB;AAAA,cAChB,wBAAwB,YAAY,GAAG;AAAA,eACtC,gBAAgB,kBACf,wBAAwB,iBAAiB,GAAG,IAC5C,eACA,gBAAgB;AAAA,YACpB;AACA,gBAAI,YAAY,UAAU;AACxB,4BAAc;AAAA,YAChB;AACA,uBAAW,YAAY;AACvB,kBAAM,wBACJ,OAAO,IAAI,WAAW,YAAY,IAAI,WAAW;AACnD,iBAAK,UAAU,EAAE,EAAE,SAAS,CAAC,EAAE;AAAA,cAC7B;AAAA,cACA,KAAK,eAAe,OAAO;AAAA,YAC7B;AACA,iBAAK,UAAU,EAAE,EAAE,SAAS,CAAC,EAAE;AAAA,cAC7B;AAAA,cACA,GAAG,KAAK,IAAI,wBAAwB,GAAG,CAAC,CAAC;AAAA,YAC3C;AACA,iBAAK,UAAU,EAAE,EAAE,SAAS,CAAC,EAAE;AAAA,cAC7B;AAAA,cACA,GAAG,KAAK,IAAI,wBAAwB,GAAG,CAAC,CAAC;AAAA,YAC3C;AACA,iBAAK,UAAU,EAAE,EAAE,SAAS,CAAC,EAAE;AAAA,cAC7B;AAAA,cACA,GAAG,qBAAqB;AAAA,YAC1B;AACA,iBAAK,UAAU,EAAE,EAAE,SAAS,CAAC,EAAE;AAAA,cAC7B;AAAA,cACA,GAAG,qBAAqB;AAAA,YAC1B;AACA,iBAAK,UAAU,EAAE,EAAE,SAAS,CAAC,EAAE;AAAA,cAC7B;AAAA,cACA,KAAK,eAAe,QAAQ;AAAA,YAC9B;AAAA,UACF,OAAO;AACL,0BAAc;AAAA,UAChB;AACA,cAAI,aAAa;AACf,gBACE,KAAK,2BACL,oBAAoB,iBAAiB,GAAG,MAAM,GAC9C;AACA,mBAAK,UAAU,EAAE,EAAE,SAAS,CAAC,EAAE,aAAa,cAAc,MAAM;AAChE,mBAAK,UAAU,EAAE,EAAE,SAAS,CAAC,EAAE,aAAa,UAAU,IAAI;AAC1D,mBAAK,UAAU,EAAE,EAAE,SAAS,CAAC,EAAE,aAAa,UAAU,IAAI;AAC1D,mBAAK,UAAU,EAAE,EAAE,SAAS,CAAC,EAAE,aAAa,UAAU,KAAK;AAC3D,mBAAK,UAAU,EAAE,EAAE,SAAS,CAAC,EAAE,aAAa,UAAU,KAAK;AAC3D,mBAAK,UAAU,EAAE,EAAE,SAAS,CAAC,EAAE;AAAA,gBAC7B;AAAA,gBACA,KAAK,eAAe,OAAO;AAAA,cAC7B;AAAA,YACF,OAAO;AACL,mBAAK,UAAU,EAAE,EAAE,SAAS,CAAC,EAAE;AAAA,gBAC7B;AAAA,gBACA,KAAK,eAAe,OAAO;AAAA,cAC7B;AACA,mBAAK,UAAU,EAAE,EAAE,SAAS,CAAC,EAAE,aAAa,UAAU,MAAM;AAC5D,mBAAK,UAAU,EAAE,EAAE,SAAS,CAAC,EAAE,aAAa,UAAU,MAAM;AAC5D,mBAAK,UAAU,EAAE,EAAE,SAAS,CAAC,EAAE,aAAa,UAAU,MAAM;AAC5D,mBAAK,UAAU,EAAE,EAAE,SAAS,CAAC,EAAE,aAAa,UAAU,MAAM;AAAA,YAC9D;AAAA,UACF;AAAA,QAGF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,YAAY,IAAY,eAA2C;AACzE,UAAM,OAAO,SAAS;AAAA,MACpB;AAAA,MACA;AAAA,IACF;AACA,SAAK,aAAa,MAAM,QAAQ,KAAK,KAAK,IAAI,EAAE,EAAE;AAClD,SAAK,aAAa,KAAK,UAAU;AACjC,UAAM,WAAW;AAAA,MACf,EAAE,QAAQ,GAAG,OAAO,cAAc;AAAA,MAClC,EAAE,QAAQ,GAAG,OAAO,QAAQ;AAAA,MAC5B,EAAE,QAAQ,GAAG,OAAO,QAAQ;AAAA,MAC5B,EAAE,QAAQ,GAAG,OAAO,cAAc;AAAA,IACpC;AACA,eAAW,WAAW,UAAU;AAC9B,YAAM,OAAO,SAAS,gBAAgB,OAAO,MAAM;AACnD,WAAK,aAAa,UAAU,GAAG,QAAQ,MAAM,GAAG;AAChD,WAAK,aAAa,cAAc,QAAQ,KAAK;AAC7C,WAAK,aAAa,gBAAgB,GAAG;AACrC,WAAK,YAAY,IAAI;AAAA,IACvB;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,UACN,WACA,KACA,aACQ;AACR,WAAO,GAAG,SAAS,KAAK,GAAG,KAAK,WAAW;AAAA,EAC7C;AAAA,EAEQ,YAAY,IAAyB;AAE3C,WAAO,KAAK,eAAe,cAAc,IAAI,EAAE,EAAE;AAAA,EACnD;AACF;;;ACzSO,IAAM,mBAAN,MAAkD;AAAA;AAAA,EAGvD,YACU,MACA,QACA,eACR;AAHQ;AACA;AACA;AAAA,EACP;AAAA,EANH,oBAAmC;AAAA;AAAA,EASnC,aAAmB;AACjB,QAAI,KAAK,mBAAmB;AAC1B,WAAK,KAAK,eAAe,UAAU,OAAO,KAAK,iBAAiB;AAAA,IAClE;AACA,SAAK,oBAAoB;AAAA,EAC3B;AAAA;AAAA,EAGA,SAAS,QAA6B;AACpC,QAAI,CAAC,KAAK,cAAc,SAAS,MAAM,GAAG;AACxC,YAAM,IAAI,MAAM,mBAAmB,MAAM,EAAE;AAAA,IAC7C;AACA,UAAM,eAAe,GAAG,KAAK,MAAM,GAAG,MAAM;AAC5C,UAAM,UAAU,KAAK,sBAAsB;AAC3C,QAAI,SAAS;AACX,WAAK,WAAW;AAChB,WAAK,KAAK,eAAe,UAAU,IAAI,YAAY;AACnD,WAAK,oBAAoB;AAAA,IAC3B;AACA,WAAO;AAAA,EACT;AACF;;;AC/BO,SAAS,YAAe,GAAiB,GAA0B;AACxE,MAAI,MAAM,GAAG;AACX,WAAO;AAAA,EACT;AACA,MAAI,EAAE,WAAW,EAAE,QAAQ;AACzB,WAAO;AAAA,EACT;AACA,WAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;AACjC,QAAI,EAAE,CAAC,MAAM,EAAE,CAAC,GAAG;AACjB,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,mBACd,GACA,GACA,SACS;AACT,MAAI,MAAM,GAAG;AACX,WAAO;AAAA,EACT;AACA,MAAI,EAAE,WAAW,EAAE,QAAQ;AACzB,WAAO;AAAA,EACT;AACA,WAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;AACjC,QAAI,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG;AACxB,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,aACd,GACA,UACA,UACQ;AACR,SAAO,UAAU,GAAG,WAAW,UAAU,QAAQ;AACnD;;;ACnBO,SAAS,gBAAgB,WAA8B;AAC5D,SAAO;AACT;;;ACCA,IAAM,gBAAN,MAAoB;AAAA;AAAA,EAKlB,YAAoB,OAA0B;AAA1B;AAClB,UAAM,WAAW,iBAAiB,CAAC,eAAe;AAChD,WAAK,aAAa;AAAA,IACpB,CAAC;AAAA,EACH;AAAA,EARA,aAAsB;AAAA,EACtB,eAAe;AAAA,EAEf,aAAqB;AAAA,EAOb,YAA6B,IAAI;AAAA,IACvC,KAAK,UAAU,KAAK,IAAI;AAAA,EAC1B;AAAA,EAEA,QAAc;AACZ,QAAI,CAAC,KAAK,YAAY;AACpB,WAAK,gBAAgB,YAAY,IAAI;AAAA,IACvC;AACA,SAAK,aAAa;AAClB,SAAK,eAAe;AACpB,SAAK,UAAU,iBAAiB;AAAA,EAClC;AAAA,EAEA,OAAa;AACX,SAAK,aAAa;AAClB,SAAK,UAAU,gBAAgB;AAAA,EACjC;AAAA,EAEA,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB,UAAU,WAAuC;AAC/C,SAAK,UAAU,iBAAiB;AAChC,UAAM,QACH,KAAK,cAAc,YAAY,KAAK,iBAAkB,KAAK;AAC9D,SAAK,gBAAgB;AAErB,SAAK,MAAM,YAAY;AAAA,OACpB,YAAkC;AACjC,cAAM,sBAAsB,MAAM,KAAK,MAAM,YAAY,IAAI;AAC7D,YAAI,oBAAoB,SAAS,MAAM;AACrC,iBAAO;AAAA,QACT;AAEA,cAAM,SAAS,oBAAoB,SAAS;AAC5C,YAAI,UAAU,GAAG;AACf,eAAK,eAAe;AACpB,eAAK,KAAK;AACV,eAAK,MAAM,iBAAiB,IAAI,KAAK;AACrC,iBAAO;AAAA,YACL,MAAM;AAAA,YACN,QAAQ;AAAA,UACV;AAAA,QACF;AACA,aAAK,eAAe;AACpB,eAAO;AAAA,UACL,MAAM,oBAAoB;AAAA,UAC1B;AAAA,QACF;AAAA,MACF,GAAG;AAAA,IACL;AAAA,EACF;AACF;AAGO,IAAM,4BAAN,MAAgC;AAAA,EAgBrC,YACE,OACQ,UACR;AADQ;AAER,SAAK,QAAQ;AACb,SAAK,uBAAuB,KAAK,gCAAgC;AAEjE,SAAK,MAAM,YAAY,iBAAiB,KAAK,cAAc,KAAK,IAAI,CAAC;AAErE,SAAK,gBAAgB,IAAI,cAAc,KAAK,KAAK;AACjD,SAAK,MAAM,YAAY,iBAAiB,KAAK,kBAAkB,KAAK,IAAI,CAAC;AAAA,EAC3E;AAAA;AAAA,EAzBQ,UAAmB;AAAA,EACnB;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA,gBAAsC;AAAA,EACtC;AAAA,EAEA,YAA6B,IAAI;AAAA,IACvC,KAAK,UAAU,KAAK,IAAI;AAAA,EAC1B;AAAA;AAAA,EAgBA,MAAM,cAAc,aAAyC;AAC3D,QAAI,YAAY,YAAY,KAAK,SAAS;AACxC,kBAAY,UAAU,KAAK,KAAK,WAAW,IAAI,KAAK,MAAM;AAAA,IAC5D;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,kBAAkB,aAAyC;AAC/D,UAAM,aAAa,YAAY,SAAS;AACxC,QAAI,eAAe,KAAK,cAAc,YAAY;AAChD,mBAAa,KAAK,cAAc,MAAM,IAAI,KAAK,cAAc,KAAK;AAAA,IACpE;AACA,SAAK,UAAU,iBAAiB;AAAA,EAClC;AAAA,EAEA,MAAM,kCAAiE;AACrE,YAAQ,MAAM,KAAK,MAAM,qBAAqB,IAAI,GAAG;AAAA,EACvD;AAAA;AAAA,EAGA,YAAY,SAAoC;AAC9C,SAAK,MAAM,iBAAiB,IAAI,OAAO;AACvC,SAAK,MAAM;AACX,QAAI,SAAS,OAAO;AAClB,WAAK,SAAS,MAAM;AAAA,IACtB;AAAA,EACF;AAAA;AAAA,EAGA,UAAU,SAAoC;AAC5C,SAAK,MAAM,iBAAiB,IAAI,KAAK;AACrC,SAAK,MAAM;AACX,QAAI,SAAS,OAAO;AAClB,WAAK,SAAS,MAAM;AAAA,IACtB;AAAA,EACF;AAAA;AAAA,EAGA,YAAkB;AAChB,QAAI,KAAK,SAAS;AAChB,WAAK,MAAM;AAAA,IACb,OAAO;AACL,WAAK,KAAK;AAAA,IACZ;AAAA,EACF;AAAA;AAAA,EAGA,KAAK,SAKI;AACP,UAAM,YAAY;AAOhB,YAAM,YAAY,SAAS;AAE3B,YAAM,qBAAqB,MAAM,KAAK,MAAM,mBAAmB,IAAI;AACnE,UAAI,SAAS,0CAA0C,MAAM;AAC3D,YAAI,kCAAoC,mBAAmB,OAAO;AAChE,eAAK,MAAM,iBAAiB,IAAI,OAAO;AACvC,eAAK,SAAS,MAAM;AAAA,QACtB;AACA,YAAI,oCAAqC,mBAAmB,SAAS;AACnE,eAAK,MAAM,iBAAiB,IAAI,KAAK;AACrC,eAAK,SAAS,MAAM;AAAA,QACtB;AAAA,MACF;AACA,WAAK,MAAM,YAAY,IAAI;AAAA,QACzB,SAAS;AAAA,QACT;AAAA,QACA,eAAe,SAAS;AAAA,QACxB,MAAM,SAAS,QAAQ;AAAA,MACzB,CAAC;AAED,WAAK,UAAU;AACf,WAAK,gBAAgB,YAAY,IAAI;AACrC,WAAK,uBAAuB,KAAK,gCAAgC;AAGjE,WAAK,UAAU,iBAAiB;AAAA,IAClC,GAAG;AAAA,EACL;AAAA,EAEA,QAAc;AACZ,SAAK,UAAU;AACf,SAAK,UAAU,gBAAgB;AAC/B,SAAK,MAAM,YAAY,IAAI;AAAA,MACzB,SAAS;AAAA,MACT;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,2CAEI,IAAI,aAEN;AAAA,EAEF,MAAM,UAAU,gBAAqD;AACnE,QAAI,KAAK,SAAS;AAChB,WAAK,UAAU,iBAAiB;AAAA,IAClC;AAEA,UAAM,gBAAgB,KAAK;AAC3B,UAAM,kBACJ,MAAM,KAAK,yCAAyC;AAAA,MAClD,QAAQ,IAAI;AAAA,QACV,KAAK,MAAM,YAAY,IAAI;AAAA,QAC3B,KAAK;AAAA,QACL,KAAK,MAAM,UAAU,IAAI;AAAA,QACzB,KAAK,MAAM,WAAW,IAAI;AAAA,QAC1B,KAAK,MAAM,gBAAgB,IAAI;AAAA,MACjC,CAAC;AAAA,IACH;AAEF,UAAM,CAAC,aAAa,eAAe,WAAW,YAAY,eAAe,IACvE;AAGF,QAAI,CAAC,YAAY,SAAS;AACxB,WAAK,UAAU;AAUf;AAAA,IACF;AAEA,QAAI,MAAM,gBAAgB;AAC1B,QACE,gBAAgB,aAAa,WAAW,KACxC,YAAY,0DACZ;AACA,YAAM,UAAU;AAAA,IAClB;AAEA,QAAI,QAAQ,gBAAgB;AAC5B,QACE,gBAAgB,aAAa,WAAW,KACxC,YAAY,0DACZ;AACA,cAAQ,UAAU;AAAA,IACpB;AAGA,QAAI,SACD,iBAAiB,iBAClB,gBAAgB,KAAK,SAAS,IAC9B;AACF,YAAQ,KAAK,IAAI,OAAO,CAAC;AACzB,aAAS,YAAY;AACrB,QAAI,eAAgB,gBAAgB;AACpC,QAAI,2BACF;AAEF,QAAI,gBAAgB,KAAK;AACvB,UAAI,YAAY,MAAM;AACpB,uBAAe;AAAA,UACb;AAAA,UACA,UAAU;AAAA,UACV,UAAU;AAAA,QACZ;AAAA,MACF,OAAO;AACL,YAAI,iBAAiB,UAAU,KAAK;AAClC,qCAA2B;AAAA,QAC7B,OAAO;AACL,yBAAe;AAAA,QACjB;AACA,aAAK,UAAU;AACf,aAAK,MAAM,YAAY,IAAI;AAAA,UACzB,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAAA,IACF,WAAW,gBAAgB,OAAO;AAChC,UAAI,YAAY,MAAM;AACpB,uBAAe;AAAA,UACb;AAAA,UACA,UAAU;AAAA,UACV,UAAU;AAAA,QACZ;AAAA,MACF,OAAO;AACL,YAAI,iBAAiB,UAAU,OAAO;AACpC,qCAA2B;AAAA,QAC7B,OAAO;AACL,yBAAe;AAAA,QACjB;AACA,aAAK,UAAU;AACf,aAAK,MAAM,YAAY,IAAI;AAAA,UACzB,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAAA,IACF;AACA,SAAK,gBAAgB;AACrB,SAAK,uBAAuB,QAAQ;AAAA,MAClC;AAAA,IACF;AACA,SAAK,MAAM,iBAAiB,IAAI,4BAA4B,YAAY;AAAA,EAC1E;AACF;;;ACpUO,IAAM,yBAAN,MAA6B;AAAA,EAGlC,YACU,OACR,UACA;AAFQ;AAGR,SAAK,sBAAsB,IAAI,0BAA0B,OAAO,QAAQ;AAAA,EAC1E;AAAA,EAPA;AAAA,EASA,YAAY,SAAoC;AAC9C,SAAK,oBAAoB,YAAY,OAAO;AAAA,EAC9C;AAAA,EAEA,UAAU,SAAoC;AAC5C,SAAK,oBAAoB,UAAU,OAAO;AAAA,EAC5C;AAAA,EAEA,WAAW,MAAgB;AACzB,QAAI,OAAO,SAAS,aAAa;AAC/B,WAAK,oBAAoB,UAAU;AAAA,IACrC;AACA,WAAO,KAAK,oBAAoB,KAAK,IAAI,KAAK,oBAAoB,MAAM;AAAA,EAC1E;AAAA,EAEA,MAAa,mBAAkC;AAC7C,UAAM,IAAI,SAAS,cAAc,GAAG;AACpC,MAAE,OAAO,MAAM,KAAK,MAAM,YAAY;AACtC,MAAE,SAAS;AACX,MAAE,MAAM;AAAA,EACV;AACF;;;ACnCO,IAAM,oBAAoB;AAAA,EAC/B,cAAc;AAAA;AAAA,EACd,MAAM;AACR;AAIO,IAAM,mBAAN,cAA+B,uBAAkD;AAAA,EACtF,kBAA6C;AAC3C,WAAO;AAAA,EACT;AACF;;;ACXO,IAAM,yBAAyB,IAAI,kBAAkB;AAC5D,uBAAuB;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuCF;;;ACxCO,IAAM,iBAAiB,IAAI,kBAAkB;AACpD,eAAe;AAAA,EACb;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoCF;;;ACbO,IAAM,iBAAN,cACG,qBAEV;AAAA;AAAA,EAIE,YACU,OACA,SACA,WACA,SACA,cACR;AACA,UAAM;AANE;AACA;AACA;AACA;AACA;AAGR,SAAK,OAAO,cAAc;AAE1B,SAAK,SAAS;AAEd,SAAK,sBAAsB;AAAA,MACzB,KAAK,MAAO;AAAA,MACZ,CAAC,aAAuB;AACtB,YAAI,cAAc,OAAO,UAAU;AACjC,eAAK,WAAW;AAAA,QAClB;AAAA,MACF;AAAA,IACF;AAEA,SAAK,sBAAsB;AAAA,MACzB,KAAK,MAAO,iBAAiB;AAAA,MAC7B,CAAC,gBAAgB;AACf,aAAK,eAAe,WAAW;AAAA,MACjC;AAAA,IACF;AAEA,SAAK,sBAAsB;AAAA,MACzB,KAAK,MAAO;AAAA,MACZ,KAAK,iBAAiB,KAAK,IAAI;AAAA,IACjC;AAEA,QAAI,KAAK,SAAS,4BAA4B;AAC5C,WAAK;AAAA,QACH,KAAK,QAAQ;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAAA,EAzCO;AAAA,EACC,YAAY,IAAI,gBAAgB,KAAK,OAAO,KAAK,IAAI,CAAC;AAAA,EAC9D,kBAAyC;AAAA,EAyCzC,wBAAwB,IAAI,qBAAqB;AAAA,EACjD,aAAmB;AACjB,SAAK,sBAAsB,WAAW;AAAA,EACxC;AAAA,EAEA,iBAAiB,UAAgC;AAC/C,QAAI;AACF,UAAI,SAAS,gBAAgB,SAAS,GAAG;AACvC,cAAM,OAAO,SAAS,gBAAgB,CAAC,EAAE;AAEzC,YAAI,cAAc;AAClB,YAAI,SAAS,gBAAgB,CAAC,EAAE,kCAAmC;AACjE,wBAAc,KAAK,OAAO;AAAA,QAC5B;AACA,cAAM,aAAa,SAAS,QAAQ,UAAU,WAAW;AAEzD,aAAK,YAAY;AAAA,UACf,SAAS;AAAA,UACT;AAAA,UACA,SAAS,gBAAgB,CAAC,EAAE;AAAA,QAC9B;AAAA,MACF,OAAO;AACL,aAAK,YAAY,KAAK,SAAS,OAAO;AACtC,aAAK,kBAAkB;AAAA,MACzB;AAAA,IACF,SAAS,GAAG;AACV,cAAQ;AAAA,QACN;AAAA,QACA,KAAK,cAAc;AAAA,QACnB;AAAA,MACF;AACA,WAAK,WAAW;AAAA,IAClB;AAAA,EACF;AAAA,EAEA,iBAAuB;AACrB,SAAK,UAAU,iBAAiB;AAAA,EAClC;AAAA,EAEA,8BACE,gBACM;AACN,SAAK,SAAS,cAAc;AAAA,EAC9B;AAAA;AAAA,EAGQ,SAAS,gBAAuC;AACtD,QAAI,KAAK,YAAY;AACnB,WAAK,cAAc,KAAK,WAAW,cAAc;AAAA,IACnD;AACA,QAAI,CAAC,KAAK,SAAS;AACjB;AAAA,IACF;AACA,SAAK,aAAa,IAAI;AAAA,MACpB,KAAK;AAAA,MACL,KAAK;AAAA,MACL;AAAA,IACF;AACA,SAAK,WAAW,KAAK,WAAW,cAAc;AAC9C,QAAI,KAAK,iBAAiB;AACxB,WAAK,iBAAiB,KAAK,eAAe;AAAA,IAC5C;AAAA,EACF;AAAA,EAEQ,+BAA+B,IAAI;AAAA,IACzC;AAAA,IACA;AAAA,IACA,OAAO,KAAK,iBAAiB;AAAA,EAC/B;AAAA,EACA,eAAe,aAAuC;AACpD,SAAK,6BAA6B;AAAA,MAChC,gBAAgB,SAAS,aAAa;AAAA,IACxC;AAAA,EACF;AAAA,EAEQ,SAAe;AAAA,EAEvB;AACF;AAEA,mBAAmB,OAAO,oBAAoB,cAAc;;;ACpJrD,IAAM,wBAAN,MAAmD;AAAA,EACxD,YACU,OACD,aACC,cACA,wBAIR;AAPQ;AACD;AACC;AACA;AAKR,SAAK,KAAK,eAAe;AAEzB,SAAK,sBAAsB;AAAA,MACzB,KAAK,MAAM,iBAAiB;AAAA,MAC5B,OAAO,mBAA+C;AACpD,SAAC,MAAM,KAAK,eAAe,GAAG;AAAA,UAC5B;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,wBAAwB,IAAI,qBAAqB;AAAA,EACjD,aAAmB;AACjB,SAAK,sBAAsB,WAAW;AAAA,EACxC;AAAA;AAAA,EAGA,iBAAuB;AAAA,EAEvB;AAAA,EAEA,wBAAwD;AAAA;AAAA,EAExD,MAAM,iBAA0C;AAC9C,WAAQ,KAAK,2BAA2B,YAAY;AAClD,YAAM,aACJ,KAAK,2BAA2B,4BAC5B,KAAK,aAAa,UAAW,IAC7B,KAAK,2BAA2B,uBAC9B,KAAK,aAAa,MAAO,IACzB,KAAK,aAAa,IAAI;AAC9B,aAAO,IAAI;AAAA,QACT,KAAK;AAAA,QACL,MAAM,KAAK,aAAa,QAAQ;AAAA,QAChC,MAAM;AAAA,QACN,CAAC;AAAA,QACD,KAAK;AAAA,MACP;AAAA,IACF,GAAG;AAAA,EACL;AACF;;;AC/CO,IAAM,uBAAN,cACG,qBAEV;AAAA,EAME,YACS,OACC,wBAIR;AACA,UAAM;AANC;AACC;AAAA,EAMV;AAAA,EAbA,wBAAwB,IAAI,qBAAqB;AAAA,EACjD,aAAmB;AACjB,SAAK,sBAAsB,WAAW;AAAA,EACxC;AAAA,EAYA,MAAM,oBAAmC;AACvC,SAAK,OAAO,sBAAsB;AAClC,QAAI,KAAK,OAAO;AACd,WAAK,sBAAsB;AAAA,QACzB,KAAK,MAAM,kBAAkB;AAAA,QAC7B,KAAK,eAAe,KAAK,IAAI;AAAA,MAC/B;AAAA,IACF;AAAA,EACF;AAAA,EAEA;AAAA,EACA,MAAM,QAA6B;AACjC,WAAQ,KAAK,kBAAkB,YAC7B,KAAK,MAAM,WAAW,GAAG,WAAW,GAAG;AAAA,EAC3C;AAAA,EAEA,iBAAuB;AACrB,SAAK,+BAA+B,eAAe;AAAA,EACrD;AAAA,EAEA;AAAA,EACA,+BAAkE;AAChE,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,MAAM,gCACJ,uBACe;AACf,UAAM,MAAM,KAAK;AACjB,SAAK,gCAAgC;AACrC,SAAK,WAAW;AAChB,UAAM,wBAAwB,sBAAsB,eAAe;AACnE,SAAK,eAAe,cAAc;AAClC,SAAK,WAAW,MAAM,qBAAqB;AAAA,EAC7C;AAAA,EAEA,MAAM,eAAe,cAA2C;AAC9D,SAAK,+BAA+B,WAAW;AAC/C,UAAM,wBAAwB,IAAI;AAAA,MAChC,KAAK,MAAO;AAAA,MACZ;AAAA,MACA;AAAA,MACA,KAAK;AAAA,IACP;AAEA,SAAK,KAAK,gCAAgC,qBAAqB;AAAA,EACjE;AACF;AAEA,mBAAmB,OAAO,2BAA2B,oBAAoB;;;AChFlE,IAAM,sBAAN,MAA6B;AAAA;AAAA,EAElC;AAAA;AAAA,EAEA;AAAA;AAAA,EACA;AAAA,EACA,cAAc;AACZ,SAAK,UAAU,IAAI,QAAQ,CAAC,SAAS,WAAW;AAC9C,WAAK,WAAW;AAChB,WAAK,SAAS;AAAA,IAChB,CAAC;AAAA,EACH;AAAA,EACA,eAAe,GAAY;AACzB,SAAK,SAAS,CAAC;AAAA,EACjB;AACF;;;ACAO,IAAM,wBAAN,cAAoC,YAAmC;AAAA,EAC5E,YACU,OACD,aACC,cACA,uBACR;AACA,UAAM;AALE;AACD;AACC;AACA;AAGR,SAAK,KAAK,eAAe;AAKzB,SAAK,sBAAsB;AAAA,MACzB,KAAK,MAAM;AAAA,MACX,CAACC,kBAA+B;AAC9B,YAAI,KAAK,aAAa,OAAOA,cAAa,IAAI;AAC5C,eAAK,WAAW;AAAA,QAClB;AAAA,MACF;AAAA,IACF;AACA,SAAK,sBAAsB;AAAA,MACzB,KAAK,MAAM;AAAA,MACX,OAAO,aAA6B;AAClC,YAAI;AACF,WAAC,MAAM,KAAK,eAAe,GAAG,iBAAiB,QAAQ;AACvD,eAAK,eAAe;AAAA,QACtB,QAAQ;AAON,eAAK,WAAW;AAAA,QAClB;AAAA,MACF;AAAA,IACF;AAEA,SAAK,sBAAsB;AAAA,MACzB,KAAK,MAAM,iBAAiB;AAAA,MAC5B,OAAO,qBAA+C;AACpD,SACG,MAAM,KAAK,eAAe,GAC3B,0BAA0B;AAAA,UAC1B,cACE,qBAAqB,SAAS,aAAa;AAAA,QAC/C,CAAC;AACD,aAAK,eAAe;AAAA,MACtB;AAAA,IACF;AACA,SAAK,sBAAsB;AAAA,MACzB,KAAK,MAAM,iBAAiB;AAAA,MAC5B,OAAO,sBAAyC;AAC9C,SACG,MAAM,KAAK,eAAe,GAC3B,0BAA0B;AAAA,UAC1B,gBAAgB,sBAAsB;AAAA,QACxC,CAAC;AACD,aAAK,eAAe;AAAA,MACtB;AAAA,IACF;AACA,SAAK,sBAAsB;AAAA,MACzB,KAAK,MAAM,iBAAiB;AAAA,MAC5B,OAAO,mBAA+C;AACpD,cAAM,WAAW,MAAM,KAAK,eAAe;AAC3C,iBAAS,kBAAkB,cAAc;AACzC,aAAK,eAAe;AAAA,MACtB;AAAA,IACF;AACA,SAAK,sBAAsB;AAAA,MACzB,KAAK,MAAM,iBAAiB;AAAA,MAC5B,OAAO,iBAAkC;AACvC,SACG,MAAM,KAAK,eAAe,GAC3B,0BAA0B;AAAA,UAC1B;AAAA,QACF,CAAC;AACD,aAAK,eAAe;AAAA,MACtB;AAAA,IACF;AAEA,SAAK,sBAAsB;AAAA,MACzB;AAAA,QACE,KAAK,MAAM,iBAAiB;AAAA,QAC5B,KAAK,MAAM,iBAAiB;AAAA,QAC5B,KAAK,MAAM,iBAAiB;AAAA,MAC9B;AAAA,MACA,OACE,WAKG;AACH,YAAI,+BAAgC,MAAM,KAAK,eAAe,GAAI;AAChE,WAAE,MAAM,KAAK,eAAe,GAAY;AAAA,YACtC,OAAO,CAAC,EAAE,qBAAqB;AAAA,YAC/B,OAAO,CAAC;AAAA,YACR,OAAO,CAAC;AAAA,UACV;AACA,eAAK,eAAe;AAAA,QACtB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,wBAAwB,IAAI,qBAAqB;AAAA,EACjD,aAAmB;AACjB,SAAK,sBAAsB,WAAW;AAAA,EACxC;AAAA,EAEA,iBAAuB;AACrB,SAAK,YAAY,eAAe;AAChC,SAAK,cAAc,IAAI,YAAY,kBAAkB,CAAC;AAAA,EACxD;AAAA,EAEA,wBAAwD;AAAA,EACxD,MAAM,iBAA0C;AAC9C,WAAQ,KAAK,2BAA2B,YAAY;AAClD,YAAM,eAAe,WAAW;AAChC,UACE,KAAK,aAAa,OAAO,WACzB,KAAK,0BAA0B,UAC/B;AAEA,cAAM;AAAA,UACJ;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,IAAI,MAAM,QAAQ,IAAI;AAAA,UACpB,KAAK,MAAM,iBAAiB,wBAAwB,IAAI;AAAA,UACxD,KAAK,MAAM,iBAAiB,kBAAkB,IAAI;AAAA,UAClD,KAAK,MAAM,iBAAiB,eAAe,IAAI;AAAA,UAC/C,KAAK,MAAM,iBAAiB,6BAA6B,IAAI;AAAA,QAC/D,CAAC;AACD,gBAAQ,MAAM,cAAc;AAAA,UAC1B,MAAM,KAAK,YAAY,eAAe;AAAA,UACtC;AAAA,YACE;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF,OAAO;AACL,cAAM,CAAC,cAAc,kBAAkB,YAAY,YAAY,IAC7D,MAAM,QAAQ,IAAI;AAAA,UAChB,KAAK,MAAM,iBAAiB,YAAY,IAAI;AAAA,UAC5C,KAAK,MAAM,iBAAiB,wBAAwB,IAAI;AAAA,UACxD,KAAK,MAAM,iBAAiB,kBAAkB,IAAI;AAAA,UAClD,KAAK,MAAM,iBAAiB,aAAa,IAAI;AAAA,QAC/C,CAAC;AACH,cAAM,QAAQ,MAAM,cAAc;AAAA,UAChC,MAAM,KAAK,YAAY,eAAe;AAAA,UACtC,KAAK;AAAA,UACL,iBAAiB,SAAS,aAAa;AAAA,UACvC;AAAA,UACA,KAAK,aAAa,OAAO;AAAA;AAAA,QAC3B;AAEA,aAAK;AAAA,UAAK,CAAC,MACT,EAAE;AAAA,YACA;AAAA,YACA,oBAAoB;AAAA,YACpB,cAAc;AAAA,UAChB;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA,IACF,GAAG;AAAA,EACL;AAAA,EAEA,MAAM,YACJ,kBACA,iBAIe;AACf,UAAM,SAAU,MAAM,KAAK,eAAe;AAE1C,QAAI,EAAE,mCAAmC,SAAS;AAChD,cAAQ,KAAK,4BAA4B;AACzC;AAAA,IACF;AAEA,UAAM,UAAU,OAAO,8BAA8B;AACrD,UAAM,CAAC,WAAW,sBAAsB,IAAI,MAAM,QAAQ,IAAI;AAAA,MAC5D;AAAA,MACA,KAAK,MAAM,iBAAiB,uBAAuB,IAAI;AAAA,IACzD,CAAC;AAED,UAAM,aAAa,UAAU,iBAAiB,OAAO;AACrD,QAAI,WAAW,SAAS,GAAG;AACzB,YAAM,cAAc,OAAO;AAAA,QACzB,WAAW,CAAC,EAAE;AAAA,QACd;AAAA,MACF;AACA,UAAI,aAAa;AACf,aAAK,MAAM,oBAAoB,YAAY,MAAM;AAAA,UAC/C,QAAQ;AAAA,QACV,CAAC;AAAA,MACH,OAAO;AACL,gBAAQ,KAAK,gBAAgB;AAAA,MAC/B;AAAA,IACF;AAAA,EACF;AACF;;;AC3MO,IAAM,uBAAN,cACG,qBAEV;AAAA,EAeE,YAAmB,OAA2B;AAC5C,UAAM;AADW;AAAA,EAEnB;AAAA;AAAA,EAfA,4BACE,IAAI,iBAAiB,MAAM,cAAc;AAAA,IACvC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAAA,EAEH,wBAAwB,IAAI,qBAAqB;AAAA,EACjD,aAAmB;AACjB,SAAK,sBAAsB,WAAW;AAAA,EACxC;AAAA,EAMA,MAAM,oBAAmC;AACvC,SAAK,OAAO,sBAAsB;AAClC,UAAM,UAAU,IAAI,gBAAgB,KAAK,OAAO,IAAI;AACpD,SAAK,WAAW,OAAO;AACvB,QAAI,KAAK,OAAO;AACd,WAAK,sBAAsB;AAAA,QACzB,CAAC,KAAK,MAAM,cAAc,KAAK,MAAM,qBAAqB;AAAA,QAC1D,KAAK,SAAS,KAAK,IAAI;AAAA,MACzB;AACA,WAAK,sBAAsB;AAAA,QACzB,KAAK,MAAM;AAAA;AAAA,QAEX,KAAK,YAAY,KAAK,IAAI;AAAA,MAC5B;AAAA,IACF;AACA,SAAK,eAAe;AAAA,EACtB;AAAA,EAEA,mBAA2C;AAAA,EAC3C,YAAY,UAAwC;AAClD,UAAM,qBAAqB,CAAC,gBAAgB,WAAW,EAAE,SAAS,QAAQ;AAC1E,UAAM,cAAc,KAAK,qBAAqB;AAE9C,SAAK,0BAA0B,SAAS,QAAQ;AAChD,QAAI,oBAAoB;AACtB,UAAI,CAAC,aAAa;AAChB,aAAK,mBAAmB,IAAI,gBAAgB,KAAK,OAAO,MAAM;AAAA,UAC5D,UAAU;AAAA,QACZ,CAAC;AACD,aAAK,WAAW,KAAK,gBAAgB;AACrC,aAAK,eAAe;AAAA,MACtB;AAAA,IACF,OAAO;AACL,UAAI,KAAK,kBAAkB;AACzB,aAAK,cAAc,KAAK,gBAAgB;AACxC,aAAK,mBAAmB;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,QACJ,GAIe;AACf,UAAM,wBAAwB,KAAK;AACnC,QAAI,CAAC,uBAAuB;AAC1B,cAAQ,KAAK,2CAA2C;AACxD;AAAA,IACF;AAEA,UAAM,oBAAoB,YAAY;AACpC,YAAM,CAAC,QAAQ,EAAE,gBAAgB,aAAa,CAAC,IAAI,MAAM,QAAQ,IAAI;AAAA,QACnE,EAAE,OAAO;AAAA,SACR,YAAY;AACX,gBAAM,EAAE,gBAAAC,iBAAgB,cAAAC,cAAa,IAAI,MAAM,WAAW;AAC1D,iBAAO,EAAE,gBAAAD,iBAAgB,cAAAC,cAAa;AAAA,QACxC,GAAG;AAAA,MACL,CAAC;AAED,YAAM,YAAY,IAAI,eAAe;AACrC,YAAM,QAAQ,IAAI;AAAA,QAChB,EAAE,OAAO,UAAU;AAAA,QACnB,EAAE,OAAO,UAAU;AAAA,MACrB;AACA,gBAAU,cAAc,OAAO,MAAM;AACrC,aAAO;AAAA,IACT,GAAG;AAEH,0BAAsB,YAAY,kBAAkB;AAAA,MAClD,QAAQ,CAAC,EAAE,OAAO,UAAU;AAAA,MAC5B,OAAO,EAAE,OAAO,UAAU,KAAK,gBAC3B,aACA,EAAE,OAAO,UAAU,KAAK,WACtB,gBACA;AAAA,IACR,CAAC;AAAA,EACH;AAAA,EAEA;AAAA,EACA,MAAM,QAA6B;AACjC,WAAQ,KAAK,kBAAkB,YAC7B,KAAK,MAAM,WAAW,GAAG,WAAW,GAAG;AAAA,EAC3C;AAAA,EAEA,YAAkC,oBAAI,IAAI;AAAA,EAC1C,WAAW,SAA0B;AACnC,YAAQ;AAAA,MACN;AAAA,MACA,KAAK,QAAQ,KAAK,IAAI;AAAA;AAAA,IACxB;AACA,SAAK,UAAU,IAAI,OAAO;AAC1B,SAAK,eAAe,YAAY,OAAO;AAAA,EACzC;AAAA,EAEA,cAAc,SAA0B;AACtC,SAAK,UAAU,OAAO,OAAO;AAC7B,YAAQ,OAAO;AACf,YAAQ,WAAW;AACnB,SAAK,+BAA+B,WAAW;AAAA,EACjD;AAAA,EAEA,uBAAkD;AAChD,WAAO,KAAK,UAAU,OAAO;AAAA,EAC/B;AAAA,EAEA,iBAAuB;AACrB,eAAW,WAAW,KAAK,WAAW;AACpC,cAAQ,eAAe;AAAA,IACzB;AAAA,EACF;AAAA,EAEA,gCAA8D;AAAA;AAAA,EAE9D,MAAM,gCACJ,OACA,uBACe;AACf,UAAM,MAAM,KAAK;AACjB,QAAI;AACF,WAAK,gCAAgC;AACrC,WAAK,WAAW;AAChB,YAAM,IAAI,MAAM,sBAAsB,eAAe,CAAC;AAAA,IACxD,UAAE;AACA,UAAI,KAAK;AAEP,cAAM,OAAO,MAAM,IAAI,eAAe,CAAC;AAAA,MACzC;AAAA,IACF;AACA,SAAK,uBAAuB,eAAe,qBAAqB;AAAA,EAClE;AAAA,EAEA,yBAAyB,IAAI,oBAA2C;AAAA;AAAA,EAExE,MAAM,oCAAoE;AACxE,WACE,KAAK,iCAAiC,KAAK,uBAAuB;AAAA,EAEtE;AAAA,EAEA,wBACE,IAAI,aAAkD;AAAA,EAExD,MAAM,SACJ,QAIe;AACf,QAAI,OAAO,CAAC,MAAM,MAAM;AAEtB;AAAA,IACF;AACA,SAAK,+BAA+B,WAAW;AAC/C,UAAM,CAAC,OAAO,qBAAqB,IACjC,MAAM,KAAK,sBAAsB;AAAA,MAC/B,QAAQ,IAAI;AAAA,QACV,KAAK,MAAM;AAAA,QACX,IAAI,sBAAsB,KAAK,OAAQ,MAAM,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;AAAA;AAAA,MACnE,CAAC;AAAA,IACH;AAEF,SAAK,KAAK,gCAAgC,OAAO,qBAAqB;AAAA,EACxE;AACF;AAEA,mBAAmB,OAAO,2BAA2B,oBAAoB;;;AChNlE,IAAM,qBACX,OAAO,aAAa,cAAc,OAAO;;;ACcpC,IAAM,oBACX,oBAAoB,qBACpB,CAAC,CAAC,oBAAoB;AAEjB,SAAS,yBAAwC;AACtD,MAAI,SAAS,gBAAgB;AAC3B,WAAO,SAAS,eAAe;AAAA,EACjC,OAAO;AACL,WAAO,SAAS,qBAAsB;AAAA,EACxC;AACF;AAEO,SAAS,4BAA4C;AAC1D,MAAI,SAAS,mBAAmB;AAC9B,WAAO,SAAS;AAAA,EAClB,OAAO;AACL,WAAO,SAAS,2BAA2B;AAAA,EAC7C;AACF;AAEO,SAAS,kBAAkB,SAAiC;AACjE,MAAI,QAAQ,mBAAmB;AAC7B,WAAO,QAAQ,kBAAkB;AAAA,EACnC,OAAO;AACL,WAAO,QAAQ,wBAAwB;AAAA,EACzC;AACF;;;ACrCO,IAAM,cAAc;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAiBO,IAAM,uBAAN,cAAmC,kBAGxC;AAAA;AAAA,EAEA,OAAO,QAAuD;AAC5D,UAAM,oBAAoB;AAAA,MACxB,YAAY;AAAA;AAAA,QAEV,SAAS;AAAA,QACT;AAAA;AAAA;AAAA,UAGE,SAAS,sBAAsB,OAC3B,qBACA;AAAA;AAAA,QACN,OAAO;AAAA,MACT;AAAA,MACA,iBAAiB;AAAA,QACf,SAAS,CAAC,OAAO,mBAAmB;AAAA,QACpC,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,MACA,uBAAuB;AAAA,QACrB,SAAS,CAAC,OAAO,mBAAmB;AAAA,QACpC,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,MACA,cAAc;AAAA,QACZ,SAAS,EACP,OAAO,mBAAmB,WAAW,OAAO,mBAAmB;AAAA,QAEjE,MAAM,OAAO,mBAAmB,UAAU,UAAU;AAAA,QACpD,OAAO,OAAO,mBAAmB,UAAU,UAAU;AAAA,MACvD;AAAA,MACA,aAAa;AAAA,QACX,SAAS,CAAC,OAAO,mBAAmB;AAAA,QACpC,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,MACA,eAAe;AAAA,QACb,SAAS,CAAC,OAAO,mBAAmB;AAAA,QACpC,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,MACA,gBAAgB;AAAA,QACd,SAAS;AAAA,QACT,MAAM;AAAA,QACN,OAAO;AAAA,QACP,QAAQ,OAAO,eAAe;AAAA,MAChC;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;;;ACrFO,IAAM,gBAAgB,IAAI,kBAAkB;AACnD,cAAc;AAAA,EACZ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA8BF;AAEO,IAAM,YAAY,IAAI,kBAAkB;AAC/C,UAAU;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiGF;;;ACpHA,IAAM,iBAAiB;AAAA,EACrB,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,uBAAuB;AAAA,EACvB,cAAc;AAAA,EACd,aAAa;AAAA,EACb,eAAe;AAAA,EACf,gBAAgB;AAClB;AAIO,IAAM,gBAAN,cAA4B,qBAAqB;AAAA;AAAA,EAItD,YACS,OACA,YACC,0BACR;AACA,UAAM;AAJC;AACA;AACC;AAAA,EAGV;AAAA,EATA,UAAsD;AAAA,EAWtD,oBAA0B;AACxB,SAAK,OAAO,aAAa;AACzB,UAAM,UAAwD,CAAC;AAC/D,eAAW,WAAW,gBAAgB;AACpC,YAAM,SAAS,IAAI,aAAa;AAChC,cAAQ,OAAwB,IAAI;AACpC,aAAO,WAAW;AAAA,QAAiB;AAAA,QAAS,MAC1C,KAAK,WAAW,OAAwB;AAAA,MAC1C;AACA,WAAK,WAAW,MAAM;AAAA,IACxB;AACA,SAAK,UAAU;AAEf,SAAK,OAAO,iBAAiB,iBAAiB,KAAK,OAAO,KAAK,IAAI,CAAC;AACpE,SAAK,OAAO,iBAAiB,YAAY;AAAA,MACvC,KAAK,kBAAkB,KAAK,IAAI;AAAA,IAClC;AAAA,EACF;AAAA,EAEA,WAAW,SAAwB;AACjC,YAAQ,SAAS;AAAA,MACf,KAAK,cAAc;AACjB,aAAK,KAAK,mBAAmB;AAC7B;AAAA,MACF;AAAA,MACA,KAAK,iBAAiB;AACpB,aAAK,YAAY,YAAY,EAAE,OAAO,KAAK,CAAC;AAC5C;AAAA,MACF;AAAA,MACA,KAAK,uBAAuB;AAC1B,aAAK,YAAY,oBAAoB,KAAK;AAAA,UACxC;AAAA,UACA;AAAA,QACF,CAAC;AACD;AAAA,MACF;AAAA,MACA,KAAK,cAAc;AACjB,aAAK,YAAY,WAAW;AAC5B;AAAA,MACF;AAAA,MACA,KAAK,aAAa;AAChB,aAAK,YAAY,oBAAoB,KAAK;AAAA,UACxC;AAAA,UACA;AAAA,QACF,CAAC;AACD;AAAA,MACF;AAAA,MACA,KAAK,eAAe;AAClB,aAAK,YAAY,UAAU,EAAE,OAAO,KAAK,CAAC;AAC1C;AAAA,MACF;AAAA,MACA,KAAK,gBAAgB;AACnB,aAAK,KAAK,YAAY,iBAAiB;AACvC;AAAA,MACF;AAAA,MACA;AACE,cAAM,IAAI,MAAM,iBAAiB;AAAA,IACrC;AAAA,EACF;AAAA;AAAA;AAAA,EAIA,MAAM,qBAAoC;AACxC,QAAI,CAAC,KAAK,0BAA0B;AAClC,YAAM,IAAI,MAAM,gDAAgD;AAAA,IAClE;AAEA,QAAI,0BAA0B,MAAM,KAAK,0BAA0B;AACjE,WAAK,uBAAuB;AAAA,IAC9B,OAAO;AAEL,WAAK,SAAS,WAAW,QAAQ,iBAAiB;AAElD,WAAK;AAAA,QACF,MAAM,KAAK,OAAO,iBAAiB,kBAAkB,IAAI,KACxD,KAAK;AAAA,MACT;AAEA,YAAM,eAAe,MAAY;AAC/B,YAAI,0BAA0B,MAAM,KAAK,0BAA0B;AACjE,eAAK,SAAS,WAAW,QAAQ,kBAAkB;AACnD,qBAAW,oBAAoB,oBAAoB,YAAY;AAAA,QACjE;AAAA,MACF;AACA,iBAAW,iBAAiB,oBAAoB,YAAY;AAAA,IAC9D;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,mBAAqD;AAEhE,eAAW,WAAW,gBAAgB;AAEpC,YAAM,SAAS,KAAK,QAAS,OAAwB;AAErD,YAAM,OAAO,kBAAkB,OAAwB;AACvD,aAAO,WAAW,WAAW,CAAC,KAAK;AACnC,aAAO,WAAW,QAAQ,KAAK;AAC/B,aAAO,QAAQ,KAAK,IAAI;AACxB,aAAO,SAAS,CAAC,CAAC,KAAK;AAAA,IAEzB;AAAA,EACF;AAAA,EAEA,kBAAkB,aAAgC;AAChD,eAAW,UAAU,OAAO,OAAO,KAAK,WAAW,CAAC,CAAC,GAAG;AACtD,aAAO,kBAAkB,WAAW;AAAA,IACtC;AAAA,EACF;AACF;AAEA,mBAAmB,OAAO,kBAAkB,aAAa;AAEzD,IAAM,eAAN,cAA2B,qBAAqB;AAAA,EAC9C,aAAgC,SAAS,cAAc,QAAQ;AAAA;AAAA,EAE/D,kBAAkB,aAAgC;AAChD,SAAK,eAAe,UAAU,OAAO,aAAa,gBAAgB,MAAM;AAAA,EAC1E;AAAA,EAEA,oBAAoB;AAClB,SAAK,OAAO,SAAS;AACrB,SAAK,WAAW,KAAK,UAAU;AAAA,EACjC;AAAA,EAEA,eAA6C,IAAI;AAAA,IAC/C;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAEA,QAAQ,UAA4B;AAClC,SAAK,aAAa,SAAS,QAAQ;AAAA,EACrC;AACF;AAEA,mBAAmB,OAAO,iBAAiB,YAAY;;;AChLhD,IAAM,oBAAoB,IAAI,kBAAkB;AACvD,kBAAkB;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyBF;;;ACfA,IAAM,sBAAsB;AAE5B,IAAI,cAAc;AAElB,oBAAoB;AAAA,EAClB;AAAA,EACA,CAAC,UAAU;AACT,QAAI,MAAM,OAAO;AACf,oBAAc;AAAA,IAChB;AAAA,EACF;AAAA,EACA;AACF;AAEA,oBAAoB;AAAA,EAClB;AAAA,EACA,CAAC,UAAU;AACT,QAAI,MAAM,OAAO;AACf,oBAAc;AAAA,IAChB;AAAA,EACF;AAAA,EACA;AACF;AAGA,IAAI,IAAI;AACR,IAAI,WAAW;AAEf,oBAAoB;AAAA,EAClB;AAAA,EACA,MAAM;AACJ;AAAA,EACF;AAAA,EACA;AACF;AAEA,oBAAoB,iBAAiB,aAAa,eAAe,KAAK;AACtE,oBAAoB,iBAAiB,cAAc,eAAe,KAAK;AAEvE,SAAS,cAAc,GAAe;AAEpC,MAAI,EAAE;AAER;AAEA,IAAM,UAAU;AAChB,IAAI,aAAa;AACjB,IAAI,UAAmB;AACvB,IAAI,kBAAkB;AAGf,IAAM,iBAAN,cAA6B,qBAAqB;AAAA,EACvD,YACS,OACA,YACP;AACA,UAAM;AAHC;AACA;AAAA,EAGT;AAAA,EAEA,MAAM,uBACJ,sBACe;AAEf,UAAM,YAAY,MAAM,KAAK,UAAU;AACvC,cAAU,MAAM,qBAAqB,UAAU,MAAM,SAAS;AAC9D,cAAU,MAAM,qBAAqB,UAAU,IAAI,SAAS;AAC5D,cAAU,WAAW,UAAU,QAAQ,UAAU;AACjD,cAAU,QAAQ,qBAAqB,UAAU,SAAS;AAAA,EAC5D;AAAA,EAEA,MAAM,oBAAmC;AACvC,SAAK,OAAO,iBAAiB;AAC7B,SAAK,WAAW,MAAM,KAAK,UAAU,CAAC;AACtC,SAAK,OAAO,iBAAiB,YAAY;AAAA,MACvC,KAAK,kBAAkB,KAAK,IAAI;AAAA,IAClC;AAAA,EACF;AAAA,EAEA,kBAAkB,aAAgC;AAChD,SAAK,eAAe,UAAU,OAAO,aAAa,gBAAgB,MAAM;AAAA,EAC1E;AAAA,EAEA,aAA+C;AAAA,EAC/C,MAAM,YAAuC;AAE3C,WAAQ,KAAK,gBAAgB,YAAY;AACvC,YAAM,OAAO,SAAS,cAAc,OAAO;AAC3C,WAAK,OAAO;AACZ,WAAK,WAAW;AAGhB,WAAK,OAAO,qBAAqB;AAAA,QAC/B,KAAK,uBAAuB,KAAK,IAAI;AAAA,MACvC;AAEA,WAAK,iBAAiB,SAAS,KAAK,QAAQ,KAAK,IAAI,CAAC;AACtD,WAAK,iBAAiB,WAAW,KAAK,WAAW,KAAK,IAAI,CAAC;AAE3D,aAAO;AAAA,IACT,GAAG;AAAA,EACL;AAAA,EAEA,MAAM,QAAQ,GAAyB;AACrC,QAAI,SAAS;AACX;AAAA,IACF;AACA,UAAM,YAAY,MAAM,KAAK,UAAU;AACvC,UAAM,KAAK,SAAS,GAAG,SAAS;AAEhC,UAAM,QAAQ,SAAS,UAAU,OAAO,EAAE;AAE1C,SAAK,OAAO,YAAY,IAAI,EAAE,SAAS,MAAM,CAAC;AAC9C,SAAK,OAAO,iBAAiB,IAAI,KAAK;AAAA,EACxC;AAAA,EAEA,WAAW,GAAwB;AACjC,YAAQ,EAAE,KAAK;AAAA,MACb,KAAK;AAAA;AAAA,MAEL,KAAK,cAAc;AACjB,aAAK,YAAY,oBAAoB,KAAK;AAAA,UACxC,WACE,EAAE,QAAQ;AAAA,UACZ;AAAA,QACF,CAAC;AACD,UAAE,eAAe;AACjB;AAAA,MACF;AAAA,MACA,KAAK,KAAK;AACR,aAAK,YAAY,WAAW;AAC5B,UAAE,eAAe;AACjB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,SAAS,GAAU,WAA4C;AACnE,QAAI,CAAC,qBAAqB;AACxB;AAAA,IACF;AAEA,QAAI,aAAa;AACf,YAAM,OAAO,UAAU,sBAAsB;AAC7C,YAAM,UAAU,KAAK,MAAM,KAAK,SAAS;AACzC,cAAQ,IAAI,SAAS,GAAG,GAAG,WAAW;AAEtC,YAAM,QAAQ,KAAK,IAAI,UAAU,CAAC;AAClC,UAAI,QAAQ;AACZ,UAAI,QAAQ,IAAI;AACd,gBAAQ,KAAK,IAAI,MAAM,EAAE,QAAQ,MAAM,KAAK,IAAI,EAAE;AAAA,MACpD;AACA,YAAM,SAAS,SAAS,UAAU,OAAO,EAAE;AAC3C,cAAQ,IAAI,MAAM,iBAAiB,UAAU,MAAM;AACnD,UAAI,oBAAoB,UAAU;AAChC,cAAM,SAAS,SAAS,cAAc;AACtC,gBAAQ,IAAI,SAAS,OAAO,KAAK;AACjC,kBAAU;AACV,YAAI,SAAS;AACb,iBACE,UACA,QAAQ,SACP,SAAS,WAAW,KAAK,IAAI,IAAI,IAAI,OAAQ,QAAQ,QAAS,GAAG;AACpE,kBAAU,QAAQ,OAAO,SAAS;AAClC,gBAAQ,IAAI,KAAK;AACjB,kBAAU;AACV,aAAK,eAAe,MAAM,UAAU,MAAM,SAAS;AAAA,MACrD,OAAO;AACL,0BAAkB;AAAA,MACpB;AACA,mBAAa;AAAA,IACf;AAAA,EACF;AACF;AAEA,mBAAmB,OAAO,mBAAmB,cAAc;;;AC/K3D,IAAI,eAAyC;AAC7C,eAAsB,WACpB,OACA,SACiC;AAIjC,QAAM;AAAA,IACJ,EAAE,wBAAwB,WAAW;AAAA,IACrC;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,MAAM,QAAQ,IAAI;AAAA,KACnB,YAAY;AACX,YAAM,EAAE,wBAAAC,yBAAwB,YAAAC,YAAW,IAAI,MAAM,WAAW;AAChE,aAAO,EAAE,wBAAAD,yBAAwB,YAAAC,YAAW;AAAA,IAC9C,GAAG;AAAA,IACH,MAAM,MAAM,aAAa,IAAI;AAAA,IAC7B,MAAM,MAAM,sBAAsB,IAAI;AAAA,IACtC,MAAM,MAAM,iBAAiB,kBAAkB,IAAI;AAAA,IACnD,MAAM,MAAM,iBAAiB,sBAAsB,IAAI;AAAA,IACvD,MAAM,MAAM,eAAe,IAAI;AAAA,IAC/B,MAAM,MAAM,iBAAiB,iBAAiB,IAAI;AAAA,EACpD,CAAC;AAED,QAAM,QAAQ,SAAS,SAAS;AAChC,QAAM,SAAS,SAAS,UAAU;AAClC,QAAM,cAAc,QAAQ;AAC5B,QAAM,SAAU,iBAAiB,OAAO,YAAY;AAClD,WAAO,IAAI,uBAAuB,IAAI,aAAa,KAAK,EAAE;AAAA,EAC5D,GAAG;AAEH,QAAM,QAAQ,IAAI,WAAW;AAC7B,QAAM,kBAAkB,IAAI;AAAA,IAC1B;AAAA,IACA,EAAE,gBAAgB,MAAM;AAAA,IAAC,EAAE;AAAA,IAC3B;AAAA,IACA;AAAA,EACF;AACA,QAAM,IAAI,MAAM,gBAAgB,eAAe,CAAC;AAChD,QAAM,8BAA8B,QAAQ,gBAAgB;AAE5D,QAAM,iBAAiB,MAAM,gBAAgB,OAAO,QAAQ,OAAO,MAAM;AACzE,QAAM,UAAU,eAAe,UAAU;AAEzC,QAAM,kBAAkB,MAAM,mBAAmB,KAAK;AAEtD,SAAO;AAAA,IACL;AAAA,IACA,UAAU,OAAO,aAAsB;AACrC,kBAAY,SAAS,YAAY,eAAe;AAAA,IAClD;AAAA,EACF;AACF;AAEA,eAAsB,mBACpB,OACiB;AACjB,QAAM,CAAC,UAAU,aAAa,IAAI,MAAM,QAAQ,IAAI;AAAA,IAClD,MAAM,SAAS,IAAI;AAAA,IACnB,MAAM,IAAI,IAAI;AAAA,EAChB,CAAC;AACD,SAAO,IAAI,QAAQ,IACjB,cAAc,IAAI,6BAA6B,MAAM,IACjD,KACA,IAAI,cAAc,IAAI,SAAS,CAAC,EACtC;AACF;AAEO,SAAS,YACd,KACA,MACA,YAAoB,OACd;AACN,QAAM,IAAI,SAAS,cAAc,GAAG;AACpC,IAAE,OAAO;AACT,IAAE,WAAW,GAAG,IAAI,IAAI,SAAS;AACjC,IAAE,MAAM;AACV;;;AC5FO,IAAM,kBAAkB,IAAI,kBAAkB;AACrD,gBAAgB;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoFF;;;ACvFO,IAAM,sBAAN,cAAkC,uBAAsC;AAAA,EAC7E,kBAAiC;AAC/B,WAAO;AAAA,EACT;AACF;;;ACJO,IAAM,UAAN,cAAsB,iBAAkD;AAAA,EAC7E,kBAA8B;AAC5B,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,OAAwC;AAC7C,QAAI,OAAO,UAAU,UAAU;AAC7B,aAAO,IAAI,IAAI,OAAO,SAAS,IAAI;AAAA,IACrC;AACA,WAAO;AAAA,EACT;AACF;;;ACTO,IAAM,YAAN,MAAM,WAAU;AAAA;AAAA,EAGZ;AAAA,EACA;AAAA,EAET,YAAY,QAAqD;AAE/D,SAAK,WAAW,OAAO,OAAO,QAAQ,YAAY,CAAC,CAAC;AACpD,SAAK,SAAS,OAAO,OAAO,QAAQ,UAAU,CAAC,CAAC;AAChD,WAAO,OAAO,IAAI;AAAA,EACpB;AAAA,EAEA,IAAI,QAAqD;AACvD,WAAO,IAAI,WAAU;AAAA,MACnB,UAAU,KAAK,SAAS,OAAO,QAAQ,YAAY,CAAC,CAAC;AAAA,MACrD,QAAQ,KAAK,OAAO,OAAO,QAAQ,UAAU,CAAC,CAAC;AAAA,IACjD,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM;AACJ,QAAI,KAAK,OAAO,SAAS,GAAG;AAC1B,cAAQ,MAAM,aAAM,KAAK,OAAO,CAAC,CAAC,EAAE;AAAA,IACtC,WAAW,KAAK,SAAS,SAAS,GAAG;AACnC,cAAQ,KAAK,gBAAM,KAAK,SAAS,CAAC,CAAC,EAAE;AAAA,IACvC,OAAO;AACL,cAAQ,KAAK,sBAAe;AAAA,IAC9B;AAAA,EACF;AACF;AAOO,SAAS,wBAAwB,GAA0B;AAChE,MAAI;AACF,UAAM,MAAM,IAAI,WAAW,CAAC;AAC5B,UAAM,WAAW,CAAC;AAClB,QAAI,IAAI,SAAS,MAAM,GAAG;AAExB,eAAS,KAAK,uBAAuB;AAAA,IACvC;AACA,WAAO;AAAA,MACL;AAAA,MACA,QAAQ,IAAI,UAAU,EAAE,SAAS,CAAC;AAAA,IACpC;AAAA,EACF,SAAS,GAAG;AACV,WAAO;AAAA,MACL,KAAK,IAAI,IAAI;AAAA,MACb,QAAQ,IAAI,UAAU;AAAA,QACpB,QAAQ,CAAC,kBAAmB,EAAY,SAAS,CAAC,EAAE;AAAA,MACtD,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEA,SAAS,oBAAoB,IAAmB,IAA4B;AAC1E,SACE,GAAG,IAAI,YAAY,GAAG,GAAG,KACzB,YAAY,GAAG,OAAO,UAAU,GAAG,OAAO,QAAQ,KAClD,YAAY,GAAG,OAAO,QAAQ,GAAG,OAAO,MAAM;AAElD;AAEO,IAAM,UAAN,cAAsB,iBAA8C;AAAA,EAChE,kBAAiC;AACxC,WAAO,EAAE,KAAK,IAAI,IAAI,GAAG,QAAQ,IAAI,UAAU,EAAE;AAAA,EACnD;AAAA,EAEmB,cAAc,IAAmB,IAAmB;AACrE,WAAO,oBAAoB,IAAI,EAAE;AAAA,EACnC;AAAA,EAEA,MAAyB,OACvB,QACwB;AACxB,QAAI,OAAO,WAAW,UAAU;AAC9B,aAAO,wBAAwB,MAAM;AAAA,IACvC,OAAO;AACL,aAAO;AAAA,QACL,KAAK;AAAA,QACL,QAAQ,IAAI,UAAU;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AACF;;;ACnFO,IAAM,wBAAN,cAAoC,kBAGzC;AAAA,EACA,OAAO,OAAqD;AAC1D,WAAO,MAAM,QAAQ,oBAAoB,MAAM,SAAS,GAAG;AAAA,EAC7D;AACF;;;ACDO,IAAM,2BAAN,cAAuC,kBAG5C;AAAA,EACA,OAAO,QAAyD;AAC9D,QAAI,OAAO,qBAAqB;AAC9B,aAAO,OAAO;AAAA,IAChB;AACA,YAAQ,OAAO,aAAa;AAAA,MAC1B,KAAK;AACH,eAAO,OAAO;AAAA,MAChB,KAAK,OAAO;AACV,cAAM,oBAAoB,OAAO,QAAQ;AAAA,UACvC,OAAO,QAAQ,kBAAkB;AAAA,QACnC;AACA,cAAM,2BAA2B,kBAAkB,OAAO;AAC1D,eAAO,OAAO,uBAAuB;AAAA,UACnC;AAAA,QACF;AAAA,MACF;AAAA,MACA;AACE,cAAM,IAAI,MAAM,gBAAgB;AAAA,IACpC;AAAA,EACF;AACF;;;AC3BO,IAAM,qCAAN,cAAiD,uBAEtD;AAAA,EACA,kBAAkD;AAChD,WAAO;AAAA,EACT;AACF;;;ACVO,IAAM,kBAAN,cAA8B,uBAAoC;AAAA,EAC9D,kBAA+B;AACtC,WAAO,EAAE,MAAM,MAAM,QAAQ,EAAE;AAAA,EACjC;AAAA,EAEmB,cAAc,IAAiB,IAAiB;AACjE,WAAO,GAAG,SAAS,GAAG,QAAQ,GAAG,WAAW,GAAG;AAAA,EACjD;AACF;;;ACGO,IAAM,8BAAN,cAA0C,kBAG/C;AAAA,EACmB,OACjB,QACyB;AACzB,WAAO;AAAA,MACL,cAAc,OAAO,gBAAgB;AAAA,MACrC,gBAAgB,OAAO,gBAAgB,eAAe;AAAA,QACpD,CAAC,oBAAoB,gBAAgB;AAAA,MACvC;AAAA,MACA,eAAe,OAAO,gBAAgB,cAAc;AAAA,QAClD,CAAC,oBAAoB,gBAAgB;AAAA,MACvC;AAAA,IACF;AAAA,EACF;AAAA,EAEmB,cACjB,IACA,IACS;AACT,WACE,GAAG,iBAAiB,GAAG,gBACvB;AAAA,MACE,GAAG;AAAA,MACH,GAAG;AAAA,MACH,CAAC,IAAU,OAAa,GAAG,YAAY,EAAE;AAAA,IAC3C,KACA;AAAA,MACE,GAAG;AAAA,MACH,GAAG;AAAA,MACH,CAAC,IAAU,OAAa,GAAG,YAAY,EAAE;AAAA,IAC3C;AAAA,EAEJ;AACF;;;AClCO,IAAM,sBAAN,cAAkC,kBAGvC;AAAA,EACA,OAAO,QAA6C;AAClD,aAAS,eAAe,iBAAmD;AACzE,UACE,OAAO,qBAAqB,SAC5B,OAAO,YAAY,SAAS,MAC5B;AACA,wBAAgB,aAAa,KAAK;AAAA,UAChC,MAAM,OAAO,YAAY;AAAA,UACzB;AAAA,UACA,UAAU,IAAI,OAAO,YAAY;AAAA,UACjC,gBAAgB;AAAA;AAAA,UAChB,cAAc;AAAA;AAAA,QAChB,CAAC;AAAA,MACH;AACA,aAAO;AAAA,IACT;AAGA,QAAI,OAAO,QAAQ,iBAAiB;AAClC,aAAO;AAAA,QACL,OAAO,QAAQ,gBAAgB,OAAO,qBAAqB,SAAS;AAAA,MACtE;AAAA,IACF,OAAO;AACL,YAAM,MAAM,OAAO,QAAQ;AAAA,QACzB,OAAO,qBAAqB;AAAA,MAC9B;AACA,YAAM,kBAAmC;AAAA,QACvC,cAAc;AAAA,QACd,cAAc,CAAC;AAAA,QACf,gBAAgB,CAAC;AAAA,QACjB,eAAe,CAAC;AAAA,QAChB,eAAe,CAAC;AAAA,QAChB,aAAa;AAAA,QACb,aAAa;AAAA,MACf;AAEA,UAAI,OAAO,QAAQ,kBAAkB,IAAI,GAAG;AAC1C,cAAM,OAAO,OAAO,QAAQ,YAAY,GAAG,GAAG,GAAG,IAAI;AACrD,YAAI,CAAC,MAAM;AACT,iBAAO,eAAe,eAAe;AAAA,QACvC;AACA,cAAM,QAAQ,OAAO,QAAQ,0BAA0B,GAAG;AAC1D,cAAM,WAAW,OAAO,QAAQ,aAAa,GAAG;AAChD,cAAM,WAAW,YACZ,OAAO,qBAAqB,YAAY,SAAS,WAClD;AACJ,cAAM,MAAO,QAAQ;AACrB,cAAM,cAA2B;AAAA,UAC/B;AAAA,UACA;AAAA,UACA;AAAA,UACA,gBAAgB;AAAA,UAChB,cAAc;AAAA,QAChB;AACA,YAAI,aAAa,GAAG;AAClB,0BAAgB,cAAc,KAAK,WAAW;AAAA,QAOhD,WAAW,aAAa,GAAG;AACzB,0BAAgB,eAAe,KAAK,WAAW;AAAA,QAOjD,OAAO;AAEL,0BAAgB,aAAa,KAAK,WAAW;AAC7C,0BAAgB,cAAc,KAAK;AAAA,YACjC,gBAAgB;AAAA,YAChB;AAAA,UACF;AACA,0BAAgB,cAAc,KAAK;AAAA,YACjC,gBAAgB;AAAA,YAChB;AAAA,UACF;AAAA,QACF;AAAA,MAGF;AACA,aAAO,eAAe,eAAe;AAAA,IACvC;AAAA,EACF;AACF;;;ACpGO,IAAM,qBAAN,cAAiC,kBAGtC;AAAA,EACA,OAAO,QAAmD;AACxD,QAAI,iBAAkC,OAAO,QAAQ;AAAA,MACnD,OAAO,wBAAwB;AAAA,IACjC;AACA,qBAAiB,OAAO,cAAc,oBAAoB,cAAc;AAGxE,eAAW,iBAAiB,OAAO,wBAAwB,gBAAgB;AACzE,uBAAiB,eAAe,UAAU,aAAa;AAAA,IACzD;AACA,eAAW,gBAAgB,OAAO,wBAAwB,eAAe;AACvE,uBAAiB,eAAe,UAAU,YAAY;AAAA,IACxD;AACA,WAAO,eAAe,WAAW;AAAA,EACnC;AACF;;;ACNA,IAAM,aAA8C;AAAA,EAClD,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AAEA,SAAS,WAAW,OAAa,OAAsB;AACrD,SACE,WAAW,MAAM,OAAO,CAAC,EAAE,YAAY,CAAC,MACxC,WAAW,MAAM,OAAO,CAAC,EAAE,YAAY,CAAC;AAE5C;AAIO,IAAM,kBAAN,cAA8B,YAAwC;AAAA,EACpE,YAAY,KAAsC;AACvD,UAAM,YAA0C,CAAC;AACjD,eAAW,gBAAgB,IAAI,cAAc,GAAG;AAC9C,gBAAU,KAAK,KAAK,gBAAgB,YAAY,CAAC;AAAA,IACnD;AACA,WAAO,MAAM,UAAU,OAAO,GAAG,SAAS;AAAA,EAC5C;AAAA,EAEO,qBAAqB,KAAsC;AAChE,QAAI,IAAI,oBAAoB,GAAG;AAC7B,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,QAAgB,CAAC;AACvB,eAAW,WAAW,IAAI,cAAc,GAAG;AACzC,UACE,EAAE,QAAQ,GAAG,IAAI,KAAK,QAAQ,GAAG,WAAW,KAAK,QAAQ,GAAG,OAAO,IACnE;AAEA,eAAO,KAAK,YAAY,GAAG;AAAA,MAC7B;AACA,YAAM,SAAS,QAAQ,GAAG,IAAI;AAC9B,UAAI,QAAQ;AACV,cAAM,KAAK,MAAM;AAAA,MACnB;AAAA,IACF;AAEA,QAAI,cAAc,yBAAyB,MAAM,CAAC,EAAE,MAAM;AAC1D,aAAS,IAAI,GAAG,IAAI,MAAM,SAAS,GAAG,KAAK;AACzC,eAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,YAAI,CAAC,WAAW,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG;AACnC,iBAAO,KAAK,YAAY,GAAG;AAAA,QAC7B;AAAA,MACF;AACA,oBAAc,KAAK;AAAA,QACjB;AAAA,QACA,yBAAyB,MAAM,CAAC,EAAE,MAAM;AAAA,MAC1C;AAAA,IACF;AAEA,UAAM,sBAAkD,MAAM;AAAA,MAC5D,CAAC,cAAwC;AACvC,eAAO;AAAA,UACL,iBAAiB;AAAA,UACjB,aAAa;AAAA,UACb,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AACA,wBAAoB,oBAAoB,SAAS,CAAC,EAAE,cAClD;AACF,WAAO;AAAA,EACT;AAAA,EAEO,iBAAiB,UAAgD;AACtE,UAAM,YAA0C,CAAC;AAEjD,UAAM,cACJ,SAAS,SAAS,IAAI,SAAS,MAAM,SAAS,IAAI,OAAO;AAC3D,aAAS,IAAI,GAAG,IAAI,KAAK,IAAI,SAAS,MAAM,GAAG,KAAK;AAClD,gBAAU,KAAK,KAAK,qBAAqB,WAAW,CAAC;AAAA,IACvD;AACA,WAAO,MAAM,UAAU,OAAO,GAAG,SAAS;AAAA,EAC5C;AAAA,EAEO,aAAa,MAAwC;AAC1D,UAAM,WAAW,yBAAyB,KAAK,MAAM;AACrD,WAAO;AAAA,MACL;AAAA,QACE,iBAAiB;AAAA,QACjB,aAAa;AAAA,QACb;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEO,mBACL,YAC4B;AAC5B,UAAM,YAA0C,CAAC;AACjD,UAAM,eAAsB;AAAA,MAC1B,WAAW;AAAA,MACX,WAAW;AAAA,MACX,WAAW,EAAE,OAAO;AAAA,MACpB,WAAW,EAAE,OAAO;AAAA,IACtB;AACA,eAAW,WAAW,cAAc;AAClC,gBAAU,KAAK,KAAK,qBAAqB,OAAO,CAAC;AAAA,IACnD;AACA,WAAO,MAAM,UAAU,OAAO,GAAG,SAAS;AAAA,EAC5C;AAAA,EAEO,kBAAkB,WAAkD;AACzE,UAAM,YAA0C,CAAC;AACjD,UAAM,eAAsB;AAAA,MAC1B,UAAU;AAAA,MACV,UAAU;AAAA,MACV,UAAU,EAAE,OAAO;AAAA,IACrB;AACA,eAAW,WAAW,cAAc;AAClC,gBAAU,KAAK,KAAK,qBAAqB,OAAO,CAAC;AAAA,IACnD;AACA,WAAO,MAAM,UAAU,OAAO,GAAG,SAAS;AAAA,EAC5C;AAAA,EAEO,cAAc,OAA0C;AAC7D,QAAI,MAAM,0BAA0B;AAClC,aAAO,CAAC;AAAA,IACV;AACA,UAAM,WAAW,yBAAyB,CAAC;AAC3C,WAAO;AAAA,MACL;AAAA,QACE,iBAAiB;AAAA,QACjB,aAAa;AAAA;AAAA,QACb;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEO,gBAAgB,UAA+C;AACpE,WAAO,CAAC;AAAA,EACV;AAAA,EAEO,oBACL,UAC4B;AAC5B,WAAO,CAAC;AAAA,EACV;AACF;AAEA,IAAM,kBAAkB,sBAAsB,eAAe;AAEtD,SAAS,WAAW,GAAiC;AAC1D,MAAI,YAAY;AAChB,QAAM,IAAI,gBAAgB,CAAC,EAAE;AAAA,IAC3B,CAAC,mBAAoE;AACnE,YAAM,gBAAgB;AAAA,QACpB,UAAU,eAAe;AAAA,QACzB,OAAO;AAAA,QACP,KAAM,YAAY,eAAe;AAAA,MACnC;AACA,mBAAa,eAAe;AAC5B,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;;;AChLO,IAAM,0BAAN,MAA8B;AAAA;AAAA,EAInC,YACU,SACR,KACA,SACA;AAHQ;AAIR,SAAK,aAAa,SAAS,2BAA2B,WAAW,GAAG;AAAA,EAEtE;AAAA,EAVQ;AAAA,EAYD,YAAY,OAA2C;AAC5D,WACE,KAAK,WAAW,KAAK,IAAI,OAAO,KAAK,WAAW,SAAS,CAAC,CAAC,GAAG,YAC9D;AAAA,EAEJ;AAAA,EAEQ,yBAAyB,OAAsC;AACrE,WAAO,KAAK,WAAW,KAAK,IAAI,OAAO,KAAK,WAAW,SAAS,CAAC,CAAC;AAAA,EACpE;AAAA,EAEO,0BAA0B,OAAqC;AACpE,QAAI,QAAQ;AACZ,QAAI,KAAK,WAAW,SAAS,GAAG;AAC9B,cACE,KAAK,WAAW,KAAK,IAAI,OAAO,KAAK,WAAW,SAAS,CAAC,CAAC,EAAE;AAAA,IACjE;AACA,WAAO;AAAA,EACT;AAAA,EAEO,iBAAiB,WAA4C;AAClE,QAAI,IAAI;AACR,SAAK,IAAI,GAAG,IAAI,KAAK,WAAW,QAAQ,KAAK;AAC3C,UAAI,KAAK,WAAW,CAAC,EAAE,SAAS,WAAW;AACzC,eAAO,KAAK,IAAI,GAAG,IAAI,CAAC;AAAA,MAC1B;AAAA,IACF;AACA,WAAO,KAAK,IAAI,GAAG,IAAI,CAAC;AAAA,EAC1B;AAAA,EAEO,oBACL,WACA,cACgB;AAChB,UAAM,kBAAkB,KAAK,gBAAgB,SAAS;AAEtD,QAAI,UACF,gBAAgB,KAAK,QAAQ,uBAAuB,EAAE,WAAW;AACnE,eAAW,iBAAiB,KAAK,WAAW;AAAA,MAC1C;AAAA,MACA,gBAAgB;AAAA,IAClB,GAAG;AACD,YAAM,OAAO,cAAc,SAAS,GAAG,IAAI;AAC3C,UAAI,SAAS,MAAM;AACjB,kBAAU,QAAQ,UAAU,IAAI;AAAA,MAClC;AAAA,IACF;AAEA,WAAO;AAAA,MACL;AAAA,MACA,iBAAiB,gBAAgB;AAAA,IACnC;AAAA,EACF;AAAA;AAAA,EAGO,gBAAgB,WAAkD;AAEvE,QAAI,0BAA0B;AAC9B,eAAW,iBAAiB,KAAK,YAAY;AAC3C,UAAI,cAAc,SAAS,aAAa,cAAc,OAAO,WAAW;AACtE,kCAA0B,KAAK;AAAA,UAC7B;AAAA,UACA,cAAc;AAAA,QAChB;AAAA,MACF,WAAW,cAAc,QAAQ,WAAW;AAC1C;AAAA,MACF;AAAA,IACF;AAEA,UAAM,eAA8B,CAAC;AACrC,UAAM,gBAA+B,CAAC;AACtC,UAAM,iBAAgC,CAAC;AACvC,UAAM,gBAA+B,CAAC;AACtC,QAAI,cAAsB;AAC1B,QAAI,cAAsB;AAE1B,QAAI,eAAuB;AAC3B,eAAW,iBAAiB,KAAK,YAAY;AAC3C,UAAI,cAAc,OAAO,yBAAyB;AAChD;AAAA;AAAA,UAEE,CAAC,SAAS,uBAAuB,KACjC,cAAc,QAAQ;AAAA,UACtB;AAEA;AAAA,QACF;AACA;AAAA,MACF,WAAW,cAAc,QAAQ,WAAW;AAC1C;AAAA,MACF,OAAO;AACL,cAAM,OAAO,cAAc,SAAS,GAAG,IAAI;AAC3C,YAAI,SAAS,MAAM;AACjB,cAAI,YACD,YAAY,cAAc,UAC1B,cAAc,MAAM,cAAc;AACrC,cAAI,eAAe;AACnB,cAAI,WAAW,GAAG;AAChB,uBAAW;AACX,2BAAe;AAAA,UACjB;AACA,gBAAM,cAAc;AAAA,YAClB;AAAA,YACA;AAAA,YACA;AAAA,YACA,gBAAgB,cAAc;AAAA,YAC9B,cAAc,cAAc;AAAA,UAC9B;AACA,kBAAQ,UAAU;AAAA,YAChB,KAAK,GAAG;AACN,4BAAc,KAAK,WAAW;AAC9B;AAAA,YACF;AAAA,YACA,KAAK,GAAG;AAEN,kBAAI,cAAc;AAChB,8BAAc,KAAK,WAAW;AAAA,cAChC,OAAO;AACL,+BAAe,KAAK,WAAW;AAAA,cACjC;AACA;AAAA,YACF;AAAA,YACA;AACE,2BAAa,KAAK,WAAW;AAC7B,4BAAc,KAAK,IAAI,aAAa,cAAc,KAAK;AACvD,4BAAc,KAAK,IAAI,aAAa,cAAc,GAAG;AAAA,UACzD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEO,eAAe,OAAe,cAAmC;AACtE,QAAI,UAAU,gBAAgB,KAAK,QAAQ,eAAe;AAC1D,aAAS,IAAI,GAAG,IAAI,KAAK,WAAW,UAAU,IAAI,OAAO,KAAK;AAC5D,YAAM,gBAAgB,KAAK,WAAW,CAAC;AACvC,YAAM,OAAO,cAAc,SAAS,GAAG,IAAI;AAC3C,UAAI,SAAS,MAAM;AACjB,kBAAU,QAAQ,UAAU,IAAI;AAAA,MAClC;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEO,sBAAsB,OAAgC;AAC3D,QAAI,iBAAiB,KAAK,QAAQ,uBAAuB;AACzD,eAAW,iBAAiB,KAAK,WAAW,MAAM,GAAG,KAAK,GAAG;AAC3D,YAAM,OAAO,cAAc,SAAS,GAAG,IAAI;AAC3C,UAAI,SAAS,MAAM;AACjB,yBAAiB,eAAe,UAAU,IAAI;AAAA,MAChD;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEO,cAAmC;AACxC,QAAI,MAAM;AACV,eAAW,iBAAiB,KAAK,YAAY;AAC3C,YAAM,KAAK,IAAI,KAAK,cAAc,GAAG;AAAA,IACvC;AACA,WAAO;AAAA,EACT;AAAA,EAEO,oBAA+B;AAEpC,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEO,aAAa,OAAuC;AACzD,UAAM,OAAO,KAAK,yBAAyB,KAAK;AAChD,WAAQ,KAAK,MAAM,KAAK;AAAA,EAC1B;AACF;;;ACxLA,IAAM,2CAA2C;AAG1C,IAAM,yBAAN,cAAqC,kBAG1C;AAAA,EACA,OAAO,QAA0D;AAC/D,YAAQ,OAAO,2BAA2B;AAAA,MACxC,KAAK;AACH,YAAI,OAAO,4BAA4B,MAAM;AAC3C,iBAAO;AAAA,QACT;AACA,YACE,iDAAiD,OAAO,IAAI,GAAG,KAC7D,4CACF,OAAO,WAAW,WAClB,OAAO,0BAA0B,UACjC;AACA,iBAAO;AAAA,QACT,OAAO;AACL,iBAAO;AAAA,QACT;AAAA,MACF,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT;AACE,cAAM,IAAI,MAAM,0BAA0B;AAAA,IAC9C;AAAA,EACF;AACF;;;ACtDO,IAAM,gCAAN,cAA4C,uBAA4C;AAAA,EAC7F,kBAAuC;AACrC,WAAO;AAAA,EACT;AACF;;;ACDO,IAAM,cAAN,cAA0B,kBAG/B;AAAA,EACA,OAAO,OAAsC;AAC3C,WAAO,IAAI,MAAM;AAAA,MACf,MAAM;AAAA,MACN,MAAM,cAAc;AAAA,MACpB,EAAE,yBAAyB,MAAM,wBAAwB;AAAA,IAC3D;AAAA,EACF;AACF;;;ACbO,IAAM,qBAAN,cAAiC,kBAGtC;AAAA,EACA,OAAO,QAAkD;AACvD,WAAO;AAAA,MACL,SAAS,OAAO;AAAA,MAChB,iBAAiB,OAAO,gBAAgB;AAAA,IAC1C;AAAA,EACF;AACF;;;AChBA,IAAI,WAAoB;AAKjB,IAAM,gBAAN,cAA4B,kBAGjC;AAAA,EACA,MAAM,OAAO,QAGc;AACzB,QAAI;AACF,UAAI,UAAU;AACZ,eAAO,QAAQ,oBAAoB,OAAO,cAAc,GAAG;AAAA,MAC7D;AAGA,aAAO,OAAO;AAAA,IAChB,SAAS,GAAG;AACV,aAAO;AAAA,QACL,KAAK,IAAI,IAAI;AAAA,QACb,QAAQ,IAAI,UAAU;AAAA,UACpB,QAAQ,CAAC,2BAA4B,EAAY,SAAS,CAAC,EAAE;AAAA,QAC/D,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;;;ACzBO,IAAM,kBAAN,cAA8B,uBAAwC;AAAA,EAC3E,kBAAmC;AACjC,WAAO;AAAA,EACT;AACF;;;ACVO,IAAM,0BAAN,cAAsC,uBAA+C;AAAA,EAC1F,kBAA0C;AACxC,WAAO;AAAA,EACT;AACF;;;ACHO,IAAM,cAAN,cAA0B,kBAG/B;AAAA,EACA,MAAM,OAAO,QAA0D;AACrE,WAAO,OAAO,aAAa,QAAQ;AAAA,EACrC;AACF;;;ACJO,IAAM,gCAAN,cAA4C,uBAEjD;AAAA,EACA,kBAAyD;AACvD,WAAO;AAAA,EACT;AACF;;;ACTO,IAAM,eAAN,cAA2B,kBAGhC;AAAA,EACA,MAAM,OAAO,QAA2D;AACtE,WAAO,OAAO,aAAa;AAAA,EAC7B;AACF;;;ACwBO,IAAM,sBAAN,cAAkC,uBAEvC;AAAA,EACA,kBAA0C;AACxC,WAAO;AAAA,EACT;AACF;;;ACzBO,IAAM,mBAAN,cAA+B,kBAGpC;AAAA,EACA,OAAO,QAA8C;AACnD,QAAI,OAAO,mBAAmB,OAAO,oBAAoB,UAAU;AACjE,YAAM,eAAe,QAAQ,OAAO,eAAe;AACnD,UAAI,CAAC,cAAc;AACjB,aAAK,wBAAyB,IAAI;AAAA,UAChC,QAAQ,CAAC,sBAAsB,OAAO,eAAe,EAAE;AAAA,QACzD,CAAC;AAAA,MACH;AACA,aAAO;AAAA,IACT;AACA,QACE,OAAO,4BACP,OAAO,6BAA6B,UACpC;AACA,aAAO,qBAAiC,OAAO,wBAAwB;AAAA,IACzE;AACA,WAAO;AAAA,EACT;AACF;;;ACbO,IAAM,yBAAN,cAAqC,kBAG1C;AAAA,EACmB,OACjB,QACoB;AACpB,WAAO;AAAA,MACL,SAAS,OAAO,YAAY;AAAA,MAC5B,SAAS,OAAO,qBAAqB;AAAA,MACrC,OAAO,OAAO,qBAAqB;AAAA,IACrC;AAAA,EACF;AAAA,EAEmB,cACjB,IACA,IACS;AACT,WACE,GAAG,YAAY,GAAG,WAClB,GAAG,YAAY,GAAG,WAClB,GAAG,UAAU,GAAG;AAAA,EAEpB;AACF;;;ACxBO,IAAM,2BAAN,cAAuC,kBAG5C;AAAA,EACmB,OACjB,QACsB;AACtB,QAAI,YAAY,KAAK,kCAAkC,MAAM;AAC7D,QAAI,UAAmB;AACvB,QAAI,QAAiB;AACrB,QAAI,aAAa,OAAO,UAAU,KAAK;AACrC,cAAQ;AACR,kBAAY,KAAK;AAAA,QACf,OAAO,UAAU;AAAA,QACjB;AAAA,MACF;AAAA,IACF;AACA,QAAI,aAAa,OAAO,UAAU,OAAO;AACvC,gBAAU;AACV,kBAAY,KAAK;AAAA,QACf,OAAO,UAAU;AAAA,QACjB;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,MACL;AAAA,MACA,WAAW,OAAO;AAAA,MAClB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,kCACE,QACsB;AACtB,YAAQ,OAAO,kBAAkB;AAAA,MAC/B,KAAK;AACH,eAAO,OAAO,gBAAgB,WAC5B,OAAO,SAAS,IAAI,oBAAoB,IACtC,OAAO,UAAU,MACjB,OAAO,UAAU;AAAA,MACvB,KAAK;AACH,eAAO,OAAO,UAAU;AAAA,MAC1B,KAAK;AACH,eAAO,OAAO,UAAU;AAAA,MAC1B,KAAK;AACH,eAAO,OAAO,gBAAgB,UAC1B,OAAO,UAAU,QACjB,OAAO,UAAU;AAAA,MACvB,KAAK;AACH,eAAO,OAAO,gBAAgB,UAC1B,OAAO,UAAU,MACjB,OAAO,UAAU;AAAA,MACvB;AACE,eAAO,OAAO;AAAA,IAClB;AAAA,EACF;AAAA,EAEmB,cACjB,IACA,IACA;AACA,WACE,GAAG,cAAc,GAAG,aACpB,GAAG,UAAU,UAAU,GAAG,UAAU,SACpC,GAAG,UAAU,QAAQ,GAAG,UAAU,OAClC,GAAG,YAAY,GAAG,WAClB,GAAG,UAAU,GAAG;AAAA,EAEpB;AACF;;;AChFO,IAAM,kBAAN,cAA8B,iBAGnC;AAAA,EACA,MAAsB,kBAAwC;AAC5D,WAAO;AAAA,MACL;AAAA,MACA,SAAS;AAAA,MACT;AAAA,MACA,MAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAyB,OACvB,SACA,iBACsB;AACtB,UAAM,WAAW,MAAM;AAEvB,UAAM,WAAwB,OAAO,OAAO,CAAC,GAAG,QAAQ;AACxD,WAAO,OAAO,UAAU,OAAO;AAC/B,WAAO;AAAA,EACT;AAAA,EAEmB,cAAc,IAAiB,IAAiB;AACjE,WACE,GAAG,cAAc,GAAG,aACpB,GAAG,YAAY,GAAG,WAClB,GAAG,kBAAkB,GAAG,iBACxB,GAAG,SAAS,GAAG;AAAA,EAEnB;AACF;;;AC3CO,IAAM,iBAAN,cAA6B,iBAAiC;AAAA,EACnE,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,GAAmB;AACxB,WAAO,IAAI,IAAI,IAAI;AAAA,EACrB;AACF;;;ACTA,IAAM,kBAAkB;AAAA,EACtB,MAAM;AAAA,EACN,OAAO;AAAA,EACP,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,mBAAmB;AACrB;AAMO,IAAM,uBAAN,cAAmC,uBAAyC;AAAA,EACxE,kBAAoC;AAC3C,WAAO;AAAA,EACT;AAAA,EAEgB,IAAI,GAAqC;AACvD,UAAM,eAAe,KAAK,IAAI;AAC9B,UAAM;AAAA,OACH,YAAY;AACX,YAAI,CAAC,KAAK,WAAW,MAAM,CAAC,GAAG;AAE7B,iBAAO;AAAA,QACT;AACA,eAAO;AAAA,MACT,GAAG;AAAA,IACL;AAAA,EACF;AAAA,EAEU,WAAW,GAA8B;AACjD,QAAI,OAAO,MAAM,UAAU;AACzB,aAAO;AAAA,IACT;AACA,QAAI,gBAAgB,CAAC,GAAG;AACtB,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AACF;;;ACnCO,IAAM,gBAAN,cAA4B,kBAGjC;AAAA,EACA,OAAO,QAA4C;AACjD,WAAO;AAAA,MACL,OAAO;AAAA,MACP,KAAK,OAAO,QAAQ,YAAY;AAAA,IAClC;AAAA,EACF;AACF;;;ACPO,IAAM,iBAAN,cAA6B,uBAA+C;AAAA,EACjF,kBAA0C;AACxC,WAAO;AAAA,EACT;AACF;;;ACDO,IAAM,0BAAN,cAAsC,uBAAoD;AAAA,EAC/F,kBAA+C;AAC7C,WAAO;AAAA,EACT;AACF;;;ACDO,IAAM,4BAAN,cAAwC,kBAG7C;AAAA,EACA,OAAO,QAAgE;AAErE,YAAQ,OAAO,UAAU;AAAA,MACvB,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,gBAAQ,OAAO,sBAAsB;AAAA,UACnC,KAAK;AAAA,UACL,KAAK;AACH,mBAAO;AAAA,UACT;AACE,mBAAO,OAAO;AAAA,QAClB;AAAA,MACF;AACE,gBAAQ,OAAO,sBAAsB;AAAA,UACnC,KAAK;AAAA,UACL,KAAK;AACH,mBAAO;AAAA,UACT,KAAK;AAAA,UACL,KAAK;AACH,gBAAI,CAAC,SAAS,SAAS,UAAU,EAAE,SAAS,OAAO,QAAQ,GAAG;AAE5D,qBAAO;AAAA,YACT,OAAO;AACL,qBAAO;AAAA,YACT;AAAA,UACF;AACE,mBAAO,OAAO;AAAA,QAClB;AAAA,IACJ;AAAA,EACF;AACF;;;ACrDO,IAAM,mBAAN,cAA+B,uBAAqC;AAAA,EACzE,kBAAgC;AAC9B,WAAO;AAAA,EACT;AACF;;;ACHO,IAAM,wBAAN,cAAoC,uBAA0C;AAAA,EACnF,kBAAqC;AACnC,WAAO;AAAA,EACT;AACF;;;ACJO,IAAM,mCAAN,cAA+C,uBAAqD;AAAA,EACzG,kBAAgD;AAC9C,WAAO;AAAA,EACT;AACF;;;ACJA,IAAI,eAAqC;AACzC,eAAe,SAAiC;AAC9C,SAAQ,iBAAiB,KAAK,MAAM,WAAW,GAAG,mBAAmB;AACvE;AAOO,IAAM,aAAN,cAAyB,kBAG9B;AAAA,EACA,MAAM,OAAO,QAAmD;AAC9D,UAAM,EAAE,WAAW,WAAW,IAAI;AAClC,QAAI,eAAe,MAAM;AACvB,aAAO;AAAA,IACT;AAEA,WAAO,IAAI,QAAQ,OAAO,SAAS,YAAY;AAC7C,YAAM,iBAAiB,MAAY;AACjC,gBAAQ,KAAK,0BAA0B,WAAW,SAAS,CAAC;AAC5D,gBAAQ,IAAI;AAAA,MACd;AAEA,UAAI;AACF,SAAC,MAAM,OAAO,GAAG;AAAA,UACf,WAAW,SAAS;AAAA,UACpB;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF,QAAQ;AACN,uBAAe;AAAA,MACjB;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AC5BA,IAAM,IAAqC;AAAA,EACzC,UAAU,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAClE;AAEA,eAAe,mBACb,cACqC;AACrC,QAAM,EAAE,WAAW,IAAI,MAAM,aAAa,QAAQ;AAClD,QAAMC,sBAAiD,EAAE,QAAQ,CAAC,EAAE;AACpE,aAAW,mBAAmB,WAAW,QAAQ;AAC/C,IAAAA,oBAAmB,OAAO,gBAAgB,SAAS,IAAI;AAAA,MACrD,QAAQ,IAAI,MAAM,gBAAgB,SAAS,EAAE,KAAK,CAAC;AAAA,IACrD;AAAA,EACF;AACA,SAAOA;AACT;AAEO,IAAM,qBAAN,cAAiC,kBAGtC;AAAA,EACA,kBAA8C;AAC5C,WAAO,EAAE,QAAQ,CAAC,EAAE;AAAA,EACtB;AAAA,EAEA,MAAM,OACJ,QACqC;AACrC,QAAI,OAAO,uBAAuB;AAChC,aAAO,OAAO;AAAA,IAChB;AACA,QAAI,OAAO,sBAAsB,WAAW;AAC1C,aAAO;AAAA,QACL,kBAAkB;AAAA,QAClB,QAAQ,CAAC;AAAA,MACX;AAAA,IACF;AACA,WACE,OAAO,aAAa;AAAA,MAClB,OAAO,qBAAqB;AAAA,IAC9B,KAAK,mBAAmB,OAAO,YAAY;AAAA,EAE/C;AAAA;AAEF;;;AC7CA,IAAM,UAAuD;AAAA,EAC3D;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AACF;AAEO,SAAS,8BACd,0BAC4B;AAC5B,QAAM,iBAA6C;AAAA,IACjD,QAAQ,CAAC;AAAA,EACX;AACA,QAAM,mBAAmB,yBAAyB,MAAM,GAAG;AAC3D,aAAW,mBAAmB,kBAAkB;AAC9C,UAAM,CAAC,WAAW,uBAAuB,GAAG,IAAI,IAC9C,gBAAgB,MAAM,GAAG;AAC3B,QAAI,KAAK,SAAS,GAAG;AACnB,YAAM,IAAI;AAAA,QACR,iEAAiE,eAAe;AAAA,MAClF;AAAA,IACF;AACA,UAAM,SAA4C,CAAC;AACnD,mBAAe,OAAO,SAAS,IAAI,EAAE,OAAO;AAC5C,eAAW,QAAQ,uBAAuB;AACxC,YAAM,kBAAkB,QAAQ,IAAI;AACpC,aAAO,KAAK,uBAAmC,eAAe,CAAC;AAAA,IACjE;AAAA,EACF;AACA,SAAO;AACT;;;AC9CO,IAAM,4BAAN,cAAwC,iBAG7C;AAAA,EACA,kBAAqD;AACnD,WAAO;AAAA,EACT;AAAA,EAEA,OACE,OACmC;AACnC,QAAI,UAAU,MAAM;AAClB,aAAO;AAAA,IACT,WAAW,OAAO,UAAU,UAAU;AACpC,aAAO,8BAA8B,KAAK;AAAA,IAC5C,OAAO;AACL,aAAO;AAAA,IACT;AAAA,EACF;AACF;;;ACHO,IAAM,wBAAN,cAAoC,uBAAsD;AAAA,EAC/F,kBAAiD;AAC/C,WAAO;AAAA,EACT;AACF;;;AChBO,IAAM,gBAAN,cAA4B,uBAAsC;AAAA,EACvE,kBAAiC;AAC/B,WAAO;AAAA,EACT;AACF;;;ACRO,IAAM,yBAAN,cAAqC,uBAA4C;AAAA,EACtF,kBAAuC;AACrC,WAAO,CAAC;AAAA,EACV;AACF;;;ACCO,IAAM,qBAAN,cAAiC,uBAAuC;AAAA,EAC7E,kBAAkC;AAChC,WAAO;AAAA,EACT;AACF;;;ACFO,IAAM,iBAAN,cAA6B,uBAAgD;AAAA,EAClF,kBAA2C;AACzC,WAAO;AAAA,EACT;AACF;;;ACLO,IAAM,kBAAN,cAA8B,kBAGnC;AAAA,EACU,OAAO,QAA4C;AAE3D,WAAO,OAAO,uBAAuB,SAAS,SAAS;AAAA,EACzD;AACF;;;ACTO,IAAM,yBAAN,cAAqC,uBAA4C;AAAA,EACtF,kBAAuC;AACrC,WAAO;AAAA,EACT;AACF;;;ACXO,IAAM,0BAAN,cAAsC,uBAAuC;AAAA,EAClF,kBAAkC;AAChC,WAAO;AAAA,EACT;AACF;;;ACFA,IAAM,yBAAyB;AAExB,IAAM,oBAAN,cAAgC,uBAA0C;AAAA,EAC/E,kBAAqC;AACnC,WAAO;AAAA,EACT;AACF;;;ACCO,SAAS,sBACd,IACA,IACS;AACT,SACE,GAAG,aAAa,GAAG,YACnB,GAAG,cAAc,GAAG,aACpB,GAAG,aAAa,GAAG;AAEvB;AAYO,IAAM,8BAAN,cAA0C,iBAG/C;AAAA,EACS,kBAA2C;AAClD,WAAO;AAAA,EACT;AAAA,EAEmB,cAAc,IAAsB,IAAsB;AAC3E,WAAO,OAAO,MAAM,sBAAsB,IAAI,EAAE;AAAA,EAClD;AAAA,EAEA,MAAyB,OACvB,gBACA,iBACkC;AAClC,QAAI,mBAAmB,QAAQ;AAC7B,aAAO;AAAA,IACT;AAEA,QAAI,WAAW,MAAM;AACrB,QAAI,aAAa,QAAQ;AACvB,iBAAW,CAAC;AAAA,IACd;AAEA,UAAM,WAAsC,OAAO,OAAO,CAAC,GAAG,QAAQ;AACtE,WAAO,OAAO,UAAU,cAAc;AAEtC,QAAI,OAAO,SAAS,aAAa,aAAa;AAC5C,eAAS,WAAW,KAAK,IAAI,KAAK,IAAI,SAAS,UAAU,GAAG,GAAG,EAAE;AAAA,IACnE;AACA,QAAI,OAAO,SAAS,cAAc,aAAa;AAC7C,eAAS,YAAY,aAAa,SAAS,WAAW,KAAK,IAAI;AAAA,IACjE;AACA,WAAO;AAAA,EACT;AACF;;;AClDO,IAAM,uBAAN,cAAmC,kBAGxC;AAAA,EACS,cAAc,IAAsB,IAAsB;AACjE,WAAO,sBAAsB,IAAI,EAAE;AAAA,EACrC;AAAA,EAEA,MAAM,OAAO,QAA+D;AAC1E,QAAI,OAAO,4BAA4B,QAAQ;AAC7C,aAAO,8BAA8B,OAAO,UAAU,OAAO,QAAQ;AAAA,IACvE;AAEA,UAAM,MAAwB,OAAO;AAAA,MACnC,OAAO;AAAA,QACL,CAAC;AAAA,QACD,8BAA8B,OAAO,UAAU,OAAO,QAAQ;AAAA,QAC9D,OAAO;AAAA,MACT;AAAA,IACF;AAEA,QAAI,KAAK,IAAI,IAAI,QAAQ,KAAK,OAAO,eAAe;AAClD,aAAO;AAAA,IACT,OAAO;AACL,YAAM,EAAE,UAAU,WAAW,SAAS,IAAI;AAE1C,aAAO;AAAA,QACL,UAAU,OAAO,gBAAgB,KAAK,KAAK,QAAQ;AAAA,QACnD;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAKO,IAAM,iCAAmD;AAAA,EAC9D,UAAU;AAAA,EACV,WAAW;AAAA,EACX,UAAU;AACZ;AAGO,IAAM,mCAAqD;AAAA,EAChE,UAAU;AAAA,EACV,WAAW;AAAA,EACX,UAAU;AACZ;AAGO,IAAM,iCAAmD;AAAA,EAC9D,UAAU;AAAA,EACV,WAAW;AAAA,EACX,UAAU;AACZ;AAEO,IAAM,iCAAmD;AAAA,EAC9D,UAAU,KAAK,KAAK,IAAI,CAAC,IAAI;AAAA,EAC7B,WAAW;AAAA,EACX,UAAU;AACZ;AAEO,IAAM,iCAAmD;AAAA,EAC9D,UAAU;AAAA,EACV,WAAW;AAAA,EACX,UAAU;AACZ;AASO,SAAS,8BACd,UACA,UACkB;AAClB,MAAI,SAAS,CAAC,MAAM,KAAK;AACvB,QAAI,aAAa,UAAU;AACzB,aAAO;AAAA,IACT,OAAO;AACL,aAAO;AAAA,IACT;AAAA,EACF,OAAO;AACL,YAAQ,UAAU;AAAA,MAChB,KAAK;AAAA,MACL,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT;AACE,eAAO;AAAA,IACX;AAAA,EACF;AACF;;;AClGO,IAAM,mBAAN,MAAuB;AAAA,EAoC5B,YAAmB,mBAAsC;AAAtC;AACjB,SAAK,mBAAmB,IAAI,qBAAqB;AAAA,MAC/C,yBAAyB,KAAK;AAAA,MAC9B,eAAe,KAAK;AAAA,MACpB,UAAU,kBAAkB;AAAA,MAC5B,UAAU,kBAAkB;AAAA,IAC9B,CAAC;AACD,SAAK,iBAAiB,IAAI,mBAAmB;AAAA,MAC3C,uBAAuB,KAAK;AAAA,MAC5B,mBAAmB,KAAK;AAAA,MACxB,cAAc,kBAAkB;AAAA,IAClC,CAAC;AAAA,EACH;AAAA;AAAA,EA9CA,aAAa,IAAI,eAAe;AAAA,EAChC,qBAAqB,IAAI,uBAAuB;AAAA,EAChD,YAAY,IAAI,cAAc;AAAA,EAC9B,oBAAoB,IAAI,sBAAsB;AAAA,EAC9C,6BAA6B,IAAI,QAAQ;AAAA,EACzC,oBAAoB,IAAI,wBAAwB;AAAA,EAChD,cAAc,IAAI,gBAAgB;AAAA,EAClC,uBAAuB,IAAI,QAAQ;AAAA,EACnC,+BAA+B,IAAI,iCAAiC;AAAA,EACpE,gBAAgB,IAAI,kBAAkB;AAAA,EACtC,iBAAiB,IAAI,mBAAmB;AAAA,EACxC,yBAAyB,IAAI,uBAAuB;AAAA,EACpD,0BACE,IAAI,4BAA4B;AAAA;AAAA,EAElC,wBAAwB,IAAI,0BAA0B;AAAA,EACtD,oBAAoB,IAAI,sBAAsB;AAAA,EAC9C,eAAe,IAAI,iBAAiB;AAAA;AAAA,EAGpC,cAAc,IAAI,gBAAgB;AAAA,IAChC,oBAAoB,KAAK;AAAA,EAC3B,CAAC;AAAA,EACD,0BAA0B,IAAI,WAAW;AAAA,IACvC,WAAW,KAAK;AAAA,EAClB,CAAC;AAAA,EACD,oBAAoB,IAAI,WAAW;AAAA,IACjC,WAAW,KAAK;AAAA,EAClB,CAAC;AAAA;AAAA,EAGD;AAAA,EACA;AAeF;;;AC/DA,IAAM,eAAe,EAAE,QAAQ,CAAC,EAAE;AAE3B,IAAM,0BAAN,cAAsC,uBAAyC;AAAA,EAC3E,kBAAoC;AAC3C,WAAO;AAAA,EACT;AAAA,EAEO,QAAQ;AACb,SAAK,IAAI,KAAK,gBAAgB,CAAC;AAAA,EACjC;AAAA,EAEmB,cACjB,KACA,KACS;AACT,WAAO,YAAY,IAAI,QAAQ,IAAI,MAAM;AAAA,EAC3C;AACF;;;ACqBO,IAAM,oBAAN,MAAwB;AAAA;AAAA;AAAA,EAG7B,0BAA0B,IAAI,wBAAwB;AAAA;AAAA;AAAA,EAMtD,MAAM,IAAI,QAAQ;AAAA,EAClB,WAAW,IAAI,aAAa;AAAA,EAC5B,eAAe,IAAI,iBAAiB;AAAA,EACpC,cAAc,IAAI,gBAAgB;AAAA,EAClC,4BAA4B,IAAI,8BAA8B;AAAA,EAC9D,cAAc,IAAI,gBAAgB;AAAA,EAClC,2BAA2B,IAAI,8BAA8B;AAAA,EAC7D,kBAAkB,IAAI,oBAAoB;AAAA,EAC1C,cAAc,IAAI,gBAAgB;AAAA,EAClC,WAAW,IAAI,QAAQ;AAAA,EACvB,sBAAsB,IAAI,wBAAwB;AAAA,EAClD,aAAa,IAAI,eAAe;AAAA,EAChC,mBAAmB,IAAI,qBAAqB;AAAA,EAC5C,aAAa,IAAI,eAAe;AAAA,EAChC,sBAAsB,IAAI,wBAAwB;AAAA;AAAA,EAElD,QAAQ,IAAI,oBAAoB;AAAA,EAChC,WAAW,IAAI,QAAQ;AAAA,EACvB,gBAAgB,IAAI,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkCxC,iCAAiC,IAAI,mCAAmC;AAAA;AAAA,EAIxE,eAAe,IAAI;AAAA,IACjB;AAAA,MACE,iBAAiB,KAAK;AAAA,MACtB,0BAA0B,KAAK;AAAA,IACjC;AAAA,IACA,KAAK;AAAA,EACP;AAAA;AAAA,EAIA,UAAU,IAAI,YAAY,EAAE,cAAc,KAAK,aAAa,CAAC;AAAA,EAE7D,WAAW,IAAI,aAAa,EAAE,cAAc,KAAK,aAAa,CAAC;AAAA;AAAA,EAI/D,YAAY,IAAI,cAAc;AAAA,IAC5B,eAAe,KAAK;AAAA,IACpB,SAAS,KAAK;AAAA,EAChB,CAAC;AAAA,EAED,iBAAiB,IAAI,cAAc;AAAA,IACjC,eAAe,KAAK;AAAA,IACpB,SAAS,KAAK;AAAA,EAChB,CAAC;AAAA,EAED,wBAAwB,IAAI,0BAA0B;AAAA,IACpD,sBAAsB,KAAK;AAAA,IAC3B,UAAU,KAAK;AAAA,EACjB,CAAC;AAAA;AAAA,EAID,qBAAqB,IAAI,uBAAuB;AAAA,IAC9C,KAAK,KAAK;AAAA,IACV,QAAQ,KAAK;AAAA,IACb,uBAAuB,KAAK;AAAA,IAC5B,2BAA2B,KAAK;AAAA,IAChC,yBAAyB,KAAK;AAAA,EAChC,CAAC;AAAA,EAED,yBAAyB,IAAI,sBAAsB;AAAA,IACjD,UAAU,KAAK;AAAA,IACf,SAAS,KAAK;AAAA,EAChB,CAAC;AAAA;AAAA,EAID,UAAU,IAAI,YAAY;AAAA,IACxB,oBAAoB,KAAK;AAAA,IACzB,eAAe,KAAK;AAAA,IACpB,SAAS,KAAK;AAAA,IACd,yBAAyB,KAAK;AAAA,EAChC,CAAC;AAAA;AAAA,EAID,uBAAuB,IAAI,yBAAyB;AAAA,IAClD,qBAAqB,KAAK;AAAA,IAC1B,aAAa,KAAK;AAAA,IAClB,wBAAwB,KAAK;AAAA,IAC7B,SAAS,KAAK;AAAA,EAChB,CAAC;AAAA,EAED,YAAY,IAAI,cAAc;AAAA,IAC5B,SAAS,KAAK;AAAA,EAChB,CAAC;AAAA;AAAA,EAID,uBAAiD,IAAI;AAAA,IACnD;AAAA,MACE,kBAAkB,KAAK;AAAA,MACvB,WAAW,KAAK;AAAA,MAChB,aAAa,KAAK;AAAA,MAClB,UAAU,KAAK;AAAA,IACjB;AAAA,EACF;AAAA;AAAA,EAIA,qBAAqB,IAAI,uBAAuB;AAAA,IAC9C,sBAAsB,KAAK;AAAA,IAC3B,aAAa,KAAK;AAAA,EACpB,CAAC;AAAA,EAED,kBAAkB,IAAI,oBAAoB;AAAA,IACxC,SAAS,KAAK;AAAA,IACd,sBAAsB,KAAK;AAAA,IAC3B,aAAa,KAAK;AAAA,EACpB,CAAC;AAAA;AAAA;AAAA,EAKD,mBAAmB,IAAI,qBAAqB;AAAA,IAC1C,oBAAoB,KAAK;AAAA,IACzB,YAAY,KAAK;AAAA,EACnB,CAAC;AAAA,EAED,0BAA0B,IAAI,4BAA4B;AAAA,IACxD,iBAAiB,KAAK;AAAA,EACxB,CAAC;AAAA;AAAA,EAID,iBAAiB,IAAI,mBAAmB;AAAA,IACtC,eAAe,KAAK;AAAA,IACpB,yBAAyB,KAAK;AAAA,IAC9B,SAAS,KAAK;AAAA,EAChB,CAAC;AAAA;AAAA,EAID,iBAAiB,IAAI,mBAAmB;AAAA,IACtC,iBAAiB,KAAK;AAAA,IACtB,gBAAgB,KAAK;AAAA,EACvB,CAAC;AAAA,EAED,mBAAmB,IAAI,iBAAiB,IAAI;AAAA,EAE5C,MAAa,cAA+B;AAC1C,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAI,MAAM,QAAQ,IAAI;AAAA,MACpB,KAAK,WAAW,IAAI;AAAA,MACpB,KAAK,SAAS,IAAI;AAAA,MAClB,KAAK,yBAAyB,IAAI;AAAA,MAClC,KAAK,IAAI,IAAI;AAAA,MACb,KAAK,SAAS,IAAI;AAAA,MAClB,KAAK,YAAY,IAAI;AAAA,MACrB,KAAK,iBAAiB,kBAAkB,IAAI;AAAA,MAC5C,KAAK,iBAAiB,kBAAkB,MAAM,IAAI;AAAA,IACpD,CAAC;AAED,UAAM,aAAa,eAAe;AAElC,UAAM,MAAM,IAAI;AAAA,MACd,6BAA6B,aAAa,YAAY,MAAM;AAAA,IAC9D;AAEA,QAAI,CAAC,IAAI,IAAI,oBAAoB,GAAG;AAClC,UAAI,aAAa,IAAI,OAAO,IAAI,IAAI,SAAS,CAAC;AAAA,IAChD;AACA,QAAI,CAAC,MAAM,IAAI,oBAAoB,GAAG;AACpC,UAAI,aAAa,IAAI,aAAa,MAAM,IAAI,SAAS,CAAC;AAAA,IACxD;AACA,QAAI,WAAW,SAAS;AACtB,UAAI,aAAa,IAAI,gBAAgB,MAAM;AAAA,IAC7C;AACA,QACE,kCAAkC,UAClC,kCAAkC,MAClC;AACA,UAAI,aAAa;AAAA,QACf;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,QAAI,cAAc,sBAAsB,UAAU;AAChD,UAAI,aAAa,IAAI,sBAAsB,iBAAiB;AAAA,IAC9D,WAAW,aAAa,SAAS;AAC/B,UAAI,aAAa,IAAI,UAAU,QAAQ;AAAA,IACzC;AACA,QAAI,mBAAmB;AACrB,UAAI,aAAa,IAAI,SAAS,iBAAiB;AAAA,IACjD;AACA,WAAO,IAAI,SAAS;AAAA,EACtB;AAAA,EAEA,uBAAuB,SAAkB,SAA+B;AACtE,UAAM,YAAY,QAAQ,GAAG,IAAI;AACjC,QAAI,WAAW;AACb,WAAK,oBAAoB,WAAW,OAAO;AAAA,IAC7C,OAAO;AACL,WAAK,IAAI;AAAA,SACN,YAAY;AACX,gBAAM,OAAO,MAAM,KAAK,IAAI,IAAI,GAAG;AACnC,gBAAM,SAAS,IAAI,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;AAC5C,eAAK,iBAAiB,IAAI,KAAK;AAC/B,iBAAO;AAAA,QACT,GAAG;AAAA,MACL;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,oBACE,cACA,SAIM;AACN,UAAM,OACJ,OAAO,iBAAiB,WAAW,IAAI,KAAK,YAAY,IAAI;AAC9D,SAAK,IAAI;AAAA,OACN,YAAY;AACX,cAAM,CAAC,EAAE,IAAI,GAAG,YAAY,IAAI,MAAM,QAAQ,IAAI;AAAA,UAChD,KAAK,IAAI,IAAI;AAAA,UACb,KAAK,aAAa,IAAI;AAAA,QACxB,CAAC;AACD,cAAM,SAAS,uBAAuB,KAAK,MAAM;AAAA,UAC/C,GAAG;AAAA,UACH,GAAI,MAAM;AAAA,YACR;AAAA,UACF;AAAA,QACF,CAAC;AACD,aAAK,iBAAiB,IAAI,KAAK;AAC/B,aAAK,YAAY,IAAI;AAAA,UACnB;AAAA,UACA,QAAQ;AAAA,QACV,CAAC;AACD,eAAO;AAAA,MACT,GAAG;AAAA,IACL;AAAA,EACF;AAAA;AAAA,EAGA,+BAAqC;AACnC,SAAK,IAAI;AAAA,OACN,YAAY;AACX,cAAM,OAAO,MAAM,KAAK,IAAI,IAAI,GAAG;AACnC,cAAM,WAAW,MAAM,KAAK,IAAI,cAAc,CAAC;AAC/C,cAAM,CAAC,UAAU,IAAI,SAAS,OAAO,EAAE;AACvC,YAAI,CAAC,YAAY;AACf,iBAAO;AAAA,QACT;AACA,aAAK,iBAAiB,IAAI,KAAK;AAC/B,cAAM,iBAAiB,WAAW,GAAG,IAAI;AACzC,YAAI,gBAAgB;AAClB,eAAK,YAAY,IAAI;AAAA,YACnB,MAAM,eAAe,OAAO;AAAA,YAC5B,QAAQ;AAAA,UACV,CAAC;AAAA,QACH;AACA,eAAO,IAAI,IAAI,QAAQ;AAAA,MACzB,GAAG;AAAA,IACL;AAAA,EACF;AACF;;;AC/UA,SAAS,IAAI,UAAyB;AACpC,SAAO,IAAI;AAAA,IACT,iBAAiB,QAAQ;AAAA,EAC3B;AACF;AAEO,IAAe,uBAAf,cAA4C,qBAAqB;AAAA,EACtE,oBAAuC,IAAI,kBAAkB;AAAA,EAE7D,IAAI,IAAI,QAAsB;AAC5B,SAAK,kBAAkB,IAAI,IAAI,MAAM;AAAA,EACvC;AAAA,EACA,IAAI,MAAa;AACf,UAAM,IAAI,KAAK;AAAA,EACjB;AAAA,EAEA,IAAI,qBAAqB,UAAwB;AAC/C,SAAK,kBAAkB,SAAS,IAAI,QAAQ;AAAA,EAC9C;AAAA,EACA,IAAI,uBAA8B;AAChC,UAAM,IAAI,OAAO;AAAA,EACnB;AAAA,EAEA,IAAI,wBAAwB,QAAyB;AACnD,SAAK,kBAAkB,YAAY,IAAI,MAAM;AAAA,EAC/C;AAAA,EACA,IAAI,0BAAiC;AACnC,UAAM,IAAI,QAAQ;AAAA,EACpB;AAAA,EAEA,IAAI,OAAO,UAAoB;AAC7B,SAAK,kBAAkB,gBAAgB,IAAI,QAAQ;AAAA,EACrD;AAAA,EACA,IAAI,SAAgB;AAClB,UAAM,IAAI,QAAQ;AAAA,EACpB;AAAA,EAEA,IAAI,8BAA8B,mBAA4C;AAC5E,SAAK,kBAAkB,yBAAyB,IAAI,iBAAiB;AAAA,EACvE;AAAA,EACA,IAAI,gCAAuC;AACzC,UAAM,IAAI,+BAA+B;AAAA,EAC3C;AAAA,EAEA,IAAI,UAAU,WAA6B;AACzC,SAAK,kBAAkB,iBAAiB,IAAI,SAAS;AAAA,EACvD;AAAA,EACA,IAAI,YAAmB;AACrB,UAAM,IAAI,WAAW;AAAA,EACvB;AAAA,EAEA,IAAI,aAAa,kBAA4C;AAC3D,SAAK,kBAAkB,iBAAiB,YAAY,IAAI,gBAAgB;AAAA,EAC1E;AAAA,EACA,IAAI,eAAsB;AACxB,UAAM,IAAI,cAAc;AAAA,EAC1B;AAAA,EAEA,IAAI,uBAAuB,YAAoC;AAC7D,SAAK,kBAAkB,iBAAiB,kBAAkB,IAAI,UAAU;AAAA,EAC1E;AAAA,EACA,IAAI,yBAAgC;AAClC,UAAM,IAAI,wBAAwB;AAAA,EACpC;AAAA,EAEA,IAAI,iCAAiC,gBAEjB;AAClB,SAAK,kBAAkB,iBAAiB,sBAAsB;AAAA,MAC5D;AAAA,IACF;AAAA,EACF;AAAA,EACA,IAAI,mCAA0C;AAC5C,UAAM,IAAI,kCAAkC;AAAA,EAC9C;AAAA,EAEA,IAAI,yBAAyB,cAA4B;AACvD,SAAK,kBAAkB,iBAAiB,aAAa,IAAI,YAAY;AAAA,EACvE;AAAA,EAEA,IAAI,2BAAkC;AACpC,UAAM,IAAI,0BAA0B;AAAA,EACtC;AAAA,EAEA,IAAI,SAAS,UAAkC;AAC7C,SAAK,kBAAkB,SAAS,IAAI,QAAQ;AAAA,EAC9C;AAAA,EACA,IAAI,WAAkB;AACpB,UAAM,IAAI,UAAU;AAAA,EACtB;AAAA,EAEA,IAAI,WAAW,iBAA0C;AACvD,SAAK,kBAAkB,iBAAiB,WAAW,IAAI,eAAe;AAAA,EACxE;AAAA,EACA,IAAI,aAAoB;AACtB,UAAM,IAAI,YAAY;AAAA,EACxB;AAAA,EAEA,IAAI,YAAY,aAAkC;AAChD,SAAK,kBAAkB,iBAAiB,mBAAmB,IAAI,WAAW;AAAA,EAC5E;AAAA,EACA,IAAI,cAAqB;AACvB,UAAM,IAAI,aAAa;AAAA,EACzB;AAAA,EAEA,IAAI,aAAa,iBAA4C;AAC3D,SAAK,kBAAkB,aAAa,IAAI,eAAe;AAAA,EACzD;AAAA,EACA,IAAI,eAAsB;AACxB,UAAM,IAAI,cAAc;AAAA,EAC1B;AAAA,EAEA,IAAI,cAAc,qBAAkD;AAClE,SAAK,kBAAkB,oBAAoB,IAAI,mBAAmB;AAAA,EACpE;AAAA,EACA,IAAI,gBAAuB;AACzB,UAAM,IAAI,eAAe;AAAA,EAC3B;AAAA,EAEA,IAAI,kBAAkB,OAAsB;AAC1C,SAAK,kBAAkB,MAAM,IAAI,KAAK;AAAA,EACxC;AAAA,EACA,IAAI,oBAA2B;AAC7B,UAAM,IAAI,mBAAmB;AAAA,EAC/B;AAAA,EAEA,IAAI,qBAAqB,UAAyB;AAChD,SAAK,kBAAkB,SAAS,IAAI,QAAQ;AAAA,EAC9C;AAAA,EACA,IAAI,uBAA8B;AAChC,UAAM,IAAI,sBAAsB;AAAA,EAClC;AAAA,EAEA,IAAI,0BAA0B,eAA8B;AAC1D,SAAK,kBAAkB,cAAc,IAAI,aAAa;AAAA,EACxD;AAAA,EACA,IAAI,4BAAmC;AACrC,UAAM,IAAI,2BAA2B;AAAA,EACvC;AAAA,EAEA,IAAI,WAAW,gBAAwC;AACrD,SAAK,kBAAkB,WAAW,IAAI,cAAc;AAAA,EACtD;AAAA,EACA,IAAI,aAAoB;AACtB,UAAM,IAAI,YAAY;AAAA,EACxB;AAAA,EAEA,IAAI,2BAA2B,gBAAgC;AAC7D,SAAK,kBAAkB,iBAAiB,eAAe,IAAI,cAAc;AAAA,EAC3E;AAAA,EACA,IAAI,6BAAoC;AACtC,UAAM,IAAI,4BAA4B;AAAA,EACxC;AAAA,EAEA,IAAI,mCAAmC,wBAA6C;AAClF,SAAK,kBAAkB,iBAAiB,uBAAuB;AAAA,MAC7D;AAAA,IACF;AAAA,EACF;AAAA,EACA,IAAI,qCAA4C;AAC9C,UAAM,IAAI,oCAAoC;AAAA,EAChD;AAAA,EAEA,IAAI,eAAe,UAAkB;AACnC,SAAK,kBAAkB,iBAAiB,wBAAwB,IAAI;AAAA,MAClE;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA,IAAI,iBAAwB;AAC1B,UAAM,IAAI,gBAAgB;AAAA,EAC5B;AAAA,EAEA,IAAI,gBAAgB,WAAmB;AACrC,SAAK,kBAAkB,iBAAiB,wBAAwB,IAAI;AAAA,MAClE;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA,IAAI,kBAAyB;AAC3B,UAAM,IAAI,iBAAiB;AAAA,EAC7B;AAAA,EAEA,IAAI,eAAe,UAAkB;AACnC,SAAK,kBAAkB,iBAAiB,wBAAwB,IAAI;AAAA,MAClE;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA,IAAI,iBAAwB;AAC1B,UAAM,IAAI,gBAAgB;AAAA,EAC5B;AAAA,EAEA,IAAI,oBAAoB,eAAuB;AAC7C,SAAK,kBAAkB,iBAAiB,cAAc,IAAI,aAAa;AAAA,EACzE;AAAA,EACA,IAAI,sBAA6B;AAC/B,UAAM,IAAI,qBAAqB;AAAA,EACjC;AAAA,EAEA,IAAI,QAAQ,SAA8B;AACxC,SAAK,kBAAkB,0BAA0B,IAAI,OAAO;AAAA,EAC9D;AAAA,EACA,IAAI,UAAiB;AACnB,UAAM,IAAI,SAAS;AAAA,EACrB;AAAA,EAEA,IAAI,WAAW,eAAuB;AACpC,SAAK,kBAAkB,WAAW,IAAI,aAAa;AAAA,EACrD;AAAA,EACA,IAAI,aAAoB;AACtB,UAAM,IAAI,YAAY;AAAA,EACxB;AAAA,EAEA,IAAI,mBAAmB,KAAmB;AACxC,SAAK,kBAAkB,iBAAiB,2BAA2B,IAAI,GAAG;AAAA,EAC5E;AAAA,EACA,IAAI,qBAA4B;AAC9B,UAAM,IAAI,oBAAoB;AAAA,EAChC;AAAA,EAEA,IAAI,uBAAuB,KAAmB;AAC5C,SAAK,kBAAkB,iBAAiB,qBAAqB,IAAI,GAAG;AAAA,EACtE;AAAA,EACA,IAAI,yBAAgC;AAClC,UAAM,IAAI,wBAAwB;AAAA,EACpC;AAAA,EAEA,IAAI,kBAAkB,SAAyB;AAC7C,SAAK,kBAAkB,iBAAiB,kBAAkB,IAAI,OAAO;AAAA,EACvE;AAAA,EACA,IAAI,oBAA2B;AAC7B,UAAM,IAAI,mBAAmB;AAAA,EAC/B;AAAA,EAEA,IAAI,yCAAyC,MAAoC;AAC/E,SAAK,kBAAkB,iBAAiB,6BAA6B;AAAA,MACnE;AAAA,IACF;AAAA,EACF;AAAA,EACA,IAAI,2CAAkD;AACpD,UAAM,IAAI,0CAA0C;AAAA,EACtD;AAAA,EAEA,IAAI,sBAAsB,eAA8B;AACtD,SAAK,kBAAkB,iBAAiB,UAAU,IAAI,aAAa;AAAA,EACrE;AAAA,EACA,IAAI,wBAA+B;AACjC,UAAM,IAAI,uBAAuB;AAAA,EACnC;AAAA,EAEA,kBAAkB,IAAI,oBAAoB,KAAK,iBAAiB;AAClE;AAEA,IAAM,sBAAN,MAA0B;AAAA,EACxB,YAAoB,OAA0B;AAA1B;AAAA,EAA2B;AAAA,EAE/C,MAAM,MAAoB;AACxB,YAAQ,MAAM,KAAK,MAAM,IAAI,IAAI,GAAG;AAAA,EACtC;AAAA,EAEA,MAAM,WAAyB;AAC7B,YAAQ,MAAM,KAAK,MAAM,SAAS,IAAI,GAAG;AAAA,EAC3C;AAAA,EAEA,WAA8B;AAC5B,WAAO,KAAK,MAAM,SAAS,IAAI;AAAA,EACjC;AAAA,EAEA,MAAM,YAA2C;AAC/C,YAAQ,MAAM,KAAK,MAAM,qBAAqB,IAAI,GAAG;AAAA,EACvD;AACF;;;ACzPA,IAAM,wBAAwB;AAIvB,IAAM,2BAA2B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOtC,KAAK;AAAA,EACL,0BAA0B;AAAA;AAAA,EAG1B,6BAA6B;AAAA,EAC7B,QAAQ;AAAA,EACR,mCAAmC;AAAA,EACnC,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,2BAA2B;AAAA,EAC3B,uCAAuC;AAAA,EACvC,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,aAAa;AAAA,EACb,gDACE;AAAA;AAAA,EAEF,eAAe;AAAA,EACf,iCAAiC;AAAA,EACjC,2BAA2B;AAAA;AAAA,EAG3B,sBAAsB;AAAA,EACtB,0BAA0B;AAAA,EAC1B,+BAA+B;AAAA;AAAA,EAG/B,mBAAmB;AAAA,EACnB,oBAAoB;AAAA,EACpB,mBAAmB;AAAA,EACnB,yBAAyB;AAAA,EACzB,eAAe;AAAA;AAAA,EAGf,uBAAuB;AAAA,EACvB,4BAA4B;AAC9B;AAIA,IAAM,aAAkD,OAAO;AAAA,EAC7D,OAAO,OAAO,wBAAwB,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;AAC9D;AAuEA,IAAM,WAAoC;AAAA,EACxC,oCAAoC;AACtC;AAEA,IAAI;AACJ,IAAM,sBAAsB,OAAO,qBAAqB;AACxD,SAAS,oBAAoB,QAAsB;AACjD,uCAAqC,IAAI;AAAA,IACvC,CAAC,SAAS,aAAa;AACrB,iBAAW,SAAS,SAAS;AAC3B,YAAI,MAAM,kBAAkB,MAAM,iBAAiB,SAAS,GAAG;AAC7D,UAAC,MAAM,OAAwB,mBAAmB,EAAE;AACpD,mBAAS,UAAU,MAAM,MAAM;AAAA,QACjC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,mCAAiC,QAAQ,MAAM;AACjD;AAqBO,IAAM,eAAN,cACG,qBAEV;AAAA,EACE,aAAqC,IAAI;AAAA,IACvC,KAAK;AAAA,IACL;AAAA,EACF;AAAA,EAEA;AAAA,EAEA,kCAA0D,MAAM;AAAA,EAAC;AAAA;AAAA;AAAA,EAKjE,YAAY,SAA6B,CAAC,GAAG;AAC3C,UAAM;AAGN,eAAW,CAAC,UAAU,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACtD,UACE,EAAE,WAAW,QAAiC,KAAK,SAAS,QAAQ,IACpE;AACA,gBAAQ,KAAK,0CAA0C,QAAQ,EAAE;AACjE;AAAA,MACF;AACA,MAAC,KAAa,QAAQ,IAAI;AAAA,IAC5B;AAAA,EACF;AAAA,EAEA,mBACE,IAAI;AAAA,IACF;AAAA,IACA;AAAA,IACC,CAAC,MAAM,EAAkC;AAAA,MACxC,OAAO,KAAK,iBAAiB;AAAA,IAC/B;AAAA,EACF;AAAA,EAEF,4BAA4B,SAAS,cAAc,KAAK;AAAA;AAAA,EACxD,aAAa,SAAS,cAAc,KAAK;AAAA;AAAA,EACzC,oBAAoB;AAAA;AAAA,EACpB,oBAA0B;AACxB,SAAK,OAAO,eAAe;AAC3B,wBAAoB,IAAI;AAAA,EAC1B;AAAA,EAEA,OAAO,mBAAmB,IAAmB;AAC3C,QAAI,KAAK,mBAAmB;AAC1B;AAAA,IACF;AACA,SAAK,oBAAoB;AAEzB,SAAK,WAAW,KAAK,yBAAyB,EAAE,UAAU;AAAA,MACxD;AAAA,IACF;AACA,SAAK,WAAW,KAAK,UAAU,EAAE,UAAU,IAAI,YAAY;AAC3D,SAAK,WAAW,cAAc;AAC9B,SAAK,kBAAkB,wBAAwB;AAAA,MAC7C,CAAC,qBAAqB;AACpB,cAAM,cAA6B,iBAAiB,OAAO,CAAC,KAAK;AACjE,aAAK,eAAe,UAAU,OAAO,SAAS,CAAC,CAAC,WAAW;AAC3D,YAAI,aAAa;AACf,eAAK,WAAW,cAAc;AAAA,QAChC;AAAA,MACF;AAAA,IACF;AAEA,UAAM,WAAW,IAAI;AAAA,MACnB,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AACA,SAAK,eAAe,YAAY,QAAQ;AAExC,SAAK,UAAU,IAAI;AAAA,MACjB,KAAK;AAAA,MACL,KAAK;AAAA,MACL;AAAA,IACF;AACA,SAAK,eAAe,YAAY,KAAK,OAAO;AAE5C,SAAK,kBAAkB,iBAAiB,WAAW;AAAA,MACjD,CAAC,oBAA6C;AAC5C,aAAK,eAAe,UAAU;AAAA,UAC5B;AAAA,UACA,CAAC,QAAQ,WAAW,EAAE,SAAS,eAAe;AAAA,QAChD;AACA,aAAK,eAAe,UAAU;AAAA,UAC5B;AAAA,UACA,oBAAoB;AAAA,QACtB;AAAA,MACF;AAAA,IACF;AAEA,SAAK,kBAAkB,iBAAiB,YAAY;AAAA,MAClD,CAAC,gBAA6B;AAC5B,aAAK,eAAe,UAAU;AAAA,UAC5B;AAAA,UACA,CAAC,MAAM,EAAE,SAAS,WAAW;AAAA,QAC/B;AAAA,MACF;AAAA,IACF;AAEA,SAAK,kBAAkB,aAAa;AAAA,MAClC,CAAC,iBAA4C;AAC3C,aAAK,iBAAiB,SAAS,YAAY;AAAA,MAC7C;AAAA,IACF;AAEA,SAAK,kBAAkB,sBAAsB;AAAA,MAC3C,KAAK,yBAAyB,KAAK,IAAI;AAAA,IACzC;AAEA,SAAK,kBAAkB,SAAS,iBAAiB,KAAK,MAAM,KAAK,IAAI,CAAC;AAAA,EACxE;AAAA,EAEA,cAA+B;AAAA;AAAA,EAE/B,0BAA0B,UAAiC;AACzD,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,QAAQ;AACN,QAAI,KAAK,gBAAgB,QAAQ;AAC/B,WAAK,uBAAuB,QAAQ,CAAC,EAAE,SAAS,KAAK,GAAG,EAAE,SAAS,EAAE,CAAC,GAAG;AAAA,QACvE,UAAU;AAAA,QACV,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,wBACE;AAAA,EACF,iCACE,IAAI,oBAA0C;AAAA,EAEhD,yBAAuD;AAAA,EACvD,yBAAyB,UAAuC;AAC9D,QAAI,aAAa,KAAK,wBAAwB;AAC5C,WAAK,uBAAuB,OAAO;AACnC,WAAK,uBAAuB,WAAW;AACvC,UAAI;AACJ,cAAQ,UAAU;AAAA,QAChB,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK,2BAA2B;AAC9B,uBAAa,IAAI;AAAA,YACf,KAAK,kBAAkB;AAAA,YACvB;AAAA,UACF;AACA;AAAA,QACF;AAAA,QACA,KAAK;AAAA,QACL,KAAK,QAAQ;AAEX,uBAAa,IAAI,qBAAqB,KAAK,iBAAiB;AAC5D,eAAK,+BAA+B,eAAe,UAAU;AAC7D;AAAA,QACF;AAAA,QACA;AACE,gBAAM,IAAI,MAAM,uBAAuB;AAAA,MAC3C;AACA,WAAK,0BAA0B,YAAY,UAAU;AACrD,WAAK,wBAAwB;AAC7B,WAAK,yBAAyB;AAAA,IAChC;AAAA,EACF;AAAA,EAEA,MAAM,8BAAkE;AACtE,SAAK,kBAAkB;AACvB,UAAM,UAAU,KAAK;AACrB,QAAI,mBAAmB,sBAAsB;AAC3C,aAAO,QAAQ,qBAAqB;AAAA,IACtC;AACA,WAAO,CAAC;AAAA,EACV;AAAA,EAEA,MAAM,8BAA4D;AAChE,UAAM,WAAW,MAAM,KAAK,4BAA4B;AACxD,UAAM,WAAgC,CAAC;AACvC,eAAW,WAAW,UAAU;AAC9B,eAAS,MAAM,MAAM,QAAQ,WAAW,GAAG,MAAM;AAAA,IACnD;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAwBA,MAAM,uCACJ,+BACmB;AACnB,SAAK,kBAAkB;AACvB,UAAM,eAAe,MAAM,KAAK,+BAA+B;AAC/D,UAAM,gBACJ,MAAM,aAAa,kCAAkC;AACvD,UAAM,wBACJ,cAAc,eAAe;AAC/B,UAAM,kBAAkB,YAAY;AAClC,YAAM;AACN,YAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,CAAC,CAAC;AAAA,IACvD,GAAG;AACH,QAAI,+BAA+B;AAKjC,YAAM,YAAY,IAAI,gBAAgB,YAAY;AAAA,MAAC,CAAC;AACpD,oBAAc,iBAAiB,oBAAoB,YAAY;AAC7D,YAAI,CAAC,UAAU,iBAAiB,GAAG;AACjC,oBAAU,iBAAiB;AAC3B,gBAAM;AACN,wCAA8B;AAAA,QAChC;AAAA,MACF,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AAAA,EAEA,YAAY,SAAoC;AAC9C,SAAK,WAAW,YAAY,OAAO;AAAA,EACrC;AAAA,EAEA,UAAU,SAAoC;AAC5C,SAAK,WAAW,UAAU,OAAO;AAAA,EACnC;AAAA,EAEA,OAAa;AACX,SAAK,WAAW,WAAW,IAAI;AAAA,EACjC;AAAA,EAEA,QAAc;AACZ,SAAK,WAAW,WAAW,KAAK;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WAAW,MAAsB;AAC/B,SAAK,WAAW,WAAW,IAAI;AAAA,EACjC;AAAA;AAAA;AAAA,EAIA,oBACE,cACA,SACM;AACN,SAAK,kBAAkB,oBAAoB,cAAc,OAAO;AAAA,EAClE;AAAA;AAAA;AAAA,EAIA,uBAAuB,SAAkB,SAA+B;AACtE,SAAK,kBAAkB,uBAAuB,SAAS,OAAO;AAAA,EAChE;AAAA,EAEA,WAAW,qBAA+B;AACxC,UAAM,WAAqB,CAAC;AAC5B,eAAW,OAAO,OAAO,KAAK,wBAAwB,GAAG;AACvD,eAAS,KAAK,KAAK,wBAAwB,GAAG;AAAA,IAChD;AACA,WAAO;AAAA,EACT;AAAA,EAEA,+BAAqC;AACnC,SAAK,kBAAkB,6BAA6B;AAAA,EACtD;AAAA,EAEA,yBACE,eACA,WACA,UACM;AACN,QAAI,cAAc,WAAW,qBAAqB,GAAG;AACnD,sBAAgB,cAAc,MAAM,sBAAsB,MAAM;AAAA,IAClE;AACA,UAAM,aACJ,yBAAyB,aAAsC;AACjE,QAAI,CAAC,YAAY;AACf;AAAA,IACF;AAEA,IAAC,KAAa,UAAU,IAAI;AAAA,EAC9B;AAAA;AAAA;AAAA,EAIA,MAAM,uBAAuB,SAGT;AAClB,YAAQ,MAAM,WAAW,KAAK,mBAAmB,OAAO,GAAG;AAAA,EAC7D;AAAA;AAAA;AAAA,EAIA,MAAM,+BAA+B,UAAkC;AACrE,QACE,CAAC,MAAM,sBAAsB,yBAAyB,EAAE;AAAA,MACtD,MAAM,KAAK,kBAAkB,sBAAsB,IAAI;AAAA,IACzD,GACA;AAEA,YAAM,YAAY,KAAK;AACvB,YAAM,iBAAiB,MAAM,UAC1B,6BAA6B,EAC7B,eAAe;AAClB,YAAM,MAAM,IAAI,cAAc,EAAE;AAAA,QAC9B,eAAe,WAAY;AAAA,MAC7B;AACA,YAAM,MAAM,IAAI,gBAAgB,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC;AAC/C;AAAA,QACE;AAAA,QACA,YAAa,MAAM,mBAAmB,KAAK,iBAAiB;AAAA,QAC5D;AAAA,MACF;AAAA,IACF,OAAO;AACL,aAAO,MAAM,WAAW,KAAK,iBAAiB,GAAG,SAAS,QAAQ;AAAA,IACpE;AAAA,EACF;AACF;AAEA,mBAAmB,OAAO,iBAAiB,YAAY;;;ACpgBvD,IAAM,aAAN,cAAyB,gBAAkC;AAAA,EAClD,YAAY,KAAU,UAA4B;AACvD,UAAM,gBAAqC,CAAC;AAC5C,QAAI,iBAAiB;AACrB,eAAW,WAAW,IAAI,cAAc,GAAG;AACzC,YAAM,SAAS,KAAK,gBAAgB,SAAS;AAAA,QAC3C,eAAgB,SAAS,gBAAgB;AAAA,MAC3C,CAAC;AACD,oBAAc,KAAK,OAAO,MAAM;AAChC,wBAAkB,OAAO;AAAA,IAC3B;AACA,WAAO;AAAA,MACL,QAAQ,MAAM,UAAU,OAAO,GAAG,aAAa;AAAA,MAC/C,iBAAiB;AAAA,IACnB;AAAA,EACF;AAAA,EAEO,iBAAiB,UAAoB,UAA4B;AACtE,UAAM,SAAS,KAAK,YAAY,SAAS,KAAK,QAAQ;AACtD,WAAO;AAAA,MACL,QAAQ,OAAO;AAAA,MACf,iBAAkB,OAAO,kBAAkB,SAAS;AAAA,IACtD;AAAA,EACF;AAAA,EAEO,aAAa,MAAY,UAA4B;AAC1D,WAAO;AAAA,MACL,QAAQ;AAAA,QACN;AAAA,UACE,MAAM;AAAA,UACN,KAAK,SAAS;AAAA,QAChB;AAAA,MACF;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,EACF;AAAA,EAEO,mBACL,YACA,UACQ;AACR,UAAM,UAAU,KAAK,YAAY,WAAW,GAAG,QAAQ;AACvD,UAAM,UAAU,KAAK,YAAY,WAAW,GAAG;AAAA,MAC7C,eAAgB,SAAS,gBACvB,QAAQ;AAAA,IACZ,CAAC;AACD,WAAO;AAAA,MACL,QAAQ,QAAQ,OAAO,OAAO,QAAQ,MAAM;AAAA,MAC5C,iBAAkB,QAAQ,kBAAkB,IAC1C,QAAQ;AAAA,IACZ;AAAA,EACF;AAAA,EAEO,kBAAkB,WAAsB,UAA4B;AACzE,UAAM,UAAU,KAAK,YAAY,UAAU,GAAG,QAAQ;AACtD,UAAM,UAAU,KAAK,YAAY,UAAU,GAAG;AAAA,MAC5C,eAAgB,SAAS,gBACvB,QAAQ;AAAA,IACZ,CAAC;AACD,WAAO;AAAA,MACL,QAAQ,QAAQ,OAAO,OAAO,QAAQ,MAAM;AAAA,MAC5C,iBAAkB,QAAQ,kBAAkB,IAC1C,QAAQ,kBAAkB;AAAA,IAC9B;AAAA,EACF;AAAA,EAEO,cAAc,OAAc,UAA4B;AAC7D,WAAO;AAAA,MACL,QAAQ;AAAA,QACN;AAAA,UACE,MAAM;AAAA,UACN,KAAK,SAAS;AAAA,QAChB;AAAA,MACF;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,EACF;AAAA,EAEO,gBAAgB,UAAmB,WAA6B;AACrE,WAAO;AAAA,MACL,QAAQ,CAAC;AAAA,MACT,iBAAiB;AAAA,IACnB;AAAA,EACF;AAAA,EAEO,oBACL,UACA,WACQ;AACR,WAAO;AAAA,MACL,QAAQ,CAAC;AAAA,MACT,iBAAiB;AAAA,IACnB;AAAA,EACF;AACF;AAEO,IAAM,aAAa,sBAAsB,UAAU;;;AC1GnD,IAAM,2BAAN,cAAuC,uBAA+B;AAAA,EAC3E,kBAA0B;AACxB,WAAO;AAAA,EACT;AACF;AAKA,IAAM,6BAAN,cAAyC,kBAGvC;AAAA,EACA,OAAO,OAAuD;AAC5D,WAAO,wBAAwB,MAAM,KAAK;AAAA,EAC5C;AAAA;AAEF;AASO,IAAM,+BAAN,cAA2C,iBAGhD;AAAA,EACA,kBAAkB;AAChB,WAAO;AAAA,MACL,gBAAgB;AAAA,MAChB,cAAc;AAAA,MACd,wBAAwB;AAAA,IAC1B;AAAA,EACF;AAAA,EAEA,MAAM,OACJ,OACA,UACwB;AACxB,UAAM,EAAE,gBAAgB,aAAa,IAAI;AACzC,UAAM,aAAa,MAAM;AACzB,UAAM,yBACJ,MAAM,mBAAmB,WAAW,kBACpC,MAAM,kBAAkB,MAAM,UAAU;AAC1C,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAMO,IAAM,iBAAN,cAA6B,kBAGlC;AAAA,EACA,OAAO,QAA8B;AACnC,WAAO,OAAO,cAAc,yBACxB,OAAO,cAAc,eACrB,OAAO,cAAc;AAAA,EAC3B;AACF;AAKA,IAAM,iBAAN,cAA6B,kBAG3B;AAAA,EACA,OAAO,QAAiD;AACtD,WAAO,WAAW,OAAO,cAAc,KAAoB;AAAA,MACzD,eAAe;AAAA,IACjB,CAAC,EAAE;AAAA,EACL;AACF;AAWA,IAAM,sBAAN,cAAkC,kBAGhC;AAAA,EACA,OAAO,QAAyD;AAC9D,aAAS,UACP,UACsB;AACtB,UAAI,aAAa,MAAM;AACrB,eAAO;AAAA,MACT;AACA,UAAI;AACJ,UAAI,OAAO,aAAa,SAAS,KAAK,iBAAiB,GAAG;AACxD,gBAAQ;AAAA,MACV,WAAW,OAAO,eAAe,SAAS,KAAK,iBAAiB,GAAG;AACjE,gBAAQ;AAAA,MACV,WAAW,OAAO,aAAa,SAAS,KAAK,eAAe,GAAG;AAC7D,gBAAQ;AAAA,MACV,WAAW,OAAO,eAAe,SAAS,KAAK,eAAe,GAAG;AAC/D,gBAAQ;AAAA,MACV,OAAO;AACL,gBAAQ;AAAA,MACV;AACA,aAAO;AAAA,QACL;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,QAAI,eAA+C;AAEnD,eAAW,YAAY,OAAO,YAAY;AACxC,UACE,OAAO,aAAa,SAAS,KAAK,iBAAiB,KACnD,iBAAiB,MACjB;AACA,eAAO,UAAU,YAAY;AAAA,MAC/B;AACA,UAAI,OAAO,cAAc,SAAS,KAAK,eAAe,GAAG;AACvD,eAAO,UAAU,QAAQ;AAAA,MAC3B;AACA,qBAAe;AAAA,IACjB;AAEA,WAAO,UAAU,YAAY;AAAA,EAC/B;AACF;AAEO,IAAM,uBAAN,MAA2B;AAAA,EAChC,YAAY,IAAI,yBAAyB;AAAA,EACzC,gBAAgB,IAAI,6BAA6B;AAAA,EACjD,iBAAiB,IAAI,eAAe,EAAE,eAAe,KAAK,cAAc,CAAC;AAAA,EAEzE,yBAAyB,IAAI,2BAA2B;AAAA,IACtD,OAAO,KAAK;AAAA,EACd,CAAC;AAAA,EAED,iBAAiB,IAAI,eAAe;AAAA,IAClC,eAAe,KAAK;AAAA,EACtB,CAAC;AAAA,EAED,kBAAkB,IAAI,oBAAoB;AAAA,IACxC,YAAY,KAAK;AAAA,IACjB,YAAY,KAAK;AAAA,EACnB,CAAC;AACH;;;ACnLA,IAAM,oBAAoB;AAE1B,SAAS,WAAW,KAAyB;AAC3C,MAAI;AACF,WAAO,IAAI,WAAW,GAAG;AAAA,EAC3B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAIA,SAAS,2BACP,KACA,WACiC;AACjC,QAAM,MAAM,IAAI,QAAQ,SAAS;AACjC,MAAI,QAAQ,IAAI;AACd,WAAO,CAAC,KAAK,EAAE;AAAA,EACjB;AACA,SAAO,CAAC,IAAI,MAAM,GAAG,GAAG,GAAG,IAAI,MAAM,GAAG,CAAC;AAC3C;AAEA,SAAS,kCAAkC,KAAqB;AAC9D,QAAM,WAAW,CAAC;AAClB,aAAW,QAAQ,IAAI,MAAM,IAAI,GAAG;AAClC,QAAI,CAAC,QAAQ,KAAK,IAAI,2BAA2B,MAAM,iBAAiB;AACxE,aAAS,OAAO,WAAW,UAAK,GAAG;AACnC,aAAS,KAAK,SAAS,KAAK;AAAA,EAC9B;AACA,SAAO,SAAS,KAAK,IAAI;AAC3B;AAEO,SAAS,kBACd,UACA,YACM;AACN,QAAM,EAAE,OAAO,SAAS,IAAI;AAC5B,QAAM,EAAE,gBAAgB,aAAa,IAAI;AAEzC,QAAM,yBAAyB,SAAS,MAAM,GAAG,cAAc;AAC/D,QAAM,yBAAyB,SAAS,MAAM,YAAY;AAE1D,eAAa,WAAW,WAAW,QAAQ,IAAI;AAI/C,QAAM,mCACJ,uBAAuB,MAAM,aAAa;AAC5C,QAAM,8BACJ,SAAS,iBAAiB,CAAC,MAAM,OAAO,WAAW,CAAC,MAAM;AAC5D,QAAM,6BACJ,oCAAoC;AAEtC,QAAM,uBAAuB,WAAW,MAAM,aAAa;AAG3D,MAAI,cAAc;AAClB,MAAI,4BAA4B;AAC9B,UAAM,CAAC,QAAQ,KAAK,IAAI,2BAA2B,YAAY,IAAI;AACnE,kBAAc,SAAS,kCAAkC,KAAK;AAAA,EAChE,OAAO;AACL,kBAAc,kCAAkC,UAAU;AAAA,EAC5D;AAgBA,QAAM,oBACJ,CAAC,8BACD,mBAAmB;AAAA,EACnB,CAAC,CAAC,MAAM,GAAG,EAAE,SAAS,YAAY,CAAC,CAAC,KACpC,CAAC,CAAC,MAAM,GAAG,EAAE,SAAS,SAAS,iBAAiB,CAAC,CAAC;AACpD,QAAM,mBACJ,CAAC,wBACD,iBAAiB,SAAS;AAAA,EAC1B,CAAE,CAAC,MAAM,GAAG,EAA6B,SAAS,YAAY,GAAG,EAAE,CAAC,KACpE,CAAC,CAAC,MAAM,GAAG,EAAE,SAAS,SAAS,YAAY,CAAC;AAE9C,WAAS,oBAAoB,QAAgB,QAAyB;AACpE,UAAM,YAAY,SAAS,cAAc;AACzC,UAAM,QAAQ,CAAC,CAAC;AAAA,MACd,yBAAyB,YAAY;AAAA,IACvC;AACA,QAAI,OAAO;AACT,oBAAc;AAAA,IAChB;AACA,WAAO;AAAA,EACT;AAGA,EAAC,qBAAqB,oBAAoB,oBAAoB,KAAK,GAAG;AAAA,EACnE,qBAAqB,oBAAoB,KAAK,EAAE;AAAA,EAChD,oBAAoB,oBAAoB,IAAI,GAAG;AAGlD,QAAM,qBAAqB,oBAAoB;AAAA,IAC7C;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,CAAC,oBAAoB;AAEvB,aAAS,aAAa,aAAa,gBAAgB,cAAc,KAAK;AAAA,EACxE;AACF;;;ACrHO,IAAM,qBAAqB,IAAI,kBAAkB;AACxD,mBAAmB;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAsEF;;;ACxCA,IAAM,8BAA8B;AACpC,IAAM,wBAAwB;AAC9B,IAAM,+BAA+B;AAK9B,IAAM,kBAAN,cAA8B,qBAAqB;AAAA,EACxD,QAAQ,IAAI,qBAAqB;AAAA;AAAA,EAGjC,YAAiC,SAAS,cAAc,UAAU;AAAA,EAClE,cAA8B,SAAS,cAAc,KAAK;AAAA,EAC1D,oBAAqC,SAAS,cAAc,MAAM;AAAA,EAClE,uBAAwC,SAAS,cAAc,MAAM;AAAA,EACrE,oBAAqC,SAAS,cAAc,MAAM;AAAA;AAAA;AAAA,EAKlE,0CAEI,IAAI,iBAAiB,MAAM,qBAAqB;AAAA,IAClD;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAAA,EAED,gBAAqC;AAAA,EACrC;AAAA,EACA,IAAI,WAA2B;AAC7B,QAAI,KAAK,kBAAkB,MAAM;AAC/B,aAAO;AAAA,IACT,OAAO;AACL,aAAO,KAAK,cAAc,kBAAkB,KAAK,iBAAiB;AAAA,IACpE;AAAA,EACF;AAAA;AAAA,EAGA,6BAAsC;AAAA,EAEtC,YAAY,SAGT;AACD,UAAM;AACN,SAAK,YAAY,UAAU,IAAI,aAAa;AAC5C,SAAK,WAAW,KAAK,WAAW;AAChC,SAAK,UAAU,OAAO;AACtB,SAAK,WAAW,KAAK,SAAS;AAC9B,SAAK,kBAAkB,UAAU,IAAI,QAAQ;AAC7C,SAAK,YAAY,YAAY,KAAK,iBAAiB;AACnD,SAAK,qBAAqB,UAAU,IAAI,WAAW;AACnD,SAAK,YAAY,YAAY,KAAK,oBAAoB;AACtD,SAAK,kBAAkB,UAAU,IAAI,QAAQ;AAC7C,SAAK,YAAY,YAAY,KAAK,iBAAiB;AAEnD,SAAK,UAAU,cAAc;AAE7B,SAAK,UAAU,aAAa,cAAc,OAAO;AAEjD,SAAK,OAAO,kBAAkB;AAG9B,SAAK,UAAU,iBAAiB,SAAS,MAAM;AAC7C,WAAK,mBAAmB;AACxB,WAAK,QAAQ;AAAA,IACf,CAAC;AACD,SAAK,UAAU,iBAAiB,QAAQ,MAAM,KAAK,OAAO,CAAC;AAC3D,aAAS;AAAA,MAAiB;AAAA,MAAmB,MAC3C,KAAK,kBAAkB;AAAA,IACzB;AAEA,QAAI,SAAS,cAAc;AACzB,WAAK,eAAe,QAAQ;AAAA,IAC9B;AACA,SAAK,oBAAoB,SAAS,oBAAoB;AAEtD,QAAI,SAAS,qBAAqB,OAAO;AACvC,WAAK,MAAM,gBAAgB;AAAA,QACzB,CAAC,kBAAwC;AACvC,cAAI,eAAe;AACjB,iBAAK,cAAc,cAAc,SAAS,IAAI;AAAA,UAChD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,oBAA0B;AACxB,SAAK,UAAU,iBAAiB,SAAS,CAAC,MAAM;AAC9C,YAAM,OAAO,EAAE,eAAe,QAAQ,MAAM;AAC5C,UAAI,MAAM;AACR,0BAAkB,KAAK,WAAW,IAAI;AACtC,UAAE,eAAe;AACjB,aAAK,QAAQ;AAAA,MACf;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,IAAI,UAAU,GAAW;AACvB,SAAK,UAAU,QAAQ;AACvB,SAAK,QAAQ;AAAA,EACf;AAAA;AAAA,EAGA,IAAI,YAAoB;AACtB,WAAO,KAAK,UAAU;AAAA,EACxB;AAAA;AAAA,EAGA,IAAI,YAAY,iBAAyB;AACvC,SAAK,UAAU,cAAc;AAAA,EAC/B;AAAA,EAEA,mBAAmB;AAAA,EACnB,UAAgB;AACd,SAAK,qBAAqB,SAAS;AACnC,SAAK,cAAc,IAAI;AAOvB,UAAM,aAAa,KAAK,UAAU,MAAM,QAAQ;AAChD,SAAK,MAAM,UAAU,IAAI,UAAU;AACnC,SAAK,UAAU,IAAI,UAAU;AAAA,EAC/B;AAAA,EAEA,MAAM,oBAAmC;AACvC,QACE,SAAS,kBAAkB,QAC3B,KAAK,OAAO,kBAAkB,KAAK,WACnC;AACA;AAAA,IACF;AACA,QAAI,KAAK,sBAAsB,OAAO;AACpC;AAAA,IACF;AAEA,UAAM,EAAE,gBAAgB,aAAa,IAAI,KAAK;AAC9C,SAAK,MAAM,cAAc,IAAI;AAAA,MAC3B;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,SAAwB;AAAA,EAU9B;AAAA,EAEA,0BAA0B,QAAsC;AAC9D,SAAK,wCAAwC,SAAS,MAAM;AAAA,EAC9D;AAAA;AAAA;AAAA,EAIA,WAAW,GAAmB;AAC5B,WAAO,EAAE,SAAS,IAAI,IAAI,GAAG,CAAC,MAAM;AAAA,EACtC;AAAA,EAEA,mBAA4D;AAAA;AAAA,EAE5D,cAAc,MAAqD;AAKjE,QAAI,SAAS,MAAM;AACjB,WAAK,kBAAkB,cAAc;AACrC,WAAK,qBAAqB,cAAc;AACxC,WAAK,kBAAkB,cAAc,KAAK;AAAA,QACxC,KAAK,UAAU;AAAA,MACjB;AACA;AAAA,IACF;AACA,QAAI,SAAS,KAAK,kBAAkB;AAClC;AAAA,IACF;AACA,SAAK,mBAAmB;AACxB,SAAK,kBAAkB,cAAc,KAAK,UAAU,MAAM;AAAA,MACxD;AAAA,MACA,KAAK,iBAAiB;AAAA,IACxB;AACA,SAAK,qBAAqB,cAAc,KAAK,UAAU,MAAM;AAAA,MAC3D,KAAK,iBAAiB;AAAA,MACtB,KAAK,eAAe;AAAA,IACtB;AACA,SAAK,kBAAkB,cAAc,KAAK;AAAA,MACxC,KAAK,UAAU,MAAM,MAAM,KAAK,eAAe,CAAC;AAAA,IAClD;AACA,SAAK,qBAAqB,SAAS;AAAA,EACrC;AAAA,EAEA,IAAI,eAAoC;AACtC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,IAAI,aAAa,cAAmC;AAClD,QAAI,KAAK,eAAe;AAEtB,cAAQ,KAAK,sDAAsD;AACnE;AAAA,IACF;AACA,SAAK,gBAAgB;AACrB,QAAI,CAAC,cAAc;AACjB;AAAA,IACF;AACA,UAAM,YAAY;AAChB,WAAK,YAAY,KAAK,YACjB,MAAM,KAAK,SAAS,IAAI,GAAG,IAAI,SAAS,IACzC;AAAA,IACN,GAAG;AAUH,QAAI,KAAK,sBAAsB,OAAO;AAMpC,WAAK,eAAe,kBAAkB,UAAU;AAAA,QAC9C,CAAC,kBAAiC;AAEhC,cAAI,cAAc,OAAO,OAAO,WAAW,GAAG;AAC5C,iBAAK;AAAA;AAAA,cAEH,cAAc,OAAO,SAAS,WAAW,IAAI,SAAS;AAAA,YACxD;AACA,kBAAM,SAAS,cAAc;AAC7B,kBAAM,SAAS,IAAI,WAAW,KAAK,SAAS;AAC5C,gBAAI,CAAC,OAAO,YAAY,MAAM,GAAG;AAC/B,mBAAK,YAAY,OAAO,SAAS;AACjC,mBAAK,QAAQ;AAAA,YACf,OAAO;AAAA,YAEP;AAAA,UACF,OAAO;AACL,iBAAK,0BAA0B,OAAO;AAAA,UACxC;AAAA,QACF;AAAA,MACF;AAEA,WAAK,MAAM,gBAAgB;AAAA,QACzB,OAAO,kBAAwC;AAC7C,cAAI,kBAAkB,MAAM;AAC1B;AAAA,UACF;AAEA,gBAAM,CAAC,SAAS,gBAAgB,IAAI,MAAM,QAAQ,IAAI;AAAA,YACpD,MAAM,aAAa,kBAAkB,QAAQ,IAAI;AAAA,YACjD,MAAM,aAAa,kBAAkB,iBAAiB,IAAI;AAAA,UAC5D,CAAC;AACD,cAAI,qBAAqB,UAAU,CAAC,KAAK,kBAAkB;AACzD;AAAA,UACF;AACA,gBAAM,qBAAqB,QAAQ;AAAA,YACjC,cAAc,SAAS;AAAA,UACzB;AACA,gBAAM,WAAW,QAAQ,aAAa,cAAc,SAAS,GAAG;AAEhE,cAAI;AACJ,kBAAQ,cAAc,OAAO;AAAA,YAC3B,KAAK,UAAU;AACb,6BAAe;AACf;AAAA,YACF;AAAA,YACA,KAAK;AAAA,YACL,KAAK,UAAU;AACb,6BAAgB,qBACd,WAAW;AACb;AAAA,YACF;AAAA,YACA,KAAK;AAAA,YACL,KAAK,SAAS;AACZ,6BAAgB,qBACd;AACF;AAAA,YACF;AAAA,YACA;AACE,sBAAQ,IAAI,eAAe;AAC3B,oBAAM,IAAI,MAAM,gBAAgB;AAAA,UACpC;AACA,cAAI,CAAC,KAAK,4BAA4B;AACpC,yBAAa,kBAAkB,iBAAiB,IAAI,YAAY;AAAA,UAClE;AAAA,QACF;AAAA,MACF;AAEA,mBAAa,kBAAkB,wBAAwB;AAAA,QACrD,OAAO,4BAAqD;AAC1D,gBAAM,UAAU,MAAM,aAAa,kBAAkB,QAAQ,IAAI;AACjE,gBAAM,OAAO,QAAQ;AAAA,YACnB,wBAAwB;AAAA,UAC1B;AACA,eAAK,cAAc,IAAmC;AAAA,QACxD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEU,yBACR,eACA,WACA,UACM;AACN,YAAQ,eAAe;AAAA,MACrB,KAAK,6BAA6B;AAChC,cAAM,OAAO,SAAS,eAAe,QAAQ;AAC7C,YAAI,CAAC,MAAM;AACT,kBAAQ,KAAK,GAAG,2BAA2B,uBAAuB;AAClE;AAAA,QACF;AACA,YAAI,EAAE,gBAAgB,eAAe;AAEnC,kBAAQ,KAAK,GAAG,2BAA2B,yBAAyB;AACpE;AAAA,QACF;AACA,aAAK,eAAe;AACpB;AAAA,MACF;AAAA,MACA,KAAK,uBAAuB;AAC1B,aAAK,cAAc;AACnB;AAAA,MACF;AAAA,MACA,KAAK,8BAA8B;AACjC,YAAI,KAAK,eAAe;AACtB,kBAAQ,IAAI,iBAAiB;AAC7B,gBAAM,IAAI,MAAM,qCAAqC;AAAA,QACvD;AACA,aAAK,oBAAoB;AACzB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,WAAW,qBAA+B;AACxC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEA,mBAAmB,OAAO,qBAAqB,eAAe;;;AC5Y9D,eAAsB,mBAAmB,IAA8B;AACrE,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,QAAI;AACF,YAAM,cAAc,SAAS,eAAe,EAAE;AAC9C,UAAI,aAAa;AACf,gBAAQ,WAAW;AAAA,MACrB;AACA,YAAM,WAAW,IAAI,iBAAiB,CAAC,cAAgC;AACrE,mBAAW,YAAY,WAAW;AAChC,cACE,SAAS,kBAAkB,QAC3B,SAAS,kBAAkB,WAC3B,SAAS,OAAO,aAAa,IAAI,MAAM,IACvC;AACA,oBAAQ,SAAS,MAAM;AACvB,qBAAS,WAAW;AAAA,UACtB;AAAA,QACF;AAAA,MACF,CAAC;AAED,eAAS,QAAQ,SAAS,MAAM;AAAA,QAC9B,iBAAiB,CAAC,IAAI;AAAA,QACtB,SAAS;AAAA,MACX,CAAC;AAAA,IACH,SAAS,GAAG;AACV,aAAO,CAAC;AAAA,IACV;AAAA,EACF,CAAC;AACH;;;AC3BO,IAAM,qBAAqB,IAAI,kBAAkB;AACxD,mBAAmB;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2BF;;;ACIA,IAAM,0BAA0B;AAahC,IAAM,oBAAN,cAAgC,qBAAqB;AAAA,EACnD,YACE,WACA,MACA,UACO,cACP,gBACA,WACA;AACA,UAAM,EAAE,MAAM,OAAO,CAAC;AAJf;AAKP,SAAK,UAAU,IAAI,SAAS;AAE5B,SAAK,OAAO,kBAAkB;AAC9B,QAAI,WAAW;AACb,YAAM,SAAS,KAAK,eAAe;AAAA,QACjC,SAAS,cAAc,GAAG;AAAA,MAC5B;AACA,aAAO,OAAO;AACd,aAAO,cAAc;AAErB,aAAO,iBAAiB,SAAS,CAAC,MAAM;AACtC,UAAE,eAAe;AACjB,aAAK,SAAS,gBAAgB;AAAA,UAC5B,SAAS;AAAA,UACT;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH,OAAO;AACL,WAAK,eAAe;AAAA,QAClB,SAAS,cAAc,MAAM;AAAA,MAC/B,EAAE,cAAc;AAAA,IAClB;AAAA,EACF;AAAA,EAEA,YAAY,QAA8D;AACxE,WAAO,CAAC;AAAA,EACV;AAAA,EAEA,eAAe,SAAkB;AAC/B,SAAK,eAAe,UAAU,OAAO,gBAAgB,OAAO;AAAA,EAC9D;AACF;AAEA,mBAAmB,OAAO,wBAAwB,iBAAiB;AAEnE,IAAM,uBAAN,cAAmC,gBAAgB;AAAA,EAGjD,YACE,WACO,cACP;AACA,UAAM;AAFC;AAGP,SAAK,UAAU,IAAI,SAAS;AAAA,EAC9B;AAAA,EARQ,QAA4B,CAAC;AAAA,EAUrC,UAAU,KAAa;AACrB,SAAK,MAAM,KAAK,SAAS,eAAe,GAAG,CAAC;AAAA,EAC9C;AAAA,EAEA,QAAQ,QAAwB;AAC9B,SAAK,MAAM,KAAK,OAAO,OAAO;AAC9B,WAAO,OAAO;AAAA,EAChB;AAAA,EAEA,WACE,8BACM;AACN,eAAW,QAAQ,iBAAiB,KAAK,OAAO,SAAS,GAAG;AAC1D,WAAK,OAAO,IAAI;AAAA,IAClB;AACA,SAAK,QAAQ,CAAC;AAAA,EAChB;AAAA,EAEA,YAAY,QAA8D;AACxE,WAAO,CAAC;AAAA,EACV;AACF;AAEA,mBAAmB,OAAO,2BAA2B,oBAAoB;AAEzE,SAAS,kBACP,WACgC;AAChC,SAAO;AAGT;AAEA,SAAS,wBACP,kBACA,QACgC;AAChC,SAAO,SAAS,IAAI,kBAAkB,gBAAgB,IAAI;AAC5D;AAEA,SAAS,iBACP,GACA,WACK;AACL,MAAI,gCAAuD;AACzD,WAAO;AAAA,EACT;AAGA,QAAM,OAAO,MAAM,KAAK,CAAC;AACzB,OAAK,QAAQ;AACb,SAAO;AACT;AAEA,IAAM,eAAN,cAA2B,gBAA0C;AAAA,EAC5D,YAAY,KAAU,UAA4B;AACvD,QAAI,YAAY;AAChB,UAAM,UAAU,IAAI,qBAAqB,kBAAkB,GAAG;AAC9D,QAAI,QAAQ;AACZ,eAAW,WAAW;AAAA,MACpB,IAAI,cAAc;AAAA,MAClB,SAAS;AAAA,IACX,GAAG;AACD,UAAI,CAAC,OAAO;AACV,gBAAQ,UAAU,GAAG;AAAA,MACvB;AACA,cAAQ;AACR,UAAI,QAAQ,GAAG,KAAK,GAAG,0BAA0B;AAC/C,gBAAQ,UAAU,IAAI;AAAA,MACxB;AAEA,UAAI,CAAC,QAAQ,GAAG,QAAQ,GAAG,6BAA6B;AACtD,qBAAa,QAAQ;AAAA,UACnB,KAAK,gBAAgB,SAAS;AAAA,YAC5B,mBAAoB,SAAS,oBAC3B;AAAA,YACF,iBAAiB,SAAS;AAAA,YAC1B,WAAW,SAAS;AAAA,UACtB,CAAC;AAAA,QACH;AAAA,MACF;AACA,UAAI,QAAQ,GAAG,KAAK,GAAG,0BAA0B;AAC/C,gBAAQ,UAAU,GAAG;AAAA,MACvB;AAAA,IACF;AACA,YAAQ,WAAW,SAAS,SAAS;AACrC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEO,iBAAiB,UAAoB,UAA4B;AACtE,UAAM,eAAe,SAAS,2BAA2B;AAKzD,UAAM,YAAY;AAAA,MAChB,SAAS;AAAA,MACT,SAAS;AAAA,IACX;AACA,QAAI,YAAY;AAChB,UAAM,UAAU,IAAI,qBAAqB,uBAAuB,QAAQ;AACxE,YAAQ,UAAU,GAAG;AAErB,QAAI,cAAc;AAChB,mBAAa,QAAQ,QAAQ;AAAA,QAC3B,WAAW;AAAA,QACX,SAAS,IAAI;AAAA,UACX;AAAA;AAAA,UACA,aAAa,CAAC,EAAE,OAAO,SAAS;AAAA,UAChC;AAAA,UACA,aAAa,CAAC;AAAA,UACd;AAAA,UACA;AAAA,QACF;AAAA,MACF,CAAC;AACD,cAAQ,UAAU,IAAI;AACtB,mBAAa,QAAQ,QAAQ;AAAA,QAC3B,WAAW;AAAA,QACX,SAAS,IAAI;AAAA,UACX;AAAA;AAAA,UACA,aAAa,CAAC,EAAE,OAAO,SAAS;AAAA,UAChC;AAAA,UACA,aAAa,CAAC;AAAA,UACd;AAAA,UACA;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH,OAAO;AACL,mBAAa,QAAQ;AAAA,QACnB,KAAK,YAAY,SAAS,KAAK;AAAA,UAC7B,mBAAoB,SAAS,oBAC3B;AAAA,UACF,iBAAiB,SAAS;AAAA,UAC1B;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAEA,YAAQ,UAAU,IAAI,SAAS,4BAA4B,EAAE;AAC7D,YAAQ,WAAW;AACnB,WAAO;AAAA,MACL,WAAW,YAAY,KAAK,IAAI,SAAS,MAAM;AAAA,MAC/C;AAAA,IACF;AAAA,EACF;AAAA,EAEO,aAAa,MAAY,UAA4B;AAC1D,UAAM,UAAU,IAAI;AAAA,MAClB;AAAA,MACA,KAAK,SAAS;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,aAAS,gBAAgB,YAAY;AAAA,MAClC,KAAsB,iBAAiB;AAAA,MACxC;AAAA,IACF;AACA,WAAO;AAAA,MACL,WAAW;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAAA,EAEO,mBACL,YACA,UACQ;AACR,QAAI,YAAY;AAChB,UAAM,UAAU,IAAI;AAAA,MAClB;AAAA,MACA;AAAA,IACF;AACA,YAAQ,UAAU,GAAG;AACrB,YAAQ,WAAW;AACnB,UAAM,CAAC,OAAO,MAAM,IAAW;AAAA,MAC7B,CAAC,WAAW,GAAG,WAAW,CAAC;AAAA,MAC3B,SAAS;AAAA,IACX;AACA,iBAAa,QAAQ;AAAA,MACnB,KAAK,YAAY,OAAO;AAAA,QACtB,mBAAoB,SAAS,oBAC3B;AAAA,QACF,iBAAiB,SAAS;AAAA,QAC1B,WAAW,SAAS;AAAA,MACtB,CAAC;AAAA,IACH;AACA,YAAQ,UAAU,IAAI;AACtB,iBAAa,QAAQ;AAAA,MACnB,KAAK,YAAY,QAAQ;AAAA,QACvB,mBAAoB,SAAS,oBAC3B;AAAA,QACF,iBAAiB,SAAS;AAAA,QAC1B,WAAW,SAAS;AAAA,MACtB,CAAC;AAAA,IACH;AACA,YAAQ,WAAW,SAAS,SAAS;AACrC,YAAQ,UAAU,GAAG;AACrB,YAAQ,WAAW;AACnB,WAAO;AAAA,MACL,WAAW,YAAY;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AAAA,EAEO,kBAAkB,WAAsB,UAA4B;AACzE,QAAI,YAAY;AAChB,UAAM,UAAU,IAAI,qBAAqB,wBAAwB,SAAS;AAC1E,YAAQ,UAAU,GAAG;AACrB,UAAM,OAAO,QAAQ;AAAA,MACnB,KAAK,YAAY,UAAU,GAAG;AAAA,QAC5B,mBAAoB,SAAS,oBAC3B;AAAA,QACF,iBAAiB,SAAS;AAAA,QAC1B,WAAW,SAAS;AAAA,MACtB,CAAC;AAAA,IACH;AACA,iBAAa;AACb,YAAQ,UAAU,IAAI;AACtB,iBAAa,QAAQ;AAAA,MACnB,KAAK,YAAY,UAAU,GAAG;AAAA,QAC5B,mBAAoB,SAAS,oBAC3B;AAAA,QACF,iBAAiB,SAAS;AAAA,QAC1B,WAAW,SAAS;AAAA,MACtB,CAAC;AAAA,IACH;AACA,YAAQ,UAAU,GAAG;AACrB,YAAQ,WAAW;AACnB,WAAO;AAAA,MACL,WAAW,YAAY;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AAAA,EAEO,cAAc,OAAc,UAA4B;AAC7D,QAAI,MAAM,0BAA0B;AAClC,aAAO,KAAK,YAAY,MAAM,yBAAyB,KAAK,QAAQ;AAAA,IACtE;AACA,WAAO;AAAA,MACL,WAAW;AAAA,MACX,SAAS,IAAI;AAAA,QACX;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEO,gBAAgB,SAAkB,WAA6B;AACpE,UAAM,UAAU,IAAI,qBAAqB,sBAAsB,OAAO;AACtE,YAAQ,OAAO,SAAS,cAAc,IAAI,CAAC;AAC3C,WAAO;AAAA,MACL,WAAW;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAAA,EAEO,oBACL,aACA,UACQ;AACR,WAAO;AAAA,MACL,WAAW;AAAA,MACX,SAAS,IAAI;AAAA,QACX;AAAA,QACA,KAAK,YAAY,IAAI;AAAA,QACrB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,IAAM,eAAe,sBAAsB,YAAY;AAEvD,IAAM,kBAAN,MAAsB;AAAA,EACpB,mBAAmD,oBAAI,IAAI;AAAA,EAC3D,cAAwC;AAAA,EAExC,QAAQ,WAAmB,MAA+B;AACxD,SAAK,iBAAiB,IAAI,WAAW,IAAI;AAAA,EAC3C;AAAA,EAEA,IAAI,MAAiC;AACnC,UAAM,UAAU,OACX,KAAK,iBAAiB,IAAI,KAAK,iBAAiB,CAAC,KAAK,OACvD;AACJ,QAAI,KAAK,gBAAgB,SAAS;AAChC;AAAA,IACF;AACA,SAAK,aAAa,UAAU,OAAO,yBAAyB;AAC5D,SAAK,aAAa,eAAe,KAAK;AACtC,aAAS,UAAU,IAAI,yBAAyB;AAChD,aAAS,eAAe,IAAI;AAC5B,SAAK,cAAc;AAAA,EACrB;AACF;AAGO,IAAM,kBAAN,cAA8B,gBAAgB;AAAA,EACnD,cAA+B,IAAI,gBAAgB;AAAA,EACnD;AAAA,EACA,gBAAqC;AAAA,EACrC,qBAAoC;AAAA,EACpC,YAAY,SAA2C;AACrD,UAAM;AACN,QAAI,SAAS,cAAc;AACzB,WAAK,eAAe,SAAS;AAAA,IAC/B;AAAA,EACF;AAAA,EAEU,oBAA0B;AAAA,EAEpC;AAAA,EAEQ,OAAO,KAAgB;AAC7B,SAAK,WAAW,aAAa,KAAK;AAAA,MAChC,mBAAmB;AAAA,MACnB,iBAAiB;AAAA,MACjB;AAAA,IACF,CAAC,EAAE;AACH,SAAK,cAAc;AACnB,SAAK,YAAY,KAAK,QAAQ;AAAA,EAChC;AAAA,EAEA,IAAI,eAAoC;AACtC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,aAAa,cAAmC;AAClD,SAAK,KAAK,iBAAiB,YAAY;AAAA,EACzC;AAAA,EAEA,MAAM,iBAAiB,cAAmC;AACxD,QAAI,KAAK,eAAe;AACtB,cAAQ,KAAK,6CAA6C;AAC1D;AAAA,IACF;AACA,QAAI,iBAAiB,MAAM;AACzB,YAAM,IAAI,MAAM,wCAAwC;AAAA,IAC1D;AACA,SAAK,gBAAgB;AAErB,SAAK,cAAc,kBAAkB,IAAI;AAAA,MACvC,CAAC,kBAAiC;AAChC,aAAK,OAAO,cAAc,GAAG;AAAA,MAC/B;AAAA,IACF;AAEA,UAAM,aAAa,MAAM,KAAK,cAAc,kBAAkB,IAAI,IAAI,GACnE;AAEH,UAAM,YACJ,qBAAsB,YAClB,YACA,IAAI,WAAW,UAAU,SAAS,CAAC;AACzC,SAAK,OAAO,SAAS;AAErB,iBAAa,kBAAkB,gBAAgB;AAAA,MAC7C,CAAC,oBAAqC;AACpC,YAAI,WAAW,gBAAgB,aAAa,CAAC;AAC7C,qBAAa,gBAAgB,cAAc,CAAC;AAC5C,qBAAa,gBAAgB,eAAe,CAAC;AAC7C,YAAI,CAAC,UAAU;AACb,eAAK,YAAY,IAAI,IAAI;AAAA,QAC3B,OAAO;AACL,gBAAM,kBAAkB,SAAS;AACjC,eAAK,YAAY,IAAI,eAA+B;AAAA,QACtD;AAAA,MACF;AAAA,IACF;AAEA,iBAAa,kBAAkB,qBAAqB;AAAA,MAClD,CAAC,yBAA+C;AAC9C,YAAI,qBAAqB,cAAc,KAAK,oBAAoB;AAC9D,eAAK,qBAAqB;AAAA,QAC5B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,YAAY,OAAkB,gBAAwC;AAE1E,UAAM,eAAe,KAAK;AAC1B,QAAI,cAAc;AAChB,mBAAa,MAAM;AACnB,YAAM,oBAAoB,YAA2C;AACnE,cAAM,UAAU,MAAM,aAAa,kBAAkB,QAAQ,IAAI;AACjE,cAAM,SAAS,iBACX,QAAQ,aAAa,KAAK,IAAI,0BAC9B;AACJ,eAAQ,QAAQ,0BAA0B,KAAK,IAC7C,QAAQ,aAAa,KAAK,IAC1B;AAAA,MACJ,GAAG;AACH,mBAAa,kBAAkB,iBAAiB;AAAA,QAC9C,MAAM;AAAA;AAAA,MACR;AACA,UAAI,KAAK,uBAAwB,MAAM,kBAAmB;AACxD,qBAAa,KAAK;AAClB,aAAK,qBAAqB;AAAA,MAC5B,OAAO;AACL,aAAK,qBAAqB,MAAM;AAAA,MAClC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAgB,yBACd,eACA,WACA,UACe;AACf,QAAI,kBAAkB,OAAO;AAC3B,UAAI,OAAuB,SAAS,eAAe,QAAQ;AAC3D,UAAI,CAAC,MAAM;AACT,gBAAQ,KAAK,2CAA2C;AAAA,MAC1D;AACA,YAAM,eAAe,YAAY,eAAe;AAEhD,aAAO,MAAM,mBAAmB,QAAQ;AACxC,UAAI,EAAE,gBAAgB,eAAe;AACnC,gBAAQ,KAAK,kCAAkC;AAC/C;AAAA,MACF;AACA,WAAK,eAAe;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,WAAW,qBAA+B;AACxC,WAAO,CAAC,KAAK;AAAA,EACf;AACF;AAEA,mBAAmB,OAAO,qBAAqB,eAAe;;;ACjiBvD,IAAM,iBAAiB,IAAI,kBAAkB;AACpD,eAAe;AAAA,EACb;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoIF;AAEO,IAAM,4BAA4B,IAAI,kBAAkB;AAC/D,0BAA0B,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CA6BrC;;;ACvDM,SAAS,iBACd,SAAS,IACT,MAAc,SAAS,MACH;AAEpB,QAAM,eAAsD;AAAA,IAC1D,KAAK;AAAA,IACL,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,sBAAsB;AAAA,IACtB,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,EACf;AAEA,QAAM,SAAS,IAAI,IAAI,GAAG,EAAE;AAC5B,QAAM,SAA6B,CAAC;AACpC,aAAW,CAAC,UAAU,iBAAiB,KAAK,OAAO,QAAQ,YAAY,GAAG;AACxE,UAAM,aAAa,OAAO,IAAI,SAAS,QAAQ;AAC/C,QAAI,eAAe,MAAM;AAEvB,YAAM,YAAY,yBAAyB,iBAAiB;AAC5D,MAAC,OAAe,SAAS,IAAI;AAAA,IAC/B;AAAA,EACF;AACA,SAAO;AACT;;;ACzHA,IAAM,gCAAgC;AACtC,IAAM,gCAAgC;AAGtC,IAAM,sBAAyE;AAAA,EAC7E,kCAA8C,GAAG;AAAA,SAC/C,6BAA6B;AAAA,SAC7B,6BAA6B;AAAA;AAAA,EAE/B,0CAAqD,GAAG;AAAA,SACtD,6BAA6B;AAAA,SAC7B,6BAA6B;AAAA;AAAA,EAE/B,kCAA8C,GAAG;AAAA,SAC/C,6BAA6B;AAAA,SAC7B,6BAA6B;AAAA;AAAA,EAE/B,0CAAqD,GAAG;AAAA,SACtD,6BAA6B;AAAA,SAC7B,6BAA6B;AAAA;AAAA,EAE/B,gCAA6C,GAAG;AAAA;AAElD;AAUA,IAAM,kCAEF;AAAA,EACF,kCAA8C,GAAG;AAAA,EACjD,0CAAqD,GAAG;AAAA,EACxD,kCAA8C,GAAG;AAAA,EACjD,0CAAqD,GAAG;AAAA,EACxD,gCAA6C,GAAG;AAClD;AAEO,IAAM,cAAN,cAA0B,qBAAqB;AAAA,EAGpD,YACU,SAIR;AACA,UAAM,EAAE,MAAM,OAAO,CAAC;AALd;AAAA,EAMV;AAAA,EATA,eAAoC;AAAA,EACpC,IAA8B;AAAA,EAU9B,YAAY;AACV,SAAK,eAAe,cAAc;AAClC,QAAI,KAAK,GAAG;AACV,YAAM,OAAO,KAAK,eAAe;AAAA,QAC/B,SAAS,cAAc,MAAM;AAAA,MAC/B;AACA,WAAK,cAAc;AACnB,WAAK,QAAQ;AACb,WAAK,WAAW,KAAK,CAAC;AAAA,IACxB;AACA,SAAK,UAAU,cAAc;AAC7B,UAAM,WAAW,KAAK,OAAO,mBAAmB,QAAQ,cAAc;AACtE,QAAI,OAAO,aAAa,aAAa;AACnC,WAAK,OAAO,mBAAmB,OAAO,UAAU,WAAW,CAAC;AAAA,IAC9D;AACA,SAAK,wBAAwB,OAAO;AAAA,EACtC;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,MAAM,oBAAoB;AACxB,SAAK,qBAAqB,KAAK,WAAW,SAAS,cAAc,KAAK,CAAC;AACvE,SAAK,mBAAmB,UAAU,IAAI,oBAAoB;AAC1D,QAAI,KAAK,SAAS,gBAAgB,QAAQ;AACxC,WAAK,eAAe,UAAU,IAAI,WAAW;AAAA,IAC/C;AACA,SAAK,OAAO,cAAc;AAC1B,QAAI,KAAK,SAAS,gBAAgB;AAChC,WAAK,OAAO,yBAAyB;AAAA,IACvC;AACA,SAAK,IAAI,KAAK,cAAc,GAAG;AAC/B,QAAI,CAAC,KAAK,GAAG;AACX;AAAA,IACF;AAEA,UAAM,SAAS,iBAAiB,IAAI,KAAK,EAAE,IAAI;AAE/C,UAAM,OAAO,KAAK,GAAG;AACrB,UAAM,EAAE,UAAU,SAAS,IAAI,IAAI,IAAI,IAAI;AAE3C,QAAI,aAAa,qBAAqB;AACpC,WAAK,UAAU;AACf;AAAA,IACF;AACA,QAAI,CAAC,UAAU,WAAW,EAAE,SAAS,QAAQ,GAAG;AAC9C,YAAM,aAAa,aAAa;AAEhC,UAAI,OAAO,UAAU,EAAE,OAAO,UAAU,UAAU;AAChD,cAAM,qBACJ,MAAM,OAAO,6BAA0B,GACvC,2BAA2B,OAAO,MAAM;AAC1C,eAAO,OAAO;AACd,eAAO,gCAAgC;AAAA,MACzC;AAEA,WAAK,eAAe,KAAK,mBAAmB;AAAA,QAC1C,IAAI,aAAa;AAAA,UACf,YAAY,KAAK,SAAS,iBACtB,0BACA;AAAA,UACJ,aAAa,KAAK,SAAS,gBAAgB,SAAS,SAAS;AAAA,UAC7D,GAAG;AAAA,UACH,YAAY,aAAa,kCAAkC;AAAA,QAC7D,CAAC;AAAA,MACH;AACA,WAAK,aAAa,oBAAoB,KAAK;AAC3C,UAAI,OAAO,mBAAmB;AAC5B,aAAK,aAAa,oBAAoB,OAAO;AAAA,MAC/C;AAEA,WAAK,oBAAoB,KAAK,mBAAmB;AAAA,QAC/C,SAAS,cAAc,KAAK;AAAA,MAC9B;AACA,WAAK,kBAAkB,UAAU,IAAI,mBAAmB;AAExD,UAAI,OAAO,mBAAmB;AAC5B,aAAK,YAAY,OAAO,iBAAiB,EAAE,UAAU,IAAI,OAAO;AAAA,MAIlE;AAEA,UAAI,OAAO,sBAAsB;AAC/B,aAAK;AAAA,UACH;AAAA,UACA,aAEI,MAAM,KAAK,cAAc,kBAAkB,SAAS,IAAI,IACvD,IAAI,SAAS,KAAK;AAAA,QACzB;AAEA,cAAM,cAAc,KAAK,kBAAkB;AAAA,UACzC,SAAS,cAAc,KAAK;AAAA,QAC9B;AACA,oBAAY,UAAU,IAAI,WAAW;AACrC,oBAAY,cAAc,IAAI;AAAA,UAC5B,OAAO;AAAA,QACT,EAAE,SAAS;AAAA,MACb;AACA,YAAM,eAAe,KAAK;AAAA,QACxB;AAAA,QACA,aAEI,MAAM,KAAK,cAAc,kBAAkB,IAAI,IAAI,IAClD,IAAI,SAAS,KAAK;AAAA,MACzB;AAEA,WAAK,iBAAiB,aAAa;AAAA,QACjC,0BAA0B,KAAK,aAAa,iBAAiB;AAAA,MAC/D;AACA,WAAK,eAAe,UAAU,IAAI,YAAY;AAE9C,YAAM,kBAAkB,KAAK,kBAAkB;AAAA,QAC7C,IAAI,gBAAgB,EAAE,cAAc,KAAK,aAAa,CAAC;AAAA,MACzD;AACA,sBAAgB,KAAK,IAAI,mBAAmB;AAAA,IAC9C,OAAO;AACL,WAAK,UAAU;AAAA,IACjB;AAAA,EACF;AAAA,EAEA,YACE,MACA,eACa;AACb,UAAM,aAAa,KAAK,kBAAmB;AAAA,MACzC,SAAS,cAAc,KAAK;AAAA,IAC9B;AACA,eAAW,UAAU,IAAI,SAAS;AAElC,UAAM,cAAc,WAAW,YAAY,SAAS,cAAc,MAAM,CAAC;AACzE,gBAAY,cAAc;AAC1B,QAAI,eAAe;AACjB,kBAAY,eAAe;AAC3B,YAAM,IAAI,YAAY,YAAY,SAAS,cAAc,GAAG,CAAC;AAC7D,QAAE,cAAc;AAChB,QAAE,OAAO;AACT,QAAE,QAAQ;AACV,qBAAe,YAAYC,OAAc;AACvC,UAAE,cAAcA;AAChB,cAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,GAAI,CAAC;AACxD,YAAI,EAAE,gBAAgBA,OAAM;AAC1B,YAAE,cAAc;AAAA,QAClB;AAAA,MACF;AACA,QAAE,iBAAiB,SAAS,OAAO,MAAM;AACvC,UAAE,eAAe;AACjB,UAAE,cAAc;AAChB,cAAM,aAAa,MAAM,cAAc;AACvC,YAAI,YAAY;AACd,cAAI;AACF,kBAAM,UAAU,UAAU,UAAU,UAAU;AAC9C,iBAAK,YAAY,iBAAK;AAAA,UACxB,SAASC,IAAG;AACV,iBAAK,YAAY,iBAAK;AACtB,kBAAMA;AAAA,UACR;AAAA,QACF,OAAO;AACL,eAAK,YAAY,iBAAK;AAAA,QACxB;AAAA,MACF,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AACF;AAEA,mBAAmB,OAAO,gBAAgB,WAAW;AAO9C,SAAS,0BACd,OACA,OAAwB,SAAS,cAAc,MAAM,GACpC;AACjB,iBAAe,SAAS;AACtB,UAAM,CAAC,eAAe,YAAY,IAAI,MAAM,QAAQ,IAAI;AAAA,MACtD,MAAM,UAAU,IAAI;AAAA,MACpB,MAAM,aAAa,IAAI;AAAA,IACzB,CAAC;AACD,QAAI,cAAc,OAAO,OAAO,WAAW,GAAG;AAC5C,WAAK,cAAc;AACnB;AAAA,IACF;AACA,QAAI,gBAAgB;AACpB,aAAS,UAAU,QAAkC;AACnD,UAAI,eAAe;AACjB,wBAAgB;AAAA,MAClB,OAAO;AACL,aAAK,OAAO,IAAI;AAAA,MAClB;AACA,YAAM,OAAO,KAAK,YAAY,SAAS,cAAc,MAAM,CAAC;AAC5D,YAAM,YAAY;AAAA,QAChB;AAAA,QACA;AAAA,QACA,cAAc;AAAA,MAChB;AACA,WAAK,OAAO,GAAG,gCAAgC,MAAM,CAAC,IAAI;AAC1D,YAAM,aAAa,KAAK,YAAY,SAAS,cAAc,MAAM,CAAC;AAClE,iBAAW,cAAc,UAAU,SAAS;AAC5C,iBAAW,UAAU,IAAI,aAAa;AAEtC,WAAK,aAAa,eAAe,oBAAoB,MAAM,KAAK,EAAE;AAClE,WAAK,aAAa,SAAS,oBAAoB,MAAM,KAAK,EAAE;AAAA,IAC9D;AAEA,SAAK,cAAc;AACnB,QAAI,aAAa,OAAO,SAAS;AAC/B,iDAAuD;AACvD,yDAA8D;AAC9D,iDAAuD;AAAA,IACzD,WAAW,aAAa,IAAI;AAC1B,iDAAuD;AACvD,yDAA8D;AAAA,IAChE;AACA,6CAAsD;AACtD,SAAK,OAAO,GAAG;AAAA,EACjB;AACA,QAAM,UAAU,iBAAiB,MAAM;AACvC,QAAM,SAAS,iBAAiB,MAAM;AACtC,SAAO;AACT;",
3
+ "sources": ["../../../../src/cubing/twisty/controllers/indexer/AlgDuration.ts", "../../../../src/cubing/twisty/controllers/indexer/SimpleAlgIndexer.ts", "../../../../src/cubing/twisty/controllers/indexer/tree/AlgWalker.ts", "../../../../src/cubing/twisty/controllers/indexer/tree/chunkAlgs.ts", "../../../../src/cubing/twisty/controllers/indexer/tree/TreeAlgIndexer.ts", "../../../../src/cubing/twisty/model/props/viewer/BackViewProp.ts", "../../../../src/cubing/twisty/views/2D/TwistyAnimatedSVG.ts", "../../../../src/cubing/twisty/views/ClassListManager.ts", "../../../../src/cubing/twisty/model/helpers.ts", "../../../../src/cubing/twisty/controllers/AnimationTypes.ts", "../../../../src/cubing/twisty/controllers/TwistyAnimationController.ts", "../../../../src/cubing/twisty/controllers/TwistyPlayerController.ts", "../../../../src/cubing/twisty/model/props/viewer/ControlPanelProp.ts", "../../../../src/cubing/twisty/views/TwistyViewerWrapper.css.ts", "../../../../src/cubing/twisty/views/2D/Twisty2DPuzzle.css.ts", "../../../../src/cubing/twisty/views/2D/Twisty2DPuzzle.ts", "../../../../src/cubing/twisty/views/2D/Twisty2DPuzzleWrapper.ts", "../../../../src/cubing/twisty/views/2D/Twisty2DSceneWrapper.ts", "../../../../src/cubing/twisty/views/InitialValueTracker.ts", "../../../../src/cubing/twisty/views/3D/Twisty3DPuzzleWrapper.ts", "../../../../src/cubing/twisty/views/3D/Twisty3DSceneWrapper.ts", "../../../../src/cubing/twisty/views/document.ts", "../../../../src/cubing/twisty/views/control-panel/webkit-fullscreen.ts", "../../../../src/cubing/twisty/model/props/viewer/ButtonAppearanceProp.ts", "../../../../src/cubing/twisty/views/control-panel/TwistyButtons.css.ts", "../../../../src/cubing/twisty/views/control-panel/TwistyButtons.ts", "../../../../src/cubing/twisty/views/control-panel/TwistyScrubber.css.ts", "../../../../src/cubing/twisty/views/control-panel/TwistyScrubber.ts", "../../../../src/cubing/twisty/views/screenshot.ts", "../../../../src/cubing/twisty/views/TwistyPlayer.css.ts", "../../../../src/cubing/twisty/model/props/general/ArbitraryStringProp.ts", "../../../../src/cubing/twisty/model/props/general/URLProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/AlgProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/AlgTransformationProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/AnchorTransformationProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/AnimationTimelineLeavesRequestProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/CatchUpMoveProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/CurrentLeavesSimplified.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/CurrentMoveInfoProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/CurrentPatternProp.ts", "../../../../src/cubing/twisty/controllers/indexer/simultaneous-moves/simul-moves.ts", "../../../../src/cubing/twisty/controllers/indexer/simultaneous-moves/SimultaneousMoveIndexer.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/IndexerConstructorProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/IndexerConstructorRequestProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/IndexerProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/LegacyPositionProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/PuzzleAlgProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/SetupAnchorProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/SetupTransformationProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/structure/KPuzzleProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/structure/PuzzleDescriptionProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/structure/PuzzleIDProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/structure/PuzzleIDRequestProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/structure/PuzzleLoaderProp.ts", "../../../../src/cubing/twisty/model/props/timeline/CoarseTimelineInfoProp.ts", "../../../../src/cubing/twisty/model/props/timeline/DetailedTimelineInfoProp.ts", "../../../../src/cubing/twisty/model/props/timeline/PlayingInfoProp.ts", "../../../../src/cubing/twisty/model/props/timeline/TempoScaleProp.ts", "../../../../src/cubing/twisty/model/props/timeline/TimestampRequestProp.ts", "../../../../src/cubing/twisty/model/props/viewer/TimeRangeProp.ts", "../../../../src/cubing/twisty/model/props/viewer/ViewerLinkProp.ts", "../../../../src/cubing/twisty/model/props/viewer/VisualizationProp.ts", "../../../../src/cubing/twisty/model/props/viewer/VisualizationStrategyProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/display/FaceletScaleProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/display/FoundationDisplayProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/display/HintFaceletsElevationProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/display/InitialHintFaceletsAnimationProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/display/SpriteProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/display/StickeringMaskProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/display/parseSerializedStickeringMask.ts", "../../../../src/cubing/twisty/model/props/puzzle/display/StickeringMaskRequestProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/display/StickeringRequestProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/DragInputProp.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/MovePressCancelOptions.ts", "../../../../src/cubing/twisty/model/props/puzzle/state/MovePressInputProp.ts", "../../../../src/cubing/twisty/model/props/viewer/BackgroundProp.ts", "../../../../src/cubing/twisty/model/props/viewer/ColorSchemeProp.ts", "../../../../src/cubing/twisty/model/props/viewer/ColorSchemeRequestProp.ts", "../../../../src/cubing/twisty/model/props/viewer/DOMElementReferenceProp.ts", "../../../../src/cubing/twisty/model/props/viewer/LatitudeLimit.ts", "../../../../src/cubing/twisty/model/props/viewer/OrbitCoordinatesRequestProp.ts", "../../../../src/cubing/twisty/model/props/viewer/OrbitCoordinatesProp.ts", "../../../../src/cubing/twisty/model/TwistySceneModel.ts", "../../../../src/cubing/twisty/model/UserVisibleErrorTracker.ts", "../../../../src/cubing/twisty/model/TwistyPlayerModel.ts", "../../../../src/cubing/twisty/views/TwistyPlayerSettable.ts", "../../../../src/cubing/twisty/views/TwistyPlayer.ts", "../../../../src/cubing/twisty/views/TwistyAlgEditor/LeafTokens.ts", "../../../../src/cubing/twisty/views/TwistyAlgEditor/model.ts", "../../../../src/cubing/twisty/views/TwistyAlgEditor/paste.ts", "../../../../src/cubing/twisty/views/TwistyAlgEditor/TwistyAlgEditor.css.ts", "../../../../src/cubing/twisty/views/TwistyAlgEditor/TwistyAlgEditor.ts", "../../../../src/cubing/twisty/views/firstElementWithId.ts", "../../../../src/cubing/twisty/views/TwistyAlgViewer.css.ts", "../../../../src/cubing/twisty/views/TwistyAlgViewer.ts", "../../../../src/cubing/twisty/views/twizzle/TwizzleLink.css.ts", "../../../../src/cubing/twisty/views/twizzle/url-params.ts", "../../../../src/cubing/twisty/views/twizzle/TwizzleLink.ts"],
4
+ "sourcesContent": ["import {\n type Alg,\n type Commutator,\n type Conjugate,\n type Grouping,\n type LineComment,\n type Move,\n type Newline,\n type Pause,\n TraversalUp,\n} from \"../../../alg\";\nimport type { MillisecondDuration } from \"../AnimationTypes\";\n\nexport function constantDurationForAmount(\n _amount: number,\n): MillisecondDuration {\n return 1000 as MillisecondDuration;\n}\n\nexport function defaultDurationForAmount(amount: number): MillisecondDuration {\n switch (Math.abs(amount)) {\n case 0:\n return 0 as MillisecondDuration;\n case 1:\n return 1000 as MillisecondDuration;\n case 2:\n return 1500 as MillisecondDuration;\n default:\n return 2000 as MillisecondDuration;\n }\n}\nexport function ExperimentalScaledDefaultDurationForAmount(\n scale: number,\n amount: number,\n): MillisecondDuration {\n switch (Math.abs(amount)) {\n case 0:\n return 0 as MillisecondDuration;\n case 1:\n return (scale * 1000) as MillisecondDuration;\n case 2:\n return (scale * 1500) as MillisecondDuration;\n default:\n return (scale * 2000) as MillisecondDuration;\n }\n}\n\nexport class AlgDuration extends TraversalUp<MillisecondDuration> {\n // TODO: Pass durationForAmount as Down type instead?\n constructor(\n public durationForAmount: (\n amount: number,\n ) => MillisecondDuration = defaultDurationForAmount,\n ) {\n super();\n }\n\n public traverseAlg(alg: Alg): MillisecondDuration {\n let total = 0;\n for (const algNode of alg.childAlgNodes()) {\n total += this.traverseAlgNode(algNode);\n }\n return total as MillisecondDuration;\n }\n\n public traverseGrouping(grouping: Grouping): MillisecondDuration {\n return (grouping.amount *\n this.traverseAlg(grouping.alg)) as MillisecondDuration;\n }\n\n public traverseMove(move: Move): MillisecondDuration {\n return this.durationForAmount(move.amount);\n }\n\n public traverseCommutator(commutator: Commutator): MillisecondDuration {\n return (2 *\n (this.traverseAlg(commutator.A) +\n this.traverseAlg(commutator.B))) as MillisecondDuration;\n }\n\n public traverseConjugate(conjugate: Conjugate): MillisecondDuration {\n return (2 * this.traverseAlg(conjugate.A) +\n this.traverseAlg(conjugate.B)) as MillisecondDuration;\n }\n\n public traversePause(_pause: Pause): MillisecondDuration {\n return this.durationForAmount(1);\n }\n\n public traverseNewline(_newline: Newline): MillisecondDuration {\n return this.durationForAmount(1);\n }\n\n public traverseLineComment(_comment: LineComment): MillisecondDuration {\n return this.durationForAmount(0);\n }\n}\n", "import { Alg, type Move, type TraversalUp } from \"../../../alg\";\nimport type { KPuzzle, KTransformation } from \"../../../kpuzzle\";\nimport type { KPattern } from \"../../../kpuzzle/KPattern\";\nimport { experimentalCountAnimatedLeaves } from \"../../../notation\";\nimport type {\n MillisecondDuration,\n MillisecondTimestamp,\n} from \"../AnimationTypes\";\nimport { AlgDuration, defaultDurationForAmount } from \"./AlgDuration\";\nimport type { AlgIndexer, LeafCount, LeafIndex } from \"./AlgIndexer\";\n\nexport class SimpleAlgIndexer implements AlgIndexer {\n private moves: Alg;\n // TODO: Allow custom `durationFn`.\n private durationFn: TraversalUp<MillisecondDuration> = new AlgDuration(\n defaultDurationForAmount,\n );\n\n constructor(\n private kpuzzle: KPuzzle,\n alg: Alg,\n ) {\n // TODO: Avoid assuming all base moves are block moves.\n this.moves = new Alg(alg.experimentalExpand());\n }\n\n public getAnimLeaf(index: number): Move {\n return Array.from(this.moves.childAlgNodes())[index] as Move; // TODO: perf\n }\n\n public indexToMoveStartTimestamp(index: number): MillisecondTimestamp {\n const alg = new Alg(Array.from(this.moves.childAlgNodes()).slice(0, index)); // TODO\n return this.durationFn.traverseAlg(alg) as number as MillisecondTimestamp;\n }\n\n public timestampToIndex(timestamp: MillisecondTimestamp): LeafIndex {\n let cumulativeTime = 0;\n let i: number;\n for (i = 0; i < this.numAnimatedLeaves(); i++) {\n cumulativeTime += this.durationFn.traverseMove(this.getAnimLeaf(i));\n if (cumulativeTime >= timestamp) {\n return i as LeafIndex;\n }\n }\n return i as LeafIndex;\n }\n\n public patternAtIndex(index: number): KPattern {\n return this.kpuzzle\n .defaultPattern()\n .applyTransformation(this.transformationAtIndex(index));\n }\n\n public transformationAtIndex(index: number): KTransformation {\n let pattern = this.kpuzzle.identityTransformation();\n for (const move of Array.from(this.moves.childAlgNodes()).slice(0, index)) {\n // TODO\n pattern = pattern.applyMove(move as Move);\n }\n return pattern;\n }\n\n public algDuration(): MillisecondDuration {\n return this.durationFn.traverseAlg(this.moves);\n }\n\n public numAnimatedLeaves(): LeafCount {\n // TODO: Cache internally once performance matters.\n return experimentalCountAnimatedLeaves(this.moves) as LeafCount;\n }\n\n public moveDuration(index: LeafIndex): MillisecondDuration {\n return this.durationFn.traverseMove(this.getAnimLeaf(index));\n }\n}\n", "import {\n Alg,\n type AlgNode,\n type Commutator,\n type Conjugate,\n type Grouping,\n type LineComment,\n type Move,\n type Newline,\n type Pause,\n TraversalDownUp,\n TraversalUp,\n} from \"../../../../alg\";\nimport {\n ExperimentalIterationDirection,\n experimentalDirectedGenerator,\n} from \"../../../../alg/cubing-private\";\nimport type { KPuzzle, KTransformation } from \"../../../../kpuzzle\";\nimport type { MillisecondDuration } from \"../../AnimationTypes\";\nimport { AlgDuration, defaultDurationForAmount } from \"../AlgDuration\";\nimport type { LeafIndex as LeafCount } from \"../AlgIndexer\";\n\nexport class AlgWalkerDecoration {\n constructor(\n public moveCount: LeafCount,\n public duration: MillisecondDuration,\n public forward: KTransformation,\n public backward: KTransformation,\n public children: AlgWalkerDecoration[] = [],\n ) {}\n}\nexport class DecoratorConstructor extends TraversalUp<AlgWalkerDecoration> {\n private identity: KTransformation;\n private dummyLeaf: AlgWalkerDecoration;\n private durationFn: TraversalUp<MillisecondDuration> = new AlgDuration(\n defaultDurationForAmount,\n );\n\n private cache: { [key: string]: AlgWalkerDecoration } = {};\n\n constructor(private kpuzzle: KPuzzle) {\n super();\n this.identity = kpuzzle.identityTransformation();\n this.dummyLeaf = new AlgWalkerDecoration(\n 0 as LeafCount,\n 0 as MillisecondDuration,\n this.identity,\n this.identity,\n [],\n );\n }\n\n public traverseAlg(alg: Alg): AlgWalkerDecoration {\n let moveCount = 0 as LeafCount;\n let duration = 0 as MillisecondDuration;\n let transformation = this.identity;\n const child: AlgWalkerDecoration[] = [];\n for (const algNode of alg.childAlgNodes()) {\n const apd = this.traverseAlgNode(algNode);\n /** @ts-expect-error: ts(2322) Rewriting this would required duplicating `moveCount`. */\n moveCount += apd.moveCount;\n /** @ts-expect-error: ts(2322) Rewriting this would required duplicating `duration`. */\n duration += apd.duration;\n if (transformation === this.identity) {\n transformation = apd.forward;\n } else {\n transformation = transformation.applyTransformation(apd.forward);\n }\n child.push(apd);\n }\n return new AlgWalkerDecoration(\n moveCount,\n duration,\n transformation,\n transformation.invert(),\n child,\n );\n }\n\n public traverseGrouping(grouping: Grouping): AlgWalkerDecoration {\n const dec = this.traverseAlg(grouping.alg);\n return this.mult(dec, grouping.amount, [dec]);\n }\n\n public traverseMove(move: Move): AlgWalkerDecoration {\n const key = move.toString();\n let r: AlgWalkerDecoration | undefined = this.cache[key];\n if (r) {\n return r;\n }\n const transformation = this.kpuzzle.moveToTransformation(move);\n r = new AlgWalkerDecoration(\n 1 as LeafCount,\n this.durationFn.traverseAlgNode(move),\n transformation,\n transformation.invert(),\n );\n this.cache[key] = r;\n return r;\n }\n\n public traverseCommutator(commutator: Commutator): AlgWalkerDecoration {\n const decA = this.traverseAlg(commutator.A);\n const decB = this.traverseAlg(commutator.B);\n const AB = decA.forward.applyTransformation(decB.forward);\n const ApBp = decA.backward.applyTransformation(decB.backward);\n const ABApBp = AB.applyTransformation(ApBp);\n const dec = new AlgWalkerDecoration(\n (2 * (decA.moveCount + decB.moveCount)) as LeafCount,\n (2 * (decA.duration + decB.duration)) as MillisecondDuration,\n ABApBp,\n ABApBp.invert(),\n [decA, decB],\n );\n return this.mult(dec, 1, [dec, decA, decB]);\n }\n\n public traverseConjugate(conjugate: Conjugate): AlgWalkerDecoration {\n const decA = this.traverseAlg(conjugate.A);\n const decB = this.traverseAlg(conjugate.B);\n const AB = decA.forward.applyTransformation(decB.forward);\n const ABAp = AB.applyTransformation(decA.backward);\n const dec = new AlgWalkerDecoration(\n (2 * decA.moveCount + decB.moveCount) as LeafCount,\n (2 * decA.duration + decB.duration) as MillisecondDuration,\n ABAp,\n ABAp.invert(),\n [decA, decB],\n );\n return this.mult(dec, 1, [dec, decA, decB]);\n }\n\n public traversePause(pause: Pause): AlgWalkerDecoration {\n if (pause.experimentalNISSGrouping) {\n return this.dummyLeaf;\n }\n return new AlgWalkerDecoration(\n 1 as LeafCount,\n this.durationFn.traverseAlgNode(pause),\n this.identity,\n this.identity,\n );\n }\n\n public traverseNewline(_newline: Newline): AlgWalkerDecoration {\n return this.dummyLeaf;\n }\n\n public traverseLineComment(_comment: LineComment): AlgWalkerDecoration {\n return this.dummyLeaf;\n }\n\n private mult(\n apd: AlgWalkerDecoration,\n n: number,\n child: AlgWalkerDecoration[],\n ): AlgWalkerDecoration {\n const absn = Math.abs(n);\n const st = apd.forward.selfMultiply(n);\n return new AlgWalkerDecoration(\n (apd.moveCount * absn) as LeafCount,\n (apd.duration * absn) as MillisecondDuration,\n st,\n st.invert(),\n child,\n );\n }\n}\nclass WalkerDown {\n constructor(\n public apd: AlgWalkerDecoration,\n public back: boolean,\n ) {\n /**/\n }\n}\nexport class AlgWalker extends TraversalDownUp<WalkerDown, boolean> {\n public move?: AlgNode;\n public moveDuration: MillisecondDuration;\n public back: boolean;\n public st: KTransformation;\n public root: WalkerDown;\n public i: LeafCount;\n public dur: MillisecondDuration;\n private goalIndex: LeafCount;\n private goalDuration: MillisecondDuration;\n constructor(\n public kpuzzle: KPuzzle,\n public algOrAlgNode: Alg | AlgNode, // TODO: can we keep these separate?\n public apd: AlgWalkerDecoration,\n ) {\n super();\n this.i = -1 as LeafCount;\n this.dur = -1 as MillisecondDuration;\n this.goalIndex = -1 as LeafCount;\n this.goalDuration = -1 as MillisecondDuration;\n this.move = undefined;\n this.back = false;\n this.moveDuration = 0 as MillisecondDuration;\n this.st = this.kpuzzle.identityTransformation();\n this.root = new WalkerDown(this.apd, false);\n }\n\n public moveByIndex(loc: LeafCount): boolean {\n if (this.i >= 0 && this.i === loc) {\n return this.move !== undefined;\n }\n return this.dosearch(loc, Infinity as MillisecondDuration);\n }\n\n public moveByDuration(dur: MillisecondDuration): boolean {\n if (\n this.dur >= 0 &&\n this.dur < dur &&\n this.dur + this.moveDuration >= dur\n ) {\n return this.move !== undefined;\n }\n return this.dosearch(Infinity as LeafCount, dur);\n }\n\n public dosearch(loc: LeafCount, dur: MillisecondDuration): boolean {\n this.goalIndex = loc;\n this.goalDuration = dur;\n this.i = 0 as LeafCount;\n this.dur = 0 as MillisecondDuration;\n this.move = undefined;\n this.moveDuration = 0 as MillisecondDuration;\n this.back = false;\n this.st = this.kpuzzle.identityTransformation();\n const r = this.algOrAlgNode.is(Alg)\n ? this.traverseAlg(this.algOrAlgNode as Alg, this.root)\n : this.traverseAlgNode(this.algOrAlgNode as AlgNode, this.root); // TODO\n return r;\n }\n\n public traverseAlg(alg: Alg, wd: WalkerDown): boolean {\n if (!this.firstcheck(wd)) {\n return false;\n }\n let i = wd.back ? alg.experimentalNumChildAlgNodes() - 1 : 0;\n for (const algNode of experimentalDirectedGenerator(\n alg.childAlgNodes(),\n wd.back\n ? ExperimentalIterationDirection.Backwards\n : ExperimentalIterationDirection.Forwards,\n )) {\n if (\n this.traverseAlgNode(\n algNode,\n new WalkerDown(wd.apd.children[i], wd.back),\n )\n ) {\n return true;\n }\n i += wd.back ? -1 : 1;\n }\n return false;\n }\n\n public traverseGrouping(grouping: Grouping, wd: WalkerDown): boolean {\n if (!this.firstcheck(wd)) {\n return false;\n }\n const back = this.domult(wd, grouping.amount);\n return this.traverseAlg(\n grouping.alg,\n new WalkerDown(wd.apd.children[0], back),\n );\n }\n\n public traverseMove(move: Move, wd: WalkerDown): boolean {\n if (!this.firstcheck(wd)) {\n return false;\n }\n this.move = move;\n this.moveDuration = wd.apd.duration;\n this.back = wd.back;\n return true;\n }\n\n public traverseCommutator(commutator: Commutator, wd: WalkerDown): boolean {\n if (!this.firstcheck(wd)) {\n return false;\n }\n const back = this.domult(wd, 1);\n if (back) {\n return (\n this.traverseAlg(\n commutator.B,\n new WalkerDown(wd.apd.children[2], !back),\n ) ||\n this.traverseAlg(\n commutator.A,\n new WalkerDown(wd.apd.children[1], !back),\n ) ||\n this.traverseAlg(\n commutator.B,\n new WalkerDown(wd.apd.children[2], back),\n ) ||\n this.traverseAlg(commutator.A, new WalkerDown(wd.apd.children[1], back))\n );\n } else {\n return (\n this.traverseAlg(\n commutator.A,\n new WalkerDown(wd.apd.children[1], back),\n ) ||\n this.traverseAlg(\n commutator.B,\n new WalkerDown(wd.apd.children[2], back),\n ) ||\n this.traverseAlg(\n commutator.A,\n new WalkerDown(wd.apd.children[1], !back),\n ) ||\n this.traverseAlg(\n commutator.B,\n new WalkerDown(wd.apd.children[2], !back),\n )\n );\n }\n }\n\n public traverseConjugate(conjugate: Conjugate, wd: WalkerDown): boolean {\n if (!this.firstcheck(wd)) {\n return false;\n }\n const back = this.domult(wd, 1);\n if (back) {\n return (\n this.traverseAlg(\n conjugate.A,\n new WalkerDown(wd.apd.children[1], !back),\n ) ||\n this.traverseAlg(\n conjugate.B,\n new WalkerDown(wd.apd.children[2], back),\n ) ||\n this.traverseAlg(conjugate.A, new WalkerDown(wd.apd.children[1], back))\n );\n } else {\n return (\n this.traverseAlg(\n conjugate.A,\n new WalkerDown(wd.apd.children[1], back),\n ) ||\n this.traverseAlg(\n conjugate.B,\n new WalkerDown(wd.apd.children[2], back),\n ) ||\n this.traverseAlg(conjugate.A, new WalkerDown(wd.apd.children[1], !back))\n );\n }\n }\n\n public traversePause(pause: Pause, wd: WalkerDown): boolean {\n if (!this.firstcheck(wd)) {\n return false;\n }\n this.move = pause;\n this.moveDuration = wd.apd.duration;\n this.back = wd.back;\n return true;\n }\n\n public traverseNewline(_newline: Newline, _wd: WalkerDown): boolean {\n return false;\n }\n\n public traverseLineComment(\n _lineComment: LineComment,\n _wd: WalkerDown,\n ): boolean {\n return false;\n }\n\n private firstcheck(wd: WalkerDown): boolean {\n if (\n wd.apd.moveCount + this.i <= this.goalIndex &&\n wd.apd.duration + this.dur < this.goalDuration\n ) {\n return this.keepgoing(wd);\n }\n return true;\n }\n\n private domult(wd: WalkerDown, amount: number): boolean {\n let back = wd.back;\n if (amount === 0) {\n // I don't believe this will ever happen\n return back;\n }\n if (amount < 0) {\n back = !back;\n amount = -amount;\n }\n const base = wd.apd.children[0];\n const full = Math.min(\n Math.floor((this.goalIndex - this.i) / base.moveCount),\n Math.ceil((this.goalDuration - this.dur) / base.duration - 1),\n );\n if (full > 0) {\n this.keepgoing(new WalkerDown(base, back), full);\n }\n return back;\n }\n\n private keepgoing(wd: WalkerDown, mul: number = 1): boolean {\n /** @ts-expect-error: ts(2322) Rewriting this would required duplicating `this.i`. */\n this.i += (mul * wd.apd.moveCount) as LeafCount;\n /** @ts-expect-error: ts(2322) Rewriting this would required duplicating `this.dur`. */\n this.dur += (mul * wd.apd.duration) as MillisecondDuration;\n if (mul !== 1) {\n if (wd.back) {\n this.st = this.st.applyTransformation(\n wd.apd.backward.selfMultiply(mul),\n );\n } else {\n this.st = this.st.applyTransformation(wd.apd.forward.selfMultiply(mul));\n }\n } else {\n if (wd.back) {\n this.st = this.st.applyTransformation(wd.apd.backward);\n } else {\n this.st = this.st.applyTransformation(wd.apd.forward);\n }\n }\n return false;\n }\n}\n", "import {\n type Alg,\n AlgBuilder,\n type AlgNode,\n type Commutator,\n Conjugate,\n functionFromTraversal,\n Grouping,\n type LineComment,\n type Move,\n type Newline,\n type Pause,\n TraversalUp,\n} from \"../../../../alg\";\n\nconst MIN_CHUNKING_THRESHOLD = 16;\n\nfunction chunkifyAlg(alg: Alg, chunkMaxLength: number): Alg {\n const mainAlgBuilder = new AlgBuilder();\n const chunkAlgBuilder = new AlgBuilder();\n for (const algNode of alg.childAlgNodes()) {\n chunkAlgBuilder.push(algNode);\n if (chunkAlgBuilder.experimentalNumAlgNodes() >= chunkMaxLength) {\n mainAlgBuilder.push(new Grouping(chunkAlgBuilder.toAlg()));\n chunkAlgBuilder.reset();\n }\n }\n mainAlgBuilder.push(new Grouping(chunkAlgBuilder.toAlg()));\n return mainAlgBuilder.toAlg();\n}\n\nclass ChunkAlgs extends TraversalUp<Alg, AlgNode> {\n traverseAlg(alg: Alg): Alg {\n const algLength = alg.experimentalNumChildAlgNodes();\n if (algLength < MIN_CHUNKING_THRESHOLD) {\n return alg;\n }\n return chunkifyAlg(alg, Math.ceil(Math.sqrt(algLength)));\n }\n\n traverseGrouping(grouping: Grouping): AlgNode {\n return new Grouping(\n this.traverseAlg(grouping.alg),\n grouping.amount, // TODO\n );\n }\n\n traverseMove(move: Move): AlgNode {\n return move;\n }\n\n traverseCommutator(commutator: Commutator): AlgNode {\n return new Conjugate(\n this.traverseAlg(commutator.A),\n this.traverseAlg(commutator.B),\n );\n }\n\n traverseConjugate(conjugate: Conjugate): AlgNode {\n return new Conjugate(\n this.traverseAlg(conjugate.A),\n this.traverseAlg(conjugate.B),\n );\n }\n\n traversePause(pause: Pause): AlgNode {\n return pause;\n }\n\n traverseNewline(newline: Newline): AlgNode {\n return newline;\n }\n\n traverseLineComment(comment: LineComment): AlgNode {\n return comment;\n }\n}\n\nexport const chunkAlgs = functionFromTraversal(ChunkAlgs);\n", "import type { Alg, Move } from \"../../../../alg\";\nimport type { KPuzzle, KTransformation } from \"../../../../kpuzzle\";\nimport type { KPattern } from \"../../../../kpuzzle/KPattern\";\nimport type {\n MillisecondDuration,\n MillisecondTimestamp,\n} from \"../../AnimationTypes\";\nimport type { AlgIndexer, LeafCount, LeafIndex } from \"../AlgIndexer\";\nimport {\n AlgWalker,\n type AlgWalkerDecoration,\n DecoratorConstructor,\n} from \"./AlgWalker\";\nimport { chunkAlgs } from \"./chunkAlgs\";\n\nexport class TreeAlgIndexer implements AlgIndexer {\n private decoration: AlgWalkerDecoration;\n private walker: AlgWalker;\n constructor(\n private kpuzzle: KPuzzle,\n alg: Alg,\n ) {\n const deccon = new DecoratorConstructor(this.kpuzzle);\n\n const chunkedAlg = chunkAlgs(alg);\n\n this.decoration = deccon.traverseAlg(chunkedAlg);\n this.walker = new AlgWalker(this.kpuzzle, chunkedAlg, this.decoration);\n }\n\n public getAnimLeaf(index: LeafIndex): Move | null {\n // FIXME need to support Pause\n if (this.walker.moveByIndex(index)) {\n if (!this.walker.move) {\n throw new Error(\"`this.walker.mv` missing\");\n }\n const move = this.walker.move as Move;\n // TODO: this type of negation needs to be in alg\n if (this.walker.back) {\n return move.invert();\n }\n return move;\n }\n return null;\n }\n\n public indexToMoveStartTimestamp(index: LeafIndex): MillisecondTimestamp {\n if (this.walker.moveByIndex(index) || this.walker.i === index) {\n return this.walker.dur as number as MillisecondTimestamp; // TODO\n }\n throw new Error(`Out of algorithm: index ${index}`);\n }\n\n public indexToMovesInProgress(index: LeafIndex): MillisecondTimestamp {\n if (this.walker.moveByIndex(index) || this.walker.i === index) {\n return this.walker.dur as number as MillisecondTimestamp; // TODO\n }\n throw new Error(`Out of algorithm: index ${index}`);\n }\n\n public patternAtIndex(index: LeafIndex, startPattern?: KPattern): KPattern {\n this.walker.moveByIndex(index);\n return (startPattern ?? this.kpuzzle.defaultPattern()).applyTransformation(\n this.walker.st,\n );\n }\n\n // TransformAtIndex does not reflect the start pattern; it only reflects\n // the change from the start pattern to the current move index. If you\n // want the actual pattern, use patternAtIndex.\n public transformationAtIndex(index: LeafIndex): KTransformation {\n this.walker.moveByIndex(index);\n return this.walker.st;\n }\n\n public numAnimatedLeaves(): LeafCount {\n return this.decoration.moveCount as number as LeafCount; // TODO: This should not need any casting?\n }\n\n public timestampToIndex(timestamp: MillisecondTimestamp): LeafIndex {\n this.walker.moveByDuration(timestamp as number as MillisecondDuration); // TODO\n return this.walker.i;\n }\n\n public algDuration(): MillisecondDuration {\n return this.decoration.duration;\n }\n\n public moveDuration(index: LeafIndex): MillisecondDuration {\n this.walker.moveByIndex(index);\n return this.walker.moveDuration;\n }\n}\n", "import { SimpleTwistyPropSource } from \"../TwistyProp\";\n\nexport const backViewLayouts = {\n none: true, // default\n \"side-by-side\": true,\n \"top-right\": true,\n};\nexport type BackViewLayout = keyof typeof backViewLayouts;\n\nexport type BackViewLayoutWithAuto = BackViewLayout | \"auto\";\n\nexport class BackViewProp extends SimpleTwistyPropSource<BackViewLayoutWithAuto> {\n getDefaultValue(): BackViewLayoutWithAuto {\n return \"auto\";\n }\n}\n", "import type { KPuzzle } from \"../../../kpuzzle\";\nimport type { KPattern } from \"../../../kpuzzle/KPattern\";\nimport type {\n FaceletMeshStickeringMask,\n StickeringMask,\n} from \"../../../puzzles/stickerings/mask\"; // TODO\n\nconst xmlns = \"http://www.w3.org/2000/svg\";\nconst DATA_COPY_ID_ATTRIBUTE = \"data-copy-id\";\n\n// Unique ID mechanism to keep SVG gradient element IDs unique. TODO: Is there\n// something more performant, and that can't be broken by other elements of the\n// page? (And also doesn't break if this library is run in parallel.)\nlet svgCounter = 0;\nfunction nextSVGID(): string {\n svgCounter += 1;\n return `svg${svgCounter.toString()}`;\n}\n\n// TODO: This is hardcoded to 3x3x3 SVGs\nconst colorMaps: Partial<\n Record<FaceletMeshStickeringMask, string | Record<string, string>>\n> = {\n dim: {\n white: \"#dddddd\",\n orange: \"#884400\",\n limegreen: \"#008800\",\n red: \"#660000\",\n \"rgb(34, 102, 255)\": \"#000088\", // TODO\n yellow: \"#888800\",\n \"rgb(102, 0, 153)\": \"rgb(50, 0, 76)\",\n purple: \"#3f003f\",\n },\n oriented: \"#44ddcc\",\n ignored: \"#555555\",\n invisible: \"#00000000\",\n};\n\nexport class TwistyAnimatedSVG {\n public wrapperElement: HTMLElement;\n public svgElement: SVGElement;\n public gradientDefs: SVGDefsElement;\n private originalColors: { [type: string]: string } = {};\n private gradients: { [type: string]: SVGGradientElement } = {};\n private svgID: string;\n constructor(\n public kpuzzle: KPuzzle,\n svgSource: string,\n experimentalStickeringMask?: StickeringMask,\n private showUnknownOrientations: boolean = false,\n ) {\n if (!svgSource) {\n throw new Error(`No SVG definition for puzzle type: ${kpuzzle.name()}`);\n }\n\n this.svgID = nextSVGID();\n\n this.wrapperElement = document.createElement(\"div\");\n this.wrapperElement.classList.add(\"svg-wrapper\");\n // TODO: Sanitization.\n this.wrapperElement.innerHTML = svgSource;\n\n const svgElem = this.wrapperElement.querySelector(\"svg\");\n if (!svgElem) {\n throw new Error(\"Could not get SVG element\");\n }\n this.svgElement = svgElem;\n if (xmlns !== svgElem.namespaceURI) {\n throw new Error(\"Unexpected XML namespace\");\n }\n svgElem.style.maxWidth = \"100%\";\n svgElem.style.maxHeight = \"100%\";\n this.gradientDefs = document.createElementNS(xmlns, \"defs\");\n svgElem.insertBefore(this.gradientDefs, svgElem.firstChild);\n\n for (const orbitDefinition of kpuzzle.definition.orbits) {\n for (let idx = 0; idx < orbitDefinition.numPieces; idx++) {\n for (\n let orientation = 0;\n orientation < orbitDefinition.numOrientations;\n orientation++\n ) {\n const id = this.elementID(\n orbitDefinition.orbitName,\n idx,\n orientation,\n );\n const elem = this.elementByID(id);\n\n let originalColor: string = elem?.style.fill;\n /// TODO: Allow setting stickering mask dynamically.\n if (experimentalStickeringMask) {\n (() => {\n // TODO: dedup with Cube3D,,factor out fallback calculations\n const a = experimentalStickeringMask.orbits;\n if (!a) {\n return;\n }\n const orbitStickeringMask = a[orbitDefinition.orbitName];\n if (!orbitStickeringMask) {\n return;\n }\n const pieceStickeringMask = orbitStickeringMask.pieces[idx];\n if (!pieceStickeringMask) {\n return;\n }\n const faceletStickeringMasks =\n pieceStickeringMask.facelets[orientation];\n if (!faceletStickeringMasks) {\n return;\n }\n const stickeringMask =\n typeof faceletStickeringMasks === \"string\"\n ? faceletStickeringMasks\n : faceletStickeringMasks?.mask;\n const colorMap = colorMaps[stickeringMask];\n if (typeof colorMap === \"string\") {\n originalColor = colorMap;\n } else if (colorMap) {\n originalColor = colorMap[originalColor];\n }\n })();\n } else {\n originalColor = elem?.style.fill;\n }\n this.originalColors[id] = originalColor;\n this.gradients[id] = this.newGradient(id, originalColor);\n this.gradientDefs.appendChild(this.gradients[id]);\n elem?.setAttribute(\"style\", `fill: url(#grad-${this.svgID}-${id})`);\n }\n }\n }\n\n for (const hintElem of Array.from(\n svgElem.querySelectorAll(`[${DATA_COPY_ID_ATTRIBUTE}]`),\n )) {\n const id = hintElem.getAttribute(DATA_COPY_ID_ATTRIBUTE);\n hintElem.setAttribute(\"style\", `fill: url(#grad-${this.svgID}-${id})`);\n }\n\n if (this.showUnknownOrientations) {\n this.drawPattern(this.kpuzzle.defaultPattern());\n }\n }\n\n public drawPattern(\n pattern: KPattern,\n nextPattern?: KPattern,\n fraction?: number,\n ): void {\n this.draw(pattern, nextPattern, fraction);\n }\n\n // TODO: save definition in the constructor?\n public draw(\n pattern: KPattern,\n nextPattern?: KPattern,\n fraction?: number,\n ): void {\n const nextTransformation = nextPattern?.experimentalToTransformation();\n if (!pattern) {\n throw new Error(\"Distinguishable pieces are not handled for SVG yet!\");\n }\n\n for (const orbitDefinition of pattern.kpuzzle.definition.orbits) {\n const currentPatternOrbit =\n pattern.patternData[orbitDefinition.orbitName];\n const nextTransformationOrbit = nextTransformation\n ? nextTransformation.transformationData[orbitDefinition.orbitName]\n : null;\n for (let idx = 0; idx < orbitDefinition.numPieces; idx++) {\n for (\n let orientation = 0;\n orientation < orbitDefinition.numOrientations;\n orientation++\n ) {\n const id = this.elementID(\n orbitDefinition.orbitName,\n idx,\n orientation,\n );\n const fromCur = this.elementID(\n orbitDefinition.orbitName,\n currentPatternOrbit.pieces[idx],\n (orbitDefinition.numOrientations -\n currentPatternOrbit.orientation[idx] +\n orientation) %\n orbitDefinition.numOrientations,\n );\n let singleColor = false;\n if (nextTransformationOrbit) {\n const fromNext = this.elementID(\n orbitDefinition.orbitName,\n nextTransformationOrbit.permutation[idx],\n (orbitDefinition.numOrientations -\n nextTransformationOrbit.orientationDelta[idx] +\n orientation) %\n orbitDefinition.numOrientations,\n );\n if (fromCur === fromNext) {\n singleColor = true; // TODO: Avoid redundant work during move.\n }\n fraction = fraction || 0; // TODO Use the type system to tie this to nextPattern?\n const easedBackwardsPercent =\n 100 * (1 - fraction * fraction * (2 - fraction * fraction)); // TODO: Move easing up the stack.\n this.gradients[id].children[0].setAttribute(\n \"stop-color\",\n this.originalColors[fromCur],\n );\n this.gradients[id].children[0].setAttribute(\n \"offset\",\n `${Math.max(easedBackwardsPercent - 5, 0)}%`,\n );\n this.gradients[id].children[1].setAttribute(\n \"offset\",\n `${Math.max(easedBackwardsPercent - 5, 0)}%`,\n );\n this.gradients[id].children[2].setAttribute(\n \"offset\",\n `${easedBackwardsPercent}%`,\n );\n this.gradients[id].children[3].setAttribute(\n \"offset\",\n `${easedBackwardsPercent}%`,\n );\n this.gradients[id].children[3].setAttribute(\n \"stop-color\",\n this.originalColors[fromNext],\n );\n } else {\n singleColor = true; // TODO: Avoid redundant work during move.\n }\n if (singleColor) {\n if (\n this.showUnknownOrientations &&\n currentPatternOrbit.orientationMod?.[idx] === 1\n ) {\n this.gradients[id].children[0].setAttribute(\"stop-color\", \"#000\");\n this.gradients[id].children[0].setAttribute(\"offset\", \"5%\");\n this.gradients[id].children[1].setAttribute(\"offset\", \"5%\");\n this.gradients[id].children[2].setAttribute(\"offset\", \"20%\");\n this.gradients[id].children[3].setAttribute(\"offset\", \"20%\");\n this.gradients[id].children[3].setAttribute(\n \"stop-color\",\n this.originalColors[fromCur],\n );\n } else {\n this.gradients[id].children[0].setAttribute(\n \"stop-color\",\n this.originalColors[fromCur],\n );\n this.gradients[id].children[0].setAttribute(\"offset\", \"100%\");\n this.gradients[id].children[1].setAttribute(\"offset\", \"100%\");\n this.gradients[id].children[2].setAttribute(\"offset\", \"100%\");\n this.gradients[id].children[3].setAttribute(\"offset\", \"100%\");\n }\n }\n // this.gradients[id]\n // this.elementByID(id).style.fill = this.originalColors[from];\n }\n }\n }\n }\n\n private newGradient(id: string, originalColor: string): SVGGradientElement {\n const grad = document.createElementNS(\n xmlns,\n \"radialGradient\",\n ) as SVGGradientElement;\n grad.setAttribute(\"id\", `grad-${this.svgID}-${id}`);\n grad.setAttribute(\"r\", \"70.7107%\"); // TODO: Adapt to puzzle.\n const stopDefs = [\n { offset: 0, color: originalColor },\n { offset: 0, color: \"black\" },\n { offset: 0, color: \"black\" },\n { offset: 0, color: originalColor },\n ];\n for (const stopDef of stopDefs) {\n const stop = document.createElementNS(xmlns, \"stop\");\n stop.setAttribute(\"offset\", `${stopDef.offset}%`);\n stop.setAttribute(\"stop-color\", stopDef.color);\n stop.setAttribute(\"stop-opacity\", \"1\");\n grad.appendChild(stop);\n }\n return grad;\n }\n\n private elementID(\n orbitName: string,\n idx: number,\n orientation: number,\n ): string {\n return `${orbitName}-l${idx}-o${orientation}`;\n }\n\n private elementByID(id: string): HTMLElement {\n // TODO: Use classes and scope selector to SVG element.\n return this.wrapperElement.querySelector(`#${id}`) as HTMLElement;\n }\n}\n", "import type { ManagedCustomElement } from \"./ManagedCustomElement\";\n\nexport class ClassListManager<SuffixType extends string> {\n #currentClassName: string | null = null;\n // The prefix should ideally end in a dash.\n constructor(\n private elem: ManagedCustomElement,\n private prefix: string,\n private validSuffixes: SuffixType[],\n ) {}\n\n // Does nothing if there was no value.\n clearValue(): void {\n if (this.#currentClassName) {\n this.elem.contentWrapper.classList.remove(this.#currentClassName);\n }\n this.#currentClassName = null; // TODO: add test for this behaviour.\n }\n\n // Returns if the value changed\n setValue(suffix: SuffixType): boolean {\n if (!this.validSuffixes.includes(suffix)) {\n throw new Error(`Invalid suffix: ${suffix}`);\n }\n const newClassName = `${this.prefix}${suffix}`;\n const changed = this.#currentClassName !== newClassName;\n if (changed) {\n this.clearValue();\n this.elem.contentWrapper.classList.add(newClassName);\n this.#currentClassName = newClassName;\n }\n return changed;\n }\n}\n", "import { offsetMod } from \"../../alg/cubing-private\";\n\nexport function arrayEquals<T>(a: readonly T[], b: readonly T[]): boolean {\n if (a === b) {\n return true;\n }\n if (a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) {\n return false;\n }\n }\n return true;\n}\n\nexport function arrayEqualsCompare<T>(\n a: readonly T[],\n b: readonly T[],\n compare: (a: T, b: T) => boolean,\n): boolean {\n if (a === b) {\n return true;\n }\n if (a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i++) {\n if (!compare(a[i], b[i])) {\n return false;\n }\n }\n return true;\n}\n\nexport function modIntoRange(\n v: number,\n rangeMin: number,\n rangeMax: number,\n): number {\n return offsetMod(v, rangeMax - rangeMin, rangeMin);\n}\n", "import type { Tagged } from \"type-fest\";\nimport type { Move } from \"../../alg\";\nimport type { KPattern } from \"../../kpuzzle/KPattern\";\n\nexport type MillisecondTimestamp = Tagged<\n DOMHighResTimeStamp,\n \"MillisecondTimestamp\"\n>;\n\n// TODO: unify duration/timstamp types\nexport type MillisecondDuration = Tagged<number, \"MillisecondDuration\">; // Duration in milliseconds\n// TODO: Extend `number`, introduce MoveSequenceTimestamp vs. EpochTimestamp,\n// force Duration to be a difference.\n\nexport type Fraction = number; // Value from 0 to 1.\n\n// 1, 0, -1 are used as scalars for `directionScalar` below.\nexport enum Direction {\n Forwards = 1,\n Paused = 0,\n Backwards = -1,\n}\n\nexport function directionScalar(direction: Direction): number {\n return direction;\n}\n\nexport interface MoveInProgress {\n move: Move;\n direction: Direction;\n fraction: number;\n}\n\nexport type PuzzlePosition = {\n pattern: KPattern;\n movesInProgress: MoveInProgress[];\n};\n\nexport enum BoundaryType {\n Move = \"move\",\n EntireTimeline = \"entire-timeline\",\n}\n\nexport interface TimeRange {\n start: MillisecondTimestamp;\n end: MillisecondTimestamp;\n}\n\n// export type DurationForAmount = (amount: number) => Duration;\n\nexport interface PositionListener {\n onPositionChange(position: PuzzlePosition): void;\n}\n", "import { modIntoRange } from \"../model/helpers\";\nimport { StaleDropper } from \"../model/PromiseFreshener\";\nimport type { CatchUpMove } from \"../model/props/puzzle/state/CatchUpMoveProp\";\nimport type {\n PlayingInfo,\n SimpleDirection,\n} from \"../model/props/timeline/PlayingInfoProp\";\nimport type { TimestampRequest } from \"../model/props/timeline/TimestampRequestProp\";\nimport type { TwistyPlayerModel } from \"../model/TwistyPlayerModel\";\nimport {\n BoundaryType,\n Direction,\n directionScalar,\n type MillisecondTimestamp,\n type TimeRange,\n} from \"./AnimationTypes\";\nimport type { CurrentMoveInfo } from \"./indexer/AlgIndexer\";\nimport { RenderScheduler } from \"./RenderScheduler\";\n\n// TODO: Figure out a better way for the controller to instruct the player.\nexport interface TwistyAnimationControllerDelegate {\n flash(): void;\n}\n\n// We use a separate helper to separate the anim frame callbacks (and their cancellations).\n// TODO: fold this into the main controller\nclass CatchUpHelper {\n catchingUp: boolean = false;\n pendingFrame = false;\n\n tempoScale: number = 1; // TODO\n constructor(private model: TwistyPlayerModel) {\n model.tempoScale.addFreshListener((tempoScale) => {\n this.tempoScale = tempoScale;\n });\n }\n\n private scheduler: RenderScheduler = new RenderScheduler(\n this.animFrame.bind(this),\n );\n\n start(): void {\n if (!this.catchingUp) {\n this.lastTimestamp = performance.now();\n }\n this.catchingUp = true;\n this.pendingFrame = true;\n this.scheduler.requestAnimFrame();\n }\n\n stop(): void {\n this.catchingUp = false;\n this.scheduler.cancelAnimFrame();\n }\n\n catchUpMs = 500;\n lastTimestamp = 0;\n animFrame(timestamp: MillisecondTimestamp): void {\n this.scheduler.requestAnimFrame();\n const delta =\n (this.tempoScale * (timestamp - this.lastTimestamp)) / this.catchUpMs;\n this.lastTimestamp = timestamp;\n\n this.model.catchUpMove.set(\n (async (): Promise<CatchUpMove> => {\n const previousCatchUpMove = await this.model.catchUpMove.get();\n if (previousCatchUpMove.move === null) {\n return previousCatchUpMove;\n }\n\n const amount = previousCatchUpMove.amount + delta; // TODO: use tempo scale?\n if (amount >= 1) {\n this.pendingFrame = true;\n this.stop();\n this.model.timestampRequest.set(\"end\");\n return {\n move: null,\n amount: 0,\n };\n }\n this.pendingFrame = false;\n return {\n move: previousCatchUpMove.move,\n amount: amount,\n };\n })(),\n );\n }\n}\n\n// This controls the logic for animation, so that the main controller can focus on the right API abstractions.\nexport class TwistyAnimationController {\n // TODO: #private?\n private playing: boolean = false;\n private direction: Direction = Direction.Forwards;\n\n private catchUpHelper: CatchUpHelper;\n\n private model: TwistyPlayerModel;\n\n private lastDatestamp: MillisecondTimestamp = 0 as MillisecondTimestamp;\n private lastTimestampPromise: Promise<MillisecondTimestamp>;\n\n private scheduler: RenderScheduler = new RenderScheduler(\n this.animFrame.bind(this),\n );\n\n constructor(\n model: TwistyPlayerModel,\n private delegate: TwistyAnimationControllerDelegate,\n ) {\n this.model = model;\n this.lastTimestampPromise = this.#effectiveTimestampMilliseconds();\n\n this.model.playingInfo.addFreshListener(this.onPlayingProp.bind(this)); // TODO\n\n this.catchUpHelper = new CatchUpHelper(this.model);\n this.model.catchUpMove.addFreshListener(this.onCatchUpMoveProp.bind(this)); // TODO\n }\n\n // TODO: Do we need this?\n async onPlayingProp(playingInfo: PlayingInfo): Promise<void> {\n if (playingInfo.playing !== this.playing) {\n playingInfo.playing ? this.play(playingInfo) : this.pause();\n }\n }\n\n // TODO: Do we need this?\n async onCatchUpMoveProp(catchUpMove: CatchUpMove): Promise<void> {\n const catchingUp = catchUpMove.move !== null;\n if (catchingUp !== this.catchUpHelper.catchingUp) {\n catchingUp ? this.catchUpHelper.start() : this.catchUpHelper.stop();\n }\n this.scheduler.requestAnimFrame();\n }\n\n async #effectiveTimestampMilliseconds(): Promise<MillisecondTimestamp> {\n return (await this.model.detailedTimelineInfo.get()).timestamp;\n }\n\n // TODO: Return the animation we've switched to.\n jumpToStart(options?: { flash: boolean }): void {\n this.model.timestampRequest.set(\"start\");\n this.pause();\n if (options?.flash) {\n this.delegate.flash();\n }\n }\n\n // TODO: Return the animation we've switched to.\n jumpToEnd(options?: { flash: boolean }): void {\n this.model.timestampRequest.set(\"end\");\n this.pause();\n if (options?.flash) {\n this.delegate.flash();\n }\n }\n\n // TODO: Return the playing info we've switched to.\n playPause(): void {\n if (this.playing) {\n this.pause();\n } else {\n this.play(); // TODO: Resume direction and looping behaviour?\n }\n }\n\n // TODO: bundle playing direction, and boundary into `toggle`.\n play(options?: {\n direction?: SimpleDirection;\n untilBoundary?: BoundaryType;\n autoSkipToOtherEndIfStartingAtBoundary?: boolean; // TODO What's a good short name that doesn't imply a more general looping concept?\n loop?: boolean;\n }): void {\n void (async () => {\n // TODO: We might need to cache all playing info?\n // Or maybe we don't have to worry about short-circuiting, since this is idempotent?\n // if (this.playing) {\n // return;\n // }\n\n const direction = options?.direction ?? Direction.Forwards;\n\n const coarseTimelineInfo = await this.model.coarseTimelineInfo.get(); // TODO: Why do we need to read this if we don't use it?\n if (options?.autoSkipToOtherEndIfStartingAtBoundary ?? true) {\n if (direction === Direction.Forwards && coarseTimelineInfo.atEnd) {\n this.model.timestampRequest.set(\"start\");\n this.delegate.flash();\n }\n if (direction === Direction.Backwards && coarseTimelineInfo.atStart) {\n this.model.timestampRequest.set(\"end\");\n this.delegate.flash();\n }\n }\n this.model.playingInfo.set({\n playing: true,\n direction,\n untilBoundary: options?.untilBoundary ?? BoundaryType.EntireTimeline,\n loop: options?.loop ?? false,\n });\n\n this.playing = true;\n this.lastDatestamp = performance.now() as MillisecondTimestamp; // TODO: Take from event.\n this.lastTimestampPromise = this.#effectiveTimestampMilliseconds();\n\n // TODO: Save timestamp from model?\n this.scheduler.requestAnimFrame();\n })();\n }\n\n pause(): void {\n this.playing = false;\n this.scheduler.cancelAnimFrame();\n this.model.playingInfo.set({\n playing: false,\n untilBoundary: BoundaryType.EntireTimeline,\n });\n }\n\n #animFrameEffectiveTimestampStaleDropper: StaleDropper<\n [PlayingInfo, MillisecondTimestamp, TimeRange, number, CurrentMoveInfo]\n > = new StaleDropper<\n [PlayingInfo, MillisecondTimestamp, TimeRange, number, CurrentMoveInfo]\n >();\n\n async animFrame(frameDatestamp: MillisecondTimestamp): Promise<void> {\n if (this.playing) {\n this.scheduler.requestAnimFrame();\n }\n\n const lastDatestamp = this.lastDatestamp;\n const freshenerResult =\n await this.#animFrameEffectiveTimestampStaleDropper.queue(\n Promise.all([\n this.model.playingInfo.get(),\n this.lastTimestampPromise,\n this.model.timeRange.get(),\n this.model.tempoScale.get(),\n this.model.currentMoveInfo.get(),\n ]),\n );\n\n const [playingInfo, lastTimestamp, timeRange, tempoScale, currentMoveInfo] =\n freshenerResult;\n\n // TODO: Get this without wasting time on the others?\n if (!playingInfo.playing) {\n this.playing = false;\n // TODO: Ideally we'd cancel the anim frame from the top of this method.\n // But `this.scheduler.cancelAnimFrame();` might accidentally cancel a\n // legit freshly scheduled frame. We should modify `RenderScheduler` to\n // either have individually cancellable requests, or to have something\n // like a \"default\" anim frame re-request that can be canceled separately.\n //\n // Note that we can't wait until here to call\n // `this.scheduler.requestAnimFrame();`, because that would slow down the\n // frame rate.\n return;\n }\n\n let end = currentMoveInfo.earliestEnd; // timeRange.end\n if (\n currentMoveInfo.currentMoves.length === 0 ||\n playingInfo.untilBoundary === BoundaryType.EntireTimeline\n ) {\n end = timeRange.end;\n }\n\n let start = currentMoveInfo.latestStart; // timeRange.end\n if (\n currentMoveInfo.currentMoves.length === 0 ||\n playingInfo.untilBoundary === BoundaryType.EntireTimeline\n ) {\n start = timeRange.start;\n }\n // const start = currentMoveInfo.latestStart; // timeRange.start // TODO\n\n let delta =\n (frameDatestamp - lastDatestamp) *\n directionScalar(this.direction) *\n tempoScale;\n delta = Math.max(delta, 1); // TODO: This guards against the timestamp going in the wrong direction by accident. Can we avoid it?\n delta *= playingInfo.direction;\n let newTimestamp = (lastTimestamp + delta) as MillisecondTimestamp; // TODO: Pre-emptively clamp.\n let newSmartTimestampRequest: Exclude<TimestampRequest, number> | null =\n null;\n\n if (newTimestamp >= end) {\n if (playingInfo.loop) {\n newTimestamp = modIntoRange(\n newTimestamp,\n timeRange.start,\n timeRange.end,\n ) as MillisecondTimestamp;\n } else {\n if (newTimestamp === timeRange.end) {\n newSmartTimestampRequest = \"end\";\n } else {\n newTimestamp = end as MillisecondTimestamp;\n }\n this.playing = false;\n this.model.playingInfo.set({\n playing: false,\n });\n }\n } else if (newTimestamp <= start) {\n if (playingInfo.loop) {\n newTimestamp = modIntoRange(\n newTimestamp,\n timeRange.start,\n timeRange.end,\n ) as MillisecondTimestamp;\n } else {\n if (newTimestamp === timeRange.start) {\n newSmartTimestampRequest = \"start\";\n } else {\n newTimestamp = start as MillisecondTimestamp;\n }\n this.playing = false;\n this.model.playingInfo.set({\n playing: false,\n });\n }\n }\n this.lastDatestamp = frameDatestamp;\n this.lastTimestampPromise = Promise.resolve(\n newTimestamp as MillisecondTimestamp,\n ); // TODO: Save this earlier? / Do we need to worry about the effecitve timestamp disagreeing?\n this.model.timestampRequest.set(newSmartTimestampRequest ?? newTimestamp);\n }\n}\n", "import type { TwistyPlayerModel } from \"../model/TwistyPlayerModel\";\nimport {\n TwistyAnimationController,\n type TwistyAnimationControllerDelegate,\n} from \"./TwistyAnimationController\";\n\nexport class TwistyPlayerController {\n animationController: TwistyAnimationController;\n\n constructor(\n private model: TwistyPlayerModel,\n delegate: TwistyAnimationControllerDelegate,\n ) {\n this.animationController = new TwistyAnimationController(model, delegate);\n }\n\n jumpToStart(options?: { flash: boolean }): void {\n this.animationController.jumpToStart(options);\n }\n\n jumpToEnd(options?: { flash: boolean }): void {\n this.animationController.jumpToEnd(options);\n }\n\n togglePlay(play?: boolean) {\n if (typeof play === \"undefined\") {\n this.animationController.playPause();\n }\n play ? this.animationController.play() : this.animationController.pause();\n }\n\n public async visitTwizzleLink(): Promise<void> {\n const a = document.createElement(\"a\");\n a.href = await this.model.twizzleLink();\n a.target = \"_blank\";\n a.click();\n }\n}\n", "import { SimpleTwistyPropSource } from \"../TwistyProp\";\n\nexport const controlsLocations = {\n \"bottom-row\": true, // default\n none: true,\n};\nexport type ControlsLocation = keyof typeof controlsLocations;\nexport type ControlPanelThemeWithAuto = ControlsLocation | \"auto\";\n\nexport class ControlPanelProp extends SimpleTwistyPropSource<ControlPanelThemeWithAuto> {\n getDefaultValue(): ControlPanelThemeWithAuto {\n return \"auto\";\n }\n}\n", "import { cssStyleSheetShim } from \"./node-custom-element-shims\";\n\nexport const twistyViewerWrapperCSS = new cssStyleSheetShim();\ntwistyViewerWrapperCSS.replaceSync(\n `\n:host {\n width: 384px;\n height: 256px;\n display: grid;\n}\n\n.wrapper {\n width: 100%;\n height: 100%;\n display: grid;\n overflow: hidden;\n}\n\n.wrapper > * {\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n\n.wrapper.back-view-side-by-side {\n grid-template-columns: 1fr 1fr;\n}\n\n.wrapper.back-view-top-right {\n grid-template-columns: 3fr 1fr;\n grid-template-rows: 1fr 3fr;\n}\n\n.wrapper.back-view-top-right > :nth-child(1) {\n grid-row: 1 / 3;\n grid-column: 1 / 3;\n}\n\n.wrapper.back-view-top-right > :nth-child(2) {\n grid-row: 1 / 2;\n grid-column: 2 / 3;\n}\n`,\n);\n", "import { cssStyleSheetShim } from \"../node-custom-element-shims\";\n\n// TODO: Can we do this without so much nesting, and styling all the nested elems?\nexport const twisty2DSVGCSS = new cssStyleSheetShim();\ntwisty2DSVGCSS.replaceSync(\n `\n:host {\n width: 384px;\n height: 256px;\n display: grid;\n}\n\n.wrapper {\n width: 100%;\n height: 100%;\n display: grid;\n overflow: hidden;\n}\n\n.svg-wrapper,\ntwisty-2d-svg,\nsvg {\n width: 100%;\n height: 100%;\n display: grid;\n min-height: 0;\n}\n\nsvg {\n animation: fade-in 0.25s ease-in;\n}\n\n@keyframes fade-in {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.hint-facelets-none .hint-facelet {\n display: none;\n}\n`,\n);\n", "import type { KPuzzle } from \"../../../kpuzzle\";\nimport type { ExperimentalStickeringMask } from \"../../../puzzles/cubing-private\";\nimport type { PuzzleLoader } from \"../../../puzzles/PuzzleLoader\";\nimport type { StickeringMask } from \"../../../puzzles/stickerings/mask\";\nimport {\n type HintFaceletStyleWithAuto,\n hintFaceletStyles,\n} from \"../../../twisty/model/props/puzzle/display/HintFaceletProp\";\nimport type { PuzzleID } from \"../..\";\nimport {\n Direction,\n type PositionListener,\n type PuzzlePosition,\n} from \"../../controllers/AnimationTypes\";\nimport { RenderScheduler } from \"../../controllers/RenderScheduler\";\nimport { FreshListenerManager } from \"../../model/props/TwistyProp\";\nimport type { TwistyPlayerModel } from \"../../model/TwistyPlayerModel\";\nimport { ClassListManager } from \"../ClassListManager\";\nimport { ManagedCustomElement } from \"../ManagedCustomElement\";\nimport { customElementsShim } from \"../node-custom-element-shims\";\nimport { twisty2DSVGCSS } from \"./Twisty2DPuzzle.css\";\nimport { TwistyAnimatedSVG } from \"./TwistyAnimatedSVG\";\n\nexport interface Twisty2DPuzzleOptions {\n experimentalStickeringMask?: ExperimentalStickeringMask;\n}\n\n// <twisty-2d-svg>\nexport class Twisty2DPuzzle\n extends ManagedCustomElement\n implements PositionListener\n{\n public svgWrapper?: TwistyAnimatedSVG;\n private scheduler = new RenderScheduler(this.render.bind(this));\n #cachedPosition: PuzzlePosition | null = null; // TODO: pull when needed.\n constructor(\n private model?: TwistyPlayerModel,\n private kpuzzle?: KPuzzle,\n private svgSource?: string,\n private options?: Twisty2DPuzzleOptions,\n private puzzleLoader?: PuzzleLoader,\n ) {\n super();\n this.addCSS(twisty2DSVGCSS);\n\n this.resetSVG(); // TODO: do this in `connectedCallback()`?\n\n this.#freshListenerManager.addListener(\n this.model!.puzzleID,\n (puzzleID: PuzzleID) => {\n if (puzzleLoader?.id !== puzzleID) {\n this.disconnect();\n }\n },\n );\n\n this.#freshListenerManager.addListener(\n this.model!.twistySceneModel.hintFacelet,\n (hintFacelet) => {\n this.setHintFacelet(hintFacelet);\n },\n );\n\n this.#freshListenerManager.addListener(\n this.model!.legacyPosition,\n this.onPositionChange.bind(this),\n );\n\n if (this.options?.experimentalStickeringMask) {\n this.experimentalSetStickeringMask(\n this.options.experimentalStickeringMask,\n );\n }\n }\n\n #freshListenerManager = new FreshListenerManager();\n disconnect(): void {\n this.#freshListenerManager.disconnect();\n }\n\n onPositionChange(position: PuzzlePosition): void {\n try {\n if (position.movesInProgress.length > 0) {\n const move = position.movesInProgress[0].move;\n\n let partialMove = move;\n if (position.movesInProgress[0].direction === Direction.Backwards) {\n partialMove = move.invert();\n }\n const newPattern = position.pattern.applyMove(partialMove);\n // TODO: move to render()\n this.svgWrapper?.draw(\n position.pattern,\n newPattern,\n position.movesInProgress[0].fraction,\n );\n } else {\n this.svgWrapper?.draw(position.pattern);\n this.#cachedPosition = position;\n }\n } catch (e) {\n console.warn(\n \"Bad position (this doesn't necessarily mean something is wrong). Pre-emptively disconnecting:\",\n this.puzzleLoader?.id,\n e,\n );\n this.disconnect();\n }\n }\n\n scheduleRender(): void {\n this.scheduler.requestAnimFrame();\n }\n\n experimentalSetStickeringMask(\n stickeringMask: ExperimentalStickeringMask,\n ): void {\n this.resetSVG(stickeringMask);\n }\n\n // TODO: do this without constructing a new SVG.\n private resetSVG(stickeringMask?: StickeringMask): void {\n if (this.svgWrapper) {\n this.removeElement(this.svgWrapper.wrapperElement);\n }\n if (!this.kpuzzle) {\n return; // TODO\n }\n this.svgWrapper = new TwistyAnimatedSVG(\n this.kpuzzle,\n this.svgSource!,\n stickeringMask,\n ); // TODO\n this.addElement(this.svgWrapper.wrapperElement);\n if (this.#cachedPosition) {\n this.onPositionChange(this.#cachedPosition);\n }\n }\n\n private hintFaceletsClassListManager = new ClassListManager(\n this,\n \"hint-facelets-\",\n Object.keys(hintFaceletStyles),\n );\n setHintFacelet(hintFacelet: HintFaceletStyleWithAuto) {\n this.hintFaceletsClassListManager.setValue(\n hintFacelet === \"auto\" ? \"floating\" : hintFacelet,\n );\n }\n\n private render(): void {\n /*...*/\n }\n}\n\ncustomElementsShim.define(\"twisty-2d-puzzle\", Twisty2DPuzzle);\n", "import type { PuzzleLoader } from \"../../../puzzles\";\nimport type { ExperimentalStickeringMask } from \"../../../puzzles/cubing-private\";\nimport type { Schedulable } from \"../../controllers/RenderScheduler\";\nimport { FreshListenerManager } from \"../../model/props/TwistyProp\";\nimport type { TwistyPlayerModel } from \"../../model/TwistyPlayerModel\";\nimport { Twisty2DPuzzle } from \"./Twisty2DPuzzle\";\n\nexport class Twisty2DPuzzleWrapper implements Schedulable {\n constructor(\n private model: TwistyPlayerModel,\n public schedulable: Schedulable,\n private puzzleLoader: PuzzleLoader,\n private effectiveVisualization:\n | \"2D\"\n | \"experimental-2D-LL\"\n | \"experimental-2D-LL-face\",\n ) {\n void this.twisty2DPuzzle(); // Start constructing.\n\n this.#freshListenerManager.addListener(\n this.model.twistySceneModel.stickeringMask,\n async (stickeringMask: ExperimentalStickeringMask) => {\n (await this.twisty2DPuzzle()).experimentalSetStickeringMask(\n stickeringMask,\n );\n },\n );\n }\n\n #freshListenerManager = new FreshListenerManager();\n disconnect(): void {\n this.#freshListenerManager.disconnect();\n }\n\n // TODO: Hook this up nicely.\n scheduleRender(): void {\n // Nothing\n }\n\n #cachedTwisty2DPuzzle: Promise<Twisty2DPuzzle> | null = null;\n // TODO: Stale dropper?\n async twisty2DPuzzle(): Promise<Twisty2DPuzzle> {\n return (this.#cachedTwisty2DPuzzle ??= (async () => {\n const svgPromise =\n this.effectiveVisualization === \"experimental-2D-LL-face\"\n ? this.puzzleLoader.llFaceSVG!()\n : this.effectiveVisualization === \"experimental-2D-LL\"\n ? this.puzzleLoader.llSVG!()\n : this.puzzleLoader.svg();\n return new Twisty2DPuzzle(\n this.model,\n await this.puzzleLoader.kpuzzle(),\n await svgPromise,\n {},\n this.puzzleLoader,\n );\n })());\n }\n}\n", "import type { Scene as ThreeScene } from \"three/src/Three.js\";\nimport type { PuzzleLoader } from \"../../../puzzles\";\nimport type { Schedulable } from \"../../controllers/RenderScheduler\";\nimport { bulk3DCode } from \"../../heavy-code-imports/3d\";\nimport { FreshListenerManager } from \"../../model/props/TwistyProp\";\nimport type { TwistySceneModel } from \"../../model/TwistySceneModel\";\nimport { ManagedCustomElement } from \"../ManagedCustomElement\";\nimport { customElementsShim } from \"../node-custom-element-shims\";\nimport { twistyViewerWrapperCSS } from \"../TwistyViewerWrapper.css\";\nimport { Twisty2DPuzzleWrapper } from \"./Twisty2DPuzzleWrapper\";\n\nexport class Twisty2DSceneWrapper\n extends ManagedCustomElement\n implements Schedulable\n{\n #freshListenerManager = new FreshListenerManager();\n disconnect(): void {\n this.#freshListenerManager.disconnect();\n }\n\n constructor(\n public model?: TwistySceneModel,\n private effectiveVisualization?:\n | \"2D\"\n | \"experimental-2D-LL\"\n | \"experimental-2D-LL-face\",\n ) {\n super();\n }\n\n async connectedCallback(): Promise<void> {\n this.addCSS(twistyViewerWrapperCSS);\n if (this.model) {\n this.#freshListenerManager.addListener(\n this.model.twistyPlayerModel.puzzleLoader,\n this.onPuzzleLoader.bind(this),\n );\n }\n }\n\n #cachedScene?: Promise<ThreeScene>;\n async scene(): Promise<ThreeScene> {\n return (this.#cachedScene ??= (async () =>\n new (await bulk3DCode()).ThreeScene())());\n }\n\n scheduleRender(): void {\n this.#currentTwisty2DPuzzleWrapper?.scheduleRender();\n }\n\n #currentTwisty2DPuzzleWrapper: Twisty2DPuzzleWrapper | undefined;\n currentTwisty2DPuzzleWrapper(): Twisty2DPuzzleWrapper | undefined {\n return this.#currentTwisty2DPuzzleWrapper;\n }\n\n // #oldTwisty3DPuzzleWrappers: Twisty3DPuzzleWrapper[] = []; // TODO: Animate these out.\n async setCurrentTwisty2DPuzzleWrapper(\n twisty2DPuzzleWrapper: Twisty2DPuzzleWrapper,\n ): Promise<void> {\n const old = this.#currentTwisty2DPuzzleWrapper;\n this.#currentTwisty2DPuzzleWrapper = twisty2DPuzzleWrapper;\n old?.disconnect(); // TODO: Disconnect properly.\n const twisty2DPuzzlePromise = twisty2DPuzzleWrapper.twisty2DPuzzle();\n this.contentWrapper.textContent = \"\"; // Clear existing ones.\n this.addElement(await twisty2DPuzzlePromise);\n }\n\n async onPuzzleLoader(puzzleLoader: PuzzleLoader): Promise<void> {\n this.#currentTwisty2DPuzzleWrapper?.disconnect();\n const twisty2DPuzzleWrapper = new Twisty2DPuzzleWrapper(\n this.model!.twistyPlayerModel,\n this,\n puzzleLoader,\n this.effectiveVisualization!,\n );\n\n void this.setCurrentTwisty2DPuzzleWrapper(twisty2DPuzzleWrapper);\n }\n}\n\ncustomElementsShim.define(\"twisty-2d-scene-wrapper\", Twisty2DSceneWrapper);\n", "export class InitialValueTracker<T> {\n // @ts-expect-error: We do initialize this synchronously (assuming no one has tampered with the `Promise` constructor).\n #resolve: (t: T) => void;\n // @ts-expect-error: We do initialize this synchronously (assuming no one has tampered with the `Promise` constructor).\n reject: (e?: Error) => void; // TODO: AbortController?\n promise: Promise<T>;\n constructor() {\n this.promise = new Promise((resolve, reject) => {\n this.#resolve = resolve;\n this.reject = reject;\n });\n }\n handleNewValue(t: T): void {\n this.#resolve(t);\n }\n}\n", "import type { Raycaster, Texture as ThreeTexture } from \"three/src/Three.js\";\nimport type { PuzzleLoader } from \"../../../puzzles\";\nimport type { ExperimentalStickeringMask } from \"../../../puzzles/cubing-private\";\nimport type { PuzzlePosition } from \"../../controllers/AnimationTypes\";\nimport type { Schedulable } from \"../../controllers/RenderScheduler\";\nimport { bulk3DCode } from \"../../heavy-code-imports/3d\";\nimport type { FoundationDisplay } from \"../../model/props/puzzle/display/FoundationDisplayProp\";\nimport type { HintFaceletStyleWithAuto } from \"../../model/props/puzzle/display/HintFaceletProp\";\nimport { FreshListenerManager } from \"../../model/props/TwistyProp\";\nimport type { VisualizationStrategy } from \"../../model/props/viewer/VisualizationStrategyProp\";\nimport type { TwistyPlayerModel } from \"../../model/TwistyPlayerModel\";\nimport type { Cube3D } from \"./puzzles/Cube3D\";\nimport type { PG3D } from \"./puzzles/PG3D\";\nimport type { Twisty3DPuzzle } from \"./puzzles/Twisty3DPuzzle\";\n\nexport class Twisty3DPuzzleWrapper extends EventTarget implements Schedulable {\n constructor(\n private model: TwistyPlayerModel,\n public schedulable: Schedulable,\n private puzzleLoader: PuzzleLoader,\n private visualizationStrategy: VisualizationStrategy,\n ) {\n super();\n void this.twisty3DPuzzle(); // Start constructing.\n\n // TODO: Hook up listeners before loading the heavy code in the async constructor, so we get any intermediate updates?\n // Repro: Switch to 40x40x40 a fraction of a second before animation finishes. When it's loaded the itmeline is at the end, but the 40x40x40 is rendered with an earlier position.\n\n this.#freshListenerManager.addListener(\n this.model.puzzleLoader,\n (puzzleLoader: PuzzleLoader) => {\n if (this.puzzleLoader.id !== puzzleLoader.id) {\n this.disconnect();\n }\n },\n );\n this.#freshListenerManager.addListener(\n this.model.legacyPosition,\n async (position: PuzzlePosition) => {\n try {\n (await this.twisty3DPuzzle()).onPositionChange(position);\n this.scheduleRender();\n } catch {\n // TODO\n // console.warn(\n // \"Bad position (this doesn't necessarily mean something is wrong). Pre-emptively disconnecting:\",\n // this.puzzleLoader.id,\n // e,\n // );\n this.disconnect();\n }\n },\n );\n\n this.#freshListenerManager.addListener(\n this.model.twistySceneModel.hintFacelet,\n async (hintFaceletStyle: HintFaceletStyleWithAuto) => {\n (\n (await this.twisty3DPuzzle()) as Cube3D | PG3D\n ).experimentalUpdateOptions({\n hintFacelets:\n hintFaceletStyle === \"auto\" ? \"floating\" : hintFaceletStyle,\n });\n this.scheduleRender();\n },\n );\n this.#freshListenerManager.addListener(\n this.model.twistySceneModel.foundationDisplay,\n async (foundationDisplay: FoundationDisplay) => {\n (\n (await this.twisty3DPuzzle()) as Cube3D | PG3D\n ).experimentalUpdateOptions({\n showFoundation: foundationDisplay !== \"none\",\n });\n this.scheduleRender();\n },\n );\n this.#freshListenerManager.addListener(\n this.model.twistySceneModel.stickeringMask,\n async (stickeringMask: ExperimentalStickeringMask) => {\n const twisty3D = await this.twisty3DPuzzle();\n twisty3D.setStickeringMask(stickeringMask);\n this.scheduleRender();\n },\n );\n this.#freshListenerManager.addListener(\n this.model.twistySceneModel.faceletScale,\n async (faceletScale: \"auto\" | number) => {\n (\n (await this.twisty3DPuzzle()) as Cube3D | PG3D\n ).experimentalUpdateOptions({\n faceletScale,\n });\n this.scheduleRender();\n },\n );\n\n this.#freshListenerManager.addListener(\n this.model.twistySceneModel.hintFaceletsElevation,\n async (hintFaceletsElevation: \"auto\" | number) => {\n (\n (await this.twisty3DPuzzle()) as Cube3D | PG3D\n ).experimentalUpdateOptions({\n hintFaceletsElevation,\n });\n this.scheduleRender();\n },\n );\n\n this.#freshListenerManager.addMultiListener3(\n [\n this.model.twistySceneModel.stickeringMask,\n this.model.twistySceneModel.foundationStickerSprite,\n this.model.twistySceneModel.hintStickerSprite,\n ],\n async (\n inputs: [\n stickeringMask: ExperimentalStickeringMask,\n foundationSprite: ThreeTexture | null,\n hintSprite: ThreeTexture | null,\n ],\n ) => {\n if (\"experimentalUpdateTexture\" in (await this.twisty3DPuzzle())) {\n ((await this.twisty3DPuzzle()) as PG3D).experimentalUpdateTexture(\n inputs[0].specialBehaviour === \"picture\",\n inputs[1],\n inputs[2],\n );\n this.scheduleRender();\n }\n },\n );\n }\n\n #freshListenerManager = new FreshListenerManager();\n disconnect(): void {\n this.#freshListenerManager.disconnect();\n }\n\n scheduleRender(): void {\n this.schedulable.scheduleRender();\n this.dispatchEvent(new CustomEvent(\"render-scheduled\"));\n }\n\n #cachedTwisty3DPuzzle: Promise<Twisty3DPuzzle> | null = null;\n async twisty3DPuzzle(): Promise<Twisty3DPuzzle> {\n return (this.#cachedTwisty3DPuzzle ??= (async () => {\n const proxyPromise = bulk3DCode();\n if (\n this.puzzleLoader.id === \"3x3x3\" &&\n this.visualizationStrategy === \"Cube3D\"\n ) {\n // TODO: synchronize\n const [\n foundationSprite,\n hintSprite,\n experimentalStickeringMask,\n initialHintFaceletsAnimation,\n faceletScale,\n hintFaceletsElevation,\n ] = await Promise.all([\n this.model.twistySceneModel.foundationStickerSprite.get(),\n this.model.twistySceneModel.hintStickerSprite.get(),\n this.model.twistySceneModel.stickeringMask.get(),\n this.model.twistySceneModel.initialHintFaceletsAnimation.get(),\n this.model.twistySceneModel.faceletScale.get(),\n this.model.twistySceneModel.hintFaceletsElevation.get(),\n ]);\n return (await proxyPromise).cube3DShim(\n () => this.schedulable.scheduleRender(),\n {\n foundationSprite,\n hintSprite,\n experimentalStickeringMask,\n initialHintFaceletsAnimation,\n faceletScale,\n hintFaceletsElevation,\n },\n );\n } else {\n const [hintFacelets, foundationSprite, hintSprite, faceletScale] =\n await Promise.all([\n this.model.twistySceneModel.hintFacelet.get(),\n this.model.twistySceneModel.foundationStickerSprite.get(),\n this.model.twistySceneModel.hintStickerSprite.get(),\n this.model.twistySceneModel.faceletScale.get(),\n ]);\n const pg3d = (await proxyPromise).pg3dShim(\n () => this.schedulable.scheduleRender(),\n this.puzzleLoader,\n hintFacelets === \"auto\" ? \"floating\" : hintFacelets,\n faceletScale,\n this.puzzleLoader.id === \"kilominx\", // TODO: generalize to other puzzles\n );\n // TODO: Figure out how to do this in one place using the listener.\n pg3d.then((p) =>\n p.experimentalUpdateTexture(\n true,\n foundationSprite ?? undefined,\n hintSprite ?? undefined,\n ),\n );\n return pg3d;\n }\n })());\n }\n\n async raycastMove(\n raycasterPromise: Promise<Raycaster>,\n transformations: {\n invert: boolean;\n depth?: \"secondSlice\" | \"rotation\" | \"none\";\n },\n ): Promise<void> {\n const puzzle = (await this.twisty3DPuzzle()) as Cube3D | PG3D;\n // TODO: check this differently.\n if (!(\"experimentalGetControlTargets\" in puzzle)) {\n console.info(\"not PG3D! skipping raycast\");\n return;\n }\n\n const targets = puzzle.experimentalGetControlTargets(); // TODO: sticker targets\n const [raycaster, movePressCancelOptions] = await Promise.all([\n raycasterPromise,\n this.model.twistySceneModel.movePressCancelOptions.get(),\n ]);\n\n const intersects = raycaster.intersectObjects(targets);\n if (intersects.length > 0) {\n const closestMove = puzzle.getClosestMoveToAxis(\n intersects[0].point,\n transformations,\n );\n if (closestMove) {\n this.model.experimentalAddMove(closestMove.move, {\n cancel: movePressCancelOptions,\n });\n } else {\n console.info(\"Skipping move!\");\n }\n }\n }\n}\n", "import type {\n PerspectiveCamera,\n Scene as ThreeScene,\n} from \"three/src/Three.js\";\nimport type { PuzzleLoader } from \"../../../puzzles\";\nimport type { Schedulable } from \"../../controllers/RenderScheduler\";\nimport { bulk3DCode } from \"../../heavy-code-imports/3d\";\nimport { StaleDropper } from \"../../model/PromiseFreshener\";\nimport { FreshListenerManager } from \"../../model/props/TwistyProp\";\nimport type { BackViewLayout as BackViewLayoutWithAuto } from \"../../model/props/viewer/BackViewProp\";\nimport type { VisualizationStrategy } from \"../../model/props/viewer/VisualizationStrategyProp\";\nimport type { TwistyPlayerModel } from \"../../model/TwistyPlayerModel\";\nimport { ClassListManager } from \"../ClassListManager\";\nimport { InitialValueTracker } from \"../InitialValueTracker\";\nimport { ManagedCustomElement } from \"../ManagedCustomElement\";\nimport { customElementsShim } from \"../node-custom-element-shims\";\nimport { twistyViewerWrapperCSS } from \"../TwistyViewerWrapper.css\";\nimport type { PressInfo } from \"./DragTracker\";\nimport { Twisty3DPuzzleWrapper } from \"./Twisty3DPuzzleWrapper\";\nimport { Twisty3DVantage } from \"./Twisty3DVantage\";\n\nexport class Twisty3DSceneWrapper\n extends ManagedCustomElement\n implements Schedulable\n{\n // @ts-expect-error TypeScript type inference appears to be borked: ts(2322)\n #backViewClassListManager: ClassListManager<BackViewLayoutWithAuto> =\n new ClassListManager(this, \"back-view-\", [\n \"auto\",\n \"none\",\n \"side-by-side\",\n \"top-right\",\n ]);\n\n #freshListenerManager = new FreshListenerManager();\n disconnect(): void {\n this.#freshListenerManager.disconnect();\n }\n\n constructor(public model?: TwistyPlayerModel) {\n super();\n }\n\n async connectedCallback(): Promise<void> {\n this.addCSS(twistyViewerWrapperCSS);\n const vantage = new Twisty3DVantage(this.model, this);\n this.addVantage(vantage);\n if (this.model) {\n this.#freshListenerManager.addMultiListener(\n [this.model.puzzleLoader, this.model.visualizationStrategy],\n this.onPuzzle.bind(this),\n );\n this.#freshListenerManager.addListener(\n this.model.backView,\n // @ts-expect-error TypeScript type inference appears to be borked: ts(2322)\n this.setBackView.bind(this),\n );\n }\n this.scheduleRender();\n }\n\n #backViewVantage: Twisty3DVantage | null = null;\n setBackView(backView: BackViewLayoutWithAuto): void {\n const shouldHaveBackView = [\"side-by-side\", \"top-right\"].includes(backView);\n const hasBackView = this.#backViewVantage !== null;\n\n this.#backViewClassListManager.setValue(backView);\n if (shouldHaveBackView) {\n if (!hasBackView) {\n this.#backViewVantage = new Twisty3DVantage(this.model, this, {\n backView: true,\n });\n this.addVantage(this.#backViewVantage);\n this.scheduleRender();\n }\n } else {\n if (this.#backViewVantage) {\n this.removeVantage(this.#backViewVantage);\n this.#backViewVantage = null;\n }\n }\n }\n\n async onPress(\n e: CustomEvent<{\n pressInfo: PressInfo;\n cameraPromise: Promise<PerspectiveCamera>;\n }>,\n ): Promise<void> {\n const twisty3DPuzzleWrapper = this.#currentTwisty3DPuzzleWrapper;\n if (!twisty3DPuzzleWrapper) {\n console.info(\"no wrapper; skipping scene wrapper press!\");\n return;\n }\n\n const raycasterPromise = (async () => {\n const [camera, { ThreeRaycaster, ThreeVector2 }] = await Promise.all([\n e.detail.cameraPromise,\n (async () => {\n const { ThreeRaycaster, ThreeVector2 } = await bulk3DCode();\n return { ThreeRaycaster, ThreeVector2 };\n })(),\n ]);\n\n const raycaster = new ThreeRaycaster();\n const mouse = new ThreeVector2(\n e.detail.pressInfo.normalizedX,\n e.detail.pressInfo.normalizedY,\n );\n raycaster.setFromCamera(mouse, camera);\n return raycaster;\n })();\n\n twisty3DPuzzleWrapper.raycastMove(raycasterPromise, {\n invert: !e.detail.pressInfo.rightClick,\n depth: e.detail.pressInfo.keys.ctrlOrMetaKey\n ? \"rotation\"\n : e.detail.pressInfo.keys.shiftKey\n ? \"secondSlice\"\n : \"none\",\n });\n }\n\n #cachedScene?: Promise<ThreeScene>;\n async scene(): Promise<ThreeScene> {\n return (this.#cachedScene ??= (async () =>\n new (await bulk3DCode()).ThreeScene())());\n }\n\n #vantages: Set<Twisty3DVantage> = new Set();\n addVantage(vantage: Twisty3DVantage) {\n vantage.addEventListener(\n \"press\",\n this.onPress.bind(this) as any as EventListener, // TODO: https://github.com/microsoft/TypeScript/issues/28357\n );\n this.#vantages.add(vantage);\n this.contentWrapper.appendChild(vantage);\n }\n\n removeVantage(vantage: Twisty3DVantage) {\n this.#vantages.delete(vantage);\n vantage.remove();\n vantage.disconnect();\n this.#currentTwisty3DPuzzleWrapper?.disconnect();\n }\n\n experimentalVantages(): Iterable<Twisty3DVantage> {\n return this.#vantages.values();\n }\n\n scheduleRender(): void {\n for (const vantage of this.#vantages) {\n vantage.scheduleRender();\n }\n }\n\n #currentTwisty3DPuzzleWrapper: Twisty3DPuzzleWrapper | null = null;\n // #oldTwisty3DPuzzleWrappers: Twisty3DPuzzleWrapper[] = []; // TODO: Animate these out.\n async setCurrentTwisty3DPuzzleWrapper(\n scene: ThreeScene,\n twisty3DPuzzleWrapper: Twisty3DPuzzleWrapper,\n ): Promise<void> {\n const old = this.#currentTwisty3DPuzzleWrapper;\n try {\n this.#currentTwisty3DPuzzleWrapper = twisty3DPuzzleWrapper;\n old?.disconnect();\n scene.add(await twisty3DPuzzleWrapper.twisty3DPuzzle());\n } finally {\n if (old) {\n // We wait for the new puzzle to be in place before removing the old one.\n scene.remove(await old.twisty3DPuzzle());\n }\n }\n this.#initialWrapperTracker.handleNewValue(twisty3DPuzzleWrapper);\n }\n\n #initialWrapperTracker = new InitialValueTracker<Twisty3DPuzzleWrapper>();\n /** @deprecated */\n async experimentalTwisty3DPuzzleWrapper(): Promise<Twisty3DPuzzleWrapper> {\n return (\n this.#currentTwisty3DPuzzleWrapper || this.#initialWrapperTracker.promise\n );\n }\n\n #twisty3DStaleDropper: StaleDropper<[ThreeScene, Twisty3DPuzzleWrapper]> =\n new StaleDropper<[ThreeScene, Twisty3DPuzzleWrapper]>();\n\n async onPuzzle(\n inputs: [\n puzzleLoader: PuzzleLoader,\n visualizationStrategy: VisualizationStrategy,\n ],\n ): Promise<void> {\n if (inputs[1] === \"2D\") {\n // We are being asked to render with stale info. Ignore.\n return;\n }\n this.#currentTwisty3DPuzzleWrapper?.disconnect();\n const [scene, twisty3DPuzzleWrapper] =\n await this.#twisty3DStaleDropper.queue(\n Promise.all([\n this.scene(),\n new Twisty3DPuzzleWrapper(this.model!, this, inputs[0], inputs[1]), // TODO\n ]),\n );\n\n void this.setCurrentTwisty3DPuzzleWrapper(scene, twisty3DPuzzleWrapper);\n }\n}\n\ncustomElementsShim.define(\"twisty-3d-scene-wrapper\", Twisty3DSceneWrapper);\n", "// Use like this:\n// const enabled = globalSafeDocument?.fullscreenEnabled;\nexport const globalSafeDocument: Document | null =\n typeof document === \"undefined\" ? null : document;\n", "// Ponyfills for prefixing in Safari.\n\nimport { globalSafeDocument } from \"../document\";\n\ndeclare global {\n interface Document {\n webkitFullscreenEnabled?: boolean;\n webkitExitFullscreen?: () => Promise<void>;\n webkitFullscreenElement?: Element | null;\n }\n\n interface Element {\n webkitRequestFullscreen: () => Promise<void>;\n }\n}\n\n// TODO: Can `webkitFullscreenEnabled` change after it's cached at page load?\nexport const fullscreenEnabled: boolean =\n globalSafeDocument?.fullscreenEnabled ||\n !!globalSafeDocument?.webkitFullscreenEnabled;\n\nexport function documentExitFullscreen(): Promise<void> {\n if (document.exitFullscreen) {\n return document.exitFullscreen();\n } else {\n return document.webkitExitFullscreen!(); // YOLO\n }\n}\n\nexport function documentFullscreenElement(): Element | null {\n if (document.fullscreenElement) {\n return document.fullscreenElement;\n } else {\n return document.webkitFullscreenElement ?? null;\n }\n}\n\nexport function requestFullscreen(element: Element): Promise<void> {\n if (element.requestFullscreen) {\n return element.requestFullscreen();\n } else {\n return element.webkitRequestFullscreen();\n }\n}\n", "import type { ButtonCommand } from \"../../../views/control-panel/TwistyButtons\";\nimport { fullscreenEnabled } from \"../../../views/control-panel/webkit-fullscreen\";\nimport { TwistyPropDerived } from \"../TwistyProp\";\nimport type { CoarseTimelineInfo } from \"../timeline/CoarseTimelineInfoProp\";\nimport type { ViewerLinkPageWithAuto } from \"./ViewerLinkProp\";\n\nexport const buttonIcons = [\n \"skip-to-start\",\n \"skip-to-end\",\n \"step-forward\",\n \"step-backward\",\n \"pause\",\n \"play\",\n \"enter-fullscreen\",\n \"exit-fullscreen\",\n \"twizzle-tw\",\n];\nexport type ButtonIcon = (typeof buttonIcons)[number];\n\ninterface ButtonAppearance {\n enabled: boolean;\n icon: ButtonIcon;\n title: string;\n hidden?: boolean;\n}\nexport type ButtonAppearances = Record<ButtonCommand, ButtonAppearance>;\n\n// TODO: reduce inputs to avoid unnecessary updates.\ninterface ButtonAppearancePropInputs {\n coarseTimelineInfo: CoarseTimelineInfo;\n viewerLink: ViewerLinkPageWithAuto;\n}\n\nexport class ButtonAppearanceProp extends TwistyPropDerived<\n ButtonAppearancePropInputs,\n ButtonAppearances\n> {\n // TODO: This still seems to fire twice for play/pause?\n derive(inputs: ButtonAppearancePropInputs): ButtonAppearances {\n const buttonAppearances = {\n fullscreen: {\n // TODO: Cache?// TODO: Cache?\n enabled: fullscreenEnabled,\n icon:\n // TODO: Check against the expected element?\n // TODO: This will *not* update when we enter/leave fullscreen. We need to work more closely with the controller.\n document.fullscreenElement === null\n ? \"enter-fullscreen\"\n : \"exit-fullscreen\",\n title: \"Enter fullscreen\",\n },\n \"jump-to-start\": {\n enabled: !inputs.coarseTimelineInfo.atStart,\n icon: \"skip-to-start\",\n title: \"Restart\",\n },\n \"play-step-backwards\": {\n enabled: !inputs.coarseTimelineInfo.atStart,\n icon: \"step-backward\",\n title: \"Step backward\",\n },\n \"play-pause\": {\n enabled: !(\n inputs.coarseTimelineInfo.atStart && inputs.coarseTimelineInfo.atEnd\n ),\n icon: inputs.coarseTimelineInfo.playing ? \"pause\" : \"play\",\n title: inputs.coarseTimelineInfo.playing ? \"Pause\" : \"Play\",\n },\n \"play-step\": {\n enabled: !inputs.coarseTimelineInfo.atEnd,\n icon: \"step-forward\",\n title: \"Step forward\",\n },\n \"jump-to-end\": {\n enabled: !inputs.coarseTimelineInfo.atEnd,\n icon: \"skip-to-end\",\n title: \"Skip to End\",\n },\n \"twizzle-link\": {\n enabled: true,\n icon: \"twizzle-tw\",\n title: \"View at Twizzle\",\n hidden: inputs.viewerLink === \"none\",\n },\n };\n return buttonAppearances;\n }\n}\n", "import { cssStyleSheetShim } from \"../node-custom-element-shims\";\n\nexport const buttonGridCSS = new cssStyleSheetShim();\nbuttonGridCSS.replaceSync(\n `\n:host {\n width: 384px;\n height: 24px;\n display: grid;\n}\n\n.wrapper {\n width: 100%;\n height: 100%;\n display: grid;\n overflow: hidden;\n backdrop-filter: blur(4px);\n -webkit-backdrop-filter: blur(4px);\n}\n\n.wrapper {\n grid-auto-flow: column;\n}\n\n.viewer-link-none .twizzle-link-button {\n display: none;\n}\n\n.wrapper twisty-button,\n.wrapper twisty-control-button {\n width: inherit;\n height: inherit;\n}\n`,\n);\n\nexport const buttonCSS = new cssStyleSheetShim();\nbuttonCSS.replaceSync(\n `\n:host:not([hidden]) {\n display: grid;\n}\n\n:host {\n width: 48px;\n height: 24px;\n}\n\n.wrapper {\n width: 100%;\n height: 100%;\n}\n\nbutton {\n width: 100%;\n height: 100%;\n border: none;\n \n background-position: center;\n background-repeat: no-repeat;\n background-size: contain;\n\n background-color: rgba(196, 196, 196, 0.75);\n}\n\nbutton:enabled {\n background-color: rgba(196, 196, 196, 0.75)\n}\n\n.dark-mode button:enabled {\n background-color: #88888888;\n}\n\nbutton:disabled {\n background-color: rgba(0, 0, 0, 0.4);\n opacity: 0.25;\n pointer-events: none;\n}\n\n.dark-mode button:disabled {\n background-color: #ffffff44;\n}\n\nbutton:enabled:hover {\n background-color: rgba(255, 255, 255, 0.75);\n box-shadow: 0 0 1em rgba(0, 0, 0, 0.25);\n cursor: pointer;\n}\n\n/* TODO: fullscreen icons have too much padding?? */\n.svg-skip-to-start button,\nbutton.svg-skip-to-start {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNTg0IiBoZWlnaHQ9IjM1ODQiIHZpZXdCb3g9IjAgMCAzNTg0IDM1ODQiPjxwYXRoIGQ9Ik0yNjQzIDEwMzdxMTktMTkgMzItMTN0MTMgMzJ2MTQ3MnEwIDI2LTEzIDMydC0zMi0xM2wtNzEwLTcxMHEtOS05LTEzLTE5djcxMHEwIDI2LTEzIDMydC0zMi0xM2wtNzEwLTcxMHEtOS05LTEzLTE5djY3OHEwIDI2LTE5IDQ1dC00NSAxOUg5NjBxLTI2IDAtNDUtMTl0LTE5LTQ1VjEwODhxMC0yNiAxOS00NXQ0NS0xOWgxMjhxMjYgMCA0NSAxOXQxOSA0NXY2NzhxNC0xMSAxMy0xOWw3MTAtNzEwcTE5LTE5IDMyLTEzdDEzIDMydjcxMHE0LTExIDEzLTE5eiIvPjwvc3ZnPg==\");\n}\n\n.svg-skip-to-end button,\nbutton.svg-skip-to-end {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNTg0IiBoZWlnaHQ9IjM1ODQiIHZpZXdCb3g9IjAgMCAzNTg0IDM1ODQiPjxwYXRoIGQ9Ik05NDEgMjU0N3EtMTkgMTktMzIgMTN0LTEzLTMyVjEwNTZxMC0yNiAxMy0zMnQzMiAxM2w3MTAgNzEwcTggOCAxMyAxOXYtNzEwcTAtMjYgMTMtMzJ0MzIgMTNsNzEwIDcxMHE4IDggMTMgMTl2LTY3OHEwLTI2IDE5LTQ1dDQ1LTE5aDEyOHEyNiAwIDQ1IDE5dDE5IDQ1djE0MDhxMCAyNi0xOSA0NXQtNDUgMTloLTEyOHEtMjYgMC00NS0xOXQtMTktNDV2LTY3OHEtNSAxMC0xMyAxOWwtNzEwIDcxMHEtMTkgMTktMzIgMTN0LTEzLTMydi03MTBxLTUgMTAtMTMgMTl6Ii8+PC9zdmc+\");\n}\n\n.svg-step-forward button,\nbutton.svg-step-forward {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNTg0IiBoZWlnaHQ9IjM1ODQiIHZpZXdCb3g9IjAgMCAzNTg0IDM1ODQiPjxwYXRoIGQ9Ik0yNjg4IDE1NjhxMCAyNi0xOSA0NWwtNTEyIDUxMnEtMTkgMTktNDUgMTl0LTQ1LTE5cS0xOS0xOS0xOS00NXYtMjU2aC0yMjRxLTk4IDAtMTc1LjUgNnQtMTU0IDIxLjVxLTc2LjUgMTUuNS0xMzMgNDIuNXQtMTA1LjUgNjkuNXEtNDkgNDIuNS04MCAxMDF0LTQ4LjUgMTM4LjVxLTE3LjUgODAtMTcuNSAxODEgMCA1NSA1IDEyMyAwIDYgMi41IDIzLjV0Mi41IDI2LjVxMCAxNS04LjUgMjV0LTIzLjUgMTBxLTE2IDAtMjgtMTctNy05LTEzLTIydC0xMy41LTMwcS03LjUtMTctMTAuNS0yNC0xMjctMjg1LTEyNy00NTEgMC0xOTkgNTMtMzMzIDE2Mi00MDMgODc1LTQwM2gyMjR2LTI1NnEwLTI2IDE5LTQ1dDQ1LTE5cTI2IDAgNDUgMTlsNTEyIDUxMnExOSAxOSAxOSA0NXoiLz48L3N2Zz4=\");\n}\n\n.svg-step-backward button,\nbutton.svg-step-backward {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNTg0IiBoZWlnaHQ9IjM1ODQiIHZpZXdCb3g9IjAgMCAzNTg0IDM1ODQiPjxwYXRoIGQ9Ik0yNjg4IDIwNDhxMCAxNjYtMTI3IDQ1MS0zIDctMTAuNSAyNHQtMTMuNSAzMHEtNiAxMy0xMyAyMi0xMiAxNy0yOCAxNy0xNSAwLTIzLjUtMTB0LTguNS0yNXEwLTkgMi41LTI2LjV0Mi41LTIzLjVxNS02OCA1LTEyMyAwLTEwMS0xNy41LTE4MXQtNDguNS0xMzguNXEtMzEtNTguNS04MC0xMDF0LTEwNS41LTY5LjVxLTU2LjUtMjctMTMzLTQyLjV0LTE1NC0yMS41cS03Ny41LTYtMTc1LjUtNmgtMjI0djI1NnEwIDI2LTE5IDQ1dC00NSAxOXEtMjYgMC00NS0xOWwtNTEyLTUxMnEtMTktMTktMTktNDV0MTktNDVsNTEyLTUxMnExOS0xOSA0NS0xOXQ0NSAxOXExOSAxOSAxOSA0NXYyNTZoMjI0cTcxMyAwIDg3NSA0MDMgNTMgMTM0IDUzIDMzM3oiLz48L3N2Zz4=\");\n}\n\n.svg-pause button,\nbutton.svg-pause {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNTg0IiBoZWlnaHQ9IjM1ODQiIHZpZXdCb3g9IjAgMCAzNTg0IDM1ODQiPjxwYXRoIGQ9Ik0yNTYwIDEwODh2MTQwOHEwIDI2LTE5IDQ1dC00NSAxOWgtNTEycS0yNiAwLTQ1LTE5dC0xOS00NVYxMDg4cTAtMjYgMTktNDV0NDUtMTloNTEycTI2IDAgNDUgMTl0MTkgNDV6bS04OTYgMHYxNDA4cTAgMjYtMTkgNDV0LTQ1IDE5aC01MTJxLTI2IDAtNDUtMTl0LTE5LTQ1VjEwODhxMC0yNiAxOS00NXQ0NS0xOWg1MTJxMjYgMCA0NSAxOXQxOSA0NXoiLz48L3N2Zz4=\");\n}\n\n.svg-play button,\nbutton.svg-play {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNTg0IiBoZWlnaHQ9IjM1ODQiIHZpZXdCb3g9IjAgMCAzNTg0IDM1ODQiPjxwYXRoIGQ9Ik0yNDcyLjUgMTgyM2wtMTMyOCA3MzhxLTIzIDEzLTM5LjUgM3QtMTYuNS0zNlYxMDU2cTAtMjYgMTYuNS0zNnQzOS41IDNsMTMyOCA3MzhxMjMgMTMgMjMgMzF0LTIzIDMxeiIvPjwvc3ZnPg==\");\n}\n\n.svg-enter-fullscreen button,\nbutton.svg-enter-fullscreen {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjgiIHZpZXdCb3g9IjAgMCAyOCAyOCIgd2lkdGg9IjI4Ij48cGF0aCBkPSJNMiAyaDI0djI0SDJ6IiBmaWxsPSJub25lIi8+PHBhdGggZD0iTTkgMTZIN3Y1aDV2LTJIOXYtM3ptLTItNGgyVjloM1Y3SDd2NXptMTIgN2gtM3YyaDV2LTVoLTJ2M3pNMTYgN3YyaDN2M2gyVjdoLTV6Ii8+PC9zdmc+\");\n}\n\n.svg-exit-fullscreen button,\nbutton.svg-exit-fullscreen {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjgiIHZpZXdCb3g9IjAgMCAyOCAyOCIgd2lkdGg9IjI4Ij48cGF0aCBkPSJNMiAyaDI0djI0SDJ6IiBmaWxsPSJub25lIi8+PHBhdGggZD0iTTcgMThoM3YzaDJ2LTVIN3Yyem0zLThIN3YyaDVWN2gtMnYzem02IDExaDJ2LTNoM3YtMmgtNXY1em0yLTExVjdoLTJ2NWg1di0yaC0zeiIvPjwvc3ZnPg==\");\n}\n\n.svg-twizzle-tw button,\nbutton.svg-twizzle-tw {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODY0IiBoZWlnaHQ9IjYwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMzk3LjU4MSAxNTEuMTh2NTcuMDg0aC04OS43MDN2MjQwLjM1MmgtNjYuOTU1VjIwOC4yNjRIMTUxLjIydi01Ny4wODNoMjQ2LjM2MXptNTQuMzEgNzEuNjc3bDcuNTEyIDMzLjY5MmMyLjcxOCAxMi4xNiA1LjU4IDI0LjY4IDguNTg0IDM3LjU1NWEyMTgwLjc3NSAyMTgwLjc3NSAwIDAwOS40NDIgMzguODQzIDEyNjYuMyAxMjY2LjMgMCAwMDEwLjA4NiAzNy41NTVjMy43Mi0xMi41OSA3LjM2OC0yNS40NjYgMTAuOTQ1LTM4LjYyOCAzLjU3Ni0xMy4xNjIgNy4wMS0yNi4xMSAxMC4zLTM4Ljg0M2w1Ljc2OS0yMi40NTZjMS4yNDgtNC44ODcgMi40NzItOS43MDUgMy42NzQtMTQuNDU1IDMuMDA0LTExLjg3NSA1LjY1MS0yMi45NjIgNy45NC0zMy4yNjNoNDYuMzU0bDIuMzg0IDEwLjU2M2EyMDAwLjc3IDIwMDAuNzcgMCAwMDMuOTM1IDE2LjgyOGw2LjcxMSAyNy43MWMxLjIxMyA0Ljk1NiAyLjQ1IDkuOTggMy43MDkgMTUuMDczYTMxMTkuNzc3IDMxMTkuNzc3IDAgMDA5Ljg3MSAzOC44NDMgMTI0OS4yMjcgMTI0OS4yMjcgMCAwMDEwLjczIDM4LjYyOCAxOTA3LjYwNSAxOTA3LjYwNSAwIDAwMTAuMzAxLTM3LjU1NSAxMzk3Ljk0IDEzOTcuOTQgMCAwMDkuNjU3LTM4Ljg0M2w0LjQtMTkuMDQ2Yy43MTUtMy4xMyAxLjQyMS02LjIzNiAyLjExOC05LjMyMWw5LjU3Ny00Mi44OGg2Ni41MjZhMjk4OC43MTggMjk4OC43MTggMCAwMS0xOS41MjkgNjYuMzExbC01LjcyOCAxOC40ODJhMzIzNy40NiAzMjM3LjQ2IDAgMDEtMTQuMDE1IDQzLjc1MmMtNi40MzggMTkuNi0xMi43MzMgMzcuNjk4LTE4Ljg4NSA1NC4yOTRsLTMuMzA2IDguODI1Yy00Ljg4NCAxMi44OTgtOS40MzMgMjQuMjYzLTEzLjY0NyAzNC4wOTVoLTQ5Ljc4N2E4NDE3LjI4OSA4NDE3LjI4OSAwIDAxLTIxLjAzMS02NC44MDkgMTI4OC42ODYgMTI4OC42ODYgMCAwMS0xOC44ODUtNjQuODEgMTk3Mi40NDQgMTk3Mi40NDQgMCAwMS0xOC4yNCA2NC44MSAyNTc5LjQxMiAyNTc5LjQxMiAwIDAxLTIwLjM4OCA2NC44MWgtNDkuNzg3Yy00LjY4Mi0xMC45MjYtOS43Mi0yMy43NDMtMTUuMTEtMzguNDUxbC0xLjYyOS00LjQ3Yy01LjI1OC0xNC41MjEtMTAuNjgtMzAuMTkyLTE2LjI2Ni00Ny4wMTRsLTIuNDA0LTcuMjhjLTYuNDM4LTE5LjYtMTMuMDItNDAuMzQ0LTE5Ljc0My02Mi4yMzRhMjk4OC43MDcgMjk4OC43MDcgMCAwMS0xOS41MjktNjYuMzExaDY3LjM4NXoiIGZpbGw9IiM0Mjg1RjQiIGZpbGwtcnVsZT0ibm9uemVybyIvPjwvc3ZnPg==\");\n}\n`,\n);\n// Sized against full-screen dimensions.\n// button.svg-twizzle-tw {\n// background-image: url(\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNzc3IiBoZWlnaHQ9IjUxMyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMzU0LjU4MSAxMDcuMTh2NTcuMDg0aC04OS43MDN2MjQwLjM1MmgtNjYuOTU1VjE2NC4yNjRIMTA4LjIydi01Ny4wODNoMjQ2LjM2MXptNTQuMzEgNzEuNjc3bDcuNTEyIDMzLjY5MmMyLjcxOCAxMi4xNiA1LjU4IDI0LjY4IDguNTg0IDM3LjU1NWEyMTgwLjc3NSAyMTgwLjc3NSAwIDAwOS40NDIgMzguODQzIDEyNjYuMyAxMjY2LjMgMCAwMDEwLjA4NiAzNy41NTVjMy43Mi0xMi41OSA3LjM2OC0yNS40NjYgMTAuOTQ1LTM4LjYyOCAzLjU3Ni0xMy4xNjIgNy4wMS0yNi4xMSAxMC4zLTM4Ljg0M2w1Ljc2OS0yMi40NTZjMS4yNDgtNC44ODcgMi40NzItOS43MDUgMy42NzQtMTQuNDU1IDMuMDA0LTExLjg3NSA1LjY1MS0yMi45NjIgNy45NC0zMy4yNjNoNDYuMzU0bDIuMzg0IDEwLjU2M2EyMDAwLjc3IDIwMDAuNzcgMCAwMDMuOTM1IDE2LjgyOGw2LjcxMSAyNy43MWMxLjIxMyA0Ljk1NiAyLjQ1IDkuOTggMy43MDkgMTUuMDczYTMxMTkuNzc3IDMxMTkuNzc3IDAgMDA5Ljg3MSAzOC44NDMgMTI0OS4yMjcgMTI0OS4yMjcgMCAwMDEwLjczIDM4LjYyOCAxOTA3LjYwNSAxOTA3LjYwNSAwIDAwMTAuMzAxLTM3LjU1NSAxMzk3Ljk0IDEzOTcuOTQgMCAwMDkuNjU3LTM4Ljg0M2w0LjQtMTkuMDQ2Yy43MTUtMy4xMyAxLjQyMS02LjIzNiAyLjExOC05LjMyMWw5LjU3Ny00Mi44OGg2Ni41MjZhMjk4OC43MTggMjk4OC43MTggMCAwMS0xOS41MjkgNjYuMzExbC01LjcyOCAxOC40ODJhMzIzNy40NiAzMjM3LjQ2IDAgMDEtMTQuMDE1IDQzLjc1MmMtNi40MzggMTkuNi0xMi43MzMgMzcuNjk4LTE4Ljg4NSA1NC4yOTRsLTMuMzA2IDguODI1Yy00Ljg4NCAxMi44OTgtOS40MzMgMjQuMjYzLTEzLjY0NyAzNC4wOTVoLTQ5Ljc4N2E4NDE3LjI4OSA4NDE3LjI4OSAwIDAxLTIxLjAzMS02NC44MDkgMTI4OC42ODYgMTI4OC42ODYgMCAwMS0xOC44ODUtNjQuODEgMTk3Mi40NDQgMTk3Mi40NDQgMCAwMS0xOC4yNCA2NC44MSAyNTc5LjQxMiAyNTc5LjQxMiAwIDAxLTIwLjM4OCA2NC44MWgtNDkuNzg3Yy00LjY4Mi0xMC45MjYtOS43Mi0yMy43NDMtMTUuMTEtMzguNDUxbC0xLjYyOS00LjQ3Yy01LjI1OC0xNC41MjEtMTAuNjgtMzAuMTkyLTE2LjI2Ni00Ny4wMTRsLTIuNDA0LTcuMjhjLTYuNDM4LTE5LjYtMTMuMDItNDAuMzQ0LTE5Ljc0My02Mi4yMzRhMjk4OC43MDcgMjk4OC43MDcgMCAwMS0xOS41MjktNjYuMzExaDY3LjM4NXoiIGZpbGw9IiM0Mjg1RjQiIGZpbGwtcnVsZT0ibm9uemVybyIvPjwvc3ZnPg==\");\n// }\n", "import { BoundaryType, Direction } from \"../../controllers/AnimationTypes\";\nimport type { TwistyPlayerController } from \"../../controllers/TwistyPlayerController\";\nimport {\n type ButtonAppearances,\n type ButtonIcon,\n buttonIcons,\n} from \"../../model/props/viewer/ButtonAppearanceProp\";\nimport type { ColorScheme } from \"../../model/props/viewer/ColorSchemeRequestProp\";\nimport type { TwistyPlayerModel } from \"../../model/TwistyPlayerModel\";\nimport { ClassListManager } from \"../ClassListManager\";\nimport { ManagedCustomElement } from \"../ManagedCustomElement\";\nimport { customElementsShim } from \"../node-custom-element-shims\";\nimport { buttonCSS, buttonGridCSS } from \"./TwistyButtons.css\";\nimport {\n documentExitFullscreen,\n documentFullscreenElement,\n requestFullscreen,\n} from \"./webkit-fullscreen\";\n\nconst buttonCommands = {\n fullscreen: true,\n \"jump-to-start\": true,\n \"play-step-backwards\": true,\n \"play-pause\": true,\n \"play-step\": true,\n \"jump-to-end\": true,\n \"twizzle-link\": true,\n};\n\nexport type ButtonCommand = keyof typeof buttonCommands;\n\nexport class TwistyButtons extends ManagedCustomElement {\n buttons: Record<ButtonCommand, TwistyButton> | null = null;\n\n // TODO: Privacy\n constructor(\n public model?: TwistyPlayerModel,\n public controller?: TwistyPlayerController,\n private defaultFullscreenElement?: HTMLElement,\n ) {\n super();\n }\n\n connectedCallback(): void {\n this.addCSS(buttonGridCSS);\n const buttons: Partial<Record<ButtonCommand, TwistyButton>> = {};\n for (const command in buttonCommands) {\n const button = new TwistyButton();\n buttons[command as ButtonCommand] = button;\n button.htmlButton.addEventListener(\"click\", () =>\n this.#onCommand(command as ButtonCommand),\n );\n this.addElement(button);\n }\n this.buttons = buttons as Record<ButtonCommand, TwistyButton>;\n\n this.model?.buttonAppearance.addFreshListener(this.update.bind(this));\n this.model?.twistySceneModel.colorScheme.addFreshListener(\n this.updateColorScheme.bind(this),\n );\n }\n\n #onCommand(command: ButtonCommand) {\n switch (command) {\n case \"fullscreen\": {\n void this.onFullscreenButton();\n break;\n }\n case \"jump-to-start\": {\n this.controller?.jumpToStart({ flash: true });\n break;\n }\n case \"play-step-backwards\": {\n this.controller?.animationController.play({\n direction: Direction.Backwards,\n untilBoundary: BoundaryType.Move,\n });\n break;\n }\n case \"play-pause\": {\n this.controller?.togglePlay();\n break;\n }\n case \"play-step\": {\n this.controller?.animationController.play({\n direction: Direction.Forwards,\n untilBoundary: BoundaryType.Move,\n });\n break;\n }\n case \"jump-to-end\": {\n this.controller?.jumpToEnd({ flash: true });\n break;\n }\n case \"twizzle-link\": {\n void this.controller?.visitTwizzleLink();\n break;\n }\n default:\n throw new Error(\"Missing command\");\n }\n }\n\n // TODO: Should we have a prop, or a way to query if we're fullscreen?\n // https://developer.mozilla.org/en-US/docs/Web/API/Element/requestFullScreen\n async onFullscreenButton(): Promise<void> {\n if (!this.defaultFullscreenElement) {\n throw new Error(\"Attempted to go fullscreen without an element.\");\n }\n\n if (documentFullscreenElement() === this.defaultFullscreenElement) {\n void documentExitFullscreen();\n } else {\n // TODO: Propagate button info to `ButtonAppearanceProp`.\n this.buttons?.fullscreen.setIcon(\"exit-fullscreen\");\n\n void requestFullscreen(\n (await this.model?.twistySceneModel.fullscreenElement.get()) ??\n this.defaultFullscreenElement,\n );\n\n const onFullscreen = (): void => {\n if (documentFullscreenElement() !== this.defaultFullscreenElement) {\n this.buttons?.fullscreen.setIcon(\"enter-fullscreen\");\n globalThis.removeEventListener(\"fullscreenchange\", onFullscreen);\n }\n };\n globalThis.addEventListener(\"fullscreenchange\", onFullscreen);\n }\n }\n\n async update(buttonAppearances: ButtonAppearances): Promise<void> {\n // TODO: Check that we have every command?\n for (const command in buttonCommands) {\n // TODO: Why doesn't `command` have the type `ButtonCommand`?\n const button = this.buttons![command as ButtonCommand];\n // TODO: track individual changes?\n const info = buttonAppearances[command as ButtonCommand];\n button.htmlButton.disabled = !info.enabled;\n button.htmlButton.title = info.title;\n button.setIcon(info.icon);\n button.hidden = !!info.hidden;\n // button.textContent = info.icon;\n }\n }\n\n updateColorScheme(colorScheme: ColorScheme): void {\n for (const button of Object.values(this.buttons ?? {})) {\n button.updateColorScheme(colorScheme);\n }\n }\n}\n\ncustomElementsShim.define(\"twisty-buttons\", TwistyButtons);\n\nclass TwistyButton extends ManagedCustomElement {\n htmlButton: HTMLButtonElement = document.createElement(\"button\"); // TODO: async?\n\n updateColorScheme(colorScheme: ColorScheme): void {\n this.contentWrapper.classList.toggle(\"dark-mode\", colorScheme === \"dark\");\n }\n\n connectedCallback() {\n this.addCSS(buttonCSS);\n this.addElement(this.htmlButton);\n }\n\n #iconManager: ClassListManager<ButtonIcon> = new ClassListManager(\n this,\n \"svg-\",\n buttonIcons,\n );\n\n setIcon(iconName: ButtonIcon): void {\n this.#iconManager.setValue(iconName);\n }\n}\n\ncustomElementsShim.define(\"twisty-button\", TwistyButton);\n", "import { cssStyleSheetShim } from \"../node-custom-element-shims\";\n\nexport const twistyScrubberCSS = new cssStyleSheetShim();\ntwistyScrubberCSS.replaceSync(\n `\n:host {\n width: 384px;\n height: 16px;\n display: grid;\n}\n\n.wrapper {\n width: 100%;\n height: 100%;\n display: grid;\n overflow: hidden;\n backdrop-filter: blur(4px);\n -webkit-backdrop-filter: blur(4px);\n background: rgba(196, 196, 196, 0.75);\n}\n\ninput:not(:disabled) {\n cursor: ew-resize;\n}\n\n.wrapper.dark-mode {\n background: #666666;\n}\n`,\n);\n", "import {\n BoundaryType,\n Direction,\n type MillisecondTimestamp,\n} from \"../../controllers/AnimationTypes\";\nimport type { TwistyPlayerController } from \"../../controllers/TwistyPlayerController\";\nimport type { DetailedTimelineInfo } from \"../../model/props/timeline/DetailedTimelineInfoProp\";\nimport type { ColorScheme } from \"../../model/props/viewer/ColorSchemeRequestProp\";\nimport type { TwistyPlayerModel } from \"../../model/TwistyPlayerModel\";\nimport { globalSafeDocument } from \"../document\";\nimport { ManagedCustomElement } from \"../ManagedCustomElement\";\nimport { customElementsShim } from \"../node-custom-element-shims\";\nimport { twistyScrubberCSS } from \"./TwistyScrubber.css\";\n\nconst SLOW_DOWN_SCRUBBING = false;\n\nlet isMouseDown = false;\n\nglobalSafeDocument?.addEventListener(\n \"mousedown\",\n (event) => {\n if (event.which) {\n isMouseDown = true;\n }\n },\n true,\n);\n\nglobalSafeDocument?.addEventListener(\n \"mouseup\",\n (event) => {\n if (event.which) {\n isMouseDown = false;\n }\n },\n true,\n);\n\n// var x = 0;\nlet y = 0;\nlet clickNum = 0;\n\nglobalSafeDocument?.addEventListener(\n \"mousedown\",\n () => {\n clickNum++;\n },\n false,\n);\n\nglobalSafeDocument?.addEventListener(\"mousemove\", onMouseUpdate, false);\nglobalSafeDocument?.addEventListener(\"mouseenter\", onMouseUpdate, false);\n\nfunction onMouseUpdate(e: MouseEvent) {\n // x = e.pageX;\n y = e.pageY;\n // console.log(x, y);\n}\n\nconst lastVal = 0;\nlet lastPreval = 0;\nlet scaling: boolean = false;\nlet currentClickNum = 0;\n\n// Values are integers.\nexport class TwistyScrubber extends ManagedCustomElement {\n constructor(\n public model?: TwistyPlayerModel,\n public controller?: TwistyPlayerController,\n ) {\n super();\n }\n\n async onDetailedTimelineInfo(\n detailedTimelineInfo: DetailedTimelineInfo,\n ): Promise<void> {\n // TODO: is this efficient enough?\n const inputElem = await this.inputElem();\n inputElem.min = detailedTimelineInfo.timeRange.start.toString();\n inputElem.max = detailedTimelineInfo.timeRange.end.toString();\n inputElem.disabled = inputElem.min === inputElem.max;\n inputElem.value = detailedTimelineInfo.timestamp.toString();\n }\n\n async connectedCallback(): Promise<void> {\n this.addCSS(twistyScrubberCSS);\n this.addElement(await this.inputElem());\n this.model?.twistySceneModel.colorScheme.addFreshListener(\n this.updateColorScheme.bind(this),\n );\n }\n\n updateColorScheme(colorScheme: ColorScheme): void {\n this.contentWrapper.classList.toggle(\"dark-mode\", colorScheme === \"dark\");\n }\n\n #inputElem: Promise<HTMLInputElement> | null = null;\n async inputElem(): Promise<HTMLInputElement> {\n // console.log(\"inputElem\", this.#inputElem);\n return (this.#inputElem ??= (async () => {\n const elem = document.createElement(\"input\");\n elem.type = \"range\";\n elem.disabled = true;\n\n // console.log(\"1\");\n this.model?.detailedTimelineInfo.addFreshListener(\n this.onDetailedTimelineInfo.bind(this),\n );\n // console.log(\"3\");\n elem.addEventListener(\"input\", this.onInput.bind(this));\n elem.addEventListener(\"keydown\", this.onKeypress.bind(this));\n\n return elem;\n })());\n }\n\n async onInput(e: Event): Promise<void> {\n if (scaling) {\n return; // TODO\n }\n const inputElem = await this.inputElem();\n await this.slowDown(e, inputElem); // TODO\n\n const value = parseInt(inputElem.value, 10) as MillisecondTimestamp;\n // console.log(\"on input\", value);\n this.model?.playingInfo.set({ playing: false });\n this.model?.timestampRequest.set(value);\n }\n\n onKeypress(e: KeyboardEvent): void {\n switch (e.key) {\n case \"ArrowLeft\":\n // fallthrough\n case \"ArrowRight\": {\n this.controller?.animationController.play({\n direction:\n e.key === \"ArrowLeft\" ? Direction.Backwards : Direction.Forwards,\n untilBoundary: BoundaryType.Move,\n });\n e.preventDefault();\n break;\n }\n case \" \": {\n this.controller?.togglePlay();\n e.preventDefault();\n break;\n }\n }\n }\n\n async slowDown(e: Event, inputElem: HTMLInputElement): Promise<void> {\n if (!SLOW_DOWN_SCRUBBING) {\n return; // TODO\n }\n\n if (isMouseDown) {\n const rect = inputElem.getBoundingClientRect();\n const sliderY = rect.top + rect.height / 2;\n console.log(sliderY, e, y, isMouseDown);\n\n const yDist = Math.abs(sliderY - y);\n let scale = 1;\n if (yDist > 64) {\n scale = Math.max(2 ** (-(yDist - 64) / 64), 1 / 32);\n }\n const preVal = parseInt(inputElem.value, 10);\n console.log(\"cl\", currentClickNum, clickNum, preVal);\n if (currentClickNum === clickNum) {\n const delta = (preVal - lastPreval) * scale;\n console.log(\"delta\", delta, yDist);\n scaling = true;\n let newVal = preVal;\n newVal =\n lastVal +\n delta * scale +\n (preVal - lastVal) * Math.min(1, (1 / 2) ** ((yDist * yDist) / 64));\n inputElem.value = newVal.toString();\n console.log(scale);\n scaling = false;\n this.contentWrapper.style.opacity = scale.toString();\n } else {\n currentClickNum = clickNum;\n }\n lastPreval = preVal;\n }\n }\n}\n\ncustomElementsShim.define(\"twisty-scrubber\", TwistyScrubber);\n", "import type { PerspectiveCamera } from \"three/src/Three.js\";\nimport { bulk3DCode } from \"../heavy-code-imports/3d\";\nimport type { TwistyPlayerModel } from \"../model/TwistyPlayerModel\";\nimport { rawRenderPooled } from \"./3D/RendererPool\";\nimport { Twisty3DPuzzleWrapper } from \"./3D/Twisty3DPuzzleWrapper\";\nimport { setCameraFromOrbitCoordinates } from \"./3D/Twisty3DVantage\";\n\nexport interface TwistyPlayerScreenshot {\n dataURL: string;\n download: (filename?: string) => Promise<void>;\n}\n\n// TODO: cache\nlet cachedCamera: PerspectiveCamera | null = null;\nexport async function screenshot(\n model: TwistyPlayerModel,\n options?: { width: number; height: number },\n): Promise<TwistyPlayerScreenshot> {\n // TODO: improve async caching\n\n // TODO: Avoid the `_stickering` and `_legacyPosition` calls in favor of proper callbacks.\n const [\n { ThreePerspectiveCamera, ThreeScene },\n puzzleLoader,\n visualizationStrategy,\n _stickering, // TODO\n _stickeringMaskRequest, // TODO\n _legacyPosition,\n orbitCoordinates,\n ] = await Promise.all([\n (async () => {\n const { ThreePerspectiveCamera, ThreeScene } = await bulk3DCode();\n return { ThreePerspectiveCamera, ThreeScene };\n })(),\n await model.puzzleLoader.get(),\n await model.visualizationStrategy.get(),\n await model.twistySceneModel.stickeringRequest.get(),\n await model.twistySceneModel.stickeringMaskRequest.get(),\n await model.legacyPosition.get(),\n await model.twistySceneModel.orbitCoordinates.get(),\n ]);\n\n const width = options?.width ?? 2048;\n const height = options?.height ?? 2048;\n const aspectRatio = width / height;\n const camera = (cachedCamera ??= await (async () => {\n return new ThreePerspectiveCamera(20, aspectRatio, 0.1, 20);\n })());\n\n const scene = new ThreeScene();\n const twisty3DWrapper = new Twisty3DPuzzleWrapper(\n model,\n { scheduleRender: () => {} },\n puzzleLoader,\n visualizationStrategy,\n );\n scene.add(await twisty3DWrapper.twisty3DPuzzle());\n await setCameraFromOrbitCoordinates(camera, orbitCoordinates);\n\n const rendererCanvas = await rawRenderPooled(width, height, scene, camera);\n const dataURL = rendererCanvas.toDataURL();\n\n const defaultFilename = await getDefaultFilename(model);\n\n return {\n dataURL,\n download: async (filename?: string) => {\n downloadURL(dataURL, filename ?? defaultFilename);\n },\n };\n}\n\nexport async function getDefaultFilename(\n model: TwistyPlayerModel,\n): Promise<string> {\n const [puzzleID, algWithIssues] = await Promise.all([\n model.puzzleID.get(),\n model.alg.get(),\n ]);\n return `[${puzzleID}]${\n algWithIssues.alg.experimentalNumChildAlgNodes() === 0\n ? \"\"\n : ` ${algWithIssues.alg.toString()}`\n }`;\n}\n\nexport function downloadURL(\n url: string,\n name: string,\n extension: string = \"png\",\n): void {\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = `${name}.${extension}`;\n a.click();\n}\n", "import { cssStyleSheetShim } from \"./node-custom-element-shims\";\n\n// TODO: figure out why `:host(twisty-player):fullscreen { background-color: white }` doesn't work.\nexport const twistyPlayerCSS = new cssStyleSheetShim();\ntwistyPlayerCSS.replaceSync(\n `\n:host {\n width: 384px;\n height: 256px;\n display: grid;\n\n -webkit-user-select: none;\n user-select: none;\n}\n\n.wrapper {\n display: grid;\n overflow: hidden;\n contain: size;\n grid-template-rows: 7fr minmax(1.5em, 0.5fr) minmax(2em, 1fr);\n}\n\n.wrapper > * {\n width: inherit;\n height: inherit;\n overflow: hidden;\n}\n\n.wrapper.controls-none {\n grid-template-rows: 7fr;\n}\n\n.wrapper.controls-none twisty-scrubber,\n.wrapper.controls-none twisty-control-button-panel ,\n.wrapper.controls-none twisty-scrubber,\n.wrapper.controls-none twisty-buttons {\n display: none;\n}\n\ntwisty-scrubber {\n background: rgba(196, 196, 196, 0.5);\n}\n\n.wrapper.checkered,\n.wrapper.checkered-transparent {\n background-color: #EAEAEA;\n background-image: linear-gradient(45deg, #DDD 25%, transparent 25%, transparent 75%, #DDD 75%, #DDD),\n linear-gradient(45deg, #DDD 25%, transparent 25%, transparent 75%, #DDD 75%, #DDD);\n background-size: 32px 32px;\n background-position: 0 0, 16px 16px;\n}\n\n.wrapper.checkered-transparent {\n background-color: #F4F4F4;\n background-image: linear-gradient(45deg, #DDDDDD88 25%, transparent 25%, transparent 75%, #DDDDDD88 75%, #DDDDDD88),\n linear-gradient(45deg, #DDDDDD88 25%, transparent 25%, transparent 75%, #DDDDDD88 75%, #DDDDDD88);\n}\n\n.wrapper.dark-mode {\n background-color: #444;\n background-image: linear-gradient(45deg, #DDDDDD0b 25%, transparent 25%, transparent 75%, #DDDDDD0b 75%, #DDDDDD0b),\n linear-gradient(45deg, #DDDDDD0b 25%, transparent 25%, transparent 75%, #DDDDDD0b 75%, #DDDDDD0b);\n}\n\n.visualization-wrapper > * {\n width: 100%;\n height: 100%;\n}\n\n.error-elem {\n width: 100%;\n height: 100%;\n display: none;\n place-content: center;\n font-family: sans-serif;\n box-shadow: inset 0 0 2em rgb(255, 0, 0);\n color: red;\n text-shadow: 0 0 0.2em white;\n background: rgba(255, 255, 255, 0.25);\n}\n\n.wrapper.error .visualization-wrapper {\n display: none;\n}\n\n.wrapper.error .error-elem {\n display: grid;\n}\n`,\n);\n", "import { SimpleTwistyPropSource } from \"../TwistyProp\";\n\nexport class ArbitraryStringProp extends SimpleTwistyPropSource<string | null> {\n getDefaultValue(): string | null {\n return null;\n }\n}\n", "import { TwistyPropSource } from \"../TwistyProp\";\n\nexport class URLProp extends TwistyPropSource<URL | null, URL | string | null> {\n getDefaultValue(): URL | null {\n return null;\n }\n\n derive(input: URL | string | null): URL | null {\n if (typeof input === \"string\") {\n return new URL(input, location.href); // TODO\n }\n return input;\n }\n}\n", "import { Alg } from \"../../../../../alg\";\nimport { arrayEquals } from \"../../../helpers\";\nimport { TwistyPropSource } from \"../../TwistyProp\";\n\nexport class AlgIssues {\n // TODO: (string | Error)[]\n\n readonly warnings: readonly string[];\n readonly errors: readonly string[];\n\n constructor(issues?: { warnings?: string[]; errors?: string[] }) {\n // TODO: clone inputs?\n this.warnings = Object.freeze(issues?.warnings ?? []);\n this.errors = Object.freeze(issues?.errors ?? []);\n Object.freeze(this);\n }\n\n add(issues?: { warnings?: string[]; errors?: string[] }) {\n return new AlgIssues({\n warnings: this.warnings.concat(issues?.warnings ?? []),\n errors: this.errors.concat(issues?.errors ?? []),\n });\n }\n\n /** @deprecated */\n log() {\n if (this.errors.length > 0) {\n console.error(`\uD83D\uDEA8 ${this.errors[0]}`);\n } else if (this.warnings.length > 0) {\n console.warn(`\u26A0\uFE0F ${this.warnings[0]}`);\n } else {\n console.info(\"\uD83D\uDE0E No issues!\");\n }\n }\n}\n\nexport interface AlgWithIssues {\n alg: Alg;\n issues: AlgIssues;\n}\n\nexport function algWithIssuesFromString(s: string): AlgWithIssues {\n try {\n const alg = Alg.fromString(s); // TODO: is this safe?\n const warnings = [];\n if (alg.toString() !== s) {\n // TODO: Push this check into the parser and return semantic info (so they can be e.g. highlighted).\n warnings.push(\"Alg is non-canonical!\");\n }\n return {\n alg,\n issues: new AlgIssues({ warnings }),\n };\n } catch (e) {\n return {\n alg: new Alg(),\n issues: new AlgIssues({\n errors: [`Malformed alg: ${(e as Error).toString()}`],\n }),\n };\n }\n}\n\nfunction algWithIssuesEquals(a1: AlgWithIssues, a2: AlgWithIssues): boolean {\n return (\n a1.alg.isIdentical(a2.alg) &&\n arrayEquals(a1.issues.warnings, a2.issues.warnings) &&\n arrayEquals(a1.issues.errors, a2.issues.errors)\n );\n}\n\nexport class AlgProp extends TwistyPropSource<AlgWithIssues, Alg | string> {\n override getDefaultValue(): AlgWithIssues {\n return { alg: new Alg(), issues: new AlgIssues() };\n }\n\n protected override canReuseValue(v1: AlgWithIssues, v2: AlgWithIssues) {\n return algWithIssuesEquals(v1, v2);\n }\n\n protected override async derive(\n newAlg: Alg | string,\n ): Promise<AlgWithIssues> {\n if (typeof newAlg === \"string\") {\n return algWithIssuesFromString(newAlg);\n } else {\n return {\n alg: newAlg,\n issues: new AlgIssues(),\n };\n }\n }\n}\n", "import type { KPuzzle, KTransformation } from \"../../../../../kpuzzle\";\nimport { TwistyPropDerived } from \"../../TwistyProp\";\nimport type { AlgWithIssues } from \"./AlgProp\";\n\ntype AlgTransformationPropInputs = {\n setupAlg: AlgWithIssues;\n kpuzzle: KPuzzle;\n};\n\nexport class AlgTransformationProp extends TwistyPropDerived<\n AlgTransformationPropInputs,\n KTransformation\n> {\n derive(input: AlgTransformationPropInputs): KTransformation {\n return input.kpuzzle.algToTransformation(input.setupAlg.alg);\n }\n}\n", "import type { KTransformation } from \"../../../../../kpuzzle\";\nimport type {\n AlgIndexer,\n LeafIndex,\n} from \"../../../../controllers/indexer/AlgIndexer\";\nimport { TwistyPropDerived } from \"../../TwistyProp\";\nimport type { SetupToLocation } from \"./SetupAnchorProp\";\n\ninterface AnchorTransformationPropInputs {\n setupTransformation: KTransformation | null;\n setupAnchor: SetupToLocation;\n setupAlgTransformation: KTransformation;\n indexer: AlgIndexer;\n}\n\nexport class AnchorTransformationProp extends TwistyPropDerived<\n AnchorTransformationPropInputs,\n KTransformation\n> {\n derive(inputs: AnchorTransformationPropInputs): KTransformation {\n if (inputs.setupTransformation) {\n return inputs.setupTransformation;\n }\n switch (inputs.setupAnchor) {\n case \"start\":\n return inputs.setupAlgTransformation;\n case \"end\": {\n const algTransformation = inputs.indexer.transformationAtIndex(\n inputs.indexer.numAnimatedLeaves() as number as LeafIndex,\n );\n const inverseAlgTransformation = algTransformation.invert();\n return inputs.setupAlgTransformation.applyTransformation(\n inverseAlgTransformation,\n );\n }\n default:\n throw new Error(\"Unimplemented!\");\n }\n }\n}\n", "import type { AlgLeaf } from \"../../../../../alg\";\nimport type { MillisecondTimestamp } from \"../../../../controllers/AnimationTypes\";\nimport { SimpleTwistyPropSource } from \"../../TwistyProp\";\n\nexport interface AnimationTimelineLeaf {\n animLeaf: AlgLeaf;\n start: MillisecondTimestamp;\n end: MillisecondTimestamp;\n}\n\nexport type AnimationTimelineLeaves = AnimationTimelineLeaf[];\n\nexport class AnimationTimelineLeavesRequestProp extends SimpleTwistyPropSource<\n AnimationTimelineLeaf[] | null\n> {\n getDefaultValue(): AnimationTimelineLeaf[] | null {\n return null;\n }\n}\n", "import type { Move } from \"../../../../../alg\";\nimport { SimpleTwistyPropSource } from \"../../TwistyProp\";\n\nexport interface CatchUpMove {\n move: Move | null;\n amount: number;\n}\n\nexport class CatchUpMoveProp extends SimpleTwistyPropSource<CatchUpMove> {\n override getDefaultValue(): CatchUpMove {\n return { move: null, amount: 0 };\n }\n\n protected override canReuseValue(v1: CatchUpMove, v2: CatchUpMove) {\n return v1.move === v2.move && v1.amount === v2.amount;\n }\n}\n", "import type { Move } from \"../../../../../alg\";\nimport type {\n CurrentMoveInfo,\n LeafIndex,\n} from \"../../../../controllers/indexer/AlgIndexer\";\nimport { arrayEqualsCompare } from \"../../../helpers\";\nimport { TwistyPropDerived } from \"../../TwistyProp\";\n\ninterface CurrentLeavesSimplifiedPropInputs {\n currentMoveInfo: CurrentMoveInfo;\n}\n\nexport interface CurrentLeavesSimplified {\n patternIndex: LeafIndex;\n movesFinishing: Move[];\n movesFinished: Move[];\n}\n\n// This started as a version of `CurrentLeaves` without highly timestamp-sensitive info like fractions, to enable easier caching.\nexport class CurrentLeavesSimplifiedProp extends TwistyPropDerived<\n CurrentLeavesSimplifiedPropInputs,\n CurrentLeavesSimplified\n> {\n protected override derive(\n inputs: CurrentLeavesSimplifiedPropInputs,\n ): CurrentLeavesSimplified {\n return {\n patternIndex: inputs.currentMoveInfo.patternIndex as LeafIndex,\n movesFinishing: inputs.currentMoveInfo.movesFinishing.map(\n (currentMoveInfo) => currentMoveInfo.move,\n ),\n movesFinished: inputs.currentMoveInfo.movesFinished.map(\n (currentMoveInfo) => currentMoveInfo.move,\n ),\n };\n }\n\n protected override canReuseValue(\n v1: CurrentLeavesSimplified,\n v2: CurrentLeavesSimplified,\n ): boolean {\n return (\n v1.patternIndex === v2.patternIndex &&\n arrayEqualsCompare(\n v1.movesFinishing,\n v2.movesFinishing,\n (m1: Move, m2: Move) => m1.isIdentical(m2),\n ) &&\n arrayEqualsCompare(\n v1.movesFinished,\n v2.movesFinished,\n (m1: Move, m2: Move) => m1.isIdentical(m2),\n )\n );\n }\n}\n", "import { Move } from \"../../../../../alg\";\nimport {\n Direction,\n type MillisecondTimestamp,\n} from \"../../../../controllers/AnimationTypes\";\nimport type {\n AlgIndexer,\n CurrentMove,\n CurrentMoveInfo,\n} from \"../../../../controllers/indexer/AlgIndexer\";\nimport { TwistyPropDerived } from \"../../TwistyProp\";\nimport type { DetailedTimelineInfo } from \"../../timeline/DetailedTimelineInfoProp\";\nimport type { CatchUpMove } from \"./CatchUpMoveProp\";\n\ninterface PositionPropInputs {\n indexer: AlgIndexer;\n detailedTimelineInfo: DetailedTimelineInfo;\n catchUpMove: CatchUpMove;\n}\n\n// TODO: Rename \"current\" (implies a single one) to \"active\"?\nexport class CurrentMoveInfoProp extends TwistyPropDerived<\n PositionPropInputs,\n CurrentMoveInfo\n> {\n derive(inputs: PositionPropInputs): CurrentMoveInfo {\n function addCatchUpMove(currentMoveInfo: CurrentMoveInfo): CurrentMoveInfo {\n if (\n inputs.detailedTimelineInfo.atEnd &&\n inputs.catchUpMove.move !== null\n ) {\n currentMoveInfo.currentMoves.push({\n move: inputs.catchUpMove.move,\n direction: Direction.Backwards,\n fraction: 1 - inputs.catchUpMove.amount,\n startTimestamp: -1 as MillisecondTimestamp, // TODO\n endTimestamp: -1 as MillisecondTimestamp, // TODO\n });\n }\n return currentMoveInfo;\n }\n\n // Copied from AlgCursor\n if (inputs.indexer.currentMoveInfo) {\n return addCatchUpMove(\n inputs.indexer.currentMoveInfo(inputs.detailedTimelineInfo.timestamp),\n );\n } else {\n const idx = inputs.indexer.timestampToIndex(\n inputs.detailedTimelineInfo.timestamp,\n );\n const currentMoveInfo: CurrentMoveInfo = {\n patternIndex: idx,\n currentMoves: [],\n movesFinishing: [],\n movesFinished: [],\n movesStarting: [],\n latestStart: -Infinity,\n earliestEnd: Infinity,\n };\n\n if (inputs.indexer.numAnimatedLeaves() > 0) {\n const move = inputs.indexer.getAnimLeaf(idx)?.as(Move);\n if (!move) {\n return addCatchUpMove(currentMoveInfo);\n }\n const start = inputs.indexer.indexToMoveStartTimestamp(idx);\n const duration = inputs.indexer.moveDuration(idx);\n const fraction = duration\n ? (inputs.detailedTimelineInfo.timestamp - start) / duration\n : 0;\n const end = (start + duration) as MillisecondTimestamp;\n const currentMove: CurrentMove = {\n move,\n direction: Direction.Forwards,\n fraction,\n startTimestamp: start,\n endTimestamp: end,\n };\n if (fraction === 0) {\n currentMoveInfo.movesStarting.push(currentMove);\n // // TODO: push this into the indexer\n // position.state = combineTransformations(\n // inputs.def,\n // state,\n // transformationForMove(inputs.def, move),\n // ) as Transformation;\n } else if (fraction === 1) {\n currentMoveInfo.movesFinishing.push(currentMove);\n // // TODO: push this into the indexer\n // position.state = combineTransformations(\n // inputs.def,\n // state,\n // transformationForMove(inputs.def, move),\n // ) as Transformation;\n } else {\n // TODO\n currentMoveInfo.currentMoves.push(currentMove);\n currentMoveInfo.latestStart = Math.max(\n currentMoveInfo.latestStart,\n start,\n );\n currentMoveInfo.earliestEnd = Math.min(\n currentMoveInfo.earliestEnd,\n end,\n );\n }\n // }\n // }\n }\n return addCatchUpMove(currentMoveInfo);\n }\n }\n}\n", "import type { KTransformation } from \"../../../../../kpuzzle\";\nimport type { KPattern } from \"../../../../../kpuzzle/KPattern\";\nimport type { AlgIndexer } from \"../../../../controllers/indexer/AlgIndexer\";\nimport { TwistyPropDerived } from \"../../TwistyProp\";\nimport type { CurrentLeavesSimplified } from \"./CurrentLeavesSimplified\";\n\ninterface CurrentTransformationPropInputs {\n anchoredStart: KTransformation; // kpuzzle todo: KPattern?\n currentLeavesSimplified: CurrentLeavesSimplified;\n indexer: AlgIndexer;\n}\n\n// TODO: Make this so we don't have to handle the finishing moves?\nexport class CurrentPatternProp extends TwistyPropDerived<\n CurrentTransformationPropInputs,\n KPattern\n> {\n derive(inputs: CurrentTransformationPropInputs): KPattern {\n let transformation: KTransformation = inputs.indexer.transformationAtIndex(\n inputs.currentLeavesSimplified.patternIndex,\n );\n transformation = inputs.anchoredStart.applyTransformation(transformation);\n\n // TODO: handle non-commutative finished/finishing/current moves.\n for (const finishingMove of inputs.currentLeavesSimplified.movesFinishing) {\n transformation = transformation.applyMove(finishingMove);\n }\n for (const finishedMove of inputs.currentLeavesSimplified.movesFinished) {\n transformation = transformation.applyMove(finishedMove);\n }\n return transformation.toKPattern(); // kpuzzle todo\n }\n}\n", "import {\n type Alg,\n type Commutator,\n type Conjugate,\n functionFromTraversal,\n type Grouping,\n LineComment,\n Move,\n Newline,\n type Pause,\n TraversalUp,\n} from \"../../../../alg\";\nimport type { AnimationTimelineLeaf } from \"../../../model/props/puzzle/state/AnimationTimelineLeavesRequestProp\";\nimport type {\n MillisecondDuration,\n MillisecondTimestamp,\n} from \"../../AnimationTypes\";\nimport { defaultDurationForAmount } from \"../AlgDuration\";\n\nexport type AnimatedLeafAlgNode = Move | Pause;\nexport interface LocalAnimLeavesWithRange {\n animLeafAlgNode: AnimatedLeafAlgNode;\n msUntilNext: MillisecondDuration;\n duration: MillisecondDuration;\n}\n\nconst axisLookup: Record<string, \"x\" | \"y\" | \"z\"> = {\n u: \"y\",\n l: \"x\",\n f: \"z\",\n r: \"x\",\n b: \"z\",\n d: \"y\",\n m: \"x\",\n e: \"y\",\n s: \"z\",\n x: \"x\",\n y: \"y\",\n z: \"z\",\n};\n\nfunction isSameAxis(move1: Move, move2: Move): boolean {\n return (\n axisLookup[move1.family[0].toLowerCase()] ===\n axisLookup[move2.family[0].toLowerCase()]\n );\n}\n\n// TODO: Replace this with an optimized implementation.\n// TODO: Consider `(x U)` and `(U x F)` to be simultaneous.\nexport class LocalSimulMoves extends TraversalUp<LocalAnimLeavesWithRange[]> {\n public traverseAlg(alg: Alg): LocalAnimLeavesWithRange[] {\n const processed: LocalAnimLeavesWithRange[][] = [];\n for (const childAlgNode of alg.childAlgNodes()) {\n processed.push(this.traverseAlgNode(childAlgNode));\n }\n return Array.prototype.concat(...processed) as LocalAnimLeavesWithRange[];\n }\n\n public traverseGroupingOnce(alg: Alg): LocalAnimLeavesWithRange[] {\n if (alg.experimentalIsEmpty()) {\n return [];\n }\n\n const moves: Move[] = [];\n for (const algNode of alg.childAlgNodes()) {\n if (\n !(algNode.is(Move) || algNode.is(LineComment) || algNode.is(Newline))\n ) {\n // TODO: define the type statically on the class?\n return this.traverseAlg(alg);\n }\n const asMove = algNode.as(Move);\n if (asMove) {\n moves.push(asMove);\n }\n }\n\n let maxSimulDur = defaultDurationForAmount(moves[0].amount);\n for (let i = 0; i < moves.length - 1; i++) {\n for (let j = 1; j < moves.length; j++) {\n if (!isSameAxis(moves[i], moves[j])) {\n return this.traverseAlg(alg);\n }\n }\n maxSimulDur = Math.max(\n maxSimulDur,\n defaultDurationForAmount(moves[i].amount),\n ) as MillisecondDuration;\n }\n\n const localMovesWithRange: LocalAnimLeavesWithRange[] = moves.map(\n (blockMove): LocalAnimLeavesWithRange => {\n return {\n animLeafAlgNode: blockMove,\n msUntilNext: 0 as MillisecondDuration,\n duration: maxSimulDur as MillisecondDuration,\n };\n },\n );\n localMovesWithRange[localMovesWithRange.length - 1].msUntilNext =\n maxSimulDur as MillisecondDuration;\n return localMovesWithRange;\n }\n\n public traverseGrouping(grouping: Grouping): LocalAnimLeavesWithRange[] {\n const processed: LocalAnimLeavesWithRange[][] = [];\n\n const segmentOnce: Alg =\n grouping.amount > 0 ? grouping.alg : grouping.alg.invert();\n for (let i = 0; i < Math.abs(grouping.amount); i++) {\n processed.push(this.traverseGroupingOnce(segmentOnce));\n }\n return Array.prototype.concat(...processed) as LocalAnimLeavesWithRange[];\n }\n\n public traverseMove(move: Move): LocalAnimLeavesWithRange[] {\n const duration = defaultDurationForAmount(move.amount);\n return [\n {\n animLeafAlgNode: move,\n msUntilNext: duration,\n duration,\n },\n ];\n }\n\n public traverseCommutator(\n commutator: Commutator,\n ): LocalAnimLeavesWithRange[] {\n const processed: LocalAnimLeavesWithRange[][] = [];\n const segmentsOnce: Alg[] = [\n commutator.A,\n commutator.B,\n commutator.A.invert(),\n commutator.B.invert(),\n ];\n for (const segment of segmentsOnce) {\n processed.push(this.traverseGroupingOnce(segment));\n }\n return Array.prototype.concat(...processed) as LocalAnimLeavesWithRange[];\n }\n\n public traverseConjugate(conjugate: Conjugate): LocalAnimLeavesWithRange[] {\n const processed: LocalAnimLeavesWithRange[][] = [];\n const segmentsOnce: Alg[] = [\n conjugate.A,\n conjugate.B,\n conjugate.A.invert(),\n ];\n for (const segment of segmentsOnce) {\n processed.push(this.traverseGroupingOnce(segment));\n }\n return Array.prototype.concat(...processed) as LocalAnimLeavesWithRange[];\n }\n\n public traversePause(pause: Pause): LocalAnimLeavesWithRange[] {\n if (pause.experimentalNISSGrouping) {\n return [];\n }\n const duration = defaultDurationForAmount(1);\n return [\n {\n animLeafAlgNode: pause,\n msUntilNext: duration, // TODO\n duration,\n },\n ];\n }\n\n public traverseNewline(_newline: Newline): LocalAnimLeavesWithRange[] {\n return [];\n }\n\n public traverseLineComment(\n _comment: LineComment,\n ): LocalAnimLeavesWithRange[] {\n return [];\n }\n}\n\nconst localSimulMoves = functionFromTraversal(LocalSimulMoves);\n\nexport function simulMoves(a: Alg): AnimationTimelineLeaf[] {\n let timestamp = 0;\n const l = localSimulMoves(a).map(\n (localSimulMove: LocalAnimLeavesWithRange): AnimationTimelineLeaf => {\n const leafWithRange = {\n animLeaf: localSimulMove.animLeafAlgNode,\n start: timestamp as MillisecondTimestamp,\n end: (timestamp + localSimulMove.duration) as MillisecondTimestamp,\n };\n timestamp += localSimulMove.msUntilNext;\n return leafWithRange;\n },\n );\n return l;\n}\n", "import { type Alg, Move } from \"../../../../alg\";\nimport type { KPuzzle, KTransformation } from \"../../../../kpuzzle\";\nimport type { KPattern } from \"../../../../kpuzzle/KPattern\";\nimport type {\n AnimationTimelineLeaf,\n AnimationTimelineLeaves,\n} from \"../../../model/props/puzzle/state/AnimationTimelineLeavesRequestProp\";\nimport {\n Direction,\n type MillisecondDuration,\n type MillisecondTimestamp,\n type PuzzlePosition,\n} from \"../../AnimationTypes\";\nimport type {\n CurrentMove,\n CurrentMoveInfo,\n LeafCount,\n LeafIndex,\n} from \"../AlgIndexer\";\nimport { type AnimatedLeafAlgNode, simulMoves } from \"./simul-moves\";\n\nexport class SimultaneousMoveIndexer {\n private animLeaves: AnimationTimelineLeaf[];\n // TODO: Allow custom `durationFn`.\n\n constructor(\n private kpuzzle: KPuzzle,\n alg: Alg,\n options?: { animationTimelineLeaves?: AnimationTimelineLeaves | null },\n ) {\n this.animLeaves = options?.animationTimelineLeaves ?? simulMoves(alg);\n // TODO: Avoid assuming all base moves are block moves.\n }\n\n public getAnimLeaf(index: number): AnimatedLeafAlgNode | null {\n return (\n this.animLeaves[Math.min(index, this.animLeaves.length - 1)]?.animLeaf ??\n null\n );\n }\n\n private getAnimationTimelineLeaf(index: number): AnimationTimelineLeaf {\n return this.animLeaves[Math.min(index, this.animLeaves.length - 1)];\n }\n\n public indexToMoveStartTimestamp(index: number): MillisecondTimestamp {\n let start = 0;\n if (this.animLeaves.length > 0) {\n start =\n this.animLeaves[Math.min(index, this.animLeaves.length - 1)].start;\n }\n return start as MillisecondTimestamp;\n }\n\n public timestampToIndex(timestamp: MillisecondTimestamp): LeafIndex {\n let i = 0;\n for (i = 0; i < this.animLeaves.length; i++) {\n if (this.animLeaves[i].start >= timestamp) {\n return Math.max(0, i - 1) as LeafIndex;\n }\n }\n return Math.max(0, i - 1) as LeafIndex;\n }\n\n public timestampToPosition(\n timestamp: MillisecondTimestamp,\n startPattern?: KPattern,\n ): PuzzlePosition {\n const currentMoveInfo = this.currentMoveInfo(timestamp);\n\n let pattern =\n startPattern ?? this.kpuzzle.identityTransformation().toKPattern();\n for (const leafWithRange of this.animLeaves.slice(\n 0,\n currentMoveInfo.patternIndex,\n )) {\n const move = leafWithRange.animLeaf.as(Move);\n if (move !== null) {\n pattern = pattern.applyMove(move);\n }\n }\n\n return {\n pattern: pattern,\n movesInProgress: currentMoveInfo.currentMoves,\n };\n }\n\n // TODO: Caching\n public currentMoveInfo(timestamp: MillisecondTimestamp): CurrentMoveInfo {\n // The starting timestamp of the earliest active move.\n let windowEarliestTimestamp = Infinity;\n for (const leafWithRange of this.animLeaves) {\n if (leafWithRange.start <= timestamp && leafWithRange.end >= timestamp) {\n windowEarliestTimestamp = Math.min(\n windowEarliestTimestamp,\n leafWithRange.start,\n );\n } else if (leafWithRange.start > timestamp) {\n break;\n }\n }\n\n const currentMoves: CurrentMove[] = [];\n const movesStarting: CurrentMove[] = [];\n const movesFinishing: CurrentMove[] = [];\n const movesFinished: CurrentMove[] = [];\n let latestStart: number = -Infinity; // TODO: is there a better way to accumulate this?\n let earliestEnd: number = Infinity; // TODO: is there a better way to accumulate this?\n\n let patternIndex: number = 0;\n for (const leafWithRange of this.animLeaves) {\n if (leafWithRange.end <= windowEarliestTimestamp) {\n if (\n // biome-ignore lint/suspicious/noGlobalIsFinite: TODO: wait on Biome to remove this check by default\n !isFinite(windowEarliestTimestamp) &&\n leafWithRange.start > timestamp\n ) {\n // Allow for time segments without any active leaf.\n break;\n }\n patternIndex++;\n } else if (leafWithRange.start > timestamp) {\n break;\n } else {\n const move = leafWithRange.animLeaf.as(Move);\n if (move !== null) {\n let fraction =\n (timestamp - leafWithRange.start) /\n (leafWithRange.end - leafWithRange.start);\n let moveFinished = false;\n if (fraction > 1) {\n fraction = 1;\n moveFinished = true;\n }\n const currentMove = {\n move: move,\n direction: Direction.Forwards,\n fraction: fraction,\n startTimestamp: leafWithRange.start,\n endTimestamp: leafWithRange.end,\n };\n switch (fraction) {\n case 0: {\n movesStarting.push(currentMove);\n break;\n }\n case 1: {\n // Generalize this to avoid reordering commuting moves.\n if (moveFinished) {\n movesFinished.push(currentMove);\n } else {\n movesFinishing.push(currentMove);\n }\n break;\n }\n default:\n currentMoves.push(currentMove);\n latestStart = Math.max(latestStart, leafWithRange.start);\n earliestEnd = Math.min(earliestEnd, leafWithRange.end);\n }\n }\n }\n }\n return {\n patternIndex: patternIndex,\n currentMoves,\n latestStart,\n earliestEnd,\n movesStarting,\n movesFinishing,\n movesFinished,\n };\n }\n\n public patternAtIndex(index: number, startPattern?: KPattern): KPattern {\n let pattern = startPattern ?? this.kpuzzle.defaultPattern();\n for (let i = 0; i < this.animLeaves.length && i < index; i++) {\n const leafWithRange = this.animLeaves[i];\n const move = leafWithRange.animLeaf.as(Move);\n if (move !== null) {\n pattern = pattern.applyMove(move);\n }\n }\n return pattern;\n }\n\n public transformationAtIndex(index: number): KTransformation {\n let transformation = this.kpuzzle.identityTransformation();\n for (const leafWithRange of this.animLeaves.slice(0, index)) {\n const move = leafWithRange.animLeaf.as(Move);\n if (move !== null) {\n transformation = transformation.applyMove(move);\n }\n }\n return transformation;\n }\n\n public algDuration(): MillisecondDuration {\n let max = 0;\n for (const leafWithRange of this.animLeaves) {\n max = Math.max(max, leafWithRange.end);\n }\n return max as MillisecondDuration;\n }\n\n public numAnimatedLeaves(): LeafCount {\n // TODO: Cache internally once performance matters.\n return this.animLeaves.length as LeafCount;\n }\n\n public moveDuration(index: LeafIndex): MillisecondDuration {\n const move = this.getAnimationTimelineLeaf(index);\n return (move.end - move.start) as MillisecondDuration;\n }\n}\n", "import type { Alg } from \"../../../../../alg\";\nimport type { KPuzzle } from \"../../../../../kpuzzle\";\nimport { countLeavesInExpansionForSimultaneousMoveIndexer } from \"../../../../../notation/CountMoves\";\nimport type { AlgIndexer } from \"../../../..\";\nimport { SimpleAlgIndexer } from \"../../../../controllers/indexer/SimpleAlgIndexer\";\nimport { SimultaneousMoveIndexer } from \"../../../../controllers/indexer/simultaneous-moves/SimultaneousMoveIndexer\";\nimport { TreeAlgIndexer } from \"../../../../controllers/indexer/tree/TreeAlgIndexer\";\nimport { TwistyPropDerived } from \"../../TwistyProp\";\nimport type { VisualizationStrategy } from \"../../viewer/VisualizationStrategyProp\";\nimport type { PuzzleID } from \"../structure/PuzzleIDRequestProp\";\nimport type { AlgWithIssues } from \"./AlgProp\";\nimport type { AnimationTimelineLeaves } from \"./AnimationTimelineLeavesRequestProp\";\nimport type { IndexerStrategyName } from \"./IndexerConstructorRequestProp\";\n\nexport type IndexerConstructor = new (\n kpuzzle: KPuzzle,\n alg: Alg,\n options?: {\n animationTimelineLeaves?: AnimationTimelineLeaves | null;\n },\n) => AlgIndexer;\n\ninterface IndexerConstructorPropInputs {\n puzzle: PuzzleID;\n alg: AlgWithIssues;\n visualizationStrategy: VisualizationStrategy;\n indexerConstructorRequest: IndexerStrategyName;\n animationTimelineLeaves: AnimationTimelineLeaves | null;\n}\n\n// `SimultaneousMoveIndexer` is currently not optimized and has to expand the alg. This bounds the number of moves in the expanded alg.\nconst SIMULTANEOUS_INDEXER_MAX_EXPANDED_LEAVES = 1024;\n\n// TODO: Also handle PG3D vs. 3D\nexport class IndexerConstructorProp extends TwistyPropDerived<\n IndexerConstructorPropInputs,\n IndexerConstructor\n> {\n derive(inputs: IndexerConstructorPropInputs): IndexerConstructor {\n switch (inputs.indexerConstructorRequest) {\n case \"auto\":\n if (inputs.animationTimelineLeaves !== null) {\n return SimultaneousMoveIndexer;\n }\n if (\n countLeavesInExpansionForSimultaneousMoveIndexer(inputs.alg.alg) <=\n SIMULTANEOUS_INDEXER_MAX_EXPANDED_LEAVES &&\n inputs.puzzle === \"3x3x3\" &&\n inputs.visualizationStrategy === \"Cube3D\"\n ) {\n return SimultaneousMoveIndexer;\n } else {\n return TreeAlgIndexer;\n }\n case \"tree\":\n return TreeAlgIndexer;\n case \"simple\":\n return SimpleAlgIndexer;\n case \"simultaneous\":\n return SimultaneousMoveIndexer;\n default:\n throw new Error(\"Invalid indexer request!\");\n }\n }\n}\n", "import { SimpleTwistyPropSource } from \"../../TwistyProp\";\n\nexport const indexerStrategyNames = {\n auto: true,\n simple: true,\n tree: true,\n simultaneous: true,\n};\nexport type IndexerStrategyName = keyof typeof indexerStrategyNames;\n\nexport class IndexerConstructorRequestProp extends SimpleTwistyPropSource<IndexerStrategyName> {\n getDefaultValue(): IndexerStrategyName {\n return \"auto\";\n }\n}\n", "import type { KPuzzle } from \"../../../../../kpuzzle\";\nimport type { AlgIndexer } from \"../../../../controllers/indexer/AlgIndexer\";\nimport { TwistyPropDerived } from \"../../TwistyProp\";\nimport type { AlgWithIssues } from \"./AlgProp\";\nimport type { AnimationTimelineLeaves } from \"./AnimationTimelineLeavesRequestProp\";\nimport type { IndexerConstructor } from \"./IndexerConstructorProp\";\n\ntype IndexerPropInputs = {\n indexerConstructor: IndexerConstructor;\n algWithIssues: AlgWithIssues;\n kpuzzle: KPuzzle;\n animationTimelineLeaves: AnimationTimelineLeaves | null;\n};\nexport class IndexerProp extends TwistyPropDerived<\n IndexerPropInputs,\n AlgIndexer\n> {\n derive(input: IndexerPropInputs): AlgIndexer {\n return new input.indexerConstructor(\n input.kpuzzle,\n input.algWithIssues.alg,\n { animationTimelineLeaves: input.animationTimelineLeaves },\n );\n }\n}\n", "import type { KPattern } from \"../../../../../kpuzzle/KPattern\";\nimport type { PuzzlePosition } from \"../../../../controllers/AnimationTypes\";\nimport type { CurrentMoveInfo } from \"../../../../controllers/indexer/AlgIndexer\";\nimport { TwistyPropDerived } from \"../../TwistyProp\";\n\nexport interface LegacyPositionPropInputs {\n currentMoveInfo: CurrentMoveInfo;\n currentPattern: KPattern;\n}\n\n// TODO: This exist as a convenience for old `Twisty3D` implementations. Get rid of this.\nexport class LegacyPositionProp extends TwistyPropDerived<\n LegacyPositionPropInputs,\n PuzzlePosition\n> {\n derive(inputs: LegacyPositionPropInputs): PuzzlePosition {\n return {\n pattern: inputs.currentPattern,\n movesInProgress: inputs.currentMoveInfo.currentMoves,\n };\n }\n}\n", "import { Alg } from \"../../../../../alg\";\nimport type { KPuzzle } from \"../../../../../kpuzzle\";\nimport { TwistyPropDerived } from \"../../TwistyProp\";\nimport { AlgIssues, type AlgWithIssues } from \"./AlgProp\";\n\nlet validate: boolean = true;\nexport function experimentalSetPuzzleAlgValidation(newValidate: boolean): void {\n validate = newValidate;\n}\n\nexport class PuzzleAlgProp extends TwistyPropDerived<\n { algWithIssues: AlgWithIssues; kpuzzle: KPuzzle },\n AlgWithIssues\n> {\n async derive(inputs: {\n algWithIssues: AlgWithIssues;\n kpuzzle: KPuzzle;\n }): Promise<AlgWithIssues> {\n try {\n if (validate) {\n inputs.kpuzzle.algToTransformation(inputs.algWithIssues.alg);\n }\n\n // Looks like we could apply the alg!\n return inputs.algWithIssues;\n } catch (e) {\n return {\n alg: new Alg(),\n issues: new AlgIssues({\n errors: [`Invalid alg for puzzle: ${(e as Error).toString()}`],\n }),\n };\n }\n }\n}\n", "import { SimpleTwistyPropSource } from \"../../TwistyProp\";\n\n// TODO: turn these maps into lists?\nexport const setupToLocations = {\n start: true, // default // TODO: \"beginning\"\n end: true,\n};\nexport type SetupToLocation = keyof typeof setupToLocations;\n\nexport class SetupAnchorProp extends SimpleTwistyPropSource<SetupToLocation> {\n getDefaultValue(): SetupToLocation {\n return \"start\";\n }\n}\n", "import type { KTransformation } from \"../../../../../kpuzzle\";\nimport { SimpleTwistyPropSource } from \"../../TwistyProp\";\n\nexport class SetupTransformationProp extends SimpleTwistyPropSource<KTransformation | null> {\n getDefaultValue(): KTransformation | null {\n return null;\n }\n}\n", "import type { KPuzzle } from \"../../../../../kpuzzle\";\nimport type { PuzzleLoader } from \"../../../../../puzzles\";\nimport { TwistyPropDerived } from \"../../TwistyProp\";\n\nexport class KPuzzleProp extends TwistyPropDerived<\n { puzzleLoader: PuzzleLoader },\n KPuzzle\n> {\n async derive(inputs: { puzzleLoader: PuzzleLoader }): Promise<KPuzzle> {\n return inputs.puzzleLoader.kpuzzle();\n }\n}\n", "import type { PuzzleDescriptionString } from \"../../../../../puzzle-geometry/pgPuzzles\";\nimport {\n NO_VALUE,\n type NoValueType,\n SimpleTwistyPropSource,\n} from \"../../TwistyProp\";\n\nexport class PGPuzzleDescriptionStringProp extends SimpleTwistyPropSource<\n PuzzleDescriptionString | NoValueType\n> {\n getDefaultValue(): PuzzleDescriptionString | NoValueType {\n return NO_VALUE;\n }\n}\n", "import type { PuzzleLoader } from \"../../../../../puzzles\";\nimport { TwistyPropDerived } from \"../../TwistyProp\";\nimport type { PuzzleID } from \"./PuzzleIDRequestProp\";\n\nexport class PuzzleIDProp extends TwistyPropDerived<\n { puzzleLoader: PuzzleLoader },\n PuzzleID\n> {\n async derive(inputs: { puzzleLoader: PuzzleLoader }): Promise<PuzzleID> {\n return inputs.puzzleLoader.id as PuzzleID;\n }\n}\n", "import {\n NO_VALUE,\n type NoValueType,\n SimpleTwistyPropSource,\n} from \"../../TwistyProp\";\n\nexport const puzzleIDs = {\n \"3x3x3\": true, // default\n custom: true,\n \"2x2x2\": true,\n \"4x4x4\": true,\n \"5x5x5\": true,\n \"6x6x6\": true,\n \"7x7x7\": true,\n \"40x40x40\": true,\n megaminx: true,\n pyraminx: true,\n square1: true,\n clock: true,\n skewb: true,\n fto: true,\n gigaminx: true,\n master_tetraminx: true,\n kilominx: true,\n redi_cube: true,\n baby_fto: true,\n melindas2x2x2x2: true,\n tri_quad: true,\n loopover: true,\n};\nexport type PuzzleID = keyof typeof puzzleIDs;\n\n// TODO: Ideally we'd use `null` to mean \"no value\", but `null` has a special meaning\n// for `TwistyProp` and might mess with caching.\n// https://github.com/cubing/cubing.js/blob/63b0a55b83963f68410bb117a2e481052a07e086/src/cubing/twisty/model/TwistyProp.ts#L189-L189\nexport class PuzzleIDRequestProp extends SimpleTwistyPropSource<\n PuzzleID | NoValueType\n> {\n getDefaultValue(): PuzzleID | NoValueType {\n return NO_VALUE;\n }\n}\n", "import type { PuzzleDescriptionString } from \"../../../../../puzzle-geometry/pgPuzzles\";\nimport { cube3x3x3, type PuzzleLoader, puzzles } from \"../../../../../puzzles\";\nimport { experimentalCustomPGPuzzleLoader } from \"../../../../../puzzles/cubing-private\";\nimport {\n NO_VALUE,\n type NoValueType,\n TwistyPropDerived,\n} from \"../../TwistyProp\";\nimport type { PuzzleID } from \"./PuzzleIDRequestProp\";\n\n8;\ninterface PuzzleLoaderPropInputs {\n puzzleIDRequest: PuzzleID | NoValueType;\n puzzleDescriptionRequest: PuzzleDescriptionString | NoValueType;\n}\n\nexport class PuzzleLoaderProp extends TwistyPropDerived<\n PuzzleLoaderPropInputs,\n PuzzleLoader\n> {\n derive(inputs: PuzzleLoaderPropInputs): PuzzleLoader {\n if (inputs.puzzleIDRequest && inputs.puzzleIDRequest !== NO_VALUE) {\n const puzzleLoader = puzzles[inputs.puzzleIDRequest];\n if (!puzzleLoader) {\n this.userVisibleErrorTracker!.set({\n errors: [`Invalid puzzle ID: ${inputs.puzzleIDRequest}`],\n });\n }\n return puzzleLoader;\n }\n if (\n inputs.puzzleDescriptionRequest &&\n inputs.puzzleDescriptionRequest !== NO_VALUE\n ) {\n return experimentalCustomPGPuzzleLoader(inputs.puzzleDescriptionRequest);\n }\n return cube3x3x3;\n }\n}\n", "import type { ButtonCommand } from \"../../../views/control-panel/TwistyButtons\";\nimport { TwistyPropDerived } from \"../TwistyProp\";\nimport type { DetailedTimelineInfo } from \"./DetailedTimelineInfoProp\";\nimport type { PlayingInfo } from \"./PlayingInfoProp\";\n\ninterface ButtonAppearance {\n enabled: boolean;\n icon: string;\n title: string;\n}\nexport type ButtonAppearances = Record<ButtonCommand, ButtonAppearance>;\n\ninterface CoarseTimelineInfoInputs {\n playingInfo: PlayingInfo;\n detailedTimelineInfo: DetailedTimelineInfo;\n}\n\nexport interface CoarseTimelineInfo {\n playing: boolean;\n atStart: boolean;\n atEnd: boolean;\n}\n\n// This started as a version of `EffectiveTimestamp` without the actual\n// timestamp, to enable easier caching.\nexport class CoarseTimelineInfoProp extends TwistyPropDerived<\n CoarseTimelineInfoInputs,\n CoarseTimelineInfo\n> {\n protected override derive(\n inputs: CoarseTimelineInfoInputs,\n ): CoarseTimelineInfo {\n return {\n playing: inputs.playingInfo.playing,\n atStart: inputs.detailedTimelineInfo.atStart,\n atEnd: inputs.detailedTimelineInfo.atEnd,\n };\n }\n\n protected override canReuseValue(\n v1: CoarseTimelineInfo,\n v2: CoarseTimelineInfo,\n ): boolean {\n return (\n v1.playing === v2.playing &&\n v1.atStart === v2.atStart &&\n v1.atEnd === v2.atEnd\n );\n }\n}\n", "import type {\n MillisecondTimestamp,\n TimeRange,\n} from \"../../../controllers/AnimationTypes\";\nimport type { AlgWithIssues } from \"../puzzle/state/AlgProp\";\nimport type { SetupToLocation } from \"../puzzle/state/SetupAnchorProp\";\nimport { TwistyPropDerived } from \"../TwistyProp\";\nimport type { TimestampRequest } from \"./TimestampRequestProp\";\n\ninterface DetailedTimelineInfoInputs {\n timestampRequest: TimestampRequest;\n timeRange: TimeRange;\n setupAnchor: SetupToLocation;\n setupAlg: AlgWithIssues;\n}\n\nexport interface DetailedTimelineInfo {\n timestamp: MillisecondTimestamp;\n timeRange: TimeRange; // TODO: Don't incluede this, and let fresh listeners listen to multiple inputs?\n // Note: `atStart` and `atEnd` can both be true. This is the case with the\n // default (empty) alg, which has a duration of 0 ms.\n atStart: boolean;\n atEnd: boolean;\n}\n\nexport class DetailedTimelineInfoProp extends TwistyPropDerived<\n DetailedTimelineInfoInputs,\n DetailedTimelineInfo\n> {\n protected override derive(\n inputs: DetailedTimelineInfoInputs,\n ): DetailedTimelineInfo {\n let timestamp = this.#requestedTimestampToMilliseconds(inputs);\n let atStart: boolean = false;\n let atEnd: boolean = false;\n if (timestamp >= inputs.timeRange.end) {\n atEnd = true;\n timestamp = Math.min(\n inputs.timeRange.end,\n timestamp,\n ) as MillisecondTimestamp;\n }\n if (timestamp <= inputs.timeRange.start) {\n atStart = true;\n timestamp = Math.max(\n inputs.timeRange.start,\n timestamp,\n ) as MillisecondTimestamp;\n }\n return {\n timestamp,\n timeRange: inputs.timeRange,\n atStart,\n atEnd,\n };\n }\n\n #requestedTimestampToMilliseconds(\n inputs: DetailedTimelineInfoInputs,\n ): MillisecondTimestamp {\n switch (inputs.timestampRequest) {\n case \"auto\":\n return inputs.setupAnchor === \"start\" &&\n inputs.setupAlg.alg.experimentalIsEmpty()\n ? inputs.timeRange.end\n : inputs.timeRange.start;\n case \"start\":\n return inputs.timeRange.start;\n case \"end\":\n return inputs.timeRange.end;\n case \"anchor\":\n return inputs.setupAnchor === \"start\"\n ? inputs.timeRange.start\n : inputs.timeRange.end;\n case \"opposite-anchor\":\n return inputs.setupAnchor === \"start\"\n ? inputs.timeRange.end\n : inputs.timeRange.start;\n default:\n return inputs.timestampRequest;\n }\n }\n\n protected override canReuseValue(\n v1: DetailedTimelineInfo,\n v2: DetailedTimelineInfo,\n ) {\n return (\n v1.timestamp === v2.timestamp &&\n v1.timeRange.start === v2.timeRange.start &&\n v1.timeRange.end === v2.timeRange.end &&\n v1.atStart === v2.atStart &&\n v1.atEnd === v2.atEnd\n );\n }\n}\n", "import { BoundaryType, Direction } from \"../../../controllers/AnimationTypes\";\nimport { TwistyPropSource } from \"../TwistyProp\";\n\nexport type SimpleDirection = Direction.Forwards | Direction.Backwards;\n\nexport interface PlayingInfo {\n playing: boolean;\n direction: SimpleDirection;\n untilBoundary: BoundaryType; // TODO: allows this to be optional in the setter?\n // TODO: Is `loop` responsible to add at this point? Maybe we should wait until we've figured out autoplay?\n // TODO: Combine `loop` into something with BoundaryType?\n loop: boolean;\n}\n\n// TODO: direction,\nexport class PlayingInfoProp extends TwistyPropSource<\n PlayingInfo,\n Partial<PlayingInfo>\n> {\n public override async getDefaultValue(): Promise<PlayingInfo> {\n return {\n direction: Direction.Forwards,\n playing: false,\n untilBoundary: BoundaryType.EntireTimeline,\n loop: false,\n };\n }\n\n protected override async derive(\n newInfo: Partial<PlayingInfo>,\n oldValuePromise: Promise<PlayingInfo>,\n ): Promise<PlayingInfo> {\n const oldValue = await oldValuePromise;\n\n const newValue: PlayingInfo = Object.assign({}, oldValue);\n Object.assign(newValue, newInfo);\n return newValue;\n }\n\n protected override canReuseValue(v1: PlayingInfo, v2: PlayingInfo) {\n return (\n v1.direction === v2.direction &&\n v1.playing === v2.playing &&\n v1.untilBoundary === v2.untilBoundary &&\n v1.loop === v2.loop\n );\n }\n}\n", "import { TwistyPropSource } from \"../TwistyProp\";\n\n// TODO: Pick a better name. `speed` is probably good, although that could mean\n// something else (e.g. shorter, faster moves but still with the same spacing).\nexport class TempoScaleProp extends TwistyPropSource<number, number> {\n getDefaultValue(): number {\n return 1;\n }\n\n derive(v: number): number {\n return v < 0 ? 1 : v;\n }\n}\n", "import type { MillisecondTimestamp } from \"../../../controllers/AnimationTypes\";\nimport { type PromiseOrValue, SimpleTwistyPropSource } from \"../TwistyProp\";\n\nconst smartTimestamps = {\n auto: true,\n start: true,\n end: true,\n anchor: true,\n \"opposite-anchor\": true,\n};\n\nexport type TimestampRequest =\n | MillisecondTimestamp\n | keyof typeof smartTimestamps;\n\nexport class TimestampRequestProp extends SimpleTwistyPropSource<TimestampRequest> {\n override getDefaultValue(): TimestampRequest {\n return \"auto\";\n }\n\n public override set(v: PromiseOrValue<TimestampRequest>) {\n const currentValue = this.get();\n super.set(\n (async () => {\n if (!this.validInput(await v)) {\n // TODO: Generalize this to more props. How do we surface this? Throw an error and catch it from sync setters that call into this?\n return currentValue;\n }\n return v;\n })(),\n );\n }\n\n protected validInput(v: TimestampRequest): boolean {\n if (typeof v === \"number\") {\n return true;\n }\n if (smartTimestamps[v]) {\n return true;\n }\n return false;\n }\n}\n", "import type {\n MillisecondTimestamp,\n TimeRange,\n} from \"../../../controllers/AnimationTypes\";\nimport type { AlgIndexer } from \"../../../controllers/indexer/AlgIndexer\";\nimport { TwistyPropDerived } from \"../TwistyProp\";\n\nexport class TimeRangeProp extends TwistyPropDerived<\n { indexer: AlgIndexer },\n TimeRange\n> {\n derive(inputs: { indexer: AlgIndexer }): TimeRange {\n return {\n start: 0 as MillisecondTimestamp,\n end: inputs.indexer.algDuration() as number as MillisecondTimestamp,\n };\n }\n}\n", "import { SimpleTwistyPropSource } from \"../TwistyProp\";\n\nexport const viewerLinkPages = {\n twizzle: true, // default\n \"experimental-twizzle-explorer\": true,\n none: true,\n};\nexport type ViewerLinkPage = keyof typeof viewerLinkPages;\nexport type ViewerLinkPageWithAuto = ViewerLinkPage | \"auto\";\n\nexport class ViewerLinkProp extends SimpleTwistyPropSource<ViewerLinkPageWithAuto> {\n getDefaultValue(): ViewerLinkPageWithAuto {\n return \"auto\";\n }\n}\n", "import { SimpleTwistyPropSource } from \"../TwistyProp\";\n\n// TODO: turn these maps into lists?\nexport const visualizationFormats = {\n \"3D\": true, // default\n \"2D\": true,\n \"experimental-2D-LL\": true, // TODO\n \"experimental-2D-LL-face\": true, // TODO\n PG3D: true,\n} as const;\nexport type VisualizationFormat = keyof typeof visualizationFormats;\nexport type VisualizationFormatWithAuto = VisualizationFormat | \"auto\";\n\nexport class VisualizationFormatProp extends SimpleTwistyPropSource<VisualizationFormatWithAuto> {\n getDefaultValue(): VisualizationFormatWithAuto {\n return \"auto\";\n }\n}\n", "import type { PuzzleID } from \"../../..\";\nimport { TwistyPropDerived } from \"../TwistyProp\";\nimport type { VisualizationFormatWithAuto } from \"./VisualizationProp\";\n\ntype VisualizationStrategyPropInputs = {\n visualizationRequest: VisualizationFormatWithAuto;\n puzzleID: PuzzleID;\n};\n\nexport type VisualizationStrategy =\n | \"Cube3D\"\n | \"2D\"\n | \"experimental-2D-LL\"\n | \"experimental-2D-LL-face\"\n | \"PG3D\";\n\nexport class VisualizationStrategyProp extends TwistyPropDerived<\n VisualizationStrategyPropInputs,\n VisualizationStrategy\n> {\n derive(inputs: VisualizationStrategyPropInputs): VisualizationStrategy {\n // TODO: let the puzzle loader tell us.\n switch (inputs.puzzleID) {\n case \"clock\":\n case \"square1\":\n case \"redi_cube\":\n case \"melindas2x2x2x2\":\n case \"tri_quad\":\n case \"loopover\":\n return \"2D\";\n case \"3x3x3\":\n switch (inputs.visualizationRequest) {\n case \"auto\":\n case \"3D\":\n return \"Cube3D\";\n default:\n return inputs.visualizationRequest;\n }\n default:\n switch (inputs.visualizationRequest) {\n case \"auto\":\n case \"3D\":\n return \"PG3D\";\n case \"experimental-2D-LL\":\n case \"experimental-2D-LL-face\":\n if ([\"2x2x2\", \"4x4x4\", \"megaminx\"].includes(inputs.puzzleID)) {\n // TODO: calculate this based on the `PuzzleLoader`.\n return \"experimental-2D-LL\";\n } else {\n return \"2D\";\n }\n default:\n return inputs.visualizationRequest;\n }\n }\n }\n}\n", "import { SimpleTwistyPropSource } from \"../../TwistyProp\";\n\nexport type FaceletScale = \"auto\" | number;\nexport class FaceletScaleProp extends SimpleTwistyPropSource<FaceletScale> {\n getDefaultValue(): FaceletScale {\n return \"auto\";\n }\n}\n", "import { SimpleTwistyPropSource } from \"../../TwistyProp\";\n\nexport type FoundationDisplay = \"auto\" | \"opaque\" | \"none\";\n\nexport class FoundationDisplayProp extends SimpleTwistyPropSource<FoundationDisplay> {\n getDefaultValue(): FoundationDisplay {\n return \"auto\";\n }\n}\n", "import { SimpleTwistyPropSource } from \"../../TwistyProp\";\n\nexport type HintFaceletsElevationRequest = \"auto\" | number;\n\nexport class HintFaceletsElevationProp extends SimpleTwistyPropSource<\n \"auto\" | number\n> {\n getDefaultValue(): \"auto\" | number {\n return \"auto\";\n }\n}\n", "import { SimpleTwistyPropSource } from \"../../TwistyProp\";\n\nexport type InitialHintFaceletsAnimation = \"auto\" | \"always\" | \"none\";\n\nexport class InitialHintFaceletsAnimationProp extends SimpleTwistyPropSource<InitialHintFaceletsAnimation> {\n getDefaultValue(): InitialHintFaceletsAnimation {\n return \"auto\";\n }\n}\n", "import type { Texture, TextureLoader } from \"three/src/Three.js\";\nimport { bulk3DCode } from \"../../../../heavy-code-imports/3d\";\nimport { TwistyPropDerived } from \"../../TwistyProp\";\n\nlet cachedLoader: TextureLoader | null = null;\nasync function loader(): Promise<TextureLoader> {\n return (cachedLoader ??= new (await bulk3DCode()).ThreeTextureLoader());\n}\n\ntype SpritePropInputs = {\n spriteURL: URL | null;\n};\n\n// TODO: Find a way to make the 3D elements own this, instead of the main `TwistyPlayerModel`.\nexport class SpriteProp extends TwistyPropDerived<\n SpritePropInputs,\n Texture | null\n> {\n async derive(inputs: SpritePropInputs): Promise<Texture | null> {\n const { spriteURL: textureURL } = inputs;\n if (textureURL === null) {\n return null;\n }\n // biome-ignore lint/suspicious/noAsyncPromiseExecutor: TODO: Find a different way to handle `onLoadingError`?\n return new Promise(async (resolve, _reject) => {\n const onLoadingError = (): void => {\n console.warn(\"Could not load sprite:\", textureURL.toString());\n resolve(null);\n };\n // TODO: provide a way to listen for errors?\n try {\n (await loader()).load(\n textureURL.toString(),\n resolve,\n onLoadingError,\n onLoadingError,\n );\n } catch {\n onLoadingError();\n }\n });\n }\n}\n", "import type { PuzzleLoader } from \"../../../../../puzzles\";\nimport type {\n ExperimentalPieceStickeringMask,\n ExperimentalStickeringMask,\n} from \"../../../../../puzzles/cubing-private\";\nimport { TwistyPropDerived } from \"../../TwistyProp\";\nimport type { ExperimentalStickering } from \"./StickeringRequestProp\";\n\ninterface StickeringMaskPropInputs {\n stickeringMaskRequest: ExperimentalStickeringMask | null;\n stickeringRequest: ExperimentalStickering | null;\n puzzleLoader: PuzzleLoader;\n}\n\nconst r: ExperimentalPieceStickeringMask = {\n facelets: [\"regular\", \"regular\", \"regular\", \"regular\", \"regular\"],\n};\n\nasync function fullStickeringMask(\n puzzleLoader: PuzzleLoader,\n): Promise<ExperimentalStickeringMask> {\n const { definition } = await puzzleLoader.kpuzzle();\n const fullStickeringMask: ExperimentalStickeringMask = { orbits: {} };\n for (const orbitDefinition of definition.orbits) {\n fullStickeringMask.orbits[orbitDefinition.orbitName] = {\n pieces: new Array(orbitDefinition.numPieces).fill(r),\n };\n }\n return fullStickeringMask;\n}\n\nexport class StickeringMaskProp extends TwistyPropDerived<\n StickeringMaskPropInputs,\n ExperimentalStickeringMask\n> {\n getDefaultValue(): ExperimentalStickeringMask {\n return { orbits: {} }; // TODO: auto\n }\n\n async derive(\n inputs: StickeringMaskPropInputs,\n ): Promise<ExperimentalStickeringMask> {\n if (inputs.stickeringMaskRequest) {\n return inputs.stickeringMaskRequest;\n }\n if (inputs.stickeringRequest === \"picture\") {\n return {\n specialBehaviour: \"picture\",\n orbits: {},\n };\n }\n return (\n inputs.puzzleLoader.stickeringMask?.(\n inputs.stickeringRequest ?? \"full\",\n ) ?? fullStickeringMask(inputs.puzzleLoader)\n );\n }\n // TODO: Implement canReuseValue?\n}\n", "// import type {\n// FaceletMeshStickeringMask,\n// PieceStickeringMask,\n// StickeringMask,\n// } from \"./mask\";\n\nimport {\n ExperimentalPieceStickering,\n type ExperimentalPieceStickeringMask,\n type ExperimentalStickeringMask,\n experimentalGetPieceStickeringMask,\n} from \"../../../../../puzzles/cubing-private\";\n\nconst charMap: Record<string, ExperimentalPieceStickering> = {\n \"-\": ExperimentalPieceStickering.Regular,\n D: ExperimentalPieceStickering.Dim,\n I: ExperimentalPieceStickering.Ignored,\n // o: ExperimentalPieceStickering.OrientationStickers, // TODO: hack for centers\n X: ExperimentalPieceStickering.Invisible,\n O: ExperimentalPieceStickering.IgnoreNonPrimary, // orient color known\n P: ExperimentalPieceStickering.PermuteNonPrimary, // Example: PLL\n o: ExperimentalPieceStickering.Ignoriented, // Example: LL edges during CLS\n \"?\": ExperimentalPieceStickering.OrientationWithoutPermutation, // ACube: ignore position\n M: ExperimentalPieceStickering.Mystery, // This piece needs highlighting, but we know nothing about it.\n \"@\": ExperimentalPieceStickering.Regular, // ACube: ignore orientation // TODO: distinguish from \"regular\"\n};\n\nexport function parseSerializedStickeringMask(\n serializedStickeringMask: string,\n): ExperimentalStickeringMask {\n const stickeringMask: ExperimentalStickeringMask = {\n orbits: {},\n };\n const serializedOrbits = serializedStickeringMask.split(\",\");\n for (const serializedOrbit of serializedOrbits) {\n const [orbitName, serializedOrbitPieces, ...rest] =\n serializedOrbit.split(\":\");\n if (rest.length > 0) {\n throw new Error(\n `Invalid serialized orbit stickering mask (too many colons): \\`${serializedOrbit}\\``,\n );\n }\n const pieces: ExperimentalPieceStickeringMask[] = [];\n stickeringMask.orbits[orbitName] = { pieces };\n for (const char of serializedOrbitPieces) {\n const pieceStickering = charMap[char];\n pieces.push(experimentalGetPieceStickeringMask(pieceStickering));\n }\n }\n return stickeringMask;\n}\n", "import type { ExperimentalStickeringMask } from \"../../../../../puzzles/cubing-private\";\nimport { TwistyPropSource } from \"../../TwistyProp\";\nimport { parseSerializedStickeringMask } from \"./parseSerializedStickeringMask\";\n\nexport class StickeringMaskRequestProp extends TwistyPropSource<\n ExperimentalStickeringMask | null,\n string | ExperimentalStickeringMask | null\n> {\n getDefaultValue(): ExperimentalStickeringMask | null {\n return null; // TODO: auto\n }\n\n derive(\n input: string | ExperimentalStickeringMask | null,\n ): ExperimentalStickeringMask | null {\n if (input === null) {\n return null;\n } else if (typeof input === \"string\") {\n return parseSerializedStickeringMask(input);\n } else {\n return input;\n }\n }\n}\n", "import { experimentalStickerings } from \"../../../../../puzzles/cubing-private\";\nimport { SimpleTwistyPropSource } from \"../../TwistyProp\";\nimport type { PuzzleID } from \"../structure/PuzzleIDRequestProp\";\n\n// TODO: turn these maps into lists?\n// TODO: alg.cubing.net parity\n\nexport type ExperimentalStickering = keyof typeof experimentalStickerings;\n\nexport function getStickeringGroup(\n stickering: ExperimentalStickering,\n puzzleID: PuzzleID,\n): string {\n const groups = experimentalStickerings[stickering]?.groups;\n if (!groups) {\n return \"Stickering\";\n }\n return groups[puzzleID] ?? \"Stickering\";\n}\n\nexport class StickeringRequestProp extends SimpleTwistyPropSource<ExperimentalStickering | null> {\n getDefaultValue(): ExperimentalStickering | null {\n return null;\n }\n}\n", "import { SimpleTwistyPropSource } from \"../../TwistyProp\";\n\nexport const dragInputModes = {\n auto: true,\n none: true,\n};\nexport type DragInputMode = keyof typeof dragInputModes;\n\nexport class DragInputProp extends SimpleTwistyPropSource<DragInputMode> {\n getDefaultValue(): DragInputMode {\n return \"auto\";\n }\n}\n", "import type { AppendCancelOptions } from \"../../../../../alg\";\nimport { SimpleTwistyPropSource } from \"../../TwistyProp\";\n\n// TODO: this should probably be dynamic based on the input, e.g. possibly even controlled using a modifier key.\nexport class MovePressCancelOptions extends SimpleTwistyPropSource<AppendCancelOptions> {\n getDefaultValue(): AppendCancelOptions {\n return {};\n }\n}\n", "import { SimpleTwistyPropSource } from \"../../TwistyProp\";\n\nexport const movePressInputNames = {\n auto: true,\n none: true,\n basic: true,\n};\nexport type MovePressInput = keyof typeof movePressInputNames;\n\nexport class MovePressInputProp extends SimpleTwistyPropSource<MovePressInput> {\n getDefaultValue(): MovePressInput {\n return \"auto\";\n }\n}\n", "import { SimpleTwistyPropSource } from \"../TwistyProp\";\n\nexport const backgroundThemes = {\n checkered: true, // default\n \"checkered-transparent\": true, // default\n none: true,\n};\nexport type BackgroundTheme = keyof typeof backgroundThemes;\n\nexport type BackgroundThemeWithAuto = BackgroundTheme | \"auto\";\n\nexport class BackgroundProp extends SimpleTwistyPropSource<BackgroundThemeWithAuto> {\n getDefaultValue(): BackgroundThemeWithAuto {\n return \"auto\";\n }\n}\n", "import { TwistyPropDerived } from \"../TwistyProp\";\nimport type {\n ColorScheme,\n ColorSchemeWithAuto,\n} from \"./ColorSchemeRequestProp\";\n\ninterface ColorSchemePropInputs {\n colorSchemeRequest: ColorSchemeWithAuto;\n}\n\nexport class ColorSchemeProp extends TwistyPropDerived<\n ColorSchemePropInputs,\n ColorScheme\n> {\n protected derive(inputs: ColorSchemePropInputs): ColorScheme {\n // TODO: Once the theme is ready, use `prefers-color-scheme` for automatic dark mode by default.\n return inputs.colorSchemeRequest === \"dark\" ? \"dark\" : \"light\";\n }\n}\n", "import { SimpleTwistyPropSource } from \"../TwistyProp\";\n\nexport const colorSchemes = {\n light: true,\n dark: true,\n};\nexport type ColorScheme = keyof typeof colorSchemes;\nexport type ColorSchemeWithAuto = ColorScheme | \"auto\";\n\nexport class ColorSchemeRequestProp extends SimpleTwistyPropSource<ColorSchemeWithAuto> {\n getDefaultValue(): ColorSchemeWithAuto {\n return \"auto\";\n }\n}\n", "import { SimpleTwistyPropSource } from \"../TwistyProp\";\n\nexport class DOMElementReferenceProp extends SimpleTwistyPropSource<Element | null> {\n getDefaultValue(): Element | null {\n return null;\n }\n}\n", "import { SimpleTwistyPropSource } from \"../TwistyProp\";\nimport type { CoordinateDegrees } from \"./OrbitCoordinatesRequestProp\";\n\n// Similar to https://alg.cubing.net/\nconst DEFAULT_LATITUDE_LIMIT = 35;\n\nexport class LatitudeLimitProp extends SimpleTwistyPropSource<CoordinateDegrees> {\n getDefaultValue(): CoordinateDegrees {\n return DEFAULT_LATITUDE_LIMIT;\n }\n}\n", "import { modIntoRange } from \"../../helpers\";\nimport { TwistyPropSource } from \"../TwistyProp\";\n\nexport type CoordinateDegrees = number;\n\nexport interface OrbitCoordinates {\n latitude: CoordinateDegrees;\n longitude: CoordinateDegrees;\n distance: number;\n}\n\nexport function orbitCoordinatesEqual(\n c1: OrbitCoordinates,\n c2: OrbitCoordinates,\n): boolean {\n return (\n c1.latitude === c2.latitude &&\n c1.longitude === c2.longitude &&\n c1.distance === c2.distance\n );\n}\n\n// TODO: Check if freezing affects perf.\n// const DEFAULT_COORDINATES = Object.freeze({\n// latitude: 35,\n// longitude: 30,\n// distance: 6,\n// });\n\nexport type OrbitCoordinatesRequest = Partial<OrbitCoordinates> | \"auto\";\n\n// TODO: Put the \"auto\" calculations in a separate place.\nexport class OrbitCoordinatesRequestProp extends TwistyPropSource<\n OrbitCoordinatesRequest,\n Partial<OrbitCoordinates> | \"auto\"\n> {\n override getDefaultValue(): OrbitCoordinatesRequest {\n return \"auto\";\n }\n\n protected override canReuseValue(v1: OrbitCoordinates, v2: OrbitCoordinates) {\n return v1 === v2 || orbitCoordinatesEqual(v1, v2);\n }\n\n protected override async derive(\n newCoordinates: Partial<OrbitCoordinates> | \"auto\",\n oldValuePromise: Promise<OrbitCoordinatesRequest>,\n ): Promise<OrbitCoordinatesRequest> {\n if (newCoordinates === \"auto\") {\n return \"auto\";\n }\n\n let oldValue = await oldValuePromise;\n if (oldValue === \"auto\") {\n oldValue = {};\n }\n\n const newValue: Partial<OrbitCoordinates> = Object.assign({}, oldValue);\n Object.assign(newValue, newCoordinates);\n\n if (typeof newValue.latitude !== \"undefined\") {\n newValue.latitude = Math.min(Math.max(newValue.latitude, -90), 90);\n }\n if (typeof newValue.longitude !== \"undefined\") {\n newValue.longitude = modIntoRange(newValue.longitude, 180, -180);\n }\n return newValue;\n }\n}\n", "import { DEGREES_PER_RADIAN } from \"../../../views/3D/TAU\";\nimport type { PuzzleID } from \"../puzzle/structure/PuzzleIDRequestProp\";\nimport { TwistyPropDerived } from \"../TwistyProp\";\nimport {\n type CoordinateDegrees,\n type OrbitCoordinates,\n type OrbitCoordinatesRequest,\n orbitCoordinatesEqual,\n} from \"./OrbitCoordinatesRequestProp\";\nimport type { VisualizationStrategy } from \"./VisualizationStrategyProp\";\n\ninterface OrbitCoordinatesPropInputs {\n orbitCoordinatesRequest: OrbitCoordinatesRequest;\n latitudeLimit: CoordinateDegrees;\n puzzleID: PuzzleID;\n strategy: VisualizationStrategy;\n}\n\nexport class OrbitCoordinatesProp extends TwistyPropDerived<\n OrbitCoordinatesPropInputs,\n OrbitCoordinates\n> {\n override canReuseValue(v1: OrbitCoordinates, v2: OrbitCoordinates) {\n return orbitCoordinatesEqual(v1, v2);\n }\n\n async derive(inputs: OrbitCoordinatesPropInputs): Promise<OrbitCoordinates> {\n if (inputs.orbitCoordinatesRequest === \"auto\") {\n return defaultCameraOrbitCoordinates(inputs.puzzleID, inputs.strategy);\n }\n\n const req: OrbitCoordinates = Object.assign(\n Object.assign(\n {},\n defaultCameraOrbitCoordinates(inputs.puzzleID, inputs.strategy),\n inputs.orbitCoordinatesRequest,\n ),\n );\n\n if (Math.abs(req.latitude) <= inputs.latitudeLimit) {\n return req;\n } else {\n const { latitude, longitude, distance } = req;\n // TODO: Should we re-normalize the request, so we don't depend on normalization in the input?\n return {\n latitude: inputs.latitudeLimit * Math.sign(latitude),\n longitude,\n distance,\n };\n }\n }\n}\n\n// const DEFAULT_CAMERA_Z = 5;\n// // Golden ratio is perfect for FTO and Megaminx.\n// const DEFAULT_CAMERA_Y = DEFAULT_CAMERA_Z * (2 / (1 + Math.sqrt(5)));\nexport const centeredCameraOrbitCoordinates: OrbitCoordinates = {\n latitude: 31.717474411461005,\n longitude: 0,\n distance: 5.877852522924731,\n};\n\n// This is tuned so that the hint facelets for 3x3x3 always fit in the canvas.\nexport const cubeCube3DCameraOrbitCoordinates: OrbitCoordinates = {\n latitude: 35,\n longitude: 30,\n distance: 6,\n};\n\n// This is tuned so that the hint facelets always fit in the canvas.\nexport const cubePG3DCameraOrbitCoordinates: OrbitCoordinates = {\n latitude: 35,\n longitude: 30,\n distance: 6.25,\n};\n\nexport const megaminxCameraOrbitCoordinates: OrbitCoordinates = {\n latitude: Math.atan(1 / 2) * DEGREES_PER_RADIAN,\n longitude: 0,\n distance: 6.7,\n};\n\nexport const pyraminxCameraOrbitCoordinates: OrbitCoordinates = {\n latitude: 26.56505117707799,\n longitude: 0,\n distance: 6,\n};\n\nexport const cornerCameraOrbitCoordinates: OrbitCoordinates = {\n latitude: 35.264389682754654,\n longitude: 45,\n distance: 6.928203230275509,\n};\n\n// TODO\nexport function defaultCameraOrbitCoordinates(\n puzzleID: PuzzleID,\n strategy: VisualizationStrategy,\n): OrbitCoordinates {\n if (puzzleID[1] === \"x\") {\n if (strategy === \"Cube3D\") {\n return cubeCube3DCameraOrbitCoordinates;\n } else {\n return cubePG3DCameraOrbitCoordinates;\n }\n } else {\n switch (puzzleID) {\n case \"megaminx\":\n case \"gigaminx\":\n return megaminxCameraOrbitCoordinates;\n case \"pyraminx\":\n case \"master_tetraminx\":\n return pyraminxCameraOrbitCoordinates;\n case \"skewb\":\n return cubePG3DCameraOrbitCoordinates;\n default:\n return centeredCameraOrbitCoordinates;\n }\n }\n}\n// TODO: templatize\nexport interface ManagedAttribute<K> {\n string: string;\n value: K;\n setString(s: string): boolean;\n setValue(v: K): boolean;\n}\n", "import { URLProp } from \"./props/general/URLProp\";\nimport { FaceletScaleProp } from \"./props/puzzle/display/FaceletScaleProp\";\nimport { FoundationDisplayProp } from \"./props/puzzle/display/FoundationDisplayProp\";\nimport { HintFaceletProp } from \"./props/puzzle/display/HintFaceletProp\";\nimport { HintFaceletsElevationProp } from \"./props/puzzle/display/HintFaceletsElevationProp\";\nimport { InitialHintFaceletsAnimationProp } from \"./props/puzzle/display/InitialHintFaceletsAnimationProp\";\nimport { SpriteProp } from \"./props/puzzle/display/SpriteProp\";\nimport { StickeringMaskProp } from \"./props/puzzle/display/StickeringMaskProp\";\nimport { StickeringMaskRequestProp } from \"./props/puzzle/display/StickeringMaskRequestProp\";\nimport { StickeringRequestProp } from \"./props/puzzle/display/StickeringRequestProp\";\nimport { DragInputProp } from \"./props/puzzle/state/DragInputProp\";\nimport { MovePressCancelOptions } from \"./props/puzzle/state/MovePressCancelOptions\";\nimport { MovePressInputProp } from \"./props/puzzle/state/MovePressInputProp\";\nimport { BackgroundProp } from \"./props/viewer/BackgroundProp\";\nimport { ColorSchemeProp } from \"./props/viewer/ColorSchemeProp\";\nimport { ColorSchemeRequestProp } from \"./props/viewer/ColorSchemeRequestProp\";\nimport { DOMElementReferenceProp } from \"./props/viewer/DOMElementReferenceProp\";\nimport { LatitudeLimitProp } from \"./props/viewer/LatitudeLimit\";\nimport { OrbitCoordinatesProp } from \"./props/viewer/OrbitCoordinatesProp\";\nimport { OrbitCoordinatesRequestProp } from \"./props/viewer/OrbitCoordinatesRequestProp\";\nimport type { TwistyPlayerModel } from \"./TwistyPlayerModel\";\n\nexport class TwistySceneModel {\n // Depth 0\n background = new BackgroundProp();\n colorSchemeRequest = new ColorSchemeRequestProp();\n dragInput = new DragInputProp();\n foundationDisplay = new FoundationDisplayProp();\n foundationStickerSpriteURL = new URLProp();\n fullscreenElement = new DOMElementReferenceProp();\n hintFacelet = new HintFaceletProp();\n hintStickerSpriteURL = new URLProp();\n initialHintFaceletsAnimation = new InitialHintFaceletsAnimationProp();\n hintFaceletsElevation = new HintFaceletsElevationProp();\n latitudeLimit = new LatitudeLimitProp();\n movePressInput = new MovePressInputProp();\n movePressCancelOptions = new MovePressCancelOptions();\n orbitCoordinatesRequest: OrbitCoordinatesRequestProp =\n new OrbitCoordinatesRequestProp();\n // `stickeringMaskRequest` takes priority over `stickeringRequest`\n stickeringMaskRequest = new StickeringMaskRequestProp();\n stickeringRequest = new StickeringRequestProp();\n faceletScale = new FaceletScaleProp();\n\n // Depth 1\n colorScheme = new ColorSchemeProp({\n colorSchemeRequest: this.colorSchemeRequest,\n });\n foundationStickerSprite = new SpriteProp({\n spriteURL: this.foundationStickerSpriteURL,\n });\n hintStickerSprite = new SpriteProp({\n spriteURL: this.hintStickerSpriteURL,\n });\n\n // Dependence on TwistyPlayerModel\n orbitCoordinates: OrbitCoordinatesProp;\n stickeringMask: StickeringMaskProp;\n\n constructor(public twistyPlayerModel: TwistyPlayerModel) {\n this.orbitCoordinates = new OrbitCoordinatesProp({\n orbitCoordinatesRequest: this.orbitCoordinatesRequest,\n latitudeLimit: this.latitudeLimit,\n puzzleID: twistyPlayerModel.puzzleID,\n strategy: twistyPlayerModel.visualizationStrategy,\n });\n this.stickeringMask = new StickeringMaskProp({\n stickeringMaskRequest: this.stickeringMaskRequest,\n stickeringRequest: this.stickeringRequest,\n puzzleLoader: twistyPlayerModel.puzzleLoader,\n });\n }\n}\n", "import { arrayEquals } from \"./helpers\";\nimport { SimpleTwistyPropSource } from \"./props/TwistyProp\";\n\ninterface UserVisibleError {\n errors: string[];\n}\n\nconst EMPTY_ERRORS = { errors: [] };\n\nexport class UserVisibleErrorTracker extends SimpleTwistyPropSource<UserVisibleError> {\n override getDefaultValue(): UserVisibleError {\n return EMPTY_ERRORS;\n }\n\n public reset() {\n this.set(this.getDefaultValue());\n }\n\n protected override canReuseValue(\n _v1: UserVisibleError,\n _v2: UserVisibleError,\n ): boolean {\n return arrayEquals(_v1.errors, _v2.errors);\n }\n}\n", "import { Alg, experimentalAppendMove, Move } from \"../../alg\";\nimport type { AlgLeaf } from \"../../alg/alg-nodes/AlgNode\";\nimport type { AppendOptions } from \"../../alg/simplify\";\nimport { getPartialAppendOptionsForPuzzleSpecificSimplifyOptions } from \"../../puzzles/cubing-private\";\nimport { ArbitraryStringProp } from \"./props/general/ArbitraryStringProp\";\nimport { URLProp } from \"./props/general/URLProp\";\nimport { AlgProp } from \"./props/puzzle/state/AlgProp\";\nimport { AlgTransformationProp } from \"./props/puzzle/state/AlgTransformationProp\";\nimport { AnchorTransformationProp } from \"./props/puzzle/state/AnchorTransformationProp\";\nimport { AnimationTimelineLeavesRequestProp } from \"./props/puzzle/state/AnimationTimelineLeavesRequestProp\";\nimport { CatchUpMoveProp } from \"./props/puzzle/state/CatchUpMoveProp\";\nimport { CurrentLeavesSimplifiedProp } from \"./props/puzzle/state/CurrentLeavesSimplified\";\nimport { CurrentMoveInfoProp } from \"./props/puzzle/state/CurrentMoveInfoProp\";\nimport { CurrentPatternProp } from \"./props/puzzle/state/CurrentPatternProp\";\nimport { IndexerConstructorProp } from \"./props/puzzle/state/IndexerConstructorProp\";\nimport { IndexerConstructorRequestProp } from \"./props/puzzle/state/IndexerConstructorRequestProp\";\nimport { IndexerProp } from \"./props/puzzle/state/IndexerProp\";\nimport { LegacyPositionProp } from \"./props/puzzle/state/LegacyPositionProp\";\nimport { PuzzleAlgProp } from \"./props/puzzle/state/PuzzleAlgProp\";\nimport { SetupAnchorProp } from \"./props/puzzle/state/SetupAnchorProp\";\nimport { SetupTransformationProp } from \"./props/puzzle/state/SetupTransformationProp\";\nimport { KPuzzleProp } from \"./props/puzzle/structure/KPuzzleProp\";\nimport { PGPuzzleDescriptionStringProp } from \"./props/puzzle/structure/PuzzleDescriptionProp\";\nimport { PuzzleIDProp } from \"./props/puzzle/structure/PuzzleIDProp\";\nimport { PuzzleIDRequestProp } from \"./props/puzzle/structure/PuzzleIDRequestProp\";\nimport { PuzzleLoaderProp } from \"./props/puzzle/structure/PuzzleLoaderProp\";\nimport { NO_VALUE } from \"./props/TwistyProp\";\nimport { CoarseTimelineInfoProp } from \"./props/timeline/CoarseTimelineInfoProp\";\nimport { DetailedTimelineInfoProp } from \"./props/timeline/DetailedTimelineInfoProp\";\nimport { PlayingInfoProp } from \"./props/timeline/PlayingInfoProp\";\nimport { TempoScaleProp } from \"./props/timeline/TempoScaleProp\";\nimport { TimestampRequestProp } from \"./props/timeline/TimestampRequestProp\";\nimport { BackViewProp } from \"./props/viewer/BackViewProp\";\nimport { ButtonAppearanceProp } from \"./props/viewer/ButtonAppearanceProp\";\nimport { ControlPanelProp } from \"./props/viewer/ControlPanelProp\";\nimport { TimeRangeProp } from \"./props/viewer/TimeRangeProp\";\nimport { ViewerLinkProp } from \"./props/viewer/ViewerLinkProp\";\nimport { VisualizationFormatProp } from \"./props/viewer/VisualizationProp\";\nimport { VisualizationStrategyProp } from \"./props/viewer/VisualizationStrategyProp\";\nimport { TwistySceneModel } from \"./TwistySceneModel\";\nimport { UserVisibleErrorTracker } from \"./UserVisibleErrorTracker\";\n\n// From https://stackoverflow.com/a/50918777\ntype Without<T, K extends string[]> = Pick<T, Exclude<keyof T, K[number]>>;\n\nexport class TwistyPlayerModel {\n // TODO: incorporate error handling into the entire prop graph.\n // TODO: Make this something that can't get confused with normal props?\n userVisibleErrorTracker = new UserVisibleErrorTracker();\n\n // TODO: Redistribute and group props with controllers.\n\n /******************************** Depth 0 ********************************/\n\n alg = new AlgProp();\n backView = new BackViewProp();\n controlPanel = new ControlPanelProp();\n catchUpMove = new CatchUpMoveProp();\n indexerConstructorRequest = new IndexerConstructorRequestProp();\n playingInfo = new PlayingInfoProp();\n puzzleDescriptionRequest = new PGPuzzleDescriptionStringProp();\n puzzleIDRequest = new PuzzleIDRequestProp();\n setupAnchor = new SetupAnchorProp();\n setupAlg = new AlgProp();\n setupTransformation = new SetupTransformationProp();\n tempoScale = new TempoScaleProp();\n timestampRequest = new TimestampRequestProp();\n viewerLink = new ViewerLinkProp();\n visualizationFormat = new VisualizationFormatProp();\n // Metadata\n title = new ArbitraryStringProp();\n videoURL = new URLProp();\n competitionID = new ArbitraryStringProp();\n /**\n * `<twisty-player>` interally supports associating custom timing information\n * for this move, but there is not an API for this yet. In order to support\n * exploratory use cases for such a feature in the future, this property\n * allows setting timeline information.\n *\n * Note that this feature may not work as expected when combined with other\n * features. In particular, it will cause sync issues with an associated\n * `<twisty-alg-viewer>` depending on how the alg/moves are constructed.\n *\n * Usage example:\n *\n * ```ts\n * import { Move, Pause } from \"cubing/alg\";\n * import { TwistyPlayer } from \"cubing/twisty\";\n *\n * const player = document.body.appendChild(new TwistyPlayer());\n * player.alg = \"R U' D2 R'\";\n *\n * // Note that:\n * // - The leaves must match those of the alg. (No consistency checks are performed at this time.)\n * // - Leaves may overlap if they can be simultaneously animated.\n * // - There must always be at least one animating leaf at any moment. You can use a `Pause` for this if there is a gap between moves.\n * player.experimentalModel.animationTimelineLeavesRequest.set([\n * { animLeaf: new Move(\"R\", 1), start: 0, end: 200 },\n * { animLeaf: new Pause(), start: 200, end: 218 },\n * { animLeaf: new Move(\"U\", -1), start: 218, end: 370 },\n * { animLeaf: new Move(\"D\", 2), start: 249, end: 520 },\n * { animLeaf: new Pause(), start: 520, end: 530 },\n * { animLeaf: new Move(\"R\", -1), start: 530, end: 790 },\n * ]);\n * ```\n */\n animationTimelineLeavesRequest = new AnimationTimelineLeavesRequestProp();\n\n /******************************** Depth 1 ********************************/\n\n puzzleLoader = new PuzzleLoaderProp(\n {\n puzzleIDRequest: this.puzzleIDRequest,\n puzzleDescriptionRequest: this.puzzleDescriptionRequest,\n },\n this.userVisibleErrorTracker,\n );\n\n /******************************** Depth 2 ********************************/\n\n kpuzzle = new KPuzzleProp({ puzzleLoader: this.puzzleLoader });\n\n puzzleID = new PuzzleIDProp({ puzzleLoader: this.puzzleLoader });\n\n /******************************** Depth 3 ********************************/\n\n puzzleAlg = new PuzzleAlgProp({\n algWithIssues: this.alg,\n kpuzzle: this.kpuzzle,\n });\n\n puzzleSetupAlg = new PuzzleAlgProp({\n algWithIssues: this.setupAlg,\n kpuzzle: this.kpuzzle,\n });\n\n visualizationStrategy = new VisualizationStrategyProp({\n visualizationRequest: this.visualizationFormat,\n puzzleID: this.puzzleID,\n });\n\n /******************************** Depth 4 ********************************/\n\n indexerConstructor = new IndexerConstructorProp({\n alg: this.alg,\n puzzle: this.puzzleID,\n visualizationStrategy: this.visualizationStrategy,\n indexerConstructorRequest: this.indexerConstructorRequest,\n animationTimelineLeaves: this.animationTimelineLeavesRequest,\n });\n\n setupAlgTransformation = new AlgTransformationProp({\n setupAlg: this.puzzleSetupAlg,\n kpuzzle: this.kpuzzle,\n });\n\n /******************************** Depth 5 ********************************/\n\n indexer = new IndexerProp({\n indexerConstructor: this.indexerConstructor,\n algWithIssues: this.puzzleAlg,\n kpuzzle: this.kpuzzle,\n animationTimelineLeaves: this.animationTimelineLeavesRequest,\n });\n\n /******************************** Depth 6 ********************************/\n\n anchorTransformation = new AnchorTransformationProp({\n setupTransformation: this.setupTransformation,\n setupAnchor: this.setupAnchor,\n setupAlgTransformation: this.setupAlgTransformation,\n indexer: this.indexer,\n });\n\n timeRange = new TimeRangeProp({\n indexer: this.indexer,\n });\n\n /******************************** Depth 7 ********************************/\n\n detailedTimelineInfo: DetailedTimelineInfoProp = new DetailedTimelineInfoProp(\n {\n timestampRequest: this.timestampRequest,\n timeRange: this.timeRange,\n setupAnchor: this.setupAnchor,\n setupAlg: this.setupAlg,\n },\n );\n\n /******************************** Depth 8 ********************************/\n\n coarseTimelineInfo = new CoarseTimelineInfoProp({\n detailedTimelineInfo: this.detailedTimelineInfo,\n playingInfo: this.playingInfo,\n });\n\n currentMoveInfo = new CurrentMoveInfoProp({\n indexer: this.indexer,\n detailedTimelineInfo: this.detailedTimelineInfo,\n catchUpMove: this.catchUpMove,\n });\n\n /******************************** Depth 9 ********************************/\n\n // TODO: Inline Twisty3D management.\n buttonAppearance = new ButtonAppearanceProp({\n coarseTimelineInfo: this.coarseTimelineInfo,\n viewerLink: this.viewerLink,\n });\n\n currentLeavesSimplified = new CurrentLeavesSimplifiedProp({\n currentMoveInfo: this.currentMoveInfo,\n });\n\n /******************************** Depth 10 ********************************/\n\n currentPattern = new CurrentPatternProp({\n anchoredStart: this.anchorTransformation,\n currentLeavesSimplified: this.currentLeavesSimplified,\n indexer: this.indexer,\n });\n\n /******************************** Depth 11 ********************************/\n\n legacyPosition = new LegacyPositionProp({\n currentMoveInfo: this.currentMoveInfo,\n currentPattern: this.currentPattern,\n });\n\n twistySceneModel = new TwistySceneModel(this);\n\n public async twizzleLink(): Promise<string> {\n const [\n viewerLink,\n puzzleID,\n puzzleDescription,\n alg,\n setup,\n anchor,\n experimentalStickeringRequest,\n experimentalTitle,\n ] = await Promise.all([\n this.viewerLink.get(),\n this.puzzleID.get(),\n this.puzzleDescriptionRequest.get(),\n this.alg.get(),\n this.setupAlg.get(),\n this.setupAnchor.get(),\n this.twistySceneModel.stickeringRequest.get(),\n this.twistySceneModel.twistyPlayerModel.title.get(),\n ]);\n\n const isExplorer = viewerLink === \"experimental-twizzle-explorer\";\n\n const url = new URL(\n `https://alpha.twizzle.net/${isExplorer ? \"explore\" : \"edit\"}/`,\n );\n\n if (!alg.alg.experimentalIsEmpty()) {\n url.searchParams.set(\"alg\", alg.alg.toString());\n }\n if (!setup.alg.experimentalIsEmpty()) {\n url.searchParams.set(\"setup-alg\", setup.alg.toString());\n }\n if (anchor !== \"start\") {\n url.searchParams.set(\"setup-anchor\", anchor);\n }\n if (\n experimentalStickeringRequest !== \"full\" &&\n experimentalStickeringRequest !== null\n ) {\n url.searchParams.set(\n \"experimental-stickering\",\n experimentalStickeringRequest,\n );\n }\n if (isExplorer && puzzleDescription !== NO_VALUE) {\n url.searchParams.set(\"puzzle-description\", puzzleDescription);\n } else if (puzzleID !== \"3x3x3\") {\n url.searchParams.set(\"puzzle\", puzzleID);\n }\n if (experimentalTitle) {\n url.searchParams.set(\"title\", experimentalTitle);\n }\n return url.toString();\n }\n\n experimentalAddAlgLeaf(algLeaf: AlgLeaf, options?: AppendOptions): void {\n const maybeMove = algLeaf.as(Move);\n if (maybeMove) {\n this.experimentalAddMove(maybeMove, options);\n } else {\n this.alg.set(\n (async () => {\n const alg = (await this.alg.get()).alg;\n const newAlg = alg.concat(new Alg([algLeaf]));\n this.timestampRequest.set(\"end\");\n return newAlg;\n })(),\n );\n }\n }\n\n // TODO: Animate the new move.\n experimentalAddMove(\n flexibleMove: Move | string,\n options?: Without<\n AppendOptions,\n [\"puzzleLoader\", \"puzzleSpecificSimplifyOptions\"] // TODO: figure out how to modify `AppendOptions` to accommodate this (or just accept cancel options for now?)\n >,\n ): void {\n const move =\n typeof flexibleMove === \"string\" ? new Move(flexibleMove) : flexibleMove;\n this.alg.set(\n (async () => {\n const [{ alg }, puzzleLoader] = await Promise.all([\n this.alg.get(),\n this.puzzleLoader.get(),\n ]);\n const newAlg = experimentalAppendMove(alg, move, {\n ...options,\n ...(await getPartialAppendOptionsForPuzzleSpecificSimplifyOptions(\n puzzleLoader,\n )),\n });\n this.timestampRequest.set(\"end\");\n this.catchUpMove.set({\n move: move,\n amount: 0,\n });\n return newAlg;\n })(),\n );\n }\n\n // TODO: allow more than 1?\n experimentalRemoveFinalChild(): void {\n this.alg.set(\n (async () => {\n const alg = (await this.alg.get()).alg;\n const children = Array.from(alg.childAlgNodes());\n const [finalChild] = children.splice(-1);\n if (!finalChild) {\n return alg;\n }\n this.timestampRequest.set(\"end\");\n const finalChildMove = finalChild.as(Move);\n if (finalChildMove) {\n this.catchUpMove.set({\n move: finalChildMove.invert(),\n amount: 0,\n });\n }\n return new Alg(children);\n })(),\n );\n }\n}\n", "import type { Alg, AppendCancelOptions } from \"../../alg\";\nimport type { PuzzleDescriptionString } from \"../../puzzle-geometry/pgPuzzles\";\nimport type { StickeringMask } from \"../../puzzles/stickerings/mask\";\nimport type { ExperimentalStickering, PuzzleID } from \"../../twisty\";\nimport type { MillisecondTimestamp } from \"../controllers/AnimationTypes\";\nimport type { FaceletScale } from \"../model/props/puzzle/display/FaceletScaleProp\";\nimport type { HintFaceletStyleWithAuto } from \"../model/props/puzzle/display/HintFaceletProp\";\nimport type { InitialHintFaceletsAnimation } from \"../model/props/puzzle/display/InitialHintFaceletsAnimationProp\";\nimport type { DragInputMode } from \"../model/props/puzzle/state/DragInputProp\";\nimport type { IndexerStrategyName } from \"../model/props/puzzle/state/IndexerConstructorRequestProp\";\nimport type { MovePressInput } from \"../model/props/puzzle/state/MovePressInputProp\";\nimport type { SetupToLocation } from \"../model/props/puzzle/state/SetupAnchorProp\";\nimport type { TimestampRequest } from \"../model/props/timeline/TimestampRequestProp\";\nimport type { BackgroundThemeWithAuto } from \"../model/props/viewer/BackgroundProp\";\nimport type { BackViewLayoutWithAuto } from \"../model/props/viewer/BackViewProp\";\nimport type { ColorSchemeWithAuto } from \"../model/props/viewer/ColorSchemeRequestProp\";\nimport type { ControlPanelThemeWithAuto } from \"../model/props/viewer/ControlPanelProp\";\nimport type { ViewerLinkPageWithAuto } from \"../model/props/viewer/ViewerLinkProp\";\nimport type { VisualizationFormatWithAuto } from \"../model/props/viewer/VisualizationProp\";\nimport { TwistyPlayerModel } from \"../model/TwistyPlayerModel\";\nimport { ManagedCustomElement } from \"./ManagedCustomElement\";\n\nfunction err(propName: string): Error {\n return new Error(\n `Cannot get \\`.${propName}\\` directly from a \\`TwistyPlayer\\`.`,\n );\n}\n\nexport abstract class TwistyPlayerSettable extends ManagedCustomElement {\n experimentalModel: TwistyPlayerModel = new TwistyPlayerModel();\n\n set alg(newAlg: Alg | string) {\n this.experimentalModel.alg.set(newAlg);\n }\n get alg(): never {\n throw err(\"alg\");\n }\n\n set experimentalSetupAlg(newSetup: Alg | string) {\n this.experimentalModel.setupAlg.set(newSetup);\n }\n get experimentalSetupAlg(): never {\n throw err(\"setup\");\n }\n\n set experimentalSetupAnchor(anchor: SetupToLocation) {\n this.experimentalModel.setupAnchor.set(anchor);\n }\n get experimentalSetupAnchor(): never {\n throw err(\"anchor\");\n }\n\n set puzzle(puzzleID: PuzzleID) {\n this.experimentalModel.puzzleIDRequest.set(puzzleID);\n }\n get puzzle(): never {\n throw err(\"puzzle\");\n }\n\n set experimentalPuzzleDescription(puzzleDescription: PuzzleDescriptionString) {\n this.experimentalModel.puzzleDescriptionRequest.set(puzzleDescription);\n }\n get experimentalPuzzleDescription(): never {\n throw err(\"experimentalPuzzleDescription\");\n }\n\n set timestamp(timestamp: TimestampRequest) {\n this.experimentalModel.timestampRequest.set(timestamp);\n }\n get timestamp(): never {\n throw err(\"timestamp\");\n }\n\n set hintFacelets(hintFaceletStyle: HintFaceletStyleWithAuto) {\n this.experimentalModel.twistySceneModel.hintFacelet.set(hintFaceletStyle);\n }\n get hintFacelets(): never {\n throw err(\"hintFacelets\");\n }\n\n set experimentalStickering(stickering: ExperimentalStickering) {\n this.experimentalModel.twistySceneModel.stickeringRequest.set(stickering);\n }\n get experimentalStickering(): never {\n throw err(\"experimentalStickering\");\n }\n\n set experimentalStickeringMaskOrbits(stickeringMask:\n | string\n | StickeringMask) {\n this.experimentalModel.twistySceneModel.stickeringMaskRequest.set(\n stickeringMask,\n );\n }\n get experimentalStickeringMaskOrbits(): never {\n throw err(\"experimentalStickeringMaskOrbits\");\n }\n\n set experimentalFaceletScale(faceletScale: FaceletScale) {\n this.experimentalModel.twistySceneModel.faceletScale.set(faceletScale);\n }\n\n get experimentalFaceletScale(): never {\n throw err(\"experimentalFaceletScale\");\n }\n\n set backView(backView: BackViewLayoutWithAuto) {\n this.experimentalModel.backView.set(backView);\n }\n get backView(): never {\n throw err(\"backView\");\n }\n\n set background(backgroundTheme: BackgroundThemeWithAuto) {\n this.experimentalModel.twistySceneModel.background.set(backgroundTheme);\n }\n get background(): never {\n throw err(\"background\");\n }\n\n set colorScheme(colorScheme: ColorSchemeWithAuto) {\n this.experimentalModel.twistySceneModel.colorSchemeRequest.set(colorScheme);\n }\n get colorScheme(): never {\n throw err(\"colorScheme\");\n }\n\n set controlPanel(newControlPanel: ControlPanelThemeWithAuto) {\n this.experimentalModel.controlPanel.set(newControlPanel);\n }\n get controlPanel(): never {\n throw err(\"controlPanel\");\n }\n\n set visualization(visualizationFormat: VisualizationFormatWithAuto) {\n this.experimentalModel.visualizationFormat.set(visualizationFormat);\n }\n get visualization(): never {\n throw err(\"visualization\");\n }\n\n set experimentalTitle(title: string | null) {\n this.experimentalModel.title.set(title);\n }\n get experimentalTitle(): never {\n throw err(\"experimentalTitle\");\n }\n\n set experimentalVideoURL(videoURL: string | null) {\n this.experimentalModel.videoURL.set(videoURL);\n }\n get experimentalVideoURL(): never {\n throw err(\"experimentalVideoURL\");\n }\n\n set experimentalCompetitionID(competitionID: string | null) {\n this.experimentalModel.competitionID.set(competitionID);\n }\n get experimentalCompetitionID(): never {\n throw err(\"experimentalCompetitionID\");\n }\n\n set viewerLink(viewerLinkPage: ViewerLinkPageWithAuto) {\n this.experimentalModel.viewerLink.set(viewerLinkPage);\n }\n get viewerLink(): never {\n throw err(\"viewerLink\");\n }\n\n set experimentalMovePressInput(movePressInput: MovePressInput) {\n this.experimentalModel.twistySceneModel.movePressInput.set(movePressInput);\n }\n get experimentalMovePressInput(): never {\n throw err(\"experimentalMovePressInput\");\n }\n\n set experimentalMovePressCancelOptions(movePressCancelOptions: AppendCancelOptions) {\n this.experimentalModel.twistySceneModel.movePressCancelOptions.set(\n movePressCancelOptions,\n );\n }\n get experimentalMovePressCancelOptions(): never {\n throw err(\"experimentalMovePressCancelOptions\");\n }\n\n set cameraLatitude(latitude: number) {\n this.experimentalModel.twistySceneModel.orbitCoordinatesRequest.set({\n latitude,\n });\n }\n get cameraLatitude(): never {\n throw err(\"cameraLatitude\");\n }\n\n set cameraLongitude(longitude: number) {\n this.experimentalModel.twistySceneModel.orbitCoordinatesRequest.set({\n longitude,\n });\n }\n get cameraLongitude(): never {\n throw err(\"cameraLongitude\");\n }\n\n set cameraDistance(distance: number) {\n this.experimentalModel.twistySceneModel.orbitCoordinatesRequest.set({\n distance,\n });\n }\n get cameraDistance(): never {\n throw err(\"cameraDistance\");\n }\n\n set cameraLatitudeLimit(latitudeLimit: number) {\n this.experimentalModel.twistySceneModel.latitudeLimit.set(latitudeLimit);\n }\n get cameraLatitudeLimit(): never {\n throw err(\"cameraLatitudeLimit\");\n }\n\n set indexer(indexer: IndexerStrategyName) {\n this.experimentalModel.indexerConstructorRequest.set(indexer);\n }\n get indexer(): never {\n throw err(\"indexer\");\n }\n\n set tempoScale(newTempoScale: number) {\n this.experimentalModel.tempoScale.set(newTempoScale);\n }\n get tempoScale(): never {\n throw err(\"tempoScale\");\n }\n\n set experimentalSprite(url: string | URL) {\n this.experimentalModel.twistySceneModel.foundationStickerSpriteURL.set(url);\n }\n get experimentalSprite(): never {\n throw err(\"experimentalSprite\");\n }\n\n set experimentalHintSprite(url: string | URL) {\n this.experimentalModel.twistySceneModel.hintStickerSpriteURL.set(url);\n }\n get experimentalHintSprite(): never {\n throw err(\"experimentalHintSprite\");\n }\n\n set fullscreenElement(element: Element | null) {\n this.experimentalModel.twistySceneModel.fullscreenElement.set(element);\n }\n get fullscreenElement(): never {\n throw err(\"fullscreenElement\");\n }\n\n set experimentalInitialHintFaceletsAnimation(anim: InitialHintFaceletsAnimation) {\n this.experimentalModel.twistySceneModel.initialHintFaceletsAnimation.set(\n anim,\n );\n }\n get experimentalInitialHintFaceletsAnimation(): never {\n throw err(\"experimentalInitialHintFaceletsAnimation\");\n }\n\n set experimentalHintFaceletsElevation(elevation: \"auto\" | number) {\n this.experimentalModel.twistySceneModel.hintFaceletsElevation.set(\n elevation,\n );\n }\n get experimentalHintFaceletsElevation(): never {\n throw err(\"experimentalHintFaceletsElevation\");\n }\n\n set experimentalDragInput(dragInputMode: DragInputMode) {\n this.experimentalModel.twistySceneModel.dragInput.set(dragInputMode);\n }\n get experimentalDragInput(): never {\n throw err(\"experimentalDragInput\");\n }\n\n experimentalGet = new ExperimentalGetters(this.experimentalModel);\n}\n\nclass ExperimentalGetters {\n constructor(private model: TwistyPlayerModel) {}\n\n async alg(): Promise<Alg> {\n return (await this.model.alg.get()).alg;\n }\n\n async setupAlg(): Promise<Alg> {\n return (await this.model.setupAlg.get()).alg;\n }\n\n puzzleID(): Promise<PuzzleID> {\n return this.model.puzzleID.get();\n }\n\n async timestamp(): Promise<MillisecondTimestamp> {\n return (await this.model.detailedTimelineInfo.get()).timestamp;\n }\n}\n", "import type { Object3D } from \"three/src/Three.js\";\nimport type { Alg, Move } from \"../../alg\";\nimport type { AlgLeaf } from \"../../alg/alg-nodes/AlgNode\";\nimport type { AppendCancelOptions, AppendOptions } from \"../../alg/simplify\";\nimport type { PuzzleDescriptionString } from \"../../puzzle-geometry/pgPuzzles\";\nimport type { ExperimentalStickeringMask } from \"../../puzzles/cubing-private\";\nimport type { ExperimentalStickering } from \"..\";\nimport { RenderScheduler } from \"../controllers/RenderScheduler\";\nimport type { TwistyAnimationControllerDelegate } from \"../controllers/TwistyAnimationController\";\nimport { TwistyPlayerController } from \"../controllers/TwistyPlayerController\";\nimport type { FaceletScale } from \"../model/props/puzzle/display/FaceletScaleProp\";\nimport type { HintFaceletStyleWithAuto } from \"../model/props/puzzle/display/HintFaceletProp\";\nimport type { HintFaceletsElevationRequest } from \"../model/props/puzzle/display/HintFaceletsElevationProp\";\nimport type { InitialHintFaceletsAnimation } from \"../model/props/puzzle/display/InitialHintFaceletsAnimationProp\";\nimport type { DragInputMode } from \"../model/props/puzzle/state/DragInputProp\";\nimport type { MovePressInput } from \"../model/props/puzzle/state/MovePressInputProp\";\nimport type { SetupToLocation } from \"../model/props/puzzle/state/SetupAnchorProp\";\nimport type { PuzzleID } from \"../model/props/puzzle/structure/PuzzleIDRequestProp\";\nimport type { BackgroundThemeWithAuto } from \"../model/props/viewer/BackgroundProp\";\nimport type { BackViewLayoutWithAuto } from \"../model/props/viewer/BackViewProp\";\nimport type {\n ColorScheme,\n ColorSchemeWithAuto,\n} from \"../model/props/viewer/ColorSchemeRequestProp\";\nimport {\n type ControlPanelThemeWithAuto,\n controlsLocations,\n} from \"../model/props/viewer/ControlPanelProp\";\nimport type { ViewerLinkPageWithAuto } from \"../model/props/viewer/ViewerLinkProp\";\nimport type { VisualizationFormatWithAuto } from \"../model/props/viewer/VisualizationProp\";\nimport type { VisualizationStrategy } from \"../model/props/viewer/VisualizationStrategyProp\";\nimport { Twisty2DSceneWrapper } from \"./2D/Twisty2DSceneWrapper\";\nimport type { Twisty3DPuzzle } from \"./3D/puzzles/Twisty3DPuzzle\";\nimport { Twisty3DSceneWrapper } from \"./3D/Twisty3DSceneWrapper\";\nimport type { Twisty3DVantage } from \"./3D/Twisty3DVantage\";\nimport { ClassListManager } from \"./ClassListManager\";\nimport { TwistyButtons } from \"./control-panel/TwistyButtons\";\nimport { TwistyScrubber } from \"./control-panel/TwistyScrubber\";\nimport { InitialValueTracker } from \"./InitialValueTracker\";\nimport { customElementsShim } from \"./node-custom-element-shims\";\nimport { downloadURL, getDefaultFilename, screenshot } from \"./screenshot\";\nimport { twistyPlayerCSS } from \"./TwistyPlayer.css\";\nimport { TwistyPlayerSettable } from \"./TwistyPlayerSettable\";\n\nconst DATA_ATTRIBUTE_PREFIX = \"data-\";\n\n// TODO: I couldn't figure out how to use use more specific types. Ideally, we'd\n// enforce consistency with the model.\nexport const twistyPlayerAttributeMap = {\n // TODO: We assume each of these can be set using a string or will be automatically converted by JS (e.g. numbers). Can we enforce\n // that with types? Do we need to add a translation mechanism for things we\n // don't want to leave settable as strings?\n // TODO: Enum validation.\n\n // Alg\n alg: \"alg\",\n \"experimental-setup-alg\": \"experimentalSetupAlg\",\n\n // String-based\n \"experimental-setup-anchor\": \"experimentalSetupAnchor\",\n puzzle: \"puzzle\",\n \"experimental-puzzle-description\": \"experimentalPuzzleDescription\",\n visualization: \"visualization\",\n \"hint-facelets\": \"hintFacelets\",\n \"experimental-stickering\": \"experimentalStickering\",\n \"experimental-stickering-mask-orbits\": \"experimentalStickeringMaskOrbits\",\n background: \"background\",\n \"color-scheme\": \"colorScheme\",\n \"control-panel\": \"controlPanel\",\n \"back-view\": \"backView\",\n \"experimental-facelet-scale\": \"experimentalFaceletScale\",\n \"experimental-initial-hint-facelets-animation\":\n \"experimentalInitialHintFaceletsAnimation\",\n \"experimental-hint-facelets-elevation\": \"experimentalHintFaceletsElevation\",\n // \"indexer\": \"indexer\",\n \"viewer-link\": \"viewerLink\",\n \"experimental-move-press-input\": \"experimentalMovePressInput\",\n \"experimental-drag-input\": \"experimentalDragInput\",\n\n // Metadata\n \"experimental-title\": \"experimentalTitle\",\n \"experimental-video-url\": \"experimentalVideoURL\",\n \"experimental-competition-id\": \"experimentalCompetitionID\",\n\n // Number-based\n \"camera-latitude\": \"cameraLatitude\",\n \"camera-longitude\": \"cameraLongitude\",\n \"camera-distance\": \"cameraDistance\",\n \"camera-latitude-limit\": \"cameraLatitudeLimit\",\n \"tempo-scale\": \"tempoScale\",\n\n // URL-based\n \"experimental-sprite\": \"experimentalSprite\",\n \"experimental-hint-sprite\": \"experimentalHintSprite\",\n};\n\nexport type TwistyPlayerAttribute = keyof typeof twistyPlayerAttributeMap;\n\nconst configKeys: Record<TwistyPlayerAttribute, true> = Object.fromEntries(\n Object.values(twistyPlayerAttributeMap).map((s) => [s, true]),\n) as any;\n\n// TODO: Find a way to share this def with `attributeMap`.\n/**\n * The config argument passed to {@link TwistyPlayer} when calling the\n * constructor. This interface type be useful for avoiding bugs when you would\n * like to create a {@link TwistyPlayer} using a dynamic config, or by combining\n * configs.\n *\n * ```js\n * import { TwistyPlayer, type TwistyPlayerConfig } from \"cubing/twisty\";\n *\n * const MY_DEFAULT_CONFIG: TwistyPlayerConfig = {\n * puzzle: \"megaminx\",\n * alg: \"R U R'\"\n * };\n * export function createTwistyPlayer(overrideConfig: TwistyPlayerConfig) {\n * const options = { ...MY_DEFAULT_CONFIG, ...overrideConfig };\n * return new TwistyPlayer(options);\n * }\n *\n * // Example: if the current page is https://alpha.twizzle.net/edit/?alg=M2+E2+S2\n * // then this gives us the \"alg\" param value \"M2 E2 S2\".\n * const myOverrideConfig: TwistyPlayerConfig = {};\n * const algParam = new URL(location.href).searchParams.get(\"alg\");\n * if (algParam) {\n * myOverrideConfig.alg = algParam;\n * }\n * createTwistyPlayer(myOverrideConfig);\n * ```\n *\n * @category TwistyPlayer\n */\nexport interface TwistyPlayerConfig {\n // Alg\n alg?: Alg | string;\n experimentalSetupAlg?: Alg | string;\n // String-based\n experimentalSetupAnchor?: SetupToLocation; // TODO: \"auto\"\n puzzle?: PuzzleID;\n experimentalPuzzleDescription?: PuzzleDescriptionString;\n visualization?: VisualizationFormatWithAuto;\n hintFacelets?: HintFaceletStyleWithAuto;\n experimentalStickering?: ExperimentalStickering | null;\n experimentalStickeringMaskOrbits?: ExperimentalStickeringMask | string;\n background?: BackgroundThemeWithAuto;\n colorScheme?: ColorSchemeWithAuto;\n controlPanel?: ControlPanelThemeWithAuto;\n backView?: BackViewLayoutWithAuto;\n experimentalInitialHintFaceletsAnimation?: InitialHintFaceletsAnimation;\n experimentalFaceletScale?: FaceletScale;\n experimentalHintFaceletsElevation?: HintFaceletsElevationRequest;\n // \"indexer\"?: \"indexer\";\n viewerLink?: ViewerLinkPageWithAuto;\n experimentalMovePressInput?: MovePressInput;\n experimentalDragInput?: DragInputMode;\n // Metadata\n experimentalTitle?: string | null;\n experimentalVideoURL?: string;\n experimentalCompetitionID?: string;\n // Number-based\n cameraLatitude?: number;\n cameraLongitude?: number;\n cameraDistance?: number;\n cameraLatitudeLimit?: number;\n tempoScale?: number;\n // URL-based\n experimentalSprite?: string | null;\n experimentalHintSprite?: string | null;\n // TODO: Not supported as attributes\n experimentalMovePressCancelOptions?: AppendCancelOptions; // TODO: Support setting via a simplified attribute enum?\n}\n\nconst propOnly: Record<string, boolean> = {\n experimentalMovePressCancelOptions: true,\n};\n\nlet cachedSharedIntersectionObserver: IntersectionObserver | undefined;\nconst intersectedCallback = Symbol(\"intersectedCallback\");\nfunction waitForIntersection(player: TwistyPlayer) {\n cachedSharedIntersectionObserver ??= new IntersectionObserver(\n (entries, observer) => {\n for (const entry of entries) {\n if (entry.isIntersecting && entry.intersectionRect.height > 0) {\n (entry.target as TwistyPlayer)[intersectedCallback]();\n observer.unobserve(entry.target);\n }\n }\n },\n );\n cachedSharedIntersectionObserver.observe(player);\n}\n\n/**\n * TwistyPlayer is the heart of `cubing.js`. It can be used to display a puzzle on a web page like this:\n *\n * <script src=\"path/to/cubing/twisty\" type=\"module\"></script>\n * <twisty-player alg=\"R U R'\"></twisty-player>\n *\n * You can also construct it directly in JavaScript:\n *\n * ```js\n * import { TwistyPlayer } from \"cubing/twisty\";\n * const twistyPlayer = new TwistyPlayer({alg: \"R U R'\"});\n * // Once the page has loaded, you can do this:\n * document.body.appendChild(twistyPlayer);\n * ```\n *\n * See {@link https://js.cubing.net/cubing/} for more examples.\n *\n * @category TwistyPlayer\n */\nexport class TwistyPlayer\n extends TwistyPlayerSettable\n implements TwistyAnimationControllerDelegate\n{\n controller: TwistyPlayerController = new TwistyPlayerController(\n this.experimentalModel,\n this,\n );\n\n buttons?: TwistyButtons;\n\n experimentalCanvasClickCallback: (...args: any) => void = () => {};\n // #onCanvasClick() {\n\n // }\n\n constructor(config: TwistyPlayerConfig = {}) {\n super();\n\n // TODO: double-check that these are all getting set sync without causing extra work.\n for (const [propName, value] of Object.entries(config)) {\n if (\n !(configKeys[propName as TwistyPlayerAttribute] || propOnly[propName])\n ) {\n console.warn(`Invalid config passed to TwistyPlayer: ${propName}`);\n break;\n }\n (this as any)[propName] = value;\n }\n }\n\n #controlsManager: ClassListManager<ControlPanelThemeWithAuto> =\n new ClassListManager<ControlPanelThemeWithAuto>(\n this,\n \"controls-\",\n ([\"auto\"] as ControlPanelThemeWithAuto[]).concat(\n Object.keys(controlsLocations) as ControlPanelThemeWithAuto[],\n ),\n );\n\n #visualizationWrapperElem = document.createElement(\"div\"); // TODO: Better pattern.\n #errorElem = document.createElement(\"div\"); // TODO: Better pattern.\n #alreadyConnected = false; // TODO: support resetting\n connectedCallback(): void {\n this.addCSS(twistyPlayerCSS);\n waitForIntersection(this);\n }\n\n async [intersectedCallback](): Promise<void> {\n if (this.#alreadyConnected) {\n return;\n }\n this.#alreadyConnected = true;\n\n this.addElement(this.#visualizationWrapperElem).classList.add(\n \"visualization-wrapper\",\n );\n this.addElement(this.#errorElem).classList.add(\"error-elem\");\n this.#errorElem.textContent = \"Error\";\n this.experimentalModel.userVisibleErrorTracker.addFreshListener(\n (userVisibleError) => {\n const errorString: string | null = userVisibleError.errors[0] ?? null;\n this.contentWrapper.classList.toggle(\"error\", !!errorString);\n if (errorString) {\n this.#errorElem.textContent = errorString;\n }\n },\n );\n\n const scrubber = new TwistyScrubber(\n this.experimentalModel,\n this.controller,\n );\n this.contentWrapper.appendChild(scrubber);\n\n this.buttons = new TwistyButtons(\n this.experimentalModel,\n this.controller,\n this,\n );\n this.contentWrapper.appendChild(this.buttons);\n\n this.experimentalModel.twistySceneModel.background.addFreshListener(\n (backgroundTheme: BackgroundThemeWithAuto) => {\n this.contentWrapper.classList.toggle(\n \"checkered\",\n [\"auto\", \"checkered\"].includes(backgroundTheme),\n );\n this.contentWrapper.classList.toggle(\n \"checkered-transparent\",\n backgroundTheme === \"checkered-transparent\",\n );\n },\n );\n\n this.experimentalModel.twistySceneModel.colorScheme.addFreshListener(\n (colorScheme: ColorScheme) => {\n this.contentWrapper.classList.toggle(\n \"dark-mode\",\n [\"dark\"].includes(colorScheme),\n );\n },\n );\n\n this.experimentalModel.controlPanel.addFreshListener(\n (controlPanel: ControlPanelThemeWithAuto) => {\n this.#controlsManager.setValue(controlPanel);\n },\n );\n\n this.experimentalModel.visualizationStrategy.addFreshListener(\n this.#setVisualizationWrapper.bind(this),\n );\n\n this.experimentalModel.puzzleID.addFreshListener(this.flash.bind(this));\n }\n\n #flashLevel: \"auto\" | \"none\" = \"auto\";\n /** @deprecated */\n experimentalSetFlashLevel(newLevel: \"auto\" | \"none\"): void {\n this.#flashLevel = newLevel;\n }\n\n flash() {\n if (this.#flashLevel === \"auto\") {\n this.#visualizationWrapper?.animate([{ opacity: 0.25 }, { opacity: 1 }], {\n duration: 250,\n easing: \"ease-out\",\n });\n }\n }\n\n #visualizationWrapper: Twisty2DSceneWrapper | Twisty3DSceneWrapper | null =\n null;\n #initial3DVisualizationWrapper =\n new InitialValueTracker<Twisty3DSceneWrapper>();\n\n #visualizationStrategy: VisualizationStrategy | null = null;\n #setVisualizationWrapper(strategy: VisualizationStrategy): void {\n if (strategy !== this.#visualizationStrategy) {\n this.#visualizationWrapper?.remove();\n this.#visualizationWrapper?.disconnect();\n let newWrapper: Twisty2DSceneWrapper | Twisty3DSceneWrapper;\n switch (strategy) {\n case \"2D\":\n case \"experimental-2D-LL\":\n case \"experimental-2D-LL-face\": {\n newWrapper = new Twisty2DSceneWrapper(\n this.experimentalModel.twistySceneModel,\n strategy,\n );\n break;\n }\n case \"Cube3D\":\n case \"PG3D\": {\n // TODO: Properly wire this up so we can set PG3D for the cube.\n newWrapper = new Twisty3DSceneWrapper(this.experimentalModel);\n this.#initial3DVisualizationWrapper.handleNewValue(newWrapper);\n break;\n }\n default:\n throw new Error(\"Invalid visualization\");\n }\n this.#visualizationWrapperElem.appendChild(newWrapper);\n this.#visualizationWrapper = newWrapper;\n this.#visualizationStrategy = strategy;\n }\n }\n\n async experimentalCurrentVantages(): Promise<Iterable<Twisty3DVantage>> {\n this.connectedCallback();\n const wrapper = this.#visualizationWrapper;\n if (wrapper instanceof Twisty3DSceneWrapper) {\n return wrapper.experimentalVantages();\n }\n return [];\n }\n\n async experimentalCurrentCanvases(): Promise<HTMLCanvasElement[]> {\n const vantages = await this.experimentalCurrentVantages();\n const canvases: HTMLCanvasElement[] = [];\n for (const vantage of vantages) {\n canvases.push((await vantage.canvasInfo()).canvas);\n }\n return canvases;\n }\n\n /**\n * Get the first available puzzle `Object3D`. This can be inserted into\n * another `three.js` scene, essentially \"adopting\" it from the\n * `TwistyPlayer`'s scenes while still allowing the `TwistyPlayer` to animate\n * it. The function returns a `Promise` that returns if and when the\n * `Object3D` is available, and accepts a callback that is called whenever a\n * render is scheduled for the puzzle (essentially, if something about the\n * puzzle has changed, like its appearance or current animated state).\n *\n * Note:\n * - This may never resolve if the player never creates the relevant 3D object\n * under the hood (e.g. if the config is set to 2D, or is not valid for\n * rendering a puzzle)\n * - The architecture of `cubing.js` may change significantly, so it is not\n * guaranteed that a `three.js` `Object3D` will be available from the main\n * thread in the future.\n * - This function only returns the current `three.js` puzzle object (once one\n * exists). If you change e.g. the `puzzle` config for the player, then the\n * object will currently become stale. This may be replaced with more\n * convenient behaviour in the future.\n *\n * @deprecated */\n async experimentalCurrentThreeJSPuzzleObject(\n puzzleRenderScheduledCallback?: () => void,\n ): Promise<Object3D> {\n this.connectedCallback();\n const sceneWrapper = await this.#initial3DVisualizationWrapper.promise;\n const puzzleWrapper =\n await sceneWrapper.experimentalTwisty3DPuzzleWrapper();\n const twisty3DPuzzlePromise: Promise<Twisty3DPuzzle> =\n puzzleWrapper.twisty3DPuzzle();\n const safeToCallback = (async () => {\n await twisty3DPuzzlePromise;\n await new Promise((resolve) => setTimeout(resolve, 0));\n })();\n if (puzzleRenderScheduledCallback) {\n // We want to notify the callback when the render is *scheduled* (once per\n // render), not when it is run. So we have a stub callback for the\n // scheduler itself, and rely on `scheduler.requestIsPending()` to dedup\n // requests below.\n const scheduler = new RenderScheduler(async () => {});\n puzzleWrapper.addEventListener(\"render-scheduled\", async () => {\n if (!scheduler.requestIsPending()) {\n scheduler.requestAnimFrame();\n await safeToCallback;\n puzzleRenderScheduledCallback();\n }\n });\n }\n return twisty3DPuzzlePromise;\n }\n\n jumpToStart(options?: { flash: boolean }): void {\n this.controller.jumpToStart(options);\n }\n\n jumpToEnd(options?: { flash: boolean }): void {\n this.controller.jumpToEnd(options);\n }\n\n play(): void {\n this.controller.togglePlay(true);\n }\n\n pause(): void {\n this.controller.togglePlay(false);\n }\n\n // Inspiration:\n // - https://developer.mozilla.org/en-US/docs/Web/API/Element/toggleAttribute (`force` argument)\n // - https://developer.mozilla.org/en-US/docs/Web/API/DOMTokenList/toggle (`force` argument)\n // We still provide `play()` and `pause()` individually for convenience, though.\n togglePlay(play?: boolean): void {\n this.controller.togglePlay(play);\n }\n\n // TODO: Animate the new move.\n // TODO: Automatically handle puzzle.\n experimentalAddMove(\n flexibleMove: Move | string,\n options?: AppendOptions,\n ): void {\n this.experimentalModel.experimentalAddMove(flexibleMove, options);\n }\n\n // TODO: Animate the new move.\n // TODO: Automatically handle puzzle.\n experimentalAddAlgLeaf(algLeaf: AlgLeaf, options?: AppendOptions): void {\n this.experimentalModel.experimentalAddAlgLeaf(algLeaf, options);\n }\n\n static get observedAttributes(): string[] {\n const observed: string[] = [];\n for (const key of Object.keys(twistyPlayerAttributeMap)) {\n observed.push(key, DATA_ATTRIBUTE_PREFIX + key);\n }\n return observed;\n }\n\n experimentalRemoveFinalChild(): void {\n this.experimentalModel.experimentalRemoveFinalChild();\n }\n\n attributeChangedCallback(\n attributeName: string,\n _oldValue: string,\n newValue: string,\n ): void {\n if (attributeName.startsWith(DATA_ATTRIBUTE_PREFIX)) {\n attributeName = attributeName.slice(DATA_ATTRIBUTE_PREFIX.length);\n }\n const setterName =\n twistyPlayerAttributeMap[attributeName as TwistyPlayerAttribute];\n if (!setterName) {\n return;\n }\n\n (this as any)[setterName] = newValue;\n }\n\n // TODO: Make this more ergonomic and flexible.\n // TODO: dimensions.\n async experimentalScreenshot(options?: {\n width: number;\n height: number;\n }): Promise<string> {\n return (await screenshot(this.experimentalModel, options)).dataURL;\n }\n\n // TODO: Make this more ergonomic and flexible.\n // TODO: dimensions.\n async experimentalDownloadScreenshot(filename?: string): Promise<void> {\n if (\n [\"2D\", \"experimental-2D-LL\", \"experimental-2D-LL-face\"].includes(\n await this.experimentalModel.visualizationStrategy.get(),\n )\n ) {\n // TODO: This has lots of async issues. It should also go into the screenshot impl file.\n const wrapper2D = this.#visualizationWrapper as Twisty2DSceneWrapper;\n const twisty2DPuzzle = await wrapper2D\n .currentTwisty2DPuzzleWrapper()!\n .twisty2DPuzzle();\n const str = new XMLSerializer().serializeToString(\n twisty2DPuzzle.svgWrapper!.svgElement,\n );\n const url = URL.createObjectURL(new Blob([str]));\n downloadURL(\n url,\n filename ?? (await getDefaultFilename(this.experimentalModel)),\n \"svg\",\n );\n } else {\n await (await screenshot(this.experimentalModel)).download(filename);\n }\n }\n}\n\ncustomElementsShim.define(\"twisty-player\", TwistyPlayer);\ndeclare global {\n interface HTMLElementTagNameMap {\n \"twisty-player\": TwistyPlayer;\n }\n}\n", "import {\n type Alg,\n type Commutator,\n type Conjugate,\n functionFromTraversal,\n type Grouping,\n type LineComment,\n type Move,\n type Newline,\n type Pause,\n TraversalDownUp,\n} from \"../../../alg\";\nimport type { Parsed } from \"../../../alg/parseAlg\";\nimport type {\n LeafCount,\n LeafIndex,\n} from \"../../controllers/indexer/AlgIndexer\";\nimport type { AnimatedLeafAlgNode } from \"../../controllers/indexer/simultaneous-moves/simul-moves\";\n\nexport type AnimatedLeafAlgNodeInfo = {\n leaf: Parsed<AnimatedLeafAlgNode>;\n idx: LeafIndex;\n};\nexport type OrderedLeafTokens = AnimatedLeafAlgNodeInfo[];\n\ninterface DataUp {\n tokens: OrderedLeafTokens;\n numLeavesInside: LeafCount;\n}\n\ninterface DataDown {\n numMovesSoFar: LeafCount;\n}\n\nclass LeafTokens extends TraversalDownUp<DataDown, DataUp> {\n public traverseAlg(alg: Alg, dataDown: DataDown): DataUp {\n const algNodeArrays: OrderedLeafTokens[] = [];\n let numMovesInside = 0;\n for (const algNode of alg.childAlgNodes()) {\n const dataUp = this.traverseAlgNode(algNode, {\n numMovesSoFar: (dataDown.numMovesSoFar + numMovesInside) as LeafCount,\n });\n algNodeArrays.push(dataUp.tokens);\n numMovesInside += dataUp.numLeavesInside;\n }\n return {\n tokens: Array.prototype.concat(...algNodeArrays),\n numLeavesInside: numMovesInside as LeafCount,\n };\n }\n\n public traverseGrouping(grouping: Grouping, dataDown: DataDown): DataUp {\n const dataUp = this.traverseAlg(grouping.alg, dataDown);\n return {\n tokens: dataUp.tokens,\n numLeavesInside: (dataUp.numLeavesInside * grouping.amount) as LeafCount,\n };\n }\n\n public traverseMove(move: Move, dataDown: DataDown): DataUp {\n return {\n tokens: [\n {\n leaf: move as Parsed<Move>,\n idx: dataDown.numMovesSoFar as number as LeafIndex,\n },\n ],\n numLeavesInside: 1 as LeafCount,\n }; // TODO: What if not parsed?\n }\n\n public traverseCommutator(\n commutator: Commutator,\n dataDown: DataDown,\n ): DataUp {\n const dataUpA = this.traverseAlg(commutator.A, dataDown);\n const dataUpB = this.traverseAlg(commutator.B, {\n numMovesSoFar: (dataDown.numMovesSoFar +\n dataUpA.numLeavesInside) as LeafCount,\n });\n return {\n tokens: dataUpA.tokens.concat(dataUpB.tokens),\n numLeavesInside: (dataUpA.numLeavesInside * 2 +\n dataUpB.numLeavesInside) as LeafCount,\n };\n }\n\n public traverseConjugate(conjugate: Conjugate, dataDown: DataDown): DataUp {\n const dataUpA = this.traverseAlg(conjugate.A, dataDown);\n const dataUpB = this.traverseAlg(conjugate.B, {\n numMovesSoFar: (dataDown.numMovesSoFar +\n dataUpA.numLeavesInside) as LeafCount,\n });\n return {\n tokens: dataUpA.tokens.concat(dataUpB.tokens),\n numLeavesInside: (dataUpA.numLeavesInside * 2 +\n dataUpB.numLeavesInside * 2) as LeafCount,\n };\n }\n\n public traversePause(pause: Pause, dataDown: DataDown): DataUp {\n return {\n tokens: [\n {\n leaf: pause as Parsed<Pause>,\n idx: dataDown.numMovesSoFar as number as LeafIndex,\n },\n ],\n numLeavesInside: 1 as LeafCount,\n }; // TODO: What if not parsed?\n }\n\n public traverseNewline(_newline: Newline, _dataDown: DataDown): DataUp {\n return {\n tokens: [],\n numLeavesInside: 0 as LeafCount,\n };\n }\n\n public traverseLineComment(\n _comment: LineComment,\n _dataDown: DataDown,\n ): DataUp {\n return {\n tokens: [],\n numLeavesInside: 0 as LeafCount,\n };\n }\n}\n\nexport const leafTokens = functionFromTraversal(LeafTokens);\n", "// TODO: Move this?\n\nimport type { Alg } from \"../../../alg\";\nimport {\n endCharIndexKey,\n type Parsed,\n startCharIndexKey,\n} from \"../../../alg/parseAlg\";\nimport type { LeafCount } from \"../../controllers/indexer/AlgIndexer\";\nimport {\n type AlgWithIssues,\n algWithIssuesFromString,\n} from \"../../model/props/puzzle/state/AlgProp\";\nimport {\n SimpleTwistyPropSource,\n TwistyPropDerived,\n TwistyPropSource,\n} from \"../../model/props/TwistyProp\";\nimport {\n type AnimatedLeafAlgNodeInfo,\n leafTokens,\n type OrderedLeafTokens,\n} from \"./LeafTokens\";\n\nexport class TwistyAlgEditorValueProp extends SimpleTwistyPropSource<string> {\n getDefaultValue(): string {\n return \"\";\n }\n}\n\ninterface AlgEditorAlgWithIssuesPropInput {\n value: string;\n}\nclass AlgEditorAlgWithIssuesProp extends TwistyPropDerived<\n AlgEditorAlgWithIssuesPropInput,\n AlgWithIssues\n> {\n derive(input: AlgEditorAlgWithIssuesPropInput): AlgWithIssues {\n return algWithIssuesFromString(input.value);\n }\n // TODO: canReuse needs to take the source string into account.\n}\n\ninterface SelectionInfoPropInput {\n selectionStart: number;\n selectionEnd: number;\n}\ninterface SelectionInfo extends SelectionInfoPropInput {\n endChangedMostRecently: boolean;\n}\nexport class TwistyAlgEditorSelectionProp extends TwistyPropSource<\n SelectionInfo,\n SelectionInfoPropInput\n> {\n getDefaultValue() {\n return {\n selectionStart: 0,\n selectionEnd: 0,\n endChangedMostRecently: false,\n };\n }\n\n async derive(\n input: SelectionInfoPropInput,\n oldValue: Promise<SelectionInfo>,\n ): Promise<SelectionInfo> {\n const { selectionStart, selectionEnd } = input;\n const lastResult = await oldValue;\n const endChangedMostRecently =\n input.selectionStart === lastResult.selectionStart &&\n input.selectionEnd !== (await oldValue).selectionEnd;\n return {\n selectionStart,\n selectionEnd,\n endChangedMostRecently,\n };\n }\n}\n\ninterface TargetCharPropInputs {\n selectionInfo: SelectionInfo;\n}\n\nexport class TargetCharProp extends TwistyPropDerived<\n TargetCharPropInputs,\n number\n> {\n derive(inputs: TargetCharPropInputs) {\n return inputs.selectionInfo.endChangedMostRecently\n ? inputs.selectionInfo.selectionEnd\n : inputs.selectionInfo.selectionStart;\n }\n}\n\ninterface LeafTokensPropInputs {\n algWithIssues: AlgWithIssues;\n}\nclass LeafTokensProp extends TwistyPropDerived<\n LeafTokensPropInputs,\n OrderedLeafTokens\n> {\n derive(inputs: LeafTokensPropInputs): OrderedLeafTokens {\n return leafTokens(inputs.algWithIssues.alg as Parsed<Alg>, {\n numMovesSoFar: 0 as LeafCount,\n }).tokens;\n }\n}\n\ninterface LeafToHighlightPropInputs {\n targetChar: number;\n leafTokens: OrderedLeafTokens;\n}\ntype HighlightWhere = \"before\" | \"start\" | \"inside\" | \"end\" | \"after\";\nexport interface HighlightInfo {\n leafInfo: AnimatedLeafAlgNodeInfo;\n where: HighlightWhere;\n}\nclass LeafToHighlightProp extends TwistyPropDerived<\n LeafToHighlightPropInputs,\n HighlightInfo | null\n> {\n derive(inputs: LeafToHighlightPropInputs): HighlightInfo | null {\n function withWhere(\n leafInfo: AnimatedLeafAlgNodeInfo | null,\n ): HighlightInfo | null {\n if (leafInfo === null) {\n return null;\n }\n let where: HighlightWhere;\n if (inputs.targetChar < leafInfo.leaf[startCharIndexKey]) {\n where = \"before\";\n } else if (inputs.targetChar === leafInfo.leaf[startCharIndexKey]) {\n where = \"start\";\n } else if (inputs.targetChar < leafInfo.leaf[endCharIndexKey]) {\n where = \"inside\";\n } else if (inputs.targetChar === leafInfo.leaf[endCharIndexKey]) {\n where = \"end\";\n } else {\n where = \"after\";\n }\n return {\n leafInfo,\n where,\n };\n }\n\n let lastLeafInfo: AnimatedLeafAlgNodeInfo | null = null;\n // TODO: binary search\n for (const leafInfo of inputs.leafTokens) {\n if (\n inputs.targetChar < leafInfo.leaf[startCharIndexKey] &&\n lastLeafInfo !== null\n ) {\n return withWhere(lastLeafInfo);\n }\n if (inputs.targetChar <= leafInfo.leaf[endCharIndexKey]) {\n return withWhere(leafInfo);\n }\n lastLeafInfo = leafInfo;\n }\n\n return withWhere(lastLeafInfo);\n }\n}\n\nexport class TwistyAlgEditorModel {\n valueProp = new TwistyAlgEditorValueProp();\n selectionProp = new TwistyAlgEditorSelectionProp();\n targetCharProp = new TargetCharProp({ selectionInfo: this.selectionProp });\n\n algEditorAlgWithIssues = new AlgEditorAlgWithIssuesProp({\n value: this.valueProp,\n });\n\n leafTokensProp = new LeafTokensProp({\n algWithIssues: this.algEditorAlgWithIssues,\n });\n\n leafToHighlight = new LeafToHighlightProp({\n leafTokens: this.leafTokensProp,\n targetChar: this.targetCharProp,\n });\n}\n", "import { Alg } from \"../../../alg\";\nimport { globalSafeDocument } from \"../document\";\n\nconst COMMENT_DELIMITER = \"//\";\n\nfunction maybeParse(str: string): Alg | null {\n try {\n return Alg.fromString(str);\n } catch {\n return null;\n }\n}\n\n// If there is no occurence, the original string is returned in the first entry.\n// If there is, the delimiter is included at the start of the second entry.\nfunction sliceBeforeFirstOccurrence(\n str: string,\n delimiter: string,\n): [before: string, after: string] {\n const idx = str.indexOf(delimiter);\n if (idx === -1) {\n return [str, \"\"];\n }\n return [str.slice(0, idx), str.slice(idx)];\n}\n\nfunction replaceSmartQuotesOutsideComments(str: string): string {\n const linesOut = [];\n for (const line of str.split(\"\\n\")) {\n let [before, after] = sliceBeforeFirstOccurrence(line, COMMENT_DELIMITER);\n before = before.replaceAll(\"\u2019\", \"'\");\n linesOut.push(before + after);\n }\n return linesOut.join(\"\\n\");\n}\n\nexport function pasteIntoTextArea(\n textArea: HTMLTextAreaElement,\n pastedText: string,\n): void {\n const { value: oldValue } = textArea;\n const { selectionStart, selectionEnd } = textArea;\n\n const textPrecedingSelection = oldValue.slice(0, selectionStart);\n const textFollowingSelection = oldValue.slice(selectionEnd);\n\n pastedText = pastedText.replaceAll(\"\\r\\n\", \"\\n\");\n\n // Does the last line end in a comment?\n // Note that we want the match to include \"R U R'\\n//hello there\" but not \"// hello there\\nR U R'\"\n const selectionStartsInExistingComment =\n textPrecedingSelection.match(/\\/\\/[^\\n]*$/);\n const pasteCreatesStartingComment =\n oldValue[selectionStart - 1] === \"/\" && pastedText[0] === \"/\"; // Pasting \"/ This is \u201Cweird\u201D.\" at the end of \"R U R' /\"\n const pasteStartsWithCommentText =\n selectionStartsInExistingComment || pasteCreatesStartingComment;\n\n const pasteEndsWithComment = pastedText.match(/\\/\\/[^\\n]*$/);\n\n // Replace smart quotes that are not in comments.\n let replacement = pastedText;\n if (pasteStartsWithCommentText) {\n const [before, after] = sliceBeforeFirstOccurrence(pastedText, \"\\n\");\n replacement = before + replaceSmartQuotesOutsideComments(after);\n } else {\n replacement = replaceSmartQuotesOutsideComments(pastedText);\n }\n\n /** Note: at this point, we would want to test which of the following produces\n * a valid alg:\n *\n * - No changes to `correctedPastedText`.\n * - Add a space prefix.\n * - Add a space suffix.\n *\n * However, the puzzle is not synchronously available to us, so we can't tell\n * whether pasting \"U\" before \"R\" should create \"UR\" (Megaminx) or \"U R\"\n * (3x3x3). So we optimistically assume the pasted alg is self-contained\n * (which is the case if it's a fully valid alg on its own) and try to perform\n * the latter directly.\n */\n\n const tryAddSpaceBefore =\n !pasteStartsWithCommentText &&\n selectionStart !== 0 && // Not at text start\n ![\"\\n\", \" \"].includes(replacement[0]) &&\n ![\"\\n\", \" \"].includes(oldValue[selectionStart - 1]); // Not at line start, no space before\n const tryAddSpaceAfter =\n !pasteEndsWithComment &&\n selectionEnd !== oldValue.length && // Not at text end\n !([\"\\n\", \" \"] as (string | undefined)[]).includes(replacement.at(-1)) &&\n ![\"\\n\", \" \"].includes(oldValue[selectionEnd]); // Not at line end, no space after\n\n function adoptSpacingIfValid(prefix: string, suffix: string): boolean {\n const candidate = prefix + replacement + suffix;\n const valid = !!maybeParse(\n textPrecedingSelection + candidate + textFollowingSelection,\n );\n if (valid) {\n replacement = candidate;\n }\n return valid;\n }\n\n // Here, we try possible space insertions. We use `||` for short-circuit logic, to adopt the first valid one.\n (tryAddSpaceBefore && tryAddSpaceAfter && adoptSpacingIfValid(\" \", \" \")) || // Paste \"R U R' U'\" over \" \" in \"F F'\" to create \"F R U R' U' F'\"\n (tryAddSpaceBefore && adoptSpacingIfValid(\" \", \"\")) || // Paste \"U\" after \"R'\" in \"R' L'\" to create \"R' U L'\"\n (tryAddSpaceAfter && adoptSpacingIfValid(\"\", \" \")); // Paste \"U\" before \"L'\" in \"R' L'\" to create \"R' U L'\"\n\n // `execCommand` is under-specced and deprecated, but it's more likely to allow undo and preserve history.\n const execCommandSuccess = globalSafeDocument?.execCommand(\n \"insertText\",\n false,\n replacement,\n );\n if (!execCommandSuccess) {\n // TODO: use \"select\" or \"preserve\" (https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setRangeText#selectmode)\n textArea.setRangeText(replacement, selectionStart, selectionEnd, \"end\");\n }\n}\n", "import { cssStyleSheetShim } from \"../node-custom-element-shims\";\n\nexport const twistyAlgEditorCSS = new cssStyleSheetShim();\ntwistyAlgEditorCSS.replaceSync(\n `\n:host {\n width: 384px;\n display: grid;\n}\n\n.wrapper {\n /*overflow: hidden;\n resize: horizontal;*/\n\n background: var(--background, none);\n display: grid;\n}\n\ntextarea, .carbon-copy {\n grid-area: 1 / 1 / 2 / 2;\n\n width: 100%;\n font-family: sans-serif;\n line-height: 1.2em;\n\n font-size: var(--font-size, inherit);\n font-family: var(--font-family, sans-serif);\n\n box-sizing: border-box;\n\n padding: var(--padding, 0.5em);\n /* Prevent horizontal growth. */\n overflow-x: hidden;\n}\n\ntextarea {\n resize: none;\n background: none;\n z-index: 2;\n border: 1px solid var(--border-color, rgba(0, 0, 0, 0.25));\n overflow: hidden;\n}\n\n.carbon-copy {\n white-space: pre-wrap;\n word-wrap: break-word;\n color: transparent;\n user-select: none;\n pointer-events: none;\n\n z-index: 1;\n}\n\n.carbon-copy .highlight {\n background: var(--highlight-color, rgba(255, 128, 0, 0.5));\n padding: 0.1em 0.2em;\n margin: -0.1em -0.2em;\n border-radius: 0.2em;\n}\n\n.wrapper.issue-warning textarea,\n.wrapper.valid-for-puzzle-warning textarea {\n outline: none;\n border: 1px solid rgba(200, 200, 0, 0.5);\n background: rgba(255, 255, 0, 0.1);\n}\n\n.wrapper.issue-error textarea,\n.wrapper.valid-for-puzzle-error textarea {\n outline: none;\n border: 1px solid red;\n background: rgba(255, 0, 0, 0.1);\n}\n`,\n);\n", "/**\n * Warning: the current implementation of <twisty-alg-editor> is *not good*,\n * but it is *good enough*. The important parts is that:\n *\n * - The editor can be used in apps without much effort.\n * - The editor handles alg validation and move highlighting *okay* when not\n * connected to a `<twisty-player>`.\n * - The editor stays in sync if it's connected to a `<twisty-player>`.\n *\n * The current implementation still has some race conditions and edge cases. A\n * proper rewrite with a better model would be very welcome.\n */\n\nimport type { ExperimentalParsed } from \"../../../alg\";\nimport { Alg, type Move, type Pause } from \"../../../alg\";\nimport {\n endCharIndexKey,\n type Parsed,\n startCharIndexKey,\n} from \"../../../alg/parseAlg\";\nimport type { MillisecondTimestamp } from \"../../controllers/AnimationTypes\";\nimport type {\n AlgProp,\n AlgWithIssues,\n} from \"../../model/props/puzzle/state/AlgProp\";\nimport type { CurrentLeavesSimplified } from \"../../model/props/puzzle/state/CurrentLeavesSimplified\";\nimport { ClassListManager } from \"../ClassListManager\";\nimport { ManagedCustomElement } from \"../ManagedCustomElement\";\nimport { customElementsShim } from \"../node-custom-element-shims\";\nimport { TwistyPlayer } from \"../TwistyPlayer\";\nimport { type HighlightInfo, TwistyAlgEditorModel } from \"./model\";\nimport { pasteIntoTextArea } from \"./paste\";\nimport { twistyAlgEditorCSS } from \"./TwistyAlgEditor.css\";\n\nconst ATTRIBUTE_FOR_TWISTY_PLAYER = \"for-twisty-player\";\nconst ATTRIBUTE_PLACEHOLDER = \"placeholder\";\nconst ATTRIBUTE_TWISTY_PLAYER_PROP = \"twisty-player-prop\";\n\ntype TwistyPlayerAlgProp = \"alg\" | \"setupAlg\";\n\n/** @category Other Custom Elements */\nexport class TwistyAlgEditor extends ManagedCustomElement {\n model = new TwistyAlgEditorModel();\n\n // #alg: Alg = new Alg();\n #textarea: HTMLTextAreaElement = document.createElement(\"textarea\");\n #carbonCopy: HTMLDivElement = document.createElement(\"div\");\n #carbonCopyPrefix: HTMLSpanElement = document.createElement(\"span\");\n #carbonCopyHighlight: HTMLSpanElement = document.createElement(\"span\");\n #carbonCopySuffix: HTMLSpanElement = document.createElement(\"span\");\n\n // #textareaClassListManager: ClassListManager<\"none\" | \"warning\" | \"error\"> =\n // new ClassListManager(this, \"issue-\", [\"none\", \"warning\", \"error\"]);\n\n #textareaClassListValidForPuzzleManager: ClassListManager<\n \"none\" | \"warning\" | \"error\"\n > = new ClassListManager(this, \"valid-for-puzzle-\", [\n \"none\",\n \"warning\",\n \"error\",\n ]);\n\n #twistyPlayer: TwistyPlayer | null = null;\n #twistyPlayerProp: TwistyPlayerAlgProp;\n get #algProp(): AlgProp | null {\n if (this.#twistyPlayer === null) {\n return null;\n } else {\n return this.#twistyPlayer.experimentalModel[this.#twistyPlayerProp];\n }\n }\n\n // Temporary Workaround for Twizzle Explorer\n debugNeverRequestTimestamp: boolean = false;\n\n constructor(options?: {\n twistyPlayer?: TwistyPlayer;\n twistyPlayerProp?: TwistyPlayerAlgProp;\n }) {\n super();\n this.#carbonCopy.classList.add(\"carbon-copy\");\n this.addElement(this.#carbonCopy);\n this.#textarea.rows = 1;\n this.addElement(this.#textarea);\n this.#carbonCopyPrefix.classList.add(\"prefix\");\n this.#carbonCopy.appendChild(this.#carbonCopyPrefix);\n this.#carbonCopyHighlight.classList.add(\"highlight\");\n this.#carbonCopy.appendChild(this.#carbonCopyHighlight);\n this.#carbonCopySuffix.classList.add(\"suffix\");\n this.#carbonCopy.appendChild(this.#carbonCopySuffix);\n\n this.#textarea.placeholder = \"Alg\";\n // Prevent iOS from defaulting to smart quotes.\n this.#textarea.setAttribute(\"spellcheck\", \"false\");\n\n this.addCSS(twistyAlgEditorCSS);\n\n // TODO: What set of events should we register? `change`? `keydown`?\n this.#textarea.addEventListener(\"input\", () => {\n this.#onInputHasFired = true;\n this.onInput();\n });\n this.#textarea.addEventListener(\"blur\", () => this.onBlur());\n document.addEventListener(\"selectionchange\", () =>\n this.onSelectionChange(),\n );\n\n if (options?.twistyPlayer) {\n this.twistyPlayer = options.twistyPlayer;\n }\n this.#twistyPlayerProp = options?.twistyPlayerProp ?? \"alg\";\n\n if (options?.twistyPlayerProp === \"alg\") {\n this.model.leafToHighlight.addFreshListener(\n (highlightInfo: HighlightInfo | null) => {\n if (highlightInfo) {\n this.highlightLeaf(highlightInfo.leafInfo.leaf);\n }\n },\n );\n }\n }\n\n connectedCallback(): void {\n this.#textarea.addEventListener(\"paste\", (e) => {\n const text = e.clipboardData?.getData(\"text\");\n if (text) {\n pasteIntoTextArea(this.#textarea, text);\n e.preventDefault();\n this.onInput();\n }\n });\n }\n\n // TODO\n set algString(s: string) {\n this.#textarea.value = s;\n this.onInput();\n }\n\n // TODO: remove?\n get algString(): string {\n return this.#textarea.value;\n }\n\n // To we need a getter?\n set placeholder(placeholderText: string) {\n this.#textarea.placeholder = placeholderText;\n }\n\n #onInputHasFired = false;\n onInput(): void {\n this.#carbonCopyHighlight.hidden = true;\n this.highlightLeaf(null);\n\n // TODO: This is a hack so that the you don't get a warning when the cursor\n // is after the space while typing `R U`. It would be nice to have something\n // cursor-aware that can also ignore whitespace warnings (or other syntax\n // errors due to normal input) adjacent to the cursor when it's in the\n // middle, but this is suffuciently useful for now.\n const endTrimmed = this.#textarea.value.trimEnd();\n this.model.valueProp.set(endTrimmed);\n this.#algProp?.set(endTrimmed);\n }\n\n async onSelectionChange(): Promise<void> {\n if (\n document.activeElement !== this ||\n this.shadow.activeElement !== this.#textarea\n ) {\n return;\n }\n if (this.#twistyPlayerProp !== \"alg\") {\n return;\n }\n\n const { selectionStart, selectionEnd } = this.#textarea;\n this.model.selectionProp.set({\n selectionStart,\n selectionEnd,\n });\n }\n\n async onBlur(): Promise<void> {\n // TODO: Figure out how not to make the cursor jump.\n // const parsed = Alg.fromString(this.algString);\n // this.algString = parsed.toString();\n // const [currentLeavesSimplified, indexer] = await Promise.all([\n // this.#twistyPlayer!.model.currentLeavesSimplifiedProp.get(),\n // this.#twistyPlayer!.model.indexerProp.get(),\n // ]);\n // const leaf = indexer.getAnimLeaf(currentLeavesSimplified.stateIndex);\n // this.highlightLeaf(leaf as Parsed<Move | Pause> | null);\n }\n\n setAlgIssueClassForPuzzle(issues: \"none\" | \"warning\" | \"error\") {\n this.#textareaClassListValidForPuzzleManager.setValue(issues);\n }\n\n // `white-space: pre;` mostly matches the formatting of the `<textarea>`, *except* when we end with a newline.\n // So we add an space to ensure that there is a character on the final line (that is very unlikely to trigger extra line wrapping).\n #padSuffix(s: string): string {\n return s.endsWith(\"\\n\") ? `${s} ` : s;\n }\n\n #highlightedLeaf: ExperimentalParsed<Move | Pause> | null = null;\n // TODO: support a primary highlighted move and secondary ones.\n highlightLeaf(leaf: ExperimentalParsed<Move | Pause> | null): void {\n // if (this.#twistyPlayerProp !== \"alg\") {\n // // TODO: make this configurable\n // return;\n // }\n if (leaf === null) {\n this.#carbonCopyPrefix.textContent = \"\";\n this.#carbonCopyHighlight.textContent = \"\";\n this.#carbonCopySuffix.textContent = this.#padSuffix(\n this.#textarea.value,\n );\n return;\n }\n if (leaf === this.#highlightedLeaf) {\n return;\n }\n this.#highlightedLeaf = leaf;\n this.#carbonCopyPrefix.textContent = this.#textarea.value.slice(\n 0,\n leaf[startCharIndexKey],\n );\n this.#carbonCopyHighlight.textContent = this.#textarea.value.slice(\n leaf[startCharIndexKey],\n leaf[endCharIndexKey],\n );\n this.#carbonCopySuffix.textContent = this.#padSuffix(\n this.#textarea.value.slice(leaf[endCharIndexKey]),\n );\n this.#carbonCopyHighlight.hidden = false;\n }\n\n get twistyPlayer(): TwistyPlayer | null {\n return this.#twistyPlayer;\n }\n\n // TODO: spread out this impl over private methods instead of self-listeners.\n set twistyPlayer(twistyPlayer: TwistyPlayer | null) {\n if (this.#twistyPlayer) {\n // TODO: support reassigment/clearing\n console.warn(\"twisty-player reassignment/clearing is not supported\");\n return;\n }\n this.#twistyPlayer = twistyPlayer;\n if (!twistyPlayer) {\n return;\n }\n void (async () => {\n this.algString = this.#algProp\n ? (await this.#algProp.get()).alg.toString()\n : \"\";\n })();\n\n // if (this.#twistyPlayerProp === \"setupAlg\") {\n // console.log(\"Setupppety!\");\n // this.#twistyPlayer?.experimentalModel.puzzleSetupAlg.addFreshListener(\n // () => {\n // this.highlightLeaf(null);\n // },\n // );\n // }\n if (this.#twistyPlayerProp === \"alg\") {\n // this.model.leafToHighlight.addFreshListener(\n // this.highlightLeaf.bind(this),\n // );\n\n // TODO: listen to puzzle prop?\n this.#twistyPlayer?.experimentalModel.puzzleAlg.addFreshListener(\n (algWithIssues: AlgWithIssues) => {\n // console.log(JSON.stringify(algWithIssues));\n if (algWithIssues.issues.errors.length === 0) {\n this.setAlgIssueClassForPuzzle(\n // TODO: Allow trailing spaces.\n algWithIssues.issues.warnings.length === 0 ? \"none\" : \"warning\",\n );\n const newAlg = algWithIssues.alg;\n const oldAlg = Alg.fromString(this.algString);\n if (!newAlg.isIdentical(oldAlg)) {\n this.algString = newAlg.toString();\n this.onInput();\n } else {\n // this.model.algInputProp.set(oldAlg);\n }\n } else {\n this.setAlgIssueClassForPuzzle(\"error\");\n }\n },\n );\n\n this.model.leafToHighlight.addFreshListener(\n async (highlightInfo: HighlightInfo | null) => {\n if (highlightInfo === null) {\n return;\n }\n // TODO: This indexer can be out of date!\n const [indexer, timestampRequest] = await Promise.all([\n await twistyPlayer.experimentalModel.indexer.get(),\n await twistyPlayer.experimentalModel.timestampRequest.get(),\n ]);\n if (timestampRequest === \"auto\" && !this.#onInputHasFired) {\n return;\n }\n const moveStartTimestamp = indexer.indexToMoveStartTimestamp(\n highlightInfo.leafInfo.idx,\n );\n const duration = indexer.moveDuration(highlightInfo.leafInfo.idx);\n\n let newTimestamp: MillisecondTimestamp;\n switch (highlightInfo.where) {\n case \"before\": {\n newTimestamp = moveStartTimestamp;\n break;\n }\n case \"start\":\n case \"inside\": {\n newTimestamp = (moveStartTimestamp +\n duration / 4) as MillisecondTimestamp;\n break;\n }\n case \"end\":\n case \"after\": {\n newTimestamp = (moveStartTimestamp +\n duration) as MillisecondTimestamp;\n break;\n }\n default:\n console.log(\"invalid where\");\n throw new Error(\"Invalid where!\");\n }\n if (!this.debugNeverRequestTimestamp) {\n twistyPlayer.experimentalModel.timestampRequest.set(newTimestamp);\n }\n },\n );\n\n twistyPlayer.experimentalModel.currentLeavesSimplified.addFreshListener(\n async (currentLeavesSimplified: CurrentLeavesSimplified) => {\n const indexer = await twistyPlayer.experimentalModel.indexer.get();\n const leaf = indexer.getAnimLeaf(\n currentLeavesSimplified.patternIndex,\n );\n this.highlightLeaf(leaf as Parsed<Move | Pause> | null);\n },\n );\n }\n }\n\n protected attributeChangedCallback(\n attributeName: string,\n _oldValue: string,\n newValue: string,\n ): void {\n switch (attributeName) {\n case ATTRIBUTE_FOR_TWISTY_PLAYER: {\n const elem = document.getElementById(newValue);\n if (!elem) {\n console.warn(`${ATTRIBUTE_FOR_TWISTY_PLAYER}= elem does not exist`);\n return;\n }\n if (!(elem instanceof TwistyPlayer)) {\n // TODO: avoid assuming single instance of lib?\n console.warn(`${ATTRIBUTE_FOR_TWISTY_PLAYER}=is not a twisty-player`);\n return;\n }\n this.twistyPlayer = elem;\n return;\n }\n case ATTRIBUTE_PLACEHOLDER: {\n this.placeholder = newValue;\n return;\n }\n case ATTRIBUTE_TWISTY_PLAYER_PROP: {\n if (this.#twistyPlayer) {\n console.log(\"cannot set prop\");\n throw new Error(\"cannot set prop after twisty player\");\n }\n this.#twistyPlayerProp = newValue as TwistyPlayerAlgProp;\n return;\n }\n }\n }\n\n static get observedAttributes(): string[] {\n return [\n ATTRIBUTE_FOR_TWISTY_PLAYER,\n ATTRIBUTE_PLACEHOLDER,\n ATTRIBUTE_TWISTY_PLAYER_PROP,\n ];\n }\n}\n\ncustomElementsShim.define(\"twisty-alg-editor\", TwistyAlgEditor);\ndeclare global {\n interface HTMLElementTagNameMap {\n \"twisty-alg-editor\": TwistyAlgEditor;\n }\n}\n", "// Normally we'd capitalize `ID`, but `Id` matches DOM API function names.\nexport async function firstElementWithId(id: string): Promise<Element> {\n return new Promise((resolve, reject) => {\n try {\n const currentElem = document.getElementById(id);\n if (currentElem) {\n resolve(currentElem);\n }\n const observer = new MutationObserver((mutations: MutationRecord[]) => {\n for (const mutation of mutations) {\n if (\n mutation.attributeName === \"id\" &&\n mutation.target instanceof Element &&\n mutation.target.getAttribute(\"id\") === id\n ) {\n resolve(mutation.target);\n observer.disconnect();\n }\n }\n });\n\n observer.observe(document.body, {\n attributeFilter: [\"id\"],\n subtree: true,\n });\n } catch (e) {\n reject(e);\n }\n });\n}\n", "import { cssStyleSheetShim } from \"./node-custom-element-shims\";\n\nexport const twistyAlgViewerCSS = new cssStyleSheetShim();\ntwistyAlgViewerCSS.replaceSync(\n `\n:host {\n display: inline;\n}\n\n.wrapper {\n display: inline;\n}\n\na:not(:hover) {\n color: inherit;\n text-decoration: none;\n}\n\ntwisty-alg-leaf-elem.twisty-alg-comment {\n color: rgba(0, 0, 0, 0.4);\n}\n\n.wrapper.current-move {\n background: rgba(66, 133, 244, 0.3);\n margin-left: -0.1em;\n margin-right: -0.1em;\n padding-left: 0.1em;\n padding-right: 0.1em;\n border-radius: 0.1em;\n}\n`,\n);\n", "import {\n Alg,\n type AlgNode,\n type Commutator,\n type Conjugate,\n functionFromTraversal,\n Grouping,\n type LineComment,\n type Move,\n type Newline,\n Pause,\n TraversalDownUp,\n} from \"../../alg\";\nimport {\n ExperimentalIterationDirection,\n experimentalDirect,\n} from \"../../alg/cubing-private\";\nimport { type Parsed, startCharIndexKey } from \"../../alg/parseAlg\";\nimport type { MillisecondTimestamp } from \"../controllers/AnimationTypes\";\nimport type {\n CurrentMoveInfo,\n LeafIndex,\n} from \"../controllers/indexer/AlgIndexer\";\nimport type { AlgWithIssues } from \"../model/props/puzzle/state/AlgProp\";\nimport type { DetailedTimelineInfo } from \"../model/props/timeline/DetailedTimelineInfoProp\";\nimport { firstElementWithId } from \"./firstElementWithId\";\nimport { ManagedCustomElement } from \"./ManagedCustomElement\";\nimport {\n customElementsShim,\n HTMLElementShim,\n} from \"./node-custom-element-shims\";\nimport { twistyAlgViewerCSS } from \"./TwistyAlgViewer.css\";\nimport { TwistyPlayer } from \"./TwistyPlayer\";\n\n// TODO: dynamically adjust the fraction to take into account moves that rotate a lot (e.g. `R100`).\nconst DEFAULT_OFFSET_FRACTION = 0.25;\n\ninterface DataDown {\n earliestMoveIndex: LeafIndex;\n twistyAlgViewer: TwistyAlgViewer;\n direction: ExperimentalIterationDirection;\n}\n\ninterface DataUp {\n moveCount: number;\n element: TwistyAlgWrapperElem | TwistyAlgLeafElem;\n}\n\nclass TwistyAlgLeafElem extends ManagedCustomElement {\n constructor(\n className: string,\n text: string,\n dataDown: DataDown,\n public algOrAlgNode: Alg | AlgNode,\n offsetIntoMove: boolean,\n clickable: boolean,\n ) {\n super({ mode: \"open\" });\n this.classList.add(className);\n\n this.addCSS(twistyAlgViewerCSS);\n if (clickable) {\n const anchor = this.contentWrapper.appendChild(\n document.createElement(\"a\"),\n );\n anchor.href = \"#\";\n anchor.textContent = text;\n\n anchor.addEventListener(\"click\", (e) => {\n e.preventDefault();\n void dataDown.twistyAlgViewer.jumpToIndex(\n dataDown.earliestMoveIndex,\n offsetIntoMove,\n );\n });\n } else {\n this.contentWrapper.appendChild(\n document.createElement(\"span\"),\n ).textContent = text;\n }\n }\n\n pathToIndex(_index: number): (TwistyAlgWrapperElem | TwistyAlgLeafElem)[] {\n return [];\n }\n\n setCurrentMove(current: boolean) {\n this.contentWrapper.classList.toggle(\"current-move\", current);\n }\n}\n\ncustomElementsShim.define(\"twisty-alg-leaf-elem\", TwistyAlgLeafElem);\n\nclass TwistyAlgWrapperElem extends HTMLElementShim {\n private queue: (Element | Text)[] = [];\n\n constructor(\n className: string,\n public algOrAlgNode: Alg | AlgNode,\n ) {\n super();\n this.classList.add(className);\n }\n\n addString(str: string) {\n this.queue.push(document.createTextNode(str));\n }\n\n addElem(dataUp: DataUp): number {\n this.queue.push(dataUp.element);\n return dataUp.moveCount;\n }\n\n flushQueue(\n direction: ExperimentalIterationDirection = ExperimentalIterationDirection.Forwards,\n ): void {\n for (const node of maybeReverseList(this.queue, direction)) {\n this.append(node);\n }\n this.queue = [];\n }\n\n pathToIndex(_index: number): (TwistyAlgWrapperElem | TwistyAlgLeafElem)[] {\n return [];\n }\n}\n\ncustomElementsShim.define(\"twisty-alg-wrapper-elem\", TwistyAlgWrapperElem);\n\nfunction oppositeDirection(\n direction: ExperimentalIterationDirection,\n): ExperimentalIterationDirection {\n return direction === ExperimentalIterationDirection.Forwards\n ? ExperimentalIterationDirection.Backwards\n : ExperimentalIterationDirection.Forwards;\n}\n\nfunction updateDirectionByAmount(\n currentDirection: ExperimentalIterationDirection,\n amount: number,\n): ExperimentalIterationDirection {\n return amount < 0 ? oppositeDirection(currentDirection) : currentDirection;\n}\n\nfunction maybeReverseList<T>(\n l: T[],\n direction: ExperimentalIterationDirection,\n): T[] {\n if (direction === ExperimentalIterationDirection.Forwards) {\n return l;\n }\n // console.log(\"rev\", Array.from(l).reverse());\n // return Array.from(l).reverse();\n const copy = Array.from(l);\n copy.reverse();\n return copy;\n}\n\nclass AlgToDOMTree extends TraversalDownUp<DataDown, DataUp, DataUp> {\n public traverseAlg(alg: Alg, dataDown: DataDown): DataUp {\n let moveCount = 0;\n const element = new TwistyAlgWrapperElem(\"twisty-alg-alg\", alg); // TODO: pick a better class name.\n let first = true;\n for (const algNode of experimentalDirect(\n alg.childAlgNodes(),\n dataDown.direction,\n )) {\n if (!first) {\n element.addString(\" \");\n }\n first = false;\n if (algNode.as(Pause)?.experimentalNISSGrouping) {\n element.addString(\"^(\"); // TODO: Handle this lower down.\n }\n // TODO: Handle this check lower down.\n if (!algNode.as(Grouping)?.experimentalNISSPlaceholder) {\n moveCount += element.addElem(\n this.traverseAlgNode(algNode, {\n earliestMoveIndex: (dataDown.earliestMoveIndex +\n moveCount) as LeafIndex,\n twistyAlgViewer: dataDown.twistyAlgViewer,\n direction: dataDown.direction,\n }),\n );\n }\n if (algNode.as(Pause)?.experimentalNISSGrouping) {\n element.addString(\")\"); // TODO: Handle this lower down.\n }\n }\n element.flushQueue(dataDown.direction);\n return {\n moveCount: moveCount,\n element,\n };\n }\n\n public traverseGrouping(grouping: Grouping, dataDown: DataDown): DataUp {\n const square1Tuple = grouping.experimentalAsSquare1Tuple();\n // if (square1Tuplle) {\n\n // }\n\n const direction = updateDirectionByAmount(\n dataDown.direction,\n grouping.amount,\n );\n let moveCount = 0;\n const element = new TwistyAlgWrapperElem(\"twisty-alg-grouping\", grouping);\n element.addString(\"(\");\n\n if (square1Tuple) {\n moveCount += element.addElem({\n moveCount: 1,\n element: new TwistyAlgLeafElem(\n \"twisty-alg-move\", // TODO: Mark the tuple with a special class?\n square1Tuple[0].amount.toString(),\n dataDown,\n square1Tuple[0],\n true,\n true,\n ),\n });\n element.addString(\", \");\n moveCount += element.addElem({\n moveCount: 1,\n element: new TwistyAlgLeafElem(\n \"twisty-alg-move\", // TODO: Mark the tuple with a special class?\n square1Tuple[1].amount.toString(),\n dataDown,\n square1Tuple[1],\n true,\n true,\n ),\n });\n } else {\n moveCount += element.addElem(\n this.traverseAlg(grouping.alg, {\n earliestMoveIndex: (dataDown.earliestMoveIndex +\n moveCount) as LeafIndex,\n twistyAlgViewer: dataDown.twistyAlgViewer,\n direction,\n }),\n );\n }\n\n element.addString(`)${grouping.experimentalRepetitionSuffix}`);\n element.flushQueue();\n return {\n moveCount: moveCount * Math.abs(grouping.amount),\n element,\n };\n }\n\n public traverseMove(move: Move, dataDown: DataDown): DataUp {\n const element = new TwistyAlgLeafElem(\n \"twisty-alg-move\",\n move.toString(),\n dataDown,\n move,\n true,\n true,\n );\n dataDown.twistyAlgViewer.highlighter.addMove(\n (move as Parsed<Move>)[startCharIndexKey],\n element,\n );\n return {\n moveCount: 1,\n element,\n };\n }\n\n public traverseCommutator(\n commutator: Commutator,\n dataDown: DataDown,\n ): DataUp {\n let moveCount = 0;\n const element = new TwistyAlgWrapperElem(\n \"twisty-alg-commutator\",\n commutator,\n );\n element.addString(\"[\");\n element.flushQueue();\n const [first, second]: Alg[] = maybeReverseList(\n [commutator.A, commutator.B],\n dataDown.direction,\n );\n moveCount += element.addElem(\n this.traverseAlg(first, {\n earliestMoveIndex: (dataDown.earliestMoveIndex +\n moveCount) as LeafIndex,\n twistyAlgViewer: dataDown.twistyAlgViewer,\n direction: dataDown.direction,\n }),\n );\n element.addString(\", \");\n moveCount += element.addElem(\n this.traverseAlg(second, {\n earliestMoveIndex: (dataDown.earliestMoveIndex +\n moveCount) as LeafIndex,\n twistyAlgViewer: dataDown.twistyAlgViewer,\n direction: dataDown.direction,\n }),\n );\n element.flushQueue(dataDown.direction);\n element.addString(\"]\");\n element.flushQueue();\n return {\n moveCount: moveCount * 2,\n element,\n };\n }\n\n public traverseConjugate(conjugate: Conjugate, dataDown: DataDown): DataUp {\n let moveCount = 0;\n const element = new TwistyAlgWrapperElem(\"twisty-alg-conjugate\", conjugate);\n element.addString(\"[\");\n const aLen = element.addElem(\n this.traverseAlg(conjugate.A, {\n earliestMoveIndex: (dataDown.earliestMoveIndex +\n moveCount) as LeafIndex,\n twistyAlgViewer: dataDown.twistyAlgViewer,\n direction: dataDown.direction,\n }),\n );\n moveCount += aLen;\n element.addString(\": \");\n moveCount += element.addElem(\n this.traverseAlg(conjugate.B, {\n earliestMoveIndex: (dataDown.earliestMoveIndex +\n moveCount) as LeafIndex,\n twistyAlgViewer: dataDown.twistyAlgViewer,\n direction: dataDown.direction,\n }),\n );\n element.addString(\"]\");\n element.flushQueue();\n return {\n moveCount: moveCount + aLen,\n element,\n };\n }\n\n public traversePause(pause: Pause, dataDown: DataDown): DataUp {\n if (pause.experimentalNISSGrouping) {\n return this.traverseAlg(pause.experimentalNISSGrouping.alg, dataDown);\n }\n return {\n moveCount: 1,\n element: new TwistyAlgLeafElem(\n \"twisty-alg-pause\",\n \".\",\n dataDown,\n pause,\n true,\n true,\n ),\n };\n }\n\n public traverseNewline(newline: Newline, _dataDown: DataDown): DataUp {\n const element = new TwistyAlgWrapperElem(\"twisty-alg-newline\", newline);\n element.append(document.createElement(\"br\"));\n return {\n moveCount: 0,\n element,\n };\n }\n\n public traverseLineComment(\n lineComment: LineComment,\n dataDown: DataDown,\n ): DataUp {\n return {\n moveCount: 0,\n element: new TwistyAlgLeafElem(\n \"twisty-alg-line-comment\",\n `//${lineComment.text}`,\n dataDown,\n lineComment,\n false,\n false,\n ),\n };\n }\n}\n\nconst algToDOMTree = functionFromTraversal(AlgToDOMTree);\n\nclass MoveHighlighter {\n moveCharIndexMap: Map<number, TwistyAlgLeafElem> = new Map();\n currentElem: TwistyAlgLeafElem | null = null;\n\n addMove(charIndex: number, elem: TwistyAlgLeafElem): void {\n this.moveCharIndexMap.set(charIndex, elem);\n }\n\n set(move: Parsed<Move> | null): void {\n const newElem = move\n ? (this.moveCharIndexMap.get(move[startCharIndexKey]) ?? null)\n : null;\n if (this.currentElem === newElem) {\n return;\n }\n this.currentElem?.classList.remove(\"twisty-alg-current-move\");\n this.currentElem?.setCurrentMove(false);\n newElem?.classList.add(\"twisty-alg-current-move\");\n newElem?.setCurrentMove(true);\n this.currentElem = newElem;\n }\n}\n\n/** @category Other Custom Elements */\nexport class TwistyAlgViewer extends HTMLElementShim {\n highlighter: MoveHighlighter = new MoveHighlighter();\n #domTree?: TwistyAlgWrapperElem | TwistyAlgLeafElem;\n #twistyPlayer: TwistyPlayer | null = null;\n lastClickTimestamp: number | null = null;\n constructor(options?: { twistyPlayer?: TwistyPlayer }) {\n super();\n if (options?.twistyPlayer) {\n this.twistyPlayer = options?.twistyPlayer;\n }\n }\n\n protected connectedCallback(): void {\n // nothing to do?\n }\n\n private setAlg(alg: Alg): void {\n this.#domTree = algToDOMTree(alg, {\n earliestMoveIndex: 0 as LeafIndex,\n twistyAlgViewer: this,\n direction: ExperimentalIterationDirection.Forwards,\n }).element;\n this.textContent = \"\";\n this.appendChild(this.#domTree);\n }\n\n get twistyPlayer(): TwistyPlayer | null {\n return this.#twistyPlayer;\n }\n\n set twistyPlayer(twistyPlayer: TwistyPlayer | null) {\n void this.#setTwistyPlayer(twistyPlayer);\n }\n\n async #setTwistyPlayer(twistyPlayer: TwistyPlayer | null) {\n if (this.#twistyPlayer) {\n console.warn(\"twisty-player reassignment is not supported\");\n return;\n }\n if (twistyPlayer === null) {\n throw new Error(\"clearing twistyPlayer is not supported\");\n }\n this.#twistyPlayer = twistyPlayer;\n\n this.#twistyPlayer.experimentalModel.alg.addFreshListener(\n (algWithIssues: AlgWithIssues) => {\n this.setAlg(algWithIssues.alg);\n },\n );\n\n const sourceAlg = (await this.#twistyPlayer.experimentalModel.alg.get())\n .alg;\n // TODO: Use proper architecture instead of a heuristic to ensure we have a parsed alg annotated with char indices.\n const parsedAlg =\n startCharIndexKey in (sourceAlg as Partial<Parsed<Alg>>)\n ? sourceAlg\n : Alg.fromString(sourceAlg.toString());\n this.setAlg(parsedAlg);\n\n twistyPlayer.experimentalModel.currentMoveInfo.addFreshListener(\n (currentMoveInfo: CurrentMoveInfo) => {\n let moveInfo = currentMoveInfo.currentMoves[0];\n moveInfo ??= currentMoveInfo.movesStarting[0];\n moveInfo ??= currentMoveInfo.movesFinishing[0];\n if (!moveInfo) {\n this.highlighter.set(null);\n } else {\n const mainCurrentMove = moveInfo.move; // TODO\n this.highlighter.set(mainCurrentMove as Parsed<Move>);\n }\n },\n );\n\n twistyPlayer.experimentalModel.detailedTimelineInfo.addFreshListener(\n (detailedTimelineInfo: DetailedTimelineInfo) => {\n if (detailedTimelineInfo.timestamp !== this.lastClickTimestamp) {\n this.lastClickTimestamp = null;\n }\n },\n );\n }\n\n async jumpToIndex(index: LeafIndex, offsetIntoMove: boolean): Promise<void> {\n // TODO: Fix async issues.\n const twistyPlayer = this.#twistyPlayer;\n if (twistyPlayer) {\n twistyPlayer.pause();\n const timestampPromise = (async (): Promise<MillisecondTimestamp> => {\n const indexer = await twistyPlayer.experimentalModel.indexer.get();\n const offset = offsetIntoMove\n ? indexer.moveDuration(index) * DEFAULT_OFFSET_FRACTION\n : 0;\n return (indexer.indexToMoveStartTimestamp(index) +\n indexer.moveDuration(index) -\n offset) as MillisecondTimestamp;\n })();\n twistyPlayer.experimentalModel.timestampRequest.set(\n await timestampPromise, // TODO\n );\n if (this.lastClickTimestamp === (await timestampPromise)) {\n twistyPlayer.play();\n this.lastClickTimestamp = null;\n } else {\n this.lastClickTimestamp = await timestampPromise;\n }\n }\n }\n\n protected async attributeChangedCallback(\n attributeName: string,\n _oldValue: string,\n newValue: string,\n ): Promise<void> {\n if (attributeName === \"for\") {\n let elem: Element | null = document.getElementById(newValue);\n if (!elem) {\n console.info(\"for= elem does not exist, waiting for one\");\n }\n await customElements.whenDefined(\"twisty-player\");\n // TODO: handle intermediate attribute changes\n elem = await firstElementWithId(newValue);\n if (!(elem instanceof TwistyPlayer)) {\n console.warn(\"for= elem is not a twisty-player\");\n return;\n }\n this.twistyPlayer = elem;\n }\n }\n\n static get observedAttributes(): string[] {\n return [\"for\"];\n }\n}\n\ncustomElementsShim.define(\"twisty-alg-viewer\", TwistyAlgViewer);\ndeclare global {\n interface HTMLElementTagNameMap {\n \"twisty-alg-viewer\": TwistyAlgViewer;\n }\n}\n", "import { cssStyleSheetShim } from \"../node-custom-element-shims\";\n\nexport const twizzleLinkCSS = new cssStyleSheetShim();\ntwizzleLinkCSS.replaceSync(\n `\n.wrapper {\n background: rgb(255, 245, 235);\n border: 1px solid rgba(0, 0, 0, 0.25);\n\n /* Workaround from https://stackoverflow.com/questions/40010597/how-do-i-apply-opacity-to-a-css-color-variable */\n --text-color: 0, 0, 0;\n --heading-background: 255, 230, 210;\n\n color: rgb(var(--text-color));\n}\n\n.setup-alg, twisty-alg-viewer {\n padding: 0.5em 1em;\n}\n\n.heading {\n background: rgba(var(--heading-background), 1);\n color: rgba(var(--text-color), 1);\n font-weight: bold;\n padding: 0.25em 0.5em;\n display: grid;\n grid-template-columns: auto 1fr;\n\n /* For the move count hover elems. */\n position: sticky;\n}\n\n.heading.title {\n background: rgb(255, 245, 235);\n font-size: 150%;\n white-space: pre-wrap;\n}\n\n.heading .move-count {\n font-weight: initial;\n text-align: right;\n color: rgba(var(--text-color), 0.4);\n}\n\n.wrapper.dark-mode .heading .move-count {\n color: rgba(var(--text-color), 0.7);\n}\n\n.heading a {\n text-decoration: none;\n color: inherit;\n}\n\ntwisty-player {\n width: 100%;\n min-height: 128px;\n height: 288px;\n resize: vertical;\n overflow-y: hidden;\n}\n\ntwisty-player + .heading {\n padding-top: 0.5em;\n}\n\ntwisty-alg-viewer {\n display: inline-block;\n}\n\n.wrapper {\n container-type: inline-size;\n}\n\n.scrollable-region {\n border-top: 1px solid rgba(0, 0, 0, 0.25);\n}\n\n.scrollable-region {\n max-height: 18em;\n overflow-y: auto;\n}\n\n@container (min-width: 512px) {\n .responsive-wrapper {\n display: grid;\n grid-template-columns: 1fr 1fr;\n }\n twisty-player {\n height: 320px\n }\n .scrollable-region {\n border-top: none;\n border-left: 1px solid rgba(0, 0, 0, 0.25);\n contain: strict;\n max-height: 100cqh;\n }\n}\n\n.wrapper:fullscreen,\n.wrapper:fullscreen .responsive-wrapper {\n width: 100%;\n height: 100%;\n}\n\n.wrapper:fullscreen twisty-player,\n.wrapper:fullscreen .scrollable-region {\n height: 50%;\n}\n\n@container (min-width: 512px) {\n .wrapper:fullscreen twisty-player,\n .wrapper:fullscreen .scrollable-region {\n height: 100%;\n }\n}\n\n/* TODO: dedup with Twizzle Editor */\n.move-count > span:hover:before {\n background-color: rgba(var(--heading-background), 1);\n color: rgba(var(--text-color), 1);\n backdrop-filter: blur(4px);\n z-index: 100;\n position: absolute;\n padding: 0.5em;\n top: 1.5em;\n right: 0;\n content: attr(data-before);\n white-space: pre-wrap;\n text-align: left;\n}\n\n.move-count > span:hover {\n color: rgba(var(--text-color), 1);\n cursor: help;\n}\n`,\n);\n\nexport const twizzleLinkForumTweaksCSS = new cssStyleSheetShim();\ntwizzleLinkForumTweaksCSS.replaceSync(`\n.wrapper {\n background: white;\n --heading-background: 232, 239, 253\n}\n\n.wrapper.dark-mode {\n --text-color: 236, 236, 236;\n --heading-background: 29, 29, 29;\n}\n\n.scrollable-region {\n overflow-y: auto;\n}\n\n.wrapper.dark-mode {\n background: #262626;\n --text-color: 142, 142, 142;\n border-color: #FFFFFF44;\n color-scheme: dark;\n}\n\n.wrapper.dark-mode .heading:not(.title) {\n background: #1d1d1d;\n}\n\n.heading.title {\n background: none;\n}\n`);\n", "import { EXPERIMENTAL_PROP_NO_VALUE } from \"../../../../cubing/twisty\";\nimport type {\n AlgProp,\n AlgWithIssues,\n} from \"../../../../cubing/twisty/model/props/puzzle/state/AlgProp\";\nimport type { TwistyPropSource } from \"../../../../cubing/twisty/model/props/TwistyProp\";\nimport type { TwistyPlayerModel } from \"../../../../cubing/twisty/model/TwistyPlayerModel\";\nimport {\n type TwistyPlayerAttribute,\n type TwistyPlayerConfig,\n twistyPlayerAttributeMap,\n} from \"../../../../cubing/twisty/views/TwistyPlayer\";\n\nfunction updateURL(url: URL): void {\n globalThis.history.replaceState(\"\", \"\", url.toString());\n}\n\n// TODO: Find a way to connect this to the `TwistyPlayer` constructor?\n\nexport type URLParamUpdaterOptions = {\n prefix?: string;\n};\n\nexport class URLParamUpdater {\n #prefix: string;\n constructor(model: TwistyPlayerModel, options?: URLParamUpdaterOptions) {\n this.#prefix = options?.prefix ?? \"\";\n\n this.listenToAlgProp(model.alg, \"alg\");\n this.listenToAlgProp(model.setupAlg, \"setup-alg\");\n this.listenToStringOrNullProp(\n model.twistySceneModel.stickeringRequest,\n \"stickering\",\n \"full\",\n );\n this.listenToStringSourceProp(model.setupAnchor, \"setup-anchor\");\n this.listenToStringOrNullProp(model.title, \"title\");\n this.listenToStringOrNoValueProp(\n model.puzzleIDRequest,\n \"puzzle\",\n EXPERIMENTAL_PROP_NO_VALUE,\n );\n this.listenToStringOrNoValueProp(\n model.puzzleDescriptionRequest,\n \"puzzle-description\",\n EXPERIMENTAL_PROP_NO_VALUE,\n );\n }\n\n // TODO: Cache parsed URL?\n setURLParam(\n unprefixedKey: string,\n value: string,\n defaultString: string,\n ): void {\n const prefixedKey = this.#prefix + unprefixedKey;\n const url = new URL(location.href);\n if (value === defaultString) {\n url.searchParams.delete(prefixedKey);\n } else {\n url.searchParams.set(prefixedKey, value);\n }\n updateURL(url);\n }\n\n listenToStringSourceProp<T extends string>(\n prop: TwistyPropSource<T>,\n key: string,\n defaultString?: T,\n ): void {\n void (async () => {\n const actualDefaultString =\n defaultString ?? (await prop.getDefaultValue()) ?? \"\"; // TODO\n prop.addFreshListener((s: string) => {\n this.setURLParam(key, s, actualDefaultString);\n });\n })();\n }\n\n listenToStringOrNullProp(\n prop: TwistyPropSource<string | null>,\n key: string,\n defaultString: string = \"\",\n ): void {\n prop.addFreshListener((s: string | null) => {\n this.setURLParam(key, s ?? defaultString, defaultString);\n });\n }\n\n listenToStringOrNoValueProp<T extends string>(\n prop: TwistyPropSource<T | typeof EXPERIMENTAL_PROP_NO_VALUE>,\n key: string,\n defaultString: T | typeof EXPERIMENTAL_PROP_NO_VALUE,\n ): void {\n prop.addFreshListener((s: string | typeof EXPERIMENTAL_PROP_NO_VALUE) => {\n if (s === EXPERIMENTAL_PROP_NO_VALUE) {\n s = defaultString;\n }\n if (s === EXPERIMENTAL_PROP_NO_VALUE) {\n this.setURLParam(key, \"\", \"\");\n } else {\n this.setURLParam(key, s, \"\"); // TODO\n }\n });\n }\n\n listenToAlgProp(prop: AlgProp, key: string): void {\n prop.addFreshListener((algWithIssues: AlgWithIssues) => {\n this.setURLParam(key, algWithIssues.alg.toString(), \"\");\n });\n }\n}\n\nexport function getConfigFromURL(\n prefix = \"\",\n url: string = location.href,\n): TwistyPlayerConfig {\n // TODO: Why does `Object.entries(paramMapping)` crash if this is defined elswhere?\n const paramMapping: Record<string, TwistyPlayerAttribute> = {\n alg: \"alg\",\n \"setup-alg\": \"experimental-setup-alg\",\n \"setup-anchor\": \"experimental-setup-anchor\",\n puzzle: \"puzzle\",\n stickering: \"experimental-stickering\",\n \"puzzle-description\": \"experimental-puzzle-description\",\n title: \"experimental-title\",\n \"video-url\": \"experimental-video-url\",\n competition: \"experimental-competition-id\",\n };\n\n const params = new URL(url).searchParams;\n const config: TwistyPlayerConfig = {};\n for (const [ourParam, twistyPlayerParam] of Object.entries(paramMapping)) {\n const paramValue = params.get(prefix + ourParam);\n if (paramValue !== null) {\n // TODO: type\n const configKey = twistyPlayerAttributeMap[twistyPlayerParam];\n (config as any)[configKey] = paramValue;\n }\n }\n return config;\n}\n\nexport function remapLegacyURLParams(\n mapping: Record<string, string | null>,\n): void {\n const url = new URL(location.href);\n for (const [oldKey, newKey] of Object.entries(mapping)) {\n // `null` indicates there is no new key, i.e. just drop the old key\n if (newKey !== null) {\n // The new key takes precedents, so we only remap the old key if the new key\n // is not already set.\n if (!url.searchParams.has(newKey)) {\n const value = url.searchParams.get(oldKey);\n if (value !== null) {\n url.searchParams.set(newKey, value);\n }\n }\n }\n url.searchParams.delete(oldKey);\n }\n updateURL(url);\n}\n", "import { Alg } from \"../../../alg\";\nimport {\n ExperimentalCommonMetric,\n experimentalCountMetricMoves,\n} from \"../../../notation\";\nimport { puzzles } from \"../../../puzzles\";\nimport { TwistyPlayer } from \"../..\";\nimport type { ColorSchemeWithAuto } from \"../../model/props/viewer/ColorSchemeRequestProp\";\nimport type { TwistyPlayerModel } from \"../../model/TwistyPlayerModel\";\nimport { ManagedCustomElement } from \"../ManagedCustomElement\";\nimport { customElementsShim } from \"../node-custom-element-shims\";\nimport { TwistyAlgViewer } from \"../TwistyAlgViewer\";\nimport { twizzleLinkCSS, twizzleLinkForumTweaksCSS } from \"./TwizzleLink.css\";\nimport { getConfigFromURL } from \"./url-params\";\n\n/** @category Other Custom Elements */\n\n// Non-breaking space\n// const NBSP = \"\\xa0\";\n\nconst OUTER_BLOCK_MOVES_EXPLANATION = \"outer block moves (e.g. R, Rw, or 4r)\";\nconst INNER_BLOCK_MOVES_EXPLANATION = \"inner block moves (e.g. M or 2-5r)\";\n\n// TODO: calculate descriptions from the cost factors directly.\nconst METRIC_EXPLANATIONS: Partial<Record<ExperimentalCommonMetric, string>> = {\n [ExperimentalCommonMetric.OuterBlockTurnMetric]: `HTM = OBTM (\"Outer Block Turn Metric\"):\n\u2022 ${INNER_BLOCK_MOVES_EXPLANATION} count as 2 turns\n\u2022 ${OUTER_BLOCK_MOVES_EXPLANATION} count as 1 turn\n\u2022 rotations (e.g. x) count as 0 turns`,\n [ExperimentalCommonMetric.OuterBlockQuantumTurnMetric]: `QTM = OBQTM (\"Outer Block Quantum Turn Metric\"):\n\u2022 ${INNER_BLOCK_MOVES_EXPLANATION} count as 2 turns per quantum (e.g. M2 counts as 4)\n\u2022 ${OUTER_BLOCK_MOVES_EXPLANATION} count as 1 turn per quantum (e.g. R2 counts as 2)\n\u2022 rotations (e.g. x) count as 0 turns`,\n [ExperimentalCommonMetric.RangeBlockTurnMetric]: `STM = RBTM (\"Range Block Turn Metric\"):\n\u2022 ${INNER_BLOCK_MOVES_EXPLANATION} count as 1 turn\n\u2022 ${OUTER_BLOCK_MOVES_EXPLANATION} count as 1 turn\n\u2022 rotations (e.g. x) count as 0 turns`,\n [ExperimentalCommonMetric.RangeBlockQuantumTurnMetric]: `SQTM = RBQTM (\"Range Block Quantum Turn Metric\"):\n\u2022 ${INNER_BLOCK_MOVES_EXPLANATION} count as 1 turn per quantum (e.g. M2 counts as 2)\n\u2022 ${OUTER_BLOCK_MOVES_EXPLANATION} count as 1 turn per quantum (e.g. R2 counts as 2)\n\u2022 rotations (e.g. x) count as 0 turns`,\n [ExperimentalCommonMetric.ExecutionTurnMetric]: `ETM (\"Execution Turn Metric\"):\n\u2022 all moves (including rotations) count as 1 turn`,\n};\n// const LEGACY_METRIC_ABBREVIATIONS: Partial<\n// Record<ExperimentalCommonMetric, string>\n// > = {\n// [ExperimentalCommonMetric.OuterBlockTurnMetric]: \"h\",\n// [ExperimentalCommonMetric.OuterBlockQuantumTurnMetric]: \"q\",\n// [ExperimentalCommonMetric.RangeBlockTurnMetric]: \"s\",\n// [ExperimentalCommonMetric.RangeBlockQuantumTurnMetric]: \"sq\",\n// [ExperimentalCommonMetric.ExecutionTurnMetric]: \"e\",\n// };\nconst CONSISTENT_METRIC_ABBREVIATIONS: Partial<\n Record<ExperimentalCommonMetric, string>\n> = {\n [ExperimentalCommonMetric.OuterBlockTurnMetric]: \"OB\",\n [ExperimentalCommonMetric.OuterBlockQuantumTurnMetric]: \"OBQ\",\n [ExperimentalCommonMetric.RangeBlockTurnMetric]: \"RB\",\n [ExperimentalCommonMetric.RangeBlockQuantumTurnMetric]: \"RBQ\",\n [ExperimentalCommonMetric.ExecutionTurnMetric]: \"E\",\n};\n\nexport class TwizzleLink extends ManagedCustomElement {\n twistyPlayer: TwistyPlayer | null = null;\n a: HTMLAnchorElement | null = null;\n constructor(\n private options?: {\n cdnForumTweaks?: boolean;\n colorScheme?: ColorSchemeWithAuto;\n },\n ) {\n super({ mode: \"open\" });\n }\n\n #fallback() {\n this.contentWrapper.textContent = \"\";\n if (this.a) {\n const span = this.contentWrapper.appendChild(\n document.createElement(\"span\"),\n );\n span.textContent = \"\u2757\uFE0F\";\n span.title = \"Could not show a player for link\";\n this.addElement(this.a);\n }\n this.removeCSS(twizzleLinkCSS);\n const cssIndex = this.shadow.adoptedStyleSheets.indexOf(twizzleLinkCSS);\n if (typeof cssIndex !== \"undefined\") {\n this.shadow.adoptedStyleSheets.splice(cssIndex, cssIndex + 1);\n }\n this.#cssCDNForumTweaksElem?.remove();\n }\n\n #cssCDNForumTweaksElem?: HTMLStyleElement;\n #scrollableRegion?: HTMLDivElement;\n #responsiveWrapper?: HTMLDivElement;\n #moveCountElem?: HTMLSpanElement;\n async connectedCallback() {\n this.#responsiveWrapper = this.addElement(document.createElement(\"div\"));\n this.#responsiveWrapper.classList.add(\"responsive-wrapper\");\n if (this.options?.colorScheme === \"dark\") {\n this.contentWrapper.classList.add(\"dark-mode\");\n }\n this.addCSS(twizzleLinkCSS);\n if (this.options?.cdnForumTweaks) {\n this.addCSS(twizzleLinkForumTweaksCSS);\n }\n this.a = this.querySelector(\"a\");\n if (!this.a) {\n return;\n }\n\n const config = getConfigFromURL(\"\", this.a.href);\n\n const href = this.a?.href;\n const { hostname, pathname } = new URL(href);\n\n if (hostname !== \"alpha.twizzle.net\") {\n this.#fallback();\n return;\n }\n if ([\"/edit/\", \"/explore/\"].includes(pathname)) {\n const isExplorer = pathname === \"/explore/\";\n\n if (config.puzzle && !(config.puzzle in puzzles)) {\n const puzzleDescription = (\n await import(\"../../../puzzle-geometry\")\n ).getPuzzleDescriptionString(config.puzzle);\n delete config.puzzle;\n config.experimentalPuzzleDescription = puzzleDescription;\n }\n\n this.twistyPlayer = this.#responsiveWrapper.appendChild(\n new TwistyPlayer({\n background: this.options?.cdnForumTweaks\n ? \"checkered-transparent\"\n : \"checkered\",\n colorScheme: this.options?.colorScheme === \"dark\" ? \"dark\" : \"light\",\n ...config,\n viewerLink: isExplorer ? \"experimental-twizzle-explorer\" : \"auto\",\n }),\n );\n this.twistyPlayer.fullscreenElement = this.contentWrapper;\n if (config.experimentalTitle) {\n this.twistyPlayer.experimentalTitle = config.experimentalTitle;\n }\n\n this.#scrollableRegion = this.#responsiveWrapper.appendChild(\n document.createElement(\"div\"),\n );\n this.#scrollableRegion.classList.add(\"scrollable-region\");\n\n if (config.experimentalTitle) {\n this.#addHeading(config.experimentalTitle).classList.add(\"title\");\n // const setupAlgDiv = this.addElement(document.createElement(\"div\"));\n // setupAlgDiv.classList.add(\"setup-alg\");\n // setupAlgDiv.textContent = puzzles[config.puzzle ?? \"3x3x3\"].fullName;\n }\n\n if (config.experimentalSetupAlg) {\n this.#addHeading(\n \"Setup\",\n async () =>\n (\n await this.twistyPlayer?.experimentalModel.setupAlg.get()\n )?.alg.toString() ?? null,\n );\n\n const setupAlgDiv = this.#scrollableRegion.appendChild(\n document.createElement(\"div\"),\n );\n setupAlgDiv.classList.add(\"setup-alg\");\n setupAlgDiv.textContent = new Alg(\n config.experimentalSetupAlg,\n ).toString();\n }\n const movesHeading = this.#addHeading(\n \"Moves\",\n async () =>\n (\n await this.twistyPlayer?.experimentalModel.alg.get()\n )?.alg.toString() ?? null,\n );\n\n this.#moveCountElem = movesHeading.appendChild(\n constructMoveCountDisplay(this.twistyPlayer.experimentalModel),\n );\n this.#moveCountElem.classList.add(\"move-count\");\n\n const twistyAlgViewer = this.#scrollableRegion.appendChild(\n new TwistyAlgViewer({ twistyPlayer: this.twistyPlayer }),\n );\n twistyAlgViewer.part.add(\"twisty-alg-viewer\");\n } else {\n this.#fallback();\n }\n }\n\n #addHeading(\n text: string,\n getTextToCopy?: () => Promise<string | null>,\n ): HTMLElement {\n const headingDiv = this.#scrollableRegion!.appendChild(\n document.createElement(\"div\"),\n );\n headingDiv.classList.add(\"heading\");\n // Wrapper span for grid layout.\n const wrapperSpan = headingDiv.appendChild(document.createElement(\"span\"));\n wrapperSpan.textContent = text;\n if (getTextToCopy) {\n wrapperSpan.textContent += \" \";\n const a = wrapperSpan.appendChild(document.createElement(\"a\"));\n a.textContent = \"\uD83D\uDCCB\";\n a.href = \"#\";\n a.title = \"Copy to clipboard\";\n async function setAndClear(text: string) {\n a.textContent = text;\n await new Promise((resolve) => setTimeout(resolve, 2000));\n if (a.textContent === text) {\n a.textContent = \"\uD83D\uDCCB\";\n }\n }\n a.addEventListener(\"click\", async (e) => {\n e.preventDefault();\n a.textContent = \"\uD83D\uDCCB\u2026\";\n const textToCopy = await getTextToCopy();\n if (textToCopy) {\n try {\n await navigator.clipboard.writeText(textToCopy);\n void setAndClear(\"\uD83D\uDCCB\u2705\");\n } catch (e) {\n void setAndClear(\"\uD83D\uDCCB\u274C\");\n throw e;\n }\n } else {\n void setAndClear(\"\uD83D\uDCCB\u274C\");\n }\n });\n }\n return headingDiv;\n }\n}\n\ncustomElementsShim.define(\"twizzle-link\", TwizzleLink);\ndeclare global {\n interface HTMLElementTagNameMap {\n \"twizzle-link\": TwizzleLink;\n }\n}\n\nexport function constructMoveCountDisplay(\n model: TwistyPlayerModel,\n elem: HTMLSpanElement = document.createElement(\"span\"),\n): HTMLSpanElement {\n async function update() {\n const [algWithIssues, puzzleLoader] = await Promise.all([\n model.puzzleAlg.get(),\n model.puzzleLoader.get(),\n ]);\n if (algWithIssues.issues.errors.length !== 0) {\n elem.textContent = \"\";\n return;\n }\n let isFirstMetric = true;\n function addMetric(metric: ExperimentalCommonMetric) {\n if (isFirstMetric) {\n isFirstMetric = false;\n } else {\n elem.append(\")(\");\n }\n const span = elem.appendChild(document.createElement(\"span\"));\n const moveCount = experimentalCountMetricMoves(\n puzzleLoader,\n metric,\n algWithIssues.alg,\n );\n span.append(`${CONSISTENT_METRIC_ABBREVIATIONS[metric]}: `);\n const moveNumber = span.appendChild(document.createElement(\"span\"));\n moveNumber.textContent = moveCount.toString();\n moveNumber.classList.add(\"move-number\");\n // span.title = METRIC_EXPLANATIONS[metric] ?? \"\";\n span.setAttribute(\"data-before\", METRIC_EXPLANATIONS[metric] ?? \"\");\n span.setAttribute(\"title\", METRIC_EXPLANATIONS[metric] ?? \"\");\n }\n\n elem.textContent = \"(\";\n if (puzzleLoader.id === \"3x3x3\") {\n addMetric(ExperimentalCommonMetric.OuterBlockTurnMetric);\n addMetric(ExperimentalCommonMetric.OuterBlockQuantumTurnMetric);\n addMetric(ExperimentalCommonMetric.RangeBlockTurnMetric);\n } else if (puzzleLoader.pg) {\n addMetric(ExperimentalCommonMetric.RangeBlockTurnMetric);\n addMetric(ExperimentalCommonMetric.RangeBlockQuantumTurnMetric);\n }\n addMetric(ExperimentalCommonMetric.ExecutionTurnMetric);\n elem.append(\")\");\n }\n model.puzzleAlg.addFreshListener(update);\n model.puzzleID.addFreshListener(update);\n return elem;\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["r", "puzzleLoader", "ThreeRaycaster", "ThreeVector2", "ThreePerspectiveCamera", "ThreeScene", "fullStickeringMask", "text", "e"]
7
7
  }