@weasel-js/core 1.11.1 → 1.13.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (488) hide show
  1. package/CHANGELOG.md +275 -0
  2. package/dist/WeaselProvider.js +1 -1
  3. package/dist/affordances/pathAnchors.js +10 -6
  4. package/dist/affordances/pathAnchors.js.map +1 -1
  5. package/dist/animation/poseTarget.js +46 -15
  6. package/dist/animation/poseTarget.js.map +1 -1
  7. package/dist/animation/poseTransition.js +3 -3
  8. package/dist/animation/poseTransition.js.map +1 -1
  9. package/dist/animation/reflow.js +3 -6
  10. package/dist/animation/reflow.js.map +1 -1
  11. package/dist/animation/rig/bindRig.js +2 -2
  12. package/dist/animation/rig/bindRig.js.map +1 -1
  13. package/dist/animation/rig/skinBinding.js +2 -2
  14. package/dist/animation/rig/skinBinding.js.map +1 -1
  15. package/dist/barrel/canvas.js +5 -1
  16. package/dist/barrel/chrome.js +3 -1
  17. package/dist/barrel/paint.js +4 -4
  18. package/dist/barrel/paths.js +9 -4
  19. package/dist/barrel/renderer.js +3 -2
  20. package/dist/barrel/routing.js +4 -4
  21. package/dist/barrel/scene.js +7 -1
  22. package/dist/barrel/text.js +2 -2
  23. package/dist/barrel/viewport.js +6 -2
  24. package/dist/canvas/Canvas.js +2 -1
  25. package/dist/canvas/Canvas.js.map +1 -1
  26. package/dist/canvas/CanvasView.js +23 -34
  27. package/dist/canvas/CanvasView.js.map +1 -1
  28. package/dist/canvas/ModalityHud.js +1 -1
  29. package/dist/canvas/NodeShape.js +5 -1
  30. package/dist/canvas/NodeShape.js.map +1 -1
  31. package/dist/canvas/SceneCanvas/ActionsProviderIfRoot.js +1 -1
  32. package/dist/canvas/SceneCanvas/DepRegistryProviderIfRoot.js +1 -1
  33. package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js +1 -1
  34. package/dist/canvas/SceneCanvas/SceneCanvasInput.js +2 -0
  35. package/dist/canvas/SceneCanvas/SceneCanvasInput.js.map +1 -1
  36. package/dist/canvas/SceneCanvas/SurfaceDeclarations.js +23 -0
  37. package/dist/canvas/SceneCanvas/SurfaceDeclarations.js.map +1 -0
  38. package/dist/canvas/SceneCanvas/canvasPassThrough.js +2 -1
  39. package/dist/canvas/SceneCanvas/canvasPassThrough.js.map +1 -1
  40. package/dist/canvas/SceneCanvas/defaultNodeRouting.js +2 -2
  41. package/dist/canvas/SceneCanvas/defaultNodeRouting.js.map +1 -1
  42. package/dist/canvas/SceneCanvas/props.js.map +1 -1
  43. package/dist/canvas/SceneCanvas/scenePointQuery.js +27 -5
  44. package/dist/canvas/SceneCanvas/scenePointQuery.js.map +1 -1
  45. package/dist/canvas/SceneCanvas/useActionTunings.js +6 -1
  46. package/dist/canvas/SceneCanvas/useActionTunings.js.map +1 -1
  47. package/dist/canvas/SceneCanvas/useCanvasDevtoolsRoot.js +1 -0
  48. package/dist/canvas/SceneCanvas/useCanvasDevtoolsRoot.js.map +1 -1
  49. package/dist/canvas/SceneCanvas/useCanvasTools.js +10 -2
  50. package/dist/canvas/SceneCanvas/useCanvasTools.js.map +1 -1
  51. package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js +25 -19
  52. package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js.map +1 -1
  53. package/dist/canvas/SceneCanvas/useSceneCanvasHandle.js +9 -3
  54. package/dist/canvas/SceneCanvas/useSceneCanvasHandle.js.map +1 -1
  55. package/dist/canvas/SceneCanvas/useSceneCanvasLayers.js +17 -2
  56. package/dist/canvas/SceneCanvas/useSceneCanvasLayers.js.map +1 -1
  57. package/dist/canvas/SceneCanvas/useSceneCanvasTools.js +2 -0
  58. package/dist/canvas/SceneCanvas/useSceneCanvasTools.js.map +1 -1
  59. package/dist/canvas/SceneCanvas/useSceneGestureDispatcher.js +19 -4
  60. package/dist/canvas/SceneCanvas/useSceneGestureDispatcher.js.map +1 -1
  61. package/dist/canvas/SceneCanvas/useScenePicking.js +31 -6
  62. package/dist/canvas/SceneCanvas/useScenePicking.js.map +1 -1
  63. package/dist/canvas/SceneCanvas/useSceneSelectTool.js +4 -5
  64. package/dist/canvas/SceneCanvas/useSceneSelectTool.js.map +1 -1
  65. package/dist/canvas/SceneCanvas/useSceneStandardActions.js +7 -4
  66. package/dist/canvas/SceneCanvas/useSceneStandardActions.js.map +1 -1
  67. package/dist/canvas/SceneCanvas.js +30 -12
  68. package/dist/canvas/SceneCanvas.js.map +1 -1
  69. package/dist/canvas/ViewMarker.js +35 -0
  70. package/dist/canvas/ViewMarker.js.map +1 -0
  71. package/dist/canvas/accentColor.js +26 -3
  72. package/dist/canvas/accentColor.js.map +1 -1
  73. package/dist/canvas/buildSceneTree.js +14 -20
  74. package/dist/canvas/buildSceneTree.js.map +1 -1
  75. package/dist/canvas/copiesAbove.js +1 -1
  76. package/dist/canvas/copiesAbove.js.map +1 -1
  77. package/dist/canvas/defaultDrawOne.js +11 -6
  78. package/dist/canvas/defaultDrawOne.js.map +1 -1
  79. package/dist/canvas/deps/areaSelect.js +5 -2
  80. package/dist/canvas/deps/areaSelect.js.map +1 -1
  81. package/dist/canvas/deps/booleans.js +3 -2
  82. package/dist/canvas/deps/booleans.js.map +1 -1
  83. package/dist/canvas/deps/enteredGroup.js +81 -0
  84. package/dist/canvas/deps/enteredGroup.js.map +1 -0
  85. package/dist/canvas/deps/hitTestArea.js +28 -16
  86. package/dist/canvas/deps/hitTestArea.js.map +1 -1
  87. package/dist/canvas/deps/insert.js +10 -38
  88. package/dist/canvas/deps/insert.js.map +1 -1
  89. package/dist/canvas/deps/insertSite.js +39 -0
  90. package/dist/canvas/deps/insertSite.js.map +1 -0
  91. package/dist/canvas/deps/lassoSelect.js +6 -3
  92. package/dist/canvas/deps/lassoSelect.js.map +1 -1
  93. package/dist/canvas/deps/pathEditCommits.js +3 -7
  94. package/dist/canvas/deps/pathEditCommits.js.map +1 -1
  95. package/dist/canvas/deps/pathLeaf.js +1 -1
  96. package/dist/canvas/deps/pathLeaf.js.map +1 -1
  97. package/dist/canvas/deps/slice.js +2 -1
  98. package/dist/canvas/deps/slice.js.map +1 -1
  99. package/dist/canvas/derivedPath.js +14 -6
  100. package/dist/canvas/derivedPath.js.map +1 -1
  101. package/dist/canvas/doubleClickTarget.js +9 -11
  102. package/dist/canvas/doubleClickTarget.js.map +1 -1
  103. package/dist/canvas/drawnBounds.js +26 -9
  104. package/dist/canvas/drawnBounds.js.map +1 -1
  105. package/dist/canvas/inheritedPaints.js +55 -0
  106. package/dist/canvas/inheritedPaints.js.map +1 -0
  107. package/dist/canvas/nodeShapes/derivedPainter.js +15 -16
  108. package/dist/canvas/nodeShapes/derivedPainter.js.map +1 -1
  109. package/dist/canvas/nodeShapes/nodePaint.js +7 -34
  110. package/dist/canvas/nodeShapes/nodePaint.js.map +1 -1
  111. package/dist/canvas/nodeShapes/pathPainter.js +7 -7
  112. package/dist/canvas/nodeShapes/pathPainter.js.map +1 -1
  113. package/dist/canvas/nodeShapes/rectFallbackPainter.js +4 -5
  114. package/dist/canvas/nodeShapes/rectFallbackPainter.js.map +1 -1
  115. package/dist/canvas/nodeShapes/shapePainter.js +9 -9
  116. package/dist/canvas/nodeShapes/shapePainter.js.map +1 -1
  117. package/dist/canvas/nodeShapes/textPainter.js +13 -12
  118. package/dist/canvas/nodeShapes/textPainter.js.map +1 -1
  119. package/dist/canvas/ownClip.js +24 -0
  120. package/dist/canvas/ownClip.js.map +1 -0
  121. package/dist/canvas/paintCull.js.map +1 -1
  122. package/dist/canvas/pickIndex/nodeBroadBox.js +86 -0
  123. package/dist/canvas/pickIndex/nodeBroadBox.js.map +1 -0
  124. package/dist/canvas/pickIndex/scenePickIndex.js +208 -0
  125. package/dist/canvas/pickIndex/scenePickIndex.js.map +1 -0
  126. package/dist/canvas/pickReach.js +3 -3
  127. package/dist/canvas/pickReach.js.map +1 -1
  128. package/dist/canvas/pickWalk.js +17 -91
  129. package/dist/canvas/pickWalk.js.map +1 -1
  130. package/dist/canvas/poseCascade.js +1 -1
  131. package/dist/canvas/poseCascade.js.map +1 -1
  132. package/dist/canvas/publishPreviews.js +97 -0
  133. package/dist/canvas/publishPreviews.js.map +1 -0
  134. package/dist/canvas/renderSceneToPixels.js +1 -1
  135. package/dist/canvas/renderSceneToPixels.js.map +1 -1
  136. package/dist/canvas/sceneAdapter.js +7 -5
  137. package/dist/canvas/sceneAdapter.js.map +1 -1
  138. package/dist/canvas/sceneClipboard.js +17 -10
  139. package/dist/canvas/sceneClipboard.js.map +1 -1
  140. package/dist/canvas/scenePickReads.js +37 -0
  141. package/dist/canvas/scenePickReads.js.map +1 -0
  142. package/dist/canvas/scenePickSource.js +74 -0
  143. package/dist/canvas/scenePickSource.js.map +1 -0
  144. package/dist/canvas/sceneSlotWiring.js +9 -3
  145. package/dist/canvas/sceneSlotWiring.js.map +1 -1
  146. package/dist/canvas/sceneViewRender.js +9 -4
  147. package/dist/canvas/sceneViewRender.js.map +1 -1
  148. package/dist/canvas/shownNodes.js +15 -0
  149. package/dist/canvas/shownNodes.js.map +1 -0
  150. package/dist/canvas/surfaceContribution.js +12 -8
  151. package/dist/canvas/surfaceContribution.js.map +1 -1
  152. package/dist/canvas/useCanvasView.js +4 -2
  153. package/dist/canvas/useCanvasView.js.map +1 -1
  154. package/dist/canvas/useLayerStack.js +6 -2
  155. package/dist/canvas/useLayerStack.js.map +1 -1
  156. package/dist/canvas/useSceneAdapter.js +5 -3
  157. package/dist/canvas/useSceneAdapter.js.map +1 -1
  158. package/dist/canvas/useViewAim.js +121 -0
  159. package/dist/canvas/useViewAim.js.map +1 -0
  160. package/dist/canvas/useViewNesting.js +3 -2
  161. package/dist/canvas/useViewNesting.js.map +1 -1
  162. package/dist/canvas/useViewRegistrySurface.js +4 -2
  163. package/dist/canvas/useViewRegistrySurface.js.map +1 -1
  164. package/dist/canvas/viewMarkers.js +63 -0
  165. package/dist/canvas/viewMarkers.js.map +1 -0
  166. package/dist/canvas/viewRegistry.js +27 -1
  167. package/dist/canvas/viewRegistry.js.map +1 -1
  168. package/dist/clipboard.d.ts +2 -2
  169. package/dist/{clone-C3e0OTuF.d.ts → clone-qb2e1F5p.d.ts} +2 -2
  170. package/dist/clone.d.ts +3 -3
  171. package/dist/core/isPlainObject.js +2 -2
  172. package/dist/core/layers/layerGroup.js.map +1 -1
  173. package/dist/core/pages/pageEdits.js +2 -3
  174. package/dist/core/pages/pageEdits.js.map +1 -1
  175. package/dist/core/paint/meshKindLazy.js +59 -2
  176. package/dist/core/paint/meshKindLazy.js.map +1 -1
  177. package/dist/core/scene/NodeRouting.js.map +1 -1
  178. package/dist/core/scene/arrivalWindow.js +1 -1
  179. package/dist/core/scene/arrivalWindow.js.map +1 -1
  180. package/dist/core/scene/clipNothing.js +10 -0
  181. package/dist/core/scene/clipNothing.js.map +1 -0
  182. package/dist/core/scene/declaredFieldSetters.js +44 -0
  183. package/dist/core/scene/declaredFieldSetters.js.map +1 -0
  184. package/dist/core/scene/depMemo.js +14 -3
  185. package/dist/core/scene/depMemo.js.map +1 -1
  186. package/dist/core/scene/dependents.js +9 -1
  187. package/dist/core/scene/dependents.js.map +1 -1
  188. package/dist/core/scene/derivedParts.js +10 -11
  189. package/dist/core/scene/derivedParts.js.map +1 -1
  190. package/dist/core/scene/documentOf.js +43 -0
  191. package/dist/core/scene/documentOf.js.map +1 -0
  192. package/dist/core/scene/effectivePose.js +44 -15
  193. package/dist/core/scene/effectivePose.js.map +1 -1
  194. package/dist/core/scene/fieldEdits.js +17 -14
  195. package/dist/core/scene/fieldEdits.js.map +1 -1
  196. package/dist/core/scene/fontReads.js +37 -0
  197. package/dist/core/scene/fontReads.js.map +1 -0
  198. package/dist/core/scene/historyForm.js +4 -4
  199. package/dist/core/scene/historyForm.js.map +1 -1
  200. package/dist/core/scene/inheritedPaint.js +97 -0
  201. package/dist/core/scene/inheritedPaint.js.map +1 -0
  202. package/dist/core/scene/kitOps.js +3 -23
  203. package/dist/core/scene/kitOps.js.map +1 -1
  204. package/dist/core/scene/kitRegistry.js +5 -0
  205. package/dist/core/scene/kitRegistry.js.map +1 -1
  206. package/dist/core/scene/layoutPass.js +1 -2
  207. package/dist/core/scene/layoutPass.js.map +1 -1
  208. package/dist/core/scene/nodeAsShown.js +72 -0
  209. package/dist/core/scene/nodeAsShown.js.map +1 -0
  210. package/dist/core/scene/nodeFnFields.js +2 -10
  211. package/dist/core/scene/nodeFnFields.js.map +1 -1
  212. package/dist/core/scene/nodeMemo.js +21 -8
  213. package/dist/core/scene/nodeMemo.js.map +1 -1
  214. package/dist/core/scene/nodeStore.js +2 -4
  215. package/dist/core/scene/nodeStore.js.map +1 -1
  216. package/dist/core/scene/pathEffects/blend.js.map +1 -1
  217. package/dist/core/scene/pathEffects/derive.js +10 -4
  218. package/dist/core/scene/pathEffects/derive.js.map +1 -1
  219. package/dist/core/scene/pathEffects/effects.js +3 -1
  220. package/dist/core/scene/pathEffects/effects.js.map +1 -1
  221. package/dist/core/scene/pathEffects/foundHidden.js +35 -0
  222. package/dist/core/scene/pathEffects/foundHidden.js.map +1 -0
  223. package/dist/core/scene/pathEffects/textAlong.js +95 -0
  224. package/dist/core/scene/pathEffects/textAlong.js.map +1 -0
  225. package/dist/core/scene/plyStacks.js +89 -0
  226. package/dist/core/scene/plyStacks.js.map +1 -0
  227. package/dist/core/scene/poseHold.js +42 -24
  228. package/dist/core/scene/poseHold.js.map +1 -1
  229. package/dist/core/scene/poseOverrides.js +35 -38
  230. package/dist/core/scene/poseOverrides.js.map +1 -1
  231. package/dist/core/scene/posePlies.js +59 -0
  232. package/dist/core/scene/posePlies.js.map +1 -0
  233. package/dist/core/scene/reconcileSpecs.js +6 -15
  234. package/dist/core/scene/reconcileSpecs.js.map +1 -1
  235. package/dist/core/scene/renderOrder.js +10 -4
  236. package/dist/core/scene/renderOrder.js.map +1 -1
  237. package/dist/core/scene/sameValue.js +17 -0
  238. package/dist/core/scene/sameValue.js.map +1 -0
  239. package/dist/core/scene/scene.js +3 -3
  240. package/dist/core/scene/scene.js.map +1 -1
  241. package/dist/core/scene/sceneEdits.js +8 -0
  242. package/dist/core/scene/sceneEdits.js.map +1 -1
  243. package/dist/core/scene/sceneState.js +1 -2
  244. package/dist/core/scene/sceneState.js.map +1 -1
  245. package/dist/core/scene/serialization.js +45 -9
  246. package/dist/core/scene/serialization.js.map +1 -1
  247. package/dist/core/scene/staleReplay.js +5 -2
  248. package/dist/core/scene/staleReplay.js.map +1 -1
  249. package/dist/core/scene/statedFields.js +4 -2
  250. package/dist/core/scene/statedFields.js.map +1 -1
  251. package/dist/core/scene/treeEdits.js +2 -4
  252. package/dist/core/scene/treeEdits.js.map +1 -1
  253. package/dist/core/scene/treeOrder.js +3 -1
  254. package/dist/core/scene/treeOrder.js.map +1 -1
  255. package/dist/core/scene/treeReads.js +1 -2
  256. package/dist/core/scene/treeReads.js.map +1 -1
  257. package/dist/core/scene/treeShape.js +13 -0
  258. package/dist/core/scene/treeShape.js.map +1 -0
  259. package/dist/core/scene/types.js.map +1 -1
  260. package/dist/core/scene/useScene.js +1 -1
  261. package/dist/core/scene/useScene.js.map +1 -1
  262. package/dist/{cornerHandles-BHuoMs1o.d.ts → cornerHandles-CNCb7aTY.d.ts} +3 -2
  263. package/dist/{depSchema-BpZNOv7q.d.ts → depSchema-B1RS-IJx.d.ts} +39 -18
  264. package/dist/devtools/handlers.js +1 -1
  265. package/dist/devtools/handlers.js.map +1 -1
  266. package/dist/devtools/protocol.js.map +1 -1
  267. package/dist/devtools/registry.js +4 -4
  268. package/dist/devtools/registry.js.map +1 -1
  269. package/dist/devtools-protocol.d.ts +4 -3
  270. package/dist/devtools.d.ts +3 -2
  271. package/dist/features/measure/measureContribution.js +4 -2
  272. package/dist/features/measure/measureContribution.js.map +1 -1
  273. package/dist/features/measure/measureHit.js +5 -3
  274. package/dist/features/measure/measureHit.js.map +1 -1
  275. package/dist/features/measure/measurement.js +1 -1
  276. package/dist/features/measure/measurement.js.map +1 -1
  277. package/dist/features/modes/modeLayers.js +14 -7
  278. package/dist/features/modes/modeLayers.js.map +1 -1
  279. package/dist/features/modes/modeTriggers.js +10 -6
  280. package/dist/features/modes/modeTriggers.js.map +1 -1
  281. package/dist/features/pathEffects/effectSources.js +69 -0
  282. package/dist/features/pathEffects/effectSources.js.map +1 -0
  283. package/dist/features/pathEffects/readSource.js +18 -2
  284. package/dist/features/pathEffects/readSource.js.map +1 -1
  285. package/dist/features/pathEffects/textItems.js +53 -0
  286. package/dist/features/pathEffects/textItems.js.map +1 -0
  287. package/dist/features/pathEffects/useEffectSourcesLayer.js +53 -0
  288. package/dist/features/pathEffects/useEffectSourcesLayer.js.map +1 -0
  289. package/dist/features/paths/editablePath.js +1 -1
  290. package/dist/features/paths/editablePath.js.map +1 -1
  291. package/dist/features/paths/pathEditState.js +5 -2
  292. package/dist/features/paths/pathEditState.js.map +1 -1
  293. package/dist/features/paths/pathSnap/sceneIndex.js +1 -1
  294. package/dist/features/paths/pathSnap/sceneIndex.js.map +1 -1
  295. package/dist/features/selection/enteredGroupFrame.js +65 -0
  296. package/dist/features/selection/enteredGroupFrame.js.map +1 -0
  297. package/dist/features/selection/enteredGroupScope.js +44 -0
  298. package/dist/features/selection/enteredGroupScope.js.map +1 -0
  299. package/dist/features/text/sceneTextDrafts.js +64 -0
  300. package/dist/features/text/sceneTextDrafts.js.map +1 -0
  301. package/dist/features/text/textHitAt.js +34 -3
  302. package/dist/features/text/textHitAt.js.map +1 -1
  303. package/dist/features/text/useSceneTextEdit.js +23 -19
  304. package/dist/features/text/useSceneTextEdit.js.map +1 -1
  305. package/dist/features/viewports/aim.js +105 -0
  306. package/dist/features/viewports/aim.js.map +1 -0
  307. package/dist/features/viewports/viewMarker.js +82 -0
  308. package/dist/features/viewports/viewMarker.js.map +1 -0
  309. package/dist/features/viewports/viewMarkerDrag.js +55 -0
  310. package/dist/features/viewports/viewMarkerDrag.js.map +1 -0
  311. package/dist/index.d.ts +709 -258
  312. package/dist/index.js +33 -12
  313. package/dist/interactions/actions/admitsChild.js +11 -0
  314. package/dist/interactions/actions/admitsChild.js.map +1 -0
  315. package/dist/interactions/actions/booleans/booleans.js +2 -1
  316. package/dist/interactions/actions/booleans/booleans.js.map +1 -1
  317. package/dist/interactions/actions/booleans/operands.js +6 -5
  318. package/dist/interactions/actions/booleans/operands.js.map +1 -1
  319. package/dist/interactions/actions/clipboard/action.js +27 -17
  320. package/dist/interactions/actions/clipboard/action.js.map +1 -1
  321. package/dist/interactions/actions/defaults/anchorEditing.js +44 -23
  322. package/dist/interactions/actions/defaults/anchorEditing.js.map +1 -1
  323. package/dist/interactions/actions/defaults/anchorJoin.js +12 -6
  324. package/dist/interactions/actions/defaults/anchorJoin.js.map +1 -1
  325. package/dist/interactions/actions/defaults/bendSegment.js +7 -4
  326. package/dist/interactions/actions/defaults/bendSegment.js.map +1 -1
  327. package/dist/interactions/actions/defaults/cancelGesture.js +11 -8
  328. package/dist/interactions/actions/defaults/cancelGesture.js.map +1 -1
  329. package/dist/interactions/actions/defaults/contextMenu.js +33 -11
  330. package/dist/interactions/actions/defaults/contextMenu.js.map +1 -1
  331. package/dist/interactions/actions/defaults/createPaintAction.js +5 -2
  332. package/dist/interactions/actions/defaults/createPaintAction.js.map +1 -1
  333. package/dist/interactions/actions/defaults/delete.js +28 -14
  334. package/dist/interactions/actions/defaults/delete.js.map +1 -1
  335. package/dist/interactions/actions/defaults/duplicate.js +11 -8
  336. package/dist/interactions/actions/defaults/duplicate.js.map +1 -1
  337. package/dist/interactions/actions/defaults/enterGroup.js +88 -0
  338. package/dist/interactions/actions/defaults/enterGroup.js.map +1 -0
  339. package/dist/interactions/actions/defaults/enterPathEdit.js +20 -10
  340. package/dist/interactions/actions/defaults/enterPathEdit.js.map +1 -1
  341. package/dist/interactions/actions/defaults/enterTextEdit.js +1 -1
  342. package/dist/interactions/actions/defaults/enterTextEdit.js.map +1 -1
  343. package/dist/interactions/actions/defaults/escape.js +11 -8
  344. package/dist/interactions/actions/defaults/escape.js.map +1 -1
  345. package/dist/interactions/actions/defaults/exitPathEdit.js +7 -4
  346. package/dist/interactions/actions/defaults/exitPathEdit.js.map +1 -1
  347. package/dist/interactions/actions/defaults/group.js +26 -20
  348. package/dist/interactions/actions/defaults/group.js.map +1 -1
  349. package/dist/interactions/actions/defaults/ingest.js +10 -4
  350. package/dist/interactions/actions/defaults/ingest.js.map +1 -1
  351. package/dist/interactions/actions/defaults/insertPathAnchor.js +7 -4
  352. package/dist/interactions/actions/defaults/insertPathAnchor.js.map +1 -1
  353. package/dist/interactions/actions/defaults/nudge.js +8 -2
  354. package/dist/interactions/actions/defaults/nudge.js.map +1 -1
  355. package/dist/interactions/actions/defaults/pathEditTools.js +11 -8
  356. package/dist/interactions/actions/defaults/pathEditTools.js.map +1 -1
  357. package/dist/interactions/actions/defaults/pinchZoom.js +7 -4
  358. package/dist/interactions/actions/defaults/pinchZoom.js.map +1 -1
  359. package/dist/interactions/actions/defaults/reorder.js +24 -6
  360. package/dist/interactions/actions/defaults/reorder.js.map +1 -1
  361. package/dist/interactions/actions/defaults/selectAll.js +15 -8
  362. package/dist/interactions/actions/defaults/selectAll.js.map +1 -1
  363. package/dist/interactions/actions/defaults/selectDeep.js +35 -0
  364. package/dist/interactions/actions/defaults/selectDeep.js.map +1 -0
  365. package/dist/interactions/actions/defaults/setFill.js +7 -3
  366. package/dist/interactions/actions/defaults/setFill.js.map +1 -1
  367. package/dist/interactions/actions/defaults/setFillOpacity.js +1 -1
  368. package/dist/interactions/actions/defaults/setStroke.js +12 -11
  369. package/dist/interactions/actions/defaults/setStroke.js.map +1 -1
  370. package/dist/interactions/actions/defaults/setStrokeOpacity.js +1 -1
  371. package/dist/interactions/actions/defaults/toolActivate.js +7 -1
  372. package/dist/interactions/actions/defaults/toolActivate.js.map +1 -1
  373. package/dist/interactions/actions/defaults/toolResetToDefault.js +7 -4
  374. package/dist/interactions/actions/defaults/toolResetToDefault.js.map +1 -1
  375. package/dist/interactions/actions/defaults/undoRedo.js +19 -13
  376. package/dist/interactions/actions/defaults/undoRedo.js.map +1 -1
  377. package/dist/interactions/actions/defaults/viewportWheelPan.js +16 -7
  378. package/dist/interactions/actions/defaults/viewportWheelPan.js.map +1 -1
  379. package/dist/interactions/actions/defaults/viewportZoom.js +24 -6
  380. package/dist/interactions/actions/defaults/viewportZoom.js.map +1 -1
  381. package/dist/interactions/actions/drawnBoxes.js +2 -1
  382. package/dist/interactions/actions/drawnBoxes.js.map +1 -1
  383. package/dist/interactions/actions/edit-anchors/action.js +7 -4
  384. package/dist/interactions/actions/edit-anchors/action.js.map +1 -1
  385. package/dist/interactions/actions/flip/action.js +8 -2
  386. package/dist/interactions/actions/flip/action.js.map +1 -1
  387. package/dist/interactions/actions/insert/action.js +1 -0
  388. package/dist/interactions/actions/insert/action.js.map +1 -1
  389. package/dist/interactions/actions/insert/parent.js +7 -5
  390. package/dist/interactions/actions/insert/parent.js.map +1 -1
  391. package/dist/interactions/actions/insert/placeAction.js +3 -2
  392. package/dist/interactions/actions/insert/placeAction.js.map +1 -1
  393. package/dist/interactions/actions/insert/repositionAction.js +2 -1
  394. package/dist/interactions/actions/insert/repositionAction.js.map +1 -1
  395. package/dist/interactions/actions/insert/session.js +2 -2
  396. package/dist/interactions/actions/insert/session.js.map +1 -1
  397. package/dist/interactions/actions/move/action.js +7 -4
  398. package/dist/interactions/actions/move/action.js.map +1 -1
  399. package/dist/interactions/actions/move/commit/reparent.js +1 -1
  400. package/dist/interactions/actions/move/commit/reparent.js.map +1 -1
  401. package/dist/interactions/actions/move/gestureAdapter.js +6 -7
  402. package/dist/interactions/actions/move/gestureAdapter.js.map +1 -1
  403. package/dist/interactions/actions/move/layout/exits.js +1 -1
  404. package/dist/interactions/actions/move/layout/exits.js.map +1 -1
  405. package/dist/interactions/actions/move/session.js +4 -4
  406. package/dist/interactions/actions/move/session.js.map +1 -1
  407. package/dist/interactions/actions/outlines/createOutlinesAction.js +8 -5
  408. package/dist/interactions/actions/outlines/createOutlinesAction.js.map +1 -1
  409. package/dist/interactions/actions/outlines/outlineStroke.js +5 -3
  410. package/dist/interactions/actions/outlines/outlineStroke.js.map +1 -1
  411. package/dist/interactions/actions/pathCommands/cutJoin.js +8 -5
  412. package/dist/interactions/actions/pathCommands/cutJoin.js.map +1 -1
  413. package/dist/interactions/actions/pathCommands/pathNodes.js +14 -5
  414. package/dist/interactions/actions/pathCommands/pathNodes.js.map +1 -1
  415. package/dist/interactions/actions/resize/cornerHandles.js +2 -1
  416. package/dist/interactions/actions/resize/cornerHandles.js.map +1 -1
  417. package/dist/interactions/actions/selectionSubtree.js +12 -7
  418. package/dist/interactions/actions/selectionSubtree.js.map +1 -1
  419. package/dist/interactions/actions/transform-again/action.js +8 -5
  420. package/dist/interactions/actions/transform-again/action.js.map +1 -1
  421. package/dist/interactions/gestures/thresholdDrag/thresholdDrag.js +14 -2
  422. package/dist/interactions/gestures/thresholdDrag/thresholdDrag.js.map +1 -1
  423. package/dist/json.d.ts +4 -0
  424. package/dist/json.js +3 -0
  425. package/dist/kitSettingsSchema.js +8 -1
  426. package/dist/kitSettingsSchema.js.map +1 -1
  427. package/dist/{math-CrJULaZI.d.ts → math-C_elShP_.d.ts} +7 -1
  428. package/dist/math.d.ts +1 -1
  429. package/dist/math.js +2 -1
  430. package/dist/move.d.ts +4 -4
  431. package/dist/{options-DBxEryYq.d.ts → options-ClEm3SEl.d.ts} +1 -1
  432. package/dist/resize.d.ts +4 -4
  433. package/dist/test-seams.d.ts +6 -6
  434. package/dist/tools/builtin/ellipse/useEllipseTool.js +1 -0
  435. package/dist/tools/builtin/ellipse/useEllipseTool.js.map +1 -1
  436. package/dist/tools/builtin/eyedropper/useEyedropperTool.js +2 -1
  437. package/dist/tools/builtin/eyedropper/useEyedropperTool.js.map +1 -1
  438. package/dist/tools/builtin/hand/dragPanContribution.js +4 -1
  439. package/dist/tools/builtin/hand/dragPanContribution.js.map +1 -1
  440. package/dist/tools/builtin/hand/useHandTool.js +7 -4
  441. package/dist/tools/builtin/hand/useHandTool.js.map +1 -1
  442. package/dist/tools/builtin/image/useImageTool.js +1 -0
  443. package/dist/tools/builtin/image/useImageTool.js.map +1 -1
  444. package/dist/tools/builtin/lasso/useLassoTool.js +1 -0
  445. package/dist/tools/builtin/lasso/useLassoTool.js.map +1 -1
  446. package/dist/tools/builtin/line/useLineTool.js +1 -0
  447. package/dist/tools/builtin/line/useLineTool.js.map +1 -1
  448. package/dist/tools/builtin/measure/useMeasureTool.js +12 -5
  449. package/dist/tools/builtin/measure/useMeasureTool.js.map +1 -1
  450. package/dist/tools/builtin/pen/usePenTool.js +14 -6
  451. package/dist/tools/builtin/pen/usePenTool.js.map +1 -1
  452. package/dist/tools/builtin/pencil/usePencilTool.js +1 -0
  453. package/dist/tools/builtin/pencil/usePencilTool.js.map +1 -1
  454. package/dist/tools/builtin/polygon/usePolygonTool.js +13 -4
  455. package/dist/tools/builtin/polygon/usePolygonTool.js.map +1 -1
  456. package/dist/tools/builtin/pressTarget.js +22 -0
  457. package/dist/tools/builtin/pressTarget.js.map +1 -0
  458. package/dist/tools/builtin/rect/useRectTool.js +1 -0
  459. package/dist/tools/builtin/rect/useRectTool.js.map +1 -1
  460. package/dist/tools/builtin/select/adapterPointQuery.js +6 -5
  461. package/dist/tools/builtin/select/adapterPointQuery.js.map +1 -1
  462. package/dist/tools/builtin/select/collapseDeferred.js +40 -0
  463. package/dist/tools/builtin/select/collapseDeferred.js.map +1 -0
  464. package/dist/tools/builtin/select/groupEntry.js +82 -0
  465. package/dist/tools/builtin/select/groupEntry.js.map +1 -0
  466. package/dist/tools/builtin/select/pressDecision.js +32 -0
  467. package/dist/tools/builtin/select/pressDecision.js.map +1 -0
  468. package/dist/tools/builtin/select/selectionContributions.js +22 -13
  469. package/dist/tools/builtin/select/selectionContributions.js.map +1 -1
  470. package/dist/tools/builtin/select/useSelectTool.js +74 -55
  471. package/dist/tools/builtin/select/useSelectTool.js.map +1 -1
  472. package/dist/tools/builtin/slice/useSliceTool.js +22 -8
  473. package/dist/tools/builtin/slice/useSliceTool.js.map +1 -1
  474. package/dist/tools/builtin/star/useStarTool.js +13 -4
  475. package/dist/tools/builtin/star/useStarTool.js.map +1 -1
  476. package/dist/tools/builtin/sticky/stickyNode.js +4 -1
  477. package/dist/tools/builtin/sticky/stickyNode.js.map +1 -1
  478. package/dist/tools/builtin/sticky/useStickyTool.js +10 -5
  479. package/dist/tools/builtin/sticky/useStickyTool.js.map +1 -1
  480. package/dist/tools/builtin/text/useTextTool.js +3 -1
  481. package/dist/tools/builtin/text/useTextTool.js.map +1 -1
  482. package/dist/{types-7puAuVD2.d.ts → types-49uYJN3j.d.ts} +1 -1
  483. package/dist/{types-CniVctmk.d.ts → types-BEdRIhNc.d.ts} +272 -109
  484. package/dist/{types-oFeQ5VjV.d.ts → types-p2alu-R1.d.ts} +1 -1
  485. package/dist/util/paint.js +1 -3
  486. package/dist/util/paint.js.map +1 -1
  487. package/dist/version.js +1 -1
  488. package/package.json +29 -25
@@ -15,8 +15,8 @@ function glidesByDefault(write) {
15
15
  }
16
16
  var exitsByDefault = (removal) => removal.origin !== "untracked";
17
17
  /** Hand `scene`'s pose writes to the seat's transition, each gliding from the
18
- * pose it was shown at. A node something else is showing through an override
19
- * — a drag's preview, another animation — is left to it. With `departures`,
18
+ * pose it was shown at. A node something else poses through an override — a
19
+ * drag's preview, another animation — is left to it. With `departures`,
20
20
  * removals leave as ghosts there, and a node that comes back while its ghost
21
21
  * is leaving returns from where the ghost was. */
22
22
  function bindPoseTransition(scene, seat, departures) {
@@ -37,7 +37,7 @@ function bindPoseTransition(scene, seat, departures) {
37
37
  t.settle(id);
38
38
  continue;
39
39
  }
40
- if (scene.overrides.has(w.id)) continue;
40
+ if (scene.overrides.read(w.id)?.pose !== void 0) continue;
41
41
  const from = w.from ?? back ?? s.enter?.(w.to);
42
42
  if (from !== void 0) t.settle(id, { from });
43
43
  }
@@ -1 +1 @@
1
- {"version":3,"file":"poseTransition.js","names":[],"sources":["../../src/animation/poseTransition.ts"],"sourcesContent":["import { useEffect, useMemo } from 'react';\nimport { useLatest } from '@weasel-js/react';\nimport type { PoseRemoval, PoseWrite, ScenePoseReports } from '../core/scene/poseWrites';\nimport type { NodeId, PoseOverrides } from '../core/scene/types';\nimport type { ReflowTransition } from '../layout/types';\nimport { createDepartures, type Departures } from './departures';\n\n/**\n * Which pose writes a canvas glides, and through what: `<SceneCanvas\n * poseTransition>`. The transition is the kind `reflowTransition` takes, and\n * one object can serve both.\n */\nexport interface PoseTransitionSeat<TPose> {\n /** Shows each glide through a pose override; writes nothing. */\n transition: ReflowTransition<TPose>;\n /** Whether `write` glides. Default {@link glidesByDefault}. */\n glides?: (write: PoseWrite<TPose>) => boolean;\n /** Where a node the scene adds is first shown, given the pose it was added\n * at. Absent, an added node appears in place. */\n enter?: (pose: TPose) => TPose;\n /** Where a node the scene removes is seen off to, given the pose it was\n * shown at: a ghost of it glides there fading out, drawn but never picked,\n * selected or recorded. Absent, a removed node vanishes. Needs a\n * transition from `useAnimatedReflow` or `createReflowTransition`. */\n exit?: (pose: TPose) => TPose;\n /** Whether a removal is seen off through `exit`. Default: every one but\n * an untracked removal. */\n exits?: (removal: PoseRemoval<TPose>) => boolean;\n}\n\n/**\n * The writes a {@link PoseTransitionSeat} glides unless told otherwise: a\n * direct scene call, an undo, and a redo. An action's commit (`'ops'`) is\n * left out because most show their own result — a drag's release is already\n * where it is written — and `tweenPose` records its op before it animates.\n * Layout writes belong to `reflowTransition`.\n */\nexport function glidesByDefault(write: PoseWrite<unknown>): boolean {\n return write.origin === 'call' || write.origin === 'undo' || write.origin === 'redo';\n}\n\nconst exitsByDefault = (removal: PoseRemoval<unknown>): boolean => removal.origin !== 'untracked';\n\n/** The part of a scene a pose transition hears and reads. */\nexport interface PoseTransitionScene<TPose, TNode = unknown> extends Pick<ScenePoseReports<TPose, TNode>, 'onPoseWrite'> {\n readonly overrides: Pick<PoseOverrides<TPose>, 'has'>;\n}\n\n/** Hand `scene`'s pose writes to the seat's transition, each gliding from the\n * pose it was shown at. A node something else is showing through an override\n * — a drag's preview, another animation — is left to it. With `departures`,\n * removals leave as ghosts there, and a node that comes back while its ghost\n * is leaving returns from where the ghost was. */\nexport function bindPoseTransition<TPose, TNode = unknown>(\n scene: PoseTransitionScene<TPose, TNode>,\n seat: () => PoseTransitionSeat<TPose> | null | undefined,\n departures?: Departures<TPose, TNode>,\n): () => void {\n return scene.onPoseWrite((writes, removed) => {\n const s = seat();\n if (!s) return;\n const glides = s.glides ?? glidesByDefault;\n const t = s.transition;\n for (const r of removed) {\n t.stop(r.id as string);\n if (s.exit && departures && (s.exits ?? exitsByDefault)(r)) departures.leave(r, s.exit, t);\n }\n for (const w of writes) {\n const id = w.id as string;\n const back = w.from === undefined ? departures?.recall(id) : undefined;\n if (!glides(w)) continue;\n // One already gliding turns toward the new pose from where it is shown.\n if (t.poseOf(id) !== undefined) {\n t.settle(id);\n continue;\n }\n if (scene.overrides.has(w.id as NodeId)) continue;\n const from = w.from ?? back ?? s.enter?.(w.to);\n if (from !== undefined) t.settle(id, { from });\n }\n });\n}\n\n/** {@link bindPoseTransition} for a component's life, following the latest\n * seat. Subscribes only while there is one. Answers the ghosts it shows. */\nexport function usePoseTransition<TPose, TNode = unknown>(\n scene: PoseTransitionScene<TPose, TNode>,\n seat: PoseTransitionSeat<TPose> | null | undefined,\n): Departures<TPose, TNode> {\n const latest = useLatest(seat);\n const on = !!seat;\n const departures = useMemo(() => createDepartures<TPose, TNode>(), []);\n useEffect(() => () => departures.dispose(), [departures]);\n useEffect(\n () => (on ? bindPoseTransition(scene, () => latest.current, departures) : undefined),\n [on, scene, latest, departures],\n );\n return departures;\n}\n"],"mappings":";;;;;;;;;;;;AAqCA,SAAgB,gBAAgB,OAAoC;CAClE,OAAO,MAAM,WAAW,UAAU,MAAM,WAAW,UAAU,MAAM,WAAW;AAChF;AAEA,IAAM,kBAAkB,YAA2C,QAAQ,WAAW;;;;;;AAYtF,SAAgB,mBACd,OACA,MACA,YACY;CACZ,OAAO,MAAM,aAAa,QAAQ,YAAY;EAC5C,MAAM,IAAI,KAAK;EACf,IAAI,CAAC,GAAG;EACR,MAAM,SAAS,EAAE,UAAU;EAC3B,MAAM,IAAI,EAAE;EACZ,KAAK,MAAM,KAAK,SAAS;GACvB,EAAE,KAAK,EAAE,EAAY;GACrB,IAAI,EAAE,QAAQ,eAAe,EAAE,SAAS,eAAA,CAAgB,CAAC,GAAG,WAAW,MAAM,GAAG,EAAE,MAAM,CAAC;EAC3F;EACA,KAAK,MAAM,KAAK,QAAQ;GACtB,MAAM,KAAK,EAAE;GACb,MAAM,OAAO,EAAE,SAAS,SAAY,YAAY,OAAO,EAAE,IAAI;GAC7D,IAAI,CAAC,OAAO,CAAC,GAAG;GAEhB,IAAI,EAAE,OAAO,EAAE,MAAM,QAAW;IAC9B,EAAE,OAAO,EAAE;IACX;GACF;GACA,IAAI,MAAM,UAAU,IAAI,EAAE,EAAY,GAAG;GACzC,MAAM,OAAO,EAAE,QAAQ,QAAQ,EAAE,QAAQ,EAAE,EAAE;GAC7C,IAAI,SAAS,QAAW,EAAE,OAAO,IAAI,EAAE,KAAK,CAAC;EAC/C;CACF,CAAC;AACH;;;AAIA,SAAgB,kBACd,OACA,MAC0B;CAC1B,MAAM,SAAS,UAAU,IAAI;CAC7B,MAAM,KAAK,CAAC,CAAC;CACb,MAAM,aAAa,cAAc,iBAA+B,GAAG,CAAC,CAAC;CACrE,sBAAsB,WAAW,QAAQ,GAAG,CAAC,UAAU,CAAC;CACxD,gBACS,KAAK,mBAAmB,aAAa,OAAO,SAAS,UAAU,IAAI,QAC1E;EAAC;EAAI;EAAO;EAAQ;CAAU,CAChC;CACA,OAAO;AACT"}
1
+ {"version":3,"file":"poseTransition.js","names":[],"sources":["../../src/animation/poseTransition.ts"],"sourcesContent":["import { useEffect, useMemo } from 'react';\nimport { useLatest } from '@weasel-js/react';\nimport type { PoseRemoval, PoseWrite, ScenePoseReports } from '../core/scene/poseWrites';\nimport type { NodeId, PoseOverrides } from '../core/scene/types';\nimport type { ReflowTransition } from '../layout/types';\nimport { createDepartures, type Departures } from './departures';\n\n/**\n * Which pose writes a canvas glides, and through what: `<SceneCanvas\n * poseTransition>`. The transition is the kind `reflowTransition` takes, and\n * one object can serve both.\n */\nexport interface PoseTransitionSeat<TPose> {\n /** Shows each glide through a pose override; writes nothing. */\n transition: ReflowTransition<TPose>;\n /** Whether `write` glides. Default {@link glidesByDefault}. */\n glides?: (write: PoseWrite<TPose>) => boolean;\n /** Where a node the scene adds is first shown, given the pose it was added\n * at. Absent, an added node appears in place. */\n enter?: (pose: TPose) => TPose;\n /** Where a node the scene removes is seen off to, given the pose it was\n * shown at: a ghost of it glides there fading out, drawn but never picked,\n * selected or recorded. Absent, a removed node vanishes. Needs a\n * transition from `useAnimatedReflow` or `createReflowTransition`. */\n exit?: (pose: TPose) => TPose;\n /** Whether a removal is seen off through `exit`. Default: every one but\n * an untracked removal. */\n exits?: (removal: PoseRemoval<TPose>) => boolean;\n}\n\n/**\n * The writes a {@link PoseTransitionSeat} glides unless told otherwise: a\n * direct scene call, an undo, and a redo. An action's commit (`'ops'`) is\n * left out because most show their own result — a drag's release is already\n * where it is written — and `tweenPose` records its op before it animates.\n * Layout writes belong to `reflowTransition`.\n */\nexport function glidesByDefault(write: PoseWrite<unknown>): boolean {\n return write.origin === 'call' || write.origin === 'undo' || write.origin === 'redo';\n}\n\nconst exitsByDefault = (removal: PoseRemoval<unknown>): boolean => removal.origin !== 'untracked';\n\n/** The part of a scene a pose transition hears and reads. */\nexport interface PoseTransitionScene<TPose, TNode = unknown> extends Pick<ScenePoseReports<TPose, TNode>, 'onPoseWrite'> {\n readonly overrides: Pick<PoseOverrides<TPose>, 'read'>;\n}\n\n/** Hand `scene`'s pose writes to the seat's transition, each gliding from the\n * pose it was shown at. A node something else poses through an override — a\n * drag's preview, another animation — is left to it. With `departures`,\n * removals leave as ghosts there, and a node that comes back while its ghost\n * is leaving returns from where the ghost was. */\nexport function bindPoseTransition<TPose, TNode = unknown>(\n scene: PoseTransitionScene<TPose, TNode>,\n seat: () => PoseTransitionSeat<TPose> | null | undefined,\n departures?: Departures<TPose, TNode>,\n): () => void {\n return scene.onPoseWrite((writes, removed) => {\n const s = seat();\n if (!s) return;\n const glides = s.glides ?? glidesByDefault;\n const t = s.transition;\n for (const r of removed) {\n t.stop(r.id as string);\n if (s.exit && departures && (s.exits ?? exitsByDefault)(r)) departures.leave(r, s.exit, t);\n }\n for (const w of writes) {\n const id = w.id as string;\n const back = w.from === undefined ? departures?.recall(id) : undefined;\n if (!glides(w)) continue;\n // One already gliding turns toward the new pose from where it is shown.\n if (t.poseOf(id) !== undefined) {\n t.settle(id);\n continue;\n }\n if (scene.overrides.read(w.id as NodeId)?.pose !== undefined) continue;\n const from = w.from ?? back ?? s.enter?.(w.to);\n if (from !== undefined) t.settle(id, { from });\n }\n });\n}\n\n/** {@link bindPoseTransition} for a component's life, following the latest\n * seat. Subscribes only while there is one. Answers the ghosts it shows. */\nexport function usePoseTransition<TPose, TNode = unknown>(\n scene: PoseTransitionScene<TPose, TNode>,\n seat: PoseTransitionSeat<TPose> | null | undefined,\n): Departures<TPose, TNode> {\n const latest = useLatest(seat);\n const on = !!seat;\n const departures = useMemo(() => createDepartures<TPose, TNode>(), []);\n useEffect(() => () => departures.dispose(), [departures]);\n useEffect(\n () => (on ? bindPoseTransition(scene, () => latest.current, departures) : undefined),\n [on, scene, latest, departures],\n );\n return departures;\n}\n"],"mappings":";;;;;;;;;;;;AAqCA,SAAgB,gBAAgB,OAAoC;CAClE,OAAO,MAAM,WAAW,UAAU,MAAM,WAAW,UAAU,MAAM,WAAW;AAChF;AAEA,IAAM,kBAAkB,YAA2C,QAAQ,WAAW;;;;;;AAYtF,SAAgB,mBACd,OACA,MACA,YACY;CACZ,OAAO,MAAM,aAAa,QAAQ,YAAY;EAC5C,MAAM,IAAI,KAAK;EACf,IAAI,CAAC,GAAG;EACR,MAAM,SAAS,EAAE,UAAU;EAC3B,MAAM,IAAI,EAAE;EACZ,KAAK,MAAM,KAAK,SAAS;GACvB,EAAE,KAAK,EAAE,EAAY;GACrB,IAAI,EAAE,QAAQ,eAAe,EAAE,SAAS,eAAA,CAAgB,CAAC,GAAG,WAAW,MAAM,GAAG,EAAE,MAAM,CAAC;EAC3F;EACA,KAAK,MAAM,KAAK,QAAQ;GACtB,MAAM,KAAK,EAAE;GACb,MAAM,OAAO,EAAE,SAAS,SAAY,YAAY,OAAO,EAAE,IAAI;GAC7D,IAAI,CAAC,OAAO,CAAC,GAAG;GAEhB,IAAI,EAAE,OAAO,EAAE,MAAM,QAAW;IAC9B,EAAE,OAAO,EAAE;IACX;GACF;GACA,IAAI,MAAM,UAAU,KAAK,EAAE,EAAY,CAAC,EAAE,SAAS,QAAW;GAC9D,MAAM,OAAO,EAAE,QAAQ,QAAQ,EAAE,QAAQ,EAAE,EAAE;GAC7C,IAAI,SAAS,QAAW,EAAE,OAAO,IAAI,EAAE,KAAK,CAAC;EAC/C;CACF,CAAC;AACH;;;AAIA,SAAgB,kBACd,OACA,MAC0B;CAC1B,MAAM,SAAS,UAAU,IAAI;CAC7B,MAAM,KAAK,CAAC,CAAC;CACb,MAAM,aAAa,cAAc,iBAA+B,GAAG,CAAC,CAAC;CACrE,sBAAsB,WAAW,QAAQ,GAAG,CAAC,UAAU,CAAC;CACxD,gBACS,KAAK,mBAAmB,aAAa,OAAO,SAAS,UAAU,IAAI,QAC1E;EAAC;EAAI;EAAO;EAAQ;CAAU,CAChC;CACA,OAAO;AACT"}
@@ -49,7 +49,7 @@ function makeGlides(scene, animator, read) {
49
49
  const release = (id, g) => {
50
50
  if (glides.get(id) === g) glides.delete(id);
51
51
  const nid = id;
52
- if (scene.overrides.get(nid) === g.entry) scene.overrides.clear(nid);
52
+ scene.overrides.clear(nid, g.entry);
53
53
  dirty = true;
54
54
  };
55
55
  const run = (id, g, to, settling) => {
@@ -131,10 +131,7 @@ function makeGlides(scene, animator, read) {
131
131
  glides.delete(id);
132
132
  animator.cancelKey(keyFor(id));
133
133
  const nid = id;
134
- if (scene.overrides.get(nid) === g.entry) {
135
- scene.overrides.clear(nid);
136
- scene.overrides.commit();
137
- }
134
+ scene.overrides.clear(nid, g.entry);
138
135
  unsubscribeIfIdle();
139
136
  };
140
137
  const start = (id, pose) => {
@@ -167,7 +164,7 @@ function makeGlides(scene, animator, read) {
167
164
  g.slot = from;
168
165
  g.entry.pose = from;
169
166
  }
170
- if (scene.overrides.get(id) !== g.entry) scene.overrides.set(id, g.entry);
167
+ if (!scene.overrides.has(id, g.entry)) scene.overrides.set(id, g.entry);
171
168
  return g;
172
169
  };
173
170
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"reflow.js","names":[],"sources":["../../src/animation/reflow.ts"],"sourcesContent":["import { useEffect, useMemo } from 'react';\nimport { useLatest } from '@weasel-js/react';\nimport { RECT_POSE_DESCRIPTOR, type PoseDescriptor } from '../core/geometry/poseDescriptor';\nimport { documentPose, effectivePose, type PosedNode, type PoseSource } from '../core/scene/effectivePose';\nimport type { NodeId, PoseOverride, PoseOverrides } from '../core/scene/types';\nimport type { ReflowTransition } from '../layout/types';\nimport { liveAxes } from './poseTarget';\nimport { createTarget, type Target } from '@weasel-js/animator';\nimport type { Animator, EasingSpec, SpringPresetName } from '@weasel-js/animator';\n\n/** How a reflowed sibling travels: a duration and easing, or a spring. */\nexport interface ReflowTransitionOptions<TPose> {\n /** Default 200. Ignored under `spring`. */\n ms?: number;\n easing?: EasingSpec;\n /** Travel on a spring instead of a duration. A retarget starts a new spring\n * from the pose on screen at the speed the node was moving. */\n spring?: {\n preset?: SpringPresetName;\n stiffness?: number;\n damping?: number;\n mass?: number;\n };\n /** Supplies the pose's axes, and its `lerp` is the path a timed glide\n * follows. Default `RECT_POSE_DESCRIPTOR`, each axis in a straight line.\n * A pose with no axes glides by `lerp` alone, and a retarget restarts it. */\n geometry?: PoseDescriptor<TPose>;\n /** Names each glide in `animator.watch` and `live()`. Default `'reflow'`. */\n label?: string;\n}\n\n/** A {@link ReflowTransition} the animator drives. `dispose` drops every\n * override it holds; the transition stays usable afterward. */\nexport interface AnimatedReflow<TPose = unknown> extends ReflowTransition<TPose> {\n dispose(): void;\n /** The same transition over another scene: its animator, timing and label,\n * for poses `geometry` describes given this one's descriptor. Option\n * changes reach it as they reach this one. */\n over<TOther>(\n scene: ReflowScene<TOther>,\n geometry: (mine: PoseDescriptor<TPose>) => PoseDescriptor<TOther>,\n ): AnimatedReflow<TOther>;\n}\n\n/** The part of a scene a reflow transition reads and overrides. */\nexport interface ReflowScene<TPose> extends PoseSource<TPose> {\n readonly overrides: PoseOverrides<TPose>;\n}\n\ninterface Glide<TPose> {\n entry: PoseOverride<TPose>;\n /** Where the layout wants the node shown: what its target commits. */\n slot: TPose;\n settling: boolean;\n /** Null for a pose with no axes, which glides by `lerp`. */\n target: Target<TPose> | null;\n}\n\n/** The animator's cancel-key for one node's glide. */\nconst keyFor = (id: string): string => `reflow:${id}`;\n\nfunction samePose(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true;\n if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return false;\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n const ka = Object.keys(a);\n if (ka.length !== Object.keys(b).length) return false;\n for (const k of ka) {\n if (!samePose((a as Record<string, unknown>)[k], (b as Record<string, unknown>)[k])) return false;\n }\n return true;\n}\n\nfunction makeReflow<TPose>(\n scene: ReflowScene<TPose>,\n animator: Animator,\n read: () => ReflowTransitionOptions<TPose>,\n): AnimatedReflow<TPose> {\n return {\n ...makeGlides(scene, animator, read),\n over: (other, geometry) => makeReflow(other, animator, () => {\n const { geometry: own, ...timing } = read();\n return { ...timing, geometry: geometry(own ?? (RECT_POSE_DESCRIPTOR as unknown as PoseDescriptor<TPose>)) };\n }),\n };\n}\n\nfunction makeGlides<TPose>(\n scene: ReflowScene<TPose>,\n animator: Animator,\n read: () => ReflowTransitionOptions<TPose>,\n): Omit<AnimatedReflow<TPose>, 'over'> {\n const glides = new Map<string, Glide<TPose>>();\n let dirty = false;\n let unsubscribe: (() => void) | null = null;\n\n // Ticks only mark the frame dirty; one commit per animator frame publishes\n // every glide at once.\n const subscribe = (): void => {\n if (unsubscribe) return;\n unsubscribe = animator.onTick(() => {\n if (!dirty) return;\n dirty = false;\n scene.overrides.commit();\n });\n };\n const unsubscribeIfIdle = (): void => {\n if (glides.size > 0 || !unsubscribe) return;\n unsubscribe();\n unsubscribe = null;\n };\n\n const release = (id: string, g: Glide<TPose>): void => {\n if (glides.get(id) === g) glides.delete(id);\n const nid = id as NodeId;\n if (scene.overrides.get(nid) === g.entry) scene.overrides.clear(nid);\n dirty = true;\n };\n\n const run = (id: string, g: Glide<TPose>, to: TPose, settling: boolean): void => {\n const from = g.entry.pose as TPose;\n g.settling = settling;\n if (samePose(from, to)) {\n animator.cancelKey(keyFor(id));\n g.slot = to;\n g.entry.pose = to;\n if (settling) release(id, g);\n scene.overrides.commit();\n unsubscribeIfIdle();\n return;\n }\n // Already on its way there: whatever is moving it finishes the job.\n if (g.target?.active && samePose(g.slot, to)) return;\n const o = read();\n const lerp = o.geometry?.lerp;\n const onDone = (): void => {\n if (g.target?.active || !g.settling) return;\n release(id, g);\n unsubscribeIfIdle();\n };\n const cancelKey = keyFor(id);\n const label = o.label ?? 'reflow';\n subscribe();\n if (g.target) {\n // A spring interrupts what is moving the node and takes its velocity; a timed glide adds to it.\n if (o.spring) animator.spring<TPose>({ target: g.target, to, ...o.spring, cancelKey, label, onDone });\n else {\n animator.tween<TPose>({\n target: g.target, to, ms: o.ms ?? 200, easing: o.easing, cancelKey, interrupt: false, label, onDone,\n interpolate: lerp && ((a, b, t) => lerp(a, b, t)),\n });\n }\n } else {\n if (!lerp) throw new Error('useAnimatedReflow: this pose has no axes; supply geometry: { ..., lerp }');\n g.slot = to;\n const onTick = (p: number): void => {\n g.entry.pose = lerp(from, to, p);\n dirty = true;\n };\n // The shared key is what retargets: the new animation interrupts the old.\n if (o.spring) animator.spring<number>({ from: 0, to: 1, ...o.spring, cancelKey, label, onTick, onDone });\n else animator.tween<number>({ from: 0, to: 1, ms: o.ms ?? 200, easing: o.easing, cancelKey, label, onTick, onDone });\n }\n scene.overrides.commit();\n };\n\n // False for a glide canceled through the animator: it stopped short of its\n // slot and nothing is carrying it there.\n const onCourse = (id: string, g: Glide<TPose>): boolean =>\n animator.isActive(keyFor(id)) || samePose(g.entry.pose, g.slot);\n\n const stop = (id: string): void => {\n const g = glides.get(id);\n if (!g) return;\n glides.delete(id);\n animator.cancelKey(keyFor(id));\n const nid = id as NodeId;\n if (scene.overrides.get(nid) === g.entry) {\n scene.overrides.clear(nid);\n scene.overrides.commit();\n }\n unsubscribeIfIdle();\n };\n\n const start = (id: string, pose: TPose): Glide<TPose> => {\n const g: Glide<TPose> = { entry: { pose }, slot: pose, settling: false, target: null };\n const descriptor = read().geometry ?? (RECT_POSE_DESCRIPTOR as unknown as PoseDescriptor<TPose>);\n const axes = liveAxes(descriptor, () => g.slot);\n if (axes) {\n g.target = createTarget<TPose>({\n axes,\n get: () => g.slot,\n set: (slot) => { g.slot = slot; },\n show: (shown) => {\n g.entry.pose = shown;\n dirty = true;\n },\n });\n }\n glides.set(id, g);\n return g;\n };\n\n // The glide for `id`, created if absent, starting from `from` when given,\n // and published over whatever override is showing the node.\n const claim = (\n id: string,\n node: PosedNode<TPose>,\n g: Glide<TPose> | undefined,\n from: TPose | undefined,\n ): Glide<TPose> => {\n if (!g) {\n g = start(id, from ?? effectivePose(scene, node));\n } else if (from !== undefined) {\n animator.cancelKey(keyFor(id));\n g.slot = from;\n g.entry.pose = from;\n }\n if (scene.overrides.get(id as NodeId) !== g.entry) scene.overrides.set(id as NodeId, g.entry);\n return g;\n };\n\n return {\n glide(id, pose, opts) {\n const node = scene.get(id as NodeId);\n if (!node) return;\n const from = opts?.from;\n const g = glides.get(id);\n if (g && from === undefined && !g.settling && samePose(g.slot, pose) && onCourse(id, g)) return;\n run(id, claim(id, node, g, from), pose, false);\n },\n settle(id, opts) {\n const from = opts?.from;\n const g = glides.get(id);\n if (!g && from === undefined) return;\n const node = scene.get(id as NodeId);\n if (!node) { stop(id); return; }\n const home = documentPose(scene, node);\n if (g && from === undefined) {\n if (g.settling && samePose(g.slot, home) && onCourse(id, g)) return;\n run(id, g, home, true);\n return;\n }\n run(id, claim(id, node, g, from), home, true);\n },\n stop,\n poseOf: (id) => glides.get(id)?.entry.pose,\n dispose() {\n for (const id of [...glides.keys()]) stop(id);\n },\n };\n}\n\n/**\n * A reflow transition over `animator`. Each node it moves has an animation\n * target whose committed value is the slot the layout wants it shown at, and\n * a new slot is a new animation on that target under the key `reflow:<id>`:\n * a timed glide adds to the ones still running, a spring interrupts them at\n * their velocity, and `animator.cancelKey` reaches one node's. See\n * {@link useAnimatedReflow} for the hook form.\n */\nexport function createReflowTransition<TPose>(\n scene: ReflowScene<TPose>,\n animator: Animator,\n opts: ReflowTransitionOptions<TPose> = {},\n): AnimatedReflow<TPose> {\n return makeReflow(scene, animator, () => opts);\n}\n\n/**\n * Opt a canvas's layout reflow into animation: pass the result to\n * `<SceneCanvas reflowTransition>` and siblings a drag displaces glide to\n * their slots instead of snapping. `null` (or `false`) turns it off, and\n * whatever it was holding snaps home. Option changes apply from the next\n * glide on, without rebuilding.\n */\nexport function useAnimatedReflow<TPose>(\n scene: ReflowScene<TPose>,\n animator: Animator,\n opts: ReflowTransitionOptions<TPose> | null | false | undefined,\n): AnimatedReflow<TPose> | null {\n const latest = useLatest(opts || {});\n const enabled = !!opts;\n const reflow = useMemo(\n () => (enabled ? makeReflow(scene, animator, () => latest.current) : null),\n [enabled, scene, animator, latest],\n );\n useEffect(() => () => reflow?.dispose(), [reflow]);\n return reflow;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"reflow.js","names":[],"sources":["../../src/animation/reflow.ts"],"sourcesContent":["import { useEffect, useMemo } from 'react';\nimport { useLatest } from '@weasel-js/react';\nimport { RECT_POSE_DESCRIPTOR, type PoseDescriptor } from '../core/geometry/poseDescriptor';\nimport { documentPose, effectivePose, type PosedNode, type PoseSource } from '../core/scene/effectivePose';\nimport type { NodeId, PoseOverride, PoseOverrides } from '../core/scene/types';\nimport type { ReflowTransition } from '../layout/types';\nimport { liveAxes } from './poseTarget';\nimport { createTarget, type Target } from '@weasel-js/animator';\nimport type { Animator, EasingSpec, SpringPresetName } from '@weasel-js/animator';\n\n/** How a reflowed sibling travels: a duration and easing, or a spring. */\nexport interface ReflowTransitionOptions<TPose> {\n /** Default 200. Ignored under `spring`. */\n ms?: number;\n easing?: EasingSpec;\n /** Travel on a spring instead of a duration. A retarget starts a new spring\n * from the pose on screen at the speed the node was moving. */\n spring?: {\n preset?: SpringPresetName;\n stiffness?: number;\n damping?: number;\n mass?: number;\n };\n /** Supplies the pose's axes, and its `lerp` is the path a timed glide\n * follows. Default `RECT_POSE_DESCRIPTOR`, each axis in a straight line.\n * A pose with no axes glides by `lerp` alone, and a retarget restarts it. */\n geometry?: PoseDescriptor<TPose>;\n /** Names each glide in `animator.watch` and `live()`. Default `'reflow'`. */\n label?: string;\n}\n\n/** A {@link ReflowTransition} the animator drives. `dispose` drops every\n * override it holds; the transition stays usable afterward. */\nexport interface AnimatedReflow<TPose = unknown> extends ReflowTransition<TPose> {\n dispose(): void;\n /** The same transition over another scene: its animator, timing and label,\n * for poses `geometry` describes given this one's descriptor. Option\n * changes reach it as they reach this one. */\n over<TOther>(\n scene: ReflowScene<TOther>,\n geometry: (mine: PoseDescriptor<TPose>) => PoseDescriptor<TOther>,\n ): AnimatedReflow<TOther>;\n}\n\n/** The part of a scene a reflow transition reads and overrides. */\nexport interface ReflowScene<TPose> extends PoseSource<TPose> {\n readonly overrides: PoseOverrides<TPose>;\n}\n\ninterface Glide<TPose> {\n entry: PoseOverride<TPose>;\n /** Where the layout wants the node shown: what its target commits. */\n slot: TPose;\n settling: boolean;\n /** Null for a pose with no axes, which glides by `lerp`. */\n target: Target<TPose> | null;\n}\n\n/** The animator's cancel-key for one node's glide. */\nconst keyFor = (id: string): string => `reflow:${id}`;\n\nfunction samePose(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true;\n if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return false;\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n const ka = Object.keys(a);\n if (ka.length !== Object.keys(b).length) return false;\n for (const k of ka) {\n if (!samePose((a as Record<string, unknown>)[k], (b as Record<string, unknown>)[k])) return false;\n }\n return true;\n}\n\nfunction makeReflow<TPose>(\n scene: ReflowScene<TPose>,\n animator: Animator,\n read: () => ReflowTransitionOptions<TPose>,\n): AnimatedReflow<TPose> {\n return {\n ...makeGlides(scene, animator, read),\n over: (other, geometry) => makeReflow(other, animator, () => {\n const { geometry: own, ...timing } = read();\n return { ...timing, geometry: geometry(own ?? (RECT_POSE_DESCRIPTOR as unknown as PoseDescriptor<TPose>)) };\n }),\n };\n}\n\nfunction makeGlides<TPose>(\n scene: ReflowScene<TPose>,\n animator: Animator,\n read: () => ReflowTransitionOptions<TPose>,\n): Omit<AnimatedReflow<TPose>, 'over'> {\n const glides = new Map<string, Glide<TPose>>();\n let dirty = false;\n let unsubscribe: (() => void) | null = null;\n\n // Ticks only mark the frame dirty; one commit per animator frame publishes\n // every glide at once.\n const subscribe = (): void => {\n if (unsubscribe) return;\n unsubscribe = animator.onTick(() => {\n if (!dirty) return;\n dirty = false;\n scene.overrides.commit();\n });\n };\n const unsubscribeIfIdle = (): void => {\n if (glides.size > 0 || !unsubscribe) return;\n unsubscribe();\n unsubscribe = null;\n };\n\n const release = (id: string, g: Glide<TPose>): void => {\n if (glides.get(id) === g) glides.delete(id);\n const nid = id as NodeId;\n scene.overrides.clear(nid, g.entry);\n dirty = true;\n };\n\n const run = (id: string, g: Glide<TPose>, to: TPose, settling: boolean): void => {\n const from = g.entry.pose as TPose;\n g.settling = settling;\n if (samePose(from, to)) {\n animator.cancelKey(keyFor(id));\n g.slot = to;\n g.entry.pose = to;\n if (settling) release(id, g);\n scene.overrides.commit();\n unsubscribeIfIdle();\n return;\n }\n // Already on its way there: whatever is moving it finishes the job.\n if (g.target?.active && samePose(g.slot, to)) return;\n const o = read();\n const lerp = o.geometry?.lerp;\n const onDone = (): void => {\n if (g.target?.active || !g.settling) return;\n release(id, g);\n unsubscribeIfIdle();\n };\n const cancelKey = keyFor(id);\n const label = o.label ?? 'reflow';\n subscribe();\n if (g.target) {\n // A spring interrupts what is moving the node and takes its velocity; a timed glide adds to it.\n if (o.spring) animator.spring<TPose>({ target: g.target, to, ...o.spring, cancelKey, label, onDone });\n else {\n animator.tween<TPose>({\n target: g.target, to, ms: o.ms ?? 200, easing: o.easing, cancelKey, interrupt: false, label, onDone,\n interpolate: lerp && ((a, b, t) => lerp(a, b, t)),\n });\n }\n } else {\n if (!lerp) throw new Error('useAnimatedReflow: this pose has no axes; supply geometry: { ..., lerp }');\n g.slot = to;\n const onTick = (p: number): void => {\n g.entry.pose = lerp(from, to, p);\n dirty = true;\n };\n // The shared key is what retargets: the new animation interrupts the old.\n if (o.spring) animator.spring<number>({ from: 0, to: 1, ...o.spring, cancelKey, label, onTick, onDone });\n else animator.tween<number>({ from: 0, to: 1, ms: o.ms ?? 200, easing: o.easing, cancelKey, label, onTick, onDone });\n }\n scene.overrides.commit();\n };\n\n // False for a glide canceled through the animator: it stopped short of its\n // slot and nothing is carrying it there.\n const onCourse = (id: string, g: Glide<TPose>): boolean =>\n animator.isActive(keyFor(id)) || samePose(g.entry.pose, g.slot);\n\n const stop = (id: string): void => {\n const g = glides.get(id);\n if (!g) return;\n glides.delete(id);\n animator.cancelKey(keyFor(id));\n const nid = id as NodeId;\n scene.overrides.clear(nid, g.entry);\n unsubscribeIfIdle();\n };\n\n const start = (id: string, pose: TPose): Glide<TPose> => {\n const g: Glide<TPose> = { entry: { pose }, slot: pose, settling: false, target: null };\n const descriptor = read().geometry ?? (RECT_POSE_DESCRIPTOR as unknown as PoseDescriptor<TPose>);\n const axes = liveAxes(descriptor, () => g.slot);\n if (axes) {\n g.target = createTarget<TPose>({\n axes,\n get: () => g.slot,\n set: (slot) => { g.slot = slot; },\n show: (shown) => {\n g.entry.pose = shown;\n dirty = true;\n },\n });\n }\n glides.set(id, g);\n return g;\n };\n\n // The glide for `id`, created if absent, starting from `from` when given,\n // and installed as a ply if it is not one: its place among other writers' is left alone.\n const claim = (\n id: string,\n node: PosedNode<TPose>,\n g: Glide<TPose> | undefined,\n from: TPose | undefined,\n ): Glide<TPose> => {\n if (!g) {\n g = start(id, from ?? effectivePose(scene, node));\n } else if (from !== undefined) {\n animator.cancelKey(keyFor(id));\n g.slot = from;\n g.entry.pose = from;\n }\n if (!scene.overrides.has(id as NodeId, g.entry)) scene.overrides.set(id as NodeId, g.entry);\n return g;\n };\n\n return {\n glide(id, pose, opts) {\n const node = scene.get(id as NodeId);\n if (!node) return;\n const from = opts?.from;\n const g = glides.get(id);\n if (g && from === undefined && !g.settling && samePose(g.slot, pose) && onCourse(id, g)) return;\n run(id, claim(id, node, g, from), pose, false);\n },\n settle(id, opts) {\n const from = opts?.from;\n const g = glides.get(id);\n if (!g && from === undefined) return;\n const node = scene.get(id as NodeId);\n if (!node) { stop(id); return; }\n const home = documentPose(scene, node);\n if (g && from === undefined) {\n if (g.settling && samePose(g.slot, home) && onCourse(id, g)) return;\n run(id, g, home, true);\n return;\n }\n run(id, claim(id, node, g, from), home, true);\n },\n stop,\n poseOf: (id) => glides.get(id)?.entry.pose,\n dispose() {\n for (const id of [...glides.keys()]) stop(id);\n },\n };\n}\n\n/**\n * A reflow transition over `animator`. Each node it moves has an animation\n * target whose committed value is the slot the layout wants it shown at, and\n * a new slot is a new animation on that target under the key `reflow:<id>`:\n * a timed glide adds to the ones still running, a spring interrupts them at\n * their velocity, and `animator.cancelKey` reaches one node's. See\n * {@link useAnimatedReflow} for the hook form.\n */\nexport function createReflowTransition<TPose>(\n scene: ReflowScene<TPose>,\n animator: Animator,\n opts: ReflowTransitionOptions<TPose> = {},\n): AnimatedReflow<TPose> {\n return makeReflow(scene, animator, () => opts);\n}\n\n/**\n * Opt a canvas's layout reflow into animation: pass the result to\n * `<SceneCanvas reflowTransition>` and siblings a drag displaces glide to\n * their slots instead of snapping. `null` (or `false`) turns it off, and\n * whatever it was holding snaps home. Option changes apply from the next\n * glide on, without rebuilding.\n */\nexport function useAnimatedReflow<TPose>(\n scene: ReflowScene<TPose>,\n animator: Animator,\n opts: ReflowTransitionOptions<TPose> | null | false | undefined,\n): AnimatedReflow<TPose> | null {\n const latest = useLatest(opts || {});\n const enabled = !!opts;\n const reflow = useMemo(\n () => (enabled ? makeReflow(scene, animator, () => latest.current) : null),\n [enabled, scene, animator, latest],\n );\n useEffect(() => () => reflow?.dispose(), [reflow]);\n return reflow;\n}\n"],"mappings":"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"}
@@ -84,7 +84,7 @@ function bindRigOn(options, seat) {
84
84
  const drop = () => {
85
85
  if (!installed) return;
86
86
  installed = false;
87
- for (const b of bound) scene.overrides.clear(b.node);
87
+ for (const b of bound) scene.overrides.clear(b.node, b.entry);
88
88
  skins.release();
89
89
  };
90
90
  const release = () => {
@@ -114,7 +114,7 @@ function bindRigOn(options, seat) {
114
114
  restWorld: b.restWorld,
115
115
  fromRest: motionOf(b.joint)
116
116
  });
117
- if (!installed) scene.overrides.set(b.node, b.entry);
117
+ if (!scene.overrides.has(b.node, b.entry)) scene.overrides.set(b.node, b.entry);
118
118
  }
119
119
  skins.joints.forEach(motionOf);
120
120
  skins.show(fromRest);
@@ -1 +1 @@
1
- {"version":3,"file":"bindRig.js","names":[],"sources":["../../../src/animation/rig/bindRig.ts"],"sourcesContent":["import type { PoseDescriptor } from '../../core/geometry/poseDescriptor';\nimport type { NodeId, PoseOverride } from '../../core/scene/types';\nimport { AUTO_POSE_DESCRIPTOR } from 'core/geometry/autoPoseDescriptor';\nimport { mat3, type GlMat3 } from '@weasel-js/geom';\nimport type { Target } from '@weasel-js/animator';\nimport { resolveSkeleton } from '@weasel-js/animator';\nimport type { Pose, Skeleton } from '@weasel-js/animator';\nimport type { Skin } from '@weasel-js/animator';\nimport { createRigSeat, type RigBinding, type RigSeat } from './rigSeat';\nimport { bindSkins, dataRestPath, type RestPath, type SkinScene } from './skinBinding';\n\n/** The part of a scene a rig writes to. */\nexport interface RigScene<TPose> extends SkinScene<TPose> {\n batch<T>(label: string, fn: () => T): T;\n}\n\n/** What a `RigApply` knows about the node it is posing. */\nexport interface RigApplyContext<TPose> {\n /** The joint the node rides. */\n joint: string;\n node: NodeId;\n /** The node's document pose when the rig was bound — where it sits at the\n * bind pose. */\n rest: TPose;\n /** The joint's world transform at the bind pose. */\n restWorld: GlMat3;\n /** `world * inverse(restWorld)`: the motion since the bind pose, in world\n * space. Carrying `rest` by it is what welding the node to the joint means. */\n fromRest: GlMat3;\n}\n\n/** Turns a joint's world transform into a pose for one bound node. The only\n * part of a rig that knows the scene's pose shape. */\nexport type RigApply<TPose> = (world: GlMat3, ctx: RigApplyContext<TPose>) => TPose;\n\n/** Options for `bindRig`. */\nexport interface BindRigOptions<TPose> {\n scene: RigScene<TPose>;\n skeleton: Skeleton;\n /** Joint name → the node or nodes that ride it. Each node keeps the offset\n * from its joint that it has at the bind pose. */\n bindings?: Readonly<Record<string, NodeId | readonly NodeId[]>>;\n /** Node id → the weights its path bends by. Where a bound node moves whole with one joint,\n * a skinned node's points each follow their own joints, and the rig shows the bent path\n * through the node's pose override, posed at the path's bounds. */\n skins?: Readonly<Record<NodeId, Skin>>;\n /** Where a skinned node's path is drawn when the rig is bound. Default\n * {@link dataRestPath}: the node's `data.path`, through its pose. */\n restPath?: RestPath<TPose>;\n /** Default: {@link rigidRigApply} over `descriptor`. */\n apply?: RigApply<TPose>;\n /** The descriptor the default `apply` reads and writes poses through.\n * Default `AUTO_POSE_DESCRIPTOR`. */\n descriptor?: PoseDescriptor<TPose>;\n}\n\n/** A skeleton bound to scene nodes, as `bindRig` returns it. */\nexport interface Rig {\n readonly skeleton: Skeleton;\n /**\n * The rig's pose as a value an animator moves. Its committed value starts as `{}`, the bind\n * pose, and each frame the rig is posed with what the target shows. A clip is a\n * `SampledTrack<Pose>` given this as its `target`: clips on one rig crossfade by their\n * `weight`s, weights short of 1 leave the rest to the committed pose, and a `spring` or\n * `tween` from a pose away from the committed one adds on top. `animator.hold` shows a pose made elsewhere the same way, an\n * IK solve included.\n */\n readonly target: Target<Pose>;\n /**\n * Commit `pose` and move every bound node to what the target now shows, which is `pose`\n * unless something is animating the target; a hold on it weighs the new pose in when it is\n * next read, at the animator's next frame or the hold's `touch()`. Writes go through the scene's pose overrides —\n * no history entry, no document write, no version bump — and are committed. `root`, where\n * given, replaces the placement, as {@link Rig.place}.\n */\n pose(pose: Pose, root?: GlMat3): void;\n /** Place the rig in the world by `root`, which may mirror it, and pose it there. It stays\n * until placed again; with no `root`, the rig goes back to where its skeleton puts it. */\n place(root?: GlMat3): void;\n /** The joint world transforms as the rig was last posed, root applied. */\n world(): ReadonlyMap<string, GlMat3>;\n /** Write the current frame into the bound nodes' document poses as one\n * undo entry, and drop the overrides. A skinned node's bent path goes into\n * its `data.path`. Later frames stay relative to the bind-time rest, so\n * baking does not compound. */\n bake(label?: string): void;\n /** Drop the overrides; the nodes show their document poses again until the\n * rig is next posed. */\n release(): void;\n}\n\n/**\n * Carries a node rigidly with its joint: the rest pose's center moves by\n * `fromRest`, and its rotation turns with the rest pose's x-axis. Scale in the\n * joint chain moves positions but not sizes — the pose model holds no shear,\n * and a sized pose under anisotropic scale would need one. Write an `apply`\n * that reads `world` to size nodes from joint scale.\n */\nexport function rigidRigApply<TPose>(descriptor: PoseDescriptor<TPose>): RigApply<TPose> {\n return (_world, { rest, fromRest }) => {\n const b = descriptor.getBounds(rest);\n const cx = b.x + b.width / 2;\n const cy = b.y + b.height / 2;\n const [nx, ny] = mat3.apply(fromRest, cx, cy);\n const moved = descriptor.translate\n ? descriptor.translate(rest, nx - cx, ny - cy)\n : descriptor.remapBounds(rest, b, { ...b, x: b.x + nx - cx, y: b.y + ny - cy });\n if (!descriptor.withRotation) return moved;\n const r0 = descriptor.getRotation?.(rest) ?? 0;\n const ux = Math.cos(r0);\n const uy = Math.sin(r0);\n return descriptor.withRotation(\n moved,\n Math.atan2(fromRest[1] * ux + fromRest[4] * uy, fromRest[0] * ux + fromRest[3] * uy),\n );\n };\n}\n\ninterface Bound<TPose> {\n node: NodeId;\n joint: string;\n rest: TPose;\n restWorld: GlMat3;\n entry: PoseOverride<TPose>;\n}\n\n/**\n * Bind a skeleton's joints to scene nodes. Nodes are written in world space\n * and the rig resolves its own hierarchy, so bound nodes are best left\n * unparented, or under containers whose pose does not compose into theirs;\n * the scene's tree stays free to order and group them for drawing.\n */\nexport function bindRig<TPose>(options: BindRigOptions<TPose>): Rig {\n const seat = createRigSeat(options.skeleton);\n const { rig, binding } = bindRigOn(options, seat);\n seat.binding = binding;\n return rig;\n}\n\n/** {@link bindRig} on a seat the caller keeps. The rig shows the seat's target once its\n * `binding` is the seat's. */\nexport function bindRigOn<TPose>(\n options: BindRigOptions<TPose>,\n seat: RigSeat,\n): { rig: Rig; binding: RigBinding } {\n const { scene, skeleton } = options;\n const descriptor = options.descriptor ?? (AUTO_POSE_DESCRIPTOR as PoseDescriptor<TPose>);\n const apply = options.apply ?? rigidRigApply(descriptor);\n const restWorlds = resolveSkeleton(skeleton, {});\n const restInverses = new Map<string, GlMat3>();\n const restInverseOf = (joint: string): GlMat3 => {\n let inverse = restInverses.get(joint);\n if (inverse) return inverse;\n const restWorld = restWorlds.get(joint);\n if (!restWorld) throw new Error(`bindRig: the skeleton has no joint \"${joint}\".`);\n inverse = mat3.invert(restWorld) ?? undefined;\n if (!inverse) throw new Error(`bindRig: joint \"${joint}\" is singular at the bind pose.`);\n restInverses.set(joint, inverse);\n return inverse;\n };\n\n const skins = bindSkins(scene, options.skins ?? {}, options.restPath ?? dataRestPath, descriptor);\n skins.joints.forEach(restInverseOf);\n\n const bound: Bound<TPose>[] = [];\n for (const [joint, ids] of Object.entries(options.bindings ?? {})) {\n restInverseOf(joint);\n const restWorld = restWorlds.get(joint)!;\n for (const node of typeof ids === 'string' ? [ids] : (ids as readonly NodeId[])) {\n if (options.skins && node in options.skins) {\n throw new Error(`bindRig: node \"${node}\" is both bound to joint \"${joint}\" and skinned.`);\n }\n const n = scene.get(node);\n if (!n) throw new Error(`bindRig: joint \"${joint}\" is bound to node \"${node}\", which the scene lacks.`);\n bound.push({ node, joint, rest: n.pose, restWorld, entry: { pose: n.pose } });\n }\n }\n\n let world: ReadonlyMap<string, GlMat3> = restWorlds;\n let installed = false;\n\n const drop = () => {\n if (!installed) return;\n installed = false;\n for (const b of bound) scene.overrides.clear(b.node);\n skins.release();\n };\n const release = () => {\n seat.shown = false;\n drop();\n };\n\n const show = (pose: Pose): void => {\n const local = resolveSkeleton(skeleton, pose);\n const { root } = seat;\n if (root) for (const [name, m] of local) local.set(name, mat3.multiply(root, m));\n world = local;\n const fromRest = new Map<string, GlMat3>();\n const motionOf = (joint: string): GlMat3 => {\n let delta = fromRest.get(joint);\n if (!delta) {\n delta = mat3.multiply(local.get(joint)!, restInverseOf(joint));\n fromRest.set(joint, delta);\n }\n return delta;\n };\n for (const b of bound) {\n const w = local.get(b.joint)!;\n b.entry.pose = apply(w, { joint: b.joint, node: b.node, rest: b.rest, restWorld: b.restWorld, fromRest: motionOf(b.joint) });\n if (!installed) scene.overrides.set(b.node, b.entry);\n }\n skins.joints.forEach(motionOf);\n skins.show(fromRest);\n installed = true;\n seat.shown = true;\n scene.overrides.commit();\n };\n\n const { target } = seat;\n const rig: Rig = {\n skeleton,\n target,\n pose(pose, at) {\n seat.committed = pose;\n if (at) seat.root = at;\n show(target.read());\n },\n place(at) {\n seat.root = at;\n show(target.read());\n },\n world: () => world,\n bake(label = 'Bake rig pose') {\n if (!installed) return;\n scene.batch(label, () => {\n for (const b of bound) if (b.entry.pose !== undefined) scene.setPose(b.node, b.entry.pose);\n skins.write();\n });\n release();\n },\n release,\n };\n return { rig, binding: { show, drop } };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"bindRig.js","names":[],"sources":["../../../src/animation/rig/bindRig.ts"],"sourcesContent":["import type { PoseDescriptor } from '../../core/geometry/poseDescriptor';\nimport type { NodeId, PoseOverride } from '../../core/scene/types';\nimport { AUTO_POSE_DESCRIPTOR } from 'core/geometry/autoPoseDescriptor';\nimport { mat3, type GlMat3 } from '@weasel-js/geom';\nimport type { Target } from '@weasel-js/animator';\nimport { resolveSkeleton } from '@weasel-js/animator';\nimport type { Pose, Skeleton } from '@weasel-js/animator';\nimport type { Skin } from '@weasel-js/animator';\nimport { createRigSeat, type RigBinding, type RigSeat } from './rigSeat';\nimport { bindSkins, dataRestPath, type RestPath, type SkinScene } from './skinBinding';\n\n/** The part of a scene a rig writes to. */\nexport interface RigScene<TPose> extends SkinScene<TPose> {\n batch<T>(label: string, fn: () => T): T;\n}\n\n/** What a `RigApply` knows about the node it is posing. */\nexport interface RigApplyContext<TPose> {\n /** The joint the node rides. */\n joint: string;\n node: NodeId;\n /** The node's document pose when the rig was bound — where it sits at the\n * bind pose. */\n rest: TPose;\n /** The joint's world transform at the bind pose. */\n restWorld: GlMat3;\n /** `world * inverse(restWorld)`: the motion since the bind pose, in world\n * space. Carrying `rest` by it is what welding the node to the joint means. */\n fromRest: GlMat3;\n}\n\n/** Turns a joint's world transform into a pose for one bound node. The only\n * part of a rig that knows the scene's pose shape. */\nexport type RigApply<TPose> = (world: GlMat3, ctx: RigApplyContext<TPose>) => TPose;\n\n/** Options for `bindRig`. */\nexport interface BindRigOptions<TPose> {\n scene: RigScene<TPose>;\n skeleton: Skeleton;\n /** Joint name → the node or nodes that ride it. Each node keeps the offset\n * from its joint that it has at the bind pose. */\n bindings?: Readonly<Record<string, NodeId | readonly NodeId[]>>;\n /** Node id → the weights its path bends by. Where a bound node moves whole with one joint,\n * a skinned node's points each follow their own joints, and the rig shows the bent path\n * through the node's pose override, posed at the path's bounds. */\n skins?: Readonly<Record<NodeId, Skin>>;\n /** Where a skinned node's path is drawn when the rig is bound. Default\n * {@link dataRestPath}: the node's `data.path`, through its pose. */\n restPath?: RestPath<TPose>;\n /** Default: {@link rigidRigApply} over `descriptor`. */\n apply?: RigApply<TPose>;\n /** The descriptor the default `apply` reads and writes poses through.\n * Default `AUTO_POSE_DESCRIPTOR`. */\n descriptor?: PoseDescriptor<TPose>;\n}\n\n/** A skeleton bound to scene nodes, as `bindRig` returns it. */\nexport interface Rig {\n readonly skeleton: Skeleton;\n /**\n * The rig's pose as a value an animator moves. Its committed value starts as `{}`, the bind\n * pose, and each frame the rig is posed with what the target shows. A clip is a\n * `SampledTrack<Pose>` given this as its `target`: clips on one rig crossfade by their\n * `weight`s, weights short of 1 leave the rest to the committed pose, and a `spring` or\n * `tween` from a pose away from the committed one adds on top. `animator.hold` shows a pose made elsewhere the same way, an\n * IK solve included.\n */\n readonly target: Target<Pose>;\n /**\n * Commit `pose` and move every bound node to what the target now shows, which is `pose`\n * unless something is animating the target; a hold on it weighs the new pose in when it is\n * next read, at the animator's next frame or the hold's `touch()`. Writes go through the scene's pose overrides —\n * no history entry, no document write, no version bump — and are committed. `root`, where\n * given, replaces the placement, as {@link Rig.place}.\n */\n pose(pose: Pose, root?: GlMat3): void;\n /** Place the rig in the world by `root`, which may mirror it, and pose it there. It stays\n * until placed again; with no `root`, the rig goes back to where its skeleton puts it. */\n place(root?: GlMat3): void;\n /** The joint world transforms as the rig was last posed, root applied. */\n world(): ReadonlyMap<string, GlMat3>;\n /** Write the current frame into the bound nodes' document poses as one\n * undo entry, and drop the overrides. A skinned node's bent path goes into\n * its `data.path`. Later frames stay relative to the bind-time rest, so\n * baking does not compound. */\n bake(label?: string): void;\n /** Drop the overrides; the nodes show their document poses again until the\n * rig is next posed. */\n release(): void;\n}\n\n/**\n * Carries a node rigidly with its joint: the rest pose's center moves by\n * `fromRest`, and its rotation turns with the rest pose's x-axis. Scale in the\n * joint chain moves positions but not sizes — the pose model holds no shear,\n * and a sized pose under anisotropic scale would need one. Write an `apply`\n * that reads `world` to size nodes from joint scale.\n */\nexport function rigidRigApply<TPose>(descriptor: PoseDescriptor<TPose>): RigApply<TPose> {\n return (_world, { rest, fromRest }) => {\n const b = descriptor.getBounds(rest);\n const cx = b.x + b.width / 2;\n const cy = b.y + b.height / 2;\n const [nx, ny] = mat3.apply(fromRest, cx, cy);\n const moved = descriptor.translate\n ? descriptor.translate(rest, nx - cx, ny - cy)\n : descriptor.remapBounds(rest, b, { ...b, x: b.x + nx - cx, y: b.y + ny - cy });\n if (!descriptor.withRotation) return moved;\n const r0 = descriptor.getRotation?.(rest) ?? 0;\n const ux = Math.cos(r0);\n const uy = Math.sin(r0);\n return descriptor.withRotation(\n moved,\n Math.atan2(fromRest[1] * ux + fromRest[4] * uy, fromRest[0] * ux + fromRest[3] * uy),\n );\n };\n}\n\ninterface Bound<TPose> {\n node: NodeId;\n joint: string;\n rest: TPose;\n restWorld: GlMat3;\n entry: PoseOverride<TPose>;\n}\n\n/**\n * Bind a skeleton's joints to scene nodes. Nodes are written in world space\n * and the rig resolves its own hierarchy, so bound nodes are best left\n * unparented, or under containers whose pose does not compose into theirs;\n * the scene's tree stays free to order and group them for drawing.\n */\nexport function bindRig<TPose>(options: BindRigOptions<TPose>): Rig {\n const seat = createRigSeat(options.skeleton);\n const { rig, binding } = bindRigOn(options, seat);\n seat.binding = binding;\n return rig;\n}\n\n/** {@link bindRig} on a seat the caller keeps. The rig shows the seat's target once its\n * `binding` is the seat's. */\nexport function bindRigOn<TPose>(\n options: BindRigOptions<TPose>,\n seat: RigSeat,\n): { rig: Rig; binding: RigBinding } {\n const { scene, skeleton } = options;\n const descriptor = options.descriptor ?? (AUTO_POSE_DESCRIPTOR as PoseDescriptor<TPose>);\n const apply = options.apply ?? rigidRigApply(descriptor);\n const restWorlds = resolveSkeleton(skeleton, {});\n const restInverses = new Map<string, GlMat3>();\n const restInverseOf = (joint: string): GlMat3 => {\n let inverse = restInverses.get(joint);\n if (inverse) return inverse;\n const restWorld = restWorlds.get(joint);\n if (!restWorld) throw new Error(`bindRig: the skeleton has no joint \"${joint}\".`);\n inverse = mat3.invert(restWorld) ?? undefined;\n if (!inverse) throw new Error(`bindRig: joint \"${joint}\" is singular at the bind pose.`);\n restInverses.set(joint, inverse);\n return inverse;\n };\n\n const skins = bindSkins(scene, options.skins ?? {}, options.restPath ?? dataRestPath, descriptor);\n skins.joints.forEach(restInverseOf);\n\n const bound: Bound<TPose>[] = [];\n for (const [joint, ids] of Object.entries(options.bindings ?? {})) {\n restInverseOf(joint);\n const restWorld = restWorlds.get(joint)!;\n for (const node of typeof ids === 'string' ? [ids] : (ids as readonly NodeId[])) {\n if (options.skins && node in options.skins) {\n throw new Error(`bindRig: node \"${node}\" is both bound to joint \"${joint}\" and skinned.`);\n }\n const n = scene.get(node);\n if (!n) throw new Error(`bindRig: joint \"${joint}\" is bound to node \"${node}\", which the scene lacks.`);\n bound.push({ node, joint, rest: n.pose, restWorld, entry: { pose: n.pose } });\n }\n }\n\n let world: ReadonlyMap<string, GlMat3> = restWorlds;\n let installed = false;\n\n const drop = () => {\n if (!installed) return;\n installed = false;\n for (const b of bound) scene.overrides.clear(b.node, b.entry);\n skins.release();\n };\n const release = () => {\n seat.shown = false;\n drop();\n };\n\n const show = (pose: Pose): void => {\n const local = resolveSkeleton(skeleton, pose);\n const { root } = seat;\n if (root) for (const [name, m] of local) local.set(name, mat3.multiply(root, m));\n world = local;\n const fromRest = new Map<string, GlMat3>();\n const motionOf = (joint: string): GlMat3 => {\n let delta = fromRest.get(joint);\n if (!delta) {\n delta = mat3.multiply(local.get(joint)!, restInverseOf(joint));\n fromRest.set(joint, delta);\n }\n return delta;\n };\n for (const b of bound) {\n const w = local.get(b.joint)!;\n b.entry.pose = apply(w, { joint: b.joint, node: b.node, rest: b.rest, restWorld: b.restWorld, fromRest: motionOf(b.joint) });\n // Checked every frame: the table drops a node's overrides when the node goes.\n if (!scene.overrides.has(b.node, b.entry)) scene.overrides.set(b.node, b.entry);\n }\n skins.joints.forEach(motionOf);\n skins.show(fromRest);\n installed = true;\n seat.shown = true;\n scene.overrides.commit();\n };\n\n const { target } = seat;\n const rig: Rig = {\n skeleton,\n target,\n pose(pose, at) {\n seat.committed = pose;\n if (at) seat.root = at;\n show(target.read());\n },\n place(at) {\n seat.root = at;\n show(target.read());\n },\n world: () => world,\n bake(label = 'Bake rig pose') {\n if (!installed) return;\n scene.batch(label, () => {\n for (const b of bound) if (b.entry.pose !== undefined) scene.setPose(b.node, b.entry.pose);\n skins.write();\n });\n release();\n },\n release,\n };\n return { rig, binding: { show, drop } };\n}\n"],"mappings":"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"}
@@ -47,7 +47,7 @@ function bindSkins(scene, skins, restPath, descriptor) {
47
47
  const path = skinPath(s.rest, s.skin, motions);
48
48
  s.entry.path = path;
49
49
  s.entry.pose = descriptor.fromBounds(boundsOfPath(path), s.restPose);
50
- if (!installed) scene.overrides.set(s.node, s.entry);
50
+ if (!scene.overrides.has(s.node, s.entry)) scene.overrides.set(s.node, s.entry);
51
51
  }
52
52
  installed = true;
53
53
  },
@@ -66,7 +66,7 @@ function bindSkins(scene, skins, restPath, descriptor) {
66
66
  release() {
67
67
  if (!installed) return;
68
68
  installed = false;
69
- for (const s of skinned) scene.overrides.clear(s.node);
69
+ for (const s of skinned) scene.overrides.clear(s.node, s.entry);
70
70
  }
71
71
  };
72
72
  }
@@ -1 +1 @@
1
- {"version":3,"file":"skinBinding.js","names":[],"sources":["../../../src/animation/rig/skinBinding.ts"],"sourcesContent":["import {\n boundsOfPath, pathInWorld, remapPointValues,\n type GlMat3, type Path, type PathInWorldPose, type PointOrigin,\n} from '@weasel-js/geom';\nimport type { PoseDescriptor } from '../../core/geometry/poseDescriptor';\nimport type { NodeId, PoseOverride, PoseOverrides } from '../../core/scene/types';\nimport { skinPath, type Skin } from '@weasel-js/animator';\n\n/** The part of a scene a rig's skins read and write. */\nexport interface SkinScene<TPose> {\n get(id: NodeId): { pose: TPose; data?: unknown } | undefined;\n readonly overrides: PoseOverrides<TPose>;\n setPose(id: NodeId, pose: TPose): void;\n update(id: NodeId, patch: { data: never }): void;\n}\n\n/** Where a node's path is drawn, for a skin to bend: `null` for a node with none. */\nexport type RestPath<TPose> = (node: { pose: TPose; data?: unknown }) => Path | null;\n\n/** The path in a node's `data.path`, carried through its pose as `kit:path` paints it. */\nexport function dataRestPath<TPose>(node: { pose: TPose; data?: unknown }): Path | null {\n const path = (node.data as { path?: Path } | null | undefined)?.path;\n return path ? pathInWorld(path, node.pose as PathInWorldPose) : null;\n}\n\n/**\n * `skin` after an edit to the points of the path it weighs: `origins` says where each point\n * of the new path came from, as `editAnchorSetTracked` answers. A point the edit made takes\n * weights between those of the points it lies between, and a joint left weighing nothing is\n * dropped.\n */\nexport function remapSkin(skin: Skin, origins: readonly (PointOrigin | null)[]): Skin {\n const next: Record<string, number[]> = {};\n for (const joint in skin) {\n const weights = remapPointValues(skin[joint], origins);\n if (weights.some((w) => w > 0)) next[joint] = weights;\n }\n return next;\n}\n\ninterface Skinned<TPose> {\n node: NodeId;\n skin: Skin;\n rest: Path;\n restPose: TPose;\n entry: PoseOverride<TPose>;\n}\n\n/** A rig's skinned nodes, as `bindSkins` returns them. */\nexport interface SkinBinding {\n /** Every joint a skin weighs. */\n readonly joints: readonly string[];\n /** Bend each skinned path by `motions`, which holds every one of `joints`, into its node's\n * pose override. The caller commits the overrides. */\n show(motions: ReadonlyMap<string, GlMat3>): void;\n /** Write each bent path and its bounds into the document. */\n write(): void;\n release(): void;\n}\n\n/** Read each skinned node's rest path and ready an override for it. */\nexport function bindSkins<TPose>(\n scene: SkinScene<TPose>,\n skins: Readonly<Record<NodeId, Skin>>,\n restPath: RestPath<TPose>,\n descriptor: PoseDescriptor<TPose>,\n): SkinBinding {\n const skinned: Skinned<TPose>[] = [];\n const joints = new Set<string>();\n for (const [id, skin] of Object.entries(skins) as [NodeId, Skin][]) {\n const node = scene.get(id);\n if (!node) throw new Error(`bindRig: a skin names node \"${id}\", which the scene lacks.`);\n const rest = restPath(node);\n if (!rest) throw new Error(`bindRig: node \"${id}\" has no path to skin.`);\n for (const joint in skin) joints.add(joint);\n skinned.push({ node: id, skin, rest, restPose: node.pose, entry: {} });\n }\n let installed = false;\n return {\n joints: [...joints],\n show(motions) {\n for (const s of skinned) {\n const path = skinPath(s.rest, s.skin, motions);\n s.entry.path = path;\n s.entry.pose = descriptor.fromBounds(boundsOfPath(path), s.restPose);\n if (!installed) scene.overrides.set(s.node, s.entry);\n }\n installed = true;\n },\n write() {\n for (const s of skinned) {\n const { path, pose } = s.entry;\n if (path === undefined || pose === undefined) continue;\n const data = scene.get(s.node)?.data;\n scene.update(s.node, { data: { ...(data as object), path } as never });\n scene.setPose(s.node, pose);\n }\n },\n release() {\n if (!installed) return;\n installed = false;\n for (const s of skinned) scene.overrides.clear(s.node);\n },\n };\n}\n"],"mappings":";;;;;AAoBA,SAAgB,aAAoB,MAAoD;CACtF,MAAM,OAAQ,KAAK,MAA6C;CAChE,OAAO,OAAO,YAAY,MAAM,KAAK,IAAuB,IAAI;AAClE;;;;;;;AAQA,SAAgB,UAAU,MAAY,SAAgD;CACpF,MAAM,OAAiC,CAAC;CACxC,KAAK,MAAM,SAAS,MAAM;EACxB,MAAM,UAAU,iBAAiB,KAAK,QAAQ,OAAO;EACrD,IAAI,QAAQ,MAAM,MAAM,IAAI,CAAC,GAAG,KAAK,SAAS;CAChD;CACA,OAAO;AACT;;AAuBA,SAAgB,UACd,OACA,OACA,UACA,YACa;CACb,MAAM,UAA4B,CAAC;CACnC,MAAM,yBAAS,IAAI,IAAY;CAC/B,KAAK,MAAM,CAAC,IAAI,SAAS,OAAO,QAAQ,KAAK,GAAuB;EAClE,MAAM,OAAO,MAAM,IAAI,EAAE;EACzB,IAAI,CAAC,MAAM,MAAM,IAAI,MAAM,+BAA+B,GAAG,0BAA0B;EACvF,MAAM,OAAO,SAAS,IAAI;EAC1B,IAAI,CAAC,MAAM,MAAM,IAAI,MAAM,kBAAkB,GAAG,uBAAuB;EACvE,KAAK,MAAM,SAAS,MAAM,OAAO,IAAI,KAAK;EAC1C,QAAQ,KAAK;GAAE,MAAM;GAAI;GAAM;GAAM,UAAU,KAAK;GAAM,OAAO,CAAC;EAAE,CAAC;CACvE;CACA,IAAI,YAAY;CAChB,OAAO;EACL,QAAQ,CAAC,GAAG,MAAM;EAClB,KAAK,SAAS;GACZ,KAAK,MAAM,KAAK,SAAS;IACvB,MAAM,OAAO,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO;IAC7C,EAAE,MAAM,OAAO;IACf,EAAE,MAAM,OAAO,WAAW,WAAW,aAAa,IAAI,GAAG,EAAE,QAAQ;IACnE,IAAI,CAAC,WAAW,MAAM,UAAU,IAAI,EAAE,MAAM,EAAE,KAAK;GACrD;GACA,YAAY;EACd;EACA,QAAQ;GACN,KAAK,MAAM,KAAK,SAAS;IACvB,MAAM,EAAE,MAAM,SAAS,EAAE;IACzB,IAAI,SAAS,UAAa,SAAS,QAAW;IAC9C,MAAM,OAAO,MAAM,IAAI,EAAE,IAAI,CAAC,EAAE;IAChC,MAAM,OAAO,EAAE,MAAM,EAAE,MAAM;KAAE,GAAI;KAAiB;IAAK,EAAW,CAAC;IACrE,MAAM,QAAQ,EAAE,MAAM,IAAI;GAC5B;EACF;EACA,UAAU;GACR,IAAI,CAAC,WAAW;GAChB,YAAY;GACZ,KAAK,MAAM,KAAK,SAAS,MAAM,UAAU,MAAM,EAAE,IAAI;EACvD;CACF;AACF"}
1
+ {"version":3,"file":"skinBinding.js","names":[],"sources":["../../../src/animation/rig/skinBinding.ts"],"sourcesContent":["import {\n boundsOfPath, pathInWorld, remapPointValues,\n type GlMat3, type Path, type PathInWorldPose, type PointOrigin,\n} from '@weasel-js/geom';\nimport type { PoseDescriptor } from '../../core/geometry/poseDescriptor';\nimport type { NodeId, PoseOverride, PoseOverrides } from '../../core/scene/types';\nimport { skinPath, type Skin } from '@weasel-js/animator';\n\n/** The part of a scene a rig's skins read and write. */\nexport interface SkinScene<TPose> {\n get(id: NodeId): { pose: TPose; data?: unknown } | undefined;\n readonly overrides: PoseOverrides<TPose>;\n setPose(id: NodeId, pose: TPose): void;\n update(id: NodeId, patch: { data: never }): void;\n}\n\n/** Where a node's path is drawn, for a skin to bend: `null` for a node with none. */\nexport type RestPath<TPose> = (node: { pose: TPose; data?: unknown }) => Path | null;\n\n/** The path in a node's `data.path`, carried through its pose as `kit:path` paints it. */\nexport function dataRestPath<TPose>(node: { pose: TPose; data?: unknown }): Path | null {\n const path = (node.data as { path?: Path } | null | undefined)?.path;\n return path ? pathInWorld(path, node.pose as PathInWorldPose) : null;\n}\n\n/**\n * `skin` after an edit to the points of the path it weighs: `origins` says where each point\n * of the new path came from, as `editAnchorSetTracked` answers. A point the edit made takes\n * weights between those of the points it lies between, and a joint left weighing nothing is\n * dropped.\n */\nexport function remapSkin(skin: Skin, origins: readonly (PointOrigin | null)[]): Skin {\n const next: Record<string, number[]> = {};\n for (const joint in skin) {\n const weights = remapPointValues(skin[joint], origins);\n if (weights.some((w) => w > 0)) next[joint] = weights;\n }\n return next;\n}\n\ninterface Skinned<TPose> {\n node: NodeId;\n skin: Skin;\n rest: Path;\n restPose: TPose;\n entry: PoseOverride<TPose>;\n}\n\n/** A rig's skinned nodes, as `bindSkins` returns them. */\nexport interface SkinBinding {\n /** Every joint a skin weighs. */\n readonly joints: readonly string[];\n /** Bend each skinned path by `motions`, which holds every one of `joints`, into its node's\n * pose override. The caller commits the overrides. */\n show(motions: ReadonlyMap<string, GlMat3>): void;\n /** Write each bent path and its bounds into the document. */\n write(): void;\n release(): void;\n}\n\n/** Read each skinned node's rest path and ready an override for it. */\nexport function bindSkins<TPose>(\n scene: SkinScene<TPose>,\n skins: Readonly<Record<NodeId, Skin>>,\n restPath: RestPath<TPose>,\n descriptor: PoseDescriptor<TPose>,\n): SkinBinding {\n const skinned: Skinned<TPose>[] = [];\n const joints = new Set<string>();\n for (const [id, skin] of Object.entries(skins) as [NodeId, Skin][]) {\n const node = scene.get(id);\n if (!node) throw new Error(`bindRig: a skin names node \"${id}\", which the scene lacks.`);\n const rest = restPath(node);\n if (!rest) throw new Error(`bindRig: node \"${id}\" has no path to skin.`);\n for (const joint in skin) joints.add(joint);\n skinned.push({ node: id, skin, rest, restPose: node.pose, entry: {} });\n }\n let installed = false;\n return {\n joints: [...joints],\n show(motions) {\n for (const s of skinned) {\n const path = skinPath(s.rest, s.skin, motions);\n s.entry.path = path;\n s.entry.pose = descriptor.fromBounds(boundsOfPath(path), s.restPose);\n if (!scene.overrides.has(s.node, s.entry)) scene.overrides.set(s.node, s.entry);\n }\n installed = true;\n },\n write() {\n for (const s of skinned) {\n const { path, pose } = s.entry;\n if (path === undefined || pose === undefined) continue;\n const data = scene.get(s.node)?.data;\n scene.update(s.node, { data: { ...(data as object), path } as never });\n scene.setPose(s.node, pose);\n }\n },\n release() {\n if (!installed) return;\n installed = false;\n for (const s of skinned) scene.overrides.clear(s.node, s.entry);\n },\n };\n}\n"],"mappings":";;;;;AAoBA,SAAgB,aAAoB,MAAoD;CACtF,MAAM,OAAQ,KAAK,MAA6C;CAChE,OAAO,OAAO,YAAY,MAAM,KAAK,IAAuB,IAAI;AAClE;;;;;;;AAQA,SAAgB,UAAU,MAAY,SAAgD;CACpF,MAAM,OAAiC,CAAC;CACxC,KAAK,MAAM,SAAS,MAAM;EACxB,MAAM,UAAU,iBAAiB,KAAK,QAAQ,OAAO;EACrD,IAAI,QAAQ,MAAM,MAAM,IAAI,CAAC,GAAG,KAAK,SAAS;CAChD;CACA,OAAO;AACT;;AAuBA,SAAgB,UACd,OACA,OACA,UACA,YACa;CACb,MAAM,UAA4B,CAAC;CACnC,MAAM,yBAAS,IAAI,IAAY;CAC/B,KAAK,MAAM,CAAC,IAAI,SAAS,OAAO,QAAQ,KAAK,GAAuB;EAClE,MAAM,OAAO,MAAM,IAAI,EAAE;EACzB,IAAI,CAAC,MAAM,MAAM,IAAI,MAAM,+BAA+B,GAAG,0BAA0B;EACvF,MAAM,OAAO,SAAS,IAAI;EAC1B,IAAI,CAAC,MAAM,MAAM,IAAI,MAAM,kBAAkB,GAAG,uBAAuB;EACvE,KAAK,MAAM,SAAS,MAAM,OAAO,IAAI,KAAK;EAC1C,QAAQ,KAAK;GAAE,MAAM;GAAI;GAAM;GAAM,UAAU,KAAK;GAAM,OAAO,CAAC;EAAE,CAAC;CACvE;CACA,IAAI,YAAY;CAChB,OAAO;EACL,QAAQ,CAAC,GAAG,MAAM;EAClB,KAAK,SAAS;GACZ,KAAK,MAAM,KAAK,SAAS;IACvB,MAAM,OAAO,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO;IAC7C,EAAE,MAAM,OAAO;IACf,EAAE,MAAM,OAAO,WAAW,WAAW,aAAa,IAAI,GAAG,EAAE,QAAQ;IACnE,IAAI,CAAC,MAAM,UAAU,IAAI,EAAE,MAAM,EAAE,KAAK,GAAG,MAAM,UAAU,IAAI,EAAE,MAAM,EAAE,KAAK;GAChF;GACA,YAAY;EACd;EACA,QAAQ;GACN,KAAK,MAAM,KAAK,SAAS;IACvB,MAAM,EAAE,MAAM,SAAS,EAAE;IACzB,IAAI,SAAS,UAAa,SAAS,QAAW;IAC9C,MAAM,OAAO,MAAM,IAAI,EAAE,IAAI,CAAC,EAAE;IAChC,MAAM,OAAO,EAAE,MAAM,EAAE,MAAM;KAAE,GAAI;KAAiB;IAAK,EAAW,CAAC;IACrE,MAAM,QAAQ,EAAE,MAAM,IAAI;GAC5B;EACF;EACA,UAAU;GACR,IAAI,CAAC,WAAW;GAChB,YAAY;GACZ,KAAK,MAAM,KAAK,SAAS,MAAM,UAAU,MAAM,EAAE,MAAM,EAAE,KAAK;EAChE;CACF;AACF"}
@@ -1,13 +1,16 @@
1
1
  import { DEFAULT_LAYER_RETAIN } from "../core/layers/retain.js";
2
2
  import { subscribeToSources } from "../core/layers/redrawSource.js";
3
3
  import { depsUnchanged, drawLayers, drawOneLayer, isLayerPainted, isLayerVisible, paintedLayers } from "../core/layers/render.js";
4
+ import { inheritedPaintIn, inheritedPaintOf, inheritsPaint, withInheritedPaint } from "../core/scene/inheritedPaint.js";
4
5
  import { dlog, dwarn, isDebugEnabled } from "../debug/flag.js";
6
+ import { paintAbove, withInheritedPaintBounds, withInheritedPaints } from "../canvas/inheritedPaints.js";
5
7
  import { OVERLAY_ROLE_STROKES } from "../canvas/overlayRoleStrokes.js";
6
8
  import { DEFAULT_INK, findNodeShape, findShapeBounds, findShapeInk, findShapeSilhouette, getNodeShapes, registerNodeShape, shapeCoversPoint } from "../canvas/NodeShape.js";
7
9
  import { drawnAABBOf, drawnBoundsOf, findShapeDrawnBounds, inkExtentsOf } from "../canvas/drawnBounds.js";
8
10
  import { insertPreviewExtent } from "../canvas/insertPreviewExtent.js";
9
11
  import { CANVAS_CONTEXT_ATTRIBUTES } from "../canvas/contextAttributes.js";
10
12
  import { isOverChildren, overChildren, splitOverChildren } from "../canvas/overChildren.js";
13
+ import { clipOutline } from "../canvas/ownClip.js";
11
14
  import { drawnBoundsScene } from "../canvas/derivedPath.js";
12
15
  import { sceneToAdapter } from "../canvas/sceneAdapter.js";
13
16
  import { defaultDrawOne, defaultPaintBounds } from "../canvas/defaultDrawOne.js";
@@ -25,6 +28,7 @@ import { PickHud } from "../canvas/PickHud.js";
25
28
  import { PATH_OVERLAY_ROLES, createPathOverlay } from "../canvas/pathOverlay.js";
26
29
  import { DevtoolsLabel, useDevtoolsLabel } from "../devtools/label.js";
27
30
  import { defaultNodeRouting, groupNodeRouting, inferredNodeRouting } from "../canvas/SceneCanvas/defaultNodeRouting.js";
31
+ import { publishPreviews } from "../canvas/publishPreviews.js";
28
32
  import { DEFAULT_HANDLE_SIZE } from "../canvas/SceneCanvas/props.js";
29
33
  import { resolveOverlays } from "../interactions/actions/resolveOverlays.js";
30
34
  import { flattenPreviews, resolvePreviews } from "../interactions/actions/resolvePreviews.js";
@@ -42,4 +46,4 @@ import { modeTriggers } from "../features/modes/modeTriggers.js";
42
46
  import { createChildrenLayer } from "../core/layers/children.js";
43
47
  import { bitmapSrc, getImageBitmap as getImageBitmap$1, imageStatus as imageStatus$1, isVectorImageSrc, releaseImage, retryImage, setImageCacheBudget, subscribeImageReady as subscribeImageReady$1 } from "@weasel-js/renderer";
44
48
 
45
- export { CANVAS_CONTEXT_ATTRIBUTES, CursorCoordsHud, DEBUG_FEATURES, DEFAULT_DEBUG_STROKES, DEFAULT_DEBUG_THEME, DEFAULT_HANDLE_SIZE, DEFAULT_INK, DEFAULT_LAYER_RETAIN, DevtoolsLabel, LeanSceneCanvas, OVERLAY_ROLE_STROKES, PATH_OVERLAY_ROLES, PickHud, SceneCanvas, WeaselProvider, bitmapSrc, buildDebugOverlayCommands, createChildrenLayer, createDebugOverlayLayer, createDebugSink, createNodeProperties, createNodeRouting, createPathOverlay, defaultDrawOne, defaultNodeProperties, defaultNodeRouting, defaultPaintBounds, depsUnchanged, dlog, drawLayers, drawOneLayer, drawnAABBOf, drawnBoundsOf, drawnBoundsScene, dwarn, findNodeShape, findShapeBounds, findShapeDrawnBounds, findShapeInk, findShapeSilhouette, flattenPreviews, getImageBitmap$1 as getImageBitmap, getNodeShapes, groupNodeRouting, hostAnchorCss, hostAnchorRect, imageStatus$1 as imageStatus, inferredNodeProperties, inferredNodeRouting, inkExtentsOf, insertPreviewExtent, isDebugEnabled, isLayerPainted, isLayerVisible, isOverChildren, isVectorImageSrc, kitTextHandler, minSizeOf, modeDecorationLayer, modeTriggers, openFilePicker, overChildren, paintedLayers, parseDebugFlags, registerContentHandler, registerNodeShape, releaseImage, resolveOverlays, resolvePreviews, retryImage, rotationDegreesUnit, routeKind, sceneToAdapter, setImageCacheBudget, shapeCoversPoint, splitOverChildren, subscribeImageReady$1 as subscribeImageReady, subscribeToSources, useDevtoolsLabel, useHostAnchor, useSceneAdapter, workspaceTintLayer };
49
+ export { CANVAS_CONTEXT_ATTRIBUTES, CursorCoordsHud, DEBUG_FEATURES, DEFAULT_DEBUG_STROKES, DEFAULT_DEBUG_THEME, DEFAULT_HANDLE_SIZE, DEFAULT_INK, DEFAULT_LAYER_RETAIN, DevtoolsLabel, LeanSceneCanvas, OVERLAY_ROLE_STROKES, PATH_OVERLAY_ROLES, PickHud, SceneCanvas, WeaselProvider, bitmapSrc, buildDebugOverlayCommands, clipOutline, createChildrenLayer, createDebugOverlayLayer, createDebugSink, createNodeProperties, createNodeRouting, createPathOverlay, defaultDrawOne, defaultNodeProperties, defaultNodeRouting, defaultPaintBounds, depsUnchanged, dlog, drawLayers, drawOneLayer, drawnAABBOf, drawnBoundsOf, drawnBoundsScene, dwarn, findNodeShape, findShapeBounds, findShapeDrawnBounds, findShapeInk, findShapeSilhouette, flattenPreviews, getImageBitmap$1 as getImageBitmap, getNodeShapes, groupNodeRouting, hostAnchorCss, hostAnchorRect, imageStatus$1 as imageStatus, inferredNodeProperties, inferredNodeRouting, inheritedPaintIn, inheritedPaintOf, inheritsPaint, inkExtentsOf, insertPreviewExtent, isDebugEnabled, isLayerPainted, isLayerVisible, isOverChildren, isVectorImageSrc, kitTextHandler, minSizeOf, modeDecorationLayer, modeTriggers, openFilePicker, overChildren, paintAbove, paintedLayers, parseDebugFlags, publishPreviews, registerContentHandler, registerNodeShape, releaseImage, resolveOverlays, resolvePreviews, retryImage, rotationDegreesUnit, routeKind, sceneToAdapter, setImageCacheBudget, shapeCoversPoint, splitOverChildren, subscribeImageReady$1 as subscribeImageReady, subscribeToSources, useDevtoolsLabel, useHostAnchor, useSceneAdapter, withInheritedPaint, withInheritedPaintBounds, withInheritedPaints, workspaceTintLayer };
@@ -4,6 +4,7 @@ import { annulusSemiAxes, hitAffordanceRegions, pointRegionFrame } from "../affo
4
4
  import { createCornerResizeAffordance } from "../affordances/cornerResize.js";
5
5
  import { createRotationAffordance } from "../affordances/rotationHandle.js";
6
6
  import { PATH_ANCHOR_CHROME_ID, createPathAnchorAffordances } from "../affordances/pathAnchors.js";
7
+ import { createEnteredGroup, useEnteredGroup } from "../canvas/deps/enteredGroup.js";
7
8
  import { actionIs, always, and, canHover, capabilityAll, capabilityIn, capabilityIs, capabilityNot, coarsePointer, cond, editingAnchors, focused, gesturing, hovering, hoveringSelected, modeIn, modeIs, modeNot, modifierHeld, multiActive, never, not, or, selectionAtLeast, selectionEmpty, selectionIs, when, zoomAtLeast } from "../features/chrome-caps/conditions.js";
8
9
  import { composeSelectionPose } from "../features/selection/selectionPose.js";
9
10
  import { createSelectionHandlesLayer, createSelectionOutlineLayer, createSelectionOverlayLayer } from "../features/selection/overlay.js";
@@ -12,8 +13,9 @@ import { resolveVisibility } from "../features/chrome-caps/resolve.js";
12
13
  import { buildChromeCtx } from "../features/chrome-caps/buildChromeCtx.js";
13
14
  import { useHoverTracking } from "../features/chrome-caps/useHoverTracking.js";
14
15
  import { ALWAYS, DEFAULT_ALLOWED_CAPABILITIES, NEVER, buildRuleCtx, describeRule, evaluate } from "../features/chrome-caps/index.js";
16
+ import { createEnteredGroupScope } from "../features/selection/enteredGroupScope.js";
15
17
  import { composeAffordanceLayer } from "../affordances/composeAffordanceLayer.js";
16
18
  import { SelectionContextProvider as SelectionContextProvider$1, SelectionContextProviderIfRoot as SelectionContextProviderIfRoot$1, usePublishSelection as usePublishSelection$1, useSelectionContext } from "@weasel-js/routing/react";
17
19
  import { ANGLE_RADIANS as ANGLE_RADIANS$1, IMPERIAL_INCHES, METRIC_MM, PIXELS, axisUnits, formatAxes, formatScoped, formatUnit, fromRoot, parseUnitExpr, resolveAxes, resolveScoped, resolveUnit, resolveUnitExpr, scopesOf as scopesOf$1, toRoot, unitScale } from "@weasel-js/quantity";
18
20
 
19
- export { ALWAYS, ANGLE_RADIANS$1 as ANGLE_RADIANS, DEFAULT_ALLOWED_CAPABILITIES, IMPERIAL_INCHES, METRIC_MM, NEVER, PATH_ANCHOR_CHROME_ID, PIXELS, SelectionContextProvider$1 as SelectionContextProvider, SelectionContextProviderIfRoot$1 as SelectionContextProviderIfRoot, actionIs, always, and, annulusSemiAxes, axisUnits, buildChromeCtx, buildRuleCtx, canHover, capabilityAll, capabilityIn, capabilityIs, capabilityNot, coarsePointer, composeAffordanceLayer, composeSelectionPose, cond, createCornerResizeAffordance, createPathAnchorAffordances, createRotationAffordance, createSelectionHandlesLayer, createSelectionOutlineLayer, createSelectionOverlayLayer, defaultVisibilityRules, describeRule, editingAnchors, evaluate, focused, formatAxes, formatScoped, formatUnit, fromRoot, gesturing, hitAffordanceRegions, hovering, hoveringSelected, modeIn, modeIs, modeNot, modifierHeld, multiActive, never, not, or, paintsLayer, parseUnitExpr, pointRegionFrame, resolveAxes, resolveScoped, resolveUnit, resolveUnitExpr, resolveVisibility, scopesOf$1 as scopesOf, selectionAtLeast, selectionEmpty, selectionIs, toRoot, unitScale, useHoverTracking, usePublishSelection$1 as usePublishSelection, useSelection, useSelectionContext, when, zoomAtLeast };
21
+ export { ALWAYS, ANGLE_RADIANS$1 as ANGLE_RADIANS, DEFAULT_ALLOWED_CAPABILITIES, IMPERIAL_INCHES, METRIC_MM, NEVER, PATH_ANCHOR_CHROME_ID, PIXELS, SelectionContextProvider$1 as SelectionContextProvider, SelectionContextProviderIfRoot$1 as SelectionContextProviderIfRoot, actionIs, always, and, annulusSemiAxes, axisUnits, buildChromeCtx, buildRuleCtx, canHover, capabilityAll, capabilityIn, capabilityIs, capabilityNot, coarsePointer, composeAffordanceLayer, composeSelectionPose, cond, createCornerResizeAffordance, createEnteredGroup, createEnteredGroupScope, createPathAnchorAffordances, createRotationAffordance, createSelectionHandlesLayer, createSelectionOutlineLayer, createSelectionOverlayLayer, defaultVisibilityRules, describeRule, editingAnchors, evaluate, focused, formatAxes, formatScoped, formatUnit, fromRoot, gesturing, hitAffordanceRegions, hovering, hoveringSelected, modeIn, modeIs, modeNot, modifierHeld, multiActive, never, not, or, paintsLayer, parseUnitExpr, pointRegionFrame, resolveAxes, resolveScoped, resolveUnit, resolveUnitExpr, resolveVisibility, scopesOf$1 as scopesOf, selectionAtLeast, selectionEmpty, selectionIs, toRoot, unitScale, useEnteredGroup, useHoverTracking, usePublishSelection$1 as usePublishSelection, useSelection, useSelectionContext, when, zoomAtLeast };
@@ -1,12 +1,12 @@
1
- import { getAlpha01, mergeAlphaFromPrev, toHex8, withAlpha01 } from "../util/color.js";
2
- import { DEFAULT_FILL_COLOR, DEFAULT_PALETTE, DEFAULT_SHAPE_FILL, DEFAULT_STROKE_COLOR, GHOST_STROKE, cycleFill, paintAlpha, paintWithAlpha, paintWithColor, solid, strokeOf, strokeWith } from "../util/paint.js";
3
1
  import { pathPaintOf } from "../canvas/nodeShapes/nodePaint.js";
4
2
  import { getPaintKind, listGradientKinds, listPaintKinds, paintKindOf, paintKindRegistry, patternFamily, registerPaintKind, registerPaintKindLoader, seedTile, switchGradientKind } from "../core/paint/paintKinds.js";
3
+ import { getAlpha01, mergeAlphaFromPrev, toHex8, withAlpha01 } from "../util/color.js";
4
+ import { DEFAULT_FILL_COLOR, DEFAULT_PALETTE, DEFAULT_STROKE_COLOR, GHOST_STROKE, cycleFill, paintAlpha, paintWithAlpha, paintWithColor, solid, strokeOf, strokeWith } from "../util/paint.js";
5
5
  import { asPaint } from "../core/paint/paintKindEntry.js";
6
6
  import { useGradientKinds, usePaintKind, usePaintKinds } from "../core/usePaintKinds.js";
7
7
  import { commandFill as commandFill$1, commandPaint as commandPaint$1, commandStroke as commandStroke$1, createTilePattern, fillInPoseFrame, fillToBoundsFrame, isPaintKindKnown as isPaintKindKnown$1, resolveFillPattern, resolvePatternSpec, warmPaintKinds as warmPaintKinds$1 } from "@weasel-js/renderer";
8
- import { STROKE_DASH_RATIOS, TILE_KINDS, alignedStrokeRect as alignedStrokeRect$1, composePatternTransform, contrastLineColor, dashForStrokeStyle as dashForStrokeStyle$1, decomposePatternTransform, gradientForBounds as gradientForBounds$1, gradientGeometry, hexToRgbBytes, hexToRgba, isGradientPaint as isGradientPaint$1, isPatternPaint, isSolidPaint, isTileKind, isTilePaint as isTilePaint$1, lerpFill as lerpFill$1, lerpPaint, lerpStroke as lerpStroke$1, normalizeHex, parseColor, parseColorToRgba255, parseHexBytes, patternPlacementOf, resolveColor, resolveScreenLength as resolveScreenLength$1, rgbaToHex, sampleGradientStops, scaleVertexWidth as scaleVertexWidth$1, strokeDashStyleOf as strokeDashStyleOf$1, tileSpecOf, vertexHalfWidths as vertexHalfWidths$1, vertexWidthFromSides as vertexWidthFromSides$1, widestHalfWidth, withGradientKind as withGradientKind$1 } from "@weasel-js/paint";
8
+ import { INHERIT as INHERIT$1, STROKE_DASH_RATIOS, TILE_KINDS, alignedStrokeRect as alignedStrokeRect$1, composePatternTransform, contrastLineColor, contrastRatio, dashForStrokeStyle as dashForStrokeStyle$1, decomposePatternTransform, gradientForBounds as gradientForBounds$1, gradientGeometry, hexToRgbBytes, hexToRgba, isGradientPaint as isGradientPaint$1, isPatternPaint, isSolidPaint, isTileKind, isTilePaint as isTilePaint$1, lerpFill as lerpFill$1, lerpPaint, lerpStroke as lerpStroke$1, normalizeHex, parseColor, parseColorToRgba255, parseHexBytes, patternPlacementOf, resolveColor, resolveFill as resolveFill$1, resolveScreenLength as resolveScreenLength$1, resolveStroke as resolveStroke$1, rgbaToHex, sampleGradientStops, scaleVertexWidth as scaleVertexWidth$1, strokeDashStyleOf as strokeDashStyleOf$1, tileSpecOf, vertexHalfWidths as vertexHalfWidths$1, vertexWidthFromSides as vertexWidthFromSides$1, wcagLevels, widestHalfWidth, withGradientKind as withGradientKind$1 } from "@weasel-js/paint";
9
9
  import { BUILTIN_MARKERS, getMarker, listMarkers as listMarkers$1, markerInset, markerKeyOf, markerRegistry, markerSites, registerMarker, resolveMarkerSize, resolveStrokeWidth as resolveStrokeWidth$1, strokeInsets as strokeInsets$1 } from "@weasel-js/stroke";
10
10
  import { trimPolyline } from "@weasel-js/geom/tessellate";
11
11
 
12
- export { BUILTIN_MARKERS, DEFAULT_FILL_COLOR, DEFAULT_PALETTE, DEFAULT_SHAPE_FILL, DEFAULT_STROKE_COLOR, GHOST_STROKE, STROKE_DASH_RATIOS, TILE_KINDS, alignedStrokeRect$1 as alignedStrokeRect, asPaint, commandFill$1 as commandFill, commandPaint$1 as commandPaint, commandStroke$1 as commandStroke, composePatternTransform, contrastLineColor, createTilePattern, cycleFill, dashForStrokeStyle$1 as dashForStrokeStyle, decomposePatternTransform, fillInPoseFrame, fillToBoundsFrame, getAlpha01, getMarker, getPaintKind, gradientForBounds$1 as gradientForBounds, gradientGeometry, hexToRgbBytes, hexToRgba, isGradientPaint$1 as isGradientPaint, isPaintKindKnown$1 as isPaintKindKnown, isPatternPaint, isSolidPaint, isTileKind, isTilePaint$1 as isTilePaint, lerpFill$1 as lerpFill, lerpPaint, lerpStroke$1 as lerpStroke, listGradientKinds, listMarkers$1 as listMarkers, listPaintKinds, markerInset, markerKeyOf, markerRegistry, markerSites, mergeAlphaFromPrev, normalizeHex, paintAlpha, paintKindOf, paintKindRegistry, paintWithAlpha, paintWithColor, parseColor, parseColorToRgba255, parseHexBytes, pathPaintOf, patternFamily, patternPlacementOf, registerMarker, registerPaintKind, registerPaintKindLoader, resolveColor, resolveFillPattern, resolveMarkerSize, resolvePatternSpec, resolveScreenLength$1 as resolveScreenLength, resolveStrokeWidth$1 as resolveStrokeWidth, rgbaToHex, sampleGradientStops, scaleVertexWidth$1 as scaleVertexWidth, seedTile, solid, strokeDashStyleOf$1 as strokeDashStyleOf, strokeInsets$1 as strokeInsets, strokeOf, strokeWith, switchGradientKind, tileSpecOf, toHex8, trimPolyline, useGradientKinds, usePaintKind, usePaintKinds, vertexHalfWidths$1 as vertexHalfWidths, vertexWidthFromSides$1 as vertexWidthFromSides, warmPaintKinds$1 as warmPaintKinds, widestHalfWidth, withAlpha01, withGradientKind$1 as withGradientKind };
12
+ export { BUILTIN_MARKERS, DEFAULT_FILL_COLOR, DEFAULT_PALETTE, DEFAULT_STROKE_COLOR, GHOST_STROKE, INHERIT$1 as INHERIT, STROKE_DASH_RATIOS, TILE_KINDS, alignedStrokeRect$1 as alignedStrokeRect, asPaint, commandFill$1 as commandFill, commandPaint$1 as commandPaint, commandStroke$1 as commandStroke, composePatternTransform, contrastLineColor, contrastRatio, createTilePattern, cycleFill, dashForStrokeStyle$1 as dashForStrokeStyle, decomposePatternTransform, fillInPoseFrame, fillToBoundsFrame, getAlpha01, getMarker, getPaintKind, gradientForBounds$1 as gradientForBounds, gradientGeometry, hexToRgbBytes, hexToRgba, isGradientPaint$1 as isGradientPaint, isPaintKindKnown$1 as isPaintKindKnown, isPatternPaint, isSolidPaint, isTileKind, isTilePaint$1 as isTilePaint, lerpFill$1 as lerpFill, lerpPaint, lerpStroke$1 as lerpStroke, listGradientKinds, listMarkers$1 as listMarkers, listPaintKinds, markerInset, markerKeyOf, markerRegistry, markerSites, mergeAlphaFromPrev, normalizeHex, paintAlpha, paintKindOf, paintKindRegistry, paintWithAlpha, paintWithColor, parseColor, parseColorToRgba255, parseHexBytes, pathPaintOf, patternFamily, patternPlacementOf, registerMarker, registerPaintKind, registerPaintKindLoader, resolveColor, resolveFill$1 as resolveFill, resolveFillPattern, resolveMarkerSize, resolvePatternSpec, resolveScreenLength$1 as resolveScreenLength, resolveStroke$1 as resolveStroke, resolveStrokeWidth$1 as resolveStrokeWidth, rgbaToHex, sampleGradientStops, scaleVertexWidth$1 as scaleVertexWidth, seedTile, solid, strokeDashStyleOf$1 as strokeDashStyleOf, strokeInsets$1 as strokeInsets, strokeOf, strokeWith, switchGradientKind, tileSpecOf, toHex8, trimPolyline, useGradientKinds, usePaintKind, usePaintKinds, vertexHalfWidths$1 as vertexHalfWidths, vertexWidthFromSides$1 as vertexWidthFromSides, warmPaintKinds$1 as warmPaintKinds, wcagLevels, widestHalfWidth, withAlpha01, withGradientKind$1 as withGradientKind };
@@ -1,4 +1,6 @@
1
- import { derivedPartsOf, pathFromParts } from "../core/scene/derivedParts.js";
1
+ import { noteFontRead } from "../core/scene/fontReads.js";
2
+ import { derivedPartsOf, pathFromParts, resolvePartPaint } from "../core/scene/derivedParts.js";
3
+ import { sourcesOf } from "../core/scene/dependents.js";
2
4
  import { pathPoseDescriptor } from "../core/geometry/pathPoseDescriptor.js";
3
5
  import { commitOps } from "../interactions/actions/defaultCommitAdapter.js";
4
6
  import { HANDLE_LOCK_ROLES, locksInForce } from "../interactions/actions/edit-anchors/handleDrag.js";
@@ -7,6 +9,9 @@ import { finishPathEditFrame, pathEditPreview } from "../interactions/actions/ed
7
9
  import { editedPathSymmetries } from "../interactions/actions/edit-anchors/symmetry.js";
8
10
  import { deleteSelectedMark, editTargetOf, markUnder } from "../interactions/actions/defaults/pathEditMarks.js";
9
11
  import { anchorEditWouldChange, commitAnchorEdit, depOf, requiresAnchorSelection } from "../interactions/actions/defaults/anchorEditing.js";
12
+ import { textAlongParts } from "../core/scene/pathEffects/textAlong.js";
13
+ import { PATH_EFFECT, createPathEffectDerivations, pathEffectNode, pathEffectOf, pathEffectParts, registeredPathEffects } from "../core/scene/pathEffects/derive.js";
14
+ import { effectSourceFor, hiddenSourcesTakenWith, sourcesHiddenBy } from "../features/pathEffects/effectSources.js";
10
15
  import { makeHandleCommand } from "../interactions/actions/defaults/anchorHandles.js";
11
16
  import { joinSelectedAnchors } from "../interactions/actions/defaults/anchorJoin.js";
12
17
  import { segmentUnder } from "../interactions/actions/defaults/segmentUnder.js";
@@ -23,12 +28,12 @@ import { PATH_SNAP_LABELS, pathSnapGlyph } from "../features/paths/pathSnap/glyp
23
28
  import { nodeOutline } from "../features/paths/strokeOutline.js";
24
29
  import { DEFAULT_OVERLAY_STYLE } from "../features/paths/anchorMarkers.js";
25
30
  import { createPathEditingOverlayLayer } from "../features/paths/pathEditingOverlayLayer.js";
31
+ import { readEffectSource } from "../features/pathEffects/readSource.js";
32
+ import { useEffectSourcesLayer } from "../features/pathEffects/useEffectSourcesLayer.js";
26
33
  import { createPathLayer } from "../features/paths/pathLayer.js";
27
34
  import { pathOriginProjection } from "../features/paths/originProjection.js";
28
35
  import { CORNER_FIT_TOLERANCE, CORNER_KEYWORDS, DEFAULT_FLATTEN_TOLERANCE, PATH_C as PATH_C$1, PATH_CMD_LENGTHS, PATH_L as PATH_L$1, PATH_M as PATH_M$1, PATH_Q as PATH_Q$1, PATH_SNAP_KINDS as PATH_SNAP_KINDS$1, PATH_Z as PATH_Z$1, PathBuilder, asPolygonPath as asPolygonPath$1, averageAnchorsAt as averageAnchorsAt$1, bendAlongPath as bendAlongPath$1, blendPaths, boundsOfPath as boundsOfPath$1, circlePath as circlePath$1, composePath, cornerAt, cornerFrameAt, cornerFrames, cornerKeywordOf, cornerShapeK, cornerShapePieces, cornerSpecAt, countPathAnchors as countPathAnchors$1, createPathSnapIndex as createPathSnapIndex$1, decomposePath, ellipsePath as ellipsePath$1, extendToMeet, findPathSnap as findPathSnap$1, flattenCubic, flattenCubicWithArcLen, flattenQuadratic, flattenQuadraticWithArcLen, hasCorners, hasOpenSubpath as hasOpenSubpath$1, intersectSegments, isCornerShape, joinAnchorsAt as joinAnchorsAt$1, lengthenOpenEnd, linePath as linePath$1, measurePath as measurePath$1, nextCornerShape, offsetPath, openEndRay, openPathEnds, pathCommandCoordCount, pathContainsPoint as pathContainsPoint$1, pathContainsPolygon, pathContainsRect, pathCrossings, pathDistanceToPoint, pathDivide, pathExclude, pathFromD as pathFromD$1, pathInPoseFrame as pathInPoseFrame$1, pathInWorld as pathInWorld$1, pathIntersect, pathIntersectsPolygon, pathIntersectsRect as pathIntersectsRect$1, pathSegments, pathSignedArea, pathSubtract, pathThroughPoseFrame as pathThroughPoseFrame$1, pathToAnchors as pathToAnchors$1, pathToD, pathUnion, pointAlongPath, pointInPath as pointInPath$1, polygonFromPoints as polygonFromPoints$1, polylineFromPoints as polylineFromPoints$1, poseFrameInverseOf as poseFrameInverseOf$1, poseFrameOf as poseFrameOf$1, poseLinearOf as poseLinearOf$1, poseRotationOf, prepareBlend as prepareBlend$1, rectMarkerPath as rectMarkerPath$1, rectPath as rectPath$1, regularPolygonPath as regularPolygonPath$1, remapPerAnchor, repeatAlongPath as repeatAlongPath$1, resolveCorners as resolveCorners$1, resolveCornersWithSources, reversePath, rotatePathAround as rotatePathAround$1, roundRectPath, scalePathToBounds, simplifyAnchorsAt, simplifyPath as simplifyPath$1, smudgePath, snipPathByPolyline, snipPathsAtCrossings, splitByClosure, splitPathByPolyline, splitPathBySegment, splitSubpaths, squarePath as squarePath$1, starPath as starPath$1, stationsAlongPath, strokeToPath, transformPath as transformPath$1, translatePath as translatePath$1, trianglesToPath, trimPathAt, unionBoundsPath, withCorner, withoutCorners, worldEditToStorage as worldEditToStorage$1 } from "../features/paths/index.js";
29
36
  import { useAnchorFields } from "../features/paths/useAnchorFields.js";
30
- import { PATH_EFFECT, createPathEffectDerivations, pathEffectNode, pathEffectOf, pathEffectParts, registeredPathEffects } from "../core/scene/pathEffects/derive.js";
31
- import { readEffectSource } from "../features/pathEffects/readSource.js";
32
37
  import { PATH_EFFECT_DERIVATIONS, withPathEffectsRegistry } from "../features/pathEffects/index.js";
33
38
  import { useBooleans } from "../interactions/actions/booleans/useBooleans.js";
34
39
  import { useBooleansAdapter } from "../interactions/actions/booleans/useBooleansAdapter.js";
@@ -36,4 +41,4 @@ import { commitBooleanPieces, resolveBooleanOperands } from "../interactions/act
36
41
  import { CONSTRAINT_TOLERANCE, constrainPathEdit, constraintAnchors, pathAnchorPoints, solveConstraints, solvePathConstraints, unsatisfiedConstraints } from "@weasel-js/geom";
37
42
  import { CURVE_REPS, bezierCubic, bezierQuadratic, nurbs, spiro } from "@weasel-js/geom/curves";
38
43
 
39
- export { CONSTRAINT_TOLERANCE, CORNER_FIT_TOLERANCE, CORNER_KEYWORDS, CURVE_REPS, DEFAULT_FLATTEN_TOLERANCE, DEFAULT_OVERLAY_STYLE, DEFAULT_SIMPLIFY_TOLERANCE, GEOMETRY_BOUND_DATA, HANDLE_LOCK_ROLES, PATHFINDER_STROKES, PATH_C$1 as PATH_C, PATH_CMD_LENGTHS, PATH_EFFECT, PATH_EFFECT_DERIVATIONS, PATH_L$1 as PATH_L, PATH_M$1 as PATH_M, PATH_Q$1 as PATH_Q, PATH_SNAP_KINDS$1 as PATH_SNAP_KINDS, PATH_SNAP_LABELS, PATH_Z$1 as PATH_Z, PathBuilder, SHAPE_COUNT_RANGE, STAR_RATIO_RANGE, anchorEditWouldChange, applyBooleanOp, asPolygonPath$1 as asPolygonPath, averageAnchorsAt$1 as averageAnchorsAt, bendAlongPath$1 as bendAlongPath, bezierCubic, bezierQuadratic, blendPaths, boundsOfPath$1 as boundsOfPath, circlePath$1 as circlePath, clampShapeGenerator, classifyPathStorage, commitAnchorEdit, commitBooleanPieces, commitOps, composePath, constrainPathEdit, constraintAnchors, cornerAt, cornerFrameAt, cornerFrames, cornerKeywordOf, cornerShapeK, cornerShapePieces, cornerSpecAt, countPathAnchors$1 as countPathAnchors, createPathEditingOverlayLayer, createPathEffectDerivations, createPathLayer, createPathSnapIndex$1 as createPathSnapIndex, createPenPreviewLayer, decomposePath, deleteNode, deleteSelectedMark, depOf, derivedPartsOf, editTargetOf, editedPathSymmetries, ellipsePath$1 as ellipsePath, extendToMeet, findPathSnap$1 as findPathSnap, finishPathEditFrame, flattenCubic, flattenCubicWithArcLen, flattenQuadratic, flattenQuadraticWithArcLen, hasCorners, hasEditablePath, hasOpenSubpath$1 as hasOpenSubpath, insertAt, intersectSegments, isCornerShape, isShapeGenerator, joinAnchorsAt$1 as joinAnchorsAt, joinPathsCommand, joinSelectedAnchors, lengthenOpenEnd, linePath$1 as linePath, livePathEdit, locksInForce, makeHandleCommand, markUnder, measurePath$1 as measurePath, nextCornerShape, nodeOutline, nurbs, offsetPath, openEndRay, openPathEnds, pathAnchorPoints, pathCommandCoordCount, pathContainsPoint$1 as pathContainsPoint, pathContainsPolygon, pathContainsRect, pathCopy, pathCrossings, pathDistanceToPoint, pathDivide, pathEditPathOf, pathEditPreview, pathEffectNode, pathEffectOf, pathEffectParts, pathExclude, pathFromD$1 as pathFromD, pathFromParts, pathInPoseFrame$1 as pathInPoseFrame, pathInWorld$1 as pathInWorld, pathIntersect, pathIntersectsPolygon, pathIntersectsRect$1 as pathIntersectsRect, pathNodesOf, pathOriginProjection, pathPoseDescriptor, pathSegments, pathSignedArea, pathSnapGlyph, pathSubtract, pathThroughPoseFrame$1 as pathThroughPoseFrame, pathToAnchors$1 as pathToAnchors, pathToD, pathUnion, planJoin, pointAlongPath, pointInPath$1 as pointInPath, polygonFromPoints$1 as polygonFromPoints, polylineFromPoints$1 as polylineFromPoints, poseFrameInverseOf$1 as poseFrameInverseOf, poseFrameOf$1 as poseFrameOf, poseLinearOf$1 as poseLinearOf, poseRotationOf, prepareBlend$1 as prepareBlend, previewBooleanOp, readEffectSource, rectMarkerPath$1 as rectMarkerPath, rectPath$1 as rectPath, regenerateShape, registeredPathEffects, regularPolygonPath$1 as regularPolygonPath, remapPerAnchor, repeatAlongPath$1 as repeatAlongPath, requiresAnchorSelection, reshapeOps, reshapeTo, resolveBooleanOperands, resolveCorners$1 as resolveCorners, resolveCornersWithSources, resolveEditablePathOf, reversePath, rotatePathAround$1 as rotatePathAround, roundRectPath, scalePathToBounds, segmentUnder, selectedPathNodes, settleShapeGenerator, shapeGeneratorOf, shapeGeneratorPath, simplifyAnchorsAt, simplifyPath$1 as simplifyPath, slotOf, smudgePath, snipPathByPolyline, snipPathsAtCrossings, solveConstraints, solvePathConstraints, spiro, splitByClosure, splitPathByPolyline, splitPathBySegment, splitSubpaths, squarePath$1 as squarePath, starPath$1 as starPath, stationsAlongPath, storeEditablePath, strokeToPath, transformPath$1 as transformPath, translatePath$1 as translatePath, trianglesToPath, trimPathAt, unionBoundsPath, unsatisfiedConstraints, useAnchorFields, useBooleans, useBooleansAdapter, withCorner, withPath, withPathEffectsRegistry, withoutCorners, withoutGeometryBoundData, withoutShapeGenerator, worldEditToStorage$1 as worldEditToStorage };
44
+ export { CONSTRAINT_TOLERANCE, CORNER_FIT_TOLERANCE, CORNER_KEYWORDS, CURVE_REPS, DEFAULT_FLATTEN_TOLERANCE, DEFAULT_OVERLAY_STYLE, DEFAULT_SIMPLIFY_TOLERANCE, GEOMETRY_BOUND_DATA, HANDLE_LOCK_ROLES, PATHFINDER_STROKES, PATH_C$1 as PATH_C, PATH_CMD_LENGTHS, PATH_EFFECT, PATH_EFFECT_DERIVATIONS, PATH_L$1 as PATH_L, PATH_M$1 as PATH_M, PATH_Q$1 as PATH_Q, PATH_SNAP_KINDS$1 as PATH_SNAP_KINDS, PATH_SNAP_LABELS, PATH_Z$1 as PATH_Z, PathBuilder, SHAPE_COUNT_RANGE, STAR_RATIO_RANGE, anchorEditWouldChange, applyBooleanOp, asPolygonPath$1 as asPolygonPath, averageAnchorsAt$1 as averageAnchorsAt, bendAlongPath$1 as bendAlongPath, bezierCubic, bezierQuadratic, blendPaths, boundsOfPath$1 as boundsOfPath, circlePath$1 as circlePath, clampShapeGenerator, classifyPathStorage, commitAnchorEdit, commitBooleanPieces, commitOps, composePath, constrainPathEdit, constraintAnchors, cornerAt, cornerFrameAt, cornerFrames, cornerKeywordOf, cornerShapeK, cornerShapePieces, cornerSpecAt, countPathAnchors$1 as countPathAnchors, createPathEditingOverlayLayer, createPathEffectDerivations, createPathLayer, createPathSnapIndex$1 as createPathSnapIndex, createPenPreviewLayer, decomposePath, deleteNode, deleteSelectedMark, depOf, derivedPartsOf, editTargetOf, editedPathSymmetries, effectSourceFor, ellipsePath$1 as ellipsePath, extendToMeet, findPathSnap$1 as findPathSnap, finishPathEditFrame, flattenCubic, flattenCubicWithArcLen, flattenQuadratic, flattenQuadraticWithArcLen, hasCorners, hasEditablePath, hasOpenSubpath$1 as hasOpenSubpath, hiddenSourcesTakenWith, insertAt, intersectSegments, isCornerShape, isShapeGenerator, joinAnchorsAt$1 as joinAnchorsAt, joinPathsCommand, joinSelectedAnchors, lengthenOpenEnd, linePath$1 as linePath, livePathEdit, locksInForce, makeHandleCommand, markUnder, measurePath$1 as measurePath, nextCornerShape, nodeOutline, noteFontRead, nurbs, offsetPath, openEndRay, openPathEnds, pathAnchorPoints, pathCommandCoordCount, pathContainsPoint$1 as pathContainsPoint, pathContainsPolygon, pathContainsRect, pathCopy, pathCrossings, pathDistanceToPoint, pathDivide, pathEditPathOf, pathEditPreview, pathEffectNode, pathEffectOf, pathEffectParts, pathExclude, pathFromD$1 as pathFromD, pathFromParts, pathInPoseFrame$1 as pathInPoseFrame, pathInWorld$1 as pathInWorld, pathIntersect, pathIntersectsPolygon, pathIntersectsRect$1 as pathIntersectsRect, pathNodesOf, pathOriginProjection, pathPoseDescriptor, pathSegments, pathSignedArea, pathSnapGlyph, pathSubtract, pathThroughPoseFrame$1 as pathThroughPoseFrame, pathToAnchors$1 as pathToAnchors, pathToD, pathUnion, planJoin, pointAlongPath, pointInPath$1 as pointInPath, polygonFromPoints$1 as polygonFromPoints, polylineFromPoints$1 as polylineFromPoints, poseFrameInverseOf$1 as poseFrameInverseOf, poseFrameOf$1 as poseFrameOf, poseLinearOf$1 as poseLinearOf, poseRotationOf, prepareBlend$1 as prepareBlend, previewBooleanOp, readEffectSource, rectMarkerPath$1 as rectMarkerPath, rectPath$1 as rectPath, regenerateShape, registeredPathEffects, regularPolygonPath$1 as regularPolygonPath, remapPerAnchor, repeatAlongPath$1 as repeatAlongPath, requiresAnchorSelection, reshapeOps, reshapeTo, resolveBooleanOperands, resolveCorners$1 as resolveCorners, resolveCornersWithSources, resolveEditablePathOf, resolvePartPaint, reversePath, rotatePathAround$1 as rotatePathAround, roundRectPath, scalePathToBounds, segmentUnder, selectedPathNodes, settleShapeGenerator, shapeGeneratorOf, shapeGeneratorPath, simplifyAnchorsAt, simplifyPath$1 as simplifyPath, slotOf, smudgePath, snipPathByPolyline, snipPathsAtCrossings, solveConstraints, solvePathConstraints, sourcesHiddenBy, sourcesOf, spiro, splitByClosure, splitPathByPolyline, splitPathBySegment, splitSubpaths, squarePath$1 as squarePath, starPath$1 as starPath, stationsAlongPath, storeEditablePath, strokeToPath, textAlongParts, transformPath$1 as transformPath, translatePath$1 as translatePath, trianglesToPath, trimPathAt, unionBoundsPath, unsatisfiedConstraints, useAnchorFields, useBooleans, useBooleansAdapter, useEffectSourcesLayer, withCorner, withPath, withPathEffectsRegistry, withoutCorners, withoutGeometryBoundData, withoutShapeGenerator, worldEditToStorage$1 as worldEditToStorage };
@@ -18,8 +18,9 @@ import { BUILTIN_TOOLS, BUILTIN_TOOL_IDS, DRAW_TOOLS, PAGE_TOOLS, SELECT_TOOLS,
18
18
  import { mergeContributions as mergeContributions$1 } from "../canvas/surfaceContribution.js";
19
19
  import { SPRITE_STRIDE, blur, cullDrawCommands as cullDrawCommands$1, frameRect, mat3 as mat3$1, registerEffect, viewToMat3 as viewToMat3$1, vignette } from "@weasel-js/renderer";
20
20
  import { createReflectable as createReflectable$1 } from "@weasel-js/registry";
21
- import { assembleEntries, liveScope, modeShortcutSpec, modeShortcuts, scopeBindings } from "@weasel-js/routing";
21
+ import { KEYMAP_HOLD, assembleEntries, captureGesture, captureKey, createKeymapStack, describeKeymap, keymapContribution, keymapLeaderBindingId, keymapLeaderId, keymapShortcuts, liveScope, modeShortcutSpec, modeShortcuts, scopeBindings } from "@weasel-js/routing";
22
22
  import { canQueryLocalFonts, cssFamilyName, cssFontFamily, cssFontFamilyLoading, enableLocalFontOutlines, fontOutlineRegistry, fontRegistry, hasFontOutlines, isCanvasFont, listFontOutlines, loadFontOutlines, outlineStatus, refreshCanvasFont, registerCanvasFont, registerFont, registerFontOutlines, subscribeGlyphReady as subscribeGlyphReady$1, unregisterCanvasFont, unregisterFontOutlines, warmFonts as warmFonts$1 } from "@weasel-js/font";
23
+ import { bindingSpec, held, key, keySpecRoute, unbound } from "@weasel-js/gestures";
23
24
  import { CURSOR_ANGLE_STEPS, CURSOR_MAX_CSS_PX, bakeCursor, createCursorSink as createCursorSink$1, createPaintedCursorState as createPaintedCursorState$1, cursorFor as cursorFor$1, resolveCursor, resolveCursorTier as resolveCursorTier$1 } from "@weasel-js/cursor";
24
25
 
25
- export { BUILTIN_TOOLS, BUILTIN_TOOL_IDS, COMPOSITE_FEATURES, CURSOR_ANGLE_STEPS, CURSOR_MAX_CSS_PX, DRAW_TOOLS, FEATURE_ACTION_IDS, KIT_SHAPE_KINDS, KIT_VERSIONS, PAGE_TOOLS, PAINTED_CURSOR_LAYER_ID, SCENE_CANVAS_FEATURES, SELECT_TOOLS, SHAPE_KINDS, SHAPE_TOOLS, SPRITE_STRIDE, TOOL_DRIVEN_ACTION_IDS, TYPE_TOOLS, VIEW_TOOLS, arrangePreset, assembleEntries, bakeCursor, blur, canQueryLocalFonts, checkRequirements, createCursorSink$1 as createCursorSink, createPaintedCursorLayer, createPaintedCursorState$1 as createPaintedCursorState, createReflectable$1 as createReflectable, cssFamilyName, cssFontFamily, cssFontFamilyLoading, cullDrawCommands$1 as cullDrawCommands, cursorFor$1 as cursorFor, editPreset, enableLocalFontOutlines, fontOutlineRegistry, fontRegistry, frameRect, hasFontOutlines, ingestPreset, isCanvasFont, listFontOutlines, liveScope, loadFontOutlines, mat3$1 as mat3, mergeContributions$1 as mergeContributions, modeShortcutSpec, modeShortcuts, movePreset, outlinePreset, outlineStatus, paletteInsertPaint, pathsPreset, refreshCanvasFont, registerCanvasFont, registerEffect, registerFont, registerFontOutlines, resizePreset, resolveCursor, resolveCursorTier$1 as resolveCursorTier, rotateAroundAABBCenter, rotatePreset, satisfiesRange, scopeBindings, selectPreset, subscribeGlyphReady$1 as subscribeGlyphReady, textBoxOf, unregisterCanvasFont, unregisterFontOutlines, useTransformFollower, viewPreset, viewToMat3$1 as viewToMat3, vignette, warmFonts$1 as warmFonts };
26
+ export { BUILTIN_TOOLS, BUILTIN_TOOL_IDS, COMPOSITE_FEATURES, CURSOR_ANGLE_STEPS, CURSOR_MAX_CSS_PX, DRAW_TOOLS, FEATURE_ACTION_IDS, KEYMAP_HOLD, KIT_SHAPE_KINDS, KIT_VERSIONS, PAGE_TOOLS, PAINTED_CURSOR_LAYER_ID, SCENE_CANVAS_FEATURES, SELECT_TOOLS, SHAPE_KINDS, SHAPE_TOOLS, SPRITE_STRIDE, TOOL_DRIVEN_ACTION_IDS, TYPE_TOOLS, VIEW_TOOLS, arrangePreset, assembleEntries, bakeCursor, bindingSpec, blur, canQueryLocalFonts, captureGesture, captureKey, checkRequirements, createCursorSink$1 as createCursorSink, createKeymapStack, createPaintedCursorLayer, createPaintedCursorState$1 as createPaintedCursorState, createReflectable$1 as createReflectable, cssFamilyName, cssFontFamily, cssFontFamilyLoading, cullDrawCommands$1 as cullDrawCommands, cursorFor$1 as cursorFor, describeKeymap, editPreset, enableLocalFontOutlines, fontOutlineRegistry, fontRegistry, frameRect, hasFontOutlines, held, ingestPreset, isCanvasFont, key, keySpecRoute, keymapContribution, keymapLeaderBindingId, keymapLeaderId, keymapShortcuts, listFontOutlines, liveScope, loadFontOutlines, mat3$1 as mat3, mergeContributions$1 as mergeContributions, modeShortcutSpec, modeShortcuts, movePreset, outlinePreset, outlineStatus, paletteInsertPaint, pathsPreset, refreshCanvasFont, registerCanvasFont, registerEffect, registerFont, registerFontOutlines, resizePreset, resolveCursor, resolveCursorTier$1 as resolveCursorTier, rotateAroundAABBCenter, rotatePreset, satisfiesRange, scopeBindings, selectPreset, subscribeGlyphReady$1 as subscribeGlyphReady, textBoxOf, unbound, unregisterCanvasFont, unregisterFontOutlines, useTransformFollower, viewPreset, viewToMat3$1 as viewToMat3, vignette, warmFonts$1 as warmFonts };
@@ -22,7 +22,7 @@ import { deleteAnchorsAction, nudgeAnchorsDownAction, nudgeAnchorsLeftAction, nu
22
22
  import { selectFromLasso } from "../interactions/actions/lasso-select/behaviors/selectFromLasso.js";
23
23
  import { lassoSelectAction } from "../interactions/actions/lasso-select/action.js";
24
24
  import { sliceAction } from "../interactions/actions/defaults/slice.js";
25
- import { commitDeleteToScene, createDeleteAction, deleteAction } from "../interactions/actions/defaults/delete.js";
25
+ import { commitDeleteToScene, createDeleteAction, deleteAction, hiddenSourceDeleteOps } from "../interactions/actions/defaults/delete.js";
26
26
  import { makePinchZoomAction, pinchZoomAction } from "../interactions/actions/defaults/pinchZoom.js";
27
27
  import { clipboardCopyAction, clipboardCutAction, clipboardPasteAction, clipboardPasteEventAction } from "../interactions/actions/clipboard/action.js";
28
28
  import { enterTextEditAction } from "../interactions/actions/defaults/enterTextEdit.js";
@@ -57,8 +57,8 @@ import { useSliceTool } from "../tools/builtin/slice/useSliceTool.js";
57
57
  import { useMeasureTool } from "../tools/builtin/measure/useMeasureTool.js";
58
58
  import { isToolSet, toolIdsOf as toolIdsOf$1, toolSet as toolSet$1, toolSetHas, withoutTools } from "../tools/index.js";
59
59
  import { useLatest as useLatest$1 } from "@weasel-js/react";
60
- import { ActionDisabledReason as ActionDisabledReason$1, actionBindings as actionBindings$1, actionCursor, actionItemTitle, actionItems, actionSettingsParams, actionShortcuts, actionsTagged, buildDepsFromRequires as buildDepsFromRequires$1, createDepRegistry, createDispatcher as createDispatcher$1, deleteScratch, evaluateActive as evaluateActive$1, evaluateEnabled as evaluateEnabled$1, getScratch as getScratch$1, heldKeySpec as heldKeySpec$1, keySpecShortcut, keysHeld, matchActionItem, overlaysOf as overlaysOf$1, readActionSettings, resolveParams as resolveParams$1, resolveSchemaMenu, roleReader as roleReader$1, scratchKey as scratchKey$1, setScratch as setScratch$1, specificity, taggedActionItems, tuneAction } from "@weasel-js/routing";
60
+ import { ActionDisabledReason as ActionDisabledReason$1, actionBindings as actionBindings$1, actionCursor, actionItemTitle, actionItems, actionSettingsParams, actionShortcuts, actionsTagged, bindingId, buildDepsFromRequires as buildDepsFromRequires$1, createDepRegistry, createDispatcher as createDispatcher$1, deleteScratch, evaluateActive as evaluateActive$1, evaluateEnabled as evaluateEnabled$1, getScratch as getScratch$1, heldKeySpec as heldKeySpec$1, keySpecShortcut, keysHeld, matchActionItem, modifierStateOf, overlaysOf as overlaysOf$1, readActionSettings, resolveBindingOverrides, resolveParams as resolveParams$1, resolveSchemaMenu, roleReader as roleReader$1, scratchKey as scratchKey$1, setScratch as setScratch$1, specificity, taggedActionItems, tuneAction } from "@weasel-js/routing";
61
61
  import { bodyPredicate, hitPredicate as hitPredicate$1 } from "@weasel-js/gestures";
62
- import { ActionsProvider as ActionsProvider$1, ActiveToolContextProvider as ActiveToolContextProvider$1, ActiveToolContextProviderIfRoot as ActiveToolContextProviderIfRoot$1, DepRegistryProvider as DepRegistryProvider$1, InputScope as InputScope$1, Yoke, useAction, useActionsRegistry as useActionsRegistry$1, useActiveToolContext, useCommand, useDepRegistry as useDepRegistry$1, useDepSource as useDepSource$1, useGestureDispatcher as useGestureDispatcher$1, useMenuHost as useMenuHost$1, useMenus, useOngoingAction, useOptionalActiveToolContext as useOptionalActiveToolContext$1, useOptionalDepRegistry as useOptionalDepRegistry$1, useYoke } from "@weasel-js/routing/react";
62
+ import { ActionsProvider as ActionsProvider$1, ActiveToolContextProvider as ActiveToolContextProvider$1, ActiveToolContextProviderIfRoot as ActiveToolContextProviderIfRoot$1, DepRegistryProvider as DepRegistryProvider$1, InputScope as InputScope$1, Yoke, useAction, useActionsRegistry as useActionsRegistry$1, useActiveToolContext, useCommand, useDepRegistry as useDepRegistry$1, useDepSource as useDepSource$1, useGestureDispatcher as useGestureDispatcher$1, useMenuHost as useMenuHost$1, useMenus, useOngoingAction, useOpenKeymap, useOptionalActiveToolContext as useOptionalActiveToolContext$1, useOptionalDepRegistry as useOptionalDepRegistry$1, useYoke } from "@weasel-js/routing/react";
63
63
 
64
- export { AREA_SELECT_ID, ActionDisabledReason$1 as ActionDisabledReason, ActionsProvider$1 as ActionsProvider, ActiveToolContextProvider$1 as ActiveToolContextProvider, ActiveToolContextProviderIfRoot$1 as ActiveToolContextProviderIfRoot, CORNER_ANCHORS, DRAG_PAN_ID, DepRegistryProvider$1 as DepRegistryProvider, EDGE_HANDLE_MIN_RADII, INSERT_REPOSITION_BINDING, InputScope$1 as InputScope, KIT_STANDARD_ACTION_IDS, PATH_GESTURE_TAGS, RESIZE_HANDLE_ANCHORS, SELECTION_MOVE_ID, SELECTION_RESIZE_ID, SELECTION_ROTATE_ID, SELECTION_TRANSFORM_ID, STICKY_DEFAULTS, Yoke, actionBindings$1 as actionBindings, actionCursor, actionItemTitle, actionItems, actionSettingsParams, actionShortcuts, actionsTagged, areaSelectAction, areaSelectContribution, bodyPredicate, buildDepsFromRequires$1 as buildDepsFromRequires, clearSelectionAction, clipboardCopyAction, clipboardCutAction, clipboardPasteAction, clipboardPasteEventAction, cloneAction, commitDeleteToScene, computeSliceOps, contextMenuAction, cornerPoint, createDeleteAction, createDepRegistry, createDispatcher$1 as createDispatcher, createPointerFollower, createResizeAction, defaultCommitAdapter, defineTool, deleteAction, deleteAnchorsAction, deleteScratch, dragPanContribution, editAnchorsAction, editingLayer, enterTextEditAction, evaluateActive$1 as evaluateActive, evaluateEnabled$1 as evaluateEnabled, exitPathEditToolAction, flipAction, getScratch$1 as getScratch, handlePoint, heldKeySpec$1 as heldKeySpec, hitPredicate$1 as hitPredicate, inPlane, insertAction, insertLayer, insertRepositionAction, isCornerHandle, isToolSet, keySpecShortcut, keysHeld, lassoSelectAction, makePinchZoomAction, makeViewportWheelPanAction, makeViewportZoomAction, matchActionItem, moveAction, nudgeAnchorsDownAction, nudgeAnchorsLeftAction, nudgeAnchorsRightAction, nudgeAnchorsUpAction, onEmptyCanvas, openContextMenu, overlaysOf$1 as overlaysOf, pathEditToolAction, pathEditToolActive, pathOperationTags, pickTopMostHit, pinchZoomAction, placeAction, readActionSettings, resizeAction, resizeHandlesFor, resolveParams$1 as resolveParams, resolveSchemaMenu, roleReader$1 as roleReader, rotateAction, scratchKey$1 as scratchKey, selectAnchorAction, selectFromLasso, selectionLayer, selectionMoveBindings, selectionMoveContribution, selectionResizeBindings, selectionResizeContribution, selectionRotateBindings, selectionRotateContribution, selectionTransformBindings, selectionTransformContribution, setScratch$1 as setScratch, sliceAction, specificity, stickyData, stickyNodeFactory, taggedActionItems, toolIdsOf$1 as toolIdsOf, toolSet$1 as toolSet, toolSetHas, tuneAction, useAction, useActionsRegistry$1 as useActionsRegistry, useActiveToolContext, useBooleansAdapterSource, useCommand, useDepRegistry$1 as useDepRegistry, useDepSource$1 as useDepSource, useEllipseTool, useEyedropperTool, useGestureDispatcher$1 as useGestureDispatcher, useHandTool, useImageTool, useKeybindings, useLassoTool, useLatest$1 as useLatest, useLineTool, useMeasureTool, useMenuHost$1 as useMenuHost, useMenus, useOngoingAction, useOptionalActiveToolContext$1 as useOptionalActiveToolContext, useOptionalDepRegistry$1 as useOptionalDepRegistry, usePenTool, usePencilTool, usePolygonTool, usePoseDescriptorDepSource, useRectTool, useResizePolicy, useSelectTool, useSliceDep, useSliceDepSource, useSliceTool, useStandardActions, useStarTool, useStickyTool, useTextTool, useTools$1 as useTools, useYoke, viewportDragPanAction, viewportWheelPanAction, viewportZoomAction, withoutTools };
64
+ export { AREA_SELECT_ID, ActionDisabledReason$1 as ActionDisabledReason, ActionsProvider$1 as ActionsProvider, ActiveToolContextProvider$1 as ActiveToolContextProvider, ActiveToolContextProviderIfRoot$1 as ActiveToolContextProviderIfRoot, CORNER_ANCHORS, DRAG_PAN_ID, DepRegistryProvider$1 as DepRegistryProvider, EDGE_HANDLE_MIN_RADII, INSERT_REPOSITION_BINDING, InputScope$1 as InputScope, KIT_STANDARD_ACTION_IDS, PATH_GESTURE_TAGS, RESIZE_HANDLE_ANCHORS, SELECTION_MOVE_ID, SELECTION_RESIZE_ID, SELECTION_ROTATE_ID, SELECTION_TRANSFORM_ID, STICKY_DEFAULTS, Yoke, actionBindings$1 as actionBindings, actionCursor, actionItemTitle, actionItems, actionSettingsParams, actionShortcuts, actionsTagged, areaSelectAction, areaSelectContribution, bindingId, bodyPredicate, buildDepsFromRequires$1 as buildDepsFromRequires, clearSelectionAction, clipboardCopyAction, clipboardCutAction, clipboardPasteAction, clipboardPasteEventAction, cloneAction, commitDeleteToScene, computeSliceOps, contextMenuAction, cornerPoint, createDeleteAction, createDepRegistry, createDispatcher$1 as createDispatcher, createPointerFollower, createResizeAction, defaultCommitAdapter, defineTool, deleteAction, deleteAnchorsAction, deleteScratch, dragPanContribution, editAnchorsAction, editingLayer, enterTextEditAction, evaluateActive$1 as evaluateActive, evaluateEnabled$1 as evaluateEnabled, exitPathEditToolAction, flipAction, getScratch$1 as getScratch, handlePoint, heldKeySpec$1 as heldKeySpec, hiddenSourceDeleteOps, hitPredicate$1 as hitPredicate, inPlane, insertAction, insertLayer, insertRepositionAction, isCornerHandle, isToolSet, keySpecShortcut, keysHeld, lassoSelectAction, makePinchZoomAction, makeViewportWheelPanAction, makeViewportZoomAction, matchActionItem, modifierStateOf, moveAction, nudgeAnchorsDownAction, nudgeAnchorsLeftAction, nudgeAnchorsRightAction, nudgeAnchorsUpAction, onEmptyCanvas, openContextMenu, overlaysOf$1 as overlaysOf, pathEditToolAction, pathEditToolActive, pathOperationTags, pickTopMostHit, pinchZoomAction, placeAction, readActionSettings, resizeAction, resizeHandlesFor, resolveBindingOverrides, resolveParams$1 as resolveParams, resolveSchemaMenu, roleReader$1 as roleReader, rotateAction, scratchKey$1 as scratchKey, selectAnchorAction, selectFromLasso, selectionLayer, selectionMoveBindings, selectionMoveContribution, selectionResizeBindings, selectionResizeContribution, selectionRotateBindings, selectionRotateContribution, selectionTransformBindings, selectionTransformContribution, setScratch$1 as setScratch, sliceAction, specificity, stickyData, stickyNodeFactory, taggedActionItems, toolIdsOf$1 as toolIdsOf, toolSet$1 as toolSet, toolSetHas, tuneAction, useAction, useActionsRegistry$1 as useActionsRegistry, useActiveToolContext, useBooleansAdapterSource, useCommand, useDepRegistry$1 as useDepRegistry, useDepSource$1 as useDepSource, useEllipseTool, useEyedropperTool, useGestureDispatcher$1 as useGestureDispatcher, useHandTool, useImageTool, useKeybindings, useLassoTool, useLatest$1 as useLatest, useLineTool, useMeasureTool, useMenuHost$1 as useMenuHost, useMenus, useOngoingAction, useOpenKeymap, useOptionalActiveToolContext$1 as useOptionalActiveToolContext, useOptionalDepRegistry$1 as useOptionalDepRegistry, usePenTool, usePencilTool, usePolygonTool, usePoseDescriptorDepSource, useRectTool, useResizePolicy, useSelectTool, useSliceDep, useSliceDepSource, useSliceTool, useStandardActions, useStarTool, useStickyTool, useTextTool, useTools$1 as useTools, useYoke, viewportDragPanAction, viewportWheelPanAction, viewportZoomAction, withoutTools };
@@ -1,5 +1,7 @@
1
1
  import { IDENTITY_POSE_COMPOSITION, composeWorldPose, composesFrames, rebaseLocalPose } from "../core/scene/composeFrame.js";
2
2
  import { RECT_POSE_COMPOSITION, RIGID_POSE_COMPOSITION, composeRectPose, composeRigidPose, decomposeRectPose, decomposeRigidPose, translateRectPose, worldPoseLookup } from "../core/scene/composePose.js";
3
+ import { documentOf } from "../core/scene/documentOf.js";
4
+ import { nodeAsShown } from "../core/scene/nodeAsShown.js";
3
5
  import { definesFrame, derivedDepOf, derivedPose, documentDepOf, documentPose, effectivePose } from "../core/scene/effectivePose.js";
4
6
  import { axisAlignedBounds, unionAABB, unionBounds } from "../core/geometry/unionBounds.js";
5
7
  import { scenePoseAdapter } from "../core/scene/scenePoseAdapter.js";
@@ -8,7 +10,9 @@ import { measureBetween, measureEndsOf, measureNode, measurePose, measurementOf
8
10
  import { asNodeId } from "../core/scene/types.js";
9
11
  import { annotationLayerIds, isAnnotationLayer, isAnnotationNode } from "../core/scene/annotation.js";
10
12
  import { hidesSubtree, isNodeHidden, isNodeLocked, nodeGates } from "../core/scene/nodeGates.js";
13
+ import { statedFields } from "../core/scene/statedFields.js";
11
14
  import { applyOpsTo, dispatchApplyBatch } from "../core/applyOps.js";
15
+ import { hasChildren, isLeaf } from "../core/scene/treeShape.js";
12
16
  import { SceneArrivalRefused } from "../core/scene/arrivals.js";
13
17
  import { opFactoryRegistry, rebuildOp, registerOpFactory, registeredOpNames } from "../core/ops/registry.js";
14
18
  import { createTransformOp } from "../core/ops/transform.js";
@@ -21,6 +25,7 @@ import { createSetSelectionOp } from "../core/ops/select.js";
21
25
  import { canBringForward, canSendBackward } from "../core/ops/reorder/algorithms.js";
22
26
  import { createSetChildOrderOp } from "../core/ops/reorder/setChildOrder.js";
23
27
  import { createMoveToIndexOp, createReorderOp } from "../core/ops/reorder/index.js";
28
+ import { CLIP_NOTHING, clipNothing } from "../core/scene/clipNothing.js";
24
29
  import { UNION_OF_CHILDREN, unionOfChildren } from "../core/scene/kitRegistry.js";
25
30
  import { createMeasurements, currentMeasureId, measureIds } from "../features/measure/measurements.js";
26
31
  import { measureAt, measureEndSource } from "../features/measure/measureHit.js";
@@ -31,6 +36,7 @@ import { createArrangeOp } from "../core/ops/arrange.js";
31
36
  import { createHistory as createHistory$1 } from "../core/ops/createHistory.js";
32
37
  import { SCENE_HISTORY_FORM } from "../core/scene/historyForm.js";
33
38
  import { sceneSelectionStore } from "../core/scene/sceneSelection.js";
39
+ import { nodeKindOf, specsFromSerialized } from "../core/scene/serialization.js";
34
40
  import { createScene, sceneFromJSON } from "../core/scene/scene.js";
35
41
  import { createSetTextOp } from "../core/ops/setText.js";
36
42
  import { createSetDependsOnOp } from "../core/ops/setDependsOn.js";
@@ -48,4 +54,4 @@ import { measurementsContribution } from "../features/measure/measureContributio
48
54
  import { MIXED } from "@weasel-js/registry";
49
55
  import { swapOp } from "@weasel-js/history";
50
56
 
51
- export { IDENTITY_POSE_COMPOSITION, MEASURE_ACTION_IDS, MEASURE_AFFORDANCE_KIND, MEASURE_LAYER_ID, MIXED, RECT_POSE_COMPOSITION, RIGID_POSE_COMPOSITION, SCENE_HISTORY_FORM, SceneArrivalRefused, UNION_OF_CHILDREN, annotationLayerIds, applyOpsTo, asNodeId, axisAlignedBounds, canBringForward, canSendBackward, carriedDescendants, composeRectPose, composeRigidPose, composeWorldPose, composesFrames, createArrangeOp, createDeleteOp, createHistory$1 as createHistory, createInsertOp, createMeasurements, createMoveToIndexOp, createPoseFeed, createPoseOverrides, createReorderOp, createReparentOp, createScene, createSetChildOrderOp, createSetDataOp, createSetDependsOnOp, createSetHiddenOp, createSetLayerOp, createSetLayoutOp, createSetLockedOp, createSetPathOp, createSetSelectionOp, createSetTextOp, createTransformOp, currentMeasureId, decomposeRectPose, decomposeRigidPose, definesFrame, derivedDepOf, derivedPose, dispatchApplyBatch, documentDepOf, documentPose, effectivePose, hidesSubtree, isAnnotationLayer, isAnnotationNode, isNodeHidden, isNodeLocked, measureAt, measureBetween, measureEndSource, measureEndsOf, measureIds, measureNode, measurePose, measurementOf, measurementsContribution, nestedHitTester, nodeGates, opFactoryRegistry, rebaseLocalPose, rebuildOp, reconcileSpecs, registerOpFactory, registeredOpNames, sceneCarrySource, sceneFromJSON, scenePoseAdapter, sceneSelectionStore, sceneSharedUnitScopes, sceneUnitScopes, swapOp, translateRectPose, unionAABB, unionBounds, unionOfChildren, unionOfChildrenVia, useScene, worldPoseLookup, writtenBy };
57
+ export { CLIP_NOTHING, IDENTITY_POSE_COMPOSITION, MEASURE_ACTION_IDS, MEASURE_AFFORDANCE_KIND, MEASURE_LAYER_ID, MIXED, RECT_POSE_COMPOSITION, RIGID_POSE_COMPOSITION, SCENE_HISTORY_FORM, SceneArrivalRefused, UNION_OF_CHILDREN, annotationLayerIds, applyOpsTo, asNodeId, axisAlignedBounds, canBringForward, canSendBackward, carriedDescendants, clipNothing, composeRectPose, composeRigidPose, composeWorldPose, composesFrames, createArrangeOp, createDeleteOp, createHistory$1 as createHistory, createInsertOp, createMeasurements, createMoveToIndexOp, createPoseFeed, createPoseOverrides, createReorderOp, createReparentOp, createScene, createSetChildOrderOp, createSetDataOp, createSetDependsOnOp, createSetHiddenOp, createSetLayerOp, createSetLayoutOp, createSetLockedOp, createSetPathOp, createSetSelectionOp, createSetTextOp, createTransformOp, currentMeasureId, decomposeRectPose, decomposeRigidPose, definesFrame, derivedDepOf, derivedPose, dispatchApplyBatch, documentDepOf, documentOf, documentPose, effectivePose, hasChildren, hidesSubtree, isAnnotationLayer, isAnnotationNode, isLeaf, isNodeHidden, isNodeLocked, measureAt, measureBetween, measureEndSource, measureEndsOf, measureIds, measureNode, measurePose, measurementOf, measurementsContribution, nestedHitTester, nodeAsShown, nodeGates, nodeKindOf, opFactoryRegistry, rebaseLocalPose, rebuildOp, reconcileSpecs, registerOpFactory, registeredOpNames, sceneCarrySource, sceneFromJSON, scenePoseAdapter, sceneSelectionStore, sceneSharedUnitScopes, sceneUnitScopes, specsFromSerialized, statedFields, swapOp, translateRectPose, unionAABB, unionBounds, unionOfChildren, unionOfChildrenVia, useScene, worldPoseLookup, writtenBy };
@@ -5,6 +5,6 @@ import { createTextLayer } from "../features/text/textLayer.js";
5
5
  import { useSceneTextEdit } from "../features/text/useSceneTextEdit.js";
6
6
  import { TEXT_EDIT_FONT_HOLD, TextOutlinesError as TextOutlinesError$1, charOffsetToDomPosition, domPositionToCharOffset, domToRuns, loadTextOutlines as loadTextOutlines$1, runsToDom, textCommand, textCommandFromPose, textCommandFromRuns, textToPath as textToPath$1, textToPathsByPaint as textToPathsByPaint$1, useTextEdit } from "../features/text/index.js";
7
7
  import { useCreateOutlinesAdapter } from "../interactions/actions/outlines/useCreateOutlinesAdapter.js";
8
- import { DEFAULT_DECORATION_METRICS, DEFAULT_TEXT_STYLE, MARKDOWN_RUN_GRAMMAR, SCRIPT_METRICS, SMALL_CAPS_SCALE, applyStyleToRange, cachedLayoutRuns, cachedPaintRuns, caretIndexAt as caretIndexAt$1, createMarkdownRenderer, decorationMetrics, defaultLabelTextRenderer, effectiveRangeStyle, fitTextPose, fontString, isBoldWeight, isSmallCapsLetter, isTextData as isTextData$1, layoutMarkdown, layoutRuns, layoutTextPose, markdownToRuns, measureText, measureTextBounds as measureTextBounds$1, measuredWidth, nodeHasFlag, numericWeight, paintRuns, paragraphDirection, patchRangeStyle, pointInTextPose as pointInTextPose$1, rangeWeight, registerBidi, renderLabel, resolveAlign as resolveAlign$1, resolveRunFace, resolveRuns, resolveTextStyle, runsToMarkdown, runsToPlainText as runsToPlainText$1, scriptMetrics, scriptMetricsFor, setFlagOverRange, smallCapsScale, smallCapsScaleFor, smallCapsText, styleAtRange, textLineBoxes as textLineBoxes$1, textPoseLayoutInput, toRuns, transformRunTexts, unboldPatch, verticalAlignOffset } from "@weasel-js/text";
8
+ import { DEFAULT_DECORATION_METRICS, DEFAULT_TEXT_FILL as DEFAULT_TEXT_FILL$1, DEFAULT_TEXT_STYLE, MARKDOWN_RUN_GRAMMAR, SCRIPT_METRICS, SMALL_CAPS_SCALE, applyStyleToRange, cachedLayoutRuns, cachedPaintRuns, caretIndexAt as caretIndexAt$1, createMarkdownRenderer, decorationMetrics, defaultLabelTextRenderer, effectiveRangeStyle, fitTextPose, fontString, isBoldWeight, isSmallCapsLetter, isTextData as isTextData$1, layoutMarkdown, layoutRuns, layoutTextPose, markdownToRuns, measureText, measureTextBounds as measureTextBounds$1, measuredWidth, nodeHasFlag, numericWeight, paintRuns, paragraphDirection, patchRangeStyle, pointInTextPose as pointInTextPose$1, rangeWeight, registerBidi, renderLabel, resolveAlign as resolveAlign$1, resolveRunFace, resolveRuns, resolveTextStyle, runsToMarkdown, runsToPlainText as runsToPlainText$1, scriptMetrics, scriptMetricsFor, setFlagOverRange, smallCapsScale, smallCapsScaleFor, smallCapsText, styleAtRange, textLineBoxes as textLineBoxes$1, textPoseLayoutInput, toRuns, transformRunTexts, unboldPatch, verticalAlignOffset } from "@weasel-js/text";
9
9
 
10
- export { DEFAULT_DECORATION_METRICS, DEFAULT_TEXT_STYLE, MARKDOWN_RUN_GRAMMAR, SCRIPT_METRICS, SMALL_CAPS_SCALE, TEXT_EDIT_FONT_HOLD, TextOutlinesError$1 as TextOutlinesError, applyCreateOutlines, applyOutlineStroke, applyStyleToRange, cachedLayoutRuns, cachedPaintRuns, caretIndexAt$1 as caretIndexAt, charOffsetToDomPosition, createMarkdownRenderer, createTextLayer, decorationMetrics, defaultLabelTextRenderer, domPositionToCharOffset, domToRuns, effectiveRangeStyle, fitTextPose, fontString, isBoldWeight, isSmallCapsLetter, isTextData$1 as isTextData, layoutMarkdown, layoutRuns, layoutTextPose, loadTextOutlines$1 as loadTextOutlines, markdownToRuns, measureText, measureTextBounds$1 as measureTextBounds, measuredWidth, nodeHasFlag, numericWeight, paintRuns, paragraphDirection, patchRangeStyle, pointInTextPose$1 as pointInTextPose, rangeWeight, registerBidi, renderLabel, resolveAlign$1 as resolveAlign, resolveRunFace, resolveRuns, resolveTextStyle, runsToDom, runsToMarkdown, runsToPlainText$1 as runsToPlainText, scriptMetrics, scriptMetricsFor, setFlagOverRange, smallCapsScale, smallCapsScaleFor, smallCapsText, strokeRegion, styleAtRange, textCommand, textCommandFromPose, textCommandFromRuns, textLineBoxes$1 as textLineBoxes, textPoseLayoutInput, textToPath$1 as textToPath, textToPathsByPaint$1 as textToPathsByPaint, toRuns, transformRunTexts, unboldPatch, useCreateOutlinesAdapter, useSceneTextEdit, useTextEdit, verticalAlignOffset };
10
+ export { DEFAULT_DECORATION_METRICS, DEFAULT_TEXT_FILL$1 as DEFAULT_TEXT_FILL, DEFAULT_TEXT_STYLE, MARKDOWN_RUN_GRAMMAR, SCRIPT_METRICS, SMALL_CAPS_SCALE, TEXT_EDIT_FONT_HOLD, TextOutlinesError$1 as TextOutlinesError, applyCreateOutlines, applyOutlineStroke, applyStyleToRange, cachedLayoutRuns, cachedPaintRuns, caretIndexAt$1 as caretIndexAt, charOffsetToDomPosition, createMarkdownRenderer, createTextLayer, decorationMetrics, defaultLabelTextRenderer, domPositionToCharOffset, domToRuns, effectiveRangeStyle, fitTextPose, fontString, isBoldWeight, isSmallCapsLetter, isTextData$1 as isTextData, layoutMarkdown, layoutRuns, layoutTextPose, loadTextOutlines$1 as loadTextOutlines, markdownToRuns, measureText, measureTextBounds$1 as measureTextBounds, measuredWidth, nodeHasFlag, numericWeight, paintRuns, paragraphDirection, patchRangeStyle, pointInTextPose$1 as pointInTextPose, rangeWeight, registerBidi, renderLabel, resolveAlign$1 as resolveAlign, resolveRunFace, resolveRuns, resolveTextStyle, runsToDom, runsToMarkdown, runsToPlainText$1 as runsToPlainText, scriptMetrics, scriptMetricsFor, setFlagOverRange, smallCapsScale, smallCapsScaleFor, smallCapsText, strokeRegion, styleAtRange, textCommand, textCommandFromPose, textCommandFromRuns, textLineBoxes$1 as textLineBoxes, textPoseLayoutInput, textToPath$1 as textToPath, textToPathsByPaint$1 as textToPathsByPaint, toRuns, transformRunTexts, unboldPatch, useCreateOutlinesAdapter, useSceneTextEdit, useTextEdit, verticalAlignOffset };