@weasel-js/core 1.9.4 → 1.10.1

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 (1191) hide show
  1. package/CHANGELOG.md +918 -0
  2. package/README.md +38 -3
  3. package/dist/WeaselProvider.js +5 -7
  4. package/dist/WeaselProvider.js.map +1 -1
  5. package/dist/affordances/composeAffordanceLayer.js +92 -84
  6. package/dist/affordances/composeAffordanceLayer.js.map +1 -1
  7. package/dist/affordances/cornerResize.js +3 -2
  8. package/dist/affordances/cornerResize.js.map +1 -1
  9. package/dist/affordances/hitAffordanceRegions.js +71 -101
  10. package/dist/affordances/hitAffordanceRegions.js.map +1 -1
  11. package/dist/affordances/pathAnchors.js +50 -28
  12. package/dist/affordances/pathAnchors.js.map +1 -1
  13. package/dist/affordances/rotateCursor.js +12 -0
  14. package/dist/affordances/rotateCursor.js.map +1 -0
  15. package/dist/affordances/rotationHandle.js +44 -46
  16. package/dist/affordances/rotationHandle.js.map +1 -1
  17. package/dist/animation/behaviors/coast.js +21 -0
  18. package/dist/animation/behaviors/coast.js.map +1 -0
  19. package/dist/animation/behaviors/coastByWrite.js +107 -0
  20. package/dist/animation/behaviors/coastByWrite.js.map +1 -0
  21. package/dist/animation/behaviors/coastOnTargets.js +94 -0
  22. package/dist/animation/behaviors/coastOnTargets.js.map +1 -0
  23. package/dist/animation/behaviors/momentum.js +48 -136
  24. package/dist/animation/behaviors/momentum.js.map +1 -1
  25. package/dist/animation/clipTargets.js +12 -0
  26. package/dist/animation/clipTargets.js.map +1 -0
  27. package/dist/animation/index.js +15 -20
  28. package/dist/animation/poseHelpers.js +112 -33
  29. package/dist/animation/poseHelpers.js.map +1 -1
  30. package/dist/animation/poseTarget.js +115 -0
  31. package/dist/animation/poseTarget.js.map +1 -0
  32. package/dist/animation/reflow.js +113 -83
  33. package/dist/animation/reflow.js.map +1 -1
  34. package/dist/animation/rewind.js +66 -0
  35. package/dist/animation/rewind.js.map +1 -0
  36. package/dist/animation/rig/bindRig.js +85 -53
  37. package/dist/animation/rig/bindRig.js.map +1 -1
  38. package/dist/animation/rig/rigNode.js +99 -0
  39. package/dist/animation/rig/rigNode.js.map +1 -0
  40. package/dist/animation/rig/rigSeat.js +59 -0
  41. package/dist/animation/rig/rigSeat.js.map +1 -0
  42. package/dist/animation/rig/skinBinding.js +64 -0
  43. package/dist/animation/rig/skinBinding.js.map +1 -0
  44. package/dist/animation/rig/useRig.js +31 -16
  45. package/dist/animation/rig/useRig.js.map +1 -1
  46. package/dist/animation/wrappers/animateLifecycle.js +8 -7
  47. package/dist/animation/wrappers/animateLifecycle.js.map +1 -1
  48. package/dist/animation/wrappers/animateOnSetPose.js +31 -31
  49. package/dist/animation/wrappers/animateOnSetPose.js.map +1 -1
  50. package/dist/animation/wrappers/instantPose.js.map +1 -1
  51. package/dist/animation/writtenPoseTarget.js +33 -0
  52. package/dist/animation/writtenPoseTarget.js.map +1 -0
  53. package/dist/autoPoseDescriptor-DHg5KqaJ.d.ts +27 -0
  54. package/dist/barrel/canvas.js +32 -0
  55. package/dist/barrel/chrome.js +10 -10
  56. package/dist/barrel/input.js +16 -17
  57. package/dist/barrel/interactions.js +34 -37
  58. package/dist/barrel/paint.js +11 -18
  59. package/dist/barrel/paths.js +13 -19
  60. package/dist/barrel/renderer.js +14 -20
  61. package/dist/barrel/routing.js +54 -47
  62. package/dist/barrel/scene.js +37 -0
  63. package/dist/barrel/text.js +9 -18
  64. package/dist/barrel/viewport.js +44 -51
  65. package/dist/canvas/Canvas.js +270 -475
  66. package/dist/canvas/Canvas.js.map +1 -1
  67. package/dist/canvas/CanvasView.js +168 -190
  68. package/dist/canvas/CanvasView.js.map +1 -1
  69. package/dist/canvas/CursorCoordsHud.js +24 -25
  70. package/dist/canvas/CursorCoordsHud.js.map +1 -1
  71. package/dist/canvas/DrawCanvas.js +39 -56
  72. package/dist/canvas/DrawCanvas.js.map +1 -1
  73. package/dist/canvas/ModalityHud.js.map +1 -1
  74. package/dist/canvas/NodeShape.js +28 -29
  75. package/dist/canvas/NodeShape.js.map +1 -1
  76. package/dist/canvas/PickHud.js.map +1 -1
  77. package/dist/canvas/SceneCanvas/DevHuds.js +40 -0
  78. package/dist/canvas/SceneCanvas/DevHuds.js.map +1 -0
  79. package/dist/canvas/SceneCanvas/GestureDispatcherMounter.js +66 -107
  80. package/dist/canvas/SceneCanvas/GestureDispatcherMounter.js.map +1 -1
  81. package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js +33 -36
  82. package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js.map +1 -1
  83. package/dist/canvas/SceneCanvas/StandardActionsRegistrar.js +38 -50
  84. package/dist/canvas/SceneCanvas/StandardActionsRegistrar.js.map +1 -1
  85. package/dist/canvas/SceneCanvas/ToolKeybindingsMounter.js +3 -3
  86. package/dist/canvas/SceneCanvas/ToolKeybindingsMounter.js.map +1 -1
  87. package/dist/canvas/SceneCanvas/coordTrace.js +37 -1
  88. package/dist/canvas/SceneCanvas/coordTrace.js.map +1 -1
  89. package/dist/canvas/SceneCanvas/defaultNodeProperties.js +319 -270
  90. package/dist/canvas/SceneCanvas/defaultNodeProperties.js.map +1 -1
  91. package/dist/canvas/SceneCanvas/defaultNodeRouting.js +1 -1
  92. package/dist/canvas/SceneCanvas/defaultNodeRouting.js.map +1 -1
  93. package/dist/canvas/SceneCanvas/dispatcherGestureBounds.js.map +1 -1
  94. package/dist/canvas/SceneCanvas/features.js +71 -62
  95. package/dist/canvas/SceneCanvas/features.js.map +1 -1
  96. package/dist/canvas/SceneCanvas/insertPreviewCommands.js +97 -0
  97. package/dist/canvas/SceneCanvas/insertPreviewCommands.js.map +1 -0
  98. package/dist/canvas/SceneCanvas/isDev.js.map +1 -1
  99. package/dist/canvas/SceneCanvas/poseGeometry.js +33 -37
  100. package/dist/canvas/SceneCanvas/poseGeometry.js.map +1 -1
  101. package/dist/canvas/SceneCanvas/props.js +15 -14
  102. package/dist/canvas/SceneCanvas/props.js.map +1 -1
  103. package/dist/canvas/SceneCanvas/scenePointQuery.js +50 -0
  104. package/dist/canvas/SceneCanvas/scenePointQuery.js.map +1 -0
  105. package/dist/canvas/SceneCanvas/shapeGeneratorProperties.js +52 -0
  106. package/dist/canvas/SceneCanvas/shapeGeneratorProperties.js.map +1 -0
  107. package/dist/canvas/SceneCanvas/toolRegistry.js +23 -0
  108. package/dist/canvas/SceneCanvas/toolRegistry.js.map +1 -0
  109. package/dist/canvas/SceneCanvas/useActionTunings.js +17 -0
  110. package/dist/canvas/SceneCanvas/useActionTunings.js.map +1 -0
  111. package/dist/canvas/SceneCanvas/useActionsPropResolver.js +6 -1
  112. package/dist/canvas/SceneCanvas/useActionsPropResolver.js.map +1 -1
  113. package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js.map +1 -1
  114. package/dist/canvas/SceneCanvas/useBuiltinTools.js +21 -0
  115. package/dist/canvas/SceneCanvas/useBuiltinTools.js.map +1 -0
  116. package/dist/canvas/SceneCanvas/useCanvasCamera.js +46 -0
  117. package/dist/canvas/SceneCanvas/useCanvasCamera.js.map +1 -0
  118. package/dist/canvas/SceneCanvas/useCanvasDispatcher.js +20 -0
  119. package/dist/canvas/SceneCanvas/useCanvasDispatcher.js.map +1 -0
  120. package/dist/canvas/SceneCanvas/useCanvasSelection.js +16 -0
  121. package/dist/canvas/SceneCanvas/useCanvasSelection.js.map +1 -0
  122. package/dist/canvas/SceneCanvas/useCanvasTools.js +67 -0
  123. package/dist/canvas/SceneCanvas/useCanvasTools.js.map +1 -0
  124. package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js +49 -113
  125. package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js.map +1 -1
  126. package/dist/canvas/SceneCanvas/useHeldModifiers.js +20 -0
  127. package/dist/canvas/SceneCanvas/useHeldModifiers.js.map +1 -0
  128. package/dist/canvas/SceneCanvas/useNodeAtPoint.js +26 -0
  129. package/dist/canvas/SceneCanvas/useNodeAtPoint.js.map +1 -0
  130. package/dist/canvas/SceneCanvas/useNodeKinds.js +26 -0
  131. package/dist/canvas/SceneCanvas/useNodeKinds.js.map +1 -0
  132. package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js +51 -41
  133. package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js.map +1 -1
  134. package/dist/canvas/SceneCanvas/useSceneCanvasHandle.js +47 -0
  135. package/dist/canvas/SceneCanvas/useSceneCanvasHandle.js.map +1 -0
  136. package/dist/canvas/SceneCanvas/useSceneCanvasLayers.js +66 -0
  137. package/dist/canvas/SceneCanvas/useSceneCanvasLayers.js.map +1 -0
  138. package/dist/canvas/SceneCanvas/useSceneChrome.js +59 -0
  139. package/dist/canvas/SceneCanvas/useSceneChrome.js.map +1 -0
  140. package/dist/canvas/SceneCanvas/useSceneRedrawSources.js +23 -0
  141. package/dist/canvas/SceneCanvas/useSceneRedrawSources.js.map +1 -0
  142. package/dist/canvas/SceneCanvas/useSceneSelectTool.js +65 -101
  143. package/dist/canvas/SceneCanvas/useSceneSelectTool.js.map +1 -1
  144. package/dist/canvas/SceneCanvas/useSceneSlotLayers.js +37 -0
  145. package/dist/canvas/SceneCanvas/useSceneSlotLayers.js.map +1 -0
  146. package/dist/canvas/SceneCanvas/useSelectionOverlayLayer.js +38 -0
  147. package/dist/canvas/SceneCanvas/useSelectionOverlayLayer.js.map +1 -0
  148. package/dist/canvas/SceneCanvas/useViewLayerGate.js +20 -0
  149. package/dist/canvas/SceneCanvas/useViewLayerGate.js.map +1 -0
  150. package/dist/canvas/SceneCanvas/useViewportActions.js +9 -1
  151. package/dist/canvas/SceneCanvas/useViewportActions.js.map +1 -1
  152. package/dist/canvas/SceneCanvas/worldPointAt.js +8 -0
  153. package/dist/canvas/SceneCanvas/worldPointAt.js.map +1 -0
  154. package/dist/canvas/SceneCanvas.js +301 -708
  155. package/dist/canvas/SceneCanvas.js.map +1 -1
  156. package/dist/canvas/SceneViewCanvas.js +41 -47
  157. package/dist/canvas/SceneViewCanvas.js.map +1 -1
  158. package/dist/canvas/SurfaceCanvas.js +40 -0
  159. package/dist/canvas/SurfaceCanvas.js.map +1 -0
  160. package/dist/canvas/adapterDerivedPath.js +26 -0
  161. package/dist/canvas/adapterDerivedPath.js.map +1 -0
  162. package/dist/canvas/adapterPickSource.js +34 -0
  163. package/dist/canvas/adapterPickSource.js.map +1 -0
  164. package/dist/canvas/affordanceAt.js +12 -2
  165. package/dist/canvas/affordanceAt.js.map +1 -1
  166. package/dist/canvas/buildSceneLayer.js +81 -61
  167. package/dist/canvas/buildSceneLayer.js.map +1 -1
  168. package/dist/canvas/buildSceneTree.js +56 -34
  169. package/dist/canvas/buildSceneTree.js.map +1 -1
  170. package/dist/canvas/canvasRenderer.js +40 -44
  171. package/dist/canvas/canvasRenderer.js.map +1 -1
  172. package/dist/canvas/colorOverrides.js.map +1 -1
  173. package/dist/canvas/copiesAbove.js +27 -0
  174. package/dist/canvas/copiesAbove.js.map +1 -0
  175. package/dist/canvas/defaultDrawOne.js +25 -24
  176. package/dist/canvas/defaultDrawOne.js.map +1 -1
  177. package/dist/canvas/deps/areaSelect.js +4 -4
  178. package/dist/canvas/deps/areaSelect.js.map +1 -1
  179. package/dist/canvas/deps/debug.js.map +1 -1
  180. package/dist/canvas/deps/editAnchors.js +47 -71
  181. package/dist/canvas/deps/editAnchors.js.map +1 -1
  182. package/dist/canvas/deps/geometryProjection.js.map +1 -1
  183. package/dist/canvas/deps/hitTestArea.js +45 -25
  184. package/dist/canvas/deps/hitTestArea.js.map +1 -1
  185. package/dist/canvas/deps/insert.js +149 -104
  186. package/dist/canvas/deps/insert.js.map +1 -1
  187. package/dist/canvas/deps/lassoSelect.js +5 -5
  188. package/dist/canvas/deps/lassoSelect.js.map +1 -1
  189. package/dist/canvas/deps/layout.js +9 -15
  190. package/dist/canvas/deps/layout.js.map +1 -1
  191. package/dist/canvas/deps/poseDescriptor.js +1 -1
  192. package/dist/canvas/deps/poseDescriptor.js.map +1 -1
  193. package/dist/canvas/deps/resizePolicy.js.map +1 -1
  194. package/dist/canvas/deps/slice.js +44 -45
  195. package/dist/canvas/deps/slice.js.map +1 -1
  196. package/dist/canvas/deps/textEdit.js +8 -8
  197. package/dist/canvas/deps/textEdit.js.map +1 -1
  198. package/dist/canvas/deps/view.js.map +1 -1
  199. package/dist/canvas/derivedPath.js +69 -43
  200. package/dist/canvas/derivedPath.js.map +1 -1
  201. package/dist/canvas/drawEnvelope.js +8 -4
  202. package/dist/canvas/drawEnvelope.js.map +1 -1
  203. package/dist/canvas/getNodeAtPoint.js +2 -6
  204. package/dist/canvas/getNodeAtPoint.js.map +1 -1
  205. package/dist/canvas/hud.module.js.map +1 -1
  206. package/dist/canvas/insertPreviewExtent.js +33 -31
  207. package/dist/canvas/insertPreviewExtent.js.map +1 -1
  208. package/dist/canvas/layerOrder.js.map +1 -1
  209. package/dist/canvas/layerSlots.js +6 -1
  210. package/dist/canvas/layerSlots.js.map +1 -1
  211. package/dist/canvas/nodeShapes/derivedPainter.js +12 -12
  212. package/dist/canvas/nodeShapes/derivedPainter.js.map +1 -1
  213. package/dist/canvas/nodeShapes/imagePainter.js +10 -10
  214. package/dist/canvas/nodeShapes/imagePainter.js.map +1 -1
  215. package/dist/canvas/nodeShapes/memo.js.map +1 -1
  216. package/dist/canvas/nodeShapes/nodePaint.js +34 -23
  217. package/dist/canvas/nodeShapes/nodePaint.js.map +1 -1
  218. package/dist/canvas/nodeShapes/pathPainter.js +23 -22
  219. package/dist/canvas/nodeShapes/pathPainter.js.map +1 -1
  220. package/dist/canvas/nodeShapes/poseBox.js +6 -6
  221. package/dist/canvas/nodeShapes/poseBox.js.map +1 -1
  222. package/dist/canvas/nodeShapes/rectFallbackPainter.js +8 -8
  223. package/dist/canvas/nodeShapes/rectFallbackPainter.js.map +1 -1
  224. package/dist/canvas/nodeShapes/shapePainter.js +16 -16
  225. package/dist/canvas/nodeShapes/shapePainter.js.map +1 -1
  226. package/dist/canvas/nodeShapes/textPainter.js +1 -1
  227. package/dist/canvas/nodeShapes/textPainter.js.map +1 -1
  228. package/dist/canvas/overChildren.js +29 -0
  229. package/dist/canvas/overChildren.js.map +1 -0
  230. package/dist/canvas/overlayRoleStrokes.js.map +1 -1
  231. package/dist/canvas/paintCull.js +6 -8
  232. package/dist/canvas/paintCull.js.map +1 -1
  233. package/dist/{features/cursor → canvas}/paintedCursorLayer.js +2 -2
  234. package/dist/canvas/paintedCursorLayer.js.map +1 -0
  235. package/dist/canvas/pickReach.js +23 -0
  236. package/dist/canvas/pickReach.js.map +1 -0
  237. package/dist/canvas/pickWalk.js +43 -70
  238. package/dist/canvas/pickWalk.js.map +1 -1
  239. package/dist/canvas/planeClips.js +18 -19
  240. package/dist/canvas/planeClips.js.map +1 -1
  241. package/dist/canvas/poseCascade.js +41 -0
  242. package/dist/canvas/poseCascade.js.map +1 -0
  243. package/dist/canvas/poseRotation.js +1 -3
  244. package/dist/canvas/poseRotation.js.map +1 -1
  245. package/dist/canvas/rasterReadback.js +22 -0
  246. package/dist/canvas/rasterReadback.js.map +1 -0
  247. package/dist/canvas/renderDebugSnapshot.js +12 -12
  248. package/dist/canvas/renderDebugSnapshot.js.map +1 -1
  249. package/dist/canvas/renderNeeds.js +3 -3
  250. package/dist/canvas/renderNeeds.js.map +1 -1
  251. package/dist/canvas/renderSceneToPixels.js +64 -83
  252. package/dist/canvas/renderSceneToPixels.js.map +1 -1
  253. package/dist/canvas/sceneAdapter.js +59 -144
  254. package/dist/canvas/sceneAdapter.js.map +1 -1
  255. package/dist/canvas/sceneClipboard.js +1 -1
  256. package/dist/canvas/sceneClipboard.js.map +1 -1
  257. package/dist/canvas/sceneLayerPaint.js +4 -4
  258. package/dist/canvas/sceneLayerPaint.js.map +1 -1
  259. package/dist/canvas/sceneSlotWiring.js +10 -9
  260. package/dist/canvas/sceneSlotWiring.js.map +1 -1
  261. package/dist/canvas/sceneViewRender.js +37 -42
  262. package/dist/canvas/sceneViewRender.js.map +1 -1
  263. package/dist/canvas/slopsDebugLayer.js +4 -4
  264. package/dist/canvas/slopsDebugLayer.js.map +1 -1
  265. package/dist/canvas/useCanvasRenderer.js +23 -11
  266. package/dist/canvas/useCanvasRenderer.js.map +1 -1
  267. package/dist/canvas/useCanvasSurface.js +31 -0
  268. package/dist/canvas/useCanvasSurface.js.map +1 -0
  269. package/dist/canvas/useCanvasView.js +51 -44
  270. package/dist/canvas/useCanvasView.js.map +1 -1
  271. package/dist/canvas/useFrameLoop.js +11 -12
  272. package/dist/canvas/useFrameLoop.js.map +1 -1
  273. package/dist/canvas/useHostAnchor.js +35 -33
  274. package/dist/canvas/useHostAnchor.js.map +1 -1
  275. package/dist/canvas/useLateContentRedraw.js +8 -8
  276. package/dist/canvas/useLateContentRedraw.js.map +1 -1
  277. package/dist/canvas/useSceneAdapter.js +22 -0
  278. package/dist/canvas/useSceneAdapter.js.map +1 -0
  279. package/dist/canvas/useSceneLayerList.js +4 -14
  280. package/dist/canvas/useSceneLayerList.js.map +1 -1
  281. package/dist/canvas/useSurfaceInput.js +39 -0
  282. package/dist/canvas/useSurfaceInput.js.map +1 -0
  283. package/dist/canvas/useToolCursor.js +29 -0
  284. package/dist/canvas/useToolCursor.js.map +1 -0
  285. package/dist/canvas/useViewHelpers.js +46 -85
  286. package/dist/canvas/useViewHelpers.js.map +1 -1
  287. package/dist/canvas/viewInputs.js.map +1 -1
  288. package/dist/canvas/viewRegistry.js +40 -34
  289. package/dist/canvas/viewRegistry.js.map +1 -1
  290. package/dist/canvas/watchElementMove.js +43 -0
  291. package/dist/canvas/watchElementMove.js.map +1 -0
  292. package/dist/canvas/wrapNodeOutput.js +7 -2
  293. package/dist/canvas/wrapNodeOutput.js.map +1 -1
  294. package/dist/clipboard.d.ts +7 -14
  295. package/dist/{types-B4iJRHC3.d.ts → clone-C0eADtS0.d.ts} +129 -84
  296. package/dist/clone.d.ts +4 -8
  297. package/dist/clone.js +0 -2
  298. package/dist/core/device/targets.js.map +1 -1
  299. package/dist/core/device/useDeviceProfile.js +13 -13
  300. package/dist/core/device/useDeviceProfile.js.map +1 -1
  301. package/dist/{interactions/actions/resize → core/geometry}/autoPoseDescriptor.js +8 -7
  302. package/dist/core/geometry/autoPoseDescriptor.js.map +1 -0
  303. package/dist/core/geometry/pathPoseDescriptor.js +88 -0
  304. package/dist/core/geometry/pathPoseDescriptor.js.map +1 -0
  305. package/dist/core/geometry/poseDescriptor.js +102 -29
  306. package/dist/core/geometry/poseDescriptor.js.map +1 -1
  307. package/dist/core/geometry/regionHit.js +35 -37
  308. package/dist/core/geometry/regionHit.js.map +1 -1
  309. package/dist/core/geometry/targetFrame.js +94 -0
  310. package/dist/core/geometry/targetFrame.js.map +1 -0
  311. package/dist/core/geometry/unionBounds.js +4 -5
  312. package/dist/core/geometry/unionBounds.js.map +1 -1
  313. package/dist/core/layers/backgroundFill.js +31 -0
  314. package/dist/core/layers/backgroundFill.js.map +1 -0
  315. package/dist/{features/groups → core/layers}/children.js +2 -4
  316. package/dist/core/layers/children.js.map +1 -0
  317. package/dist/{features/focus → core/layers}/gateLayer.js +2 -2
  318. package/dist/core/layers/gateLayer.js.map +1 -0
  319. package/dist/core/layers/layerGroup.js +40 -0
  320. package/dist/core/layers/layerGroup.js.map +1 -0
  321. package/dist/core/layers/render.js +50 -76
  322. package/dist/core/layers/render.js.map +1 -1
  323. package/dist/core/ops/create.js +2 -2
  324. package/dist/core/ops/create.js.map +1 -1
  325. package/dist/core/ops/createHistory.js +9 -9
  326. package/dist/core/ops/createHistory.js.map +1 -1
  327. package/dist/core/ops/delete.js +19 -23
  328. package/dist/core/ops/delete.js.map +1 -1
  329. package/dist/core/ops/reorder/index.js +3 -7
  330. package/dist/core/ops/reorder/index.js.map +1 -1
  331. package/dist/core/ops/reorder/setChildOrder.js +2 -4
  332. package/dist/core/ops/reorder/setChildOrder.js.map +1 -1
  333. package/dist/core/ops/reparent.js +0 -1
  334. package/dist/core/ops/reparent.js.map +1 -1
  335. package/dist/core/ops/slot.js +3 -6
  336. package/dist/core/ops/slot.js.map +1 -1
  337. package/dist/core/pages/fitViewToPage.js +15 -0
  338. package/dist/core/pages/fitViewToPage.js.map +1 -0
  339. package/dist/core/pages/pages.js +65 -0
  340. package/dist/core/pages/pages.js.map +1 -0
  341. package/dist/core/pages/pagesLayer.js +27 -0
  342. package/dist/core/pages/pagesLayer.js.map +1 -0
  343. package/dist/core/paint/meshKind.js +16 -0
  344. package/dist/core/paint/meshKind.js.map +1 -0
  345. package/dist/{features/meshPaint/lazyKind.js → core/paint/meshKindLazy.js} +104 -93
  346. package/dist/core/paint/meshKindLazy.js.map +1 -0
  347. package/dist/core/paint/paintKindEntry.js +8 -0
  348. package/dist/core/paint/paintKindEntry.js.map +1 -0
  349. package/dist/core/paint/paintKinds.js +144 -0
  350. package/dist/core/paint/paintKinds.js.map +1 -0
  351. package/dist/core/paint/registerMesh.js +7 -0
  352. package/dist/core/paint/registerMesh.js.map +1 -0
  353. package/dist/core/scene/NodeProperties.js.map +1 -1
  354. package/dist/core/scene/NodeRouting.js.map +1 -1
  355. package/dist/core/scene/arrivalWindow.js +65 -64
  356. package/dist/core/scene/arrivalWindow.js.map +1 -1
  357. package/dist/core/scene/boundOps.js +40 -0
  358. package/dist/core/scene/boundOps.js.map +1 -0
  359. package/dist/core/scene/composeFrame.js +9 -6
  360. package/dist/core/scene/composeFrame.js.map +1 -1
  361. package/dist/core/scene/composePose.js +105 -0
  362. package/dist/core/scene/composePose.js.map +1 -0
  363. package/dist/core/scene/depMemo.js +31 -6
  364. package/dist/core/scene/depMemo.js.map +1 -1
  365. package/dist/core/scene/derivedPath.js +19 -20
  366. package/dist/core/scene/derivedPath.js.map +1 -1
  367. package/dist/core/scene/editMode.js +26 -0
  368. package/dist/core/scene/editMode.js.map +1 -0
  369. package/dist/core/scene/effectivePose.js +42 -39
  370. package/dist/core/scene/effectivePose.js.map +1 -1
  371. package/dist/core/scene/fieldEdits.js +98 -0
  372. package/dist/core/scene/fieldEdits.js.map +1 -0
  373. package/dist/core/scene/historyFacade.js +122 -70
  374. package/dist/core/scene/historyFacade.js.map +1 -1
  375. package/dist/core/scene/historyForm.js +6 -0
  376. package/dist/core/scene/historyForm.js.map +1 -0
  377. package/dist/core/scene/kitOps.js +83 -71
  378. package/dist/core/scene/kitOps.js.map +1 -1
  379. package/dist/core/scene/kitRegistry.js.map +1 -1
  380. package/dist/core/scene/layerStack.js +105 -12
  381. package/dist/core/scene/layerStack.js.map +1 -1
  382. package/dist/core/scene/layoutPass.js +58 -59
  383. package/dist/core/scene/layoutPass.js.map +1 -1
  384. package/dist/{features/groups → core/scene}/nestedHit.js +3 -3
  385. package/dist/core/scene/nestedHit.js.map +1 -0
  386. package/dist/core/scene/nodeFnFields.js +16 -9
  387. package/dist/core/scene/nodeFnFields.js.map +1 -1
  388. package/dist/core/scene/nodeMemo.js.map +1 -1
  389. package/dist/core/scene/nodeStore.js +72 -71
  390. package/dist/core/scene/nodeStore.js.map +1 -1
  391. package/dist/core/scene/notifier.js +37 -0
  392. package/dist/core/scene/notifier.js.map +1 -0
  393. package/dist/core/scene/opTable.js +50 -0
  394. package/dist/core/scene/opTable.js.map +1 -0
  395. package/dist/core/scene/outerOps.js +67 -0
  396. package/dist/core/scene/outerOps.js.map +1 -0
  397. package/dist/core/scene/poseHold.js +39 -0
  398. package/dist/core/scene/poseHold.js.map +1 -0
  399. package/dist/core/scene/poseOverrides.js +44 -36
  400. package/dist/core/scene/poseOverrides.js.map +1 -1
  401. package/dist/core/scene/poseSnapshot.js.map +1 -1
  402. package/dist/core/scene/reconcileSpecs.js +4 -3
  403. package/dist/core/scene/reconcileSpecs.js.map +1 -1
  404. package/dist/core/scene/recorder.js +86 -0
  405. package/dist/core/scene/recorder.js.map +1 -0
  406. package/dist/core/scene/renderOrder.js.map +1 -1
  407. package/dist/core/scene/scene.js +81 -690
  408. package/dist/core/scene/scene.js.map +1 -1
  409. package/dist/core/scene/sceneEdits.js +58 -0
  410. package/dist/core/scene/sceneEdits.js.map +1 -0
  411. package/dist/core/scene/sceneMutators.js +49 -0
  412. package/dist/core/scene/sceneMutators.js.map +1 -0
  413. package/dist/core/scene/scenePoseAdapter.js +16 -0
  414. package/dist/core/scene/scenePoseAdapter.js.map +1 -0
  415. package/dist/core/scene/sceneRecording.js +91 -0
  416. package/dist/core/scene/sceneRecording.js.map +1 -0
  417. package/dist/core/scene/sceneSelection.js +28 -0
  418. package/dist/core/scene/sceneSelection.js.map +1 -0
  419. package/dist/core/scene/sceneState.js +49 -0
  420. package/dist/core/scene/sceneState.js.map +1 -0
  421. package/dist/core/scene/serialization.js +8 -5
  422. package/dist/core/scene/serialization.js.map +1 -1
  423. package/dist/core/scene/staleReplay.js +51 -0
  424. package/dist/core/scene/staleReplay.js.map +1 -0
  425. package/dist/core/scene/statedFields.js +9 -0
  426. package/dist/core/scene/statedFields.js.map +1 -0
  427. package/dist/core/scene/treeEdits.js +127 -0
  428. package/dist/core/scene/treeEdits.js.map +1 -0
  429. package/dist/core/scene/treeReads.js +26 -0
  430. package/dist/core/scene/treeReads.js.map +1 -0
  431. package/dist/core/scene/types.js.map +1 -1
  432. package/dist/{features/groups → core/scene}/unionOfChildren.js +3 -3
  433. package/dist/core/scene/unionOfChildren.js.map +1 -0
  434. package/dist/core/scene/unitScopes.js +13 -0
  435. package/dist/core/scene/unitScopes.js.map +1 -0
  436. package/dist/core/scene/useScene.js.map +1 -1
  437. package/dist/core/selection/readOnlySelection.js +32 -0
  438. package/dist/core/selection/readOnlySelection.js.map +1 -0
  439. package/dist/core/selection/usePublishSceneSelection.js +26 -0
  440. package/dist/core/selection/usePublishSceneSelection.js.map +1 -0
  441. package/dist/core/selection/useSelection.js +34 -25
  442. package/dist/core/selection/useSelection.js.map +1 -1
  443. package/dist/core/shapeKinds.js.map +1 -1
  444. package/dist/core/stylus/stylus.js.map +1 -1
  445. package/dist/core/stylus/usePointerStylus.js.map +1 -1
  446. package/dist/core/usePaintKinds.js +1 -1
  447. package/dist/core/usePaintKinds.js.map +1 -1
  448. package/dist/core/viewport/clientToWorld.js.map +1 -1
  449. package/dist/core/viewport/fitViewToBounds.js.map +1 -1
  450. package/dist/core/viewport/parallax.js.map +1 -1
  451. package/dist/core/viewport/screenSlop.js +11 -11
  452. package/dist/core/viewport/screenSlop.js.map +1 -1
  453. package/dist/core/viewport/useCanvasSize.js.map +1 -1
  454. package/dist/core/viewport/useDecayLoop.js +31 -33
  455. package/dist/core/viewport/useDecayLoop.js.map +1 -1
  456. package/dist/core/viewport/useNodeOverlayFrame.js +84 -0
  457. package/dist/core/viewport/useNodeOverlayFrame.js.map +1 -0
  458. package/dist/core/viewport/useViewAnimation.js +113 -53
  459. package/dist/core/viewport/useViewAnimation.js.map +1 -1
  460. package/dist/core/viewport/view.js +14 -11
  461. package/dist/core/viewport/view.js.map +1 -1
  462. package/dist/core/viewport/wheelHandler.js.map +1 -1
  463. package/dist/core/viewport/zoomAt.js +11 -2
  464. package/dist/core/viewport/zoomAt.js.map +1 -1
  465. package/dist/{cornerHandles-CtCb8a3G.d.ts → cornerHandles-BSKbyuvQ.d.ts} +11 -24
  466. package/dist/debug/createDebugOverlayLayer.js +100 -100
  467. package/dist/debug/createDebugOverlayLayer.js.map +1 -1
  468. package/dist/debug/createDebugSink.js.map +1 -1
  469. package/dist/debug/frameStats.js.map +1 -1
  470. package/dist/debug/useDebugSink.js +52 -0
  471. package/dist/debug/useDebugSink.js.map +1 -0
  472. package/dist/features/chrome-caps/buildChromeCtx.js.map +1 -1
  473. package/dist/features/chrome-caps/conditions.js.map +1 -1
  474. package/dist/features/chrome-caps/defaults.js.map +1 -1
  475. package/dist/features/chrome-caps/resolve.js.map +1 -1
  476. package/dist/features/chrome-caps/useChromeCaps.js +54 -0
  477. package/dist/features/chrome-caps/useChromeCaps.js.map +1 -0
  478. package/dist/features/chrome-caps/useHoverTracking.js.map +1 -1
  479. package/dist/features/ingestion/contentHandlers.js +25 -19
  480. package/dist/features/ingestion/contentHandlers.js.map +1 -1
  481. package/dist/features/ingestion/imageHandler.js +21 -24
  482. package/dist/features/ingestion/imageHandler.js.map +1 -1
  483. package/dist/features/ingestion/openFilePicker.js.map +1 -1
  484. package/dist/features/ingestion/placement.js +16 -0
  485. package/dist/features/ingestion/placement.js.map +1 -0
  486. package/dist/features/ingestion/svgHandler.js +5 -0
  487. package/dist/features/ingestion/svgHandler.js.map +1 -1
  488. package/dist/features/ingestion/textHandler.js +28 -0
  489. package/dist/features/ingestion/textHandler.js.map +1 -0
  490. package/dist/features/ingestion/useCanvasIngestion.js +48 -0
  491. package/dist/features/ingestion/useCanvasIngestion.js.map +1 -0
  492. package/dist/features/ingestion/weaselJsonHandler.js +5 -0
  493. package/dist/features/ingestion/weaselJsonHandler.js.map +1 -1
  494. package/dist/features/longPress/longPressFeedback.js.map +1 -1
  495. package/dist/features/modes/modeLayers.js +7 -7
  496. package/dist/features/modes/modeLayers.js.map +1 -1
  497. package/dist/features/paths/editablePath.js +63 -0
  498. package/dist/features/paths/editablePath.js.map +1 -0
  499. package/dist/features/paths/index.js +9 -16
  500. package/dist/features/paths/pathEditState.js +41 -0
  501. package/dist/features/paths/pathEditState.js.map +1 -0
  502. package/dist/features/paths/pathEditingOverlayLayer.js +36 -38
  503. package/dist/features/paths/pathEditingOverlayLayer.js.map +1 -1
  504. package/dist/features/paths/pathLayer.js +3 -2
  505. package/dist/features/paths/pathLayer.js.map +1 -1
  506. package/dist/features/paths/penPreviewLayer.js +86 -88
  507. package/dist/features/paths/penPreviewLayer.js.map +1 -1
  508. package/dist/features/paths/shapeGenerator.js +89 -0
  509. package/dist/features/paths/shapeGenerator.js.map +1 -0
  510. package/dist/features/paths/usePathEdit.js +34 -0
  511. package/dist/features/paths/usePathEdit.js.map +1 -0
  512. package/dist/features/poseRun/usePoseRun.js +44 -57
  513. package/dist/features/poseRun/usePoseRun.js.map +1 -1
  514. package/dist/features/selection/overlay.js +170 -178
  515. package/dist/features/selection/overlay.js.map +1 -1
  516. package/dist/features/text/index.js +6 -0
  517. package/dist/features/text/textLayer.js +1 -1
  518. package/dist/features/text/textLayer.js.map +1 -1
  519. package/dist/features/text/useSceneTextEdit.js +119 -88
  520. package/dist/features/text/useSceneTextEdit.js.map +1 -1
  521. package/dist/features/viewports/viewResolver.js +28 -24
  522. package/dist/features/viewports/viewResolver.js.map +1 -1
  523. package/dist/features/viewports/viewportLayer.js +25 -36
  524. package/dist/features/viewports/viewportLayer.js.map +1 -1
  525. package/dist/icons/SliceIcon.js +24 -0
  526. package/dist/icons/SliceIcon.js.map +1 -0
  527. package/dist/index.d.ts +5200 -8777
  528. package/dist/index.js +284 -320
  529. package/dist/input/keyState.js +14 -14
  530. package/dist/interactions/actions/actionShortcuts.js.map +1 -1
  531. package/dist/interactions/actions/{defaults/align.js → align/action.js} +15 -16
  532. package/dist/interactions/actions/align/action.js.map +1 -0
  533. package/dist/interactions/actions/align/align.js +24 -24
  534. package/dist/interactions/actions/align/align.js.map +1 -1
  535. package/dist/interactions/actions/booleans/action.js +65 -0
  536. package/dist/interactions/actions/booleans/action.js.map +1 -0
  537. package/dist/interactions/actions/booleans/booleans.js +74 -83
  538. package/dist/interactions/actions/booleans/booleans.js.map +1 -1
  539. package/dist/interactions/actions/booleans/operands.js +40 -0
  540. package/dist/interactions/actions/booleans/operands.js.map +1 -0
  541. package/dist/interactions/actions/booleans/pieces.js +45 -0
  542. package/dist/interactions/actions/booleans/pieces.js.map +1 -0
  543. package/dist/interactions/actions/booleans/placement.js +24 -0
  544. package/dist/interactions/actions/booleans/placement.js.map +1 -0
  545. package/dist/interactions/actions/booleans/useBooleans.js +11 -9
  546. package/dist/interactions/actions/booleans/useBooleans.js.map +1 -1
  547. package/dist/interactions/actions/booleans/useBooleansAdapter.js.map +1 -1
  548. package/dist/interactions/actions/{defaults/clipboard.js → clipboard/action.js} +19 -19
  549. package/dist/interactions/actions/clipboard/action.js.map +1 -0
  550. package/dist/interactions/actions/clipboard/clipboardOps.js +15 -15
  551. package/dist/interactions/actions/clipboard/clipboardOps.js.map +1 -1
  552. package/dist/interactions/actions/clipboard/wireFormat.js.map +1 -1
  553. package/dist/interactions/actions/clone/action.js +103 -0
  554. package/dist/interactions/actions/clone/action.js.map +1 -0
  555. package/dist/interactions/actions/clone/behaviors.js +52 -0
  556. package/dist/interactions/actions/clone/behaviors.js.map +1 -0
  557. package/dist/interactions/actions/defaultCommitAdapter.js +10 -37
  558. package/dist/interactions/actions/defaultCommitAdapter.js.map +1 -1
  559. package/dist/interactions/actions/defaults/anchorEditing.js +69 -74
  560. package/dist/interactions/actions/defaults/anchorEditing.js.map +1 -1
  561. package/dist/interactions/actions/defaults/anchorHandles.js +42 -0
  562. package/dist/interactions/actions/defaults/anchorHandles.js.map +1 -0
  563. package/dist/interactions/actions/defaults/anchorJoin.js +92 -0
  564. package/dist/interactions/actions/defaults/anchorJoin.js.map +1 -0
  565. package/dist/interactions/actions/defaults/areaSelect.js.map +1 -1
  566. package/dist/interactions/actions/defaults/bendSegment.js +46 -0
  567. package/dist/interactions/actions/defaults/bendSegment.js.map +1 -0
  568. package/dist/interactions/actions/defaults/cancelGesture.js.map +1 -1
  569. package/dist/interactions/actions/defaults/clearSelection.js.map +1 -1
  570. package/dist/interactions/actions/defaults/copySubtree.js +1 -1
  571. package/dist/interactions/actions/defaults/copySubtree.js.map +1 -1
  572. package/dist/interactions/actions/defaults/createPaintAction.js.map +1 -1
  573. package/dist/interactions/actions/defaults/delete.js.map +1 -1
  574. package/dist/interactions/actions/defaults/duplicate.js +36 -21
  575. package/dist/interactions/actions/defaults/duplicate.js.map +1 -1
  576. package/dist/interactions/actions/defaults/enterPathEdit.js +19 -7
  577. package/dist/interactions/actions/defaults/enterPathEdit.js.map +1 -1
  578. package/dist/interactions/actions/defaults/enterTextEdit.js.map +1 -1
  579. package/dist/interactions/actions/defaults/group.js +35 -40
  580. package/dist/interactions/actions/defaults/group.js.map +1 -1
  581. package/dist/interactions/actions/defaults/icons/anchorIcons.js +75 -0
  582. package/dist/interactions/actions/defaults/icons/anchorIcons.js.map +1 -0
  583. package/dist/interactions/actions/defaults/icons/booleanIcons.js +24 -1
  584. package/dist/interactions/actions/defaults/icons/booleanIcons.js.map +1 -1
  585. package/dist/interactions/actions/defaults/icons/editIcons.js +35 -8
  586. package/dist/interactions/actions/defaults/icons/editIcons.js.map +1 -1
  587. package/dist/interactions/actions/defaults/icons/outlineIcons.js +39 -1
  588. package/dist/interactions/actions/defaults/icons/outlineIcons.js.map +1 -1
  589. package/dist/interactions/actions/defaults/ingest.js +19 -15
  590. package/dist/interactions/actions/defaults/ingest.js.map +1 -1
  591. package/dist/interactions/actions/defaults/insertPathAnchor.js +18 -34
  592. package/dist/interactions/actions/defaults/insertPathAnchor.js.map +1 -1
  593. package/dist/interactions/actions/defaults/nudge.js +43 -39
  594. package/dist/interactions/actions/defaults/nudge.js.map +1 -1
  595. package/dist/interactions/actions/defaults/pinchZoom.js +29 -29
  596. package/dist/interactions/actions/defaults/pinchZoom.js.map +1 -1
  597. package/dist/interactions/actions/defaults/requiresSelection.js.map +1 -1
  598. package/dist/interactions/actions/defaults/segmentUnder.js +22 -0
  599. package/dist/interactions/actions/defaults/segmentUnder.js.map +1 -0
  600. package/dist/interactions/actions/defaults/setFill.js +9 -3
  601. package/dist/interactions/actions/defaults/setFill.js.map +1 -1
  602. package/dist/interactions/actions/defaults/setFillOpacity.js +4 -1
  603. package/dist/interactions/actions/defaults/setFillOpacity.js.map +1 -1
  604. package/dist/interactions/actions/defaults/setStroke.js.map +1 -1
  605. package/dist/interactions/actions/defaults/sliceOps.js +20 -22
  606. package/dist/interactions/actions/defaults/sliceOps.js.map +1 -1
  607. package/dist/interactions/actions/defaults/toolActivate.js.map +1 -1
  608. package/dist/interactions/actions/defaults/toolResetToDefault.js.map +1 -1
  609. package/dist/interactions/actions/defaults/viewportDragPan.js +1 -1
  610. package/dist/interactions/actions/defaults/viewportDragPan.js.map +1 -1
  611. package/dist/interactions/actions/defaults/viewportWheelPan.js.map +1 -1
  612. package/dist/interactions/actions/defaults/viewportZoom.js +82 -79
  613. package/dist/interactions/actions/defaults/viewportZoom.js.map +1 -1
  614. package/dist/interactions/actions/{defaults/distribute.js → distribute/action.js} +18 -19
  615. package/dist/interactions/actions/distribute/action.js.map +1 -0
  616. package/dist/interactions/actions/distribute/distribute.js +15 -15
  617. package/dist/interactions/actions/distribute/distribute.js.map +1 -1
  618. package/dist/interactions/actions/edit-anchors/action.js +101 -0
  619. package/dist/interactions/actions/edit-anchors/action.js.map +1 -0
  620. package/dist/interactions/actions/edit-anchors/geometry.js +2 -4
  621. package/dist/interactions/actions/edit-anchors/geometry.js.map +1 -1
  622. package/dist/interactions/actions/edit-anchors/preview.js +26 -0
  623. package/dist/interactions/actions/edit-anchors/preview.js.map +1 -0
  624. package/dist/interactions/actions/edit-anchors/symmetry.js +11 -0
  625. package/dist/interactions/actions/edit-anchors/symmetry.js.map +1 -0
  626. package/dist/interactions/actions/flip/action.js +124 -0
  627. package/dist/interactions/actions/flip/action.js.map +1 -0
  628. package/dist/interactions/actions/flip/helpers.js +1 -1
  629. package/dist/interactions/actions/flip/helpers.js.map +1 -1
  630. package/dist/interactions/actions/geometryProjection.js.map +1 -1
  631. package/dist/interactions/actions/gestureFrames.js +18 -0
  632. package/dist/interactions/actions/gestureFrames.js.map +1 -0
  633. package/dist/interactions/actions/gestureLifecycle.js +47 -20
  634. package/dist/interactions/actions/gestureLifecycle.js.map +1 -1
  635. package/dist/interactions/actions/insert/action.js +79 -0
  636. package/dist/interactions/actions/insert/action.js.map +1 -0
  637. package/dist/interactions/actions/insert/commit.js +28 -0
  638. package/dist/interactions/actions/insert/commit.js.map +1 -0
  639. package/dist/interactions/actions/insert/extras.js +65 -0
  640. package/dist/interactions/actions/insert/extras.js.map +1 -0
  641. package/dist/interactions/actions/insert/frame.js +55 -0
  642. package/dist/interactions/actions/insert/frame.js.map +1 -0
  643. package/dist/interactions/actions/insert/geometry.js +35 -0
  644. package/dist/interactions/actions/insert/geometry.js.map +1 -0
  645. package/dist/interactions/actions/insert/repositionAction.js +31 -0
  646. package/dist/interactions/actions/insert/repositionAction.js.map +1 -0
  647. package/dist/interactions/actions/insert/rotateAction.js +21 -0
  648. package/dist/interactions/actions/insert/rotateAction.js.map +1 -0
  649. package/dist/interactions/actions/insert/session.js +59 -0
  650. package/dist/interactions/actions/insert/session.js.map +1 -0
  651. package/dist/interactions/actions/insert/shape.js +34 -0
  652. package/dist/interactions/actions/insert/shape.js.map +1 -0
  653. package/dist/interactions/actions/lasso-select/action.js +143 -0
  654. package/dist/interactions/actions/lasso-select/action.js.map +1 -0
  655. package/dist/interactions/actions/move/action.js +91 -0
  656. package/dist/interactions/actions/move/action.js.map +1 -0
  657. package/dist/interactions/actions/move/behaviors/layoutDrop.js +51 -0
  658. package/dist/interactions/actions/move/behaviors/layoutDrop.js.map +1 -0
  659. package/dist/interactions/actions/move/behaviors/reparentOnDrop.js +15 -0
  660. package/dist/interactions/actions/move/behaviors/reparentOnDrop.js.map +1 -0
  661. package/dist/interactions/actions/move/behaviors/snapToContainer.js +35 -28
  662. package/dist/interactions/actions/move/behaviors/snapToContainer.js.map +1 -1
  663. package/dist/interactions/actions/move/capture.js +108 -0
  664. package/dist/interactions/actions/move/capture.js.map +1 -0
  665. package/dist/interactions/actions/move/commit/index.js +41 -0
  666. package/dist/interactions/actions/move/commit/index.js.map +1 -0
  667. package/dist/interactions/actions/move/commit/layoutDrop.js +44 -0
  668. package/dist/interactions/actions/move/commit/layoutDrop.js.map +1 -0
  669. package/dist/interactions/actions/move/commit/layoutRelease.js +100 -0
  670. package/dist/interactions/actions/move/commit/layoutRelease.js.map +1 -0
  671. package/dist/interactions/actions/move/commit/rebase.js +18 -0
  672. package/dist/interactions/actions/move/commit/rebase.js.map +1 -0
  673. package/dist/interactions/actions/move/commit/reparent.js +65 -0
  674. package/dist/interactions/actions/move/commit/reparent.js.map +1 -0
  675. package/dist/interactions/actions/move/delta.js +51 -0
  676. package/dist/interactions/actions/move/delta.js.map +1 -0
  677. package/dist/interactions/actions/move/frame.js +47 -0
  678. package/dist/interactions/actions/move/frame.js.map +1 -0
  679. package/dist/interactions/actions/move/gestureAdapter.js +15 -40
  680. package/dist/interactions/actions/move/gestureAdapter.js.map +1 -1
  681. package/dist/interactions/actions/move/landedDescendants.js +8 -8
  682. package/dist/interactions/actions/move/layout/container.js +94 -0
  683. package/dist/interactions/actions/move/layout/container.js.map +1 -0
  684. package/dist/interactions/actions/move/layout/dragged.js +58 -0
  685. package/dist/interactions/actions/move/layout/dragged.js.map +1 -0
  686. package/dist/interactions/actions/move/layout/dropPass.js +122 -0
  687. package/dist/interactions/actions/move/layout/dropPass.js.map +1 -0
  688. package/dist/interactions/actions/move/layout/exits.js +38 -0
  689. package/dist/interactions/actions/move/layout/exits.js.map +1 -0
  690. package/dist/interactions/actions/move/layout/glide.js +48 -0
  691. package/dist/interactions/actions/move/layout/glide.js.map +1 -0
  692. package/dist/interactions/actions/move/session.js +63 -0
  693. package/dist/interactions/actions/move/session.js.map +1 -0
  694. package/dist/interactions/actions/move/translate.js +61 -0
  695. package/dist/interactions/actions/move/translate.js.map +1 -0
  696. package/dist/interactions/actions/outlines/createOutlines.js +17 -64
  697. package/dist/interactions/actions/outlines/createOutlines.js.map +1 -1
  698. package/dist/interactions/actions/outlines/createOutlinesAction.js +51 -0
  699. package/dist/interactions/actions/outlines/createOutlinesAction.js.map +1 -0
  700. package/dist/interactions/actions/outlines/outlineStroke.js +72 -0
  701. package/dist/interactions/actions/outlines/outlineStroke.js.map +1 -0
  702. package/dist/interactions/actions/outlines/outlineStrokeAction.js +37 -0
  703. package/dist/interactions/actions/outlines/outlineStrokeAction.js.map +1 -0
  704. package/dist/interactions/actions/outlines/replaceWithPaths.js +54 -0
  705. package/dist/interactions/actions/outlines/replaceWithPaths.js.map +1 -0
  706. package/dist/interactions/actions/outlines/strokeRegion.js +27 -0
  707. package/dist/interactions/actions/outlines/strokeRegion.js.map +1 -0
  708. package/dist/interactions/actions/pathCommands/cutJoin.js +102 -0
  709. package/dist/interactions/actions/pathCommands/cutJoin.js.map +1 -0
  710. package/dist/interactions/actions/pathCommands/livePathEdit.js +64 -0
  711. package/dist/interactions/actions/pathCommands/livePathEdit.js.map +1 -0
  712. package/dist/interactions/actions/pathCommands/pathNodes.js +99 -0
  713. package/dist/interactions/actions/pathCommands/pathNodes.js.map +1 -0
  714. package/dist/interactions/actions/pathCommands/simplifyOffset.js +42 -0
  715. package/dist/interactions/actions/pathCommands/simplifyOffset.js.map +1 -0
  716. package/dist/interactions/actions/planeInput.js.map +1 -1
  717. package/dist/interactions/actions/pointerState.js +12 -0
  718. package/dist/interactions/actions/pointerState.js.map +1 -0
  719. package/dist/interactions/actions/poseDescriptorDep.js +1 -1
  720. package/dist/interactions/actions/poseDescriptorDep.js.map +1 -1
  721. package/dist/interactions/actions/poseFrame.js +26 -26
  722. package/dist/interactions/actions/poseFrame.js.map +1 -1
  723. package/dist/interactions/actions/resize/action.js +66 -0
  724. package/dist/interactions/actions/resize/action.js.map +1 -0
  725. package/dist/interactions/actions/resize/behaviors/lockAspect.js.map +1 -1
  726. package/dist/interactions/actions/resize/boxFrame.js +16 -0
  727. package/dist/interactions/actions/resize/boxFrame.js.map +1 -0
  728. package/dist/interactions/actions/resize/capture.js +85 -0
  729. package/dist/interactions/actions/resize/capture.js.map +1 -0
  730. package/dist/interactions/actions/resize/commit.js +69 -0
  731. package/dist/interactions/actions/resize/commit.js.map +1 -0
  732. package/dist/interactions/actions/resize/frame.js +88 -0
  733. package/dist/interactions/actions/resize/frame.js.map +1 -0
  734. package/dist/interactions/actions/resize/pointSnap.js +111 -0
  735. package/dist/interactions/actions/resize/pointSnap.js.map +1 -0
  736. package/dist/interactions/actions/resize/replay.js +47 -0
  737. package/dist/interactions/actions/resize/replay.js.map +1 -0
  738. package/dist/interactions/actions/resize/ruleBounds.js +9 -0
  739. package/dist/interactions/actions/resize/ruleBounds.js.map +1 -0
  740. package/dist/interactions/actions/resize/session.js +63 -0
  741. package/dist/interactions/actions/resize/session.js.map +1 -0
  742. package/dist/interactions/actions/resolveOverlays.js +2 -1
  743. package/dist/interactions/actions/resolveOverlays.js.map +1 -1
  744. package/dist/interactions/actions/resolvePreviews.js.map +1 -1
  745. package/dist/interactions/actions/rotate/action.js +71 -0
  746. package/dist/interactions/actions/rotate/action.js.map +1 -0
  747. package/dist/interactions/actions/rotate/behaviors/index.js +7 -0
  748. package/dist/interactions/actions/rotate/behaviors/index.js.map +1 -0
  749. package/dist/interactions/actions/rotate/behaviors/snapRotation.js +12 -0
  750. package/dist/interactions/actions/rotate/behaviors/snapRotation.js.map +1 -0
  751. package/dist/interactions/actions/rotate/commit.js +40 -0
  752. package/dist/interactions/actions/rotate/commit.js.map +1 -0
  753. package/dist/interactions/actions/rotate/frame.js +65 -0
  754. package/dist/interactions/actions/rotate/frame.js.map +1 -0
  755. package/dist/interactions/actions/rotate/handle.js +12 -12
  756. package/dist/interactions/actions/rotate/handle.js.map +1 -1
  757. package/dist/interactions/actions/rotate/replay.js +22 -0
  758. package/dist/interactions/actions/rotate/replay.js.map +1 -0
  759. package/dist/interactions/actions/rotate/session.js +102 -0
  760. package/dist/interactions/actions/rotate/session.js.map +1 -0
  761. package/dist/interactions/actions/spatialReference.js.map +1 -1
  762. package/dist/interactions/actions/transform-again/action.js +63 -0
  763. package/dist/interactions/actions/transform-again/action.js.map +1 -0
  764. package/dist/interactions/actions/transform-again/memory.js +35 -0
  765. package/dist/interactions/actions/transform-again/memory.js.map +1 -0
  766. package/dist/interactions/actions/useStandardActions.js +84 -61
  767. package/dist/interactions/actions/useStandardActions.js.map +1 -1
  768. package/dist/interactions/gestures/pointerDrag/pointerDrag.js +61 -42
  769. package/dist/interactions/gestures/pointerDrag/pointerDrag.js.map +1 -1
  770. package/dist/interactions/gestures/shared/originProjection.js +1 -1
  771. package/dist/interactions/gestures/shared/originProjection.js.map +1 -1
  772. package/dist/interactions/gestures/shared/screenTolerance.js +8 -2
  773. package/dist/interactions/gestures/shared/screenTolerance.js.map +1 -1
  774. package/dist/interactions/gestures/shared/snap.js.map +1 -1
  775. package/dist/math-CYUjoyyU.d.ts +33 -0
  776. package/dist/math.d.ts +5 -2
  777. package/dist/math.js +6 -6
  778. package/dist/mesh.d.ts +4 -268
  779. package/dist/mesh.js +3 -7
  780. package/dist/move.d.ts +6 -4
  781. package/dist/{originProjection-gHnOup4e.d.ts → originProjection-CoNVpITV.d.ts} +1 -1
  782. package/dist/patterns-builtin.d.ts +1 -118
  783. package/dist/patterns-builtin.js +2 -3
  784. package/dist/poseDescriptor-Bqk-11Rl.d.ts +73 -0
  785. package/dist/renderer.d.ts +1 -92
  786. package/dist/renderer.js +2 -19
  787. package/dist/resize.d.ts +11 -22
  788. package/dist/resize.js +1 -1
  789. package/dist/style.css +1 -1
  790. package/dist/test-hook/install.js.map +1 -1
  791. package/dist/test-hook/useTestHook.js +22 -0
  792. package/dist/test-hook/useTestHook.js.map +1 -0
  793. package/dist/test-seams-D0pyV3pR.d.ts +149 -0
  794. package/dist/test-seams.d.ts +4 -4
  795. package/dist/test-seams.js +2 -2
  796. package/dist/tools/builtin/bone/boneActions.js +130 -0
  797. package/dist/tools/builtin/bone/boneActions.js.map +1 -0
  798. package/dist/tools/builtin/bone/boneOverlay.js +58 -0
  799. package/dist/tools/builtin/bone/boneOverlay.js.map +1 -0
  800. package/dist/tools/builtin/bone/placedRig.js +24 -0
  801. package/dist/tools/builtin/bone/placedRig.js.map +1 -0
  802. package/dist/tools/builtin/bone/rigEditState.js +21 -0
  803. package/dist/tools/builtin/bone/rigEditState.js.map +1 -0
  804. package/dist/tools/builtin/bone/useBoneTool.js +98 -0
  805. package/dist/tools/builtin/bone/useBoneTool.js.map +1 -0
  806. package/dist/tools/builtin/ellipse/useEllipseTool.js +16 -15
  807. package/dist/tools/builtin/ellipse/useEllipseTool.js.map +1 -1
  808. package/dist/tools/builtin/eyedropper/useEyedropperTool.js.map +1 -1
  809. package/dist/tools/builtin/hand/useHandTool.js.map +1 -1
  810. package/dist/tools/builtin/image/useImageTool.js.map +1 -1
  811. package/dist/tools/builtin/lasso/useLassoTool.js.map +1 -1
  812. package/dist/tools/builtin/line/useLineTool.js +16 -15
  813. package/dist/tools/builtin/line/useLineTool.js.map +1 -1
  814. package/dist/tools/builtin/pen/usePenTool.js +162 -164
  815. package/dist/tools/builtin/pen/usePenTool.js.map +1 -1
  816. package/dist/tools/builtin/pencil/usePencilTool.js.map +1 -1
  817. package/dist/tools/builtin/pickTopMostHit.js +11 -14
  818. package/dist/tools/builtin/pickTopMostHit.js.map +1 -1
  819. package/dist/tools/builtin/polygon/usePolygonTool.js +17 -15
  820. package/dist/tools/builtin/polygon/usePolygonTool.js.map +1 -1
  821. package/dist/tools/builtin/rect/useRectTool.js +15 -14
  822. package/dist/tools/builtin/rect/useRectTool.js.map +1 -1
  823. package/dist/tools/builtin/select/adapterPointQuery.js +40 -0
  824. package/dist/tools/builtin/select/adapterPointQuery.js.map +1 -0
  825. package/dist/tools/builtin/select/selectionContributions.js +5 -5
  826. package/dist/tools/builtin/select/selectionContributions.js.map +1 -1
  827. package/dist/tools/builtin/select/useSelectTool.js +44 -71
  828. package/dist/tools/builtin/select/useSelectTool.js.map +1 -1
  829. package/dist/tools/builtin/shared/pointerFollower.js.map +1 -1
  830. package/dist/tools/builtin/slice/useSliceTool.js +69 -72
  831. package/dist/tools/builtin/slice/useSliceTool.js.map +1 -1
  832. package/dist/tools/builtin/star/useStarTool.js +18 -16
  833. package/dist/tools/builtin/star/useStarTool.js.map +1 -1
  834. package/dist/tools/builtin/text/useTextTool.js +10 -2
  835. package/dist/tools/builtin/text/useTextTool.js.map +1 -1
  836. package/dist/tools/builtin/weight/useWeightTool.js +77 -0
  837. package/dist/tools/builtin/weight/useWeightTool.js.map +1 -0
  838. package/dist/tools/builtin/weight/weightActions.js +112 -0
  839. package/dist/tools/builtin/weight/weightActions.js.map +1 -0
  840. package/dist/tools/builtin/weight/weightOverlay.js +61 -0
  841. package/dist/tools/builtin/weight/weightOverlay.js.map +1 -0
  842. package/dist/tools/overlayBinding.js.map +1 -1
  843. package/dist/tools/useKeybindings.js +20 -14
  844. package/dist/tools/useKeybindings.js.map +1 -1
  845. package/dist/{types-k-5Oqh-U.d.ts → types-DBbbCy0i.d.ts} +103 -176
  846. package/dist/util/paint.js +1 -1
  847. package/dist/util/paint.js.map +1 -1
  848. package/dist/version.js +1 -1
  849. package/package.json +26 -21
  850. package/dist/animation/colorHelpers.js +0 -135
  851. package/dist/animation/colorHelpers.js.map +0 -1
  852. package/dist/animation/colorRegistry.js +0 -37
  853. package/dist/animation/colorRegistry.js.map +0 -1
  854. package/dist/animation/engine/axes.js +0 -36
  855. package/dist/animation/engine/axes.js.map +0 -1
  856. package/dist/animation/engine/codec.js +0 -170
  857. package/dist/animation/engine/codec.js.map +0 -1
  858. package/dist/animation/engine/integrator.js +0 -12
  859. package/dist/animation/engine/integrator.js.map +0 -1
  860. package/dist/animation/loop.js +0 -60
  861. package/dist/animation/loop.js.map +0 -1
  862. package/dist/animation/observe.js +0 -23
  863. package/dist/animation/observe.js.map +0 -1
  864. package/dist/animation/rig/blendPoses.js +0 -43
  865. package/dist/animation/rig/blendPoses.js.map +0 -1
  866. package/dist/animation/rig/mirrorPose.js +0 -19
  867. package/dist/animation/rig/mirrorPose.js.map +0 -1
  868. package/dist/animation/rig/resolveSkeleton.js +0 -33
  869. package/dist/animation/rig/resolveSkeleton.js.map +0 -1
  870. package/dist/animation/rig/solveIk.js +0 -103
  871. package/dist/animation/rig/solveIk.js.map +0 -1
  872. package/dist/animation/rig/types.js +0 -12
  873. package/dist/animation/rig/types.js.map +0 -1
  874. package/dist/animation/slew.js +0 -27
  875. package/dist/animation/slew.js.map +0 -1
  876. package/dist/animation/stagger.js +0 -146
  877. package/dist/animation/stagger.js.map +0 -1
  878. package/dist/animation/timeline/booking.js +0 -114
  879. package/dist/animation/timeline/booking.js.map +0 -1
  880. package/dist/animation/timeline/createTimeline.js +0 -125
  881. package/dist/animation/timeline/createTimeline.js.map +0 -1
  882. package/dist/animation/timeline/sampleTrack.js +0 -79
  883. package/dist/animation/timeline/sampleTrack.js.map +0 -1
  884. package/dist/animation/useAnimator.js +0 -388
  885. package/dist/animation/useAnimator.js.map +0 -1
  886. package/dist/autoPoseDescriptor-Ct7yqivU.d.ts +0 -108
  887. package/dist/builtins-DPcdghtB.d.ts +0 -1223
  888. package/dist/canvas/MinimapCanvas.js +0 -140
  889. package/dist/canvas/MinimapCanvas.js.map +0 -1
  890. package/dist/canvas/deps/poseComposition.js +0 -11
  891. package/dist/canvas/deps/poseComposition.js.map +0 -1
  892. package/dist/canvas/minimapMath.js +0 -82
  893. package/dist/canvas/minimapMath.js.map +0 -1
  894. package/dist/canvas/toolPreview.js +0 -39
  895. package/dist/canvas/toolPreview.js.map +0 -1
  896. package/dist/core/adapters/arrayAdapter.js +0 -94
  897. package/dist/core/adapters/arrayAdapter.js.map +0 -1
  898. package/dist/core/adapters/useArrayAdapter.js +0 -13
  899. package/dist/core/adapters/useArrayAdapter.js.map +0 -1
  900. package/dist/core/fillInPoseFrame.js +0 -102
  901. package/dist/core/fillInPoseFrame.js.map +0 -1
  902. package/dist/core/geometry/poseFrame.js +0 -44
  903. package/dist/core/geometry/poseFrame.js.map +0 -1
  904. package/dist/core/geometry/poseRotation.js +0 -58
  905. package/dist/core/geometry/poseRotation.js.map +0 -1
  906. package/dist/core/gradient.js +0 -136
  907. package/dist/core/gradient.js.map +0 -1
  908. package/dist/core/markerInset.js +0 -24
  909. package/dist/core/markerInset.js.map +0 -1
  910. package/dist/core/mixed.js +0 -6
  911. package/dist/core/mixed.js.map +0 -1
  912. package/dist/core/paintKinds.js +0 -156
  913. package/dist/core/paintKinds.js.map +0 -1
  914. package/dist/core/scene/pickability.js +0 -6
  915. package/dist/core/scene/pickability.js.map +0 -1
  916. package/dist/core/strokeMarkerShapes.js +0 -139
  917. package/dist/core/strokeMarkerShapes.js.map +0 -1
  918. package/dist/core/strokeMarkers.js +0 -28
  919. package/dist/core/strokeMarkers.js.map +0 -1
  920. package/dist/core/viewport/meanScale.js +0 -8
  921. package/dist/core/viewport/meanScale.js.map +0 -1
  922. package/dist/core/viewport/pxExtent.js +0 -42
  923. package/dist/core/viewport/pxExtent.js.map +0 -1
  924. package/dist/features/cursor/paintedCursorLayer.js.map +0 -1
  925. package/dist/features/focus/gateLayer.js.map +0 -1
  926. package/dist/features/focus/useCanvasFocus.js +0 -29
  927. package/dist/features/focus/useCanvasFocus.js.map +0 -1
  928. package/dist/features/groups/children.js.map +0 -1
  929. package/dist/features/groups/composePose.js +0 -67
  930. package/dist/features/groups/composePose.js.map +0 -1
  931. package/dist/features/groups/nestedHit.js.map +0 -1
  932. package/dist/features/groups/unionOfChildren.js.map +0 -1
  933. package/dist/features/images/imageCache.js +0 -104
  934. package/dist/features/images/imageCache.js.map +0 -1
  935. package/dist/features/ingestion/index.js +0 -8
  936. package/dist/features/meshPaint/bake.js +0 -79
  937. package/dist/features/meshPaint/bake.js.map +0 -1
  938. package/dist/features/meshPaint/bakeCache.js +0 -59
  939. package/dist/features/meshPaint/bakeCache.js.map +0 -1
  940. package/dist/features/meshPaint/handles.js +0 -86
  941. package/dist/features/meshPaint/handles.js.map +0 -1
  942. package/dist/features/meshPaint/lazyKind.js.map +0 -1
  943. package/dist/features/meshPaint/meshPaint.js +0 -239
  944. package/dist/features/meshPaint/meshPaint.js.map +0 -1
  945. package/dist/features/meshPaint/meshShader.js +0 -6
  946. package/dist/features/meshPaint/meshShader.js.map +0 -1
  947. package/dist/features/meshPaint/register.js +0 -7
  948. package/dist/features/meshPaint/register.js.map +0 -1
  949. package/dist/features/meshPaint/surface.js +0 -110
  950. package/dist/features/meshPaint/surface.js.map +0 -1
  951. package/dist/features/minimap/actions.js +0 -53
  952. package/dist/features/minimap/actions.js.map +0 -1
  953. package/dist/features/minimap/createMinimapContribution.js +0 -96
  954. package/dist/features/minimap/createMinimapContribution.js.map +0 -1
  955. package/dist/features/minimap/layers.js +0 -85
  956. package/dist/features/minimap/layers.js.map +0 -1
  957. package/dist/features/overlays/useNodeOverlayFrame.js +0 -103
  958. package/dist/features/overlays/useNodeOverlayFrame.js.map +0 -1
  959. package/dist/features/parallax/createParallaxLayer.js +0 -26
  960. package/dist/features/parallax/createParallaxLayer.js.map +0 -1
  961. package/dist/features/parallax/createParallaxPlane.js +0 -22
  962. package/dist/features/parallax/createParallaxPlane.js.map +0 -1
  963. package/dist/features/paths/anchorEdits.js +0 -167
  964. package/dist/features/paths/anchorEdits.js.map +0 -1
  965. package/dist/features/paths/anchors.js +0 -159
  966. package/dist/features/paths/anchors.js.map +0 -1
  967. package/dist/features/paths/booleans.js +0 -2
  968. package/dist/features/paths/markerCommands.js +0 -149
  969. package/dist/features/paths/markerCommands.js.map +0 -1
  970. package/dist/features/paths/markerSites.js +0 -59
  971. package/dist/features/paths/markerSites.js.map +0 -1
  972. package/dist/features/paths/markers.js +0 -95
  973. package/dist/features/paths/markers.js.map +0 -1
  974. package/dist/features/paths/nearestAnchor.js +0 -36
  975. package/dist/features/paths/nearestAnchor.js.map +0 -1
  976. package/dist/features/paths/pathInWorld.js +0 -41
  977. package/dist/features/paths/pathInWorld.js.map +0 -1
  978. package/dist/features/paths/poseDescriptor.js +0 -39
  979. package/dist/features/paths/poseDescriptor.js.map +0 -1
  980. package/dist/features/paths/strokeToPath.js +0 -40
  981. package/dist/features/paths/strokeToPath.js.map +0 -1
  982. package/dist/features/paths/tessellate/dash.js +0 -52
  983. package/dist/features/paths/tessellate/dash.js.map +0 -1
  984. package/dist/features/paths/tessellate/insets.js +0 -32
  985. package/dist/features/paths/tessellate/insets.js.map +0 -1
  986. package/dist/features/paths/tessellate/metric.js +0 -72
  987. package/dist/features/paths/tessellate/metric.js.map +0 -1
  988. package/dist/features/paths/tessellate/stroke.js +0 -170
  989. package/dist/features/paths/tessellate/stroke.js.map +0 -1
  990. package/dist/features/paths/tessellate/vertexWidths.js +0 -32
  991. package/dist/features/paths/tessellate/vertexWidths.js.map +0 -1
  992. package/dist/features/patterns/commandPaint.js +0 -18
  993. package/dist/features/patterns/commandPaint.js.map +0 -1
  994. package/dist/features/patterns/index.js +0 -11
  995. package/dist/features/patterns/index.js.map +0 -1
  996. package/dist/features/patterns/patterns-builtin.js +0 -38
  997. package/dist/features/patterns/patterns-builtin.js.map +0 -1
  998. package/dist/features/patterns/rasterizeTile.js +0 -17
  999. package/dist/features/patterns/rasterizeTile.js.map +0 -1
  1000. package/dist/features/patterns/resolveSpec.js +0 -65
  1001. package/dist/features/patterns/resolveSpec.js.map +0 -1
  1002. package/dist/features/patterns/tileGeometry.js +0 -158
  1003. package/dist/features/patterns/tileGeometry.js.map +0 -1
  1004. package/dist/features/pointer/PointerContext.js +0 -45
  1005. package/dist/features/pointer/PointerContext.js.map +0 -1
  1006. package/dist/features/selection/SelectionContext.js +0 -51
  1007. package/dist/features/selection/SelectionContext.js.map +0 -1
  1008. package/dist/features/simulation/createSimulation.js +0 -61
  1009. package/dist/features/simulation/createSimulation.js.map +0 -1
  1010. package/dist/features/simulation/types.js +0 -6
  1011. package/dist/features/simulation/types.js.map +0 -1
  1012. package/dist/features/simulation/useSimulation.js +0 -74
  1013. package/dist/features/simulation/useSimulation.js.map +0 -1
  1014. package/dist/features/text/domOffsets.js +0 -82
  1015. package/dist/features/text/domOffsets.js.map +0 -1
  1016. package/dist/features/text/domRuns.js +0 -230
  1017. package/dist/features/text/domRuns.js.map +0 -1
  1018. package/dist/features/text/fitTextPose.js +0 -38
  1019. package/dist/features/text/fitTextPose.js.map +0 -1
  1020. package/dist/features/text/hitTest.js +0 -48
  1021. package/dist/features/text/hitTest.js.map +0 -1
  1022. package/dist/features/text/isTextData.js +0 -8
  1023. package/dist/features/text/isTextData.js.map +0 -1
  1024. package/dist/features/text/overlayDirection.js +0 -15
  1025. package/dist/features/text/overlayDirection.js.map +0 -1
  1026. package/dist/features/text/renderLabel.js +0 -14
  1027. package/dist/features/text/renderLabel.js.map +0 -1
  1028. package/dist/features/text/runs/effectiveRangeStyle.js +0 -66
  1029. package/dist/features/text/runs/effectiveRangeStyle.js.map +0 -1
  1030. package/dist/features/text/runs/flagRange.js +0 -53
  1031. package/dist/features/text/runs/flagRange.js.map +0 -1
  1032. package/dist/features/text/runs/rangeStyle.js +0 -133
  1033. package/dist/features/text/runs/rangeStyle.js.map +0 -1
  1034. package/dist/features/text/textCommand.js +0 -60
  1035. package/dist/features/text/textCommand.js.map +0 -1
  1036. package/dist/features/text/textToPath.js +0 -181
  1037. package/dist/features/text/textToPath.js.map +0 -1
  1038. package/dist/features/text/useTextEdit.js +0 -491
  1039. package/dist/features/text/useTextEdit.js.map +0 -1
  1040. package/dist/features/tiling/createTiledLayer.js +0 -65
  1041. package/dist/features/tiling/createTiledLayer.js.map +0 -1
  1042. package/dist/features/tiling/tiledProject.js +0 -14
  1043. package/dist/features/tiling/tiledProject.js.map +0 -1
  1044. package/dist/interactions/actions/clone/behaviors/cloneByAltDrag.js +0 -26
  1045. package/dist/interactions/actions/clone/behaviors/cloneByAltDrag.js.map +0 -1
  1046. package/dist/interactions/actions/defaults/align.js.map +0 -1
  1047. package/dist/interactions/actions/defaults/booleans.js +0 -52
  1048. package/dist/interactions/actions/defaults/booleans.js.map +0 -1
  1049. package/dist/interactions/actions/defaults/clipboard.js.map +0 -1
  1050. package/dist/interactions/actions/defaults/clone.js +0 -91
  1051. package/dist/interactions/actions/defaults/clone.js.map +0 -1
  1052. package/dist/interactions/actions/defaults/createOutlines.js +0 -47
  1053. package/dist/interactions/actions/defaults/createOutlines.js.map +0 -1
  1054. package/dist/interactions/actions/defaults/distribute.js.map +0 -1
  1055. package/dist/interactions/actions/defaults/editAnchors.js +0 -100
  1056. package/dist/interactions/actions/defaults/editAnchors.js.map +0 -1
  1057. package/dist/interactions/actions/defaults/flip.js +0 -125
  1058. package/dist/interactions/actions/defaults/flip.js.map +0 -1
  1059. package/dist/interactions/actions/defaults/insert.js +0 -287
  1060. package/dist/interactions/actions/defaults/insert.js.map +0 -1
  1061. package/dist/interactions/actions/defaults/lassoSelect.js +0 -153
  1062. package/dist/interactions/actions/defaults/lassoSelect.js.map +0 -1
  1063. package/dist/interactions/actions/defaults/move.js +0 -778
  1064. package/dist/interactions/actions/defaults/move.js.map +0 -1
  1065. package/dist/interactions/actions/defaults/resize.js +0 -341
  1066. package/dist/interactions/actions/defaults/resize.js.map +0 -1
  1067. package/dist/interactions/actions/defaults/rotate.js +0 -185
  1068. package/dist/interactions/actions/defaults/rotate.js.map +0 -1
  1069. package/dist/interactions/actions/previewOverrides.js +0 -25
  1070. package/dist/interactions/actions/previewOverrides.js.map +0 -1
  1071. package/dist/interactions/actions/resize/autoPoseDescriptor.js.map +0 -1
  1072. package/dist/layout/arrivals.js +0 -36
  1073. package/dist/layout/arrivals.js.map +0 -1
  1074. package/dist/math-J-ACHyEg.d.ts +0 -159
  1075. package/dist/registerProgram-T9S_PfAX.d.ts +0 -208
  1076. package/dist/renderer/DrawCommand.js +0 -6
  1077. package/dist/renderer/DrawCommand.js.map +0 -1
  1078. package/dist/renderer/WeaselRenderer.js +0 -333
  1079. package/dist/renderer/WeaselRenderer.js.map +0 -1
  1080. package/dist/renderer/batchClip.js +0 -46
  1081. package/dist/renderer/batchClip.js.map +0 -1
  1082. package/dist/renderer/cache/GLImageCache.js +0 -74
  1083. package/dist/renderer/cache/GLImageCache.js.map +0 -1
  1084. package/dist/renderer/cache/GLMeshCache.js +0 -102
  1085. package/dist/renderer/cache/GLMeshCache.js.map +0 -1
  1086. package/dist/renderer/cache/GLTextureCache.js +0 -68
  1087. package/dist/renderer/cache/GLTextureCache.js.map +0 -1
  1088. package/dist/renderer/cache/GradientRampAtlas.js +0 -82
  1089. package/dist/renderer/cache/GradientRampAtlas.js.map +0 -1
  1090. package/dist/renderer/cache/cache.js +0 -13
  1091. package/dist/renderer/cache/cache.js.map +0 -1
  1092. package/dist/renderer/cache/markerCommandCache.js +0 -63
  1093. package/dist/renderer/cache/markerCommandCache.js.map +0 -1
  1094. package/dist/renderer/cache/outlineMeshCache.js +0 -15
  1095. package/dist/renderer/cache/outlineMeshCache.js.map +0 -1
  1096. package/dist/renderer/cache/outlineStrokeMeshCache.js +0 -36
  1097. package/dist/renderer/cache/outlineStrokeMeshCache.js.map +0 -1
  1098. package/dist/renderer/cache/strokeMeshCache.js +0 -55
  1099. package/dist/renderer/cache/strokeMeshCache.js.map +0 -1
  1100. package/dist/renderer/cullDrawCommands.js +0 -90
  1101. package/dist/renderer/cullDrawCommands.js.map +0 -1
  1102. package/dist/renderer/draw/batch.js +0 -133
  1103. package/dist/renderer/draw/batch.js.map +0 -1
  1104. package/dist/renderer/draw/clip.js +0 -89
  1105. package/dist/renderer/draw/clip.js.map +0 -1
  1106. package/dist/renderer/draw/customShader.js +0 -230
  1107. package/dist/renderer/draw/customShader.js.map +0 -1
  1108. package/dist/renderer/draw/drawTriangles.js +0 -8
  1109. package/dist/renderer/draw/drawTriangles.js.map +0 -1
  1110. package/dist/renderer/draw/effects.js +0 -28
  1111. package/dist/renderer/draw/effects.js.map +0 -1
  1112. package/dist/renderer/draw/flushBatch.js +0 -35
  1113. package/dist/renderer/draw/flushBatch.js.map +0 -1
  1114. package/dist/renderer/draw/gradient.js +0 -90
  1115. package/dist/renderer/draw/gradient.js.map +0 -1
  1116. package/dist/renderer/draw/image.js +0 -38
  1117. package/dist/renderer/draw/image.js.map +0 -1
  1118. package/dist/renderer/draw/mesh.js +0 -16
  1119. package/dist/renderer/draw/mesh.js.map +0 -1
  1120. package/dist/renderer/draw/paintBind.js +0 -70
  1121. package/dist/renderer/draw/paintBind.js.map +0 -1
  1122. package/dist/renderer/draw/pathPaint.js +0 -142
  1123. package/dist/renderer/draw/pathPaint.js.map +0 -1
  1124. package/dist/renderer/draw/scratchPass.js +0 -83
  1125. package/dist/renderer/draw/scratchPass.js.map +0 -1
  1126. package/dist/renderer/draw/stencil.js +0 -28
  1127. package/dist/renderer/draw/stencil.js.map +0 -1
  1128. package/dist/renderer/draw/text.js +0 -167
  1129. package/dist/renderer/draw/text.js.map +0 -1
  1130. package/dist/renderer/draw/uniforms.js +0 -77
  1131. package/dist/renderer/draw/uniforms.js.map +0 -1
  1132. package/dist/renderer/draw.js +0 -79
  1133. package/dist/renderer/draw.js.map +0 -1
  1134. package/dist/renderer/drawBatch.js +0 -198
  1135. package/dist/renderer/drawBatch.js.map +0 -1
  1136. package/dist/renderer/effects/EffectTargets.js +0 -48
  1137. package/dist/renderer/effects/EffectTargets.js.map +0 -1
  1138. package/dist/renderer/effects/builtins.js +0 -31
  1139. package/dist/renderer/effects/builtins.js.map +0 -1
  1140. package/dist/renderer/effects/composite.js +0 -11
  1141. package/dist/renderer/effects/composite.js.map +0 -1
  1142. package/dist/renderer/effects/effectPrelude.js +0 -10
  1143. package/dist/renderer/effects/effectPrelude.js.map +0 -1
  1144. package/dist/renderer/effects/types.js +0 -10
  1145. package/dist/renderer/effects/types.js.map +0 -1
  1146. package/dist/renderer/glyphOutlineMesh.js +0 -67
  1147. package/dist/renderer/glyphOutlineMesh.js.map +0 -1
  1148. package/dist/renderer/index.js +0 -20
  1149. package/dist/renderer/math/color.js +0 -321
  1150. package/dist/renderer/math/color.js.map +0 -1
  1151. package/dist/renderer/math/mat3.js +0 -80
  1152. package/dist/renderer/math/mat3.js.map +0 -1
  1153. package/dist/renderer/math/patternSpace.js +0 -22
  1154. package/dist/renderer/math/patternSpace.js.map +0 -1
  1155. package/dist/renderer/math/viewToMat3.js +0 -19
  1156. package/dist/renderer/math/viewToMat3.js.map +0 -1
  1157. package/dist/renderer/paintResources.js +0 -18
  1158. package/dist/renderer/paintResources.js.map +0 -1
  1159. package/dist/renderer/paintScratch.js +0 -37
  1160. package/dist/renderer/paintScratch.js.map +0 -1
  1161. package/dist/renderer/shaders/ShaderProgram.js +0 -74
  1162. package/dist/renderer/shaders/ShaderProgram.js.map +0 -1
  1163. package/dist/renderer/shaders/batchFill.js +0 -119
  1164. package/dist/renderer/shaders/batchFill.js.map +0 -1
  1165. package/dist/renderer/shaders/customPrelude.js +0 -34
  1166. package/dist/renderer/shaders/customPrelude.js.map +0 -1
  1167. package/dist/renderer/shaders/extractUniformNames.js +0 -184
  1168. package/dist/renderer/shaders/extractUniformNames.js.map +0 -1
  1169. package/dist/renderer/shaders/glyphPaint.js +0 -61
  1170. package/dist/renderer/shaders/glyphPaint.js.map +0 -1
  1171. package/dist/renderer/shaders/gradFill.js +0 -31
  1172. package/dist/renderer/shaders/gradFill.js.map +0 -1
  1173. package/dist/renderer/shaders/pathFill.js +0 -14
  1174. package/dist/renderer/shaders/pathFill.js.map +0 -1
  1175. package/dist/renderer/shaders/patternFill.js +0 -25
  1176. package/dist/renderer/shaders/patternFill.js.map +0 -1
  1177. package/dist/renderer/shaders/registerProgram.js +0 -18
  1178. package/dist/renderer/shaders/registerProgram.js.map +0 -1
  1179. package/dist/renderer/spriteSheet.js +0 -14
  1180. package/dist/renderer/spriteSheet.js.map +0 -1
  1181. package/dist/renderer/state/GroupState.js +0 -77
  1182. package/dist/renderer/state/GroupState.js.map +0 -1
  1183. package/dist/renderer/strokeLengths.js +0 -50
  1184. package/dist/renderer/strokeLengths.js.map +0 -1
  1185. package/dist/renderer/syntheticItalic.js +0 -6
  1186. package/dist/renderer/syntheticItalic.js.map +0 -1
  1187. package/dist/renderer/textures/registerTexture.js +0 -34
  1188. package/dist/renderer/textures/registerTexture.js.map +0 -1
  1189. package/dist/scheduling/useVisibleRaf.js +0 -69
  1190. package/dist/scheduling/useVisibleRaf.js.map +0 -1
  1191. package/dist/test-seams-DM2B87-g.d.ts +0 -356
@@ -0,0 +1,42 @@
1
+ import { commitAnchorEdit as e, depOf as t, requiresAnchorSelection as n } from "./anchorEditing.js";
2
+ import { RetractHandlesIcon as r, SymmetricHandlesIcon as i } from "./icons/anchorIcons.js";
3
+ import { editAnchorSetTracked as a, makeHandlesSymmetric as o, retractHandles as s } from "@weasel-js/geom";
4
+ import { ActionDisabledReason as c } from "@weasel-js/routing";
5
+ import { jsx as l } from "react/jsx-runtime";
6
+ //#region src/interactions/actions/defaults/anchorHandles.tsx
7
+ function u(r, i, a, o) {
8
+ return {
9
+ id: r,
10
+ label: i,
11
+ icon: a,
12
+ group: "anchors",
13
+ eligible: { capability: "edits-anchors" },
14
+ requires: ["editAnchors"],
15
+ invoker: {
16
+ timing: "immediate",
17
+ run: (n) => {
18
+ let r = t(n);
19
+ if (!r || r.selectedAnchors.size === 0) return;
20
+ let a = [...r.selectedAnchors];
21
+ e(r, i, (e) => o(e, a));
22
+ }
23
+ },
24
+ enabled: (e) => {
25
+ let t = n(e);
26
+ return t === !0 ? d(e, o) ? !0 : c.NotApplicable : t;
27
+ }
28
+ };
29
+ }
30
+ function d(e, n) {
31
+ let r = t(e);
32
+ if (!r) return !1;
33
+ let i = r.getEditablePath(r.editingId);
34
+ if (!i || i.kind !== "polygon") return !1;
35
+ let o = [...r.selectedAnchors];
36
+ return a(i, (e) => n(e, o)) !== null;
37
+ }
38
+ var f = u("retractHandles", "Retract handles", /* @__PURE__ */ l(r, {}), s), p = u("makeHandlesSymmetric", "Make handles symmetric", /* @__PURE__ */ l(i, {}), o);
39
+ //#endregion
40
+ export { p as makeHandlesSymmetricAction, f as retractHandlesAction };
41
+
42
+ //# sourceMappingURL=anchorHandles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anchorHandles.js","names":["makeHandleCommand","dep","depOf","deps","selected","label","edit","set","selection","requiresAnchorSelection","wouldChange","ActionDisabledReason","path","editAnchorSetTracked","retractHandlesAction","RetractHandlesIcon","retractHandles","makeHandlesSymmetricAction","SymmetricHandlesIcon","makeHandlesSymmetric"],"sources":["../../../../src/interactions/actions/defaults/anchorHandles.tsx"],"sourcesContent":["/**\n * Commands on the handles of the anchors selected in path edit: retract them\n * onto their anchors, or make each anchor's pair symmetric.\n */\n\nimport type { Action, ActionDeps, ImmediateInvoker } from '@weasel-js/routing';\nimport { ActionDisabledReason } from '@weasel-js/routing';\nimport {\n editAnchorSetTracked,\n makeHandlesSymmetric,\n retractHandles,\n type AnchorSet,\n type PolygonPath,\n} from '@weasel-js/geom';\nimport { commitAnchorEdit, depOf, requiresAnchorSelection } from './anchorEditing';\nimport { RetractHandlesIcon, SymmetricHandlesIcon } from './icons/anchorIcons';\n\ntype HandleEdit = (set: AnchorSet, flatIndexes: Iterable<number>) => boolean;\n\nfunction makeHandleCommand(\n id: string,\n label: string,\n icon: Action['icon'],\n edit: HandleEdit,\n): Action & { requires: string[] } {\n return {\n id,\n label,\n icon,\n group: 'anchors',\n eligible: { capability: 'edits-anchors' },\n requires: ['editAnchors'],\n invoker: {\n timing: 'immediate',\n run: (deps) => {\n const dep = depOf(deps);\n if (!dep || dep.selectedAnchors.size === 0) return;\n const selected = [...dep.selectedAnchors];\n commitAnchorEdit(dep, label, (set) => edit(set, selected));\n },\n } as ImmediateInvoker,\n enabled: (deps) => {\n const selection = requiresAnchorSelection(deps);\n if (selection !== true) return selection;\n return wouldChange(deps, edit) ? true : ActionDisabledReason.NotApplicable;\n },\n };\n}\n\n/** Whether `edit` would change the edited path, tried on a scratch decode. */\nfunction wouldChange(deps: ActionDeps | undefined, edit: HandleEdit): boolean {\n const dep = depOf(deps);\n if (!dep) return false;\n const path = dep.getEditablePath(dep.editingId) as PolygonPath | undefined;\n if (!path || path.kind !== 'polygon') return false;\n const selected = [...dep.selectedAnchors];\n return editAnchorSetTracked(path, (set) => edit(set, selected)) !== null;\n}\n\n/** Collapse the selected anchors' handles onto them, making sharp corners. */\nexport const retractHandlesAction = makeHandleCommand(\n 'retractHandles',\n 'Retract handles',\n <RetractHandlesIcon />,\n retractHandles,\n);\n\n/** Give each selected anchor equal, opposite handles, making it smooth. */\nexport const makeHandlesSymmetricAction = makeHandleCommand(\n 'makeHandlesSymmetric',\n 'Make handles symmetric',\n <SymmetricHandlesIcon />,\n makeHandlesSymmetric,\n);\n"],"mappings":";;;;;;AAmBA,SAASA,EACP,GACA,GACA,GACA,GACiC;CACjC,OAAO;EACL;EACA;EACA;EACA,OAAO;EACP,UAAU,EAAE,YAAY,gBAAgB;EACxC,UAAU,CAAC,aAAa;EACxB,SAAS;GACP,QAAQ;GACR,MAAM,MAAS;IACb,IAAMC,IAAMC,EAAMC,CAAI;IACtB,IAAI,CAACF,KAAOA,EAAI,gBAAgB,SAAS,GAAG;IAC5C,IAAMG,IAAW,CAAC,GAAGH,EAAI,eAAe;IACxC,EAAiBA,GAAKI,IAAQ,MAAQC,EAAKC,GAAKH,CAAQ,CAAC;GAC3D;EACF;EACA,UAAU,MAAS;GACjB,IAAMI,IAAYC,EAAwBN,CAAI;GAE9C,OADIK,MAAc,KACXE,EAAYP,GAAMG,CAAI,IAAI,KAAOK,EAAqB,gBAD9BH;EAEjC;CACF;AACF;AAGA,SAASE,EAAY,GAA8B,GAA2B;CAC5E,IAAMT,IAAMC,EAAMC,CAAI;CACtB,IAAI,CAACF,GAAK,OAAO;CACjB,IAAMW,IAAOX,EAAI,gBAAgBA,EAAI,SAAS;CAC9C,IAAI,CAACW,KAAQA,EAAK,SAAS,WAAW,OAAO;CAC7C,IAAMR,IAAW,CAAC,GAAGH,EAAI,eAAe;CACxC,OAAOY,EAAqBD,IAAO,MAAQN,EAAKC,GAAKH,CAAQ,CAAC,MAAM;AACtE;AAGA,IAAaU,IAAuBd,EAClC,kBACA,mBACA,kBAACe,GAAD,CAAqB,CAAA,GACrBC,CACF,GAGaC,IAA6BjB,EACxC,wBACA,0BACA,kBAACkB,GAAD,CAAuB,CAAA,GACvBC,CACF"}
@@ -0,0 +1,92 @@
1
+ import { commitAnchorEdit as e, depOf as t } from "./anchorEditing.js";
2
+ import { averageAnchorsAt as n, editAnchorSetTracked as r, joinAnchorsAt as i } from "@weasel-js/geom";
3
+ import { ActionDisabledReason as a } from "@weasel-js/routing";
4
+ //#region src/interactions/actions/defaults/anchorJoin.ts
5
+ function o(e, n) {
6
+ let i = t(e);
7
+ if (!i) return !1;
8
+ let a = i.getEditablePath(i.editingId);
9
+ if (!a || a.kind !== "polygon") return !1;
10
+ let o = [...i.selectedAnchors];
11
+ return r(a, (e) => n(e, o)) !== null;
12
+ }
13
+ var s = (e) => {
14
+ let t = e?.axis;
15
+ return t === "x" || t === "y" ? t : "both";
16
+ }, c = {
17
+ id: "averageAnchors",
18
+ label: "Average anchors",
19
+ group: "anchors",
20
+ variants: [
21
+ {
22
+ key: "both",
23
+ label: "Average anchors",
24
+ params: { axis: "both" }
25
+ },
26
+ {
27
+ key: "x",
28
+ label: "Line anchors up vertically",
29
+ params: { axis: "x" }
30
+ },
31
+ {
32
+ key: "y",
33
+ label: "Line anchors up horizontally",
34
+ params: { axis: "y" }
35
+ }
36
+ ],
37
+ defaultBinding: [{
38
+ spec: {
39
+ kind: "key",
40
+ key: "j",
41
+ code: "KeyJ",
42
+ mods: {
43
+ mod: !0,
44
+ alt: !0
45
+ }
46
+ },
47
+ opts: { params: { axis: "both" } }
48
+ }],
49
+ eligible: { capability: "edits-anchors" },
50
+ requires: ["editAnchors"],
51
+ invoker: {
52
+ timing: "immediate",
53
+ run: (r, i) => {
54
+ let a = t(r);
55
+ if (!a || a.selectedAnchors.size < 2) return;
56
+ let o = [...a.selectedAnchors];
57
+ e(a, "Average anchors", (e) => n(e, o, s(i)));
58
+ }
59
+ },
60
+ enabled: (e) => {
61
+ let n = t(e);
62
+ return !n || n.selectedAnchors.size < 2 ? a.SelectionRequired : !0;
63
+ }
64
+ }, l = (e, t) => t.length === 2 && i(e, t[0], t[1]), u = {
65
+ id: "joinAnchors",
66
+ label: "Join anchors",
67
+ group: "anchors",
68
+ defaultBinding: {
69
+ kind: "key",
70
+ key: "j",
71
+ mods: { mod: !0 }
72
+ },
73
+ eligible: { capability: "edits-anchors" },
74
+ requires: ["editAnchors"],
75
+ invoker: {
76
+ timing: "immediate",
77
+ run: (n) => {
78
+ let r = t(n);
79
+ if (!r || r.selectedAnchors.size !== 2) return;
80
+ let i = [...r.selectedAnchors];
81
+ e(r, "Join anchors", (e) => l(e, i)) && r.setSelectedAnchors([]);
82
+ }
83
+ },
84
+ enabled: (e) => {
85
+ let n = t(e);
86
+ return !n || n.selectedAnchors.size !== 2 ? a.SelectionRequired : o(e, l) ? !0 : a.NotApplicable;
87
+ }
88
+ };
89
+ //#endregion
90
+ export { c as averageAnchorsAction, u as joinAnchorsAction };
91
+
92
+ //# sourceMappingURL=anchorJoin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anchorJoin.js","names":["wouldChange","dep","depOf","deps","path","selected","editAnchorSetTracked","edit","set","axisOf","axis","params","averageAnchorsAction","averageAnchorsAt","ActionDisabledReason","join","joinAnchorsAt","joinAnchorsAction","commitAnchorEdit"],"sources":["../../../../src/interactions/actions/defaults/anchorJoin.ts"],"sourcesContent":["/**\n * Average and Join on the anchors selected in path edit.\n */\n\nimport type { Action, ActionDeps, ImmediateInvoker } from '@weasel-js/routing';\nimport { ActionDisabledReason } from '@weasel-js/routing';\nimport {\n averageAnchorsAt, editAnchorSetTracked, joinAnchorsAt, type AnchorSet, type AverageAxis, type PolygonPath,\n} from '@weasel-js/geom';\nimport { commitAnchorEdit, depOf } from './anchorEditing';\n\ntype AnchorEdit = (set: AnchorSet, selected: number[]) => boolean;\n\n/** Whether `edit` would change the edited path, tried on a scratch decode. */\nfunction wouldChange(deps: ActionDeps | undefined, edit: AnchorEdit): boolean {\n const dep = depOf(deps);\n if (!dep) return false;\n const path = dep.getEditablePath(dep.editingId) as PolygonPath | undefined;\n if (!path || path.kind !== 'polygon') return false;\n const selected = [...dep.selectedAnchors];\n return editAnchorSetTracked(path, (set) => edit(set, selected)) !== null;\n}\n\nconst axisOf = (params: Record<string, unknown> | undefined): AverageAxis => {\n const axis = params?.axis;\n return axis === 'x' || axis === 'y' ? axis : 'both';\n};\n\n/**\n * @experimental Move the selected anchors to their mean position:\n * `params.axis` `'both'` (the default) stacks them on one point, `'x'` lines\n * them up on one vertical, `'y'` on one horizontal.\n */\nexport const averageAnchorsAction: Action & { requires: string[] } = {\n id: 'averageAnchors',\n label: 'Average anchors',\n group: 'anchors',\n variants: [\n { key: 'both', label: 'Average anchors', params: { axis: 'both' } },\n { key: 'x', label: 'Line anchors up vertically', params: { axis: 'x' } },\n { key: 'y', label: 'Line anchors up horizontally', params: { axis: 'y' } },\n ],\n // `code` too: with Alt held on a Mac the key reads as another glyph.\n defaultBinding: [{\n spec: { kind: 'key', key: 'j', code: 'KeyJ', mods: { mod: true, alt: true } },\n opts: { params: { axis: 'both' } },\n }],\n eligible: { capability: 'edits-anchors' },\n requires: ['editAnchors'],\n invoker: {\n timing: 'immediate',\n run: (deps, params) => {\n const dep = depOf(deps);\n if (!dep || dep.selectedAnchors.size < 2) return;\n const selected = [...dep.selectedAnchors];\n commitAnchorEdit(dep, 'Average anchors', (set) => averageAnchorsAt(set, selected, axisOf(params)));\n },\n } as ImmediateInvoker,\n enabled: (deps) => {\n const dep = depOf(deps);\n if (!dep || dep.selectedAnchors.size < 2) return ActionDisabledReason.SelectionRequired;\n return true;\n },\n};\n\nconst join: AnchorEdit = (set, selected) => selected.length === 2 && joinAnchorsAt(set, selected[0], selected[1]);\n\n/**\n * @experimental Join the two selected anchors, each the end of an open\n * subpath: the ends of one subpath close it, and ends of two make them one\n * (`joinAnchorsAt`). Joining renumbers the anchors, so the anchor selection\n * is cleared.\n */\nexport const joinAnchorsAction: Action & { requires: string[] } = {\n id: 'joinAnchors',\n label: 'Join anchors',\n group: 'anchors',\n defaultBinding: { kind: 'key', key: 'j', mods: { mod: true } },\n eligible: { capability: 'edits-anchors' },\n requires: ['editAnchors'],\n invoker: {\n timing: 'immediate',\n run: (deps) => {\n const dep = depOf(deps);\n if (!dep || dep.selectedAnchors.size !== 2) return;\n const selected = [...dep.selectedAnchors];\n if (commitAnchorEdit(dep, 'Join anchors', (set) => join(set, selected))) dep.setSelectedAnchors([]);\n },\n } as ImmediateInvoker,\n enabled: (deps) => {\n const dep = depOf(deps);\n if (!dep || dep.selectedAnchors.size !== 2) return ActionDisabledReason.SelectionRequired;\n return wouldChange(deps, join) ? true : ActionDisabledReason.NotApplicable;\n },\n};\n"],"mappings":";;;;AAcA,SAASA,EAAY,GAA8B,GAA2B;CAC5E,IAAMC,IAAMC,EAAMC,CAAI;CACtB,IAAI,CAACF,GAAK,OAAO;CACjB,IAAMG,IAAOH,EAAI,gBAAgBA,EAAI,SAAS;CAC9C,IAAI,CAACG,KAAQA,EAAK,SAAS,WAAW,OAAO;CAC7C,IAAMC,IAAW,CAAC,GAAGJ,EAAI,eAAe;CACxC,OAAOK,EAAqBF,IAAO,MAAQG,EAAKC,GAAKH,CAAQ,CAAC,MAAM;AACtE;AAEA,IAAMI,KAAU,MAA6D;CAC3E,IAAMC,IAAOC,GAAQ;CACrB,OAAOD,MAAS,OAAOA,MAAS,MAAMA,IAAO;AAC/C,GAOaE,IAAwD;CACnE,IAAI;CACJ,OAAO;CACP,OAAO;CACP,UAAU;EACR;GAAE,KAAK;GAAQ,OAAO;GAAmB,QAAQ,EAAE,MAAM,OAAO;EAAE;EAClE;GAAE,KAAK;GAAK,OAAO;GAA8B,QAAQ,EAAE,MAAM,IAAI;EAAE;EACvE;GAAE,KAAK;GAAK,OAAO;GAAgC,QAAQ,EAAE,MAAM,IAAI;EAAE;CAC3E;CAEA,gBAAgB,CAAC;EACf,MAAM;GAAE,MAAM;GAAO,KAAK;GAAK,MAAM;GAAQ,MAAM;IAAE,KAAK;IAAM,KAAK;GAAK;EAAE;EAC5E,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,EAAE;CACnC,CAAC;CACD,UAAU,EAAE,YAAY,gBAAgB;CACxC,UAAU,CAAC,aAAa;CACxB,SAAS;EACP,QAAQ;EACR,MAAM,GAAM,MAAW;GACrB,IAAMX,IAAMC,EAAMC,CAAI;GACtB,IAAI,CAACF,KAAOA,EAAI,gBAAgB,OAAO,GAAG;GAC1C,IAAMI,IAAW,CAAC,GAAGJ,EAAI,eAAe;GACxC,EAAiBA,GAAK,oBAAoB,MAAQY,EAAiBL,GAAKH,GAAUI,EAAOE,CAAM,CAAC,CAAC;EACnG;CACF;CACA,UAAU,MAAS;EACjB,IAAMV,IAAMC,EAAMC,CAAI;EAEtB,OADI,CAACF,KAAOA,EAAI,gBAAgB,OAAO,IAAUa,EAAqB,oBAC/D;CACT;AACF,GAEMC,KAAoB,GAAK,MAAaV,EAAS,WAAW,KAAKW,EAAcR,GAAKH,EAAS,IAAIA,EAAS,EAAE,GAQnGY,IAAqD;CAChE,IAAI;CACJ,OAAO;CACP,OAAO;CACP,gBAAgB;EAAE,MAAM;EAAO,KAAK;EAAK,MAAM,EAAE,KAAK,GAAK;CAAE;CAC7D,UAAU,EAAE,YAAY,gBAAgB;CACxC,UAAU,CAAC,aAAa;CACxB,SAAS;EACP,QAAQ;EACR,MAAM,MAAS;GACb,IAAMhB,IAAMC,EAAMC,CAAI;GACtB,IAAI,CAACF,KAAOA,EAAI,gBAAgB,SAAS,GAAG;GAC5C,IAAMI,IAAW,CAAC,GAAGJ,EAAI,eAAe;GACxC,AAAIiB,EAAiBjB,GAAK,iBAAiB,MAAQc,EAAKP,GAAKH,CAAQ,CAAC,KAAGJ,EAAI,mBAAmB,CAAC,CAAC;EACpG;CACF;CACA,UAAU,MAAS;EACjB,IAAMA,IAAMC,EAAMC,CAAI;EAEtB,OADI,CAACF,KAAOA,EAAI,gBAAgB,SAAS,IAAUa,EAAqB,oBACjEd,EAAYG,GAAMY,CAAI,IAAI,KAAOD,EAAqB;CAC/D;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"areaSelect.js","names":["areaSelectAction","dep","ctx","affordanceKind","scratch","moveCtx","reason","d","x","startX","currentX","y","startY","currentY","width","height","shiftHeld","hits","view","selectionFromHits"],"sources":["../../../../src/interactions/actions/defaults/areaSelect.ts"],"sourcesContent":["/**\n * `areaSelectAction` — ongoing Action descriptor for marquee area selection.\n *\n * The marquee selection:\n * - `start`: records the drag start world point and shift state.\n * - `onMove`: tracks the current drag corner (no scene writes).\n * - `onEnd('commit')`: derives the marquee bounds from start + current;\n * calls `deps.areaSelect.hitTestArea(bounds)` to find overlapping nodes;\n * calls `deps.areaSelect.setSelection(ids)` to update selection (extending\n * with shift held). This is a **transient** write (no undo entry).\n * - `onEnd('cancel')`: no-op.\n *\n * ## Dependencies\n *\n * Requires `areaSelect` dep from DepSchema:\n * `{ hitTestArea(bounds): NodeId[], getSelection(): NodeId[], setSelection(ids): void }`\n *\n * `<SceneCanvas>` / `<StandardActionsRegistrar>` should source this dep by\n * iterating scene nodes and checking AABB overlap. The dep is intentionally\n * simple — consumers override it for custom hit-testing (contain-mode,\n * layer-aware filtering, etc.).\n *\n * ## What this does not wire\n *\n * - `AreaSelectBehavior` pipeline — omitted; only the default replace/extend\n * semantics are implemented.\n * - Debug sink recording — not available in the descriptor model.\n */\n\nimport type { Action } from '@weasel-js/routing';\nimport type { InvocationCtx, OngoingHandle, OngoingOverlay } from '@weasel-js/routing';\nimport type { NodeId } from 'core/scene/types';\nimport type { AreaSelectDep, ViewApi } from '../depSchema';\nimport { selectionFromHits } from '../hitSelection';\n\n// ---------------------------------------------------------------------------\n// Internal scratch\n// ---------------------------------------------------------------------------\n\ninterface AreaSelectScratch {\n dep: AreaSelectDep;\n /** The view the marquee started in: what it does not paint is not taken. */\n view: ViewApi | undefined;\n startX: number;\n startY: number;\n shiftHeld: boolean;\n currentX: number;\n currentY: number;\n /** Cleared once `onEnd` runs so subsequent `overlay()` calls report no\n * in-flight marquee (the dispatcher releases the handle after onEnd so\n * this is belt-and-suspenders for any consumer that retains a handle). */\n open: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Descriptor\n// ---------------------------------------------------------------------------\n\n/**\n * @experimental\n * Static descriptor for the `areaSelect` Action.\n *\n * Requires dep-schema entry: `areaSelect`.\n *\n * The invoker implements replace/extend marquee selection via the `areaSelect`\n * dep. Hit-testing and selection writes are delegated to the dep; the invoker\n * contains only the bounds-derivation and shift-extend logic.\n */\nexport const areaSelectAction: Action & { requires: string[] } = {\n id: 'areaSelect',\n label: 'Area Select',\n // Crosshair while the marquee is being pulled — the select tool used to\n // read this off its own gesture scratch.\n activeCursor: 'crosshair',\n eligible: { capability: 'creates-selection' },\n requires: ['areaSelect', 'editAnchors', 'view'],\n invoker: {\n timing: 'ongoing',\n start(ctx: InvocationCtx, _opts): OngoingHandle {\n const dep = ctx.deps.areaSelect;\n if (!dep) return {};\n\n // Decline on anchor / control-handle affordances: the select tool's\n // active-scope binding for this action is `{ kind: 'drag', target: 'empty' }`,\n // which matches whenever `bodyTarget === 'empty'` — including drags\n // where an anchor was hit on top of empty body. Without this opt-out\n // areaSelect would beat editAnchors via scope priority. The\n // dispatcher's empty-handle fallthrough then forwards the gesture.\n const affordanceKind = ctx.drag?.affordance?.kind;\n if (\n typeof affordanceKind === 'string'\n && /^(anchor|controlIn|controlOut):/.test(affordanceKind)\n ) {\n return {};\n }\n\n // Decline for the same reason while a path is in anchor-edit mode:\n // an empty-canvas drag there means \"rubber-band some anchors\", which\n // is `marqueeAnchorsAction`'s job. Capability eligibility already\n // filters this action out in path-edit mode, but only for consumers\n // that wired a mode registry — without one the dispatcher skips\n // eligibility entirely and areaSelect's active scope would beat\n // marqueeAnchors' ambient scope. Declining here covers both.\n const editAnchors = ctx.deps.editAnchors;\n if (editAnchors?.editingId) return {};\n\n // Drag start is the world point at the moment start() is called.\n const scratch: AreaSelectScratch = {\n dep,\n view: ctx.deps.view,\n startX: ctx.world.x,\n startY: ctx.world.y,\n shiftHeld: ctx.modifiers.shift,\n currentX: ctx.world.x,\n currentY: ctx.world.y,\n open: true,\n };\n\n return {\n kind: 'marquee',\n onMove(moveCtx: InvocationCtx): void {\n scratch.currentX = moveCtx.world.x;\n scratch.currentY = moveCtx.world.y;\n },\n overlay(): OngoingOverlay | null {\n if (!scratch.open) return null;\n return {\n kind: 'marquee',\n start: { x: scratch.startX, y: scratch.startY },\n current: { x: scratch.currentX, y: scratch.currentY },\n shiftHeld: scratch.shiftHeld,\n };\n },\n onEnd(_endCtx: InvocationCtx, reason: 'commit' | 'cancel'): void {\n scratch.open = false;\n if (reason === 'cancel') return;\n\n const { dep: d, view, startX, startY, currentX, currentY, shiftHeld } = scratch;\n\n // Derive the marquee AABB from the two world-space corners.\n const x = Math.min(startX, currentX);\n const y = Math.min(startY, currentY);\n const width = Math.abs(currentX - startX);\n const height = Math.abs(currentY - startY);\n\n // Zero-size marquee (click without drag) → clear selection (or no-op with shift).\n if (width === 0 || height === 0) {\n if (!shiftHeld) d.setSelection([]);\n return;\n }\n\n const hits = d.hitTestArea({ x, y, width, height }, view) as NodeId[];\n\n d.setSelection(selectionFromHits(d.getSelection(), hits, shiftHeld));\n },\n };\n },\n },\n /**\n * Always enabled at the dispatcher level. The dispatcher's\n * specificity-fallthrough loop treats anything `!== true` as \"skip this\n * match\" — returning a disabled reason would let lower-specificity\n * ambient bindings win. The invoker has no preconditions to guard.\n */\n enabled: () => true,\n};\n"],"mappings":";;AAoEA,IAAaA,IAAoD;CAC/D,IAAI;CACJ,OAAO;CAGP,cAAc;CACd,UAAU,EAAE,YAAY,oBAAoB;CAC5C,UAAU;EAAC;EAAc;EAAe;CAAM;CAC9C,SAAS;EACP,QAAQ;EACR,MAAM,GAAoB,GAAsB;GAC9C,IAAMC,IAAMC,EAAI,KAAK;GACrB,IAAI,CAACD,GAAK,OAAO,CAAC;GAQlB,IAAME,IAAiBD,EAAI,MAAM,YAAY;GAgB7C,IAdE,OAAOC,KAAmB,YACvB,kCAAkC,KAAKA,CAAc,KAYtCD,EAAI,KAAK,aACZ,WAAW,OAAO,CAAC;GAGpC,IAAME,IAA6B;IACjC;IACA,MAAMF,EAAI,KAAK;IACf,QAAQA,EAAI,MAAM;IAClB,QAAQA,EAAI,MAAM;IAClB,WAAWA,EAAI,UAAU;IACzB,UAAUA,EAAI,MAAM;IACpB,UAAUA,EAAI,MAAM;IACpB,MAAM;GACR;GAEA,OAAO;IACL,MAAM;IACN,OAAO,GAA8B;KAEnC,AADA,EAAQ,WAAWG,EAAQ,MAAM,GACjC,EAAQ,WAAWA,EAAQ,MAAM;IACnC;IACA,UAAiC;KAE/B,OADKD,EAAQ,OACN;MACL,MAAM;MACN,OAAO;OAAE,GAAGA,EAAQ;OAAQ,GAAGA,EAAQ;MAAO;MAC9C,SAAS;OAAE,GAAGA,EAAQ;OAAU,GAAGA,EAAQ;MAAS;MACpD,WAAWA,EAAQ;KACrB,IAN0B;IAO5B;IACA,MAAM,GAAwB,GAAmC;KAE/D,IADA,EAAQ,OAAO,IACXE,MAAW,UAAU;KAEzB,IAAM,EAAE,KAAKC,GAAG,SAAM,WAAQ,WAAQ,aAAU,aAAU,iBAAcH,GAGlEI,IAAI,KAAK,IAAIC,GAAQC,CAAQ,GAC7BC,IAAI,KAAK,IAAIC,GAAQC,CAAQ,GAC7BC,IAAQ,KAAK,IAAIJ,IAAWD,CAAM,GAClCM,IAAS,KAAK,IAAIF,IAAWD,CAAM;KAGzC,IAAIE,MAAU,KAAKC,MAAW,GAAG;MAC/B,AAAKC,KAAWT,EAAE,aAAa,CAAC,CAAC;MACjC;KACF;KAEA,IAAMU,IAAOV,EAAE,YAAY;MAAE;MAAG;MAAG;MAAO;KAAO,GAAGW,CAAI;KAExD,EAAE,aAAaC,EAAkBZ,EAAE,aAAa,GAAGU,GAAMD,CAAS,CAAC;IACrE;GACF;EACF;CACF;CAOA,eAAe;AACjB"}
1
+ {"version":3,"file":"areaSelect.js","names":["areaSelectAction","dep","ctx","affordanceKind","scratch","moveCtx","reason","d","x","startX","currentX","y","startY","currentY","width","height","shiftHeld","hits","view","selectionFromHits"],"sources":["../../../../src/interactions/actions/defaults/areaSelect.ts"],"sourcesContent":["import type { Action } from '@weasel-js/routing';\nimport type { InvocationCtx, OngoingHandle, OngoingOverlay } from '@weasel-js/routing';\nimport type { NodeId } from 'core/scene/types';\nimport type { AreaSelectDep, ViewApi } from '../depSchema';\nimport { selectionFromHits } from '../hitSelection';\n\ninterface AreaSelectScratch {\n dep: AreaSelectDep;\n /** The view the marquee started in: what it does not paint is not taken. */\n view: ViewApi | undefined;\n startX: number;\n startY: number;\n shiftHeld: boolean;\n currentX: number;\n currentY: number;\n /** Cleared once `onEnd` runs, so a consumer that retains the handle gets\n * no marquee from `overlay()`. */\n open: boolean;\n}\n\n/**\n * @experimental\n * Marquee selection: replace, or extend with shift held. Hit-testing and\n * selection writes are delegated to the `areaSelect` dep, and the selection\n * write makes no undo entry.\n */\nexport const areaSelectAction: Action & { requires: string[] } = {\n id: 'areaSelect',\n label: 'Area Select',\n activeCursor: 'crosshair',\n eligible: { capability: 'creates-selection' },\n requires: ['areaSelect', 'editAnchors', 'view'],\n invoker: {\n timing: 'ongoing',\n start(ctx: InvocationCtx, _opts): OngoingHandle {\n const dep = ctx.deps.areaSelect;\n if (!dep) return {};\n\n // Decline on anchor / control-handle affordances: the select tool's\n // `{ kind: 'drag', target: 'empty' }` binding also matches an anchor hit\n // on top of empty body, and would beat editAnchors via scope priority.\n const affordanceKind = ctx.drag?.affordance?.kind;\n if (\n typeof affordanceKind === 'string'\n && /^(anchor|controlIn|controlOut):/.test(affordanceKind)\n ) {\n return {};\n }\n\n // Decline while a path is in anchor-edit mode, where an empty-canvas\n // drag is `marqueeAnchorsAction`'s. Capability eligibility filters this\n // only for consumers that wired a mode registry; without one\n // areaSelect's active scope would beat marqueeAnchors' ambient scope.\n const editAnchors = ctx.deps.editAnchors;\n if (editAnchors?.editingId) return {};\n\n const scratch: AreaSelectScratch = {\n dep,\n view: ctx.deps.view,\n startX: ctx.world.x,\n startY: ctx.world.y,\n shiftHeld: ctx.modifiers.shift,\n currentX: ctx.world.x,\n currentY: ctx.world.y,\n open: true,\n };\n\n return {\n kind: 'marquee',\n onMove(moveCtx: InvocationCtx): void {\n scratch.currentX = moveCtx.world.x;\n scratch.currentY = moveCtx.world.y;\n },\n overlay(): OngoingOverlay | null {\n if (!scratch.open) return null;\n return {\n kind: 'marquee',\n start: { x: scratch.startX, y: scratch.startY },\n current: { x: scratch.currentX, y: scratch.currentY },\n shiftHeld: scratch.shiftHeld,\n };\n },\n onEnd(_endCtx: InvocationCtx, reason: 'commit' | 'cancel'): void {\n scratch.open = false;\n if (reason === 'cancel') return;\n\n const { dep: d, view, startX, startY, currentX, currentY, shiftHeld } = scratch;\n\n const x = Math.min(startX, currentX);\n const y = Math.min(startY, currentY);\n const width = Math.abs(currentX - startX);\n const height = Math.abs(currentY - startY);\n\n // Zero-size marquee (click without drag) → clear selection (or no-op with shift).\n if (width === 0 || height === 0) {\n if (!shiftHeld) d.setSelection([]);\n return;\n }\n\n const hits = d.hitTestArea({ x, y, width, height }, view) as NodeId[];\n\n d.setSelection(selectionFromHits(d.getSelection(), hits, shiftHeld));\n },\n };\n },\n },\n /** Always enabled: the dispatcher treats anything `!== true` as \"skip this\n * match\", so a disabled reason would let lower-specificity ambient bindings win. */\n enabled: () => true,\n};\n"],"mappings":";;AA0BA,IAAaA,IAAoD;CAC/D,IAAI;CACJ,OAAO;CACP,cAAc;CACd,UAAU,EAAE,YAAY,oBAAoB;CAC5C,UAAU;EAAC;EAAc;EAAe;CAAM;CAC9C,SAAS;EACP,QAAQ;EACR,MAAM,GAAoB,GAAsB;GAC9C,IAAMC,IAAMC,EAAI,KAAK;GACrB,IAAI,CAACD,GAAK,OAAO,CAAC;GAKlB,IAAME,IAAiBD,EAAI,MAAM,YAAY;GAa7C,IAXE,OAAOC,KAAmB,YACvB,kCAAkC,KAAKA,CAAc,KAStCD,EAAI,KAAK,aACZ,WAAW,OAAO,CAAC;GAEpC,IAAME,IAA6B;IACjC;IACA,MAAMF,EAAI,KAAK;IACf,QAAQA,EAAI,MAAM;IAClB,QAAQA,EAAI,MAAM;IAClB,WAAWA,EAAI,UAAU;IACzB,UAAUA,EAAI,MAAM;IACpB,UAAUA,EAAI,MAAM;IACpB,MAAM;GACR;GAEA,OAAO;IACL,MAAM;IACN,OAAO,GAA8B;KAEnC,AADA,EAAQ,WAAWG,EAAQ,MAAM,GACjC,EAAQ,WAAWA,EAAQ,MAAM;IACnC;IACA,UAAiC;KAE/B,OADKD,EAAQ,OACN;MACL,MAAM;MACN,OAAO;OAAE,GAAGA,EAAQ;OAAQ,GAAGA,EAAQ;MAAO;MAC9C,SAAS;OAAE,GAAGA,EAAQ;OAAU,GAAGA,EAAQ;MAAS;MACpD,WAAWA,EAAQ;KACrB,IAN0B;IAO5B;IACA,MAAM,GAAwB,GAAmC;KAE/D,IADA,EAAQ,OAAO,IACXE,MAAW,UAAU;KAEzB,IAAM,EAAE,KAAKC,GAAG,SAAM,WAAQ,WAAQ,aAAU,aAAU,iBAAcH,GAElEI,IAAI,KAAK,IAAIC,GAAQC,CAAQ,GAC7BC,IAAI,KAAK,IAAIC,GAAQC,CAAQ,GAC7BC,IAAQ,KAAK,IAAIJ,IAAWD,CAAM,GAClCM,IAAS,KAAK,IAAIF,IAAWD,CAAM;KAGzC,IAAIE,MAAU,KAAKC,MAAW,GAAG;MAC/B,AAAKC,KAAWT,EAAE,aAAa,CAAC,CAAC;MACjC;KACF;KAEA,IAAMU,IAAOV,EAAE,YAAY;MAAE;MAAG;MAAG;MAAO;KAAO,GAAGW,CAAI;KAExD,EAAE,aAAaC,EAAkBZ,EAAE,aAAa,GAAGU,GAAMD,CAAS,CAAC;IACrE;GACF;EACF;CACF;CAGA,eAAe;AACjB"}
@@ -0,0 +1,46 @@
1
+ import { editingLayer as e, inPlane as t } from "../planeInput.js";
2
+ import { pathEditPreview as n } from "../edit-anchors/preview.js";
3
+ import { segmentUnder as r } from "./segmentUnder.js";
4
+ import { bendSegment as i, editAnchorSetTracked as a } from "@weasel-js/geom";
5
+ import { ActionDisabledReason as o, isSegment as s } from "@weasel-js/routing";
6
+ var c = t({
7
+ id: "bendSegment",
8
+ label: "Bend segment",
9
+ defaultBinding: {
10
+ kind: "drag",
11
+ target: { kindOf: s }
12
+ },
13
+ cursor: "grab",
14
+ eligible: { capability: "edits-anchors" },
15
+ requires: ["editAnchors", "view"],
16
+ invoker: {
17
+ timing: "ongoing",
18
+ start(e) {
19
+ let t = r(e.deps, e.world.x, e.world.y);
20
+ if (!t) return {};
21
+ let { dep: o, path: s, hit: c } = t, l = o.editingId, u = {
22
+ x: e.world.x,
23
+ y: e.world.y
24
+ }, d = null, f = n(o, l, () => d?.path ?? null);
25
+ return f ? {
26
+ kind: "bend-segment",
27
+ onMove(e) {
28
+ let t = e.world.x - u.x, n = e.world.y - u.y;
29
+ d = a(s, (e) => i(e, c, t, n)) ?? d;
30
+ },
31
+ onEnd(e, t) {
32
+ let n = d;
33
+ d = null, t !== "cancel" && n && o.applyEdit(l, n.path, "Bend segment", n.origins);
34
+ },
35
+ previewIds: f.previewIds,
36
+ previewPose: f.previewPose,
37
+ previewData: f.previewData
38
+ } : {};
39
+ }
40
+ },
41
+ enabled: (e, t) => !e?.editAnchors?.editingId || t && !r(e, t.x, t.y) ? o.NotApplicable : !0
42
+ }, e);
43
+ //#endregion
44
+ export { c as bendSegmentAction };
45
+
46
+ //# sourceMappingURL=bendSegment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bendSegment.js","names":["bendSegmentAction","inPlane","isSegment","under","segmentUnder","ctx","originPath","id","dep","press","current","preview","pathEditPreview","dx","moveCtx","dy","editAnchorSetTracked","bendSegment","set","hit","done","reason","deps","at","ActionDisabledReason","editingLayer"],"sources":["../../../../src/interactions/actions/defaults/bendSegment.ts"],"sourcesContent":["/**\n * `bendSegmentAction` — drag a segment of the path being edited to reshape\n * it: the point pressed follows the pointer, and the segment's two handles\n * move to carry it (`bendSegment`). A straight segment becomes a curve.\n *\n * Bound to the `segment` affordance path edit lays along the outline, which\n * ties the marquee's `empty` and move's `selected-body` on specificity and\n * registers ahead of the marquee; move turns segment presses down itself.\n * An anchor's own affordance sits above the segment's, so a press on an\n * anchor is the anchor drag's.\n */\n\nimport type { Action, InvocationCtx, OngoingHandle } from '@weasel-js/routing';\nimport { ActionDisabledReason, isSegment } from '@weasel-js/routing';\nimport type { CursorSpec } from '@weasel-js/cursor';\nimport { bendSegment, editAnchorSetTracked, type PointOrigin, type PolygonPath } from '@weasel-js/geom';\nimport { inPlane, editingLayer } from '../planeInput';\nimport { pathEditPreview } from '../edit-anchors/preview';\nimport { segmentUnder } from './segmentUnder';\n\nconst BEND_CURSOR: CursorSpec = 'grab';\n\nexport const bendSegmentAction: Action & { requires: string[] } = inPlane({\n id: 'bendSegment',\n label: 'Bend segment',\n defaultBinding: { kind: 'drag', target: { kindOf: isSegment } },\n cursor: BEND_CURSOR,\n eligible: { capability: 'edits-anchors' },\n requires: ['editAnchors', 'view'],\n invoker: {\n timing: 'ongoing',\n start(ctx: InvocationCtx): OngoingHandle {\n const under = segmentUnder(ctx.deps, ctx.world.x, ctx.world.y);\n if (!under) return {};\n const { dep, path: originPath, hit } = under;\n const id = dep.editingId;\n const press = { x: ctx.world.x, y: ctx.world.y };\n let current: { path: PolygonPath; origins?: readonly (PointOrigin | null)[] } | null = null;\n const preview = pathEditPreview(dep, id, () => current?.path ?? null);\n if (!preview) return {};\n\n return {\n kind: 'bend-segment',\n onMove(moveCtx: InvocationCtx): void {\n const dx = moveCtx.world.x - press.x;\n const dy = moveCtx.world.y - press.y;\n current = editAnchorSetTracked(originPath, (set) => bendSegment(set, hit, dx, dy)) ?? current;\n },\n onEnd(_endCtx: InvocationCtx, reason: 'commit' | 'cancel'): void {\n const done = current;\n current = null;\n if (reason === 'cancel' || !done) return;\n dep.applyEdit(id, done.path, 'Bend segment', done.origins);\n },\n previewIds: preview.previewIds,\n previewPose: preview.previewPose,\n previewData: preview.previewData,\n };\n },\n },\n enabled: (deps, at) => {\n if (!deps?.editAnchors?.editingId) return ActionDisabledReason.NotApplicable;\n if (at && !segmentUnder(deps, at.x, at.y)) return ActionDisabledReason.NotApplicable;\n return true;\n },\n}, editingLayer);\n"],"mappings":";;;;;AAsBA,IAAaA,IAAqDC,EAAQ;CACxE,IAAI;CACJ,OAAO;CACP,gBAAgB;EAAE,MAAM;EAAQ,QAAQ,EAAE,QAAQC,EAAU;CAAE;CAC9D,QAAQ;CACR,UAAU,EAAE,YAAY,gBAAgB;CACxC,UAAU,CAAC,eAAe,MAAM;CAChC,SAAS;EACP,QAAQ;EACR,MAAM,GAAmC;GACvC,IAAMC,IAAQC,EAAaC,EAAI,MAAMA,EAAI,MAAM,GAAGA,EAAI,MAAM,CAAC;GAC7D,IAAI,CAACF,GAAO,OAAO,CAAC;GACpB,IAAM,EAAE,QAAK,MAAMG,GAAY,WAAQH,GACjCI,IAAKC,EAAI,WACTC,IAAQ;IAAE,GAAGJ,EAAI,MAAM;IAAG,GAAGA,EAAI,MAAM;GAAE,GAC3CK,IAAmF,MACjFC,IAAUC,EAAgBJ,GAAKD,SAAUG,GAAS,QAAQ,IAAI;GAGpE,OAFKC,IAEE;IACL,MAAM;IACN,OAAO,GAA8B;KACnC,IAAME,IAAKC,EAAQ,MAAM,IAAIL,EAAM,GAC7BM,IAAKD,EAAQ,MAAM,IAAIL,EAAM;KACnC,IAAUO,EAAqBV,IAAa,MAAQW,EAAYC,GAAKC,GAAKN,GAAIE,CAAE,CAAC,KAAKL;IACxF;IACA,MAAM,GAAwB,GAAmC;KAC/D,IAAMU,IAAOV;KAEb,AADA,IAAU,MACNW,MAAW,YAAaD,KAC5BZ,EAAI,UAAUD,GAAIa,EAAK,MAAM,gBAAgBA,EAAK,OAAO;IAC3D;IACA,YAAYT,EAAQ;IACpB,aAAaA,EAAQ;IACrB,aAAaA,EAAQ;GACvB,IAlBqB,CAAC;EAmBxB;CACF;CACA,UAAU,GAAM,MACV,CAACW,GAAM,aAAa,aACpBC,KAAM,CAACnB,EAAakB,GAAMC,EAAG,GAAGA,EAAG,CAAC,IAAUC,EAAqB,gBAChE;AAEX,GAAGC,CAAY"}
@@ -1 +1 @@
1
- {"version":3,"file":"cancelGesture.js","names":["cancelGestureAction"],"sources":["../../../../src/interactions/actions/defaults/cancelGesture.ts"],"sourcesContent":["import type { Action } from '@weasel-js/routing';\n\n/**\n * @experimental\n * Static descriptor for the `cancelGesture` Action — Escape mid-drag\n * tells the dispatcher to abort every in-flight handle (`onEnd('cancel')`\n * on each, scratch discarded, no scene mutation).\n *\n * Phase-gated to `[*:engaged]` so it fires only when at least one tool\n * has a handle in flight; the unmodified `escape` action retains its\n * idle-phase binding (clears selection) without conflict.\n */\n// No `eligible` field → always eligible. Cancelling an in-flight gesture\n// must work regardless of mode.\nexport const cancelGestureAction: Action & { requires: string[] } = {\n id: 'cancelGesture',\n label: 'Cancel gesture',\n defaultBinding: {\n kind: 'key',\n key: 'Escape',\n phase: [{ channel: '*', phase: 'engaged' }],\n },\n requires: ['dispatcher'],\n invoker: {\n timing: 'immediate',\n run: (deps) => {\n const d = deps.dispatcher;\n d?.cancelAll('cancel');\n },\n },\n};\n"],"mappings":";AAcA,IAAaA,IAAuD;CAClE,IAAI;CACJ,OAAO;CACP,gBAAgB;EACd,MAAM;EACN,KAAK;EACL,OAAO,CAAC;GAAE,SAAS;GAAK,OAAO;EAAU,CAAC;CAC5C;CACA,UAAU,CAAC,YAAY;CACvB,SAAS;EACP,QAAQ;EACR,MAAM,MAAS;GAEb,EADe,YACZ,UAAU,QAAQ;EACvB;CACF;AACF"}
1
+ {"version":3,"file":"cancelGesture.js","names":["cancelGestureAction"],"sources":["../../../../src/interactions/actions/defaults/cancelGesture.ts"],"sourcesContent":["import type { Action } from '@weasel-js/routing';\n\n/**\n * @experimental\n * Escape mid-drag tells the dispatcher to abort every in-flight handle\n * (`onEnd('cancel')` on each, no scene mutation).\n *\n * Phase-gated to `[*:engaged]` so it fires only when a handle is in flight,\n * leaving the idle-phase `escape` action (clears selection) without conflict.\n */\n// No `eligible` field: canceling an in-flight gesture must work in every mode.\nexport const cancelGestureAction: Action & { requires: string[] } = {\n id: 'cancelGesture',\n label: 'Cancel gesture',\n defaultBinding: {\n kind: 'key',\n key: 'Escape',\n phase: [{ channel: '*', phase: 'engaged' }],\n },\n requires: ['dispatcher'],\n invoker: {\n timing: 'immediate',\n run: (deps) => {\n const d = deps.dispatcher;\n d?.cancelAll('cancel');\n },\n },\n};\n"],"mappings":";AAWA,IAAaA,IAAuD;CAClE,IAAI;CACJ,OAAO;CACP,gBAAgB;EACd,MAAM;EACN,KAAK;EACL,OAAO,CAAC;GAAE,SAAS;GAAK,OAAO;EAAU,CAAC;CAC5C;CACA,UAAU,CAAC,YAAY;CACvB,SAAS;EACP,QAAQ;EACR,MAAM,MAAS;GAEb,EADe,YACZ,UAAU,QAAQ;EACvB;CACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"clearSelection.js","names":["clearSelectionAction","deps","ActionDisabledReason"],"sources":["../../../../src/interactions/actions/defaults/clearSelection.ts"],"sourcesContent":["/**\n * `clearSelectionAction` — immediate Action descriptor for click-on-empty\n * selection clearing.\n *\n * ## Status: REAL\n *\n * Fires via `useSelectTool.bindings` when the user clicks on empty canvas\n * with no modifier held. Clears the selection by calling `deps.selection.set([])`.\n *\n * ## No defaultBinding\n *\n * This action has no ambient `defaultBinding` / `defaultBinding` — it fires\n * ONLY via `useSelectTool`'s `Tool.bindings` entry:\n * `{ spec: { kind: 'click', target: 'empty', mods: {} }, actionId: 'clearSelection' }`\n *\n * This avoids ambient double-fire and keeps the action scoped to select-tool\n * context where `classifyTarget` is wired.\n *\n * ## enabled — the anchor-editing fall-through\n *\n * There is no \"is anything selected?\" guard: clearing an already-empty\n * selection is a safe no-op, and the binding spec is the real gate for\n * where the click landed.\n *\n * What `enabled` *does* do is decline while a path is in anchor-edit mode,\n * so the dispatcher falls through to `selectAnchorAction`. This is the\n * click twin of the opt-out `areaSelectAction.start` already performs for\n * the drag gesture, and it exists for the same reason: `useSelectTool`\n * binds this action at **active** scope while `selectAnchor` is **ambient**,\n * so without the gate an anchor that happens to sit over empty canvas\n * clears the node selection instead of selecting the anchor.\n *\n * Capability eligibility (`creates-selection`, which `path-edit` does not\n * allow) already covers consumers that wired a mode registry. Consumers\n * without one get no eligibility filtering at all, so this gate is the only\n * thing separating the two. Both mechanisms are needed — see the header of\n * `anchorEditing.ts`.\n */\n\nimport type { Action } from '@weasel-js/routing';\nimport { ActionDisabledReason } from '@weasel-js/routing';\nimport type { ActionDeps } from '@weasel-js/routing';\n\n/**\n * @experimental\n * Static descriptor for the `clearSelection` Action.\n *\n * Requires dep-schema entries: `selection`, `editAnchors`.\n *\n * Registered via `useStandardActions`; bound via `useSelectTool.bindings`.\n */\nexport const clearSelectionAction: Action & { requires: string[] } = {\n id: 'clearSelection',\n label: 'Clear selection',\n // No defaultBinding / defaultBinding — fires only via Tool.bindings.\n eligible: { capability: 'creates-selection' },\n // `editAnchors` is required for the `enabled` gate below, not for the run.\n requires: ['selection', 'editAnchors'],\n invoker: {\n timing: 'immediate',\n run: (deps) => {\n deps.selection?.set([]);\n },\n },\n enabled: (deps?: ActionDeps) => {\n const editAnchors = deps?.editAnchors;\n // Absent dep means the consumer never wired anchor editing — nothing to\n // defer to, so the click is ours.\n if (editAnchors?.editingId) return ActionDisabledReason.NotApplicable;\n return true;\n },\n};\n"],"mappings":";;AAmDA,IAAaA,IAAwD;CACnE,IAAI;CACJ,OAAO;CAEP,UAAU,EAAE,YAAY,oBAAoB;CAE5C,UAAU,CAAC,aAAa,aAAa;CACrC,SAAS;EACP,QAAQ;EACR,MAAM,MAAS;GACb,EAAK,WAAW,IAAI,CAAC,CAAC;EACxB;CACF;CACA,UAAU,MAIR,CAHoBC,GAAM,aAGT,aAAkBC,EAAqB;AAG5D"}
1
+ {"version":3,"file":"clearSelection.js","names":["clearSelectionAction","deps","ActionDisabledReason"],"sources":["../../../../src/interactions/actions/defaults/clearSelection.ts"],"sourcesContent":["import type { Action } from '@weasel-js/routing';\nimport { ActionDisabledReason } from '@weasel-js/routing';\nimport type { ActionDeps } from '@weasel-js/routing';\n\n/**\n * @experimental\n * Clears the selection on a click on empty canvas. It has no ambient\n * `defaultBinding`: it fires only through `useSelectTool`'s bindings.\n *\n * `enabled` declines while a path is in anchor-edit mode, so the dispatcher\n * falls through to `selectAnchorAction`. `useSelectTool` binds this action at\n * **active** scope while `selectAnchor` is **ambient**, so without the gate an\n * anchor that sits over empty canvas clears the node selection instead of\n * selecting the anchor. Capability eligibility covers only consumers that\n * wired a mode registry.\n */\nexport const clearSelectionAction: Action & { requires: string[] } = {\n id: 'clearSelection',\n label: 'Clear selection',\n eligible: { capability: 'creates-selection' },\n // `editAnchors` is required for the `enabled` gate below, not for the run.\n requires: ['selection', 'editAnchors'],\n invoker: {\n timing: 'immediate',\n run: (deps) => {\n deps.selection?.set([]);\n },\n },\n enabled: (deps?: ActionDeps) => {\n const editAnchors = deps?.editAnchors;\n // Absent dep means the consumer never wired anchor editing — nothing to\n // defer to, so the click is ours.\n if (editAnchors?.editingId) return ActionDisabledReason.NotApplicable;\n return true;\n },\n};\n"],"mappings":";;AAgBA,IAAaA,IAAwD;CACnE,IAAI;CACJ,OAAO;CACP,UAAU,EAAE,YAAY,oBAAoB;CAE5C,UAAU,CAAC,aAAa,aAAa;CACrC,SAAS;EACP,QAAQ;EACR,MAAM,MAAS;GACb,EAAK,WAAW,IAAI,CAAC,CAAC;EACxB;CACF;CACA,UAAU,MAIR,CAHoBC,GAAM,aAGT,aAAkBC,EAAqB;AAG5D"}
@@ -27,7 +27,7 @@ function r(t, r, i, a) {
27
27
  }
28
28
  for (let e of o) {
29
29
  let t = e.args.node, n = t.dependsOn;
30
- Array.isArray(n) && n.every((e) => c.has(e)) && (t.dependsOn = n.map((e) => c.get(e)));
30
+ Array.isArray(n) && n.some((e) => c.has(e)) && (t.dependsOn = n.map((e) => c.get(e) ?? e));
31
31
  }
32
32
  return {
33
33
  ops: o,
@@ -1 +1 @@
1
- {"version":3,"file":"copySubtree.js","names":["copySubtree","node","scene","id","newId","copy","poseOf","isRoot","createInsertOp","child","label","ops","copyOf","copySelection","copies","selectedRoots","ids","op","deps","dep"],"sources":["../../../../src/interactions/actions/defaults/copySubtree.ts"],"sourcesContent":["import type { Node, NodeId, Scene } from 'core/scene/types';\nimport type { Op } from 'core/ops/types';\nimport { createInsertOp } from 'core/ops/create';\nimport { selectedRoots } from '../selectionSubtree';\n\ntype AnyScene = Scene<unknown, string, unknown>;\ntype AnyNode = Node<unknown, string, unknown>;\n\n/** The pose a copy of `node` is stored with. `isRoot` is true for a selected\n * node and false for one copied because an ancestor was. */\nexport type CopyPose = (id: NodeId, node: AnyNode, isRoot: boolean) => unknown;\n\nfunction copySubtree(\n scene: AnyScene,\n id: NodeId,\n parent: NodeId | null,\n isRoot: boolean,\n poseOf: CopyPose,\n label: string,\n ops: Op[],\n copyOf: Map<NodeId, NodeId>,\n): NodeId | null {\n const node = scene.get(id);\n if (!node) return null;\n const newId = scene.mintId();\n copyOf.set(id, newId);\n const copy = { ...node, id: newId, pose: poseOf(id, node, isRoot), parent } as AnyNode;\n ops.push(createInsertOp<AnyNode>({ node: copy, label }));\n for (const child of scene.childrenOf(id)) {\n copySubtree(scene, child, newId, false, poseOf, label, ops, copyOf);\n }\n return newId;\n}\n\n/**\n * Insert ops copying each of `ids` with its whole subtree, so copying a group\n * produces a populated group. Ops are in pre-order: a parent is inserted\n * before its children. A copied root keeps its source's parent.\n *\n * A copy that derives from an id list follows the copies when every node in\n * the list was copied with it, and keeps the original list otherwise.\n */\nexport function copySelection(\n scene: AnyScene,\n ids: readonly string[],\n poseOf: CopyPose,\n label: string,\n): { ops: Op[]; copies: NodeId[] } {\n const ops: Op[] = [];\n const copies: NodeId[] = [];\n const copyOf = new Map<NodeId, NodeId>();\n for (const id of selectedRoots(scene, ids)) {\n const newId = copySubtree(scene, id, scene.get(id)?.parent ?? null, true, poseOf, label, ops, copyOf);\n if (newId) copies.push(newId);\n }\n for (const op of ops) {\n const node = (op.args as { node: AnyNode }).node;\n const deps = node.dependsOn;\n if (!Array.isArray(deps) || !deps.every((dep) => copyOf.has(dep))) continue;\n (node as { dependsOn?: readonly NodeId[] }).dependsOn = deps.map((dep) => copyOf.get(dep)!);\n }\n return { ops, copies };\n}\n"],"mappings":";;;AAYA,SAASA,EACP,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACe;CACf,IAAMC,IAAOC,EAAM,IAAIC,CAAE;CACzB,IAAI,CAACF,GAAM,OAAO;CAClB,IAAMG,IAAQF,EAAM,OAAO;CAC3B,EAAO,IAAIC,GAAIC,CAAK;CACpB,IAAMC,IAAO;EAAE,GAAGJ;EAAM,IAAIG;EAAO,MAAME,EAAOH,GAAIF,GAAMM,CAAM;EAAG;CAAO;CAC1E,EAAI,KAAKC,EAAwB;EAAE,MAAMH;EAAM;CAAM,CAAC,CAAC;CACvD,KAAK,IAAMI,KAASP,EAAM,WAAWC,CAAE,GACrC,EAAYD,GAAOO,GAAOL,GAAO,IAAOE,GAAQI,GAAOC,GAAKC,CAAM;CAEpE,OAAOR;AACT;AAUA,SAAgBS,EACd,GACA,GACA,GACA,GACiC;CACjC,IAAMF,IAAY,CAAC,GACbG,IAAmB,CAAC,GACpBF,oBAAS,IAAI,IAAoB;CACvC,KAAK,IAAMT,KAAMY,EAAcb,GAAOc,CAAG,GAAG;EAC1C,IAAMZ,IAAQJ,EAAYE,GAAOC,GAAID,EAAM,IAAIC,CAAE,CAAC,EAAE,UAAU,MAAM,IAAMG,GAAQI,GAAOC,GAAKC,CAAM;EACpG,AAAIR,KAAOU,EAAO,KAAKV,CAAK;CAC9B;CACA,KAAK,IAAMa,KAAMN,GAAK;EACpB,IAAMV,IAAQgB,EAAG,KAA2B,MACtCC,IAAOjB,EAAK;EAClB,AAAK,MAAM,QAAQiB,CAAI,KAAMA,EAAK,OAAO,MAAQN,EAAO,IAAIO,CAAG,CAAC,MAChE,EAA4C,YAAYD,EAAK,KAAK,MAAQN,EAAO,IAAIO,CAAG,CAAE;CAC5F;CACA,OAAO;EAAE;EAAK;CAAO;AACvB"}
1
+ {"version":3,"file":"copySubtree.js","names":["copySubtree","node","scene","id","newId","copy","poseOf","isRoot","createInsertOp","child","label","ops","copyOf","copySelection","copies","selectedRoots","ids","op","deps","dep"],"sources":["../../../../src/interactions/actions/defaults/copySubtree.ts"],"sourcesContent":["import type { Node, NodeId, Scene } from 'core/scene/types';\nimport type { Op } from 'core/ops/types';\nimport { createInsertOp } from 'core/ops/create';\nimport { selectedRoots } from '../selectionSubtree';\n\ntype AnyScene = Scene<unknown, string, unknown>;\ntype AnyNode = Node<unknown, string, unknown>;\n\n/** The pose a copy of `node` is stored with. `isRoot` is true for a selected\n * node and false for one copied because an ancestor was. */\nexport type CopyPose = (id: NodeId, node: AnyNode, isRoot: boolean) => unknown;\n\nfunction copySubtree(\n scene: AnyScene,\n id: NodeId,\n parent: NodeId | null,\n isRoot: boolean,\n poseOf: CopyPose,\n label: string,\n ops: Op[],\n copyOf: Map<NodeId, NodeId>,\n): NodeId | null {\n const node = scene.get(id);\n if (!node) return null;\n const newId = scene.mintId();\n copyOf.set(id, newId);\n const copy = { ...node, id: newId, pose: poseOf(id, node, isRoot), parent } as AnyNode;\n ops.push(createInsertOp<AnyNode>({ node: copy, label }));\n for (const child of scene.childrenOf(id)) {\n copySubtree(scene, child, newId, false, poseOf, label, ops, copyOf);\n }\n return newId;\n}\n\n/**\n * Insert ops copying each of `ids` with its whole subtree, so copying a group\n * produces a populated group. Ops are in pre-order: a parent is inserted\n * before its children. A copied root keeps its source's parent.\n *\n * A copy that derives from an id list follows the copy of each node in the\n * list that was copied with it, and the original of each that was not: the\n * originals are still in the scene to follow.\n */\nexport function copySelection(\n scene: AnyScene,\n ids: readonly string[],\n poseOf: CopyPose,\n label: string,\n): { ops: Op[]; copies: NodeId[] } {\n const ops: Op[] = [];\n const copies: NodeId[] = [];\n const copyOf = new Map<NodeId, NodeId>();\n for (const id of selectedRoots(scene, ids)) {\n const newId = copySubtree(scene, id, scene.get(id)?.parent ?? null, true, poseOf, label, ops, copyOf);\n if (newId) copies.push(newId);\n }\n for (const op of ops) {\n const node = (op.args as { node: AnyNode }).node;\n const deps = node.dependsOn;\n if (!Array.isArray(deps) || !deps.some((dep) => copyOf.has(dep))) continue;\n (node as { dependsOn?: readonly NodeId[] }).dependsOn = deps.map((dep) => copyOf.get(dep) ?? dep);\n }\n return { ops, copies };\n}\n"],"mappings":";;;AAYA,SAASA,EACP,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACe;CACf,IAAMC,IAAOC,EAAM,IAAIC,CAAE;CACzB,IAAI,CAACF,GAAM,OAAO;CAClB,IAAMG,IAAQF,EAAM,OAAO;CAC3B,EAAO,IAAIC,GAAIC,CAAK;CACpB,IAAMC,IAAO;EAAE,GAAGJ;EAAM,IAAIG;EAAO,MAAME,EAAOH,GAAIF,GAAMM,CAAM;EAAG;CAAO;CAC1E,EAAI,KAAKC,EAAwB;EAAE,MAAMH;EAAM;CAAM,CAAC,CAAC;CACvD,KAAK,IAAMI,KAASP,EAAM,WAAWC,CAAE,GACrC,EAAYD,GAAOO,GAAOL,GAAO,IAAOE,GAAQI,GAAOC,GAAKC,CAAM;CAEpE,OAAOR;AACT;AAWA,SAAgBS,EACd,GACA,GACA,GACA,GACiC;CACjC,IAAMF,IAAY,CAAC,GACbG,IAAmB,CAAC,GACpBF,oBAAS,IAAI,IAAoB;CACvC,KAAK,IAAMT,KAAMY,EAAcb,GAAOc,CAAG,GAAG;EAC1C,IAAMZ,IAAQJ,EAAYE,GAAOC,GAAID,EAAM,IAAIC,CAAE,CAAC,EAAE,UAAU,MAAM,IAAMG,GAAQI,GAAOC,GAAKC,CAAM;EACpG,AAAIR,KAAOU,EAAO,KAAKV,CAAK;CAC9B;CACA,KAAK,IAAMa,KAAMN,GAAK;EACpB,IAAMV,IAAQgB,EAAG,KAA2B,MACtCC,IAAOjB,EAAK;EAClB,AAAK,MAAM,QAAQiB,CAAI,KAAMA,EAAK,MAAM,MAAQN,EAAO,IAAIO,CAAG,CAAC,MAC/D,EAA4C,YAAYD,EAAK,KAAK,MAAQN,EAAO,IAAIO,CAAG,KAAKA,CAAG;CAClG;CACA,OAAO;EAAE;EAAK;CAAO;AACvB"}
@@ -1 +1 @@
1
- {"version":3,"file":"createPaintAction.js","names":["createPaintAction","refreshPreviews","id","scratch","prev","next","spec","selection","ctx","scene","applyOps","ids","fallback","opts","pick","key","startData","node","moveCtx","reason","ops","merged","nodeNow","from","to","createSetDataOp","defaultCommitAdapter","sel","deps","ActionDisabledReason"],"sources":["../../../../src/interactions/actions/defaults/createPaintAction.ts"],"sourcesContent":["import type { Action } from '@weasel-js/routing';\nimport type { InvocationCtx, OngoingHandle, BindingOpts } from '@weasel-js/routing';\nimport { ActionDisabledReason } from '@weasel-js/routing';\nimport type { Scene, NodeId } from 'core/scene/types';\nimport type { Op } from 'core/ops/types';\nimport { createSetDataOp } from 'core/ops/setData';\nimport { defaultCommitAdapter } from '../defaultCommitAdapter';\n\n/** The node data one paint action reads and writes: its own key, nothing else. */\ntype PaintData<K extends string, TValue> = { [P in K]?: TValue | null };\n\ntype Params = Record<string, unknown> | undefined;\n\n/** Read a param from the invocation, falling back to the binding's. */\nexport type PickParam = <T>(key: string) => T | undefined;\n\n/**\n * What distinguishes one paint action from the other three.\n *\n * `TState` is the action's gesture state — a color plus an optional paint for\n * the two setters, a bare alpha for the two opacity actions. It is a reducer,\n * not a paint: `setFill` and `setStroke` supersede a paint with a later color,\n * which no per-field merge of the params can express.\n */\nexport interface PaintActionSpec<TState, TValue, K extends string> {\n id: string;\n label: string;\n /** The `data` key this action owns. */\n dataKey: K;\n /** Gesture state at start. */\n initialState(pick: PickParam): TState;\n /** The state one onMove tick moves to, or `null` when its params carry\n * nothing this action reads — the preview then stands. */\n readParams(prev: TState, params: Params): TState | null;\n /** The value to write for one node, from that node's value at gesture start.\n * `null` writes the absence of paint, which is a value like any other —\n * a node with `fill: null` paints no fill. */\n merge(prev: TValue | null | undefined, state: TState): TValue | null;\n}\n\ninterface Scratch<TState, TValue, K extends string> {\n ids: NodeId[];\n scene: Scene<PaintData<K, TValue>, string, unknown>;\n /** Data snapshot at gesture start, keyed by node id. */\n startData: Map<NodeId, PaintData<K, TValue>>;\n state: TState;\n /** Preview data entries — the merged value per selected node. Populated on\n * start and refreshed on every onMove. */\n previews: Map<NodeId, PaintData<K, TValue>>;\n /** Optional consumer commit hook captured at gesture start. When present,\n * the ops-based commit routes through it (consumer history) instead of\n * `scene.applyBatch`. Undefined → fall back to `scene.applyBatch`. */\n applyOps?: (ops: Op[], label: string) => void;\n}\n\n/**\n * The one ongoing-action body the four paint actions share.\n *\n * On start it captures each selected node's data; on each onMove it refreshes\n * the preview without touching the scene; on commit it emits one\n * `createSetDataOp` per node (from = pre-commit data, to = the same data with\n * the merged value) and routes the batch through the consumer `applyOps` hook\n * when present (consumer history) else `scene.applyBatch` +\n * `defaultCommitAdapter` (whose `setData` delegates to `scene.update({ data })`).\n * Either path is a single batch → one undo entry.\n *\n * The `from` data is re-read at commit rather than reused from the start\n * snapshot, so a concurrent edit to a field this action does not own is not\n * clobbered.\n */\nexport function createPaintAction<TState, TValue, K extends string>(\n spec: PaintActionSpec<TState, TValue, K>,\n): Action & { requires: string[] } {\n type Data = PaintData<K, TValue>;\n\n const refreshPreviews = (scratch: Scratch<TState, TValue, K>): void => {\n scratch.previews.clear();\n for (const id of scratch.ids) {\n const prev = scratch.startData.get(id);\n const next = spec.merge(prev?.[spec.dataKey], scratch.state);\n scratch.previews.set(id, { ...(prev ?? {}), [spec.dataKey]: next } as Data);\n }\n };\n\n return {\n id: spec.id,\n label: spec.label,\n eligible: { capability: 'applies-fill' },\n requires: ['selection', 'scene', 'applyOps'],\n invoker: {\n timing: 'ongoing',\n start(ctx: InvocationCtx, opts?: BindingOpts): OngoingHandle {\n const selection = ctx.deps.selection;\n const scene = ctx.deps.scene as Scene<Data, string, unknown> | undefined;\n const applyOps = ctx.deps.applyOps;\n\n if (!selection || !scene) return {};\n\n const ids = selection.get() as NodeId[];\n if (ids.length === 0) return {};\n\n const fallback = opts?.params as Params;\n const pick = (<T>(key: string) =>\n (ctx.params?.[key] ?? fallback?.[key]) as T | undefined) as PickParam;\n\n const startData = new Map<NodeId, Data>();\n for (const id of ids) {\n const node = scene.get(id);\n if (node) startData.set(id, { ...(node.data as Data) });\n }\n\n const scratch: Scratch<TState, TValue, K> = {\n ids,\n scene,\n startData,\n state: spec.initialState(pick),\n previews: new Map(),\n applyOps,\n };\n refreshPreviews(scratch);\n\n return {\n onMove(moveCtx: InvocationCtx): void {\n const next = spec.readParams(scratch.state, moveCtx.params);\n if (next === null) return;\n scratch.state = next;\n refreshPreviews(scratch);\n },\n onEnd(_endCtx: InvocationCtx, reason: 'commit' | 'cancel'): void {\n if (reason === 'cancel') {\n scratch.previews.clear();\n return;\n }\n const ops: Op[] = [];\n for (const id of scratch.ids) {\n const merged = spec.merge(\n scratch.startData.get(id)?.[spec.dataKey],\n scratch.state,\n );\n const nodeNow = scratch.scene.get(id);\n if (!nodeNow) continue;\n const from = { ...(nodeNow.data as object) } as Data;\n const to = { ...from, [spec.dataKey]: merged } as Data;\n ops.push(createSetDataOp<Data>({ id: id as string, from, to }));\n }\n if (ops.length > 0) {\n if (scratch.applyOps) scratch.applyOps(ops, spec.label);\n else scratch.scene.applyBatch(ops, spec.label, defaultCommitAdapter(scratch.scene, selection.adapterMethods));\n }\n scratch.previews.clear();\n },\n previewIds: () => scratch.previews.keys(),\n previewData: (id: string) => scratch.previews.get(id as unknown as NodeId) ?? null,\n };\n },\n },\n enabled: (deps) => {\n const sel = deps?.selection;\n if (!sel || (sel.get() as unknown[]).length === 0) {\n return ActionDisabledReason.SelectionRequired;\n }\n return true;\n },\n };\n}\n"],"mappings":";;;;AAsEA,SAAgBA,EACd,GACiC;CAGjC,IAAMC,KAAmB,MAA8C;EACrE,EAAQ,SAAS,MAAM;EACvB,KAAK,IAAMC,KAAMC,EAAQ,KAAK;GAC5B,IAAMC,IAAOD,EAAQ,UAAU,IAAID,CAAE,GAC/BG,IAAOC,EAAK,MAAMF,IAAOE,EAAK,UAAUH,EAAQ,KAAK;GAC3D,EAAQ,SAAS,IAAID,GAAI;IAAE,GAAIE,KAAQ,CAAC;KAAKE,EAAK,UAAUD;GAAK,CAAS;EAC5E;CACF;CAEA,OAAO;EACL,IAAIC,EAAK;EACT,OAAOA,EAAK;EACZ,UAAU,EAAE,YAAY,eAAe;EACvC,UAAU;GAAC;GAAa;GAAS;EAAU;EAC3C,SAAS;GACP,QAAQ;GACR,MAAM,GAAoB,GAAmC;IAC3D,IAAMC,IAAYC,EAAI,KAAK,WACrBC,IAAQD,EAAI,KAAK,OACjBE,IAAWF,EAAI,KAAK;IAE1B,IAAI,CAACD,KAAa,CAACE,GAAO,OAAO,CAAC;IAElC,IAAME,IAAMJ,EAAU,IAAI;IAC1B,IAAII,EAAI,WAAW,GAAG,OAAO,CAAC;IAE9B,IAAMC,IAAWC,GAAM,QACjBC,MAAY,MACfN,EAAI,SAASO,MAAQH,IAAWG,KAE7BC,oBAAY,IAAI,IAAkB;IACxC,KAAK,IAAMd,KAAMS,GAAK;KACpB,IAAMM,IAAOR,EAAM,IAAIP,CAAE;KACzB,AAAIe,KAAMD,EAAU,IAAId,GAAI,EAAE,GAAIe,EAAK,KAAc,CAAC;IACxD;IAEA,IAAMd,IAAsC;KAC1C;KACA;KACA;KACA,OAAOG,EAAK,aAAaQ,CAAI;KAC7B,0BAAU,IAAI,IAAI;KAClB;IACF;IAGA,OAFAb,EAAgBE,CAAO,GAEhB;KACL,OAAO,GAA8B;MACnC,IAAME,IAAOC,EAAK,WAAWH,EAAQ,OAAOe,EAAQ,MAAM;MAC1D,AAAIb,MAAS,SACb,EAAQ,QAAQA,GAChBJ,EAAgBE,CAAO;KACzB;KACA,MAAM,GAAwB,GAAmC;MAC/D,IAAIgB,MAAW,UAAU;OACvB,EAAQ,SAAS,MAAM;OACvB;MACF;MACA,IAAMC,IAAY,CAAC;MACnB,KAAK,IAAMlB,KAAMC,EAAQ,KAAK;OAC5B,IAAMkB,IAASf,EAAK,MAClBH,EAAQ,UAAU,IAAID,CAAE,CAAC,GAAGI,EAAK,UACjCH,EAAQ,KACV,GACMmB,IAAUnB,EAAQ,MAAM,IAAID,CAAE;OACpC,IAAI,CAACoB,GAAS;OACd,IAAMC,IAAO,EAAE,GAAID,EAAQ,KAAgB,GACrCE,IAAK;QAAE,GAAGD;SAAOjB,EAAK,UAAUe;OAAO;OAC7C,EAAI,KAAKI,EAAsB;QAAM;QAAc;QAAM;OAAG,CAAC,CAAC;MAChE;MAKA,AAJIL,EAAI,SAAS,MACXjB,EAAQ,WAAUA,EAAQ,SAASiB,GAAKd,EAAK,KAAK,IACjDH,EAAQ,MAAM,WAAWiB,GAAKd,EAAK,OAAOoB,EAAqBvB,EAAQ,OAAOI,EAAU,cAAc,CAAC,IAE9GJ,EAAQ,SAAS,MAAM;KACzB;KACA,kBAAkBA,EAAQ,SAAS,KAAK;KACxC,cAAc,MAAeA,EAAQ,SAAS,IAAID,CAAuB,KAAK;IAChF;GACF;EACF;EACA,UAAU,MAAS;GACjB,IAAMyB,IAAMC,GAAM;GAIlB,OAHI,CAACD,KAAQA,EAAI,IAAI,CAAC,CAAe,WAAW,IACvCE,EAAqB,oBAEvB;EACT;CACF;AACF"}
1
+ {"version":3,"file":"createPaintAction.js","names":["createPaintAction","refreshPreviews","id","scratch","prev","next","spec","selection","ctx","scene","applyOps","ids","fallback","opts","pick","key","startData","node","moveCtx","reason","ops","merged","nodeNow","from","to","createSetDataOp","defaultCommitAdapter","sel","deps","ActionDisabledReason"],"sources":["../../../../src/interactions/actions/defaults/createPaintAction.ts"],"sourcesContent":["import type { Action } from '@weasel-js/routing';\nimport type { InvocationCtx, OngoingHandle, BindingOpts } from '@weasel-js/routing';\nimport { ActionDisabledReason } from '@weasel-js/routing';\nimport type { Scene, NodeId } from 'core/scene/types';\nimport type { Op } from 'core/ops/types';\nimport { createSetDataOp } from 'core/ops/setData';\nimport { defaultCommitAdapter } from '../defaultCommitAdapter';\n\n/** The node data one paint action reads and writes: its own key, nothing else. */\ntype PaintData<K extends string, TValue> = { [P in K]?: TValue | null };\n\ntype Params = Record<string, unknown> | undefined;\n\n/** Read a param from the invocation, falling back to the binding's. */\nexport type PickParam = <T>(key: string) => T | undefined;\n\n/**\n * What distinguishes one paint action from another.\n *\n * `TState` is the action's gesture state. It is a reducer, not a paint:\n * `setFill` and `setStroke` supersede a paint with a later color, which no\n * per-field merge of the params can express.\n */\nexport interface PaintActionSpec<TState, TValue, K extends string> {\n id: string;\n label: string;\n /** The `data` key this action owns. */\n dataKey: K;\n /** Gesture state at start. */\n initialState(pick: PickParam): TState;\n /** The state one onMove tick moves to, or `null` when its params carry\n * nothing this action reads — the preview then stands. */\n readParams(prev: TState, params: Params): TState | null;\n /** The value to write for one node, from that node's value at gesture start.\n * `null` writes the absence of paint, which is a value like any other —\n * a node with `fill: null` paints no fill. */\n merge(prev: TValue | null | undefined, state: TState): TValue | null;\n}\n\ninterface Scratch<TState, TValue, K extends string> {\n ids: NodeId[];\n scene: Scene<PaintData<K, TValue>, string, unknown>;\n /** Data snapshot at gesture start, keyed by node id. */\n startData: Map<NodeId, PaintData<K, TValue>>;\n state: TState;\n /** Preview data entries — the merged value per selected node. */\n previews: Map<NodeId, PaintData<K, TValue>>;\n /** Consumer commit hook captured at gesture start; undefined falls back to\n * `scene.applyBatch`. */\n applyOps?: (ops: Op[], label: string) => void;\n}\n\n/**\n * The ongoing-action body the paint actions share: it previews without\n * touching the scene, and commits one batch (one undo entry) through the\n * consumer `applyOps` hook when present, else `scene.applyBatch`.\n *\n * The `from` data is re-read at commit rather than reused from the start\n * snapshot, so a concurrent edit to a field this action does not own is not\n * clobbered.\n */\nexport function createPaintAction<TState, TValue, K extends string>(\n spec: PaintActionSpec<TState, TValue, K>,\n): Action & { requires: string[] } {\n type Data = PaintData<K, TValue>;\n\n const refreshPreviews = (scratch: Scratch<TState, TValue, K>): void => {\n scratch.previews.clear();\n for (const id of scratch.ids) {\n const prev = scratch.startData.get(id);\n const next = spec.merge(prev?.[spec.dataKey], scratch.state);\n scratch.previews.set(id, { ...(prev ?? {}), [spec.dataKey]: next } as Data);\n }\n };\n\n return {\n id: spec.id,\n label: spec.label,\n eligible: { capability: 'applies-fill' },\n requires: ['selection', 'scene', 'applyOps'],\n invoker: {\n timing: 'ongoing',\n start(ctx: InvocationCtx, opts?: BindingOpts): OngoingHandle {\n const selection = ctx.deps.selection;\n const scene = ctx.deps.scene as Scene<Data, string, unknown> | undefined;\n const applyOps = ctx.deps.applyOps;\n\n if (!selection || !scene) return {};\n\n const ids = selection.get() as NodeId[];\n if (ids.length === 0) return {};\n\n const fallback = opts?.params as Params;\n const pick = (<T>(key: string) =>\n (ctx.params?.[key] ?? fallback?.[key]) as T | undefined) as PickParam;\n\n const startData = new Map<NodeId, Data>();\n for (const id of ids) {\n const node = scene.get(id);\n if (node) startData.set(id, { ...(node.data as Data) });\n }\n\n const scratch: Scratch<TState, TValue, K> = {\n ids,\n scene,\n startData,\n state: spec.initialState(pick),\n previews: new Map(),\n applyOps,\n };\n refreshPreviews(scratch);\n\n return {\n onMove(moveCtx: InvocationCtx): void {\n const next = spec.readParams(scratch.state, moveCtx.params);\n if (next === null) return;\n scratch.state = next;\n refreshPreviews(scratch);\n },\n onEnd(_endCtx: InvocationCtx, reason: 'commit' | 'cancel'): void {\n if (reason === 'cancel') {\n scratch.previews.clear();\n return;\n }\n const ops: Op[] = [];\n for (const id of scratch.ids) {\n const merged = spec.merge(\n scratch.startData.get(id)?.[spec.dataKey],\n scratch.state,\n );\n const nodeNow = scratch.scene.get(id);\n if (!nodeNow) continue;\n const from = { ...(nodeNow.data as object) } as Data;\n const to = { ...from, [spec.dataKey]: merged } as Data;\n ops.push(createSetDataOp<Data>({ id: id as string, from, to }));\n }\n if (ops.length > 0) {\n if (scratch.applyOps) scratch.applyOps(ops, spec.label);\n else scratch.scene.applyBatch(ops, spec.label, defaultCommitAdapter(scratch.scene, selection.adapterMethods));\n }\n scratch.previews.clear();\n },\n previewIds: () => scratch.previews.keys(),\n previewData: (id: string) => scratch.previews.get(id as unknown as NodeId) ?? null,\n };\n },\n },\n enabled: (deps) => {\n const sel = deps?.selection;\n if (!sel || (sel.get() as unknown[]).length === 0) {\n return ActionDisabledReason.SelectionRequired;\n }\n return true;\n },\n };\n}\n"],"mappings":";;;;AA6DA,SAAgBA,EACd,GACiC;CAGjC,IAAMC,KAAmB,MAA8C;EACrE,EAAQ,SAAS,MAAM;EACvB,KAAK,IAAMC,KAAMC,EAAQ,KAAK;GAC5B,IAAMC,IAAOD,EAAQ,UAAU,IAAID,CAAE,GAC/BG,IAAOC,EAAK,MAAMF,IAAOE,EAAK,UAAUH,EAAQ,KAAK;GAC3D,EAAQ,SAAS,IAAID,GAAI;IAAE,GAAIE,KAAQ,CAAC;KAAKE,EAAK,UAAUD;GAAK,CAAS;EAC5E;CACF;CAEA,OAAO;EACL,IAAIC,EAAK;EACT,OAAOA,EAAK;EACZ,UAAU,EAAE,YAAY,eAAe;EACvC,UAAU;GAAC;GAAa;GAAS;EAAU;EAC3C,SAAS;GACP,QAAQ;GACR,MAAM,GAAoB,GAAmC;IAC3D,IAAMC,IAAYC,EAAI,KAAK,WACrBC,IAAQD,EAAI,KAAK,OACjBE,IAAWF,EAAI,KAAK;IAE1B,IAAI,CAACD,KAAa,CAACE,GAAO,OAAO,CAAC;IAElC,IAAME,IAAMJ,EAAU,IAAI;IAC1B,IAAII,EAAI,WAAW,GAAG,OAAO,CAAC;IAE9B,IAAMC,IAAWC,GAAM,QACjBC,MAAY,MACfN,EAAI,SAASO,MAAQH,IAAWG,KAE7BC,oBAAY,IAAI,IAAkB;IACxC,KAAK,IAAMd,KAAMS,GAAK;KACpB,IAAMM,IAAOR,EAAM,IAAIP,CAAE;KACzB,AAAIe,KAAMD,EAAU,IAAId,GAAI,EAAE,GAAIe,EAAK,KAAc,CAAC;IACxD;IAEA,IAAMd,IAAsC;KAC1C;KACA;KACA;KACA,OAAOG,EAAK,aAAaQ,CAAI;KAC7B,0BAAU,IAAI,IAAI;KAClB;IACF;IAGA,OAFAb,EAAgBE,CAAO,GAEhB;KACL,OAAO,GAA8B;MACnC,IAAME,IAAOC,EAAK,WAAWH,EAAQ,OAAOe,EAAQ,MAAM;MAC1D,AAAIb,MAAS,SACb,EAAQ,QAAQA,GAChBJ,EAAgBE,CAAO;KACzB;KACA,MAAM,GAAwB,GAAmC;MAC/D,IAAIgB,MAAW,UAAU;OACvB,EAAQ,SAAS,MAAM;OACvB;MACF;MACA,IAAMC,IAAY,CAAC;MACnB,KAAK,IAAMlB,KAAMC,EAAQ,KAAK;OAC5B,IAAMkB,IAASf,EAAK,MAClBH,EAAQ,UAAU,IAAID,CAAE,CAAC,GAAGI,EAAK,UACjCH,EAAQ,KACV,GACMmB,IAAUnB,EAAQ,MAAM,IAAID,CAAE;OACpC,IAAI,CAACoB,GAAS;OACd,IAAMC,IAAO,EAAE,GAAID,EAAQ,KAAgB,GACrCE,IAAK;QAAE,GAAGD;SAAOjB,EAAK,UAAUe;OAAO;OAC7C,EAAI,KAAKI,EAAsB;QAAM;QAAc;QAAM;OAAG,CAAC,CAAC;MAChE;MAKA,AAJIL,EAAI,SAAS,MACXjB,EAAQ,WAAUA,EAAQ,SAASiB,GAAKd,EAAK,KAAK,IACjDH,EAAQ,MAAM,WAAWiB,GAAKd,EAAK,OAAOoB,EAAqBvB,EAAQ,OAAOI,EAAU,cAAc,CAAC,IAE9GJ,EAAQ,SAAS,MAAM;KACzB;KACA,kBAAkBA,EAAQ,SAAS,KAAK;KACxC,cAAc,MAAeA,EAAQ,SAAS,IAAID,CAAuB,KAAK;IAChF;GACF;EACF;EACA,UAAU,MAAS;GACjB,IAAMyB,IAAMC,GAAM;GAIlB,OAHI,CAACD,KAAQA,EAAI,IAAI,CAAC,CAAe,WAAW,IACvCE,EAAqB,oBAEvB;EACT;CACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"delete.js","names":["hostIndex","node","scene","id","buildDeleteOps","covered","ops","ids","taken","createDeleteOp","deleteAction","createElement","DeleteIcon","selection","deps","applyOps","defaultCommitAdapter","requiresSelection"],"sources":["../../../../src/interactions/actions/defaults/delete.ts"],"sourcesContent":["import { createElement } from 'react';\nimport { DeleteIcon } from './icons/actionGlyphIcons';\nimport type { Node, NodeId, Scene } from 'core/scene/types';\nimport type { Op } from 'core/ops/types';\nimport { createDeleteOp } from 'core/ops/delete';\nimport { defaultCommitAdapter } from '../defaultCommitAdapter';\nimport type { Action } from '@weasel-js/routing';\nimport { requiresSelection } from './requiresSelection';\n\n/** Host-array index of `id`: its slot among the scene roots (parent `null`)\n * or among its parent's children. `-1` when not found. Forwarded to\n * `createDeleteOp` so the inverse re-insert restores paint order on undo. */\nfunction hostIndex(scene: Scene<unknown, string, unknown>, id: NodeId): number {\n const node = scene.get(id);\n const siblings = node?.parent == null ? scene.roots : scene.childrenOf(node.parent);\n return siblings.indexOf(id);\n}\n\n/**\n * Delete ops for `ids`, in the order given. Each op captures the node and its\n * host-array index BEFORE any removal, so `invert()` re-inserts at the right\n * slot and undo restores paint order. Ids with no live node are skipped.\n *\n * Ids an already-emitted op will take are skipped: `removeNode` cascades both\n * the subtree and the dependents, so a second op for a node the first has taken\n * would throw `unknown node id` mid-batch — escaping the batch with the scene\n * already mutated. Selecting a container and its members, or a node and an edge\n * drawn from it, is the ordinary way to hit this; Cmd+A does both.\n *\n * `scene.removalClosure` is what decides that, rather than a walk back up from\n * each candidate: the scene owns the cascade relations, so a third one added\n * there is honored here for free. Asking about the ops already emitted, rather\n * than about the whole selection, is what settles a cycle — two ids that reach\n * each other each cover the other, and filtering both deletes nothing, while\n * growing the covered set in input order keeps the first and drops the rest.\n *\n * Which ids survive the filter depends on their order, so the ops are a cover\n * of the selection rather than its minimal set of roots.\n *\n * Shared with `clipboardCutAction` — cut is copy plus exactly this.\n */\nexport function buildDeleteOps(\n scene: Scene<unknown, string, unknown>,\n ids: readonly string[],\n label: string,\n): Op[] {\n const covered = new Set<string>();\n const ops: Op[] = [];\n for (const id of ids) {\n const node = scene.get(id as NodeId);\n if (!node) continue;\n if (covered.has(id)) continue;\n for (const taken of scene.removalClosure([id as NodeId])) covered.add(taken);\n ops.push(createDeleteOp<Node<unknown, string, unknown>>({\n node,\n index: hostIndex(scene, id as NodeId),\n label,\n }));\n }\n return ops;\n}\n\n/**\n * @experimental\n * Static descriptor for the `delete` Action. Removes every selected\n * node from the scene as a single batched op (one undo entry).\n *\n * Undo restores everything the removal cascaded — a container's children and\n * a deleted node's dependents come back with it, at their own slots. Each op\n * snapshots that set through the adapter's `getRemovalClosure` before removing.\n */\nexport const deleteAction: Action & { requires: string[] } = {\n id: 'delete',\n label: 'Delete',\n icon: createElement(DeleteIcon),\n group: 'edit',\n // Suppressed while any tool is mid-gesture — accidentally hitting\n // Delete during a drag shouldn't wipe the selection out from under\n // the in-flight handle.\n defaultBinding: {\n kind: 'key',\n key: ['Delete', 'Backspace'],\n phase: [{ channel: '*', phase: 'initial' }],\n },\n eligible: { capability: 'edits-page' },\n requires: ['scene', 'selection', 'applyOps'],\n invoker: {\n timing: 'immediate',\n run: (deps) => {\n const selection = deps.selection;\n const scene = deps.scene;\n // Optional consumer commit hook. When present, ops route through it\n // (consumer history) as one undo entry; otherwise they fall back to the\n // scene's own history via `scene.applyBatch`.\n const applyOps = deps.applyOps;\n if (!selection || !scene) return;\n const ids = selection.get();\n if (ids.length === 0) return;\n\n const ops = buildDeleteOps(scene, ids, 'Delete');\n\n if (ops.length > 0) {\n if (applyOps) applyOps(ops, 'Delete');\n else scene.applyBatch(ops, 'Delete', defaultCommitAdapter(scene, selection.adapterMethods));\n }\n selection.set([]);\n },\n },\n enabled: requiresSelection,\n};\n"],"mappings":";;;;;;AAYA,SAASA,EAAU,GAAwC,GAAoB;CAC7E,IAAMC,IAAOC,EAAM,IAAIC,CAAE;CAEzB,QADiBF,GAAM,UAAU,OAAOC,EAAM,QAAQA,EAAM,WAAWD,EAAK,MAAM,EAAA,CAClE,QAAQE,CAAE;AAC5B;AAyBA,SAAgBC,EACd,GACA,GACA,GACM;CACN,IAAMC,oBAAU,IAAI,IAAY,GAC1BC,IAAY,CAAC;CACnB,KAAK,IAAMH,KAAMI,GAAK;EACpB,IAAMN,IAAOC,EAAM,IAAIC,CAAY;EACnC,IAAKF,KACD,GAAQ,IAAIE,CAAE,GAClB;QAAK,IAAMK,KAASN,EAAM,eAAe,CAACC,CAAY,CAAC,GAAG,EAAQ,IAAIK,CAAK;GAC3E,EAAI,KAAKC,EAA+C;IACtD;IACA,OAAOT,EAAUE,GAAOC,CAAY;IACpC;GACF,CAAC,CAAC;EALyE;CAM7E;CACA,OAAOG;AACT;AAWA,IAAaI,IAAgD;CAC3D,IAAI;CACJ,OAAO;CACP,MAAMC,EAAcC,CAAU;CAC9B,OAAO;CAIP,gBAAgB;EACd,MAAM;EACN,KAAK,CAAC,UAAU,WAAW;EAC3B,OAAO,CAAC;GAAE,SAAS;GAAK,OAAO;EAAU,CAAC;CAC5C;CACA,UAAU,EAAE,YAAY,aAAa;CACrC,UAAU;EAAC;EAAS;EAAa;CAAU;CAC3C,SAAS;EACP,QAAQ;EACR,MAAM,MAAS;GACb,IAAMC,IAAYC,EAAK,WACjBZ,IAAQY,EAAK,OAIbC,IAAWD,EAAK;GACtB,IAAI,CAACD,KAAa,CAACX,GAAO;GAC1B,IAAMK,IAAMM,EAAU,IAAI;GAC1B,IAAIN,EAAI,WAAW,GAAG;GAEtB,IAAMD,IAAMF,EAAeF,GAAOK,GAAK,QAAQ;GAM/C,AAJID,EAAI,SAAS,MACXS,IAAUA,EAAST,GAAK,QAAQ,IAC/BJ,EAAM,WAAWI,GAAK,UAAUU,EAAqBd,GAAOW,EAAU,cAAc,CAAC,IAE5FA,EAAU,IAAI,CAAC,CAAC;EAClB;CACF;CACA,SAASI;AACX"}
1
+ {"version":3,"file":"delete.js","names":["hostIndex","node","scene","id","buildDeleteOps","covered","ops","ids","taken","createDeleteOp","deleteAction","createElement","DeleteIcon","selection","deps","applyOps","defaultCommitAdapter","requiresSelection"],"sources":["../../../../src/interactions/actions/defaults/delete.ts"],"sourcesContent":["import { createElement } from 'react';\nimport { DeleteIcon } from './icons/actionGlyphIcons';\nimport type { Node, NodeId, Scene } from 'core/scene/types';\nimport type { Op } from 'core/ops/types';\nimport { createDeleteOp } from 'core/ops/delete';\nimport { defaultCommitAdapter } from '../defaultCommitAdapter';\nimport type { Action } from '@weasel-js/routing';\nimport { requiresSelection } from './requiresSelection';\n\n/** `id`'s slot among the scene roots or its parent's children, or `-1`. */\nfunction hostIndex(scene: Scene<unknown, string, unknown>, id: NodeId): number {\n const node = scene.get(id);\n const siblings = node?.parent == null ? scene.roots : scene.childrenOf(node.parent);\n return siblings.indexOf(id);\n}\n\n/**\n * Delete ops for `ids`, in the order given. Each op captures the node and its\n * host-array index BEFORE any removal, so `invert()` re-inserts at the right\n * slot and undo restores paint order. Ids with no live node are skipped.\n *\n * Ids an already-emitted op will take are skipped: `removeNode` cascades both\n * the subtree and the dependents, so a second op for a node the first has taken\n * would throw `unknown node id` mid-batch — escaping the batch with the scene\n * already mutated. Selecting a container and its members does this.\n *\n * The covered set grows from the ops already emitted, not from the whole\n * selection, which is what settles a cycle: two ids that reach each other each\n * cover the other, and filtering both would delete nothing. So which ids\n * survive depends on their order, and the ops are a cover of the selection\n * rather than its minimal set of roots.\n */\nexport function buildDeleteOps(\n scene: Scene<unknown, string, unknown>,\n ids: readonly string[],\n label: string,\n): Op[] {\n const covered = new Set<string>();\n const ops: Op[] = [];\n for (const id of ids) {\n const node = scene.get(id as NodeId);\n if (!node) continue;\n if (covered.has(id)) continue;\n for (const taken of scene.removalClosure([id as NodeId])) covered.add(taken);\n ops.push(createDeleteOp<Node<unknown, string, unknown>>({\n node,\n index: hostIndex(scene, id as NodeId),\n label,\n }));\n }\n return ops;\n}\n\n/**\n * @experimental\n * Removes every selected node from the scene as one undo entry. Undo restores\n * everything the removal cascaded — a container's children and a deleted\n * node's dependents come back with it, at their own slots.\n */\nexport const deleteAction: Action & { requires: string[] } = {\n id: 'delete',\n label: 'Delete',\n icon: createElement(DeleteIcon),\n group: 'edit',\n // Suppressed while any tool is mid-gesture — accidentally hitting\n // Delete during a drag shouldn't wipe the selection out from under\n // the in-flight handle.\n defaultBinding: {\n kind: 'key',\n key: ['Delete', 'Backspace'],\n phase: [{ channel: '*', phase: 'initial' }],\n },\n eligible: { capability: 'edits-page' },\n requires: ['scene', 'selection', 'applyOps'],\n invoker: {\n timing: 'immediate',\n run: (deps) => {\n const selection = deps.selection;\n const scene = deps.scene;\n const applyOps = deps.applyOps;\n if (!selection || !scene) return;\n const ids = selection.get();\n if (ids.length === 0) return;\n\n const ops = buildDeleteOps(scene, ids, 'Delete');\n\n if (ops.length > 0) {\n if (applyOps) applyOps(ops, 'Delete');\n else scene.applyBatch(ops, 'Delete', defaultCommitAdapter(scene, selection.adapterMethods));\n }\n selection.set([]);\n },\n },\n enabled: requiresSelection,\n};\n"],"mappings":";;;;;;AAUA,SAASA,EAAU,GAAwC,GAAoB;CAC7E,IAAMC,IAAOC,EAAM,IAAIC,CAAE;CAEzB,QADiBF,GAAM,UAAU,OAAOC,EAAM,QAAQA,EAAM,WAAWD,EAAK,MAAM,EAAA,CAClE,QAAQE,CAAE;AAC5B;AAkBA,SAAgBC,EACd,GACA,GACA,GACM;CACN,IAAMC,oBAAU,IAAI,IAAY,GAC1BC,IAAY,CAAC;CACnB,KAAK,IAAMH,KAAMI,GAAK;EACpB,IAAMN,IAAOC,EAAM,IAAIC,CAAY;EACnC,IAAKF,KACD,GAAQ,IAAIE,CAAE,GAClB;QAAK,IAAMK,KAASN,EAAM,eAAe,CAACC,CAAY,CAAC,GAAG,EAAQ,IAAIK,CAAK;GAC3E,EAAI,KAAKC,EAA+C;IACtD;IACA,OAAOT,EAAUE,GAAOC,CAAY;IACpC;GACF,CAAC,CAAC;EALyE;CAM7E;CACA,OAAOG;AACT;AAQA,IAAaI,IAAgD;CAC3D,IAAI;CACJ,OAAO;CACP,MAAMC,EAAcC,CAAU;CAC9B,OAAO;CAIP,gBAAgB;EACd,MAAM;EACN,KAAK,CAAC,UAAU,WAAW;EAC3B,OAAO,CAAC;GAAE,SAAS;GAAK,OAAO;EAAU,CAAC;CAC5C;CACA,UAAU,EAAE,YAAY,aAAa;CACrC,UAAU;EAAC;EAAS;EAAa;CAAU;CAC3C,SAAS;EACP,QAAQ;EACR,MAAM,MAAS;GACb,IAAMC,IAAYC,EAAK,WACjBZ,IAAQY,EAAK,OACbC,IAAWD,EAAK;GACtB,IAAI,CAACD,KAAa,CAACX,GAAO;GAC1B,IAAMK,IAAMM,EAAU,IAAI;GAC1B,IAAIN,EAAI,WAAW,GAAG;GAEtB,IAAMD,IAAMF,EAAeF,GAAOK,GAAK,QAAQ;GAM/C,AAJID,EAAI,SAAS,MACXS,IAAUA,EAAST,GAAK,QAAQ,IAC/BJ,EAAM,WAAWI,GAAK,UAAUU,EAAqBd,GAAOW,EAAU,cAAc,CAAC,IAE5FA,EAAU,IAAI,CAAC,CAAC;EAClB;CACF;CACA,SAASI;AACX"}
@@ -1,43 +1,58 @@
1
- import { translatePoseViaDescriptor as e } from "../../../core/geometry/poseDescriptor.js";
2
- import { nodeDescriptors as t, poseDescriptorOf as n } from "../poseDescriptorDep.js";
3
- import { defaultCommitAdapter as r } from "../defaultCommitAdapter.js";
4
- import { copySelection as i } from "./copySubtree.js";
5
- import { DuplicateIcon as a } from "./icons/editIcons.js";
6
- import { requiresSelection as o } from "./requiresSelection.js";
7
- import { createElement as s } from "react";
1
+ import { composesFrames as e } from "../../../core/scene/composeFrame.js";
2
+ import { translatePoseViaDescriptor as t } from "../../../core/geometry/poseDescriptor.js";
3
+ import { nodeDescriptors as n, poseDescriptorOf as r } from "../poseDescriptorDep.js";
4
+ import { defaultCommitAdapter as i } from "../defaultCommitAdapter.js";
5
+ import { recordTransform as a } from "../transform-again/memory.js";
6
+ import { copySelection as o } from "./copySubtree.js";
7
+ import { DuplicateIcon as s } from "./icons/editIcons.js";
8
+ import { requiresSelection as c } from "./requiresSelection.js";
9
+ import { createElement as l } from "react";
8
10
  //#region src/interactions/actions/defaults/duplicate.ts
9
- var c = 12, l = {
11
+ var u = 12;
12
+ function d(a, s, c, l = "Duplicate") {
13
+ let u = a.selection, d = a.scene, f = a.applyOps;
14
+ if (!u || !d) return null;
15
+ let p = u.get();
16
+ if (p.length === 0) return null;
17
+ let m = n(d, r(a.poseDescriptor)), h = !e(d.composition), { ops: g, copies: _ } = o(d, p, (e, n, r) => r || h ? t(n.pose, s, c, m(e)) : n.pose, l);
18
+ return g.length === 0 ? null : (f ? f(g, l) : d.applyBatch(g, l, i(d, u.adapterMethods)), u.set(_), _);
19
+ }
20
+ var f = {
10
21
  id: "duplicate",
11
22
  label: "Duplicate",
12
- icon: s(a),
23
+ icon: l(s),
13
24
  group: "edit",
14
25
  defaultBinding: {
15
26
  kind: "key",
16
- key: "d",
17
- mods: { mod: !0 }
27
+ key: ["d", "D"],
28
+ mods: {
29
+ mod: !0,
30
+ shift: !0
31
+ }
18
32
  },
19
33
  eligible: { capability: ["edits-page", "creates-selection"] },
20
34
  requires: [
21
35
  "scene",
22
36
  "selection",
23
37
  "applyOps",
24
- "poseComposition",
25
38
  "poseDescriptor"
26
39
  ],
27
40
  invoker: {
28
41
  timing: "immediate",
29
- run: (a) => {
30
- let o = a.selection, s = a.scene, l = a.applyOps;
31
- if (!o || !s) return;
32
- let u = o.get();
33
- if (u.length === 0) return;
34
- let d = t(s, n(a.poseDescriptor)), f = a.poseComposition === void 0, { ops: p, copies: m } = i(s, u, (t, n, r) => r || f ? e(n.pose, c, c, d(t)) : n.pose, "Duplicate");
35
- p.length !== 0 && (l ? l(p, "Duplicate") : s.applyBatch(p, "Duplicate", r(s, o.adapterMethods)), o.set(m));
42
+ run: (e) => {
43
+ let t = e.scene, n = e.selection;
44
+ if (!t || !n) return;
45
+ let r = d(e, u, u);
46
+ r && a(t, {
47
+ kind: "duplicate",
48
+ dx: u,
49
+ dy: u
50
+ }, r);
36
51
  }
37
52
  },
38
- enabled: o
53
+ enabled: c
39
54
  };
40
55
  //#endregion
41
- export { l as duplicateAction };
56
+ export { u as DUPLICATE_OFFSET, f as duplicateAction, d as duplicateSelection };
42
57
 
43
58
  //# sourceMappingURL=duplicate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"duplicate.js","names":["DUPLICATE_OFFSET","duplicateAction","createElement","DuplicateIcon","selection","deps","scene","applyOps","ids","descriptorOf","nodeDescriptors","poseDescriptorOf","offsetDescendants","newIds","copySelection","isRoot","translatePoseViaDescriptor","node","id","ops","defaultCommitAdapter","requiresSelection"],"sources":["../../../../src/interactions/actions/defaults/duplicate.ts"],"sourcesContent":["import type { Action } from '@weasel-js/routing';\nimport { createElement } from 'react';\nimport { DuplicateIcon } from './icons/editIcons';\nimport { defaultCommitAdapter } from '../defaultCommitAdapter';\nimport { copySelection } from './copySubtree';\nimport { requiresSelection } from './requiresSelection';\nimport { nodeDescriptors, poseDescriptorOf } from '../poseDescriptorDep';\nimport { translatePoseViaDescriptor } from '../resize/geometry';\n\n/** Same nudge `sceneToAdapter.getPasteOffset` gives a paste, so duplicate and\n * paste land in the same place rather than disagreeing by a few units. */\nconst DUPLICATE_OFFSET = 12;\n\n/**\n * @experimental\n * Static descriptor for the `duplicate` Action. Copies each selected node —\n * with its subtree, so duplicating a group produces a populated group — offset\n * by a small nudge, as one undoable batch, then selects the copies.\n */\nexport const duplicateAction: Action & { requires: string[] } = {\n id: 'duplicate',\n label: 'Duplicate',\n icon: createElement(DuplicateIcon),\n group: 'edit',\n defaultBinding: { kind: 'key', key: 'd', mods: { mod: true } },\n eligible: { capability: ['edits-page', 'creates-selection'] },\n // `selection` is read by the `enabled` gate as well as the invoker. An\n // undeclared read throws inside the dev-build deps Proxy before the gate can\n // answer, which is how this action spent a while doing nothing at all.\n requires: ['scene', 'selection', 'applyOps', 'poseComposition', 'poseDescriptor'],\n invoker: {\n timing: 'immediate',\n run: (deps) => {\n const selection = deps.selection;\n const scene = deps.scene;\n const applyOps = deps.applyOps;\n if (!selection || !scene) return;\n const ids = selection.get();\n if (ids.length === 0) return;\n\n const descriptorOf = nodeDescriptors(scene, poseDescriptorOf(deps.poseDescriptor));\n // With a `poseComposition` a child's pose is relative, so offsetting the\n // root carries the subtree and offsetting a child again would double it.\n const offsetDescendants = deps.poseComposition === undefined;\n const { ops, copies: newIds } = copySelection(\n scene,\n ids,\n (id, node, isRoot) => (isRoot || offsetDescendants\n ? translatePoseViaDescriptor(node.pose, DUPLICATE_OFFSET, DUPLICATE_OFFSET, descriptorOf(id))\n : node.pose),\n 'Duplicate',\n );\n\n if (ops.length === 0) return;\n if (applyOps) applyOps(ops, 'Duplicate');\n else scene.applyBatch(ops, 'Duplicate', defaultCommitAdapter(scene, selection.adapterMethods));\n selection.set(newIds);\n },\n },\n enabled: requiresSelection,\n};\n"],"mappings":";;;;;;;;AAWA,IAAMA,IAAmB,IAQZC,IAAmD;CAC9D,IAAI;CACJ,OAAO;CACP,MAAMC,EAAcC,CAAa;CACjC,OAAO;CACP,gBAAgB;EAAE,MAAM;EAAO,KAAK;EAAK,MAAM,EAAE,KAAK,GAAK;CAAE;CAC7D,UAAU,EAAE,YAAY,CAAC,cAAc,mBAAmB,EAAE;CAI5D,UAAU;EAAC;EAAS;EAAa;EAAY;EAAmB;CAAgB;CAChF,SAAS;EACP,QAAQ;EACR,MAAM,MAAS;GACb,IAAMC,IAAYC,EAAK,WACjBC,IAAQD,EAAK,OACbE,IAAWF,EAAK;GACtB,IAAI,CAACD,KAAa,CAACE,GAAO;GAC1B,IAAME,IAAMJ,EAAU,IAAI;GAC1B,IAAII,EAAI,WAAW,GAAG;GAEtB,IAAMC,IAAeC,EAAgBJ,GAAOK,EAAiBN,EAAK,cAAc,CAAC,GAG3EO,IAAoBP,EAAK,oBAAoB,KAAA,GAC7C,EAAE,QAAK,QAAQQ,MAAWC,EAC9BR,GACAE,IACC,GAAI,GAAM,MAAYO,KAAUH,IAC7BI,EAA2BC,EAAK,MAAMjB,GAAkBA,GAAkBS,EAAaS,CAAE,CAAC,IAC1FD,EAAK,MACT,WACF;GAEA,AAAIE,EAAI,WAAW,MACfZ,IAAUA,EAASY,GAAK,WAAW,IAClCb,EAAM,WAAWa,GAAK,aAAaC,EAAqBd,GAAOF,EAAU,cAAc,CAAC,GAC7FA,EAAU,IAAIS,CAAM;EACtB;CACF;CACA,SAASQ;AACX"}
1
+ {"version":3,"file":"duplicate.js","names":["DUPLICATE_OFFSET","duplicateSelection","selection","deps","scene","applyOps","ids","descriptorOf","nodeDescriptors","poseDescriptorOf","offsetDescendants","composesFrames","copySelection","isRoot","translatePoseViaDescriptor","node","dx","dy","id","label","ops","defaultCommitAdapter","copies","duplicateAction","createElement","DuplicateIcon","recordTransform","requiresSelection"],"sources":["../../../../src/interactions/actions/defaults/duplicate.ts"],"sourcesContent":["import type { Action, ActionDeps } from '@weasel-js/routing';\nimport { composesFrames } from 'core/scene/composePose';\nimport { createElement } from 'react';\nimport { DuplicateIcon } from './icons/editIcons';\nimport { defaultCommitAdapter } from '../defaultCommitAdapter';\nimport { copySelection } from './copySubtree';\nimport { requiresSelection } from './requiresSelection';\nimport { nodeDescriptors, poseDescriptorOf } from '../poseDescriptorDep';\nimport { translatePoseViaDescriptor } from '../resize/geometry';\nimport { recordTransform } from '../transform-again/memory';\n\n/** Same nudge `sceneToAdapter.getPasteOffset` gives a paste, so duplicate and\n * paste land in the same place rather than disagreeing by a few units. */\nexport const DUPLICATE_OFFSET = 12;\n\n/**\n * Copy each selected node, with its subtree, offset by `(dx, dy)`, as one\n * undoable batch labeled `label`, and select the copies. Returns the copies'\n * ids, or null when nothing was copied.\n */\nexport function duplicateSelection(\n deps: ActionDeps,\n dx: number,\n dy: number,\n label = 'Duplicate',\n): string[] | null {\n const selection = deps.selection;\n const scene = deps.scene;\n const applyOps = deps.applyOps;\n if (!selection || !scene) return null;\n const ids = selection.get();\n if (ids.length === 0) return null;\n\n const descriptorOf = nodeDescriptors(scene, poseDescriptorOf(deps.poseDescriptor));\n // Under a frame a child's pose is relative, so offsetting the root\n // carries the subtree and offsetting a child again would double it.\n const offsetDescendants = !composesFrames(scene.composition);\n const { ops, copies } = copySelection(\n scene,\n ids,\n (id, node, isRoot) => (isRoot || offsetDescendants\n ? translatePoseViaDescriptor(node.pose, dx, dy, descriptorOf(id))\n : node.pose),\n label,\n );\n\n if (ops.length === 0) return null;\n if (applyOps) applyOps(ops, label);\n else scene.applyBatch(ops, label, defaultCommitAdapter(scene, selection.adapterMethods));\n selection.set(copies);\n return copies as string[];\n}\n\n/**\n * @experimental\n * Static descriptor for the `duplicate` Action. Copies each selected node —\n * with its subtree, so duplicating a group produces a populated group — offset\n * by a small nudge, as one undoable batch, then selects the copies.\n */\nexport const duplicateAction: Action & { requires: string[] } = {\n id: 'duplicate',\n label: 'Duplicate',\n icon: createElement(DuplicateIcon),\n group: 'edit',\n // Cmd/Ctrl+D is `transformAgain`, which duplicates when nothing else is\n // there to repeat.\n defaultBinding: { kind: 'key', key: ['d', 'D'], mods: { mod: true, shift: true } },\n eligible: { capability: ['edits-page', 'creates-selection'] },\n // `selection` is read by the `enabled` gate as well as the invoker. An\n // undeclared read throws inside the dev-build deps Proxy before the gate can\n // answer, which is how this action spent a while doing nothing at all.\n requires: ['scene', 'selection', 'applyOps', 'poseDescriptor'],\n invoker: {\n timing: 'immediate',\n run: (deps) => {\n const scene = deps.scene;\n const selection = deps.selection;\n if (!scene || !selection) return;\n const copies = duplicateSelection(deps, DUPLICATE_OFFSET, DUPLICATE_OFFSET);\n if (copies) recordTransform(scene, { kind: 'duplicate', dx: DUPLICATE_OFFSET, dy: DUPLICATE_OFFSET }, copies);\n },\n },\n enabled: requiresSelection,\n};\n"],"mappings":";;;;;;;;;;AAaA,IAAaA,IAAmB;AAOhC,SAAgBC,EACd,GACA,GACA,GACA,IAAQ,aACS;CACjB,IAAMC,IAAYC,EAAK,WACjBC,IAAQD,EAAK,OACbE,IAAWF,EAAK;CACtB,IAAI,CAACD,KAAa,CAACE,GAAO,OAAO;CACjC,IAAME,IAAMJ,EAAU,IAAI;CAC1B,IAAII,EAAI,WAAW,GAAG,OAAO;CAE7B,IAAMC,IAAeC,EAAgBJ,GAAOK,EAAiBN,EAAK,cAAc,CAAC,GAG3EO,IAAoB,CAACC,EAAeP,EAAM,WAAW,GACrD,EAAE,QAAK,cAAWQ,EACtBR,GACAE,IACC,GAAI,GAAM,MAAYO,KAAUH,IAC7BI,EAA2BC,EAAK,MAAMC,GAAIC,GAAIV,EAAaW,CAAE,CAAC,IAC9DH,EAAK,MACTI,CACF;CAMA,OAJIC,EAAI,WAAW,IAAU,QACzBf,IAAUA,EAASe,GAAKD,CAAK,IAC5Bf,EAAM,WAAWgB,GAAKD,GAAOE,EAAqBjB,GAAOF,EAAU,cAAc,CAAC,GACvFA,EAAU,IAAIoB,CAAM,GACbA;AACT;AAQA,IAAaC,IAAmD;CAC9D,IAAI;CACJ,OAAO;CACP,MAAMC,EAAcC,CAAa;CACjC,OAAO;CAGP,gBAAgB;EAAE,MAAM;EAAO,KAAK,CAAC,KAAK,GAAG;EAAG,MAAM;GAAE,KAAK;GAAM,OAAO;EAAK;CAAE;CACjF,UAAU,EAAE,YAAY,CAAC,cAAc,mBAAmB,EAAE;CAI5D,UAAU;EAAC;EAAS;EAAa;EAAY;CAAgB;CAC7D,SAAS;EACP,QAAQ;EACR,MAAM,MAAS;GACb,IAAMrB,IAAQD,EAAK,OACbD,IAAYC,EAAK;GACvB,IAAI,CAACC,KAAS,CAACF,GAAW;GAC1B,IAAMoB,IAASrB,EAAmBE,GAAMH,GAAkBA,CAAgB;GAC1E,AAAIsB,KAAQI,EAAgBtB,GAAO;IAAE,MAAM;IAAa,IAAIJ;IAAkB,IAAIA;GAAiB,GAAGsB,CAAM;EAC9G;CACF;CACA,SAASK;AACX"}
@@ -8,15 +8,27 @@ var t = {
8
8
  target: { kindOf: e }
9
9
  },
10
10
  eligible: { mode: { in: ["normal", "isolation"] } },
11
- requires: ["editAnchors", "selection"],
11
+ requires: [
12
+ "editAnchors",
13
+ "selection",
14
+ "nodeAtPoint"
15
+ ],
12
16
  invoker: {
13
17
  timing: "immediate",
14
- run(e) {
15
- let t = e.editAnchors, n = e.selection;
16
- if (!t || !n) return;
17
- let r = n.get();
18
- for (let e of r) if (t.getEditablePath(e)) {
19
- t.setEditingId(e);
18
+ run(e, t) {
19
+ let n = e.editAnchors, r = e.selection;
20
+ if (!n || !r) return;
21
+ let i = t?.worldX, a = t?.worldY, o = typeof i == "number" && typeof a == "number" ? e.nodeAtPoint?.({
22
+ x: i,
23
+ y: a
24
+ }) : null;
25
+ if (o && n.getEditablePath(o)) {
26
+ n.setEditingId(o);
27
+ return;
28
+ }
29
+ let s = r.get();
30
+ for (let e of s) if (n.getEditablePath(e)) {
31
+ n.setEditingId(e);
20
32
  return;
21
33
  }
22
34
  }
@@ -1 +1 @@
1
- {"version":3,"file":"enterPathEdit.js","names":["enterPathEditAction","isBody","editAnchors","deps","selection","ids","id"],"sources":["../../../../src/interactions/actions/defaults/enterPathEdit.ts"],"sourcesContent":["/**\n * `enterPathEditAction` — immediate Action that enters path-anchor edit\n * mode on a double-click against a selected polygon. Sets\n * `editAnchors.editingId` to the first selected polygon's id; the\n * gesture-side hit-test (via `buildAffordanceAt`) and the\n * `pathEditingOverlayLayer` chrome both gate on that id.\n *\n * No-op when the selection contains no polygon. The companion\n * `exitPathEditAction` (Escape) clears edit mode.\n */\n\nimport type { Action } from '@weasel-js/routing';\nimport type { ImmediateInvoker } from '@weasel-js/routing';\nimport type { NodeId } from 'core/scene/types';\nimport { isBody } from '@weasel-js/routing';\n\nexport const enterPathEditAction: Action & { requires: string[] } = {\n id: 'enterPathEdit',\n label: 'Edit path anchors',\n // Double-click on a polygon body (selected OR unselected) — matches the\n // Figma/Illustrator convention where double-clicking a path enters edit\n // mode regardless of prior selection state. The `kindOf` predicate fires\n // on either body class but not on empty space, so a double-click on\n // empty canvas doesn't accidentally enter edit mode.\n defaultBinding: {\n kind: 'doubleClick',\n target: { kindOf: isBody },\n },\n eligible: { mode: { in: ['normal', 'isolation'] } },\n requires: ['editAnchors', 'selection'],\n invoker: {\n timing: 'immediate',\n run(deps) {\n const editAnchors = deps.editAnchors;\n const selection = deps.selection;\n if (!editAnchors || !selection) return;\n const ids = selection.get() as NodeId[];\n // Use the dep's editability check rather than poking at node.pose\n // directly — the dep knows whether a node has an editable polygon\n // (pose-as-polygon OR data.path) so this picks up both shapes.\n for (const id of ids) {\n if (editAnchors.getEditablePath(id)) {\n editAnchors.setEditingId(id);\n return;\n }\n }\n },\n } as ImmediateInvoker,\n enabled: () => true,\n};\n"],"mappings":";;AAgBA,IAAaA,IAAuD;CAClE,IAAI;CACJ,OAAO;CAMP,gBAAgB;EACd,MAAM;EACN,QAAQ,EAAE,QAAQC,EAAO;CAC3B;CACA,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,UAAU,WAAW,EAAE,EAAE;CAClD,UAAU,CAAC,eAAe,WAAW;CACrC,SAAS;EACP,QAAQ;EACR,IAAI,GAAM;GACR,IAAMC,IAAcC,EAAK,aACnBC,IAAYD,EAAK;GACvB,IAAI,CAACD,KAAe,CAACE,GAAW;GAChC,IAAMC,IAAMD,EAAU,IAAI;GAI1B,KAAK,IAAME,KAAMD,GACf,IAAIH,EAAY,gBAAgBI,CAAE,GAAG;IACnC,EAAY,aAAaA,CAAE;IAC3B;GACF;EAEJ;CACF;CACA,eAAe;AACjB"}
1
+ {"version":3,"file":"enterPathEdit.js","names":["enterPathEditAction","isBody","editAnchors","deps","selection","x","params","y","under","ids","id"],"sources":["../../../../src/interactions/actions/defaults/enterPathEdit.ts"],"sourcesContent":["/**\n * `enterPathEditAction` — immediate Action that enters path-anchor edit\n * mode on a double-click against a selected polygon. Sets\n * `editAnchors.editingId` to the first selected polygon's id; the\n * gesture-side hit-test (via `buildAffordanceAt`) and the\n * `pathEditingOverlayLayer` chrome both gate on that id.\n *\n * No-op when the selection contains no polygon. The companion\n * `exitPathEditAction` (Escape) clears edit mode.\n */\n\nimport type { Action } from '@weasel-js/routing';\nimport type { ImmediateInvoker } from '@weasel-js/routing';\nimport type { NodeId } from 'core/scene/types';\nimport { isBody } from '@weasel-js/routing';\n\nexport const enterPathEditAction: Action & { requires: string[] } = {\n id: 'enterPathEdit',\n label: 'Edit path anchors',\n // Double-click on a polygon body (selected OR unselected) — matches the\n // Figma/Illustrator convention where double-clicking a path enters edit\n // mode regardless of prior selection state. The `kindOf` predicate fires\n // on either body class but not on empty space, so a double-click on\n // empty canvas doesn't accidentally enter edit mode.\n defaultBinding: {\n kind: 'doubleClick',\n target: { kindOf: isBody },\n },\n eligible: { mode: { in: ['normal', 'isolation'] } },\n requires: ['editAnchors', 'selection', 'nodeAtPoint'],\n invoker: {\n timing: 'immediate',\n run(deps, params) {\n const editAnchors = deps.editAnchors;\n const selection = deps.selection;\n if (!editAnchors || !selection) return;\n // The path under the pointer wins: with several selected, the first may not be the one\n // double-clicked.\n const x = params?.worldX, y = params?.worldY;\n const under = typeof x === 'number' && typeof y === 'number' ? deps.nodeAtPoint?.({ x, y }) : null;\n if (under && editAnchors.getEditablePath(under)) {\n editAnchors.setEditingId(under);\n return;\n }\n const ids = selection.get() as NodeId[];\n // Use the dep's editability check rather than poking at node.pose\n // directly — the dep knows whether a node has an editable polygon\n // (pose-as-polygon OR data.path) so this picks up both shapes.\n for (const id of ids) {\n if (editAnchors.getEditablePath(id)) {\n editAnchors.setEditingId(id);\n return;\n }\n }\n },\n } as ImmediateInvoker,\n enabled: () => true,\n};\n"],"mappings":";;AAgBA,IAAaA,IAAuD;CAClE,IAAI;CACJ,OAAO;CAMP,gBAAgB;EACd,MAAM;EACN,QAAQ,EAAE,QAAQC,EAAO;CAC3B;CACA,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,UAAU,WAAW,EAAE,EAAE;CAClD,UAAU;EAAC;EAAe;EAAa;CAAa;CACpD,SAAS;EACP,QAAQ;EACR,IAAI,GAAM,GAAQ;GAChB,IAAMC,IAAcC,EAAK,aACnBC,IAAYD,EAAK;GACvB,IAAI,CAACD,KAAe,CAACE,GAAW;GAGhC,IAAMC,IAAIC,GAAQ,QAAQC,IAAID,GAAQ,QAChCE,IAAQ,OAAOH,KAAM,YAAY,OAAOE,KAAM,WAAWJ,EAAK,cAAc;IAAE;IAAG;GAAE,CAAC,IAAI;GAC9F,IAAIK,KAASN,EAAY,gBAAgBM,CAAK,GAAG;IAC/C,EAAY,aAAaA,CAAK;IAC9B;GACF;GACA,IAAMC,IAAML,EAAU,IAAI;GAI1B,KAAK,IAAMM,KAAMD,GACf,IAAIP,EAAY,gBAAgBQ,CAAE,GAAG;IACnC,EAAY,aAAaA,CAAE;IAC3B;GACF;EAEJ;CACF;CACA,eAAe;AACjB"}
@@ -1 +1 @@
1
- {"version":3,"file":"enterTextEdit.js","names":["enterTextEditAction","sel","deps","id","textEdit"],"sources":["../../../../src/interactions/actions/defaults/enterTextEdit.ts"],"sourcesContent":["/**\n * `enterTextEditAction` — immediate Action descriptor for entering in-place\n * text editing on a selected text node.\n *\n * ## Status: REAL\n *\n * Fires via `useTextTool.bindings` when the user clicks on a\n * selected text node. Calls `deps.textEdit.startEdit(id)` to activate the\n * contenteditable overlay managed by `useTextEdit` / `useSceneTextEdit`.\n *\n * ## No defaultBinding / defaultBinding\n *\n * This action has no ambient key or gesture binding — it fires ONLY via\n * `useTextTool`'s `Tool.bindings` entry:\n *\n * ```ts\n * bindings: [\n * { spec: { kind: 'click', target: 'selected-body' }, actionId: 'enterTextEdit' },\n * ]\n * ```\n *\n * Keeping it binding-free avoids ambient double-fire and scopes the action to\n * the text tool context where `classifyTarget` is already wired.\n *\n * ## Self-guard: only act on text nodes\n *\n * The `'selected-body'` target yields a match for any selected node kind. To\n * avoid entering text-edit mode when the text tool happens to have a non-text\n * node selected, the action self-guards via an optional `isTextNode` predicate\n * on `TextEditDep`:\n *\n * - When `isTextNode` is absent: action fires unconditionally (the binding\n * spec is the real gate — consumers should only bind this action from the\n * text tool).\n * - When `isTextNode(id)` returns `false`: action is a no-op for that node.\n *\n * ### Pre-filtering at dispatch time\n *\n * `classifyTarget` now surfaces node kind, so a binding can pre-filter instead\n * of relying on the self-guard:\n *\n * ```ts\n * { spec: { kind: 'click', target: 'kind:text:selected' }, actionId: 'enterTextEdit' }\n * ```\n *\n * That reads the *routing trait's* kind, so it matches whatever names the\n * consumer registered in `<SceneCanvas routing>` — `'text'` under the kit's\n * inferred default. `isTextNode` stays on `TextEditDep` because it also covers\n * consumers who bind the broader `'selected-body'` target, and because it is\n * the only guard for a consumer who opted out of routing entirely.\n *\n * ## Migration plan for useTextTool\n *\n * When wiring `useTextTool` to `Tool.bindings`:\n *\n * 1. Add to `useTextTool`'s `bindings`:\n * ```ts\n * { spec: { kind: 'click', target: 'selected-body' }, actionId: 'enterTextEdit' }\n * ```\n * 2. Register a `textEdit` dep sourced from the `useTextEdit` / `useSceneTextEdit`\n * return value, plus an `isTextNode` predicate (`isTextData`, or however the\n * consumer identifies text nodes).\n * 3. The existing `hitExisting` gate in `useTextTool`'s click route becomes\n * redundant — remove it in the same pass.\n */\n\nimport type { Action } from '@weasel-js/routing';\n\n// ---------------------------------------------------------------------------\n// TextEditDep\n// ---------------------------------------------------------------------------\n\n// ---------------------------------------------------------------------------\n// Descriptor\n// ---------------------------------------------------------------------------\n\n/**\n * @experimental\n * Static descriptor for the `enterTextEdit` Action.\n *\n * Requires dep-schema entries: `textEdit`, `selection`.\n *\n * No `defaultBinding` / `defaultBinding` — fires only via `Tool.bindings`.\n * Self-guards via `TextEditDep.isTextNode` when provided.\n */\nexport const enterTextEditAction: Action & { requires: string[] } = {\n id: 'enterTextEdit',\n label: 'Enter text edit',\n // No defaultBinding / defaultBinding — fires only via Tool.bindings.\n eligible: { mode: { in: ['normal', 'isolation'] } },\n requires: ['textEdit', 'selection'],\n invoker: {\n timing: 'immediate',\n run: (deps) => {\n const sel = deps.selection?.get() ?? [];\n if (sel.length !== 1) return;\n\n const id = sel[0];\n const textEdit = deps.textEdit;\n if (!textEdit) return;\n\n // Self-guard: skip non-text nodes when the predicate is supplied.\n if (textEdit.isTextNode && !textEdit.isTextNode(id)) return;\n\n textEdit.startEdit(id);\n },\n },\n};\n"],"mappings":";AAqFA,IAAaA,IAAuD;CAClE,IAAI;CACJ,OAAO;CAEP,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,UAAU,WAAW,EAAE,EAAE;CAClD,UAAU,CAAC,YAAY,WAAW;CAClC,SAAS;EACP,QAAQ;EACR,MAAM,MAAS;GACb,IAAMC,IAAMC,EAAK,WAAW,IAAI,KAAK,CAAC;GACtC,IAAID,EAAI,WAAW,GAAG;GAEtB,IAAME,IAAKF,EAAI,IACTG,IAAWF,EAAK;GACtB,AAAKE,MAGD,GAAS,cAAeA,EAAS,WAAWD,CAAE,MAElDC,EAAS,UAAUD,CAAE;EACvB;CACF;AACF"}
1
+ {"version":3,"file":"enterTextEdit.js","names":["enterTextEditAction","sel","deps","id","textEdit"],"sources":["../../../../src/interactions/actions/defaults/enterTextEdit.ts"],"sourcesContent":["import type { Action } from '@weasel-js/routing';\n\n/**\n * @experimental\n * Starts in-place text editing on the single selected node. It has no\n * `defaultBinding`: it fires only via `Tool.bindings`.\n *\n * A `'selected-body'` target matches any selected node kind, so the action\n * skips a node `TextEditDep.isTextNode` rejects. With no `isTextNode` it fires\n * unconditionally, and the binding spec is the only gate; a binding can\n * pre-filter with `target: 'kind:text:selected'` instead.\n */\nexport const enterTextEditAction: Action & { requires: string[] } = {\n id: 'enterTextEdit',\n label: 'Enter text edit',\n eligible: { mode: { in: ['normal', 'isolation'] } },\n requires: ['textEdit', 'selection'],\n invoker: {\n timing: 'immediate',\n run: (deps) => {\n const sel = deps.selection?.get() ?? [];\n if (sel.length !== 1) return;\n\n const id = sel[0];\n const textEdit = deps.textEdit;\n if (!textEdit) return;\n\n // Self-guard: skip non-text nodes when the predicate is supplied.\n if (textEdit.isTextNode && !textEdit.isTextNode(id)) return;\n\n textEdit.startEdit(id);\n },\n },\n};\n"],"mappings":";AAYA,IAAaA,IAAuD;CAClE,IAAI;CACJ,OAAO;CACP,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,UAAU,WAAW,EAAE,EAAE;CAClD,UAAU,CAAC,YAAY,WAAW;CAClC,SAAS;EACP,QAAQ;EACR,MAAM,MAAS;GACb,IAAMC,IAAMC,EAAK,WAAW,IAAI,KAAK,CAAC;GACtC,IAAID,EAAI,WAAW,GAAG;GAEtB,IAAME,IAAKF,EAAI,IACTG,IAAWF,EAAK;GACtB,AAAKE,MAGD,GAAS,cAAeA,EAAS,WAAWD,CAAE,MAElDC,EAAS,UAAUD,CAAE;EACvB;CACF;AACF"}