@weasel-js/core 1.10.1 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1431) hide show
  1. package/CHANGELOG.md +587 -0
  2. package/README.md +16 -15
  3. package/dist/WeaselProvider.js +25 -9
  4. package/dist/WeaselProvider.js.map +1 -1
  5. package/dist/affordances/composeAffordanceLayer.js +217 -140
  6. package/dist/affordances/composeAffordanceLayer.js.map +1 -1
  7. package/dist/affordances/cornerResize.js +92 -50
  8. package/dist/affordances/cornerResize.js.map +1 -1
  9. package/dist/affordances/hitAffordanceRegions.js +147 -84
  10. package/dist/affordances/hitAffordanceRegions.js.map +1 -1
  11. package/dist/affordances/pathAnchors.js +140 -65
  12. package/dist/affordances/pathAnchors.js.map +1 -1
  13. package/dist/affordances/rotateCursor.js +10 -4
  14. package/dist/affordances/rotateCursor.js.map +1 -1
  15. package/dist/affordances/rotationHandle.js +83 -60
  16. package/dist/affordances/rotationHandle.js.map +1 -1
  17. package/dist/animation/behaviors/coast.js +20 -14
  18. package/dist/animation/behaviors/coast.js.map +1 -1
  19. package/dist/animation/behaviors/coastByWrite.js +98 -70
  20. package/dist/animation/behaviors/coastByWrite.js.map +1 -1
  21. package/dist/animation/behaviors/coastOnTargets.js +115 -67
  22. package/dist/animation/behaviors/coastOnTargets.js.map +1 -1
  23. package/dist/animation/behaviors/momentum.js +88 -53
  24. package/dist/animation/behaviors/momentum.js.map +1 -1
  25. package/dist/animation/clipTargets.js +14 -7
  26. package/dist/animation/clipTargets.js.map +1 -1
  27. package/dist/animation/departures.js +116 -0
  28. package/dist/animation/departures.js.map +1 -0
  29. package/dist/animation/index.js +18 -15
  30. package/dist/animation/poseHelpers.js +147 -107
  31. package/dist/animation/poseHelpers.js.map +1 -1
  32. package/dist/animation/poseTarget.js +158 -85
  33. package/dist/animation/poseTarget.js.map +1 -1
  34. package/dist/animation/poseTransition.js +64 -0
  35. package/dist/animation/poseTransition.js.map +1 -0
  36. package/dist/animation/reflow.js +208 -120
  37. package/dist/animation/reflow.js.map +1 -1
  38. package/dist/animation/rewind.js +76 -45
  39. package/dist/animation/rewind.js.map +1 -1
  40. package/dist/animation/rig/bindRig.js +135 -82
  41. package/dist/animation/rig/bindRig.js.map +1 -1
  42. package/dist/animation/rig/rigNode.js +120 -75
  43. package/dist/animation/rig/rigNode.js.map +1 -1
  44. package/dist/animation/rig/rigSeat.js +61 -41
  45. package/dist/animation/rig/rigSeat.js.map +1 -1
  46. package/dist/animation/rig/skinBinding.js +57 -45
  47. package/dist/animation/rig/skinBinding.js.map +1 -1
  48. package/dist/animation/rig/useRig.js +44 -30
  49. package/dist/animation/rig/useRig.js.map +1 -1
  50. package/dist/animation/wrappers/animateLifecycle.js +51 -35
  51. package/dist/animation/wrappers/animateLifecycle.js.map +1 -1
  52. package/dist/animation/wrappers/animateOnSetPose.js +55 -32
  53. package/dist/animation/wrappers/animateOnSetPose.js.map +1 -1
  54. package/dist/animation/wrappers/instantPose.js +13 -8
  55. package/dist/animation/wrappers/instantPose.js.map +1 -1
  56. package/dist/animation/writtenPoseTarget.js +44 -22
  57. package/dist/animation/writtenPoseTarget.js.map +1 -1
  58. package/dist/{autoPoseDescriptor-DHg5KqaJ.d.ts → autoPoseDescriptor-CZ1eXbzY.d.ts} +1 -1
  59. package/dist/barrel/canvas.js +41 -32
  60. package/dist/barrel/chrome.js +19 -16
  61. package/dist/barrel/icons.js +6 -0
  62. package/dist/barrel/input.js +19 -18
  63. package/dist/barrel/interactions.js +40 -39
  64. package/dist/barrel/paint.js +12 -11
  65. package/dist/barrel/paths.js +39 -13
  66. package/dist/barrel/renderer.js +24 -14
  67. package/dist/barrel/routing.js +69 -58
  68. package/dist/barrel/scene.js +48 -37
  69. package/dist/barrel/text.js +10 -9
  70. package/dist/barrel/viewport.js +47 -45
  71. package/dist/canvas/Canvas.js +189 -306
  72. package/dist/canvas/Canvas.js.map +1 -1
  73. package/dist/canvas/CanvasView.js +273 -199
  74. package/dist/canvas/CanvasView.js.map +1 -1
  75. package/dist/canvas/CursorCoordsHud.js +103 -64
  76. package/dist/canvas/CursorCoordsHud.js.map +1 -1
  77. package/dist/canvas/DrawCanvas.js +68 -41
  78. package/dist/canvas/DrawCanvas.js.map +1 -1
  79. package/dist/canvas/LeanSceneCanvas.js +23 -0
  80. package/dist/canvas/LeanSceneCanvas.js.map +1 -0
  81. package/dist/canvas/ModalityHud.js +58 -43
  82. package/dist/canvas/ModalityHud.js.map +1 -1
  83. package/dist/canvas/NodeShape.js +137 -60
  84. package/dist/canvas/NodeShape.js.map +1 -1
  85. package/dist/canvas/PickHud.js +77 -59
  86. package/dist/canvas/PickHud.js.map +1 -1
  87. package/dist/canvas/SceneCanvas/ActionsProviderIfRoot.js +9 -6
  88. package/dist/canvas/SceneCanvas/ActionsProviderIfRoot.js.map +1 -1
  89. package/dist/canvas/SceneCanvas/CanvasKitProviders.js +25 -0
  90. package/dist/canvas/SceneCanvas/CanvasKitProviders.js.map +1 -0
  91. package/dist/canvas/SceneCanvas/DepRegistryProviderIfRoot.js +10 -6
  92. package/dist/canvas/SceneCanvas/DepRegistryProviderIfRoot.js.map +1 -1
  93. package/dist/canvas/SceneCanvas/DevHuds.js +47 -32
  94. package/dist/canvas/SceneCanvas/DevHuds.js.map +1 -1
  95. package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js +72 -37
  96. package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js.map +1 -1
  97. package/dist/canvas/SceneCanvas/SceneCanvasInput.js +110 -0
  98. package/dist/canvas/SceneCanvas/SceneCanvasInput.js.map +1 -0
  99. package/dist/canvas/SceneCanvas/brushOverlay.js +36 -0
  100. package/dist/canvas/SceneCanvas/brushOverlay.js.map +1 -0
  101. package/dist/canvas/SceneCanvas/canvasPassThrough.js +72 -0
  102. package/dist/canvas/SceneCanvas/canvasPassThrough.js.map +1 -0
  103. package/dist/canvas/SceneCanvas/contributionFrameHooks.js +54 -32
  104. package/dist/canvas/SceneCanvas/contributionFrameHooks.js.map +1 -1
  105. package/dist/canvas/SceneCanvas/coordTrace.js +36 -29
  106. package/dist/canvas/SceneCanvas/coordTrace.js.map +1 -1
  107. package/dist/canvas/SceneCanvas/defaultNodeProperties.js +318 -159
  108. package/dist/canvas/SceneCanvas/defaultNodeProperties.js.map +1 -1
  109. package/dist/canvas/SceneCanvas/defaultNodeRouting.js +39 -13
  110. package/dist/canvas/SceneCanvas/defaultNodeRouting.js.map +1 -1
  111. package/dist/canvas/SceneCanvas/dispatcherGestureBounds.js +83 -47
  112. package/dist/canvas/SceneCanvas/dispatcherGestureBounds.js.map +1 -1
  113. package/dist/canvas/SceneCanvas/features.js +83 -106
  114. package/dist/canvas/SceneCanvas/features.js.map +1 -1
  115. package/dist/canvas/SceneCanvas/insertPreviewCommands.js +80 -62
  116. package/dist/canvas/SceneCanvas/insertPreviewCommands.js.map +1 -1
  117. package/dist/canvas/SceneCanvas/mergeLayers.js +43 -0
  118. package/dist/canvas/SceneCanvas/mergeLayers.js.map +1 -0
  119. package/dist/canvas/SceneCanvas/namedPresets.js +56 -0
  120. package/dist/canvas/SceneCanvas/namedPresets.js.map +1 -0
  121. package/dist/canvas/SceneCanvas/poseGeometry.js +66 -31
  122. package/dist/canvas/SceneCanvas/poseGeometry.js.map +1 -1
  123. package/dist/canvas/SceneCanvas/poseRegistrars.js +18 -8
  124. package/dist/canvas/SceneCanvas/poseRegistrars.js.map +1 -1
  125. package/dist/canvas/SceneCanvas/presets/arrange.js +27 -0
  126. package/dist/canvas/SceneCanvas/presets/arrange.js.map +1 -0
  127. package/dist/canvas/SceneCanvas/presets/chrome.js +14 -0
  128. package/dist/canvas/SceneCanvas/presets/chrome.js.map +1 -0
  129. package/dist/canvas/SceneCanvas/presets/edit.js +59 -0
  130. package/dist/canvas/SceneCanvas/presets/edit.js.map +1 -0
  131. package/dist/canvas/SceneCanvas/presets/ingest.js +13 -0
  132. package/dist/canvas/SceneCanvas/presets/ingest.js.map +1 -0
  133. package/dist/canvas/SceneCanvas/presets/paths.js +67 -0
  134. package/dist/canvas/SceneCanvas/presets/paths.js.map +1 -0
  135. package/dist/canvas/SceneCanvas/presets/select.js +19 -0
  136. package/dist/canvas/SceneCanvas/presets/select.js.map +1 -0
  137. package/dist/canvas/SceneCanvas/presets/toolDriven.js +20 -0
  138. package/dist/canvas/SceneCanvas/presets/toolDriven.js.map +1 -0
  139. package/dist/canvas/SceneCanvas/presets/transform.js +41 -0
  140. package/dist/canvas/SceneCanvas/presets/transform.js.map +1 -0
  141. package/dist/canvas/SceneCanvas/presets/view.js +14 -0
  142. package/dist/canvas/SceneCanvas/presets/view.js.map +1 -0
  143. package/dist/canvas/SceneCanvas/props.js +19 -35
  144. package/dist/canvas/SceneCanvas/props.js.map +1 -1
  145. package/dist/canvas/SceneCanvas/scenePointQuery.js +43 -35
  146. package/dist/canvas/SceneCanvas/scenePointQuery.js.map +1 -1
  147. package/dist/canvas/SceneCanvas/shapeGeneratorProperties.js +22 -15
  148. package/dist/canvas/SceneCanvas/shapeGeneratorProperties.js.map +1 -1
  149. package/dist/canvas/SceneCanvas/toolRegistry.js +30 -15
  150. package/dist/canvas/SceneCanvas/toolRegistry.js.map +1 -1
  151. package/dist/canvas/SceneCanvas/useActionTunings.js +14 -11
  152. package/dist/canvas/SceneCanvas/useActionTunings.js.map +1 -1
  153. package/dist/canvas/SceneCanvas/useActionsPropResolver.js +68 -35
  154. package/dist/canvas/SceneCanvas/useActionsPropResolver.js.map +1 -1
  155. package/dist/canvas/SceneCanvas/useBakedScene.js +17 -0
  156. package/dist/canvas/SceneCanvas/useBakedScene.js.map +1 -0
  157. package/dist/canvas/SceneCanvas/useBuiltinRigTools.js +65 -0
  158. package/dist/canvas/SceneCanvas/useBuiltinRigTools.js.map +1 -0
  159. package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js +47 -23
  160. package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js.map +1 -1
  161. package/dist/canvas/SceneCanvas/useBuiltinTools.js +29 -14
  162. package/dist/canvas/SceneCanvas/useBuiltinTools.js.map +1 -1
  163. package/dist/canvas/SceneCanvas/useCanvasCamera.js +53 -38
  164. package/dist/canvas/SceneCanvas/useCanvasCamera.js.map +1 -1
  165. package/dist/canvas/SceneCanvas/useCanvasDispatcher.js +24 -14
  166. package/dist/canvas/SceneCanvas/useCanvasDispatcher.js.map +1 -1
  167. package/dist/canvas/SceneCanvas/useCanvasSelection.js +30 -12
  168. package/dist/canvas/SceneCanvas/useCanvasSelection.js.map +1 -1
  169. package/dist/canvas/SceneCanvas/useCanvasTools.js +112 -53
  170. package/dist/canvas/SceneCanvas/useCanvasTools.js.map +1 -1
  171. package/dist/canvas/SceneCanvas/useChromeAffordances.js +31 -0
  172. package/dist/canvas/SceneCanvas/useChromeAffordances.js.map +1 -0
  173. package/dist/canvas/SceneCanvas/useContributionRoles.js +107 -56
  174. package/dist/canvas/SceneCanvas/useContributionRoles.js.map +1 -1
  175. package/dist/canvas/SceneCanvas/useDepartureGhostLayer.js +64 -0
  176. package/dist/canvas/SceneCanvas/useDepartureGhostLayer.js.map +1 -0
  177. package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js +104 -71
  178. package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js.map +1 -1
  179. package/dist/canvas/SceneCanvas/useHeldModifiers.js +21 -14
  180. package/dist/canvas/SceneCanvas/useHeldModifiers.js.map +1 -1
  181. package/dist/canvas/SceneCanvas/useNodeAtPoint.js +21 -19
  182. package/dist/canvas/SceneCanvas/useNodeAtPoint.js.map +1 -1
  183. package/dist/canvas/SceneCanvas/useNodeKinds.js +28 -19
  184. package/dist/canvas/SceneCanvas/useNodeKinds.js.map +1 -1
  185. package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js +91 -59
  186. package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js.map +1 -1
  187. package/dist/canvas/SceneCanvas/useSceneCanvasHandle.js +62 -35
  188. package/dist/canvas/SceneCanvas/useSceneCanvasHandle.js.map +1 -1
  189. package/dist/canvas/SceneCanvas/useSceneCanvasLayers.js +110 -50
  190. package/dist/canvas/SceneCanvas/useSceneCanvasLayers.js.map +1 -1
  191. package/dist/canvas/SceneCanvas/useSceneCanvasPathEdit.js +30 -0
  192. package/dist/canvas/SceneCanvas/useSceneCanvasPathEdit.js.map +1 -0
  193. package/dist/canvas/SceneCanvas/useSceneCanvasTools.js +40 -0
  194. package/dist/canvas/SceneCanvas/useSceneCanvasTools.js.map +1 -0
  195. package/dist/canvas/SceneCanvas/useSceneChrome.js +100 -44
  196. package/dist/canvas/SceneCanvas/useSceneChrome.js.map +1 -1
  197. package/dist/canvas/SceneCanvas/useSceneGestureDispatcher.js +163 -0
  198. package/dist/canvas/SceneCanvas/useSceneGestureDispatcher.js.map +1 -0
  199. package/dist/canvas/SceneCanvas/useScenePicking.js +69 -0
  200. package/dist/canvas/SceneCanvas/useScenePicking.js.map +1 -0
  201. package/dist/canvas/SceneCanvas/useSceneRedrawSources.js +28 -17
  202. package/dist/canvas/SceneCanvas/useSceneRedrawSources.js.map +1 -1
  203. package/dist/canvas/SceneCanvas/useSceneSelectTool.js +159 -80
  204. package/dist/canvas/SceneCanvas/useSceneSelectTool.js.map +1 -1
  205. package/dist/canvas/SceneCanvas/useSceneSlotLayers.js +38 -26
  206. package/dist/canvas/SceneCanvas/useSceneSlotLayers.js.map +1 -1
  207. package/dist/canvas/SceneCanvas/useSceneStandardActions.js +108 -0
  208. package/dist/canvas/SceneCanvas/useSceneStandardActions.js.map +1 -0
  209. package/dist/canvas/SceneCanvas/useSelectionOverlayLayer.js +40 -27
  210. package/dist/canvas/SceneCanvas/useSelectionOverlayLayer.js.map +1 -1
  211. package/dist/canvas/SceneCanvas/useSurfaceRouting.js +29 -0
  212. package/dist/canvas/SceneCanvas/useSurfaceRouting.js.map +1 -0
  213. package/dist/canvas/SceneCanvas/useSurfaceViewInputs.js +44 -0
  214. package/dist/canvas/SceneCanvas/useSurfaceViewInputs.js.map +1 -0
  215. package/dist/canvas/SceneCanvas/useToolKeybindings.js +28 -0
  216. package/dist/canvas/SceneCanvas/useToolKeybindings.js.map +1 -0
  217. package/dist/canvas/SceneCanvas/useViewportActions.js +52 -28
  218. package/dist/canvas/SceneCanvas/useViewportActions.js.map +1 -1
  219. package/dist/canvas/SceneCanvas/worldPointAt.js +10 -4
  220. package/dist/canvas/SceneCanvas/worldPointAt.js.map +1 -1
  221. package/dist/canvas/SceneCanvas.js +274 -312
  222. package/dist/canvas/SceneCanvas.js.map +1 -1
  223. package/dist/canvas/SceneViewCanvas.js +68 -42
  224. package/dist/canvas/SceneViewCanvas.js.map +1 -1
  225. package/dist/canvas/SurfaceCanvas.js +53 -31
  226. package/dist/canvas/SurfaceCanvas.js.map +1 -1
  227. package/dist/canvas/accentColor.js +8 -5
  228. package/dist/canvas/accentColor.js.map +1 -1
  229. package/dist/canvas/adapterDerivedPath.js +33 -18
  230. package/dist/canvas/adapterDerivedPath.js.map +1 -1
  231. package/dist/canvas/adapterPickSource.js +49 -23
  232. package/dist/canvas/adapterPickSource.js.map +1 -1
  233. package/dist/canvas/affordanceAt.js +106 -50
  234. package/dist/canvas/affordanceAt.js.map +1 -1
  235. package/dist/canvas/buildSceneLayer.js +111 -80
  236. package/dist/canvas/buildSceneLayer.js.map +1 -1
  237. package/dist/canvas/buildSceneTree.js +101 -59
  238. package/dist/canvas/buildSceneTree.js.map +1 -1
  239. package/dist/canvas/canvasRenderer.js +156 -71
  240. package/dist/canvas/canvasRenderer.js.map +1 -1
  241. package/dist/canvas/colorOverrides.js +18 -10
  242. package/dist/canvas/colorOverrides.js.map +1 -1
  243. package/dist/canvas/copiesAbove.js +24 -14
  244. package/dist/canvas/copiesAbove.js.map +1 -1
  245. package/dist/canvas/defaultDrawOne.js +55 -31
  246. package/dist/canvas/defaultDrawOne.js.map +1 -1
  247. package/dist/canvas/deps/areaSelect.js +30 -12
  248. package/dist/canvas/deps/areaSelect.js.map +1 -1
  249. package/dist/canvas/deps/booleans.js +104 -0
  250. package/dist/canvas/deps/booleans.js.map +1 -0
  251. package/dist/canvas/deps/changes.js +17 -9
  252. package/dist/canvas/deps/changes.js.map +1 -1
  253. package/dist/canvas/deps/debug.js +12 -5
  254. package/dist/canvas/deps/debug.js.map +1 -1
  255. package/dist/canvas/deps/dispatchSources.js +27 -0
  256. package/dist/canvas/deps/dispatchSources.js.map +1 -0
  257. package/dist/canvas/deps/dispatcher.js +18 -7
  258. package/dist/canvas/deps/dispatcher.js.map +1 -1
  259. package/dist/canvas/deps/editAnchors.js +253 -63
  260. package/dist/canvas/deps/editAnchors.js.map +1 -1
  261. package/dist/canvas/deps/geometryProjection.js +13 -7
  262. package/dist/canvas/deps/geometryProjection.js.map +1 -1
  263. package/dist/canvas/deps/hitTestArea.js +78 -53
  264. package/dist/canvas/deps/hitTestArea.js.map +1 -1
  265. package/dist/canvas/deps/ingestion.js +18 -13
  266. package/dist/canvas/deps/ingestion.js.map +1 -1
  267. package/dist/canvas/deps/insert.js +176 -116
  268. package/dist/canvas/deps/insert.js.map +1 -1
  269. package/dist/canvas/deps/kitSettings.js +16 -0
  270. package/dist/canvas/deps/kitSettings.js.map +1 -0
  271. package/dist/canvas/deps/lassoSelect.js +25 -13
  272. package/dist/canvas/deps/lassoSelect.js.map +1 -1
  273. package/dist/canvas/deps/layout.js +32 -20
  274. package/dist/canvas/deps/layout.js.map +1 -1
  275. package/dist/canvas/deps/nodeAtPoint.js +28 -14
  276. package/dist/canvas/deps/nodeAtPoint.js.map +1 -1
  277. package/dist/canvas/deps/pathLeaf.js +66 -0
  278. package/dist/canvas/deps/pathLeaf.js.map +1 -0
  279. package/dist/canvas/deps/pathLeafDeps.js +13 -0
  280. package/dist/canvas/deps/pathLeafDeps.js.map +1 -0
  281. package/dist/canvas/deps/poseDescriptor.js +10 -8
  282. package/dist/canvas/deps/poseDescriptor.js.map +1 -1
  283. package/dist/canvas/deps/previewPaths.js +44 -0
  284. package/dist/canvas/deps/previewPaths.js.map +1 -0
  285. package/dist/canvas/deps/resizePolicy.js +32 -25
  286. package/dist/canvas/deps/resizePolicy.js.map +1 -1
  287. package/dist/canvas/deps/slice.js +73 -87
  288. package/dist/canvas/deps/slice.js.map +1 -1
  289. package/dist/canvas/deps/snap.js +58 -7
  290. package/dist/canvas/deps/snap.js.map +1 -1
  291. package/dist/canvas/deps/surface.js +30 -0
  292. package/dist/canvas/deps/surface.js.map +1 -0
  293. package/dist/canvas/deps/textEdit.js +21 -13
  294. package/dist/canvas/deps/textEdit.js.map +1 -1
  295. package/dist/canvas/deps/view.js +46 -34
  296. package/dist/canvas/deps/view.js.map +1 -1
  297. package/dist/canvas/derivedPath.js +154 -70
  298. package/dist/canvas/derivedPath.js.map +1 -1
  299. package/dist/canvas/doubleClickTarget.js +20 -0
  300. package/dist/canvas/doubleClickTarget.js.map +1 -0
  301. package/dist/canvas/drawEnvelope.js +26 -17
  302. package/dist/canvas/drawEnvelope.js.map +1 -1
  303. package/dist/canvas/drawnBounds.js +116 -0
  304. package/dist/canvas/drawnBounds.js.map +1 -0
  305. package/dist/canvas/getNodeAtPoint.js +11 -8
  306. package/dist/canvas/getNodeAtPoint.js.map +1 -1
  307. package/dist/canvas/hostAnchor.js +35 -18
  308. package/dist/canvas/hostAnchor.js.map +1 -1
  309. package/dist/canvas/hud.module.js +25 -14
  310. package/dist/canvas/hud.module.js.map +1 -1
  311. package/dist/canvas/insertPreviewExtent.js +82 -61
  312. package/dist/canvas/insertPreviewExtent.js.map +1 -1
  313. package/dist/canvas/kitRequirements.js +154 -115
  314. package/dist/canvas/kitRequirements.js.map +1 -1
  315. package/dist/canvas/layerHover.js +28 -0
  316. package/dist/canvas/layerHover.js.map +1 -0
  317. package/dist/canvas/layerOrder.js +107 -57
  318. package/dist/canvas/layerOrder.js.map +1 -1
  319. package/dist/canvas/layerSlots.js +16 -9
  320. package/dist/canvas/layerSlots.js.map +1 -1
  321. package/dist/canvas/mountedCanvases.js +23 -13
  322. package/dist/canvas/mountedCanvases.js.map +1 -1
  323. package/dist/canvas/nodeShapes/derivedPainter.js +65 -25
  324. package/dist/canvas/nodeShapes/derivedPainter.js.map +1 -1
  325. package/dist/canvas/nodeShapes/imagePainter.js +69 -53
  326. package/dist/canvas/nodeShapes/imagePainter.js.map +1 -1
  327. package/dist/canvas/nodeShapes/measurePainter.js +58 -0
  328. package/dist/canvas/nodeShapes/measurePainter.js.map +1 -0
  329. package/dist/canvas/nodeShapes/memo.js +16 -5
  330. package/dist/canvas/nodeShapes/memo.js.map +1 -1
  331. package/dist/canvas/nodeShapes/nodePaint.js +125 -46
  332. package/dist/canvas/nodeShapes/nodePaint.js.map +1 -1
  333. package/dist/canvas/nodeShapes/pathPainter.js +41 -27
  334. package/dist/canvas/nodeShapes/pathPainter.js.map +1 -1
  335. package/dist/canvas/nodeShapes/poseBox.js +20 -13
  336. package/dist/canvas/nodeShapes/poseBox.js.map +1 -1
  337. package/dist/canvas/nodeShapes/rectFallbackPainter.js +26 -22
  338. package/dist/canvas/nodeShapes/rectFallbackPainter.js.map +1 -1
  339. package/dist/canvas/nodeShapes/shapePainter.js +67 -46
  340. package/dist/canvas/nodeShapes/shapePainter.js.map +1 -1
  341. package/dist/canvas/nodeShapes/strokedBounds.js +177 -0
  342. package/dist/canvas/nodeShapes/strokedBounds.js.map +1 -0
  343. package/dist/canvas/nodeShapes/textPainter.js +170 -37
  344. package/dist/canvas/nodeShapes/textPainter.js.map +1 -1
  345. package/dist/canvas/overChildren.js +29 -18
  346. package/dist/canvas/overChildren.js.map +1 -1
  347. package/dist/canvas/overlayRoleStrokes.js +20 -3
  348. package/dist/canvas/overlayRoleStrokes.js.map +1 -1
  349. package/dist/canvas/paintCull.js +24 -12
  350. package/dist/canvas/paintCull.js.map +1 -1
  351. package/dist/canvas/paintedCursorLayer.js +59 -35
  352. package/dist/canvas/paintedCursorLayer.js.map +1 -1
  353. package/dist/canvas/pathOverlay.js +63 -0
  354. package/dist/canvas/pathOverlay.js.map +1 -0
  355. package/dist/canvas/pickReach.js +34 -17
  356. package/dist/canvas/pickReach.js.map +1 -1
  357. package/dist/canvas/pickWalk.js +151 -102
  358. package/dist/canvas/pickWalk.js.map +1 -1
  359. package/dist/canvas/planeClips.js +39 -22
  360. package/dist/canvas/planeClips.js.map +1 -1
  361. package/dist/canvas/poseCascade.js +51 -27
  362. package/dist/canvas/poseCascade.js.map +1 -1
  363. package/dist/canvas/poseRotation.js +24 -14
  364. package/dist/canvas/poseRotation.js.map +1 -1
  365. package/dist/canvas/rasterReadback.js +23 -15
  366. package/dist/canvas/rasterReadback.js.map +1 -1
  367. package/dist/canvas/rasterToPng.js +21 -15
  368. package/dist/canvas/rasterToPng.js.map +1 -1
  369. package/dist/canvas/renderDebugSnapshot.js +36 -19
  370. package/dist/canvas/renderDebugSnapshot.js.map +1 -1
  371. package/dist/canvas/renderNeeds.js +33 -18
  372. package/dist/canvas/renderNeeds.js.map +1 -1
  373. package/dist/canvas/renderSceneToPixels.js +202 -87
  374. package/dist/canvas/renderSceneToPixels.js.map +1 -1
  375. package/dist/canvas/sceneAdapter.js +96 -75
  376. package/dist/canvas/sceneAdapter.js.map +1 -1
  377. package/dist/canvas/sceneClipboard.js +141 -92
  378. package/dist/canvas/sceneClipboard.js.map +1 -1
  379. package/dist/canvas/sceneLayerPaint.js +56 -27
  380. package/dist/canvas/sceneLayerPaint.js.map +1 -1
  381. package/dist/canvas/sceneSlotWiring.js +24 -14
  382. package/dist/canvas/sceneSlotWiring.js.map +1 -1
  383. package/dist/canvas/sceneViewRender.js +85 -49
  384. package/dist/canvas/sceneViewRender.js.map +1 -1
  385. package/dist/canvas/slopsDebugLayer.js +58 -49
  386. package/dist/canvas/slopsDebugLayer.js.map +1 -1
  387. package/dist/canvas/surfaceContribution.js +22 -10
  388. package/dist/canvas/surfaceContribution.js.map +1 -1
  389. package/dist/canvas/useCanvasElements.js +31 -0
  390. package/dist/canvas/useCanvasElements.js.map +1 -0
  391. package/dist/canvas/useCanvasHandle.js +69 -0
  392. package/dist/canvas/useCanvasHandle.js.map +1 -0
  393. package/dist/canvas/useCanvasPaint.js +91 -0
  394. package/dist/canvas/useCanvasPaint.js.map +1 -0
  395. package/dist/canvas/useCanvasRenderer.js +45 -23
  396. package/dist/canvas/useCanvasRenderer.js.map +1 -1
  397. package/dist/canvas/useCanvasSurface.js +41 -23
  398. package/dist/canvas/useCanvasSurface.js.map +1 -1
  399. package/dist/canvas/useCanvasView.js +80 -48
  400. package/dist/canvas/useCanvasView.js.map +1 -1
  401. package/dist/canvas/useClientToWorld.js +27 -0
  402. package/dist/canvas/useClientToWorld.js.map +1 -0
  403. package/dist/canvas/useExtraLayers.js +45 -0
  404. package/dist/canvas/useExtraLayers.js.map +1 -0
  405. package/dist/canvas/useFrameLoop.js +109 -49
  406. package/dist/canvas/useFrameLoop.js.map +1 -1
  407. package/dist/canvas/useHitObserver.js +22 -15
  408. package/dist/canvas/useHitObserver.js.map +1 -1
  409. package/dist/canvas/useHostAnchor.js +83 -53
  410. package/dist/canvas/useHostAnchor.js.map +1 -1
  411. package/dist/canvas/useLateContentRedraw.js +21 -14
  412. package/dist/canvas/useLateContentRedraw.js.map +1 -1
  413. package/dist/canvas/useLayerStack.js +72 -0
  414. package/dist/canvas/useLayerStack.js.map +1 -0
  415. package/dist/canvas/usePaintedCursor.js +28 -0
  416. package/dist/canvas/usePaintedCursor.js.map +1 -0
  417. package/dist/canvas/useRedrawOn.js +24 -14
  418. package/dist/canvas/useRedrawOn.js.map +1 -1
  419. package/dist/canvas/useSceneAdapter.js +21 -16
  420. package/dist/canvas/useSceneAdapter.js.map +1 -1
  421. package/dist/canvas/useSceneLayerList.js +15 -7
  422. package/dist/canvas/useSceneLayerList.js.map +1 -1
  423. package/dist/canvas/useSurfaceInput.js +46 -27
  424. package/dist/canvas/useSurfaceInput.js.map +1 -1
  425. package/dist/canvas/useSurfaceSize.js +43 -0
  426. package/dist/canvas/useSurfaceSize.js.map +1 -0
  427. package/dist/canvas/useToolCursor.js +30 -21
  428. package/dist/canvas/useToolCursor.js.map +1 -1
  429. package/dist/canvas/useViewHelpers.js +112 -61
  430. package/dist/canvas/useViewHelpers.js.map +1 -1
  431. package/dist/canvas/useViewLayerGate.js +29 -0
  432. package/dist/canvas/useViewLayerGate.js.map +1 -0
  433. package/dist/canvas/useViewNesting.js +104 -0
  434. package/dist/canvas/useViewNesting.js.map +1 -0
  435. package/dist/canvas/useViewRegistrySurface.js +44 -0
  436. package/dist/canvas/useViewRegistrySurface.js.map +1 -0
  437. package/dist/canvas/viewInputs.js +14 -11
  438. package/dist/canvas/viewInputs.js.map +1 -1
  439. package/dist/canvas/viewRegistry.js +140 -42
  440. package/dist/canvas/viewRegistry.js.map +1 -1
  441. package/dist/canvas/watchElementMove.js +71 -33
  442. package/dist/canvas/watchElementMove.js.map +1 -1
  443. package/dist/canvas/wrapNodeOutput.js +20 -13
  444. package/dist/canvas/wrapNodeOutput.js.map +1 -1
  445. package/dist/clipboard.d.ts +7 -3
  446. package/dist/clipboard.js +4 -3
  447. package/dist/{clone-C0eADtS0.d.ts → clone-DZDrfIlU.d.ts} +20 -53
  448. package/dist/clone.d.ts +5 -4
  449. package/dist/core/adapters/testing/rootsTree.js +17 -0
  450. package/dist/core/adapters/testing/rootsTree.js.map +1 -0
  451. package/dist/core/applyOps.js +23 -7
  452. package/dist/core/applyOps.js.map +1 -1
  453. package/dist/core/device/index.js +6 -5
  454. package/dist/core/device/targets.js +29 -8
  455. package/dist/core/device/targets.js.map +1 -1
  456. package/dist/core/device/useDeviceProfile.js +86 -52
  457. package/dist/core/device/useDeviceProfile.js.map +1 -1
  458. package/dist/core/device/useTargetBasePx.js +23 -0
  459. package/dist/core/device/useTargetBasePx.js.map +1 -0
  460. package/dist/core/device/watchDevicePixelRatio.js +27 -10
  461. package/dist/core/device/watchDevicePixelRatio.js.map +1 -1
  462. package/dist/core/geometry/autoPoseDescriptor.js +38 -24
  463. package/dist/core/geometry/autoPoseDescriptor.js.map +1 -1
  464. package/dist/core/geometry/inkExtents.js +60 -0
  465. package/dist/core/geometry/inkExtents.js.map +1 -0
  466. package/dist/core/geometry/pathPoseDescriptor.js +101 -76
  467. package/dist/core/geometry/pathPoseDescriptor.js.map +1 -1
  468. package/dist/core/geometry/poseDescriptor.js +199 -136
  469. package/dist/core/geometry/poseDescriptor.js.map +1 -1
  470. package/dist/core/geometry/regionHit.js +127 -79
  471. package/dist/core/geometry/regionHit.js.map +1 -1
  472. package/dist/core/geometry/targetFrame.js +84 -60
  473. package/dist/core/geometry/targetFrame.js.map +1 -1
  474. package/dist/core/geometry/unionBounds.js +103 -48
  475. package/dist/core/geometry/unionBounds.js.map +1 -1
  476. package/dist/core/isPlainObject.js +3 -2
  477. package/dist/core/layers/backgroundFill.js +23 -15
  478. package/dist/core/layers/backgroundFill.js.map +1 -1
  479. package/dist/core/layers/children.js +16 -13
  480. package/dist/core/layers/children.js.map +1 -1
  481. package/dist/core/layers/gateLayer.js +24 -9
  482. package/dist/core/layers/gateLayer.js.map +1 -1
  483. package/dist/core/layers/layerGroup.js +42 -29
  484. package/dist/core/layers/layerGroup.js.map +1 -1
  485. package/dist/core/layers/redrawSource.js +15 -0
  486. package/dist/core/layers/redrawSource.js.map +1 -0
  487. package/dist/core/layers/render.js +183 -93
  488. package/dist/core/layers/render.js.map +1 -1
  489. package/dist/core/layers/retain.js +38 -0
  490. package/dist/core/layers/retain.js.map +1 -0
  491. package/dist/core/ops/arrange.js +30 -19
  492. package/dist/core/ops/arrange.js.map +1 -1
  493. package/dist/core/ops/create.js +32 -23
  494. package/dist/core/ops/create.js.map +1 -1
  495. package/dist/core/ops/createHistory.js +23 -14
  496. package/dist/core/ops/createHistory.js.map +1 -1
  497. package/dist/core/ops/delete.js +80 -53
  498. package/dist/core/ops/delete.js.map +1 -1
  499. package/dist/core/ops/nodeFlags.js +44 -0
  500. package/dist/core/ops/nodeFlags.js.map +1 -0
  501. package/dist/core/ops/registry.js +26 -11
  502. package/dist/core/ops/registry.js.map +1 -1
  503. package/dist/core/ops/reorder/algorithms.js +62 -38
  504. package/dist/core/ops/reorder/algorithms.js.map +1 -1
  505. package/dist/core/ops/reorder/index.js +124 -84
  506. package/dist/core/ops/reorder/index.js.map +1 -1
  507. package/dist/core/ops/reorder/setChildOrder.js +32 -23
  508. package/dist/core/ops/reorder/setChildOrder.js.map +1 -1
  509. package/dist/core/ops/reparent.js +63 -37
  510. package/dist/core/ops/reparent.js.map +1 -1
  511. package/dist/core/ops/select.js +23 -20
  512. package/dist/core/ops/select.js.map +1 -1
  513. package/dist/core/ops/setData.js +23 -21
  514. package/dist/core/ops/setData.js.map +1 -1
  515. package/dist/core/ops/setLayer.js +26 -21
  516. package/dist/core/ops/setLayer.js.map +1 -1
  517. package/dist/core/ops/setLayout.js +27 -18
  518. package/dist/core/ops/setLayout.js.map +1 -1
  519. package/dist/core/ops/setPath.js +60 -41
  520. package/dist/core/ops/setPath.js.map +1 -1
  521. package/dist/core/ops/setText.js +26 -21
  522. package/dist/core/ops/setText.js.map +1 -1
  523. package/dist/core/ops/slot.js +36 -22
  524. package/dist/core/ops/slot.js.map +1 -1
  525. package/dist/core/ops/transform.js +35 -28
  526. package/dist/core/ops/transform.js.map +1 -1
  527. package/dist/core/pages/fitViewToPage.js +13 -11
  528. package/dist/core/pages/fitViewToPage.js.map +1 -1
  529. package/dist/core/pages/pages.js +73 -42
  530. package/dist/core/pages/pages.js.map +1 -1
  531. package/dist/core/pages/pagesLayer.js +19 -13
  532. package/dist/core/pages/pagesLayer.js.map +1 -1
  533. package/dist/core/paint/meshKind.js +16 -11
  534. package/dist/core/paint/meshKind.js.map +1 -1
  535. package/dist/core/paint/meshKindLazy.js +1 -1
  536. package/dist/core/paint/meshKindLazy.js.map +1 -1
  537. package/dist/core/paint/paintKindEntry.js +13 -4
  538. package/dist/core/paint/paintKindEntry.js.map +1 -1
  539. package/dist/core/paint/paintKinds.js +149 -88
  540. package/dist/core/paint/paintKinds.js.map +1 -1
  541. package/dist/core/paint/registerMesh.js +6 -4
  542. package/dist/core/paint/registerMesh.js.map +1 -1
  543. package/dist/core/scene/NodeProperties.js +15 -10
  544. package/dist/core/scene/NodeProperties.js.map +1 -1
  545. package/dist/core/scene/NodeRouting.js +16 -12
  546. package/dist/core/scene/NodeRouting.js.map +1 -1
  547. package/dist/core/scene/annotation.js +28 -0
  548. package/dist/core/scene/annotation.js.map +1 -0
  549. package/dist/core/scene/appliedLog.js +31 -23
  550. package/dist/core/scene/appliedLog.js.map +1 -1
  551. package/dist/core/scene/arrivalWindow.js +120 -75
  552. package/dist/core/scene/arrivalWindow.js.map +1 -1
  553. package/dist/core/scene/arrivals.js +17 -6
  554. package/dist/core/scene/arrivals.js.map +1 -1
  555. package/dist/core/scene/boundOps.js +42 -23
  556. package/dist/core/scene/boundOps.js.map +1 -1
  557. package/dist/core/scene/composeFrame.js +51 -21
  558. package/dist/core/scene/composeFrame.js.map +1 -1
  559. package/dist/core/scene/composePose.js +114 -62
  560. package/dist/core/scene/composePose.js.map +1 -1
  561. package/dist/core/scene/depFrame.js +94 -0
  562. package/dist/core/scene/depFrame.js.map +1 -0
  563. package/dist/core/scene/depMemo.js +44 -19
  564. package/dist/core/scene/depMemo.js.map +1 -1
  565. package/dist/core/scene/dependents.js +73 -45
  566. package/dist/core/scene/dependents.js.map +1 -1
  567. package/dist/core/scene/derivedParts.js +58 -0
  568. package/dist/core/scene/derivedParts.js.map +1 -0
  569. package/dist/core/scene/derivedPath.js +52 -22
  570. package/dist/core/scene/derivedPath.js.map +1 -1
  571. package/dist/core/scene/editMode.js +11 -11
  572. package/dist/core/scene/editMode.js.map +1 -1
  573. package/dist/core/scene/effectivePose.js +167 -51
  574. package/dist/core/scene/effectivePose.js.map +1 -1
  575. package/dist/core/scene/fieldEdits.js +95 -75
  576. package/dist/core/scene/fieldEdits.js.map +1 -1
  577. package/dist/core/scene/historyFacade.js +126 -87
  578. package/dist/core/scene/historyFacade.js.map +1 -1
  579. package/dist/core/scene/historyForm.js +7 -3
  580. package/dist/core/scene/historyForm.js.map +1 -1
  581. package/dist/core/scene/kitOps.js +203 -131
  582. package/dist/core/scene/kitOps.js.map +1 -1
  583. package/dist/core/scene/kitRegistry.js +49 -22
  584. package/dist/core/scene/kitRegistry.js.map +1 -1
  585. package/dist/core/scene/layerStack.js +123 -92
  586. package/dist/core/scene/layerStack.js.map +1 -1
  587. package/dist/core/scene/layoutPass.js +118 -72
  588. package/dist/core/scene/layoutPass.js.map +1 -1
  589. package/dist/core/scene/lockGuard.js +32 -24
  590. package/dist/core/scene/lockGuard.js.map +1 -1
  591. package/dist/core/scene/minSize.js +17 -0
  592. package/dist/core/scene/minSize.js.map +1 -0
  593. package/dist/core/scene/nestedHit.js +45 -31
  594. package/dist/core/scene/nestedHit.js.map +1 -1
  595. package/dist/core/scene/nodeFlags.js +43 -0
  596. package/dist/core/scene/nodeFlags.js.map +1 -0
  597. package/dist/core/scene/nodeFnFields.js +58 -41
  598. package/dist/core/scene/nodeFnFields.js.map +1 -1
  599. package/dist/core/scene/nodeGates.js +58 -0
  600. package/dist/core/scene/nodeGates.js.map +1 -0
  601. package/dist/core/scene/nodeMemo.js +92 -40
  602. package/dist/core/scene/nodeMemo.js.map +1 -1
  603. package/dist/core/scene/nodeStore.js +179 -99
  604. package/dist/core/scene/nodeStore.js.map +1 -1
  605. package/dist/core/scene/notifier.js +30 -19
  606. package/dist/core/scene/notifier.js.map +1 -1
  607. package/dist/core/scene/opTable.js +42 -36
  608. package/dist/core/scene/opTable.js.map +1 -1
  609. package/dist/core/scene/outerOps.js +49 -43
  610. package/dist/core/scene/outerOps.js.map +1 -1
  611. package/dist/core/scene/pathEffects/blend.js +80 -0
  612. package/dist/core/scene/pathEffects/blend.js.map +1 -0
  613. package/dist/core/scene/pathEffects/derive.js +112 -0
  614. package/dist/core/scene/pathEffects/derive.js.map +1 -0
  615. package/dist/core/scene/pathEffects/effects.js +40 -0
  616. package/dist/core/scene/pathEffects/effects.js.map +1 -0
  617. package/dist/core/scene/poseFeed.js +95 -60
  618. package/dist/core/scene/poseFeed.js.map +1 -1
  619. package/dist/core/scene/poseHold.js +33 -24
  620. package/dist/core/scene/poseHold.js.map +1 -1
  621. package/dist/core/scene/poseOverrides.js +86 -49
  622. package/dist/core/scene/poseOverrides.js.map +1 -1
  623. package/dist/core/scene/poseRemovals.js +58 -0
  624. package/dist/core/scene/poseRemovals.js.map +1 -0
  625. package/dist/core/scene/poseSnapshot.js +62 -41
  626. package/dist/core/scene/poseSnapshot.js.map +1 -1
  627. package/dist/core/scene/poseWrites.js +151 -0
  628. package/dist/core/scene/poseWrites.js.map +1 -0
  629. package/dist/core/scene/reconcileSpecs.js +63 -34
  630. package/dist/core/scene/reconcileSpecs.js.map +1 -1
  631. package/dist/core/scene/recorder.js +90 -57
  632. package/dist/core/scene/recorder.js.map +1 -1
  633. package/dist/core/scene/renderOrder.js +105 -59
  634. package/dist/core/scene/renderOrder.js.map +1 -1
  635. package/dist/core/scene/scene.js +133 -80
  636. package/dist/core/scene/scene.js.map +1 -1
  637. package/dist/core/scene/sceneEdits.js +62 -49
  638. package/dist/core/scene/sceneEdits.js.map +1 -1
  639. package/dist/core/scene/sceneMutators.js +44 -36
  640. package/dist/core/scene/sceneMutators.js.map +1 -1
  641. package/dist/core/scene/scenePoseAdapter.js +13 -9
  642. package/dist/core/scene/scenePoseAdapter.js.map +1 -1
  643. package/dist/core/scene/sceneRecording.js +89 -73
  644. package/dist/core/scene/sceneRecording.js.map +1 -1
  645. package/dist/core/scene/sceneSelection.js +23 -16
  646. package/dist/core/scene/sceneSelection.js.map +1 -1
  647. package/dist/core/scene/sceneState.js +54 -36
  648. package/dist/core/scene/sceneState.js.map +1 -1
  649. package/dist/core/scene/serialization.js +87 -50
  650. package/dist/core/scene/serialization.js.map +1 -1
  651. package/dist/core/scene/staleReplay.js +35 -26
  652. package/dist/core/scene/staleReplay.js.map +1 -1
  653. package/dist/core/scene/statedFields.js +10 -5
  654. package/dist/core/scene/statedFields.js.map +1 -1
  655. package/dist/core/scene/treeEdits.js +129 -98
  656. package/dist/core/scene/treeEdits.js.map +1 -1
  657. package/dist/core/scene/treeOrder.js +13 -8
  658. package/dist/core/scene/treeOrder.js.map +1 -1
  659. package/dist/core/scene/treeReads.js +25 -16
  660. package/dist/core/scene/treeReads.js.map +1 -1
  661. package/dist/core/scene/types.js +4 -3
  662. package/dist/core/scene/types.js.map +1 -1
  663. package/dist/core/scene/unionOfChildren.js +20 -10
  664. package/dist/core/scene/unionOfChildren.js.map +1 -1
  665. package/dist/core/scene/unitScopes.js +15 -8
  666. package/dist/core/scene/unitScopes.js.map +1 -1
  667. package/dist/core/scene/useScene.js +32 -24
  668. package/dist/core/scene/useScene.js.map +1 -1
  669. package/dist/core/selection/chromeState.js +41 -17
  670. package/dist/core/selection/chromeState.js.map +1 -1
  671. package/dist/core/selection/readOnlySelection.js +39 -24
  672. package/dist/core/selection/readOnlySelection.js.map +1 -1
  673. package/dist/core/selection/selectionTarget.js +14 -3
  674. package/dist/core/selection/selectionTarget.js.map +1 -1
  675. package/dist/core/selection/usePublishSceneSelection.js +25 -18
  676. package/dist/core/selection/usePublishSceneSelection.js.map +1 -1
  677. package/dist/core/selection/useSelection.js +90 -57
  678. package/dist/core/selection/useSelection.js.map +1 -1
  679. package/dist/core/shapeKinds.js +43 -28
  680. package/dist/core/shapeKinds.js.map +1 -1
  681. package/dist/core/stableStringify.js +5 -4
  682. package/dist/core/stableStringify.js.map +1 -1
  683. package/dist/core/stylus/stylus.js +49 -25
  684. package/dist/core/stylus/stylus.js.map +1 -1
  685. package/dist/core/stylus/usePointerStylus.js +61 -34
  686. package/dist/core/stylus/usePointerStylus.js.map +1 -1
  687. package/dist/core/usePaintKinds.js +21 -11
  688. package/dist/core/usePaintKinds.js.map +1 -1
  689. package/dist/core/viewport/clampView.js +31 -15
  690. package/dist/core/viewport/clampView.js.map +1 -1
  691. package/dist/core/viewport/clientToWorld.js +15 -4
  692. package/dist/core/viewport/clientToWorld.js.map +1 -1
  693. package/dist/core/viewport/createVelocityTracker.js +23 -19
  694. package/dist/core/viewport/createVelocityTracker.js.map +1 -1
  695. package/dist/core/viewport/fitToBounds.js +28 -11
  696. package/dist/core/viewport/fitToBounds.js.map +1 -1
  697. package/dist/core/viewport/fitViewToBounds.js +45 -19
  698. package/dist/core/viewport/fitViewToBounds.js.map +1 -1
  699. package/dist/core/viewport/interpolateView.js +40 -20
  700. package/dist/core/viewport/interpolateView.js.map +1 -1
  701. package/dist/core/viewport/parallax.js +89 -56
  702. package/dist/core/viewport/parallax.js.map +1 -1
  703. package/dist/core/viewport/sceneNodeClientRect.js +21 -12
  704. package/dist/core/viewport/sceneNodeClientRect.js.map +1 -1
  705. package/dist/core/viewport/screenSlop.js +40 -17
  706. package/dist/core/viewport/screenSlop.js.map +1 -1
  707. package/dist/core/viewport/useAutoCenter.js +36 -22
  708. package/dist/core/viewport/useAutoCenter.js.map +1 -1
  709. package/dist/core/viewport/useCanvasSize.js +43 -22
  710. package/dist/core/viewport/useCanvasSize.js.map +1 -1
  711. package/dist/core/viewport/useDecayLoop.js +120 -48
  712. package/dist/core/viewport/useDecayLoop.js.map +1 -1
  713. package/dist/core/viewport/useNodeOverlayFrame.js +93 -58
  714. package/dist/core/viewport/useNodeOverlayFrame.js.map +1 -1
  715. package/dist/core/viewport/useVelocityTracker.js +9 -6
  716. package/dist/core/viewport/useVelocityTracker.js.map +1 -1
  717. package/dist/core/viewport/useViewAnimation.js +143 -84
  718. package/dist/core/viewport/useViewAnimation.js.map +1 -1
  719. package/dist/core/viewport/view.js +48 -24
  720. package/dist/core/viewport/view.js.map +1 -1
  721. package/dist/core/viewport/viewTransform.js +8 -6
  722. package/dist/core/viewport/viewTransform.js.map +1 -1
  723. package/dist/core/viewport/viewportWorldRect.js +15 -7
  724. package/dist/core/viewport/viewportWorldRect.js.map +1 -1
  725. package/dist/core/viewport/wheelHandler.js +31 -20
  726. package/dist/core/viewport/wheelHandler.js.map +1 -1
  727. package/dist/core/viewport/zoomAt.js +47 -19
  728. package/dist/core/viewport/zoomAt.js.map +1 -1
  729. package/dist/core/viewport/zoomBounds.js +33 -17
  730. package/dist/core/viewport/zoomBounds.js.map +1 -1
  731. package/dist/cornerHandles-Camw_yeu.d.ts +169 -0
  732. package/dist/debug/createDebugOverlayLayer.js +303 -215
  733. package/dist/debug/createDebugOverlayLayer.js.map +1 -1
  734. package/dist/debug/createDebugSink.js +68 -47
  735. package/dist/debug/createDebugSink.js.map +1 -1
  736. package/dist/debug/defaultTheme.js +16 -4
  737. package/dist/debug/defaultTheme.js.map +1 -1
  738. package/dist/debug/flag.js +3 -2
  739. package/dist/debug/frameStats.js +11 -9
  740. package/dist/debug/frameStats.js.map +1 -1
  741. package/dist/debug/parseDebugFlags.js +25 -17
  742. package/dist/debug/parseDebugFlags.js.map +1 -1
  743. package/dist/debug/useDebugSink.js +52 -33
  744. package/dist/debug/useDebugSink.js.map +1 -1
  745. package/dist/depSchema-Cgfu_G9s.d.ts +3581 -0
  746. package/dist/features/chrome-caps/buildChromeCtx.js +12 -10
  747. package/dist/features/chrome-caps/buildChromeCtx.js.map +1 -1
  748. package/dist/features/chrome-caps/conditions.js +103 -25
  749. package/dist/features/chrome-caps/conditions.js.map +1 -1
  750. package/dist/features/chrome-caps/defaults.js +18 -10
  751. package/dist/features/chrome-caps/defaults.js.map +1 -1
  752. package/dist/features/chrome-caps/index.js +8 -7
  753. package/dist/features/chrome-caps/resolve.js +28 -16
  754. package/dist/features/chrome-caps/resolve.js.map +1 -1
  755. package/dist/features/chrome-caps/useChromeCaps.js +52 -44
  756. package/dist/features/chrome-caps/useChromeCaps.js.map +1 -1
  757. package/dist/features/chrome-caps/useHoverTracking.js +52 -26
  758. package/dist/features/chrome-caps/useHoverTracking.js.map +1 -1
  759. package/dist/features/ingestion/contentHandlers.js +80 -34
  760. package/dist/features/ingestion/contentHandlers.js.map +1 -1
  761. package/dist/features/ingestion/imageHandler.js +49 -29
  762. package/dist/features/ingestion/imageHandler.js.map +1 -1
  763. package/dist/features/ingestion/openFilePicker.js +27 -9
  764. package/dist/features/ingestion/openFilePicker.js.map +1 -1
  765. package/dist/features/ingestion/placement.js +20 -11
  766. package/dist/features/ingestion/placement.js.map +1 -1
  767. package/dist/features/ingestion/registerKitHandlers.js +35 -18
  768. package/dist/features/ingestion/registerKitHandlers.js.map +1 -1
  769. package/dist/features/ingestion/svgHandler.js +60 -34
  770. package/dist/features/ingestion/svgHandler.js.map +1 -1
  771. package/dist/features/ingestion/textHandler.js +37 -16
  772. package/dist/features/ingestion/textHandler.js.map +1 -1
  773. package/dist/features/ingestion/useCanvasIngestion.js +57 -39
  774. package/dist/features/ingestion/useCanvasIngestion.js.map +1 -1
  775. package/dist/features/ingestion/weaselJsonHandler.js +38 -28
  776. package/dist/features/ingestion/weaselJsonHandler.js.map +1 -1
  777. package/dist/features/longPress/longPressFeedback.js +110 -81
  778. package/dist/features/longPress/longPressFeedback.js.map +1 -1
  779. package/dist/features/measure/actionIds.js +22 -0
  780. package/dist/features/measure/actionIds.js.map +1 -0
  781. package/dist/features/measure/measureCommands.js +178 -0
  782. package/dist/features/measure/measureCommands.js.map +1 -0
  783. package/dist/features/measure/measureContribution.js +57 -0
  784. package/dist/features/measure/measureContribution.js.map +1 -0
  785. package/dist/features/measure/measureEdits.js +82 -0
  786. package/dist/features/measure/measureEdits.js.map +1 -0
  787. package/dist/features/measure/measureGestures.js +185 -0
  788. package/dist/features/measure/measureGestures.js.map +1 -0
  789. package/dist/features/measure/measureHit.js +80 -0
  790. package/dist/features/measure/measureHit.js.map +1 -0
  791. package/dist/features/measure/measureLayer.js +86 -0
  792. package/dist/features/measure/measureLayer.js.map +1 -0
  793. package/dist/features/measure/measurement.js +79 -0
  794. package/dist/features/measure/measurement.js.map +1 -0
  795. package/dist/features/measure/measurements.js +41 -0
  796. package/dist/features/measure/measurements.js.map +1 -0
  797. package/dist/features/modes/modeLayers.js +81 -55
  798. package/dist/features/modes/modeLayers.js.map +1 -1
  799. package/dist/features/modes/modeTriggers.js +66 -0
  800. package/dist/features/modes/modeTriggers.js.map +1 -0
  801. package/dist/features/pathEffects/index.js +35 -0
  802. package/dist/features/pathEffects/index.js.map +1 -0
  803. package/dist/features/pathEffects/readSource.js +46 -0
  804. package/dist/features/pathEffects/readSource.js.map +1 -0
  805. package/dist/features/paths/anchorData.js +65 -0
  806. package/dist/features/paths/anchorData.js.map +1 -0
  807. package/dist/features/paths/anchorMarkers.js +137 -0
  808. package/dist/features/paths/anchorMarkers.js.map +1 -0
  809. package/dist/features/paths/editablePath.js +149 -46
  810. package/dist/features/paths/editablePath.js.map +1 -1
  811. package/dist/features/paths/index.js +12 -9
  812. package/dist/features/paths/originProjection.js +16 -9
  813. package/dist/features/paths/originProjection.js.map +1 -1
  814. package/dist/features/paths/pathEditExtension.js +26 -0
  815. package/dist/features/paths/pathEditExtension.js.map +1 -0
  816. package/dist/features/paths/pathEditState.js +107 -26
  817. package/dist/features/paths/pathEditState.js.map +1 -1
  818. package/dist/features/paths/pathEditingOverlayLayer.js +58 -110
  819. package/dist/features/paths/pathEditingOverlayLayer.js.map +1 -1
  820. package/dist/features/paths/pathLayer.js +79 -29
  821. package/dist/features/paths/pathLayer.js.map +1 -1
  822. package/dist/features/paths/pathRepresentation.js +27 -0
  823. package/dist/features/paths/pathRepresentation.js.map +1 -0
  824. package/dist/features/paths/pathSnap/glyphs.js +39 -0
  825. package/dist/features/paths/pathSnap/glyphs.js.map +1 -0
  826. package/dist/features/paths/pathSnap/pathSnapSource.js +82 -0
  827. package/dist/features/paths/pathSnap/pathSnapSource.js.map +1 -0
  828. package/dist/features/paths/pathSnap/sceneIndex.js +78 -0
  829. package/dist/features/paths/pathSnap/sceneIndex.js.map +1 -0
  830. package/dist/features/paths/pathSnap/snapGeometry.js +47 -0
  831. package/dist/features/paths/pathSnap/snapGeometry.js.map +1 -0
  832. package/dist/features/paths/penPreviewLayer.js +135 -102
  833. package/dist/features/paths/penPreviewLayer.js.map +1 -1
  834. package/dist/features/paths/shapeGenerator.js +112 -60
  835. package/dist/features/paths/shapeGenerator.js.map +1 -1
  836. package/dist/features/paths/strokeOutline.js +15 -0
  837. package/dist/features/paths/strokeOutline.js.map +1 -0
  838. package/dist/features/paths/useAnchorFields.js +35 -0
  839. package/dist/features/paths/useAnchorFields.js.map +1 -0
  840. package/dist/features/paths/usePathEdit.js +58 -28
  841. package/dist/features/paths/usePathEdit.js.map +1 -1
  842. package/dist/features/poseRun/usePoseRun.js +110 -43
  843. package/dist/features/poseRun/usePoseRun.js.map +1 -1
  844. package/dist/features/selection/handleCommands.js +116 -0
  845. package/dist/features/selection/handleCommands.js.map +1 -0
  846. package/dist/features/selection/overlay.js +288 -328
  847. package/dist/features/selection/overlay.js.map +1 -1
  848. package/dist/features/selection/selectionPose.js +109 -0
  849. package/dist/features/selection/selectionPose.js.map +1 -0
  850. package/dist/features/snap/angle2d.js +158 -0
  851. package/dist/features/snap/angle2d.js.map +1 -0
  852. package/dist/features/snap/debugCandidates.js +27 -0
  853. package/dist/features/snap/debugCandidates.js.map +1 -0
  854. package/dist/features/snap/gather.js +71 -0
  855. package/dist/features/snap/gather.js.map +1 -0
  856. package/dist/features/snap/inputSubspace.js +46 -0
  857. package/dist/features/snap/inputSubspace.js.map +1 -0
  858. package/dist/features/snap/marks.js +29 -0
  859. package/dist/features/snap/marks.js.map +1 -0
  860. package/dist/features/snap/outcomeStore.js +25 -0
  861. package/dist/features/snap/outcomeStore.js.map +1 -0
  862. package/dist/features/snap/pointSnap.js +48 -0
  863. package/dist/features/snap/pointSnap.js.map +1 -0
  864. package/dist/features/snap/probes2d.js +91 -0
  865. package/dist/features/snap/probes2d.js.map +1 -0
  866. package/dist/features/snap/readoutDraw.js +93 -0
  867. package/dist/features/snap/readoutDraw.js.map +1 -0
  868. package/dist/features/snap/readoutLayer.js +49 -0
  869. package/dist/features/snap/readoutLayer.js.map +1 -0
  870. package/dist/features/snap/registry.js +27 -0
  871. package/dist/features/snap/registry.js.map +1 -0
  872. package/dist/features/snap/resizeBox.js +137 -0
  873. package/dist/features/snap/resizeBox.js.map +1 -0
  874. package/dist/features/snap/roles.js +31 -0
  875. package/dist/features/snap/roles.js.map +1 -0
  876. package/dist/features/snap/rotationSource.js +30 -0
  877. package/dist/features/snap/rotationSource.js.map +1 -0
  878. package/dist/features/snap/sceneReads.js +45 -0
  879. package/dist/features/snap/sceneReads.js.map +1 -0
  880. package/dist/features/snap/sceneSession2d.js +79 -0
  881. package/dist/features/snap/sceneSession2d.js.map +1 -0
  882. package/dist/features/snap/screen.js +23 -0
  883. package/dist/features/snap/screen.js.map +1 -0
  884. package/dist/features/snap/session2d.js +129 -0
  885. package/dist/features/snap/session2d.js.map +1 -0
  886. package/dist/features/snap/spanSnap.js +77 -0
  887. package/dist/features/snap/spanSnap.js.map +1 -0
  888. package/dist/features/snap/stepAngles.js +15 -0
  889. package/dist/features/snap/stepAngles.js.map +1 -0
  890. package/dist/features/text/editingDrawOne.js +32 -0
  891. package/dist/features/text/editingDrawOne.js.map +1 -0
  892. package/dist/features/text/index.js +7 -6
  893. package/dist/features/text/textHitAt.js +51 -0
  894. package/dist/features/text/textHitAt.js.map +1 -0
  895. package/dist/features/text/textLayer.js +21 -27
  896. package/dist/features/text/textLayer.js.map +1 -1
  897. package/dist/features/text/useSceneTextEdit.js +190 -128
  898. package/dist/features/text/useSceneTextEdit.js.map +1 -1
  899. package/dist/features/viewports/viewResolver.js +48 -39
  900. package/dist/features/viewports/viewResolver.js.map +1 -1
  901. package/dist/features/viewports/viewportLayer.js +60 -29
  902. package/dist/features/viewports/viewportLayer.js.map +1 -1
  903. package/dist/iconRegistry/IconRegistryProvider.js +73 -0
  904. package/dist/iconRegistry/IconRegistryProvider.js.map +1 -0
  905. package/dist/iconRegistry/useIconGlyph.js +14 -0
  906. package/dist/iconRegistry/useIconGlyph.js.map +1 -0
  907. package/dist/iconRegistry/useIconVariant.js +29 -0
  908. package/dist/iconRegistry/useIconVariant.js.map +1 -0
  909. package/dist/icons.d.ts +6 -0
  910. package/dist/icons.js +3 -0
  911. package/dist/icons.table.js +13 -0
  912. package/dist/icons.table.js.map +1 -0
  913. package/dist/icons.table.json +556 -0
  914. package/dist/icons2.table.js +9 -0
  915. package/dist/icons2.table.js.map +1 -0
  916. package/dist/index.d.ts +4259 -5074
  917. package/dist/index.js +340 -285
  918. package/dist/input/keyState.js +118 -54
  919. package/dist/input/keyState.js.map +1 -1
  920. package/dist/input/useKeyModifiers.js +13 -7
  921. package/dist/input/useKeyModifiers.js.map +1 -1
  922. package/dist/input/useKeyState.js +23 -16
  923. package/dist/input/useKeyState.js.map +1 -1
  924. package/dist/interactions/actions/align/action.js +76 -45
  925. package/dist/interactions/actions/align/action.js.map +1 -1
  926. package/dist/interactions/actions/align/align.js +86 -48
  927. package/dist/interactions/actions/align/align.js.map +1 -1
  928. package/dist/interactions/actions/booleans/action.js +67 -33
  929. package/dist/interactions/actions/booleans/action.js.map +1 -1
  930. package/dist/interactions/actions/booleans/booleans.js +77 -70
  931. package/dist/interactions/actions/booleans/booleans.js.map +1 -1
  932. package/dist/interactions/actions/booleans/commit.js +49 -0
  933. package/dist/interactions/actions/booleans/commit.js.map +1 -0
  934. package/dist/interactions/actions/booleans/custom.js +48 -0
  935. package/dist/interactions/actions/booleans/custom.js.map +1 -0
  936. package/dist/interactions/actions/booleans/operands.js +43 -32
  937. package/dist/interactions/actions/booleans/operands.js.map +1 -1
  938. package/dist/interactions/actions/booleans/pieces.js +29 -23
  939. package/dist/interactions/actions/booleans/pieces.js.map +1 -1
  940. package/dist/interactions/actions/booleans/placement.js +30 -17
  941. package/dist/interactions/actions/booleans/placement.js.map +1 -1
  942. package/dist/interactions/actions/booleans/useBooleans.js +30 -17
  943. package/dist/interactions/actions/booleans/useBooleans.js.map +1 -1
  944. package/dist/interactions/actions/booleans/useBooleansAdapter.js +8 -5
  945. package/dist/interactions/actions/booleans/useBooleansAdapter.js.map +1 -1
  946. package/dist/interactions/actions/clipboard/action.js +81 -40
  947. package/dist/interactions/actions/clipboard/action.js.map +1 -1
  948. package/dist/interactions/actions/clipboard/clipboardOps.js +100 -72
  949. package/dist/interactions/actions/clipboard/clipboardOps.js.map +1 -1
  950. package/dist/interactions/actions/clipboard/materializePaste.js +38 -19
  951. package/dist/interactions/actions/clipboard/materializePaste.js.map +1 -1
  952. package/dist/interactions/actions/clipboard/wireFormat.js +66 -28
  953. package/dist/interactions/actions/clipboard/wireFormat.js.map +1 -1
  954. package/dist/interactions/actions/clone/action.js +102 -70
  955. package/dist/interactions/actions/clone/action.js.map +1 -1
  956. package/dist/interactions/actions/clone/behaviors.js +55 -38
  957. package/dist/interactions/actions/clone/behaviors.js.map +1 -1
  958. package/dist/interactions/actions/defaultCommitAdapter.js +32 -10
  959. package/dist/interactions/actions/defaultCommitAdapter.js.map +1 -1
  960. package/dist/interactions/actions/defaults/anchorEditing.js +252 -111
  961. package/dist/interactions/actions/defaults/anchorEditing.js.map +1 -1
  962. package/dist/interactions/actions/defaults/anchorFields.js +54 -0
  963. package/dist/interactions/actions/defaults/anchorFields.js.map +1 -0
  964. package/dist/interactions/actions/defaults/anchorHandles.js +31 -27
  965. package/dist/interactions/actions/defaults/anchorHandles.js.map +1 -1
  966. package/dist/interactions/actions/defaults/anchorJoin.js +55 -37
  967. package/dist/interactions/actions/defaults/anchorJoin.js.map +1 -1
  968. package/dist/interactions/actions/defaults/areaSelect.js +56 -40
  969. package/dist/interactions/actions/defaults/areaSelect.js.map +1 -1
  970. package/dist/interactions/actions/defaults/bendSegment.js +67 -31
  971. package/dist/interactions/actions/defaults/bendSegment.js.map +1 -1
  972. package/dist/interactions/actions/defaults/cancelGesture.js +12 -5
  973. package/dist/interactions/actions/defaults/cancelGesture.js.map +1 -1
  974. package/dist/interactions/actions/defaults/clearSelection.js +22 -7
  975. package/dist/interactions/actions/defaults/clearSelection.js.map +1 -1
  976. package/dist/interactions/actions/defaults/contextMenu.js +149 -0
  977. package/dist/interactions/actions/defaults/contextMenu.js.map +1 -0
  978. package/dist/interactions/actions/defaults/copySubtree.js +43 -29
  979. package/dist/interactions/actions/defaults/copySubtree.js.map +1 -1
  980. package/dist/interactions/actions/defaults/createPaintAction.js +79 -54
  981. package/dist/interactions/actions/defaults/createPaintAction.js.map +1 -1
  982. package/dist/interactions/actions/defaults/delete.js +61 -33
  983. package/dist/interactions/actions/defaults/delete.js.map +1 -1
  984. package/dist/interactions/actions/defaults/duplicate.js +60 -32
  985. package/dist/interactions/actions/defaults/duplicate.js.map +1 -1
  986. package/dist/interactions/actions/defaults/enterPathEdit.js +22 -18
  987. package/dist/interactions/actions/defaults/enterPathEdit.js.map +1 -1
  988. package/dist/interactions/actions/defaults/enterTextEdit.js +20 -8
  989. package/dist/interactions/actions/defaults/enterTextEdit.js.map +1 -1
  990. package/dist/interactions/actions/defaults/escape.js +16 -7
  991. package/dist/interactions/actions/defaults/escape.js.map +1 -1
  992. package/dist/interactions/actions/defaults/exitPathEdit.js +6 -6
  993. package/dist/interactions/actions/defaults/exitPathEdit.js.map +1 -1
  994. package/dist/interactions/actions/defaults/group.js +122 -73
  995. package/dist/interactions/actions/defaults/group.js.map +1 -1
  996. package/dist/interactions/actions/defaults/ingest.js +52 -35
  997. package/dist/interactions/actions/defaults/ingest.js.map +1 -1
  998. package/dist/interactions/actions/defaults/insertPathAnchor.js +43 -22
  999. package/dist/interactions/actions/defaults/insertPathAnchor.js.map +1 -1
  1000. package/dist/interactions/actions/defaults/nudge.js +79 -52
  1001. package/dist/interactions/actions/defaults/nudge.js.map +1 -1
  1002. package/dist/interactions/actions/defaults/nudgeSteps.js +17 -12
  1003. package/dist/interactions/actions/defaults/nudgeSteps.js.map +1 -1
  1004. package/dist/interactions/actions/defaults/pathEditMarks.js +60 -0
  1005. package/dist/interactions/actions/defaults/pathEditMarks.js.map +1 -0
  1006. package/dist/interactions/actions/defaults/pathEditTools.js +57 -0
  1007. package/dist/interactions/actions/defaults/pathEditTools.js.map +1 -0
  1008. package/dist/interactions/actions/defaults/pinchZoom.js +55 -39
  1009. package/dist/interactions/actions/defaults/pinchZoom.js.map +1 -1
  1010. package/dist/interactions/actions/defaults/reorder.js +71 -40
  1011. package/dist/interactions/actions/defaults/reorder.js.map +1 -1
  1012. package/dist/interactions/actions/defaults/requiresSelection.js +13 -6
  1013. package/dist/interactions/actions/defaults/requiresSelection.js.map +1 -1
  1014. package/dist/interactions/actions/defaults/segmentUnder.js +24 -16
  1015. package/dist/interactions/actions/defaults/segmentUnder.js.map +1 -1
  1016. package/dist/interactions/actions/defaults/selectAll.js +21 -7
  1017. package/dist/interactions/actions/defaults/selectAll.js.map +1 -1
  1018. package/dist/interactions/actions/defaults/setFill.js +37 -21
  1019. package/dist/interactions/actions/defaults/setFill.js.map +1 -1
  1020. package/dist/interactions/actions/defaults/setFillOpacity.js +19 -10
  1021. package/dist/interactions/actions/defaults/setFillOpacity.js.map +1 -1
  1022. package/dist/interactions/actions/defaults/setStroke.js +46 -25
  1023. package/dist/interactions/actions/defaults/setStroke.js.map +1 -1
  1024. package/dist/interactions/actions/defaults/setStrokeOpacity.js +19 -11
  1025. package/dist/interactions/actions/defaults/setStrokeOpacity.js.map +1 -1
  1026. package/dist/interactions/actions/defaults/slice.js +42 -17
  1027. package/dist/interactions/actions/defaults/slice.js.map +1 -1
  1028. package/dist/interactions/actions/defaults/sliceOps.js +63 -42
  1029. package/dist/interactions/actions/defaults/sliceOps.js.map +1 -1
  1030. package/dist/interactions/actions/defaults/toolActivate.js +34 -16
  1031. package/dist/interactions/actions/defaults/toolActivate.js.map +1 -1
  1032. package/dist/interactions/actions/defaults/toolResetToDefault.js +29 -10
  1033. package/dist/interactions/actions/defaults/toolResetToDefault.js.map +1 -1
  1034. package/dist/interactions/actions/defaults/undoRedo.js +26 -20
  1035. package/dist/interactions/actions/defaults/undoRedo.js.map +1 -1
  1036. package/dist/interactions/actions/defaults/viewportDragPan.js +91 -58
  1037. package/dist/interactions/actions/defaults/viewportDragPan.js.map +1 -1
  1038. package/dist/interactions/actions/defaults/viewportWheelPan.js +42 -23
  1039. package/dist/interactions/actions/defaults/viewportWheelPan.js.map +1 -1
  1040. package/dist/interactions/actions/defaults/viewportZoom.js +107 -59
  1041. package/dist/interactions/actions/defaults/viewportZoom.js.map +1 -1
  1042. package/dist/interactions/actions/distribute/action.js +62 -39
  1043. package/dist/interactions/actions/distribute/action.js.map +1 -1
  1044. package/dist/interactions/actions/distribute/distribute.js +53 -34
  1045. package/dist/interactions/actions/distribute/distribute.js.map +1 -1
  1046. package/dist/interactions/actions/distribute/plan.js +40 -22
  1047. package/dist/interactions/actions/distribute/plan.js.map +1 -1
  1048. package/dist/interactions/actions/drawnBoxes.js +31 -0
  1049. package/dist/interactions/actions/drawnBoxes.js.map +1 -0
  1050. package/dist/interactions/actions/edit-anchors/action.js +248 -72
  1051. package/dist/interactions/actions/edit-anchors/action.js.map +1 -1
  1052. package/dist/interactions/actions/edit-anchors/extensionDrags.js +50 -0
  1053. package/dist/interactions/actions/edit-anchors/extensionDrags.js.map +1 -0
  1054. package/dist/interactions/actions/edit-anchors/geometry.js +74 -47
  1055. package/dist/interactions/actions/edit-anchors/geometry.js.map +1 -1
  1056. package/dist/interactions/actions/edit-anchors/handleDrag.js +101 -0
  1057. package/dist/interactions/actions/edit-anchors/handleDrag.js.map +1 -0
  1058. package/dist/interactions/actions/edit-anchors/handles.js +41 -27
  1059. package/dist/interactions/actions/edit-anchors/handles.js.map +1 -1
  1060. package/dist/interactions/actions/edit-anchors/params.js +12 -0
  1061. package/dist/interactions/actions/edit-anchors/params.js.map +1 -0
  1062. package/dist/interactions/actions/edit-anchors/preview.js +61 -19
  1063. package/dist/interactions/actions/edit-anchors/preview.js.map +1 -1
  1064. package/dist/interactions/actions/edit-anchors/symmetry.js +12 -7
  1065. package/dist/interactions/actions/edit-anchors/symmetry.js.map +1 -1
  1066. package/dist/interactions/actions/flip/action.js +119 -61
  1067. package/dist/interactions/actions/flip/action.js.map +1 -1
  1068. package/dist/interactions/actions/flip/helpers.js +69 -36
  1069. package/dist/interactions/actions/flip/helpers.js.map +1 -1
  1070. package/dist/interactions/actions/geometryProjection.js +17 -12
  1071. package/dist/interactions/actions/geometryProjection.js.map +1 -1
  1072. package/dist/interactions/actions/gestureFrames.js +20 -11
  1073. package/dist/interactions/actions/gestureFrames.js.map +1 -1
  1074. package/dist/interactions/actions/gestureLifecycle.js +93 -48
  1075. package/dist/interactions/actions/gestureLifecycle.js.map +1 -1
  1076. package/dist/interactions/actions/hitSelection.js +6 -4
  1077. package/dist/interactions/actions/hitSelection.js.map +1 -1
  1078. package/dist/interactions/actions/insert/action.js +71 -42
  1079. package/dist/interactions/actions/insert/action.js.map +1 -1
  1080. package/dist/interactions/actions/insert/commit.js +44 -22
  1081. package/dist/interactions/actions/insert/commit.js.map +1 -1
  1082. package/dist/interactions/actions/insert/extras.js +60 -38
  1083. package/dist/interactions/actions/insert/extras.js.map +1 -1
  1084. package/dist/interactions/actions/insert/frame.js +58 -39
  1085. package/dist/interactions/actions/insert/frame.js.map +1 -1
  1086. package/dist/interactions/actions/insert/geometry.js +29 -25
  1087. package/dist/interactions/actions/insert/geometry.js.map +1 -1
  1088. package/dist/interactions/actions/insert/placeAction.js +108 -0
  1089. package/dist/interactions/actions/insert/placeAction.js.map +1 -0
  1090. package/dist/interactions/actions/insert/repositionAction.js +26 -11
  1091. package/dist/interactions/actions/insert/repositionAction.js.map +1 -1
  1092. package/dist/interactions/actions/insert/rotateAction.js +19 -8
  1093. package/dist/interactions/actions/insert/rotateAction.js.map +1 -1
  1094. package/dist/interactions/actions/insert/session.js +57 -41
  1095. package/dist/interactions/actions/insert/session.js.map +1 -1
  1096. package/dist/interactions/actions/insert/shape.js +83 -25
  1097. package/dist/interactions/actions/insert/shape.js.map +1 -1
  1098. package/dist/interactions/actions/lasso-select/action.js +160 -100
  1099. package/dist/interactions/actions/lasso-select/action.js.map +1 -1
  1100. package/dist/interactions/actions/lasso-select/behaviors/selectFromLasso.js +44 -25
  1101. package/dist/interactions/actions/lasso-select/behaviors/selectFromLasso.js.map +1 -1
  1102. package/dist/interactions/actions/move/action.js +87 -52
  1103. package/dist/interactions/actions/move/action.js.map +1 -1
  1104. package/dist/interactions/actions/move/behaviors/layoutDrop.js +56 -36
  1105. package/dist/interactions/actions/move/behaviors/layoutDrop.js.map +1 -1
  1106. package/dist/interactions/actions/move/behaviors/reparentOnDrop.js +20 -10
  1107. package/dist/interactions/actions/move/behaviors/reparentOnDrop.js.map +1 -1
  1108. package/dist/interactions/actions/move/behaviors/snapBackOrDelete.js +40 -24
  1109. package/dist/interactions/actions/move/behaviors/snapBackOrDelete.js.map +1 -1
  1110. package/dist/interactions/actions/move/behaviors/snapToContainer.js +102 -64
  1111. package/dist/interactions/actions/move/behaviors/snapToContainer.js.map +1 -1
  1112. package/dist/interactions/actions/move/capture.js +103 -78
  1113. package/dist/interactions/actions/move/capture.js.map +1 -1
  1114. package/dist/interactions/actions/move/commit/index.js +43 -34
  1115. package/dist/interactions/actions/move/commit/index.js.map +1 -1
  1116. package/dist/interactions/actions/move/commit/layoutDrop.js +43 -32
  1117. package/dist/interactions/actions/move/commit/layoutDrop.js.map +1 -1
  1118. package/dist/interactions/actions/move/commit/layoutRelease.js +97 -77
  1119. package/dist/interactions/actions/move/commit/layoutRelease.js.map +1 -1
  1120. package/dist/interactions/actions/move/commit/rebase.js +16 -13
  1121. package/dist/interactions/actions/move/commit/rebase.js.map +1 -1
  1122. package/dist/interactions/actions/move/commit/reparent.js +83 -57
  1123. package/dist/interactions/actions/move/commit/reparent.js.map +1 -1
  1124. package/dist/interactions/actions/move/delta.js +58 -36
  1125. package/dist/interactions/actions/move/delta.js.map +1 -1
  1126. package/dist/interactions/actions/move/frame.js +72 -35
  1127. package/dist/interactions/actions/move/frame.js.map +1 -1
  1128. package/dist/interactions/actions/move/gestureAdapter.js +30 -20
  1129. package/dist/interactions/actions/move/gestureAdapter.js.map +1 -1
  1130. package/dist/interactions/actions/move/landedDescendants.js +40 -25
  1131. package/dist/interactions/actions/move/landedDescendants.js.map +1 -1
  1132. package/dist/interactions/actions/move/layout/container.js +92 -72
  1133. package/dist/interactions/actions/move/layout/container.js.map +1 -1
  1134. package/dist/interactions/actions/move/layout/dragged.js +61 -39
  1135. package/dist/interactions/actions/move/layout/dragged.js.map +1 -1
  1136. package/dist/interactions/actions/move/layout/dropPass.js +136 -94
  1137. package/dist/interactions/actions/move/layout/dropPass.js.map +1 -1
  1138. package/dist/interactions/actions/move/layout/exits.js +58 -30
  1139. package/dist/interactions/actions/move/layout/exits.js.map +1 -1
  1140. package/dist/interactions/actions/move/layout/glide.js +55 -34
  1141. package/dist/interactions/actions/move/layout/glide.js.map +1 -1
  1142. package/dist/interactions/actions/move/session.js +85 -56
  1143. package/dist/interactions/actions/move/session.js.map +1 -1
  1144. package/dist/interactions/actions/move/translate.js +58 -43
  1145. package/dist/interactions/actions/move/translate.js.map +1 -1
  1146. package/dist/interactions/actions/outlines/createOutlines.js +28 -20
  1147. package/dist/interactions/actions/outlines/createOutlines.js.map +1 -1
  1148. package/dist/interactions/actions/outlines/createOutlinesAction.js +43 -31
  1149. package/dist/interactions/actions/outlines/createOutlinesAction.js.map +1 -1
  1150. package/dist/interactions/actions/outlines/outlineStroke.js +68 -45
  1151. package/dist/interactions/actions/outlines/outlineStroke.js.map +1 -1
  1152. package/dist/interactions/actions/outlines/outlineStrokeAction.js +24 -19
  1153. package/dist/interactions/actions/outlines/outlineStrokeAction.js.map +1 -1
  1154. package/dist/interactions/actions/outlines/replaceWithPaths.js +57 -42
  1155. package/dist/interactions/actions/outlines/replaceWithPaths.js.map +1 -1
  1156. package/dist/interactions/actions/outlines/strokeRegion.js +37 -22
  1157. package/dist/interactions/actions/outlines/strokeRegion.js.map +1 -1
  1158. package/dist/interactions/actions/outlines/useCreateOutlinesAdapter.js +8 -5
  1159. package/dist/interactions/actions/outlines/useCreateOutlinesAdapter.js.map +1 -1
  1160. package/dist/interactions/actions/pathCommands/cutJoin.js +119 -72
  1161. package/dist/interactions/actions/pathCommands/cutJoin.js.map +1 -1
  1162. package/dist/interactions/actions/pathCommands/livePathEdit.js +74 -40
  1163. package/dist/interactions/actions/pathCommands/livePathEdit.js.map +1 -1
  1164. package/dist/interactions/actions/pathCommands/pathNodes.js +91 -82
  1165. package/dist/interactions/actions/pathCommands/pathNodes.js.map +1 -1
  1166. package/dist/interactions/actions/pathCommands/simplifyOffset.js +52 -28
  1167. package/dist/interactions/actions/pathCommands/simplifyOffset.js.map +1 -1
  1168. package/dist/interactions/actions/pathGestureTags.js +29 -0
  1169. package/dist/interactions/actions/pathGestureTags.js.map +1 -0
  1170. package/dist/interactions/actions/planeInput.js +198 -123
  1171. package/dist/interactions/actions/planeInput.js.map +1 -1
  1172. package/dist/interactions/actions/pointerState.js +12 -7
  1173. package/dist/interactions/actions/pointerState.js.map +1 -1
  1174. package/dist/interactions/actions/poseDescriptorDep.js +24 -14
  1175. package/dist/interactions/actions/poseDescriptorDep.js.map +1 -1
  1176. package/dist/interactions/actions/poseFrame.js +45 -28
  1177. package/dist/interactions/actions/poseFrame.js.map +1 -1
  1178. package/dist/interactions/actions/resize/action.js +68 -39
  1179. package/dist/interactions/actions/resize/action.js.map +1 -1
  1180. package/dist/interactions/actions/resize/aspect.js +44 -0
  1181. package/dist/interactions/actions/resize/aspect.js.map +1 -0
  1182. package/dist/interactions/actions/resize/behaviors/clampMinSize.js +38 -13
  1183. package/dist/interactions/actions/resize/behaviors/clampMinSize.js.map +1 -1
  1184. package/dist/interactions/actions/resize/boxFrame.js +15 -11
  1185. package/dist/interactions/actions/resize/boxFrame.js.map +1 -1
  1186. package/dist/interactions/actions/resize/capture.js +105 -62
  1187. package/dist/interactions/actions/resize/capture.js.map +1 -1
  1188. package/dist/interactions/actions/resize/commit.js +75 -56
  1189. package/dist/interactions/actions/resize/commit.js.map +1 -1
  1190. package/dist/interactions/actions/resize/cornerHandles.js +154 -17
  1191. package/dist/interactions/actions/resize/cornerHandles.js.map +1 -1
  1192. package/dist/interactions/actions/resize/frame.js +133 -66
  1193. package/dist/interactions/actions/resize/frame.js.map +1 -1
  1194. package/dist/interactions/actions/resize/minimum.js +35 -0
  1195. package/dist/interactions/actions/resize/minimum.js.map +1 -0
  1196. package/dist/interactions/actions/resize/replay.js +40 -30
  1197. package/dist/interactions/actions/resize/replay.js.map +1 -1
  1198. package/dist/interactions/actions/resize/ruleBounds.js +8 -5
  1199. package/dist/interactions/actions/resize/ruleBounds.js.map +1 -1
  1200. package/dist/interactions/actions/resize/session.js +95 -50
  1201. package/dist/interactions/actions/resize/session.js.map +1 -1
  1202. package/dist/interactions/actions/resolveOverlays.js +48 -33
  1203. package/dist/interactions/actions/resolveOverlays.js.map +1 -1
  1204. package/dist/interactions/actions/resolvePreviews.js +63 -46
  1205. package/dist/interactions/actions/resolvePreviews.js.map +1 -1
  1206. package/dist/interactions/actions/rotate/action.js +68 -42
  1207. package/dist/interactions/actions/rotate/action.js.map +1 -1
  1208. package/dist/interactions/actions/rotate/commit.js +39 -31
  1209. package/dist/interactions/actions/rotate/commit.js.map +1 -1
  1210. package/dist/interactions/actions/rotate/frame.js +75 -47
  1211. package/dist/interactions/actions/rotate/frame.js.map +1 -1
  1212. package/dist/interactions/actions/rotate/geometry.js +36 -24
  1213. package/dist/interactions/actions/rotate/geometry.js.map +1 -1
  1214. package/dist/interactions/actions/rotate/handle.js +28 -15
  1215. package/dist/interactions/actions/rotate/handle.js.map +1 -1
  1216. package/dist/interactions/actions/rotate/replay.js +22 -18
  1217. package/dist/interactions/actions/rotate/replay.js.map +1 -1
  1218. package/dist/interactions/actions/rotate/session.js +115 -76
  1219. package/dist/interactions/actions/rotate/session.js.map +1 -1
  1220. package/dist/interactions/actions/selectionSubtree.js +124 -53
  1221. package/dist/interactions/actions/selectionSubtree.js.map +1 -1
  1222. package/dist/interactions/actions/spatialReference.js +33 -26
  1223. package/dist/interactions/actions/spatialReference.js.map +1 -1
  1224. package/dist/interactions/actions/testUtils.js +53 -0
  1225. package/dist/interactions/actions/testUtils.js.map +1 -0
  1226. package/dist/interactions/actions/transform-again/action.js +50 -35
  1227. package/dist/interactions/actions/transform-again/action.js.map +1 -1
  1228. package/dist/interactions/actions/transform-again/memory.js +32 -21
  1229. package/dist/interactions/actions/transform-again/memory.js.map +1 -1
  1230. package/dist/interactions/actions/useActionSet.js +83 -0
  1231. package/dist/interactions/actions/useActionSet.js.map +1 -0
  1232. package/dist/interactions/actions/useStandardActions.js +23 -165
  1233. package/dist/interactions/actions/useStandardActions.js.map +1 -1
  1234. package/dist/interactions/gestures/dragGesture/dragGesture.js +109 -68
  1235. package/dist/interactions/gestures/dragGesture/dragGesture.js.map +1 -1
  1236. package/dist/interactions/gestures/dragGesture/dragPointOf.js +17 -10
  1237. package/dist/interactions/gestures/dragGesture/dragPointOf.js.map +1 -1
  1238. package/dist/interactions/gestures/dragRadial/dragRadial.js +129 -93
  1239. package/dist/interactions/gestures/dragRadial/dragRadial.js.map +1 -1
  1240. package/dist/interactions/gestures/dragRect/dragRect.js +155 -111
  1241. package/dist/interactions/gestures/dragRect/dragRect.js.map +1 -1
  1242. package/dist/interactions/gestures/handleDrag/handleDrag.js +52 -30
  1243. package/dist/interactions/gestures/handleDrag/handleDrag.js.map +1 -1
  1244. package/dist/interactions/gestures/pointerDrag/pointerDrag.js +168 -97
  1245. package/dist/interactions/gestures/pointerDrag/pointerDrag.js.map +1 -1
  1246. package/dist/interactions/gestures/shared/originProjection.js +32 -25
  1247. package/dist/interactions/gestures/shared/originProjection.js.map +1 -1
  1248. package/dist/interactions/gestures/shared/screenTolerance.js +26 -17
  1249. package/dist/interactions/gestures/shared/screenTolerance.js.map +1 -1
  1250. package/dist/interactions/gestures/thresholdDrag/thresholdDrag.js +39 -21
  1251. package/dist/interactions/gestures/thresholdDrag/thresholdDrag.js.map +1 -1
  1252. package/dist/kitSettingsSchema.js +80 -0
  1253. package/dist/kitSettingsSchema.js.map +1 -0
  1254. package/dist/{math-CYUjoyyU.d.ts → math-CrJULaZI.d.ts} +5 -6
  1255. package/dist/math.d.ts +4 -5
  1256. package/dist/math.js +7 -6
  1257. package/dist/mesh.js +3 -2
  1258. package/dist/move.d.ts +7 -6
  1259. package/dist/move.js +4 -3
  1260. package/dist/{originProjection-CoNVpITV.d.ts → options-p9GZMXbY.d.ts} +4 -27
  1261. package/dist/originProjection-gY0jb4Wb.d.ts +24 -0
  1262. package/dist/patterns-builtin.js +3 -2
  1263. package/dist/{poseDescriptor-Bqk-11Rl.d.ts → poseDescriptor-DN2yfnq_.d.ts} +7 -7
  1264. package/dist/renderer.d.ts +1 -1
  1265. package/dist/renderer.js +3 -2
  1266. package/dist/resize.d.ts +10 -28
  1267. package/dist/resize.js +6 -7
  1268. package/dist/routing.js +3 -2
  1269. package/dist/style.css +88 -1
  1270. package/dist/test-hook/createTestHook.js +23 -20
  1271. package/dist/test-hook/createTestHook.js.map +1 -1
  1272. package/dist/test-hook/install.js +32 -13
  1273. package/dist/test-hook/install.js.map +1 -1
  1274. package/dist/test-hook/useTestHook.js +22 -16
  1275. package/dist/test-hook/useTestHook.js.map +1 -1
  1276. package/dist/test-seams.d.ts +164 -1
  1277. package/dist/test-seams.js +8 -3
  1278. package/dist/tools/builtin/bone/boneActions.js +96 -70
  1279. package/dist/tools/builtin/bone/boneActions.js.map +1 -1
  1280. package/dist/tools/builtin/bone/boneOverlay.js +49 -36
  1281. package/dist/tools/builtin/bone/boneOverlay.js.map +1 -1
  1282. package/dist/tools/builtin/bone/placedRig.js +18 -14
  1283. package/dist/tools/builtin/bone/placedRig.js.map +1 -1
  1284. package/dist/tools/builtin/bone/rigEditState.js +22 -13
  1285. package/dist/tools/builtin/bone/rigEditState.js.map +1 -1
  1286. package/dist/tools/builtin/bone/useBoneTool.js +68 -41
  1287. package/dist/tools/builtin/bone/useBoneTool.js.map +1 -1
  1288. package/dist/tools/builtin/ellipse/useEllipseTool.js +22 -17
  1289. package/dist/tools/builtin/ellipse/useEllipseTool.js.map +1 -1
  1290. package/dist/tools/builtin/eyedropper/useEyedropperTool.js +44 -28
  1291. package/dist/tools/builtin/eyedropper/useEyedropperTool.js.map +1 -1
  1292. package/dist/tools/builtin/hand/dragPanContribution.js +12 -7
  1293. package/dist/tools/builtin/hand/dragPanContribution.js.map +1 -1
  1294. package/dist/tools/builtin/hand/useHandTool.js +21 -13
  1295. package/dist/tools/builtin/hand/useHandTool.js.map +1 -1
  1296. package/dist/tools/builtin/image/useImageTool.js +28 -19
  1297. package/dist/tools/builtin/image/useImageTool.js.map +1 -1
  1298. package/dist/tools/builtin/lasso/useLassoTool.js +48 -36
  1299. package/dist/tools/builtin/lasso/useLassoTool.js.map +1 -1
  1300. package/dist/tools/builtin/line/useLineTool.js +24 -17
  1301. package/dist/tools/builtin/line/useLineTool.js.map +1 -1
  1302. package/dist/tools/builtin/measure/useMeasureTool.js +84 -0
  1303. package/dist/tools/builtin/measure/useMeasureTool.js.map +1 -0
  1304. package/dist/tools/builtin/pen/penHandle.js +60 -0
  1305. package/dist/tools/builtin/pen/penHandle.js.map +1 -0
  1306. package/dist/tools/builtin/pen/usePenTool.js +461 -303
  1307. package/dist/tools/builtin/pen/usePenTool.js.map +1 -1
  1308. package/dist/tools/builtin/pencil/usePencilTool.js +20 -15
  1309. package/dist/tools/builtin/pencil/usePencilTool.js.map +1 -1
  1310. package/dist/tools/builtin/pickTopMostHit.js +51 -31
  1311. package/dist/tools/builtin/pickTopMostHit.js.map +1 -1
  1312. package/dist/tools/builtin/polygon/usePolygonTool.js +45 -28
  1313. package/dist/tools/builtin/polygon/usePolygonTool.js.map +1 -1
  1314. package/dist/tools/builtin/rect/useRectTool.js +24 -16
  1315. package/dist/tools/builtin/rect/useRectTool.js.map +1 -1
  1316. package/dist/tools/builtin/select/adapterPointQuery.js +47 -30
  1317. package/dist/tools/builtin/select/adapterPointQuery.js.map +1 -1
  1318. package/dist/tools/builtin/select/selectionContributions.js +94 -56
  1319. package/dist/tools/builtin/select/selectionContributions.js.map +1 -1
  1320. package/dist/tools/builtin/select/useSelectTool.js +155 -108
  1321. package/dist/tools/builtin/select/useSelectTool.js.map +1 -1
  1322. package/dist/tools/builtin/shared/insertToolOptions.js +5 -4
  1323. package/dist/tools/builtin/shared/insertToolOptions.js.map +1 -1
  1324. package/dist/tools/builtin/shared/pointerFollower.js +15 -8
  1325. package/dist/tools/builtin/shared/pointerFollower.js.map +1 -1
  1326. package/dist/tools/builtin/slice/useSliceTool.js +148 -101
  1327. package/dist/tools/builtin/slice/useSliceTool.js.map +1 -1
  1328. package/dist/tools/builtin/star/useStarTool.js +48 -31
  1329. package/dist/tools/builtin/star/useStarTool.js.map +1 -1
  1330. package/dist/tools/builtin/sticky/stickyNode.js +49 -0
  1331. package/dist/tools/builtin/sticky/stickyNode.js.map +1 -0
  1332. package/dist/tools/builtin/sticky/useStickyTool.js +86 -0
  1333. package/dist/tools/builtin/sticky/useStickyTool.js.map +1 -0
  1334. package/dist/tools/builtin/text/useTextTool.js +59 -34
  1335. package/dist/tools/builtin/text/useTextTool.js.map +1 -1
  1336. package/dist/tools/builtin/weight/useWeightTool.js +66 -42
  1337. package/dist/tools/builtin/weight/useWeightTool.js.map +1 -1
  1338. package/dist/tools/builtin/weight/weightActions.js +93 -65
  1339. package/dist/tools/builtin/weight/weightActions.js.map +1 -1
  1340. package/dist/tools/builtin/weight/weightOverlay.js +47 -30
  1341. package/dist/tools/builtin/weight/weightOverlay.js.map +1 -1
  1342. package/dist/tools/overlayBinding.js +7 -5
  1343. package/dist/tools/overlayBinding.js.map +1 -1
  1344. package/dist/tools/useKeybindings.js +62 -46
  1345. package/dist/tools/useKeybindings.js.map +1 -1
  1346. package/dist/{types-DBbbCy0i.d.ts → types-CHVXGfYm.d.ts} +5 -5
  1347. package/dist/util/color.js +39 -18
  1348. package/dist/util/color.js.map +1 -1
  1349. package/dist/util/paint.js +93 -38
  1350. package/dist/util/paint.js.map +1 -1
  1351. package/dist/version.js +11 -3
  1352. package/dist/version.js.map +1 -1
  1353. package/package.json +35 -23
  1354. package/dist/canvas/SceneCanvas/GestureDispatcherMounter.js +0 -126
  1355. package/dist/canvas/SceneCanvas/GestureDispatcherMounter.js.map +0 -1
  1356. package/dist/canvas/SceneCanvas/StandardActionsRegistrar.js +0 -55
  1357. package/dist/canvas/SceneCanvas/StandardActionsRegistrar.js.map +0 -1
  1358. package/dist/canvas/SceneCanvas/ToolKeybindingsMounter.js +0 -16
  1359. package/dist/canvas/SceneCanvas/ToolKeybindingsMounter.js.map +0 -1
  1360. package/dist/canvas/SceneCanvas/isDev.js +0 -12
  1361. package/dist/canvas/SceneCanvas/isDev.js.map +0 -1
  1362. package/dist/canvas/SceneCanvas/useViewLayerGate.js +0 -20
  1363. package/dist/canvas/SceneCanvas/useViewLayerGate.js.map +0 -1
  1364. package/dist/cornerHandles-BSKbyuvQ.d.ts +0 -104
  1365. package/dist/icons/ArrowIcon.js +0 -23
  1366. package/dist/icons/ArrowIcon.js.map +0 -1
  1367. package/dist/icons/EllipseIcon.js +0 -21
  1368. package/dist/icons/EllipseIcon.js.map +0 -1
  1369. package/dist/icons/EyedropperIcon.js +0 -49
  1370. package/dist/icons/EyedropperIcon.js.map +0 -1
  1371. package/dist/icons/HandIcon.js +0 -59
  1372. package/dist/icons/HandIcon.js.map +0 -1
  1373. package/dist/icons/ImageIcon.js +0 -34
  1374. package/dist/icons/ImageIcon.js.map +0 -1
  1375. package/dist/icons/LassoIcon.js +0 -22
  1376. package/dist/icons/LassoIcon.js.map +0 -1
  1377. package/dist/icons/LineIcon.js +0 -22
  1378. package/dist/icons/LineIcon.js.map +0 -1
  1379. package/dist/icons/PenIcon.js +0 -36
  1380. package/dist/icons/PenIcon.js.map +0 -1
  1381. package/dist/icons/PencilIcon.js +0 -25
  1382. package/dist/icons/PencilIcon.js.map +0 -1
  1383. package/dist/icons/PolygonIcon.js +0 -19
  1384. package/dist/icons/PolygonIcon.js.map +0 -1
  1385. package/dist/icons/RectIcon.js +0 -37
  1386. package/dist/icons/RectIcon.js.map +0 -1
  1387. package/dist/icons/SelectIcon.js +0 -20
  1388. package/dist/icons/SelectIcon.js.map +0 -1
  1389. package/dist/icons/SliceIcon.js +0 -24
  1390. package/dist/icons/SliceIcon.js.map +0 -1
  1391. package/dist/icons/StarIcon.js +0 -19
  1392. package/dist/icons/StarIcon.js.map +0 -1
  1393. package/dist/icons/TextIcon.js +0 -19
  1394. package/dist/icons/TextIcon.js.map +0 -1
  1395. package/dist/icons/UnknownIcon.js +0 -33
  1396. package/dist/icons/UnknownIcon.js.map +0 -1
  1397. package/dist/icons/_base.js +0 -12
  1398. package/dist/icons/_base.js.map +0 -1
  1399. package/dist/interactions/actions/actionShortcuts.js +0 -32
  1400. package/dist/interactions/actions/actionShortcuts.js.map +0 -1
  1401. package/dist/interactions/actions/defaults/icons/actionGlyphIcons.js +0 -40
  1402. package/dist/interactions/actions/defaults/icons/actionGlyphIcons.js.map +0 -1
  1403. package/dist/interactions/actions/defaults/icons/actionGlyphs.js +0 -10
  1404. package/dist/interactions/actions/defaults/icons/actionGlyphs.js.map +0 -1
  1405. package/dist/interactions/actions/defaults/icons/alignIcons.js +0 -173
  1406. package/dist/interactions/actions/defaults/icons/alignIcons.js.map +0 -1
  1407. package/dist/interactions/actions/defaults/icons/anchorIcons.js +0 -75
  1408. package/dist/interactions/actions/defaults/icons/anchorIcons.js.map +0 -1
  1409. package/dist/interactions/actions/defaults/icons/booleanIcons.js +0 -194
  1410. package/dist/interactions/actions/defaults/icons/booleanIcons.js.map +0 -1
  1411. package/dist/interactions/actions/defaults/icons/distributeIcons.js +0 -63
  1412. package/dist/interactions/actions/defaults/icons/distributeIcons.js.map +0 -1
  1413. package/dist/interactions/actions/defaults/icons/editIcons.js +0 -307
  1414. package/dist/interactions/actions/defaults/icons/editIcons.js.map +0 -1
  1415. package/dist/interactions/actions/defaults/icons/outlineIcons.js +0 -91
  1416. package/dist/interactions/actions/defaults/icons/outlineIcons.js.map +0 -1
  1417. package/dist/interactions/actions/resize/behaviors/index.js +0 -8
  1418. package/dist/interactions/actions/resize/behaviors/index.js.map +0 -1
  1419. package/dist/interactions/actions/resize/behaviors/lockAspect.js +0 -24
  1420. package/dist/interactions/actions/resize/behaviors/lockAspect.js.map +0 -1
  1421. package/dist/interactions/actions/resize/pointSnap.js +0 -111
  1422. package/dist/interactions/actions/resize/pointSnap.js.map +0 -1
  1423. package/dist/interactions/actions/rotate/behaviors/index.js +0 -7
  1424. package/dist/interactions/actions/rotate/behaviors/index.js.map +0 -1
  1425. package/dist/interactions/actions/rotate/behaviors/snapRotation.js +0 -12
  1426. package/dist/interactions/actions/rotate/behaviors/snapRotation.js.map +0 -1
  1427. package/dist/interactions/gestures/shared/snap.js +0 -24
  1428. package/dist/interactions/gestures/shared/snap.js.map +0 -1
  1429. package/dist/test-seams-D0pyV3pR.d.ts +0 -149
  1430. package/dist/util/constrainTo45.js +0 -17
  1431. package/dist/util/constrainTo45.js.map +0 -1
@@ -0,0 +1,3581 @@
1
+ import { TileKind, Paint, GradStop, TilePaint, Fill, Stroke, CommandFill, CommandStroke, CommandPaint } from '@weasel-js/paint';
2
+ import { Reflection } from '@weasel-js/registry';
3
+ import { ComponentType } from 'react';
4
+ import { IconRef } from '@weasel-js/icons';
5
+ import { PaintDrawKind, DrawCommand, Effect, CompositeOp, BlendFactors } from '@weasel-js/renderer';
6
+ import * as _weasel_js_routing_react from '@weasel-js/routing/react';
7
+ import * as _weasel_js_geom from '@weasel-js/geom';
8
+ import { Path, PoseLinear, Affine, FramedBox, View, Rect, Scale2, PolygonPath, PathFillRule, AnchorSet, PointOrigin } from '@weasel-js/geom';
9
+ import * as _weasel_js_history from '@weasel-js/history';
10
+ import { SerializedHistory, Op, History } from '@weasel-js/history';
11
+ import { NodeId, ModifierState, OverlayRole, ResizeAnchor, ActionDeps, OngoingHandle, OngoingOverlay, SelectionApi, IngestItem, Point2, DragSample, DebugSink, LongPressState } from '@weasel-js/routing';
12
+ import { TextNodeSource, TextOutlinesError, TextStyle, StyledRun, TextVerticalAlign } from '@weasel-js/text';
13
+ import { CursorSpec } from '@weasel-js/cursor';
14
+ import { ClaimableGesture } from '@weasel-js/gestures';
15
+ import { SnapTier, ProbeRole } from '@weasel-js/geom/nd';
16
+ import { a as ParallaxOpts, C as ContainerBounds, L as LayoutStrategy, P as PlaneMap, I as InsertAdapter, b as PasteOmission, R as RegionPickView, c as LayoutDropTargetMode, d as ReflowTransition } from './types-CHVXGfYm.js';
17
+ import { UnitScope } from '@weasel-js/quantity';
18
+ import { O as OriginProjection } from './originProjection-gY0jb4Wb.js';
19
+ import { EasingSpec, InterpolatorFactory, Target, Animator, TargetAxes } from '@weasel-js/animator';
20
+ import { B as BoundsConstraint } from './clone-DZDrfIlU.js';
21
+ import { P as PoseDescriptor } from './poseDescriptor-DN2yfnq_.js';
22
+
23
+ /** The form a scene's undo entries are recorded in. A serialized history
24
+ * carries it, and one carrying another is not restored. Form 2 holds the
25
+ * scene's own ops for every edit; before it, an `applyBatch` entry held the
26
+ * ops it was given. */
27
+ declare const SCENE_HISTORY_FORM = 2;
28
+ /** What `Scene.serializeHistory` answers with. */
29
+ interface SerializedSceneHistory extends SerializedHistory {
30
+ form: typeof SCENE_HISTORY_FORM;
31
+ }
32
+
33
+ interface LayerRecordBase<TLayer extends string> {
34
+ id: TLayer;
35
+ visible: boolean;
36
+ locked: boolean;
37
+ /** Draw this layer as a parallax plane: through a view derived from the
38
+ * camera's (see `deriveParallaxView`), and picked through the same one.
39
+ * Absent means the layer moves with the camera. */
40
+ parallax?: ParallaxOpts;
41
+ /** A non-printing layer of aids — measurements, notes — rather than content.
42
+ * Its nodes draw on the canvas and save with the scene, but export leaves
43
+ * them out and content picking passes through them. Read it through
44
+ * `isAnnotationLayer`. Absent means content. */
45
+ annotation?: boolean;
46
+ }
47
+ /** A layer declared when the scene was created. Fixed set, no display name —
48
+ * these are the kit's own render bands, not something a user manages. */
49
+ interface SystemLayerRecord<TLayer extends string> extends LayerRecordBase<TLayer> {
50
+ kind: 'system';
51
+ }
52
+ /** A layer the user created and can rename, reorder or delete. */
53
+ interface UserLayerRecord<TLayer extends string> extends LayerRecordBase<TLayer> {
54
+ kind: 'user';
55
+ name: string;
56
+ }
57
+ /** Per-layer metadata held by the scene: whether it is visible and locked,
58
+ * and where it sits in the render stack. Distinct from a node's `layer` tag,
59
+ * which merely names one of these. */
60
+ type LayerRecord<TLayer extends string> = SystemLayerRecord<TLayer> | UserLayerRecord<TLayer>;
61
+ /** One of the layers a scene is created with. */
62
+ interface SystemLayerSpec<TLayer extends string> {
63
+ id: TLayer;
64
+ visible?: boolean;
65
+ locked?: boolean;
66
+ /** See `LayerRecord.parallax`. */
67
+ parallax?: ParallaxOpts;
68
+ /** See `LayerRecord.annotation`. */
69
+ annotation?: boolean;
70
+ }
71
+ /** Argument to `Scene.addLayer`. Always produces a `UserLayerRecord`
72
+ * (`kind: 'user'`). */
73
+ interface AddLayerSpec<TLayer extends string> {
74
+ id: TLayer;
75
+ name: string;
76
+ /** Default `true`. */
77
+ visible?: boolean;
78
+ /** Default `false`. */
79
+ locked?: boolean;
80
+ /** See `LayerRecord.parallax`. */
81
+ parallax?: ParallaxOpts;
82
+ /** See `LayerRecord.annotation`. */
83
+ annotation?: boolean;
84
+ /** Render-stack position. Default: top of stack (highest render index). */
85
+ index?: number;
86
+ }
87
+
88
+ /** A pose a container's layout wrote — reported by `Scene.onReflow` — in the
89
+ * node's stored frame. */
90
+ interface LayoutMove<TPose> {
91
+ id: NodeId;
92
+ from: TPose;
93
+ to: TPose;
94
+ }
95
+ /** How a scene reads and resizes a laid-out container's bounds. */
96
+ interface LayoutFrame<TPose> {
97
+ /** The container's bounds, from its world pose. Default: the pose's own
98
+ * `x`/`y`/`width`/`height`; a pose without them is not laid out. */
99
+ bounds?(pose: TPose): ContainerBounds | null;
100
+ /** `pose` resized from bounds `from` to `to`, for a layout that grows its
101
+ * container. Default: `to`'s fields written over the pose. */
102
+ remap?(pose: TPose, from: ContainerBounds, to: ContainerBounds): TPose;
103
+ }
104
+
105
+ /** Folding a node's pose up its parent chain to world, and back down. */
106
+ /** Minimal adapter needed by `composeWorldPose` and friends — pose lookup plus parent walk. */
107
+ interface PoseAdapter<TPose> {
108
+ getPose(id: string): TPose;
109
+ getParent(id: string): string | null;
110
+ /** Whether `id`'s pose is a frame its children are expressed in. Absent
111
+ * means every node is one. A container whose pose derives from its children
112
+ * is not: its children share its frame, so the fold passes over it. */
113
+ definesFrame?(id: string): boolean;
114
+ }
115
+ /**
116
+ * What a container's pose does to its children under a `compose`: nothing,
117
+ * an offset, or a whole frame. `'rigid'` is the frame: a container's rotation
118
+ * and its `transform` both reach its children, and a child's `transform`
119
+ * holds the skew or stretch its box and rotation cannot.
120
+ */
121
+ type PoseClosure = 'identity' | 'translation' | 'rigid';
122
+ /** Consumer's pose-composition strategy for hierarchical scenes. `compose`
123
+ * folds a child's pose (in parent's frame) up to the next frame; `decompose`
124
+ * is its inverse. Default is IDENTITY — an absolute-pose scene where every
125
+ * node already stores world coords (parent is grouping-only, no transform). */
126
+ interface PoseComposition<TPose> {
127
+ compose(parent: TPose, child: TPose): TPose;
128
+ decompose(parent: TPose, world: TPose): TPose;
129
+ closure: PoseClosure;
130
+ }
131
+ /** Default pose-composition strategy: IDENTITY, an absolute-pose scene. */
132
+ declare const IDENTITY_POSE_COMPOSITION: PoseComposition<unknown>;
133
+ /** Whether `composition` makes a container's pose a frame, so a stored pose
134
+ * is local to it. False for the absolute-pose model. */
135
+ declare function composesFrames(composition: {
136
+ closure: PoseClosure;
137
+ }): boolean;
138
+ /**
139
+ * Walk `id`'s parent chain and fold local poses into a world pose via
140
+ * `compose`. Cycle-safe.
141
+ *
142
+ * `compose(parent, child)` interprets `child` as expressed *in `parent`'s
143
+ * local frame* and returns the equivalent pose in the next frame up.
144
+ */
145
+ declare function composeWorldPose<TPose>(adapter: PoseAdapter<TPose>, id: string, compose: (parent: TPose, child: TPose) => TPose): TPose;
146
+ /**
147
+ * Convert `worldPose` into a local pose expressed under `newParentId`'s
148
+ * frame, so a reparented child keeps its visual world position.
149
+ *
150
+ * `decompose(parent, world)` returns the local pose `child` such that
151
+ * `compose(parent, child) === world`. Pass `newParentId === null` for the
152
+ * root frame; the function returns `worldPose` unchanged.
153
+ */
154
+ declare function rebaseLocalPose<TPose>(adapter: PoseAdapter<TPose>, worldPose: TPose, newParentId: string | null, compose: (parent: TPose, child: TPose) => TPose, decompose: (parent: TPose, world: TPose) => TPose): TPose;
155
+
156
+ /**
157
+ * Where a reported pose write came from.
158
+ *
159
+ * - `'call'` — a scene method called directly, alone or inside `scene.batch`:
160
+ * a button's `scene.setPose`, a `scene.add`.
161
+ * - `'ops'` — ops applied as one edit through `applyBatch` or `history.apply`,
162
+ * which is how actions commit: a drag's release, a resize, a nudge, an align.
163
+ * - `'undo'` / `'redo'` — a history step, a jump through the history included.
164
+ * - `'layout'` — a container's layout arranging what a live edit changed; also
165
+ * reported to `onReflow`.
166
+ * - `'untracked'` — a write inside `scene.untracked`, such as a pose target
167
+ * committing an animation's destination.
168
+ */
169
+ type PoseWriteOrigin = 'call' | 'ops' | 'undo' | 'redo' | 'layout' | 'untracked';
170
+ /** One node's pose as a scene change left it, in the node's stored frame. */
171
+ interface PoseWrite<TPose> {
172
+ id: NodeId;
173
+ /** The pose before the change; `undefined` for a node the change added. */
174
+ from: TPose | undefined;
175
+ to: TPose;
176
+ origin: PoseWriteOrigin;
177
+ /** The edit's label (`'setPose'`, a batch's, an action's `'Move'`) for
178
+ * `'call'` and `'ops'`; `undefined` otherwise. */
179
+ label?: string;
180
+ }
181
+ /** A removed node as it was last shown, with the descendants it took along. */
182
+ interface RemovedNode<TPose, TNode = unknown> {
183
+ /** The node as it stood before the change removed it. */
184
+ node: TNode;
185
+ /** Where it was shown, override included, in its stored frame. */
186
+ pose: TPose;
187
+ children: readonly RemovedNode<TPose, TNode>[];
188
+ }
189
+ /** One node a scene change removed, a removal's root: its descendants ride
190
+ * beneath it rather than being reported apart. */
191
+ interface PoseRemoval<TPose, TNode = unknown> extends RemovedNode<TPose, TNode> {
192
+ id: NodeId;
193
+ /** The parent it was removed from, which may still be in the scene. */
194
+ parent: NodeId | null;
195
+ origin: PoseWriteOrigin;
196
+ label?: string;
197
+ }
198
+ /** What a scene reports about the poses its edits write. */
199
+ interface ScenePoseReports<TPose, TNode = unknown> {
200
+ /** Called with the poses each live edit's layout pass wrote, after the
201
+ * edit lands — never for an undo or redo, which restore poses rather than
202
+ * arrange them. What a reflow animation glides from. */
203
+ onReflow(listener: (moves: readonly LayoutMove<TPose>[]) => void): () => void;
204
+ /** Called once per change, before the scene's subscribers hear of it, with
205
+ * every node whose pose the change wrote or that it added, and every node
206
+ * it removed — an undone add among them. A node written back to the pose
207
+ * it had, or both added and removed by the change, is left out of both.
208
+ * Not called for `loadState` or the scene's initial nodes. */
209
+ onPoseWrite(listener: (writes: readonly PoseWrite<TPose>[], removed: readonly PoseRemoval<TPose, TNode>[]) => void): () => void;
210
+ }
211
+
212
+ /**
213
+ * One node's ephemeral presentation override — what a frame loop wants to say
214
+ * about a node without saying it about the document.
215
+ *
216
+ * Not document content: never recorded in history, never in `toJSON`, and
217
+ * writing one does not bump `Scene.getVersion()`. Hoist one entry per node and
218
+ * mutate it in place on a frame loop; `PoseOverrides.commit()` is what makes a
219
+ * mutation visible.
220
+ */
221
+ interface PoseOverride<TPose> {
222
+ /** Replaces the node's document pose everywhere the render and hit-test
223
+ * paths read one, including the clip a container derives from its pose, and
224
+ * winning over a `derivePose`. Resolved by `effectivePose` — reading
225
+ * `node.pose` directly is how those paths came to disagree about where a
226
+ * node is. */
227
+ pose?: TPose;
228
+ /** Multiplied into the node's painted alpha, on top of any `alphaFor`. */
229
+ alpha?: number;
230
+ /** Replaces the geometry the node paints and is picked by: the path in its data, or the one
231
+ * it derives. It is in the frame a painter draws in, so give `pose` beside it, as the
232
+ * path's bounds with no rotation, or the pose's turn is applied to the path again and the
233
+ * selection chrome stays on the old box. A skinned rig is the writer. */
234
+ path?: Path;
235
+ }
236
+ /**
237
+ * The scene's ephemeral per-node overrides — see {@link PoseOverride}.
238
+ *
239
+ * The intended shape of a frame is: `set` each node once, mutate the entries
240
+ * in place per frame, `commit()` once. `commit` is not optional bookkeeping —
241
+ * the painter memo keys on pose *reference*, so a mutation without a commit
242
+ * paints the previous frame with no error.
243
+ *
244
+ * To promote a frame to document state (dropping a drag, baking an animation),
245
+ * write it once through `Scene.setPose` and `clear` the override.
246
+ */
247
+ interface PoseOverrides<TPose> {
248
+ /** Store `entry` for `id` **by reference**; the caller keeps mutating it. */
249
+ set(id: NodeId, entry: PoseOverride<TPose>): void;
250
+ /** The entry `set` stored, by reference — what a writer checks to know
251
+ * whether its own entry is still installed. Painting reads `read`. */
252
+ get(id: NodeId): PoseOverride<TPose> | undefined;
253
+ /** What the node is drawn and picked with: every source of overrides for
254
+ * it folded into one, as of the last write or `commit()`. `undefined` for
255
+ * a node nothing overrides. The object is reused per node. */
256
+ read(id: NodeId): PoseOverride<TPose> | undefined;
257
+ has(id: NodeId): boolean;
258
+ /** The overridden ids, as a snapshot array. */
259
+ ids(): readonly NodeId[];
260
+ clear(id: NodeId): void;
261
+ clearAll(): void;
262
+ /** Publish this frame's in-place mutations: invalidate the painter memo for
263
+ * every overridden node, then notify subscribers. */
264
+ commit(): void;
265
+ /** Notified after every write. The canvas uses this to repaint without a
266
+ * scene version bump. */
267
+ subscribe(fn: () => void): () => void;
268
+ /** Monotonic write counter. A snapshot for observers that poll. */
269
+ getGeneration(): number;
270
+ /** A claim on some nodes' poses for a writer that publishes a whole frame
271
+ * at a time: a gesture's preview, a layout run. Each call is a new claim. */
272
+ hold(): PoseHold<TPose>;
273
+ }
274
+ /**
275
+ * One writer's claim on some nodes' pose overrides, from
276
+ * {@link PoseOverrides.hold}.
277
+ *
278
+ * A hold knows which entries are its own, so several writers share the table
279
+ * without clearing each other: a drag and a layout run each publish their
280
+ * frame, and each sees the other's nodes as pinned.
281
+ */
282
+ interface PoseHold<TPose> {
283
+ /** Publish this frame's poses. It is the whole picture, not a delta: an id
284
+ * the frame leaves out is released. Subscribers are notified once. */
285
+ set(poses: Iterable<readonly [NodeId, TPose]>): void;
286
+ /** The poses other writers are publishing, by id. */
287
+ others(): ReadonlyMap<NodeId, TPose>;
288
+ /** Release every id still held. An id whose entry another writer has since
289
+ * replaced is left alone: that writer owns it now. When the frame is being
290
+ * committed to the document, call this after the write lands, or the scene
291
+ * answers with the old pose in between. */
292
+ drop(): void;
293
+ }
294
+
295
+ /** One layer as it appears in a snapshot. A snapshot written before layer
296
+ * kind was serialized carries neither field, and loads as a system layer —
297
+ * which is what every layer in such a snapshot was. */
298
+ interface SerializedLayer<TLayer extends string> extends SystemLayerSpec<TLayer> {
299
+ kind?: 'system' | 'user';
300
+ /** Present on a user layer, absent on a system one. */
301
+ name?: string;
302
+ }
303
+ /** JSON-serializable shape of a Scene's current state. Produced by
304
+ * `scene.toJSON()`; consumed by `sceneFromJSON()`. Function fields
305
+ * (e.g., `clipFromPose`) appear as string keys (`clipFromPoseKey`) and
306
+ * are resolved through `SceneRegistry` at load time. */
307
+ interface SerializedScene<TData, TLayer extends string, TPose> {
308
+ version: 1;
309
+ /** The whole layer stack, system and user alike — the name predates user
310
+ * layers and is kept so existing snapshots still parse. */
311
+ systemLayers: readonly SerializedLayer<TLayer>[];
312
+ nodes: readonly SerializedNode<TData, TLayer, TPose>[];
313
+ }
314
+ /** JSON-serializable shape of a single node. Mirrors `AddNodeSpec` but
315
+ * with function fields replaced by registry keys. */
316
+ interface SerializedNode<TData, TLayer extends string, TPose> {
317
+ id: string;
318
+ kind: 'leaf' | 'container';
319
+ layer: TLayer;
320
+ pose: TPose;
321
+ data: TData;
322
+ /** Parent id; omitted for roots. */
323
+ parent?: string;
324
+ /** Registry key for the container's clip-path factory.
325
+ * Containers only; omitted when the container has no clip. */
326
+ clipFromPoseKey?: string;
327
+ /** Registry key for the container's `copiesFromPose`. Containers only;
328
+ * omitted when it draws no copies. */
329
+ copiesFromPoseKey?: string;
330
+ /** Ids this node's geometry derives from, or `'children'`. Omitted when it
331
+ * derives from nothing. */
332
+ dependsOn?: readonly string[] | 'children';
333
+ /** Mirrors `SceneNode.pickable`. Omitted when the node is pickable. */
334
+ pickable?: boolean;
335
+ /** Mirrors `SceneNode.hidden`. Omitted when the node is shown. */
336
+ hidden?: boolean;
337
+ /** Mirrors `SceneNode.locked`. Omitted when the node is unlocked. */
338
+ locked?: boolean;
339
+ /** Registry key for the node's `derivePath` function. Omitted when it has none. */
340
+ derivePathKey?: string;
341
+ /** Registry key for the node's `derivePose` function. Omitted when it has none. */
342
+ derivePoseKey?: string;
343
+ /** Registry key for the container's layout strategy. Omitted when it has none. */
344
+ layoutKey?: string;
345
+ /** Mirrors `ContainerNode.units`. Omitted when the container declares none. */
346
+ units?: UnitScope;
347
+ }
348
+
349
+ /**
350
+ * Axis-aligned rectangle pose with optional rotation. Rotation is in
351
+ * radians, pivoted on the unrotated AABB center; absent === 0.
352
+ */
353
+ interface RectPose {
354
+ x: number;
355
+ y: number;
356
+ width: number;
357
+ height: number;
358
+ /** Rotation in radians around the unrotated AABB center. Absent === 0. */
359
+ rotation?: number;
360
+ /** A skew or per-axis scale the box and rotation cannot hold; see
361
+ * {@link PoseLinear}. Absent is the identity. */
362
+ transform?: PoseLinear;
363
+ }
364
+
365
+ /**
366
+ * One dependency, as a derivation reads it: the node itself and the pose it is
367
+ * painted at.
368
+ *
369
+ * The node comes along because a connector legitimately reads more than a box
370
+ * — an edge that thickens with its endpoint's weight, or routes only to nodes
371
+ * on a given layer, is answering off `data` and `layer`.
372
+ */
373
+ interface DerivedDep<TPose, TData = unknown, TLayer extends string = string> {
374
+ node: Node<TData, TLayer, TPose>;
375
+ /** Its override when it has one, else its own derived pose, else the pose
376
+ * the document stores — `effectivePose`, the same answer the renderer uses. */
377
+ pose: TPose;
378
+ /** The path a pose override shows it by, else the one it derives, else
379
+ * `null`; the document reading skips the override, and a `toPose` lookup
380
+ * carries it into the box its `toPose` answers. Read
381
+ * it to place something *along* a dependency: a label on a routed edge.
382
+ * Resolved on first read and memoized on the dependency. */
383
+ readonly path: Path | null;
384
+ }
385
+ /** `F` with its parameters checked bivariantly, as a method's are, so that a
386
+ * `Scene<D, L, MyPose>` is a `Scene<unknown, string, unknown>`. A callback for
387
+ * an unrelated pose is still rejected; one for a narrower pose is not. */
388
+ type Bivariant<F extends (...args: never[]) => unknown> = {
389
+ method(...args: Parameters<F>): ReturnType<F>;
390
+ }['method'];
391
+ /** Computes a node's path from its dependencies: the type of a node's
392
+ * `derivePath` and of each entry in `SceneRegistry.derivePath`. */
393
+ type DerivePathFn<TPose, TData = unknown, TLayer extends string = string> = Bivariant<(node: Node<TData, TLayer, TPose>, deps: readonly (DerivedDep<TPose, TData, TLayer> | undefined)[]) => Path | null>;
394
+ /** Computes a node's pose from its dependencies: the type of a node's
395
+ * `derivePose` and of each entry in `SceneRegistry.derivePose`. */
396
+ type DerivePoseFn<TPose, TData = unknown, TLayer extends string = string> = Bivariant<(node: Node<TData, TLayer, TPose>, deps: readonly (DerivedDep<TPose, TData, TLayer> | undefined)[]) => TPose | null>;
397
+ /** A container's clip, from its pose: the type of `ContainerNode.clipFromPose`
398
+ * and of each entry in `SceneRegistry.clipFromPose`. */
399
+ type ClipFromPoseFn<TPose> = Bivariant<(pose: TPose) => Path | null>;
400
+ /** The extra times a container draws its children: the type of
401
+ * `ContainerNode.copiesFromPose` and of each entry in
402
+ * `SceneRegistry.copiesFromPose`. Each affine is in world coordinates and
403
+ * carries the children, as drawn, to one copy. */
404
+ type CopiesFromPoseFn<TPose, TData = unknown, TLayer extends string = string> = Bivariant<(pose: TPose, node: ContainerNode<TData, TLayer, TPose>) => readonly Affine[] | null>;
405
+
406
+ /** Brand a string as a NodeId. */
407
+ declare const asNodeId: (s: string) => NodeId;
408
+
409
+ interface NodeBase<TData, TLayer extends string, TPose> {
410
+ id: NodeId;
411
+ layer: TLayer;
412
+ pose: TPose;
413
+ data: TData;
414
+ parent: NodeId | null;
415
+ /** Nodes whose poses this node's geometry is computed from. Fixed at add
416
+ * time. Absent or empty means the node's geometry is authored, which is the
417
+ * normal case.
418
+ *
419
+ * `'children'` means "my own children, in child order" — a container that
420
+ * hugs its contents, which a fixed id list cannot express because
421
+ * reparenting would have to maintain it. The two forms differ in lifetime
422
+ * as well as in membership: deleting a node deletes everything that names
423
+ * it in `dependsOn`, but a container outlives the children it derives
424
+ * from — an emptied group is still a group. */
425
+ dependsOn?: readonly NodeId[] | 'children';
426
+ /** Whether the hit-test walk can return this node. Default `true`; `false`
427
+ * makes it transparent to picking, so a click on it lands on whatever is
428
+ * behind — normally its own container.
429
+ *
430
+ * For content a container owns rather than content the user selects on its
431
+ * own: the label inside a box, a body's rows. It does not hide the node
432
+ * from anything else — it still paints, still clips, and a consumer can
433
+ * still select it by id. */
434
+ pickable?: boolean;
435
+ /** Not drawn, with its whole subtree: picking, area selection, select-all,
436
+ * snapping and the selection pass over it, and an SVG export writes it with
437
+ * `display="none"`. Absent means shown; `Scene.isHidden` folds in its
438
+ * ancestors' flags and its layer's visibility. */
439
+ hidden?: boolean;
440
+ /** Out of reach, with its whole subtree: still drawn, but picking and area
441
+ * selection pass over it, the selection drops it, and every edit to it
442
+ * throws, as on a locked layer. Absent means unlocked; `Scene.isLocked`
443
+ * folds in its ancestors' and its layer's. */
444
+ locked?: boolean;
445
+ /** Computes this node's path from its dependencies, in `dependsOn` order —
446
+ * each one the node and the pose it is painted at.
447
+ * A dependency that has been removed arrives as `undefined`.
448
+ * Returning `null` means "nothing to draw right now". Re-evaluated when a
449
+ * dependency's world pose changes, never authored. */
450
+ derivePath?: DerivePathFn<TPose, TData, TLayer>;
451
+ /** Computes this node's pose from its dependencies' poses, the same way
452
+ * `derivePath` computes its path — same `dependsOn` list, same
453
+ * registry-keyed serialization.
454
+ *
455
+ * Where a derived path is resolved at paint time and reaches only the
456
+ * painter, a derived pose is what the node *is* at: it feeds bounds,
457
+ * hit-testing, selection chrome, snapping and layout, and every reader
458
+ * gets it through `effectivePose`. A pose override still wins over it.
459
+ *
460
+ * Returning `null` means "I have nothing to derive from right now", and
461
+ * the node falls back to its authored `pose`. `setPose` on a derived node
462
+ * still writes that authored pose; it is simply not what anything reads. */
463
+ derivePose?: DerivePoseFn<TPose, TData, TLayer>;
464
+ }
465
+ /** A node with no children — a shape, a label, an image. */
466
+ interface LeafNode<TData, TLayer extends string, TPose = RectPose> extends NodeBase<TData, TLayer, TPose> {
467
+ kind: 'leaf';
468
+ }
469
+ /** A node with an ordered list of children. This is the real group: what
470
+ * Cmd+G creates, what SVG `<g>` round-trips to. A container has its own pose,
471
+ * which its children's poses are relative to, and may optionally clip them. */
472
+ interface ContainerNode<TData, TLayer extends string, TPose = RectPose> extends NodeBase<TData, TLayer, TPose> {
473
+ kind: 'container';
474
+ children: NodeId[];
475
+ /** Optional clip-path source. Re-evaluated each render. Returning `null`
476
+ * means "no clip for this container right now"; an empty / zero-area path
477
+ * means "clip everything out" (children render nowhere). */
478
+ clipFromPose?: ClipFromPoseFn<TPose>;
479
+ /** Draws the whole subtree again under each affine it returns, on top of
480
+ * the original, which still draws once as authored. The copies are paint,
481
+ * not nodes: nothing stores them, so they follow every edit to the
482
+ * children, and a pick that lands on one answers with the child it copies.
483
+ * A copy is a copy of the clipped content — the clip travels with it.
484
+ * Re-evaluated each render; `null` or `[]` draws no copies. */
485
+ copiesFromPose?: CopiesFromPoseFn<TPose, TData, TLayer>;
486
+ /** How this container arranges its children. Whenever the container's
487
+ * child set or order changes, or its bounds change size, the scene hands
488
+ * the change to the strategy — `depart` for children that left it,
489
+ * `arrive` for children that joined it, `childPoses` otherwise — and records the poses it writes in the same
490
+ * undo entry as the change. A drag reads it too: it is the layout `move`
491
+ * reflows and drops against. */
492
+ layout?: LayoutStrategy<TPose>;
493
+ /** The unit system this container's contents are written in, and what one
494
+ * of its base units is worth in the enclosing scope's. It covers the
495
+ * children, not the container; `sceneUnitScopes` reads the chain. */
496
+ units?: UnitScope;
497
+ }
498
+ /** A node in the scene tree: either a leaf or a container. Re-exported
499
+ * publicly as `SceneNode`, to avoid colliding with the DOM's `Node`. */
500
+ type Node<TData, TLayer extends string, TPose = RectPose> = LeafNode<TData, TLayer, TPose> | ContainerNode<TData, TLayer, TPose>;
501
+ /** What `Scene.add` needs to mint a node. Everything except the id is
502
+ * required; the id is generated unless one is supplied. */
503
+ interface AddNodeSpec<TData, TLayer extends string, TPose = RectPose> {
504
+ kind: 'leaf' | 'container';
505
+ layer: TLayer;
506
+ pose: TPose;
507
+ data: TData;
508
+ parent?: NodeId | null;
509
+ index?: number;
510
+ /** Explicit id wins over the Scene's `generateId` and the kit default. */
511
+ id?: NodeId;
512
+ /** Mirrors `SceneNode.pickable`. Omit for the default, which is pickable. */
513
+ pickable?: boolean;
514
+ /** Mirrors `SceneNode.hidden`. */
515
+ hidden?: boolean;
516
+ /** Mirrors `SceneNode.locked`. */
517
+ locked?: boolean;
518
+ /** Only meaningful when `kind === 'container'`. Attach a clip-path function
519
+ * to the node; ignored for leaves. Mirrors `ContainerNode.clipFromPose`. */
520
+ clipFromPose?: ClipFromPoseFn<TPose>;
521
+ /** Mirrors `ContainerNode.copiesFromPose`; ignored for leaves. */
522
+ copiesFromPose?: CopiesFromPoseFn<TPose, TData, TLayer>;
523
+ /** Mirrors `SceneNode.dependsOn`. */
524
+ dependsOn?: readonly NodeId[] | 'children';
525
+ /** Mirrors `SceneNode.derivePath`. Taken as a live function; its registry key is
526
+ * looked up from it, never passed in. */
527
+ derivePath?: DerivePathFn<TPose, TData, TLayer>;
528
+ /** Mirrors `SceneNode.derivePose`, on the same terms as `derivePath`. */
529
+ derivePose?: DerivePoseFn<TPose, TData, TLayer>;
530
+ /** Mirrors `ContainerNode.layout`; ignored for leaves. */
531
+ layout?: LayoutStrategy<TPose>;
532
+ /** Mirrors `ContainerNode.units`; ignored for leaves. */
533
+ units?: UnitScope;
534
+ }
535
+ /** A custom scene mutation registered with `Scene.registerOp`: how to apply
536
+ * it and how to undo it. The pair is what makes it participate in history. */
537
+ interface RegisteredOp<P> {
538
+ apply: (payload: P) => void;
539
+ revert: (payload: P) => void;
540
+ /** Opts this kind into coalescing under `UseSceneOptions.coalesceWindowMs`:
541
+ * two entries of this kind that return the same key inside the window
542
+ * merge, and undoing the merged entry calls `revert` with the first
543
+ * payload only. Declare it only when `revert` restores an absolute state
544
+ * (a stored "from" value), never for a relative payload such as a delta.
545
+ * Omitted, or returning `undefined`, the op is always its own entry. */
546
+ coalesceKey?: (payload: P) => string | undefined;
547
+ }
548
+ /** Per-scene registry mapping string keys to live function references.
549
+ * Passed to `createScene({ ..., registry })` and `sceneFromJSON(json, { registry })`.
550
+ * Each function-field type has its own keyed map. */
551
+ interface SceneRegistry<TPose, TData = unknown, TLayer extends string = string> {
552
+ /** Maps registry keys to `clipFromPose` factory functions for container nodes. */
553
+ clipFromPose?: Readonly<Record<string, ClipFromPoseFn<TPose>>>;
554
+ /** Maps registry keys to `copiesFromPose` functions for container nodes. */
555
+ copiesFromPose?: Readonly<Record<string, CopiesFromPoseFn<TPose, TData, TLayer>>>;
556
+ /** Maps registry keys to `derivePath` functions for nodes with `dependsOn`. */
557
+ derivePath?: Readonly<Record<string, DerivePathFn<TPose, TData, TLayer>>>;
558
+ /** Maps registry keys to `derivePose` functions for nodes with `dependsOn`. */
559
+ derivePose?: Readonly<Record<string, DerivePoseFn<TPose, TData, TLayer>>>;
560
+ /** Maps registry keys to container layout strategies. */
561
+ layout?: Readonly<Record<string, LayoutStrategy<TPose>>>;
562
+ }
563
+ /**
564
+ * Decides what one edit's changes to containers do to their children.
565
+ * `arrivals` maps each container to the ids that joined it — by an `add`
566
+ * under it or a `move` into it, whatever op or call made them — in the order
567
+ * they arrived. `changed` names every container whose child set or order
568
+ * changed, or whose pose changed size, arrivals included. Both are read once
569
+ * the edit's other mutations have landed.
570
+ *
571
+ * Return the poses to write, in each node's stored frame; they become part of
572
+ * the same edit, and so of the same undo step. An empty map writes nothing.
573
+ * Return `null` to refuse: the whole edit is reverted (see
574
+ * `SceneArrivalRefused`).
575
+ *
576
+ * Runs only for live edits. Undo, redo and a restored history replay the
577
+ * arrangement that was decided the first time. With none installed, a scene
578
+ * holding declared layouts (`ContainerNode.layout`) runs its own.
579
+ */
580
+ type SceneArrivalHandler<TPose> = (arrivals: ReadonlyMap<NodeId, readonly NodeId[]>, changed: ReadonlySet<NodeId>,
581
+ /** The nodes that left each container in the edit, by the container they
582
+ * left — removed, or moved out. */
583
+ departures: ReadonlyMap<NodeId, readonly NodeId[]>) => ReadonlyMap<NodeId, TPose> | null;
584
+ /**
585
+ * The kit-owned scene tree: nodes, layers, and the undo history over both.
586
+ *
587
+ * A scene is logical, not visual — it says what exists and where, and nothing
588
+ * about how it is painted. Every mutating method is undoable, and reads are
589
+ * snapshots rather than live views. Nodes are addressed by `NodeId`; hold ids
590
+ * across mutations, not node objects.
591
+ *
592
+ * Three type parameters keep it domain-agnostic: `TData` is the app's payload,
593
+ * which the kit never inspects; `TPose` is the transform shape, `RectPose` by
594
+ * default; `TLayer` is the union of layer names.
595
+ */
596
+ interface Scene<TData, TLayer extends string, TPose = RectPose> extends ScenePoseReports<TPose, Node<TData, TLayer, TPose>> {
597
+ readonly nodes: ReadonlyMap<NodeId, Node<TData, TLayer, TPose>>;
598
+ readonly roots: readonly NodeId[];
599
+ readonly layers: readonly LayerRecord<TLayer>[];
600
+ /** The registry this scene resolves node functions against — the consumer's
601
+ * entries over the kit's. */
602
+ readonly registry: SceneRegistry<TPose, TData, TLayer>;
603
+ /** See {@link UseSceneOptions.composition}. */
604
+ readonly composition: PoseComposition<TPose>;
605
+ get(id: NodeId): Node<TData, TLayer, TPose> | undefined;
606
+ /** A token for the node `id` names right now, for telling one node from a
607
+ * later one that reuses its id. It holds for as long as the node stays in
608
+ * the scene, whatever edits it takes, and is different every time the id
609
+ * enters the scene — by `add`, by an undo or redo that brings it back, or
610
+ * by `loadState`. `undefined` when `id` is not in the scene. Compare tokens
611
+ * for equality only; their order means nothing. */
612
+ incarnation(id: NodeId): number | undefined;
613
+ childrenOf(id: NodeId): readonly NodeId[];
614
+ ancestorsOf(id: NodeId): readonly NodeId[];
615
+ renderOrder(): Iterable<NodeId>;
616
+ /** The same layer-major sequence as {@link Scene.renderOrder}, as the nodes
617
+ * themselves. Prefer this wherever the ids are only going to be resolved
618
+ * back to nodes. Cached until a structural edit, so repeat calls hand back
619
+ * the same array — a snapshot, not a live view, and not yours to mutate. */
620
+ renderOrderNodes(): readonly Node<TData, TLayer, TPose>[];
621
+ /** The nodes on one layer, in render order. Cached alongside
622
+ * {@link Scene.renderOrderNodes} until a structural edit. A snapshot, not
623
+ * a live view, and not yours to mutate. An unknown layer id yields an
624
+ * empty array. */
625
+ nodesOnLayer(layer: TLayer): readonly Node<TData, TLayer, TPose>[];
626
+ /** A fresh id from this scene's `generateId`, or the kit default: the id
627
+ * `add` would give a spec with none. For code that has to name a node
628
+ * before it exists, such as one building an insert op. */
629
+ mintId(): NodeId;
630
+ add(spec: AddNodeSpec<TData, TLayer, TPose>): NodeId;
631
+ /** Delete `id`, its **entire subtree**, and **everything that derives from**
632
+ * any of those nodes — a node listing one of them in `dependsOn` goes too,
633
+ * along with its own subtree, transitively. A dependent can live anywhere in
634
+ * the tree, so this deletes nodes the caller never named and may unlink
635
+ * several disjoint subtrees at once. Recorded as one undoable step; `undo()`
636
+ * restores every one of them where it was, child order intact. */
637
+ remove(id: NodeId): void;
638
+ /** {@link remove} over several roots at once, as a **single** undoable step.
639
+ * Ids resolve against the tree as it stands at the call, so an id that
640
+ * another one would cascade away is absorbed rather than removed twice —
641
+ * which is what makes it safe to pass a whole selection. Throws if any id is
642
+ * not in the scene; an empty list does nothing and records no step. */
643
+ removeMany(ids: readonly NodeId[]): void;
644
+ /** Every node {@link removeMany} would take if given `ids`: each id, its
645
+ * subtree, everything deriving from any of those, and those nodes' subtrees
646
+ * in turn. Ids not in the scene come back unchanged.
647
+ *
648
+ * A set, not a restore order: a dependent can be reached before the parent
649
+ * it sits under, which is also in the closure. */
650
+ removalClosure(ids: readonly NodeId[]): readonly NodeId[];
651
+ update(id: NodeId, patch: {
652
+ data: TData;
653
+ }): void;
654
+ setPose(id: NodeId, pose: TPose): void;
655
+ /** Retag `id` to `layer`. On a **container this cascades**: every descendant
656
+ * is moved to the same layer, recorded as a **single** undo step.
657
+ *
658
+ * Invariants:
659
+ * - **Layer floor** — a child may not render below its parent, so retagging
660
+ * to a layer *below* the node's parent throws. Retagging to the parent's
661
+ * layer or any higher one is allowed; a node with no parent is
662
+ * unconstrained.
663
+ * - **No-op elision** — setting the layer a node already has does nothing
664
+ * and pushes **no** history entry. */
665
+ setLayer(id: NodeId, layer: TLayer): void;
666
+ /** Point `id` at a different set of dependencies — retargeting an edge's end
667
+ * onto another node, or switching a container between an id list and
668
+ * `'children'`. Recorded as one undoable step.
669
+ *
670
+ * Order is significant: a derivation reads its dependencies positionally,
671
+ * so `[b, a]` is not `[a, b]`. Ids need not be in the scene — a declared
672
+ * dependency that appears later invalidates the node when it does, the same
673
+ * as one declared at `add`. Passing `undefined` drops the declaration, after
674
+ * which nothing cascades the node away.
675
+ *
676
+ * **No-op elision** — declaring what the node already declares does nothing
677
+ * and pushes no history entry. */
678
+ setDependsOn(id: NodeId, dependsOn: readonly NodeId[] | 'children' | undefined): void;
679
+ /** Give container `id` a different layout — a strategy, its key in
680
+ * `SceneRegistry.layout`, or `null` for none — and re-arrange its children
681
+ * under it, as one undoable step. Throws for a leaf, or a key the registry
682
+ * does not hold. A registered layout is recorded by its key, so a
683
+ * serialized history restores it; an unregistered one lives only as long
684
+ * as the session.
685
+ *
686
+ * **No-op elision** — setting the layout a container already has does
687
+ * nothing and pushes no history entry. */
688
+ setLayout(id: NodeId, layout: LayoutStrategy<TPose> | string | null): void;
689
+ /** Reparent `id` under `parent` (or to a root when `parent` is `null`) at
690
+ * `index` within the new sibling list, appending when `index` is omitted.
691
+ * Siblings are reindexed. Recorded as one undoable step.
692
+ *
693
+ * Rejected (throws) when:
694
+ * - `parent` exists but is a **leaf**, not a container;
695
+ * - the move would form a **cycle** — `parent` is `id` itself or one of
696
+ * `id`'s own descendants;
697
+ * - it would drop `id` **below its new parent's layer** (child may not
698
+ * render below its parent).
699
+ *
700
+ * `move(id, null)` — detaching to a root — is always allowed regardless of
701
+ * layer, since a root has no parent to render beneath. */
702
+ move(id: NodeId, parent: NodeId | null, index?: number): void;
703
+ /** Shift `id` to `index` within its **current** parent's child list. Unlike
704
+ * {@link move}, the parent never changes — only sibling order. */
705
+ reorder(id: NodeId, index: number): void;
706
+ /** Show or hide a layer. Hiding drops its nodes from the selection. */
707
+ setLayerVisible(layer: TLayer, visible: boolean): void;
708
+ /** Lock or unlock a layer. A locked layer still paints, but its nodes are
709
+ * out of reach: picking and area selection pass over them, the selection
710
+ * drops them, and every node mutation on them throws. Locking is never
711
+ * blocked by the lock, and neither are the other layer operations. */
712
+ setLayerLocked(layer: TLayer, locked: boolean): void;
713
+ /** Set or clear (`undefined`) a layer's parallax — see
714
+ * `LayerRecord.parallax`. Undoable; an animation tweening it writes inside
715
+ * {@link Scene.untracked} so no frame becomes an undo step. */
716
+ setLayerParallax(layer: TLayer, parallax: ParallaxOpts | undefined): void;
717
+ /** Whether `id` is locked: it or an ancestor carries `locked`, or sits on a
718
+ * locked layer. A lock covers its whole subtree, whatever layers the
719
+ * descendants are tagged to. An id not in the scene is not locked. */
720
+ isLocked(id: NodeId): boolean;
721
+ /** Whether `id` is not drawn: its own layer is hidden, or it or an ancestor
722
+ * carries `hidden`. A hidden layer hides only the nodes tagged to it. An
723
+ * id not in the scene is not hidden. */
724
+ isHidden(id: NodeId): boolean;
725
+ /** Hide or show node `id` and its subtree — see `SceneNode.hidden`. One
726
+ * undo step; hiding drops the subtree from the selection. Never blocked by
727
+ * a lock, and setting what the node already has records nothing. */
728
+ setHidden(id: NodeId, hidden: boolean): void;
729
+ /** Lock or unlock node `id` and its subtree — see `SceneNode.locked`. One
730
+ * undo step; locking drops the subtree from the selection. Never blocked
731
+ * by a lock, and setting what the node already has records nothing. */
732
+ setLocked(id: NodeId, locked: boolean): void;
733
+ /** Run `fn` with the lock guard lifted, for a programmatic edit that has to
734
+ * reach a locked node. Undo and redo never need it. */
735
+ unlocked<T>(fn: () => T): T;
736
+ addLayer(spec: AddLayerSpec<TLayer>): void;
737
+ /** Drop a user layer and every node tagged to it, as one undoable step.
738
+ * Removal cascades, so this also deletes nodes **on other layers** that
739
+ * derive from a node on this one. */
740
+ removeLayer(layer: TLayer): void;
741
+ renameLayer(layer: TLayer, name: string): void;
742
+ moveLayer(layer: TLayer, index: number): void;
743
+ registerOp<P>(kind: string, handler: RegisteredOp<P>): void;
744
+ recordOp<P>(op: {
745
+ kind: string;
746
+ payload: P;
747
+ }): void;
748
+ /** Install (or clear with `null`) the active-journal accessor after scene
749
+ * construction, for a journal source built with `scene.history` as a
750
+ * dependency. Overrides any `getActiveJournal` set in `UseSceneOptions`. */
751
+ setActiveJournalAccessor(fn: (() => _weasel_js_history.Journal | null) | null): void;
752
+ /** Install what the scene does when nodes join a container, replacing any
753
+ * handler installed before; `null` removes it. Returns a function that
754
+ * removes this handler, and does nothing once another has replaced it.
755
+ * See {@link SceneArrivalHandler}. */
756
+ setArrivalHandler(handler: SceneArrivalHandler<TPose> | null): () => void;
757
+ /** Apply a batch of ops against `adapter` as one undo entry.
758
+ *
759
+ * The entry holds the scene writes the ops made, as a direct call records
760
+ * them, and beside them any op that wrote no scene state, bound to
761
+ * `adapter`. Undo restores those writes; it does not call an op's
762
+ * `invert()` or the adapter again. **What an op states is not recorded**:
763
+ * one applied over a document that already holds its result, as after an
764
+ * `untracked` preview, records a write from that pose to itself, and undo
765
+ * goes nowhere. Put the document back first.
766
+ *
767
+ * The entry lands in the open `batch` when there is one, else on the
768
+ * active journal, else on the scene's own history, where it can coalesce
769
+ * under `coalesceWindowMs` with one whose ops' keys match.
770
+ *
771
+ * Returns false when the arrival handler refused the batch: it is reverted
772
+ * and unrecorded. Inside `batch` it is true; that batch may still refuse. */
773
+ applyBatch(ops: Op[], label: string, adapter: unknown): boolean;
774
+ /** The transient set of active ids — "operate on these N as a unit".
775
+ * Shared by every view over this scene unless a view supplies its own
776
+ * (see `CanvasView.selection`). Not document content: it never appears
777
+ * in `toJSON`. It does ride on history entries, so undo and redo put
778
+ * back the selection an edit was made under; changing it is never an
779
+ * undo step of its own. Removing a node deselects it. */
780
+ getSelection(): readonly NodeId[];
781
+ setSelection(ids: readonly NodeId[]): void;
782
+ /** Per-node pose / alpha overrides the render and hit-test paths read
783
+ * through. Like {@link Scene.getSelection} this is not document content:
784
+ * writes are never recorded, never serialized, and do not bump
785
+ * {@link Scene.getVersion}. See {@link PoseOverrides}. */
786
+ readonly overrides: PoseOverrides<TPose>;
787
+ /** The scene's undo/redo engine, in the shape `@weasel-js/history` defines.
788
+ * Mutating members route through
789
+ * the scene's own wrappers, so an undo driven through this bumps
790
+ * {@link Scene.getVersion} and notifies subscribers exactly as
791
+ * {@link Scene.undo} does; `getVersion` / `subscribe` on it report the
792
+ * engine's history version, not the scene's. */
793
+ readonly history: History;
794
+ undo(): boolean;
795
+ redo(): boolean;
796
+ canUndo(): boolean;
797
+ canRedo(): boolean;
798
+ batch<T>(label: string, fn: () => T): T;
799
+ /** The layout container `id` declares, or `null` for a leaf or a
800
+ * container that declares none. */
801
+ layoutOf(id: NodeId): LayoutStrategy<TPose> | null;
802
+ /** Declare the unit scope of container `id`, or clear it with `null`. */
803
+ setUnits(id: NodeId, units: UnitScope | null): void;
804
+ /** Run `fn` with every mutation applied but none recorded — for writes
805
+ * that are not edits, such as a simulation stepping poses each frame.
806
+ * Undo and redo move between recorded states and never restore an
807
+ * untracked write; the next recorded change starts from whatever the
808
+ * untracked writes left, so undoing it lands there. A `batch` inside
809
+ * records nothing; inside a `batch`, these writes stay out of its entry.
810
+ * Notifies once, reverts `fn`'s writes if it throws, and throws on
811
+ * `applyBatch` and `history.apply` / `applyOps`, which exist to record. */
812
+ untracked<T>(fn: () => T): T;
813
+ /** Read-only snapshot of every history entry currently reachable from
814
+ * the present state. Oldest applied first, then redoable entries in
815
+ * the order they'd be re-applied. Each entry id is stable. */
816
+ historyEntries(): readonly {
817
+ id: string;
818
+ label: string;
819
+ }[];
820
+ /** Index of the "current state". Equals the count of applied entries;
821
+ * `0` means "nothing applied" (initial). */
822
+ historyIndex(): number;
823
+ /** Jump to the given history index, clamped to [0, total]. Returns true
824
+ * if any movement occurred. */
825
+ jumpToHistoryIndex(index: number): boolean;
826
+ /** Snapshot the undo/redo history in a JSON-serializable form (the
827
+ * engine's `SerializedHistory`, marked with the scene's recorded form).
828
+ * An entry holds the scene's own ops, whichever way the edit was made.
829
+ * An op handed to `applyBatch` that wrote no scene state is held as
830
+ * itself, and an entry with a nameless one is dropped. Payload
831
+ * JSON-safety (e.g. typed arrays inside poses) is the caller's concern.
832
+ * Do not call mid-`batch` — the open batch's ops are not yet recorded. */
833
+ serializeHistory(): SerializedSceneHistory;
834
+ /** Replace the undo/redo history from a `serializeHistory()` snapshot.
835
+ * Call on a scene whose node/layer state already matches the snapshot's
836
+ * head state (i.e. right after `loadState` from the paired scene
837
+ * snapshot); node state is NOT mutated. Ops re-registered via
838
+ * `registerOp` before this call round-trip; unknown kinds become no-op
839
+ * placeholders; external ops rebuild via the global op-factory registry
840
+ * and replay against the `setHistoryAdapter` accessor. Restored entries
841
+ * never coalesce with new ones. Notifies once. A snapshot that is not in
842
+ * the current recorded form (see `SCENE_HISTORY_FORM`) is dropped:
843
+ * the history is left as it was. Do not call mid-`batch`:
844
+ * the stacks are replaced underneath the open batch, whose eventual
845
+ * flush would graft onto (and evict against) the restored stacks. */
846
+ restoreHistory(snapshot: SerializedHistory): void;
847
+ /** Install (or clear with `null`) the accessor for the adapter that
848
+ * RESTORED external ops apply against on undo/redo: the ops handed to
849
+ * `applyBatch` that wrote no scene state, such as a selection change,
850
+ * rebuilt from a `restoreHistory` snapshot. Resolved lazily at each
851
+ * apply, so wiring order relative to `restoreHistory` doesn't matter.
852
+ * Live `applyBatch` entries are unaffected (they bind their call-site
853
+ * adapter). If unset when a restored op applies, the op is a debug-warned
854
+ * no-op. */
855
+ setHistoryAdapter(fn: (() => unknown) | null): void;
856
+ /** Snapshot the current scene state to a JSON-serializable shape.
857
+ * History (undo/redo stacks) is NOT captured. Function fields like
858
+ * `ContainerNode.clipFromPose` are translated to string keys via the
859
+ * scene's registry; throws if any function field has no matching key. */
860
+ toJSON(): SerializedScene<TData, TLayer, TPose>;
861
+ /** Replace this scene's entire node + layer state in place from a snapshot
862
+ * produced by `toJSON()`. Unlike `sceneFromJSON`, the existing Scene
863
+ * instance is preserved — holders such as `<SceneCanvas>` keep their
864
+ * reference. History (undo/redo) is cleared, matching `sceneFromJSON`.
865
+ * Bumps `getVersion()` and notifies subscribers exactly once. Selected
866
+ * ids the snapshot does not hold leave the selection, and every pose
867
+ * override is cleared.
868
+ *
869
+ * Throws inside any other edit — `batch`, `untracked`, `applyBatch`, an
870
+ * undo — which would revert to a state this replaces. Throws on an unsupported version or unknown registry/layer ids; on a
871
+ * malformed snapshot the scene is left empty or partially populated (callers should treat a
872
+ * `loadState` throw as fatal and reload). Snapshots from `toJSON()` are
873
+ * always well-formed. */
874
+ loadState(json: SerializedScene<TData, TLayer, TPose>): void;
875
+ subscribe(listener: () => void): () => void;
876
+ /** Monotonically increasing version. Snapshot for `useSyncExternalStore`. */
877
+ getVersion(): number;
878
+ }
879
+
880
+ /** Pixel dimensions of the canvas viewport. */
881
+ interface ViewportDims {
882
+ width: number;
883
+ height: number;
884
+ }
885
+ /** Options for {@link fitViewToBounds}. */
886
+ interface FitViewToBoundsOptions {
887
+ /** Inset (in CSS px) around the bounds. Default 16. */
888
+ padding?: number;
889
+ /** Defaults to the kit-wide max zoom (`DEFAULT_MAX_ZOOM`). */
890
+ maxScale?: number;
891
+ /** Defaults to the kit-wide min zoom (`DEFAULT_MIN_ZOOM`). */
892
+ minScale?: number;
893
+ /**
894
+ * Fit mode:
895
+ * - `'contain'` (default): uniform scale = `min(availW/w, availH/h)`. Bounds fit entirely; one axis has letterboxing.
896
+ * - `'fill'`: uniform scale = `max(...)`. Bounds overflow viewport on one axis.
897
+ * - `'stretch'`: per-axis scale. Bounds match viewport exactly; scale is non-uniform.
898
+ */
899
+ mode?: 'contain' | 'fill' | 'stretch';
900
+ /**
901
+ * Where bounds that overflow the viewport on an axis sit, which happens when
902
+ * `minScale` stops the fit or `mode` is `'fill'`. `'center'` (default) shows
903
+ * their middle; `'start'` shows their left or top edge, inset by `padding`.
904
+ * An axis that fits is centered either way.
905
+ */
906
+ anchor?: 'center' | 'start';
907
+ }
908
+ /**
909
+ * Compute the target {@link View} that fits `bounds` (world space) inside
910
+ * `viewportDims` (CSS px). The bounds are centered in the viewport with
911
+ * uniform padding on all sides; the resulting scale is clamped to the
912
+ * configured min/max.
913
+ *
914
+ * Empty / zero-sized bounds or viewports cannot be fit — in that case this
915
+ * returns `currentView` unchanged and logs a `console.warn`.
916
+ */
917
+ declare function fitViewToBounds(bounds: FramedBox, viewportDims: ViewportDims, currentView: View, opts?: FitViewToBoundsOptions): View;
918
+
919
+ /**
920
+ * `Paint`'s discriminant, open on the string the way `ChromeId` is: the
921
+ * kinds the kit ships, plus whatever a consumer registers.
922
+ */
923
+ type PaintKind = 'solid' | 'linear-gradient' | 'radial-gradient' | 'conic-gradient' | TileKind | 'texture' | (string & {});
924
+ /**
925
+ * A set of kinds an editor offers as one choice. Kinds sharing a family show
926
+ * as a single segment in a kind bar, named by the family, and the member is
927
+ * picked inside that segment's body. The built-in tiles and `texture` are the
928
+ * `patternFamily`.
929
+ */
930
+ interface PaintKindFamily {
931
+ id: string;
932
+ label: string;
933
+ /** Glyph for the family's segment. */
934
+ icon?: IconRef;
935
+ }
936
+ /** What a registered kind's editor renders. `PaintInput` in `@weasel-js/ui`
937
+ * is the control that mounts it. */
938
+ interface PaintKindEditorProps {
939
+ value: Paint;
940
+ onInput?(next: Paint): void;
941
+ onChange(next: Paint): void;
942
+ }
943
+ /**
944
+ * One paint kind: the renderer's draw slots, plus what an editor and a
945
+ * serializer read.
946
+ *
947
+ * `seed`, `label` and `colorOf` are the editor's slots and every kind has
948
+ * them. The rest are optional because a kind may not need them.
949
+ */
950
+ interface PaintKindEntry extends PaintDrawKind {
951
+ label: string;
952
+ /** Glyph naming this kind in an editor's kind bar. A kind without one is
953
+ * named by its `label`. */
954
+ icon?: IconRef;
955
+ /** The family this kind is offered under; see {@link PaintKindFamily}. A
956
+ * kind without one is its own segment. */
957
+ family?: PaintKindFamily;
958
+ /** A paint of this kind seeded from a color — what an editor writes when a
959
+ * consumer switches a solid to this kind. */
960
+ seed(fromColor: string): Paint;
961
+ /** The single color this paint shows, or `undefined` when it has none. */
962
+ colorOf(paint: Paint): string | undefined;
963
+ /** Editor slot. */
964
+ Editor?: ComponentType<PaintKindEditorProps>;
965
+ /**
966
+ * The stop list this paint reads as. With `fromStops`, it is what makes a
967
+ * kind a gradient: `listGradientKinds` returns the kinds carrying both, and
968
+ * `switchGradientKind` converts between any two of them through the list.
969
+ */
970
+ stopsOf?(paint: Paint): GradStop[];
971
+ /** A paint of this kind built from a stop list, in `bounds` units. The
972
+ * converse of `stopsOf`; supply both or neither. */
973
+ fromStops?(stops: GradStop[]): Paint;
974
+ /**
975
+ * The `<defs>` entry backing a `url(#id)` reference.
976
+ *
977
+ * SVG has paint servers for two gradients and a pattern and nothing else, so
978
+ * a kind beyond those has no element to target: write a foreign-namespaced
979
+ * one under the `wzl:` prefix `@weasel-js/svg` declares on the root whenever
980
+ * a document holds such a paint. That package emits the fallback color
981
+ * beside the reference on its own, from `colorOf`.
982
+ */
983
+ toSvg?(id: string, fill: Paint): string;
984
+ }
985
+ /**
986
+ * A consumer's own paint, typed as a `Paint`.
987
+ *
988
+ * `Paint` stays a closed union: opening its discriminant would widen every
989
+ * built-in member and break the narrowing the kit's own branches depend on.
990
+ * A registered kind declares its own interface instead and passes it through
991
+ * here — the kit reads only `kind` and hands the whole object back to that
992
+ * kind's slots.
993
+ */
994
+ declare function asPaint<T extends {
995
+ kind: string;
996
+ }>(paint: T): Paint;
997
+
998
+ /**
999
+ * The paint-kind registry — what makes `Paint` open. The built-in kinds
1000
+ * are registered here at module load so an editor's kind bar can enumerate
1001
+ * every kind through one list.
1002
+ *
1003
+ * Every entry is also handed to the renderer's own registry, which reads only
1004
+ * its draw slots. A built-in kind has none: its render slot is a branch in the
1005
+ * GL renderer and its serialize slot lives in `@weasel-js/svg`.
1006
+ */
1007
+
1008
+ /** The family the built-in tiles and `texture` are offered under. A consumer's
1009
+ * own pattern kind joins it by naming this as its `family`. */
1010
+ declare const patternFamily: PaintKindFamily;
1011
+ /** A tile paint seeded from a color. `units: 'bounds'` anchors the tile to the
1012
+ * node's box, so the texture travels with the shape. */
1013
+ declare function seedTile(kind: TileKind, color: string): TilePaint;
1014
+ /** Resolves with the entry for a kind that is loaded on first use. */
1015
+ type PaintKindLoader = () => Promise<PaintKindEntry>;
1016
+ /** Every registered paint kind, with the overrides each displaced. */
1017
+ declare const paintKindRegistry: Reflection<PaintKindEntry>;
1018
+ /** Register a paint kind. Returns a disposer that removes it. Re-registering an
1019
+ * existing id is an override; disposing it uncovers whatever it displaced. */
1020
+ declare function registerPaintKind(entry: PaintKindEntry): () => void;
1021
+ /**
1022
+ * Declare a paint kind that is loaded the first time something looks it up,
1023
+ * so its code stays out of the bundle until a paint of it appears — typically
1024
+ * `() => import('./myKind').then((m) => m.myKindEntry)`.
1025
+ *
1026
+ * Until it lands the kind is unregistered: the renderer draws nothing for its
1027
+ * paints, and every other reader treats it as unknown. Registering it fires
1028
+ * `paintKindRegistry`'s subscribers. Call `warmPaintKinds` to load ahead of
1029
+ * the first frame instead.
1030
+ *
1031
+ * A kind that is already registered never calls its loader. Returns a
1032
+ * disposer that removes the loader.
1033
+ */
1034
+ declare function registerPaintKindLoader(id: string, load: PaintKindLoader): () => void;
1035
+ /** The entry for `kind`, or `undefined`. A lookup that misses on a kind with
1036
+ * a loader starts that load; see {@link registerPaintKindLoader}. */
1037
+ declare function getPaintKind(kind: string | undefined): PaintKindEntry | undefined;
1038
+ /** Every registered kind, built-ins first, in registration order. The same
1039
+ * array until the registry changes. */
1040
+ declare function listPaintKinds(): readonly PaintKindEntry[];
1041
+ /** Every registered gradient kind — the ones that read as and build from a
1042
+ * stop list — in registration order. The same array until the registry
1043
+ * changes. */
1044
+ declare function listGradientKinds(): readonly PaintKindEntry[];
1045
+ /**
1046
+ * `paint` retargeted to gradient kind `kind`, or `undefined` when either side
1047
+ * is not a gradient kind.
1048
+ *
1049
+ * Between two of the stop gradients this is `withGradientKind`, which carries
1050
+ * the geometry. Any other pair goes through the stop list — `stopsOf` on the
1051
+ * way out, `fromStops` on the way in — keeping `interpolate` and `opacity`.
1052
+ * Lossy wherever the kinds hold different information.
1053
+ */
1054
+ declare function switchGradientKind(paint: Paint, kind: PaintKind): Paint | undefined;
1055
+ /** The registry entry for a paint, or `undefined` when its kind is unknown. */
1056
+ declare function paintKindOf(fill: Paint): PaintKindEntry | undefined;
1057
+ /** @internal Test helper — do not call from product code. */
1058
+ declare function _resetPaintKindsForTests(): void;
1059
+
1060
+ /** The paint a path node wears, resolved: what an action that turns ink into
1061
+ * geometry reads from a node and tells a consumer to put on a result. */
1062
+ interface PathPaint {
1063
+ /** `null` is no fill. */
1064
+ fill: Fill | null;
1065
+ /** Absent for no stroke. */
1066
+ stroke?: Stroke;
1067
+ }
1068
+ /** {@link PathPaint} of a node that keeps its paint in `data.fill` and
1069
+ * `data.stroke`, as the built-in path painter draws it: a stroke with no
1070
+ * `paint` is none, and an undeclared fill is the default shape fill unless
1071
+ * the node is stroked. */
1072
+ declare function pathPaintOf(data: {
1073
+ fill?: Fill | null;
1074
+ stroke?: Stroke | null;
1075
+ }): PathPaint;
1076
+
1077
+ /**
1078
+ * Create Outlines: replace each selected text node with path nodes carrying
1079
+ * its glyph outlines, giving up editability for geometry — the destructive
1080
+ * conversion every vector editor has. One path per paint the text wears; one
1081
+ * undoable batch; the replacement takes the text node's slot, so stacking
1082
+ * order is unchanged.
1083
+ */
1084
+
1085
+ /** What a path minted by an outline action must carry — see
1086
+ * {@link CreateOutlinesAdapter.createPathNode}. */
1087
+ interface OutlinePathSpec extends PathPaint {
1088
+ /** The parent the path goes under: the source's own, or the container
1089
+ * minted to hold a source's several paths. */
1090
+ parent: string | null;
1091
+ }
1092
+ /** What `applyCreateOutlines` and `applyOutlineStroke` read and write through. */
1093
+ interface CreateOutlinesAdapter {
1094
+ getSelection(): readonly NodeId[] | readonly string[];
1095
+ /** The text node behind `id`, or `undefined` for anything else. */
1096
+ getTextSource(id: NodeId): TextNodeSource | undefined;
1097
+ /**
1098
+ * Optional: the world-space path of the path node behind `id`, and the
1099
+ * paint it wears. Outline Stroke reads both, and passes over a node that
1100
+ * lacks either.
1101
+ */
1102
+ getWorldPath?(id: NodeId): Path | undefined;
1103
+ getPaint?(id: NodeId): PathPaint | undefined;
1104
+ /**
1105
+ * Optional: the frame the node behind `id` draws its stroke in, as the
1106
+ * matrix taking that frame to world (`poseFrameOf`); null or absent for a
1107
+ * node drawn straight. Outline Stroke skews and stretches a world-width
1108
+ * stroke with it. Without it every stroke is outlined in world.
1109
+ */
1110
+ getStrokeFrame?(id: NodeId): Affine | null | undefined;
1111
+ /**
1112
+ * Mint one path node of node `sourceId`'s outlines. `path` is in world
1113
+ * space. The node must wear `spec`'s fill and stroke — a text whose runs
1114
+ * differ in paint gets one path per paint, and a filled node whose stroke
1115
+ * is outlined gets one for the fill and one for the stroke — and sit under
1116
+ * `spec.parent`. The kit places it; only the consumer knows its data shape,
1117
+ * so anything else of the source's `data` worth keeping is the adapter's to
1118
+ * copy: onto this path when it stands alone in the source's slot, onto the
1119
+ * container when `createContainerNode` minted one.
1120
+ */
1121
+ createPathNode(path: Path, sourceId: NodeId, spec: OutlinePathSpec): {
1122
+ id: string;
1123
+ };
1124
+ /**
1125
+ * Mint the container that holds one source's several paths, under `parent`.
1126
+ * `bounds` is the world envelope of the paths. The kit puts the container in
1127
+ * the source's slot and the paths inside it, back to front. Without this,
1128
+ * the paths are laid flat in that slot instead.
1129
+ */
1130
+ createContainerNode?(sourceId: NodeId, spec: {
1131
+ parent: string | null;
1132
+ bounds: Rect;
1133
+ }): {
1134
+ id: string;
1135
+ };
1136
+ /** Full node for `id`, so undo restores the text node whole. */
1137
+ getNode(id: string): {
1138
+ id: string;
1139
+ } | undefined | null;
1140
+ /** The tree: each path is inserted at its source node's index among its
1141
+ * parent's children. */
1142
+ getParent(id: string): string | null;
1143
+ getChildren(parentId: string | null): string[];
1144
+ applyOps?(ops: Op[], label?: string): void;
1145
+ setSelection?(ids: NodeId[]): void;
1146
+ insertNode?(node: {
1147
+ id: string;
1148
+ }, index?: number): void;
1149
+ removeNode?(id: string): void;
1150
+ }
1151
+ /** Outcome of {@link applyCreateOutlines}. */
1152
+ type CreateOutlinesResult =
1153
+ /** `resultIds` are what replaced the text nodes at their level — a path,
1154
+ * a container, or a run of flat paths each — which is also what is now
1155
+ * selected in the text nodes' place. */
1156
+ {
1157
+ kind: 'applied';
1158
+ resultIds: string[];
1159
+ }
1160
+ /** Nothing selected is text with ink. */
1161
+ | {
1162
+ kind: 'noop';
1163
+ reason: 'no-text';
1164
+ }
1165
+ /** Some selected text has no outline geometry; nothing was changed. */
1166
+ | {
1167
+ kind: 'failed';
1168
+ reason: 'text-outlines';
1169
+ error: TextOutlinesError;
1170
+ };
1171
+ /**
1172
+ * Convert every text node in the selection to outlines, as one batch labeled
1173
+ * "Create Outlines". Other selected nodes are left alone and stay selected.
1174
+ * All or nothing: if any text node's face cannot supply outlines the scene is
1175
+ * untouched and the error comes back in the result.
1176
+ */
1177
+ declare function applyCreateOutlines(adapter: CreateOutlinesAdapter): CreateOutlinesResult;
1178
+
1179
+ /**
1180
+ * What each selected node gives a Boolean operation: its path, its glyph
1181
+ * outlines, or the region its ink covers once a stroke is counted.
1182
+ */
1183
+
1184
+ /**
1185
+ * What a stroked operand gives a Boolean operation.
1186
+ *
1187
+ * - `'ignore'`: its path, as though it had no stroke.
1188
+ * - `'unfilled'`: the region its stroke covers when it has no fill, as a line
1189
+ * or an open pencil stroke has none; its path when it is filled.
1190
+ * - `'include'`: what it paints — its fill and its stroke together, or the
1191
+ * stroke alone when it has no fill.
1192
+ *
1193
+ * Any mode but `'ignore'` needs {@link BooleansAdapter.getPaint}.
1194
+ */
1195
+ type BooleanStrokes = 'ignore' | 'unfilled' | 'include';
1196
+ /** Options for `applyBooleanOp`. */
1197
+ interface BooleanOpOptions {
1198
+ /** Default `'ignore'`. */
1199
+ strokes?: BooleanStrokes;
1200
+ /** The view scale a `{ px }` stroke width resolves against: one number, or
1201
+ * the view's own scale per axis. Default 1. */
1202
+ scale?: number | Scale2;
1203
+ }
1204
+
1205
+ /**
1206
+ * Pure action core for path boolean operations. Resolves the current
1207
+ * selection into z-ordered paths, runs the chosen op, and dispatches a
1208
+ * single batch of `Op`s (delete sources + insert results + set selection).
1209
+ */
1210
+
1211
+ /** Boolean op identifiers: the five Pathfinder primaries, and Crop, Trim, and Merge. */
1212
+ type BooleanOp = 'union' | 'intersect' | 'subtract' | 'exclude' | 'divide' | 'crop' | 'trim' | 'merge';
1213
+ /** Adapter the hook and the pure core both consume. */
1214
+ interface BooleansAdapter {
1215
+ getSelection(): readonly NodeId[] | readonly string[];
1216
+ getWorldPath(id: NodeId): Path | undefined;
1217
+ /**
1218
+ * Optional: the text node behind `id`, for an id `getWorldPath` has no path
1219
+ * for. Its glyph outlines (`textToPath`) become the operand, so text can be
1220
+ * cut, united or intersected like any shape.
1221
+ */
1222
+ getTextSource?(id: NodeId): TextNodeSource | undefined;
1223
+ /**
1224
+ * Optional: the paint the path node behind `id` wears. An operation told to
1225
+ * count strokes (`BooleanOpOptions.strokes`) reads it to learn whether the
1226
+ * node is stroked and whether it is filled; without it every operand is its
1227
+ * path alone.
1228
+ */
1229
+ getPaint?(id: NodeId): PathPaint | undefined;
1230
+ /**
1231
+ * Optional: the frame the node behind `id` draws its stroke in, as the
1232
+ * matrix taking that frame to world (`poseFrameOf`); null or absent for a
1233
+ * node drawn straight. A counted world-width stroke is skewed and stretched
1234
+ * with it. Without it every stroke is outlined in world.
1235
+ */
1236
+ getStrokeFrame?(id: NodeId): Affine | null | undefined;
1237
+ compareZ(a: NodeId, b: NodeId): number;
1238
+ /**
1239
+ * Mint a new node from a boolean-op result `Path`. `producedBy` names the
1240
+ * op that synthesized it — adapters that store provenance (e.g. for a
1241
+ * layer-panel icon) record it; others ignore the arg. `sourceId` is the
1242
+ * source the result stands in for: the topmost, except that each piece of
1243
+ * a Divide, Crop, Trim, or Merge names the topmost source it was cut from. Give the
1244
+ * node that source's parent, or the kit's reorder cannot find it there.
1245
+ * `paint` is passed when that source's stroke went into the geometry, and
1246
+ * the node must wear it as given: wearing the source's stroke again would
1247
+ * draw it twice. Without `paint`, give it that source's paint. The kit never
1248
+ * reads a node's `data`: anything else the result should keep of its source,
1249
+ * a name say, is the adapter's to copy from `sourceId`.
1250
+ */
1251
+ createPathNode(path: Path, producedBy: BooleanOp, sourceId: NodeId, paint?: PathPaint): {
1252
+ id: string;
1253
+ };
1254
+ /**
1255
+ * The full object for an id. The delete ops capture it, so their `invert`
1256
+ * (an insert) restores the complete object on undo.
1257
+ */
1258
+ getNode(id: NodeId): {
1259
+ id: string;
1260
+ } | undefined | null;
1261
+ /**
1262
+ * The tree. The kit reads each source's slot among its siblings through
1263
+ * `getParent` and `getChildren`, and moves each result into the slot of
1264
+ * the topmost source in its own source's parent through `setChildOrder`.
1265
+ * `defaultCommitAdapter` supplies all three, and `getNode`.
1266
+ */
1267
+ getParent(id: string): string | null;
1268
+ getChildren(parentId: string | null): string[];
1269
+ setChildOrder(parentId: string | null, ids: string[]): void;
1270
+ applyOps?(ops: Op[], label?: string): void;
1271
+ setSelection?(ids: NodeId[]): void;
1272
+ insertNode?(node: {
1273
+ id: string;
1274
+ }): void;
1275
+ removeNode?(id: string): void;
1276
+ }
1277
+ /** Outcome reported back to callers (lets the hook surface no-op signals). */
1278
+ type BooleanOpResult = {
1279
+ kind: 'applied';
1280
+ resultIds: string[];
1281
+ } | {
1282
+ kind: 'noop';
1283
+ reason: 'no-paths' | 'too-few-for-subtract' | 'empty-result';
1284
+ }
1285
+ /** A text operand had no outline geometry. Nothing was changed: an op that
1286
+ * quietly dropped the operand would commit a different shape than asked. */
1287
+ | {
1288
+ kind: 'failed';
1289
+ reason: 'text-outlines';
1290
+ error: TextOutlinesError;
1291
+ };
1292
+ /** One path a Boolean operation would make. */
1293
+ interface BooleanPreviewPiece {
1294
+ path: Path;
1295
+ /** The source the piece stands in for; see `BooleansAdapter.createPathNode`. */
1296
+ sourceId: NodeId;
1297
+ /** Set when that source's stroke went into `path`: the paint the piece wears. */
1298
+ paint?: PathPaint;
1299
+ }
1300
+ /** What {@link previewBooleanOp} answers: the pieces, or why there are none. */
1301
+ type BooleanOpPreview = {
1302
+ kind: 'pieces';
1303
+ pieces: BooleanPreviewPiece[];
1304
+ } | Exclude<BooleanOpResult, {
1305
+ kind: 'applied';
1306
+ }>;
1307
+ /**
1308
+ * What {@link applyBooleanOp} would make of the selection, without minting a
1309
+ * node or committing anything: for drawing an operation before it is applied.
1310
+ */
1311
+ declare function previewBooleanOp(adapter: BooleansAdapter, op: BooleanOp, opts?: BooleanOpOptions): BooleanOpPreview;
1312
+ /**
1313
+ * Run one Boolean operation over the selected paths and commit the result as a
1314
+ * single undoable batch.
1315
+ *
1316
+ * Operands are ordered back-to-front, which is what makes `subtract` mean
1317
+ * "everything in front removed from the backmost shape". Returns without
1318
+ * mutating anything when the selection holds no paths, or too few for the
1319
+ * requested operation. `opts.strokes` says what a stroked operand gives.
1320
+ */
1321
+ declare function applyBooleanOp(adapter: BooleansAdapter, op: BooleanOp, opts?: BooleanOpOptions): BooleanOpResult;
1322
+
1323
+ /**
1324
+ * Read-only state that affordances consult on every render and hit-test
1325
+ * call. Built via `buildChromeState` and held across renders, so affordances
1326
+ * must not cache anything they read from it.
1327
+ */
1328
+ interface ChromeState {
1329
+ /** Currently selected ids. Live; reflects useSelection's React state,
1330
+ * less any on a layer this view does not paint. */
1331
+ readonly selection: readonly NodeId[];
1332
+ /** True when the canvas is in multi-mode AND >= 2 ids are selected, and
1333
+ * still >= 2 once `selection` drops the ones this view does not paint. */
1334
+ readonly multiActive: boolean;
1335
+ /** Bounds for any selection member id. Honors active-tool overlay state
1336
+ * (move/resize/rotate ghosts → ghost bounds; otherwise → committed
1337
+ * pose bounds). Returns null for unknown ids or ids whose bounds aren't
1338
+ * computable. */
1339
+ boundsOf(id: string): FramedBox | null;
1340
+ /** Multi-union AABB when `multiActive`. Recomputed from `boundsOf` over
1341
+ * every selected id on each read, expanding rotated members to the extent
1342
+ * of their ink; null otherwise. */
1343
+ readonly unionBounds: FramedBox | null;
1344
+ /** Active modifier state at the moment of the call. */
1345
+ readonly modifiers: ModifierState;
1346
+ /** True iff the node's pose-descriptor declares it can carry a rotation.
1347
+ * Affordances consult this to decide whether to expose rotate cursors /
1348
+ * drag-bands. Defaults to `true` when the descriptor doesn't declare
1349
+ * (back-compat) or when the id is unknown — the rotation gesture will
1350
+ * no-op visually for poses without AABB fields, but the affordance
1351
+ * doesn't lie about the cursor. Optional on the interface so unit-test
1352
+ * call sites that construct `ChromeState` by hand keep compiling;
1353
+ * affordances should treat an absent predicate as "true". */
1354
+ canRotate?(id: string): boolean;
1355
+ /** Whether a scene layer reaches the screen in the view this state was
1356
+ * built for — its `layerVisibility` / `layerOrder`, as `ViewApi` answers
1357
+ * it. Absent: the view paints every layer the scene shows. An affordance
1358
+ * that reads it puts no chrome on a node whose layer it says `false` to. */
1359
+ layerIsPainted?(layerId: string): boolean;
1360
+ }
1361
+ /** Whether chrome goes on something painted on `layer`, as `gate` — a
1362
+ * `ChromeState`, a `ViewApi` — says. No layer, or no gate: it does. */
1363
+ declare function paintsLayer(gate: {
1364
+ layerIsPainted?(layerId: string): boolean;
1365
+ } | null | undefined, layer: string | undefined): boolean;
1366
+
1367
+ /**
1368
+ * A single interactive piece of chrome. Affordances declare interactive regions in a target's
1369
+ * *local* frame; `composeAffordanceLayer` composes the target's bounds transform (rotation
1370
+ * around the AABB center, when present) for both paint and hit-test, so the affordance never
1371
+ * touches rotation, view.scale, or world↔screen math.
1372
+ */
1373
+ interface Affordance {
1374
+ /** Stable id for debug overlays + visibility maps. */
1375
+ id: string;
1376
+ /** This affordance's interactive regions. Each lives in some target id's local frame (or
1377
+ * the world frame when `targetId` is `null`). `[]` means no chrome for this state. */
1378
+ regions(state: ChromeState): readonly AffordanceRegion[];
1379
+ /** Optional non-interactive decoration (e.g., a leader line from a bounds edge to a
1380
+ * handle). Receives raw state + view because it may live outside any single target's
1381
+ * local frame. */
1382
+ decorate?(state: ChromeState, view: View): DrawCommand[];
1383
+ }
1384
+ /**
1385
+ * One interactive region produced by an affordance. The framework owns
1386
+ * the local↔world transform for `targetId` (when non-null), so `shape`,
1387
+ * `paint.sizePx`, and `hitRadiusPx` are always specified in coordinates
1388
+ * the affordance can reason about directly.
1389
+ */
1390
+ interface AffordanceRegion<TScratch = unknown> {
1391
+ /** Stable id, e.g. `corner-min-min`. Used for debug overlays + a11y. */
1392
+ id: string;
1393
+ /** A chrome-caps id gating this region on top of its affordance's. */
1394
+ chromeId?: string;
1395
+ /** Target id whose `state.boundsOf(targetId)` defines this region's
1396
+ * local frame: the bounds' `rotation` and `transform`, as `poseFrameOf`
1397
+ * composes them about the box center. Pass
1398
+ * `null` for affordances anchored to the viewport / world frame
1399
+ * (identity transform). */
1400
+ targetId: string | null;
1401
+ /** Region geometry, expressed in the target's local frame.
1402
+ *
1403
+ * - `point` — square hit of half-extent `hitRadiusPx` screen pixels,
1404
+ * axis-aligned on screen unless `turned`. `standoff` pushes the anchor `px`
1405
+ * screen pixels off the edge whose outward normal (target-local) is
1406
+ * `normal`, measured along that normal as it lands on screen — for
1407
+ * chrome that floats a fixed distance off an edge at any zoom.
1408
+ * - `rect` — axis-aligned rect (target rotation applies).
1409
+ * - `annulus` — outer ellipse minus inner rect cutout, for zones that sit *around* the
1410
+ * AABB (e.g. a rotate-on-hover band).
1411
+ * - `outline` — within `hitRadiusPx` screen pixels of `path`'s outline, either side of it,
1412
+ * for chrome that is a path's own edge (path edit's segments). Hit-only. */
1413
+ shape: {
1414
+ kind: 'point';
1415
+ x: number;
1416
+ y: number;
1417
+ hitRadiusPx: number;
1418
+ standoff?: {
1419
+ px: number;
1420
+ normal: {
1421
+ x: number;
1422
+ y: number;
1423
+ };
1424
+ };
1425
+ /** Turn the square to the target, at the angle the target's x axis
1426
+ * lands on screen (`screenAngleOf`) — for handles painted turned. */
1427
+ turned?: boolean;
1428
+ /** The body this point is a corner of: its target-local size, and
1429
+ * which way leads out of it on each axis. While the body spans under
1430
+ * four `hitRadiusPx` on an axis on screen, only the outward half of
1431
+ * the square on that axis takes a press, so a small body can still be
1432
+ * grabbed. The cut runs along the square's own axes: pair it with
1433
+ * `turned` on a target that can rotate. */
1434
+ cornerOf?: {
1435
+ width: number;
1436
+ height: number;
1437
+ outward: {
1438
+ x: -1 | 1;
1439
+ y: -1 | 1;
1440
+ };
1441
+ };
1442
+ /** The body this point is an edge midpoint of: its target-local
1443
+ * size. While either side spans under `EDGE_HANDLE_MIN_RADII`
1444
+ * `hitRadiusPx` on screen, the point is neither hit nor painted, so it
1445
+ * cannot crowd the corners or cover the middle of a small body. */
1446
+ edgeOf?: {
1447
+ width: number;
1448
+ height: number;
1449
+ };
1450
+ } | {
1451
+ kind: 'rect';
1452
+ x: number;
1453
+ y: number;
1454
+ width: number;
1455
+ height: number;
1456
+ } | {
1457
+ kind: 'annulus';
1458
+ /** Outer-ellipse center (target-local). */
1459
+ cx: number;
1460
+ cy: number;
1461
+ /** Outer-ellipse semi-axes (target-local). */
1462
+ rx: number;
1463
+ ry: number;
1464
+ /** Inner rect (target-local) — the cutout. Typically the
1465
+ * selection's AABB. */
1466
+ innerX: number;
1467
+ innerY: number;
1468
+ innerWidth: number;
1469
+ innerHeight: number;
1470
+ /** Minimum band thickness outside the inner rect, in **screen**
1471
+ * pixels. The framework widens `rx`/`ry` to at least
1472
+ * `innerHalfExtent + pxExtent(minBandPx, view.scale)` on each axis
1473
+ * for both paint and hit-test.
1474
+ *
1475
+ * In screen pixels because the clamp has to know the view and the affordance
1476
+ * doesn't: `ChromeState` carries no scale. */
1477
+ minBandPx?: number;
1478
+ } | {
1479
+ kind: 'outline';
1480
+ path: PolygonPath;
1481
+ hitRadiusPx: number;
1482
+ };
1483
+ /** Optional paint. World position is derived from `shape` + target
1484
+ * transform; visual size stays in screen pixels (so handles don't
1485
+ * warp under zoom or non-uniform scale). Omit for hit-only regions.
1486
+ *
1487
+ * - `square` — small fixed-size square (only valid over `point` shapes).
1488
+ * - `annulus` — fill + stroke the annulus ring (only valid over `annulus` shapes).
1489
+ * - `custom` — emit arbitrary draw commands; receives a {@link CustomPaintContext}. */
1490
+ paint?: {
1491
+ kind: 'square';
1492
+ sizePx: number;
1493
+ fill?: CommandFill;
1494
+ stroke?: CommandStroke;
1495
+ } | {
1496
+ kind: 'annulus';
1497
+ fill?: CommandFill;
1498
+ stroke?: CommandStroke;
1499
+ insetPx?: number;
1500
+ } | {
1501
+ kind: 'custom';
1502
+ draw: (ctx: CustomPaintContext) => DrawCommand[];
1503
+ };
1504
+ /** Discriminator a press on this region reports as `AffordanceHit.kind` —
1505
+ * the string routing specs match on (`'handle:top-left'`,
1506
+ * `'rotate-handle'`, `'anchor:3'`). Omit for regions that only exist
1507
+ * inside a consumer-registered layer, where the layer id is the
1508
+ * discriminator; `buildAffordanceAt` falls back to
1509
+ * `<affordanceId>:<regionId>`. */
1510
+ hitKind?: string;
1511
+ /** Cursor to show while hovering this region: one spec, or one worked out
1512
+ * from where the pointer is (`at`, in world coords). */
1513
+ cursor?: CursorSpec | ((at: {
1514
+ x: number;
1515
+ y: number;
1516
+ }, view: View) => CursorSpec);
1517
+ /** `'exclusive'` bars every binding whose target doesn't consult the
1518
+ * affordance. Read only when the affordance is composed into a
1519
+ * consumer-registered layer; kit chrome routes through
1520
+ * `buildAffordanceAt`, which reports `'shared'`. */
1521
+ strength?: 'exclusive' | 'shared';
1522
+ /** Which gestures an exclusive claim bars. Omitted bars all of them. */
1523
+ claimedKinds?: readonly ClaimableGesture[];
1524
+ /** Drag binding produced when this region is hit. Called lazily, so state snapshots
1525
+ * (e.g., capturing per-leaf poses at click time) belong inside `bind()`, not inside
1526
+ * `regions()`. */
1527
+ bind(): AffordanceBinding<TScratch>;
1528
+ }
1529
+ /** Context passed to a region's `paint.kind === 'custom'` draw callback. */
1530
+ interface CustomPaintContext {
1531
+ /** World-space mapping of `shape`. For `point`, only `x`/`y` are set.
1532
+ * For `rect`, all four fields are set. */
1533
+ world: {
1534
+ x: number;
1535
+ y: number;
1536
+ width?: number;
1537
+ height?: number;
1538
+ };
1539
+ /** The original local shape (same object identity as `region.shape`). */
1540
+ local: AffordanceRegion['shape'];
1541
+ view: View;
1542
+ state: ChromeState;
1543
+ }
1544
+ /**
1545
+ * Result of an affordance hit. `initialScratch` is what the region already knows (which
1546
+ * corner, which target id) so the action that picks up the drag doesn't re-derive it. It
1547
+ * reaches the matching action through `InvocationCtx.drag.affordance`.
1548
+ */
1549
+ interface AffordanceBinding<TScratch = unknown> {
1550
+ initialScratch?: TScratch;
1551
+ }
1552
+ /**
1553
+ * The fields `buildAffordanceAt` lifts out of a region's `initialScratch` when it turns a
1554
+ * region hit into an `AffordanceHit`. Scratch is otherwise opaque; these names mean the same
1555
+ * thing to every affordance. An affordance that doesn't set them produces a hit without
1556
+ * those fields.
1557
+ */
1558
+ interface CommonAffordanceScratch {
1559
+ /** The node (or `MULTI_RESIZE_TARGET_ID`) this chrome acts on. Becomes
1560
+ * `AffordanceHit.targetIds`. */
1561
+ targetId?: string;
1562
+ /** For resize chrome: which corner stays pinned. Mirrors the kit's
1563
+ * `ResizeAnchor`, spelled inline so `affordances/` doesn't take a type
1564
+ * dependency on the gesture layer for one field. */
1565
+ anchor?: {
1566
+ x: 'min' | 'max' | 'free';
1567
+ y: 'min' | 'max' | 'free';
1568
+ };
1569
+ /** World-space invariant point of the transform — the fixed corner for a
1570
+ * resize, the pivot for a rotation. */
1571
+ fixedPoint?: {
1572
+ x: number;
1573
+ y: number;
1574
+ };
1575
+ }
1576
+ /**
1577
+ * What a **registered layer's** `hitTest` returns. The added fields are how a consumer's own
1578
+ * chrome says the things kit chrome says through `AffordanceRegion` — which cursor to show,
1579
+ * and whether it owns the point outright.
1580
+ */
1581
+ interface LayerHit<TScratch = unknown> extends AffordanceBinding<TScratch> {
1582
+ /** Cursor while the pointer is over this hit. Reaches the hover-cursor
1583
+ * pump as `AffordanceHit.cursor`, the same path kit chrome uses. */
1584
+ cursor?: CursorSpec;
1585
+ /** `'exclusive'` bars every binding whose target doesn't consult the affordance. Omitted
1586
+ * means `'shared'`. Becomes `AffordanceHit.strength`. */
1587
+ strength?: 'exclusive' | 'shared';
1588
+ /** Which gestures an exclusive claim bars. Omitted bars all of them. */
1589
+ claimedKinds?: readonly ClaimableGesture[];
1590
+ }
1591
+
1592
+ /**
1593
+ * Several consecutive layers composited as one.
1594
+ *
1595
+ * A layer's own `effects` run over that layer alone, which is the wrong
1596
+ * picture whenever a pass reads neighboring pixels: `blur(A over B)` is not
1597
+ * `blur(A) over blur(B)`. A group draws its members into one buffer, runs one
1598
+ * chain over it, and composites the result back once.
1599
+ *
1600
+ * Membership is by `RenderLayer.id` — the same names `layerOrder` and
1601
+ * `layerVisibility` use, not the `layers` map's slot keys.
1602
+ *
1603
+ * Only *consecutive* members share a buffer. A group whose members are
1604
+ * separated in the render order is drawn as one bracket per run, with a
1605
+ * warning.
1606
+ *
1607
+ * This is a render-stack bracket, not a scene `ContainerNode`.
1608
+ */
1609
+ interface LayerGroup {
1610
+ /** Names the group in warnings; not a layer id and never drawn. */
1611
+ id: string;
1612
+ /**
1613
+ * Member layer ids. Order here is ignored — the render order decides.
1614
+ *
1615
+ * A name claims that layer and every layer under it in the `:` namespace, so
1616
+ * `'scene'` covers the `scene:<layerId>` layers a scene with declared layers
1617
+ * draws as. The separator is required: `'scene'` does not reach `scenery`.
1618
+ * A name matching no layer being drawn is warned about.
1619
+ */
1620
+ layers: readonly string[];
1621
+ /** Passes over the group's combined pixels, in order. A thunk is re-read on
1622
+ * every frame, so an animating radius costs no React render. */
1623
+ effects?: readonly Effect[] | ((view: View, dims: Dims) => readonly Effect[]);
1624
+ /** Opacity applied to the group's composited result, not to each member. */
1625
+ alpha?: number;
1626
+ /** 4×5 color matrix (row-major, 20 numbers) applied to the composited
1627
+ * result. See `GroupDrawCommand.colorMatrix`. */
1628
+ colorMatrix?: number[];
1629
+ /** How the composited result joins the layers under it. Default
1630
+ * `source-over`. See `GroupDrawCommand.composite`. */
1631
+ composite?: CompositeOp | BlendFactors;
1632
+ }
1633
+
1634
+ /**
1635
+ * When `drawLayers` asks the renderer to keep a layer's pixels between frames
1636
+ * (`GroupDrawCommand.retain`) rather than submit its commands again.
1637
+ *
1638
+ * A layer is retained once its `deps` have held for a frame, the view has held
1639
+ * since the frame before (for a world-space layer, whose pixels move with
1640
+ * it), and it holds at least `minCommands` drawing commands. A layer changing
1641
+ * every frame is never retained: drawing it into its surface and compositing
1642
+ * that costs more than drawing it.
1643
+ */
1644
+ interface LayerRetainPolicy {
1645
+ minCommands: number;
1646
+ }
1647
+ /** Measured on 1280x800 at dpr 2: an unchanged layer composites cheaper than
1648
+ * it submits from about 130 to 250 commands, depending on the layer count. */
1649
+ declare const DEFAULT_LAYER_RETAIN: LayerRetainPolicy;
1650
+
1651
+ /** Something outside React whose changes a paint reads — a mode registry, a
1652
+ * scoping lookup. A notification repaints the canvas; the listener takes no
1653
+ * arguments and the returned function unsubscribes. */
1654
+ interface RedrawSource {
1655
+ subscribe(listener: () => void): () => void;
1656
+ }
1657
+ /** The `subscribe` for a layer that draws `sources`: it notifies whenever any
1658
+ * of them does. A thunk is read when the subscription is made. */
1659
+ declare function subscribeToSources(sources: readonly {
1660
+ subscribe?: RedrawSource['subscribe'];
1661
+ }[] | (() => readonly {
1662
+ subscribe?: RedrawSource['subscribe'];
1663
+ }[])): RedrawSource['subscribe'];
1664
+
1665
+ /** Canvas size in CSS pixels, so layers don't have to know about DPR. */
1666
+ interface Dims {
1667
+ width: number;
1668
+ height: number;
1669
+ }
1670
+ /**
1671
+ * What a layer's `draw` threw, and which layer threw it. A throw that escaped
1672
+ * the frame loop would take the whole frame with it, every other layer
1673
+ * included.
1674
+ */
1675
+ interface LayerDrawFailure {
1676
+ layerId: string;
1677
+ error: unknown;
1678
+ }
1679
+ /** One layer's memoized output, keyed by layer id. Owned by the canvas that
1680
+ * calls `drawLayers`, not by `drawLayers` itself — the function is pure. */
1681
+ type LayerCommandCache = Map<string, {
1682
+ deps: readonly unknown[];
1683
+ cmds: DrawCommand[];
1684
+ /** Whether the last frame served `cmds` from here rather than drawing. */
1685
+ reused?: boolean;
1686
+ /** The view the last frame drew under. */
1687
+ view?: View;
1688
+ }>;
1689
+ /**
1690
+ * One layer of a canvas: `draw` turns `data` and the view into draw commands;
1691
+ * the other fields control caching, visibility, coordinate space and hit-testing.
1692
+ *
1693
+ * @template TData - The data object passed to each draw call.
1694
+ */
1695
+ interface RenderLayer<TData> {
1696
+ /** Unique identifier used in visibility maps and ordering arrays. When a
1697
+ * cache is in use, an id must identify the same logical layer across
1698
+ * frames — reusing it for a different layer can serve cross-layer commands. */
1699
+ id: string;
1700
+ /** Human-readable name for UI toggles. */
1701
+ label: string;
1702
+ /**
1703
+ * Emit a DrawCommand tree, in the coordinates `space` names. A world-space
1704
+ * layer must NOT apply the view transform itself.
1705
+ */
1706
+ draw: (data: TData, view: View, dims: Dims) => DrawCommand[];
1707
+ /**
1708
+ * Optional cache key. When present and a `LayerCommandCache` is supplied to
1709
+ * `drawLayers`, the layer's previous `DrawCommand[]` is reused as long as
1710
+ * every entry is `Object.is`-equal to the previous call's. A layer with no
1711
+ * `deps` rebuilds on every frame.
1712
+ *
1713
+ * **The returned commands must be treated as immutable.** A cached tree is
1714
+ * handed to the renderer again on later frames, so mutating a tree you
1715
+ * previously returned corrupts the cache silently rather than erroring.
1716
+ *
1717
+ * **Screen-space layers are not protected against a stale `view`/`dims`
1718
+ * the way world-space layers are** (see `space` below) — include them in
1719
+ * `deps` if `draw` reads them.
1720
+ */
1721
+ deps?: (data: TData, view: View, dims: Dims) => readonly unknown[];
1722
+ /** Whether the layer is shown when no explicit visibility entry exists.
1723
+ * Defaults to `true` when absent. */
1724
+ defaultVisible?: boolean;
1725
+ /** When true, the layer is always drawn regardless of the visibility map. */
1726
+ alwaysOn?: boolean;
1727
+ /**
1728
+ * Coordinate space the layer draws in.
1729
+ *
1730
+ * - `'world'` (default): the layer's `draw` returns world-space commands;
1731
+ * `drawLayers` wraps them in a `kind: 'group'` with `viewToMat3(view)`
1732
+ * automatically.
1733
+ * - `'screen'`: the layer's `draw` returns screen-space (CSS-pixel)
1734
+ * commands; `drawLayers` passes them through unchanged. World-anchored
1735
+ * chrome inside a screen-space layer must call `worldToScreen` or wrap
1736
+ * the relevant subset with `viewToMat3(view)` manually.
1737
+ */
1738
+ space?: 'world' | 'screen';
1739
+ /**
1740
+ * Where the layer learns that state `draw` reads, outside the scene and the
1741
+ * props, has changed. The canvas painting it subscribes while the layer is
1742
+ * mounted and repaints on every notification.
1743
+ */
1744
+ subscribe?: RedrawSource['subscribe'];
1745
+ /**
1746
+ * Full-screen passes run over this layer's own pixels before it joins the
1747
+ * frame. See `GroupDrawCommand.effects` for what a pass may read, and
1748
+ * {@link LayerGroup} to run one chain over several layers at once.
1749
+ */
1750
+ effects?: readonly Effect[];
1751
+ /**
1752
+ * Whether the renderer may keep this layer's pixels between frames and
1753
+ * composite them as one quad instead of drawing its commands again — see
1754
+ * {@link LayerRetainPolicy} for when `drawLayers` does. `false` never
1755
+ * retains it, `true` retains it whatever its size; either way only a layer
1756
+ * with `deps`, drawn through a cache, and without `effects`.
1757
+ */
1758
+ retain?: boolean;
1759
+ /**
1760
+ * Optional hit-test for **consumer-attached** layers.
1761
+ *
1762
+ * Only layers registered through `CanvasExtensionApi.registerLayer` are
1763
+ * hit-tested, last-registered-first, ahead of the kit's own selection
1764
+ * chrome. First non-null result wins; null means "I don't claim this hit,
1765
+ * try the next layer."
1766
+ *
1767
+ * Layers that reach the draw stack some other way — a `Tool.overlay`, an
1768
+ * entry in the `layers` map — are painted but never hit-tested, so defining
1769
+ * `hitTest` on one has no effect.
1770
+ *
1771
+ * Coordinates are world-space.
1772
+ */
1773
+ hitTest?: (worldX: number, worldY: number, data: TData, view: View, dims: Dims,
1774
+ /** Chrome-caps visibility predicate. When supplied, the layer must
1775
+ * not return a hit from any chrome element whose id reports
1776
+ * `false`. Absent → every element is hittable. */
1777
+ isVisible?: (id: string) => boolean) => LayerHit | null;
1778
+ /**
1779
+ * Called on every pointermove when no gesture is currently captured, so a
1780
+ * layer can track hover state. Coords are world-space, and the layer does
1781
+ * its own throttling.
1782
+ */
1783
+ onUncapturedMove?: (worldX: number, worldY: number, evt: PointerEvent, view: View, dims: Dims) => void;
1784
+ /** Called when the cursor leaves the canvas element. */
1785
+ onUncapturedLeave?: () => void;
1786
+ }
1787
+ /** Where one layer's commands landed in {@link drawLayers}' output,
1788
+ * `[start, end)`, and the CPU milliseconds its `draw` took. A layer group's
1789
+ * run is one span under the group's id. */
1790
+ interface LayerDrawSpan {
1791
+ id: string;
1792
+ start: number;
1793
+ end: number;
1794
+ buildMs: number;
1795
+ }
1796
+ /**
1797
+ * Walk visible layers and concatenate their emitted DrawCommand arrays into
1798
+ * one flat list, ready to feed to `WeaselRenderer.render(commands)`.
1799
+ *
1800
+ * A layer whose `draw` throws is dropped for the frame and reported through
1801
+ * `onLayerError` — the rest of the frame still paints.
1802
+ *
1803
+ * `groups` brackets runs of consecutive layers so they composite as one — see
1804
+ * `LayerGroup`. `spans`, when passed, receives one {@link LayerDrawSpan} per
1805
+ * layer drawn. `retain` decides which unchanged layers the renderer keeps
1806
+ * as pixels between frames; `false` keeps none.
1807
+ */
1808
+ declare function drawLayers<TData>(layers: RenderLayer<TData>[], data: TData, visibility: Record<string, boolean>, order: string[] | undefined, view: View | undefined, dims: Dims, cache?: LayerCommandCache, onLayerError?: (failure: LayerDrawFailure) => void, groups?: readonly LayerGroup[], spans?: LayerDrawSpan[], retain?: LayerRetainPolicy | false): DrawCommand[];
1809
+ /**
1810
+ * Resolve one layer's visibility: `alwaysOn` wins, then an explicit entry in
1811
+ * `visibility`, then `defaultVisible`, defaulting to shown.
1812
+ */
1813
+ declare function isLayerVisible<TData>(layer: RenderLayer<TData>, visibility: Record<string, boolean>): boolean;
1814
+ /**
1815
+ * Does this layer reach the screen at all — membership of
1816
+ * {@link paintedLayers}, asked of one layer.
1817
+ *
1818
+ * **A listed `order` is the whole list**, so omission from it drops a layer
1819
+ * that `visibility` would have shown, and `alwaysOn` does not rescue it.
1820
+ * Hit-testing asks this, not `isLayerVisible`.
1821
+ */
1822
+ declare function isLayerPainted<TData>(layer: RenderLayer<TData>, visibility: Record<string, boolean>, order: readonly string[] | undefined): boolean;
1823
+ /**
1824
+ * The layers that reach the screen, in the order they are drawn: `order`
1825
+ * sequences them and drops what it leaves out, then `visibility` drops what is
1826
+ * hidden. What `drawLayers` paints, and what a view narrows its stack with.
1827
+ */
1828
+ declare function paintedLayers<TData>(layers: readonly RenderLayer<TData>[], visibility: Record<string, boolean>, order: readonly string[] | undefined): RenderLayer<TData>[];
1829
+ /**
1830
+ * Draw one layer and put its commands in the space its `space` declares:
1831
+ * world-space output wrapped in a `viewToMat3(view)` group, screen-space
1832
+ * output passed through.
1833
+ *
1834
+ * Anything rendering layers through a view goes through here.
1835
+ *
1836
+ * A `draw` that throws yields no commands, and `onLayerError` is told which
1837
+ * layer it was. The layer's cache entry goes with it, so the next frame is a
1838
+ * real re-attempt.
1839
+ */
1840
+ declare function drawOneLayer<TData>(layer: RenderLayer<TData>, data: TData, view: View, dims: Dims, cache?: LayerCommandCache, onLayerError?: (failure: LayerDrawFailure) => void): DrawCommand[];
1841
+ /** Whether `b` matches `a` entry for entry under `Object.is` — how
1842
+ * `RenderLayer.deps` is compared, and any cache keyed the same way. */
1843
+ declare function depsUnchanged(a: readonly unknown[], b: readonly unknown[]): boolean;
1844
+
1845
+ /**
1846
+ * Paths that are no node, drawn over the scene: a region a tool would take,
1847
+ * the result an operation would make before it is applied.
1848
+ */
1849
+
1850
+ /** One path to draw, in world coordinates, and what it is. */
1851
+ interface TransientPath {
1852
+ path: Path;
1853
+ /** Omitted reads as `'chrome'`. */
1854
+ role?: OverlayRole;
1855
+ }
1856
+ /** How one role reads. The stroke is one screen pixel wide at any zoom. */
1857
+ interface PathOverlayStyle {
1858
+ fill?: CommandPaint;
1859
+ stroke?: CommandPaint;
1860
+ }
1861
+ /**
1862
+ * The kit's roles: `'chrome'` for a path shown for reference, `'picked'` for
1863
+ * one a gesture has taken, and `'remove'` for one it would delete.
1864
+ */
1865
+ declare const PATH_OVERLAY_ROLES: Readonly<Record<string, PathOverlayStyle>>;
1866
+ /** The paths an overlay holds, and the layer that draws them. */
1867
+ interface PathOverlay {
1868
+ get(): readonly TransientPath[];
1869
+ /** Replace every path. */
1870
+ set(paths: readonly TransientPath[]): void;
1871
+ clear(): void;
1872
+ /** A world-space layer drawing the paths in order, repainting on each change. */
1873
+ layer: RenderLayer<unknown>;
1874
+ }
1875
+ /** Options for {@link createPathOverlay}. */
1876
+ interface PathOverlayOptions {
1877
+ /** The layer's id; see `RenderLayer.id`. */
1878
+ id: string;
1879
+ label?: string;
1880
+ /** Styles per role, merged over {@link PATH_OVERLAY_ROLES}. A role with
1881
+ * none paints as `'chrome'`. */
1882
+ roles?: Readonly<Record<string, PathOverlayStyle>>;
1883
+ }
1884
+ /** A store of transient paths and the layer that draws it; hand the layer to
1885
+ * a tool's `overlay` or a canvas's `layers`. */
1886
+ declare function createPathOverlay({ id, label, roles }: PathOverlayOptions): PathOverlay;
1887
+
1888
+ /** Cancel-key prefix. Each hook instance appends its own id, so two runners
1889
+ * sharing an animator do not cancel each other. */
1890
+ declare const VIEW_ANIMATION_KEY = "view";
1891
+ /** How the camera should move. */
1892
+ interface ViewAnimationOptions {
1893
+ /** Duration in ms. Default the `view.animationMs` kit setting, else `DEFAULT_VIEW_ANIMATION_MS`;
1894
+ * 0 under `prefers-reduced-motion`. */
1895
+ ms?: number;
1896
+ /** Easing curve. Default `easeOutCubic`. */
1897
+ easing?: EasingSpec;
1898
+ /** Replace the kit's log-scale / fixed-anchor curve. */
1899
+ interpolator?: InterpolatorFactory<View>;
1900
+ /** Fires when the target is reached. Not called on cancel. */
1901
+ onDone?: () => void;
1902
+ }
1903
+ /** Options accepted by {@link ViewAnimationApi.animateToBounds}. */
1904
+ interface AnimateToBoundsOptions extends FitViewToBoundsOptions, ViewAnimationOptions {
1905
+ }
1906
+ /** What the runner reads and writes. On `<SceneCanvas>` this is the same
1907
+ * channel `view.set` uses, so a camera animation on an uncontrolled canvas
1908
+ * costs no React render. */
1909
+ interface ViewChannel {
1910
+ get(): View;
1911
+ set(v: View): void;
1912
+ }
1913
+ /** The camera animation surface. Its own animations run one at a time. */
1914
+ interface ViewAnimationApi {
1915
+ /** Glide from the live view to `to`. A thunk receives the pending target when
1916
+ * one is in flight, so successive discrete steps compound. */
1917
+ animate(to: View | ((base: View) => View), opts?: ViewAnimationOptions): void;
1918
+ /** `fitViewToBounds` composed with `animate`. */
1919
+ animateToBounds(bounds: FramedBox, dims: ViewportDims, opts?: AnimateToBoundsOptions): void;
1920
+ /** Cancel. The view stays where it is — no jump to the target. */
1921
+ stop(): void;
1922
+ isAnimating(): boolean;
1923
+ /** Where the in-flight animation is heading, or null when none is. */
1924
+ target(): View | null;
1925
+ /** Cancel unless the write that prompted this came from the runner's own
1926
+ * per-frame write. Feed it from every channel that can move the camera. */
1927
+ stopIfExternal(): void;
1928
+ /**
1929
+ * The view as a {@link Target}, for running another animation on it: a shake
1930
+ * or a nudge adds to a camera animation in flight, and neither cancels the
1931
+ * other. Move it with the animator this runner was given, and without this
1932
+ * runner's cancel key. `stop` and an outside write leave such an animation
1933
+ * running.
1934
+ */
1935
+ readonly viewTarget: Target<View>;
1936
+ }
1937
+ /** A `View` as the four numbers an animation moves: `x`, `y`, `scale.x`, `scale.y`. */
1938
+ declare const viewAxes: TargetAxes<View>;
1939
+ /**
1940
+ * Animate the viewport `View`. Runs on the kit's {@link Animator} — pass one to
1941
+ * share a canvas's animator, or omit it and the hook makes its own. A caller
1942
+ * that always has one should use {@link useViewAnimationOn}, which builds none.
1943
+ *
1944
+ * Every animation from one instance registers under that instance's cancel key,
1945
+ * so starting one cancels whatever *it* had in flight, and each starts from where
1946
+ * the last one was rather than a captured value — an interrupted camera never jumps.
1947
+ * Two instances on one animator are independent. The view is a target
1948
+ * ({@link ViewAnimationApi.viewTarget}), so other animations can add to the camera's.
1949
+ */
1950
+ declare function useViewAnimation(view: ViewChannel, animator?: Animator): ViewAnimationApi;
1951
+ /** {@link useViewAnimation} on an animator the caller owns. Constructs no
1952
+ * animator of its own, so the camera runs on exactly the one passed. */
1953
+ declare function useViewAnimationOn(view: ViewChannel, animator: Animator): ViewAnimationApi;
1954
+
1955
+ /** Paths drawn over the canvas until the function `show` returns is called.
1956
+ * A later `show` replaces what an earlier one drew, and the earlier one's
1957
+ * function then takes nothing down. */
1958
+ interface PreviewPathsDep {
1959
+ show(paths: readonly TransientPath[]): () => void;
1960
+ }
1961
+
1962
+ /** The snap readout's colors and line width, for a mark that sets no `color`. */
1963
+ interface SnapReadoutStyle {
1964
+ /** Points, lines and their labels. Default orange, as the path marker. */
1965
+ color?: string;
1966
+ /** Gap and distance marks. Default blue, as the guides. */
1967
+ gapColor?: string;
1968
+ /** Stroke width in screen px. Default 1. */
1969
+ lineWidth?: number;
1970
+ }
1971
+ /** A screen-space layer drawing the marks in `store`, redrawn when they change. */
1972
+ declare function createSnapReadoutLayer(store: SnapOutcomeStore, style?: SnapReadoutStyle): RenderLayer<unknown>;
1973
+
1974
+ /** The `snap` dep: what a drawn or dragged point locks to. */
1975
+
1976
+ type Point$4 = {
1977
+ x: number;
1978
+ y: number;
1979
+ };
1980
+ /** Geometry a gesture brings to snap to that is in no scene node: what stays
1981
+ * put of a path whose anchors it is dragging. World coords. */
1982
+ interface SnapGeometry {
1983
+ paths?: readonly Path[];
1984
+ /** Points to snap to as anchors. */
1985
+ anchors?: readonly Point$4[];
1986
+ }
1987
+ /** What builds a gesture's input subspace while `snap.constrain` is held:
1988
+ * an angle step in radians about `origin` (a rotate's every multiple of
1989
+ * it, required), an axis or 45° lock about the press, or a resize's
1990
+ * aspect. */
1991
+ type SnapConstrain = {
1992
+ step: number;
1993
+ } | 'aspect' | 'axis';
1994
+ /** The box a resize drags, as drawn, in its own frame. */
1995
+ interface SnapResizeBox {
1996
+ bounds: FramedBox;
1997
+ /** Its frame into ctx coordinates, an affine map. Default: the identity. */
1998
+ toWorld?: (p: Point$4) => Point$4;
1999
+ }
2000
+ /** What a gesture tells the snap dep when it starts. Points are ctx
2001
+ * coordinates: world in 2D. */
2002
+ interface SnapBegin {
2003
+ gesture: SnapGesture;
2004
+ press: Point$4;
2005
+ /** The subject, whose geometry offers no targets. */
2006
+ ids?: readonly string[];
2007
+ /** Resize: the sides the drag pins. An axis left `free` is an edge handle. */
2008
+ handle?: ResizeAnchor;
2009
+ /** Resize: the box `handle` belongs to. Default: the subject's drawn box,
2010
+ * axis-aligned. */
2011
+ box?: SnapResizeBox;
2012
+ /** Rotate, handle: the point the angle turns about. Default `press`. */
2013
+ pivot?: Point$4;
2014
+ /** Rotate: the subject's angle at press, radians. Default 0. */
2015
+ theta0?: number;
2016
+ /** Angle gestures: the reach as an angle, radians, in place of screen px
2017
+ * through the press radius; it overrides each source's `reachPx` and is
2018
+ * not capped. */
2019
+ reachRad?: number;
2020
+ /** Point gestures: the fixed end of what the gesture draws — a span's
2021
+ * start, the previous anchor, the anchor a handle pulls from. Tangent and
2022
+ * perpendicular targets are measured from it, a `constrain` step turns
2023
+ * about it, and no point target on it is offered. */
2024
+ origin?: Point$4;
2025
+ also?: SnapGeometry;
2026
+ constrain?: SnapConstrain;
2027
+ /** How the camera's world maps into the parallax plane the gesture's points
2028
+ * are in, read each frame; absent or null in the camera's own world. */
2029
+ plane?: () => PlaneMap | null;
2030
+ }
2031
+ /** The snap roles held this frame. */
2032
+ interface SnapMods {
2033
+ /** No source answers; the input subspace still applies. */
2034
+ suspend: boolean;
2035
+ constrain: boolean;
2036
+ /** Angle gestures: the angle stays at `theta0`, which becomes a required
2037
+ * target. */
2038
+ hold?: boolean;
2039
+ }
2040
+ /** Where a session put one frame's point, and the marks to draw for it. */
2041
+ interface SnapOutcome {
2042
+ point: Point$4;
2043
+ /** Whether some target holds the point. */
2044
+ held: boolean;
2045
+ marks: readonly SnapMark[];
2046
+ }
2047
+ /** One gesture's snapping, from press to release. */
2048
+ interface SnapSession {
2049
+ /** Where `p` lands. */
2050
+ at(p: Point$4, mods: SnapMods): SnapOutcome;
2051
+ /** Where the angle `theta` (radians, about `pivot`) lands. */
2052
+ angle(theta: number, mods: SnapMods): {
2053
+ theta: number;
2054
+ marks: readonly SnapMark[];
2055
+ };
2056
+ /** Clears the gesture's marks. */
2057
+ end(): void;
2058
+ }
2059
+ /**
2060
+ * Snapping, for every gesture that snaps: each one begins a session at press
2061
+ * and asks it, frame by frame, where its point lands. Points are ctx
2062
+ * coordinates — world in 2D, screen in a 3D host.
2063
+ */
2064
+ interface SnapDep {
2065
+ /** Start a gesture's snap session. */
2066
+ begin(req: SnapBegin): SnapSession;
2067
+ }
2068
+
2069
+ /** The snap source contract: what a target set offers a snap session, and
2070
+ * the marks a session draws for what it met. */
2071
+
2072
+ type Point$3 = {
2073
+ x: number;
2074
+ y: number;
2075
+ };
2076
+ /** The positions a target allows: `at` plus any combination of `dirs`. No
2077
+ * dirs is a point, one a line, two a plane. */
2078
+ interface Locus<P = Point$3> {
2079
+ at: P;
2080
+ dirs: readonly P[];
2081
+ /** One interval per dir, in multiples of it: a segment or a bounded face. */
2082
+ span?: readonly (readonly [number, number])[];
2083
+ }
2084
+ /** One locus a source offers one probe. */
2085
+ interface SourceCandidate<P = Point$3> {
2086
+ /** The id of a probe the source was offered. */
2087
+ probe: string;
2088
+ locus: Locus<P>;
2089
+ /** The result must meet one required candidate, whatever its reach. */
2090
+ required?: boolean;
2091
+ /** Drawn when the result meets this candidate. A function is handed the
2092
+ * resolved move, so the marks can sit where the probe landed. */
2093
+ mark?: SnapMarks<P> | ((delta: P) => SnapMarks<P>);
2094
+ }
2095
+ /** `'handle'` is an angle about an anchor, as `'rotate'` is about a pivot,
2096
+ * but asks only sources that name it. */
2097
+ type SnapGesture = 'point' | 'move' | 'resize' | 'rotate' | 'handle';
2098
+ /** The sides of a box a gesture moves on one axis; null for neither. */
2099
+ type SnapEdge = 'min' | 'max' | 'both' | null;
2100
+ /** Which sides of the subject's box a gesture moves, per axis. */
2101
+ interface SnapEdges {
2102
+ x: SnapEdge;
2103
+ y: SnapEdge;
2104
+ }
2105
+ /** A point on the subject that should land on a locus. */
2106
+ interface SnapProbeAt<P = Point$3> {
2107
+ id: string;
2108
+ at: P;
2109
+ role: ProbeRole;
2110
+ }
2111
+ /** What a session asks a source for, once per frame. */
2112
+ interface SnapCollect<P = Point$3> {
2113
+ gesture: SnapGesture;
2114
+ /** The probes this source matches, where the unsnapped gesture puts them. */
2115
+ probes: readonly SnapProbeAt<P>[];
2116
+ /** The unsnapped move from the press. A probe at `at` here lands at
2117
+ * `at - delta0 + delta` for the resolved `delta` a function mark gets. */
2118
+ delta0: P;
2119
+ /** The subject's drawn box, stroke included, where the unsnapped gesture
2120
+ * puts it: a move's union of boxes, or the box a resize drags. Absent for
2121
+ * other gestures. */
2122
+ box?: FramedBox;
2123
+ /** Which sides of `box` the gesture moves on each axis. Default: both, as
2124
+ * a move does. */
2125
+ edges?: SnapEdges;
2126
+ /** `id`'s drawn box, measured as `box` is. Absent in a host with no 2D
2127
+ * scene. */
2128
+ drawnBox?(id: string): FramedBox | undefined;
2129
+ /** Nodes that offer no targets: what the gesture moves. */
2130
+ exclude: readonly string[];
2131
+ /** Only these nodes offer targets. */
2132
+ include?: readonly string[];
2133
+ /** Where the geometry being drawn starts; tangent and perpendicular targets
2134
+ * are measured from it. */
2135
+ origin?: P;
2136
+ also?: SnapGeometry;
2137
+ /** `px` screen pixels as world units: a radius to cull targets by. */
2138
+ reachWorld(px: number): number;
2139
+ /** The reach, in screen px, the session applies to this source: its own
2140
+ * `reachPx`, else the canvas's. Candidates past it are dropped anyway. */
2141
+ reachPx: number;
2142
+ /** Absent in a host with no 2D scene. */
2143
+ scene?: Scene<unknown, string, unknown>;
2144
+ /** How the camera's world maps into the parallax plane the probes are in.
2145
+ * Absent in the camera's own world. A target the camera draws, a grid or
2146
+ * a ruler guide, is carried through it. */
2147
+ plane?: PlaneMap | null;
2148
+ }
2149
+ /** What a rotate or handle drag asks a source for, once per frame. Angles
2150
+ * are radians about `pivot`, in the frame `rotationOf` reads. */
2151
+ interface AngleCollect {
2152
+ pivot: Point$3;
2153
+ /** Where the gesture was pressed: its distance from `pivot` is the radius
2154
+ * the default marks are drawn at. */
2155
+ press: Point$3;
2156
+ /** The angle at press. */
2157
+ theta0: number;
2158
+ /** The unsnapped angle now. */
2159
+ theta: number;
2160
+ /** The subject. */
2161
+ ids: readonly string[];
2162
+ /** Nodes that offer no targets: the subject and everything under it. */
2163
+ exclude: readonly string[];
2164
+ mods: SnapMods;
2165
+ also?: SnapGeometry;
2166
+ /** Absent in a host with no 2D scene. */
2167
+ scene?: Scene<unknown, string, unknown>;
2168
+ /** `id`'s world rotation, read as the subject's is; undefined for a node
2169
+ * that cannot turn. */
2170
+ rotationOf?(id: string): number | undefined;
2171
+ }
2172
+ /** An angle a source offers. The session compares it round the circle, so
2173
+ * any whole turn of it is the same target. */
2174
+ interface AngleCandidate {
2175
+ angle: number;
2176
+ /** The result must land on one required angle, whatever its reach. */
2177
+ required?: boolean;
2178
+ /** Drawn when the result lands on it. Default: a ray from the pivot along
2179
+ * the snapped angle, labeled in degrees. */
2180
+ mark?: SnapMarks;
2181
+ }
2182
+ /** A set of snap targets. */
2183
+ interface SnapSource<P = Point$3> {
2184
+ id: string;
2185
+ /** Default `'target'`. A fallback never displaces a target in reach. */
2186
+ tier?: SnapTier;
2187
+ /** Overrides the canvas's reach for this source, in screen px. */
2188
+ reachPx?: number;
2189
+ /** The probe roles it matches; it is never offered a probe of another. */
2190
+ roles: readonly ProbeRole[];
2191
+ /** Default: every gesture but `'rotate'` and `'handle'`. */
2192
+ gestures?: readonly SnapGesture[];
2193
+ collect(q: SnapCollect<P>): Iterable<SourceCandidate<P>>;
2194
+ /** Angle targets, for a source whose `gestures` include `'rotate'` or `'handle'`. */
2195
+ angles?(q: AngleCollect): Iterable<AngleCandidate>;
2196
+ }
2197
+ /** One mark, or several, for one candidate. */
2198
+ type SnapMarks<P = Point$3> = SnapMark<P> | readonly SnapMark<P>[];
2199
+ /** What a session draws for a candidate the result meets. World coords. */
2200
+ type SnapMark<P = Point$3> = {
2201
+ kind: 'point';
2202
+ at: P;
2203
+ glyph: string;
2204
+ label?: string;
2205
+ color?: string;
2206
+ } | {
2207
+ kind: 'line';
2208
+ from: P;
2209
+ to: P;
2210
+ color?: string;
2211
+ } | {
2212
+ kind: 'gap';
2213
+ from: P;
2214
+ to: P;
2215
+ value: number;
2216
+ color?: string;
2217
+ } | {
2218
+ kind: 'distance';
2219
+ from: P;
2220
+ to: P;
2221
+ value: number;
2222
+ color?: string;
2223
+ };
2224
+ /** `<SceneCanvas snap>`. */
2225
+ interface SceneCanvasSnap {
2226
+ /** Sources ahead of the presets' `snapSources` and any `useSnapSource`.
2227
+ * One source per id is asked: the last listed, in the order prop,
2228
+ * presets, `useSnapSource` in mount order. A canvas default (`'rotation'`,
2229
+ * `'path-snap'`) loses to any of them. */
2230
+ sources?: readonly SnapSource[];
2231
+ /** Ids of canvas defaults to leave out: `'rotation'` stops a rotate
2232
+ * snapping to quarter turns and other nodes' angles (Shift's step is the
2233
+ * rotate's own and stays), and `'path-snap'` stops a point gesture (the
2234
+ * pen, an anchor drag, a drawn line's ends, a measurement) snapping to
2235
+ * other nodes' anchors. */
2236
+ omit?: readonly string[];
2237
+ /** The reach of a source that sets none, in screen px. Default: the kit
2238
+ * setting `targets.snapPx`. */
2239
+ reachPx?: number;
2240
+ /** How a pose's origin is read, for the `origin` probe a grid or a ruler
2241
+ * guide snaps: a pose neither a rect nor a `Path` needs its own. Default
2242
+ * `AUTO_ORIGIN_PROJECTION`. */
2243
+ originProjection?: OriginProjection<unknown>;
2244
+ /** Whether the snap marks are drawn. Default `true`. */
2245
+ readout?: boolean;
2246
+ /** The readout's default colors and line width, for a mark that sets no `color`. */
2247
+ readoutStyle?: SnapReadoutStyle;
2248
+ }
2249
+
2250
+ type Point$2 = {
2251
+ x: number;
2252
+ y: number;
2253
+ };
2254
+ /** The marks of the snap in flight, for the readout to draw. */
2255
+ interface SnapOutcomeStore<P = Point$2> {
2256
+ get(): readonly SnapMark<P>[];
2257
+ set(marks: readonly SnapMark<P>[]): void;
2258
+ subscribe(listener: () => void): () => void;
2259
+ }
2260
+ /** An empty outcome store, which notifies only when the marks change. */
2261
+ declare function createSnapOutcomeStore<P = Point$2>(): SnapOutcomeStore<P>;
2262
+
2263
+ /** The `snapReadout` dep: where marks go to be drawn. */
2264
+ interface SnapReadoutDep {
2265
+ store: SnapOutcomeStore;
2266
+ }
2267
+
2268
+ /**
2269
+ * Consumer-supplied node factory for one insert `kind`. Given the drag AABB
2270
+ * and the tool's `extras`, returns the node's `data` (in the consumer's own
2271
+ * data shape) plus an optional `pose` override — the dep supplies id, layer,
2272
+ * and the undoable insert op. Return `null` to reject the insert.
2273
+ *
2274
+ * A factory registered for a kit kind (`rect`, `line`, …) fully replaces the
2275
+ * kit's default `{ path, fill }` factory for that kind; a factory for a novel
2276
+ * kind adds support the kit doesn't ship (e.g. `text`). To change only the
2277
+ * paint of a kit shape, pass an {@link InsertPaint}. See
2278
+ * `SceneCanvas`'s `insertNodeFactories` prop.
2279
+ */
2280
+ type InsertNodeFactory = (bounds: {
2281
+ x: number;
2282
+ y: number;
2283
+ width: number;
2284
+ height: number;
2285
+ }, extras: InsertExtras) => {
2286
+ data: unknown;
2287
+ pose?: unknown;
2288
+ } | null;
2289
+ /**
2290
+ * The paint a kit-built shape is inserted with. `kind` is the shape being
2291
+ * built and `seq` counts this canvas's inserts from 1. A key left out stays
2292
+ * off the node, so its painter's default applies; `null` is "none". A pencil
2293
+ * trail too short to fit is built as a rect and asks as one. A line and an
2294
+ * open pen path are inserted unfilled: a fill given to either is dropped.
2295
+ * `fillRule` is the rule a path that carries one is built with, where the
2296
+ * kit's own is nonzero; a rect or an ellipse has none to set.
2297
+ *
2298
+ * It paints only the shapes the kit builds: an `InsertNodeFactory` owns its
2299
+ * node's whole `data`. See `SceneCanvas`'s `insertPaint` prop.
2300
+ */
2301
+ type InsertPaint = (kind: string, seq: number) => {
2302
+ fill?: Fill | null;
2303
+ stroke?: Stroke | null;
2304
+ fillRule?: PathFillRule;
2305
+ };
2306
+ /** The default {@link InsertPaint}: the next color of the kit palette, as a
2307
+ * fill on a closed shape, a fill and a stroke on a pen path, and a stroke
2308
+ * alone on a line or a pencil trail. */
2309
+ declare const paletteInsertPaint: InsertPaint;
2310
+
2311
+ /** The `data` a `kit:text` node carries. */
2312
+ interface TextNodeData {
2313
+ text: string;
2314
+ style?: TextStyle;
2315
+ runs?: readonly StyledRun[];
2316
+ fill?: Fill | null;
2317
+ stroke?: Stroke | null;
2318
+ verticalAlign?: TextVerticalAlign;
2319
+ /** Paint for the whole pose box, drawn under the glyphs. `fill` is the
2320
+ * glyphs' own paint, so a box behind them needs a key of its own. */
2321
+ background?: Fill | null;
2322
+ /** World units between the pose box and the box the text lays out in, on
2323
+ * every side. */
2324
+ padding?: number;
2325
+ /** What happens to text that runs past the pose box: `'visible'` (the
2326
+ * default) draws it there, `'clip'` cuts it at the box's edge. */
2327
+ overflow?: TextOverflow;
2328
+ }
2329
+ /** How a text node treats lines that run past its box. */
2330
+ type TextOverflow = 'visible' | 'clip';
2331
+ /** The box a text node's lines lay out in: its pose box, inset by
2332
+ * `data.padding` and never past its center. */
2333
+ declare function textBoxOf(d: Pick<TextNodeData, 'padding'>, p: RectPose): {
2334
+ x: number;
2335
+ y: number;
2336
+ width: number;
2337
+ height: number;
2338
+ };
2339
+
2340
+ /** The smallest box a node may be drawn or resized to, in world units. */
2341
+ interface MinSize {
2342
+ width: number;
2343
+ height: number;
2344
+ }
2345
+ /** A node's minimum, from `data.minSize`, or `null` when it has none. A
2346
+ * side that is not a positive number holds nothing. */
2347
+ declare function minSizeOf(data: unknown): MinSize | null;
2348
+
2349
+ /** How a sticky note looks as it is made, named as the text node it becomes
2350
+ * names them. Every field but `fill` has a default, in {@link STICKY_DEFAULTS}. */
2351
+ interface StickyStyle {
2352
+ /** The note itself, painted over its whole box. */
2353
+ background?: Fill;
2354
+ /** The text's paint. Absent, the text style's default. */
2355
+ fill?: Fill;
2356
+ /** World units from the note's edge to its text, on every side. */
2357
+ padding?: number;
2358
+ /** Typography for the note's text. */
2359
+ style?: TextStyle;
2360
+ verticalAlign?: TextVerticalAlign;
2361
+ /** What happens to text that outgrows the note. */
2362
+ overflow?: TextOverflow;
2363
+ /** The smallest note a drag makes or a resize leaves, in world units. */
2364
+ minSize?: MinSize;
2365
+ /** The note a click makes, centered on the click, in world units. A drag
2366
+ * makes the note it draws. */
2367
+ size?: {
2368
+ width: number;
2369
+ height: number;
2370
+ };
2371
+ }
2372
+ /** The look a sticky note takes for any field its tool leaves out. */
2373
+ declare const STICKY_DEFAULTS: {
2374
+ readonly background: {
2375
+ readonly paint: {
2376
+ readonly kind: "solid";
2377
+ readonly color: "#fff1a6ff";
2378
+ };
2379
+ };
2380
+ readonly padding: 12;
2381
+ readonly style: {
2382
+ readonly fontSize: 18;
2383
+ readonly align: "center";
2384
+ readonly wrap: true;
2385
+ };
2386
+ readonly verticalAlign: "center";
2387
+ readonly overflow: "clip";
2388
+ readonly minSize: {
2389
+ readonly width: 48;
2390
+ readonly height: 48;
2391
+ };
2392
+ readonly size: {
2393
+ readonly width: 160;
2394
+ readonly height: 160;
2395
+ };
2396
+ };
2397
+ /**
2398
+ * A sticky note's `data`: a text node with a `background`, so the `kit:text`
2399
+ * painter draws it and the text editor edits it with no sticky case of its
2400
+ * own. `look` is the `sticky` insert's extras, which carry the tool's
2401
+ * {@link StickyStyle}.
2402
+ */
2403
+ declare function stickyData(look: StickyStyle & {
2404
+ text?: string;
2405
+ }): TextNodeData & {
2406
+ minSize: MinSize;
2407
+ };
2408
+ /** The kit's `sticky` insert as an `InsertNodeFactory`, for a canvas that
2409
+ * wraps it — to tag the data with a `kind`, say — under `insertNodeFactories`. */
2410
+ declare const stickyNodeFactory: InsertNodeFactory;
2411
+
2412
+ /** Per-axis limits on a view's position. Any side may be left open. */
2413
+ interface PanBounds {
2414
+ minX?: number;
2415
+ maxX?: number;
2416
+ minY?: number;
2417
+ maxY?: number;
2418
+ }
2419
+ /** Momentum settings for a pan: how quickly a flung view slows, when it stops,
2420
+ * and what happens at the pan limits. The `DecayLoopConfig` fields a caller
2421
+ * chooses up front, without the per-gesture `velocity` / `onTick`. */
2422
+ interface InertiaConfig {
2423
+ friction?: number;
2424
+ minSpeed?: number;
2425
+ /** What to do when inertial pan reaches `bounds`. Default: no clamping. */
2426
+ boundary?: 'stop' | 'bounce' | 'spring';
2427
+ /** View-coordinate limits for boundary clamping. Requires `boundary` to take effect. */
2428
+ bounds?: PanBounds;
2429
+ }
2430
+ /** How a decay should run: its starting velocity, how fast it slows, and what
2431
+ * happens if it reaches the pan limits. */
2432
+ interface DecayLoopConfig {
2433
+ velocity: {
2434
+ vx: number;
2435
+ vy: number;
2436
+ };
2437
+ friction?: number;
2438
+ minSpeed?: number;
2439
+ /** Bounds for boundary clamping. Requires `boundary` to take effect. */
2440
+ viewBounds?: PanBounds;
2441
+ /**
2442
+ * What to do when the accumulated position hits `viewBounds`. Default: no clamping.
2443
+ * - `'stop'`: clamp at boundary, kill velocity component.
2444
+ * - `'bounce'`: linear reflection — flip velocity sign, magnitude preserved.
2445
+ * - `'spring'`: damped reflection — flip velocity sign and shrink magnitude
2446
+ * by `SPRING_DAMPING` per bounce so the motion settles naturally.
2447
+ */
2448
+ boundary?: 'stop' | 'bounce' | 'spring';
2449
+ /** Starting position for internal boundary tracking. Required when `viewBounds` is set. */
2450
+ initialPosition?: {
2451
+ x: number;
2452
+ y: number;
2453
+ };
2454
+ onTick: (dx: number, dy: number) => void;
2455
+ onEnd?: () => void;
2456
+ }
2457
+ /** A rAF loop that coasts a value to a stop under friction, reporting the
2458
+ * per-frame delta. What turns a released pan drag into momentum scrolling. */
2459
+ declare function useDecayLoop(): {
2460
+ start: (config: DecayLoopConfig) => void;
2461
+ cancel: () => void;
2462
+ };
2463
+
2464
+ /**
2465
+ * The lifecycle the ongoing transform actions (`move`, `resize`, `rotate`)
2466
+ * share: what their committed batch is called in history, whether it is
2467
+ * recorded at all, and the callbacks fired as the gesture opens and closes.
2468
+ *
2469
+ * Move and rotate read it from their binding's params; resize reads it from
2470
+ * the `resizePolicy` dep, where the rest of its options already live.
2471
+ */
2472
+
2473
+ /** The lifecycle options, as a binding's params or the resize policy carry
2474
+ * them. */
2475
+ interface GestureLifecycleOptions {
2476
+ /** History label for the committed batch. Unset, the batch takes its first
2477
+ * op's label (a layout drop or a behavior names its own), else the
2478
+ * action's. */
2479
+ label?: string;
2480
+ /** Commit through `scene.untracked`: the edit lands, but no undo entry
2481
+ * records it and the consumer `applyOps` hook is bypassed. Unset, any
2482
+ * behavior's `defaultTransient: true` turns it on. */
2483
+ transient?: boolean;
2484
+ /** Fired once the gesture starts changing poses, with the ids it moves. */
2485
+ onGestureStart?(ids: string[]): void;
2486
+ /** Fired once per `onGestureStart`: `true` when the gesture wrote to the
2487
+ * document, `false` on cancel, abort, or a release with nothing to write. */
2488
+ onGestureEnd?(committed: boolean): void;
2489
+ }
2490
+
2491
+ /** Optional consumer seam: given a node and the affine `m` that a pose-transform
2492
+ * action applied to the node's POSE, return updated `data` with the node's
2493
+ * data-held geometry transformed by `m`, or `null` if this node has no
2494
+ * data-held geometry (the kit leaves `data` alone). */
2495
+ interface GeometryProjection {
2496
+ transform(node: {
2497
+ id?: string;
2498
+ data: unknown;
2499
+ pose: unknown;
2500
+ }, m: Affine): unknown | null;
2501
+ }
2502
+
2503
+ /** What a handle drag holds fixed: its direction from the anchor, or its length. */
2504
+ type HandleLock = 'angle' | 'length';
2505
+ /** Which handle locks are held for every handle drag, on top of the modifiers.
2506
+ * Both together freeze the handle. */
2507
+ interface HandleLocks {
2508
+ angle: boolean;
2509
+ length: boolean;
2510
+ }
2511
+ /**
2512
+ * The params `editAnchors` reads, through `<SceneCanvas tune>` or a binding.
2513
+ * Read on every move, so a change mid-drag reaches the drag.
2514
+ */
2515
+ type EditAnchorsParams = {
2516
+ /** A lock held for every handle drag without a modifier: Shift holds the
2517
+ * angle, Mod (Cmd or Ctrl) the length. Under `<SceneCanvas>` this is where
2518
+ * the `handleLock.angle` and `handleLock.length` toggles start from; once
2519
+ * one is pressed, the locks the `editAnchors` dep holds decide. */
2520
+ handleLock?: HandleLock | null;
2521
+ };
2522
+
2523
+ /**
2524
+ * A path drawn from another form the node keeps beside it, such as a curve
2525
+ * solved through the points it passes. The node's path stays the geometry
2526
+ * every reader draws and hit-tests; `data.representation` holds the form,
2527
+ * named by its `kind`. A preset that knows a kind brings a
2528
+ * {@link PathRepresentation} for it (`PathEditExtension.representation`),
2529
+ * through which path edit shows and edits the form. Where none is on, path
2530
+ * edit edits the drawn path, and the edit drops the form.
2531
+ */
2532
+
2533
+ /** What `data.representation` holds: a form named by `kind`, with whatever
2534
+ * that kind keeps. */
2535
+ interface PathForm {
2536
+ readonly kind: string;
2537
+ readonly [field: string]: unknown;
2538
+ }
2539
+ type Point$1 = {
2540
+ x: number;
2541
+ y: number;
2542
+ };
2543
+ /** The outline of an anchor's marker, in screen space: `size` px across at
2544
+ * `at`, with the anchor's neighbors along its subpath, null past an open
2545
+ * end. */
2546
+ type AnchorMarkerShape = (at: Point$1, size: number, prev: Point$1 | null, next: Point$1 | null) => PolygonPath;
2547
+ /** How path edit reads and writes one kind of {@link PathForm}. */
2548
+ interface PathRepresentation {
2549
+ /** The `kind` of the forms it reads. */
2550
+ readonly kind: string;
2551
+ /** What path edit shows and moves for a node holding `form`, whose drawn
2552
+ * path in world space is `path`. Null when `form` does not describe
2553
+ * `path`: path edit then edits `path`, and the edit drops the form. */
2554
+ editPath(path: PolygonPath, form: PathForm): PolygonPath | null;
2555
+ /**
2556
+ * The drawn path an edit makes, and the form to keep beside it: `edited` is
2557
+ * an edit of what {@link editPath} gave, `path` the drawn path it was given
2558
+ * from. Null when `form` does not describe `path`; the edit is then stored
2559
+ * as drawn, without the form. Runs on every commit of an edit and every
2560
+ * frame of one in flight.
2561
+ */
2562
+ store(path: PolygonPath, form: PathForm, edited: PolygonPath): {
2563
+ path: PolygonPath;
2564
+ form: PathForm;
2565
+ } | null;
2566
+ /** The marker of each anchor of the edit path, by flat index. An anchor
2567
+ * with none draws path edit's square. */
2568
+ anchorMarkers?(form: PathForm): readonly (AnchorMarkerShape | null)[];
2569
+ /**
2570
+ * A press at world point `at` on the drawn outline of the node in path
2571
+ * edit: the drag it starts, or null when it starts none there. A
2572
+ * representation that has this takes every segment press, in place of
2573
+ * Bend segment.
2574
+ */
2575
+ segmentPress?(deps: ActionDeps, at: Point$1): (() => OngoingHandle) | null;
2576
+ }
2577
+
2578
+ /**
2579
+ * What a feature adds to path edit without path edit knowing it: marks drawn
2580
+ * on the open path, parts of it to press, marks a click selects and Delete
2581
+ * removes, a share in shaping an anchor or handle drag, what an edit must keep
2582
+ * true when it commits, and how a path drawn from another form is edited. A
2583
+ * preset carries its extensions as `FeaturePreset.pathEdit`; core consults
2584
+ * them in preset order.
2585
+ */
2586
+
2587
+ /** A mark an extension drew that is selected in place of anchors: Delete
2588
+ * acts on it, and selecting anchors clears it. */
2589
+ interface PathEditMark {
2590
+ /** The extension that drew it. */
2591
+ owner: string;
2592
+ /** Which of its marks, in the extension's own numbering. */
2593
+ index: number;
2594
+ }
2595
+ /** The open path as an extension's marks and parts read it. */
2596
+ interface PathEditTarget {
2597
+ /** The node being edited. */
2598
+ id: string;
2599
+ /** Its committed pose and data. */
2600
+ node: {
2601
+ pose: unknown;
2602
+ data: unknown;
2603
+ };
2604
+ /** The path as drawn now, in-flight edits included, in world space. */
2605
+ path: PolygonPath;
2606
+ /** `path`'s anchors. */
2607
+ anchors: AnchorSet;
2608
+ }
2609
+ /** What {@link PathEditExtension.marks} draws with. */
2610
+ interface PathEditMarksCtx extends PathEditTarget {
2611
+ view: View;
2612
+ /** World space to the screen space the marks are drawn in. */
2613
+ toScreen(p: {
2614
+ x: number;
2615
+ y: number;
2616
+ }): {
2617
+ x: number;
2618
+ y: number;
2619
+ };
2620
+ /** Chrome-caps' answer for a chrome id; marks gated by one ask it. */
2621
+ isVisible(chromeId: string): boolean;
2622
+ /** The selected mark's index when this extension owns it, else null. */
2623
+ selected: number | null;
2624
+ }
2625
+ /** A grabbable point an extension adds to the open path. A press on it
2626
+ * routes as an affordance hit of kind `hitKind`. */
2627
+ interface PathEditPart {
2628
+ x: number;
2629
+ y: number;
2630
+ hitKind: string;
2631
+ /** Chrome-caps id it is hit-tested under, beside `path-edit.anchors`. */
2632
+ chromeId?: string;
2633
+ /** Hit radius in screen px; path edit's anchor radius when left out. */
2634
+ hitRadiusPx?: number;
2635
+ /** Pushes the part `px` screen pixels from (x, y) along the world-space
2636
+ * `normal`, so it keeps its distance at any zoom. */
2637
+ standoff?: {
2638
+ px: number;
2639
+ normal: {
2640
+ x: number;
2641
+ y: number;
2642
+ };
2643
+ };
2644
+ }
2645
+ type Point = {
2646
+ x: number;
2647
+ y: number;
2648
+ };
2649
+ /** An anchor or handle drag on the open path, as it starts. */
2650
+ interface PathEditDragStart extends Omit<PathEditTarget, 'node'> {
2651
+ /** The node's committed pose and data; null when it cannot be read. */
2652
+ node: PathEditTarget['node'] | null;
2653
+ /** What the press grabbed: an anchor, or one of its handles. */
2654
+ part: 'anchor' | 'controlIn' | 'controlOut';
2655
+ /** The pressed anchor, as a flat index. */
2656
+ anchorIndex: number;
2657
+ /** The anchors an anchor drag moves, as flat indices; empty for a handle
2658
+ * drag, or when Shift took the pressed anchor out of the selection. */
2659
+ dragging: readonly number[];
2660
+ /** The view's world-to-screen scale at the press, to measure in screen
2661
+ * pixels by; absent without a view. */
2662
+ scale?: {
2663
+ x: number;
2664
+ y: number;
2665
+ };
2666
+ /** The canvas's `snap` dep, to begin a session on; absent without one. */
2667
+ snap?: SnapDep;
2668
+ }
2669
+ /** A handle drag's move, as {@link PathEditDrag.handle} reads it. */
2670
+ interface PathEditHandleMove {
2671
+ /** The handle locks in force this move, modifiers included. */
2672
+ locks: HandleLocks;
2673
+ }
2674
+ /** One extension's share of a drag in flight. Every member is optional. */
2675
+ interface PathEditDrag {
2676
+ /**
2677
+ * For an anchor drag, anchors that follow it and the share of its delta
2678
+ * each moves by, keyed by flat index. Read every move. When any extension
2679
+ * gives one, the drag moves its dragged anchors in full and every anchor
2680
+ * named by the largest share given, and moves no symmetric images.
2681
+ */
2682
+ weights?(): ReadonlyMap<number, number>;
2683
+ /** For a handle drag, where the handle goes, given `to`: where the pointer
2684
+ * and the locks in force put it. Extensions answer in turn, each from the
2685
+ * last one's answer. */
2686
+ handle?(to: Point, move: PathEditHandleMove): Point;
2687
+ /** A wheel turned while the drag is in flight. Return true to claim it;
2688
+ * the drag then redoes its last move. */
2689
+ wheel?(wheel: {
2690
+ deltaX: number;
2691
+ deltaY: number;
2692
+ deltaZ: number;
2693
+ }): boolean;
2694
+ /** Overlays to draw while the drag is in flight, for `current`, the path
2695
+ * as the drag has made it. */
2696
+ overlays?(current: AnchorSet): readonly OngoingOverlay[];
2697
+ /** The drag is over, committed or canceled. */
2698
+ end?(): void;
2699
+ }
2700
+ /** Another node an edit changes along with the edited one. */
2701
+ interface PathEditOther {
2702
+ id: string;
2703
+ /** Its new path, in world space, stored where the node keeps its own. */
2704
+ path?: PolygonPath;
2705
+ /** Data fields to set on it. */
2706
+ data?: Record<string, unknown>;
2707
+ /** Delete it: what it kept true no longer has anything to hold. */
2708
+ remove?: boolean;
2709
+ }
2710
+ /** What an edit commits once an extension has finished it. */
2711
+ interface FinishedPathEdit {
2712
+ path: PolygonPath;
2713
+ /** Data fields to set beside the path. */
2714
+ data?: Record<string, unknown>;
2715
+ /** Other nodes the edit changes, committed in the same history entry and previewed with it. */
2716
+ others?: readonly PathEditOther[];
2717
+ }
2718
+ /** The scene as {@link PathEditExtension.finishEdit} reads it, for an edit that reaches past one node. */
2719
+ interface PathEditFinishCtx {
2720
+ /** The edited node's id. */
2721
+ id: string;
2722
+ /** A node's committed pose, data and dependencies; null when there is none. */
2723
+ node(id: string): {
2724
+ pose: unknown;
2725
+ data: unknown;
2726
+ dependsOn?: readonly string[] | 'children';
2727
+ } | null;
2728
+ /** A node's committed editable path, in world space; null when it has none. */
2729
+ path(id: string): PolygonPath | null;
2730
+ /** The nodes that list `id` in their `dependsOn`, directly or through others. */
2731
+ dependents(id: string): readonly string[];
2732
+ }
2733
+ /** One feature's share of path edit. Every member is optional. */
2734
+ interface PathEditExtension {
2735
+ /** Names it as a {@link PathEditMark}'s owner. Unique per canvas. */
2736
+ readonly id: string;
2737
+ /** Draw commands for the open path, in screen space, under its anchor
2738
+ * markers. Called every frame the overlay paints. */
2739
+ marks?(ctx: PathEditMarksCtx): DrawCommand[];
2740
+ /** Grabbable points on the open path, pressed ahead of its segments and
2741
+ * behind its anchors. */
2742
+ parts?(target: PathEditTarget): readonly PathEditPart[];
2743
+ /** The index of this extension's mark a click at `screen` (in the
2744
+ * overlay's screen space) lands on, or -1. Asked when a click misses
2745
+ * every anchor. */
2746
+ markAt?(target: PathEditTarget, toScreen: PathEditMarksCtx['toScreen'], screen: {
2747
+ x: number;
2748
+ y: number;
2749
+ }): number;
2750
+ /** Remove mark `index` of the node `target` names, committing through
2751
+ * `store`. Delete in path edit calls it on the selected mark. */
2752
+ deleteMark?(target: PathEditTarget, index: number, store: PathEditStore): void;
2753
+ /** Its share of an anchor or handle drag starting on the open path, or
2754
+ * null to sit it out. Asked once, at the press. */
2755
+ drag?(start: PathEditDragStart): PathEditDrag | null;
2756
+ /**
2757
+ * `worldPath`, an edit of `node`'s committed path, finished so whatever
2758
+ * this extension keeps true holds — the path, and any data fields that
2759
+ * change with it, and any other nodes it has to move to keep it. Null when
2760
+ * it cannot hold, and the edit should then not happen. Runs on every commit
2761
+ * of an edit and every frame of one in flight. `ctx` reads the rest of the
2762
+ * scene; it is absent where an edit has no scene behind it.
2763
+ */
2764
+ finishEdit?(node: {
2765
+ pose: unknown;
2766
+ data: unknown;
2767
+ }, worldPath: PolygonPath, origins?: readonly (PointOrigin | null)[], ctx?: PathEditFinishCtx): FinishedPathEdit | null;
2768
+ /** How path edit reads and writes the nodes whose `data.representation`
2769
+ * is of its kind. */
2770
+ representation?: PathRepresentation;
2771
+ }
2772
+ /** Commits a node's new path and data as one history entry, with no
2773
+ * extension finishing it. */
2774
+ type PathEditStore = (id: string, worldPath: PolygonPath, label: string, data?: Record<string, unknown>) => void;
2775
+ /**
2776
+ * Data fields that describe how a node's geometry was made, or name its
2777
+ * anchors, and so mean nothing once the geometry is replaced some other way.
2778
+ * A writer replacing a node's path drops them: a held warp, path
2779
+ * constraints, a skin, the form a path was drawn from.
2780
+ */
2781
+ declare const GEOMETRY_BOUND_DATA: readonly string[];
2782
+ /** `data` without the fields in {@link GEOMETRY_BOUND_DATA}, other than `keep`. */
2783
+ declare function withoutGeometryBoundData<T>(data: T, keep?: readonly string[]): T;
2784
+
2785
+ /** An edit as {@link EditAnchorsDep.finishEdit} finishes it: the edited node's world path, and the other nodes' that move with it. */
2786
+ interface FinishedEditFrame {
2787
+ path: unknown;
2788
+ others: readonly {
2789
+ id: string;
2790
+ path: unknown;
2791
+ }[];
2792
+ }
2793
+ /**
2794
+ * Adapter dep for `editAnchorsAction`: narrow read/write access to the
2795
+ * editable polygon of a single node, so anchor-edit actions need not know
2796
+ * whether it lives directly on the node's pose (`pose.kind === 'polygon'`)
2797
+ * or on `node.data.path`.
2798
+ *
2799
+ * In-flight edit state is surfaced through the dispatcher's
2800
+ * `OngoingHandle.previewIds/previewPose/previewData` triple, not this dep.
2801
+ */
2802
+ interface EditAnchorsDep {
2803
+ /** Id of the node currently being edited. Empty string means no node is
2804
+ * currently in edit mode — the chrome and gesture both opt out. */
2805
+ editingId: string;
2806
+ /** Enter/exit edit mode for a specific node. Pass `null` (or an empty
2807
+ * string) to exit. */
2808
+ setEditingId(id: string | null): void;
2809
+ /** Returns the COMMITTED editable polygon in world coordinates, or
2810
+ * null if this node has no editable polygon. For a node whose path was
2811
+ * drawn from a form a `PathRepresentation` reads, it is that form's edit
2812
+ * path, which `applyEdit` turns back into the drawn path. Does NOT consult in-
2813
+ * flight previews — callers that need live state read the dispatcher's
2814
+ * in-flight handles. */
2815
+ getEditablePath(id: string): unknown;
2816
+ /** The drawn geometry, in world coordinates, whose outline is a segment press, where it
2817
+ * differs from `getEditablePath`'s: a path drawn from a form. Absent, `getEditablePath`'s. */
2818
+ getOutlinePath?(id: string): unknown;
2819
+ /** Returns where the polygon is stored — `'pose'` when `node.pose`
2820
+ * IS the polygon, `'data'` when it lives on `node.data.path` with a
2821
+ * rect pose, or `null` when the node has no editable polygon. */
2822
+ getStorageKind(id: string): 'pose' | 'data' | null;
2823
+ /** Returns the node's raw `pose` and `data` so storage-aware actions
2824
+ * can capture origin state at gesture-start and synthesize a matching
2825
+ * `previewPose` / `previewData` during `onMove`. Returns null when the
2826
+ * node is gone. */
2827
+ getNodeShape(id: string): {
2828
+ pose: unknown;
2829
+ data: unknown;
2830
+ } | null;
2831
+ /** Commit `worldPath` as the new value for `id`, as one history entry
2832
+ * labeled `label`: a setPose when the pose IS the polygon, a batched
2833
+ * setPose+update when it lives on data.path. Given `origins` (from
2834
+ * `editAnchorSetTracked`), its per-anchor data (skin, vertex colors) is
2835
+ * renumbered in that entry. The edit is finished first (see `finishEdit`); one an extension cannot
2836
+ * finish commits nothing. */
2837
+ applyEdit(id: string, worldPath: unknown, label: string, origins?: readonly (PointOrigin | null)[]): void;
2838
+ /** The ops `applyEdit` would commit for the same arguments, unapplied, so
2839
+ * a caller can make the edit part of a larger batch — the pen joining
2840
+ * two paths edits one node and deletes the other in one undo step.
2841
+ * Optional; a caller that needs it declines the composite edit without
2842
+ * it. Returns `[]` when `id` has no editable polygon, or when an
2843
+ * extension cannot finish the edit. */
2844
+ editOps?(id: string, worldPath: unknown, label: string, origins?: readonly (PointOrigin | null)[]): Op[];
2845
+ /**
2846
+ * Anchors currently selected within the edited path, as **flat anchor
2847
+ * indices** — the same numbering `enumerateAnchors` produces and the
2848
+ * `anchor:N` affordance kinds carry.
2849
+ *
2850
+ * Selection is transient UI state, deliberately not part of the scene:
2851
+ * it is cleared whenever `editingId` changes, and any edit that
2852
+ * renumbers anchors (insert, delete) is responsible for leaving it
2853
+ * coherent. Empty means "no anchor selected" — the keyboard actions
2854
+ * (nudge, delete) no-op rather than acting on all anchors.
2855
+ */
2856
+ selectedAnchors: ReadonlySet<number>;
2857
+ /** Replace the anchor selection. Pass an empty iterable to clear. */
2858
+ setSelectedAnchors(next: Iterable<number>): void;
2859
+ /** In-flight anchor-marquee rect in world coords, or null when no
2860
+ * marquee drag is active. */
2861
+ marquee: {
2862
+ x: number;
2863
+ y: number;
2864
+ width: number;
2865
+ height: number;
2866
+ } | null;
2867
+ /** Set or clear the in-flight marquee rect. */
2868
+ setMarquee(rect: {
2869
+ x: number;
2870
+ y: number;
2871
+ width: number;
2872
+ height: number;
2873
+ } | null): void;
2874
+ /** The path-edit tool in use, or null for plain anchor editing — one of a
2875
+ * set of named tools, such as `'simplifyBrush'`, that each change what a
2876
+ * plain drag in path edit does. Always null with no path open. */
2877
+ tool: string | null;
2878
+ /** Switch path-edit tool, or pass null for plain anchor editing. */
2879
+ setTool(id: string | null): void;
2880
+ /** The handle locks held for every handle drag, on top of the modifiers —
2881
+ * what the `handleLock.angle` and `handleLock.length` toggles set. Absent,
2882
+ * the drag holds what its `handleLock` param names. Unlike the anchor
2883
+ * selection, they outlast a change of edited path. */
2884
+ handleLocks?: HandleLocks;
2885
+ /** Replace the held handle locks. Absent, the toggles are unavailable. */
2886
+ setHandleLocks?(next: HandleLocks): void;
2887
+ /**
2888
+ * `worldPath`, an edit of `id`'s committed path, finished by every
2889
+ * extension's `finishEdit` in turn — path constraints made to hold, say —
2890
+ * with the paths of any other nodes that move with it. Null when one cannot
2891
+ * finish it, and the edit should then not happen. `applyEdit` and `editOps`
2892
+ * run it themselves; an ongoing edit calls it each frame so its preview is
2893
+ * what they will commit. Optional: absent, edits stand as they are.
2894
+ */
2895
+ finishEdit?(id: string, worldPath: unknown, origins?: readonly (PointOrigin | null)[]): FinishedEditFrame | null;
2896
+ /**
2897
+ * Commit `worldPath` for `id` with `data` laid over its data, as one
2898
+ * history entry, finished by no extension: what an extension writing its
2899
+ * own data with a path it already solved commits through. Optional.
2900
+ */
2901
+ store?: PathEditStore;
2902
+ /** The canvas's path-edit extensions, in order. */
2903
+ extensions?: readonly PathEditExtension[];
2904
+ /**
2905
+ * The extension mark selected in place of anchors, or null. Selecting one
2906
+ * clears the anchor selection and selecting anchors clears it, so Delete
2907
+ * acts on one or the other. Optional.
2908
+ */
2909
+ selectedMark?: PathEditMark | null;
2910
+ /** Select an extension's mark, or pass null to clear. */
2911
+ setSelectedMark?(mark: PathEditMark | null): void;
2912
+ }
2913
+
2914
+ /** Context handed to every content handler for one ingest event. */
2915
+ interface IngestCtx {
2916
+ /** World-space arrival point (drop / pointed imperative ingest); `null`
2917
+ * for paste and point-less calls — handlers pick their own policy
2918
+ * (the kit image handler centers on the viewport). */
2919
+ point: {
2920
+ x: number;
2921
+ y: number;
2922
+ } | null;
2923
+ /** Visible canvas area in world coordinates. */
2924
+ viewportWorldRect(): {
2925
+ x: number;
2926
+ y: number;
2927
+ width: number;
2928
+ height: number;
2929
+ };
2930
+ /** The kit insert dep — id/layer/undoable-op supplied; the canonical way
2931
+ * for a handler to mint a node (`insert.commit(bounds, { kind, ... })`). */
2932
+ insert: InsertDep;
2933
+ /** Raw op commit for handlers that build their own ops. */
2934
+ applyOps(ops: Op[], label?: string): void;
2935
+ scene: Scene<unknown, string, unknown>;
2936
+ selection: SelectionApi;
2937
+ /** Consumer file→src resolver (SceneCanvas `ingestion.resolveSrc`).
2938
+ * When absent, the kit image handler embeds as a `data:` URI. */
2939
+ resolveSrc?: (file: File) => Promise<string>;
2940
+ /** Kit SVG-handler options (SceneCanvas `ingestion.svg`) — e.g.
2941
+ * `{ unpack: unpackSvgFiles }` (from `@weasel-js/svg`) to parse SVG files
2942
+ * into scene nodes. */
2943
+ svg?: SvgIngestOptions;
2944
+ /** Clipboard-paste seam — present when the hosting `SceneCanvas` supplied
2945
+ * an adapter with `commitPaste`. `reviver` comes from
2946
+ * `SceneCanvasProps.ingestion.clipboard`. Absent ⇒ the kit weasel-JSON
2947
+ * handler declines inert (dwarn, nothing ingested) — its matched items
2948
+ * were already consumed at match time, so they do NOT fall through;
2949
+ * only match-level misses flow on to other handlers. */
2950
+ clipboard?: ClipboardIngestCtx;
2951
+ /** Set to `true` by the kit weasel-JSON handler when it successfully
2952
+ * pastes a payload in this event. `kit:svg`'s `text/plain` SVG fallback
2953
+ * reads this to decline the SVG flavor of a copy whose weasel-JSON flavor
2954
+ * already ingested (avoids a double-paste when both flavors ride one
2955
+ * clipboard event). */
2956
+ consumedWeaselPayload?: boolean;
2957
+ /** Full action-deps bag, for consumer handlers that need more. */
2958
+ deps: ActionDeps;
2959
+ }
2960
+ /** A handler for content arriving by paste, drop or file picker. Handlers are
2961
+ * matched by MIME glob or predicate and run highest-priority first; the kit's
2962
+ * own register at a low priority so a consumer's handler wins by default. */
2963
+ interface ContentHandlerEntry {
2964
+ /** Stable identifier — used for unregistration and debugging
2965
+ * (`'kit:image'`, `'app:csv'`). */
2966
+ id: string;
2967
+ /** MIME glob(s) (`'image/*'`, `'text/csv'`) or an item predicate. */
2968
+ match: string | string[] | ((item: IngestItem) => boolean);
2969
+ /** For a predicate `match`: the MIME globs it could say yes to. A drag
2970
+ * still in flight shows its MIMEs and no contents, so a predicate cannot be
2971
+ * asked about it; this is what it is asked instead. Without it, no drag
2972
+ * can be refused while this handler is registered. */
2973
+ types?: readonly string[];
2974
+ /** Higher runs earlier. Kit defaults register at -100 so any consumer
2975
+ * handler (default 0) beats them. */
2976
+ priority?: number;
2977
+ handle(items: IngestItem[], ctx: IngestCtx): void | Promise<void>;
2978
+ }
2979
+ /** Register a content handler. Returns a disposer that removes it. */
2980
+ declare function registerContentHandler(entry: ContentHandlerEntry): () => void;
2981
+
2982
+ /**
2983
+ * Options for the kit `image/svg+xml` content handler, threaded from
2984
+ * SceneCanvas's `ingestion={{ svg }}` prop.
2985
+ */
2986
+ interface SvgIngestOptions {
2987
+ /** Parse dropped/pasted/picked SVG files into native scene nodes (path /
2988
+ * text leaves under containers mirroring the source `<g>` structure)
2989
+ * instead of the default single embedded-image node.
2990
+ *
2991
+ * Pass `unpackSvgFiles` from `@weasel-js/svg`:
2992
+ *
2993
+ * ```ts
2994
+ * import { unpackSvgFiles } from '@weasel-js/svg';
2995
+ * <SceneCanvas ingestion={{ svg: { unpack: unpackSvgFiles } }} />
2996
+ * ```
2997
+ *
2998
+ * It is injected rather than flagged on with `true` because the SVG parser
2999
+ * lives in `@weasel-js/svg`, which depends on this package. */
3000
+ unpack?: SvgUnpacker;
3001
+ }
3002
+ /** Parses SVG files and inserts the resulting nodes into `ctx.scene`, as one
3003
+ * `applyOps` batch per file. Implemented by `unpackSvgFiles` in
3004
+ * `@weasel-js/svg`; see {@link SvgIngestOptions.unpack}. */
3005
+ type SvgUnpacker = (files: File[], ctx: IngestCtx) => Promise<void>;
3006
+ /**
3007
+ * Clipboard-paste seam consumed by the kit weasel-JSON content handler
3008
+ * (`IngestCtx.clipboard`). Built by `<SceneCanvas>` from its own synthesized
3009
+ * adapter + the `ingestion.clipboard` prop; absent when the consumer set
3010
+ * `ingestion.clipboard.enabled === false` or the adapter lacks `commitPaste`.
3011
+ * Absence makes the handler decline inert (dwarn, nothing ingested) — its
3012
+ * matched items were already consumed at match time and do not fall through
3013
+ * to other handlers.
3014
+ */
3015
+ interface ClipboardIngestCtx {
3016
+ /** The hosting canvas's adapter — `commitPaste` materializes the pasted
3017
+ * nodes (fresh ids, offset applied); insertion still goes through ops. */
3018
+ adapter: InsertAdapter<{
3019
+ id: string;
3020
+ }>;
3021
+ /** JSON reviver for the weasel wire payload (typed arrays etc.) — from
3022
+ * `SceneCanvasProps.ingestion.clipboard.reviver`. */
3023
+ reviver?: (key: string, value: unknown) => unknown;
3024
+ /** Told what a paste left out and why — from
3025
+ * `SceneCanvasProps.ingestion.clipboard.onOmitted`. */
3026
+ onOmitted?: (omitted: PasteOmission[]) => void;
3027
+ }
3028
+ /** Dep for the `ingest` action (external-content ingestion). */
3029
+ interface IngestionDep {
3030
+ /** Visible canvas area in world coordinates. */
3031
+ viewportWorldRect(): {
3032
+ x: number;
3033
+ y: number;
3034
+ width: number;
3035
+ height: number;
3036
+ };
3037
+ /** Consumer file→src resolver (from SceneCanvas's `ingestion` prop).
3038
+ * Live accessor — read it at use time. Destructuring (or copying the
3039
+ * property early) snapshots the current value and won't track later
3040
+ * prop changes across an `await`. */
3041
+ resolveSrc?: (file: File) => Promise<string>;
3042
+ /** Kit SVG-handler options (from SceneCanvas's `ingestion` prop).
3043
+ * Live accessor, same caveat as `resolveSrc`. */
3044
+ svg?: SvgIngestOptions;
3045
+ /** Clipboard-paste seam for the kit weasel-JSON handler.
3046
+ * Live accessor, same caveat as `resolveSrc`. */
3047
+ clipboard?: ClipboardIngestCtx;
3048
+ }
3049
+
3050
+ /** The gesture an insert's bounds came from, in the same coordinates: `bounds`
3051
+ * is the box `start` and `end` span, or with `fromCenter`, the box centered
3052
+ * on `start` reaching `end`. A host whose bounds lose information on the
3053
+ * way, a 3D one casting them onto a plane, reads the ends instead. */
3054
+ interface InsertEnds {
3055
+ start: {
3056
+ x: number;
3057
+ y: number;
3058
+ };
3059
+ end: {
3060
+ x: number;
3061
+ y: number;
3062
+ };
3063
+ fromCenter?: boolean;
3064
+ }
3065
+ /** Adapter dep for `insertAction`. The `extras` carry the active tool's kind
3066
+ * + per-kind geometry. */
3067
+ interface InsertDep {
3068
+ /**
3069
+ * Materialise a new node from the given drag-rect bounds and typed
3070
+ * per-kind extras. Returns the new node's id, or `null` if the consumer
3071
+ * rejected the insert (e.g. sub-threshold bounds, unknown kind).
3072
+ */
3073
+ commit(bounds: {
3074
+ x: number;
3075
+ y: number;
3076
+ width: number;
3077
+ height: number;
3078
+ }, extras: InsertExtras,
3079
+ /** Absent when no gesture made the bounds: a path the pen or spiro
3080
+ * drew, or content a paste ingests. A click-place reads as a drag out
3081
+ * from its center. */
3082
+ ends?: InsertEnds): NodeId | null;
3083
+ /**
3084
+ * What `commit` would apply, unapplied: the new node's id and the ops that
3085
+ * insert it, for a caller that has more to put in the same undo step. The
3086
+ * pen joins two paths this way. Without it such a caller declines.
3087
+ */
3088
+ build?(bounds: {
3089
+ x: number;
3090
+ y: number;
3091
+ width: number;
3092
+ height: number;
3093
+ }, extras: InsertExtras, ends?: InsertEnds): {
3094
+ id: NodeId;
3095
+ ops: Op[];
3096
+ } | null;
3097
+ /** The scene layer `commit` puts the node on. An insert on a layer carrying
3098
+ * `parallax` is dragged out in that plane's world, so `bounds` arrive
3099
+ * there too. Omitted: the camera's world. */
3100
+ layer?(): string;
3101
+ }
3102
+ /**
3103
+ * What `editAnchorsAction` keeps a path symmetric under. Asked once at the
3104
+ * press, with the id of the path being edited; answer every transform of the
3105
+ * symmetry group except the identity, in world coordinates. Of those, the
3106
+ * ones the path is already its own image under are held through the drag:
3107
+ * each image of a dragged anchor or handle follows it, and one a transform
3108
+ * fixes stays where that transform allows.
3109
+ */
3110
+ interface PathSymmetryDep {
3111
+ transforms(id: string): readonly Affine[];
3112
+ }
3113
+ /** Where the `insert` dep puts what it makes. Read at each insert. A node
3114
+ * goes onto the container's layer, with its pose made local to it when the
3115
+ * scene composes frames; an id naming no container is the same as `null`. */
3116
+ interface InsertIntoDep {
3117
+ get(): string | null;
3118
+ }
3119
+ /** Holder for the insert gesture in flight in one input scope. `gesture` is
3120
+ * `insertAction`'s own state, opaque to everything else, and `null` between
3121
+ * gestures. A source must return the same object on every read. */
3122
+ interface InsertLive {
3123
+ gesture: unknown;
3124
+ }
3125
+
3126
+ /**
3127
+ * The deps behind text editing, the clipboard, and Slice.
3128
+ */
3129
+
3130
+ /**
3131
+ * Dep for `enterTextEditAction`.
3132
+ *
3133
+ * Wrap the return value of `useTextEdit` / `useSceneTextEdit` to source this
3134
+ * dep. The `isTextNode` predicate is optional — when absent the action fires
3135
+ * unconditionally (the binding spec acts as the gate).
3136
+ *
3137
+ * @example
3138
+ * ```ts
3139
+ * const textEdit = useSceneTextEdit(scene, container);
3140
+ * useDepSource('textEdit', () => ({
3141
+ * startEdit: textEdit.startEdit,
3142
+ * isTextNode: textEdit.isTextNode,
3143
+ * }));
3144
+ * ```
3145
+ */
3146
+ interface TextEditDep {
3147
+ /** Begin editing the node with `id`. */
3148
+ startEdit(id: string, opts?: {
3149
+ caret?: number | 'all';
3150
+ }): void;
3151
+ /**
3152
+ * Optional predicate: returns `true` when the node with `id` is a text node.
3153
+ * When absent the action fires on any selected node (binding spec is the gate).
3154
+ * When present and returning `false`, the invocation is a no-op.
3155
+ */
3156
+ isTextNode?(id: string): boolean;
3157
+ }
3158
+ /**
3159
+ * Clipboard dep — the imperative surface `useClipboardOps` returns.
3160
+ *
3161
+ * Consumers publish their live clipboard through `useDepSource('clipboard',
3162
+ * …)` from inside the `<DepRegistryProvider>` (i.e. under `<SceneCanvas>`).
3163
+ * The kit deliberately does not build one for them: `useClipboardOps` needs
3164
+ * an adapter and a selection reader that only the consumer can supply.
3165
+ */
3166
+ interface ClipboardDep {
3167
+ copy(): void;
3168
+ paste(at?: {
3169
+ worldX: number;
3170
+ worldY: number;
3171
+ }): void;
3172
+ isEmpty(): boolean;
3173
+ }
3174
+ /**
3175
+ * The commit behind the Slice action. `commit` receives the cut as a polyline
3176
+ * of at least two points (world coords): the drag's two ends for a straight
3177
+ * cut, its whole trail for a freehand one, the placed points for a
3178
+ * click-by-click one, whose last point equals its first when it closes into
3179
+ * a loop. `<SceneCanvas>` publishes one over its scene (`useSliceDepSource`);
3180
+ * a consumer replaces it with `useSliceDep`.
3181
+ */
3182
+ interface SliceDep {
3183
+ commit(cut: ReadonlyArray<Point2>): void;
3184
+ }
3185
+
3186
+ /** Minimal view API the action layer consumes. */
3187
+ interface ViewApi {
3188
+ get(): View;
3189
+ set(v: View): void;
3190
+ /** How this camera's world maps into the world the invocation edits in,
3191
+ * when that is a parallax plane — set by `inPlane` on the view it hands a
3192
+ * wrapped action. Absent or null: the camera's own world. */
3193
+ plane?(): PlaneMap | null;
3194
+ /** How the world the invocation edits in maps into the world `layer`'s
3195
+ * nodes are stored in, read now — set by `inPlane` alongside `plane`.
3196
+ * Absent or null: the same world. */
3197
+ planeOf?(layer: string): PlaneMap | null;
3198
+ /** Optional recenter callback. When wired, `viewportZoomAction`'s `reset`
3199
+ * branch (Cmd-0) calls this instead of resetting to identity. Return the
3200
+ * target `View` to let the action animate there; return nothing to keep
3201
+ * dispatching the view yourself. */
3202
+ recenter?(): View | void;
3203
+ /** Optional canvas-local host dimensions (CSS px). When wired,
3204
+ * `viewportZoomAction`'s keyboard branches (Cmd+= / Cmd+-) anchor at the
3205
+ * host center instead of the top-left origin. Null when the host isn't
3206
+ * measurable (unmounted). */
3207
+ hostSize?(): {
3208
+ width: number;
3209
+ height: number;
3210
+ } | null;
3211
+ /** Optional camera animation. `<SceneCanvas>` wires these three; a consumer
3212
+ * publishing their own `view` dep need not, and actions fall back to `set`. */
3213
+ animate?(to: View, opts?: ViewAnimationOptions): void;
3214
+ stopAnimation?(): void;
3215
+ /** Where an in-flight camera animation is heading, or null. Compute the next
3216
+ * discrete step from this so repeated presses compound. */
3217
+ animationTarget?(): View | null;
3218
+ /** Optional momentum decay. `<SceneCanvas>` wires this from `useDecayLoop`;
3219
+ * a consumer publishing their own `view` dep need not, and `viewport.dragPan`
3220
+ * simply lands the pan without coasting. */
3221
+ decay?(config: DecayLoopConfig): void;
3222
+ stopDecay?(): void;
3223
+ /** Whether a scene layer reaches the screen in this view — its own
3224
+ * `layerVisibility` / `layerOrder`, on top of the scene's `visible` flag.
3225
+ * Absent: this view paints every layer the scene shows. Selecting actions
3226
+ * pass over what the asking view does not paint. */
3227
+ layerIsPainted?(layerId: string): boolean;
3228
+ }
3229
+ /** The part of the asking view a region hit-test consults. `get` is its
3230
+ * camera, which a parallax layer is picked through. */
3231
+ type HitTestView = RegionPickView;
3232
+ /**
3233
+ * Topmost-node-at-world-point dep, for any action that needs a single-best
3234
+ * pick. The dep walks hits front-to-back and returns the first id not in
3235
+ * `exclude`. Pass moving-node roots + their descendants when the caller
3236
+ * wants to ignore the nodes it's manipulating.
3237
+ */
3238
+ type NodeAtPointDep = (point: {
3239
+ x: number;
3240
+ y: number;
3241
+ }, exclude?: Iterable<NodeId>) => NodeId | null;
3242
+ /** What an area-selecting action needs: a way to ask what a region covers,
3243
+ * and a way to read and replace the selection. */
3244
+ interface AreaSelectDep {
3245
+ /** Return ids of all scene nodes whose AABB overlaps `bounds`, skipping any
3246
+ * on a layer `view` — the view the gesture ran in — does not paint. */
3247
+ hitTestArea(bounds: {
3248
+ x: number;
3249
+ y: number;
3250
+ width: number;
3251
+ height: number;
3252
+ }, view?: HitTestView): NodeId[];
3253
+ /** Return the current selection id list. */
3254
+ getSelection(): NodeId[];
3255
+ /** Replace the current selection. */
3256
+ setSelection(ids: NodeId[]): void;
3257
+ }
3258
+ /**
3259
+ * Adapter dep for `lassoSelectAction`: polygon-lasso hit-testing +
3260
+ * selection read/write.
3261
+ */
3262
+ interface LassoSelectDep {
3263
+ /**
3264
+ * Hit-test against a closed polygon (vertex order CW or CCW; last→first
3265
+ * closing edge is implicit). Returns matching node ids.
3266
+ * Optional — when absent, `lassoSelectAction` falls back to AABB via
3267
+ * `hitTestArea`.
3268
+ */
3269
+ hitTestLasso?(polygon: ReadonlyArray<{
3270
+ x: number;
3271
+ y: number;
3272
+ }>, mode: 'centers' | 'intersect' | 'enclosed', view?: HitTestView): string[];
3273
+ /** Return ids of nodes whose AABB overlaps the given rect (fallback). */
3274
+ hitTestArea(bounds: {
3275
+ x: number;
3276
+ y: number;
3277
+ width: number;
3278
+ height: number;
3279
+ }, view?: HitTestView): string[];
3280
+ /** Return the current selection id list. */
3281
+ getSelection(): string[];
3282
+ /** Replace the current selection. */
3283
+ setSelection(ids: string[]): void;
3284
+ }
3285
+
3286
+ /**
3287
+ * Per-kind extra geometry passed to `InsertDep.commit`.
3288
+ *
3289
+ * Built-in tools populate a typed variant so the kit's default factory can
3290
+ * render the true tool params (line endpoints, polygon side count, star
3291
+ * geometry, pencil sample list). Consumer-defined tools may pass any
3292
+ * `{ kind: string; ... }` payload; the kit's factory falls back to AABB
3293
+ * inscription for unknown kinds.
3294
+ *
3295
+ * `bounds` is still passed alongside as a useful AABB pose hint — factories
3296
+ * may use it as the node's pose even when richer geometry is available. Any may carry a `minSize`
3297
+ * (`{ width, height }`), which the kit's factories keep as `data.minSize` so a resize holds to it.
3298
+ */
3299
+ type InsertExtras = {
3300
+ kind: 'rect';
3301
+ } | {
3302
+ kind: 'ellipse';
3303
+ } | {
3304
+ kind: 'line';
3305
+ a: {
3306
+ x: number;
3307
+ y: number;
3308
+ };
3309
+ b: {
3310
+ x: number;
3311
+ y: number;
3312
+ };
3313
+ } | {
3314
+ kind: 'polygon';
3315
+ sides: number;
3316
+ rotation: number;
3317
+ center?: {
3318
+ x: number;
3319
+ y: number;
3320
+ };
3321
+ radius?: number;
3322
+ } | {
3323
+ kind: 'star';
3324
+ points: number;
3325
+ innerRadiusRatio: number;
3326
+ rotation: number;
3327
+ center?: {
3328
+ x: number;
3329
+ y: number;
3330
+ };
3331
+ outerRadius?: number;
3332
+ } | {
3333
+ kind: 'pencil';
3334
+ samples: ReadonlyArray<DragSample>;
3335
+ } | {
3336
+ kind: 'text';
3337
+ text?: string;
3338
+ }
3339
+ /** A sticky note: a text node with a background, in the look its tool names. */
3340
+ | ({
3341
+ kind: 'sticky';
3342
+ text?: string;
3343
+ } & StickyStyle)
3344
+ /** A finished path in world coords, as the pen tool commits one. `bounds`
3345
+ * is its AABB. An open path takes no fill. `data` is laid under the path
3346
+ * and paint on the node's data: the form the path was drawn from
3347
+ * (`data.representation`), say. */
3348
+ | {
3349
+ kind: 'path';
3350
+ path: _weasel_js_geom.PolygonPath;
3351
+ closed: boolean;
3352
+ data?: Readonly<Record<string, unknown>>;
3353
+ } | {
3354
+ kind: 'image';
3355
+ src?: string;
3356
+ opacity?: number;
3357
+ /** Chrome-only: what the in-flight drag paints. Read by the overlay
3358
+ * layer, ignored by the insert dep. */
3359
+ preview?: 'bitmap' | 'outline';
3360
+ } | {
3361
+ kind: string;
3362
+ [extra: string]: unknown;
3363
+ };
3364
+
3365
+ /**
3366
+ * Adapter dep for `resizeAction`: bounds-frame behaviors (e.g.
3367
+ * `clampMinSize`) and group-expansion (`expandIds`). Snapping is the `snap`
3368
+ * dep's.
3369
+ *
3370
+ * The generic is erased to `unknown` at the schema entry; consumers cast at
3371
+ * the call site.
3372
+ */
3373
+ interface ResizePolicy<TPose> extends GestureLifecycleOptions {
3374
+ /** Bounds-frame constraints. Constrained to `TPose extends Bounds` since
3375
+ * constraints read/write `{x,y,width,height}`. For non-rect TPose pass `[]`. */
3376
+ constraints: TPose extends FramedBox ? BoundsConstraint<TPose>[] : never[];
3377
+ /** Group-expansion at gesture start. Identity (`ids => ids`) when group
3378
+ * resize isn't wanted. */
3379
+ expandIds: (ids: string[]) => string[];
3380
+ }
3381
+ /**
3382
+ * Layout-strategy lookup by container id, consumed by `moveAction` to run
3383
+ * the drag-time reflow pass. Sourced by `<SceneCanvas>` from the layout each
3384
+ * container declares on its scene node. `getLayout` returns null for a
3385
+ * container that declares none, so the reflow pass is a no-op then.
3386
+ */
3387
+ interface LayoutDep {
3388
+ getLayout(containerId: string): LayoutStrategy<unknown> | null;
3389
+ /** Which container wins when several contain the drop point. Default
3390
+ * `'innermost'`. */
3391
+ dropTarget?: LayoutDropTargetMode;
3392
+ /** Carries displaced siblings to their slots over time. Absent, they snap. */
3393
+ reflow?: ReflowTransition<unknown> | null;
3394
+ }
3395
+
3396
+ /**
3397
+ * The names an action may declare in `requires`, and what each resolves to.
3398
+ *
3399
+ * This is the whole vocabulary of things an action can reach — selection,
3400
+ * scene, view, history, and the rest. The interface is declared in
3401
+ * `@weasel-js/routing`, which knows that an action names its dependencies but
3402
+ * owns only `activeTool` among them; these entries are the kit's, merged in from
3403
+ * outside exactly the way a consumer merges its own
3404
+ * (`declare module '@weasel-js/core'`).
3405
+ */
3406
+ declare module '@weasel-js/routing' {
3407
+ interface DepSchema {
3408
+ /** Kit selection state — ids of currently selected nodes. */
3409
+ selection: SelectionApi;
3410
+ /** Current viewport — camera position + scale. */
3411
+ view: ViewApi;
3412
+ /**
3413
+ * Scene tree — structural reads + undoable mutations.
3414
+ *
3415
+ * The entry uses the fully-erased form `Scene<unknown, string, unknown>`
3416
+ * because `DepSchema` must be concrete; any `Scene<MyData, MyLayer,
3417
+ * MyPose>` is assignable to it. Actions that need a typed scene back
3418
+ * should cast: `deps.scene as Scene<MyData, MyLayer, MyPose>`.
3419
+ */
3420
+ scene: Scene<unknown, string, unknown>;
3421
+ /** Undo/redo history bound to the current scene. */
3422
+ history: History;
3423
+ /** Area-select dep — AABB hit-test + selection read/write. Override
3424
+ * per-consumer for custom hit-testing (e.g. contain-mode). */
3425
+ areaSelect: AreaSelectDep;
3426
+ /** Topmost node at a world-space point. Optional: actions that read this
3427
+ * (e.g. `moveAction` reparent-on-drop) fall back to a no-op when the dep
3428
+ * isn't registered. */
3429
+ nodeAtPoint?: NodeAtPointDep;
3430
+ /** Insert dep — node factory for drag-to-insert. Override per-consumer to
3431
+ * provide a typed node factory (e.g. with custom data payloads). */
3432
+ insert: InsertDep;
3433
+ /** Where `insertAction` keeps its gesture in flight, so
3434
+ * `insert.adjustRotation` reaches the one in its own input scope.
3435
+ * Sourced by `<SceneCanvas>`; without it the rotation does nothing. */
3436
+ insertLive?: InsertLive;
3437
+ /** The params an action starts with in this scope when its binding
3438
+ * passes `given`, `<SceneCanvas tune>` included: what a tool's chrome
3439
+ * reads to draw what the action it binds will make. Sourced by
3440
+ * `<SceneCanvas>`. */
3441
+ actionParams?: (id: string, given?: Record<string, unknown>) => Record<string, unknown>;
3442
+ /** The container the `insert` dep puts new nodes into — every shape a
3443
+ * tool draws and every dropped image or text. Absent, or answering
3444
+ * `null`: the top of the tree. */
3445
+ insertInto?: InsertIntoDep;
3446
+ /** Snap dep: the sessions a gesture snaps through, over `<SceneCanvas
3447
+ * snap>`'s sources. Absent means no snapping. */
3448
+ snap?: SnapDep;
3449
+ /** The store the snap readout layer draws, for an action's own marks. Sourced by `<SceneCanvas>`. */
3450
+ snapReadout?: SnapReadoutDep;
3451
+ /**
3452
+ * The canvas's debug sink.
3453
+ * Sourced by `<SceneCanvas>`; absent while its `debug` overlay is off.
3454
+ * Actions report what they did here, and the overlay draws it.
3455
+ */
3456
+ debug?: DebugSink;
3457
+ /** Where an action's `preview` draws what it would make, over the canvas.
3458
+ * Sourced by `<SceneCanvas>`. */
3459
+ previewPaths?: PreviewPathsDep;
3460
+ /** Viewport point of a world point on this canvas, or null before it mounts.
3461
+ * Sourced by `<SceneCanvas>`. */
3462
+ worldToClient?: (x: number, y: number) => {
3463
+ x: number;
3464
+ y: number;
3465
+ } | null;
3466
+ /** Lasso-select dep — polygon hit-test + selection read/write. */
3467
+ lassoSelect: LassoSelectDep;
3468
+ /** Edit-anchors dep — narrow read/write of one polygon's path. If
3469
+ * absent, `editAnchorsAction`'s `start` returns an empty handle (no-op). */
3470
+ editAnchors: EditAnchorsDep;
3471
+ /** The transforms a path being edited should stay its own image under.
3472
+ * Absent: an anchor drag moves only what is dragged. */
3473
+ pathSymmetry?: PathSymmetryDep;
3474
+ /**
3475
+ * Text-edit dep — activates the in-place text editing overlay. Sourced
3476
+ * from consumer via `useTextEdit` / `useSceneTextEdit`.
3477
+ *
3478
+ * The optional `isTextNode` predicate guards against entering edit mode on
3479
+ * non-text nodes. A binding can pre-filter instead with a
3480
+ * `target: 'kind:text:selected'` spec; the guard remains for consumers who
3481
+ * bind the broader `'selected-body'` target or opted out of routing.
3482
+ */
3483
+ textEdit: TextEditDep;
3484
+ /**
3485
+ * Resize-policy dep — bounds constraints, point-snap behaviors and
3486
+ * group expansion for `resizeAction`. Optional: when omitted,
3487
+ * `resizeAction` falls back to identity defaults. Consumers wire via
3488
+ * `useDepSource('resizePolicy', ...)` or the `useResizePolicy` helper.
3489
+ */
3490
+ resizePolicy?: ResizePolicy<unknown>;
3491
+ /**
3492
+ * How to read and rewrite a pose — bounds, translate, remap, rotation. Every
3493
+ * built-in action that touches a pose reads it. Sourced by `<SceneCanvas>`
3494
+ * from its `poseDescriptor` prop; `AUTO_POSE_DESCRIPTOR` when absent.
3495
+ */
3496
+ poseDescriptor?: PoseDescriptor<unknown>;
3497
+ /** Whether the box resize, rotate, flip, align, and distribute work against
3498
+ * includes the stroke. From `<SceneCanvas geometry.boundsIncludeStroke>`;
3499
+ * absent means `true`. */
3500
+ boundsIncludeStroke?: boolean;
3501
+ /**
3502
+ * Booleans adapter — read selection ids, fetch world-space `Path`s,
3503
+ * compare z-order, and mint result nodes for Pathfinder ops.
3504
+ *
3505
+ * Consumers wire via `useBooleansAdapter(adapter)`.
3506
+ */
3507
+ booleansAdapter?: BooleansAdapter;
3508
+ /**
3509
+ * Create Outlines adapter — read selection ids, resolve text nodes, and
3510
+ * mint the path nodes that replace them. Consumers wire it with
3511
+ * `useCreateOutlinesAdapter(adapter)`; the `createOutlines` action reads it
3512
+ * in both its `enabled` predicate and its invoker.
3513
+ */
3514
+ createOutlinesAdapter?: CreateOutlinesAdapter;
3515
+ /** Gesture dispatcher control surface, so an action can abort an
3516
+ * in-flight handle (Escape cancels a drag, etc.). */
3517
+ dispatcher?: {
3518
+ cancelAll(reason: 'commit' | 'cancel'): void;
3519
+ };
3520
+ /**
3521
+ * Layout-strategy lookup. Sourced by `<SceneCanvas>` from the scene.
3522
+ * Optional: absent (or all-null) → `moveAction` skips reflow.
3523
+ */
3524
+ layout?: LayoutDep;
3525
+ /**
3526
+ * Slice dep — the commit for the Slice action. `<SceneCanvas>` publishes
3527
+ * `useSliceDepSource`; a consumer overrides it with `useSliceDep`.
3528
+ *
3529
+ * Optional: when absent, `sliceAction` is a no-op.
3530
+ */
3531
+ slice?: SliceDep;
3532
+ /** Clipboard dep; see {@link ClipboardDep}. `clipboard.copy` and
3533
+ * `clipboard.cut` both no-op when it is absent. */
3534
+ clipboard?: ClipboardDep;
3535
+ /**
3536
+ * Optional consumer commit hook. When present, `moveAction` (and other
3537
+ * default actions) submit their committed ops through it instead of
3538
+ * `scene.applyBatch`, so apps with their own history integration
3539
+ * (checkpoint + push entry) capture the gesture as one undo entry.
3540
+ * When absent, commits fall back to `scene.applyBatch`.
3541
+ */
3542
+ applyOps?: (ops: Op[], label: string) => void;
3543
+ /**
3544
+ * Ingestion dep — canvas viewport rect + consumer file→src resolver.
3545
+ * Optional: when absent, the `ingest` action no-ops (there is no
3546
+ * placement geometry to work with).
3547
+ */
3548
+ ingestion?: IngestionDep;
3549
+ /**
3550
+ * Optional consumer seam for the eager-sync layer: lets pose-transform
3551
+ * actions (resize/move/nudge/flip — NOT rotate) ALSO rewrite a node's
3552
+ * data-held geometry. Given a node and the affine `m` applied to its pose,
3553
+ * `transform(node, m)` returns updated `data` (geometry mapped by `m`) or
3554
+ * `null` for nodes with no data-held geometry.
3555
+ *
3556
+ * Strictly opt-in: when absent (or when `transform` returns null), the kit
3557
+ * emits only the pose op and leaves `data` untouched. Rotate intentionally
3558
+ * never consults this seam (rotation lives on the pose, baked at render).
3559
+ */
3560
+ geometryProjection?: GeometryProjection;
3561
+ /**
3562
+ * The surface's own camera. Inside a `<CanvasView>`, `view` answers that
3563
+ * view's camera and this one does not change: an action bound in a view
3564
+ * that must move the main camera — a minimap's pan — reads this.
3565
+ */
3566
+ rootView: ViewApi;
3567
+ /**
3568
+ * The pointer store in scope: where the pointer is, in which view. Shared
3569
+ * by every surface under one `<PointerContextProvider>`.
3570
+ */
3571
+ pointer?: _weasel_js_routing_react.PointerContextValue;
3572
+ /**
3573
+ * The touch or pen long-press being held, if any: where, since when, how
3574
+ * far through, and whether any binding would fire on it. Sourced by
3575
+ * `<SceneCanvas>` from its gesture dispatcher; press feedback reads it.
3576
+ */
3577
+ longPress?: LongPressState;
3578
+ }
3579
+ }
3580
+
3581
+ export { type CreateOutlinesAdapter as $, type AddNodeSpec as A, type LayerGroup as B, type ContentHandlerEntry as C, type Dims as D, type EditAnchorsDep as E, type FitViewToBoundsOptions as F, type GestureLifecycleOptions as G, type HandleLocks as H, type InertiaConfig as I, type SerializedScene as J, type GeometryProjection as K, type LayoutFrame as L, type InsertNodeFactory as M, type Node as N, type InsertPaint as O, type PathEditMark as P, type SvgIngestOptions as Q, type RectPose as R, type Scene as S, type SceneCanvasSnap as T, type Affordance as U, type ViewAnimationOptions as V, type AffordanceRegion as W, type AffordanceBinding as X, type CommonAffordanceScratch as Y, type TextOverflow as Z, _resetPaintKindsForTests as _, type PathEditExtension as a, type PaintKind as a$, type PaintKindEntry as a0, type DerivePoseFn as a1, type DerivePathFn as a2, type DerivedDep as a3, type PathEditTarget as a4, type PathSymmetryDep as a5, type BooleanOpOptions as a6, type BooleansAdapter as a7, type BooleanOp as a8, type PathPaint as a9, type FinishedEditFrame as aA, type FinishedPathEdit as aB, GEOMETRY_BOUND_DATA as aC, type HandleLock as aD, type HitTestView as aE, IDENTITY_POSE_COMPOSITION as aF, type IngestCtx as aG, type IngestionDep as aH, type InsertDep as aI, type InsertEnds as aJ, type InsertExtras as aK, type InsertIntoDep as aL, type InsertLive as aM, type LassoSelectDep as aN, type LayerCommandCache as aO, type LayerDrawFailure as aP, type LayerDrawSpan as aQ, type LayerRecord as aR, type LayerRetainPolicy as aS, type LayoutDep as aT, type LayoutMove as aU, type LeafNode as aV, type Locus as aW, type MinSize as aX, type NodeAtPointDep as aY, type OutlinePathSpec as aZ, PATH_OVERLAY_ROLES as a_, type BooleanOpResult as aa, type BooleanStrokes as ab, type SnapMods as ac, type SourceCandidate as ad, type SnapProbeAt as ae, type SnapCollect as af, type SnapMark as ag, type SnapDep as ah, type SnapOutcome as ai, type AddLayerSpec as aj, type AngleCandidate as ak, type AngleCollect as al, type AnimateToBoundsOptions as am, type AreaSelectDep as an, type Bivariant as ao, type BooleanOpPreview as ap, type BooleanPreviewPiece as aq, type ClipFromPoseFn as ar, type ClipboardDep as as, type ClipboardIngestCtx as at, type ContainerNode as au, type CopiesFromPoseFn as av, type CreateOutlinesResult as aw, type CustomPaintContext as ax, DEFAULT_LAYER_RETAIN as ay, type DecayLoopConfig as az, type SnapSource as b, listPaintKinds as b$, type PaintKindEditorProps as b0, type PaintKindFamily as b1, type PaintKindLoader as b2, type PanBounds as b3, type PathEditDrag as b4, type PathEditDragStart as b5, type PathEditFinishCtx as b6, type PathEditHandleMove as b7, type PathEditMarksCtx as b8, type PathEditOther as b9, type SvgUnpacker as bA, type SystemLayerRecord as bB, type TextEditDep as bC, type TextNodeData as bD, type TransientPath as bE, type UserLayerRecord as bF, VIEW_ANIMATION_KEY as bG, type ViewAnimationApi as bH, type ViewApi as bI, type ViewChannel as bJ, applyBooleanOp as bK, applyCreateOutlines as bL, asNodeId as bM, asPaint as bN, composeWorldPose as bO, composesFrames as bP, createPathOverlay as bQ, createSnapOutcomeStore as bR, createSnapReadoutLayer as bS, depsUnchanged as bT, drawLayers as bU, drawOneLayer as bV, fitViewToBounds as bW, getPaintKind as bX, isLayerPainted as bY, isLayerVisible as bZ, listGradientKinds as b_, type PathEditPart as ba, type PathEditStore as bb, type PathForm as bc, type PathOverlay as bd, type PathOverlayOptions as be, type PathOverlayStyle as bf, type PathRepresentation as bg, type PoseClosure as bh, type PoseHold as bi, type PoseOverride as bj, type PoseWriteOrigin as bk, type PreviewPathsDep as bl, type RemovedNode as bm, type ResizePolicy as bn, SCENE_HISTORY_FORM as bo, STICKY_DEFAULTS as bp, type SceneArrivalHandler as bq, type SerializedLayer as br, type SerializedNode as bs, type SerializedSceneHistory as bt, type SnapBegin as bu, type SnapEdge as bv, type SnapEdges as bw, type SnapMarks as bx, type SnapReadoutDep as by, type SnapReadoutStyle as bz, type SnapGesture as c, minSizeOf as c0, paintKindOf as c1, paintKindRegistry as c2, paintedLayers as c3, paintsLayer as c4, paletteInsertPaint as c5, pathPaintOf as c6, patternFamily as c7, previewBooleanOp as c8, rebaseLocalPose as c9, registerContentHandler as ca, registerPaintKind as cb, registerPaintKindLoader as cc, seedTile as cd, stickyData as ce, stickyNodeFactory as cf, subscribeToSources as cg, switchGradientKind as ch, textBoxOf as ci, useDecayLoop as cj, useViewAnimation as ck, useViewAnimationOn as cl, viewAxes as cm, withoutGeometryBoundData as cn, type SnapConstrain as d, type SnapResizeBox as e, type SnapGeometry as f, type SnapOutcomeStore as g, type SnapSession as h, type SystemLayerSpec as i, type RegisteredOp as j, type SceneRegistry as k, type PoseComposition as l, type RenderLayer as m, type LayerHit as n, type PoseAdapter as o, type ViewportDims as p, type RedrawSource as q, type EditAnchorsParams as r, type SliceDep as s, type StickyStyle as t, type PoseOverrides as u, type PoseRemoval as v, type PoseWrite as w, type ScenePoseReports as x, type AnchorMarkerShape as y, type ChromeState as z };