cubing 0.20.2 → 0.21.0-pre12

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 (770) hide show
  1. package/README.md +6 -9
  2. package/dist/.DS_Store +0 -0
  3. package/dist/bin/puzzle-geometry-bin.js +1124 -1128
  4. package/dist/bin/puzzle-geometry-bin.js.map +3 -3
  5. package/dist/bundle-global/cubing.bundle-global.js +3978 -3587
  6. package/dist/esm/.DS_Store +0 -0
  7. package/dist/esm/{2x2x2.kpuzzle.json_-ZLJSYD5K.js → 2x2x2.kpuzzle.json-JOGUSQ4N.js} +3 -3
  8. package/dist/esm/{2x2x2.kpuzzle.json_-ZLJSYD5K.js.map → 2x2x2.kpuzzle.json-JOGUSQ4N.js.map} +1 -1
  9. package/dist/esm/{2x2x2.kpuzzle.svg-BNXPAM3A.js → 2x2x2.kpuzzle.svg-CQF2FTV7.js} +2 -2
  10. package/dist/esm/{2x2x2.kpuzzle.svg-BNXPAM3A.js.map → 2x2x2.kpuzzle.svg-CQF2FTV7.js.map} +0 -0
  11. package/dist/esm/3d-JZD3V366.js +39 -0
  12. package/dist/esm/3d-JZD3V366.js.map +7 -0
  13. package/dist/esm/{3x3x3-ll.kpuzzle.svg-EC42JHOH.js → 3x3x3-ll.kpuzzle.svg-53CBPG5O.js} +2 -2
  14. package/dist/esm/{3x3x3-ll.kpuzzle.svg-EC42JHOH.js.map → 3x3x3-ll.kpuzzle.svg-53CBPG5O.js.map} +0 -0
  15. package/dist/esm/{3x3x3.kpuzzle.svg-DUKG2WHC.js → 3x3x3.kpuzzle.svg-ERSSH66P.js} +2 -2
  16. package/dist/esm/{3x3x3.kpuzzle.svg-DUKG2WHC.js.map → 3x3x3.kpuzzle.svg-ERSSH66P.js.map} +0 -0
  17. package/dist/esm/alg/index.js +2 -2
  18. package/dist/esm/bluetooth/index.js +13 -11
  19. package/dist/esm/bluetooth/index.js.map +2 -2
  20. package/dist/esm/chunk-5DN4DAAX.js +2512 -0
  21. package/dist/esm/chunk-5DN4DAAX.js.map +7 -0
  22. package/dist/esm/{chunk-KKSDHNLH.js → chunk-7GADUDIG.js} +49 -71
  23. package/dist/esm/chunk-7GADUDIG.js.map +7 -0
  24. package/dist/esm/{chunk-YNB7QLBF.js → chunk-BU5PUJK3.js} +9 -10
  25. package/dist/esm/chunk-BU5PUJK3.js.map +7 -0
  26. package/dist/esm/chunk-CQS6JZ7G.js +762 -0
  27. package/dist/esm/chunk-CQS6JZ7G.js.map +7 -0
  28. package/dist/esm/{chunk-2GRKPQQL.js → chunk-RE7MIN5R.js} +2 -2
  29. package/dist/esm/{chunk-2GRKPQQL.js.map → chunk-RE7MIN5R.js.map} +0 -0
  30. package/dist/esm/{chunk-WJ7AVUI7.js → chunk-WO2AXYFE.js} +12 -1
  31. package/dist/esm/{chunk-WJ7AVUI7.js.map → chunk-WO2AXYFE.js.map} +0 -0
  32. package/dist/esm/{chunk-CWVB5RRW.js → chunk-YV3RT5PX.js} +625 -1282
  33. package/dist/esm/chunk-YV3RT5PX.js.map +7 -0
  34. package/dist/esm/{clock.kpuzzle.json_-PXORG6YF.js → clock.kpuzzle.json-EKWRMHJM.js} +3 -3
  35. package/dist/esm/{clock.kpuzzle.json_-PXORG6YF.js.map → clock.kpuzzle.json-EKWRMHJM.js.map} +1 -1
  36. package/dist/esm/{clock.kpuzzle.svg-E52B5OQV.js → clock.kpuzzle.svg-B7TMN3SY.js} +2 -2
  37. package/dist/esm/{clock.kpuzzle.svg-E52B5OQV.js.map → clock.kpuzzle.svg-B7TMN3SY.js.map} +0 -0
  38. package/dist/esm/esm-test-worker.js +2 -2
  39. package/dist/esm/esm-test-worker.js.map +1 -1
  40. package/dist/esm/kpuzzle/index.js +5 -3
  41. package/dist/esm/{node-SIGYKAZG.js → node-BSAQKO3G.js} +2 -2
  42. package/dist/esm/{node-SIGYKAZG.js.map → node-BSAQKO3G.js.map} +0 -0
  43. package/dist/esm/{node-BHGOVUN3.js → node-WEHVBEKP.js} +2 -2
  44. package/dist/esm/{node-BHGOVUN3.js.map → node-WEHVBEKP.js.map} +0 -0
  45. package/dist/esm/notation/index.js +3 -3
  46. package/dist/esm/protocol/index.js +3 -3
  47. package/dist/esm/puzzle-geometry/index.js +1085 -1179
  48. package/dist/esm/puzzle-geometry/index.js.map +3 -3
  49. package/dist/esm/puzzles/index.js +10 -4
  50. package/dist/esm/{pyraminx.kpuzzle.svg-QKUJX37T.js → pyraminx.kpuzzle.svg-QBBMZVDY.js} +2 -2
  51. package/dist/esm/{pyraminx.kpuzzle.svg-QKUJX37T.js.map → pyraminx.kpuzzle.svg-QBBMZVDY.js.map} +0 -0
  52. package/dist/esm/scramble/index.js +5 -4
  53. package/dist/esm/search/index.js +7 -4
  54. package/dist/esm/{sq1-hyperorbit.kpuzzle.json_-7KW5LSXC.js → sq1-hyperorbit.kpuzzle.json-N3FGCPML.js} +3 -3
  55. package/dist/esm/{sq1-hyperorbit.kpuzzle.json_-7KW5LSXC.js.map → sq1-hyperorbit.kpuzzle.json-N3FGCPML.js.map} +1 -1
  56. package/dist/esm/{sq1-hyperorbit.kpuzzle.svg-7Y7N37NN.js → sq1-hyperorbit.kpuzzle.svg-ID57EER7.js} +2 -2
  57. package/dist/esm/{sq1-hyperorbit.kpuzzle.svg-7Y7N37NN.js.map → sq1-hyperorbit.kpuzzle.svg-ID57EER7.js.map} +0 -0
  58. package/dist/esm/stream/index.js +3 -3
  59. package/dist/esm/stream/index.js.map +2 -2
  60. package/dist/esm/twisty/index.js +4442 -3214
  61. package/dist/esm/twisty/index.js.map +3 -3
  62. package/dist/esm/worker-inside-generated-string-KDZOUGJF.js +2831 -0
  63. package/dist/esm/worker-inside-generated-string-KDZOUGJF.js.map +7 -0
  64. package/dist/types/alg/Alg.d.ts +88 -0
  65. package/dist/types/alg/Alg.d.ts.map +1 -1
  66. package/dist/types/alg/Alg.spec.d.ts +2 -0
  67. package/dist/types/alg/Alg.spec.d.ts.map +1 -0
  68. package/dist/types/alg/common.d.ts.map +1 -1
  69. package/dist/types/alg/operation.spec.d.ts +2 -0
  70. package/dist/types/alg/operation.spec.d.ts.map +1 -0
  71. package/dist/types/alg/parse.spec.d.ts +2 -0
  72. package/dist/types/alg/parse.spec.d.ts.map +1 -0
  73. package/dist/types/alg/test/alg-comparison.d.ts.map +1 -1
  74. package/dist/types/alg/test/alg.spec.d.ts +2 -0
  75. package/dist/types/alg/test/alg.spec.d.ts.map +1 -0
  76. package/dist/types/alg/units/leaves/LineComment.spec.d.ts +2 -0
  77. package/dist/types/alg/units/leaves/LineComment.spec.d.ts.map +1 -0
  78. package/dist/types/alg/units/leaves/Move.spec.d.ts +2 -0
  79. package/dist/types/alg/units/leaves/Move.spec.d.ts.map +1 -0
  80. package/dist/types/alg/url.spec.d.ts +2 -0
  81. package/dist/types/alg/url.spec.d.ts.map +1 -0
  82. package/dist/types/bluetooth/smart-puzzle/bluetooth-puzzle.d.ts +1 -1
  83. package/dist/types/bluetooth/smart-puzzle/bluetooth-puzzle.d.ts.map +1 -1
  84. package/dist/types/bluetooth/smart-puzzle/giiker.spec.d.ts +5 -0
  85. package/dist/types/bluetooth/smart-puzzle/giiker.spec.d.ts.map +1 -0
  86. package/dist/types/kpuzzle/3x3x3/3x3x3.kpuzzle.json.d.ts +3 -0
  87. package/dist/types/kpuzzle/3x3x3/3x3x3.kpuzzle.json.d.ts.map +1 -0
  88. package/dist/types/kpuzzle/3x3x3/3x3x3.kpuzzle.json.spec.d.ts +2 -0
  89. package/dist/types/kpuzzle/3x3x3/3x3x3.kpuzzle.json.spec.d.ts.map +1 -0
  90. package/dist/types/kpuzzle/canon.spec.d.ts +2 -0
  91. package/dist/types/kpuzzle/canon.spec.d.ts.map +1 -0
  92. package/dist/types/kpuzzle/index.d.ts +1 -0
  93. package/dist/types/kpuzzle/index.d.ts.map +1 -1
  94. package/dist/types/kpuzzle/kpuzzle.spec.d.ts +2 -0
  95. package/dist/types/kpuzzle/kpuzzle.spec.d.ts.map +1 -0
  96. package/dist/types/kpuzzle/prunetable.spec.d.ts +2 -0
  97. package/dist/types/kpuzzle/prunetable.spec.d.ts.map +1 -0
  98. package/dist/types/kpuzzle/svg.d.ts.map +1 -1
  99. package/dist/types/kpuzzle/transformations.spec.d.ts +2 -0
  100. package/dist/types/kpuzzle/transformations.spec.d.ts.map +1 -0
  101. package/dist/types/protocol/binary/binary3x3x3.spec.d.ts +2 -0
  102. package/dist/types/protocol/binary/binary3x3x3.spec.d.ts.map +1 -0
  103. package/dist/types/protocol/binary/hex.spec.d.ts +2 -0
  104. package/dist/types/protocol/binary/hex.spec.d.ts.map +1 -0
  105. package/dist/types/protocol/binary/orbit-indexing.spec.d.ts +2 -0
  106. package/dist/types/protocol/binary/orbit-indexing.spec.d.ts.map +1 -0
  107. package/dist/types/puzzle-geometry/Options.d.ts +45 -1
  108. package/dist/types/puzzle-geometry/Options.d.ts.map +1 -1
  109. package/dist/types/puzzle-geometry/PGPuzzles.spec.d.ts +2 -0
  110. package/dist/types/puzzle-geometry/PGPuzzles.spec.d.ts.map +1 -0
  111. package/dist/types/puzzle-geometry/PermOriSet.d.ts +39 -39
  112. package/dist/types/puzzle-geometry/PermOriSet.d.ts.map +1 -1
  113. package/dist/types/puzzle-geometry/PuzzleGeometry.d.ts +118 -110
  114. package/dist/types/puzzle-geometry/PuzzleGeometry.d.ts.map +1 -1
  115. package/dist/types/puzzle-geometry/Quat.d.ts +0 -11
  116. package/dist/types/puzzle-geometry/Quat.d.ts.map +1 -1
  117. package/dist/types/puzzle-geometry/Quat.spec.d.ts +2 -0
  118. package/dist/types/puzzle-geometry/Quat.spec.d.ts.map +1 -0
  119. package/dist/types/puzzle-geometry/SchreierSims.d.ts.map +1 -1
  120. package/dist/types/puzzle-geometry/index.d.ts +2 -4
  121. package/dist/types/puzzle-geometry/index.d.ts.map +1 -1
  122. package/dist/types/puzzle-geometry/interfaces.d.ts +1 -21
  123. package/dist/types/puzzle-geometry/interfaces.d.ts.map +1 -1
  124. package/dist/types/puzzle-geometry/orientcenters.spec.d.ts +2 -0
  125. package/dist/types/puzzle-geometry/orientcenters.spec.d.ts.map +1 -0
  126. package/dist/types/puzzles/async/async-pg3d.d.ts.map +1 -1
  127. package/dist/types/puzzles/customPGPuzzleLoader.d.ts +12 -0
  128. package/dist/types/puzzles/customPGPuzzleLoader.d.ts.map +1 -0
  129. package/dist/types/puzzles/implementations/2x2x2/{2x2x2.kpuzzle.json_.d.ts → 2x2x2.kpuzzle.json.d.ts} +1 -1
  130. package/dist/types/puzzles/implementations/2x2x2/2x2x2.kpuzzle.json.d.ts.map +1 -0
  131. package/dist/types/puzzles/implementations/3x3x3/index.d.ts.map +1 -1
  132. package/dist/types/puzzles/implementations/clock/{clock.kpuzzle.json_.d.ts → clock.kpuzzle.json.d.ts} +1 -1
  133. package/dist/types/puzzles/implementations/clock/clock.kpuzzle.json.d.ts.map +1 -0
  134. package/dist/types/puzzles/implementations/fto/index.d.ts +2 -2
  135. package/dist/types/puzzles/implementations/fto/index.d.ts.map +1 -1
  136. package/dist/types/puzzles/implementations/pyraminx/{pyraminx.kpuzzle.json_.d.ts → pyraminx.kpuzzle.json.d.ts} +1 -1
  137. package/dist/types/puzzles/implementations/pyraminx/pyraminx.kpuzzle.json.d.ts.map +1 -0
  138. package/dist/types/puzzles/implementations/square1/index.d.ts.map +1 -1
  139. package/dist/types/puzzles/implementations/square1/{sq1-hyperorbit.kpuzzle.json_.d.ts → sq1-hyperorbit.kpuzzle.json.d.ts} +1 -1
  140. package/dist/types/puzzles/implementations/square1/sq1-hyperorbit.kpuzzle.json.d.ts.map +1 -0
  141. package/dist/types/puzzles/index.d.ts +4 -2
  142. package/dist/types/puzzles/index.d.ts.map +1 -1
  143. package/dist/types/puzzles/stickerings/appearance.d.ts +9 -9
  144. package/dist/types/puzzles/stickerings/appearance.d.ts.map +1 -1
  145. package/dist/types/puzzles/stickerings/cube-stickerings.d.ts.map +1 -1
  146. package/dist/types/puzzles/stickerings/fto-stickerings.d.ts.map +1 -1
  147. package/dist/types/puzzles/stickerings/global-custom-stickering-hack.d.ts +3 -0
  148. package/dist/types/puzzles/stickerings/global-custom-stickering-hack.d.ts.map +1 -0
  149. package/dist/types/search/index.d.ts +1 -1
  150. package/dist/types/search/index.d.ts.map +1 -1
  151. package/dist/types/search/inside/api.d.ts +2 -1
  152. package/dist/types/search/inside/api.d.ts.map +1 -1
  153. package/dist/types/search/inside/api.spec.d.ts +2 -0
  154. package/dist/types/search/inside/api.spec.d.ts.map +1 -0
  155. package/dist/types/search/inside/solve/parseSGS.d.ts.map +1 -1
  156. package/dist/types/search/inside/solve/puzzles/3x3x3/filter.d.ts.map +1 -1
  157. package/dist/types/search/inside/solve/puzzles/3x3x3/index.d.ts.map +1 -1
  158. package/dist/types/search/inside/solve/puzzles/megaminx.sgs.json.d.ts.map +1 -1
  159. package/dist/types/search/inside/solve/puzzles/sgs-defs.spec.d.ts +2 -0
  160. package/dist/types/search/inside/solve/puzzles/sgs-defs.spec.d.ts.map +1 -0
  161. package/dist/types/search/inside/solve/puzzles/skewb.sgs.json.d.ts.map +1 -1
  162. package/dist/types/search/inside/solve/tremble.d.ts.map +1 -1
  163. package/dist/types/search/inside/solve/vendor/cstimer/src/js/lib/mathlib.d.ts +4 -31
  164. package/dist/types/search/inside/solve/vendor/cstimer/src/js/lib/mathlib.d.ts.map +1 -1
  165. package/dist/types/search/inside/solve/vendor/cstimer/src/js/scramble/scramble_444.d.ts.map +1 -1
  166. package/dist/types/search/inside/solve/vendor/min2phase/gwt.d.ts +3 -0
  167. package/dist/types/search/inside/solve/vendor/min2phase/gwt.d.ts.map +1 -0
  168. package/dist/types/search/inside/solve/vendor/random-uint-below/get-random-values.d.ts.map +1 -1
  169. package/dist/types/search/inside/solve/vendor/random-uint-below/random-int.d.ts.map +1 -1
  170. package/dist/types/search/inside/solve/vendor/sq12phase/scramble_sq1.d.ts.map +1 -1
  171. package/dist/types/search/instantiator.d.ts.map +1 -1
  172. package/dist/types/search/outside.d.ts +4 -2
  173. package/dist/types/search/outside.d.ts.map +1 -1
  174. package/dist/types/search/worker-inside-generated-string.d.ts +1 -1
  175. package/dist/types/search/worker-inside-generated-string.d.ts.map +1 -1
  176. package/dist/types/stream/twizzle/TwizzleStream.d.ts +9 -8
  177. package/dist/types/stream/twizzle/TwizzleStream.d.ts.map +1 -1
  178. package/dist/types/stream/websocket-proxy.d.ts +1 -1
  179. package/dist/types/stream/websocket-proxy.d.ts.map +1 -1
  180. package/dist/types/twisty/controllers/TwistyAnimationController.d.ts +34 -0
  181. package/dist/types/twisty/controllers/TwistyAnimationController.d.ts.map +1 -0
  182. package/dist/types/twisty/controllers/TwistyPlayerController.d.ts +16 -0
  183. package/dist/types/twisty/controllers/TwistyPlayerController.d.ts.map +1 -0
  184. package/dist/types/twisty/heavy-code-imports/3d.d.ts +3 -0
  185. package/dist/types/twisty/heavy-code-imports/3d.d.ts.map +1 -0
  186. package/dist/types/twisty/heavy-code-imports/dynamic-entries/3d.d.ts +12 -0
  187. package/dist/types/twisty/heavy-code-imports/dynamic-entries/3d.d.ts.map +1 -0
  188. package/dist/types/twisty/index.d.ts +20 -15
  189. package/dist/types/twisty/index.d.ts.map +1 -1
  190. package/dist/types/twisty/model/PromiseFreshener.d.ts +14 -0
  191. package/dist/types/twisty/model/PromiseFreshener.d.ts.map +1 -0
  192. package/dist/types/twisty/model/TwistyPlayerModel.d.ts +84 -0
  193. package/dist/types/twisty/model/TwistyPlayerModel.d.ts.map +1 -0
  194. package/dist/types/twisty/model/UserVisibleErrorTracker.d.ts +11 -0
  195. package/dist/types/twisty/model/UserVisibleErrorTracker.d.ts.map +1 -0
  196. package/dist/types/twisty/model/helpers.d.ts +5 -0
  197. package/dist/types/twisty/model/helpers.d.ts.map +1 -0
  198. package/dist/types/twisty/model/props/TwistyProp.d.ts +60 -0
  199. package/dist/types/twisty/model/props/TwistyProp.d.ts.map +1 -0
  200. package/dist/types/twisty/model/props/TwistyProp.spec.d.ts +5 -0
  201. package/dist/types/twisty/model/props/TwistyProp.spec.d.ts.map +1 -0
  202. package/dist/types/twisty/model/props/TwistyPropDebugger.d.ts +28 -0
  203. package/dist/types/twisty/model/props/TwistyPropDebugger.d.ts.map +1 -0
  204. package/dist/types/twisty/model/props/general/URLProp.d.ts +6 -0
  205. package/dist/types/twisty/model/props/general/URLProp.d.ts.map +1 -0
  206. package/dist/types/twisty/model/props/puzzle/display/HintFaceletProp.d.ts +7 -0
  207. package/dist/types/twisty/model/props/puzzle/display/HintFaceletProp.d.ts.map +1 -0
  208. package/dist/types/twisty/model/props/puzzle/display/SpriteProp.d.ts +10 -0
  209. package/dist/types/twisty/model/props/puzzle/display/SpriteProp.d.ts.map +1 -0
  210. package/dist/types/twisty/model/props/puzzle/display/StickeringProp.d.ts +6 -0
  211. package/dist/types/twisty/model/props/puzzle/display/StickeringProp.d.ts.map +1 -0
  212. package/dist/types/twisty/model/props/puzzle/state/AlgProp.d.ts +27 -0
  213. package/dist/types/twisty/model/props/puzzle/state/AlgProp.d.ts.map +1 -0
  214. package/dist/types/twisty/model/props/puzzle/state/AlgTransformationProp.d.ts +14 -0
  215. package/dist/types/twisty/model/props/puzzle/state/AlgTransformationProp.d.ts.map +1 -0
  216. package/dist/types/twisty/model/props/puzzle/state/AnchoredStartProp.d.ts +15 -0
  217. package/dist/types/twisty/model/props/puzzle/state/AnchoredStartProp.d.ts.map +1 -0
  218. package/dist/types/twisty/model/props/puzzle/state/CurrentLeavesProp.d.ts +12 -0
  219. package/dist/types/twisty/model/props/puzzle/state/CurrentLeavesProp.d.ts.map +1 -0
  220. package/dist/types/twisty/model/props/puzzle/state/CurrentLeavesSimplified.d.ts +17 -0
  221. package/dist/types/twisty/model/props/puzzle/state/CurrentLeavesSimplified.d.ts.map +1 -0
  222. package/dist/types/twisty/model/props/puzzle/state/CurrentTransformationProp.d.ts +15 -0
  223. package/dist/types/twisty/model/props/puzzle/state/CurrentTransformationProp.d.ts.map +1 -0
  224. package/dist/types/twisty/model/props/puzzle/state/IndexerConstructorProp.d.ts +17 -0
  225. package/dist/types/twisty/model/props/puzzle/state/IndexerConstructorProp.d.ts.map +1 -0
  226. package/dist/types/twisty/model/props/puzzle/state/IndexerConstructorRequestProp.d.ts +12 -0
  227. package/dist/types/twisty/model/props/puzzle/state/IndexerConstructorRequestProp.d.ts.map +1 -0
  228. package/dist/types/twisty/model/props/puzzle/state/IndexerProp.d.ts +15 -0
  229. package/dist/types/twisty/model/props/puzzle/state/IndexerProp.d.ts.map +1 -0
  230. package/dist/types/twisty/model/props/puzzle/state/LegacyPositionProp.d.ts +12 -0
  231. package/dist/types/twisty/model/props/puzzle/state/LegacyPositionProp.d.ts.map +1 -0
  232. package/dist/types/twisty/model/props/puzzle/state/PuzzleAlgProp.d.ts +13 -0
  233. package/dist/types/twisty/model/props/puzzle/state/PuzzleAlgProp.d.ts.map +1 -0
  234. package/dist/types/twisty/model/props/puzzle/state/SetupAnchorProp.d.ts +6 -0
  235. package/dist/types/twisty/model/props/puzzle/state/SetupAnchorProp.d.ts.map +1 -0
  236. package/dist/types/twisty/model/props/puzzle/structure/PuzzleDefProp.d.ts +11 -0
  237. package/dist/types/twisty/model/props/puzzle/structure/PuzzleDefProp.d.ts.map +1 -0
  238. package/dist/types/twisty/model/props/puzzle/structure/PuzzleDescriptionProp.d.ts +6 -0
  239. package/dist/types/twisty/model/props/puzzle/structure/PuzzleDescriptionProp.d.ts.map +1 -0
  240. package/dist/types/twisty/model/props/puzzle/structure/PuzzleIDProp.d.ts +11 -0
  241. package/dist/types/twisty/model/props/puzzle/structure/PuzzleIDProp.d.ts.map +1 -0
  242. package/dist/types/twisty/model/props/puzzle/structure/PuzzleIDRequestProp.d.ts +6 -0
  243. package/dist/types/twisty/model/props/puzzle/structure/PuzzleIDRequestProp.d.ts.map +1 -0
  244. package/dist/types/twisty/model/props/puzzle/structure/PuzzleLoaderProp.d.ts +13 -0
  245. package/dist/types/twisty/model/props/puzzle/structure/PuzzleLoaderProp.d.ts.map +1 -0
  246. package/dist/types/twisty/model/props/timeline/CoarseTimelineInfoProp.d.ts +25 -0
  247. package/dist/types/twisty/model/props/timeline/CoarseTimelineInfoProp.d.ts.map +1 -0
  248. package/dist/types/twisty/model/props/timeline/DetailedTimelineInfoProp.d.ts +23 -0
  249. package/dist/types/twisty/model/props/timeline/DetailedTimelineInfoProp.d.ts.map +1 -0
  250. package/dist/types/twisty/model/props/timeline/PlayingInfoProp.d.ts +15 -0
  251. package/dist/types/twisty/model/props/timeline/PlayingInfoProp.d.ts.map +1 -0
  252. package/dist/types/twisty/model/props/timeline/TempoScaleProp.d.ts +6 -0
  253. package/dist/types/twisty/model/props/timeline/TempoScaleProp.d.ts.map +1 -0
  254. package/dist/types/twisty/model/props/timeline/TimestampRequestProp.d.ts +16 -0
  255. package/dist/types/twisty/model/props/timeline/TimestampRequestProp.d.ts.map +1 -0
  256. package/dist/types/twisty/model/props/viewer/BackViewProp.d.ts +7 -0
  257. package/dist/types/twisty/model/props/viewer/BackViewProp.d.ts.map +1 -0
  258. package/dist/types/twisty/model/props/viewer/BackgroundProp.d.ts +7 -0
  259. package/dist/types/twisty/model/props/viewer/BackgroundProp.d.ts.map +1 -0
  260. package/dist/types/twisty/model/props/viewer/ButtonAppearanceProp.d.ts +22 -0
  261. package/dist/types/twisty/model/props/viewer/ButtonAppearanceProp.d.ts.map +1 -0
  262. package/dist/types/twisty/model/props/viewer/ControlPanelProp.d.ts +7 -0
  263. package/dist/types/twisty/model/props/viewer/ControlPanelProp.d.ts.map +1 -0
  264. package/dist/types/twisty/model/props/viewer/LatitudeLimit.d.ts +6 -0
  265. package/dist/types/twisty/model/props/viewer/LatitudeLimit.d.ts.map +1 -0
  266. package/dist/types/twisty/model/props/viewer/OrbitCoordinatesProp.d.ts +16 -0
  267. package/dist/types/twisty/model/props/viewer/OrbitCoordinatesProp.d.ts.map +1 -0
  268. package/dist/types/twisty/model/props/viewer/OrbitCoordinatesRequestProp.d.ts +15 -0
  269. package/dist/types/twisty/model/props/viewer/OrbitCoordinatesRequestProp.d.ts.map +1 -0
  270. package/dist/types/twisty/model/props/viewer/TimeRangeProp.d.ts +11 -0
  271. package/dist/types/twisty/model/props/viewer/TimeRangeProp.d.ts.map +1 -0
  272. package/dist/types/twisty/model/props/viewer/ViewerLinkProp.d.ts +7 -0
  273. package/dist/types/twisty/model/props/viewer/ViewerLinkProp.d.ts.map +1 -0
  274. package/dist/types/twisty/model/props/viewer/VisualizationProp.d.ts +7 -0
  275. package/dist/types/twisty/model/props/viewer/VisualizationProp.d.ts.map +1 -0
  276. package/dist/types/twisty/model/props/viewer/VisualizationStrategyProp.d.ts +13 -0
  277. package/dist/types/twisty/model/props/viewer/VisualizationStrategyProp.d.ts.map +1 -0
  278. package/dist/types/twisty/{animation → old/animation}/RenderScheduler.d.ts +3 -0
  279. package/dist/types/twisty/old/animation/RenderScheduler.d.ts.map +1 -0
  280. package/dist/types/twisty/{animation → old/animation}/Timeline.d.ts +0 -0
  281. package/dist/types/twisty/old/animation/Timeline.d.ts.map +1 -0
  282. package/dist/types/twisty/{animation → old/animation}/cursor/AlgCursor.d.ts +4 -4
  283. package/dist/types/twisty/old/animation/cursor/AlgCursor.d.ts.map +1 -0
  284. package/dist/types/twisty/{animation → old/animation}/cursor/CursorTypes.d.ts +4 -4
  285. package/dist/types/twisty/old/animation/cursor/CursorTypes.d.ts.map +1 -0
  286. package/dist/types/twisty/{animation → old/animation}/easing.d.ts +0 -0
  287. package/dist/types/twisty/old/animation/easing.d.ts.map +1 -0
  288. package/dist/types/twisty/{animation → old/animation}/indexer/AlgDuration.d.ts +1 -1
  289. package/dist/types/twisty/old/animation/indexer/AlgDuration.d.ts.map +1 -0
  290. package/dist/types/twisty/old/animation/indexer/AlgIndexer.d.ts +36 -0
  291. package/dist/types/twisty/old/animation/indexer/AlgIndexer.d.ts.map +1 -0
  292. package/dist/types/twisty/{animation → old/animation}/indexer/SimpleAlgIndexer.d.ts +3 -3
  293. package/dist/types/twisty/old/animation/indexer/SimpleAlgIndexer.d.ts.map +1 -0
  294. package/dist/types/twisty/{animation → old/animation}/indexer/simultaneous-moves/SimultaneousMoveIndexer.d.ts +6 -5
  295. package/dist/types/twisty/old/animation/indexer/simultaneous-moves/SimultaneousMoveIndexer.d.ts.map +1 -0
  296. package/dist/types/twisty/old/animation/indexer/simultaneous-moves/SimultaneousMoveIndexerV2.d.ts +22 -0
  297. package/dist/types/twisty/old/animation/indexer/simultaneous-moves/SimultaneousMoveIndexerV2.d.ts.map +1 -0
  298. package/dist/types/twisty/old/animation/indexer/simultaneous-moves/simul-moves.d.ts +26 -0
  299. package/dist/types/twisty/old/animation/indexer/simultaneous-moves/simul-moves.d.ts.map +1 -0
  300. package/dist/types/twisty/{animation → old/animation}/indexer/tree/AlgWalker.d.ts +2 -2
  301. package/dist/types/twisty/old/animation/indexer/tree/AlgWalker.d.ts.map +1 -0
  302. package/dist/types/twisty/{animation → old/animation}/indexer/tree/TreeAlgIndexer.d.ts +3 -3
  303. package/dist/types/twisty/old/animation/indexer/tree/TreeAlgIndexer.d.ts.map +1 -0
  304. package/dist/types/twisty/old/animation/indexer/tree/chunkAlgs.d.ts +3 -0
  305. package/dist/types/twisty/old/animation/indexer/tree/chunkAlgs.d.ts.map +1 -0
  306. package/dist/types/twisty/{animation → old/animation}/stream/timeline-move-calculation-draft.d.ts +1 -1
  307. package/dist/types/twisty/old/animation/stream/timeline-move-calculation-draft.d.ts.map +1 -0
  308. package/dist/types/twisty/{dom/TwistyAlgViewer.css_.d.ts → old/dom/TwistyAlgViewerV1.css.d.ts} +1 -1
  309. package/dist/types/twisty/old/dom/TwistyAlgViewerV1.css.d.ts.map +1 -0
  310. package/dist/types/twisty/old/dom/TwistyAlgViewerV1.d.ts +52 -0
  311. package/dist/types/twisty/old/dom/TwistyAlgViewerV1.d.ts.map +1 -0
  312. package/dist/types/twisty/{dom/TwistyPlayer.css_.d.ts → old/dom/TwistyPlayer.css.d.ts} +1 -1
  313. package/dist/types/twisty/old/dom/TwistyPlayer.css.d.ts.map +1 -0
  314. package/dist/types/twisty/{dom → old/dom}/TwistyPlayer.d.ts +8 -8
  315. package/dist/types/twisty/old/dom/TwistyPlayer.d.ts.map +1 -0
  316. package/dist/types/twisty/old/dom/TwistyPlayer.spec.d.ts +5 -0
  317. package/dist/types/twisty/old/dom/TwistyPlayer.spec.d.ts.map +1 -0
  318. package/dist/types/twisty/{dom → old/dom}/TwistyPlayerConfig.d.ts +10 -5
  319. package/dist/types/twisty/old/dom/TwistyPlayerConfig.d.ts.map +1 -0
  320. package/dist/types/twisty/old/dom/controls/TwistyControlElement.d.ts +2 -0
  321. package/dist/types/twisty/old/dom/controls/TwistyControlElement.d.ts.map +1 -0
  322. package/dist/types/twisty/{dom/controls/TwistyScrubber.css_.d.ts → old/dom/controls/TwistyScrubber.css.d.ts} +1 -1
  323. package/dist/types/twisty/old/dom/controls/TwistyScrubber.css.d.ts.map +1 -0
  324. package/dist/types/twisty/{dom → old/dom}/controls/TwistyScrubber.d.ts +1 -1
  325. package/dist/types/twisty/old/dom/controls/TwistyScrubber.d.ts.map +1 -0
  326. package/dist/types/twisty/{dom/controls/buttons.css_.d.ts → old/dom/controls/buttons.css.d.ts} +1 -1
  327. package/dist/types/twisty/old/dom/controls/buttons.css.d.ts.map +1 -0
  328. package/dist/types/twisty/{dom → old/dom}/controls/buttons.d.ts +1 -1
  329. package/dist/types/twisty/old/dom/controls/buttons.d.ts.map +1 -0
  330. package/dist/types/twisty/old/dom/controls/buttons.spec.d.ts +5 -0
  331. package/dist/types/twisty/old/dom/controls/buttons.spec.d.ts.map +1 -0
  332. package/dist/types/twisty/{dom → old/dom}/element/ClassListManager.d.ts +0 -0
  333. package/dist/types/twisty/old/dom/element/ClassListManager.d.ts.map +1 -0
  334. package/dist/types/twisty/{dom → old/dom}/element/ElementConfig.d.ts +1 -1
  335. package/dist/types/twisty/old/dom/element/ElementConfig.d.ts.map +1 -0
  336. package/dist/types/twisty/{dom → old/dom}/element/ManagedCustomElement.d.ts +0 -0
  337. package/dist/types/twisty/old/dom/element/ManagedCustomElement.d.ts.map +1 -0
  338. package/dist/types/twisty/{dom → old/dom}/element/node-custom-element-shims.d.ts +0 -0
  339. package/dist/types/twisty/old/dom/element/node-custom-element-shims.d.ts.map +1 -0
  340. package/dist/types/twisty/{dom/stream/TwistyStreamSource.css_.d.ts → old/dom/stream/TwistyStreamSource.css.d.ts} +1 -1
  341. package/dist/types/twisty/old/dom/stream/TwistyStreamSource.css.d.ts.map +1 -0
  342. package/dist/types/twisty/{dom → old/dom}/stream/TwistyStreamSource.d.ts +0 -0
  343. package/dist/types/twisty/old/dom/stream/TwistyStreamSource.d.ts.map +1 -0
  344. package/dist/types/twisty/{dom → old/dom}/viewers/Twisty2DSVG.d.ts +2 -2
  345. package/dist/types/twisty/old/dom/viewers/Twisty2DSVG.d.ts.map +1 -0
  346. package/dist/types/twisty/{dom/viewers/Twisty2DSVGView.css_.d.ts → old/dom/viewers/Twisty2DSVGView.css.d.ts} +1 -1
  347. package/dist/types/twisty/old/dom/viewers/Twisty2DSVGView.css.d.ts.map +1 -0
  348. package/dist/types/twisty/{dom/viewers/Twisty3DCanvas.css_.d.ts → old/dom/viewers/Twisty3DCanvas.css.d.ts} +1 -1
  349. package/dist/types/twisty/old/dom/viewers/Twisty3DCanvas.css.d.ts.map +1 -0
  350. package/dist/types/twisty/{dom → old/dom}/viewers/Twisty3DCanvas.d.ts +1 -2
  351. package/dist/types/twisty/old/dom/viewers/Twisty3DCanvas.d.ts.map +1 -0
  352. package/dist/types/twisty/{dom → old/dom}/viewers/TwistyOrbitControls.d.ts +0 -0
  353. package/dist/types/twisty/old/dom/viewers/TwistyOrbitControls.d.ts.map +1 -0
  354. package/dist/types/twisty/old/dom/viewers/TwistyViewerElement.d.ts +4 -0
  355. package/dist/types/twisty/old/dom/viewers/TwistyViewerElement.d.ts.map +1 -0
  356. package/dist/types/twisty/{dom/viewers/TwistyViewerWrapper.css_.d.ts → old/dom/viewers/TwistyViewerWrapper.css.d.ts} +1 -1
  357. package/dist/types/twisty/old/dom/viewers/TwistyViewerWrapper.css.d.ts.map +1 -0
  358. package/dist/types/twisty/{dom → old/dom}/viewers/TwistyViewerWrapper.d.ts +0 -0
  359. package/dist/types/twisty/old/dom/viewers/TwistyViewerWrapper.d.ts.map +1 -0
  360. package/dist/types/twisty/old/dom/viewers/canvas.d.ts +3 -0
  361. package/dist/types/twisty/old/dom/viewers/canvas.d.ts.map +1 -0
  362. package/dist/types/twisty/views/2D/Twisty2DPuzzle.d.ts +29 -0
  363. package/dist/types/twisty/views/2D/Twisty2DPuzzle.d.ts.map +1 -0
  364. package/dist/types/twisty/views/2D/Twisty2DPuzzleWrapper.d.ts +16 -0
  365. package/dist/types/twisty/views/2D/Twisty2DPuzzleWrapper.d.ts.map +1 -0
  366. package/dist/types/twisty/views/2D/Twisty2DSceneWrapper.d.ts +20 -0
  367. package/dist/types/twisty/views/2D/Twisty2DSceneWrapper.d.ts.map +1 -0
  368. package/dist/types/twisty/views/3D/RendererPool.d.ts +4 -0
  369. package/dist/types/twisty/views/3D/RendererPool.d.ts.map +1 -0
  370. package/dist/types/twisty/{3D → views/3D}/TAU.d.ts +0 -0
  371. package/dist/types/twisty/views/3D/TAU.d.ts.map +1 -0
  372. package/dist/types/twisty/views/3D/Twisty3DPuzzleWrapper.d.ts +17 -0
  373. package/dist/types/twisty/views/3D/Twisty3DPuzzleWrapper.d.ts.map +1 -0
  374. package/dist/types/twisty/{3D → views/3D}/Twisty3DRenderTarget.d.ts +0 -0
  375. package/dist/types/twisty/views/3D/Twisty3DRenderTarget.d.ts.map +1 -0
  376. package/dist/types/twisty/{3D → views/3D}/Twisty3DScene.d.ts +0 -0
  377. package/dist/types/twisty/views/3D/Twisty3DScene.d.ts.map +1 -0
  378. package/dist/types/twisty/views/3D/Twisty3DSceneWrapper.d.ts +28 -0
  379. package/dist/types/twisty/views/3D/Twisty3DSceneWrapper.d.ts.map +1 -0
  380. package/dist/types/twisty/views/3D/Twisty3DVantage.d.ts +32 -0
  381. package/dist/types/twisty/views/3D/Twisty3DVantage.d.ts.map +1 -0
  382. package/dist/types/twisty/views/3D/TwistyOrbitControlsV2.d.ts +41 -0
  383. package/dist/types/twisty/views/3D/TwistyOrbitControlsV2.d.ts.map +1 -0
  384. package/dist/types/twisty/views/3D/TwistyOrbitControlsV2.spec.d.ts +5 -0
  385. package/dist/types/twisty/views/3D/TwistyOrbitControlsV2.spec.d.ts.map +1 -0
  386. package/dist/types/twisty/{3D → views/3D}/puzzles/Cube3D.d.ts +11 -7
  387. package/dist/types/twisty/views/3D/puzzles/Cube3D.d.ts.map +1 -0
  388. package/dist/types/twisty/{3D → views/3D}/puzzles/KPuzzleWrapper.d.ts +2 -2
  389. package/dist/types/twisty/views/3D/puzzles/KPuzzleWrapper.d.ts.map +1 -0
  390. package/dist/types/twisty/views/3D/puzzles/PG3D.d.ts +57 -0
  391. package/dist/types/twisty/views/3D/puzzles/PG3D.d.ts.map +1 -0
  392. package/dist/types/twisty/{3D → views/3D}/puzzles/Twisty3DPuzzle.d.ts +1 -1
  393. package/dist/types/twisty/views/3D/puzzles/Twisty3DPuzzle.d.ts.map +1 -0
  394. package/dist/types/twisty/{3D → views/3D}/puzzles/TwistyTestBox.d.ts +2 -2
  395. package/dist/types/twisty/views/3D/puzzles/TwistyTestBox.d.ts.map +1 -0
  396. package/dist/types/twisty/views/TwistyAlgEditor/LeafTokens.d.ts +18 -0
  397. package/dist/types/twisty/views/TwistyAlgEditor/LeafTokens.d.ts.map +1 -0
  398. package/dist/types/twisty/views/TwistyAlgEditor/TwistyAlgEditor.css.d.ts +3 -0
  399. package/dist/types/twisty/views/TwistyAlgEditor/TwistyAlgEditor.css.d.ts.map +1 -0
  400. package/dist/types/twisty/views/TwistyAlgEditor/TwistyAlgEditor.d.ts +40 -0
  401. package/dist/types/twisty/views/TwistyAlgEditor/TwistyAlgEditor.d.ts.map +1 -0
  402. package/dist/types/twisty/views/TwistyAlgEditor/TwistyAlgEditor.spec.d.ts +5 -0
  403. package/dist/types/twisty/views/TwistyAlgEditor/TwistyAlgEditor.spec.d.ts.map +1 -0
  404. package/dist/types/twisty/views/TwistyAlgEditor/model.d.ts +61 -0
  405. package/dist/types/twisty/views/TwistyAlgEditor/model.d.ts.map +1 -0
  406. package/dist/types/twisty/views/TwistyAlgViewer.css.d.ts +3 -0
  407. package/dist/types/twisty/views/TwistyAlgViewer.css.d.ts.map +1 -0
  408. package/dist/types/twisty/{dom → views}/TwistyAlgViewer.d.ts +6 -6
  409. package/dist/types/twisty/views/TwistyAlgViewer.d.ts.map +1 -0
  410. package/dist/types/twisty/views/TwistyPlayer.d.ts +97 -0
  411. package/dist/types/twisty/views/TwistyPlayer.d.ts.map +1 -0
  412. package/dist/types/twisty/views/TwistyPlayerSettable.d.ts +71 -0
  413. package/dist/types/twisty/views/TwistyPlayerSettable.d.ts.map +1 -0
  414. package/dist/types/twisty/views/control-panel/TwistyButtonsV2.d.ts +33 -0
  415. package/dist/types/twisty/views/control-panel/TwistyButtonsV2.d.ts.map +1 -0
  416. package/dist/types/twisty/views/control-panel/TwistyScrubberV2.d.ts +14 -0
  417. package/dist/types/twisty/views/control-panel/TwistyScrubberV2.d.ts.map +1 -0
  418. package/dist/types/twisty/views/control-panel/webkit-fullscreen.d.ts +15 -0
  419. package/dist/types/twisty/views/control-panel/webkit-fullscreen.d.ts.map +1 -0
  420. package/dist/types/twisty/views/document.d.ts +2 -0
  421. package/dist/types/twisty/views/document.d.ts.map +1 -0
  422. package/dist/types/twisty/views/screenshot.d.ts +12 -0
  423. package/dist/types/twisty/views/screenshot.d.ts.map +1 -0
  424. package/dist/types/vendor/p-lazy/p-lazy.d.ts +10 -0
  425. package/dist/types/vendor/p-lazy/p-lazy.d.ts.map +1 -0
  426. package/dist/types/vendor/three/examples/jsm/libs/stats.modified.module.d.ts +33 -0
  427. package/dist/types/vendor/three/examples/jsm/libs/stats.modified.module.d.ts.map +1 -0
  428. package/docs/.DS_Store +0 -0
  429. package/docs/cubing/.DS_Store +0 -0
  430. package/docs/cubing/alg/index.html +37 -23
  431. package/docs/cubing/index.html +56 -252
  432. package/docs/cubing/scramble/index.html +122 -0
  433. package/docs/cubing/twisty/index.html +329 -0
  434. package/docs/main.css +15 -3
  435. package/package.json +83 -57
  436. package/src/cubing/.DS_Store +0 -0
  437. package/src/cubing/alg/.DS_Store +0 -0
  438. package/src/cubing/alg/Alg.ts +89 -0
  439. package/src/cubing/alg/common.ts +4 -2
  440. package/src/cubing/alg/iteration.ts +1 -1
  441. package/src/cubing/alg/parse.ts +2 -0
  442. package/src/cubing/alg/test/alg-comparison.ts +1 -0
  443. package/src/cubing/alg/units/.DS_Store +0 -0
  444. package/src/cubing/alg/units/Unit.ts +0 -3
  445. package/src/cubing/alg/units/containers/Commutator.ts +1 -1
  446. package/src/cubing/alg/units/leaves/Move.ts +4 -4
  447. package/src/cubing/bluetooth/.DS_Store +0 -0
  448. package/src/cubing/bluetooth/connect/index.ts +1 -1
  449. package/src/cubing/bluetooth/smart-puzzle/Heykube.ts +1 -1
  450. package/src/cubing/bluetooth/smart-puzzle/bluetooth-puzzle.ts +1 -1
  451. package/src/cubing/bluetooth/smart-puzzle/gan.ts +5 -5
  452. package/src/cubing/bluetooth/smart-puzzle/giiker.ts +2 -2
  453. package/src/cubing/bluetooth/smart-puzzle/gocube.ts +5 -5
  454. package/src/cubing/bluetooth/smart-robot/GanRobot.ts +5 -5
  455. package/src/cubing/bluetooth/smart-timer/GanTimer.ts +2 -2
  456. package/src/cubing/kpuzzle/.DS_Store +0 -0
  457. package/src/cubing/kpuzzle/3x3x3/3x3x3.kpuzzle.json.spec.ts +40 -0
  458. package/src/cubing/{puzzles/implementations/3x3x3/3x3x3.kpuzzle.json_.ts → kpuzzle/3x3x3/3x3x3.kpuzzle.json.ts} +11 -6
  459. package/src/cubing/kpuzzle/canon.spec.ts +6 -11
  460. package/src/cubing/kpuzzle/canonicalize.ts +1 -1
  461. package/src/cubing/kpuzzle/definition_types.ts +0 -3
  462. package/src/cubing/kpuzzle/index.ts +1 -0
  463. package/src/cubing/kpuzzle/prunetable.spec.ts +2 -4
  464. package/src/cubing/kpuzzle/puzzle-orientation.ts +1 -1
  465. package/src/cubing/kpuzzle/svg.ts +4 -9
  466. package/src/cubing/kpuzzle/transformations.ts +1 -1
  467. package/src/cubing/protocol/binary/binary3x3x3.spec.ts +5 -2
  468. package/src/cubing/protocol/binary/hex.ts +4 -4
  469. package/src/cubing/protocol/binary/orbit-indexing.ts +2 -2
  470. package/src/cubing/protocol/binary/puzzle-orientation.ts +2 -2
  471. package/src/cubing/puzzle-geometry/Options.ts +151 -22
  472. package/src/cubing/puzzle-geometry/PGPuzzles.spec.ts +24 -28
  473. package/src/cubing/puzzle-geometry/PermOriSet.ts +99 -98
  474. package/src/cubing/puzzle-geometry/PlatonicGenerator.ts +1 -1
  475. package/src/cubing/puzzle-geometry/PuzzleGeometry.ts +836 -867
  476. package/src/cubing/puzzle-geometry/Quat.ts +1 -68
  477. package/src/cubing/puzzle-geometry/SchreierSims.ts +2 -13
  478. package/src/cubing/puzzle-geometry/index.ts +2 -11
  479. package/src/cubing/puzzle-geometry/interfaces.ts +1 -27
  480. package/src/cubing/puzzle-geometry/orientcenters.spec.ts +24 -30
  481. package/src/cubing/puzzles/.DS_Store +0 -0
  482. package/src/cubing/puzzles/PuzzleLoader.ts +1 -1
  483. package/src/cubing/puzzles/async/async-pg3d.ts +5 -8
  484. package/src/cubing/puzzles/customPGPuzzleLoader.ts +60 -0
  485. package/src/cubing/puzzles/implementations/.DS_Store +0 -0
  486. package/src/cubing/puzzles/implementations/2x2x2/{2x2x2.kpuzzle.json_.ts → 2x2x2.kpuzzle.json.ts} +0 -0
  487. package/src/cubing/puzzles/implementations/2x2x2/index.ts +1 -1
  488. package/src/cubing/puzzles/implementations/3x3x3/index.ts +2 -3
  489. package/src/cubing/puzzles/implementations/clock/{clock.kpuzzle.json_.ts → clock.kpuzzle.json.ts} +0 -0
  490. package/src/cubing/puzzles/implementations/clock/index.ts +1 -1
  491. package/src/cubing/puzzles/implementations/fto/index.ts +19 -11
  492. package/src/cubing/puzzles/implementations/pyraminx/{pyraminx.kpuzzle.json_.ts → pyraminx.kpuzzle.json.ts} +0 -0
  493. package/src/cubing/puzzles/implementations/square1/index.ts +1 -2
  494. package/src/cubing/puzzles/implementations/square1/{sq1-hyperorbit.kpuzzle.json_.ts → sq1-hyperorbit.kpuzzle.json.ts} +0 -0
  495. package/src/cubing/puzzles/index.ts +30 -20
  496. package/src/cubing/puzzles/stickerings/appearance.ts +10 -9
  497. package/src/cubing/puzzles/stickerings/cube-stickerings.ts +8 -0
  498. package/src/cubing/puzzles/stickerings/fto-stickerings.ts +9 -0
  499. package/src/cubing/puzzles/stickerings/global-custom-stickering-hack.ts +61 -0
  500. package/src/cubing/search/.DS_Store +0 -0
  501. package/src/cubing/search/.gitignore +1 -2
  502. package/src/cubing/search/esm-test-worker.js +1 -1
  503. package/src/cubing/search/index.ts +1 -0
  504. package/src/cubing/search/inside/api.spec.ts +1 -0
  505. package/src/cubing/search/inside/api.ts +6 -1
  506. package/src/cubing/search/inside/solve/parseSGS.ts +7 -11
  507. package/src/cubing/search/inside/solve/puzzles/2x2x2.ts +3 -3
  508. package/src/cubing/search/inside/solve/puzzles/3x3x3/filter.ts +0 -6
  509. package/src/cubing/search/inside/solve/puzzles/3x3x3/index.ts +0 -2
  510. package/src/cubing/search/inside/solve/puzzles/FTO.sgs +264 -0
  511. package/src/cubing/search/inside/solve/puzzles/megaminx.sgs.json.ts +4 -6
  512. package/src/cubing/search/inside/solve/puzzles/skewb.sgs.json.ts +4 -6
  513. package/src/cubing/search/inside/solve/tremble.ts +6 -9
  514. package/src/cubing/search/inside/solve/vendor/cstimer/src/js/lib/mathlib.ts +20 -822
  515. package/src/cubing/search/inside/solve/vendor/cstimer/src/js/scramble/scramble_444.ts +177 -252
  516. package/src/cubing/search/inside/solve/vendor/min2phase/gwt.js +62 -222
  517. package/src/cubing/search/inside/solve/vendor/random-uint-below/get-random-values.ts +4 -5
  518. package/src/cubing/search/inside/solve/vendor/random-uint-below/random-int.ts +9 -11
  519. package/src/cubing/search/inside/solve/vendor/sq12phase/scramble_sq1.js +13 -582
  520. package/src/cubing/search/instantiator.ts +11 -7
  521. package/src/cubing/search/outside.ts +8 -2
  522. package/src/cubing/search/worker-inside-generated-string.js +1 -1
  523. package/src/cubing/stream/.DS_Store +0 -0
  524. package/src/cubing/stream/process/ReorientedStream.ts +1 -1
  525. package/src/cubing/stream/twizzle/TwizzleStream.ts +11 -8
  526. package/src/cubing/stream/websocket-proxy.ts +1 -3
  527. package/src/cubing/twisty/.DS_Store +0 -0
  528. package/src/cubing/twisty/controllers/TwistyAnimationController.ts +248 -0
  529. package/src/cubing/twisty/controllers/TwistyPlayerController.ts +38 -0
  530. package/src/cubing/twisty/heavy-code-imports/3d.ts +18 -0
  531. package/src/cubing/twisty/heavy-code-imports/dynamic-entries/3d.ts +41 -0
  532. package/src/cubing/twisty/index.ts +24 -17
  533. package/src/cubing/twisty/model/.DS_Store +0 -0
  534. package/src/cubing/twisty/model/PromiseFreshener.ts +49 -0
  535. package/src/cubing/twisty/model/TwistyPlayerModel.ts +222 -0
  536. package/src/cubing/twisty/model/UserVisibleErrorTracker.ts +22 -0
  537. package/src/cubing/twisty/model/helpers.ts +47 -0
  538. package/src/cubing/{search/vendor → twisty/model/props}/.DS_Store +0 -0
  539. package/src/cubing/twisty/model/props/TwistyProp.spec.ts +38 -0
  540. package/src/cubing/twisty/model/props/TwistyProp.ts +366 -0
  541. package/src/cubing/twisty/model/props/TwistyPropDebugger.ts +370 -0
  542. package/src/cubing/twisty/model/props/general/URLProp.ts +14 -0
  543. package/src/cubing/{solve → twisty/model/props/puzzle}/.DS_Store +0 -0
  544. package/src/cubing/twisty/model/props/puzzle/display/HintFaceletProp.ts +10 -0
  545. package/src/cubing/twisty/model/props/puzzle/display/SpriteProp.ts +43 -0
  546. package/src/cubing/twisty/model/props/puzzle/display/StickeringProp.ts +8 -0
  547. package/src/cubing/twisty/model/props/puzzle/state/AlgProp.ts +91 -0
  548. package/src/cubing/twisty/model/props/puzzle/state/AlgTransformationProp.ts +28 -0
  549. package/src/cubing/twisty/model/props/puzzle/state/AnchoredStartProp.ts +44 -0
  550. package/src/cubing/twisty/model/props/puzzle/state/CurrentLeavesProp.ts +91 -0
  551. package/src/cubing/twisty/model/props/puzzle/state/CurrentLeavesSimplified.ts +48 -0
  552. package/src/cubing/twisty/model/props/puzzle/state/CurrentTransformationProp.ts +46 -0
  553. package/src/cubing/twisty/model/props/puzzle/state/IndexerConstructorProp.ts +46 -0
  554. package/src/cubing/twisty/model/props/puzzle/state/IndexerConstructorRequestProp.ts +15 -0
  555. package/src/cubing/twisty/model/props/puzzle/state/IndexerProp.ts +24 -0
  556. package/src/cubing/twisty/model/props/puzzle/state/LegacyPositionProp.ts +22 -0
  557. package/src/cubing/twisty/model/props/puzzle/state/PuzzleAlgProp.ts +28 -0
  558. package/src/cubing/twisty/model/props/puzzle/state/SetupAnchorProp.ts +8 -0
  559. package/src/cubing/twisty/model/props/puzzle/structure/PuzzleDefProp.ts +14 -0
  560. package/src/cubing/twisty/model/props/puzzle/structure/PuzzleDescriptionProp.ts +14 -0
  561. package/src/cubing/twisty/model/props/puzzle/structure/PuzzleIDProp.ts +12 -0
  562. package/src/cubing/twisty/model/props/puzzle/structure/PuzzleIDRequestProp.ts +17 -0
  563. package/src/cubing/twisty/model/props/puzzle/structure/PuzzleLoaderProp.ts +38 -0
  564. package/src/cubing/twisty/model/props/timeline/CoarseTimelineInfoProp.ts +45 -0
  565. package/src/cubing/twisty/model/props/timeline/DetailedTimelineInfoProp.ts +76 -0
  566. package/src/cubing/twisty/model/props/timeline/PlayingInfoProp.ts +51 -0
  567. package/src/cubing/twisty/model/props/timeline/TempoScaleProp.ts +13 -0
  568. package/src/cubing/twisty/model/props/timeline/TimestampRequestProp.ts +38 -0
  569. package/src/cubing/twisty/model/props/viewer/BackViewProp.ts +10 -0
  570. package/src/cubing/twisty/model/props/viewer/BackgroundProp.ts +10 -0
  571. package/src/cubing/twisty/model/props/viewer/ButtonAppearanceProp.ts +86 -0
  572. package/src/cubing/twisty/model/props/viewer/ControlPanelProp.ts +10 -0
  573. package/src/cubing/twisty/model/props/viewer/LatitudeLimit.ts +11 -0
  574. package/src/cubing/twisty/model/props/viewer/OrbitCoordinatesProp.ts +56 -0
  575. package/src/cubing/twisty/model/props/viewer/OrbitCoordinatesRequestProp.ts +69 -0
  576. package/src/cubing/twisty/model/props/viewer/TimeRangeProp.ts +15 -0
  577. package/src/cubing/twisty/model/props/viewer/ViewerLinkProp.ts +10 -0
  578. package/src/cubing/twisty/model/props/viewer/VisualizationProp.ts +10 -0
  579. package/src/cubing/twisty/model/props/viewer/VisualizationStrategyProp.ts +45 -0
  580. package/src/cubing/twisty/old/.DS_Store +0 -0
  581. package/src/cubing/twisty/old/animation/.DS_Store +0 -0
  582. package/src/cubing/twisty/{animation → old/animation}/RenderScheduler.ts +5 -0
  583. package/src/cubing/twisty/{animation → old/animation}/Timeline.ts +0 -0
  584. package/src/cubing/twisty/{animation → old/animation}/cursor/AlgCursor.ts +15 -8
  585. package/src/cubing/twisty/{animation → old/animation}/cursor/CursorTypes.ts +4 -4
  586. package/src/cubing/twisty/{animation → old/animation}/easing.ts +0 -0
  587. package/src/cubing/{search/inside → twisty/old/animation/indexer}/.DS_Store +0 -0
  588. package/src/cubing/twisty/{animation → old/animation}/indexer/AlgDuration.ts +1 -1
  589. package/src/cubing/twisty/old/animation/indexer/AlgIndexer.ts +86 -0
  590. package/src/cubing/twisty/{animation → old/animation}/indexer/SimpleAlgIndexer.ts +9 -6
  591. package/src/cubing/twisty/old/animation/indexer/simultaneous-moves/SimultaneousMoveIndexer.ts +181 -0
  592. package/src/cubing/twisty/old/animation/indexer/simultaneous-moves/SimultaneousMoveIndexerV2.ts +243 -0
  593. package/src/cubing/twisty/{animation → old/animation}/indexer/simultaneous-moves/simul-moves.ts +46 -34
  594. package/src/cubing/twisty/{animation → old/animation}/indexer/tree/AlgWalker.ts +6 -3
  595. package/src/cubing/twisty/{animation → old/animation}/indexer/tree/TreeAlgIndexer.ts +8 -5
  596. package/src/cubing/twisty/{animation → old/animation}/indexer/tree/chunkAlgs.ts +2 -2
  597. package/src/cubing/twisty/{animation → old/animation}/stream/timeline-move-calculation-draft.spec.ts.TODO +0 -0
  598. package/src/cubing/twisty/{animation → old/animation}/stream/timeline-move-calculation-draft.ts +2 -2
  599. package/src/cubing/twisty/old/dom/.DS_Store +0 -0
  600. package/src/cubing/twisty/{dom/TwistyAlgViewer.css_.ts → old/dom/TwistyAlgViewerV1.css.ts} +0 -0
  601. package/src/cubing/twisty/{dom/TwistyAlgViewer.ts → old/dom/TwistyAlgViewerV1.ts} +43 -36
  602. package/src/cubing/twisty/{dom/TwistyPlayer.css_.ts → old/dom/TwistyPlayer.css.ts} +28 -1
  603. package/src/cubing/twisty/{dom → old/dom}/TwistyPlayer.spec.ts +5 -6
  604. package/src/cubing/twisty/{dom → old/dom}/TwistyPlayer.ts +36 -43
  605. package/src/cubing/twisty/{dom → old/dom}/TwistyPlayerConfig.ts +27 -10
  606. package/src/cubing/twisty/{dom/controls/TwistyControlElement.ts.ts → old/dom/controls/TwistyControlElement.ts} +0 -0
  607. package/src/cubing/twisty/{dom/controls/TwistyScrubber.css_.ts → old/dom/controls/TwistyScrubber.css.ts} +0 -0
  608. package/src/cubing/twisty/{dom → old/dom}/controls/TwistyScrubber.ts +3 -3
  609. package/src/cubing/twisty/{dom/controls/buttons.css_.ts → old/dom/controls/buttons.css.ts} +14 -1
  610. package/src/cubing/twisty/{dom → old/dom}/controls/buttons.spec.ts +1 -1
  611. package/src/cubing/twisty/{dom → old/dom}/controls/buttons.ts +15 -15
  612. package/src/cubing/twisty/{dom → old/dom}/element/ClassListManager.ts +0 -0
  613. package/src/cubing/twisty/{dom → old/dom}/element/ElementConfig.ts +1 -1
  614. package/src/cubing/twisty/{dom → old/dom}/element/ManagedCustomElement.ts +0 -0
  615. package/src/cubing/twisty/{dom → old/dom}/element/node-custom-element-shims.ts +0 -0
  616. package/src/cubing/twisty/{dom/stream/TwistyStreamSource.css_.ts → old/dom/stream/TwistyStreamSource.css.ts} +0 -0
  617. package/src/cubing/twisty/{dom → old/dom}/stream/TwistyStreamSource.ts +8 -8
  618. package/src/cubing/twisty/{dom → old/dom}/viewers/Twisty2DSVG.ts +7 -9
  619. package/src/cubing/twisty/{dom/viewers/Twisty2DSVGView.css_.ts → old/dom/viewers/Twisty2DSVGView.css.ts} +0 -0
  620. package/src/cubing/twisty/{dom/viewers/Twisty3DCanvas.css_.ts → old/dom/viewers/Twisty3DCanvas.css.ts} +0 -0
  621. package/src/cubing/twisty/{dom → old/dom}/viewers/Twisty3DCanvas.ts +5 -12
  622. package/src/cubing/twisty/{dom → old/dom}/viewers/TwistyOrbitControls.ts +53 -20
  623. package/src/cubing/twisty/{dom → old/dom}/viewers/TwistyViewerElement.ts +1 -1
  624. package/src/cubing/twisty/{dom/viewers/TwistyViewerWrapper.css_.ts → old/dom/viewers/TwistyViewerWrapper.css.ts} +0 -0
  625. package/src/cubing/twisty/{dom → old/dom}/viewers/TwistyViewerWrapper.ts +1 -1
  626. package/src/cubing/twisty/old/dom/viewers/canvas.ts +9 -0
  627. package/src/cubing/twisty/views/.DS_Store +0 -0
  628. package/src/cubing/twisty/views/2D/Twisty2DPuzzle.ts +150 -0
  629. package/src/cubing/twisty/views/2D/Twisty2DPuzzleWrapper.ts +52 -0
  630. package/src/cubing/twisty/views/2D/Twisty2DSceneWrapper.ts +77 -0
  631. package/src/cubing/twisty/views/3D/RendererPool.ts +53 -0
  632. package/src/cubing/twisty/{3D → views/3D}/TAU.ts +0 -0
  633. package/src/cubing/twisty/views/3D/Twisty3DPuzzleWrapper.ts +168 -0
  634. package/src/cubing/twisty/{3D → views/3D}/Twisty3DRenderTarget.ts +0 -0
  635. package/src/cubing/twisty/{3D → views/3D}/Twisty3DScene.ts +0 -0
  636. package/src/cubing/twisty/views/3D/Twisty3DSceneWrapper.ts +144 -0
  637. package/src/cubing/twisty/views/3D/Twisty3DVantage.ts +244 -0
  638. package/src/cubing/twisty/views/3D/TwistyOrbitControlsV2.spec.ts +209 -0
  639. package/src/cubing/twisty/views/3D/TwistyOrbitControlsV2.ts +270 -0
  640. package/src/cubing/twisty/{3D → views/3D}/puzzles/Cube3D.ts +36 -15
  641. package/src/cubing/twisty/{3D → views/3D}/puzzles/KPuzzleWrapper.ts +4 -5
  642. package/src/cubing/twisty/views/3D/puzzles/PG3D.ts +988 -0
  643. package/src/cubing/twisty/views/3D/puzzles/Twisty3DPuzzle.ts +6 -0
  644. package/src/cubing/twisty/{3D → views/3D}/puzzles/TwistyTestBox.ts +2 -2
  645. package/src/cubing/twisty/views/TwistyAlgEditor/LeafTokens.ts +116 -0
  646. package/src/cubing/twisty/{dom/TwistyAlgEditor.css_.ts → views/TwistyAlgEditor/TwistyAlgEditor.css.ts} +3 -1
  647. package/src/cubing/twisty/{dom → views/TwistyAlgEditor}/TwistyAlgEditor.spec.ts +7 -6
  648. package/src/cubing/twisty/views/TwistyAlgEditor/TwistyAlgEditor.ts +360 -0
  649. package/src/cubing/twisty/views/TwistyAlgEditor/model.ts +179 -0
  650. package/src/cubing/twisty/views/TwistyAlgViewer.css.ts +25 -0
  651. package/src/cubing/twisty/views/TwistyAlgViewer.ts +502 -0
  652. package/src/cubing/twisty/views/TwistyPlayer.ts +327 -0
  653. package/src/cubing/twisty/views/TwistyPlayerSettable.ts +111 -0
  654. package/src/cubing/twisty/views/control-panel/TwistyButtonsV2.ts +159 -0
  655. package/src/cubing/twisty/views/control-panel/TwistyScrubberV2.ts +145 -0
  656. package/src/cubing/twisty/views/control-panel/webkit-fullscreen.ts +44 -0
  657. package/src/cubing/twisty/views/document.ts +4 -0
  658. package/src/cubing/twisty/views/screenshot.ts +90 -0
  659. package/src/cubing/vendor/.DS_Store +0 -0
  660. package/src/cubing/vendor/p-lazy/license +9 -0
  661. package/src/cubing/vendor/p-lazy/p-lazy.ts +52 -0
  662. package/src/cubing/vendor/p-lazy/readme.md +54 -0
  663. package/src/cubing/vendor/three/examples/jsm/libs/stats.modified.module.ts +179 -0
  664. package/dist/esm/chunk-CWVB5RRW.js.map +0 -7
  665. package/dist/esm/chunk-KKSDHNLH.js.map +0 -7
  666. package/dist/esm/chunk-YNB7QLBF.js.map +0 -7
  667. package/dist/esm/worker-inside-generated-string-LT4NV55Q.js +0 -2826
  668. package/dist/esm/worker-inside-generated-string-LT4NV55Q.js.map +0 -7
  669. package/dist/types/puzzles/implementations/2x2x2/2x2x2.kpuzzle.json_.d.ts.map +0 -1
  670. package/dist/types/puzzles/implementations/3x3x3/3x3x3.kpuzzle.json_.d.ts +0 -3
  671. package/dist/types/puzzles/implementations/3x3x3/3x3x3.kpuzzle.json_.d.ts.map +0 -1
  672. package/dist/types/puzzles/implementations/clock/clock.kpuzzle.json_.d.ts.map +0 -1
  673. package/dist/types/puzzles/implementations/pyraminx/pyraminx.kpuzzle.json_.d.ts.map +0 -1
  674. package/dist/types/puzzles/implementations/square1/sq1-hyperorbit.kpuzzle.json_.d.ts.map +0 -1
  675. package/dist/types/search/inside/solve/vendor/cstimer/src/js/lgarron-additions-for-typescript/shim-lib.d.ts +0 -3
  676. package/dist/types/search/inside/solve/vendor/cstimer/src/js/lgarron-additions-for-typescript/shim-lib.d.ts.map +0 -1
  677. package/dist/types/twisty/3D/TAU.d.ts.map +0 -1
  678. package/dist/types/twisty/3D/Twisty3DRenderTarget.d.ts.map +0 -1
  679. package/dist/types/twisty/3D/Twisty3DScene.d.ts.map +0 -1
  680. package/dist/types/twisty/3D/puzzles/Cube3D.d.ts.map +0 -1
  681. package/dist/types/twisty/3D/puzzles/KPuzzleWrapper.d.ts.map +0 -1
  682. package/dist/types/twisty/3D/puzzles/PG3D.d.ts +0 -51
  683. package/dist/types/twisty/3D/puzzles/PG3D.d.ts.map +0 -1
  684. package/dist/types/twisty/3D/puzzles/Twisty3DPuzzle.d.ts.map +0 -1
  685. package/dist/types/twisty/3D/puzzles/TwistyTestBox.d.ts.map +0 -1
  686. package/dist/types/twisty/animation/RenderScheduler.d.ts.map +0 -1
  687. package/dist/types/twisty/animation/Timeline.d.ts.map +0 -1
  688. package/dist/types/twisty/animation/cursor/AlgCursor.d.ts.map +0 -1
  689. package/dist/types/twisty/animation/cursor/CursorTypes.d.ts.map +0 -1
  690. package/dist/types/twisty/animation/easing.d.ts.map +0 -1
  691. package/dist/types/twisty/animation/indexer/AlgDuration.d.ts.map +0 -1
  692. package/dist/types/twisty/animation/indexer/AlgIndexer.d.ts +0 -15
  693. package/dist/types/twisty/animation/indexer/AlgIndexer.d.ts.map +0 -1
  694. package/dist/types/twisty/animation/indexer/SimpleAlgIndexer.d.ts.map +0 -1
  695. package/dist/types/twisty/animation/indexer/simultaneous-moves/SimultaneousMoveIndexer.d.ts.map +0 -1
  696. package/dist/types/twisty/animation/indexer/simultaneous-moves/simul-moves.d.ts +0 -25
  697. package/dist/types/twisty/animation/indexer/simultaneous-moves/simul-moves.d.ts.map +0 -1
  698. package/dist/types/twisty/animation/indexer/tree/AlgWalker.d.ts.map +0 -1
  699. package/dist/types/twisty/animation/indexer/tree/TreeAlgIndexer.d.ts.map +0 -1
  700. package/dist/types/twisty/animation/indexer/tree/chunkAlgs.d.ts +0 -3
  701. package/dist/types/twisty/animation/indexer/tree/chunkAlgs.d.ts.map +0 -1
  702. package/dist/types/twisty/animation/stream/timeline-move-calculation-draft.d.ts.map +0 -1
  703. package/dist/types/twisty/dom/TwistyAlgEditor.css_.d.ts +0 -3
  704. package/dist/types/twisty/dom/TwistyAlgEditor.css_.d.ts.map +0 -1
  705. package/dist/types/twisty/dom/TwistyAlgEditor.d.ts +0 -27
  706. package/dist/types/twisty/dom/TwistyAlgEditor.d.ts.map +0 -1
  707. package/dist/types/twisty/dom/TwistyAlgEditorStartCharSearch.d.ts +0 -26
  708. package/dist/types/twisty/dom/TwistyAlgEditorStartCharSearch.d.ts.map +0 -1
  709. package/dist/types/twisty/dom/TwistyAlgViewer.css_.d.ts.map +0 -1
  710. package/dist/types/twisty/dom/TwistyAlgViewer.d.ts.map +0 -1
  711. package/dist/types/twisty/dom/TwistyPlayer.css_.d.ts.map +0 -1
  712. package/dist/types/twisty/dom/TwistyPlayer.d.ts.map +0 -1
  713. package/dist/types/twisty/dom/TwistyPlayerConfig.d.ts.map +0 -1
  714. package/dist/types/twisty/dom/controls/TwistyControlElement.ts.d.ts +0 -2
  715. package/dist/types/twisty/dom/controls/TwistyControlElement.ts.d.ts.map +0 -1
  716. package/dist/types/twisty/dom/controls/TwistyScrubber.css_.d.ts.map +0 -1
  717. package/dist/types/twisty/dom/controls/TwistyScrubber.d.ts.map +0 -1
  718. package/dist/types/twisty/dom/controls/buttons.css_.d.ts.map +0 -1
  719. package/dist/types/twisty/dom/controls/buttons.d.ts.map +0 -1
  720. package/dist/types/twisty/dom/element/ClassListManager.d.ts.map +0 -1
  721. package/dist/types/twisty/dom/element/ElementConfig.d.ts.map +0 -1
  722. package/dist/types/twisty/dom/element/ManagedCustomElement.d.ts.map +0 -1
  723. package/dist/types/twisty/dom/element/node-custom-element-shims.d.ts.map +0 -1
  724. package/dist/types/twisty/dom/stream/TwistyStreamSource.css_.d.ts.map +0 -1
  725. package/dist/types/twisty/dom/stream/TwistyStreamSource.d.ts.map +0 -1
  726. package/dist/types/twisty/dom/viewers/Twisty2DSVG.d.ts.map +0 -1
  727. package/dist/types/twisty/dom/viewers/Twisty2DSVGView.css_.d.ts.map +0 -1
  728. package/dist/types/twisty/dom/viewers/Twisty3DCanvas.css_.d.ts.map +0 -1
  729. package/dist/types/twisty/dom/viewers/Twisty3DCanvas.d.ts.map +0 -1
  730. package/dist/types/twisty/dom/viewers/TwistyOrbitControls.d.ts.map +0 -1
  731. package/dist/types/twisty/dom/viewers/TwistyViewerElement.d.ts +0 -4
  732. package/dist/types/twisty/dom/viewers/TwistyViewerElement.d.ts.map +0 -1
  733. package/dist/types/twisty/dom/viewers/TwistyViewerWrapper.css_.d.ts.map +0 -1
  734. package/dist/types/twisty/dom/viewers/TwistyViewerWrapper.d.ts.map +0 -1
  735. package/dist/types/twisty/dom/viewers/canvas.d.ts +0 -2
  736. package/dist/types/twisty/dom/viewers/canvas.d.ts.map +0 -1
  737. package/dist/types/vendor/three/examples/jsm/libs/stats.module.d.ts +0 -2
  738. package/dist/types/vendor/three/examples/jsm/libs/stats.module.d.ts.map +0 -1
  739. package/dist/types/vendor/three/examples/jsm/libs/stats.module.wrapped.d.ts +0 -21
  740. package/dist/types/vendor/three/examples/jsm/libs/stats.module.wrapped.d.ts.map +0 -1
  741. package/src/cubing/protocol/.DS_Store +0 -0
  742. package/src/cubing/puzzle-geometry/.DS_Store +0 -0
  743. package/src/cubing/search/inside/solve/.DS_Store +0 -0
  744. package/src/cubing/search/inside/solve/puzzles/.DS_Store +0 -0
  745. package/src/cubing/search/inside/solve/puzzles/3x3x3/.DS_Store +0 -0
  746. package/src/cubing/search/inside/solve/vendor/.DS_Store +0 -0
  747. package/src/cubing/search/inside/solve/vendor/cstimer/.DS_Store +0 -0
  748. package/src/cubing/search/inside/solve/vendor/cstimer/src/.DS_Store +0 -0
  749. package/src/cubing/search/inside/solve/vendor/cstimer/src/js/.DS_Store +0 -0
  750. package/src/cubing/search/inside/solve/vendor/cstimer/src/js/lgarron-additions-for-typescript/.DS_Store +0 -0
  751. package/src/cubing/search/inside/solve/vendor/cstimer/src/js/lgarron-additions-for-typescript/shim-lib.ts +0 -13
  752. package/src/cubing/search/inside/solve/vendor/cstimer/src/js/lib/.DS_Store +0 -0
  753. package/src/cubing/search/inside/solve/vendor/cstimer/src/js/scramble/.DS_Store +0 -0
  754. package/src/cubing/search/inside/solve/vendor/sgs/.DS_Store +0 -0
  755. package/src/cubing/search/inside/solve/vendor/sgs/src/.DS_Store +0 -0
  756. package/src/cubing/search/inside/solve/vendor/sgs/src/test/.DS_Store +0 -0
  757. package/src/cubing/search/vendor/comlink-everywhere/.DS_Store +0 -0
  758. package/src/cubing/twisty/3D/puzzles/PG3D.ts +0 -600
  759. package/src/cubing/twisty/3D/puzzles/Twisty3DPuzzle.ts +0 -9
  760. package/src/cubing/twisty/3D/puzzles/mkbhd.svg +0 -5
  761. package/src/cubing/twisty/animation/indexer/AlgIndexer.ts +0 -25
  762. package/src/cubing/twisty/animation/indexer/simultaneous-moves/SimultaneousMoveIndexer.ts +0 -168
  763. package/src/cubing/twisty/dom/TwistyAlgEditor.ts +0 -373
  764. package/src/cubing/twisty/dom/TwistyAlgEditorStartCharSearch.ts +0 -138
  765. package/src/cubing/twisty/dom/viewers/canvas.ts +0 -4
  766. package/src/cubing/twisty/views/3D/.DS_Store +0 -0
  767. package/src/cubing/vendor/three/.DS_Store +0 -0
  768. package/src/cubing/vendor/three/examples/jsm/libs/stats.module.ts +0 -2
  769. package/src/cubing/vendor/three/examples/jsm/libs/stats.module.wrapped.d.ts +0 -24
  770. package/src/cubing/vendor/three/examples/jsm/libs/stats.module.wrapped.js +0 -178
@@ -1,15 +1,6 @@
1
- /* tslint:disable no-bitwise */
2
- /* tslint:disable prefer-for-of */ // TODO
3
- /* tslint:disable only-arrow-functions */ // TODO
4
- /* tslint:disable typedef */ // TODO
5
-
6
1
  import { Move, QuantumMove } from "../alg";
7
2
  import { FaceNameSwizzler } from "./FaceNameSwizzler";
8
- import type {
9
- MoveNotation,
10
- PGVendoredKPuzzleDefinition,
11
- Transformation as KTransformation,
12
- } from "./interfaces";
3
+ import type { MoveNotation } from "./interfaces";
13
4
  import {
14
5
  FaceRenamingMapper,
15
6
  FTONotationMapper,
@@ -21,14 +12,21 @@ import {
21
12
  SkewbNotationMapper,
22
13
  TetraminxNotationMapper,
23
14
  } from "./notation-mapping";
15
+ import {
16
+ BaseFaceCount,
17
+ FaceBasedOrientationDescription,
18
+ FaceBasedOrientationDescriptionLookup,
19
+ PuzzleGeometryOptions,
20
+ PuzzleGeometryFullOptions,
21
+ } from "./Options";
24
22
  import { iota, Perm, zeros } from "./Perm";
25
23
  import {
26
24
  externalName,
27
- Orbit,
28
- OrbitDef,
29
- OrbitsDef,
25
+ PGOrbit,
26
+ PGOrbitDef,
27
+ PGOrbitsDef,
30
28
  showcanon,
31
- Transformation,
29
+ PGTransform,
32
30
  VisibleState,
33
31
  } from "./PermOriSet";
34
32
  import { PGPuzzles, PuzzleDescriptionString, PuzzleName } from "./PGPuzzles";
@@ -42,20 +40,29 @@ import {
42
40
  tetrahedron,
43
41
  uniqueplanes,
44
42
  } from "./PlatonicGenerator";
45
- import { centermassface, expandfaces, FaceTree, Quat } from "./Quat";
43
+ import { centermassface, Quat } from "./Quat";
44
+ import { schreierSims } from "./SchreierSims";
45
+ import type {
46
+ KPuzzleDefinition,
47
+ Transformation as KTransformation,
48
+ } from "../kpuzzle";
46
49
 
47
- const DEFAULT_COLOR_FRACTION = 0.77;
50
+ export interface TextureMapper {
51
+ getuv(fn: number, threed: number[]): number[];
52
+ }
48
53
 
49
54
  export interface StickerDatSticker {
50
- coords: number[][];
55
+ coords: number[];
51
56
  color: string;
52
57
  orbit: string;
53
58
  ord: number;
54
59
  ori: number;
60
+ face: number;
61
+ isDup?: boolean;
55
62
  }
56
63
 
57
64
  export interface StickerDatFace {
58
- coords: number[][];
65
+ coords: number[];
59
66
  name: string;
60
67
  }
61
68
 
@@ -63,17 +70,116 @@ export type StickerDatAxis = [number[], string, number];
63
70
 
64
71
  export interface StickerDat {
65
72
  stickers: StickerDatSticker[];
66
- foundations: StickerDatSticker[];
67
73
  faces: StickerDatFace[];
68
74
  axis: StickerDatAxis[];
69
75
  unswizzle(mv: Move): string;
70
76
  notationMapper: NotationMapper;
77
+ textureMapper: TextureMapper;
78
+ }
79
+
80
+ // you can fill these in to help with timing if you want
81
+ function tstart(s: string): string {
82
+ return s;
83
+ }
84
+
85
+ function tend(_: string): void {}
86
+
87
+ class Face {
88
+ private coords: number[];
89
+ public length: number;
90
+ constructor(q: Quat[]) {
91
+ this.coords = new Array(q.length * 3);
92
+ for (let i = 0; i < q.length; i++) {
93
+ this.coords[3 * i] = q[i].b;
94
+ this.coords[3 * i + 1] = q[i].c;
95
+ this.coords[3 * i + 2] = q[i].d;
96
+ }
97
+ this.length = q.length;
98
+ }
99
+
100
+ get(off: number): Quat {
101
+ return new Quat(
102
+ 0,
103
+ this.coords[3 * off],
104
+ this.coords[3 * off + 1],
105
+ this.coords[3 * off + 2],
106
+ );
107
+ }
108
+
109
+ centermass(): Quat {
110
+ let sx = 0;
111
+ let sy = 0;
112
+ let sz = 0;
113
+ for (let i = 0; i < this.length; i++) {
114
+ sx += this.coords[3 * i];
115
+ sy += this.coords[3 * i + 1];
116
+ sz += this.coords[3 * i + 2];
117
+ }
118
+ return new Quat(0, sx / this.length, sy / this.length, sz / this.length);
119
+ }
120
+
121
+ rotate(q: Quat): Face {
122
+ const a = [];
123
+ for (let i = 0; i < this.length; i++) {
124
+ a.push(this.get(i).rotatepoint(q));
125
+ }
126
+ return new Face(a);
127
+ }
128
+
129
+ rotateforward(): Face {
130
+ const a = [];
131
+ for (let i = 1; i < this.length; i++) {
132
+ a.push(this.get(i));
133
+ }
134
+ a.push(this.get(0));
135
+ return new Face(a);
136
+ }
137
+ }
138
+
139
+ export class FaceTree {
140
+ constructor(
141
+ private face: Quat[],
142
+ private left?: FaceTree,
143
+ private right?: FaceTree,
144
+ ) {}
145
+
146
+ public split(q: Quat): FaceTree {
147
+ const t = q.cutface(this.face);
148
+ if (t !== null) {
149
+ if (this.left === undefined) {
150
+ this.left = new FaceTree(t[0]);
151
+ this.right = new FaceTree(t[1]);
152
+ } else {
153
+ this.left = this.left?.split(q);
154
+ this.right = this.right?.split(q);
155
+ }
156
+ }
157
+ return this;
158
+ }
159
+
160
+ public collect(arr: Face[], leftfirst: boolean): Face[] {
161
+ if (this.left === undefined) {
162
+ arr.push(new Face(this.face));
163
+ } else if (leftfirst) {
164
+ this.left?.collect(arr, false);
165
+ this.right?.collect(arr, true);
166
+ } else {
167
+ this.right?.collect(arr, false);
168
+ this.left?.collect(arr, true);
169
+ }
170
+ return arr;
171
+ }
71
172
  }
72
173
 
73
- // TODO: Remove this once we no longer have prefix restrictions.
74
- let NEW_FACE_NAMES = true;
75
- export function useNewFaceNames(use: boolean): void {
76
- NEW_FACE_NAMES = use;
174
+ export function expandfaces(rots: Quat[], faces: Face[]): Face[] {
175
+ // given a set of faces, expand by rotation set
176
+ const nfaces = [];
177
+ for (const rot of rots) {
178
+ for (const face of faces) {
179
+ nfaces.push(face.rotate(rot));
180
+ }
181
+ }
182
+ return nfaces;
77
183
  }
78
184
 
79
185
  // Now we have a geometry class that does the 3D goemetry to calculate
@@ -266,17 +372,32 @@ function defaultfaceorders(): any {
266
372
  * this information is explicitly given in the twizzle app file.
267
373
  */
268
374
  // TODO: change this back to a const JSON definition.
269
- function defaultOrientations(): any {
375
+ function defaultOrientations(): FaceBasedOrientationDescriptionLookup {
270
376
  return {
271
- 4: ["FLR", [0, 1, 0], "F", [0, 0, 1]], // FLR towards viewer
272
- 6: ["U", [0, 1, 0], "F", [0, 0, 1]], // URF towards viewer
273
- 8: ["U", [0, 1, 0], "F", [0, 0, 1]], // FLUR towards viewer
274
- 12: ["U", [0, 1, 0], "F", [0, 0, 1]], // F towards viewer
275
- 20: ["GUQMJ", [0, 1, 0], "F", [0, 0, 1]], // F towards viewer
377
+ 4: [
378
+ ["FLR", [0, 1, 0]],
379
+ ["F", [0, 0, 1]],
380
+ ], // FLR towards viewer
381
+ 6: [
382
+ ["U", [0, 1, 0]],
383
+ ["F", [0, 0, 1]],
384
+ ], // URF towards viewer
385
+ 8: [
386
+ ["U", [0, 1, 0]],
387
+ ["F", [0, 0, 1]],
388
+ ], // FLUR towards viewer
389
+ 12: [
390
+ ["U", [0, 1, 0]],
391
+ ["F", [0, 0, 1]],
392
+ ], // F towards viewer
393
+ 20: [
394
+ ["GUQMJ", [0, 1, 0]],
395
+ ["F", [0, 0, 1]],
396
+ ], // F towards viewer
276
397
  };
277
398
  }
278
399
 
279
- function findelement(a: any[], p: Quat): number {
400
+ function findelement(a: Quat[][], p: Quat): number {
280
401
  // find something in facenames, vertexnames, edgenames
281
402
  for (let i = 0; i < a.length; i++) {
282
403
  if (a[i][0].dist(p) < eps) {
@@ -296,40 +417,51 @@ export function getpuzzle(puzzleName: PuzzleName): PuzzleDescriptionString {
296
417
  return PGPuzzles[puzzleName];
297
418
  }
298
419
 
299
- export function parsedesc(s: string): any {
420
+ export type CutDescription = { cutType: string; distance: number };
421
+ export type PuzzleDescription = {
422
+ shape: string;
423
+ cuts: CutDescription[];
424
+ };
425
+
426
+ export function parsePuzzleDescription(
427
+ s: PuzzleDescriptionString,
428
+ ): PuzzleDescription | null {
300
429
  // parse a text description
301
430
  const a = s.split(/ /).filter(Boolean);
302
431
  if (a.length % 2 === 0) {
303
- return false;
432
+ return null;
304
433
  }
434
+ const shape = a[0];
305
435
  if (
306
- a[0] !== "o" &&
307
- a[0] !== "c" &&
308
- a[0] !== "i" &&
309
- a[0] !== "d" &&
310
- a[0] !== "t"
436
+ shape !== "o" &&
437
+ shape !== "c" &&
438
+ shape !== "i" &&
439
+ shape !== "d" &&
440
+ shape !== "t"
311
441
  ) {
312
- return false;
442
+ return null;
313
443
  }
314
- const r = [];
444
+ const cuts: CutDescription[] = [];
315
445
  for (let i = 1; i < a.length; i += 2) {
316
446
  if (a[i] !== "f" && a[i] !== "v" && a[i] !== "e") {
317
- return false;
447
+ return null;
318
448
  }
319
- r.push([a[i], a[i + 1]]);
449
+ cuts.push({ cutType: a[i], distance: parseFloat(a[i + 1]) });
320
450
  }
321
- return [a[0], r];
451
+ return { shape, cuts };
322
452
  }
323
453
 
324
454
  export function getPuzzleGeometryByDesc(
325
455
  desc: string,
326
- options: string[] = [],
456
+ options: PuzzleGeometryOptions = {},
327
457
  ): PuzzleGeometry {
328
- const [shape, cuts] = parsedesc(desc);
458
+ const parsed = parsePuzzleDescription(desc);
459
+ if (parsed === null) {
460
+ throw new Error("Could not parse the puzzle description");
461
+ }
329
462
  const pg = new PuzzleGeometry(
330
- shape,
331
- cuts,
332
- ["allmoves", "true"].concat(options),
463
+ parsed,
464
+ Object.assign({}, { allMoves: true } as PuzzleGeometryOptions, options),
333
465
  );
334
466
  pg.allstickers();
335
467
  pg.genperms();
@@ -338,12 +470,16 @@ export function getPuzzleGeometryByDesc(
338
470
 
339
471
  export function getPuzzleGeometryByName(
340
472
  puzzleName: PuzzleName,
341
- options: string[] = [],
473
+ options?: PuzzleGeometryOptions,
342
474
  ): PuzzleGeometry {
343
475
  return getPuzzleGeometryByDesc(PGPuzzles[puzzleName], options);
344
476
  }
345
477
 
346
- function getmovename(geo: any, bits: number[], slices: number): any {
478
+ function getmovename(
479
+ geo: any,
480
+ bits: number[],
481
+ slices: number,
482
+ ): [string, boolean] {
347
483
  // generate a move name based on bits, slice, and geo
348
484
  // if the move name is from the opposite face, say so.
349
485
  // find the face that's turned.
@@ -354,7 +490,7 @@ function getmovename(geo: any, bits: number[], slices: number): any {
354
490
  bits = [slices - bits[1], slices - bits[0]];
355
491
  inverted = true;
356
492
  }
357
- let movenameFamily = geo[0];
493
+ let movenameFamily = geo[0] as string;
358
494
  let movenamePrefix = "";
359
495
  if (bits[0] === 0 && bits[1] === slices) {
360
496
  movenameFamily = movenameFamily + "v";
@@ -368,14 +504,14 @@ function getmovename(geo: any, bits: number[], slices: number): any {
368
504
  movenamePrefix = String(bits[1] + 1);
369
505
  }
370
506
  } else {
371
- throw "We only support slice and outer block moves right now. " + bits;
507
+ throw `We only support slice and outer block moves right now. ${bits}`;
372
508
  }
373
509
  return [movenamePrefix + movenameFamily, inverted];
374
510
  }
375
511
 
376
512
  // split a geometrical element into face names. Do greedy match.
377
513
  // Permit underscores between names.
378
- function splitByFaceNames(s: string, facenames: any[]): string[] {
514
+ function splitByFaceNames(s: string, facenames: [Quat[], string][]): string[] {
379
515
  const r: string[] = [];
380
516
  let at = 0;
381
517
  while (at < s.length) {
@@ -383,12 +519,12 @@ function splitByFaceNames(s: string, facenames: any[]): string[] {
383
519
  at++;
384
520
  }
385
521
  let currentMatch = "";
386
- for (let i = 0; i < facenames.length; i++) {
522
+ for (const facename of facenames) {
387
523
  if (
388
- s.substr(at).startsWith(facenames[i][1]) &&
389
- facenames[i][1].length > currentMatch.length
524
+ s.substr(at).startsWith(facename[1]) &&
525
+ facename[1].length > currentMatch.length
390
526
  ) {
391
- currentMatch = facenames[i][1];
527
+ currentMatch = facename[1];
392
528
  }
393
529
  }
394
530
  if (currentMatch !== "") {
@@ -405,206 +541,98 @@ function toCoords(q: Quat, maxdist: number): number[] {
405
541
  return [q.b / maxdist, -q.c / maxdist, q.d / maxdist];
406
542
  }
407
543
 
408
- function toFaceCoords(q: Quat[], maxdist: number): number[][] {
544
+ function toFaceCoords(q: Face, maxdist: number): number[] {
409
545
  const r = [];
410
546
  const n = q.length;
411
547
  for (let i = 0; i < n; i++) {
412
- r[n - i - 1] = toCoords(q[i], maxdist);
548
+ const pt = toCoords(q.get(n - i - 1), maxdist);
549
+ r[3 * i] = pt[0];
550
+ r[3 * i + 1] = pt[1];
551
+ r[3 * i + 2] = pt[2];
413
552
  }
414
553
  return r;
415
554
  }
416
555
 
417
- function trimEdges(face: Quat[], tr: number): Quat[] {
418
- const r: Quat[] = [];
419
- for (let iter = 1; iter < 10; iter++) {
420
- for (let i = 0; i < face.length; i++) {
421
- const pi = (i + face.length - 1) % face.length;
422
- const ni = (i + 1) % face.length;
423
- const A = face[pi].sub(face[i]).normalize();
424
- const B = face[ni].sub(face[i]).normalize();
425
- const d = A.dot(B);
426
- const m = tr / Math.sqrt(1 - d * d);
427
- r[i] = face[i].sum(A.sum(B).smul(m));
428
- }
429
- let good = true;
430
- for (let i = 0; good && i < r.length; i++) {
431
- const pi = (i + face.length - 1) % face.length;
432
- const ni = (i + 1) % face.length;
433
- if (r[pi].sub(r[i]).cross(r[ni].sub(r[i])).dot(r[i]) >= 0) {
434
- good = false;
435
- }
436
- }
437
- if (good) {
438
- return r;
439
- }
440
- tr /= 2;
441
- }
442
- return face;
443
- }
444
-
445
556
  export class PuzzleGeometry {
446
- public args: string = "";
447
- public rotations: Quat[]; // all members of the rotation group
557
+ private rotations: Quat[]; // all members of the rotation group
448
558
  public baseplanerot: Quat[]; // unique rotations of the baseplane
449
- public baseplanes: Quat[]; // planes, corresponding to faces
450
- public facenames: any[]; // face names
451
- public faceplanes: any; // face planes
452
- public edgenames: any[]; // edge names
453
- public vertexnames: any[]; // vertexnames
454
- public geonormals: any[]; // all geometric directions, with names and types
455
- public moveplanes: Quat[]; // the planes that split moves
456
- public moveplanes2: Quat[]; // the planes that split moves, filtered
457
- public moveplanesets: any[]; // the move planes, in parallel sets
458
- public moveplanenormals: Quat[]; // one move plane
459
- public movesetorders: any[]; // the order of rotations for each move set
460
- public movesetgeos: any[]; // geometric feature information for move sets
461
- public basefaces: Quat[][]; // polytope faces before cuts
462
- public faces: Quat[][]; // all the stickers
463
- public facecentermass: Quat[]; // center of mass of all faces
464
- public basefacecount: number; // number of base faces
559
+ private baseplanes: Quat[]; // planes, corresponding to faces
560
+ private facenames: [Quat[], string][]; // face names
561
+ private faceplanes: [Quat, string][]; // face planes
562
+ private edgenames: [Quat, string][]; // edge names
563
+ private vertexnames: [Quat, string][]; // vertexnames
564
+ private geonormals: [Quat, string, string][]; // all geometric directions, with names and types
565
+ private moveplanes: Quat[]; // the planes that split moves
566
+ private moveplanes2: Quat[]; // the planes that split moves, filtered
567
+ public moveplanesets: Quat[][]; // the move planes, in parallel sets
568
+ private moveplanenormals: Quat[]; // one move plane
569
+ public movesetorders: number[]; // the order of rotations for each move set
570
+ public movesetgeos: [string, string, string, string, number][]; // geometric feature information for move sets
571
+ private basefaces: Face[]; // polytope faces before cuts
572
+ private faces: Face[]; // all the stickers
573
+ private facecentermass: Quat[]; // center of mass of all faces
574
+ private baseFaceCount: BaseFaceCount; // number of base faces
465
575
  public stickersperface: number; // number of stickers per face
466
- public cornerfaces: number; // number of faces that meet at a corner
467
- public cubies: any[]; // the cubies
468
- public shortedge: number; // shortest edge
469
- public vertexdistance: number; // vertex distance
470
- public edgedistance: number; // edge distance
471
- public orbits: number; // count of cubie orbits
472
- public facetocubies: any[]; // map a face to a cubie index and offset
473
- public moverotations: Quat[][]; // move rotations
474
- public cubiekey: any; // cubie locator
475
- public cubiekeys: string[]; // cubie keys
476
- public facelisthash: any; // face list by key
477
- public cubiesetnames: any[]; // cubie set names
478
- public cubieords: number[]; // the size of each orbit
479
- public cubiesetnums: number[];
480
- public cubieordnums: number[];
481
- public orbitoris: number[]; // the orientation size of each orbit
482
- public cubievaluemap: number[]; // the map for identical cubies
483
- public cubiesetcubies: number[][]; // cubies in each cubie set
576
+ public shortedge: number; // number of stickers per face
577
+ public cubies: number[][]; // the cubies
578
+ private vertexdistance: number; // vertex distance
579
+ private edgedistance: number; // edge distance
580
+ private facetocubie: number[]; // map a face to a cubie index
581
+ private facetoord: number[]; // map a face to a cubie ord
582
+ private moverotations: Quat[][]; // move rotations
583
+ private facelisthash: Map<string, number[]>; // face list by key
584
+ private cubiesetnames: string[]; // cubie set names
585
+ private cubieords: number[]; // the size of each orbit
586
+ private cubiesetnums: number[];
587
+ private cubieordnums: number[];
588
+ private orbitoris: number[]; // the orientation size of each orbit
589
+ private cubievaluemap: number[]; // the map for identical cubies
590
+ private cubiesetcubies: number[][]; // cubies in each cubie set
484
591
  public cmovesbyslice: number[][][] = []; // cmoves as perms by slice
485
- // options
486
- public verbose: number = 0; // verbosity (console.log)
487
- public allmoves: boolean = false; // generate all slice moves in ksolve
488
- public outerblockmoves: boolean; // generate outer block moves
489
- public vertexmoves: boolean; // generate vertex moves
490
- public addrotations: boolean; // add symmetry information to ksolve output
491
- public movelist: any; // move list to generate
492
- public parsedmovelist: any; // parsed move list
493
- public puzzleOrientation: any; // single puzzle orientation from options
494
- public puzzleOrientations: any; // puzzle orientation override list from options
495
- public cornersets: boolean = true; // include corner sets
496
- public centersets: boolean = true; // include center sets
497
- public edgesets: boolean = true; // include edge sets
498
- public omitsets: string[] = []; // omit these sets
499
- public graycorners: boolean = false; // make corner sets gray
500
- public graycenters: boolean = false; // make center sets gray
501
- public grayedges: boolean = false; // make edge sets gray
502
- public killorientation: boolean = false; // eliminate any orientations
503
- public optimize: boolean = false; // optimize PermOri
504
- public scramble: number = 0; // scramble?
505
- public ksolvemovenames: string[]; // move names from ksolve
506
- public fixPiece: string = ""; // fix a piece?
507
- public orientCenters: boolean = false; // orient centers?
508
- public duplicatedFaces: number[] = []; // which faces are duplicated
509
- public duplicatedCubies: number[] = []; // which cubies are duplicated
510
- public fixedCubie: number = -1; // fixed cubie, if any
511
- public svggrips: any[]; // grips from svg generation by svg coordinate
512
- public net: any = [];
513
- public colors: any = [];
514
- public faceorder: any = [];
515
- public faceprecedence: number[] = [];
516
- public swizzler: FaceNameSwizzler;
592
+ public parsedmovelist: [
593
+ string | undefined,
594
+ number,
595
+ number,
596
+ number,
597
+ boolean,
598
+ number,
599
+ ][]; // parsed move list
600
+
601
+ private duplicatedFaces: number[] = []; // which faces are duplicated
602
+ private duplicatedCubies: number[] = []; // which cubies are duplicated
603
+ private fixedCubie: number = -1; // fixed cubie, if any
604
+ private net: string[][] = [];
605
+ private colors: any = [];
606
+ private faceorder: string[] = [];
607
+ private faceprecedence: number[] = [];
608
+ private swizzler: FaceNameSwizzler;
517
609
  public notationMapper: NotationMapper = new NullMapper();
518
- public addNotationMapper: string = "";
519
- public setReidOrder: boolean = false;
520
- constructor(shape: string, cuts: string[][], optionlist: any[] | undefined) {
521
- function asstructured(v: any): any {
522
- if (typeof v === "string") {
523
- return JSON.parse(v);
524
- }
525
- return v;
526
- }
527
- function asboolean(v: any): boolean {
528
- if (typeof v === "string") {
529
- if (v === "false") {
530
- return false;
531
- }
532
- return true;
533
- } else {
534
- return v ? true : false;
535
- }
536
- }
537
- if (optionlist !== undefined) {
538
- if (optionlist.length % 2 !== 0) {
539
- throw new Error("Odd length in option list?");
540
- }
541
- for (let i = 0; i < optionlist.length; i += 2) {
542
- if (optionlist[i] === "verbose") {
543
- this.verbose++;
544
- } else if (optionlist[i] === "quiet") {
545
- this.verbose = 0;
546
- } else if (optionlist[i] === "allmoves") {
547
- this.allmoves = asboolean(optionlist[i + 1]);
548
- } else if (optionlist[i] === "outerblockmoves") {
549
- this.outerblockmoves = asboolean(optionlist[i + 1]);
550
- } else if (optionlist[i] === "vertexmoves") {
551
- this.vertexmoves = asboolean(optionlist[i + 1]);
552
- } else if (optionlist[i] === "rotations") {
553
- this.addrotations = asboolean(optionlist[i + 1]);
554
- } else if (optionlist[i] === "cornersets") {
555
- this.cornersets = asboolean(optionlist[i + 1]);
556
- } else if (optionlist[i] === "centersets") {
557
- this.centersets = asboolean(optionlist[i + 1]);
558
- } else if (optionlist[i] === "edgesets") {
559
- this.edgesets = asboolean(optionlist[i + 1]);
560
- } else if (optionlist[i] === "omit") {
561
- this.omitsets = optionlist[i + 1];
562
- } else if (optionlist[i] === "graycorners") {
563
- this.graycorners = asboolean(optionlist[i + 1]);
564
- } else if (optionlist[i] === "graycenters") {
565
- this.graycenters = asboolean(optionlist[i + 1]);
566
- } else if (optionlist[i] === "grayedges") {
567
- this.grayedges = asboolean(optionlist[i + 1]);
568
- } else if (optionlist[i] === "movelist") {
569
- this.movelist = asstructured(optionlist[i + 1]);
570
- } else if (optionlist[i] === "killorientation") {
571
- this.killorientation = asboolean(optionlist[i + 1]);
572
- } else if (optionlist[i] === "optimize") {
573
- this.optimize = asboolean(optionlist[i + 1]);
574
- } else if (optionlist[i] === "scramble") {
575
- this.scramble = optionlist[i + 1];
576
- } else if (optionlist[i] === "fix") {
577
- this.fixPiece = optionlist[i + 1];
578
- } else if (optionlist[i] === "orientcenters") {
579
- this.orientCenters = asboolean(optionlist[i + 1]);
580
- } else if (optionlist[i] === "puzzleorientation") {
581
- this.puzzleOrientation = asstructured(optionlist[i + 1]);
582
- } else if (optionlist[i] === "puzzleorientations") {
583
- this.puzzleOrientations = asstructured(optionlist[i + 1]);
584
- } else {
585
- throw new Error(
586
- "Bad option while processing option list " + optionlist[i],
587
- );
588
- }
589
- }
590
- }
591
- this.args = shape + " " + cuts.map((_) => _.join(" ")).join(" ");
592
- if (optionlist) {
593
- this.args += " " + optionlist.join(" ");
594
- }
595
- if (this.verbose > 0) {
610
+ private addNotationMapper: string = "";
611
+ private setReidOrder: boolean = false;
612
+
613
+ private options: PuzzleGeometryFullOptions;
614
+
615
+ constructor(
616
+ puzzleDescription: PuzzleDescription,
617
+ options: PuzzleGeometryOptions,
618
+ ) {
619
+ const t1 = tstart("genperms");
620
+ this.options = new PuzzleGeometryFullOptions(options);
621
+ if (this.options.verbosity > 0) {
596
622
  console.log(this.header("# "));
597
623
  }
598
- this.create(shape, cuts);
624
+ this.create(puzzleDescription);
625
+ tend(t1);
599
626
  }
600
627
 
601
- public create(shape: string, cuts: any[]): void {
628
+ public create(puzzleDescription: PuzzleDescription): void {
629
+ const { shape, cuts } = puzzleDescription;
630
+
602
631
  // create the shape, doing all the essential geometry
603
632
  // create only goes far enough to figure out how many stickers per
604
633
  // face, and what the short edge is. If the short edge is too short,
605
634
  // we probably don't want to display or manipulate this one. How
606
635
  // short is too short is hard to say.
607
- // var that = this ; // TODO
608
636
  this.moveplanes = [];
609
637
  this.moveplanes2 = [];
610
638
  this.faces = [];
@@ -630,47 +658,47 @@ export class PuzzleGeometry {
630
658
  throw new Error("Bad shape argument: " + shape);
631
659
  }
632
660
  this.rotations = closure(g);
633
- if (this.verbose) {
661
+ if (this.options.verbosity) {
634
662
  console.log("# Rotations: " + this.rotations.length);
635
663
  }
636
664
  const baseplane = g[0];
637
665
  this.baseplanerot = uniqueplanes(baseplane, this.rotations);
638
666
  const baseplanes = this.baseplanerot.map((_) => baseplane.rotateplane(_));
639
667
  this.baseplanes = baseplanes;
640
- this.basefacecount = baseplanes.length;
668
+ this.baseFaceCount = baseplanes.length as BaseFaceCount;
641
669
  const net = defaultnets()[baseplanes.length];
642
670
  this.net = net;
643
671
  this.colors = defaultcolors()[baseplanes.length];
644
672
  this.faceorder = defaultfaceorders()[baseplanes.length];
645
- if (this.verbose) {
673
+ if (this.options.verbosity > 0) {
646
674
  console.log("# Base planes: " + baseplanes.length);
647
675
  }
648
676
  const baseface = getface(baseplanes);
649
677
  const zero = new Quat(0, 0, 0, 0);
650
- if (this.verbose) {
678
+ if (this.options.verbosity > 0) {
651
679
  console.log("# Face vertices: " + baseface.length);
652
680
  }
653
681
  const facenormal = baseplanes[0].makenormal();
654
682
  const edgenormal = baseface[0].sum(baseface[1]).makenormal();
655
683
  const vertexnormal = baseface[0].makenormal();
656
684
  const boundary = new Quat(1, facenormal.b, facenormal.c, facenormal.d);
657
- if (this.verbose) {
685
+ if (this.options.verbosity > 0) {
658
686
  console.log("# Boundary is " + boundary);
659
687
  }
660
688
  const planerot = uniqueplanes(boundary, this.rotations);
661
689
  const planes = planerot.map((_) => boundary.rotateplane(_));
662
- let faces = [getface(planes)];
663
- this.edgedistance = faces[0][0].sum(faces[0][1]).smul(0.5).dist(zero);
664
- this.vertexdistance = faces[0][0].dist(zero);
690
+ const firstface = getface(planes);
691
+ this.edgedistance = firstface[0].sum(firstface[1]).smul(0.5).dist(zero);
692
+ this.vertexdistance = firstface[0].dist(zero);
665
693
  const cutplanes = [];
666
694
  const intersects = [];
667
695
  let sawface = false; // what cuts did we see?
668
696
  let sawedge = false;
669
697
  let sawvertex = false;
670
- for (let i = 0; i < cuts.length; i++) {
698
+ for (const cut of cuts) {
671
699
  let normal = null;
672
700
  let distance = 0;
673
- switch (cuts[i][0]) {
701
+ switch (cut.cutType) {
674
702
  case "f":
675
703
  normal = facenormal;
676
704
  distance = 1;
@@ -687,12 +715,12 @@ export class PuzzleGeometry {
687
715
  sawedge = true;
688
716
  break;
689
717
  default:
690
- throw new Error("Bad cut argument: " + cuts[i][0]);
718
+ throw new Error("Bad cut argument: " + cut.cutType);
691
719
  }
692
- cutplanes.push(normal.makecut(Number(cuts[i][1])));
693
- intersects.push(cuts[i][1] < distance);
720
+ cutplanes.push(normal.makecut(cut.distance));
721
+ intersects.push(cut.distance < distance);
694
722
  }
695
- if (this.addrotations) {
723
+ if (this.options.addRotations) {
696
724
  if (!sawface) {
697
725
  cutplanes.push(facenormal.makecut(10));
698
726
  }
@@ -704,9 +732,9 @@ export class PuzzleGeometry {
704
732
  }
705
733
  }
706
734
  this.basefaces = [];
707
- for (let i = 0; i < this.baseplanerot.length; i++) {
708
- const face = this.baseplanerot[i].rotateface(faces[0]);
709
- this.basefaces.push(face);
735
+ for (const baseplanerot of this.baseplanerot) {
736
+ const face = baseplanerot.rotateface(firstface);
737
+ this.basefaces.push(new Face(face));
710
738
  }
711
739
  //
712
740
  // Determine names for edges, vertices, and planes. Planes are defined
@@ -716,22 +744,22 @@ export class PuzzleGeometry {
716
744
  // n planes meet at a vertex. We arbitrarily choose the one that is
717
745
  // alphabetically first (and we will probably want to change this).
718
746
  //
719
- const facenames: any[] = [];
720
- const faceplanes = [];
747
+ const facenames: [Quat[], string][] = [];
748
+ const faceplanes: [Quat, string][] = [];
721
749
  const vertexnames: any[] = [];
722
750
  const edgenames: any[] = [];
723
- const edgesperface = faces[0].length;
751
+ const edgesperface = firstface.length;
724
752
  function searchaddelement(a: any[], p: Quat, name: any): void {
725
- for (let i = 0; i < a.length; i++) {
726
- if (a[i][0].dist(p) < eps) {
727
- a[i].push(name);
753
+ for (const el of a) {
754
+ if (el[0].dist(p) < eps) {
755
+ el.push(name);
728
756
  return;
729
757
  }
730
758
  }
731
759
  a.push([p, name]);
732
760
  }
733
761
  for (let i = 0; i < this.baseplanerot.length; i++) {
734
- const face = this.baseplanerot[i].rotateface(faces[0]);
762
+ const face = this.baseplanerot[i].rotateface(firstface);
735
763
  for (let j = 0; j < face.length; j++) {
736
764
  const jj = (j + 1) % face.length;
737
765
  const midpoint = face[j].sum(face[jj]).smul(0.5);
@@ -740,7 +768,7 @@ export class PuzzleGeometry {
740
768
  }
741
769
  const otherfaces = [];
742
770
  for (let i = 0; i < this.baseplanerot.length; i++) {
743
- const face = this.baseplanerot[i].rotateface(faces[0]);
771
+ const face = this.baseplanerot[i].rotateface(firstface);
744
772
  const facelist = [];
745
773
  for (let j = 0; j < face.length; j++) {
746
774
  const jj = (j + 1) % face.length;
@@ -757,13 +785,13 @@ export class PuzzleGeometry {
757
785
  otherfaces.push(facelist);
758
786
  }
759
787
  const facenametoindex: any = {};
760
- const faceindextoname: any = [];
788
+ const faceindextoname: string[] = [];
761
789
  faceindextoname.push(net[0][0]);
762
790
  facenametoindex[net[0][0]] = 0;
763
791
  faceindextoname[otherfaces[0][0]] = net[0][1];
764
792
  facenametoindex[net[0][1]] = otherfaces[0][0];
765
- for (let i = 0; i < net.length; i++) {
766
- const f0 = net[i][0];
793
+ for (const neti of net) {
794
+ const f0 = neti[0];
767
795
  const fi = facenametoindex[f0];
768
796
  if (fi === undefined) {
769
797
  throw new Error("Bad edge description; first edge not connected");
@@ -771,7 +799,7 @@ export class PuzzleGeometry {
771
799
  let ii = -1;
772
800
  for (let j = 0; j < otherfaces[fi].length; j++) {
773
801
  const fn2 = faceindextoname[otherfaces[fi][j]];
774
- if (fn2 !== undefined && fn2 === net[i][1]) {
802
+ if (fn2 !== undefined && fn2 === neti[1]) {
775
803
  ii = j;
776
804
  break;
777
805
  }
@@ -779,17 +807,17 @@ export class PuzzleGeometry {
779
807
  if (ii < 0) {
780
808
  throw new Error("First element of a net not known");
781
809
  }
782
- for (let j = 2; j < net[i].length; j++) {
783
- if (net[i][j] === "") {
810
+ for (let j = 2; j < neti.length; j++) {
811
+ if (neti[j] === "") {
784
812
  continue;
785
813
  }
786
814
  const of = otherfaces[fi][(j + ii - 1) % edgesperface];
787
815
  const fn2 = faceindextoname[of];
788
- if (fn2 !== undefined && fn2 !== net[i][j]) {
816
+ if (fn2 !== undefined && fn2 !== neti[j]) {
789
817
  throw new Error("Face mismatch in net");
790
818
  }
791
- faceindextoname[of] = net[i][j];
792
- facenametoindex[net[i][j]] = of;
819
+ faceindextoname[of] = neti[j];
820
+ facenametoindex[neti[j]] = of;
793
821
  }
794
822
  }
795
823
  for (let i = 0; i < faceindextoname.length; i++) {
@@ -811,14 +839,14 @@ export class PuzzleGeometry {
811
839
  }
812
840
  }
813
841
  for (let i = 0; i < this.baseplanerot.length; i++) {
814
- const face = this.baseplanerot[i].rotateface(faces[0]);
842
+ const face = this.baseplanerot[i].rotateface(firstface);
815
843
  const faceplane = boundary.rotateplane(this.baseplanerot[i]);
816
844
  const facename = faceindextoname[i];
817
845
  facenames.push([face, facename]);
818
846
  faceplanes.push([faceplane, facename]);
819
847
  }
820
848
  for (let i = 0; i < this.baseplanerot.length; i++) {
821
- const face = this.baseplanerot[i].rotateface(faces[0]);
849
+ const face = this.baseplanerot[i].rotateface(firstface);
822
850
  const facename = faceindextoname[i];
823
851
  for (let j = 0; j < face.length; j++) {
824
852
  const jj = (j + 1) % face.length;
@@ -830,7 +858,7 @@ export class PuzzleGeometry {
830
858
  searchaddelement(vertexnames, face[jj], [facename, e2, e1]);
831
859
  }
832
860
  }
833
- this.swizzler = new FaceNameSwizzler(facenames.map((_: any) => _[1]));
861
+ this.swizzler = new FaceNameSwizzler(facenames.map((_) => _[1]));
834
862
  const sep = this.swizzler.prefixFree ? "" : "_";
835
863
  // fix the edge names; use face precedence order
836
864
  for (let i = 0; i < edgenames.length; i++) {
@@ -850,7 +878,6 @@ export class PuzzleGeometry {
850
878
  edgenames[i] = [edgenames[i][0], c1];
851
879
  }
852
880
  // fix the vertex names; counterclockwise rotations; low face first.
853
- this.cornerfaces = vertexnames[0].length - 1;
854
881
  for (let i = 0; i < vertexnames.length; i++) {
855
882
  if (vertexnames[i].length < 4) {
856
883
  throw new Error("Bad length in vertex names");
@@ -880,32 +907,34 @@ export class PuzzleGeometry {
880
907
  }
881
908
  vertexnames[i] = [vertexnames[i][0], r];
882
909
  }
883
- if (this.verbose > 1) {
910
+ if (this.options.verbosity > 1) {
884
911
  console.log("# Face precedence list: " + this.faceorder.join(" "));
885
- console.log("# Face names: " + facenames.map((_: any) => _[1]).join(" "));
886
- console.log("# Edge names: " + edgenames.map((_: any) => _[1]).join(" "));
887
- console.log(
888
- "# Vertex names: " + vertexnames.map((_: any) => _[1]).join(" "),
889
- );
912
+ console.log("# Face names: " + facenames.map((_) => _[1]).join(" "));
913
+ // TODO
914
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
915
+ console.log("# Edge names: " + edgenames.map((_) => _[1]).join(" "));
916
+ // TODO
917
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
918
+ console.log("# Vertex names: " + vertexnames.map((_) => _[1]).join(" "));
890
919
  }
891
- const geonormals = [];
892
- for (let i = 0; i < faceplanes.length; i++) {
893
- geonormals.push([faceplanes[i][0].makenormal(), faceplanes[i][1], "f"]);
920
+ const geonormals: [Quat, string, string][] = [];
921
+ for (const faceplane of faceplanes) {
922
+ geonormals.push([faceplane[0].makenormal(), faceplane[1], "f"]);
894
923
  }
895
- for (let i = 0; i < edgenames.length; i++) {
896
- geonormals.push([edgenames[i][0].makenormal(), edgenames[i][1], "e"]);
924
+ for (const edgename of edgenames) {
925
+ geonormals.push([edgename[0].makenormal(), edgename[1], "e"]);
897
926
  }
898
- for (let i = 0; i < vertexnames.length; i++) {
899
- geonormals.push([vertexnames[i][0].makenormal(), vertexnames[i][1], "v"]);
927
+ for (const vertexname of vertexnames) {
928
+ geonormals.push([vertexname[0].makenormal(), vertexname[1], "v"]);
900
929
  }
901
930
  this.facenames = facenames;
902
931
  this.faceplanes = faceplanes;
903
932
  this.edgenames = edgenames;
904
933
  this.vertexnames = vertexnames;
905
934
  this.geonormals = geonormals;
906
- const geonormalnames = geonormals.map((_: any) => _[1]);
935
+ const geonormalnames = geonormals.map((_) => _[1]);
907
936
  this.swizzler.setGripNames(geonormalnames);
908
- if (this.verbose) {
937
+ if (this.options.verbosity > 0) {
909
938
  console.log(
910
939
  "# Distances: face " +
911
940
  1 +
@@ -917,11 +946,11 @@ export class PuzzleGeometry {
917
946
  }
918
947
  // expand cutplanes by rotations. We only work with one face here.
919
948
  for (let c = 0; c < cutplanes.length; c++) {
920
- for (let i = 0; i < this.rotations.length; i++) {
921
- const q = cutplanes[c].rotateplane(this.rotations[i]);
949
+ for (const rotation of this.rotations) {
950
+ const q = cutplanes[c].rotateplane(rotation);
922
951
  let wasseen = false;
923
- for (let j = 0; j < this.moveplanes.length; j++) {
924
- if (q.sameplane(this.moveplanes[j])) {
952
+ for (const moveplane of this.moveplanes) {
953
+ if (q.sameplane(moveplane)) {
925
954
  wasseen = true;
926
955
  break;
927
956
  }
@@ -934,7 +963,7 @@ export class PuzzleGeometry {
934
963
  }
935
964
  }
936
965
  }
937
- let ft = new FaceTree(faces[0]);
966
+ let ft = new FaceTree(firstface);
938
967
  const tar = this.moveplanes2.slice();
939
968
  // we want to use Math.random() here but we can't, because when
940
969
  // we call multiple times we'll get different orbits/layouts.
@@ -948,27 +977,66 @@ export class PuzzleGeometry {
948
977
  tar[j] = tar[i];
949
978
  rval = (rval * 1657 + 101) % 65536;
950
979
  }
951
- faces = ft.collect([], true);
980
+ const faces = ft.collect([], true);
952
981
  this.faces = faces;
953
- if (this.verbose) {
982
+ if (this.options.verbosity > 0) {
954
983
  console.log("# Faces is now " + faces.length);
955
984
  }
956
985
  this.stickersperface = faces.length;
986
+ // the faces when rotated don't preserve the vertex order at this
987
+ // point. to improve 3d rendering speed, we would like to preserve
988
+ // vertex order on rotation. First, let's see what rotations preserve
989
+ // the base face; these are the ones we want to work with.
990
+ const simplerot: Quat[] = [];
991
+ const cm = centermassface(firstface);
992
+ for (const rotation of this.rotations) {
993
+ const f = rotation.rotateface(firstface);
994
+ if (cm.dist(centermassface(f)) < eps) {
995
+ simplerot.push(rotation);
996
+ }
997
+ }
998
+ const finished = new Array<boolean>(faces.length);
999
+ const sortme: [number, Quat, number][] = [];
1000
+ for (let i = 0; i < faces.length; i++) {
1001
+ const cm2 = faces[i].centermass();
1002
+ sortme.push([cm.dist(cm2), cm2, i]);
1003
+ }
1004
+ sortme.sort((a, b) => a[0] - b[0]);
1005
+ for (let ii = 0; ii < faces.length; ii++) {
1006
+ const i = sortme[ii][2];
1007
+ if (!finished[i]) {
1008
+ finished[i] = true;
1009
+ for (const rot of simplerot) {
1010
+ const f2 = faces[i].rotate(rot);
1011
+ const cm = f2.centermass();
1012
+ for (let kk = ii + 1; kk < faces.length; kk++) {
1013
+ if (sortme[kk][0] - sortme[ii][0] > eps) {
1014
+ break;
1015
+ }
1016
+ const k = sortme[kk][2];
1017
+ if (!finished[k] && cm.dist(sortme[kk][1]) < eps) {
1018
+ finished[k] = true;
1019
+ faces[k] = f2;
1020
+ break;
1021
+ }
1022
+ }
1023
+ }
1024
+ }
1025
+ }
957
1026
  // Find and report the shortest edge in any of the faces. If this
958
1027
  // is small the puzzle is probably not practical or displayable.
959
- let shortedge = 1e99;
960
- for (let i = 0; i < faces.length; i++) {
961
- for (let j = 0; j < faces[i].length; j++) {
962
- const k = (j + 1) % faces[i].length;
963
- const t = faces[i][j].dist(faces[i][k]);
964
- if (t < shortedge) {
965
- shortedge = t;
1028
+ this.shortedge = 1e99;
1029
+ for (const face of faces) {
1030
+ for (let j = 0; j < face.length; j++) {
1031
+ const k = (j + 1) % face.length;
1032
+ const t = face.get(j).dist(face.get(k));
1033
+ if (t < this.shortedge) {
1034
+ this.shortedge = t;
966
1035
  }
967
1036
  }
968
1037
  }
969
- this.shortedge = shortedge;
970
- if (this.verbose) {
971
- console.log("# Short edge is " + shortedge);
1038
+ if (this.options.verbosity > 0) {
1039
+ console.log("# Short edge is " + this.shortedge);
972
1040
  }
973
1041
  // add nxnxn cube notation if it has cube face moves
974
1042
  if (shape === "c" && sawface && !sawedge && !sawvertex) {
@@ -984,7 +1052,7 @@ export class PuzzleGeometry {
984
1052
  if (shape === "t" && (sawvertex || sawface) && !sawedge) {
985
1053
  this.addNotationMapper = "PyraminxOrTetraminxMapper";
986
1054
  }
987
- if (shape === "o" && sawface && NEW_FACE_NAMES) {
1055
+ if (shape === "o" && sawface) {
988
1056
  this.notationMapper = new FaceRenamingMapper(
989
1057
  this.swizzler,
990
1058
  new FaceNameSwizzler(["F", "D", "L", "BL", "R", "U", "BR", "B"]),
@@ -993,7 +1061,7 @@ export class PuzzleGeometry {
993
1061
  this.addNotationMapper = "FTOMapper";
994
1062
  }
995
1063
  }
996
- if (shape === "d" && sawface && NEW_FACE_NAMES) {
1064
+ if (shape === "d" && sawface) {
997
1065
  this.addNotationMapper = "MegaminxMapper";
998
1066
  this.notationMapper = new FaceRenamingMapper(
999
1067
  this.swizzler,
@@ -1015,67 +1083,78 @@ export class PuzzleGeometry {
1015
1083
  }
1016
1084
  }
1017
1085
 
1018
- public keyface(face: Quat[]): string {
1019
- return this.keyface2(centermassface(face));
1086
+ private keyface(face: Face): string {
1087
+ return this.keyface2(face.centermass());
1020
1088
  }
1021
1089
 
1022
- public keyface2(cm: Quat): string {
1090
+ private keyface2(cm: Quat): string {
1023
1091
  // take a face and figure out the sides of each move plane
1024
1092
  let s = "";
1025
- for (let i = 0; i < this.moveplanesets.length; i++) {
1026
- if (this.moveplanesets[i].length > 0) {
1027
- const dv = cm.dot(this.moveplanesets[i][0]);
1093
+ const sfcc = String.fromCharCode;
1094
+ for (const moveplaneset of this.moveplanesets) {
1095
+ if (moveplaneset.length > 0) {
1096
+ const dv = cm.dot(moveplaneset[0]);
1028
1097
  let t = 0;
1029
1098
  let b = 1;
1030
- while (b * 2 <= this.moveplanesets[i].length) {
1099
+ while (b * 2 <= moveplaneset.length) {
1031
1100
  b *= 2;
1032
1101
  }
1033
1102
  for (; b > 0; b >>= 1) {
1034
- if (
1035
- t + b <= this.moveplanesets[i].length &&
1036
- dv > this.moveplanesets[i][t + b - 1].a
1037
- ) {
1103
+ if (t + b <= moveplaneset.length && dv > moveplaneset[t + b - 1].a) {
1038
1104
  t += b;
1039
1105
  }
1040
1106
  }
1041
- if (t <= 90) {
1042
- s = s + String.fromCharCode(34 + t);
1043
- } else {
1107
+ if (t < 47) {
1108
+ s = s + sfcc(33 + t);
1109
+ } else if (t < 47 + 47 * 47) {
1110
+ s = s + sfcc(33 + 47 + Math.floor(t / 47) - 1) + sfcc(33 + (t % 47));
1111
+ } else if (t < 47 + 47 * 47 + 47 * 47 * 47) {
1044
1112
  s =
1045
1113
  s +
1046
- "!" +
1047
- String.fromCharCode(34 + Math.floor(t / 90)) +
1048
- String.fromCharCode(34 + (t % 90));
1114
+ sfcc(33 + 47 + Math.floor((t - 47) / (47 * 47) - 1)) +
1115
+ sfcc(33 + 47 + (Math.floor((t - 47) / 47) % 47)) +
1116
+ sfcc(33 + (t % 47));
1117
+ } else {
1118
+ throw Error("Too many slices for cubie encoding");
1049
1119
  }
1050
1120
  }
1051
1121
  }
1052
1122
  return s;
1053
1123
  }
1054
1124
 
1055
- public findface(face: Quat[]): number {
1056
- const cm = centermassface(face);
1057
- const key = this.keyface2(cm);
1058
- const arr = this.facelisthash[key];
1059
- if (arr.length === 1) {
1060
- return arr[0];
1061
- }
1062
- for (let i = 0; i + 1 < arr.length; i++) {
1063
- const face2 = this.facelisthash[key][i];
1064
- if (Math.abs(cm.dist(this.facecentermass[face2])) < eps) {
1065
- return face2;
1125
+ // same as above, but instead of returning an encoded string, return
1126
+ // an array with offsets.
1127
+ private keyface3(face: Face): number[] {
1128
+ const cm = face.centermass();
1129
+ // take a face and figure out the sides of each move plane
1130
+ const r = [];
1131
+ for (const moveplaneset of this.moveplanesets) {
1132
+ if (moveplaneset.length > 0) {
1133
+ const dv = cm.dot(moveplaneset[0]);
1134
+ let t = 0;
1135
+ let b = 1;
1136
+ while (b * 2 <= moveplaneset.length) {
1137
+ b *= 2;
1138
+ }
1139
+ for (; b > 0; b >>= 1) {
1140
+ if (t + b <= moveplaneset.length && dv > moveplaneset[t + b - 1].a) {
1141
+ t += b;
1142
+ }
1143
+ }
1144
+ r.push(t);
1066
1145
  }
1067
1146
  }
1068
- return arr[arr.length - 1];
1147
+ return r;
1069
1148
  }
1070
1149
 
1071
- public findface2(cm: Quat): number {
1150
+ private findface(cm: Quat): number {
1072
1151
  const key = this.keyface2(cm);
1073
- const arr = this.facelisthash[key];
1152
+ const arr = this.facelisthash.get(key)!;
1074
1153
  if (arr.length === 1) {
1075
1154
  return arr[0];
1076
1155
  }
1077
1156
  for (let i = 0; i + 1 < arr.length; i++) {
1078
- const face2 = this.facelisthash[key][i];
1157
+ const face2 = this.facelisthash.get(key)![i];
1079
1158
  if (Math.abs(cm.dist(this.facecentermass[face2])) < eps) {
1080
1159
  return face2;
1081
1160
  }
@@ -1083,7 +1162,11 @@ export class PuzzleGeometry {
1083
1162
  return arr[arr.length - 1];
1084
1163
  }
1085
1164
 
1086
- public project2d(facen: number, edgen: number, targvec: Quat[]): any {
1165
+ private project2d(
1166
+ facen: number,
1167
+ edgen: number,
1168
+ targvec: Quat[],
1169
+ ): [Quat, Quat, Quat] {
1087
1170
  // calculate geometry to map a particular edge of a particular
1088
1171
  // face to a given 2D vector. The face is given as an index into the
1089
1172
  // facenames/baseplane arrays, and the edge is given as an offset into
@@ -1112,28 +1195,28 @@ export class PuzzleGeometry {
1112
1195
  }
1113
1196
 
1114
1197
  public allstickers(): void {
1198
+ const t1 = tstart("allstickers");
1115
1199
  // next step is to calculate all the stickers and orbits
1116
1200
  // We do enough work here to display the cube on the screen.
1117
1201
  // take our newly split base face and expand it by the rotation matrix.
1118
1202
  // this generates our full set of "stickers".
1119
1203
  this.faces = expandfaces(this.baseplanerot, this.faces);
1120
- if (this.verbose) {
1204
+ if (this.options.verbosity > 0) {
1121
1205
  console.log("# Total stickers is now " + this.faces.length);
1122
1206
  }
1123
1207
  this.facecentermass = new Array(this.faces.length);
1124
1208
  for (let i = 0; i < this.faces.length; i++) {
1125
- this.facecentermass[i] = centermassface(this.faces[i]);
1209
+ this.facecentermass[i] = this.faces[i].centermass();
1126
1210
  }
1127
1211
  // Split moveplanes into a list of parallel planes.
1128
1212
  const moveplanesets: Quat[][] = [];
1129
1213
  const moveplanenormals: Quat[] = [];
1130
1214
  // get the normals, first, from unfiltered moveplanes.
1131
- for (let i = 0; i < this.moveplanes.length; i++) {
1132
- const q = this.moveplanes[i];
1215
+ for (const q of this.moveplanes) {
1133
1216
  const qnormal = q.makenormal();
1134
1217
  let wasseen = false;
1135
- for (let j = 0; j < moveplanenormals.length; j++) {
1136
- if (qnormal.sameplane(moveplanenormals[j].makenormal())) {
1218
+ for (const moveplanenormal of moveplanenormals) {
1219
+ if (qnormal.sameplane(moveplanenormal.makenormal())) {
1137
1220
  wasseen = true;
1138
1221
  }
1139
1222
  }
@@ -1142,8 +1225,7 @@ export class PuzzleGeometry {
1142
1225
  moveplanesets.push([]);
1143
1226
  }
1144
1227
  }
1145
- for (let i = 0; i < this.moveplanes2.length; i++) {
1146
- const q = this.moveplanes2[i];
1228
+ for (const q of this.moveplanes2) {
1147
1229
  const qnormal = q.makenormal();
1148
1230
  for (let j = 0; j < moveplanenormals.length; j++) {
1149
1231
  if (qnormal.sameplane(moveplanenormals[j])) {
@@ -1167,7 +1249,7 @@ export class PuzzleGeometry {
1167
1249
  this.moveplanesets = moveplanesets;
1168
1250
  this.moveplanenormals = moveplanenormals;
1169
1251
  const sizes = moveplanesets.map((_) => _.length);
1170
- if (this.verbose) {
1252
+ if (this.options.verbosity > 0) {
1171
1253
  console.log("# Move plane sets: " + sizes);
1172
1254
  }
1173
1255
  // for each of the move planes, find the rotations that are relevant
@@ -1175,8 +1257,7 @@ export class PuzzleGeometry {
1175
1257
  for (let i = 0; i < moveplanesets.length; i++) {
1176
1258
  moverotations.push([]);
1177
1259
  }
1178
- for (let i = 0; i < this.rotations.length; i++) {
1179
- const q: Quat = this.rotations[i];
1260
+ for (const q of this.rotations) {
1180
1261
  if (Math.abs(Math.abs(q.a) - 1) < eps) {
1181
1262
  continue;
1182
1263
  }
@@ -1207,20 +1288,20 @@ export class PuzzleGeometry {
1207
1288
  }
1208
1289
  const sizes2 = moverotations.map((_) => 1 + _.length);
1209
1290
  this.movesetorders = sizes2;
1210
- const movesetgeos = [];
1291
+ const movesetgeos: [string, string, string, string, number][] = [];
1211
1292
  let gtype = "?";
1212
1293
  for (let i = 0; i < moveplanesets.length; i++) {
1213
1294
  const p0 = moveplanenormals[i];
1214
1295
  let neg = null;
1215
1296
  let pos = null;
1216
- for (let j = 0; j < this.geonormals.length; j++) {
1217
- const d = p0.dot(this.geonormals[j][0]);
1297
+ for (const geonormal of this.geonormals) {
1298
+ const d = p0.dot(geonormal[0]);
1218
1299
  if (Math.abs(d - 1) < eps) {
1219
- pos = [this.geonormals[j][1], this.geonormals[j][2]];
1220
- gtype = this.geonormals[j][2];
1300
+ pos = [geonormal[1], geonormal[2]];
1301
+ gtype = geonormal[2];
1221
1302
  } else if (Math.abs(d + 1) < eps) {
1222
- neg = [this.geonormals[j][1], this.geonormals[j][2]];
1223
- gtype = this.geonormals[j][2];
1303
+ neg = [geonormal[1], geonormal[2]];
1304
+ gtype = geonormal[2];
1224
1305
  }
1225
1306
  }
1226
1307
  if (pos === null || neg === null) {
@@ -1283,128 +1364,100 @@ export class PuzzleGeometry {
1283
1364
  // This also works for faces; no face should ever lie on a move
1284
1365
  // plane. This allows us to take a set of stickers and break
1285
1366
  // them up into cubie sets.
1286
- const cubiehash: any = {};
1287
- const facelisthash: any = {};
1288
- const cubiekey: any = {};
1289
- const cubiekeys = [];
1290
- const cubies: Quat[][][] = [];
1367
+ const facelisthash = new Map();
1291
1368
  const faces = this.faces;
1292
1369
  for (let i = 0; i < faces.length; i++) {
1293
1370
  const face = faces[i];
1294
1371
  const s = this.keyface(face);
1295
- if (!cubiehash[s]) {
1296
- cubiekey[s] = cubies.length;
1297
- cubiekeys.push(s);
1298
- cubiehash[s] = [];
1299
- facelisthash[s] = [];
1300
- cubies.push(cubiehash[s]);
1301
- }
1302
- facelisthash[s].push(i);
1303
- cubiehash[s].push(face);
1304
- // If we find a core cubie, split it up into multiple cubies,
1305
- // because ksolve doesn't handle orientations that are not
1306
- // cyclic, and the rotation group of the core is not cyclic.
1307
- if (facelisthash[s].length === this.basefacecount) {
1308
- if (this.verbose) {
1309
- console.log("# Splitting core.");
1310
- }
1311
- for (let suff = 0; suff < this.basefacecount; suff++) {
1312
- const s2 = s + " " + suff;
1313
- facelisthash[s2] = [facelisthash[s][suff]];
1314
- cubiehash[s2] = [cubiehash[s][suff]];
1315
- cubiekeys.push(s2);
1316
- cubiekey[s2] = cubies.length;
1317
- cubies.push(cubiehash[s2]);
1318
- }
1319
- cubiehash[s] = [];
1320
- cubies[cubiekey[s]] = [];
1321
- }
1322
- }
1323
- this.cubiekey = cubiekey;
1324
- this.facelisthash = facelisthash;
1325
- this.cubiekeys = cubiekeys;
1326
- if (this.verbose) {
1327
- console.log("# Cubies: " + Object.keys(cubiehash).length);
1328
- }
1329
- // Sort the faces around each corner so they are counterclockwise. Only
1330
- // relevant for cubies that actually are corners (three or more
1331
- // faces). In general cubies might have many faces; for icosohedrons
1332
- // there are five faces on the corner cubies.
1333
- this.cubies = cubies;
1334
- for (let k = 0; k < cubies.length; k++) {
1335
- const cubie = cubies[k];
1336
- if (cubie.length < 2) {
1337
- continue;
1372
+ if (!facelisthash.get(s)) {
1373
+ facelisthash.set(s, [i]);
1374
+ } else {
1375
+ const arr = facelisthash.get(s)!;
1376
+ arr.push(i);
1377
+ // If we find a core cubie, split it up into multiple cubies,
1378
+ // because ksolve doesn't handle orientations that are not
1379
+ // cyclic, and the rotation group of the core is not cyclic.
1380
+ if (arr.length === this.baseFaceCount) {
1381
+ if (this.options.verbosity > 0) {
1382
+ console.log("# Splitting core.");
1383
+ }
1384
+ for (let suff = 0; suff < arr.length; suff++) {
1385
+ const s2 = s + " " + suff;
1386
+ facelisthash.set(s2, [arr[suff]]);
1387
+ }
1388
+ }
1338
1389
  }
1339
- if (cubie.length === this.basefacecount) {
1340
- // looks like core? don't sort
1390
+ }
1391
+ this.facelisthash = facelisthash;
1392
+ if (this.options.verbosity > 0) {
1393
+ console.log("# Cubies: " + facelisthash.size);
1394
+ }
1395
+ const cubies: number[][] = [];
1396
+ const facetocubie = [];
1397
+ const facetoord = [];
1398
+ for (const facelist of facelisthash.values()) {
1399
+ if (facelist.length === this.baseFaceCount) {
1400
+ // this is the original "cubie" of a split core; we ignore it.
1341
1401
  continue;
1342
1402
  }
1343
- if (cubie.length > 5) {
1344
- throw new Error(
1345
- "Bad math; too many faces on this cubie " + cubie.length,
1346
- );
1347
- }
1348
- const cm = cubie.map((_) => centermassface(_));
1349
- const s = this.keyface2(cm[0]);
1350
- const facelist = facelisthash[s];
1351
- const cmall = centermassface(cm);
1352
- for (let looplimit = 0; cubie.length > 2; looplimit++) {
1353
- let changed = false;
1354
- for (let i = 0; i < cubie.length; i++) {
1355
- const j = (i + 1) % cubie.length;
1356
- // var ttt = cmall.dot(cm[i].cross(cm[j])) ; // TODO
1357
- if (cmall.dot(cm[i].cross(cm[j])) < 0) {
1358
- const t = cubie[i];
1359
- cubie[i] = cubie[j];
1360
- cubie[j] = t;
1361
- const u = cm[i];
1362
- cm[i] = cm[j];
1363
- cm[j] = u;
1364
- const v = facelist[i];
1365
- facelist[i] = facelist[j];
1366
- facelist[j] = v;
1367
- changed = true;
1403
+ // Sort the faces around each corner so they are counterclockwise. Only
1404
+ // relevant for cubies that actually are corners (three or more
1405
+ // faces). In general cubies might have many faces; for icosohedrons
1406
+ // there are five faces on the corner cubies.
1407
+ if (facelist.length > 1) {
1408
+ const cm = facelist.map((_: number) => faces[_].centermass());
1409
+ const cmall = centermassface(cm);
1410
+ for (let looplimit = 0; facelist.length > 2; looplimit++) {
1411
+ let changed = false;
1412
+ for (let i = 0; i < facelist.length; i++) {
1413
+ const j = (i + 1) % facelist.length;
1414
+ // var ttt = cmall.dot(cm[i].cross(cm[j])) ; // TODO
1415
+ if (cmall.dot(cm[i].cross(cm[j])) < 0) {
1416
+ const u = cm[i];
1417
+ cm[i] = cm[j];
1418
+ cm[j] = u;
1419
+ const v = facelist[i];
1420
+ facelist[i] = facelist[j];
1421
+ facelist[j] = v;
1422
+ changed = true;
1423
+ }
1424
+ }
1425
+ if (!changed) {
1426
+ break;
1427
+ }
1428
+ if (looplimit > 1000) {
1429
+ throw new Error("Bad epsilon math; too close to border");
1368
1430
  }
1369
1431
  }
1370
- if (!changed) {
1371
- break;
1372
- }
1373
- if (looplimit > 1000) {
1374
- throw new Error("Bad epsilon math; too close to border");
1375
- }
1376
- }
1377
- let mini = 0;
1378
- let minf = this.findface(cubie[mini]);
1379
- for (let i = 1; i < cubie.length; i++) {
1380
- const temp = this.findface(cubie[i]);
1381
- if (
1382
- this.faceprecedence[this.getfaceindex(temp)] <
1383
- this.faceprecedence[this.getfaceindex(minf)]
1384
- ) {
1385
- mini = i;
1386
- minf = temp;
1432
+ let mini = 0;
1433
+ let minf = facelist[mini];
1434
+ for (let i = 1; i < facelist.length; i++) {
1435
+ const temp = facelist[i];
1436
+ if (
1437
+ this.faceprecedence[this.getfaceindex(temp)] <
1438
+ this.faceprecedence[this.getfaceindex(minf)]
1439
+ ) {
1440
+ mini = i;
1441
+ minf = temp;
1442
+ }
1387
1443
  }
1388
- }
1389
- if (mini !== 0) {
1390
- const ocubie = cubie.slice();
1391
- const ofacelist = facelist.slice();
1392
- for (let i = 0; i < cubie.length; i++) {
1393
- cubie[i] = ocubie[(mini + i) % cubie.length];
1394
- facelist[i] = ofacelist[(mini + i) % cubie.length];
1444
+ if (mini !== 0) {
1445
+ const ofacelist = facelist.slice();
1446
+ for (let i = 0; i < facelist.length; i++) {
1447
+ facelist[i] = ofacelist[(mini + i) % facelist.length];
1448
+ }
1395
1449
  }
1396
1450
  }
1397
- }
1398
- // Build an array that takes each face to a cubie ordinal and a
1399
- // face number.
1400
- const facetocubies = [];
1401
- for (let i = 0; i < cubies.length; i++) {
1402
- const facelist = facelisthash[cubiekeys[i]];
1403
1451
  for (let j = 0; j < facelist.length; j++) {
1404
- facetocubies[facelist[j]] = [i, j];
1452
+ const k = facelist[j];
1453
+ facetocubie[k] = cubies.length;
1454
+ facetoord[k] = j;
1405
1455
  }
1456
+ cubies.push(facelist);
1406
1457
  }
1407
- this.facetocubies = facetocubies;
1458
+ this.cubies = cubies;
1459
+ this.facetocubie = facetocubie;
1460
+ this.facetoord = facetoord;
1408
1461
  // Calculate the orbits of each cubie. Assumes we do all moves.
1409
1462
  // Also calculates which cubies are identical.
1410
1463
  const typenames = ["?", "CENTERS", "EDGES", "CORNERS", "C4RNER", "C5RNER"];
@@ -1416,14 +1469,11 @@ export class PuzzleGeometry {
1416
1469
  const cubiesetnums = [];
1417
1470
  const cubieordnums = [];
1418
1471
  const cubieords = [];
1419
- // var cubiesetnumhash = {} ; // TODO
1420
1472
  const cubievaluemap = [];
1421
1473
  // Later we will make this smarter to use a get color for face function
1422
1474
  // so we support puzzles with multiple faces the same color
1423
1475
  const getcolorkey = (cubienum: number): string => {
1424
- return cubies[cubienum]
1425
- .map((_) => this.getfaceindex(this.findface(_)))
1426
- .join(" ");
1476
+ return cubies[cubienum].map((_) => this.getfaceindex(_)).join(" ");
1427
1477
  };
1428
1478
  const cubiesetcubies: any = [];
1429
1479
  for (let i = 0; i < cubies.length; i++) {
@@ -1441,7 +1491,7 @@ export class PuzzleGeometry {
1441
1491
  const facecnt = cubie.length;
1442
1492
  const typectr = cubietypecounts[facecnt]++;
1443
1493
  let typename = typenames[facecnt];
1444
- if (typename === undefined || facecnt === this.basefacecount) {
1494
+ if (typename === undefined || facecnt === this.baseFaceCount) {
1445
1495
  typename = "CORE";
1446
1496
  }
1447
1497
  typename = typename + (typectr === 0 ? "" : typectr + 1);
@@ -1461,12 +1511,10 @@ export class PuzzleGeometry {
1461
1511
  cubiesetcubies[cubiesetnum].push(cind);
1462
1512
  cubieordnums[cind] = cubieords[cubiesetnum]++;
1463
1513
  if (queue.length < this.rotations.length) {
1464
- const cm = centermassface(cubies[cind][0]);
1465
- for (let j = 0; j < moverotations.length; j++) {
1514
+ const cm = this.facecentermass[cubies[cind][0]];
1515
+ for (const moverotation of moverotations) {
1466
1516
  const tq =
1467
- this.facetocubies[
1468
- this.findface2(cm.rotatepoint(moverotations[j][0]))
1469
- ][0];
1517
+ this.facetocubie[this.findface(cm.rotatepoint(moverotation[0]))];
1470
1518
  if (!seen[tq]) {
1471
1519
  queue.push(tq);
1472
1520
  seen[tq] = true;
@@ -1474,21 +1522,6 @@ export class PuzzleGeometry {
1474
1522
  }
1475
1523
  }
1476
1524
  }
1477
- const that = this;
1478
- queue.sort(function (a: number, b: number): number {
1479
- if (that.cubiekeys[a] < that.cubiekeys[b]) {
1480
- return 1;
1481
- } else if (that.cubiekeys[a] > that.cubiekeys[b]) {
1482
- return -1;
1483
- } else {
1484
- return 0;
1485
- }
1486
- });
1487
- for (let i = 0; i < queue.length; i++) {
1488
- if (i > 1000000) {
1489
- cubieordnums[queue[i]] = i;
1490
- }
1491
- }
1492
1525
  cubiesetnum++;
1493
1526
  }
1494
1527
  if (
@@ -1515,32 +1548,27 @@ export class PuzzleGeometry {
1515
1548
  ["U", "L", "F", "R", "B", "D"],
1516
1549
  ];
1517
1550
  const reidmap: { [key: number]: number } = {};
1518
- for (let i = 0; i < reidorder.length; i++) {
1519
- for (let j = 0; j < reidorder[i].length; j++) {
1551
+ for (const cubie of reidorder) {
1552
+ for (let j = 0; j < cubie.length; j++) {
1520
1553
  let mask = 0;
1521
- for (let k = 0; k < reidorder[i][j].length; k++) {
1522
- mask |= 1 << (reidorder[i][j].charCodeAt(k) - 65);
1554
+ for (let k = 0; k < cubie[j].length; k++) {
1555
+ mask |= 1 << (cubie[j].charCodeAt(k) - 65);
1523
1556
  }
1524
1557
  reidmap[mask] = j;
1525
1558
  }
1526
1559
  }
1527
- for (let i = 0; i < cubiesetnum; i++) {
1528
- for (let j = 0; j < cubiesetcubies[i].length; j++) {
1529
- const cubienum = cubiesetcubies[i][j];
1560
+ for (const cubieset of cubiesetcubies) {
1561
+ for (const cubienum of cubieset) {
1530
1562
  let mask = 0;
1531
- for (let k = 0; k < cubies[cubienum].length; k++) {
1563
+ for (const cubie of cubies[cubienum]) {
1532
1564
  mask |=
1533
1565
  1 <<
1534
- (this.facenames[
1535
- this.getfaceindex(this.findface(cubies[cubienum][k]))
1536
- ][1].charCodeAt(0) -
1537
- 65);
1566
+ (this.facenames[this.getfaceindex(cubie)][1].charCodeAt(0) - 65);
1538
1567
  }
1539
1568
  cubieordnums[cubienum] = reidmap[mask];
1540
1569
  }
1541
1570
  }
1542
1571
  }
1543
- this.orbits = cubieords.length;
1544
1572
  this.cubiesetnums = cubiesetnums;
1545
1573
  this.cubieordnums = cubieordnums;
1546
1574
  this.cubiesetnames = cubiesetnames;
@@ -1549,12 +1577,12 @@ export class PuzzleGeometry {
1549
1577
  this.cubievaluemap = cubievaluemap;
1550
1578
  this.cubiesetcubies = cubiesetcubies;
1551
1579
  // if we fix a cubie, find a cubie to fix
1552
- if (this.fixPiece !== "") {
1580
+ if (this.options.fixedPieceType !== null) {
1553
1581
  for (let i = 0; i < cubies.length; i++) {
1554
1582
  if (
1555
- (this.fixPiece === "v" && cubies[i].length > 2) ||
1556
- (this.fixPiece === "e" && cubies[i].length === 2) ||
1557
- (this.fixPiece === "f" && cubies[i].length === 1)
1583
+ (this.options.fixedPieceType === "v" && cubies[i].length > 2) ||
1584
+ (this.options.fixedPieceType === "e" && cubies[i].length === 2) ||
1585
+ (this.options.fixedPieceType === "f" && cubies[i].length === 1)
1558
1586
  ) {
1559
1587
  this.fixedCubie = i;
1560
1588
  break;
@@ -1562,14 +1590,17 @@ export class PuzzleGeometry {
1562
1590
  }
1563
1591
  if (this.fixedCubie < 0) {
1564
1592
  throw new Error(
1565
- "Could not find a cubie of type " + this.fixPiece + " to fix.",
1593
+ "Could not find a cubie of type " +
1594
+ this.options.fixedPieceType +
1595
+ " to fix.",
1566
1596
  );
1567
1597
  }
1568
1598
  }
1569
1599
  // show the orbits
1570
- if (this.verbose) {
1600
+ if (this.options.verbosity > 0) {
1571
1601
  console.log("# Cubie orbit sizes " + cubieords);
1572
1602
  }
1603
+ tend(t1);
1573
1604
  }
1574
1605
 
1575
1606
  public unswizzle(mv: Move): string {
@@ -1582,7 +1613,7 @@ export class PuzzleGeometry {
1582
1613
 
1583
1614
  // We use an extremely permissive parse here; any character but
1584
1615
  // digits are allowed in a family name.
1585
- public stringToBlockMove(mv: string): Move {
1616
+ private stringToBlockMove(mv: string): Move {
1586
1617
  // parse a move from the command line
1587
1618
  const re = RegExp("^(([0-9]+)-)?([0-9]+)?([^0-9]+)([0-9]+'?)?$");
1588
1619
  const p = mv.match(re);
@@ -1613,7 +1644,9 @@ export class PuzzleGeometry {
1613
1644
  return new Move(new QuantumMove(grip, hislice, loslice), amount);
1614
1645
  }
1615
1646
 
1616
- public parseMove(move: Move): any {
1647
+ public parseMove(
1648
+ move: Move,
1649
+ ): [string | undefined, number, number, number, boolean, number] {
1617
1650
  const bm = this.notationMapper.notationToInternal(move); // pluggable notation
1618
1651
  if (bm === null) {
1619
1652
  throw new Error("Bad move " + move.family);
@@ -1707,17 +1740,19 @@ export class PuzzleGeometry {
1707
1740
  "! full puzzle rotations must be specified with v suffix.",
1708
1741
  );
1709
1742
  }
1710
- const r = [undefined, msi, loslice, hislice, firstgrip, move.amount];
1711
- return r;
1743
+ return [undefined, msi, loslice, hislice, firstgrip, move.amount];
1712
1744
  }
1713
1745
 
1714
- public parsemove(mv: string): any {
1746
+ private parsemove(
1747
+ mv: string,
1748
+ ): [string | undefined, number, number, number, boolean, number] {
1715
1749
  const r = this.parseMove(this.stringToBlockMove(mv));
1716
1750
  r[0] = mv;
1717
1751
  return r;
1718
1752
  }
1719
1753
 
1720
1754
  public genperms(): void {
1755
+ const t1 = tstart("genperms");
1721
1756
  // generate permutations for moves
1722
1757
  if (this.cmovesbyslice.length > 0) {
1723
1758
  // did this already?
@@ -1727,18 +1762,17 @@ export class PuzzleGeometry {
1727
1762
  // if orientCenters is set, we find all cubies that have only one
1728
1763
  // sticker and that sticker is in the center of a face, and we
1729
1764
  // introduce duplicate stickers so we can orient them properly.
1730
- if (this.orientCenters) {
1765
+ if (this.options.orientCenters) {
1731
1766
  for (let k = 0; k < this.cubies.length; k++) {
1732
1767
  if (this.cubies[k].length === 1) {
1733
- const kk = this.findface(this.cubies[k][0]);
1768
+ const kk = this.cubies[k][0];
1734
1769
  const i = this.getfaceindex(kk);
1735
1770
  if (
1736
- centermassface(this.basefaces[i]).dist(this.facecentermass[kk]) <
1737
- eps
1771
+ this.basefaces[i].centermass().dist(this.facecentermass[kk]) < eps
1738
1772
  ) {
1739
1773
  const o = this.basefaces[i].length;
1740
- for (let m = 0; m < o; m++) {
1741
- this.cubies[k].push(this.cubies[k][0]);
1774
+ for (let m = 1; m < o; m++) {
1775
+ this.cubies[k].push(this.cubies[k][m - 1]);
1742
1776
  }
1743
1777
  this.duplicatedFaces[kk] = o;
1744
1778
  this.duplicatedCubies[k] = o;
@@ -1784,7 +1818,7 @@ export class PuzzleGeometry {
1784
1818
  if (slicenum[i] < 0) {
1785
1819
  continue;
1786
1820
  }
1787
- const b = this.facetocubies[i].slice();
1821
+ const b = [this.facetocubie[i], this.facetoord[i]];
1788
1822
  let cm = this.facecentermass[i];
1789
1823
  const ocm = cm;
1790
1824
  let fi2 = i;
@@ -1795,9 +1829,8 @@ export class PuzzleGeometry {
1795
1829
  if (cm2.dist(ocm) < eps) {
1796
1830
  break;
1797
1831
  }
1798
- fi2 = this.findface2(cm2);
1799
- const c = this.facetocubies[fi2];
1800
- b.push(c[0], c[1]);
1832
+ fi2 = this.findface(cm2);
1833
+ b.push(this.facetocubie[fi2], this.facetoord[fi2]);
1801
1834
  cm = cm2;
1802
1835
  }
1803
1836
  // If an oriented center is moving, we need to figure out
@@ -1822,23 +1855,22 @@ export class PuzzleGeometry {
1822
1855
  // center itself.
1823
1856
  if (
1824
1857
  b.length > 2 &&
1825
- this.orientCenters &&
1826
- (this.cubies[b[0]].length === 1 ||
1827
- this.cubies[b[0]][0] === this.cubies[b[0]][1])
1858
+ this.options.orientCenters &&
1859
+ (this.cubies[b[0]].length === 1 || this.duplicatedCubies[b[0]] > 1)
1828
1860
  ) {
1829
1861
  // is this a real center cubie, around an axis?
1830
1862
  if (
1831
1863
  this.facecentermass[i].dist(
1832
- centermassface(this.basefaces[this.getfaceindex(i)]),
1864
+ this.basefaces[this.getfaceindex(i)].centermass(),
1833
1865
  ) < eps
1834
1866
  ) {
1835
1867
  // how does remapping of the face/point set map to the original?
1836
- let face1 = this.cubies[b[0]][0];
1868
+ let face1 = this.faces[this.cubies[b[0]][0]];
1837
1869
  for (let ii = 0; ii < b.length; ii += 2) {
1838
- const face0 = this.cubies[b[ii]][0];
1870
+ const face0 = this.faces[this.cubies[b[ii]][0]];
1839
1871
  let o = -1;
1840
1872
  for (let jj = 0; jj < face1.length; jj++) {
1841
- if (face0[jj].dist(face1[0]) < eps) {
1873
+ if (face0.get(jj).dist(face1.get(0)) < eps) {
1842
1874
  o = jj;
1843
1875
  break;
1844
1876
  }
@@ -1849,7 +1881,7 @@ export class PuzzleGeometry {
1849
1881
  );
1850
1882
  } else {
1851
1883
  b[ii + 1] = o;
1852
- face1 = this.moverotations[k][0].rotateface(face1);
1884
+ face1 = face1.rotate(this.moverotations[k][0]);
1853
1885
  }
1854
1886
  }
1855
1887
  }
@@ -1857,7 +1889,7 @@ export class PuzzleGeometry {
1857
1889
  // b.length == 2 means a sticker is spinning in place.
1858
1890
  // in this case we add duplicate stickers
1859
1891
  // so that we can make it animate properly in a 3D world.
1860
- if (b.length === 2 && this.orientCenters) {
1892
+ if (b.length === 2 && this.options.orientCenters) {
1861
1893
  for (let ii = 1; ii < this.movesetorders[k]; ii++) {
1862
1894
  if (sc === 0) {
1863
1895
  b.push(b[0], ii);
@@ -1873,38 +1905,41 @@ export class PuzzleGeometry {
1873
1905
  if (b.length !== 2 * this.movesetorders[k]) {
1874
1906
  throw new Error("Bad length in perm gen");
1875
1907
  }
1876
- for (let j = 0; j < b.length; j++) {
1877
- axiscmoves[sc].push(b[j]);
1908
+ for (const v of b) {
1909
+ axiscmoves[sc].push(v);
1878
1910
  }
1879
1911
  }
1880
1912
  for (let j = 0; j < b.length; j += 2) {
1881
1913
  cubiedone[b[j]] = true;
1882
1914
  }
1883
1915
  }
1916
+ for (let kk = 0; kk < axiscmoves.length; kk++) {
1917
+ axiscmoves[kk] = axiscmoves[kk].slice();
1918
+ }
1884
1919
  cmovesbyslice.push(axiscmoves);
1885
1920
  }
1886
1921
  this.cmovesbyslice = cmovesbyslice;
1887
- if (this.movelist !== undefined) {
1888
- const parsedmovelist: any[] = [];
1922
+ if (this.options.moveList) {
1923
+ const parsedmovelist: [
1924
+ string | undefined,
1925
+ number,
1926
+ number,
1927
+ number,
1928
+ boolean,
1929
+ number,
1930
+ ][] = [];
1889
1931
  // make sure the movelist makes sense based on the geos.
1890
- for (let i = 0; i < this.movelist.length; i++) {
1891
- parsedmovelist.push(this.parsemove(this.movelist[i]));
1932
+ for (const moveString of this.options.moveList) {
1933
+ parsedmovelist.push(this.parsemove(moveString));
1892
1934
  }
1893
1935
  this.parsedmovelist = parsedmovelist;
1894
1936
  }
1895
- this.facelisthash = null;
1937
+ this.facelisthash.clear();
1896
1938
  this.facecentermass = [];
1897
- this.cubiekey = [];
1939
+ tend(t1);
1898
1940
  }
1899
1941
 
1900
- public getfaces(): number[][][] {
1901
- // get the faces for 3d.
1902
- return this.faces.map((_) => {
1903
- return _.map((__) => [__.b, __.c, __.d]);
1904
- });
1905
- }
1906
-
1907
- public getboundarygeometry(): any {
1942
+ private getboundarygeometry(): any {
1908
1943
  // get the boundary geometry
1909
1944
  return {
1910
1945
  baseplanes: this.baseplanes,
@@ -1916,16 +1951,15 @@ export class PuzzleGeometry {
1916
1951
  };
1917
1952
  }
1918
1953
 
1919
- public getmovesets(k: number): any {
1954
+ private getmovesets(k: number): any {
1920
1955
  // get the move sets we support based on slices
1921
1956
  // for even values we omit the middle "slice". This isn't perfect
1922
1957
  // but it is what we do for now.
1923
1958
  // if there was a move list specified, pull values from that
1924
1959
  const slices = this.moveplanesets[k].length;
1925
- let r = [];
1960
+ let r: any[] = [];
1926
1961
  if (this.parsedmovelist !== undefined) {
1927
- for (let i = 0; i < this.parsedmovelist.length; i++) {
1928
- const parsedmove = this.parsedmovelist[i];
1962
+ for (const parsedmove of this.parsedmovelist) {
1929
1963
  if (parsedmove[1] !== k) {
1930
1964
  continue;
1931
1965
  }
@@ -1936,19 +1970,19 @@ export class PuzzleGeometry {
1936
1970
  }
1937
1971
  r.push(parsedmove[5]);
1938
1972
  }
1939
- } else if (this.vertexmoves && !this.allmoves) {
1973
+ } else if (this.options.vertexMoves && !this.options.allMoves) {
1940
1974
  const msg = this.movesetgeos[k];
1941
1975
  if (msg[1] !== msg[3]) {
1942
1976
  for (let i = 0; i < slices; i++) {
1943
1977
  if (msg[1] !== "v") {
1944
- if (this.outerblockmoves) {
1978
+ if (this.options.outerBlockMoves) {
1945
1979
  r.push([i + 1, slices]);
1946
1980
  } else {
1947
1981
  r.push([i + 1]);
1948
1982
  }
1949
1983
  r.push(1);
1950
1984
  } else {
1951
- if (this.outerblockmoves) {
1985
+ if (this.options.outerBlockMoves) {
1952
1986
  r.push([0, i]);
1953
1987
  } else {
1954
1988
  r.push([i, i]);
@@ -1959,10 +1993,10 @@ export class PuzzleGeometry {
1959
1993
  }
1960
1994
  } else {
1961
1995
  for (let i = 0; i <= slices; i++) {
1962
- if (!this.allmoves && i + i === slices) {
1996
+ if (!this.options.allMoves && i + i === slices) {
1963
1997
  continue;
1964
1998
  }
1965
- if (this.outerblockmoves) {
1999
+ if (this.options.outerBlockMoves) {
1966
2000
  if (i + i > slices) {
1967
2001
  r.push([i, slices]);
1968
2002
  } else {
@@ -1975,7 +2009,7 @@ export class PuzzleGeometry {
1975
2009
  }
1976
2010
  }
1977
2011
  if (this.fixedCubie >= 0) {
1978
- const dep = +this.cubiekeys[this.fixedCubie].trim().split(" ")[k];
2012
+ const dep = this.keyface3(this.faces[this.cubies[this.fixedCubie][0]])[k];
1979
2013
  const newr = [];
1980
2014
  for (let i = 0; i < r.length; i += 2) {
1981
2015
  let o = r[i];
@@ -2006,47 +2040,44 @@ export class PuzzleGeometry {
2006
2040
  }
2007
2041
  r = newr;
2008
2042
  }
2043
+ // TODO
2044
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
2009
2045
  return r;
2010
2046
  }
2011
2047
 
2012
- public graybyori(cubie: number): boolean {
2048
+ private graybyori(cubie: number): boolean {
2013
2049
  let ori = this.cubies[cubie].length;
2014
2050
  if (this.duplicatedCubies[cubie]) {
2015
2051
  ori = 1;
2016
2052
  }
2017
2053
  return (
2018
- (ori === 1 && (this.graycenters || !this.centersets)) ||
2019
- (ori === 2 && (this.grayedges || !this.edgesets)) ||
2020
- (ori > 2 && (this.graycorners || !this.cornersets))
2054
+ (ori === 1 &&
2055
+ (this.options.grayCenters || !this.options.includeCenterOrbits)) ||
2056
+ (ori === 2 &&
2057
+ (this.options.grayEdges || !this.options.includeEdgeOrbits)) ||
2058
+ (ori > 2 &&
2059
+ (this.options.grayCorners || !this.options.includeCornerOrbits))
2021
2060
  );
2022
2061
  }
2023
2062
 
2024
- public skipbyori(cubie: number): boolean {
2063
+ private skipbyori(cubie: number): boolean {
2025
2064
  let ori = this.cubies[cubie].length;
2026
2065
  if (this.duplicatedCubies[cubie]) {
2027
2066
  ori = 1;
2028
2067
  }
2029
2068
  return (
2030
- (ori === 1 && !this.centersets) ||
2031
- (ori === 2 && !this.edgesets) ||
2032
- (ori > 2 && !this.cornersets)
2069
+ (ori === 1 && !this.options.includeCenterOrbits) ||
2070
+ (ori === 2 && !this.options.includeEdgeOrbits) ||
2071
+ (ori > 2 && !this.options.includeCornerOrbits)
2033
2072
  );
2034
2073
  }
2035
2074
 
2036
- public skipcubie(fi: number): boolean {
2075
+ private skipcubie(fi: number): boolean {
2037
2076
  return this.skipbyori(fi);
2038
2077
  }
2039
2078
 
2040
- public skipset(set: number[]): boolean {
2041
- if (set.length === 0) {
2042
- return true;
2043
- }
2044
- const fi = set[0];
2045
- return this.skipbyori(this.facetocubies[fi][0]);
2046
- }
2047
-
2048
- public header(comment: string): string {
2049
- return comment + copyright + "\n" + comment + this.args + "\n";
2079
+ private header(comment: string): string {
2080
+ return comment + copyright + "\n" + comment + "\n";
2050
2081
  }
2051
2082
 
2052
2083
  public writegap(): string {
@@ -2078,6 +2109,8 @@ export class PuzzleGeometry {
2078
2109
  ip.map((_) => "[" + _.map((__) => __ + 1).join(",") + "]").join(",") +
2079
2110
  "];",
2080
2111
  );
2112
+ r.push("# Size(Group(Gen));");
2113
+ r.push("# Size(Stabilizer(Group(Gen), ip, OnTuplesSets));");
2081
2114
  r.push("");
2082
2115
  return this.header("# ") + r.join("\n");
2083
2116
  }
@@ -2089,9 +2122,15 @@ export class PuzzleGeometry {
2089
2122
  );
2090
2123
  }
2091
2124
 
2092
- public writekpuzzle(fortwisty: boolean = true): PGVendoredKPuzzleDefinition {
2093
- const od = this.getOrbitsDef(fortwisty);
2094
- const r = od.toKpuzzle() as PGVendoredKPuzzleDefinition;
2125
+ public writekpuzzle(
2126
+ fortwisty: boolean = true,
2127
+ includemoves: boolean = true,
2128
+ ): KPuzzleDefinition {
2129
+ const od = this.getOrbitsDef(fortwisty, includemoves);
2130
+ const r = od.toKPuzzle(includemoves);
2131
+ if (!r) {
2132
+ throw new Error("Missing definition!");
2133
+ }
2095
2134
  r.moveNotation = new PGNotation(this, od);
2096
2135
  return r;
2097
2136
  }
@@ -2103,13 +2142,13 @@ export class PuzzleGeometry {
2103
2142
  axiscmoves: number[][],
2104
2143
  setmoves: number[] | undefined,
2105
2144
  movesetorder: number,
2106
- ): Transformation {
2107
- const moveorbits: Orbit[] = [];
2145
+ ): PGTransform {
2146
+ const moveorbits: PGOrbit[] = [];
2108
2147
  const perms = [];
2109
2148
  const oris = [];
2110
- for (let ii = 0; ii < this.cubiesetnames.length; ii++) {
2111
- perms.push(iota(this.cubieords[ii]));
2112
- oris.push(zeros(this.cubieords[ii]));
2149
+ for (const len of this.cubieords) {
2150
+ perms.push(iota(len));
2151
+ oris.push(zeros(len));
2113
2152
  }
2114
2153
  for (let m = moverange[0]; m <= moverange[1]; m++) {
2115
2154
  const slicecmoves = axiscmoves[m];
@@ -2127,13 +2166,13 @@ export class PuzzleGeometry {
2127
2166
  }
2128
2167
  if (perms[setnum] === iota(this.cubieords[setnum])) {
2129
2168
  perms[setnum] = perms[setnum].slice();
2130
- if (this.orbitoris[setnum] > 1 && !this.killorientation) {
2169
+ if (this.orbitoris[setnum] > 1 && !this.options.fixedOrientation) {
2131
2170
  oris[setnum] = oris[setnum].slice();
2132
2171
  }
2133
2172
  }
2134
2173
  for (let ii = 0; ii < mperm.length; ii += 2) {
2135
2174
  perms[setnum][mperm[(ii + inc) % mperm.length]] = mperm[ii];
2136
- if (this.orbitoris[setnum] > 1 && !this.killorientation) {
2175
+ if (this.orbitoris[setnum] > 1 && !this.options.fixedOrientation) {
2137
2176
  oris[setnum][mperm[ii]] =
2138
2177
  (mperm[(ii + oinc) % mperm.length] -
2139
2178
  mperm[(ii + 1) % mperm.length] +
@@ -2143,19 +2182,19 @@ export class PuzzleGeometry {
2143
2182
  }
2144
2183
  }
2145
2184
  }
2146
- let lastId = new Orbit(iota(24), zeros(24), 1);
2185
+ let lastId = new PGOrbit(iota(24), zeros(24), 1);
2147
2186
  for (let ii = 0; ii < this.cubiesetnames.length; ii++) {
2148
2187
  if (setmoves && !setmoves[ii]) {
2149
2188
  continue;
2150
2189
  }
2151
- if (this.orbitoris[ii] === 1 || this.killorientation) {
2190
+ if (this.orbitoris[ii] === 1 || this.options.fixedOrientation) {
2152
2191
  if (perms[ii] === iota(lastId.perm.length)) {
2153
2192
  if (perms[ii] !== lastId.perm) {
2154
- lastId = new Orbit(perms[ii], oris[ii], 1);
2193
+ lastId = new PGOrbit(perms[ii], oris[ii], 1);
2155
2194
  }
2156
2195
  moveorbits.push(lastId);
2157
2196
  } else {
2158
- moveorbits.push(new Orbit(perms[ii], oris[ii], 1));
2197
+ moveorbits.push(new PGOrbit(perms[ii], oris[ii], 1));
2159
2198
  }
2160
2199
  } else {
2161
2200
  const no = new Array<number>(oris[ii].length);
@@ -2163,26 +2202,26 @@ export class PuzzleGeometry {
2163
2202
  for (let jj = 0; jj < perms[ii].length; jj++) {
2164
2203
  no[jj] = oris[ii][perms[ii][jj]];
2165
2204
  }
2166
- moveorbits.push(new Orbit(perms[ii], no, this.orbitoris[ii]));
2205
+ moveorbits.push(new PGOrbit(perms[ii], no, this.orbitoris[ii]));
2167
2206
  }
2168
2207
  }
2169
- let mv = new Transformation(moveorbits);
2208
+ let mv = new PGTransform(moveorbits);
2170
2209
  if (amount !== 1) {
2171
2210
  mv = mv.mulScalar(amount);
2172
2211
  }
2173
2212
  return mv;
2174
2213
  }
2175
2214
 
2176
- public omitSet(name: string): boolean {
2177
- for (let k = 0; k < this.omitsets.length; k++) {
2178
- if (this.omitsets[k] === name) {
2215
+ private omitSet(name: string): boolean {
2216
+ for (const excludedSet of this.options.excludeOrbits) {
2217
+ if (excludedSet === name) {
2179
2218
  return true;
2180
2219
  }
2181
2220
  }
2182
2221
  return false;
2183
2222
  }
2184
2223
 
2185
- public diffmvsets(a: any[], b: any[], slices: number, neg: boolean) {
2224
+ private diffmvsets(a: any[], b: any[], slices: number, neg: boolean) {
2186
2225
  for (let i = 0; i < a.length; i += 2) {
2187
2226
  let found = false;
2188
2227
  for (let j = 0; !found && j < b.length; j += 2) {
@@ -2211,7 +2250,11 @@ export class PuzzleGeometry {
2211
2250
  return false;
2212
2251
  }
2213
2252
 
2214
- public getOrbitsDef(fortwisty: boolean): OrbitsDef {
2253
+ // TODO: This is only public for testing; can we make it private again?
2254
+ public getOrbitsDef(
2255
+ fortwisty: boolean,
2256
+ includemoves: boolean = true,
2257
+ ): PGOrbitsDef {
2215
2258
  // generate a representation of the puzzle
2216
2259
  const setmoves = [];
2217
2260
  if (fortwisty) {
@@ -2220,7 +2263,7 @@ export class PuzzleGeometry {
2220
2263
  }
2221
2264
  }
2222
2265
  const setnames: string[] = [];
2223
- const setdefs: OrbitDef[] = [];
2266
+ const setdefs: PGOrbitDef[] = [];
2224
2267
  // if both a movelist and rotations are needed, eliminate rotations
2225
2268
  // that do not preserve the movelist.
2226
2269
  const mps = [];
@@ -2228,13 +2271,13 @@ export class PuzzleGeometry {
2228
2271
  for (let k = 0; k < this.moveplanesets.length; k++) {
2229
2272
  const moveset = this.getmovesets(k);
2230
2273
  mps.push(moveset);
2231
- if (this.addrotations) {
2274
+ if (this.options.addRotations) {
2232
2275
  addrot.push(1);
2233
2276
  } else {
2234
2277
  addrot.push(0);
2235
2278
  }
2236
2279
  }
2237
- if (this.movelist && this.addrotations) {
2280
+ if (this.options.moveList && this.options.addRotations) {
2238
2281
  for (let i = 0; i < this.moverotations.length; i++) {
2239
2282
  addrot[i] = 0;
2240
2283
  }
@@ -2249,22 +2292,20 @@ export class PuzzleGeometry {
2249
2292
  }
2250
2293
  let found = -1;
2251
2294
  let neg = false;
2252
- for (
2253
- let j = 0;
2254
- found < 0 && j < this.moveplanenormals.length;
2255
- j++
2256
- ) {
2295
+ for (let j = 0; j < this.moveplanenormals.length; j++) {
2257
2296
  if (nn.dist(this.moveplanenormals[j]) < eps) {
2258
2297
  found = j;
2298
+ break;
2259
2299
  } else if (nn.dist(this.moveplanenormals[j].smul(-1)) < eps) {
2260
2300
  found = j;
2261
2301
  neg = true;
2302
+ break;
2262
2303
  }
2263
2304
  }
2264
2305
  if (found < 0) {
2265
2306
  throw new Error("Could not find rotation");
2266
2307
  }
2267
- let cmp = mps[found];
2308
+ const cmp = mps[found];
2268
2309
  if (
2269
2310
  cmp.length !== mps[k].length ||
2270
2311
  this.moveplanesets[k].length !==
@@ -2345,13 +2386,13 @@ export class PuzzleGeometry {
2345
2386
  }
2346
2387
  setnames.push(this.cubiesetnames[i]);
2347
2388
  setdefs.push(
2348
- new OrbitDef(
2389
+ new PGOrbitDef(
2349
2390
  this.cubieords[i],
2350
- this.killorientation ? 1 : this.orbitoris[i],
2391
+ this.options.fixedOrientation ? 1 : this.orbitoris[i],
2351
2392
  ),
2352
2393
  );
2353
2394
  }
2354
- const solved: Orbit[] = [];
2395
+ const solved: PGOrbit[] = [];
2355
2396
  for (let i = 0; i < this.cubiesetnames.length; i++) {
2356
2397
  if (!setmoves[i]) {
2357
2398
  continue;
@@ -2371,58 +2412,61 @@ export class PuzzleGeometry {
2371
2412
  o.push(0);
2372
2413
  }
2373
2414
  solved.push(
2374
- new Orbit(p, o, this.killorientation ? 1 : this.orbitoris[i]),
2415
+ new PGOrbit(
2416
+ p,
2417
+ o,
2418
+ this.options.fixedOrientation ? 1 : this.orbitoris[i],
2419
+ ),
2375
2420
  );
2376
2421
  }
2377
2422
  const movenames: string[] = [];
2378
- const moves: Transformation[] = [];
2379
- for (let k = 0; k < this.moveplanesets.length; k++) {
2380
- const moveplaneset = this.moveplanesets[k];
2381
- const slices = moveplaneset.length;
2382
- const moveset = mps[k];
2383
- const movesetgeo = this.movesetgeos[k];
2384
- for (let i = 0; i < moveset.length; i += 2) {
2385
- const movebits = moveset[i];
2386
- const mna = getmovename(movesetgeo, movebits, slices);
2387
- const movename = mna[0];
2388
- const inverted = mna[1];
2389
- if (moveset[i + 1] === 1) {
2390
- movenames.push(movename);
2391
- } else {
2392
- movenames.push(movename + moveset[i + 1]);
2393
- }
2394
- const mv = this.getMoveFromBits(
2395
- movebits,
2396
- moveset[i + 1],
2397
- inverted,
2398
- this.cmovesbyslice[k],
2399
- setmoves,
2400
- this.movesetorders[k],
2401
- );
2402
- moves.push(mv);
2423
+ const moves: PGTransform[] = [];
2424
+ if (includemoves) {
2425
+ for (let k = 0; k < this.moveplanesets.length; k++) {
2426
+ const moveplaneset = this.moveplanesets[k];
2427
+ const slices = moveplaneset.length;
2428
+ const moveset = mps[k];
2429
+ const movesetgeo = this.movesetgeos[k];
2430
+ for (let i = 0; i < moveset.length; i += 2) {
2431
+ const movebits = moveset[i];
2432
+ const mna = getmovename(movesetgeo, movebits, slices);
2433
+ const movename = mna[0];
2434
+ const inverted = mna[1];
2435
+ if (moveset[i + 1] === 1) {
2436
+ movenames.push(movename);
2437
+ } else {
2438
+ movenames.push(movename + moveset[i + 1]);
2439
+ }
2440
+ const mv = this.getMoveFromBits(
2441
+ movebits,
2442
+ moveset[i + 1],
2443
+ inverted,
2444
+ this.cmovesbyslice[k],
2445
+ setmoves,
2446
+ this.movesetorders[k],
2447
+ );
2448
+ moves.push(mv);
2449
+ }
2403
2450
  }
2404
2451
  }
2405
- this.ksolvemovenames = movenames; // hack!
2406
- let r = new OrbitsDef(
2452
+ let r = new PGOrbitsDef(
2407
2453
  setnames,
2408
2454
  setdefs,
2409
2455
  new VisibleState(solved),
2410
2456
  movenames,
2411
2457
  moves,
2412
2458
  );
2413
- if (this.optimize) {
2459
+ if (this.options.optimizeOrbits) {
2414
2460
  r = r.optimize();
2415
2461
  }
2416
- if (this.scramble !== 0) {
2417
- r.scramble(this.scramble);
2462
+ if (this.options.scrambleAmount !== 0) {
2463
+ r.scramble(this.options.scrambleAmount);
2418
2464
  }
2419
2465
  return r;
2420
2466
  }
2421
2467
 
2422
2468
  public getMovesAsPerms(): Perm[] {
2423
- return this.getOrbitsDef(false).moveops.map((_: Transformation) =>
2424
- _.toPerm(),
2425
- );
2469
+ return this.getOrbitsDef(false).moveops.map((_) => _.toPerm());
2426
2470
  }
2427
2471
 
2428
2472
  public showcanon(disp: (s: string) => void): void {
@@ -2433,7 +2477,7 @@ export class PuzzleGeometry {
2433
2477
  public getsolved(): Perm {
2434
2478
  // get a solved position
2435
2479
  const r = [];
2436
- for (let i = 0; i < this.basefacecount; i++) {
2480
+ for (let i = 0; i < this.baseFaceCount; i++) {
2437
2481
  for (let j = 0; j < this.stickersperface; j++) {
2438
2482
  r.push(i);
2439
2483
  }
@@ -2445,21 +2489,12 @@ export class PuzzleGeometry {
2445
2489
  // with a given vector, and then as much as possible feature2
2446
2490
  // with another given vector, return a Quaternion that
2447
2491
  // performs this rotation.
2448
- public getOrientationRotation(desiredRotation: any[]): Quat {
2449
- const feature1name = desiredRotation[0];
2450
- const direction1 = new Quat(
2451
- 0,
2452
- desiredRotation[1][0],
2453
- -desiredRotation[1][1],
2454
- desiredRotation[1][2],
2455
- );
2456
- const feature2name = desiredRotation[2];
2457
- const direction2 = new Quat(
2458
- 0,
2459
- desiredRotation[3][0],
2460
- -desiredRotation[3][1],
2461
- desiredRotation[3][2],
2462
- );
2492
+ private getOrientationRotation(desiredRotation: any[]): Quat {
2493
+ const [feature1name, [x1, y1, z1]] = desiredRotation[0];
2494
+ const direction1 = new Quat(0, x1, -y1, z1);
2495
+
2496
+ const [feature2name, [x2, y2, z2]] = desiredRotation[1];
2497
+ const direction2 = new Quat(0, x2, -y2, z2);
2463
2498
  let feature1: Quat | null = null;
2464
2499
  let feature2: Quat | null = null;
2465
2500
  const feature1geoname = this.swizzler.unswizzle(feature1name);
@@ -2486,32 +2521,33 @@ export class PuzzleGeometry {
2486
2521
  return r2.mul(r1);
2487
2522
  }
2488
2523
 
2489
- public getInitial3DRotation(): Quat {
2490
- const basefacecount = this.basefacecount;
2491
- let rotDesc: any = null;
2492
- if (this.puzzleOrientation) {
2493
- rotDesc = this.puzzleOrientation;
2494
- } else if (this.puzzleOrientations) {
2495
- rotDesc = this.puzzleOrientations[basefacecount];
2524
+ private getInitial3DRotation(): Quat {
2525
+ const basefacecount = this.baseFaceCount;
2526
+ let orientationDescription: FaceBasedOrientationDescription | null = null;
2527
+ if (this.options.puzzleOrientation) {
2528
+ orientationDescription = this.options.puzzleOrientation;
2529
+ } else if (this.options.puzzleOrientations) {
2530
+ orientationDescription = this.options.puzzleOrientations[basefacecount];
2496
2531
  }
2497
2532
  // either no option specified or no matching key in
2498
2533
  // puzzleOrientations.
2499
- if (!rotDesc) {
2500
- rotDesc = defaultOrientations()[basefacecount];
2534
+ if (!orientationDescription) {
2535
+ orientationDescription = defaultOrientations()[basefacecount];
2501
2536
  }
2502
- if (!rotDesc) {
2537
+ if (!orientationDescription) {
2503
2538
  throw new Error("No default orientation?");
2504
2539
  }
2505
- return this.getOrientationRotation(rotDesc);
2540
+ return this.getOrientationRotation(orientationDescription);
2506
2541
  }
2507
2542
 
2508
- public generatesvg(
2543
+ private generate2dmapping(
2509
2544
  w: number = 800,
2510
2545
  h: number = 500,
2511
2546
  trim: number = 10,
2512
2547
  threed: boolean = false,
2513
- ): string {
2514
- // generate svg to interoperate with Lucas twistysim
2548
+ twodshrink: number = 0.92,
2549
+ ): (fn: number, q: Quat) => number[] {
2550
+ // generate a mapping to use for 2D for textures, svg
2515
2551
  w -= 2 * trim;
2516
2552
  h -= 2 * trim;
2517
2553
  function extendedges(a: number[][], n: number): void {
@@ -2527,40 +2563,6 @@ export class PuzzleGeometry {
2527
2563
  a.push([a[i - 1][0] + dx, a[i - 1][1] + dy]);
2528
2564
  }
2529
2565
  }
2530
- // if we don't add this noise to coordinate values, then Safari
2531
- // doesn't render our polygons correctly. What a hack.
2532
- function noise(c: number): number {
2533
- return c + 0 * (Math.random() - 0.5);
2534
- }
2535
- function drawedges(id: string, pts: number[][], color: string): string {
2536
- return (
2537
- '<polygon id="' +
2538
- id +
2539
- '" class="sticker" style="fill: ' +
2540
- color +
2541
- '" points="' +
2542
- pts.map((p) => noise(p[0]) + " " + noise(p[1])).join(" ") +
2543
- '"/>\n'
2544
- );
2545
- }
2546
- // What grips do we need? if rotations, add all grips.
2547
- let needvertexgrips = this.addrotations;
2548
- let neededgegrips = this.addrotations;
2549
- let needfacegrips = this.addrotations;
2550
- for (let i = 0; i < this.movesetgeos.length; i++) {
2551
- const msg = this.movesetgeos[i];
2552
- for (let j = 1; j <= 3; j += 2) {
2553
- if (msg[j] === "v") {
2554
- needvertexgrips = true;
2555
- }
2556
- if (msg[j] === "f") {
2557
- needfacegrips = true;
2558
- }
2559
- if (msg[j] === "e") {
2560
- neededgegrips = true;
2561
- }
2562
- }
2563
- }
2564
2566
  // Find a net from a given face count. Walk it, assuming we locate
2565
2567
  // the first edge from (0,0) to (1,1) and compute the minimum and
2566
2568
  // maximum vertex locations from this. Then do a second walk, and
@@ -2583,13 +2585,13 @@ export class PuzzleGeometry {
2583
2585
  [0, 0],
2584
2586
  ];
2585
2587
  extendedges(edges[net[0][0]], polyn);
2586
- for (let i = 0; i < net.length; i++) {
2587
- const f0 = net[i][0];
2588
+ for (const neti of net) {
2589
+ const f0 = neti[0];
2588
2590
  if (!edges[f0]) {
2589
2591
  throw new Error("Bad edge description; first edge not connected.");
2590
2592
  }
2591
- for (let j = 1; j < net[i].length; j++) {
2592
- const f1 = net[i][j];
2593
+ for (let j = 1; j < neti.length; j++) {
2594
+ const f1 = neti[j];
2593
2595
  if (f1 === "" || edges[f1]) {
2594
2596
  continue;
2595
2597
  }
@@ -2599,17 +2601,17 @@ export class PuzzleGeometry {
2599
2601
  }
2600
2602
  for (const f in edges) {
2601
2603
  const es = edges[f];
2602
- for (let i = 0; i < es.length; i++) {
2603
- minx = Math.min(minx, es[i][0]);
2604
- maxx = Math.max(maxx, es[i][0]);
2605
- miny = Math.min(miny, es[i][1]);
2606
- maxy = Math.max(maxy, es[i][1]);
2604
+ for (const esi of es) {
2605
+ minx = Math.min(minx, esi[0]);
2606
+ maxx = Math.max(maxx, esi[0]);
2607
+ miny = Math.min(miny, esi[1]);
2608
+ maxy = Math.max(maxy, esi[1]);
2607
2609
  }
2608
2610
  }
2609
2611
  const sc = Math.min(w / (maxx - minx), h / (maxy - miny));
2610
2612
  const xoff = 0.5 * (w - sc * (maxx + minx));
2611
2613
  const yoff = 0.5 * (h - sc * (maxy + miny));
2612
- const geos: any = {};
2614
+ const geos: Record<string, Quat[]> = {};
2613
2615
  const bg = this.getboundarygeometry();
2614
2616
  const edges2: any = {};
2615
2617
  const initv = [
@@ -2624,8 +2626,8 @@ export class PuzzleGeometry {
2624
2626
  ]);
2625
2627
  const connectat = [];
2626
2628
  connectat[0] = 0;
2627
- for (let i = 0; i < net.length; i++) {
2628
- const f0 = net[i][0];
2629
+ for (const neti of net) {
2630
+ const f0 = neti[0];
2629
2631
  if (!edges2[f0]) {
2630
2632
  throw new Error("Bad edge description; first edge not connected.");
2631
2633
  }
@@ -2640,8 +2642,8 @@ export class PuzzleGeometry {
2640
2642
  throw new Error("Could not find first face name " + f0);
2641
2643
  }
2642
2644
  const thisface = bg.facenames[gfi][0];
2643
- for (let j = 1; j < net[i].length; j++) {
2644
- const f1 = net[i][j];
2645
+ for (let j = 1; j < neti.length; j++) {
2646
+ const f1 = neti[j];
2645
2647
  if (f1 === "" || edges2[f1]) {
2646
2648
  continue;
2647
2649
  }
@@ -2685,30 +2687,22 @@ export class PuzzleGeometry {
2685
2687
  }
2686
2688
  }
2687
2689
  }
2688
- // Let's build arrays for faster rendering. We want to map from geo
2689
- // base face number to color, and we want to map from geo face number
2690
- // to 2D geometry. These can be reused as long as the puzzle overall
2691
- // orientation and canvas size remains unchanged.
2692
- const pos = this.getsolved();
2693
- const colormap = [];
2694
- const facegeo = [];
2695
- for (let i = 0; i < this.basefacecount; i++) {
2696
- colormap[i] = this.colors[this.facenames[i][1]];
2697
- }
2698
2690
  let hix = 0;
2699
2691
  let hiy = 0;
2700
2692
  const rot = this.getInitial3DRotation();
2701
- for (let i = 0; i < this.faces.length; i++) {
2702
- let face = this.faces[i];
2703
- face = rot.rotateface(face);
2693
+ for (let face of this.faces) {
2694
+ if (threed) {
2695
+ face = face.rotate(rot);
2696
+ }
2704
2697
  for (let j = 0; j < face.length; j++) {
2705
- hix = Math.max(hix, Math.abs(face[j].b));
2706
- hiy = Math.max(hiy, Math.abs(face[j].c));
2698
+ hix = Math.max(hix, Math.abs(face.get(j).b));
2699
+ hiy = Math.max(hiy, Math.abs(face.get(j).c));
2707
2700
  }
2708
2701
  }
2709
2702
  const sc2 = Math.min(h / hiy / 2, (w - trim) / hix / 4);
2710
2703
  const mappt2d = (fn: number, q: Quat): number[] => {
2711
2704
  if (threed) {
2705
+ q = q.rotatepoint(rot);
2712
2706
  const xoff2 = 0.5 * trim + 0.25 * w;
2713
2707
  const xmul = this.baseplanes[fn].rotateplane(rot).d < 0 ? 1 : -1;
2714
2708
  return [
@@ -2717,26 +2711,61 @@ export class PuzzleGeometry {
2717
2711
  ];
2718
2712
  } else {
2719
2713
  const g = geos[this.facenames[fn][1]];
2720
- return [trim + q.dot(g[0]) + g[2].b, trim + h - q.dot(g[1]) - g[2].c];
2714
+ return [
2715
+ trim + twodshrink * q.dot(g[0]) + g[2].b,
2716
+ trim + h - twodshrink * q.dot(g[1]) - g[2].c,
2717
+ ];
2721
2718
  }
2722
2719
  };
2720
+ return mappt2d;
2721
+ }
2722
+
2723
+ public generatesvg(
2724
+ w: number = 800,
2725
+ h: number = 500,
2726
+ trim: number = 10,
2727
+ threed: boolean = false,
2728
+ ): string {
2729
+ const mappt2d = this.generate2dmapping(w, h, trim, threed);
2730
+ function drawedges(id: string, pts: number[][], color: string): string {
2731
+ return (
2732
+ '<polygon id="' +
2733
+ id +
2734
+ '" class="sticker" style="fill: ' +
2735
+ color +
2736
+ '" points="' +
2737
+ pts.map((p) => p[0] + " " + p[1]).join(" ") +
2738
+ '"/>\n'
2739
+ );
2740
+ }
2741
+ // Let's build arrays for faster rendering. We want to map from geo
2742
+ // base face number to color, and we want to map from geo face number
2743
+ // to 2D geometry. These can be reused as long as the puzzle overall
2744
+ // orientation and canvas size remains unchanged.
2745
+ const pos = this.getsolved();
2746
+ const colormap = [];
2747
+ const facegeo = [];
2748
+ for (let i = 0; i < this.baseFaceCount; i++) {
2749
+ colormap[i] = this.colors[this.facenames[i][1]];
2750
+ }
2723
2751
  for (let i = 0; i < this.faces.length; i++) {
2724
- let face = this.faces[i];
2752
+ const face = this.faces[i];
2725
2753
  const facenum = Math.floor(i / this.stickersperface);
2726
- if (threed) {
2727
- face = rot.rotateface(face);
2754
+ const fg = [];
2755
+ for (let j = 0; j < face.length; j++) {
2756
+ fg.push(mappt2d(facenum, face.get(j)));
2728
2757
  }
2729
- facegeo.push(face.map((_: Quat) => mappt2d(facenum, _)));
2758
+ facegeo.push(fg);
2730
2759
  }
2731
2760
  const svg = [];
2732
2761
  // group each base face so we can add a hover element
2733
- for (let j = 0; j < this.basefacecount; j++) {
2762
+ for (let j = 0; j < this.baseFaceCount; j++) {
2734
2763
  svg.push("<g>");
2735
2764
  svg.push("<title>" + this.facenames[j][1] + "</title>\n");
2736
2765
  for (let ii = 0; ii < this.stickersperface; ii++) {
2737
2766
  const i = j * this.stickersperface + ii;
2738
- const cubie = this.facetocubies[i][0];
2739
- const cubieori = this.facetocubies[i][1];
2767
+ const cubie = this.facetocubie[i];
2768
+ const cubieori = this.facetoord[i];
2740
2769
  const cubiesetnum = this.cubiesetnums[cubie];
2741
2770
  const cubieord = this.cubieordnums[cubie];
2742
2771
  const color = this.graybyori(cubie) ? "#808080" : colormap[pos.p[i]];
@@ -2752,53 +2781,6 @@ export class PuzzleGeometry {
2752
2781
  }
2753
2782
  svg.push("</g>");
2754
2783
  }
2755
- const svggrips: any[] = [];
2756
- function addgrip(
2757
- onface: number,
2758
- name: string,
2759
- pt: Quat,
2760
- order: number,
2761
- ): void {
2762
- const pt2 = mappt2d(onface, pt);
2763
- for (let i = 0; i < svggrips.length; i++) {
2764
- if (
2765
- Math.hypot(pt2[0] - svggrips[i][0], pt2[1] - svggrips[i][1]) < eps
2766
- ) {
2767
- return;
2768
- }
2769
- }
2770
- svggrips.push([pt2[0], pt2[1], name, order]);
2771
- }
2772
- for (let i = 0; i < this.faceplanes.length; i++) {
2773
- const baseface = this.facenames[i][0];
2774
- let facecoords = baseface;
2775
- if (threed) {
2776
- facecoords = rot.rotateface(facecoords);
2777
- }
2778
- if (needfacegrips) {
2779
- let pt = this.faceplanes[i][0];
2780
- if (threed) {
2781
- pt = pt.rotatepoint(rot);
2782
- }
2783
- addgrip(i, this.faceplanes[i][1], pt, polyn);
2784
- }
2785
- for (let j = 0; j < baseface.length; j++) {
2786
- if (neededgegrips) {
2787
- const mp = baseface[j]
2788
- .sum(baseface[(j + 1) % baseface.length])
2789
- .smul(0.5);
2790
- const ep = findelement(this.edgenames, mp);
2791
- const mpc = facecoords[j]
2792
- .sum(facecoords[(j + 1) % baseface.length])
2793
- .smul(0.5);
2794
- addgrip(i, this.edgenames[ep][1], mpc, 2);
2795
- }
2796
- if (needvertexgrips) {
2797
- const vp = findelement(this.vertexnames, baseface[j]);
2798
- addgrip(i, this.vertexnames[vp][1], facecoords[j], this.cornerfaces);
2799
- }
2800
- }
2801
- }
2802
2784
  const html =
2803
2785
  '<svg id="svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 800 500">\n' +
2804
2786
  '<style type="text/css"><![CDATA[' +
@@ -2806,58 +2788,27 @@ export class PuzzleGeometry {
2806
2788
  "]]></style>\n" +
2807
2789
  svg.join("") +
2808
2790
  "</svg>";
2809
- this.svggrips = svggrips;
2810
2791
  return html;
2811
2792
  }
2812
2793
 
2813
- public dist(a: number[], b: number[]): number {
2814
- return Math.hypot(a[0] - b[0], a[1] - b[1], a[2] - b[2]);
2815
- }
2816
-
2817
- public triarea(a: number[], b: number[], c: number[]): number {
2818
- const ab = this.dist(a, b);
2819
- const bc = this.dist(b, c);
2820
- const ac = this.dist(a, c);
2821
- const p = (ab + bc + ac) / 2;
2822
- return Math.sqrt(p * (p - ab) * (p - bc) * (p - ac));
2823
- }
2824
-
2825
- public polyarea(coords: number[][]): number {
2826
- let sum = 0;
2827
- for (let i = 2; i < coords.length; i++) {
2828
- sum += this.triarea(coords[0], coords[1], coords[i]);
2829
- }
2830
- return sum;
2831
- }
2832
-
2833
2794
  // The colorfrac parameter says how much of the face should be
2834
2795
  // colored (vs dividing lines); we default to 0.77 which seems
2835
2796
  // to work pretty well. It should be a number between probably
2836
2797
  // 0.4 and 0.9.
2837
- public get3d(
2838
- colorfrac: number = DEFAULT_COLOR_FRACTION,
2839
- options?: {
2840
- stickerColors?: string[];
2841
- },
2842
- ): StickerDat {
2843
- const stickers: any = [];
2844
- const foundations: any = [];
2798
+ public get3d(options?: { stickerColors?: string[] }): StickerDat {
2799
+ const stickers = [];
2845
2800
  const rot = this.getInitial3DRotation();
2846
- const faces: any = [];
2847
- const maxdist: number = 0.52 * this.basefaces[0][0].len();
2848
- let avgstickerarea = 0;
2801
+ const faces = [];
2802
+ const maxdist: number = 0.52 * this.basefaces[0].get(0).len();
2849
2803
  for (let i = 0; i < this.basefaces.length; i++) {
2850
- const coords = rot.rotateface(this.basefaces[i]);
2804
+ const coords = this.basefaces[i].rotate(rot);
2851
2805
  const name = this.facenames[i][1];
2852
2806
  faces.push({ coords: toFaceCoords(coords, maxdist), name });
2853
- avgstickerarea += this.polyarea(faces[i].coords);
2854
2807
  }
2855
- avgstickerarea /= this.faces.length;
2856
- const trim = (Math.sqrt(avgstickerarea) * (1 - Math.sqrt(colorfrac))) / 2;
2857
2808
  for (let i = 0; i < this.faces.length; i++) {
2858
2809
  const facenum = Math.floor(i / this.stickersperface);
2859
- const cubie = this.facetocubies[i][0];
2860
- const cubieori = this.facetocubies[i][1];
2810
+ const cubie = this.facetocubie[i];
2811
+ const cubieori = this.facetoord[i];
2861
2812
  const cubiesetnum = this.cubiesetnums[cubie];
2862
2813
  const cubieord = this.cubieordnums[cubie];
2863
2814
  let color = this.graybyori(cubie)
@@ -2866,40 +2817,30 @@ export class PuzzleGeometry {
2866
2817
  if (options?.stickerColors) {
2867
2818
  color = options.stickerColors[i];
2868
2819
  }
2869
- let coords = rot.rotateface(this.faces[i]);
2870
- foundations.push({
2871
- coords: toFaceCoords(coords, maxdist),
2872
- color,
2873
- orbit: this.cubiesetnames[cubiesetnum],
2874
- ord: cubieord,
2875
- ori: cubieori,
2876
- });
2877
- const fcoords = coords;
2878
- if (trim && trim > 0) {
2879
- coords = trimEdges(coords, trim);
2880
- }
2820
+ const coords = this.faces[i].rotate(rot);
2881
2821
  stickers.push({
2882
2822
  coords: toFaceCoords(coords, maxdist),
2883
2823
  color,
2884
2824
  orbit: this.cubiesetnames[cubiesetnum],
2885
2825
  ord: cubieord,
2886
2826
  ori: cubieori,
2827
+ face: facenum,
2887
2828
  });
2829
+ let fcoords = coords;
2888
2830
  if (this.duplicatedFaces[i]) {
2831
+ const rotdist = fcoords.length / this.duplicatedFaces[i];
2889
2832
  for (let jj = 1; jj < this.duplicatedFaces[i]; jj++) {
2833
+ for (let k = 0; k < rotdist; k++) {
2834
+ fcoords = fcoords.rotateforward();
2835
+ }
2890
2836
  stickers.push({
2891
- coords: toFaceCoords(coords, maxdist),
2892
- color,
2893
- orbit: this.cubiesetnames[cubiesetnum],
2894
- ord: cubieord,
2895
- ori: jj,
2896
- });
2897
- foundations.push({
2898
2837
  coords: toFaceCoords(fcoords, maxdist),
2899
2838
  color,
2900
2839
  orbit: this.cubiesetnames[cubiesetnum],
2901
2840
  ord: cubieord,
2902
2841
  ori: jj,
2842
+ face: facenum,
2843
+ isDup: true,
2903
2844
  });
2904
2845
  }
2905
2846
  }
@@ -2908,8 +2849,7 @@ export class PuzzleGeometry {
2908
2849
  for (let i = 0; i < this.movesetgeos.length; i++) {
2909
2850
  const msg = this.movesetgeos[i];
2910
2851
  const order = this.movesetorders[i];
2911
- for (let j = 0; j < this.geonormals.length; j++) {
2912
- const gn = this.geonormals[j];
2852
+ for (const gn of this.geonormals) {
2913
2853
  if (msg[0] === gn[1] && msg[1] === gn[2]) {
2914
2854
  grips.push([toCoords(gn[0].rotatepoint(rot), 1), msg[0], order]);
2915
2855
  grips.push([
@@ -2920,18 +2860,30 @@ export class PuzzleGeometry {
2920
2860
  }
2921
2861
  }
2922
2862
  }
2923
- const f = (function () {
2924
- return function (mv: Move): string {
2925
- return this.unswizzle(mv);
2863
+ const twodmapper = this.generate2dmapping(2880, 2160, 0, false, 1.0);
2864
+ const g = (function () {
2865
+ const irot = rot.invrot();
2866
+ return function (facenum: number, coords: number[]): number[] {
2867
+ let q = new Quat(
2868
+ 0,
2869
+ coords[0] * maxdist,
2870
+ -coords[1] * maxdist,
2871
+ coords[2] * maxdist,
2872
+ );
2873
+ q = q.rotatepoint(irot);
2874
+ const x = twodmapper(facenum, q);
2875
+ x[0] /= 2880;
2876
+ x[1] = 1 - x[1] / 2160;
2877
+ return x;
2926
2878
  };
2927
2879
  })().bind(this);
2928
2880
  return {
2929
2881
  stickers,
2930
- foundations,
2931
2882
  faces,
2932
2883
  axis: grips,
2933
- unswizzle: f,
2884
+ unswizzle: this.unswizzle.bind(this),
2934
2885
  notationMapper: this.notationMapper,
2886
+ textureMapper: { getuv: g },
2935
2887
  };
2936
2888
  }
2937
2889
 
@@ -2943,8 +2895,7 @@ export class PuzzleGeometry {
2943
2895
  public getGeoNormal(geoname: string): number[] | undefined {
2944
2896
  const rot = this.getInitial3DRotation();
2945
2897
  const grip = this.swizzler.unswizzle(geoname);
2946
- for (let j = 0; j < this.geonormals.length; j++) {
2947
- const gn = this.geonormals[j];
2898
+ for (const gn of this.geonormals) {
2948
2899
  if (grip === gn[1]) {
2949
2900
  const r = toCoords(gn[0].rotatepoint(rot), 1);
2950
2901
  // This routine is intended to use for the camera location.
@@ -2967,12 +2918,30 @@ export class PuzzleGeometry {
2967
2918
  const divid = this.stickersperface;
2968
2919
  return Math.floor(facenum / divid);
2969
2920
  }
2921
+
2922
+ public textForTwizzleExplorer(): string {
2923
+ return `Faces ${this.baseplanerot.length}
2924
+ Stickers per face ${this.stickersperface}
2925
+ Short edge ${this.shortedge}
2926
+ Cubies ${this.cubies.length}
2927
+ Edge distance ${this.edgedistance}
2928
+ Vertex distance ${this.vertexdistance}`;
2929
+ }
2930
+
2931
+ writeSchreierSims(tw: (s: string) => void) {
2932
+ const os = this.getOrbitsDef(false);
2933
+ const as = os.reassemblySize();
2934
+ tw(`Reassembly size is ${as}`);
2935
+ const ss = schreierSims(this.getMovesAsPerms(), tw);
2936
+ const r = as / ss;
2937
+ tw(`Ratio is ${r}`);
2938
+ }
2970
2939
  }
2971
2940
 
2972
2941
  class PGNotation implements MoveNotation {
2973
2942
  private cache: { [key: string]: KTransformation } = {};
2974
- public orbitNames: string[];
2975
- constructor(public pg: PuzzleGeometry, od: OrbitsDef) {
2943
+ private orbitNames: string[];
2944
+ constructor(private pg: PuzzleGeometry, od: PGOrbitsDef) {
2976
2945
  this.orbitNames = od.orbitnames;
2977
2946
  }
2978
2947
 
@@ -2985,12 +2954,12 @@ class PGNotation implements MoveNotation {
2985
2954
  // if a move list subset is defined, don't return moves outside the subset.
2986
2955
  if (this.pg.parsedmovelist) {
2987
2956
  let found = false;
2988
- for (let i = 0; i < this.pg.parsedmovelist.length; i++) {
2957
+ for (const parsedmove of this.pg.parsedmovelist) {
2989
2958
  if (
2990
- this.pg.parsedmovelist[i][1] === mv[1] &&
2991
- this.pg.parsedmovelist[i][2] === mv[2] &&
2992
- this.pg.parsedmovelist[i][3] === mv[3] &&
2993
- this.pg.parsedmovelist[i][4] === mv[4]
2959
+ parsedmove[1] === mv[1] &&
2960
+ parsedmove[2] === mv[2] &&
2961
+ parsedmove[3] === mv[3] &&
2962
+ parsedmove[4] === mv[4]
2994
2963
  ) {
2995
2964
  found = true;
2996
2965
  }
@@ -3012,7 +2981,7 @@ class PGNotation implements MoveNotation {
3012
2981
  undefined,
3013
2982
  this.pg.movesetorders[mv[1]],
3014
2983
  );
3015
- const r = OrbitsDef.transformToKPuzzle(this.orbitNames, pgmv);
2984
+ const r = PGOrbitsDef.transformToKPuzzle(this.orbitNames, pgmv);
3016
2985
  this.cache[key] = r;
3017
2986
  return r;
3018
2987
  }