@weasel-js/core 1.10.1 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1431) hide show
  1. package/CHANGELOG.md +587 -0
  2. package/README.md +16 -15
  3. package/dist/WeaselProvider.js +25 -9
  4. package/dist/WeaselProvider.js.map +1 -1
  5. package/dist/affordances/composeAffordanceLayer.js +217 -140
  6. package/dist/affordances/composeAffordanceLayer.js.map +1 -1
  7. package/dist/affordances/cornerResize.js +92 -50
  8. package/dist/affordances/cornerResize.js.map +1 -1
  9. package/dist/affordances/hitAffordanceRegions.js +147 -84
  10. package/dist/affordances/hitAffordanceRegions.js.map +1 -1
  11. package/dist/affordances/pathAnchors.js +140 -65
  12. package/dist/affordances/pathAnchors.js.map +1 -1
  13. package/dist/affordances/rotateCursor.js +10 -4
  14. package/dist/affordances/rotateCursor.js.map +1 -1
  15. package/dist/affordances/rotationHandle.js +83 -60
  16. package/dist/affordances/rotationHandle.js.map +1 -1
  17. package/dist/animation/behaviors/coast.js +20 -14
  18. package/dist/animation/behaviors/coast.js.map +1 -1
  19. package/dist/animation/behaviors/coastByWrite.js +98 -70
  20. package/dist/animation/behaviors/coastByWrite.js.map +1 -1
  21. package/dist/animation/behaviors/coastOnTargets.js +115 -67
  22. package/dist/animation/behaviors/coastOnTargets.js.map +1 -1
  23. package/dist/animation/behaviors/momentum.js +88 -53
  24. package/dist/animation/behaviors/momentum.js.map +1 -1
  25. package/dist/animation/clipTargets.js +14 -7
  26. package/dist/animation/clipTargets.js.map +1 -1
  27. package/dist/animation/departures.js +116 -0
  28. package/dist/animation/departures.js.map +1 -0
  29. package/dist/animation/index.js +18 -15
  30. package/dist/animation/poseHelpers.js +147 -107
  31. package/dist/animation/poseHelpers.js.map +1 -1
  32. package/dist/animation/poseTarget.js +158 -85
  33. package/dist/animation/poseTarget.js.map +1 -1
  34. package/dist/animation/poseTransition.js +64 -0
  35. package/dist/animation/poseTransition.js.map +1 -0
  36. package/dist/animation/reflow.js +208 -120
  37. package/dist/animation/reflow.js.map +1 -1
  38. package/dist/animation/rewind.js +76 -45
  39. package/dist/animation/rewind.js.map +1 -1
  40. package/dist/animation/rig/bindRig.js +135 -82
  41. package/dist/animation/rig/bindRig.js.map +1 -1
  42. package/dist/animation/rig/rigNode.js +120 -75
  43. package/dist/animation/rig/rigNode.js.map +1 -1
  44. package/dist/animation/rig/rigSeat.js +61 -41
  45. package/dist/animation/rig/rigSeat.js.map +1 -1
  46. package/dist/animation/rig/skinBinding.js +57 -45
  47. package/dist/animation/rig/skinBinding.js.map +1 -1
  48. package/dist/animation/rig/useRig.js +44 -30
  49. package/dist/animation/rig/useRig.js.map +1 -1
  50. package/dist/animation/wrappers/animateLifecycle.js +51 -35
  51. package/dist/animation/wrappers/animateLifecycle.js.map +1 -1
  52. package/dist/animation/wrappers/animateOnSetPose.js +55 -32
  53. package/dist/animation/wrappers/animateOnSetPose.js.map +1 -1
  54. package/dist/animation/wrappers/instantPose.js +13 -8
  55. package/dist/animation/wrappers/instantPose.js.map +1 -1
  56. package/dist/animation/writtenPoseTarget.js +44 -22
  57. package/dist/animation/writtenPoseTarget.js.map +1 -1
  58. package/dist/{autoPoseDescriptor-DHg5KqaJ.d.ts → autoPoseDescriptor-CZ1eXbzY.d.ts} +1 -1
  59. package/dist/barrel/canvas.js +41 -32
  60. package/dist/barrel/chrome.js +19 -16
  61. package/dist/barrel/icons.js +6 -0
  62. package/dist/barrel/input.js +19 -18
  63. package/dist/barrel/interactions.js +40 -39
  64. package/dist/barrel/paint.js +12 -11
  65. package/dist/barrel/paths.js +39 -13
  66. package/dist/barrel/renderer.js +24 -14
  67. package/dist/barrel/routing.js +69 -58
  68. package/dist/barrel/scene.js +48 -37
  69. package/dist/barrel/text.js +10 -9
  70. package/dist/barrel/viewport.js +47 -45
  71. package/dist/canvas/Canvas.js +189 -306
  72. package/dist/canvas/Canvas.js.map +1 -1
  73. package/dist/canvas/CanvasView.js +273 -199
  74. package/dist/canvas/CanvasView.js.map +1 -1
  75. package/dist/canvas/CursorCoordsHud.js +103 -64
  76. package/dist/canvas/CursorCoordsHud.js.map +1 -1
  77. package/dist/canvas/DrawCanvas.js +68 -41
  78. package/dist/canvas/DrawCanvas.js.map +1 -1
  79. package/dist/canvas/LeanSceneCanvas.js +23 -0
  80. package/dist/canvas/LeanSceneCanvas.js.map +1 -0
  81. package/dist/canvas/ModalityHud.js +58 -43
  82. package/dist/canvas/ModalityHud.js.map +1 -1
  83. package/dist/canvas/NodeShape.js +137 -60
  84. package/dist/canvas/NodeShape.js.map +1 -1
  85. package/dist/canvas/PickHud.js +77 -59
  86. package/dist/canvas/PickHud.js.map +1 -1
  87. package/dist/canvas/SceneCanvas/ActionsProviderIfRoot.js +9 -6
  88. package/dist/canvas/SceneCanvas/ActionsProviderIfRoot.js.map +1 -1
  89. package/dist/canvas/SceneCanvas/CanvasKitProviders.js +25 -0
  90. package/dist/canvas/SceneCanvas/CanvasKitProviders.js.map +1 -0
  91. package/dist/canvas/SceneCanvas/DepRegistryProviderIfRoot.js +10 -6
  92. package/dist/canvas/SceneCanvas/DepRegistryProviderIfRoot.js.map +1 -1
  93. package/dist/canvas/SceneCanvas/DevHuds.js +47 -32
  94. package/dist/canvas/SceneCanvas/DevHuds.js.map +1 -1
  95. package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js +72 -37
  96. package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js.map +1 -1
  97. package/dist/canvas/SceneCanvas/SceneCanvasInput.js +110 -0
  98. package/dist/canvas/SceneCanvas/SceneCanvasInput.js.map +1 -0
  99. package/dist/canvas/SceneCanvas/brushOverlay.js +36 -0
  100. package/dist/canvas/SceneCanvas/brushOverlay.js.map +1 -0
  101. package/dist/canvas/SceneCanvas/canvasPassThrough.js +72 -0
  102. package/dist/canvas/SceneCanvas/canvasPassThrough.js.map +1 -0
  103. package/dist/canvas/SceneCanvas/contributionFrameHooks.js +54 -32
  104. package/dist/canvas/SceneCanvas/contributionFrameHooks.js.map +1 -1
  105. package/dist/canvas/SceneCanvas/coordTrace.js +36 -29
  106. package/dist/canvas/SceneCanvas/coordTrace.js.map +1 -1
  107. package/dist/canvas/SceneCanvas/defaultNodeProperties.js +318 -159
  108. package/dist/canvas/SceneCanvas/defaultNodeProperties.js.map +1 -1
  109. package/dist/canvas/SceneCanvas/defaultNodeRouting.js +39 -13
  110. package/dist/canvas/SceneCanvas/defaultNodeRouting.js.map +1 -1
  111. package/dist/canvas/SceneCanvas/dispatcherGestureBounds.js +83 -47
  112. package/dist/canvas/SceneCanvas/dispatcherGestureBounds.js.map +1 -1
  113. package/dist/canvas/SceneCanvas/features.js +83 -106
  114. package/dist/canvas/SceneCanvas/features.js.map +1 -1
  115. package/dist/canvas/SceneCanvas/insertPreviewCommands.js +80 -62
  116. package/dist/canvas/SceneCanvas/insertPreviewCommands.js.map +1 -1
  117. package/dist/canvas/SceneCanvas/mergeLayers.js +43 -0
  118. package/dist/canvas/SceneCanvas/mergeLayers.js.map +1 -0
  119. package/dist/canvas/SceneCanvas/namedPresets.js +56 -0
  120. package/dist/canvas/SceneCanvas/namedPresets.js.map +1 -0
  121. package/dist/canvas/SceneCanvas/poseGeometry.js +66 -31
  122. package/dist/canvas/SceneCanvas/poseGeometry.js.map +1 -1
  123. package/dist/canvas/SceneCanvas/poseRegistrars.js +18 -8
  124. package/dist/canvas/SceneCanvas/poseRegistrars.js.map +1 -1
  125. package/dist/canvas/SceneCanvas/presets/arrange.js +27 -0
  126. package/dist/canvas/SceneCanvas/presets/arrange.js.map +1 -0
  127. package/dist/canvas/SceneCanvas/presets/chrome.js +14 -0
  128. package/dist/canvas/SceneCanvas/presets/chrome.js.map +1 -0
  129. package/dist/canvas/SceneCanvas/presets/edit.js +59 -0
  130. package/dist/canvas/SceneCanvas/presets/edit.js.map +1 -0
  131. package/dist/canvas/SceneCanvas/presets/ingest.js +13 -0
  132. package/dist/canvas/SceneCanvas/presets/ingest.js.map +1 -0
  133. package/dist/canvas/SceneCanvas/presets/paths.js +67 -0
  134. package/dist/canvas/SceneCanvas/presets/paths.js.map +1 -0
  135. package/dist/canvas/SceneCanvas/presets/select.js +19 -0
  136. package/dist/canvas/SceneCanvas/presets/select.js.map +1 -0
  137. package/dist/canvas/SceneCanvas/presets/toolDriven.js +20 -0
  138. package/dist/canvas/SceneCanvas/presets/toolDriven.js.map +1 -0
  139. package/dist/canvas/SceneCanvas/presets/transform.js +41 -0
  140. package/dist/canvas/SceneCanvas/presets/transform.js.map +1 -0
  141. package/dist/canvas/SceneCanvas/presets/view.js +14 -0
  142. package/dist/canvas/SceneCanvas/presets/view.js.map +1 -0
  143. package/dist/canvas/SceneCanvas/props.js +19 -35
  144. package/dist/canvas/SceneCanvas/props.js.map +1 -1
  145. package/dist/canvas/SceneCanvas/scenePointQuery.js +43 -35
  146. package/dist/canvas/SceneCanvas/scenePointQuery.js.map +1 -1
  147. package/dist/canvas/SceneCanvas/shapeGeneratorProperties.js +22 -15
  148. package/dist/canvas/SceneCanvas/shapeGeneratorProperties.js.map +1 -1
  149. package/dist/canvas/SceneCanvas/toolRegistry.js +30 -15
  150. package/dist/canvas/SceneCanvas/toolRegistry.js.map +1 -1
  151. package/dist/canvas/SceneCanvas/useActionTunings.js +14 -11
  152. package/dist/canvas/SceneCanvas/useActionTunings.js.map +1 -1
  153. package/dist/canvas/SceneCanvas/useActionsPropResolver.js +68 -35
  154. package/dist/canvas/SceneCanvas/useActionsPropResolver.js.map +1 -1
  155. package/dist/canvas/SceneCanvas/useBakedScene.js +17 -0
  156. package/dist/canvas/SceneCanvas/useBakedScene.js.map +1 -0
  157. package/dist/canvas/SceneCanvas/useBuiltinRigTools.js +65 -0
  158. package/dist/canvas/SceneCanvas/useBuiltinRigTools.js.map +1 -0
  159. package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js +47 -23
  160. package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js.map +1 -1
  161. package/dist/canvas/SceneCanvas/useBuiltinTools.js +29 -14
  162. package/dist/canvas/SceneCanvas/useBuiltinTools.js.map +1 -1
  163. package/dist/canvas/SceneCanvas/useCanvasCamera.js +53 -38
  164. package/dist/canvas/SceneCanvas/useCanvasCamera.js.map +1 -1
  165. package/dist/canvas/SceneCanvas/useCanvasDispatcher.js +24 -14
  166. package/dist/canvas/SceneCanvas/useCanvasDispatcher.js.map +1 -1
  167. package/dist/canvas/SceneCanvas/useCanvasSelection.js +30 -12
  168. package/dist/canvas/SceneCanvas/useCanvasSelection.js.map +1 -1
  169. package/dist/canvas/SceneCanvas/useCanvasTools.js +112 -53
  170. package/dist/canvas/SceneCanvas/useCanvasTools.js.map +1 -1
  171. package/dist/canvas/SceneCanvas/useChromeAffordances.js +31 -0
  172. package/dist/canvas/SceneCanvas/useChromeAffordances.js.map +1 -0
  173. package/dist/canvas/SceneCanvas/useContributionRoles.js +107 -56
  174. package/dist/canvas/SceneCanvas/useContributionRoles.js.map +1 -1
  175. package/dist/canvas/SceneCanvas/useDepartureGhostLayer.js +64 -0
  176. package/dist/canvas/SceneCanvas/useDepartureGhostLayer.js.map +1 -0
  177. package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js +104 -71
  178. package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js.map +1 -1
  179. package/dist/canvas/SceneCanvas/useHeldModifiers.js +21 -14
  180. package/dist/canvas/SceneCanvas/useHeldModifiers.js.map +1 -1
  181. package/dist/canvas/SceneCanvas/useNodeAtPoint.js +21 -19
  182. package/dist/canvas/SceneCanvas/useNodeAtPoint.js.map +1 -1
  183. package/dist/canvas/SceneCanvas/useNodeKinds.js +28 -19
  184. package/dist/canvas/SceneCanvas/useNodeKinds.js.map +1 -1
  185. package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js +91 -59
  186. package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js.map +1 -1
  187. package/dist/canvas/SceneCanvas/useSceneCanvasHandle.js +62 -35
  188. package/dist/canvas/SceneCanvas/useSceneCanvasHandle.js.map +1 -1
  189. package/dist/canvas/SceneCanvas/useSceneCanvasLayers.js +110 -50
  190. package/dist/canvas/SceneCanvas/useSceneCanvasLayers.js.map +1 -1
  191. package/dist/canvas/SceneCanvas/useSceneCanvasPathEdit.js +30 -0
  192. package/dist/canvas/SceneCanvas/useSceneCanvasPathEdit.js.map +1 -0
  193. package/dist/canvas/SceneCanvas/useSceneCanvasTools.js +40 -0
  194. package/dist/canvas/SceneCanvas/useSceneCanvasTools.js.map +1 -0
  195. package/dist/canvas/SceneCanvas/useSceneChrome.js +100 -44
  196. package/dist/canvas/SceneCanvas/useSceneChrome.js.map +1 -1
  197. package/dist/canvas/SceneCanvas/useSceneGestureDispatcher.js +163 -0
  198. package/dist/canvas/SceneCanvas/useSceneGestureDispatcher.js.map +1 -0
  199. package/dist/canvas/SceneCanvas/useScenePicking.js +69 -0
  200. package/dist/canvas/SceneCanvas/useScenePicking.js.map +1 -0
  201. package/dist/canvas/SceneCanvas/useSceneRedrawSources.js +28 -17
  202. package/dist/canvas/SceneCanvas/useSceneRedrawSources.js.map +1 -1
  203. package/dist/canvas/SceneCanvas/useSceneSelectTool.js +159 -80
  204. package/dist/canvas/SceneCanvas/useSceneSelectTool.js.map +1 -1
  205. package/dist/canvas/SceneCanvas/useSceneSlotLayers.js +38 -26
  206. package/dist/canvas/SceneCanvas/useSceneSlotLayers.js.map +1 -1
  207. package/dist/canvas/SceneCanvas/useSceneStandardActions.js +108 -0
  208. package/dist/canvas/SceneCanvas/useSceneStandardActions.js.map +1 -0
  209. package/dist/canvas/SceneCanvas/useSelectionOverlayLayer.js +40 -27
  210. package/dist/canvas/SceneCanvas/useSelectionOverlayLayer.js.map +1 -1
  211. package/dist/canvas/SceneCanvas/useSurfaceRouting.js +29 -0
  212. package/dist/canvas/SceneCanvas/useSurfaceRouting.js.map +1 -0
  213. package/dist/canvas/SceneCanvas/useSurfaceViewInputs.js +44 -0
  214. package/dist/canvas/SceneCanvas/useSurfaceViewInputs.js.map +1 -0
  215. package/dist/canvas/SceneCanvas/useToolKeybindings.js +28 -0
  216. package/dist/canvas/SceneCanvas/useToolKeybindings.js.map +1 -0
  217. package/dist/canvas/SceneCanvas/useViewportActions.js +52 -28
  218. package/dist/canvas/SceneCanvas/useViewportActions.js.map +1 -1
  219. package/dist/canvas/SceneCanvas/worldPointAt.js +10 -4
  220. package/dist/canvas/SceneCanvas/worldPointAt.js.map +1 -1
  221. package/dist/canvas/SceneCanvas.js +274 -312
  222. package/dist/canvas/SceneCanvas.js.map +1 -1
  223. package/dist/canvas/SceneViewCanvas.js +68 -42
  224. package/dist/canvas/SceneViewCanvas.js.map +1 -1
  225. package/dist/canvas/SurfaceCanvas.js +53 -31
  226. package/dist/canvas/SurfaceCanvas.js.map +1 -1
  227. package/dist/canvas/accentColor.js +8 -5
  228. package/dist/canvas/accentColor.js.map +1 -1
  229. package/dist/canvas/adapterDerivedPath.js +33 -18
  230. package/dist/canvas/adapterDerivedPath.js.map +1 -1
  231. package/dist/canvas/adapterPickSource.js +49 -23
  232. package/dist/canvas/adapterPickSource.js.map +1 -1
  233. package/dist/canvas/affordanceAt.js +106 -50
  234. package/dist/canvas/affordanceAt.js.map +1 -1
  235. package/dist/canvas/buildSceneLayer.js +111 -80
  236. package/dist/canvas/buildSceneLayer.js.map +1 -1
  237. package/dist/canvas/buildSceneTree.js +101 -59
  238. package/dist/canvas/buildSceneTree.js.map +1 -1
  239. package/dist/canvas/canvasRenderer.js +156 -71
  240. package/dist/canvas/canvasRenderer.js.map +1 -1
  241. package/dist/canvas/colorOverrides.js +18 -10
  242. package/dist/canvas/colorOverrides.js.map +1 -1
  243. package/dist/canvas/copiesAbove.js +24 -14
  244. package/dist/canvas/copiesAbove.js.map +1 -1
  245. package/dist/canvas/defaultDrawOne.js +55 -31
  246. package/dist/canvas/defaultDrawOne.js.map +1 -1
  247. package/dist/canvas/deps/areaSelect.js +30 -12
  248. package/dist/canvas/deps/areaSelect.js.map +1 -1
  249. package/dist/canvas/deps/booleans.js +104 -0
  250. package/dist/canvas/deps/booleans.js.map +1 -0
  251. package/dist/canvas/deps/changes.js +17 -9
  252. package/dist/canvas/deps/changes.js.map +1 -1
  253. package/dist/canvas/deps/debug.js +12 -5
  254. package/dist/canvas/deps/debug.js.map +1 -1
  255. package/dist/canvas/deps/dispatchSources.js +27 -0
  256. package/dist/canvas/deps/dispatchSources.js.map +1 -0
  257. package/dist/canvas/deps/dispatcher.js +18 -7
  258. package/dist/canvas/deps/dispatcher.js.map +1 -1
  259. package/dist/canvas/deps/editAnchors.js +253 -63
  260. package/dist/canvas/deps/editAnchors.js.map +1 -1
  261. package/dist/canvas/deps/geometryProjection.js +13 -7
  262. package/dist/canvas/deps/geometryProjection.js.map +1 -1
  263. package/dist/canvas/deps/hitTestArea.js +78 -53
  264. package/dist/canvas/deps/hitTestArea.js.map +1 -1
  265. package/dist/canvas/deps/ingestion.js +18 -13
  266. package/dist/canvas/deps/ingestion.js.map +1 -1
  267. package/dist/canvas/deps/insert.js +176 -116
  268. package/dist/canvas/deps/insert.js.map +1 -1
  269. package/dist/canvas/deps/kitSettings.js +16 -0
  270. package/dist/canvas/deps/kitSettings.js.map +1 -0
  271. package/dist/canvas/deps/lassoSelect.js +25 -13
  272. package/dist/canvas/deps/lassoSelect.js.map +1 -1
  273. package/dist/canvas/deps/layout.js +32 -20
  274. package/dist/canvas/deps/layout.js.map +1 -1
  275. package/dist/canvas/deps/nodeAtPoint.js +28 -14
  276. package/dist/canvas/deps/nodeAtPoint.js.map +1 -1
  277. package/dist/canvas/deps/pathLeaf.js +66 -0
  278. package/dist/canvas/deps/pathLeaf.js.map +1 -0
  279. package/dist/canvas/deps/pathLeafDeps.js +13 -0
  280. package/dist/canvas/deps/pathLeafDeps.js.map +1 -0
  281. package/dist/canvas/deps/poseDescriptor.js +10 -8
  282. package/dist/canvas/deps/poseDescriptor.js.map +1 -1
  283. package/dist/canvas/deps/previewPaths.js +44 -0
  284. package/dist/canvas/deps/previewPaths.js.map +1 -0
  285. package/dist/canvas/deps/resizePolicy.js +32 -25
  286. package/dist/canvas/deps/resizePolicy.js.map +1 -1
  287. package/dist/canvas/deps/slice.js +73 -87
  288. package/dist/canvas/deps/slice.js.map +1 -1
  289. package/dist/canvas/deps/snap.js +58 -7
  290. package/dist/canvas/deps/snap.js.map +1 -1
  291. package/dist/canvas/deps/surface.js +30 -0
  292. package/dist/canvas/deps/surface.js.map +1 -0
  293. package/dist/canvas/deps/textEdit.js +21 -13
  294. package/dist/canvas/deps/textEdit.js.map +1 -1
  295. package/dist/canvas/deps/view.js +46 -34
  296. package/dist/canvas/deps/view.js.map +1 -1
  297. package/dist/canvas/derivedPath.js +154 -70
  298. package/dist/canvas/derivedPath.js.map +1 -1
  299. package/dist/canvas/doubleClickTarget.js +20 -0
  300. package/dist/canvas/doubleClickTarget.js.map +1 -0
  301. package/dist/canvas/drawEnvelope.js +26 -17
  302. package/dist/canvas/drawEnvelope.js.map +1 -1
  303. package/dist/canvas/drawnBounds.js +116 -0
  304. package/dist/canvas/drawnBounds.js.map +1 -0
  305. package/dist/canvas/getNodeAtPoint.js +11 -8
  306. package/dist/canvas/getNodeAtPoint.js.map +1 -1
  307. package/dist/canvas/hostAnchor.js +35 -18
  308. package/dist/canvas/hostAnchor.js.map +1 -1
  309. package/dist/canvas/hud.module.js +25 -14
  310. package/dist/canvas/hud.module.js.map +1 -1
  311. package/dist/canvas/insertPreviewExtent.js +82 -61
  312. package/dist/canvas/insertPreviewExtent.js.map +1 -1
  313. package/dist/canvas/kitRequirements.js +154 -115
  314. package/dist/canvas/kitRequirements.js.map +1 -1
  315. package/dist/canvas/layerHover.js +28 -0
  316. package/dist/canvas/layerHover.js.map +1 -0
  317. package/dist/canvas/layerOrder.js +107 -57
  318. package/dist/canvas/layerOrder.js.map +1 -1
  319. package/dist/canvas/layerSlots.js +16 -9
  320. package/dist/canvas/layerSlots.js.map +1 -1
  321. package/dist/canvas/mountedCanvases.js +23 -13
  322. package/dist/canvas/mountedCanvases.js.map +1 -1
  323. package/dist/canvas/nodeShapes/derivedPainter.js +65 -25
  324. package/dist/canvas/nodeShapes/derivedPainter.js.map +1 -1
  325. package/dist/canvas/nodeShapes/imagePainter.js +69 -53
  326. package/dist/canvas/nodeShapes/imagePainter.js.map +1 -1
  327. package/dist/canvas/nodeShapes/measurePainter.js +58 -0
  328. package/dist/canvas/nodeShapes/measurePainter.js.map +1 -0
  329. package/dist/canvas/nodeShapes/memo.js +16 -5
  330. package/dist/canvas/nodeShapes/memo.js.map +1 -1
  331. package/dist/canvas/nodeShapes/nodePaint.js +125 -46
  332. package/dist/canvas/nodeShapes/nodePaint.js.map +1 -1
  333. package/dist/canvas/nodeShapes/pathPainter.js +41 -27
  334. package/dist/canvas/nodeShapes/pathPainter.js.map +1 -1
  335. package/dist/canvas/nodeShapes/poseBox.js +20 -13
  336. package/dist/canvas/nodeShapes/poseBox.js.map +1 -1
  337. package/dist/canvas/nodeShapes/rectFallbackPainter.js +26 -22
  338. package/dist/canvas/nodeShapes/rectFallbackPainter.js.map +1 -1
  339. package/dist/canvas/nodeShapes/shapePainter.js +67 -46
  340. package/dist/canvas/nodeShapes/shapePainter.js.map +1 -1
  341. package/dist/canvas/nodeShapes/strokedBounds.js +177 -0
  342. package/dist/canvas/nodeShapes/strokedBounds.js.map +1 -0
  343. package/dist/canvas/nodeShapes/textPainter.js +170 -37
  344. package/dist/canvas/nodeShapes/textPainter.js.map +1 -1
  345. package/dist/canvas/overChildren.js +29 -18
  346. package/dist/canvas/overChildren.js.map +1 -1
  347. package/dist/canvas/overlayRoleStrokes.js +20 -3
  348. package/dist/canvas/overlayRoleStrokes.js.map +1 -1
  349. package/dist/canvas/paintCull.js +24 -12
  350. package/dist/canvas/paintCull.js.map +1 -1
  351. package/dist/canvas/paintedCursorLayer.js +59 -35
  352. package/dist/canvas/paintedCursorLayer.js.map +1 -1
  353. package/dist/canvas/pathOverlay.js +63 -0
  354. package/dist/canvas/pathOverlay.js.map +1 -0
  355. package/dist/canvas/pickReach.js +34 -17
  356. package/dist/canvas/pickReach.js.map +1 -1
  357. package/dist/canvas/pickWalk.js +151 -102
  358. package/dist/canvas/pickWalk.js.map +1 -1
  359. package/dist/canvas/planeClips.js +39 -22
  360. package/dist/canvas/planeClips.js.map +1 -1
  361. package/dist/canvas/poseCascade.js +51 -27
  362. package/dist/canvas/poseCascade.js.map +1 -1
  363. package/dist/canvas/poseRotation.js +24 -14
  364. package/dist/canvas/poseRotation.js.map +1 -1
  365. package/dist/canvas/rasterReadback.js +23 -15
  366. package/dist/canvas/rasterReadback.js.map +1 -1
  367. package/dist/canvas/rasterToPng.js +21 -15
  368. package/dist/canvas/rasterToPng.js.map +1 -1
  369. package/dist/canvas/renderDebugSnapshot.js +36 -19
  370. package/dist/canvas/renderDebugSnapshot.js.map +1 -1
  371. package/dist/canvas/renderNeeds.js +33 -18
  372. package/dist/canvas/renderNeeds.js.map +1 -1
  373. package/dist/canvas/renderSceneToPixels.js +202 -87
  374. package/dist/canvas/renderSceneToPixels.js.map +1 -1
  375. package/dist/canvas/sceneAdapter.js +96 -75
  376. package/dist/canvas/sceneAdapter.js.map +1 -1
  377. package/dist/canvas/sceneClipboard.js +141 -92
  378. package/dist/canvas/sceneClipboard.js.map +1 -1
  379. package/dist/canvas/sceneLayerPaint.js +56 -27
  380. package/dist/canvas/sceneLayerPaint.js.map +1 -1
  381. package/dist/canvas/sceneSlotWiring.js +24 -14
  382. package/dist/canvas/sceneSlotWiring.js.map +1 -1
  383. package/dist/canvas/sceneViewRender.js +85 -49
  384. package/dist/canvas/sceneViewRender.js.map +1 -1
  385. package/dist/canvas/slopsDebugLayer.js +58 -49
  386. package/dist/canvas/slopsDebugLayer.js.map +1 -1
  387. package/dist/canvas/surfaceContribution.js +22 -10
  388. package/dist/canvas/surfaceContribution.js.map +1 -1
  389. package/dist/canvas/useCanvasElements.js +31 -0
  390. package/dist/canvas/useCanvasElements.js.map +1 -0
  391. package/dist/canvas/useCanvasHandle.js +69 -0
  392. package/dist/canvas/useCanvasHandle.js.map +1 -0
  393. package/dist/canvas/useCanvasPaint.js +91 -0
  394. package/dist/canvas/useCanvasPaint.js.map +1 -0
  395. package/dist/canvas/useCanvasRenderer.js +45 -23
  396. package/dist/canvas/useCanvasRenderer.js.map +1 -1
  397. package/dist/canvas/useCanvasSurface.js +41 -23
  398. package/dist/canvas/useCanvasSurface.js.map +1 -1
  399. package/dist/canvas/useCanvasView.js +80 -48
  400. package/dist/canvas/useCanvasView.js.map +1 -1
  401. package/dist/canvas/useClientToWorld.js +27 -0
  402. package/dist/canvas/useClientToWorld.js.map +1 -0
  403. package/dist/canvas/useExtraLayers.js +45 -0
  404. package/dist/canvas/useExtraLayers.js.map +1 -0
  405. package/dist/canvas/useFrameLoop.js +109 -49
  406. package/dist/canvas/useFrameLoop.js.map +1 -1
  407. package/dist/canvas/useHitObserver.js +22 -15
  408. package/dist/canvas/useHitObserver.js.map +1 -1
  409. package/dist/canvas/useHostAnchor.js +83 -53
  410. package/dist/canvas/useHostAnchor.js.map +1 -1
  411. package/dist/canvas/useLateContentRedraw.js +21 -14
  412. package/dist/canvas/useLateContentRedraw.js.map +1 -1
  413. package/dist/canvas/useLayerStack.js +72 -0
  414. package/dist/canvas/useLayerStack.js.map +1 -0
  415. package/dist/canvas/usePaintedCursor.js +28 -0
  416. package/dist/canvas/usePaintedCursor.js.map +1 -0
  417. package/dist/canvas/useRedrawOn.js +24 -14
  418. package/dist/canvas/useRedrawOn.js.map +1 -1
  419. package/dist/canvas/useSceneAdapter.js +21 -16
  420. package/dist/canvas/useSceneAdapter.js.map +1 -1
  421. package/dist/canvas/useSceneLayerList.js +15 -7
  422. package/dist/canvas/useSceneLayerList.js.map +1 -1
  423. package/dist/canvas/useSurfaceInput.js +46 -27
  424. package/dist/canvas/useSurfaceInput.js.map +1 -1
  425. package/dist/canvas/useSurfaceSize.js +43 -0
  426. package/dist/canvas/useSurfaceSize.js.map +1 -0
  427. package/dist/canvas/useToolCursor.js +30 -21
  428. package/dist/canvas/useToolCursor.js.map +1 -1
  429. package/dist/canvas/useViewHelpers.js +112 -61
  430. package/dist/canvas/useViewHelpers.js.map +1 -1
  431. package/dist/canvas/useViewLayerGate.js +29 -0
  432. package/dist/canvas/useViewLayerGate.js.map +1 -0
  433. package/dist/canvas/useViewNesting.js +104 -0
  434. package/dist/canvas/useViewNesting.js.map +1 -0
  435. package/dist/canvas/useViewRegistrySurface.js +44 -0
  436. package/dist/canvas/useViewRegistrySurface.js.map +1 -0
  437. package/dist/canvas/viewInputs.js +14 -11
  438. package/dist/canvas/viewInputs.js.map +1 -1
  439. package/dist/canvas/viewRegistry.js +140 -42
  440. package/dist/canvas/viewRegistry.js.map +1 -1
  441. package/dist/canvas/watchElementMove.js +71 -33
  442. package/dist/canvas/watchElementMove.js.map +1 -1
  443. package/dist/canvas/wrapNodeOutput.js +20 -13
  444. package/dist/canvas/wrapNodeOutput.js.map +1 -1
  445. package/dist/clipboard.d.ts +7 -3
  446. package/dist/clipboard.js +4 -3
  447. package/dist/{clone-C0eADtS0.d.ts → clone-DZDrfIlU.d.ts} +20 -53
  448. package/dist/clone.d.ts +5 -4
  449. package/dist/core/adapters/testing/rootsTree.js +17 -0
  450. package/dist/core/adapters/testing/rootsTree.js.map +1 -0
  451. package/dist/core/applyOps.js +23 -7
  452. package/dist/core/applyOps.js.map +1 -1
  453. package/dist/core/device/index.js +6 -5
  454. package/dist/core/device/targets.js +29 -8
  455. package/dist/core/device/targets.js.map +1 -1
  456. package/dist/core/device/useDeviceProfile.js +86 -52
  457. package/dist/core/device/useDeviceProfile.js.map +1 -1
  458. package/dist/core/device/useTargetBasePx.js +23 -0
  459. package/dist/core/device/useTargetBasePx.js.map +1 -0
  460. package/dist/core/device/watchDevicePixelRatio.js +27 -10
  461. package/dist/core/device/watchDevicePixelRatio.js.map +1 -1
  462. package/dist/core/geometry/autoPoseDescriptor.js +38 -24
  463. package/dist/core/geometry/autoPoseDescriptor.js.map +1 -1
  464. package/dist/core/geometry/inkExtents.js +60 -0
  465. package/dist/core/geometry/inkExtents.js.map +1 -0
  466. package/dist/core/geometry/pathPoseDescriptor.js +101 -76
  467. package/dist/core/geometry/pathPoseDescriptor.js.map +1 -1
  468. package/dist/core/geometry/poseDescriptor.js +199 -136
  469. package/dist/core/geometry/poseDescriptor.js.map +1 -1
  470. package/dist/core/geometry/regionHit.js +127 -79
  471. package/dist/core/geometry/regionHit.js.map +1 -1
  472. package/dist/core/geometry/targetFrame.js +84 -60
  473. package/dist/core/geometry/targetFrame.js.map +1 -1
  474. package/dist/core/geometry/unionBounds.js +103 -48
  475. package/dist/core/geometry/unionBounds.js.map +1 -1
  476. package/dist/core/isPlainObject.js +3 -2
  477. package/dist/core/layers/backgroundFill.js +23 -15
  478. package/dist/core/layers/backgroundFill.js.map +1 -1
  479. package/dist/core/layers/children.js +16 -13
  480. package/dist/core/layers/children.js.map +1 -1
  481. package/dist/core/layers/gateLayer.js +24 -9
  482. package/dist/core/layers/gateLayer.js.map +1 -1
  483. package/dist/core/layers/layerGroup.js +42 -29
  484. package/dist/core/layers/layerGroup.js.map +1 -1
  485. package/dist/core/layers/redrawSource.js +15 -0
  486. package/dist/core/layers/redrawSource.js.map +1 -0
  487. package/dist/core/layers/render.js +183 -93
  488. package/dist/core/layers/render.js.map +1 -1
  489. package/dist/core/layers/retain.js +38 -0
  490. package/dist/core/layers/retain.js.map +1 -0
  491. package/dist/core/ops/arrange.js +30 -19
  492. package/dist/core/ops/arrange.js.map +1 -1
  493. package/dist/core/ops/create.js +32 -23
  494. package/dist/core/ops/create.js.map +1 -1
  495. package/dist/core/ops/createHistory.js +23 -14
  496. package/dist/core/ops/createHistory.js.map +1 -1
  497. package/dist/core/ops/delete.js +80 -53
  498. package/dist/core/ops/delete.js.map +1 -1
  499. package/dist/core/ops/nodeFlags.js +44 -0
  500. package/dist/core/ops/nodeFlags.js.map +1 -0
  501. package/dist/core/ops/registry.js +26 -11
  502. package/dist/core/ops/registry.js.map +1 -1
  503. package/dist/core/ops/reorder/algorithms.js +62 -38
  504. package/dist/core/ops/reorder/algorithms.js.map +1 -1
  505. package/dist/core/ops/reorder/index.js +124 -84
  506. package/dist/core/ops/reorder/index.js.map +1 -1
  507. package/dist/core/ops/reorder/setChildOrder.js +32 -23
  508. package/dist/core/ops/reorder/setChildOrder.js.map +1 -1
  509. package/dist/core/ops/reparent.js +63 -37
  510. package/dist/core/ops/reparent.js.map +1 -1
  511. package/dist/core/ops/select.js +23 -20
  512. package/dist/core/ops/select.js.map +1 -1
  513. package/dist/core/ops/setData.js +23 -21
  514. package/dist/core/ops/setData.js.map +1 -1
  515. package/dist/core/ops/setLayer.js +26 -21
  516. package/dist/core/ops/setLayer.js.map +1 -1
  517. package/dist/core/ops/setLayout.js +27 -18
  518. package/dist/core/ops/setLayout.js.map +1 -1
  519. package/dist/core/ops/setPath.js +60 -41
  520. package/dist/core/ops/setPath.js.map +1 -1
  521. package/dist/core/ops/setText.js +26 -21
  522. package/dist/core/ops/setText.js.map +1 -1
  523. package/dist/core/ops/slot.js +36 -22
  524. package/dist/core/ops/slot.js.map +1 -1
  525. package/dist/core/ops/transform.js +35 -28
  526. package/dist/core/ops/transform.js.map +1 -1
  527. package/dist/core/pages/fitViewToPage.js +13 -11
  528. package/dist/core/pages/fitViewToPage.js.map +1 -1
  529. package/dist/core/pages/pages.js +73 -42
  530. package/dist/core/pages/pages.js.map +1 -1
  531. package/dist/core/pages/pagesLayer.js +19 -13
  532. package/dist/core/pages/pagesLayer.js.map +1 -1
  533. package/dist/core/paint/meshKind.js +16 -11
  534. package/dist/core/paint/meshKind.js.map +1 -1
  535. package/dist/core/paint/meshKindLazy.js +1 -1
  536. package/dist/core/paint/meshKindLazy.js.map +1 -1
  537. package/dist/core/paint/paintKindEntry.js +13 -4
  538. package/dist/core/paint/paintKindEntry.js.map +1 -1
  539. package/dist/core/paint/paintKinds.js +149 -88
  540. package/dist/core/paint/paintKinds.js.map +1 -1
  541. package/dist/core/paint/registerMesh.js +6 -4
  542. package/dist/core/paint/registerMesh.js.map +1 -1
  543. package/dist/core/scene/NodeProperties.js +15 -10
  544. package/dist/core/scene/NodeProperties.js.map +1 -1
  545. package/dist/core/scene/NodeRouting.js +16 -12
  546. package/dist/core/scene/NodeRouting.js.map +1 -1
  547. package/dist/core/scene/annotation.js +28 -0
  548. package/dist/core/scene/annotation.js.map +1 -0
  549. package/dist/core/scene/appliedLog.js +31 -23
  550. package/dist/core/scene/appliedLog.js.map +1 -1
  551. package/dist/core/scene/arrivalWindow.js +120 -75
  552. package/dist/core/scene/arrivalWindow.js.map +1 -1
  553. package/dist/core/scene/arrivals.js +17 -6
  554. package/dist/core/scene/arrivals.js.map +1 -1
  555. package/dist/core/scene/boundOps.js +42 -23
  556. package/dist/core/scene/boundOps.js.map +1 -1
  557. package/dist/core/scene/composeFrame.js +51 -21
  558. package/dist/core/scene/composeFrame.js.map +1 -1
  559. package/dist/core/scene/composePose.js +114 -62
  560. package/dist/core/scene/composePose.js.map +1 -1
  561. package/dist/core/scene/depFrame.js +94 -0
  562. package/dist/core/scene/depFrame.js.map +1 -0
  563. package/dist/core/scene/depMemo.js +44 -19
  564. package/dist/core/scene/depMemo.js.map +1 -1
  565. package/dist/core/scene/dependents.js +73 -45
  566. package/dist/core/scene/dependents.js.map +1 -1
  567. package/dist/core/scene/derivedParts.js +58 -0
  568. package/dist/core/scene/derivedParts.js.map +1 -0
  569. package/dist/core/scene/derivedPath.js +52 -22
  570. package/dist/core/scene/derivedPath.js.map +1 -1
  571. package/dist/core/scene/editMode.js +11 -11
  572. package/dist/core/scene/editMode.js.map +1 -1
  573. package/dist/core/scene/effectivePose.js +167 -51
  574. package/dist/core/scene/effectivePose.js.map +1 -1
  575. package/dist/core/scene/fieldEdits.js +95 -75
  576. package/dist/core/scene/fieldEdits.js.map +1 -1
  577. package/dist/core/scene/historyFacade.js +126 -87
  578. package/dist/core/scene/historyFacade.js.map +1 -1
  579. package/dist/core/scene/historyForm.js +7 -3
  580. package/dist/core/scene/historyForm.js.map +1 -1
  581. package/dist/core/scene/kitOps.js +203 -131
  582. package/dist/core/scene/kitOps.js.map +1 -1
  583. package/dist/core/scene/kitRegistry.js +49 -22
  584. package/dist/core/scene/kitRegistry.js.map +1 -1
  585. package/dist/core/scene/layerStack.js +123 -92
  586. package/dist/core/scene/layerStack.js.map +1 -1
  587. package/dist/core/scene/layoutPass.js +118 -72
  588. package/dist/core/scene/layoutPass.js.map +1 -1
  589. package/dist/core/scene/lockGuard.js +32 -24
  590. package/dist/core/scene/lockGuard.js.map +1 -1
  591. package/dist/core/scene/minSize.js +17 -0
  592. package/dist/core/scene/minSize.js.map +1 -0
  593. package/dist/core/scene/nestedHit.js +45 -31
  594. package/dist/core/scene/nestedHit.js.map +1 -1
  595. package/dist/core/scene/nodeFlags.js +43 -0
  596. package/dist/core/scene/nodeFlags.js.map +1 -0
  597. package/dist/core/scene/nodeFnFields.js +58 -41
  598. package/dist/core/scene/nodeFnFields.js.map +1 -1
  599. package/dist/core/scene/nodeGates.js +58 -0
  600. package/dist/core/scene/nodeGates.js.map +1 -0
  601. package/dist/core/scene/nodeMemo.js +92 -40
  602. package/dist/core/scene/nodeMemo.js.map +1 -1
  603. package/dist/core/scene/nodeStore.js +179 -99
  604. package/dist/core/scene/nodeStore.js.map +1 -1
  605. package/dist/core/scene/notifier.js +30 -19
  606. package/dist/core/scene/notifier.js.map +1 -1
  607. package/dist/core/scene/opTable.js +42 -36
  608. package/dist/core/scene/opTable.js.map +1 -1
  609. package/dist/core/scene/outerOps.js +49 -43
  610. package/dist/core/scene/outerOps.js.map +1 -1
  611. package/dist/core/scene/pathEffects/blend.js +80 -0
  612. package/dist/core/scene/pathEffects/blend.js.map +1 -0
  613. package/dist/core/scene/pathEffects/derive.js +112 -0
  614. package/dist/core/scene/pathEffects/derive.js.map +1 -0
  615. package/dist/core/scene/pathEffects/effects.js +40 -0
  616. package/dist/core/scene/pathEffects/effects.js.map +1 -0
  617. package/dist/core/scene/poseFeed.js +95 -60
  618. package/dist/core/scene/poseFeed.js.map +1 -1
  619. package/dist/core/scene/poseHold.js +33 -24
  620. package/dist/core/scene/poseHold.js.map +1 -1
  621. package/dist/core/scene/poseOverrides.js +86 -49
  622. package/dist/core/scene/poseOverrides.js.map +1 -1
  623. package/dist/core/scene/poseRemovals.js +58 -0
  624. package/dist/core/scene/poseRemovals.js.map +1 -0
  625. package/dist/core/scene/poseSnapshot.js +62 -41
  626. package/dist/core/scene/poseSnapshot.js.map +1 -1
  627. package/dist/core/scene/poseWrites.js +151 -0
  628. package/dist/core/scene/poseWrites.js.map +1 -0
  629. package/dist/core/scene/reconcileSpecs.js +63 -34
  630. package/dist/core/scene/reconcileSpecs.js.map +1 -1
  631. package/dist/core/scene/recorder.js +90 -57
  632. package/dist/core/scene/recorder.js.map +1 -1
  633. package/dist/core/scene/renderOrder.js +105 -59
  634. package/dist/core/scene/renderOrder.js.map +1 -1
  635. package/dist/core/scene/scene.js +133 -80
  636. package/dist/core/scene/scene.js.map +1 -1
  637. package/dist/core/scene/sceneEdits.js +62 -49
  638. package/dist/core/scene/sceneEdits.js.map +1 -1
  639. package/dist/core/scene/sceneMutators.js +44 -36
  640. package/dist/core/scene/sceneMutators.js.map +1 -1
  641. package/dist/core/scene/scenePoseAdapter.js +13 -9
  642. package/dist/core/scene/scenePoseAdapter.js.map +1 -1
  643. package/dist/core/scene/sceneRecording.js +89 -73
  644. package/dist/core/scene/sceneRecording.js.map +1 -1
  645. package/dist/core/scene/sceneSelection.js +23 -16
  646. package/dist/core/scene/sceneSelection.js.map +1 -1
  647. package/dist/core/scene/sceneState.js +54 -36
  648. package/dist/core/scene/sceneState.js.map +1 -1
  649. package/dist/core/scene/serialization.js +87 -50
  650. package/dist/core/scene/serialization.js.map +1 -1
  651. package/dist/core/scene/staleReplay.js +35 -26
  652. package/dist/core/scene/staleReplay.js.map +1 -1
  653. package/dist/core/scene/statedFields.js +10 -5
  654. package/dist/core/scene/statedFields.js.map +1 -1
  655. package/dist/core/scene/treeEdits.js +129 -98
  656. package/dist/core/scene/treeEdits.js.map +1 -1
  657. package/dist/core/scene/treeOrder.js +13 -8
  658. package/dist/core/scene/treeOrder.js.map +1 -1
  659. package/dist/core/scene/treeReads.js +25 -16
  660. package/dist/core/scene/treeReads.js.map +1 -1
  661. package/dist/core/scene/types.js +4 -3
  662. package/dist/core/scene/types.js.map +1 -1
  663. package/dist/core/scene/unionOfChildren.js +20 -10
  664. package/dist/core/scene/unionOfChildren.js.map +1 -1
  665. package/dist/core/scene/unitScopes.js +15 -8
  666. package/dist/core/scene/unitScopes.js.map +1 -1
  667. package/dist/core/scene/useScene.js +32 -24
  668. package/dist/core/scene/useScene.js.map +1 -1
  669. package/dist/core/selection/chromeState.js +41 -17
  670. package/dist/core/selection/chromeState.js.map +1 -1
  671. package/dist/core/selection/readOnlySelection.js +39 -24
  672. package/dist/core/selection/readOnlySelection.js.map +1 -1
  673. package/dist/core/selection/selectionTarget.js +14 -3
  674. package/dist/core/selection/selectionTarget.js.map +1 -1
  675. package/dist/core/selection/usePublishSceneSelection.js +25 -18
  676. package/dist/core/selection/usePublishSceneSelection.js.map +1 -1
  677. package/dist/core/selection/useSelection.js +90 -57
  678. package/dist/core/selection/useSelection.js.map +1 -1
  679. package/dist/core/shapeKinds.js +43 -28
  680. package/dist/core/shapeKinds.js.map +1 -1
  681. package/dist/core/stableStringify.js +5 -4
  682. package/dist/core/stableStringify.js.map +1 -1
  683. package/dist/core/stylus/stylus.js +49 -25
  684. package/dist/core/stylus/stylus.js.map +1 -1
  685. package/dist/core/stylus/usePointerStylus.js +61 -34
  686. package/dist/core/stylus/usePointerStylus.js.map +1 -1
  687. package/dist/core/usePaintKinds.js +21 -11
  688. package/dist/core/usePaintKinds.js.map +1 -1
  689. package/dist/core/viewport/clampView.js +31 -15
  690. package/dist/core/viewport/clampView.js.map +1 -1
  691. package/dist/core/viewport/clientToWorld.js +15 -4
  692. package/dist/core/viewport/clientToWorld.js.map +1 -1
  693. package/dist/core/viewport/createVelocityTracker.js +23 -19
  694. package/dist/core/viewport/createVelocityTracker.js.map +1 -1
  695. package/dist/core/viewport/fitToBounds.js +28 -11
  696. package/dist/core/viewport/fitToBounds.js.map +1 -1
  697. package/dist/core/viewport/fitViewToBounds.js +45 -19
  698. package/dist/core/viewport/fitViewToBounds.js.map +1 -1
  699. package/dist/core/viewport/interpolateView.js +40 -20
  700. package/dist/core/viewport/interpolateView.js.map +1 -1
  701. package/dist/core/viewport/parallax.js +89 -56
  702. package/dist/core/viewport/parallax.js.map +1 -1
  703. package/dist/core/viewport/sceneNodeClientRect.js +21 -12
  704. package/dist/core/viewport/sceneNodeClientRect.js.map +1 -1
  705. package/dist/core/viewport/screenSlop.js +40 -17
  706. package/dist/core/viewport/screenSlop.js.map +1 -1
  707. package/dist/core/viewport/useAutoCenter.js +36 -22
  708. package/dist/core/viewport/useAutoCenter.js.map +1 -1
  709. package/dist/core/viewport/useCanvasSize.js +43 -22
  710. package/dist/core/viewport/useCanvasSize.js.map +1 -1
  711. package/dist/core/viewport/useDecayLoop.js +120 -48
  712. package/dist/core/viewport/useDecayLoop.js.map +1 -1
  713. package/dist/core/viewport/useNodeOverlayFrame.js +93 -58
  714. package/dist/core/viewport/useNodeOverlayFrame.js.map +1 -1
  715. package/dist/core/viewport/useVelocityTracker.js +9 -6
  716. package/dist/core/viewport/useVelocityTracker.js.map +1 -1
  717. package/dist/core/viewport/useViewAnimation.js +143 -84
  718. package/dist/core/viewport/useViewAnimation.js.map +1 -1
  719. package/dist/core/viewport/view.js +48 -24
  720. package/dist/core/viewport/view.js.map +1 -1
  721. package/dist/core/viewport/viewTransform.js +8 -6
  722. package/dist/core/viewport/viewTransform.js.map +1 -1
  723. package/dist/core/viewport/viewportWorldRect.js +15 -7
  724. package/dist/core/viewport/viewportWorldRect.js.map +1 -1
  725. package/dist/core/viewport/wheelHandler.js +31 -20
  726. package/dist/core/viewport/wheelHandler.js.map +1 -1
  727. package/dist/core/viewport/zoomAt.js +47 -19
  728. package/dist/core/viewport/zoomAt.js.map +1 -1
  729. package/dist/core/viewport/zoomBounds.js +33 -17
  730. package/dist/core/viewport/zoomBounds.js.map +1 -1
  731. package/dist/cornerHandles-Camw_yeu.d.ts +169 -0
  732. package/dist/debug/createDebugOverlayLayer.js +303 -215
  733. package/dist/debug/createDebugOverlayLayer.js.map +1 -1
  734. package/dist/debug/createDebugSink.js +68 -47
  735. package/dist/debug/createDebugSink.js.map +1 -1
  736. package/dist/debug/defaultTheme.js +16 -4
  737. package/dist/debug/defaultTheme.js.map +1 -1
  738. package/dist/debug/flag.js +3 -2
  739. package/dist/debug/frameStats.js +11 -9
  740. package/dist/debug/frameStats.js.map +1 -1
  741. package/dist/debug/parseDebugFlags.js +25 -17
  742. package/dist/debug/parseDebugFlags.js.map +1 -1
  743. package/dist/debug/useDebugSink.js +52 -33
  744. package/dist/debug/useDebugSink.js.map +1 -1
  745. package/dist/depSchema-Cgfu_G9s.d.ts +3581 -0
  746. package/dist/features/chrome-caps/buildChromeCtx.js +12 -10
  747. package/dist/features/chrome-caps/buildChromeCtx.js.map +1 -1
  748. package/dist/features/chrome-caps/conditions.js +103 -25
  749. package/dist/features/chrome-caps/conditions.js.map +1 -1
  750. package/dist/features/chrome-caps/defaults.js +18 -10
  751. package/dist/features/chrome-caps/defaults.js.map +1 -1
  752. package/dist/features/chrome-caps/index.js +8 -7
  753. package/dist/features/chrome-caps/resolve.js +28 -16
  754. package/dist/features/chrome-caps/resolve.js.map +1 -1
  755. package/dist/features/chrome-caps/useChromeCaps.js +52 -44
  756. package/dist/features/chrome-caps/useChromeCaps.js.map +1 -1
  757. package/dist/features/chrome-caps/useHoverTracking.js +52 -26
  758. package/dist/features/chrome-caps/useHoverTracking.js.map +1 -1
  759. package/dist/features/ingestion/contentHandlers.js +80 -34
  760. package/dist/features/ingestion/contentHandlers.js.map +1 -1
  761. package/dist/features/ingestion/imageHandler.js +49 -29
  762. package/dist/features/ingestion/imageHandler.js.map +1 -1
  763. package/dist/features/ingestion/openFilePicker.js +27 -9
  764. package/dist/features/ingestion/openFilePicker.js.map +1 -1
  765. package/dist/features/ingestion/placement.js +20 -11
  766. package/dist/features/ingestion/placement.js.map +1 -1
  767. package/dist/features/ingestion/registerKitHandlers.js +35 -18
  768. package/dist/features/ingestion/registerKitHandlers.js.map +1 -1
  769. package/dist/features/ingestion/svgHandler.js +60 -34
  770. package/dist/features/ingestion/svgHandler.js.map +1 -1
  771. package/dist/features/ingestion/textHandler.js +37 -16
  772. package/dist/features/ingestion/textHandler.js.map +1 -1
  773. package/dist/features/ingestion/useCanvasIngestion.js +57 -39
  774. package/dist/features/ingestion/useCanvasIngestion.js.map +1 -1
  775. package/dist/features/ingestion/weaselJsonHandler.js +38 -28
  776. package/dist/features/ingestion/weaselJsonHandler.js.map +1 -1
  777. package/dist/features/longPress/longPressFeedback.js +110 -81
  778. package/dist/features/longPress/longPressFeedback.js.map +1 -1
  779. package/dist/features/measure/actionIds.js +22 -0
  780. package/dist/features/measure/actionIds.js.map +1 -0
  781. package/dist/features/measure/measureCommands.js +178 -0
  782. package/dist/features/measure/measureCommands.js.map +1 -0
  783. package/dist/features/measure/measureContribution.js +57 -0
  784. package/dist/features/measure/measureContribution.js.map +1 -0
  785. package/dist/features/measure/measureEdits.js +82 -0
  786. package/dist/features/measure/measureEdits.js.map +1 -0
  787. package/dist/features/measure/measureGestures.js +185 -0
  788. package/dist/features/measure/measureGestures.js.map +1 -0
  789. package/dist/features/measure/measureHit.js +80 -0
  790. package/dist/features/measure/measureHit.js.map +1 -0
  791. package/dist/features/measure/measureLayer.js +86 -0
  792. package/dist/features/measure/measureLayer.js.map +1 -0
  793. package/dist/features/measure/measurement.js +79 -0
  794. package/dist/features/measure/measurement.js.map +1 -0
  795. package/dist/features/measure/measurements.js +41 -0
  796. package/dist/features/measure/measurements.js.map +1 -0
  797. package/dist/features/modes/modeLayers.js +81 -55
  798. package/dist/features/modes/modeLayers.js.map +1 -1
  799. package/dist/features/modes/modeTriggers.js +66 -0
  800. package/dist/features/modes/modeTriggers.js.map +1 -0
  801. package/dist/features/pathEffects/index.js +35 -0
  802. package/dist/features/pathEffects/index.js.map +1 -0
  803. package/dist/features/pathEffects/readSource.js +46 -0
  804. package/dist/features/pathEffects/readSource.js.map +1 -0
  805. package/dist/features/paths/anchorData.js +65 -0
  806. package/dist/features/paths/anchorData.js.map +1 -0
  807. package/dist/features/paths/anchorMarkers.js +137 -0
  808. package/dist/features/paths/anchorMarkers.js.map +1 -0
  809. package/dist/features/paths/editablePath.js +149 -46
  810. package/dist/features/paths/editablePath.js.map +1 -1
  811. package/dist/features/paths/index.js +12 -9
  812. package/dist/features/paths/originProjection.js +16 -9
  813. package/dist/features/paths/originProjection.js.map +1 -1
  814. package/dist/features/paths/pathEditExtension.js +26 -0
  815. package/dist/features/paths/pathEditExtension.js.map +1 -0
  816. package/dist/features/paths/pathEditState.js +107 -26
  817. package/dist/features/paths/pathEditState.js.map +1 -1
  818. package/dist/features/paths/pathEditingOverlayLayer.js +58 -110
  819. package/dist/features/paths/pathEditingOverlayLayer.js.map +1 -1
  820. package/dist/features/paths/pathLayer.js +79 -29
  821. package/dist/features/paths/pathLayer.js.map +1 -1
  822. package/dist/features/paths/pathRepresentation.js +27 -0
  823. package/dist/features/paths/pathRepresentation.js.map +1 -0
  824. package/dist/features/paths/pathSnap/glyphs.js +39 -0
  825. package/dist/features/paths/pathSnap/glyphs.js.map +1 -0
  826. package/dist/features/paths/pathSnap/pathSnapSource.js +82 -0
  827. package/dist/features/paths/pathSnap/pathSnapSource.js.map +1 -0
  828. package/dist/features/paths/pathSnap/sceneIndex.js +78 -0
  829. package/dist/features/paths/pathSnap/sceneIndex.js.map +1 -0
  830. package/dist/features/paths/pathSnap/snapGeometry.js +47 -0
  831. package/dist/features/paths/pathSnap/snapGeometry.js.map +1 -0
  832. package/dist/features/paths/penPreviewLayer.js +135 -102
  833. package/dist/features/paths/penPreviewLayer.js.map +1 -1
  834. package/dist/features/paths/shapeGenerator.js +112 -60
  835. package/dist/features/paths/shapeGenerator.js.map +1 -1
  836. package/dist/features/paths/strokeOutline.js +15 -0
  837. package/dist/features/paths/strokeOutline.js.map +1 -0
  838. package/dist/features/paths/useAnchorFields.js +35 -0
  839. package/dist/features/paths/useAnchorFields.js.map +1 -0
  840. package/dist/features/paths/usePathEdit.js +58 -28
  841. package/dist/features/paths/usePathEdit.js.map +1 -1
  842. package/dist/features/poseRun/usePoseRun.js +110 -43
  843. package/dist/features/poseRun/usePoseRun.js.map +1 -1
  844. package/dist/features/selection/handleCommands.js +116 -0
  845. package/dist/features/selection/handleCommands.js.map +1 -0
  846. package/dist/features/selection/overlay.js +288 -328
  847. package/dist/features/selection/overlay.js.map +1 -1
  848. package/dist/features/selection/selectionPose.js +109 -0
  849. package/dist/features/selection/selectionPose.js.map +1 -0
  850. package/dist/features/snap/angle2d.js +158 -0
  851. package/dist/features/snap/angle2d.js.map +1 -0
  852. package/dist/features/snap/debugCandidates.js +27 -0
  853. package/dist/features/snap/debugCandidates.js.map +1 -0
  854. package/dist/features/snap/gather.js +71 -0
  855. package/dist/features/snap/gather.js.map +1 -0
  856. package/dist/features/snap/inputSubspace.js +46 -0
  857. package/dist/features/snap/inputSubspace.js.map +1 -0
  858. package/dist/features/snap/marks.js +29 -0
  859. package/dist/features/snap/marks.js.map +1 -0
  860. package/dist/features/snap/outcomeStore.js +25 -0
  861. package/dist/features/snap/outcomeStore.js.map +1 -0
  862. package/dist/features/snap/pointSnap.js +48 -0
  863. package/dist/features/snap/pointSnap.js.map +1 -0
  864. package/dist/features/snap/probes2d.js +91 -0
  865. package/dist/features/snap/probes2d.js.map +1 -0
  866. package/dist/features/snap/readoutDraw.js +93 -0
  867. package/dist/features/snap/readoutDraw.js.map +1 -0
  868. package/dist/features/snap/readoutLayer.js +49 -0
  869. package/dist/features/snap/readoutLayer.js.map +1 -0
  870. package/dist/features/snap/registry.js +27 -0
  871. package/dist/features/snap/registry.js.map +1 -0
  872. package/dist/features/snap/resizeBox.js +137 -0
  873. package/dist/features/snap/resizeBox.js.map +1 -0
  874. package/dist/features/snap/roles.js +31 -0
  875. package/dist/features/snap/roles.js.map +1 -0
  876. package/dist/features/snap/rotationSource.js +30 -0
  877. package/dist/features/snap/rotationSource.js.map +1 -0
  878. package/dist/features/snap/sceneReads.js +45 -0
  879. package/dist/features/snap/sceneReads.js.map +1 -0
  880. package/dist/features/snap/sceneSession2d.js +79 -0
  881. package/dist/features/snap/sceneSession2d.js.map +1 -0
  882. package/dist/features/snap/screen.js +23 -0
  883. package/dist/features/snap/screen.js.map +1 -0
  884. package/dist/features/snap/session2d.js +129 -0
  885. package/dist/features/snap/session2d.js.map +1 -0
  886. package/dist/features/snap/spanSnap.js +77 -0
  887. package/dist/features/snap/spanSnap.js.map +1 -0
  888. package/dist/features/snap/stepAngles.js +15 -0
  889. package/dist/features/snap/stepAngles.js.map +1 -0
  890. package/dist/features/text/editingDrawOne.js +32 -0
  891. package/dist/features/text/editingDrawOne.js.map +1 -0
  892. package/dist/features/text/index.js +7 -6
  893. package/dist/features/text/textHitAt.js +51 -0
  894. package/dist/features/text/textHitAt.js.map +1 -0
  895. package/dist/features/text/textLayer.js +21 -27
  896. package/dist/features/text/textLayer.js.map +1 -1
  897. package/dist/features/text/useSceneTextEdit.js +190 -128
  898. package/dist/features/text/useSceneTextEdit.js.map +1 -1
  899. package/dist/features/viewports/viewResolver.js +48 -39
  900. package/dist/features/viewports/viewResolver.js.map +1 -1
  901. package/dist/features/viewports/viewportLayer.js +60 -29
  902. package/dist/features/viewports/viewportLayer.js.map +1 -1
  903. package/dist/iconRegistry/IconRegistryProvider.js +73 -0
  904. package/dist/iconRegistry/IconRegistryProvider.js.map +1 -0
  905. package/dist/iconRegistry/useIconGlyph.js +14 -0
  906. package/dist/iconRegistry/useIconGlyph.js.map +1 -0
  907. package/dist/iconRegistry/useIconVariant.js +29 -0
  908. package/dist/iconRegistry/useIconVariant.js.map +1 -0
  909. package/dist/icons.d.ts +6 -0
  910. package/dist/icons.js +3 -0
  911. package/dist/icons.table.js +13 -0
  912. package/dist/icons.table.js.map +1 -0
  913. package/dist/icons.table.json +556 -0
  914. package/dist/icons2.table.js +9 -0
  915. package/dist/icons2.table.js.map +1 -0
  916. package/dist/index.d.ts +4259 -5074
  917. package/dist/index.js +340 -285
  918. package/dist/input/keyState.js +118 -54
  919. package/dist/input/keyState.js.map +1 -1
  920. package/dist/input/useKeyModifiers.js +13 -7
  921. package/dist/input/useKeyModifiers.js.map +1 -1
  922. package/dist/input/useKeyState.js +23 -16
  923. package/dist/input/useKeyState.js.map +1 -1
  924. package/dist/interactions/actions/align/action.js +76 -45
  925. package/dist/interactions/actions/align/action.js.map +1 -1
  926. package/dist/interactions/actions/align/align.js +86 -48
  927. package/dist/interactions/actions/align/align.js.map +1 -1
  928. package/dist/interactions/actions/booleans/action.js +67 -33
  929. package/dist/interactions/actions/booleans/action.js.map +1 -1
  930. package/dist/interactions/actions/booleans/booleans.js +77 -70
  931. package/dist/interactions/actions/booleans/booleans.js.map +1 -1
  932. package/dist/interactions/actions/booleans/commit.js +49 -0
  933. package/dist/interactions/actions/booleans/commit.js.map +1 -0
  934. package/dist/interactions/actions/booleans/custom.js +48 -0
  935. package/dist/interactions/actions/booleans/custom.js.map +1 -0
  936. package/dist/interactions/actions/booleans/operands.js +43 -32
  937. package/dist/interactions/actions/booleans/operands.js.map +1 -1
  938. package/dist/interactions/actions/booleans/pieces.js +29 -23
  939. package/dist/interactions/actions/booleans/pieces.js.map +1 -1
  940. package/dist/interactions/actions/booleans/placement.js +30 -17
  941. package/dist/interactions/actions/booleans/placement.js.map +1 -1
  942. package/dist/interactions/actions/booleans/useBooleans.js +30 -17
  943. package/dist/interactions/actions/booleans/useBooleans.js.map +1 -1
  944. package/dist/interactions/actions/booleans/useBooleansAdapter.js +8 -5
  945. package/dist/interactions/actions/booleans/useBooleansAdapter.js.map +1 -1
  946. package/dist/interactions/actions/clipboard/action.js +81 -40
  947. package/dist/interactions/actions/clipboard/action.js.map +1 -1
  948. package/dist/interactions/actions/clipboard/clipboardOps.js +100 -72
  949. package/dist/interactions/actions/clipboard/clipboardOps.js.map +1 -1
  950. package/dist/interactions/actions/clipboard/materializePaste.js +38 -19
  951. package/dist/interactions/actions/clipboard/materializePaste.js.map +1 -1
  952. package/dist/interactions/actions/clipboard/wireFormat.js +66 -28
  953. package/dist/interactions/actions/clipboard/wireFormat.js.map +1 -1
  954. package/dist/interactions/actions/clone/action.js +102 -70
  955. package/dist/interactions/actions/clone/action.js.map +1 -1
  956. package/dist/interactions/actions/clone/behaviors.js +55 -38
  957. package/dist/interactions/actions/clone/behaviors.js.map +1 -1
  958. package/dist/interactions/actions/defaultCommitAdapter.js +32 -10
  959. package/dist/interactions/actions/defaultCommitAdapter.js.map +1 -1
  960. package/dist/interactions/actions/defaults/anchorEditing.js +252 -111
  961. package/dist/interactions/actions/defaults/anchorEditing.js.map +1 -1
  962. package/dist/interactions/actions/defaults/anchorFields.js +54 -0
  963. package/dist/interactions/actions/defaults/anchorFields.js.map +1 -0
  964. package/dist/interactions/actions/defaults/anchorHandles.js +31 -27
  965. package/dist/interactions/actions/defaults/anchorHandles.js.map +1 -1
  966. package/dist/interactions/actions/defaults/anchorJoin.js +55 -37
  967. package/dist/interactions/actions/defaults/anchorJoin.js.map +1 -1
  968. package/dist/interactions/actions/defaults/areaSelect.js +56 -40
  969. package/dist/interactions/actions/defaults/areaSelect.js.map +1 -1
  970. package/dist/interactions/actions/defaults/bendSegment.js +67 -31
  971. package/dist/interactions/actions/defaults/bendSegment.js.map +1 -1
  972. package/dist/interactions/actions/defaults/cancelGesture.js +12 -5
  973. package/dist/interactions/actions/defaults/cancelGesture.js.map +1 -1
  974. package/dist/interactions/actions/defaults/clearSelection.js +22 -7
  975. package/dist/interactions/actions/defaults/clearSelection.js.map +1 -1
  976. package/dist/interactions/actions/defaults/contextMenu.js +149 -0
  977. package/dist/interactions/actions/defaults/contextMenu.js.map +1 -0
  978. package/dist/interactions/actions/defaults/copySubtree.js +43 -29
  979. package/dist/interactions/actions/defaults/copySubtree.js.map +1 -1
  980. package/dist/interactions/actions/defaults/createPaintAction.js +79 -54
  981. package/dist/interactions/actions/defaults/createPaintAction.js.map +1 -1
  982. package/dist/interactions/actions/defaults/delete.js +61 -33
  983. package/dist/interactions/actions/defaults/delete.js.map +1 -1
  984. package/dist/interactions/actions/defaults/duplicate.js +60 -32
  985. package/dist/interactions/actions/defaults/duplicate.js.map +1 -1
  986. package/dist/interactions/actions/defaults/enterPathEdit.js +22 -18
  987. package/dist/interactions/actions/defaults/enterPathEdit.js.map +1 -1
  988. package/dist/interactions/actions/defaults/enterTextEdit.js +20 -8
  989. package/dist/interactions/actions/defaults/enterTextEdit.js.map +1 -1
  990. package/dist/interactions/actions/defaults/escape.js +16 -7
  991. package/dist/interactions/actions/defaults/escape.js.map +1 -1
  992. package/dist/interactions/actions/defaults/exitPathEdit.js +6 -6
  993. package/dist/interactions/actions/defaults/exitPathEdit.js.map +1 -1
  994. package/dist/interactions/actions/defaults/group.js +122 -73
  995. package/dist/interactions/actions/defaults/group.js.map +1 -1
  996. package/dist/interactions/actions/defaults/ingest.js +52 -35
  997. package/dist/interactions/actions/defaults/ingest.js.map +1 -1
  998. package/dist/interactions/actions/defaults/insertPathAnchor.js +43 -22
  999. package/dist/interactions/actions/defaults/insertPathAnchor.js.map +1 -1
  1000. package/dist/interactions/actions/defaults/nudge.js +79 -52
  1001. package/dist/interactions/actions/defaults/nudge.js.map +1 -1
  1002. package/dist/interactions/actions/defaults/nudgeSteps.js +17 -12
  1003. package/dist/interactions/actions/defaults/nudgeSteps.js.map +1 -1
  1004. package/dist/interactions/actions/defaults/pathEditMarks.js +60 -0
  1005. package/dist/interactions/actions/defaults/pathEditMarks.js.map +1 -0
  1006. package/dist/interactions/actions/defaults/pathEditTools.js +57 -0
  1007. package/dist/interactions/actions/defaults/pathEditTools.js.map +1 -0
  1008. package/dist/interactions/actions/defaults/pinchZoom.js +55 -39
  1009. package/dist/interactions/actions/defaults/pinchZoom.js.map +1 -1
  1010. package/dist/interactions/actions/defaults/reorder.js +71 -40
  1011. package/dist/interactions/actions/defaults/reorder.js.map +1 -1
  1012. package/dist/interactions/actions/defaults/requiresSelection.js +13 -6
  1013. package/dist/interactions/actions/defaults/requiresSelection.js.map +1 -1
  1014. package/dist/interactions/actions/defaults/segmentUnder.js +24 -16
  1015. package/dist/interactions/actions/defaults/segmentUnder.js.map +1 -1
  1016. package/dist/interactions/actions/defaults/selectAll.js +21 -7
  1017. package/dist/interactions/actions/defaults/selectAll.js.map +1 -1
  1018. package/dist/interactions/actions/defaults/setFill.js +37 -21
  1019. package/dist/interactions/actions/defaults/setFill.js.map +1 -1
  1020. package/dist/interactions/actions/defaults/setFillOpacity.js +19 -10
  1021. package/dist/interactions/actions/defaults/setFillOpacity.js.map +1 -1
  1022. package/dist/interactions/actions/defaults/setStroke.js +46 -25
  1023. package/dist/interactions/actions/defaults/setStroke.js.map +1 -1
  1024. package/dist/interactions/actions/defaults/setStrokeOpacity.js +19 -11
  1025. package/dist/interactions/actions/defaults/setStrokeOpacity.js.map +1 -1
  1026. package/dist/interactions/actions/defaults/slice.js +42 -17
  1027. package/dist/interactions/actions/defaults/slice.js.map +1 -1
  1028. package/dist/interactions/actions/defaults/sliceOps.js +63 -42
  1029. package/dist/interactions/actions/defaults/sliceOps.js.map +1 -1
  1030. package/dist/interactions/actions/defaults/toolActivate.js +34 -16
  1031. package/dist/interactions/actions/defaults/toolActivate.js.map +1 -1
  1032. package/dist/interactions/actions/defaults/toolResetToDefault.js +29 -10
  1033. package/dist/interactions/actions/defaults/toolResetToDefault.js.map +1 -1
  1034. package/dist/interactions/actions/defaults/undoRedo.js +26 -20
  1035. package/dist/interactions/actions/defaults/undoRedo.js.map +1 -1
  1036. package/dist/interactions/actions/defaults/viewportDragPan.js +91 -58
  1037. package/dist/interactions/actions/defaults/viewportDragPan.js.map +1 -1
  1038. package/dist/interactions/actions/defaults/viewportWheelPan.js +42 -23
  1039. package/dist/interactions/actions/defaults/viewportWheelPan.js.map +1 -1
  1040. package/dist/interactions/actions/defaults/viewportZoom.js +107 -59
  1041. package/dist/interactions/actions/defaults/viewportZoom.js.map +1 -1
  1042. package/dist/interactions/actions/distribute/action.js +62 -39
  1043. package/dist/interactions/actions/distribute/action.js.map +1 -1
  1044. package/dist/interactions/actions/distribute/distribute.js +53 -34
  1045. package/dist/interactions/actions/distribute/distribute.js.map +1 -1
  1046. package/dist/interactions/actions/distribute/plan.js +40 -22
  1047. package/dist/interactions/actions/distribute/plan.js.map +1 -1
  1048. package/dist/interactions/actions/drawnBoxes.js +31 -0
  1049. package/dist/interactions/actions/drawnBoxes.js.map +1 -0
  1050. package/dist/interactions/actions/edit-anchors/action.js +248 -72
  1051. package/dist/interactions/actions/edit-anchors/action.js.map +1 -1
  1052. package/dist/interactions/actions/edit-anchors/extensionDrags.js +50 -0
  1053. package/dist/interactions/actions/edit-anchors/extensionDrags.js.map +1 -0
  1054. package/dist/interactions/actions/edit-anchors/geometry.js +74 -47
  1055. package/dist/interactions/actions/edit-anchors/geometry.js.map +1 -1
  1056. package/dist/interactions/actions/edit-anchors/handleDrag.js +101 -0
  1057. package/dist/interactions/actions/edit-anchors/handleDrag.js.map +1 -0
  1058. package/dist/interactions/actions/edit-anchors/handles.js +41 -27
  1059. package/dist/interactions/actions/edit-anchors/handles.js.map +1 -1
  1060. package/dist/interactions/actions/edit-anchors/params.js +12 -0
  1061. package/dist/interactions/actions/edit-anchors/params.js.map +1 -0
  1062. package/dist/interactions/actions/edit-anchors/preview.js +61 -19
  1063. package/dist/interactions/actions/edit-anchors/preview.js.map +1 -1
  1064. package/dist/interactions/actions/edit-anchors/symmetry.js +12 -7
  1065. package/dist/interactions/actions/edit-anchors/symmetry.js.map +1 -1
  1066. package/dist/interactions/actions/flip/action.js +119 -61
  1067. package/dist/interactions/actions/flip/action.js.map +1 -1
  1068. package/dist/interactions/actions/flip/helpers.js +69 -36
  1069. package/dist/interactions/actions/flip/helpers.js.map +1 -1
  1070. package/dist/interactions/actions/geometryProjection.js +17 -12
  1071. package/dist/interactions/actions/geometryProjection.js.map +1 -1
  1072. package/dist/interactions/actions/gestureFrames.js +20 -11
  1073. package/dist/interactions/actions/gestureFrames.js.map +1 -1
  1074. package/dist/interactions/actions/gestureLifecycle.js +93 -48
  1075. package/dist/interactions/actions/gestureLifecycle.js.map +1 -1
  1076. package/dist/interactions/actions/hitSelection.js +6 -4
  1077. package/dist/interactions/actions/hitSelection.js.map +1 -1
  1078. package/dist/interactions/actions/insert/action.js +71 -42
  1079. package/dist/interactions/actions/insert/action.js.map +1 -1
  1080. package/dist/interactions/actions/insert/commit.js +44 -22
  1081. package/dist/interactions/actions/insert/commit.js.map +1 -1
  1082. package/dist/interactions/actions/insert/extras.js +60 -38
  1083. package/dist/interactions/actions/insert/extras.js.map +1 -1
  1084. package/dist/interactions/actions/insert/frame.js +58 -39
  1085. package/dist/interactions/actions/insert/frame.js.map +1 -1
  1086. package/dist/interactions/actions/insert/geometry.js +29 -25
  1087. package/dist/interactions/actions/insert/geometry.js.map +1 -1
  1088. package/dist/interactions/actions/insert/placeAction.js +108 -0
  1089. package/dist/interactions/actions/insert/placeAction.js.map +1 -0
  1090. package/dist/interactions/actions/insert/repositionAction.js +26 -11
  1091. package/dist/interactions/actions/insert/repositionAction.js.map +1 -1
  1092. package/dist/interactions/actions/insert/rotateAction.js +19 -8
  1093. package/dist/interactions/actions/insert/rotateAction.js.map +1 -1
  1094. package/dist/interactions/actions/insert/session.js +57 -41
  1095. package/dist/interactions/actions/insert/session.js.map +1 -1
  1096. package/dist/interactions/actions/insert/shape.js +83 -25
  1097. package/dist/interactions/actions/insert/shape.js.map +1 -1
  1098. package/dist/interactions/actions/lasso-select/action.js +160 -100
  1099. package/dist/interactions/actions/lasso-select/action.js.map +1 -1
  1100. package/dist/interactions/actions/lasso-select/behaviors/selectFromLasso.js +44 -25
  1101. package/dist/interactions/actions/lasso-select/behaviors/selectFromLasso.js.map +1 -1
  1102. package/dist/interactions/actions/move/action.js +87 -52
  1103. package/dist/interactions/actions/move/action.js.map +1 -1
  1104. package/dist/interactions/actions/move/behaviors/layoutDrop.js +56 -36
  1105. package/dist/interactions/actions/move/behaviors/layoutDrop.js.map +1 -1
  1106. package/dist/interactions/actions/move/behaviors/reparentOnDrop.js +20 -10
  1107. package/dist/interactions/actions/move/behaviors/reparentOnDrop.js.map +1 -1
  1108. package/dist/interactions/actions/move/behaviors/snapBackOrDelete.js +40 -24
  1109. package/dist/interactions/actions/move/behaviors/snapBackOrDelete.js.map +1 -1
  1110. package/dist/interactions/actions/move/behaviors/snapToContainer.js +102 -64
  1111. package/dist/interactions/actions/move/behaviors/snapToContainer.js.map +1 -1
  1112. package/dist/interactions/actions/move/capture.js +103 -78
  1113. package/dist/interactions/actions/move/capture.js.map +1 -1
  1114. package/dist/interactions/actions/move/commit/index.js +43 -34
  1115. package/dist/interactions/actions/move/commit/index.js.map +1 -1
  1116. package/dist/interactions/actions/move/commit/layoutDrop.js +43 -32
  1117. package/dist/interactions/actions/move/commit/layoutDrop.js.map +1 -1
  1118. package/dist/interactions/actions/move/commit/layoutRelease.js +97 -77
  1119. package/dist/interactions/actions/move/commit/layoutRelease.js.map +1 -1
  1120. package/dist/interactions/actions/move/commit/rebase.js +16 -13
  1121. package/dist/interactions/actions/move/commit/rebase.js.map +1 -1
  1122. package/dist/interactions/actions/move/commit/reparent.js +83 -57
  1123. package/dist/interactions/actions/move/commit/reparent.js.map +1 -1
  1124. package/dist/interactions/actions/move/delta.js +58 -36
  1125. package/dist/interactions/actions/move/delta.js.map +1 -1
  1126. package/dist/interactions/actions/move/frame.js +72 -35
  1127. package/dist/interactions/actions/move/frame.js.map +1 -1
  1128. package/dist/interactions/actions/move/gestureAdapter.js +30 -20
  1129. package/dist/interactions/actions/move/gestureAdapter.js.map +1 -1
  1130. package/dist/interactions/actions/move/landedDescendants.js +40 -25
  1131. package/dist/interactions/actions/move/landedDescendants.js.map +1 -1
  1132. package/dist/interactions/actions/move/layout/container.js +92 -72
  1133. package/dist/interactions/actions/move/layout/container.js.map +1 -1
  1134. package/dist/interactions/actions/move/layout/dragged.js +61 -39
  1135. package/dist/interactions/actions/move/layout/dragged.js.map +1 -1
  1136. package/dist/interactions/actions/move/layout/dropPass.js +136 -94
  1137. package/dist/interactions/actions/move/layout/dropPass.js.map +1 -1
  1138. package/dist/interactions/actions/move/layout/exits.js +58 -30
  1139. package/dist/interactions/actions/move/layout/exits.js.map +1 -1
  1140. package/dist/interactions/actions/move/layout/glide.js +55 -34
  1141. package/dist/interactions/actions/move/layout/glide.js.map +1 -1
  1142. package/dist/interactions/actions/move/session.js +85 -56
  1143. package/dist/interactions/actions/move/session.js.map +1 -1
  1144. package/dist/interactions/actions/move/translate.js +58 -43
  1145. package/dist/interactions/actions/move/translate.js.map +1 -1
  1146. package/dist/interactions/actions/outlines/createOutlines.js +28 -20
  1147. package/dist/interactions/actions/outlines/createOutlines.js.map +1 -1
  1148. package/dist/interactions/actions/outlines/createOutlinesAction.js +43 -31
  1149. package/dist/interactions/actions/outlines/createOutlinesAction.js.map +1 -1
  1150. package/dist/interactions/actions/outlines/outlineStroke.js +68 -45
  1151. package/dist/interactions/actions/outlines/outlineStroke.js.map +1 -1
  1152. package/dist/interactions/actions/outlines/outlineStrokeAction.js +24 -19
  1153. package/dist/interactions/actions/outlines/outlineStrokeAction.js.map +1 -1
  1154. package/dist/interactions/actions/outlines/replaceWithPaths.js +57 -42
  1155. package/dist/interactions/actions/outlines/replaceWithPaths.js.map +1 -1
  1156. package/dist/interactions/actions/outlines/strokeRegion.js +37 -22
  1157. package/dist/interactions/actions/outlines/strokeRegion.js.map +1 -1
  1158. package/dist/interactions/actions/outlines/useCreateOutlinesAdapter.js +8 -5
  1159. package/dist/interactions/actions/outlines/useCreateOutlinesAdapter.js.map +1 -1
  1160. package/dist/interactions/actions/pathCommands/cutJoin.js +119 -72
  1161. package/dist/interactions/actions/pathCommands/cutJoin.js.map +1 -1
  1162. package/dist/interactions/actions/pathCommands/livePathEdit.js +74 -40
  1163. package/dist/interactions/actions/pathCommands/livePathEdit.js.map +1 -1
  1164. package/dist/interactions/actions/pathCommands/pathNodes.js +91 -82
  1165. package/dist/interactions/actions/pathCommands/pathNodes.js.map +1 -1
  1166. package/dist/interactions/actions/pathCommands/simplifyOffset.js +52 -28
  1167. package/dist/interactions/actions/pathCommands/simplifyOffset.js.map +1 -1
  1168. package/dist/interactions/actions/pathGestureTags.js +29 -0
  1169. package/dist/interactions/actions/pathGestureTags.js.map +1 -0
  1170. package/dist/interactions/actions/planeInput.js +198 -123
  1171. package/dist/interactions/actions/planeInput.js.map +1 -1
  1172. package/dist/interactions/actions/pointerState.js +12 -7
  1173. package/dist/interactions/actions/pointerState.js.map +1 -1
  1174. package/dist/interactions/actions/poseDescriptorDep.js +24 -14
  1175. package/dist/interactions/actions/poseDescriptorDep.js.map +1 -1
  1176. package/dist/interactions/actions/poseFrame.js +45 -28
  1177. package/dist/interactions/actions/poseFrame.js.map +1 -1
  1178. package/dist/interactions/actions/resize/action.js +68 -39
  1179. package/dist/interactions/actions/resize/action.js.map +1 -1
  1180. package/dist/interactions/actions/resize/aspect.js +44 -0
  1181. package/dist/interactions/actions/resize/aspect.js.map +1 -0
  1182. package/dist/interactions/actions/resize/behaviors/clampMinSize.js +38 -13
  1183. package/dist/interactions/actions/resize/behaviors/clampMinSize.js.map +1 -1
  1184. package/dist/interactions/actions/resize/boxFrame.js +15 -11
  1185. package/dist/interactions/actions/resize/boxFrame.js.map +1 -1
  1186. package/dist/interactions/actions/resize/capture.js +105 -62
  1187. package/dist/interactions/actions/resize/capture.js.map +1 -1
  1188. package/dist/interactions/actions/resize/commit.js +75 -56
  1189. package/dist/interactions/actions/resize/commit.js.map +1 -1
  1190. package/dist/interactions/actions/resize/cornerHandles.js +154 -17
  1191. package/dist/interactions/actions/resize/cornerHandles.js.map +1 -1
  1192. package/dist/interactions/actions/resize/frame.js +133 -66
  1193. package/dist/interactions/actions/resize/frame.js.map +1 -1
  1194. package/dist/interactions/actions/resize/minimum.js +35 -0
  1195. package/dist/interactions/actions/resize/minimum.js.map +1 -0
  1196. package/dist/interactions/actions/resize/replay.js +40 -30
  1197. package/dist/interactions/actions/resize/replay.js.map +1 -1
  1198. package/dist/interactions/actions/resize/ruleBounds.js +8 -5
  1199. package/dist/interactions/actions/resize/ruleBounds.js.map +1 -1
  1200. package/dist/interactions/actions/resize/session.js +95 -50
  1201. package/dist/interactions/actions/resize/session.js.map +1 -1
  1202. package/dist/interactions/actions/resolveOverlays.js +48 -33
  1203. package/dist/interactions/actions/resolveOverlays.js.map +1 -1
  1204. package/dist/interactions/actions/resolvePreviews.js +63 -46
  1205. package/dist/interactions/actions/resolvePreviews.js.map +1 -1
  1206. package/dist/interactions/actions/rotate/action.js +68 -42
  1207. package/dist/interactions/actions/rotate/action.js.map +1 -1
  1208. package/dist/interactions/actions/rotate/commit.js +39 -31
  1209. package/dist/interactions/actions/rotate/commit.js.map +1 -1
  1210. package/dist/interactions/actions/rotate/frame.js +75 -47
  1211. package/dist/interactions/actions/rotate/frame.js.map +1 -1
  1212. package/dist/interactions/actions/rotate/geometry.js +36 -24
  1213. package/dist/interactions/actions/rotate/geometry.js.map +1 -1
  1214. package/dist/interactions/actions/rotate/handle.js +28 -15
  1215. package/dist/interactions/actions/rotate/handle.js.map +1 -1
  1216. package/dist/interactions/actions/rotate/replay.js +22 -18
  1217. package/dist/interactions/actions/rotate/replay.js.map +1 -1
  1218. package/dist/interactions/actions/rotate/session.js +115 -76
  1219. package/dist/interactions/actions/rotate/session.js.map +1 -1
  1220. package/dist/interactions/actions/selectionSubtree.js +124 -53
  1221. package/dist/interactions/actions/selectionSubtree.js.map +1 -1
  1222. package/dist/interactions/actions/spatialReference.js +33 -26
  1223. package/dist/interactions/actions/spatialReference.js.map +1 -1
  1224. package/dist/interactions/actions/testUtils.js +53 -0
  1225. package/dist/interactions/actions/testUtils.js.map +1 -0
  1226. package/dist/interactions/actions/transform-again/action.js +50 -35
  1227. package/dist/interactions/actions/transform-again/action.js.map +1 -1
  1228. package/dist/interactions/actions/transform-again/memory.js +32 -21
  1229. package/dist/interactions/actions/transform-again/memory.js.map +1 -1
  1230. package/dist/interactions/actions/useActionSet.js +83 -0
  1231. package/dist/interactions/actions/useActionSet.js.map +1 -0
  1232. package/dist/interactions/actions/useStandardActions.js +23 -165
  1233. package/dist/interactions/actions/useStandardActions.js.map +1 -1
  1234. package/dist/interactions/gestures/dragGesture/dragGesture.js +109 -68
  1235. package/dist/interactions/gestures/dragGesture/dragGesture.js.map +1 -1
  1236. package/dist/interactions/gestures/dragGesture/dragPointOf.js +17 -10
  1237. package/dist/interactions/gestures/dragGesture/dragPointOf.js.map +1 -1
  1238. package/dist/interactions/gestures/dragRadial/dragRadial.js +129 -93
  1239. package/dist/interactions/gestures/dragRadial/dragRadial.js.map +1 -1
  1240. package/dist/interactions/gestures/dragRect/dragRect.js +155 -111
  1241. package/dist/interactions/gestures/dragRect/dragRect.js.map +1 -1
  1242. package/dist/interactions/gestures/handleDrag/handleDrag.js +52 -30
  1243. package/dist/interactions/gestures/handleDrag/handleDrag.js.map +1 -1
  1244. package/dist/interactions/gestures/pointerDrag/pointerDrag.js +168 -97
  1245. package/dist/interactions/gestures/pointerDrag/pointerDrag.js.map +1 -1
  1246. package/dist/interactions/gestures/shared/originProjection.js +32 -25
  1247. package/dist/interactions/gestures/shared/originProjection.js.map +1 -1
  1248. package/dist/interactions/gestures/shared/screenTolerance.js +26 -17
  1249. package/dist/interactions/gestures/shared/screenTolerance.js.map +1 -1
  1250. package/dist/interactions/gestures/thresholdDrag/thresholdDrag.js +39 -21
  1251. package/dist/interactions/gestures/thresholdDrag/thresholdDrag.js.map +1 -1
  1252. package/dist/kitSettingsSchema.js +80 -0
  1253. package/dist/kitSettingsSchema.js.map +1 -0
  1254. package/dist/{math-CYUjoyyU.d.ts → math-CrJULaZI.d.ts} +5 -6
  1255. package/dist/math.d.ts +4 -5
  1256. package/dist/math.js +7 -6
  1257. package/dist/mesh.js +3 -2
  1258. package/dist/move.d.ts +7 -6
  1259. package/dist/move.js +4 -3
  1260. package/dist/{originProjection-CoNVpITV.d.ts → options-p9GZMXbY.d.ts} +4 -27
  1261. package/dist/originProjection-gY0jb4Wb.d.ts +24 -0
  1262. package/dist/patterns-builtin.js +3 -2
  1263. package/dist/{poseDescriptor-Bqk-11Rl.d.ts → poseDescriptor-DN2yfnq_.d.ts} +7 -7
  1264. package/dist/renderer.d.ts +1 -1
  1265. package/dist/renderer.js +3 -2
  1266. package/dist/resize.d.ts +10 -28
  1267. package/dist/resize.js +6 -7
  1268. package/dist/routing.js +3 -2
  1269. package/dist/style.css +88 -1
  1270. package/dist/test-hook/createTestHook.js +23 -20
  1271. package/dist/test-hook/createTestHook.js.map +1 -1
  1272. package/dist/test-hook/install.js +32 -13
  1273. package/dist/test-hook/install.js.map +1 -1
  1274. package/dist/test-hook/useTestHook.js +22 -16
  1275. package/dist/test-hook/useTestHook.js.map +1 -1
  1276. package/dist/test-seams.d.ts +164 -1
  1277. package/dist/test-seams.js +8 -3
  1278. package/dist/tools/builtin/bone/boneActions.js +96 -70
  1279. package/dist/tools/builtin/bone/boneActions.js.map +1 -1
  1280. package/dist/tools/builtin/bone/boneOverlay.js +49 -36
  1281. package/dist/tools/builtin/bone/boneOverlay.js.map +1 -1
  1282. package/dist/tools/builtin/bone/placedRig.js +18 -14
  1283. package/dist/tools/builtin/bone/placedRig.js.map +1 -1
  1284. package/dist/tools/builtin/bone/rigEditState.js +22 -13
  1285. package/dist/tools/builtin/bone/rigEditState.js.map +1 -1
  1286. package/dist/tools/builtin/bone/useBoneTool.js +68 -41
  1287. package/dist/tools/builtin/bone/useBoneTool.js.map +1 -1
  1288. package/dist/tools/builtin/ellipse/useEllipseTool.js +22 -17
  1289. package/dist/tools/builtin/ellipse/useEllipseTool.js.map +1 -1
  1290. package/dist/tools/builtin/eyedropper/useEyedropperTool.js +44 -28
  1291. package/dist/tools/builtin/eyedropper/useEyedropperTool.js.map +1 -1
  1292. package/dist/tools/builtin/hand/dragPanContribution.js +12 -7
  1293. package/dist/tools/builtin/hand/dragPanContribution.js.map +1 -1
  1294. package/dist/tools/builtin/hand/useHandTool.js +21 -13
  1295. package/dist/tools/builtin/hand/useHandTool.js.map +1 -1
  1296. package/dist/tools/builtin/image/useImageTool.js +28 -19
  1297. package/dist/tools/builtin/image/useImageTool.js.map +1 -1
  1298. package/dist/tools/builtin/lasso/useLassoTool.js +48 -36
  1299. package/dist/tools/builtin/lasso/useLassoTool.js.map +1 -1
  1300. package/dist/tools/builtin/line/useLineTool.js +24 -17
  1301. package/dist/tools/builtin/line/useLineTool.js.map +1 -1
  1302. package/dist/tools/builtin/measure/useMeasureTool.js +84 -0
  1303. package/dist/tools/builtin/measure/useMeasureTool.js.map +1 -0
  1304. package/dist/tools/builtin/pen/penHandle.js +60 -0
  1305. package/dist/tools/builtin/pen/penHandle.js.map +1 -0
  1306. package/dist/tools/builtin/pen/usePenTool.js +461 -303
  1307. package/dist/tools/builtin/pen/usePenTool.js.map +1 -1
  1308. package/dist/tools/builtin/pencil/usePencilTool.js +20 -15
  1309. package/dist/tools/builtin/pencil/usePencilTool.js.map +1 -1
  1310. package/dist/tools/builtin/pickTopMostHit.js +51 -31
  1311. package/dist/tools/builtin/pickTopMostHit.js.map +1 -1
  1312. package/dist/tools/builtin/polygon/usePolygonTool.js +45 -28
  1313. package/dist/tools/builtin/polygon/usePolygonTool.js.map +1 -1
  1314. package/dist/tools/builtin/rect/useRectTool.js +24 -16
  1315. package/dist/tools/builtin/rect/useRectTool.js.map +1 -1
  1316. package/dist/tools/builtin/select/adapterPointQuery.js +47 -30
  1317. package/dist/tools/builtin/select/adapterPointQuery.js.map +1 -1
  1318. package/dist/tools/builtin/select/selectionContributions.js +94 -56
  1319. package/dist/tools/builtin/select/selectionContributions.js.map +1 -1
  1320. package/dist/tools/builtin/select/useSelectTool.js +155 -108
  1321. package/dist/tools/builtin/select/useSelectTool.js.map +1 -1
  1322. package/dist/tools/builtin/shared/insertToolOptions.js +5 -4
  1323. package/dist/tools/builtin/shared/insertToolOptions.js.map +1 -1
  1324. package/dist/tools/builtin/shared/pointerFollower.js +15 -8
  1325. package/dist/tools/builtin/shared/pointerFollower.js.map +1 -1
  1326. package/dist/tools/builtin/slice/useSliceTool.js +148 -101
  1327. package/dist/tools/builtin/slice/useSliceTool.js.map +1 -1
  1328. package/dist/tools/builtin/star/useStarTool.js +48 -31
  1329. package/dist/tools/builtin/star/useStarTool.js.map +1 -1
  1330. package/dist/tools/builtin/sticky/stickyNode.js +49 -0
  1331. package/dist/tools/builtin/sticky/stickyNode.js.map +1 -0
  1332. package/dist/tools/builtin/sticky/useStickyTool.js +86 -0
  1333. package/dist/tools/builtin/sticky/useStickyTool.js.map +1 -0
  1334. package/dist/tools/builtin/text/useTextTool.js +59 -34
  1335. package/dist/tools/builtin/text/useTextTool.js.map +1 -1
  1336. package/dist/tools/builtin/weight/useWeightTool.js +66 -42
  1337. package/dist/tools/builtin/weight/useWeightTool.js.map +1 -1
  1338. package/dist/tools/builtin/weight/weightActions.js +93 -65
  1339. package/dist/tools/builtin/weight/weightActions.js.map +1 -1
  1340. package/dist/tools/builtin/weight/weightOverlay.js +47 -30
  1341. package/dist/tools/builtin/weight/weightOverlay.js.map +1 -1
  1342. package/dist/tools/overlayBinding.js +7 -5
  1343. package/dist/tools/overlayBinding.js.map +1 -1
  1344. package/dist/tools/useKeybindings.js +62 -46
  1345. package/dist/tools/useKeybindings.js.map +1 -1
  1346. package/dist/{types-DBbbCy0i.d.ts → types-CHVXGfYm.d.ts} +5 -5
  1347. package/dist/util/color.js +39 -18
  1348. package/dist/util/color.js.map +1 -1
  1349. package/dist/util/paint.js +93 -38
  1350. package/dist/util/paint.js.map +1 -1
  1351. package/dist/version.js +11 -3
  1352. package/dist/version.js.map +1 -1
  1353. package/package.json +35 -23
  1354. package/dist/canvas/SceneCanvas/GestureDispatcherMounter.js +0 -126
  1355. package/dist/canvas/SceneCanvas/GestureDispatcherMounter.js.map +0 -1
  1356. package/dist/canvas/SceneCanvas/StandardActionsRegistrar.js +0 -55
  1357. package/dist/canvas/SceneCanvas/StandardActionsRegistrar.js.map +0 -1
  1358. package/dist/canvas/SceneCanvas/ToolKeybindingsMounter.js +0 -16
  1359. package/dist/canvas/SceneCanvas/ToolKeybindingsMounter.js.map +0 -1
  1360. package/dist/canvas/SceneCanvas/isDev.js +0 -12
  1361. package/dist/canvas/SceneCanvas/isDev.js.map +0 -1
  1362. package/dist/canvas/SceneCanvas/useViewLayerGate.js +0 -20
  1363. package/dist/canvas/SceneCanvas/useViewLayerGate.js.map +0 -1
  1364. package/dist/cornerHandles-BSKbyuvQ.d.ts +0 -104
  1365. package/dist/icons/ArrowIcon.js +0 -23
  1366. package/dist/icons/ArrowIcon.js.map +0 -1
  1367. package/dist/icons/EllipseIcon.js +0 -21
  1368. package/dist/icons/EllipseIcon.js.map +0 -1
  1369. package/dist/icons/EyedropperIcon.js +0 -49
  1370. package/dist/icons/EyedropperIcon.js.map +0 -1
  1371. package/dist/icons/HandIcon.js +0 -59
  1372. package/dist/icons/HandIcon.js.map +0 -1
  1373. package/dist/icons/ImageIcon.js +0 -34
  1374. package/dist/icons/ImageIcon.js.map +0 -1
  1375. package/dist/icons/LassoIcon.js +0 -22
  1376. package/dist/icons/LassoIcon.js.map +0 -1
  1377. package/dist/icons/LineIcon.js +0 -22
  1378. package/dist/icons/LineIcon.js.map +0 -1
  1379. package/dist/icons/PenIcon.js +0 -36
  1380. package/dist/icons/PenIcon.js.map +0 -1
  1381. package/dist/icons/PencilIcon.js +0 -25
  1382. package/dist/icons/PencilIcon.js.map +0 -1
  1383. package/dist/icons/PolygonIcon.js +0 -19
  1384. package/dist/icons/PolygonIcon.js.map +0 -1
  1385. package/dist/icons/RectIcon.js +0 -37
  1386. package/dist/icons/RectIcon.js.map +0 -1
  1387. package/dist/icons/SelectIcon.js +0 -20
  1388. package/dist/icons/SelectIcon.js.map +0 -1
  1389. package/dist/icons/SliceIcon.js +0 -24
  1390. package/dist/icons/SliceIcon.js.map +0 -1
  1391. package/dist/icons/StarIcon.js +0 -19
  1392. package/dist/icons/StarIcon.js.map +0 -1
  1393. package/dist/icons/TextIcon.js +0 -19
  1394. package/dist/icons/TextIcon.js.map +0 -1
  1395. package/dist/icons/UnknownIcon.js +0 -33
  1396. package/dist/icons/UnknownIcon.js.map +0 -1
  1397. package/dist/icons/_base.js +0 -12
  1398. package/dist/icons/_base.js.map +0 -1
  1399. package/dist/interactions/actions/actionShortcuts.js +0 -32
  1400. package/dist/interactions/actions/actionShortcuts.js.map +0 -1
  1401. package/dist/interactions/actions/defaults/icons/actionGlyphIcons.js +0 -40
  1402. package/dist/interactions/actions/defaults/icons/actionGlyphIcons.js.map +0 -1
  1403. package/dist/interactions/actions/defaults/icons/actionGlyphs.js +0 -10
  1404. package/dist/interactions/actions/defaults/icons/actionGlyphs.js.map +0 -1
  1405. package/dist/interactions/actions/defaults/icons/alignIcons.js +0 -173
  1406. package/dist/interactions/actions/defaults/icons/alignIcons.js.map +0 -1
  1407. package/dist/interactions/actions/defaults/icons/anchorIcons.js +0 -75
  1408. package/dist/interactions/actions/defaults/icons/anchorIcons.js.map +0 -1
  1409. package/dist/interactions/actions/defaults/icons/booleanIcons.js +0 -194
  1410. package/dist/interactions/actions/defaults/icons/booleanIcons.js.map +0 -1
  1411. package/dist/interactions/actions/defaults/icons/distributeIcons.js +0 -63
  1412. package/dist/interactions/actions/defaults/icons/distributeIcons.js.map +0 -1
  1413. package/dist/interactions/actions/defaults/icons/editIcons.js +0 -307
  1414. package/dist/interactions/actions/defaults/icons/editIcons.js.map +0 -1
  1415. package/dist/interactions/actions/defaults/icons/outlineIcons.js +0 -91
  1416. package/dist/interactions/actions/defaults/icons/outlineIcons.js.map +0 -1
  1417. package/dist/interactions/actions/resize/behaviors/index.js +0 -8
  1418. package/dist/interactions/actions/resize/behaviors/index.js.map +0 -1
  1419. package/dist/interactions/actions/resize/behaviors/lockAspect.js +0 -24
  1420. package/dist/interactions/actions/resize/behaviors/lockAspect.js.map +0 -1
  1421. package/dist/interactions/actions/resize/pointSnap.js +0 -111
  1422. package/dist/interactions/actions/resize/pointSnap.js.map +0 -1
  1423. package/dist/interactions/actions/rotate/behaviors/index.js +0 -7
  1424. package/dist/interactions/actions/rotate/behaviors/index.js.map +0 -1
  1425. package/dist/interactions/actions/rotate/behaviors/snapRotation.js +0 -12
  1426. package/dist/interactions/actions/rotate/behaviors/snapRotation.js.map +0 -1
  1427. package/dist/interactions/gestures/shared/snap.js +0 -24
  1428. package/dist/interactions/gestures/shared/snap.js.map +0 -1
  1429. package/dist/test-seams-D0pyV3pR.d.ts +0 -149
  1430. package/dist/util/constrainTo45.js +0 -17
  1431. package/dist/util/constrainTo45.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"hitAffordanceRegions.js","names":["hitAffordanceRegions","i","affordances","a","isVisible","regions","state","best","j","region","xf","transformOf","hitRegion","wx","wy","view","d2","regionDistance2","at","cursor","s","w","pointRegionAnchor","localToWorld","dx","dy","targetId","IDENTITY_TARGET","targetTransformOf","pointRegionFrame","shape","angle","screenAngleOf","angleOf","half","u","v","body","floor","pxExtentIn","SMALL_BODY_RADII","b","c","d","vOut","pointRegionScreenQuad","f","cx","cy","toScreen","sn","standoff","normalToWorld","annulusSemiAxes","bandPx","band","scaleDelta","local","worldToLocal","strokeHitTest","multiply","scale","rx","ry","ex","ey","r"],"sources":["../../src/affordances/hitAffordanceRegions.ts"],"sourcesContent":["/**\n * The one affordance hit-test walk: an affordance's `regions()` is the single\n * source of truth for where its chrome is and what a press on it means.\n */\n\nimport type { View } from 'core/viewport/view';\nimport { multiply, scale, scaleDelta, screenAngleOf, standoff, strokeHitTest } from '@weasel-js/geom';\nimport type { ChromeState } from 'core/selection/chromeState';\nimport {\n angleOf, IDENTITY_TARGET, localToWorld, normalToWorld, pxExtentIn, targetTransformOf, worldToLocal,\n type TargetTransform,\n} from 'core/geometry/targetFrame';\nimport type { Affordance, AffordanceBinding, AffordanceRegion } from './types';\nimport type { CursorSpec } from '@weasel-js/cursor';\n\n/** What the walk found: the region, plus the ids needed to describe it. */\nexport interface AffordanceRegionHit {\n /** `Affordance.id` — also the chrome-caps visibility id. */\n affordanceId: string;\n /** `AffordanceRegion.id`. */\n regionId: string;\n /** The region itself, so callers can read `hitKind`. */\n region: AffordanceRegion;\n /** The region's cursor at the hit point. */\n cursor?: CursorSpec;\n /** Result of the region's `bind()`, called exactly once. */\n binding: AffordanceBinding;\n}\n\n/**\n * Walk affordances for a world-space hit, topmost first.\n *\n * **Across affordances**: order mirrors paint. Affordances are drawn first →\n * last (bottom → top), so the walk runs last → first and stops at the first\n * one that claims the point. Layering wins outright — a nearer region on a\n * lower affordance does not beat a farther one on top of it.\n *\n * **Within an affordance**: the *nearest* hit region wins, ties going to the\n * later-declared one. Regions overlap: the four corner handles of a selection\n * smaller than the hit radius all contain the same click.\n *\n * `isVisible` (when supplied) gates by the same chrome id used at paint time,\n * so chrome that isn't drawn can't be hit either.\n */\nexport function hitAffordanceRegions(\n affordances: readonly Affordance[],\n wx: number,\n wy: number,\n state: ChromeState,\n view: View,\n isVisible?: (id: string) => boolean,\n): AffordanceRegionHit | null {\n for (let i = affordances.length - 1; i >= 0; i--) {\n const a = affordances[i];\n if (isVisible && !isVisible(a.id)) continue;\n const regions = a.regions(state);\n let best: { region: AffordanceRegion; d2: number } | null = null;\n for (let j = 0; j < regions.length; j++) {\n const region = regions[j];\n const xf = transformOf(state, region.targetId);\n if (!hitRegion(region, wx, wy, xf, view)) continue;\n const d2 = regionDistance2(region, wx, wy, xf, view);\n // `<=` so a later-declared region wins an exact tie, preserving the\n // \"later is on top\" reading of declaration order.\n if (best === null || d2 <= best.d2) best = { region, d2 };\n }\n if (best) {\n const { cursor } = best.region;\n const at = typeof cursor === 'function' ? cursor({ x: wx, y: wy }, view) : cursor;\n return {\n affordanceId: a.id,\n regionId: best.region.id,\n region: best.region,\n ...(at !== undefined ? { cursor: at } : {}),\n binding: best.region.bind(),\n };\n }\n }\n return null;\n}\n\n/** Squared world distance from the point to a region's representative center,\n * used only to rank regions that all already contain the point. */\nfunction regionDistance2(\n region: AffordanceRegion,\n wx: number,\n wy: number,\n xf: TargetTransform,\n view: View,\n): number {\n const s = region.shape;\n if (s.kind === 'outline') return 0;\n const w = s.kind === 'point'\n ? pointRegionAnchor(s, xf, view)\n : s.kind === 'annulus'\n ? localToWorld(xf, s.cx, s.cy)\n : localToWorld(xf, s.x + s.width / 2, s.y + s.height / 2);\n const dx = w.x - wx;\n const dy = w.y - wy;\n return dx * dx + dy * dy;\n}\n\n// ─── Transform helpers ──────────────────────────────────────────────────────\n\nexport { angleOf, localToWorld, type TargetTransform };\n\n/** The frame `targetId`'s bounds are drawn in; identity for no target. */\nexport function transformOf(state: ChromeState, targetId: string | null): TargetTransform {\n if (targetId === null) return IDENTITY_TARGET;\n return targetTransformOf(state.boundsOf(targetId));\n}\n\n// ─── Shape resolution ───────────────────────────────────────────────────────\n\ntype PointShape = Extract<AffordanceRegion['shape'], { kind: 'point' }>;\n\n/** Where a point region's hit square sits: its center in world coords, its\n * turn on screen, its screen half-extent, and the span of the square that\n * takes a press along each of its own axes (`[-half, half]` unless\n * `cornerOf` cuts it). */\nexport function pointRegionFrame(\n shape: PointShape,\n xf: TargetTransform,\n view: View,\n): { x: number; y: number; angle: number; half: number; u: [number, number]; v: [number, number] } {\n const a = pointRegionAnchor(shape, xf, view);\n const angle = shape.turned ? screenAngleOf(angleOf(xf), view.scale) : 0;\n const half = shape.hitRadiusPx;\n const u: [number, number] = [-half, half];\n const v: [number, number] = [-half, half];\n const body = shape.cornerOf;\n if (body) {\n // The body in world units that spans four hit radii on screen, per axis.\n const floor = pxExtentIn(SMALL_BODY_RADII * half, view.scale, xf);\n // `v` runs a quarter turn on from `u` on screen, which is the target's +y\n // only while the view and the target's frame keep their handedness.\n const [a, b, c, d] = xf.toWorld;\n const vOut = body.outward.y * Math.sign(view.scale.x * view.scale.y * (a * d - b * c));\n if (body.width < floor.x) u[body.outward.x > 0 ? 0 : 1] = 0;\n if (body.height < floor.y) v[vOut > 0 ? 0 : 1] = 0;\n }\n return { x: a.x, y: a.y, angle, half, u, v };\n}\n\n/** A body under this many hit radii across gives up the inward half of each\n * corner's hit square, so there is somewhere on it that is not a handle. */\nconst SMALL_BODY_RADII = 4;\n\n/** A point region's hit square as four screen-space corners, relative to its\n * world center carried to the screen by `toScreen`. */\nexport function pointRegionScreenQuad(\n shape: PointShape,\n xf: TargetTransform,\n view: View,\n toScreen: (x: number, y: number) => [number, number],\n): { x: number; y: number }[] {\n const f = pointRegionFrame(shape, xf, view);\n const [cx, cy] = toScreen(f.x, f.y);\n const c = Math.cos(f.angle), sn = Math.sin(f.angle);\n return [[f.u[0], f.v[0]], [f.u[1], f.v[0]], [f.u[1], f.v[1]], [f.u[0], f.v[1]]].map(([u, v]) => ({\n x: cx + c * u - sn * v,\n y: cy + sn * u + c * v,\n }));\n}\n\n/** A point region's anchor in world coords, its `standoff` applied. */\nexport function pointRegionAnchor(\n shape: PointShape,\n xf: TargetTransform,\n view: View,\n): { x: number; y: number } {\n const a = localToWorld(xf, shape.x, shape.y);\n if (!shape.standoff) return a;\n return standoff(a, normalToWorld(xf, shape.standoff.normal), shape.standoff.px, view.scale);\n}\n\n/**\n * An annulus region's effective outer semi-axes, in world units, with the\n * screen-space `minBandPx` floor on band thickness applied. Paint calls it\n * too, so the visible ring and the hoverable ring are the same ring.\n */\nexport function annulusSemiAxes(\n shape: Extract<AffordanceRegion['shape'], { kind: 'annulus' }>,\n view: View,\n /** The target's frame, which decides what a screen pixel is along each of\n * its axes. */\n xf: TargetTransform = IDENTITY_TARGET,\n): { rx: number; ry: number } {\n const bandPx = shape.minBandPx ?? 0;\n if (bandPx === 0) return { rx: shape.rx, ry: shape.ry };\n const band = pxExtentIn(bandPx, view.scale, xf);\n return {\n rx: Math.max(shape.rx, shape.innerWidth / 2 + band.x),\n ry: Math.max(shape.ry, shape.innerHeight / 2 + band.y),\n };\n}\n\n// ─── Per-shape hit-test ─────────────────────────────────────────────────────\n\nfunction hitRegion(\n region: AffordanceRegion,\n wx: number,\n wy: number,\n xf: TargetTransform,\n view: View,\n): boolean {\n if (region.shape.kind === 'point') {\n // Square hit, not circular: the handle a `point` region paints is a\n // square, and a circle leaves its corners unclickable.\n //\n // Compared in screen space: testing it in the target's local frame would\n // stretch it under non-uniform zoom.\n const f = pointRegionFrame(region.shape, xf, view);\n const d = scaleDelta(wx - f.x, wy - f.y, view.scale);\n const c = Math.cos(f.angle), sn = Math.sin(f.angle);\n const u = c * d.x + sn * d.y, v = -sn * d.x + c * d.y;\n return u >= f.u[0] && u <= f.u[1] && v >= f.v[0] && v <= f.v[1];\n }\n const local = worldToLocal(xf, wx, wy);\n if (!local) return false;\n if (region.shape.kind === 'outline') {\n const s = region.shape;\n return strokeHitTest(s.path, local.x, local.y, 0, {\n slop: { px: s.hitRadiusPx, transform: multiply(scale(view.scale.x, view.scale.y), xf.toWorld) },\n });\n }\n if (region.shape.kind === 'annulus') {\n const s = region.shape;\n // Outside the inner-rect cutout?\n const insideInner =\n local.x >= s.innerX && local.x <= s.innerX + s.innerWidth &&\n local.y >= s.innerY && local.y <= s.innerY + s.innerHeight;\n if (insideInner) return false;\n // Inside the outer ellipse? `((x-cx)/rx)² + ((y-cy)/ry)² ≤ 1`.\n const { rx, ry } = annulusSemiAxes(s, view, xf);\n if (rx <= 0 || ry <= 0) return false;\n const ex = (local.x - s.cx) / rx;\n const ey = (local.y - s.cy) / ry;\n return ex * ex + ey * ey <= 1;\n }\n // rect: axis-aligned in local frame.\n const r = region.shape;\n return local.x >= r.x && local.x <= r.x + r.width\n && local.y >= r.y && local.y <= r.y + r.height;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"hitAffordanceRegions.js","names":[],"sources":["../../src/affordances/hitAffordanceRegions.ts"],"sourcesContent":["/**\n * The one affordance hit-test walk: an affordance's `regions()` is the single\n * source of truth for where its chrome is and what a press on it means.\n */\n\nimport type { View } from 'core/viewport/view';\nimport { multiply, scale, scaleDelta, screenAngleOf, standoff, strokeHitTest } from '@weasel-js/geom';\nimport type { ChromeState } from 'core/selection/chromeState';\nimport {\n angleOf, IDENTITY_TARGET, localToWorld, normalToWorld, pxExtentIn, targetTransformOf, worldToLocal,\n type TargetTransform,\n} from 'core/geometry/targetFrame';\nimport type { Affordance, AffordanceBinding, AffordanceRegion } from './types';\nimport type { CursorSpec } from '@weasel-js/cursor';\nimport { edgeHandlesFit } from 'interactions/actions/resize/cornerHandles';\n\n/** What the walk found: the region, plus the ids needed to describe it. */\nexport interface AffordanceRegionHit {\n /** `Affordance.id` — also the chrome-caps visibility id. */\n affordanceId: string;\n /** `AffordanceRegion.id`. */\n regionId: string;\n /** The region itself, so callers can read `hitKind`. */\n region: AffordanceRegion;\n /** The region's cursor at the hit point. */\n cursor?: CursorSpec;\n /** Result of the region's `bind()`, called exactly once. */\n binding: AffordanceBinding;\n}\n\n/**\n * Walk affordances for a world-space hit, topmost first.\n *\n * **Across affordances**: order mirrors paint. Affordances are drawn first →\n * last (bottom → top), so the walk runs last → first and stops at the first\n * one that claims the point. Layering wins outright — a nearer region on a\n * lower affordance does not beat a farther one on top of it.\n *\n * **Within an affordance**: the *nearest* hit region wins, ties going to the\n * later-declared one. Regions overlap: the four corner handles of a selection\n * smaller than the hit radius all contain the same click.\n *\n * `isVisible` (when supplied) gates by the same chrome id used at paint time,\n * so chrome that isn't drawn can't be hit either.\n */\nexport function hitAffordanceRegions(\n affordances: readonly Affordance[],\n wx: number,\n wy: number,\n state: ChromeState,\n view: View,\n isVisible?: (id: string) => boolean,\n): AffordanceRegionHit | null {\n for (let i = affordances.length - 1; i >= 0; i--) {\n const a = affordances[i];\n if (isVisible && !isVisible(a.id)) continue;\n const regions = a.regions(state);\n let best: { region: AffordanceRegion; d2: number } | null = null;\n for (let j = 0; j < regions.length; j++) {\n const region = regions[j];\n if (isVisible && region.chromeId && !isVisible(region.chromeId)) continue;\n const xf = transformOf(state, region.targetId);\n if (!hitRegion(region, wx, wy, xf, view)) continue;\n const d2 = regionDistance2(region, wx, wy, xf, view);\n // `<=` so a later-declared region wins an exact tie, preserving the\n // \"later is on top\" reading of declaration order.\n if (best === null || d2 <= best.d2) best = { region, d2 };\n }\n if (best) {\n const { cursor } = best.region;\n const at = typeof cursor === 'function' ? cursor({ x: wx, y: wy }, view) : cursor;\n return {\n affordanceId: a.id,\n regionId: best.region.id,\n region: best.region,\n ...(at !== undefined ? { cursor: at } : {}),\n binding: best.region.bind(),\n };\n }\n }\n return null;\n}\n\n/** Squared world distance from the point to a region's representative center,\n * used only to rank regions that all already contain the point. */\nfunction regionDistance2(\n region: AffordanceRegion,\n wx: number,\n wy: number,\n xf: TargetTransform,\n view: View,\n): number {\n const s = region.shape;\n if (s.kind === 'outline') return 0;\n const w = s.kind === 'point'\n ? pointRegionAnchor(s, xf, view)\n : s.kind === 'annulus'\n ? localToWorld(xf, s.cx, s.cy)\n : localToWorld(xf, s.x + s.width / 2, s.y + s.height / 2);\n const dx = w.x - wx;\n const dy = w.y - wy;\n return dx * dx + dy * dy;\n}\n\n// ─── Transform helpers ──────────────────────────────────────────────────────\n\nexport { angleOf, localToWorld, type TargetTransform };\n\n/** The frame `targetId`'s bounds are drawn in; identity for no target. */\nexport function transformOf(state: ChromeState, targetId: string | null): TargetTransform {\n if (targetId === null) return IDENTITY_TARGET;\n return targetTransformOf(state.boundsOf(targetId));\n}\n\n// ─── Shape resolution ───────────────────────────────────────────────────────\n\ntype PointShape = Extract<AffordanceRegion['shape'], { kind: 'point' }>;\n\n/** Where a point region's hit square sits: its center in world coords, its\n * turn on screen, its screen half-extent, and the span of the square that\n * takes a press along each of its own axes (`[-half, half]` unless\n * `cornerOf` cuts it). */\nexport function pointRegionFrame(\n shape: PointShape,\n xf: TargetTransform,\n view: View,\n): { x: number; y: number; angle: number; half: number; u: [number, number]; v: [number, number] } {\n const a = pointRegionAnchor(shape, xf, view);\n const angle = shape.turned ? screenAngleOf(angleOf(xf), view.scale) : 0;\n const half = shape.hitRadiusPx;\n const u: [number, number] = [-half, half];\n const v: [number, number] = [-half, half];\n const body = shape.cornerOf;\n if (body) {\n // The body in world units that spans four hit radii on screen, per axis.\n const floor = pxExtentIn(SMALL_BODY_RADII * half, view.scale, xf);\n // `v` runs a quarter turn on from `u` on screen, which is the target's +y\n // only while the view and the target's frame keep their handedness.\n const [a, b, c, d] = xf.toWorld;\n const vOut = body.outward.y * Math.sign(view.scale.x * view.scale.y * (a * d - b * c));\n if (body.width < floor.x) u[body.outward.x > 0 ? 0 : 1] = 0;\n if (body.height < floor.y) v[vOut > 0 ? 0 : 1] = 0;\n }\n return { x: a.x, y: a.y, angle, half, u, v };\n}\n\n/** Whether a point region is live in `view`: false for an edge handle whose\n * body is too small on screen to have room for one (`edgeOf`). A region that\n * is not live is neither hit nor painted. */\nexport function pointRegionLive(shape: PointShape, xf: TargetTransform, view: View): boolean {\n return !shape.edgeOf || edgeHandlesFit(shape.edgeOf, xf, view.scale, shape.hitRadiusPx);\n}\n\n/** A body under this many hit radii across gives up the inward half of each\n * corner's hit square, so there is somewhere on it that is not a handle. */\nconst SMALL_BODY_RADII = 4;\n\n/** A point region's hit square as four screen-space corners, relative to its\n * world center carried to the screen by `toScreen`. */\nexport function pointRegionScreenQuad(\n shape: PointShape,\n xf: TargetTransform,\n view: View,\n toScreen: (x: number, y: number) => [number, number],\n): { x: number; y: number }[] {\n const f = pointRegionFrame(shape, xf, view);\n const [cx, cy] = toScreen(f.x, f.y);\n const c = Math.cos(f.angle), sn = Math.sin(f.angle);\n return [[f.u[0], f.v[0]], [f.u[1], f.v[0]], [f.u[1], f.v[1]], [f.u[0], f.v[1]]].map(([u, v]) => ({\n x: cx + c * u - sn * v,\n y: cy + sn * u + c * v,\n }));\n}\n\n/** A point region's anchor in world coords, its `standoff` applied. */\nexport function pointRegionAnchor(\n shape: PointShape,\n xf: TargetTransform,\n view: View,\n): { x: number; y: number } {\n const a = localToWorld(xf, shape.x, shape.y);\n if (!shape.standoff) return a;\n return standoff(a, normalToWorld(xf, shape.standoff.normal), shape.standoff.px, view.scale);\n}\n\n/**\n * An annulus region's effective outer semi-axes, in world units, with the\n * screen-space `minBandPx` floor on band thickness applied. Paint calls it\n * too, so the visible ring and the hoverable ring are the same ring.\n */\nexport function annulusSemiAxes(\n shape: Extract<AffordanceRegion['shape'], { kind: 'annulus' }>,\n view: View,\n /** The target's frame, which decides what a screen pixel is along each of\n * its axes. */\n xf: TargetTransform = IDENTITY_TARGET,\n): { rx: number; ry: number } {\n const bandPx = shape.minBandPx ?? 0;\n if (bandPx === 0) return { rx: shape.rx, ry: shape.ry };\n const band = pxExtentIn(bandPx, view.scale, xf);\n return {\n rx: Math.max(shape.rx, shape.innerWidth / 2 + band.x),\n ry: Math.max(shape.ry, shape.innerHeight / 2 + band.y),\n };\n}\n\n// ─── Per-shape hit-test ─────────────────────────────────────────────────────\n\nfunction hitRegion(\n region: AffordanceRegion,\n wx: number,\n wy: number,\n xf: TargetTransform,\n view: View,\n): boolean {\n if (region.shape.kind === 'point') {\n // Square hit, not circular: the handle a `point` region paints is a\n // square, and a circle leaves its corners unclickable.\n //\n // Compared in screen space: testing it in the target's local frame would\n // stretch it under non-uniform zoom.\n if (!pointRegionLive(region.shape, xf, view)) return false;\n const f = pointRegionFrame(region.shape, xf, view);\n const d = scaleDelta(wx - f.x, wy - f.y, view.scale);\n const c = Math.cos(f.angle), sn = Math.sin(f.angle);\n const u = c * d.x + sn * d.y, v = -sn * d.x + c * d.y;\n return u >= f.u[0] && u <= f.u[1] && v >= f.v[0] && v <= f.v[1];\n }\n const local = worldToLocal(xf, wx, wy);\n if (!local) return false;\n if (region.shape.kind === 'outline') {\n const s = region.shape;\n return strokeHitTest(s.path, local.x, local.y, 0, {\n slop: { px: s.hitRadiusPx, transform: multiply(scale(view.scale.x, view.scale.y), xf.toWorld) },\n });\n }\n if (region.shape.kind === 'annulus') {\n const s = region.shape;\n // Outside the inner-rect cutout?\n const insideInner =\n local.x >= s.innerX && local.x <= s.innerX + s.innerWidth &&\n local.y >= s.innerY && local.y <= s.innerY + s.innerHeight;\n if (insideInner) return false;\n // Inside the outer ellipse? `((x-cx)/rx)² + ((y-cy)/ry)² ≤ 1`.\n const { rx, ry } = annulusSemiAxes(s, view, xf);\n if (rx <= 0 || ry <= 0) return false;\n const ex = (local.x - s.cx) / rx;\n const ey = (local.y - s.cy) / ry;\n return ex * ex + ey * ey <= 1;\n }\n // rect: axis-aligned in local frame.\n const r = region.shape;\n return local.x >= r.x && local.x <= r.x + r.width\n && local.y >= r.y && local.y <= r.y + r.height;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AA6CA,SAAgB,qBACd,aACA,IACA,IACA,OACA,MACA,WAC4B;CAC5B,KAAK,IAAI,IAAI,YAAY,SAAS,GAAG,KAAK,GAAG,KAAK;EAChD,MAAM,IAAI,YAAY;EACtB,IAAI,aAAa,CAAC,UAAU,EAAE,EAAE,GAAG;EACnC,MAAM,UAAU,EAAE,QAAQ,KAAK;EAC/B,IAAI,OAAwD;EAC5D,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;GACvC,MAAM,SAAS,QAAQ;GACvB,IAAI,aAAa,OAAO,YAAY,CAAC,UAAU,OAAO,QAAQ,GAAG;GACjE,MAAM,KAAK,YAAY,OAAO,OAAO,QAAQ;GAC7C,IAAI,CAAC,UAAU,QAAQ,IAAI,IAAI,IAAI,IAAI,GAAG;GAC1C,MAAM,KAAK,gBAAgB,QAAQ,IAAI,IAAI,IAAI,IAAI;GAGnD,IAAI,SAAS,QAAQ,MAAM,KAAK,IAAI,OAAO;IAAE;IAAQ;GAAG;EAC1D;EACA,IAAI,MAAM;GACR,MAAM,EAAE,WAAW,KAAK;GACxB,MAAM,KAAK,OAAO,WAAW,aAAa,OAAO;IAAE,GAAG;IAAI,GAAG;GAAG,GAAG,IAAI,IAAI;GAC3E,OAAO;IACL,cAAc,EAAE;IAChB,UAAU,KAAK,OAAO;IACtB,QAAQ,KAAK;IACb,GAAI,OAAO,SAAY,EAAE,QAAQ,GAAG,IAAI,CAAC;IACzC,SAAS,KAAK,OAAO,KAAK;GAC5B;EACF;CACF;CACA,OAAO;AACT;;;AAIA,SAAS,gBACP,QACA,IACA,IACA,IACA,MACQ;CACR,MAAM,IAAI,OAAO;CACjB,IAAI,EAAE,SAAS,WAAW,OAAO;CACjC,MAAM,IAAI,EAAE,SAAS,UACjB,kBAAkB,GAAG,IAAI,IAAI,IAC7B,EAAE,SAAS,YACT,aAAa,IAAI,EAAE,IAAI,EAAE,EAAE,IAC3B,aAAa,IAAI,EAAE,IAAI,EAAE,QAAQ,GAAG,EAAE,IAAI,EAAE,SAAS,CAAC;CAC5D,MAAM,KAAK,EAAE,IAAI;CACjB,MAAM,KAAK,EAAE,IAAI;CACjB,OAAO,KAAK,KAAK,KAAK;AACxB;;AAOA,SAAgB,YAAY,OAAoB,UAA0C;CACxF,IAAI,aAAa,MAAM,OAAO;CAC9B,OAAO,kBAAkB,MAAM,SAAS,QAAQ,CAAC;AACnD;;;;;AAUA,SAAgB,iBACd,OACA,IACA,MACiG;CACjG,MAAM,IAAI,kBAAkB,OAAO,IAAI,IAAI;CAC3C,MAAM,QAAQ,MAAM,SAAS,cAAc,QAAQ,EAAE,GAAG,KAAK,KAAK,IAAI;CACtE,MAAM,OAAO,MAAM;CACnB,MAAM,IAAsB,CAAC,CAAC,MAAM,IAAI;CACxC,MAAM,IAAsB,CAAC,CAAC,MAAM,IAAI;CACxC,MAAM,OAAO,MAAM;CACnB,IAAI,MAAM;EAER,MAAM,QAAQ,WAAW,mBAAmB,MAAM,KAAK,OAAO,EAAE;EAGhE,MAAM,CAAC,GAAG,GAAG,GAAG,KAAK,GAAG;EACxB,MAAM,OAAO,KAAK,QAAQ,IAAI,KAAK,KAAK,KAAK,MAAM,IAAI,KAAK,MAAM,KAAK,IAAI,IAAI,IAAI,EAAE;EACrF,IAAI,KAAK,QAAQ,MAAM,GAAG,EAAE,KAAK,QAAQ,IAAI,IAAI,IAAI,KAAK;EAC1D,IAAI,KAAK,SAAS,MAAM,GAAG,EAAE,OAAO,IAAI,IAAI,KAAK;CACnD;CACA,OAAO;EAAE,GAAG,EAAE;EAAG,GAAG,EAAE;EAAG;EAAO;EAAM;EAAG;CAAE;AAC7C;;;;AAKA,SAAgB,gBAAgB,OAAmB,IAAqB,MAAqB;CAC3F,OAAO,CAAC,MAAM,UAAU,eAAe,MAAM,QAAQ,IAAI,KAAK,OAAO,MAAM,WAAW;AACxF;;;AAIA,IAAM,mBAAmB;;;AAIzB,SAAgB,sBACd,OACA,IACA,MACA,UAC4B;CAC5B,MAAM,IAAI,iBAAiB,OAAO,IAAI,IAAI;CAC1C,MAAM,CAAC,IAAI,MAAM,SAAS,EAAE,GAAG,EAAE,CAAC;CAClC,MAAM,IAAI,KAAK,IAAI,EAAE,KAAK,GAAG,KAAK,KAAK,IAAI,EAAE,KAAK;CAClD,OAAO;EAAC,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;EAAG,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;EAAG,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;EAAG,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,QAAQ;EAC/F,GAAG,KAAK,IAAI,IAAI,KAAK;EACrB,GAAG,KAAK,KAAK,IAAI,IAAI;CACvB,EAAE;AACJ;;AAGA,SAAgB,kBACd,OACA,IACA,MAC0B;CAC1B,MAAM,IAAI,aAAa,IAAI,MAAM,GAAG,MAAM,CAAC;CAC3C,IAAI,CAAC,MAAM,UAAU,OAAO;CAC5B,OAAO,SAAS,GAAG,cAAc,IAAI,MAAM,SAAS,MAAM,GAAG,MAAM,SAAS,IAAI,KAAK,KAAK;AAC5F;;;;;;AAOA,SAAgB,gBACd,OACA,MAGA,KAAsB,iBACM;CAC5B,MAAM,SAAS,MAAM,aAAa;CAClC,IAAI,WAAW,GAAG,OAAO;EAAE,IAAI,MAAM;EAAI,IAAI,MAAM;CAAG;CACtD,MAAM,OAAO,WAAW,QAAQ,KAAK,OAAO,EAAE;CAC9C,OAAO;EACL,IAAI,KAAK,IAAI,MAAM,IAAI,MAAM,aAAa,IAAI,KAAK,CAAC;EACpD,IAAI,KAAK,IAAI,MAAM,IAAI,MAAM,cAAc,IAAI,KAAK,CAAC;CACvD;AACF;AAIA,SAAS,UACP,QACA,IACA,IACA,IACA,MACS;CACT,IAAI,OAAO,MAAM,SAAS,SAAS;EAMjC,IAAI,CAAC,gBAAgB,OAAO,OAAO,IAAI,IAAI,GAAG,OAAO;EACrD,MAAM,IAAI,iBAAiB,OAAO,OAAO,IAAI,IAAI;EACjD,MAAM,IAAI,WAAW,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,KAAK;EACnD,MAAM,IAAI,KAAK,IAAI,EAAE,KAAK,GAAG,KAAK,KAAK,IAAI,EAAE,KAAK;EAClD,MAAM,IAAI,IAAI,EAAE,IAAI,KAAK,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,IAAI,EAAE;EACpD,OAAO,KAAK,EAAE,EAAE,MAAM,KAAK,EAAE,EAAE,MAAM,KAAK,EAAE,EAAE,MAAM,KAAK,EAAE,EAAE;CAC/D;CACA,MAAM,QAAQ,aAAa,IAAI,IAAI,EAAE;CACrC,IAAI,CAAC,OAAO,OAAO;CACnB,IAAI,OAAO,MAAM,SAAS,WAAW;EACnC,MAAM,IAAI,OAAO;EACjB,OAAO,cAAc,EAAE,MAAM,MAAM,GAAG,MAAM,GAAG,GAAG,EAChD,MAAM;GAAE,IAAI,EAAE;GAAa,WAAW,SAAS,MAAM,KAAK,MAAM,GAAG,KAAK,MAAM,CAAC,GAAG,GAAG,OAAO;EAAE,EAChG,CAAC;CACH;CACA,IAAI,OAAO,MAAM,SAAS,WAAW;EACnC,MAAM,IAAI,OAAO;EAKjB,IAFE,MAAM,KAAK,EAAE,UAAU,MAAM,KAAK,EAAE,SAAS,EAAE,cAC/C,MAAM,KAAK,EAAE,UAAU,MAAM,KAAK,EAAE,SAAS,EAAE,aAChC,OAAO;EAExB,MAAM,EAAE,IAAI,OAAO,gBAAgB,GAAG,MAAM,EAAE;EAC9C,IAAI,MAAM,KAAK,MAAM,GAAG,OAAO;EAC/B,MAAM,MAAM,MAAM,IAAI,EAAE,MAAM;EAC9B,MAAM,MAAM,MAAM,IAAI,EAAE,MAAM;EAC9B,OAAO,KAAK,KAAK,KAAK,MAAM;CAC9B;CAEA,MAAM,IAAI,OAAO;CACjB,OAAO,MAAM,KAAK,EAAE,KAAK,MAAM,KAAK,EAAE,IAAI,EAAE,SACrC,MAAM,KAAK,EAAE,KAAK,MAAM,KAAK,EAAE,IAAI,EAAE;AAC9C"}
@@ -1,88 +1,163 @@
1
- import { enumerateAnchors as e } from "../interactions/actions/edit-anchors/geometry.js";
1
+ import { enumerateAnchors } from "../interactions/actions/edit-anchors/geometry.js";
2
+ import { pathToAnchors } from "@weasel-js/geom";
3
+
2
4
  //#region src/affordances/pathAnchors.ts
3
- var t = "path-edit.anchors";
4
- function n(n, r = {}) {
5
- let { hitRadius: i = 8, cursor: a = "pointer" } = r, o = (e) => {
6
- let t = n();
7
- if (!t) return [];
8
- let r = [];
9
- for (let n of e.selection) {
10
- let e = t.getPose(n);
11
- e && e.kind === "polygon" && r.push({
12
- id: n,
13
- path: e
5
+ /** Chrome-caps id gating the anchor, control, and segment affordances. */
6
+ var PATH_ANCHOR_CHROME_ID = "path-edit.anchors";
7
+ /**
8
+ * Segment, extension-part, anchor, and control affordances for the selected
9
+ * paths, bottom → top.
10
+ *
11
+ * Three affordances rather than one, so that a control handle beats an anchor
12
+ * regardless of which is nearer, the way controls draw on top, and both beat
13
+ * the segment they sit on. Within each, nearest wins. A press on the edited
14
+ * path's outline is a `segment` hit, which the segment bend binds to and a
15
+ * selection move turns down. Anchors, controls, and segments share one id:
16
+ * chrome-caps gates anchor editing as a single piece of chrome. A part a
17
+ * path-edit extension adds (`PathEditExtension.parts`) may name a chrome id of
18
+ * its own as well, so it can be shown apart from the anchors.
19
+ *
20
+ * Order matters — spread this into an affordance list in the returned order.
21
+ */
22
+ function createPathAnchorAffordances(getAnchorState, opts = {}) {
23
+ const { hitRadius = 8, cursor = "pointer" } = opts;
24
+ /** Selected polygon paths, paired with their node id. */
25
+ const editablePaths = (state) => {
26
+ const anchorState = getAnchorState();
27
+ if (!anchorState) return [];
28
+ const out = [];
29
+ for (const id of state.selection) {
30
+ const pose = anchorState.getPose(id);
31
+ if (!pose || pose.kind !== "polygon") continue;
32
+ out.push({
33
+ id,
34
+ path: pose
14
35
  });
15
36
  }
16
- return r;
17
- }, s = (e, t, n, r, o, s) => ({
18
- id: e,
37
+ return out;
38
+ };
39
+ const point = (id, targetId, x, y, scratch, hitKind) => ({
40
+ id,
19
41
  targetId: null,
20
42
  shape: {
21
43
  kind: "point",
22
- x: n,
23
- y: r,
24
- hitRadiusPx: i
44
+ x,
45
+ y,
46
+ hitRadiusPx: hitRadius
25
47
  },
26
- hitKind: s,
27
- cursor: a,
48
+ hitKind,
49
+ ...getAnchorState()?.tool ? {} : { cursor },
28
50
  bind: () => ({ initialScratch: {
29
- ...o,
30
- targetId: t
51
+ ...scratch,
52
+ targetId
31
53
  } })
32
54
  });
55
+ const anchors = {
56
+ id: PATH_ANCHOR_CHROME_ID,
57
+ regions(state) {
58
+ const editingId = getAnchorState()?.editingId ?? null;
59
+ const out = [];
60
+ for (const { id, path } of editablePaths(state)) {
61
+ if (editingId !== null && id !== editingId) continue;
62
+ for (const a of enumerateAnchors(path)) out.push(point(`${id}:anchor:${a.anchorIndex}`, id, a.x, a.y, {
63
+ targetId: id,
64
+ anchorIndex: a.anchorIndex,
65
+ part: "anchor"
66
+ }, `anchor:${a.anchorIndex}`));
67
+ }
68
+ return out;
69
+ }
70
+ };
71
+ const controls = {
72
+ id: PATH_ANCHOR_CHROME_ID,
73
+ regions(state) {
74
+ const editingId = getAnchorState()?.editingId ?? null;
75
+ if (editingId === null) return [];
76
+ const out = [];
77
+ for (const { id, path } of editablePaths(state)) {
78
+ if (id !== editingId) continue;
79
+ for (const a of enumerateAnchors(path)) {
80
+ if (a.controlIn) out.push(point(`${id}:controlIn:${a.anchorIndex}`, id, a.controlIn.x, a.controlIn.y, {
81
+ targetId: id,
82
+ anchorIndex: a.anchorIndex,
83
+ part: "controlIn"
84
+ }, `controlIn:${a.anchorIndex}`));
85
+ if (a.controlOut) out.push(point(`${id}:controlOut:${a.anchorIndex}`, id, a.controlOut.x, a.controlOut.y, {
86
+ targetId: id,
87
+ anchorIndex: a.anchorIndex,
88
+ part: "controlOut"
89
+ }, `controlOut:${a.anchorIndex}`));
90
+ }
91
+ }
92
+ return out;
93
+ }
94
+ };
33
95
  return [
34
96
  {
35
- id: t,
36
- regions(e) {
37
- let t = n()?.editingId ?? null;
38
- if (t === null) return [];
39
- let r = o(e).find(({ id: e }) => e === t);
40
- return r ? [{
41
- id: `${t}:segment`,
97
+ id: PATH_ANCHOR_CHROME_ID,
98
+ regions(state) {
99
+ const editingId = getAnchorState()?.editingId ?? null;
100
+ if (editingId === null) return [];
101
+ const edited = editablePaths(state).find(({ id }) => id === editingId);
102
+ if (!edited) return [];
103
+ const outline = getAnchorState()?.getOutline?.(editingId);
104
+ return [{
105
+ id: `${editingId}:segment`,
42
106
  targetId: null,
43
107
  shape: {
44
108
  kind: "outline",
45
- path: r.path,
46
- hitRadiusPx: i
109
+ path: outline?.kind === "polygon" ? outline : edited.path,
110
+ hitRadiusPx: hitRadius
47
111
  },
48
112
  hitKind: "segment",
49
- bind: () => ({ initialScratch: { targetId: t } })
50
- }] : [];
113
+ bind: () => ({ initialScratch: { targetId: editingId } })
114
+ }];
51
115
  }
52
116
  },
53
- {
54
- id: t,
55
- regions(t) {
56
- let r = n()?.editingId ?? null, i = [];
57
- for (let { id: n, path: a } of o(t)) if (r === null || n === r) for (let t of e(a)) i.push(s(`${n}:anchor:${t.anchorIndex}`, n, t.x, t.y, {
58
- targetId: n,
59
- anchorIndex: t.anchorIndex,
60
- part: "anchor"
61
- }, `anchor:${t.anchorIndex}`));
62
- return i;
63
- }
64
- },
65
- {
66
- id: t,
67
- regions(t) {
68
- let r = n()?.editingId ?? null;
69
- if (r === null) return [];
70
- let i = [];
71
- for (let { id: n, path: a } of o(t)) if (n === r) for (let t of e(a)) t.controlIn && i.push(s(`${n}:controlIn:${t.anchorIndex}`, n, t.controlIn.x, t.controlIn.y, {
72
- targetId: n,
73
- anchorIndex: t.anchorIndex,
74
- part: "controlIn"
75
- }, `controlIn:${t.anchorIndex}`)), t.controlOut && i.push(s(`${n}:controlOut:${t.anchorIndex}`, n, t.controlOut.x, t.controlOut.y, {
76
- targetId: n,
77
- anchorIndex: t.anchorIndex,
78
- part: "controlOut"
79
- }, `controlOut:${t.anchorIndex}`));
80
- return i;
81
- }
82
- }
117
+ extensionParts(getAnchorState, hitRadius, cursor),
118
+ anchors,
119
+ controls
83
120
  ];
84
121
  }
85
- //#endregion
86
- export { t as PATH_ANCHOR_CHROME_ID, n as createPathAnchorAffordances };
122
+ /** The parts path-edit extensions add to the path in edit mode while it is
123
+ * selected, each pressed as its own `hitKind`. */
124
+ function extensionParts(getAnchorState, hitRadius, cursor) {
125
+ return {
126
+ id: PATH_ANCHOR_CHROME_ID,
127
+ regions(state) {
128
+ const anchorState = getAnchorState();
129
+ const editingId = anchorState?.editingId ?? null;
130
+ const extensions = anchorState?.extensions?.filter((e) => e.parts) ?? [];
131
+ if (editingId === null || extensions.length === 0) return [];
132
+ if (!state.selection.includes(editingId)) return [];
133
+ const pose = anchorState.getPose(editingId);
134
+ const node = anchorState.getNode?.(editingId);
135
+ if (!node || !pose || pose.kind !== "polygon") return [];
136
+ const target = {
137
+ id: editingId,
138
+ node,
139
+ path: pose,
140
+ anchors: pathToAnchors(pose)
141
+ };
142
+ return extensions.flatMap((ext) => ext.parts(target).map((part) => ({
143
+ id: `${editingId}:${part.hitKind}`,
144
+ targetId: null,
145
+ shape: {
146
+ kind: "point",
147
+ x: part.x,
148
+ y: part.y,
149
+ hitRadiusPx: part.hitRadiusPx ?? hitRadius,
150
+ ...part.standoff ? { standoff: part.standoff } : {}
151
+ },
152
+ hitKind: part.hitKind,
153
+ ...part.chromeId ? { chromeId: part.chromeId } : {},
154
+ cursor,
155
+ bind: () => ({ initialScratch: { targetId: editingId } })
156
+ })));
157
+ }
158
+ };
159
+ }
87
160
 
161
+ //#endregion
162
+ export { PATH_ANCHOR_CHROME_ID, createPathAnchorAffordances };
88
163
  //# sourceMappingURL=pathAnchors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pathAnchors.js","names":["PATH_ANCHOR_CHROME_ID","createPathAnchorAffordances","opts","editablePaths","anchorState","getAnchorState","out","id","state","pose","point","hitRadius","scratch","editingId","edited","a","enumerateAnchors","path"],"sources":["../../src/affordances/pathAnchors.ts"],"sourcesContent":["/** Path anchor, control-handle, and segment affordances. */\n\nimport type { CursorSpec } from '@weasel-js/cursor';\nimport type { Affordance, AffordanceBinding, AffordanceRegion, CommonAffordanceScratch } from './types';\nimport type { ChromeState } from 'core/selection/chromeState';\nimport type { PolygonPath } from '@weasel-js/geom';\nimport { enumerateAnchors } from 'interactions/actions/edit-anchors/geometry';\n\n/**\n * Live anchor-editing state. The thunk that returns it is called on every\n * pointer event, so it must be cheap (O(1) field reads).\n */\nexport interface AnchorState {\n /** Id of the path currently in anchor-edit mode, or `null`. Control handles\n * are only hittable on the path that is being edited. */\n editingId: string | null;\n /** Current editable path for a node id. Non-polygon values are ignored. */\n getPose(id: string): unknown;\n}\n\n/** Options for the path-anchor affordances. */\nexport interface PathAnchorAffordanceOptions {\n /** Hit radius (screen-px) for anchor and control points. Default 8. */\n hitRadius?: number;\n /** Cursor while hovering an anchor or control. Defaults to `'pointer'`. */\n cursor?: CursorSpec;\n}\n\n/** What an anchor hit hands to the action that follows. */\nexport interface AnchorScratch extends CommonAffordanceScratch {\n /** Node id of the path the anchor belongs to. */\n targetId: string;\n /** Sequential anchor index in path walk order. */\n anchorIndex: number;\n /** Which of the anchor's three grabbable points this is. */\n part: 'anchor' | 'controlIn' | 'controlOut';\n}\n\n/** Chrome-caps id gating every returned affordance. */\nexport const PATH_ANCHOR_CHROME_ID = 'path-edit.anchors';\n\n/**\n * Segment, anchor, and control affordances for the selected paths, bottom →\n * top.\n *\n * Three affordances rather than one, so that a control handle beats an anchor\n * regardless of which is nearer, the way controls draw on top, and both beat\n * the segment they sit on. Within each, nearest wins. A press on the edited\n * path's outline is a `segment` hit, which the segment bend binds to and a\n * selection move turns down. They deliberately share one id: chrome-caps\n * gates anchor editing as a single piece of chrome.\n *\n * Order matters — spread this into an affordance list in the returned order.\n */\nexport function createPathAnchorAffordances(\n getAnchorState: () => AnchorState | null,\n opts: PathAnchorAffordanceOptions = {},\n): Affordance[] {\n const { hitRadius = 8, cursor = 'pointer' } = opts;\n\n /** Selected polygon paths, paired with their node id. */\n const editablePaths = (state: ChromeState): Array<{ id: string; path: PolygonPath }> => {\n const anchorState = getAnchorState();\n if (!anchorState) return [];\n const out: Array<{ id: string; path: PolygonPath }> = [];\n for (const id of state.selection) {\n const pose = anchorState.getPose(id);\n if (!pose || (pose as { kind?: string }).kind !== 'polygon') continue;\n out.push({ id, path: pose as PolygonPath });\n }\n return out;\n };\n\n const point = (\n id: string,\n targetId: string,\n x: number,\n y: number,\n scratch: AnchorScratch,\n hitKind: string,\n ): AffordanceRegion => ({\n id,\n // Anchor coordinates are already world space, pose rotation baked in.\n // Anchoring to `null` keeps the framework from applying it twice.\n targetId: null,\n shape: { kind: 'point', x, y, hitRadiusPx: hitRadius },\n hitKind,\n cursor,\n bind: (): AffordanceBinding => ({ initialScratch: { ...scratch, targetId } }),\n });\n\n const anchors: Affordance = {\n id: PATH_ANCHOR_CHROME_ID,\n regions(state) {\n const editingId = getAnchorState()?.editingId ?? null;\n const out: AffordanceRegion[] = [];\n for (const { id, path } of editablePaths(state)) {\n // `editAnchorsAction` edits whatever path the dep says is in edit\n // mode, ignoring which one was hit — so once a path IS being edited,\n // only its own anchors may claim the press.\n if (editingId !== null && id !== editingId) continue;\n for (const a of enumerateAnchors(path)) {\n out.push(point(\n `${id}:anchor:${a.anchorIndex}`,\n id, a.x, a.y,\n { targetId: id, anchorIndex: a.anchorIndex, part: 'anchor' },\n `anchor:${a.anchorIndex}`,\n ));\n }\n }\n return out;\n },\n };\n\n const controls: Affordance = {\n id: PATH_ANCHOR_CHROME_ID,\n regions(state) {\n const anchorState = getAnchorState();\n const editingId = anchorState?.editingId ?? null;\n if (editingId === null) return [];\n const out: AffordanceRegion[] = [];\n for (const { id, path } of editablePaths(state)) {\n // Controls are grabbable only on the path actually in edit mode.\n if (id !== editingId) continue;\n for (const a of enumerateAnchors(path)) {\n if (a.controlIn) {\n out.push(point(\n `${id}:controlIn:${a.anchorIndex}`,\n id, a.controlIn.x, a.controlIn.y,\n { targetId: id, anchorIndex: a.anchorIndex, part: 'controlIn' },\n `controlIn:${a.anchorIndex}`,\n ));\n }\n if (a.controlOut) {\n out.push(point(\n `${id}:controlOut:${a.anchorIndex}`,\n id, a.controlOut.x, a.controlOut.y,\n { targetId: id, anchorIndex: a.anchorIndex, part: 'controlOut' },\n `controlOut:${a.anchorIndex}`,\n ));\n }\n }\n }\n return out;\n },\n };\n\n const segments: Affordance = {\n id: PATH_ANCHOR_CHROME_ID,\n regions(state) {\n const editingId = getAnchorState()?.editingId ?? null;\n if (editingId === null) return [];\n const edited = editablePaths(state).find(({ id }) => id === editingId);\n if (!edited) return [];\n return [{\n id: `${editingId}:segment`,\n targetId: null,\n shape: { kind: 'outline', path: edited.path, hitRadiusPx: hitRadius },\n hitKind: 'segment',\n bind: (): AffordanceBinding => ({ initialScratch: { targetId: editingId } }),\n }];\n },\n };\n\n return [segments, anchors, controls];\n}\n"],"mappings":";;AAuCA,IAAaA,IAAwB;AAerC,SAAgBC,EACd,GACA,IAAoC,CAAC,GACvB;CACd,IAAM,EAAE,eAAY,GAAG,YAAS,cAAcC,GAGxCC,KAAiB,MAAiE;EACtF,IAAMC,IAAcC,EAAe;EACnC,IAAI,CAACD,GAAa,OAAO,CAAC;EAC1B,IAAME,IAAgD,CAAC;EACvD,KAAK,IAAMC,KAAMC,EAAM,WAAW;GAChC,IAAMC,IAAOL,EAAY,QAAQG,CAAE;GACnC,AAAKE,KAASA,EAA2B,SAAS,aAClDH,EAAI,KAAK;IAAE;IAAI,MAAMG;GAAoB,CAAC;EAC5C;EACA,OAAOH;CACT,GAEMI,KACJ,GACA,GACA,GACA,GACA,GACA,OACsB;EACtB;EAGA,UAAU;EACV,OAAO;GAAE,MAAM;GAAS;GAAG;GAAG,aAAaC;EAAU;EACrD;EACA;EACA,aAAgC,EAAE,gBAAgB;GAAE,GAAGC;GAAS;EAAS,EAAE;CAC7E;CA2EA,OAAO;EAAC;GAhBN,IAAIZ;GACJ,QAAQ,GAAO;IACb,IAAMa,IAAYR,EAAe,CAAC,EAAE,aAAa;IACjD,IAAIQ,MAAc,MAAM,OAAO,CAAC;IAChC,IAAMC,IAASX,EAAcK,CAAK,CAAC,CAAC,MAAM,EAAE,YAASD,MAAOM,CAAS;IAErE,OADKC,IACE,CAAC;KACN,IAAI,GAAGD,EAAU;KACjB,UAAU;KACV,OAAO;MAAE,MAAM;MAAW,MAAMC,EAAO;MAAM,aAAaH;KAAU;KACpE,SAAS;KACT,aAAgC,EAAE,gBAAgB,EAAE,UAAUE,EAAU,EAAE;IAC5E,CAAC,IAPmB,CAAC;GAQvB;EAGM;EAAU;GAxEhB,IAAIb;GACJ,QAAQ,GAAO;IACb,IAAMa,IAAYR,EAAe,CAAC,EAAE,aAAa,MAC3CC,IAA0B,CAAC;IACjC,KAAK,IAAM,EAAE,OAAI,aAAUH,EAAcK,CAAK,GAI5C,IAAIK,MAAc,QAAQN,MAAOM,GACjC,KAAK,IAAME,KAAKC,EAAiBC,CAAI,GACnC,EAAI,KAAKP,EACP,GAAGH,EAAG,UAAUQ,EAAE,eAClBR,GAAIQ,EAAE,GAAGA,EAAE,GACX;KAAE,UAAUR;KAAI,aAAaQ,EAAE;KAAa,MAAM;IAAS,GAC3D,UAAUA,EAAE,aACd,CAAC;IAGL,OAAOT;GACT;EAqDgB;EAAS;GAjDzB,IAAIN;GACJ,QAAQ,GAAO;IAEb,IAAMa,IADcR,EACF,CAAA,EAAa,aAAa;IAC5C,IAAIQ,MAAc,MAAM,OAAO,CAAC;IAChC,IAAMP,IAA0B,CAAC;IACjC,KAAK,IAAM,EAAE,OAAI,aAAUH,EAAcK,CAAK,GAE5C,IAAID,MAAOM,GACX,KAAK,IAAME,KAAKC,EAAiBC,CAAI,GASnC,AARIF,EAAE,aACJT,EAAI,KAAKI,EACP,GAAGH,EAAG,aAAaQ,EAAE,eACrBR,GAAIQ,EAAE,UAAU,GAAGA,EAAE,UAAU,GAC/B;KAAE,UAAUR;KAAI,aAAaQ,EAAE;KAAa,MAAM;IAAY,GAC9D,aAAaA,EAAE,aACjB,CAAC,GAECA,EAAE,cACJT,EAAI,KAAKI,EACP,GAAGH,EAAG,cAAcQ,EAAE,eACtBR,GAAIQ,EAAE,WAAW,GAAGA,EAAE,WAAW,GACjC;KAAE,UAAUR;KAAI,aAAaQ,EAAE;KAAa,MAAM;IAAa,GAC/D,cAAcA,EAAE,aAClB,CAAC;IAIP,OAAOT;GACT;EAoByB;CAAQ;AACrC"}
1
+ {"version":3,"file":"pathAnchors.js","names":[],"sources":["../../src/affordances/pathAnchors.ts"],"sourcesContent":["/** Path anchor, control-handle, and segment affordances, and the parts path-edit extensions add. */\n\nimport type { CursorSpec } from '@weasel-js/cursor';\nimport type { Affordance, AffordanceBinding, AffordanceRegion, CommonAffordanceScratch } from './types';\nimport type { ChromeState } from 'core/selection/chromeState';\nimport { pathToAnchors, type AnchorSet, type PolygonPath } from '@weasel-js/geom';\nimport { enumerateAnchors } from 'interactions/actions/edit-anchors/geometry';\nimport type { PathEditExtension } from 'features/paths/pathEditExtension';\n\n/**\n * Live anchor-editing state. The thunk that returns it is called on every\n * pointer event, so it must be cheap (O(1) field reads).\n */\nexport interface AnchorState {\n /** Id of the path currently in anchor-edit mode, or `null`. Control handles\n * are only hittable on the path that is being edited. */\n editingId: string | null;\n /** Current editable path for a node id. Non-polygon values are ignored. */\n getPose(id: string): unknown;\n /** The committed pose and data of a node, which extensions' parts read. */\n getNode?(id: string): { pose: unknown; data: unknown } | null;\n /** The path-edit extensions whose parts are pressed, in order. */\n extensions?: readonly PathEditExtension[];\n /** The active path-edit tool, if any. While one is set, anchors and controls\n * carry no cursor of their own, so the tool's action shows its own. */\n tool?: string | null;\n /** The path whose outline counts as a segment press, when it is not\n * `getPose`'s: a path drawn from a form, edited through the form's edit\n * path. */\n getOutline?(id: string): unknown;\n}\n\n/** Options for the path-anchor affordances. */\nexport interface PathAnchorAffordanceOptions {\n /** Hit radius (screen-px) for anchor and control points. Default 8. */\n hitRadius?: number;\n /** Cursor while hovering an anchor or control, with no path-edit tool\n * active. Defaults to `'pointer'`. */\n cursor?: CursorSpec;\n}\n\n/** What an anchor hit hands to the action that follows. */\nexport interface AnchorScratch extends CommonAffordanceScratch {\n /** Node id of the path the anchor belongs to. */\n targetId: string;\n /** Sequential anchor index in path walk order. */\n anchorIndex: number;\n /** Which of the anchor's three grabbable points this is. */\n part: 'anchor' | 'controlIn' | 'controlOut';\n}\n\n/** Chrome-caps id gating the anchor, control, and segment affordances. */\nexport const PATH_ANCHOR_CHROME_ID = 'path-edit.anchors';\n\n/**\n * Segment, extension-part, anchor, and control affordances for the selected\n * paths, bottom → top.\n *\n * Three affordances rather than one, so that a control handle beats an anchor\n * regardless of which is nearer, the way controls draw on top, and both beat\n * the segment they sit on. Within each, nearest wins. A press on the edited\n * path's outline is a `segment` hit, which the segment bend binds to and a\n * selection move turns down. Anchors, controls, and segments share one id:\n * chrome-caps gates anchor editing as a single piece of chrome. A part a\n * path-edit extension adds (`PathEditExtension.parts`) may name a chrome id of\n * its own as well, so it can be shown apart from the anchors.\n *\n * Order matters — spread this into an affordance list in the returned order.\n */\nexport function createPathAnchorAffordances(\n getAnchorState: () => AnchorState | null,\n opts: PathAnchorAffordanceOptions = {},\n): Affordance[] {\n const { hitRadius = 8, cursor = 'pointer' } = opts;\n\n /** Selected polygon paths, paired with their node id. */\n const editablePaths = (state: ChromeState): Array<{ id: string; path: PolygonPath }> => {\n const anchorState = getAnchorState();\n if (!anchorState) return [];\n const out: Array<{ id: string; path: PolygonPath }> = [];\n for (const id of state.selection) {\n const pose = anchorState.getPose(id);\n if (!pose || (pose as { kind?: string }).kind !== 'polygon') continue;\n out.push({ id, path: pose as PolygonPath });\n }\n return out;\n };\n\n const point = (\n id: string,\n targetId: string,\n x: number,\n y: number,\n scratch: AnchorScratch,\n hitKind: string,\n ): AffordanceRegion => ({\n id,\n // Anchor coordinates are already world space, pose rotation baked in.\n // Anchoring to `null` keeps the framework from applying it twice.\n targetId: null,\n shape: { kind: 'point', x, y, hitRadiusPx: hitRadius },\n hitKind,\n ...(getAnchorState()?.tool ? {} : { cursor }),\n bind: (): AffordanceBinding => ({ initialScratch: { ...scratch, targetId } }),\n });\n\n const anchors: Affordance = {\n id: PATH_ANCHOR_CHROME_ID,\n regions(state) {\n const editingId = getAnchorState()?.editingId ?? null;\n const out: AffordanceRegion[] = [];\n for (const { id, path } of editablePaths(state)) {\n // `editAnchorsAction` edits whatever path the dep says is in edit\n // mode, ignoring which one was hit — so once a path IS being edited,\n // only its own anchors may claim the press.\n if (editingId !== null && id !== editingId) continue;\n for (const a of enumerateAnchors(path)) {\n out.push(point(\n `${id}:anchor:${a.anchorIndex}`,\n id, a.x, a.y,\n { targetId: id, anchorIndex: a.anchorIndex, part: 'anchor' },\n `anchor:${a.anchorIndex}`,\n ));\n }\n }\n return out;\n },\n };\n\n const controls: Affordance = {\n id: PATH_ANCHOR_CHROME_ID,\n regions(state) {\n const anchorState = getAnchorState();\n const editingId = anchorState?.editingId ?? null;\n if (editingId === null) return [];\n const out: AffordanceRegion[] = [];\n for (const { id, path } of editablePaths(state)) {\n // Controls are grabbable only on the path actually in edit mode.\n if (id !== editingId) continue;\n for (const a of enumerateAnchors(path)) {\n if (a.controlIn) {\n out.push(point(\n `${id}:controlIn:${a.anchorIndex}`,\n id, a.controlIn.x, a.controlIn.y,\n { targetId: id, anchorIndex: a.anchorIndex, part: 'controlIn' },\n `controlIn:${a.anchorIndex}`,\n ));\n }\n if (a.controlOut) {\n out.push(point(\n `${id}:controlOut:${a.anchorIndex}`,\n id, a.controlOut.x, a.controlOut.y,\n { targetId: id, anchorIndex: a.anchorIndex, part: 'controlOut' },\n `controlOut:${a.anchorIndex}`,\n ));\n }\n }\n }\n return out;\n },\n };\n\n const segments: Affordance = {\n id: PATH_ANCHOR_CHROME_ID,\n regions(state) {\n const editingId = getAnchorState()?.editingId ?? null;\n if (editingId === null) return [];\n const edited = editablePaths(state).find(({ id }) => id === editingId);\n if (!edited) return [];\n const outline = getAnchorState()?.getOutline?.(editingId) as PolygonPath | null | undefined;\n return [{\n id: `${editingId}:segment`,\n targetId: null,\n shape: { kind: 'outline', path: outline?.kind === 'polygon' ? outline : edited.path, hitRadiusPx: hitRadius },\n hitKind: 'segment',\n bind: (): AffordanceBinding => ({ initialScratch: { targetId: editingId } }),\n }];\n },\n };\n\n return [segments, extensionParts(getAnchorState, hitRadius, cursor), anchors, controls];\n}\n\n/** The parts path-edit extensions add to the path in edit mode while it is\n * selected, each pressed as its own `hitKind`. */\nfunction extensionParts(\n getAnchorState: () => AnchorState | null,\n hitRadius: number,\n cursor: CursorSpec,\n): Affordance {\n return {\n id: PATH_ANCHOR_CHROME_ID,\n regions(state) {\n const anchorState = getAnchorState();\n const editingId = anchorState?.editingId ?? null;\n const extensions = anchorState?.extensions?.filter((e) => e.parts) ?? [];\n if (editingId === null || extensions.length === 0) return [];\n if (!(state.selection as readonly string[]).includes(editingId)) return [];\n const pose = anchorState!.getPose(editingId);\n const node = anchorState!.getNode?.(editingId);\n if (!node || !pose || (pose as { kind?: string }).kind !== 'polygon') return [];\n const target = {\n id: editingId, node, path: pose as PolygonPath, anchors: pathToAnchors(pose as PolygonPath) as AnchorSet,\n };\n return extensions.flatMap((ext) => ext.parts!(target).map((part): AffordanceRegion => ({\n id: `${editingId}:${part.hitKind}`,\n targetId: null,\n shape: {\n kind: 'point', x: part.x, y: part.y, hitRadiusPx: part.hitRadiusPx ?? hitRadius,\n ...(part.standoff ? { standoff: part.standoff } : {}),\n },\n hitKind: part.hitKind,\n ...(part.chromeId ? { chromeId: part.chromeId } : {}),\n cursor,\n bind: (): AffordanceBinding => ({ initialScratch: { targetId: editingId } }),\n })));\n },\n };\n}\n"],"mappings":"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"}
@@ -1,12 +1,18 @@
1
1
  //#region src/affordances/rotateCursor.ts
2
- function e(e, t, n) {
2
+ /**
3
+ * The `rotate` glyph for a pointer at world point `at` turning something
4
+ * about world point `pivot`, seen through a view of `scale`. The glyph's arc
5
+ * is drawn over the top of its box, so its up points from the pivot to the
6
+ * pointer and the opening faces what is being turned.
7
+ */
8
+ function rotateCursorAt(pivot, at, scale) {
3
9
  return {
4
10
  glyph: "rotate",
5
- angle: Math.atan2((t.x - e.x) * n.x, -(t.y - e.y) * n.y),
11
+ angle: Math.atan2((at.x - pivot.x) * scale.x, -(at.y - pivot.y) * scale.y),
6
12
  fallback: "grab"
7
13
  };
8
14
  }
9
- //#endregion
10
- export { e as rotateCursorAt };
11
15
 
16
+ //#endregion
17
+ export { rotateCursorAt };
12
18
  //# sourceMappingURL=rotateCursor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"rotateCursor.js","names":["rotateCursorAt","at","pivot","scale"],"sources":["../../src/affordances/rotateCursor.ts"],"sourcesContent":["import type { CursorSpec } from '@weasel-js/cursor';\nimport type { Scale2 } from '@weasel-js/geom';\n\n/**\n * The `rotate` glyph for a pointer at world point `at` turning something\n * about world point `pivot`, seen through a view of `scale`. The glyph's arc\n * is drawn over the top of its box, so its up points from the pivot to the\n * pointer and the opening faces what is being turned.\n */\nexport function rotateCursorAt(\n pivot: { x: number; y: number },\n at: { x: number; y: number },\n scale: Scale2,\n): CursorSpec {\n return {\n glyph: 'rotate',\n angle: Math.atan2((at.x - pivot.x) * scale.x, -(at.y - pivot.y) * scale.y),\n fallback: 'grab',\n };\n}\n"],"mappings":";AASA,SAAgBA,EACd,GACA,GACA,GACY;CACZ,OAAO;EACL,OAAO;EACP,OAAO,KAAK,OAAOC,EAAG,IAAIC,EAAM,KAAKC,EAAM,GAAG,EAAEF,EAAG,IAAIC,EAAM,KAAKC,EAAM,CAAC;EACzE,UAAU;CACZ;AACF"}
1
+ {"version":3,"file":"rotateCursor.js","names":[],"sources":["../../src/affordances/rotateCursor.ts"],"sourcesContent":["import type { CursorSpec } from '@weasel-js/cursor';\nimport type { Scale2 } from '@weasel-js/geom';\n\n/**\n * The `rotate` glyph for a pointer at world point `at` turning something\n * about world point `pivot`, seen through a view of `scale`. The glyph's arc\n * is drawn over the top of its box, so its up points from the pivot to the\n * pointer and the opening faces what is being turned.\n */\nexport function rotateCursorAt(\n pivot: { x: number; y: number },\n at: { x: number; y: number },\n scale: Scale2,\n): CursorSpec {\n return {\n glyph: 'rotate',\n angle: Math.atan2((at.x - pivot.x) * scale.x, -(at.y - pivot.y) * scale.y),\n fallback: 'grab',\n };\n}\n"],"mappings":";;;;;;;AASA,SAAgB,eACd,OACA,IACA,OACY;CACZ,OAAO;EACL,OAAO;EACP,OAAO,KAAK,OAAO,GAAG,IAAI,MAAM,KAAK,MAAM,GAAG,EAAE,GAAG,IAAI,MAAM,KAAK,MAAM,CAAC;EACzE,UAAU;CACZ;AACF"}
@@ -1,66 +1,89 @@
1
- import { localToWorld as e } from "../core/geometry/targetFrame.js";
2
- import { transformOf as t } from "./hitAffordanceRegions.js";
3
- import { MULTI_RESIZE_TARGET_ID as n } from "../core/selection/selectionTarget.js";
4
- import { rotateCursorAt as r } from "./rotateCursor.js";
1
+ import { localToWorld } from "../core/geometry/targetFrame.js";
2
+ import { transformOf } from "./hitAffordanceRegions.js";
3
+ import { MULTI_RESIZE_TARGET_ID } from "../core/selection/selectionTarget.js";
4
+ import { rotateCursorAt } from "./rotateCursor.js";
5
+
5
6
  //#region src/affordances/rotationHandle.ts
6
- var i = (e) => "fill" in e || "stroke" in e || "insetPx" in e, a = {
7
+ var isAnnulusForm = (paint) => "fill" in paint || "stroke" in paint || "insetPx" in paint;
8
+ var DEFAULT_PAINT = {
7
9
  fill: { paint: {
8
10
  kind: "solid",
9
11
  color: "rgba(26, 19, 13, 0.12)"
10
12
  } },
11
13
  insetPx: 10
12
14
  };
13
- function o(n = {}) {
14
- let { bandPx: o = 24, paint: c = a, cursor: l, handle: u } = n, d = c ? i(c) ? {
15
- kind: "annulus",
16
- ...c.fill ? { fill: c.fill } : {},
17
- ...c.stroke ? { stroke: c.stroke } : {},
18
- ...c.insetPx === void 0 ? {} : { insetPx: c.insetPx }
19
- } : {
20
- kind: "annulus",
21
- stroke: c
22
- } : null;
15
+ /**
16
+ * Rotation affordance for the active selection: an elliptical ring that wraps the selection —
17
+ * the smallest ellipse containing the AABB, minus the AABB itself. Hovering the ring sets the
18
+ * cursor (default the `rotate` glyph) and a drag from it triggers `rotateAction`.
19
+ *
20
+ * The ring is target-local — under target rotation the ellipse rotates with the AABB.
21
+ * Visibility is gated by chrome-caps' `'selection.rotation-handle'` rule. `paint: null` leaves
22
+ * the cursor change as the only cue.
23
+ */
24
+ function createRotationAffordance(opts = {}) {
25
+ const { bandPx = 24, paint = DEFAULT_PAINT, cursor, handle } = opts;
26
+ const annulusPaint = (() => {
27
+ if (!paint) return null;
28
+ if (!isAnnulusForm(paint)) return {
29
+ kind: "annulus",
30
+ stroke: paint
31
+ };
32
+ return {
33
+ kind: "annulus",
34
+ ...paint.fill ? { fill: paint.fill } : {},
35
+ ...paint.stroke ? { stroke: paint.stroke } : {},
36
+ ...paint.insetPx !== void 0 ? { insetPx: paint.insetPx } : {}
37
+ };
38
+ })();
23
39
  return {
24
40
  id: "selection.rotation-handle",
25
- regions(n) {
26
- let i = s(n);
27
- if (!i) return [];
28
- let a = i.bounds, c = a.width / 2, f = a.height / 2, p = e(t(n, i.id), a.x + c, a.y + f), m = l ?? ((e, t) => r(p, e, t.scale)), h = () => ({ initialScratch: {
29
- targetId: i.id,
41
+ regions(state) {
42
+ const target = pickTarget(state);
43
+ if (!target) return [];
44
+ const b = target.bounds;
45
+ const halfW = b.width / 2;
46
+ const halfH = b.height / 2;
47
+ const pivot = localToWorld(transformOf(state, target.id), b.x + halfW, b.y + halfH);
48
+ const regionCursor = cursor ?? ((at, view) => rotateCursorAt(pivot, at, view.scale));
49
+ const bind = () => ({ initialScratch: {
50
+ targetId: target.id,
30
51
  fixedPoint: {
31
- x: a.x + c,
32
- y: a.y + f
52
+ x: b.x + halfW,
53
+ y: b.y + halfH
33
54
  }
34
- } }), g = {
55
+ } });
56
+ const region = {
35
57
  id: "selection.rotation-handle",
36
- targetId: i.id,
58
+ targetId: target.id,
37
59
  shape: {
38
60
  kind: "annulus",
39
- cx: a.x + c,
40
- cy: a.y + f,
41
- rx: c * Math.SQRT2,
42
- ry: f * Math.SQRT2,
43
- innerX: a.x,
44
- innerY: a.y,
45
- innerWidth: a.width,
46
- innerHeight: a.height,
47
- minBandPx: o
61
+ cx: b.x + halfW,
62
+ cy: b.y + halfH,
63
+ rx: halfW * Math.SQRT2,
64
+ ry: halfH * Math.SQRT2,
65
+ innerX: b.x,
66
+ innerY: b.y,
67
+ innerWidth: b.width,
68
+ innerHeight: b.height,
69
+ minBandPx: bandPx
48
70
  },
49
- ...d ? { paint: d } : {},
71
+ ...annulusPaint ? { paint: annulusPaint } : {},
50
72
  hitKind: "rotate-handle",
51
- cursor: m,
52
- bind: h
73
+ cursor: regionCursor,
74
+ bind
53
75
  };
54
- return u ? [g, {
76
+ if (!handle) return [region];
77
+ return [region, {
55
78
  id: "rotation-badge",
56
- targetId: i.id,
79
+ targetId: target.id,
57
80
  shape: {
58
81
  kind: "point",
59
- x: a.x + c,
60
- y: a.y,
61
- hitRadiusPx: u.hitRadiusPx,
82
+ x: b.x + halfW,
83
+ y: b.y,
84
+ hitRadiusPx: handle.hitRadiusPx,
62
85
  standoff: {
63
- px: u.distancePx,
86
+ px: handle.distancePx,
64
87
  normal: {
65
88
  x: 0,
66
89
  y: -1
@@ -68,34 +91,34 @@ function o(n = {}) {
68
91
  }
69
92
  },
70
93
  hitKind: "rotate-handle",
71
- cursor: m,
72
- bind: h
73
- }] : [g];
94
+ cursor: regionCursor,
95
+ bind
96
+ }];
74
97
  }
75
98
  };
76
99
  }
77
- function s(e) {
78
- if (e.selection.length === 1) {
79
- let t = e.selection[0];
80
- if (e.canRotate && !e.canRotate(t)) return null;
81
- let n = e.boundsOf(t);
82
- return n ? {
83
- id: t,
84
- bounds: n
100
+ function pickTarget(state) {
101
+ if (state.selection.length === 1) {
102
+ const id = state.selection[0];
103
+ if (state.canRotate && !state.canRotate(id)) return null;
104
+ const b = state.boundsOf(id);
105
+ return b ? {
106
+ id,
107
+ bounds: b
85
108
  } : null;
86
109
  }
87
- if (e.multiActive && e.unionBounds) {
88
- if (e.canRotate) {
89
- for (let t of e.selection) if (!e.canRotate(t)) return null;
110
+ if (state.multiActive && state.unionBounds) {
111
+ if (state.canRotate) {
112
+ for (const id of state.selection) if (!state.canRotate(id)) return null;
90
113
  }
91
114
  return {
92
- id: n,
93
- bounds: e.unionBounds
115
+ id: MULTI_RESIZE_TARGET_ID,
116
+ bounds: state.unionBounds
94
117
  };
95
118
  }
96
119
  return null;
97
120
  }
98
- //#endregion
99
- export { o as createRotationAffordance };
100
121
 
122
+ //#endregion
123
+ export { createRotationAffordance };
101
124
  //# sourceMappingURL=rotationHandle.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"rotationHandle.js","names":["isAnnulusForm","paint","DEFAULT_PAINT","createRotationAffordance","opts","annulusPaint","target","pickTarget","state","b","halfW","halfH","pivot","localToWorld","transformOf","regionCursor","cursor","rotateCursorAt","at","view","bind","region","bandPx","handle","id","MULTI_RESIZE_TARGET_ID"],"sources":["../../src/affordances/rotationHandle.ts"],"sourcesContent":["import type { Affordance, AffordanceBinding, AffordanceRegion, CommonAffordanceScratch } from './types';\nimport type { ChromeState, Bounds } from 'core/selection/chromeState';\nimport type { CommandStroke, CommandFill } from '@weasel-js/paint';\nimport { MULTI_RESIZE_TARGET_ID } from 'core/selection/selectionTarget';\nimport { localToWorld, transformOf } from './hitAffordanceRegions';\nimport type { CursorSpec } from '@weasel-js/cursor';\nimport { rotateCursorAt } from './rotateCursor';\n\n/** Options for `createRotationAffordance` — how thick the rotate band is\n * outside the selection, and how (or whether) it is painted. */\nexport interface RotationAffordanceOptions {\n /** Minimum screen-space thickness of the rotate-zone band outside the selection AABB, so\n * the zone stays hoverable at any zoom and any selection size. Default 24. */\n bandPx?: number;\n /** Paint for the ring. `null` / `false` = invisible. Default is a semi-transparent fill of\n * the band, contracted by `insetPx` screen pixels on the outer edge. Pass a `Stroke` (or\n * `{ fill, stroke, insetPx }`) to override. */\n paint?:\n | CommandStroke\n | { fill?: CommandFill; stroke?: CommandStroke; insetPx?: number }\n | null\n | false;\n /** Cursor while hovering the ring. Defaults to the `rotate` glyph turned\n * square to the line from the pivot to the pointer, falling back to\n * `'grab'` if the browser rejects the image. */\n cursor?: CursorSpec;\n /** A grab region for a rotate badge painted off the top edge — the one\n * the selection overlay's `rotationHandle` draws. `distancePx` is how far\n * off the edge it sits and `hitRadiusPx` the half-extent of its square,\n * both in screen pixels. Placed by the same `standoff` the painted badge\n * is, so the two cannot drift apart. Omitted, only the ring rotates. */\n handle?: { distancePx: number; hitRadiusPx: number };\n}\n\n/** What a rotation-handle hit hands to the rotate action: what is being\n * rotated, and the world-space pivot it turns around. */\nexport interface RotationScratch extends CommonAffordanceScratch {\n /** Id of the rotation target — single selection id, or\n * `MULTI_RESIZE_TARGET_ID` for multi-selection. */\n targetId: string;\n /** Rotation pivot in world coords — the AABB (or union AABB) center. */\n fixedPoint: { x: number; y: number };\n}\n\ntype AnnulusPaintForm = { fill?: CommandFill; stroke?: CommandStroke; insetPx?: number };\n\nconst isAnnulusForm = (paint: CommandStroke | AnnulusPaintForm): paint is AnnulusPaintForm =>\n 'fill' in paint || 'stroke' in paint || 'insetPx' in paint;\n\nconst DEFAULT_PAINT: AnnulusPaintForm = {\n fill: { paint: { kind: 'solid', color: 'rgba(26, 19, 13, 0.12)' } },\n insetPx: 10,\n};\n\n/**\n * @experimental\n * Rotation affordance for the active selection: an elliptical ring that wraps the selection —\n * the smallest ellipse containing the AABB, minus the AABB itself. Hovering the ring sets the\n * cursor (default the `rotate` glyph) and a drag from it triggers `rotateAction`.\n *\n * The ring is target-local — under target rotation the ellipse rotates with the AABB.\n * Visibility is gated by chrome-caps' `'selection.rotation-handle'` rule. `paint: null` leaves\n * the cursor change as the only cue.\n */\nexport function createRotationAffordance(\n opts: RotationAffordanceOptions = {},\n): Affordance {\n const { bandPx = 24, paint = DEFAULT_PAINT, cursor, handle } = opts;\n\n // A bare `Stroke` carries none of the object form's three keys, and cannot be told apart\n // by its own `paint` since that is optional.\n const annulusPaint:\n | { kind: 'annulus'; fill?: CommandFill; stroke?: CommandStroke; insetPx?: number }\n | null = (() => {\n if (!paint) return null;\n if (!isAnnulusForm(paint)) {\n return { kind: 'annulus' as const, stroke: paint };\n }\n return {\n kind: 'annulus' as const,\n ...(paint.fill ? { fill: paint.fill } : {}),\n ...(paint.stroke ? { stroke: paint.stroke } : {}),\n ...(paint.insetPx !== undefined ? { insetPx: paint.insetPx } : {}),\n };\n })();\n\n return {\n id: 'selection.rotation-handle',\n regions(state: ChromeState): readonly AffordanceRegion[] {\n const target = pickTarget(state);\n if (!target) return [];\n const b = target.bounds;\n\n // The natural ring is the smallest ellipse containing the AABB. `minBandPx` asks the\n // framework to widen it to at least `bandPx` screen pixels outside the rect; the floor is\n // declared in screen units because `ChromeState` carries no view scale.\n const halfW = b.width / 2;\n const halfH = b.height / 2;\n\n const pivot = localToWorld(transformOf(state, target.id), b.x + halfW, b.y + halfH);\n const regionCursor: AffordanceRegion['cursor'] = cursor\n ?? ((at, view) => rotateCursorAt(pivot, at, view.scale));\n const bind = (): AffordanceBinding => ({\n initialScratch: {\n targetId: target.id,\n // Pivot. `rotateAction` recomputes its own union pivot for\n // multi-selection, but the single-target case reads this.\n fixedPoint: { x: b.x + halfW, y: b.y + halfH },\n } satisfies RotationScratch,\n });\n\n const region: AffordanceRegion = {\n id: 'selection.rotation-handle',\n targetId: target.id,\n shape: {\n kind: 'annulus',\n cx: b.x + halfW,\n cy: b.y + halfH,\n rx: halfW * Math.SQRT2,\n ry: halfH * Math.SQRT2,\n innerX: b.x,\n innerY: b.y,\n innerWidth: b.width,\n innerHeight: b.height,\n minBandPx: bandPx,\n },\n ...(annulusPaint ? { paint: annulusPaint } : {}),\n hitKind: 'rotate-handle',\n cursor: regionCursor,\n bind,\n };\n if (!handle) return [region];\n const badge: AffordanceRegion = {\n id: 'rotation-badge',\n targetId: target.id,\n shape: {\n kind: 'point',\n x: b.x + halfW,\n y: b.y,\n hitRadiusPx: handle.hitRadiusPx,\n standoff: { px: handle.distancePx, normal: { x: 0, y: -1 } },\n },\n hitKind: 'rotate-handle',\n cursor: regionCursor,\n bind,\n };\n return [region, badge];\n },\n };\n}\n\nfunction pickTarget(state: ChromeState): { id: string; bounds: Bounds } | null {\n if (state.selection.length === 1) {\n const id = state.selection[0];\n // Skip when the selected node's pose-descriptor declares it can't carry a rotation;\n // otherwise the ring would offer a rotate cursor over a node whose write is dropped.\n if (state.canRotate && !state.canRotate(id)) return null;\n const b = state.boundsOf(id);\n return b ? { id, bounds: b } : null;\n }\n // Multi-selection: anchor the ring to the union AABB; `rotateAction` ignores the synthetic\n // id and pivots at its own union center. Every selected id must support rotation — a\n // partial multi-rotate would feel broken.\n if (state.multiActive && state.unionBounds) {\n if (state.canRotate) {\n for (const id of state.selection) {\n if (!state.canRotate(id)) return null;\n }\n }\n return { id: MULTI_RESIZE_TARGET_ID, bounds: state.unionBounds };\n }\n return null;\n}\n"],"mappings":";;;;;AA8CA,IAAMA,KAAiB,MACrB,UAAUC,KAAS,YAAYA,KAAS,aAAaA,GAEjDC,IAAkC;CACtC,MAAM,EAAE,OAAO;EAAE,MAAM;EAAS,OAAO;CAAyB,EAAE;CAClE,SAAS;AACX;AAYA,SAAgBC,EACd,IAAkC,CAAC,GACvB;CACZ,IAAM,EAAE,YAAS,IAAI,WAAQD,GAAe,WAAQ,cAAWE,GAIzDC,IAGGJ,IACAD,EAAcC,CAAK,IAGjB;EACL,MAAM;EACN,GAAIA,EAAM,OAAO,EAAE,MAAMA,EAAM,KAAK,IAAI,CAAC;EACzC,GAAIA,EAAM,SAAS,EAAE,QAAQA,EAAM,OAAO,IAAI,CAAC;EAC/C,GAAIA,EAAM,YAAY,KAAA,IAAyC,CAAC,IAA9B,EAAE,SAASA,EAAM,QAAQ;CAC7D,IAPS;EAAE,MAAM;EAAoB,QAAQA;CAAM,IAFhC;CAYvB,OAAO;EACL,IAAI;EACJ,QAAQ,GAAiD;GACvD,IAAMK,IAASC,EAAWC,CAAK;GAC/B,IAAI,CAACF,GAAQ,OAAO,CAAC;GACrB,IAAMG,IAAIH,EAAO,QAKXI,IAAQD,EAAE,QAAQ,GAClBE,IAAQF,EAAE,SAAS,GAEnBG,IAAQC,EAAaC,EAAYN,GAAOF,EAAO,EAAE,GAAGG,EAAE,IAAIC,GAAOD,EAAE,IAAIE,CAAK,GAC5EI,IAA2CC,OAC1C,GAAI,MAASC,EAAeL,GAAOM,GAAIC,EAAK,KAAK,IAClDC,WAAiC,EACrC,gBAAgB;IACd,UAAUd,EAAO;IAGjB,YAAY;KAAE,GAAGG,EAAE,IAAIC;KAAO,GAAGD,EAAE,IAAIE;IAAM;GAC/C,EACF,IAEMU,IAA2B;IAC/B,IAAI;IACJ,UAAUf,EAAO;IACjB,OAAO;KACL,MAAM;KACN,IAAIG,EAAE,IAAIC;KACV,IAAID,EAAE,IAAIE;KACV,IAAID,IAAQ,KAAK;KACjB,IAAIC,IAAQ,KAAK;KACjB,QAAQF,EAAE;KACV,QAAQA,EAAE;KACV,YAAYA,EAAE;KACd,aAAaA,EAAE;KACf,WAAWa;IACb;IACA,GAAIjB,IAAe,EAAE,OAAOA,EAAa,IAAI,CAAC;IAC9C,SAAS;IACT,QAAQU;IACR;GACF;GAgBA,OAfKQ,IAeE,CAACF,GAAQ;IAbd,IAAI;IACJ,UAAUf,EAAO;IACjB,OAAO;KACL,MAAM;KACN,GAAGG,EAAE,IAAIC;KACT,GAAGD,EAAE;KACL,aAAac,EAAO;KACpB,UAAU;MAAE,IAAIA,EAAO;MAAY,QAAQ;OAAE,GAAG;OAAG,GAAG;MAAG;KAAE;IAC7D;IACA,SAAS;IACT,QAAQR;IACR;GAEc,CAAK,IAfD,CAACM,CAAM;EAgB7B;CACF;AACF;AAEA,SAASd,EAAW,GAA2D;CAC7E,IAAIC,EAAM,UAAU,WAAW,GAAG;EAChC,IAAMgB,IAAKhB,EAAM,UAAU;EAG3B,IAAIA,EAAM,aAAa,CAACA,EAAM,UAAUgB,CAAE,GAAG,OAAO;EACpD,IAAMf,IAAID,EAAM,SAASgB,CAAE;EAC3B,OAAOf,IAAI;GAAE;GAAI,QAAQA;EAAE,IAAI;CACjC;CAIA,IAAID,EAAM,eAAeA,EAAM,aAAa;EAC1C,IAAIA,EAAM,WACH;QAAA,IAAMgB,KAAMhB,EAAM,WACrB,IAAI,CAACA,EAAM,UAAUgB,CAAE,GAAG,OAAO;EAAA;EAGrC,OAAO;GAAE,IAAIC;GAAwB,QAAQjB,EAAM;EAAY;CACjE;CACA,OAAO;AACT"}
1
+ {"version":3,"file":"rotationHandle.js","names":[],"sources":["../../src/affordances/rotationHandle.ts"],"sourcesContent":["import type { Affordance, AffordanceBinding, AffordanceRegion, CommonAffordanceScratch } from './types';\nimport type { ChromeState, Bounds } from 'core/selection/chromeState';\nimport type { CommandStroke, CommandFill } from '@weasel-js/paint';\nimport { MULTI_RESIZE_TARGET_ID } from 'core/selection/selectionTarget';\nimport { localToWorld, transformOf } from './hitAffordanceRegions';\nimport type { CursorSpec } from '@weasel-js/cursor';\nimport { rotateCursorAt } from './rotateCursor';\n\n/** Options for `createRotationAffordance` — how thick the rotate band is\n * outside the selection, and how (or whether) it is painted. */\nexport interface RotationAffordanceOptions {\n /** Minimum screen-space thickness of the rotate-zone band outside the selection AABB, so\n * the zone stays hoverable at any zoom and any selection size. Default 24. */\n bandPx?: number;\n /** Paint for the ring. `null` / `false` = invisible. Default is a semi-transparent fill of\n * the band, contracted by `insetPx` screen pixels on the outer edge. Pass a `Stroke` (or\n * `{ fill, stroke, insetPx }`) to override. */\n paint?:\n | CommandStroke\n | { fill?: CommandFill; stroke?: CommandStroke; insetPx?: number }\n | null\n | false;\n /** Cursor while hovering the ring. Defaults to the `rotate` glyph turned\n * square to the line from the pivot to the pointer, falling back to\n * `'grab'` if the browser rejects the image. */\n cursor?: CursorSpec;\n /** A grab region for a rotate badge painted off the top edge — the one\n * the selection overlay's `rotationHandle` draws. `distancePx` is how far\n * off the edge it sits and `hitRadiusPx` the half-extent of its square,\n * both in screen pixels. Placed by the same `standoff` the painted badge\n * is, so the two cannot drift apart. Omitted, only the ring rotates. */\n handle?: { distancePx: number; hitRadiusPx: number };\n}\n\n/** What a rotation-handle hit hands to the rotate action: what is being\n * rotated, and the world-space pivot it turns around. */\nexport interface RotationScratch extends CommonAffordanceScratch {\n /** Id of the rotation target — single selection id, or\n * `MULTI_RESIZE_TARGET_ID` for multi-selection. */\n targetId: string;\n /** Rotation pivot in world coords — the AABB (or union AABB) center. */\n fixedPoint: { x: number; y: number };\n}\n\ntype AnnulusPaintForm = { fill?: CommandFill; stroke?: CommandStroke; insetPx?: number };\n\nconst isAnnulusForm = (paint: CommandStroke | AnnulusPaintForm): paint is AnnulusPaintForm =>\n 'fill' in paint || 'stroke' in paint || 'insetPx' in paint;\n\nconst DEFAULT_PAINT: AnnulusPaintForm = {\n fill: { paint: { kind: 'solid', color: 'rgba(26, 19, 13, 0.12)' } },\n insetPx: 10,\n};\n\n/**\n * Rotation affordance for the active selection: an elliptical ring that wraps the selection —\n * the smallest ellipse containing the AABB, minus the AABB itself. Hovering the ring sets the\n * cursor (default the `rotate` glyph) and a drag from it triggers `rotateAction`.\n *\n * The ring is target-local — under target rotation the ellipse rotates with the AABB.\n * Visibility is gated by chrome-caps' `'selection.rotation-handle'` rule. `paint: null` leaves\n * the cursor change as the only cue.\n */\nexport function createRotationAffordance(\n opts: RotationAffordanceOptions = {},\n): Affordance {\n const { bandPx = 24, paint = DEFAULT_PAINT, cursor, handle } = opts;\n\n // A bare `Stroke` carries none of the object form's three keys, and cannot be told apart\n // by its own `paint` since that is optional.\n const annulusPaint:\n | { kind: 'annulus'; fill?: CommandFill; stroke?: CommandStroke; insetPx?: number }\n | null = (() => {\n if (!paint) return null;\n if (!isAnnulusForm(paint)) {\n return { kind: 'annulus' as const, stroke: paint };\n }\n return {\n kind: 'annulus' as const,\n ...(paint.fill ? { fill: paint.fill } : {}),\n ...(paint.stroke ? { stroke: paint.stroke } : {}),\n ...(paint.insetPx !== undefined ? { insetPx: paint.insetPx } : {}),\n };\n })();\n\n return {\n id: 'selection.rotation-handle',\n regions(state: ChromeState): readonly AffordanceRegion[] {\n const target = pickTarget(state);\n if (!target) return [];\n const b = target.bounds;\n\n // The natural ring is the smallest ellipse containing the AABB. `minBandPx` asks the\n // framework to widen it to at least `bandPx` screen pixels outside the rect; the floor is\n // declared in screen units because `ChromeState` carries no view scale.\n const halfW = b.width / 2;\n const halfH = b.height / 2;\n\n const pivot = localToWorld(transformOf(state, target.id), b.x + halfW, b.y + halfH);\n const regionCursor: AffordanceRegion['cursor'] = cursor\n ?? ((at, view) => rotateCursorAt(pivot, at, view.scale));\n const bind = (): AffordanceBinding => ({\n initialScratch: {\n targetId: target.id,\n // Pivot. `rotateAction` recomputes its own union pivot for\n // multi-selection, but the single-target case reads this.\n fixedPoint: { x: b.x + halfW, y: b.y + halfH },\n } satisfies RotationScratch,\n });\n\n const region: AffordanceRegion = {\n id: 'selection.rotation-handle',\n targetId: target.id,\n shape: {\n kind: 'annulus',\n cx: b.x + halfW,\n cy: b.y + halfH,\n rx: halfW * Math.SQRT2,\n ry: halfH * Math.SQRT2,\n innerX: b.x,\n innerY: b.y,\n innerWidth: b.width,\n innerHeight: b.height,\n minBandPx: bandPx,\n },\n ...(annulusPaint ? { paint: annulusPaint } : {}),\n hitKind: 'rotate-handle',\n cursor: regionCursor,\n bind,\n };\n if (!handle) return [region];\n const badge: AffordanceRegion = {\n id: 'rotation-badge',\n targetId: target.id,\n shape: {\n kind: 'point',\n x: b.x + halfW,\n y: b.y,\n hitRadiusPx: handle.hitRadiusPx,\n standoff: { px: handle.distancePx, normal: { x: 0, y: -1 } },\n },\n hitKind: 'rotate-handle',\n cursor: regionCursor,\n bind,\n };\n return [region, badge];\n },\n };\n}\n\nfunction pickTarget(state: ChromeState): { id: string; bounds: Bounds } | null {\n if (state.selection.length === 1) {\n const id = state.selection[0];\n // Skip when the selected node's pose-descriptor declares it can't carry a rotation;\n // otherwise the ring would offer a rotate cursor over a node whose write is dropped.\n if (state.canRotate && !state.canRotate(id)) return null;\n const b = state.boundsOf(id);\n return b ? { id, bounds: b } : null;\n }\n // Multi-selection: anchor the ring to the union AABB; `rotateAction` ignores the synthetic\n // id and pivots at its own union center. Every selected id must support rotation — a\n // partial multi-rotate would feel broken.\n if (state.multiActive && state.unionBounds) {\n if (state.canRotate) {\n for (const id of state.selection) {\n if (!state.canRotate(id)) return null;\n }\n }\n return { id: MULTI_RESIZE_TARGET_ID, bounds: state.unionBounds };\n }\n return null;\n}\n"],"mappings":";;;;;;AA8CA,IAAM,iBAAiB,UACrB,UAAU,SAAS,YAAY,SAAS,aAAa;AAEvD,IAAM,gBAAkC;CACtC,MAAM,EAAE,OAAO;EAAE,MAAM;EAAS,OAAO;CAAyB,EAAE;CAClE,SAAS;AACX;;;;;;;;;;AAWA,SAAgB,yBACd,OAAkC,CAAC,GACvB;CACZ,MAAM,EAAE,SAAS,IAAI,QAAQ,eAAe,QAAQ,WAAW;CAI/D,MAAM,sBAEY;EACd,IAAI,CAAC,OAAO,OAAO;EACnB,IAAI,CAAC,cAAc,KAAK,GACtB,OAAO;GAAE,MAAM;GAAoB,QAAQ;EAAM;EAEnD,OAAO;GACL,MAAM;GACN,GAAI,MAAM,OAAO,EAAE,MAAM,MAAM,KAAK,IAAI,CAAC;GACzC,GAAI,MAAM,SAAS,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;GAC/C,GAAI,MAAM,YAAY,SAAY,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;EAClE;CACF,EAAA,CAAG;CAEL,OAAO;EACL,IAAI;EACJ,QAAQ,OAAiD;GACvD,MAAM,SAAS,WAAW,KAAK;GAC/B,IAAI,CAAC,QAAQ,OAAO,CAAC;GACrB,MAAM,IAAI,OAAO;GAKjB,MAAM,QAAQ,EAAE,QAAQ;GACxB,MAAM,QAAQ,EAAE,SAAS;GAEzB,MAAM,QAAQ,aAAa,YAAY,OAAO,OAAO,EAAE,GAAG,EAAE,IAAI,OAAO,EAAE,IAAI,KAAK;GAClF,MAAM,eAA2C,YAC1C,IAAI,SAAS,eAAe,OAAO,IAAI,KAAK,KAAK;GACxD,MAAM,cAAiC,EACrC,gBAAgB;IACd,UAAU,OAAO;IAGjB,YAAY;KAAE,GAAG,EAAE,IAAI;KAAO,GAAG,EAAE,IAAI;IAAM;GAC/C,EACF;GAEA,MAAM,SAA2B;IAC/B,IAAI;IACJ,UAAU,OAAO;IACjB,OAAO;KACL,MAAM;KACN,IAAI,EAAE,IAAI;KACV,IAAI,EAAE,IAAI;KACV,IAAI,QAAQ,KAAK;KACjB,IAAI,QAAQ,KAAK;KACjB,QAAQ,EAAE;KACV,QAAQ,EAAE;KACV,YAAY,EAAE;KACd,aAAa,EAAE;KACf,WAAW;IACb;IACA,GAAI,eAAe,EAAE,OAAO,aAAa,IAAI,CAAC;IAC9C,SAAS;IACT,QAAQ;IACR;GACF;GACA,IAAI,CAAC,QAAQ,OAAO,CAAC,MAAM;GAe3B,OAAO,CAAC,QAAQ;IAbd,IAAI;IACJ,UAAU,OAAO;IACjB,OAAO;KACL,MAAM;KACN,GAAG,EAAE,IAAI;KACT,GAAG,EAAE;KACL,aAAa,OAAO;KACpB,UAAU;MAAE,IAAI,OAAO;MAAY,QAAQ;OAAE,GAAG;OAAG,GAAG;MAAG;KAAE;IAC7D;IACA,SAAS;IACT,QAAQ;IACR;GAEc,CAAK;EACvB;CACF;AACF;AAEA,SAAS,WAAW,OAA2D;CAC7E,IAAI,MAAM,UAAU,WAAW,GAAG;EAChC,MAAM,KAAK,MAAM,UAAU;EAG3B,IAAI,MAAM,aAAa,CAAC,MAAM,UAAU,EAAE,GAAG,OAAO;EACpD,MAAM,IAAI,MAAM,SAAS,EAAE;EAC3B,OAAO,IAAI;GAAE;GAAI,QAAQ;EAAE,IAAI;CACjC;CAIA,IAAI,MAAM,eAAe,MAAM,aAAa;EAC1C,IAAI,MAAM,WACR;QAAK,MAAM,MAAM,MAAM,WACrB,IAAI,CAAC,MAAM,UAAU,EAAE,GAAG,OAAO;EACnC;EAEF,OAAO;GAAE,IAAI;GAAwB,QAAQ,MAAM;EAAY;CACjE;CACA,OAAO;AACT"}