@weasel-js/core 1.6.1 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1005) hide show
  1. package/CHANGELOG.md +1006 -0
  2. package/README.md +28 -9
  3. package/dist/WeaselProvider.js +15 -0
  4. package/dist/WeaselProvider.js.map +1 -0
  5. package/dist/affordances/composeAffordanceLayer.js +224 -0
  6. package/dist/affordances/composeAffordanceLayer.js.map +1 -0
  7. package/dist/affordances/cornerResize.js +69 -0
  8. package/dist/affordances/cornerResize.js.map +1 -0
  9. package/dist/affordances/hitAffordanceRegions.js +138 -0
  10. package/dist/affordances/hitAffordanceRegions.js.map +1 -0
  11. package/dist/affordances/pathAnchors.js +66 -0
  12. package/dist/affordances/pathAnchors.js.map +1 -0
  13. package/dist/affordances/rotationHandle.js +103 -0
  14. package/dist/affordances/rotationHandle.js.map +1 -0
  15. package/dist/animation/behaviors/momentum.js +118 -0
  16. package/dist/animation/behaviors/momentum.js.map +1 -0
  17. package/dist/animation/colorHelpers.js +135 -0
  18. package/dist/animation/colorHelpers.js.map +1 -0
  19. package/dist/animation/colorRegistry.js +37 -0
  20. package/dist/animation/colorRegistry.js.map +1 -0
  21. package/dist/animation/index.js +20 -0
  22. package/dist/animation/loop.js +62 -0
  23. package/dist/animation/loop.js.map +1 -0
  24. package/dist/animation/observe.js +23 -0
  25. package/dist/animation/observe.js.map +1 -0
  26. package/dist/animation/poseHelpers.js +50 -0
  27. package/dist/animation/poseHelpers.js.map +1 -0
  28. package/dist/animation/reflow.js +121 -0
  29. package/dist/animation/reflow.js.map +1 -0
  30. package/dist/animation/rig/bindRig.js +74 -0
  31. package/dist/animation/rig/bindRig.js.map +1 -0
  32. package/dist/animation/rig/blendPoses.js +43 -0
  33. package/dist/animation/rig/blendPoses.js.map +1 -0
  34. package/dist/animation/rig/mirrorPose.js +19 -0
  35. package/dist/animation/rig/mirrorPose.js.map +1 -0
  36. package/dist/animation/rig/resolveSkeleton.js +33 -0
  37. package/dist/animation/rig/resolveSkeleton.js.map +1 -0
  38. package/dist/animation/rig/solveIk.js +103 -0
  39. package/dist/animation/rig/solveIk.js.map +1 -0
  40. package/dist/animation/rig/types.js +12 -0
  41. package/dist/animation/rig/types.js.map +1 -0
  42. package/dist/animation/rig/useRig.js +23 -0
  43. package/dist/animation/rig/useRig.js.map +1 -0
  44. package/dist/animation/slew.js +27 -0
  45. package/dist/animation/slew.js.map +1 -0
  46. package/dist/animation/stagger.js +138 -0
  47. package/dist/animation/stagger.js.map +1 -0
  48. package/dist/animation/timeline/booking.js +106 -0
  49. package/dist/animation/timeline/booking.js.map +1 -0
  50. package/dist/animation/timeline/createTimeline.js +116 -0
  51. package/dist/animation/timeline/createTimeline.js.map +1 -0
  52. package/dist/animation/timeline/sampleTrack.js +29 -0
  53. package/dist/animation/timeline/sampleTrack.js.map +1 -0
  54. package/dist/animation/useAnimator.js +329 -0
  55. package/dist/animation/useAnimator.js.map +1 -0
  56. package/dist/animation/wrappers/animateLifecycle.js +40 -0
  57. package/dist/animation/wrappers/animateLifecycle.js.map +1 -0
  58. package/dist/animation/wrappers/animateOnSetPose.js +44 -0
  59. package/dist/animation/wrappers/animateOnSetPose.js.map +1 -0
  60. package/dist/{autoPoseDescriptor-_XOyF7t4.d.ts → autoPoseDescriptor-BT_vp9FO.d.ts} +2 -2
  61. package/dist/{builtins-HWyuLzE-.d.ts → builtins-BSUfH8nU.d.ts} +1301 -508
  62. package/dist/canvas/Canvas.js +608 -0
  63. package/dist/canvas/Canvas.js.map +1 -0
  64. package/dist/canvas/CanvasView.js +255 -0
  65. package/dist/canvas/CanvasView.js.map +1 -0
  66. package/dist/canvas/CursorCoordsHud.js +75 -0
  67. package/dist/canvas/CursorCoordsHud.js.map +1 -0
  68. package/dist/canvas/DrawCanvas.js +67 -0
  69. package/dist/canvas/DrawCanvas.js.map +1 -0
  70. package/dist/canvas/MinimapCanvas.js +139 -0
  71. package/dist/canvas/MinimapCanvas.js.map +1 -0
  72. package/dist/canvas/ModalityHud.js +66 -0
  73. package/dist/canvas/ModalityHud.js.map +1 -0
  74. package/dist/canvas/NodeShape.js +391 -0
  75. package/dist/canvas/NodeShape.js.map +1 -0
  76. package/dist/canvas/PickHud.js +93 -0
  77. package/dist/canvas/PickHud.js.map +1 -0
  78. package/dist/canvas/SceneCanvas/ActionsProviderIfRoot.js +10 -0
  79. package/dist/canvas/SceneCanvas/ActionsProviderIfRoot.js.map +1 -0
  80. package/dist/canvas/SceneCanvas/DepRegistryProviderIfRoot.js +10 -0
  81. package/dist/canvas/SceneCanvas/DepRegistryProviderIfRoot.js.map +1 -0
  82. package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js +51 -0
  83. package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js.map +1 -0
  84. package/dist/canvas/SceneCanvas/contributionFrameHooks.js +42 -0
  85. package/dist/canvas/SceneCanvas/contributionFrameHooks.js.map +1 -0
  86. package/dist/canvas/SceneCanvas/defaultNodeProperties.js +549 -0
  87. package/dist/canvas/SceneCanvas/defaultNodeProperties.js.map +1 -0
  88. package/dist/canvas/SceneCanvas/defaultNodeRouting.js +26 -0
  89. package/dist/canvas/SceneCanvas/defaultNodeRouting.js.map +1 -0
  90. package/dist/canvas/SceneCanvas/dispatcherGestureBounds.js +69 -0
  91. package/dist/canvas/SceneCanvas/dispatcherGestureBounds.js.map +1 -0
  92. package/dist/canvas/SceneCanvas/features.js +97 -0
  93. package/dist/canvas/SceneCanvas/features.js.map +1 -0
  94. package/dist/canvas/SceneCanvas/poseGeometry.js +46 -0
  95. package/dist/canvas/SceneCanvas/poseGeometry.js.map +1 -0
  96. package/dist/canvas/SceneCanvas/useActionsPropResolver.js +48 -0
  97. package/dist/canvas/SceneCanvas/useActionsPropResolver.js.map +1 -0
  98. package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js +70 -0
  99. package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js.map +1 -0
  100. package/dist/canvas/SceneCanvas/useContributionRoles.js +75 -0
  101. package/dist/canvas/SceneCanvas/useContributionRoles.js.map +1 -0
  102. package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js +172 -0
  103. package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js.map +1 -0
  104. package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js +69 -0
  105. package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js.map +1 -0
  106. package/dist/canvas/SceneCanvas/useSceneSelectTool.js +127 -0
  107. package/dist/canvas/SceneCanvas/useSceneSelectTool.js.map +1 -0
  108. package/dist/canvas/SceneCanvas/useViewportActions.js +30 -0
  109. package/dist/canvas/SceneCanvas/useViewportActions.js.map +1 -0
  110. package/dist/canvas/SceneCanvas.js +992 -0
  111. package/dist/canvas/SceneCanvas.js.map +1 -0
  112. package/dist/canvas/SceneViewCanvas.js +54 -0
  113. package/dist/canvas/SceneViewCanvas.js.map +1 -0
  114. package/dist/canvas/accentColor.js +9 -0
  115. package/dist/canvas/accentColor.js.map +1 -0
  116. package/dist/canvas/affordanceAt.js +63 -0
  117. package/dist/canvas/affordanceAt.js.map +1 -0
  118. package/dist/canvas/buildSceneTree.js +65 -0
  119. package/dist/canvas/buildSceneTree.js.map +1 -0
  120. package/dist/canvas/canvasRenderer.js +89 -0
  121. package/dist/canvas/canvasRenderer.js.map +1 -0
  122. package/dist/canvas/colorOverrides.js +16 -0
  123. package/dist/canvas/colorOverrides.js.map +1 -0
  124. package/dist/canvas/defaultDrawOne.js +43 -0
  125. package/dist/canvas/defaultDrawOne.js.map +1 -0
  126. package/dist/canvas/deps/areaSelect.js +19 -0
  127. package/dist/canvas/deps/areaSelect.js.map +1 -0
  128. package/dist/canvas/deps/debug.js +9 -0
  129. package/dist/canvas/deps/debug.js.map +1 -0
  130. package/dist/canvas/deps/dispatcher.js +11 -0
  131. package/dist/canvas/deps/dispatcher.js.map +1 -0
  132. package/dist/canvas/deps/editAnchors.js +101 -0
  133. package/dist/canvas/deps/editAnchors.js.map +1 -0
  134. package/dist/canvas/deps/geometryProjection.js +11 -0
  135. package/dist/canvas/deps/geometryProjection.js.map +1 -0
  136. package/dist/canvas/deps/hitTestArea.js +51 -0
  137. package/dist/canvas/deps/hitTestArea.js.map +1 -0
  138. package/dist/canvas/deps/ingestion.js +31 -0
  139. package/dist/canvas/deps/ingestion.js.map +1 -0
  140. package/dist/canvas/deps/insert.js +116 -0
  141. package/dist/canvas/deps/insert.js.map +1 -0
  142. package/dist/canvas/deps/lassoSelect.js +20 -0
  143. package/dist/canvas/deps/lassoSelect.js.map +1 -0
  144. package/dist/canvas/deps/layout.js +34 -0
  145. package/dist/canvas/deps/layout.js.map +1 -0
  146. package/dist/canvas/deps/nodeAtPoint.js +19 -0
  147. package/dist/canvas/deps/nodeAtPoint.js.map +1 -0
  148. package/dist/canvas/deps/poseComposition.js +11 -0
  149. package/dist/canvas/deps/poseComposition.js.map +1 -0
  150. package/dist/canvas/deps/poseDescriptor.js +12 -0
  151. package/dist/canvas/deps/poseDescriptor.js.map +1 -0
  152. package/dist/canvas/deps/resizePolicy.js +35 -0
  153. package/dist/canvas/deps/resizePolicy.js.map +1 -0
  154. package/dist/canvas/deps/slice.js +99 -0
  155. package/dist/canvas/deps/slice.js.map +1 -0
  156. package/dist/canvas/deps/snap.js +11 -0
  157. package/dist/canvas/deps/snap.js.map +1 -0
  158. package/dist/canvas/deps/textEdit.js +21 -0
  159. package/dist/canvas/deps/textEdit.js.map +1 -0
  160. package/dist/canvas/deps/view.js +43 -0
  161. package/dist/canvas/deps/view.js.map +1 -0
  162. package/dist/canvas/derivedPath.js +47 -0
  163. package/dist/canvas/derivedPath.js.map +1 -0
  164. package/dist/canvas/drawEnvelope.js +22 -0
  165. package/dist/canvas/drawEnvelope.js.map +1 -0
  166. package/dist/canvas/getNodeAtPoint.js +18 -0
  167. package/dist/canvas/getNodeAtPoint.js.map +1 -0
  168. package/dist/canvas/hostAnchor.js +29 -0
  169. package/dist/canvas/hostAnchor.js.map +1 -0
  170. package/dist/canvas/hud.module.js +18 -0
  171. package/dist/canvas/hud.module.js.map +1 -0
  172. package/dist/canvas/insertPreviewExtent.js +103 -0
  173. package/dist/canvas/insertPreviewExtent.js.map +1 -0
  174. package/dist/canvas/kitRequirements.js +177 -0
  175. package/dist/canvas/kitRequirements.js.map +1 -0
  176. package/dist/canvas/layerOrder.js +66 -0
  177. package/dist/canvas/layerOrder.js.map +1 -0
  178. package/dist/canvas/layerSlots.js +14 -0
  179. package/dist/canvas/layerSlots.js.map +1 -0
  180. package/dist/canvas/minimapMath.js +80 -0
  181. package/dist/canvas/minimapMath.js.map +1 -0
  182. package/dist/canvas/mountedCanvases.js +20 -0
  183. package/dist/canvas/mountedCanvases.js.map +1 -0
  184. package/dist/canvas/overlayRoleStrokes.js +17 -0
  185. package/dist/canvas/overlayRoleStrokes.js.map +1 -0
  186. package/dist/canvas/paintCull.js +20 -0
  187. package/dist/canvas/paintCull.js.map +1 -0
  188. package/dist/canvas/pickWalk.js +158 -0
  189. package/dist/canvas/pickWalk.js.map +1 -0
  190. package/dist/canvas/planeClips.js +30 -0
  191. package/dist/canvas/planeClips.js.map +1 -0
  192. package/dist/canvas/poseRotation.js +35 -0
  193. package/dist/canvas/poseRotation.js.map +1 -0
  194. package/dist/canvas/rasterToPng.js +21 -0
  195. package/dist/canvas/rasterToPng.js.map +1 -0
  196. package/dist/canvas/renderDebugSnapshot.js +32 -0
  197. package/dist/canvas/renderDebugSnapshot.js.map +1 -0
  198. package/dist/canvas/renderNeeds.js +25 -0
  199. package/dist/canvas/renderNeeds.js.map +1 -0
  200. package/dist/canvas/renderSceneToPixels.js +143 -0
  201. package/dist/canvas/renderSceneToPixels.js.map +1 -0
  202. package/dist/canvas/sceneAdapter.js +270 -0
  203. package/dist/canvas/sceneAdapter.js.map +1 -0
  204. package/dist/canvas/sceneLayerPaint.js +37 -0
  205. package/dist/canvas/sceneLayerPaint.js.map +1 -0
  206. package/dist/canvas/sceneSlotWiring.js +20 -0
  207. package/dist/canvas/sceneSlotWiring.js.map +1 -0
  208. package/dist/canvas/sceneViewRender.js +72 -0
  209. package/dist/canvas/sceneViewRender.js.map +1 -0
  210. package/dist/canvas/slopsDebugLayer.js +61 -0
  211. package/dist/canvas/slopsDebugLayer.js.map +1 -0
  212. package/dist/canvas/surfaceContribution.js +15 -0
  213. package/dist/canvas/surfaceContribution.js.map +1 -0
  214. package/dist/canvas/toolPreview.js +39 -0
  215. package/dist/canvas/toolPreview.js.map +1 -0
  216. package/dist/canvas/useCanvasRenderer.js +11 -0
  217. package/dist/canvas/useCanvasRenderer.js.map +1 -0
  218. package/dist/canvas/useFrameLoop.js +60 -0
  219. package/dist/canvas/useFrameLoop.js.map +1 -0
  220. package/dist/canvas/useHostAnchor.js +71 -0
  221. package/dist/canvas/useHostAnchor.js.map +1 -0
  222. package/dist/canvas/useLateContentRedraw.js +21 -0
  223. package/dist/canvas/useLateContentRedraw.js.map +1 -0
  224. package/dist/canvas/useRedrawOn.js +21 -0
  225. package/dist/canvas/useRedrawOn.js.map +1 -0
  226. package/dist/canvas/useViewHelpers.js +120 -0
  227. package/dist/canvas/useViewHelpers.js.map +1 -0
  228. package/dist/canvas/viewInputs.js +17 -0
  229. package/dist/canvas/viewInputs.js.map +1 -0
  230. package/dist/canvas/viewRegistry.js +61 -0
  231. package/dist/canvas/viewRegistry.js.map +1 -0
  232. package/dist/canvas/wrapNodeOutput.js +14 -0
  233. package/dist/canvas/wrapNodeOutput.js.map +1 -0
  234. package/dist/clipboard.d.ts +10 -5
  235. package/dist/clipboard.js +3 -5
  236. package/dist/clone.d.ts +3 -3
  237. package/dist/clone.js +2 -5
  238. package/dist/core/adapters/arrayAdapter.js +85 -0
  239. package/dist/core/adapters/arrayAdapter.js.map +1 -0
  240. package/dist/core/adapters/useArrayAdapter.js +13 -0
  241. package/dist/core/adapters/useArrayAdapter.js.map +1 -0
  242. package/dist/core/applyOps.js +12 -0
  243. package/dist/core/applyOps.js.map +1 -0
  244. package/dist/core/device/index.js +4 -0
  245. package/dist/core/device/targets.js +17 -0
  246. package/dist/core/device/targets.js.map +1 -0
  247. package/dist/core/device/useDeviceProfile.js +75 -0
  248. package/dist/core/device/useDeviceProfile.js.map +1 -0
  249. package/dist/core/fillInPoseFrame.js +102 -0
  250. package/dist/core/fillInPoseFrame.js.map +1 -0
  251. package/dist/core/geometry/poseDescriptor.js +98 -0
  252. package/dist/core/geometry/poseDescriptor.js.map +1 -0
  253. package/dist/core/geometry/poseRotation.js +58 -0
  254. package/dist/core/geometry/poseRotation.js.map +1 -0
  255. package/dist/core/geometry/regionHit.js +102 -0
  256. package/dist/core/geometry/regionHit.js.map +1 -0
  257. package/dist/core/geometry/unionBounds.js +60 -0
  258. package/dist/core/geometry/unionBounds.js.map +1 -0
  259. package/dist/core/gradient.js +136 -0
  260. package/dist/core/gradient.js.map +1 -0
  261. package/dist/core/isPlainObject.js +11 -0
  262. package/dist/core/isPlainObject.js.map +1 -0
  263. package/dist/core/layers/render.js +150 -0
  264. package/dist/core/layers/render.js.map +1 -0
  265. package/dist/core/markerInset.js +24 -0
  266. package/dist/core/markerInset.js.map +1 -0
  267. package/dist/core/mixed.js +6 -0
  268. package/dist/core/mixed.js.map +1 -0
  269. package/dist/core/ops/arrange.js +31 -0
  270. package/dist/core/ops/arrange.js.map +1 -0
  271. package/dist/core/ops/create.js +32 -0
  272. package/dist/core/ops/create.js.map +1 -0
  273. package/dist/core/ops/createHistory.js +20 -0
  274. package/dist/core/ops/createHistory.js.map +1 -0
  275. package/dist/core/ops/delete.js +89 -0
  276. package/dist/core/ops/delete.js.map +1 -0
  277. package/dist/core/ops/registry.js +17 -0
  278. package/dist/core/ops/registry.js.map +1 -0
  279. package/dist/core/ops/reorder/algorithms.js +55 -0
  280. package/dist/core/ops/reorder/algorithms.js.map +1 -0
  281. package/dist/core/ops/reorder/index.js +140 -0
  282. package/dist/core/ops/reorder/index.js.map +1 -0
  283. package/dist/core/ops/reparent.js +52 -0
  284. package/dist/core/ops/reparent.js.map +1 -0
  285. package/dist/core/ops/select.js +34 -0
  286. package/dist/core/ops/select.js.map +1 -0
  287. package/dist/core/ops/setData.js +34 -0
  288. package/dist/core/ops/setData.js.map +1 -0
  289. package/dist/core/ops/setLayer.js +34 -0
  290. package/dist/core/ops/setLayer.js.map +1 -0
  291. package/dist/core/ops/setLayout.js +31 -0
  292. package/dist/core/ops/setLayout.js.map +1 -0
  293. package/dist/core/ops/setPath.js +57 -0
  294. package/dist/core/ops/setPath.js.map +1 -0
  295. package/dist/core/ops/setText.js +34 -0
  296. package/dist/core/ops/setText.js.map +1 -0
  297. package/dist/core/ops/slot.js +37 -0
  298. package/dist/core/ops/slot.js.map +1 -0
  299. package/dist/core/ops/transform.js +42 -0
  300. package/dist/core/ops/transform.js.map +1 -0
  301. package/dist/core/paintKinds.js +156 -0
  302. package/dist/core/paintKinds.js.map +1 -0
  303. package/dist/core/scene/NodeProperties.js +20 -0
  304. package/dist/core/scene/NodeProperties.js.map +1 -0
  305. package/dist/core/scene/NodeRouting.js +24 -0
  306. package/dist/core/scene/NodeRouting.js.map +1 -0
  307. package/dist/core/scene/arrivals.js +12 -0
  308. package/dist/core/scene/arrivals.js.map +1 -0
  309. package/dist/core/scene/composeFrame.js +29 -0
  310. package/dist/core/scene/composeFrame.js.map +1 -0
  311. package/dist/core/scene/depMemo.js +18 -0
  312. package/dist/core/scene/depMemo.js.map +1 -0
  313. package/dist/core/scene/dependents.js +66 -0
  314. package/dist/core/scene/dependents.js.map +1 -0
  315. package/dist/core/scene/derivedPath.js +31 -0
  316. package/dist/core/scene/derivedPath.js.map +1 -0
  317. package/dist/core/scene/effectivePose.js +78 -0
  318. package/dist/core/scene/effectivePose.js.map +1 -0
  319. package/dist/core/scene/kitRegistry.js +33 -0
  320. package/dist/core/scene/kitRegistry.js.map +1 -0
  321. package/dist/core/scene/layoutPass.js +96 -0
  322. package/dist/core/scene/layoutPass.js.map +1 -0
  323. package/dist/core/scene/nodeFnFields.js +83 -0
  324. package/dist/core/scene/nodeFnFields.js.map +1 -0
  325. package/dist/core/scene/nodeMemo.js +28 -0
  326. package/dist/core/scene/nodeMemo.js.map +1 -0
  327. package/dist/core/scene/poseFeed.js +87 -0
  328. package/dist/core/scene/poseFeed.js.map +1 -0
  329. package/dist/core/scene/poseOverrides.js +52 -0
  330. package/dist/core/scene/poseOverrides.js.map +1 -0
  331. package/dist/core/scene/poseSnapshot.js +54 -0
  332. package/dist/core/scene/poseSnapshot.js.map +1 -0
  333. package/dist/core/scene/scene.js +1271 -0
  334. package/dist/core/scene/scene.js.map +1 -0
  335. package/dist/core/scene/types.js +6 -0
  336. package/dist/core/scene/types.js.map +1 -0
  337. package/dist/core/scene/useScene.js +32 -0
  338. package/dist/core/scene/useScene.js.map +1 -0
  339. package/dist/core/selection/chromeState.js +31 -0
  340. package/dist/core/selection/chromeState.js.map +1 -0
  341. package/dist/core/selection/selectionTarget.js +6 -0
  342. package/dist/core/selection/selectionTarget.js.map +1 -0
  343. package/dist/core/selection/useSelection.js +71 -0
  344. package/dist/core/selection/useSelection.js.map +1 -0
  345. package/dist/core/shapeKinds.js +54 -0
  346. package/dist/core/shapeKinds.js.map +1 -0
  347. package/dist/core/strokeMarkerShapes.js +139 -0
  348. package/dist/core/strokeMarkerShapes.js.map +1 -0
  349. package/dist/core/strokeMarkers.js +28 -0
  350. package/dist/core/strokeMarkers.js.map +1 -0
  351. package/dist/core/stylus/stylus.js +39 -0
  352. package/dist/core/stylus/stylus.js.map +1 -0
  353. package/dist/core/stylus/usePointerStylus.js +51 -0
  354. package/dist/core/stylus/usePointerStylus.js.map +1 -0
  355. package/dist/core/usePaintKinds.js +17 -0
  356. package/dist/core/usePaintKinds.js.map +1 -0
  357. package/dist/core/viewport/clampView.js +24 -0
  358. package/dist/core/viewport/clampView.js.map +1 -0
  359. package/dist/core/viewport/clientToWorld.js +8 -0
  360. package/dist/core/viewport/clientToWorld.js.map +1 -0
  361. package/dist/core/viewport/createVelocityTracker.js +39 -0
  362. package/dist/core/viewport/createVelocityTracker.js.map +1 -0
  363. package/dist/core/viewport/fitToBounds.js +18 -0
  364. package/dist/core/viewport/fitToBounds.js.map +1 -0
  365. package/dist/core/viewport/fitViewToBounds.js +36 -0
  366. package/dist/core/viewport/fitViewToBounds.js.map +1 -0
  367. package/dist/core/viewport/interpolateView.js +34 -0
  368. package/dist/core/viewport/interpolateView.js.map +1 -0
  369. package/dist/core/viewport/meanScale.js +8 -0
  370. package/dist/core/viewport/meanScale.js.map +1 -0
  371. package/dist/core/viewport/parallax.js +111 -0
  372. package/dist/core/viewport/parallax.js.map +1 -0
  373. package/dist/core/viewport/pxExtent.js +42 -0
  374. package/dist/core/viewport/pxExtent.js.map +1 -0
  375. package/dist/core/viewport/sceneNodeClientRect.js +18 -0
  376. package/dist/core/viewport/sceneNodeClientRect.js.map +1 -0
  377. package/dist/core/viewport/screenSlop.js +27 -0
  378. package/dist/core/viewport/screenSlop.js.map +1 -0
  379. package/dist/core/viewport/useAutoCenter.js +32 -0
  380. package/dist/core/viewport/useAutoCenter.js.map +1 -0
  381. package/dist/core/viewport/useCanvasSize.js +29 -0
  382. package/dist/core/viewport/useCanvasSize.js.map +1 -0
  383. package/dist/core/viewport/useDecayLoop.js +63 -0
  384. package/dist/core/viewport/useDecayLoop.js.map +1 -0
  385. package/dist/core/viewport/useVelocityTracker.js +10 -0
  386. package/dist/core/viewport/useVelocityTracker.js.map +1 -0
  387. package/dist/core/viewport/useViewAnimation.js +63 -0
  388. package/dist/core/viewport/useViewAnimation.js.map +1 -0
  389. package/dist/core/viewport/view.js +37 -0
  390. package/dist/core/viewport/view.js.map +1 -0
  391. package/dist/core/viewport/viewTransform.js +11 -0
  392. package/dist/core/viewport/viewTransform.js.map +1 -0
  393. package/dist/core/viewport/viewportWorldRect.js +13 -0
  394. package/dist/core/viewport/viewportWorldRect.js.map +1 -0
  395. package/dist/core/viewport/wheelHandler.js +30 -0
  396. package/dist/core/viewport/wheelHandler.js.map +1 -0
  397. package/dist/core/viewport/zoomAt.js +22 -0
  398. package/dist/core/viewport/zoomAt.js.map +1 -0
  399. package/dist/core/viewport/zoomBounds.js +20 -0
  400. package/dist/core/viewport/zoomBounds.js.map +1 -0
  401. package/dist/{pointSnapToGrid-7mCcm6qG.d.ts → cornerHandles-CDcZOV8h.d.ts} +54 -71
  402. package/dist/debug/createDebugOverlayLayer.js +358 -0
  403. package/dist/debug/createDebugOverlayLayer.js.map +1 -0
  404. package/dist/debug/createDebugSink.js +83 -0
  405. package/dist/debug/createDebugSink.js.map +1 -0
  406. package/dist/debug/defaultTheme.js +31 -0
  407. package/dist/debug/defaultTheme.js.map +1 -0
  408. package/dist/debug/flag.js +41 -0
  409. package/dist/debug/flag.js.map +1 -0
  410. package/dist/debug/frameStats.js +16 -0
  411. package/dist/debug/frameStats.js.map +1 -0
  412. package/dist/debug/parseDebugFlags.js +32 -0
  413. package/dist/debug/parseDebugFlags.js.map +1 -0
  414. package/dist/features/chrome-caps/buildChromeCtx.js +16 -0
  415. package/dist/features/chrome-caps/buildChromeCtx.js.map +1 -0
  416. package/dist/features/chrome-caps/conditions.js +36 -0
  417. package/dist/features/chrome-caps/conditions.js.map +1 -0
  418. package/dist/features/chrome-caps/defaults.js +26 -0
  419. package/dist/features/chrome-caps/defaults.js.map +1 -0
  420. package/dist/features/chrome-caps/index.js +7 -0
  421. package/dist/features/chrome-caps/resolve.js +23 -0
  422. package/dist/features/chrome-caps/resolve.js.map +1 -0
  423. package/dist/features/chrome-caps/useHoverTracking.js +27 -0
  424. package/dist/features/chrome-caps/useHoverTracking.js.map +1 -0
  425. package/dist/features/cursor/paintedCursorLayer.js +60 -0
  426. package/dist/features/cursor/paintedCursorLayer.js.map +1 -0
  427. package/dist/features/focus/gateLayer.js +14 -0
  428. package/dist/features/focus/gateLayer.js.map +1 -0
  429. package/dist/features/focus/useCanvasFocus.js +29 -0
  430. package/dist/features/focus/useCanvasFocus.js.map +1 -0
  431. package/dist/features/groups/children.js +23 -0
  432. package/dist/features/groups/children.js.map +1 -0
  433. package/dist/features/groups/composePose.js +67 -0
  434. package/dist/features/groups/composePose.js.map +1 -0
  435. package/dist/features/groups/nestedHit.js +40 -0
  436. package/dist/features/groups/nestedHit.js.map +1 -0
  437. package/dist/features/groups/unionOfChildren.js +15 -0
  438. package/dist/features/groups/unionOfChildren.js.map +1 -0
  439. package/dist/features/images/imageCache.js +94 -0
  440. package/dist/features/images/imageCache.js.map +1 -0
  441. package/dist/features/ingestion/contentHandlers.js +37 -0
  442. package/dist/features/ingestion/contentHandlers.js.map +1 -0
  443. package/dist/features/ingestion/imageHandler.js +45 -0
  444. package/dist/features/ingestion/imageHandler.js.map +1 -0
  445. package/dist/features/ingestion/index.js +8 -0
  446. package/dist/features/ingestion/openFilePicker.js +15 -0
  447. package/dist/features/ingestion/openFilePicker.js.map +1 -0
  448. package/dist/features/ingestion/registerKitHandlers.js +26 -0
  449. package/dist/features/ingestion/registerKitHandlers.js.map +1 -0
  450. package/dist/features/ingestion/svgHandler.js +58 -0
  451. package/dist/features/ingestion/svgHandler.js.map +1 -0
  452. package/dist/features/ingestion/weaselJsonHandler.js +39 -0
  453. package/dist/features/ingestion/weaselJsonHandler.js.map +1 -0
  454. package/dist/features/longPress/longPressFeedback.js +96 -0
  455. package/dist/features/longPress/longPressFeedback.js.map +1 -0
  456. package/dist/features/meshPaint/bake.js +79 -0
  457. package/dist/features/meshPaint/bake.js.map +1 -0
  458. package/dist/features/meshPaint/bakeCache.js +59 -0
  459. package/dist/features/meshPaint/bakeCache.js.map +1 -0
  460. package/dist/features/meshPaint/handles.js +86 -0
  461. package/dist/features/meshPaint/handles.js.map +1 -0
  462. package/dist/features/meshPaint/lazyKind.js +1298 -0
  463. package/dist/features/meshPaint/lazyKind.js.map +1 -0
  464. package/dist/features/meshPaint/meshPaint.js +236 -0
  465. package/dist/features/meshPaint/meshPaint.js.map +1 -0
  466. package/dist/features/meshPaint/meshShader.js +6 -0
  467. package/dist/features/meshPaint/meshShader.js.map +1 -0
  468. package/dist/features/meshPaint/register.js +7 -0
  469. package/dist/features/meshPaint/register.js.map +1 -0
  470. package/dist/features/meshPaint/surface.js +110 -0
  471. package/dist/features/meshPaint/surface.js.map +1 -0
  472. package/dist/features/minimap/actions.js +53 -0
  473. package/dist/features/minimap/actions.js.map +1 -0
  474. package/dist/features/minimap/createMinimapContribution.js +96 -0
  475. package/dist/features/minimap/createMinimapContribution.js.map +1 -0
  476. package/dist/features/minimap/layers.js +103 -0
  477. package/dist/features/minimap/layers.js.map +1 -0
  478. package/dist/features/modes/modeLayers.js +113 -0
  479. package/dist/features/modes/modeLayers.js.map +1 -0
  480. package/dist/features/overlays/useNodeOverlayFrame.js +103 -0
  481. package/dist/features/overlays/useNodeOverlayFrame.js.map +1 -0
  482. package/dist/features/parallax/createParallaxLayer.js +26 -0
  483. package/dist/features/parallax/createParallaxLayer.js.map +1 -0
  484. package/dist/features/parallax/createParallaxPlane.js +26 -0
  485. package/dist/features/parallax/createParallaxPlane.js.map +1 -0
  486. package/dist/features/paths/anchorEdits.js +156 -0
  487. package/dist/features/paths/anchorEdits.js.map +1 -0
  488. package/dist/features/paths/anchors.js +154 -0
  489. package/dist/features/paths/anchors.js.map +1 -0
  490. package/dist/features/paths/booleans.js +2 -0
  491. package/dist/features/paths/index.js +15 -0
  492. package/dist/features/paths/markerCommands.js +116 -0
  493. package/dist/features/paths/markerCommands.js.map +1 -0
  494. package/dist/features/paths/markerSites.js +59 -0
  495. package/dist/features/paths/markerSites.js.map +1 -0
  496. package/dist/features/paths/markers.js +95 -0
  497. package/dist/features/paths/markers.js.map +1 -0
  498. package/dist/features/paths/nearestAnchor.js +36 -0
  499. package/dist/features/paths/nearestAnchor.js.map +1 -0
  500. package/dist/features/paths/originProjection.js +16 -0
  501. package/dist/features/paths/originProjection.js.map +1 -0
  502. package/dist/features/paths/pathEditingOverlayLayer.js +137 -0
  503. package/dist/features/paths/pathEditingOverlayLayer.js.map +1 -0
  504. package/dist/features/paths/pathInWorld.js +41 -0
  505. package/dist/features/paths/pathInWorld.js.map +1 -0
  506. package/dist/features/paths/pathLayer.js +44 -0
  507. package/dist/features/paths/pathLayer.js.map +1 -0
  508. package/dist/features/paths/penPreviewLayer.js +220 -0
  509. package/dist/features/paths/penPreviewLayer.js.map +1 -0
  510. package/dist/features/paths/poseDescriptor.js +44 -0
  511. package/dist/features/paths/poseDescriptor.js.map +1 -0
  512. package/dist/features/paths/tessellate/stroke.js +230 -0
  513. package/dist/features/paths/tessellate/stroke.js.map +1 -0
  514. package/dist/features/patterns/index.js +23 -0
  515. package/dist/features/patterns/index.js.map +1 -0
  516. package/dist/features/patterns/patterns-builtin.js +38 -0
  517. package/dist/features/patterns/patterns-builtin.js.map +1 -0
  518. package/dist/features/patterns/resolveSpec.js +57 -0
  519. package/dist/features/patterns/resolveSpec.js.map +1 -0
  520. package/dist/features/patterns/tileGeometry.js +158 -0
  521. package/dist/features/patterns/tileGeometry.js.map +1 -0
  522. package/dist/features/pointer/PointerContext.js +45 -0
  523. package/dist/features/pointer/PointerContext.js.map +1 -0
  524. package/dist/features/poseRun/usePoseRun.js +70 -0
  525. package/dist/features/poseRun/usePoseRun.js.map +1 -0
  526. package/dist/features/selection/SelectionContext.js +46 -0
  527. package/dist/features/selection/SelectionContext.js.map +1 -0
  528. package/dist/features/selection/overlay.js +442 -0
  529. package/dist/features/selection/overlay.js.map +1 -0
  530. package/dist/features/simulation/createSimulation.js +61 -0
  531. package/dist/features/simulation/createSimulation.js.map +1 -0
  532. package/dist/features/simulation/types.js +6 -0
  533. package/dist/features/simulation/types.js.map +1 -0
  534. package/dist/features/simulation/useSimulation.js +74 -0
  535. package/dist/features/simulation/useSimulation.js.map +1 -0
  536. package/dist/features/text/domRuns.js +258 -0
  537. package/dist/features/text/domRuns.js.map +1 -0
  538. package/dist/features/text/fitTextPose.js +38 -0
  539. package/dist/features/text/fitTextPose.js.map +1 -0
  540. package/dist/features/text/hitTest.js +45 -0
  541. package/dist/features/text/hitTest.js.map +1 -0
  542. package/dist/features/text/renderLabel.js +14 -0
  543. package/dist/features/text/renderLabel.js.map +1 -0
  544. package/dist/features/text/runs/effectiveRangeStyle.js +66 -0
  545. package/dist/features/text/runs/effectiveRangeStyle.js.map +1 -0
  546. package/dist/features/text/runs/flagRange.js +53 -0
  547. package/dist/features/text/runs/flagRange.js.map +1 -0
  548. package/dist/features/text/runs/rangeStyle.js +135 -0
  549. package/dist/features/text/runs/rangeStyle.js.map +1 -0
  550. package/dist/features/text/textCommand.js +59 -0
  551. package/dist/features/text/textCommand.js.map +1 -0
  552. package/dist/features/text/textLayer.js +35 -0
  553. package/dist/features/text/textLayer.js.map +1 -0
  554. package/dist/features/text/textToPath.js +181 -0
  555. package/dist/features/text/textToPath.js.map +1 -0
  556. package/dist/features/text/useSceneTextEdit.js +138 -0
  557. package/dist/features/text/useSceneTextEdit.js.map +1 -0
  558. package/dist/features/text/useTextEdit.js +465 -0
  559. package/dist/features/text/useTextEdit.js.map +1 -0
  560. package/dist/features/tiling/createTiledLayer.js +63 -0
  561. package/dist/features/tiling/createTiledLayer.js.map +1 -0
  562. package/dist/features/tiling/tiledProject.js +14 -0
  563. package/dist/features/tiling/tiledProject.js.map +1 -0
  564. package/dist/features/viewports/viewResolver.js +59 -0
  565. package/dist/features/viewports/viewResolver.js.map +1 -0
  566. package/dist/features/viewports/viewportLayer.js +58 -0
  567. package/dist/features/viewports/viewportLayer.js.map +1 -0
  568. package/dist/icons/ArrowIcon.js +23 -0
  569. package/dist/icons/ArrowIcon.js.map +1 -0
  570. package/dist/icons/EllipseIcon.js +21 -0
  571. package/dist/icons/EllipseIcon.js.map +1 -0
  572. package/dist/icons/EyedropperIcon.js +49 -0
  573. package/dist/icons/EyedropperIcon.js.map +1 -0
  574. package/dist/icons/HandIcon.js +59 -0
  575. package/dist/icons/HandIcon.js.map +1 -0
  576. package/dist/icons/ImageIcon.js +34 -0
  577. package/dist/icons/ImageIcon.js.map +1 -0
  578. package/dist/icons/LassoIcon.js +22 -0
  579. package/dist/icons/LassoIcon.js.map +1 -0
  580. package/dist/icons/LineIcon.js +22 -0
  581. package/dist/icons/LineIcon.js.map +1 -0
  582. package/dist/icons/PenIcon.js +36 -0
  583. package/dist/icons/PenIcon.js.map +1 -0
  584. package/dist/icons/PencilIcon.js +25 -0
  585. package/dist/icons/PencilIcon.js.map +1 -0
  586. package/dist/icons/PolygonIcon.js +19 -0
  587. package/dist/icons/PolygonIcon.js.map +1 -0
  588. package/dist/icons/RectIcon.js +37 -0
  589. package/dist/icons/RectIcon.js.map +1 -0
  590. package/dist/icons/SelectIcon.js +20 -0
  591. package/dist/icons/SelectIcon.js.map +1 -0
  592. package/dist/icons/StarIcon.js +19 -0
  593. package/dist/icons/StarIcon.js.map +1 -0
  594. package/dist/icons/TextIcon.js +19 -0
  595. package/dist/icons/TextIcon.js.map +1 -0
  596. package/dist/icons/UnknownIcon.js +33 -0
  597. package/dist/icons/UnknownIcon.js.map +1 -0
  598. package/dist/icons/_base.js +12 -0
  599. package/dist/icons/_base.js.map +1 -0
  600. package/dist/index.css +2 -86
  601. package/dist/index.d.ts +2349 -2609
  602. package/dist/index.js +312 -13
  603. package/dist/input/keyState.js +76 -0
  604. package/dist/input/keyState.js.map +1 -0
  605. package/dist/input/useKeyState.js +22 -0
  606. package/dist/input/useKeyState.js.map +1 -0
  607. package/dist/interactions/actions/actionShortcuts.js +32 -0
  608. package/dist/interactions/actions/actionShortcuts.js.map +1 -0
  609. package/dist/interactions/actions/align/align.js +81 -0
  610. package/dist/interactions/actions/align/align.js.map +1 -0
  611. package/dist/interactions/actions/booleans/booleans.js +120 -0
  612. package/dist/interactions/actions/booleans/booleans.js.map +1 -0
  613. package/dist/interactions/actions/booleans/useBooleans.js +20 -0
  614. package/dist/interactions/actions/booleans/useBooleans.js.map +1 -0
  615. package/dist/interactions/actions/booleans/useBooleansAdapter.js +9 -0
  616. package/dist/interactions/actions/booleans/useBooleansAdapter.js.map +1 -0
  617. package/dist/interactions/actions/clipboard/clipboardOps.js +94 -0
  618. package/dist/interactions/actions/clipboard/clipboardOps.js.map +1 -0
  619. package/dist/interactions/actions/clipboard/materializePaste.js +25 -0
  620. package/dist/interactions/actions/clipboard/materializePaste.js.map +1 -0
  621. package/dist/interactions/actions/clipboard/wireFormat.js +43 -0
  622. package/dist/interactions/actions/clipboard/wireFormat.js.map +1 -0
  623. package/dist/interactions/actions/clone/behaviors/cloneByAltDrag.js +26 -0
  624. package/dist/interactions/actions/clone/behaviors/cloneByAltDrag.js.map +1 -0
  625. package/dist/interactions/actions/defaultCommitAdapter.js +42 -0
  626. package/dist/interactions/actions/defaultCommitAdapter.js.map +1 -0
  627. package/dist/interactions/actions/defaults/align.js +71 -0
  628. package/dist/interactions/actions/defaults/align.js.map +1 -0
  629. package/dist/interactions/actions/defaults/anchorEditing.js +235 -0
  630. package/dist/interactions/actions/defaults/anchorEditing.js.map +1 -0
  631. package/dist/interactions/actions/defaults/areaSelect.js +75 -0
  632. package/dist/interactions/actions/defaults/areaSelect.js.map +1 -0
  633. package/dist/interactions/actions/defaults/booleans.js +52 -0
  634. package/dist/interactions/actions/defaults/booleans.js.map +1 -0
  635. package/dist/interactions/actions/defaults/cancelGesture.js +24 -0
  636. package/dist/interactions/actions/defaults/cancelGesture.js.map +1 -0
  637. package/dist/interactions/actions/defaults/clearSelection.js +19 -0
  638. package/dist/interactions/actions/defaults/clearSelection.js.map +1 -0
  639. package/dist/interactions/actions/defaults/clipboard.js +78 -0
  640. package/dist/interactions/actions/defaults/clipboard.js.map +1 -0
  641. package/dist/interactions/actions/defaults/clone.js +96 -0
  642. package/dist/interactions/actions/defaults/clone.js.map +1 -0
  643. package/dist/interactions/actions/defaults/createOutlines.js +47 -0
  644. package/dist/interactions/actions/defaults/createOutlines.js.map +1 -0
  645. package/dist/interactions/actions/defaults/createPaintAction.js +85 -0
  646. package/dist/interactions/actions/defaults/createPaintAction.js.map +1 -0
  647. package/dist/interactions/actions/defaults/delete.js +61 -0
  648. package/dist/interactions/actions/defaults/delete.js.map +1 -0
  649. package/dist/interactions/actions/defaults/distribute.js +66 -0
  650. package/dist/interactions/actions/defaults/distribute.js.map +1 -0
  651. package/dist/interactions/actions/defaults/duplicate.js +83 -0
  652. package/dist/interactions/actions/defaults/duplicate.js.map +1 -0
  653. package/dist/interactions/actions/defaults/editAnchors.js +100 -0
  654. package/dist/interactions/actions/defaults/editAnchors.js.map +1 -0
  655. package/dist/interactions/actions/defaults/enterPathEdit.js +29 -0
  656. package/dist/interactions/actions/defaults/enterPathEdit.js.map +1 -0
  657. package/dist/interactions/actions/defaults/enterTextEdit.js +20 -0
  658. package/dist/interactions/actions/defaults/enterTextEdit.js.map +1 -0
  659. package/dist/interactions/actions/defaults/escape.js +26 -0
  660. package/dist/interactions/actions/defaults/escape.js.map +1 -0
  661. package/dist/interactions/actions/defaults/exitPathEdit.js +22 -0
  662. package/dist/interactions/actions/defaults/exitPathEdit.js.map +1 -0
  663. package/dist/interactions/actions/defaults/flip.js +119 -0
  664. package/dist/interactions/actions/defaults/flip.js.map +1 -0
  665. package/dist/interactions/actions/defaults/freshNodeId.js +10 -0
  666. package/dist/interactions/actions/defaults/freshNodeId.js.map +1 -0
  667. package/dist/interactions/actions/defaults/group.js +131 -0
  668. package/dist/interactions/actions/defaults/group.js.map +1 -0
  669. package/dist/interactions/actions/defaults/icons/actionGlyphIcons.js +40 -0
  670. package/dist/interactions/actions/defaults/icons/actionGlyphIcons.js.map +1 -0
  671. package/dist/interactions/actions/defaults/icons/actionGlyphs.js +10 -0
  672. package/dist/interactions/actions/defaults/icons/actionGlyphs.js.map +1 -0
  673. package/dist/interactions/actions/defaults/icons/alignIcons.js +173 -0
  674. package/dist/interactions/actions/defaults/icons/alignIcons.js.map +1 -0
  675. package/dist/interactions/actions/defaults/icons/booleanIcons.js +171 -0
  676. package/dist/interactions/actions/defaults/icons/booleanIcons.js.map +1 -0
  677. package/dist/interactions/actions/defaults/icons/distributeIcons.js +63 -0
  678. package/dist/interactions/actions/defaults/icons/distributeIcons.js.map +1 -0
  679. package/dist/interactions/actions/defaults/icons/editIcons.js +280 -0
  680. package/dist/interactions/actions/defaults/icons/editIcons.js.map +1 -0
  681. package/dist/interactions/actions/defaults/icons/outlineIcons.js +53 -0
  682. package/dist/interactions/actions/defaults/icons/outlineIcons.js.map +1 -0
  683. package/dist/interactions/actions/defaults/ingest.js +58 -0
  684. package/dist/interactions/actions/defaults/ingest.js.map +1 -0
  685. package/dist/interactions/actions/defaults/insert.js +288 -0
  686. package/dist/interactions/actions/defaults/insert.js.map +1 -0
  687. package/dist/interactions/actions/defaults/insertPathAnchor.js +50 -0
  688. package/dist/interactions/actions/defaults/insertPathAnchor.js.map +1 -0
  689. package/dist/interactions/actions/defaults/lassoSelect.js +156 -0
  690. package/dist/interactions/actions/defaults/lassoSelect.js.map +1 -0
  691. package/dist/interactions/actions/defaults/move.js +656 -0
  692. package/dist/interactions/actions/defaults/move.js.map +1 -0
  693. package/dist/interactions/actions/defaults/nudge.js +110 -0
  694. package/dist/interactions/actions/defaults/nudge.js.map +1 -0
  695. package/dist/interactions/actions/defaults/pinchZoom.js +63 -0
  696. package/dist/interactions/actions/defaults/pinchZoom.js.map +1 -0
  697. package/dist/interactions/actions/defaults/reorder.js +143 -0
  698. package/dist/interactions/actions/defaults/reorder.js.map +1 -0
  699. package/dist/interactions/actions/defaults/requiresSelection.js +10 -0
  700. package/dist/interactions/actions/defaults/requiresSelection.js.map +1 -0
  701. package/dist/interactions/actions/defaults/resize.js +332 -0
  702. package/dist/interactions/actions/defaults/resize.js.map +1 -0
  703. package/dist/interactions/actions/defaults/rotate.js +181 -0
  704. package/dist/interactions/actions/defaults/rotate.js.map +1 -0
  705. package/dist/interactions/actions/defaults/selectAll.js +27 -0
  706. package/dist/interactions/actions/defaults/selectAll.js.map +1 -0
  707. package/dist/interactions/actions/defaults/setFill.js +27 -0
  708. package/dist/interactions/actions/defaults/setFill.js.map +1 -0
  709. package/dist/interactions/actions/defaults/setFillOpacity.js +15 -0
  710. package/dist/interactions/actions/defaults/setFillOpacity.js.map +1 -0
  711. package/dist/interactions/actions/defaults/setStroke.js +36 -0
  712. package/dist/interactions/actions/defaults/setStroke.js.map +1 -0
  713. package/dist/interactions/actions/defaults/setStrokeOpacity.js +21 -0
  714. package/dist/interactions/actions/defaults/setStrokeOpacity.js.map +1 -0
  715. package/dist/interactions/actions/defaults/slice.js +39 -0
  716. package/dist/interactions/actions/defaults/slice.js.map +1 -0
  717. package/dist/interactions/actions/defaults/sliceOps.js +60 -0
  718. package/dist/interactions/actions/defaults/sliceOps.js.map +1 -0
  719. package/dist/interactions/actions/defaults/toolActivate.js +35 -0
  720. package/dist/interactions/actions/defaults/toolActivate.js.map +1 -0
  721. package/dist/interactions/actions/defaults/toolResetToDefault.js +26 -0
  722. package/dist/interactions/actions/defaults/toolResetToDefault.js.map +1 -0
  723. package/dist/interactions/actions/defaults/undoRedo.js +51 -0
  724. package/dist/interactions/actions/defaults/undoRedo.js.map +1 -0
  725. package/dist/interactions/actions/defaults/viewportDragPan.js +88 -0
  726. package/dist/interactions/actions/defaults/viewportDragPan.js.map +1 -0
  727. package/dist/interactions/actions/defaults/viewportWheelPan.js +57 -0
  728. package/dist/interactions/actions/defaults/viewportWheelPan.js.map +1 -0
  729. package/dist/interactions/actions/defaults/viewportZoom.js +143 -0
  730. package/dist/interactions/actions/defaults/viewportZoom.js.map +1 -0
  731. package/dist/interactions/actions/distribute/distribute.js +42 -0
  732. package/dist/interactions/actions/distribute/distribute.js.map +1 -0
  733. package/dist/interactions/actions/distribute/plan.js +29 -0
  734. package/dist/interactions/actions/distribute/plan.js.map +1 -0
  735. package/dist/interactions/actions/edit-anchors/geometry.js +61 -0
  736. package/dist/interactions/actions/edit-anchors/geometry.js.map +1 -0
  737. package/dist/interactions/actions/edit-anchors/handles.js +43 -0
  738. package/dist/interactions/actions/edit-anchors/handles.js.map +1 -0
  739. package/dist/interactions/actions/flip/helpers.js +35 -0
  740. package/dist/interactions/actions/flip/helpers.js.map +1 -0
  741. package/dist/interactions/actions/geometryProjection.js +18 -0
  742. package/dist/interactions/actions/geometryProjection.js.map +1 -0
  743. package/dist/interactions/actions/gestureLifecycle.js +44 -0
  744. package/dist/interactions/actions/gestureLifecycle.js.map +1 -0
  745. package/dist/interactions/actions/lasso-select/behaviors/selectFromLasso.js +39 -0
  746. package/dist/interactions/actions/lasso-select/behaviors/selectFromLasso.js.map +1 -0
  747. package/dist/interactions/actions/move/behaviors/snapBackOrDelete.js +36 -0
  748. package/dist/interactions/actions/move/behaviors/snapBackOrDelete.js.map +1 -0
  749. package/dist/interactions/actions/move/behaviors/snapToContainer.js +67 -0
  750. package/dist/interactions/actions/move/behaviors/snapToContainer.js.map +1 -0
  751. package/dist/interactions/actions/move/gestureAdapter.js +37 -0
  752. package/dist/interactions/actions/move/gestureAdapter.js.map +1 -0
  753. package/dist/interactions/actions/outlines/createOutlines.js +84 -0
  754. package/dist/interactions/actions/outlines/createOutlines.js.map +1 -0
  755. package/dist/interactions/actions/outlines/useCreateOutlinesAdapter.js +9 -0
  756. package/dist/interactions/actions/outlines/useCreateOutlinesAdapter.js.map +1 -0
  757. package/dist/interactions/actions/planeInput.js +168 -0
  758. package/dist/interactions/actions/planeInput.js.map +1 -0
  759. package/dist/interactions/actions/poseDescriptorDep.js +9 -0
  760. package/dist/interactions/actions/poseDescriptorDep.js.map +1 -0
  761. package/dist/interactions/actions/poseFrame.js +38 -0
  762. package/dist/interactions/actions/poseFrame.js.map +1 -0
  763. package/dist/interactions/actions/previewOverrides.js +25 -0
  764. package/dist/interactions/actions/previewOverrides.js.map +1 -0
  765. package/dist/interactions/actions/resize/autoPoseDescriptor.js +32 -0
  766. package/dist/interactions/actions/resize/autoPoseDescriptor.js.map +1 -0
  767. package/dist/interactions/actions/resize/behaviors/clampMinSize.js +18 -0
  768. package/dist/interactions/actions/resize/behaviors/clampMinSize.js.map +1 -0
  769. package/dist/interactions/actions/resize/behaviors/index.js +8 -0
  770. package/dist/interactions/actions/resize/behaviors/index.js.map +1 -0
  771. package/dist/interactions/actions/resize/behaviors/lockAspect.js +24 -0
  772. package/dist/interactions/actions/resize/behaviors/lockAspect.js.map +1 -0
  773. package/dist/interactions/actions/resize/cornerHandles.js +72 -0
  774. package/dist/interactions/actions/resize/cornerHandles.js.map +1 -0
  775. package/dist/interactions/actions/resolveOverlays.js +60 -0
  776. package/dist/interactions/actions/resolveOverlays.js.map +1 -0
  777. package/dist/interactions/actions/resolvePreviews.js +61 -0
  778. package/dist/interactions/actions/resolvePreviews.js.map +1 -0
  779. package/dist/interactions/actions/rotate/geometry.js +46 -0
  780. package/dist/interactions/actions/rotate/geometry.js.map +1 -0
  781. package/dist/interactions/actions/rotate/handle.js +27 -0
  782. package/dist/interactions/actions/rotate/handle.js.map +1 -0
  783. package/dist/interactions/actions/spatialReference.js +42 -0
  784. package/dist/interactions/actions/spatialReference.js.map +1 -0
  785. package/dist/interactions/actions/useStandardActions.js +142 -0
  786. package/dist/interactions/actions/useStandardActions.js.map +1 -0
  787. package/dist/interactions/gestures/dragGesture/dragGesture.js +111 -0
  788. package/dist/interactions/gestures/dragGesture/dragGesture.js.map +1 -0
  789. package/dist/interactions/gestures/dragRadial/dragRadial.js +117 -0
  790. package/dist/interactions/gestures/dragRadial/dragRadial.js.map +1 -0
  791. package/dist/interactions/gestures/dragRect/dragRect.js +164 -0
  792. package/dist/interactions/gestures/dragRect/dragRect.js.map +1 -0
  793. package/dist/interactions/gestures/handleDrag/handleDrag.js +46 -0
  794. package/dist/interactions/gestures/handleDrag/handleDrag.js.map +1 -0
  795. package/dist/interactions/gestures/pointerDrag/pointerDrag.js +118 -0
  796. package/dist/interactions/gestures/pointerDrag/pointerDrag.js.map +1 -0
  797. package/dist/interactions/gestures/shared/originProjection.js +42 -0
  798. package/dist/interactions/gestures/shared/originProjection.js.map +1 -0
  799. package/dist/interactions/gestures/shared/screenTolerance.js +21 -0
  800. package/dist/interactions/gestures/shared/screenTolerance.js.map +1 -0
  801. package/dist/interactions/gestures/shared/snap.js +24 -0
  802. package/dist/interactions/gestures/shared/snap.js.map +1 -0
  803. package/dist/interactions/gestures/thresholdDrag/thresholdDrag.js +30 -0
  804. package/dist/interactions/gestures/thresholdDrag/thresholdDrag.js.map +1 -0
  805. package/dist/layout/arrivals.js +36 -0
  806. package/dist/layout/arrivals.js.map +1 -0
  807. package/dist/{math-MCQcf_gc.d.ts → math-CUMxmZzn.d.ts} +8 -116
  808. package/dist/math.d.ts +4 -5
  809. package/dist/math.js +6 -4
  810. package/dist/mesh.d.ts +268 -0
  811. package/dist/mesh.js +7 -0
  812. package/dist/move.d.ts +7 -48
  813. package/dist/move.js +3 -142
  814. package/dist/originProjection-BSn4xiEy.d.ts +57 -0
  815. package/dist/patterns-builtin.js +3 -3
  816. package/dist/{poseDescriptor-rZa9W5hJ.d.ts → poseDescriptor-CjSXMf8X.d.ts} +3 -3
  817. package/dist/registerProgram-ateHDGjw.d.ts +193 -0
  818. package/dist/renderer/DrawCommand.js +6 -0
  819. package/dist/renderer/DrawCommand.js.map +1 -0
  820. package/dist/renderer/WeaselRenderer.js +328 -0
  821. package/dist/renderer/WeaselRenderer.js.map +1 -0
  822. package/dist/renderer/cache/GLImageCache.js +64 -0
  823. package/dist/renderer/cache/GLImageCache.js.map +1 -0
  824. package/dist/renderer/cache/GLMeshCache.js +102 -0
  825. package/dist/renderer/cache/GLMeshCache.js.map +1 -0
  826. package/dist/renderer/cache/GLTextureCache.js +51 -0
  827. package/dist/renderer/cache/GLTextureCache.js.map +1 -0
  828. package/dist/renderer/cache/GradientRampAtlas.js +82 -0
  829. package/dist/renderer/cache/GradientRampAtlas.js.map +1 -0
  830. package/dist/renderer/cache/cache.js +13 -0
  831. package/dist/renderer/cache/cache.js.map +1 -0
  832. package/dist/renderer/cache/markerCommandCache.js +59 -0
  833. package/dist/renderer/cache/markerCommandCache.js.map +1 -0
  834. package/dist/renderer/cache/outlineMeshCache.js +15 -0
  835. package/dist/renderer/cache/outlineMeshCache.js.map +1 -0
  836. package/dist/renderer/cache/outlineStrokeMeshCache.js +31 -0
  837. package/dist/renderer/cache/outlineStrokeMeshCache.js.map +1 -0
  838. package/dist/renderer/cache/strokeMeshCache.js +44 -0
  839. package/dist/renderer/cache/strokeMeshCache.js.map +1 -0
  840. package/dist/renderer/cullDrawCommands.js +89 -0
  841. package/dist/renderer/cullDrawCommands.js.map +1 -0
  842. package/dist/renderer/draw.js +1109 -0
  843. package/dist/renderer/draw.js.map +1 -0
  844. package/dist/renderer/drawBatch.js +168 -0
  845. package/dist/renderer/drawBatch.js.map +1 -0
  846. package/dist/renderer/effects/EffectTargets.js +45 -0
  847. package/dist/renderer/effects/EffectTargets.js.map +1 -0
  848. package/dist/renderer/effects/builtins.js +31 -0
  849. package/dist/renderer/effects/builtins.js.map +1 -0
  850. package/dist/renderer/effects/composite.js +9 -0
  851. package/dist/renderer/effects/composite.js.map +1 -0
  852. package/dist/renderer/effects/effectPrelude.js +10 -0
  853. package/dist/renderer/effects/effectPrelude.js.map +1 -0
  854. package/dist/renderer/effects/types.js +10 -0
  855. package/dist/renderer/effects/types.js.map +1 -0
  856. package/dist/renderer/index.js +19 -0
  857. package/dist/renderer/math/color.js +341 -0
  858. package/dist/renderer/math/color.js.map +1 -0
  859. package/dist/renderer/math/mat3.js +71 -0
  860. package/dist/renderer/math/mat3.js.map +1 -0
  861. package/dist/renderer/math/patternSpace.js +22 -0
  862. package/dist/renderer/math/patternSpace.js.map +1 -0
  863. package/dist/renderer/math/viewToMat3.js +19 -0
  864. package/dist/renderer/math/viewToMat3.js.map +1 -0
  865. package/dist/renderer/paintResources.js +18 -0
  866. package/dist/renderer/paintResources.js.map +1 -0
  867. package/dist/renderer/paintScratch.js +37 -0
  868. package/dist/renderer/paintScratch.js.map +1 -0
  869. package/dist/renderer/shaders/ShaderProgram.js +74 -0
  870. package/dist/renderer/shaders/ShaderProgram.js.map +1 -0
  871. package/dist/renderer/shaders/batchFill.js +118 -0
  872. package/dist/renderer/shaders/batchFill.js.map +1 -0
  873. package/dist/renderer/shaders/customPrelude.js +34 -0
  874. package/dist/renderer/shaders/customPrelude.js.map +1 -0
  875. package/dist/renderer/shaders/extractUniformNames.js +184 -0
  876. package/dist/renderer/shaders/extractUniformNames.js.map +1 -0
  877. package/dist/renderer/shaders/glyphPaint.js +61 -0
  878. package/dist/renderer/shaders/glyphPaint.js.map +1 -0
  879. package/dist/renderer/shaders/gradFill.js +30 -0
  880. package/dist/renderer/shaders/gradFill.js.map +1 -0
  881. package/dist/renderer/shaders/imageFill.js +14 -0
  882. package/dist/renderer/shaders/imageFill.js.map +1 -0
  883. package/dist/renderer/shaders/pathFill.js +13 -0
  884. package/dist/renderer/shaders/pathFill.js.map +1 -0
  885. package/dist/renderer/shaders/patternFill.js +24 -0
  886. package/dist/renderer/shaders/patternFill.js.map +1 -0
  887. package/dist/renderer/shaders/registerProgram.js +18 -0
  888. package/dist/renderer/shaders/registerProgram.js.map +1 -0
  889. package/dist/renderer/spriteSheet.js +14 -0
  890. package/dist/renderer/spriteSheet.js.map +1 -0
  891. package/dist/renderer/state/GroupState.js +77 -0
  892. package/dist/renderer/state/GroupState.js.map +1 -0
  893. package/dist/renderer/syntheticItalic.js +6 -0
  894. package/dist/renderer/syntheticItalic.js.map +1 -0
  895. package/dist/renderer/textures/registerTexture.js +14 -0
  896. package/dist/renderer/textures/registerTexture.js.map +1 -0
  897. package/dist/renderer.d.ts +18 -20
  898. package/dist/renderer.js +18 -13
  899. package/dist/resize.d.ts +10 -46
  900. package/dist/resize.js +7 -5
  901. package/dist/routing.d.ts +1 -1
  902. package/dist/routing.js +2 -3
  903. package/dist/scheduling/useVisibleRaf.js +69 -0
  904. package/dist/scheduling/useVisibleRaf.js.map +1 -0
  905. package/dist/test-hook/createTestHook.js +39 -0
  906. package/dist/test-hook/createTestHook.js.map +1 -0
  907. package/dist/test-hook/install.js +12 -0
  908. package/dist/test-hook/install.js.map +1 -0
  909. package/dist/test-seams-fYf6m5pu.d.ts +356 -0
  910. package/dist/test-seams.d.ts +6 -0
  911. package/dist/test-seams.js +3 -0
  912. package/dist/tools/builtin/ellipse/useEllipseTool.js +33 -0
  913. package/dist/tools/builtin/ellipse/useEllipseTool.js.map +1 -0
  914. package/dist/tools/builtin/eyedropper/useEyedropperTool.js +55 -0
  915. package/dist/tools/builtin/eyedropper/useEyedropperTool.js.map +1 -0
  916. package/dist/tools/builtin/hand/dragPanContribution.js +17 -0
  917. package/dist/tools/builtin/hand/dragPanContribution.js.map +1 -0
  918. package/dist/tools/builtin/hand/useHandTool.js +31 -0
  919. package/dist/tools/builtin/hand/useHandTool.js.map +1 -0
  920. package/dist/tools/builtin/image/useImageTool.js +41 -0
  921. package/dist/tools/builtin/image/useImageTool.js.map +1 -0
  922. package/dist/tools/builtin/lasso/useLassoTool.js +42 -0
  923. package/dist/tools/builtin/lasso/useLassoTool.js.map +1 -0
  924. package/dist/tools/builtin/line/useLineTool.js +33 -0
  925. package/dist/tools/builtin/line/useLineTool.js.map +1 -0
  926. package/dist/tools/builtin/pen/usePenTool.js +414 -0
  927. package/dist/tools/builtin/pen/usePenTool.js.map +1 -0
  928. package/dist/tools/builtin/pencil/usePencilTool.js +36 -0
  929. package/dist/tools/builtin/pencil/usePencilTool.js.map +1 -0
  930. package/dist/tools/builtin/pickTopMostHit.js +45 -0
  931. package/dist/tools/builtin/pickTopMostHit.js.map +1 -0
  932. package/dist/tools/builtin/polygon/usePolygonTool.js +81 -0
  933. package/dist/tools/builtin/polygon/usePolygonTool.js.map +1 -0
  934. package/dist/tools/builtin/rect/useRectTool.js +32 -0
  935. package/dist/tools/builtin/rect/useRectTool.js.map +1 -0
  936. package/dist/tools/builtin/select/selectionContributions.js +109 -0
  937. package/dist/tools/builtin/select/selectionContributions.js.map +1 -0
  938. package/dist/tools/builtin/select/useSelectTool.js +162 -0
  939. package/dist/tools/builtin/select/useSelectTool.js.map +1 -0
  940. package/dist/tools/builtin/shared/insertToolOptions.js +8 -0
  941. package/dist/tools/builtin/shared/insertToolOptions.js.map +1 -0
  942. package/dist/tools/builtin/slice/useSliceTool.js +263 -0
  943. package/dist/tools/builtin/slice/useSliceTool.js.map +1 -0
  944. package/dist/tools/builtin/star/useStarTool.js +82 -0
  945. package/dist/tools/builtin/star/useStarTool.js.map +1 -0
  946. package/dist/tools/builtin/text/useTextTool.js +177 -0
  947. package/dist/tools/builtin/text/useTextTool.js.map +1 -0
  948. package/dist/tools/overlayBinding.js +8 -0
  949. package/dist/tools/overlayBinding.js.map +1 -0
  950. package/dist/tools/prefs.js +47 -0
  951. package/dist/tools/prefs.js.map +1 -0
  952. package/dist/tools/useKeybindings.js +66 -0
  953. package/dist/tools/useKeybindings.js.map +1 -0
  954. package/dist/{types-CxC8P6W0.d.ts → types-CA54-mAZ.d.ts} +188 -17
  955. package/dist/{types-D_74YlWs.d.ts → types-DSjd6W3n.d.ts} +35 -12
  956. package/dist/util/color.js +26 -0
  957. package/dist/util/color.js.map +1 -0
  958. package/dist/util/constrainTo45.js +17 -0
  959. package/dist/util/constrainTo45.js.map +1 -0
  960. package/dist/util/paint.js +72 -0
  961. package/dist/util/paint.js.map +1 -0
  962. package/dist/version.js +6 -0
  963. package/dist/version.js.map +1 -0
  964. package/package.json +31 -18
  965. package/dist/chunk-44EWMJV2.js +0 -128
  966. package/dist/chunk-44EWMJV2.js.map +0 -1
  967. package/dist/chunk-4RJP2N2L.js +0 -143
  968. package/dist/chunk-4RJP2N2L.js.map +0 -1
  969. package/dist/chunk-BJN5ZRIJ.js +0 -167
  970. package/dist/chunk-BJN5ZRIJ.js.map +0 -1
  971. package/dist/chunk-D4AAWR64.js +0 -28
  972. package/dist/chunk-D4AAWR64.js.map +0 -1
  973. package/dist/chunk-DOBSZOPR.js +0 -29
  974. package/dist/chunk-DOBSZOPR.js.map +0 -1
  975. package/dist/chunk-H6N2JSZ3.js +0 -248
  976. package/dist/chunk-H6N2JSZ3.js.map +0 -1
  977. package/dist/chunk-HPFJUUTF.js +0 -167
  978. package/dist/chunk-HPFJUUTF.js.map +0 -1
  979. package/dist/chunk-L5YNZYEG.js +0 -648
  980. package/dist/chunk-L5YNZYEG.js.map +0 -1
  981. package/dist/chunk-MZAIDI6D.js +0 -32492
  982. package/dist/chunk-MZAIDI6D.js.map +0 -1
  983. package/dist/chunk-PNNZSYRD.js +0 -318
  984. package/dist/chunk-PNNZSYRD.js.map +0 -1
  985. package/dist/chunk-RMR4QMM6.js +0 -250
  986. package/dist/chunk-RMR4QMM6.js.map +0 -1
  987. package/dist/clipboard.js.map +0 -1
  988. package/dist/clone.js.map +0 -1
  989. package/dist/grid-BXdz8GF2.d.ts +0 -158
  990. package/dist/index.css.map +0 -1
  991. package/dist/index.js.map +0 -1
  992. package/dist/insert.d.ts +0 -37
  993. package/dist/insert.js +0 -81
  994. package/dist/insert.js.map +0 -1
  995. package/dist/math.js.map +0 -1
  996. package/dist/move.js.map +0 -1
  997. package/dist/options-CzjxFoYZ.d.ts +0 -67
  998. package/dist/path-JEV2c5If.d.ts +0 -48
  999. package/dist/patterns-builtin.js.map +0 -1
  1000. package/dist/renderer.css +0 -86
  1001. package/dist/renderer.css.map +0 -1
  1002. package/dist/renderer.js.map +0 -1
  1003. package/dist/resize.js.map +0 -1
  1004. package/dist/routing.js.map +0 -1
  1005. package/dist/types-D2tTKEU0.d.ts +0 -18
@@ -1,15 +1,85 @@
1
- import { GradStop, ColorSpace, TextureHandle, FillStyle, Stroke, ScreenLength } from '@weasel-js/paint';
2
- import { NodeId, Bounds, View, SelectionApi, ActionDeps, IngestItem, DragSample, Point2 } from '@weasel-js/routing';
3
- import { P as Path } from './path-JEV2c5If.js';
4
- import { ResolvedRun, TextStyle, TextVerticalAlign } from '@weasel-js/text';
5
- import { Mat3 } from '@weasel-js/geom';
1
+ import { G as GlMat3, a as ShaderProgramHandle, b as ShaderUniform, c as ShaderProgram } from './registerProgram-ateHDGjw.js';
2
+ import { Mesh } from '@weasel-js/geom/tessellate';
3
+ import { GradStop, ColorSpace, FillStyle, Stroke, ScreenLength } from '@weasel-js/paint';
4
+ import { NodeId, Bounds, View, ModifierState, SelectionApi, ActionDeps, IngestItem, DragSample, DebugSink, Point2, LongPressState, AnyToolOf, Contribution as Contribution$1, ContributionChrome as ContributionChrome$1, Tool as Tool$1, ToolDef as ToolDef$1 } from '@weasel-js/routing';
5
+ import { Path, EasingSpec, SpringPresetName, PolygonPath, Rect, Mat3 } from '@weasel-js/geom';
6
6
  import { ReactNode } from 'react';
7
7
  import * as _weasel_js_history from '@weasel-js/history';
8
8
  import { Op, History, SerializedHistory } from '@weasel-js/history';
9
- import { a as SceneAdapter, L as LayoutStrategy, b as LayoutDropTargetMode, I as InsertAdapter } from './types-CxC8P6W0.js';
10
- import { P as PoseDescriptor } from './poseDescriptor-rZa9W5hJ.js';
11
- import { ActiveToolContextValue } from '@weasel-js/routing/react';
12
- import { B as BoundsConstraint, P as PointSnapBehavior } from './types-D_74YlWs.js';
9
+ import { L as LayoutStrategy, a as ParallaxOpts, C as ContainerBounds, b as SceneAdapter, P as PlaneMap, R as RegionPickView, c as LayoutDropTargetMode, d as ReflowTransition, I as InsertAdapter } from './types-CA54-mAZ.js';
10
+ import { FontStyle } from '@weasel-js/font';
11
+ import { ResolvedRun, TextStyle, TextVerticalAlign, StyledRun } from '@weasel-js/text';
12
+ import { P as PoseDescriptor } from './poseDescriptor-CjSXMf8X.js';
13
+ import { ActiveToolContextValue, ToolsApi as ToolsApi$1, UseToolsOptions as UseToolsOptions$1 } from '@weasel-js/routing/react';
14
+ import { B as BoundsConstraint, P as PointSnapBehavior } from './types-DSjd6W3n.js';
15
+ import { CursorSpec } from '@weasel-js/cursor';
16
+ import { ClaimableGesture } from '@weasel-js/gestures';
17
+
18
+ /**
19
+ * Folding a node's pose up its parent chain to world, and back down. Lives
20
+ * under `core/` so the scene can lay out in world without reaching up into
21
+ * `features/`; `features/groups/composePose` re-exports all of it.
22
+ */
23
+ /** Minimal adapter needed by `composeWorldPose` and friends — pose lookup plus parent walk. */
24
+ interface PoseAdapter<TPose> {
25
+ getPose(id: string): TPose;
26
+ getParent(id: string): string | null;
27
+ /** Whether `id`'s pose is a frame its children are expressed in. Absent
28
+ * means every node is one. A container whose pose derives from its children
29
+ * is not: its children share its frame, so the fold passes over it. */
30
+ definesFrame?(id: string): boolean;
31
+ }
32
+ /**
33
+ * The transforms a `compose` represents **exactly**. A parent transform wider
34
+ * than its strategy's closure is rounded to the nearest pose — for `'rigid'`
35
+ * that means an anisotropically scaled parent turns a rotated child into a
36
+ * parallelogram, which `{x, y, width, height, rotation}` cannot hold, so the
37
+ * shear is dropped.
38
+ *
39
+ * Measured over 50,000 random parent/child pairs: rotation and translation
40
+ * compose to within 5.7e-13, anisotropic scale to a right-angle error of 0.99.
41
+ * See `docs/superpowers/specs/2026-09-10-group-as-frame-design.md`.
42
+ */
43
+ type PoseClosure = 'identity' | 'translation' | 'rigid';
44
+ /** Consumer's pose-composition strategy for hierarchical scenes. `compose`
45
+ * folds a child's pose (in parent's frame) up to the next frame; `decompose`
46
+ * is its inverse. Default is IDENTITY — an absolute-pose scene where every
47
+ * node already stores world coords (parent is grouping-only, no transform). */
48
+ interface PoseComposition<TPose> {
49
+ compose: (parent: TPose, child: TPose) => TPose;
50
+ decompose: (parent: TPose, world: TPose) => TPose;
51
+ closure: PoseClosure;
52
+ }
53
+ /** Default pose-composition strategy: IDENTITY. Both `compose` and
54
+ * `decompose` return the child/world pose unchanged, modeling an
55
+ * absolute-pose scene where every node stores world coords and parents are
56
+ * grouping-only (no transform). With this strategy `composeWorldPose`
57
+ * returns a node's own raw pose and `rebaseLocalPose` is a no-op. */
58
+ declare const IDENTITY_POSE_COMPOSITION: PoseComposition<unknown>;
59
+ /**
60
+ * Walk `id`'s parent chain (root first to id last) and fold local poses into
61
+ * a world pose via `compose`. Returns the world pose for `id`. Cycle-safe:
62
+ * a visited-set guard breaks if the chain ever loops back to itself.
63
+ *
64
+ * `compose(parent, child)` interprets `child` as expressed *in `parent`'s
65
+ * local frame* and returns the equivalent pose in the next frame up. For a
66
+ * standard translation-only rect: `world = { x: p.x + c.x, y: p.y + c.y,
67
+ * width: c.width, height: c.height }`.
68
+ */
69
+ declare function composeWorldPose<TPose>(adapter: PoseAdapter<TPose>, id: string, compose: (parent: TPose, child: TPose) => TPose): TPose;
70
+ /**
71
+ * Convert `worldPose` into a local pose expressed under `newParentId`'s
72
+ * frame. Used when reparenting so the child's visual world position is
73
+ * preserved despite the change of frame. Inverse of one `compose` step.
74
+ *
75
+ * `decompose(parent, world)` returns the local pose `child` such that
76
+ * `compose(parent, child) === world`. For axis-aligned rects:
77
+ * `child = { ...world, x: world.x - parent.x, y: world.y - parent.y }`.
78
+ *
79
+ * Pass `newParentId === null` for the root frame; the function returns
80
+ * `worldPose` unchanged.
81
+ */
82
+ 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;
13
83
 
14
84
  /**
15
85
  * Axis-aligned rectangle pose with optional rotation. The canonical pose
@@ -56,6 +126,12 @@ interface DerivedDep<TPose> {
56
126
  * about costs nothing. */
57
127
  readonly path: Path | null;
58
128
  }
129
+ /** Computes a node's path from its dependencies: the type of a node's
130
+ * `derivePath` and of each entry in `SceneRegistry.derivePath`. */
131
+ type DerivePathFn<TPose> = (node: Node<unknown, string, TPose>, deps: readonly (DerivedDep<TPose> | undefined)[]) => Path | null;
132
+ /** Computes a node's pose from its dependencies: the type of a node's
133
+ * `derivePose` and of each entry in `SceneRegistry.derivePose`. */
134
+ type DerivePoseFn<TPose> = (node: Node<unknown, string, TPose>, deps: readonly (DerivedDep<TPose> | undefined)[]) => TPose | null;
59
135
  interface NodeBase<TData, TLayer extends string, TPose> {
60
136
  id: NodeId;
61
137
  layer: TLayer;
@@ -93,7 +169,7 @@ interface NodeBase<TData, TLayer extends string, TPose> {
93
169
  * `node` is deliberately widened: naming `TData`/`TLayer` here puts them in
94
170
  * a contravariant position, making `Scene` invariant in both and breaking
95
171
  * assignment kit-wide. The cost is that a `derivePath` casts to read `node.data`. */
96
- derivePath?: (node: Node<unknown, string, TPose>, deps: readonly (DerivedDep<TPose> | undefined)[]) => Path | null;
172
+ derivePath?: DerivePathFn<TPose>;
97
173
  /** Computes this node's pose from its dependencies' poses, the same way
98
174
  * `derivePath` computes its path — same `dependsOn` list, same widened
99
175
  * `node`, same registry-keyed serialization.
@@ -107,7 +183,7 @@ interface NodeBase<TData, TLayer extends string, TPose> {
107
183
  * Returning `null` means "I have nothing to derive from right now", and
108
184
  * the node falls back to its authored `pose`. `setPose` on a derived node
109
185
  * still writes that authored pose; it is simply not what anything reads. */
110
- derivePose?: (node: Node<unknown, string, TPose>, deps: readonly (DerivedDep<TPose> | undefined)[]) => TPose | null;
186
+ derivePose?: DerivePoseFn<TPose>;
111
187
  }
112
188
  /** A node with no children — a shape, a label, an image. */
113
189
  interface LeafNode<TData, TLayer extends string, TPose = RectPose> extends NodeBase<TData, TLayer, TPose> {
@@ -125,6 +201,33 @@ interface ContainerNode<TData, TLayer extends string, TPose = RectPose> extends
125
201
  * renderer rasterizes the returned path into the stencil buffer and
126
202
  * paints descendants only where it covers. */
127
203
  clipFromPose?: (pose: TPose) => Path | null;
204
+ /** How this container arranges its children. Whenever the container's
205
+ * child set or order changes, or its bounds change size, the scene hands
206
+ * the change to the strategy — `depart` for children that left it,
207
+ * `arrive` for children that joined it, `childPoses` otherwise — and records the poses it writes in the same
208
+ * undo entry as the change. A drag reads it too: it is the layout `move`
209
+ * reflows and drops against. */
210
+ layout?: LayoutStrategy<TPose>;
211
+ }
212
+ /** A pose a container's layout wrote — reported by {@link Scene.onReflow} —
213
+ * in the node's stored frame. */
214
+ interface LayoutMove<TPose> {
215
+ id: NodeId;
216
+ from: TPose;
217
+ to: TPose;
218
+ }
219
+ /** How a scene reads a laid-out container's bounds and folds poses to the
220
+ * world frame a {@link LayoutStrategy} works in. */
221
+ interface LayoutFrame<TPose> {
222
+ /** The container's bounds, from its world pose. Default: the pose's own
223
+ * `x`/`y`/`width`/`height`; a pose without them is not laid out. */
224
+ bounds?(pose: TPose): ContainerBounds | null;
225
+ /** `pose` resized from bounds `from` to `to`, for a layout that grows its
226
+ * container. Default: `to`'s fields written over the pose. */
227
+ remap?(pose: TPose, from: ContainerBounds, to: ContainerBounds): TPose;
228
+ /** Omit for the absolute-pose model. A scene whose canvas composes poses
229
+ * (`<SceneCanvas poseComposition>`) passes the same strategy here. */
230
+ composition?: PoseComposition<TPose>;
128
231
  }
129
232
  /** A node in the scene tree: either a leaf or a container. Re-exported
130
233
  * publicly as `SceneNode`, to avoid colliding with the DOM's `Node`. */
@@ -133,6 +236,10 @@ interface LayerRecordBase<TLayer extends string> {
133
236
  id: TLayer;
134
237
  visible: boolean;
135
238
  locked: boolean;
239
+ /** Draw this layer as a parallax plane: through a view derived from the
240
+ * camera's (see `deriveParallaxView`), and picked through the same one.
241
+ * Absent means the layer moves with the camera. */
242
+ parallax?: ParallaxOpts;
136
243
  }
137
244
  /** A layer declared when the scene was created. Fixed set, no display name —
138
245
  * these are the kit's own render bands, not something a user manages. */
@@ -168,9 +275,11 @@ interface AddNodeSpec<TData, TLayer extends string, TPose = RectPose> {
168
275
  dependsOn?: readonly NodeId[] | 'children';
169
276
  /** Mirrors `SceneNode.derivePath`. Taken as a live function; its registry key is
170
277
  * looked up from it, never passed in. */
171
- derivePath?: (node: Node<unknown, string, TPose>, deps: readonly (DerivedDep<TPose> | undefined)[]) => Path | null;
278
+ derivePath?: DerivePathFn<TPose>;
172
279
  /** Mirrors `SceneNode.derivePose`, on the same terms as `derivePath`. */
173
- derivePose?: (node: Node<unknown, string, TPose>, deps: readonly (DerivedDep<TPose> | undefined)[]) => TPose | null;
280
+ derivePose?: DerivePoseFn<TPose>;
281
+ /** Mirrors `ContainerNode.layout`; ignored for leaves. */
282
+ layout?: LayoutStrategy<TPose>;
174
283
  }
175
284
  /** A custom scene mutation registered with `Scene.registerOp`: how to apply
176
285
  * it and how to undo it. The pair is what makes it participate in history. */
@@ -183,6 +292,8 @@ interface SystemLayerSpec<TLayer extends string> {
183
292
  id: TLayer;
184
293
  visible?: boolean;
185
294
  locked?: boolean;
295
+ /** See `LayerRecord.parallax`. */
296
+ parallax?: ParallaxOpts;
186
297
  }
187
298
  /** Argument to `Scene.addLayer`. Always produces a `UserLayerRecord`
188
299
  * (`kind: 'user'`). */
@@ -193,6 +304,8 @@ interface AddLayerSpec<TLayer extends string> {
193
304
  visible?: boolean;
194
305
  /** Default `false`. */
195
306
  locked?: boolean;
307
+ /** See `LayerRecord.parallax`. */
308
+ parallax?: ParallaxOpts;
196
309
  /** Render-stack position. Default: top of stack (highest render index). */
197
310
  index?: number;
198
311
  }
@@ -237,6 +350,8 @@ interface SerializedNode<TData, TLayer extends string, TPose> {
237
350
  derivePathKey?: string;
238
351
  /** Registry key for the node's `derivePose` function. Omitted when it has none. */
239
352
  derivePoseKey?: string;
353
+ /** Registry key for the container's layout strategy. Omitted when it has none. */
354
+ layoutKey?: string;
240
355
  }
241
356
  /** Per-scene registry mapping string keys to live function references.
242
357
  * Passed to `createScene({ ..., registry })` and `sceneFromJSON(json, { registry })`.
@@ -245,10 +360,33 @@ interface SceneRegistry<TPose> {
245
360
  /** Maps registry keys to `clipFromPose` factory functions for container nodes. */
246
361
  clipFromPose?: Readonly<Record<string, (pose: TPose) => Path | null>>;
247
362
  /** Maps registry keys to `derivePath` functions for nodes with `dependsOn`. */
248
- derivePath?: Readonly<Record<string, (node: Node<unknown, string, TPose>, deps: readonly (DerivedDep<TPose> | undefined)[]) => Path | null>>;
363
+ derivePath?: Readonly<Record<string, DerivePathFn<TPose>>>;
249
364
  /** Maps registry keys to `derivePose` functions for nodes with `dependsOn`. */
250
- derivePose?: Readonly<Record<string, (node: Node<unknown, string, TPose>, deps: readonly (DerivedDep<TPose> | undefined)[]) => TPose | null>>;
365
+ derivePose?: Readonly<Record<string, DerivePoseFn<TPose>>>;
366
+ /** Maps registry keys to container layout strategies. */
367
+ layout?: Readonly<Record<string, LayoutStrategy<TPose>>>;
251
368
  }
369
+ /**
370
+ * Decides what one edit's changes to containers do to their children.
371
+ * `arrivals` maps each container to the ids that joined it — by an `add`
372
+ * under it or a `move` into it, whatever op or call made them — in the order
373
+ * they arrived. `changed` names every container whose child set or order
374
+ * changed, or whose pose changed size, arrivals included. Both are read once
375
+ * the edit's other mutations have landed.
376
+ *
377
+ * Return the poses to write, in each node's stored frame; they become part of
378
+ * the same edit, and so of the same undo step. An empty map writes nothing.
379
+ * Return `null` to refuse: the whole edit is reverted (see
380
+ * `SceneArrivalRefused`).
381
+ *
382
+ * Runs only for live edits. Undo, redo and a restored history replay the
383
+ * arrangement that was decided the first time. With none installed, a scene
384
+ * holding declared layouts (`ContainerNode.layout`) runs its own.
385
+ */
386
+ type SceneArrivalHandler<TPose> = (arrivals: ReadonlyMap<NodeId, readonly NodeId[]>, changed: ReadonlySet<NodeId>,
387
+ /** The nodes that left each container in the edit, by the container they
388
+ * left — removed, or moved out. */
389
+ departures: ReadonlyMap<NodeId, readonly NodeId[]>) => ReadonlyMap<NodeId, TPose> | null;
252
390
  /** Options for `useScene` — the layers the scene has, what it starts out
253
391
  * holding, and how its history behaves. */
254
392
  interface UseSceneOptions<TData, TLayer extends string, TPose = RectPose> {
@@ -268,6 +406,8 @@ interface UseSceneOptions<TData, TLayer extends string, TPose = RectPose> {
268
406
  /** Per-scene registry for non-serializable function fields (clipFromPose, etc.).
269
407
  * Required only when serializing/deserializing scenes that use function fields. */
270
408
  registry?: SceneRegistry<TPose>;
409
+ /** How laid-out containers are measured. See {@link LayoutFrame}. */
410
+ layoutFrame?: LayoutFrame<TPose>;
271
411
  /** When supplied, `scene.applyOps(ops, label)` consults this on every call.
272
412
  * If it returns a non-null `Journal`, ops are routed to the journal's
273
413
  * `applyBatch` instead of recording a new parent-history entry. The journal
@@ -357,6 +497,13 @@ interface Scene<TData, TLayer extends string, TPose = RectPose> {
357
497
  * entries over the kit's. */
358
498
  readonly registry: SceneRegistry<TPose>;
359
499
  get(id: NodeId): Node<TData, TLayer, TPose> | undefined;
500
+ /** A token for the node `id` names right now, for telling one node from a
501
+ * later one that reuses its id. It holds for as long as the node stays in
502
+ * the scene, whatever edits it takes, and is different every time the id
503
+ * enters the scene — by `add`, by an undo or redo that brings it back, or
504
+ * by `loadState`. `undefined` when `id` is not in the scene. Compare tokens
505
+ * for equality only; their order means nothing. */
506
+ incarnation(id: NodeId): number | undefined;
360
507
  childrenOf(id: NodeId): readonly NodeId[];
361
508
  ancestorsOf(id: NodeId): readonly NodeId[];
362
509
  renderOrder(): Iterable<NodeId>;
@@ -424,6 +571,16 @@ interface Scene<TData, TLayer extends string, TPose = RectPose> {
424
571
  * **No-op elision** — declaring what the node already declares does nothing
425
572
  * and pushes no history entry. */
426
573
  setDependsOn(id: NodeId, dependsOn: readonly NodeId[] | 'children' | undefined): void;
574
+ /** Give container `id` a different layout — a strategy, its key in
575
+ * `SceneRegistry.layout`, or `null` for none — and re-arrange its children
576
+ * under it, as one undoable step. Throws for a leaf, or a key the registry
577
+ * does not hold. A registered layout is recorded by its key, so a
578
+ * serialized history restores it; an unregistered one lives only as long
579
+ * as the session.
580
+ *
581
+ * **No-op elision** — setting the layout a container already has does
582
+ * nothing and pushes no history entry. */
583
+ setLayout(id: NodeId, layout: LayoutStrategy<TPose> | string | null): void;
427
584
  /** Reparent `id` under `parent` (or to a root when `parent` is `null`) at
428
585
  * `index` within the new sibling list, appending when `index` is omitted.
429
586
  * Siblings are reindexed. Recorded as one undoable step.
@@ -447,6 +604,10 @@ interface Scene<TData, TLayer extends string, TPose = RectPose> {
447
604
  * drops them, and every node mutation on them throws. Locking is never
448
605
  * blocked by the lock, and neither are the other layer operations. */
449
606
  setLayerLocked(layer: TLayer, locked: boolean): void;
607
+ /** Set or clear (`undefined`) a layer's parallax — see
608
+ * `LayerRecord.parallax`. Undoable; an animation tweening it writes inside
609
+ * {@link Scene.untracked} so no frame becomes an undo step. */
610
+ setLayerParallax(layer: TLayer, parallax: ParallaxOpts | undefined): void;
450
611
  /** Whether `id` sits on a locked layer or under a container that does.
451
612
  * A container's lock covers its whole subtree, whatever layers the
452
613
  * descendants are tagged to. An id not in the scene is not locked. */
@@ -474,6 +635,11 @@ interface Scene<TData, TLayer extends string, TPose = RectPose> {
474
635
  * Pass `null` to detach. Overrides any `getActiveJournal` set in
475
636
  * `UseSceneOptions`. */
476
637
  setActiveJournalAccessor(fn: (() => _weasel_js_history.Journal | null) | null): void;
638
+ /** Install what the scene does when nodes join a container, replacing any
639
+ * handler installed before; `null` removes it. Returns a function that
640
+ * removes this handler, and does nothing once another has replaced it.
641
+ * See {@link SceneArrivalHandler}. */
642
+ setArrivalHandler(handler: SceneArrivalHandler<TPose> | null): () => void;
477
643
  /** Apply a batch of ops with journal-aware routing.
478
644
  *
479
645
  * - **Without active journal** (or no `getActiveJournal` in options):
@@ -517,6 +683,13 @@ interface Scene<TData, TLayer extends string, TPose = RectPose> {
517
683
  canUndo(): boolean;
518
684
  canRedo(): boolean;
519
685
  batch<T>(label: string, fn: () => T): T;
686
+ /** The layout container `id` declares, or `null` for a leaf or a
687
+ * container that declares none. */
688
+ layoutOf(id: NodeId): LayoutStrategy<TPose> | null;
689
+ /** Called with the poses each live edit's layout pass wrote, after the
690
+ * edit lands — never for an undo or redo, which restore poses rather than
691
+ * arrange them. What a reflow animation glides from. */
692
+ onReflow(listener: (moves: readonly LayoutMove<TPose>[]) => void): () => void;
520
693
  /** Run `fn` with every mutation applied but none recorded — for writes
521
694
  * that are not edits, such as a simulation stepping poses each frame.
522
695
  * Undo and redo move between recorded states and never restore an
@@ -631,64 +804,6 @@ interface FitViewToBoundsOptions {
631
804
  */
632
805
  declare function fitViewToBounds(bounds: Bounds, viewportDims: ViewportDims, currentView: View, opts?: FitViewToBoundsOptions): View;
633
806
 
634
- /**
635
- * Minimal compile/link/lookup wrapper for a GL program. Throws
636
- * `ShaderCompileError` on compile or link failure with the GL info log
637
- * embedded in the error message — never returns a half-initialized program.
638
- *
639
- * Designed so test code can stub `getShaderParameter` / `getProgramParameter`
640
- * via the recorder Proxy without further special-casing.
641
- */
642
- type Stage = 'vertex' | 'fragment' | 'link';
643
- /** Thrown when a shader fails to compile or link, carrying which stage failed
644
- * and the driver's log. */
645
- declare class ShaderCompileError extends Error {
646
- readonly stage: Stage;
647
- readonly log: string;
648
- constructor(stage: Stage, log: string);
649
- }
650
- declare class ShaderProgram {
651
- private readonly gl;
652
- readonly handle: WebGLProgram;
653
- private readonly uniforms;
654
- private readonly attributes;
655
- constructor(gl: WebGL2RenderingContext, vertSrc: string, fragSrc: string);
656
- private compile;
657
- lookupUniforms(names: readonly string[]): void;
658
- lookupAttributes(names: readonly string[]): void;
659
- uniform(name: string): WebGLUniformLocation | undefined;
660
- attribute(name: string): number | undefined;
661
- }
662
-
663
- /**
664
- * A tessellated representation of a Path, ready to upload to GL.
665
- *
666
- * - `vertices` is interleaved x,y in path-local coordinates (`Float32Array`
667
- * of length `2 * vertexCount`).
668
- * - `indices` are triangle indices into `vertices` (`Uint32Array`, length
669
- * `3 * triangleCount`).
670
- * - `requiresStencil` is set for paths whose fillRule is `'evenodd'` and
671
- * whose triangulation is a *naive* per-contour fan rather than a clean
672
- * inside/outside triangulation. The renderer must use a stencil
673
- * two-pass when this flag is true. Single-contour paths and `'nonzero'`
674
- * multi-contour paths leave it false.
675
- * - `anchorA` / `anchorB` / `anchorT` parameterize each mesh vertex by
676
- * the two consecutive path anchors it lies between and the arc-length
677
- * fraction along that segment (0 = at A, 1 = at B). Vertices that fall
678
- * exactly on an anchor set A === B and t = 0. Used at draw time when
679
- * the DrawCommand supplies per-anchor colors so the renderer can lerp
680
- * per mesh vertex. Optional — emitted by the path tessellators; absent
681
- * on meshes built by other paths (e.g. text glyphs).
682
- */
683
- interface Mesh {
684
- readonly vertices: Float32Array;
685
- readonly indices: Uint32Array;
686
- readonly requiresStencil?: boolean;
687
- readonly anchorA?: Uint32Array;
688
- readonly anchorB?: Uint32Array;
689
- readonly anchorT?: Float32Array;
690
- }
691
-
692
807
  interface GLMeshHandle {
693
808
  readonly vao: WebGLVertexArrayObject;
694
809
  readonly indexCount: number;
@@ -738,7 +853,10 @@ declare class GLMeshCache {
738
853
  /** Meshes this context has drawn at least once; see `uploadRecurring`. */
739
854
  private readonly seen;
740
855
  private readonly finalizer;
856
+ /** Every persistent upload not yet freed, so `dispose` can reach them. */
857
+ private readonly persistent;
741
858
  private readonly pendingDeletes;
859
+ private disposed;
742
860
  /** Transient resources allocated this frame; freed at end of render(). */
743
861
  private readonly transientThisFrame;
744
862
  constructor(gl: WebGL2RenderingContext, aPositionLoc: number);
@@ -772,6 +890,13 @@ declare class GLMeshCache {
772
890
  * Called by the renderer at the top of each `render()`, before any draws.
773
891
  */
774
892
  drainPendingDeletes(): void;
893
+ /**
894
+ * Free every GL resource this cache holds — persistent, pending and
895
+ * transient — and ignore finalizers from here on. Idempotent. Unlike the
896
+ * other paths this does not wait on GC, which is what lets a renderer on a
897
+ * context it does not own give back everything it uploaded.
898
+ */
899
+ dispose(): void;
775
900
  /** @internal — for tests asserting the queue size. */
776
901
  _pendingDeleteCount(): number;
777
902
  /** @internal — for tests that need to simulate the finalizer firing. */
@@ -830,7 +955,7 @@ declare class GLTextureCache {
830
955
  * Key: ImageBitmap (or pattern source object) identity (WeakMap) — lets GC
831
956
  * reclaim unreferenced bitmaps. The GL textures are NOT freed when the source
832
957
  * is gc'd; a source's owner that knows it will never be drawn again frees them
833
- * with {@link releaseImageSource}.
958
+ * with {@link releaseImageSource}, and `dispose` frees them all.
834
959
  *
835
960
  * Wrapping is set once at upload time per the `repetition` parameter:
836
961
  * - undefined / 'no-repeat' → CLAMP_TO_EDGE
@@ -850,6 +975,9 @@ declare class GLImageCache {
850
975
  /** This context's `MAX_TEXTURE_SIZE`. */
851
976
  readonly maxTextureSide: number;
852
977
  private readonly map;
978
+ /** Every texture `map` holds, so `dispose` can reach them — a WeakMap
979
+ * cannot be enumerated. */
980
+ private readonly textures;
853
981
  /**
854
982
  * MAG_FILTER each texture currently carries, so a redundant write can be
855
983
  * skipped.
@@ -876,9 +1004,12 @@ declare class GLImageCache {
876
1004
  constructor(gl: WebGL2RenderingContext, minification?: ImageMinification);
877
1005
  /** Delete `key`'s texture, if it has one. */
878
1006
  release(key: object): void;
879
- /** Stop answering {@link releaseImageSource} and {@link maxImageTextureSide}.
880
- * Call when the context is disposed or lost. */
1007
+ /** Delete every texture this cache uploaded and stop answering
1008
+ * {@link releaseImageSource} and {@link maxImageTextureSide}. Idempotent. */
881
1009
  dispose(): void;
1010
+ /** {@link dispose} without the deletes, for a cache whose context was lost:
1011
+ * its textures died with it. */
1012
+ abandon(): void;
882
1013
  upload(key: object, source: TexSource, repetition?: PatternRepetition): WebGLTexture;
883
1014
  bind(key: object, unit: number): void;
884
1015
  /** Set `key`'s MAG_FILTER, skipping the call when it already holds that
@@ -967,70 +1098,6 @@ declare class GradientRampAtlas {
967
1098
  private writeRow;
968
1099
  }
969
1100
 
970
- /**
971
- * 2D affine matrix utilities. Column-major 9-element Float32Array, matching
972
- * `WebGL2RenderingContext.uniformMatrix3fv` byte order so we can pass the
973
- * array directly without a transpose flag.
974
- *
975
- * Layout (column-major):
976
- * [m00, m10, 0,
977
- * m01, m11, 0,
978
- * tx, ty, 1]
979
- *
980
- * `apply(m, x, y)` returns `[m * (x, y, 1)] = [m00*x + m01*y + tx,
981
- * m10*x + m11*y + ty]`.
982
- */
983
-
984
- type GlMat3 = Float32Array;
985
- declare function identity(): GlMat3;
986
- declare function multiply(out: GlMat3, m: GlMat3): GlMat3;
987
- /** `m · T(tx, ty)`: composes onto `m`, where `@weasel-js/geom`'s `translate`
988
- * constructs a fresh matrix. */
989
- declare function translated(m: GlMat3, tx: number, ty: number): GlMat3;
990
- /** `m · S(sx, sy)`: composes onto `m`, where geom's `scale` constructs one. */
991
- declare function scaled(m: GlMat3, sx: number, sy: number): GlMat3;
992
- /** This layout read as the kernel's 6-element affine. The two carry the same
993
- * logical order, so the conversion is a repack and nothing else — it exists
994
- * so the repack has a name instead of appearing inline at each crossing. */
995
- declare function toAffine(m: GlMat3): Mat3;
996
- /** The kernel's affine in this layout. The inverse of {@link toAffine}, and
997
- * what an `SvgGroupNode.transform` (also a kernel affine) becomes on its way
998
- * to a `GroupDrawCommand`. */
999
- declare function fromAffine(a: Mat3): GlMat3;
1000
- /** Inverse of an affine matrix, or `null` when `@weasel-js/geom`'s `invert`
1001
- * finds it singular — the same rule, read through this layout. */
1002
- declare function invert(m: GlMat3): GlMat3 | null;
1003
- declare function apply(m: GlMat3, x: number, y: number): [number, number];
1004
- /**
1005
- * Map screen pixel coords (0..width on X, 0..height on Y, top-left origin)
1006
- * into clip space (-1..1 on X, 1..-1 on Y — note Y flip so screen-down
1007
- * matches clip-down).
1008
- */
1009
- declare function screenToClip(width: number, height: number): GlMat3;
1010
- /**
1011
- * Uniform-equivalent scale factor: the square root of the absolute
1012
- * determinant of the linear part, i.e. the geometric mean of the two axis
1013
- * scales. Rotation-invariant. Under non-uniform scale it is between the two
1014
- * axes and exact on neither — the same compromise `meanScale` documents.
1015
- */
1016
- declare function meanScaleOf(m: GlMat3): number;
1017
- /** The renderer's 3x3 matrix operations, as one namespace. These work on the
1018
- * 9-element `Float32Array` form the GL uniform upload wants — distinct from
1019
- * `@weasel-js/geom`'s 6-element affine `GlMat3`, though the logical element
1020
- * order is the same. */
1021
- declare const mat3: {
1022
- identity: typeof identity;
1023
- toAffine: typeof toAffine;
1024
- fromAffine: typeof fromAffine;
1025
- multiply: typeof multiply;
1026
- translated: typeof translated;
1027
- scaled: typeof scaled;
1028
- invert: typeof invert;
1029
- apply: typeof apply;
1030
- screenToClip: typeof screenToClip;
1031
- meanScaleOf: typeof meanScaleOf;
1032
- };
1033
-
1034
1101
  /** Row-major 4×5 color matrix identity. */
1035
1102
  declare const IDENTITY_COLOR_MATRIX: Float32Array<ArrayBuffer>;
1036
1103
  interface GroupFrame {
@@ -1069,66 +1136,6 @@ declare class GroupState {
1069
1136
  pop(): void;
1070
1137
  }
1071
1138
 
1072
- /**
1073
- * registerProgram — public API for registering custom shader programs.
1074
- *
1075
- * Stores raw GLSL source strings in a module-level registry. GL compilation
1076
- * happens on each WeaselRenderer via WeaselRenderer.registerProgram(), which
1077
- * calls getProgramSource() and compiles the result. This keeps registerProgram
1078
- * GL-context-agnostic — identical pattern to registerFont storing ImageBitmap.
1079
- *
1080
- * Module-level state = source strings only; compiled GL
1081
- * programs live on each renderer's programRegistry (Map<id, ShaderProgram>).
1082
- *
1083
- * Lifecycle: program sources live for the module lifetime. No unregister in v1.
1084
- */
1085
-
1086
- /** Opaque handle to a compiled custom shader program. */
1087
- interface ShaderProgramHandle {
1088
- readonly id: string;
1089
- }
1090
- /**
1091
- * Scalar and vector uniform types accepted by the custom shader uniform binder.
1092
- *
1093
- * | TS type | GL call |
1094
- * |-------------------------|--------------------------------------|
1095
- * | number | uniform1f |
1096
- * | [n, n] | uniform2fv |
1097
- * | [n, n, n] | uniform3fv |
1098
- * | [n, n, n, n] | uniform4fv |
1099
- * | Float32Array length 9 | uniformMatrix3fv (column-major) |
1100
- * | Float32Array length 16 | uniformMatrix4fv (column-major) |
1101
- * | TextureHandle | bind to next tex unit + uniform1i |
1102
- */
1103
- type ShaderUniform = number | [number, number] | [number, number, number] | [number, number, number, number] | Float32Array | TextureHandle;
1104
- /**
1105
- * Register a custom shader program by id.
1106
- *
1107
- * Pass an empty string for `vert` to use the kit's default vertex shader
1108
- * (recommended). The kit's vertex shader exposes `v_uv`, `v_screen`, and
1109
- * `v_world` varyings plus `u_bounds` and `u_view` uniforms.
1110
- *
1111
- * **IMPORTANT — Premultiplied alpha:**
1112
- * Your fragment shader MUST output premultiplied alpha:
1113
- * `outColor = vec4(rgb * a, a);` ← correct
1114
- * `outColor = vec4(rgb, a);` ← WRONG — over-brightens translucent regions
1115
- *
1116
- * The renderer uses `gl.blendFunc(ONE, ONE_MINUS_SRC_ALPHA)` to match.
1117
- * Opaque fragments (a=1) are unaffected; only fragments with a < 1 differ.
1118
- *
1119
- * **Re-registration behavior:**
1120
- * - Dev mode (`NODE_ENV !== 'production'`): calling with an existing id replaces
1121
- * the source (hot-reload). Each renderer must call `WeaselRenderer.registerProgram(handle)`
1122
- * again to pick up the new source.
1123
- * - Prod mode: calling with an existing id throws.
1124
- *
1125
- * Actual GL compilation and `ShaderCompileError` throwing happen in
1126
- * `WeaselRenderer.registerProgram()`, not here.
1127
- *
1128
- * @experimental API may break before v2.
1129
- */
1130
- declare function registerProgram(id: string, vert: string, frag: string): ShaderProgramHandle;
1131
-
1132
1139
  /**
1133
1140
  * One full-screen pass over what a group has already drawn.
1134
1141
  *
@@ -1248,6 +1255,9 @@ interface TextDrawCommand {
1248
1255
  /** Wrap width. Absent never wraps. */
1249
1256
  maxWidth?: number;
1250
1257
  align?: 'left' | 'center' | 'right';
1258
+ /** Spread each wrapped line across `width` — see `LayoutRunsOpts.justify`.
1259
+ * `align` then sets only the lines it does not spread. Default `false`. */
1260
+ justify?: boolean;
1251
1261
  /** Box width `align` resolves within, from `x`. Default `maxWidth`; with
1252
1262
  * neither, `x` is the line's left edge, midpoint or right edge. */
1253
1263
  width?: number;
@@ -1505,11 +1515,43 @@ declare class DrawBatch {
1505
1515
  /** How to construct a `WeaselRenderer`: the GL context or canvas to draw
1506
1516
  * into, the output size, and the quality knobs that separate screen
1507
1517
  * rendering from print. */
1518
+ /** A run of top-level commands, `[start, end)` by index, that
1519
+ * {@link WeaselRenderer.lastFrameStats} accounts for separately — one render
1520
+ * layer's commands, say. Spans are in order and do not overlap. */
1521
+ interface RenderSpan {
1522
+ id: string;
1523
+ start: number;
1524
+ end: number;
1525
+ }
1526
+ /** Per-frame options for {@link WeaselRenderer.render}. */
1527
+ interface RenderOptions {
1528
+ spans?: readonly RenderSpan[];
1529
+ }
1530
+ /** What one span cost. A batched run is drawn when something closes it, so
1531
+ * its draw call counts toward the span that closed it. */
1532
+ interface RenderSpanStats {
1533
+ id: string;
1534
+ drawCalls: number;
1535
+ ms: number;
1536
+ }
1537
+ /** What one `render()` cost. See {@link WeaselRenderer.lastFrameStats}. */
1538
+ interface RenderStats {
1539
+ drawCalls: number;
1540
+ ms: number;
1541
+ spans: RenderSpanStats[];
1542
+ }
1543
+ /** Construction options for {@link WeaselRenderer}. Pass `gl` or `canvas`;
1544
+ * a context passed in must have a stencil buffer. */
1508
1545
  interface WeaselRendererOptions {
1546
+ /** A WebGL2 context to draw with. Wins over `canvas`. */
1509
1547
  gl?: WebGL2RenderingContext;
1548
+ /** A canvas to open a stencil-backed WebGL2 context on, when `gl` is absent. */
1510
1549
  canvas?: HTMLCanvasElement;
1550
+ /** Drawing size in CSS pixels. */
1511
1551
  width: number;
1552
+ /** Drawing size in CSS pixels. */
1512
1553
  height: number;
1554
+ /** Device pixels per CSS pixel. */
1513
1555
  dpr: number;
1514
1556
  /** MIN_FILTER strategy for image/pattern textures (`GLImageCache`).
1515
1557
  * Default `'linear'` — the existing screen behavior. The headless
@@ -1566,17 +1608,23 @@ interface RenderTarget {
1566
1608
  */
1567
1609
  declare class WeaselRenderer {
1568
1610
  private readonly gl;
1611
+ private stats;
1569
1612
  private pathFill;
1570
1613
  private pathFillVColor;
1571
1614
  private imageFill;
1572
1615
  private batchFill;
1573
1616
  private gradFill;
1574
1617
  private patternFill;
1618
+ /** Compiled on first use: only atlas text under a texture paint needs one. */
1619
+ private glyphPaintPrograms;
1575
1620
  private meshCache;
1576
1621
  private textureCache;
1577
1622
  private imageCache;
1578
1623
  private gradRamps;
1579
1624
  private programRegistry;
1625
+ /** The source each compiled custom program was built from — or, after a
1626
+ * failed recompile, the source that failed, so it is not retried every frame. */
1627
+ private programSources;
1580
1628
  private quadVbo;
1581
1629
  private quadIbo;
1582
1630
  private drawBatch;
@@ -1592,6 +1640,7 @@ declare class WeaselRenderer {
1592
1640
  /** Offscreen buffers for group effects. Allocates nothing until a group
1593
1641
  * with effects asks, so a canvas without them pays no memory. */
1594
1642
  private readonly effectTargets;
1643
+ private readonly paintScratch;
1595
1644
  private readonly imageMinification;
1596
1645
  private flattenTolerance?;
1597
1646
  private readonly bakeBudget;
@@ -1602,6 +1651,9 @@ declare class WeaselRenderer {
1602
1651
  /** True after `dispose()`. A disposed renderer ignores further `render()`
1603
1652
  * calls and `registerProgram()` calls. */
1604
1653
  private disposed;
1654
+ /** What registered paint kinds hang their GPU state on. One per context
1655
+ * generation: a restore releases it and opens the next. */
1656
+ private paintResources;
1605
1657
  constructor(opts: WeaselRendererOptions);
1606
1658
  private uploadQuadGeometry;
1607
1659
  /**
@@ -1615,6 +1667,10 @@ declare class WeaselRenderer {
1615
1667
  * @experimental
1616
1668
  */
1617
1669
  registerProgram(handle: ShaderProgramHandle): void;
1670
+ private installProgram;
1671
+ /** Recompile every program whose module-level source was re-registered
1672
+ * since it was compiled. A source that fails keeps the old program drawing. */
1673
+ private refreshPrograms;
1618
1674
  /**
1619
1675
  * The compiled program for `id`, compiling it against this context on first
1620
1676
  * use. Unlike {@link registerProgram} this neither throws on a missing
@@ -1622,6 +1678,7 @@ declare class WeaselRenderer {
1622
1678
  * never registered must decline the paint, not take down the frame.
1623
1679
  */
1624
1680
  private ensureProgram;
1681
+ private glyphPaintProgram;
1625
1682
  /** The GL state every frame assumes. Applied per `render()` rather than once
1626
1683
  * at construction because a co-tenant sharing this context moves all of it
1627
1684
  * between our frames. */
@@ -1636,27 +1693,15 @@ declare class WeaselRenderer {
1636
1693
  isContextLost(): boolean;
1637
1694
  private onContextLost;
1638
1695
  private onContextRestored;
1639
- /** Free the GL resources this renderer itself owns and detach context-loss
1696
+ /** Free every GL resource this renderer created and detach context-loss
1640
1697
  * listeners when a canvas was supplied. Idempotent.
1641
1698
  *
1642
- * Scope: built-in shader programs, any consumer-registered programs, the
1643
- * shared quad/rect geometry, any in-flight transient meshes, and the
1644
- * enumerable Map-keyed caches (`GLTextureCache` atlas/image textures,
1645
- * `GradientRampAtlas`'s ramp texture) ARE freed.
1646
- *
1647
- * NOT freed: `GLImageCache` (bitmap/pattern textures) and `GLMeshCache`'s
1648
- * persistent per-Path mesh cache are keyed by `WeakMap`, not enumerable,
1649
- * and are only reclaimed when the GL context itself goes away (cf.
1650
- * `GLImageCache`'s own "deferred to v2" note). On a caller-owned
1651
- * long-lived context — the headless render-to-pixels path hands the same
1652
- * `gl` to many short-lived renderers — the image/pattern textures and
1653
- * persistent Path meshes each renderer uploads DO accumulate across
1654
- * renderer instances until the caller recycles the context.
1655
- *
1656
- * Also: a Mesh that gets GC'd after `dispose()` still lands in
1657
- * `GLMeshCache`'s `pendingDeletes` queue via its `FinalizationRegistry`,
1658
- * but nothing drains that queue post-dispose (only `render()` does) —
1659
- * those GL resources leak until the context goes away too.
1699
+ * That covers the built-in and consumer-registered programs (their shaders
1700
+ * go with them), the shared quad geometry, the batch, the effect targets,
1701
+ * and every cache: atlas and gradient-ramp textures, bitmap and pattern
1702
+ * textures, and meshes — transient, persistent, and those whose Path was
1703
+ * already collected. The context itself is left alone, so a caller-owned
1704
+ * context can host renderer after renderer without accumulating anything.
1660
1705
  *
1661
1706
  * A disposed renderer ignores further `render()` and `registerProgram()`
1662
1707
  * calls. */
@@ -1669,7 +1714,11 @@ declare class WeaselRenderer {
1669
1714
  * it — every other command carries its own transform in the stream, so
1670
1715
  * callers with no view concept can keep calling `render(commands)`.
1671
1716
  */
1672
- render(commands: DrawCommand[], viewMatrix?: GlMat3): void;
1717
+ render(commands: DrawCommand[], viewMatrix?: GlMat3, opts?: RenderOptions): void;
1718
+ /** What the last `render()` cost: GL draw calls issued and CPU milliseconds
1719
+ * spent issuing them, in total and per requested span. GPU time is not
1720
+ * measured; the GPU runs asynchronously. */
1721
+ lastFrameStats(): RenderStats;
1673
1722
  /** Change the curve-flattening tolerance after construction. `undefined`
1674
1723
  * restores the cached `DEFAULT_FLATTEN_TOLERANCE` route. */
1675
1724
  setFlattenTolerance(tolerance: number | undefined): void;
@@ -1774,6 +1823,547 @@ interface CullRect {
1774
1823
  */
1775
1824
  declare function cullDrawCommands(cmds: DrawCommand[], transform: GlMat3, rect: CullRect): DrawCommand[];
1776
1825
 
1826
+ /**
1827
+ * Read-only state that affordances consult on every render and hit-test
1828
+ * call. Built via `buildChromeState` and held across renders, so affordances
1829
+ * must not cache anything they read from it.
1830
+ */
1831
+ interface ChromeState {
1832
+ /** Currently selected ids. Live; reflects useSelection's React state. */
1833
+ readonly selection: readonly NodeId[];
1834
+ /** True when the canvas is in multi-mode AND >= 2 ids are selected. */
1835
+ readonly multiActive: boolean;
1836
+ /** Bounds for any selection member id. Honors active-tool overlay state
1837
+ * (move/resize/rotate ghosts → ghost bounds; otherwise → committed
1838
+ * pose bounds). Returns null for unknown ids or ids whose bounds aren't
1839
+ * computable. */
1840
+ boundsOf(id: string): Bounds | null;
1841
+ /** Multi-union AABB when `multiActive`. Recomputed from `boundsOf` over
1842
+ * every selected id on each read, expanding rotated members to the extent
1843
+ * of their ink; null otherwise. */
1844
+ readonly unionBounds: Bounds | null;
1845
+ /** Active modifier state at the moment of the call. */
1846
+ readonly modifiers: ModifierState;
1847
+ /** True iff the node's pose-descriptor declares it can carry a rotation.
1848
+ * Affordances consult this to decide whether to expose rotate cursors /
1849
+ * drag-bands. Defaults to `true` when the descriptor doesn't declare
1850
+ * (back-compat) or when the id is unknown — the rotation gesture will
1851
+ * no-op visually for poses without AABB fields, but the affordance
1852
+ * doesn't lie about the cursor. Optional on the interface so unit-test
1853
+ * call sites that construct `ChromeState` by hand keep compiling;
1854
+ * affordances should treat an absent predicate as "true". */
1855
+ canRotate?(id: string): boolean;
1856
+ }
1857
+
1858
+ /**
1859
+ * @experimental
1860
+ * A single interactive piece of chrome. Pure functions; the kit composes
1861
+ * multiple affordances into a single RenderLayer per tool via
1862
+ * `composeAffordanceLayer`.
1863
+ *
1864
+ * Affordances declare interactive regions in a target's *local* frame.
1865
+ * The framework (`composeAffordanceLayer`) composes the target's bounds
1866
+ * transform (rotation around the AABB center, when present) for both paint
1867
+ * and hit-test, so the affordance never touches rotation, view.scale, or
1868
+ * world↔screen math.
1869
+ */
1870
+ interface Affordance {
1871
+ /** Stable id for debug overlays + visibility maps. */
1872
+ id: string;
1873
+ /** Enumerate this affordance's interactive regions. Each region lives in
1874
+ * some target id's local frame (or in the world frame when `targetId`
1875
+ * is `null`). Returning `[]` means "no chrome for this state" (no
1876
+ * selection, multi-mode disabled, etc.). */
1877
+ regions(state: ChromeState): readonly AffordanceRegion[];
1878
+ /** Optional non-interactive decoration (e.g., a leader line drawn from
1879
+ * a bounds edge to a handle — visual only, not draggable). Receives
1880
+ * raw state + view because the decoration may live outside any single
1881
+ * target's local frame. Most affordances leave this undefined. */
1882
+ decorate?(state: ChromeState, view: View): DrawCommand[];
1883
+ }
1884
+ /**
1885
+ * @experimental
1886
+ * One interactive region produced by an affordance. The framework owns
1887
+ * the local↔world transform for `targetId` (when non-null), so `shape`,
1888
+ * `paint.sizePx`, and `hitRadiusPx` are always specified in coordinates
1889
+ * the affordance can reason about directly.
1890
+ */
1891
+ interface AffordanceRegion<TScratch = unknown> {
1892
+ /** Stable id, e.g. `corner-min-min`. Used for debug overlays + a11y. */
1893
+ id: string;
1894
+ /** Target id whose `state.boundsOf(targetId)` defines this region's
1895
+ * local frame. `bounds.rotation` (if present) is the only transform
1896
+ * applied — translation is the AABB origin; scale is identity. Pass
1897
+ * `null` for affordances anchored to the viewport / world frame
1898
+ * (identity transform). */
1899
+ targetId: string | null;
1900
+ /** Region geometry, expressed in the target's local frame.
1901
+ *
1902
+ * - `point` — square hit of half-extent `hitRadiusPx` screen pixels,
1903
+ * axis-aligned on screen unless `turned`. `standoff` pushes the anchor `px`
1904
+ * screen pixels off the edge whose outward normal (target-local) is
1905
+ * `normal`, measured along that normal as it lands on screen — for
1906
+ * chrome that floats a fixed distance off an edge at any zoom.
1907
+ * - `rect` — axis-aligned rect (target rotation applies).
1908
+ * - `annulus` — outer ellipse minus inner rect cutout. Used for
1909
+ * invisible zones that sit *around* the AABB (e.g. rotate-on-
1910
+ * hover band). The outer ellipse is defined by world-space
1911
+ * semi-axes `rx` / `ry` around `(cx, cy)`; the inner rect is the
1912
+ * same target-local rect that defines the AABB. Hit-test:
1913
+ * inside outer ellipse AND outside inner rect. */
1914
+ shape: {
1915
+ kind: 'point';
1916
+ x: number;
1917
+ y: number;
1918
+ hitRadiusPx: number;
1919
+ standoff?: {
1920
+ px: number;
1921
+ normal: {
1922
+ x: number;
1923
+ y: number;
1924
+ };
1925
+ };
1926
+ /** Turn the square to the target, at the angle the target's x axis
1927
+ * lands on screen (`screenAngleOf`) — for handles painted turned. */
1928
+ turned?: boolean;
1929
+ } | {
1930
+ kind: 'rect';
1931
+ x: number;
1932
+ y: number;
1933
+ width: number;
1934
+ height: number;
1935
+ } | {
1936
+ kind: 'annulus';
1937
+ /** Outer-ellipse center (target-local). */
1938
+ cx: number;
1939
+ cy: number;
1940
+ /** Outer-ellipse semi-axes (target-local). */
1941
+ rx: number;
1942
+ ry: number;
1943
+ /** Inner rect (target-local) — the cutout. Typically the
1944
+ * selection's AABB. */
1945
+ innerX: number;
1946
+ innerY: number;
1947
+ innerWidth: number;
1948
+ innerHeight: number;
1949
+ /** Minimum band thickness outside the inner rect, in **screen**
1950
+ * pixels. The framework widens `rx`/`ry` to at least
1951
+ * `innerHalfExtent + pxExtent(minBandPx, view.scale)` on each axis
1952
+ * for both paint and hit-test.
1953
+ *
1954
+ * This exists because the clamp has to know the view and the
1955
+ * affordance doesn't: `ChromeState` carries no scale. Expressing the
1956
+ * floor in world units instead (which is what the rotate ring used
1957
+ * to do) makes the band shrink on screen as you zoom in, until the
1958
+ * ring around a small shape is too thin to hover. */
1959
+ minBandPx?: number;
1960
+ };
1961
+ /** Optional paint. World position is derived from `shape` + target
1962
+ * transform; visual size stays in screen pixels (so handles don't
1963
+ * warp under zoom or non-uniform scale). Omit for hit-only regions.
1964
+ *
1965
+ * - `square` — small fixed-size square (only valid over `point` shapes).
1966
+ * - `annulus` — fill + stroke the annulus ring (only valid over
1967
+ * `annulus` shapes). Uses even-odd fill rule to punch the inner-rect
1968
+ * cutout.
1969
+ * - `custom` — emit arbitrary draw commands; receives a {@link CustomPaintContext}. */
1970
+ paint?: {
1971
+ kind: 'square';
1972
+ sizePx: number;
1973
+ fill?: FillStyle;
1974
+ stroke?: Stroke;
1975
+ } | {
1976
+ kind: 'annulus';
1977
+ fill?: FillStyle;
1978
+ stroke?: Stroke;
1979
+ insetPx?: number;
1980
+ } | {
1981
+ kind: 'custom';
1982
+ draw: (ctx: CustomPaintContext) => DrawCommand[];
1983
+ };
1984
+ /** Discriminator a press on this region reports as `AffordanceHit.kind` —
1985
+ * the string routing specs match on (`'handle:top-left'`,
1986
+ * `'rotate-handle'`, `'anchor:3'`). Omit for regions that only exist
1987
+ * inside a consumer-registered layer, where the layer id is the
1988
+ * discriminator; `buildAffordanceAt` falls back to
1989
+ * `<affordanceId>:<regionId>`. */
1990
+ hitKind?: string;
1991
+ /** Cursor to show while hovering this region. Read by the hover-cursor
1992
+ * pump in `useGestureDispatcher` via `AffordanceHit.cursor`, which
1993
+ * `buildAffordanceAt` fills in from the region the walk landed on. */
1994
+ cursor?: CursorSpec;
1995
+ /** `'exclusive'` bars every binding whose target doesn't consult the
1996
+ * affordance. Read only when the affordance is composed into a
1997
+ * consumer-registered layer; kit chrome routes through
1998
+ * `buildAffordanceAt`, which reports `'shared'`. */
1999
+ strength?: 'exclusive' | 'shared';
2000
+ /** Which gestures an exclusive claim bars. Omitted bars all of them. */
2001
+ claimedKinds?: readonly ClaimableGesture[];
2002
+ /** Drag binding produced when this region is hit. Lazily called so
2003
+ * affordances don't pay binding-construction cost on every paint frame —
2004
+ * state snapshots (e.g., capturing per-leaf poses at click time) belong
2005
+ * inside `bind()`, not inside `regions()`. */
2006
+ bind(): AffordanceBinding<TScratch>;
2007
+ }
2008
+ /** Context passed to a region's `paint.kind === 'custom'` draw callback.
2009
+ * Provides both the world-space anchor (already transformed) and the
2010
+ * original local shape, for affordances that want to do additional
2011
+ * geometry themselves. */
2012
+ interface CustomPaintContext {
2013
+ /** World-space mapping of `shape`. For `point`, only `x`/`y` are set.
2014
+ * For `rect`, all four fields are set. */
2015
+ world: {
2016
+ x: number;
2017
+ y: number;
2018
+ width?: number;
2019
+ height?: number;
2020
+ };
2021
+ /** The original local shape (same object identity as `region.shape`). */
2022
+ local: AffordanceRegion['shape'];
2023
+ view: View;
2024
+ state: ChromeState;
2025
+ }
2026
+ /**
2027
+ * @experimental
2028
+ * Result of an affordance hit — what the region computed about itself.
2029
+ *
2030
+ * `initialScratch` is the payload: what the region already knows (which
2031
+ * corner, which target id) so the action that picks up the drag doesn't
2032
+ * re-derive it. `<SceneCanvas>` reads it out of the layer hit-test and packs
2033
+ * it into `AffordanceHit`, which flows to the matching action through
2034
+ * `InvocationCtx.drag.affordance`.
2035
+ *
2036
+ * This used to also carry a `drag: DragChannel` naming the handlers the
2037
+ * tool-routing dispatcher should wire up. Every implementation supplied a
2038
+ * no-op stub that claimed, because the real routing had already moved to
2039
+ * bindings; the field went with that dispatcher.
2040
+ */
2041
+ interface AffordanceBinding<TScratch = unknown> {
2042
+ initialScratch?: TScratch;
2043
+ }
2044
+ /**
2045
+ * The fields `buildAffordanceAt` lifts out of a region's `initialScratch`
2046
+ * when it turns a region hit into an `AffordanceHit`.
2047
+ *
2048
+ * Scratch is otherwise opaque — whatever the affordance wants to hand the
2049
+ * action that picks up the drag. These few names are the exception: they mean
2050
+ * the same thing to every affordance, and the actions that consume them
2051
+ * (`resizeAction`, `rotateAction`) read them off `AffordanceHit` rather than
2052
+ * out of scratch. An affordance that doesn't set them simply produces a hit
2053
+ * without those fields.
2054
+ */
2055
+ interface CommonAffordanceScratch {
2056
+ /** The node (or `MULTI_RESIZE_TARGET_ID`) this chrome acts on. Becomes
2057
+ * `AffordanceHit.targetIds`. */
2058
+ targetId?: string;
2059
+ /** For resize chrome: which corner stays pinned. Mirrors the kit's
2060
+ * `ResizeAnchor`, spelled inline so `affordances/` doesn't take a type
2061
+ * dependency on the gesture layer for one field. */
2062
+ anchor?: {
2063
+ x: 'min' | 'max' | 'free';
2064
+ y: 'min' | 'max' | 'free';
2065
+ };
2066
+ /** World-space invariant point of the transform — the fixed corner for a
2067
+ * resize, the pivot for a rotation. */
2068
+ fixedPoint?: {
2069
+ x: number;
2070
+ y: number;
2071
+ };
2072
+ }
2073
+ /**
2074
+ * What a **registered layer's** `hitTest` returns. Extends `AffordanceBinding`
2075
+ * so existing implementations keep typechecking; the added fields are how a
2076
+ * consumer's own chrome says the things kit chrome says through
2077
+ * `AffordanceRegion` — which cursor to show, and whether it owns the point
2078
+ * outright.
2079
+ */
2080
+ interface LayerHit<TScratch = unknown> extends AffordanceBinding<TScratch> {
2081
+ /** Cursor while the pointer is over this hit. Reaches the hover-cursor
2082
+ * pump as `AffordanceHit.cursor`, the same path kit chrome uses. */
2083
+ cursor?: CursorSpec;
2084
+ /** `'exclusive'` bars every binding whose target doesn't consult the
2085
+ * affordance. Omitted means `'shared'` — today's behavior. Same name and
2086
+ * meaning as `AffordanceHit.strength`, which it becomes. */
2087
+ strength?: 'exclusive' | 'shared';
2088
+ /** Which gestures an exclusive claim bars. Omitted bars all of them. */
2089
+ claimedKinds?: readonly ClaimableGesture[];
2090
+ }
2091
+
2092
+ /**
2093
+ * Canvas size in CSS pixels — passed to `draw` for layers that anchor to
2094
+ * canvas edges (e.g. the debug overlay's layer-list panel). The GL backend
2095
+ * supplies it explicitly so layers don't have to know about DPR.
2096
+ */
2097
+ interface Dims {
2098
+ width: number;
2099
+ height: number;
2100
+ }
2101
+ /**
2102
+ * What a layer's `draw` threw, and which layer threw it.
2103
+ *
2104
+ * A `draw` runs on the frame loop, so a throw that escapes it surfaces as an
2105
+ * uncaught `requestAnimationFrame` error on the window and takes the whole
2106
+ * frame with it — every other layer included. One broken layer painting
2107
+ * nothing, named in the console, is the lesser wrong.
2108
+ */
2109
+ interface LayerDrawFailure {
2110
+ layerId: string;
2111
+ error: unknown;
2112
+ }
2113
+ /**
2114
+ * Several consecutive layers composited as one.
2115
+ *
2116
+ * A layer's own `effects` run over that layer alone, which is the wrong
2117
+ * picture whenever a pass reads neighboring pixels: `blur(A over B)` is not
2118
+ * `blur(A) over blur(B)`, and it costs a buffer and a pass chain per layer. A
2119
+ * group draws its members into one buffer, runs one chain over it, and
2120
+ * composites the result back once.
2121
+ *
2122
+ * Membership is by `RenderLayer.id` — the same names `layerOrder` and
2123
+ * `layerVisibility` use, not the `layers` map's slot keys.
2124
+ *
2125
+ * Only *consecutive* members share a buffer, because anything drawn between
2126
+ * two members has to land between them. A group whose members are separated in
2127
+ * the render order is drawn as one bracket per run, with a warning: the
2128
+ * picture is right, the declaration almost certainly is not.
2129
+ *
2130
+ * This is a render-stack bracket, not a scene `ContainerNode` — it holds no
2131
+ * ids, survives no reload, and nothing in the scene knows about it.
2132
+ */
2133
+ interface LayerGroup {
2134
+ /** Names the group in warnings; not a layer id and never drawn. */
2135
+ id: string;
2136
+ /**
2137
+ * Member layer ids. Order here is ignored — the render order decides.
2138
+ *
2139
+ * A name claims that layer and every layer under it in the `:` namespace, so
2140
+ * `'scene'` covers the `scene:<layerId>` layers a scene with declared layers
2141
+ * draws as — the same set `before`/`after: 'scene'` anchors against. The
2142
+ * separator is required: `'scene'` does not reach `scenery`. A name matching
2143
+ * no layer being drawn is warned about rather than ignored.
2144
+ */
2145
+ layers: readonly string[];
2146
+ /**
2147
+ * Passes over the group's combined pixels, in order. A thunk is re-read on
2148
+ * every frame, so an animating radius costs no React render; an array is
2149
+ * read once per frame either way.
2150
+ */
2151
+ effects?: readonly Effect[] | ((view: View, dims: Dims) => readonly Effect[]);
2152
+ /** Opacity applied to the group's composited result, not to each member. */
2153
+ alpha?: number;
2154
+ /** 4×5 color matrix (row-major, 20 numbers) applied to the composited
2155
+ * result. See `GroupDrawCommand.colorMatrix`. */
2156
+ colorMatrix?: number[];
2157
+ }
2158
+ /** One layer's memoized output, keyed by layer id. Owned by the canvas that
2159
+ * calls `drawLayers`, not by `drawLayers` itself — the function is pure. */
2160
+ type LayerCommandCache = Map<string, {
2161
+ deps: readonly unknown[];
2162
+ cmds: DrawCommand[];
2163
+ }>;
2164
+ /**
2165
+ * A single named render sub-layer within a canvas renderer.
2166
+ *
2167
+ * @template TData - The data object passed to each draw call.
2168
+ */
2169
+ /** Something outside React whose changes a paint reads — a mode registry, a
2170
+ * scoping lookup. A notification repaints the canvas; the listener takes no
2171
+ * arguments and the returned function unsubscribes. */
2172
+ interface RedrawSource {
2173
+ subscribe(listener: () => void): () => void;
2174
+ }
2175
+ /** The `subscribe` for a layer that draws `sources`: it notifies whenever any
2176
+ * of them does. A thunk is read when the subscription is made. Every layer
2177
+ * that draws other layers declares this, so wrapping never silences what
2178
+ * repaints a source. */
2179
+ declare function subscribeToSources(sources: readonly {
2180
+ subscribe?: RedrawSource['subscribe'];
2181
+ }[] | (() => readonly {
2182
+ subscribe?: RedrawSource['subscribe'];
2183
+ }[])): RedrawSource['subscribe'];
2184
+ /** One layer of a canvas: `draw` turns `data` and the view into draw commands;
2185
+ * the other fields control caching, visibility, coordinate space and hit-testing. */
2186
+ interface RenderLayer<TData> {
2187
+ /** Unique identifier used in visibility maps and ordering arrays. When a
2188
+ * cache is in use, an id must identify the same logical layer across
2189
+ * frames — reusing it for a different layer can serve cross-layer commands. */
2190
+ id: string;
2191
+ /** Human-readable name for UI toggles. */
2192
+ label: string;
2193
+ /**
2194
+ * Emit a DrawCommand tree for the GL backend to dispatch.
2195
+ *
2196
+ * For world-space layers (the default), emit commands in WORLD COORDS —
2197
+ * `drawLayers` automatically wraps them in `{ kind: 'group', transform:
2198
+ * viewToMat3(view), ... }` before handing them to the renderer. Do NOT
2199
+ * apply the view transform yourself.
2200
+ *
2201
+ * For screen-space layers (`space: 'screen'`), emit commands in CSS-pixel
2202
+ * coords directly; `drawLayers` passes them through unchanged. If part
2203
+ * of a screen-space layer's output needs to track the view, wrap that
2204
+ * subset manually with `viewToMat3(view)`.
2205
+ */
2206
+ draw: (data: TData, view: View, dims: Dims) => DrawCommand[];
2207
+ /**
2208
+ * Optional cache key. When present and a `LayerCommandCache` is supplied to
2209
+ * `drawLayers`, the layer's previous `DrawCommand[]` is reused as long as
2210
+ * every entry is `Object.is`-equal to the previous call's. A layer with no
2211
+ * `deps` rebuilds on every frame.
2212
+ *
2213
+ * **The returned commands must be treated as immutable.** A cached tree is
2214
+ * handed to the renderer again on later frames, so mutating a tree you
2215
+ * previously returned corrupts the cache silently rather than erroring.
2216
+ *
2217
+ * **Screen-space layers are not protected against a stale `view`/`dims`
2218
+ * the way world-space layers are** (see `space` below) — include them in
2219
+ * `deps` if `draw` reads them.
2220
+ */
2221
+ deps?: (data: TData, view: View, dims: Dims) => readonly unknown[];
2222
+ /**
2223
+ * Whether the layer is shown when no explicit visibility entry exists.
2224
+ * Defaults to `true` when absent.
2225
+ */
2226
+ defaultVisible?: boolean;
2227
+ /**
2228
+ * When true, the layer is always drawn regardless of the visibility map.
2229
+ * Useful for layers that must never be hidden (e.g. base grid).
2230
+ */
2231
+ alwaysOn?: boolean;
2232
+ /**
2233
+ * Coordinate space the layer draws in.
2234
+ *
2235
+ * - `'world'` (default): the layer's `draw` returns world-space commands;
2236
+ * `drawLayers` wraps them in a `kind: 'group'` with `viewToMat3(view)`
2237
+ * automatically.
2238
+ * - `'screen'`: the layer's `draw` returns screen-space (CSS-pixel)
2239
+ * commands; `drawLayers` passes them through unchanged. World-anchored
2240
+ * chrome inside a screen-space layer must call `worldToScreen` or wrap
2241
+ * the relevant subset with `viewToMat3(view)` manually.
2242
+ */
2243
+ space?: 'world' | 'screen';
2244
+ /**
2245
+ * Where the layer learns that state `draw` reads, outside the scene and the
2246
+ * props, has changed. The canvas painting it subscribes while the layer is
2247
+ * mounted and repaints on every notification, so a layer reading a mode
2248
+ * registry needs no consumer code to follow a mode switch.
2249
+ */
2250
+ subscribe?: RedrawSource['subscribe'];
2251
+ /**
2252
+ * Full-screen passes run over this layer's own pixels before it joins the
2253
+ * frame — a blur here blurs the world and leaves the HUD drawn above it
2254
+ * sharp, which is the thing a CSS `filter` on the `<canvas>` cannot do.
2255
+ *
2256
+ * Costs nothing while empty: the renderer allocates no offscreen buffer
2257
+ * until a layer actually declares one. See `GroupDrawCommand.effects` for
2258
+ * what a pass may read, and {@link LayerGroup} to run one chain over
2259
+ * several layers at once instead of one chain each.
2260
+ */
2261
+ effects?: readonly Effect[];
2262
+ /**
2263
+ * Optional hit-test for **consumer-attached** layers.
2264
+ *
2265
+ * Only layers registered through `CanvasExtensionApi.registerLayer` are
2266
+ * hit-tested: `hitTestExtras` walks them last-registered-first on
2267
+ * pointerdown, and `<SceneCanvas>` folds the result into its `affordanceAt`
2268
+ * thunk ahead of the kit's own selection chrome. First non-null result
2269
+ * wins; null means "I don't claim this hit, try the next layer."
2270
+ *
2271
+ * Layers that reach the draw stack some other way — a `Tool.overlay`, an
2272
+ * entry in the `layers` map — are painted but never hit-tested, so defining
2273
+ * `hitTest` on one has no effect. (The kit's own chrome doesn't need it: it
2274
+ * goes through `buildAffordanceAt`.)
2275
+ *
2276
+ * Coordinates are world-space. The `data` arg is the layer's
2277
+ * configured data slot (same as `draw`); `view` and `dims` mirror
2278
+ * `draw`'s arguments.
2279
+ */
2280
+ hitTest?: (worldX: number, worldY: number, data: TData, view: View, dims: Dims,
2281
+ /** Chrome-caps visibility predicate. When supplied, the layer must
2282
+ * not return a hit from any chrome element whose id reports
2283
+ * `false`. Absent → every element is hittable. */
2284
+ isVisible?: (id: string) => boolean) => LayerHit | null;
2285
+ /**
2286
+ * Called on every pointermove when no gesture is currently captured.
2287
+ * Lets layers (e.g. HUD widgets) track hover state without participating
2288
+ * in the drag pipeline. Coords are world-space; the layer is responsible
2289
+ * for any further conversion (e.g. world→screen for screen-space layers)
2290
+ * and for its own throttling.
2291
+ */
2292
+ onUncapturedMove?: (worldX: number, worldY: number, evt: PointerEvent, view: View, dims: Dims) => void;
2293
+ /**
2294
+ * Called when the cursor leaves the canvas element. Lets layers clear
2295
+ * any hover state they're holding.
2296
+ */
2297
+ onUncapturedLeave?: () => void;
2298
+ }
2299
+ /** Where one layer's commands landed in {@link drawLayers}' output,
2300
+ * `[start, end)`, and the CPU milliseconds its `draw` took. A layer group's
2301
+ * run is one span under the group's id. */
2302
+ interface LayerDrawSpan {
2303
+ id: string;
2304
+ start: number;
2305
+ end: number;
2306
+ buildMs: number;
2307
+ }
2308
+ /**
2309
+ * Walk visible layers and concatenate their emitted DrawCommand arrays into
2310
+ * one flat list, ready to feed to `WeaselRenderer.render(commands)`.
2311
+ *
2312
+ * Visibility resolution order:
2313
+ * 1. `alwaysOn` — always drawn, ignores visibility map.
2314
+ * 2. Explicit entry in `visibility` map — overrides default.
2315
+ * 3. `layer.defaultVisible` — falls back to `true` when absent.
2316
+ *
2317
+ * Transform composition: world-space layers (the default; `space` unset or
2318
+ * `'world'`) have their commands wrapped in a `kind: 'group'` with
2319
+ * `viewToMat3(view)` before they reach the renderer. Screen-space layers
2320
+ * (`space: 'screen'`) pass through unchanged.
2321
+ *
2322
+ * A layer whose `draw` throws is dropped for the frame and reported through
2323
+ * `onLayerError` — the rest of the frame still paints.
2324
+ *
2325
+ * `groups` brackets runs of consecutive layers so they composite as one — see
2326
+ * `LayerGroup`. A layer named by no group is emitted exactly as it was before
2327
+ * groups existed, and a frame that declares none allocates nothing.
2328
+ *
2329
+ * `spans`, when passed, receives one {@link LayerDrawSpan} per layer drawn.
2330
+ */
2331
+ 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[]): DrawCommand[];
2332
+ /**
2333
+ * Resolve one layer's visibility: `alwaysOn` wins, then an explicit entry in
2334
+ * `visibility`, then `defaultVisible`, defaulting to shown.
2335
+ */
2336
+ declare function isLayerVisible<TData>(layer: RenderLayer<TData>, visibility: Record<string, boolean>): boolean;
2337
+ /**
2338
+ * Does this layer reach the screen at all — both gates, in the order
2339
+ * `drawLayers` applies them.
2340
+ *
2341
+ * **A listed `order` is the whole list**, so omission from it drops a layer
2342
+ * that `visibility` would have shown, and `alwaysOn` does not rescue it.
2343
+ * Hit-testing asks this, not `isLayerVisible`: a layer that is not painted
2344
+ * but still claims pointer events is a pointer landing on nothing the user
2345
+ * can see.
2346
+ */
2347
+ declare function isLayerPainted<TData>(layer: RenderLayer<TData>, visibility: Record<string, boolean>, order: string[] | undefined): boolean;
2348
+ /**
2349
+ * Draw one layer and put its commands in the space its `space` declares:
2350
+ * world-space output wrapped in a `viewToMat3(view)` group, screen-space
2351
+ * output passed through.
2352
+ *
2353
+ * Anything rendering layers through a view — the canvas itself, a viewport
2354
+ * node's inner pass — goes through here. A second copy of this rule that
2355
+ * forgets the wrap draws world content at raw world coords, which looks
2356
+ * plausible at the identity view and wrong everywhere else.
2357
+ *
2358
+ * A `draw` that throws yields no commands, and `onLayerError` is told which
2359
+ * layer it was. The layer's cache entry goes with it, so the next frame is a
2360
+ * real re-attempt rather than a stale tree served under fresh deps.
2361
+ */
2362
+ declare function drawOneLayer<TData>(layer: RenderLayer<TData>, data: TData, view: View, dims: Dims, cache?: LayerCommandCache, onLayerError?: (failure: LayerDrawFailure) => void): DrawCommand[];
2363
+ /** Whether `b` matches `a` entry for entry under `Object.is` — how
2364
+ * `RenderLayer.deps` is compared, and any cache keyed the same way. */
2365
+ declare function depsUnchanged(a: readonly unknown[], b: readonly unknown[]): boolean;
2366
+
1777
2367
  /** Per-axis limits on a view's position. Any side may be left open. */
1778
2368
  interface PanBounds {
1779
2369
  minX?: number;
@@ -1891,7 +2481,9 @@ interface TimelineClock {
1891
2481
  interface EventBookingHandle {
1892
2482
  stop(): void;
1893
2483
  }
2484
+ /** One entry on an `EventTrack`. Give it `fire`, `book`, or both. */
1894
2485
  interface TimelineEvent {
2486
+ /** Time within the track's timeline, in ms. */
1895
2487
  t: number;
1896
2488
  /** Runs on the frame that crosses the edge, told how far behind the frame it
1897
2489
  * was crossed, in ms — never negative, and measured against `duration` on
@@ -1913,6 +2505,7 @@ interface EventTrack {
1913
2505
  /** Sorted ascending by `t`. */
1914
2506
  events: TimelineEvent[];
1915
2507
  }
2508
+ /** How a timeline books its events against an outside clock. */
1916
2509
  interface EventBooking {
1917
2510
  clock: TimelineClock;
1918
2511
  /** How far ahead of the playhead to book, in clock ms. Default 100. An event
@@ -1930,6 +2523,7 @@ interface TimelineTrack {
1930
2523
  at: number;
1931
2524
  timeline: NestedTimeline;
1932
2525
  }
2526
+ /** Any track a timeline can hold. */
1933
2527
  type Track = SampledTrack<any> | EventTrack | TimelineTrack;
1934
2528
  /** What a child timeline may declare. The parent owns playback, so `loop`,
1935
2529
  * `autoplay`, `onDone` and `cancelKey` have no meaning below the root. */
@@ -1938,18 +2532,24 @@ interface NestedTimeline {
1938
2532
  /** Defaults to the largest end time across `tracks`. */
1939
2533
  duration?: number;
1940
2534
  }
2535
+ /** What `animator.timeline` takes: a root timeline, which owns playback. */
1941
2536
  interface TimelineOptions extends NestedTimeline {
1942
2537
  /** `true` loops forever, `n` loops n additional times. Default false. */
1943
2538
  loop?: boolean | number;
1944
2539
  /** Default true. When false the timeline registers but holds at t=0 until resumed. */
1945
2540
  autoplay?: boolean;
2541
+ /** Called when playback reaches the end of its last lap. */
1946
2542
  onDone?: () => void;
2543
+ /** Any new animation passed the same `cancelKey` cancels this one. */
1947
2544
  cancelKey?: string;
2545
+ /** Names this timeline in `animator.watch` events and `animator.live()`. */
2546
+ label?: string;
1948
2547
  /** Books each event's `book` against a clock the timeline does not own, so a
1949
2548
  * consumer on that clock lands it at its true sub-frame time. The frame
1950
2549
  * clock's mapping onto it is smoothed each frame and resynced on a jump. */
1951
2550
  booking?: EventBooking;
1952
2551
  }
2552
+ /** What `animator.timeline` returns: playback control plus live editing. */
1953
2553
  interface TimelineHandle extends AnimationHandle {
1954
2554
  /** Move the playhead. Never fires event tracks, at any depth. */
1955
2555
  seek(t: number): void;
@@ -1974,144 +2574,6 @@ interface TimelineHandle extends AnimationHandle {
1974
2574
  subscribe(cb: () => void): () => void;
1975
2575
  }
1976
2576
 
1977
- /** No easing: constant rate from start to finish. */
1978
- declare const linear: EasingFn;
1979
- /** Accelerates from a standstill, gently. */
1980
- declare const easeInQuad: EasingFn;
1981
- /** Decelerates to a stop, gently. The safe default for UI motion. */
1982
- declare const easeOutQuad: EasingFn;
1983
- /** Accelerates then decelerates, gently. */
1984
- declare const easeInOutQuad: EasingFn;
1985
- /** Accelerates from a standstill, moderately. */
1986
- declare const easeInCubic: EasingFn;
1987
- /** Decelerates to a stop, moderately. */
1988
- declare const easeOutCubic: EasingFn;
1989
- /** Accelerates then decelerates, moderately. */
1990
- declare const easeInOutCubic: EasingFn;
1991
- /** Accelerates from a standstill, sharply. */
1992
- declare const easeInQuart: EasingFn;
1993
- /** Decelerates to a stop, sharply. */
1994
- declare const easeOutQuart: EasingFn;
1995
- /** Accelerates then decelerates, sharply. */
1996
- declare const easeInOutQuart: EasingFn;
1997
- /** Accelerates from a standstill, very sharply. */
1998
- declare const easeInQuint: EasingFn;
1999
- /** Decelerates to a stop, very sharply. */
2000
- declare const easeOutQuint: EasingFn;
2001
- /** Accelerates then decelerates, very sharply. */
2002
- declare const easeInOutQuint: EasingFn;
2003
- /** Accelerates from a standstill along a sine curve — the mildest
2004
- * acceleration of the built-ins. */
2005
- declare const easeInSine: EasingFn;
2006
- /** Decelerates to a stop along a sine curve — the mildest
2007
- * deceleration of the built-ins. */
2008
- declare const easeOutSine: EasingFn;
2009
- /** Accelerates then decelerates along a sine curve. */
2010
- declare const easeInOutSine: EasingFn;
2011
- /** Accelerates exponentially: barely moves at first, then rushes. */
2012
- declare const easeInExpo: EasingFn;
2013
- /** Decelerates exponentially: leaps away, then creeps in. */
2014
- declare const easeOutExpo: EasingFn;
2015
- /** Exponential at both ends — a very fast middle between two
2016
- * near-still extremes. */
2017
- declare const easeInOutExpo: EasingFn;
2018
- /** Accelerates along a circular arc: slow start, abrupt arrival. */
2019
- declare const easeInCirc: EasingFn;
2020
- /** Decelerates along a circular arc: abrupt start, slow arrival. */
2021
- declare const easeOutCirc: EasingFn;
2022
- /** Circular arcs at both ends. */
2023
- declare const easeInOutCirc: EasingFn;
2024
- /** Pulls back past the start before moving forward. Overshoots below 0. */
2025
- declare const easeInBack: EasingFn;
2026
- /** Overshoots the target, then settles back onto it. Exceeds 1. */
2027
- declare const easeOutBack: EasingFn;
2028
- /** Overshoots at both ends. Leaves the 0–1 range on each side. */
2029
- declare const easeInOutBack: EasingFn;
2030
- /** Oscillates around the start with growing amplitude, then snaps away. */
2031
- declare const easeInElastic: EasingFn;
2032
- /** Springs past the target and wobbles into it. Exceeds 1. */
2033
- declare const easeOutElastic: EasingFn;
2034
- /** Wobbles at both ends. Leaves the 0–1 range on each side. */
2035
- declare const easeInOutElastic: EasingFn;
2036
- /** Lands on the target and bounces, in hops of decreasing height. */
2037
- declare const easeOutBounce: EasingFn;
2038
- /** Bounces up to the start before departing — `easeOutBounce` reversed. */
2039
- declare const easeInBounce: EasingFn;
2040
- /** Bounces at both ends. */
2041
- declare const easeInOutBounce: EasingFn;
2042
- /** Alias for `easeInQuad`, kept for call sites that predate the
2043
- * named-curve library. */
2044
- declare const easeIn: EasingFn;
2045
- /** Alias for `easeOutQuad`, kept for call sites that predate the
2046
- * named-curve library. */
2047
- declare const easeOut: EasingFn;
2048
- /** Alias for `easeInOutQuad`, kept for call sites that predate the
2049
- * named-curve library. */
2050
- declare const easeInOut: EasingFn;
2051
- /** All easings in one bag — useful for demos / pickers. */
2052
- declare const EASINGS: {
2053
- readonly linear: EasingFn;
2054
- readonly easeInQuad: EasingFn;
2055
- readonly easeOutQuad: EasingFn;
2056
- readonly easeInOutQuad: EasingFn;
2057
- readonly easeInCubic: EasingFn;
2058
- readonly easeOutCubic: EasingFn;
2059
- readonly easeInOutCubic: EasingFn;
2060
- readonly easeInQuart: EasingFn;
2061
- readonly easeOutQuart: EasingFn;
2062
- readonly easeInOutQuart: EasingFn;
2063
- readonly easeInQuint: EasingFn;
2064
- readonly easeOutQuint: EasingFn;
2065
- readonly easeInOutQuint: EasingFn;
2066
- readonly easeInSine: EasingFn;
2067
- readonly easeOutSine: EasingFn;
2068
- readonly easeInOutSine: EasingFn;
2069
- readonly easeInExpo: EasingFn;
2070
- readonly easeOutExpo: EasingFn;
2071
- readonly easeInOutExpo: EasingFn;
2072
- readonly easeInCirc: EasingFn;
2073
- readonly easeOutCirc: EasingFn;
2074
- readonly easeInOutCirc: EasingFn;
2075
- readonly easeInBack: EasingFn;
2076
- readonly easeOutBack: EasingFn;
2077
- readonly easeInOutBack: EasingFn;
2078
- readonly easeInElastic: EasingFn;
2079
- readonly easeOutElastic: EasingFn;
2080
- readonly easeInOutElastic: EasingFn;
2081
- readonly easeInBounce: EasingFn;
2082
- readonly easeOutBounce: EasingFn;
2083
- readonly easeInOutBounce: EasingFn;
2084
- };
2085
- /** The name of one of the built-in easing curves. */
2086
- type EasingName = keyof typeof EASINGS;
2087
- /** Named spring tunings, from softest to firmest. Springs settle on a target
2088
- * rather than running for a fixed duration, so these are an alternative to an
2089
- * easing curve, not a modifier on one. */
2090
- declare const SPRING_PRESETS: Record<SpringPresetName, SpringPreset>;
2091
-
2092
- /** Cubic-bezier control points, CSS `cubic-bezier()` order. The curve's two
2093
- * endpoints are implicit at (0,0) and (1,1). */
2094
- interface BezierEasing {
2095
- /** `readonly` so an `as const` preset is assignable; nothing ever writes it. */
2096
- bezier: readonly [number, number, number, number];
2097
- }
2098
- /** An easing curve as a value: a function, the name of a built-in, or control
2099
- * points. Anything an editor has to name, show or serialize must not be a bare
2100
- * function, which is why the union exists. */
2101
- type EasingSpec = EasingFn | EasingName | BezierEasing;
2102
- /** Build the easing curve for four cubic-bezier control points. `x1`/`x2` are
2103
- * clamped to [0,1] — CSS `cubic-bezier()`'s constraint for a monotone x(t),
2104
- * which both `solveForX` root-finders assume. `y1`/`y2` are unclamped: an
2105
- * overshoot easing (back, elastic) needs them outside 0..1. */
2106
- declare function cubicBezierEasing(x1: number, y1: number, x2: number, y2: number): EasingFn;
2107
- /** Resolve a spec to the function that shapes progress. `undefined` is linear. */
2108
- declare function resolveEasing(spec?: EasingSpec): EasingFn;
2109
-
2110
- /** An easing curve: maps normalized progress `t ∈ [0, 1]` to eased progress.
2111
- * Curves may leave the 0–1 range in the middle (back, elastic) but should
2112
- * pass through 0 at 0 and 1 at 1. */
2113
- type EasingFn = (t: number) => number;
2114
-
2115
2577
  /** Blends two `T` values at eased progress `t`. Called once per frame; see
2116
2578
  * {@link InterpolatorFactory} when the blend has setup worth hoisting. */
2117
2579
  type Interpolate<T> = (from: T, to: T, t: number) => T;
@@ -2121,15 +2583,6 @@ type Interpolate<T> = (from: T, to: T, t: number) => T;
2121
2583
  * shape exactly. For cheap interpolations the per-tick `Interpolate<T>` form is
2122
2584
  * fine; this is the escape hatch when setup-per-tick is wasteful. */
2123
2585
  type InterpolatorFactory<T> = (from: T, to: T) => (t: number) => T;
2124
- /** A spring's physical parameters. Higher stiffness settles faster, higher
2125
- * damping overshoots less, higher mass makes both sluggish. */
2126
- interface SpringPreset {
2127
- stiffness: number;
2128
- damping: number;
2129
- mass: number;
2130
- }
2131
- /** One of the tunings in `SPRING_PRESETS`. */
2132
- type SpringPresetName = 'gentle' | 'wobbly' | 'stiff' | 'slow';
2133
2586
  /** A running animation. Cancel it, or bend its time — pausing and time-scaling
2134
2587
  * act on this animation's own virtual clock, independent of the animator's. */
2135
2588
  interface AnimationHandle {
@@ -2169,6 +2622,8 @@ interface TweenOptions<T> {
2169
2622
  onDone?: () => void;
2170
2623
  /** Any new animation passed the same cancelKey cancels the prior one in flight. */
2171
2624
  cancelKey?: string;
2625
+ /** Names this animation in {@link AnimatorEvent}s and `animator.live()`. */
2626
+ label?: string;
2172
2627
  }
2173
2628
  /** A spring animation: runs until the value settles on `to` rather than for a
2174
2629
  * set duration, so it absorbs an initial velocity naturally. Non-numeric `T`
@@ -2193,6 +2648,8 @@ interface SpringOptions<T> {
2193
2648
  onTick: (value: T) => void;
2194
2649
  onDone?: () => void;
2195
2650
  cancelKey?: string;
2651
+ /** Names this animation in {@link AnimatorEvent}s and `animator.live()`. */
2652
+ label?: string;
2196
2653
  }
2197
2654
  /** Spring and decay as one animation. With a `to`, a spring pulls toward it;
2198
2655
  * with `to: null`, the value coasts on its velocity. Either can become the
@@ -2216,6 +2673,8 @@ interface PhysicsOptions<T> {
2216
2673
  onTick: (value: T) => void;
2217
2674
  onDone?: () => void;
2218
2675
  cancelKey?: string;
2676
+ /** Names this animation in {@link AnimatorEvent}s and `animator.live()`. */
2677
+ label?: string;
2219
2678
  }
2220
2679
  /** An `AnimationHandle` that can also be steered while it runs — the point of
2221
2680
  * the physics primitive. */
@@ -2240,6 +2699,8 @@ interface DecayOptions<T> {
2240
2699
  onTick: (value: T) => void;
2241
2700
  onDone?: () => void;
2242
2701
  cancelKey?: string;
2702
+ /** Names this animation in {@link AnimatorEvent}s and `animator.live()`. */
2703
+ label?: string;
2243
2704
  }
2244
2705
  /** Options for `useAnimator`. Everything here is an injection seam for tests;
2245
2706
  * the defaults are the real clock, rAF, and `setTimeout`. */
@@ -2374,7 +2835,82 @@ interface Animator {
2374
2835
  * stop firing even though the override is still installed.
2375
2836
  */
2376
2837
  keepAlive(): () => void;
2838
+ /**
2839
+ * Subscribe to the lifecycle of every animation this animator runs, the
2840
+ * composites and timelines included. Returns an unsubscribe. Events arrive
2841
+ * synchronously, as each thing happens — see {@link AnimatorEvent} for the
2842
+ * order. With no listener attached nothing is built or delivered, so an
2843
+ * unwatched animator pays nothing for this.
2844
+ */
2845
+ watch(listener: AnimatorListener): () => void;
2846
+ /** What is running right now, in registration order: a fresh snapshot per
2847
+ * call, for a debug overlay to draw. */
2848
+ live(): LiveAnimation[];
2377
2849
  }
2850
+ /** Which animator call started an animation. A loop, tween loop or stagger is
2851
+ * an entry of its own beside the children it runs; `keepAlive` holds the
2852
+ * frame loop open and animates nothing. */
2853
+ type AnimationKind = 'tween' | 'spring' | 'decay' | 'physics' | 'timeline' | 'loop' | 'tweenLoop' | 'stagger' | 'keepAlive';
2854
+ /** Who an {@link AnimatorEvent} is about. One object per registration, so the
2855
+ * same animation's events share it by identity. */
2856
+ interface AnimationInfo {
2857
+ /** The id on the animation's handle. */
2858
+ readonly id: number;
2859
+ readonly kind: AnimationKind;
2860
+ /** The animation's `cancelKey`. Pose helpers key by node, as `pose:<id>`. */
2861
+ readonly key?: string;
2862
+ /** The animation's `label` option. */
2863
+ readonly label?: string;
2864
+ }
2865
+ /** One row of `animator.live()`. */
2866
+ interface LiveAnimation extends AnimationInfo {
2867
+ /** Paused on its own handle. The animator-wide pause is `animator.isPaused()`. */
2868
+ readonly paused: boolean;
2869
+ /** Its own time scale; the animator's multiplies on top. */
2870
+ readonly timeScale: number;
2871
+ /** Virtual ms its clock has advanced since it started. */
2872
+ readonly elapsed: number;
2873
+ /** 0 to 1, for a tween or a timeline (the playhead over its duration).
2874
+ * Absent where there is no end to measure against: physics, composites. */
2875
+ readonly progress?: number;
2876
+ }
2877
+ /**
2878
+ * One thing happening to an animation, as `animator.watch` delivers it.
2879
+ *
2880
+ * - `start` — registered. A finished timeline that `seek` or `edit` revives
2881
+ * starts again, under the same id.
2882
+ * - `end` — finished on its own. Delivered once every animation has ticked
2883
+ * that frame, in registration order.
2884
+ * - `cancel` — stopped by its handle, `cancel`, `cancelKey` or `cancelAll`.
2885
+ * - `interrupt` — stopped because `by` claimed its `cancelKey`. Delivered
2886
+ * before `by`'s `start`.
2887
+ * - `lap` — a looping timeline wrapped; `lap` counts wraps since it started.
2888
+ * - `fire` — an event on a timeline's event track was crossed, at any depth.
2889
+ * `path` indexes from the root timeline's `tracks()` down through each
2890
+ * nested timeline to the event track. Delivered after the event's own `fire`.
2891
+ */
2892
+ type AnimatorEvent = {
2893
+ readonly type: 'start' | 'end' | 'cancel';
2894
+ readonly animation: AnimationInfo;
2895
+ } | {
2896
+ readonly type: 'interrupt';
2897
+ readonly animation: AnimationInfo;
2898
+ readonly by: AnimationInfo;
2899
+ } | {
2900
+ readonly type: 'lap';
2901
+ readonly animation: AnimationInfo;
2902
+ readonly lap: number;
2903
+ } | {
2904
+ readonly type: 'fire';
2905
+ readonly animation: AnimationInfo;
2906
+ readonly track: EventTrack;
2907
+ readonly path: readonly number[];
2908
+ readonly event: TimelineEvent;
2909
+ /** As the event's own `fire` is told: ms behind the frame it was crossed. */
2910
+ readonly lateBy: number;
2911
+ };
2912
+ /** Receives what `animator.watch` delivers. */
2913
+ type AnimatorListener = (event: AnimatorEvent) => void;
2378
2914
  /** Options for `Animator.loop`. */
2379
2915
  interface LoopOptions {
2380
2916
  /** Maximum number of iterations. Default Infinity. */
@@ -2384,13 +2920,18 @@ interface LoopOptions {
2384
2920
  /** Any new animation passed the same cancelKey cancels the prior one in flight.
2385
2921
  * Also enables `animator.cancelKey` / `animator.isActive(key)` for this loop. */
2386
2922
  cancelKey?: string;
2923
+ /** Names this loop in {@link AnimatorEvent}s and `animator.live()`. */
2924
+ label?: string;
2387
2925
  }
2388
- /** Options for the top-level `Animator.stagger` factory form (third overload). */
2926
+ /** A stagger run's own options: the factory form's fourth argument, and part
2927
+ * of every fluent builder method's options. */
2389
2928
  interface StaggerOptions {
2390
2929
  /** Cancel-key for the supervising registration. `animator.cancelKey(key)`
2391
2930
  * cancels the whole stagger; `animator.isActive(key)` returns true while
2392
2931
  * any timer or child is alive. */
2393
2932
  cancelKey?: string;
2933
+ /** Names this stagger in {@link AnimatorEvent}s and `animator.live()`. */
2934
+ label?: string;
2394
2935
  }
2395
2936
  /** Produces one iteration of a loop. Must arrange for `next` to be called when
2396
2937
  * the animation it returns finishes, or the loop stalls after one pass. */
@@ -2405,8 +2946,9 @@ type StaggerFactory<TItem> = (item: TItem, index: number) => AnimationHandle;
2405
2946
  * vary an option (e.g. `to: (_item, i) => (i + 1) * 10`). */
2406
2947
  type StaggerPerItem<T, TItem> = T | ((item: TItem, index: number) => T);
2407
2948
  /** Options for the stagger builder's `.tween`: a tween per item, where
2408
- * `from`, `to` and `ms` may each vary by item. */
2409
- interface StaggerTweenOptions<T, TItem> {
2949
+ * `from`, `to` and `ms` may each vary by item. `cancelKey` and `label` belong
2950
+ * to the stagger as a whole, as in {@link StaggerOptions}. */
2951
+ interface StaggerTweenOptions<T, TItem> extends StaggerOptions {
2410
2952
  from: StaggerPerItem<T, TItem>;
2411
2953
  to: StaggerPerItem<T, TItem>;
2412
2954
  ms: StaggerPerItem<number, TItem>;
@@ -2416,8 +2958,10 @@ interface StaggerTweenOptions<T, TItem> {
2416
2958
  onDone?: (item: TItem, index: number) => void;
2417
2959
  }
2418
2960
  /** Options for the stagger builder's `.springPose`: the spring tuning, and
2419
- * whether each item's settle is recorded as an undoable op. */
2420
- interface StaggerSpringPoseOptions<TPose> {
2961
+ * whether each item's settle is recorded as an undoable op. `cancelKey` and
2962
+ * `label` belong to the stagger as a whole, as in {@link StaggerOptions};
2963
+ * each item's spring keeps its own per-node key. */
2964
+ interface StaggerSpringPoseOptions<TPose> extends StaggerOptions {
2421
2965
  preset?: SpringPresetName;
2422
2966
  stiffness?: number;
2423
2967
  damping?: number;
@@ -2430,7 +2974,7 @@ interface StaggerSpringPoseOptions<TPose> {
2430
2974
  * items and the delay schedule are already fixed. */
2431
2975
  interface StaggerBuilder<TItem> {
2432
2976
  /** Run an arbitrary per-item factory. */
2433
- each(factory: StaggerFactory<TItem>): AnimationHandle;
2977
+ each(factory: StaggerFactory<TItem>, opts?: StaggerOptions): AnimationHandle;
2434
2978
  /** Sugar: per-item `animator.tween` with per-item-varying options. */
2435
2979
  tween<T>(opts: StaggerTweenOptions<T, TItem>): AnimationHandle;
2436
2980
  /** Sugar: per-item `springPose` against an adapter. `poseFn` returns the
@@ -2458,6 +3002,8 @@ interface TweenLoopOptions<T> {
2458
3002
  onTick: (value: T) => void;
2459
3003
  onDone?: () => void;
2460
3004
  cancelKey?: string;
3005
+ /** Names this animation in {@link AnimatorEvent}s and `animator.live()`. */
3006
+ label?: string;
2461
3007
  }
2462
3008
 
2463
3009
  /** Cancel-key prefix. Each hook instance appends its own id, so two runners
@@ -2576,144 +3122,275 @@ declare function usePointerContext(): PointerContextValue | null;
2576
3122
  declare function usePointerPosition(): PointerWorldPos;
2577
3123
 
2578
3124
  /**
2579
- * Pose composition for hierarchical scene graphs.
3125
+ * Project a leaf path from its source frame into world coordinates given a
3126
+ * `{x, y, width, height, rotation?}` pose. Two transforms compose, in this
3127
+ * order:
2580
3128
  *
2581
- * As of the nesting change, `getPose(id)` on adapters returns the
2582
- * **local** pose — relative to the object's direct parent. Anything in the
2583
- * kit that needs to draw, hit-test, snap, or otherwise reason about world
2584
- * coordinates routes through `composeWorldPose`, which walks the parent
2585
- * chain and folds local poses together via a consumer-supplied `compose`.
3129
+ * 1. Translate so the path's source AABB origin lands at `pose.x, pose.y`.
3130
+ * 2. If `pose.rotation` is nonzero, rotate every coord about the unrotated
3131
+ * AABB center — i.e. `(pose.x + pose.width/2, pose.y + pose.height/2)`,
3132
+ * matching `SceneCanvas.rotateAroundAABBCenter` so the baked geometry
3133
+ * lines up with what the renderer draws.
2586
3134
  *
2587
- * Pose shape is generic, so the compose strategy is too. For the common
2588
- * `{x, y, width, height}` axis-aligned rect, use `composeRectPose` —
2589
- * translation only, child dimensions preserved. Custom pose shapes (paths,
2590
- * matrix transforms) supply their own.
3135
+ * RectPaths can't carry rotation as-is (they're axis-aligned by definition);
3136
+ * a non-zero `pose.rotation` on a rect promotes the result to a polygon so
3137
+ * the four corners are baked into world coords. Callers that need to keep
3138
+ * the rect fast-path can pre-check `pose.rotation` themselves.
2591
3139
  *
2592
- * The inverse — `rebaseLocalPose` — converts a world-space pose into a
2593
- * local pose under a target parent. Used when reparenting so the visual
2594
- * world position of a child is preserved across the parent change.
3140
+ * Used by adapters that need true world geometry — most notably boolean ops,
3141
+ * where operating on the unrotated source path produces wrong shapes.
2595
3142
  */
2596
- /** Re-exported; the declaration lives in `core/scene/types.ts`, which names
2597
- * it and may not import from features. */
2598
3143
 
2599
- /** Minimal adapter needed by `composeWorldPose` and friends — pose lookup plus parent walk. */
2600
- interface PoseAdapter<TPose> {
2601
- getPose(id: string): TPose;
2602
- getParent(id: string): string | null;
2603
- /** Whether `id`'s pose is a frame its children are expressed in. Absent
2604
- * means every node is one. A container whose pose derives from its children
2605
- * is not: its children share its frame, so the fold passes over it. */
2606
- definesFrame?(id: string): boolean;
3144
+ /** Subset of pose fields this helper consumes. Matches the kit's auto-rotate
3145
+ * convention (`SceneCanvas.defaultDrawOne`): `x/y/width/height` define an
3146
+ * AABB whose unrotated center is the rotation pivot. */
3147
+ interface PathInWorldPose {
3148
+ x: number;
3149
+ y: number;
3150
+ width: number;
3151
+ height: number;
3152
+ rotation?: number;
2607
3153
  }
2608
3154
  /**
2609
- * The transforms a `compose` represents **exactly**. A parent transform wider
2610
- * than its strategy's closure is rounded to the nearest pose — for `'rigid'`
2611
- * that means an anisotropically scaled parent turns a rotated child into a
2612
- * parallelogram, which `{x, y, width, height, rotation}` cannot hold, so the
2613
- * shear is dropped.
3155
+ * Project a stored path into the pose's **local frame** — translate (and, for
3156
+ * rects, rebase to the pose's `width`/`height`) so the path's AABB origin sits
3157
+ * at the pose origin. This is translate-only: it does NOT apply
3158
+ * `pose.rotation`. Callers that want the fully world-positioned (rotated) path
3159
+ * should use `pathInWorld`, which composes this with the rotation wrap.
2614
3160
  *
2615
- * Measured over 50,000 random parent/child pairs: rotation and translation
2616
- * compose to within 5.7e-13, anisotropic scale to a right-angle error of 0.99.
2617
- * See `docs/superpowers/specs/2026-09-10-group-as-frame-design.md`.
3161
+ * Rects rebase onto the pose's `width`/`height` because resize updates the pose,
3162
+ * not the stored `RectPath` — so the live size lives on the pose. Honoring it
3163
+ * here keeps this in lockstep with the renderer (`SceneCanvas` paints the rect
3164
+ * at `pose.width/height`); otherwise world-space consumers (slice, booleans,
3165
+ * release-compound) would operate on the stale pre-resize dimensions.
3166
+ *
3167
+ * Used by the local seams: the default painter (paint + silhouette), and as the
3168
+ * building block `pathInWorld`/`findShapeSilhouette` rotate on top of.
2618
3169
  */
2619
- type PoseClosure = 'identity' | 'translation' | 'rigid';
2620
- /** Consumer's pose-composition strategy for hierarchical scenes. `compose`
2621
- * folds a child's pose (in parent's frame) up to the next frame; `decompose`
2622
- * is its inverse. Default is IDENTITY — an absolute-pose scene where every
2623
- * node already stores world coords (parent is grouping-only, no transform). */
2624
- interface PoseComposition<TPose> {
2625
- compose: (parent: TPose, child: TPose) => TPose;
2626
- decompose: (parent: TPose, world: TPose) => TPose;
2627
- closure: PoseClosure;
2628
- }
2629
- /** Default pose-composition strategy: IDENTITY. Both `compose` and
2630
- * `decompose` return the child/world pose unchanged, modeling an
2631
- * absolute-pose scene where every node stores world coords and parents are
2632
- * grouping-only (no transform). With this strategy `composeWorldPose`
2633
- * returns a node's own raw pose and `rebaseLocalPose` is a no-op. */
2634
- declare const IDENTITY_POSE_COMPOSITION: PoseComposition<unknown>;
3170
+ declare function pathInPoseFrame(path: Path, pose: PathInWorldPose): Path;
2635
3171
  /**
2636
- * Walk `id`'s parent chain (root first to id last) and fold local poses into
2637
- * a world pose via `compose`. Returns the world pose for `id`. Cycle-safe:
2638
- * a visited-set guard breaks if the chain ever loops back to itself.
3172
+ * Bake `pose` into `path`'s coordinates so the returned path is positioned
3173
+ * in world space. Returns a fresh `Path` instance; never mutates inputs.
3174
+ */
3175
+ declare function pathInWorld(path: Path, pose: PathInWorldPose): Path;
3176
+ /**
3177
+ * Inverse of `pathInWorld` for a path in **world** space: the unrotated
3178
+ * stored path plus the pose that draws it there. Inverse-rotates about the
3179
+ * pose's AABB center, so the stored path is unrotated and the pose's
3180
+ * `rotation` is preserved, then fits the pose's AABB fields to the result.
3181
+ * The new box's center is placed where the old rotation carries it, since
3182
+ * the pivot moves with the box: `pathInWorld(result.path, result.pose)`
3183
+ * reproduces `worldPath` whether or not its bounds changed.
2639
3184
  *
2640
- * `compose(parent, child)` interprets `child` as expressed *in `parent`'s
2641
- * local frame* and returns the equivalent pose in the next frame up. For a
2642
- * standard translation-only rect: `world = { x: p.x + c.x, y: p.y + c.y,
2643
- * width: c.width, height: c.height }`.
3185
+ * Generic in the pose type so consumer-defined pose fields (including
3186
+ * `rotation`) survive the round-trip. Used by the anchor-edit commit, its
3187
+ * live preview, and the default slice dep.
2644
3188
  */
2645
- declare function composeWorldPose<TPose>(adapter: PoseAdapter<TPose>, id: string, compose: (parent: TPose, child: TPose) => TPose): TPose;
3189
+ declare function worldEditToStorage<P extends PathInWorldPose>(pose: P, worldPath: PolygonPath): {
3190
+ pose: P;
3191
+ path: PolygonPath;
3192
+ };
3193
+ declare function worldEditToStorage<P extends PathInWorldPose>(pose: P, worldPath: Path): {
3194
+ pose: P;
3195
+ path: Path;
3196
+ };
3197
+
2646
3198
  /**
2647
- * Default `compose` for axis-aligned rectangles. Adds translation; preserves
2648
- * child width/height. Treat as the canonical compose for any
2649
- * `{x, y, width, height}` pose under a translation-only hierarchy.
3199
+ * Text as path geometry: the glyph outlines a text node draws, placed in
3200
+ * world space and composed into one `Path`. What "Create Outlines" replaces a
3201
+ * text node with, and what a Boolean op reads when a text node is an operand.
2650
3202
  *
2651
- * Generic over the concrete pose type so callers with a wider pose
2652
- * (e.g. `RectPose & { rotation }`) can pass it through; the extra fields
2653
- * are taken from the child unchanged.
3203
+ * The walk is `layoutRuns`', so the glyphs land exactly where the renderer's
3204
+ * outline tier puts them — same pen positions, same baselines, same synthetic
3205
+ * italic shear — but with the tier forced on for every glyph whatever its
3206
+ * size, and with paint set aside: unfilled text has outlines too.
3207
+ * `textToPathsByPaint` is the same walk, split by the paint each glyph wears.
2654
3208
  */
2655
- declare function composeRectPose<TPose extends RectPose>(parent: TPose, child: TPose): TPose;
3209
+
3210
+ /** The fields of a text node's data that decide its glyph geometry, and the
3211
+ * paint `textToPathsByPaint` splits it by. Paint never changes the geometry. */
3212
+ interface TextOutlineSource {
3213
+ text: string;
3214
+ runs?: readonly StyledRun[];
3215
+ style?: TextStyle;
3216
+ verticalAlign?: TextVerticalAlign;
3217
+ /** The node's `data.fill`: `null` is no fill, absent the default black. */
3218
+ fill?: FillStyle | null;
3219
+ /** The node's `data.stroke`: absent or `null` is no stroke. */
3220
+ stroke?: Stroke | null;
3221
+ }
3222
+ /** One paint's share of a text node's outlines — see {@link textToPathsByPaint}. */
3223
+ interface TextPaintPath {
3224
+ /** The resolved fill these glyphs wear: the run's own, else the node's.
3225
+ * `null` for unfilled text, painted by its stroke alone. */
3226
+ fill: FillStyle | null;
3227
+ /** The resolved stroke — the run's own, else the node's — or absent. */
3228
+ stroke?: Stroke;
3229
+ /** World-space outlines, as {@link textToPath} builds them. */
3230
+ path: PolygonPath;
3231
+ }
3232
+ /** A text node as {@link textToPath} reads it: its data and its pose. */
3233
+ interface TextNodeSource {
3234
+ data: TextOutlineSource;
3235
+ pose: PathInWorldPose;
3236
+ }
3237
+ /** Options for {@link textToPath}. */
3238
+ interface TextToPathOptions {
3239
+ /** The view scale a `{ px }` `fontSize` or `letterSpacing` resolves
3240
+ * against, as for `textCommandFromPose`. Default 1. */
3241
+ scale?: number;
3242
+ }
2656
3243
  /**
2657
- * Translate a `RectPose`-shaped pose by `(dx, dy)`. Suitable as the default
2658
- * `translatePose` for `useMove` when poses carry top-level `x`/`y`. Other
2659
- * fields (width/height, plus any extra props on `TPose`) are preserved.
3244
+ * Why a text node has no outline geometry to give:
3245
+ *
3246
+ * - `'no-outlines'` — the face that serves it has no outlines registered
3247
+ * (`registerFontOutlines`), so there is no geometry to read.
3248
+ * - `'outlines-loading'` — registered but not parsed yet. `loadTextOutlines`
3249
+ * waits for it; the call has already started the load.
3250
+ * - `'outlines-failed'` — registered, and the bytes did not load or parse.
3251
+ * - `'synthetic-bold'` — the requested weight is faked from a lighter face.
3252
+ * The renderer thickens the distance field for that, and a path has no
3253
+ * field to thicken; emboldening geometry needs outline offsetting, which
3254
+ * the kit does not have. Converting would silently lighten the text.
2660
3255
  */
2661
- declare function translateRectPose<TPose extends RectPose>(pose: TPose, dx: number, dy: number): TPose;
3256
+ type TextOutlinesFailure = 'no-outlines' | 'outlines-loading' | 'outlines-failed' | 'synthetic-bold';
3257
+ /** Thrown by {@link textToPath} when some run of the text has no outline
3258
+ * geometry. Names the run's requested face. */
3259
+ declare class TextOutlinesError extends Error {
3260
+ readonly reason: TextOutlinesFailure;
3261
+ readonly family: string;
3262
+ readonly weight: number;
3263
+ readonly style: FontStyle;
3264
+ constructor(reason: TextOutlinesFailure, family: string, weight: number, style: FontStyle, detail: string);
3265
+ }
2662
3266
  /**
2663
- * Convert `worldPose` into a local pose expressed under `newParentId`'s
2664
- * frame. Used when reparenting so the child's visual world position is
2665
- * preserved despite the change of frame. Inverse of one `compose` step.
3267
+ * The outline geometry of a text node, in world space: every glyph and every
3268
+ * underline, strikethrough and overline rule it draws, as one `'nonzero'`
3269
+ * compound path whose filled region is their union. Glyphs keep the font's
3270
+ * curves; overlapping contours are not merged — run the result through
3271
+ * `pathUnion` for that, at the cost of flattening the curves.
2666
3272
  *
2667
- * `decompose(parent, world)` returns the local pose `child` such that
2668
- * `compose(parent, child) === world`. For axis-aligned rects:
2669
- * `child = { ...world, x: world.x - parent.x, y: world.y - parent.y }`.
3273
+ * `pose` is the node's box and rotation. Synthetic italic is sheared exactly
3274
+ * as the renderer shears it. Throws {@link TextOutlinesError} when any run's
3275
+ * face cannot supply outlines — never returns a partial or empty path for
3276
+ * that. Text with no ink (empty, or only spaces) returns an empty path.
3277
+ */
3278
+ declare function textToPath(data: TextOutlineSource, pose: PathInWorldPose, opts?: TextToPathOptions): PolygonPath;
3279
+ /**
3280
+ * {@link textToPath}, split by paint: one path per distinct resolved fill and
3281
+ * stroke, each gathering the glyphs and decoration rules that wear it — a
3282
+ * rule takes the fill of the run it underlines. Groups come in the order
3283
+ * their paint first appears in the text; a paint whose runs put down no ink
3284
+ * has none. Together the paths cover exactly what `textToPath` covers.
2670
3285
  *
2671
- * Pass `newParentId === null` for the root frame; the function returns
2672
- * `worldPose` unchanged.
3286
+ * Paint resolves as the renderer resolves it: a run's `fill` / `stroke`, else
3287
+ * the node's `data.fill` / `data.stroke` from `data`, else the default black
3288
+ * fill and no stroke. Throws as `textToPath` does.
2673
3289
  */
2674
- 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;
2675
- /** Inverse of `composeRectPose` — subtracts parent translation. */
2676
- declare function decomposeRectPose<TPose extends RectPose>(parent: TPose, world: TPose): TPose;
2677
- /**
2678
- * `compose` for a container whose pose defines a **frame**: the child's local
2679
- * pose is offset into the parent's unrotated box, then the whole thing is
2680
- * turned about the parent's center. Rotations add; the child keeps its size.
2681
- *
2682
- * Reduces to `composeRectPose` when the parent is upright, so a scene that
2683
- * never rotates a container behaves identically under either strategy.
2684
- *
2685
- * Exact for translation and rotation. A parent carrying scale is outside what
2686
- * this can express — see `PoseClosure`.
2687
- */
2688
- declare function composeRigidPose<TPose extends RectPose>(parent: TPose, child: TPose): TPose;
2689
- /** Inverse of `composeRigidPose` — un-turns about the parent's center, then
2690
- * subtracts the parent's offset. */
2691
- declare function decomposeRigidPose<TPose extends RectPose>(parent: TPose, world: TPose): TPose;
2692
- /** Translation-only composition over `RectPose`. What a scene wants when a
2693
- * container groups its children but never turns them. */
2694
- declare const RECT_POSE_COMPOSITION: PoseComposition<RectPose>;
2695
- /** Composition over `RectPose` where a container's pose is a frame: rotating
2696
- * the container rotates its contents. */
2697
- declare const RIGID_POSE_COMPOSITION: PoseComposition<RectPose>;
2698
- /**
2699
- * Build a `(id) => world pose | null` callback over a `PoseAdapter`.
2700
- * Convenience for RenderLayers that take a `getPose` callback (selection
2701
- * overlays, debug layers, etc.) so consumers don't hand-write a
2702
- * `composeWorldPose` call per layer.
2703
- *
2704
- * Returns `null` when `adapter.getPose` or `adapter.getParent` throws — the
2705
- * common case is an id removed mid-render between selection state and the
2706
- * next paint. Layers should treat `null` as "skip this id."
2707
- */
2708
- declare function worldPoseLookup<TPose>(adapter: PoseAdapter<TPose>, compose: (parent: TPose, child: TPose) => TPose): (id: string) => TPose | null;
3290
+ declare function textToPathsByPaint(data: TextOutlineSource, pose: PathInWorldPose, opts?: TextToPathOptions): TextPaintPath[];
3291
+ /**
3292
+ * Load the outlines of every face `data` is set in — the requested faces and
3293
+ * the ones they resolve to — so a following {@link textToPath} does not fail
3294
+ * with `'outlines-loading'`. Resolves once each has loaded or failed.
3295
+ */
3296
+ declare function loadTextOutlines(data: TextOutlineSource, opts?: TextToPathOptions): Promise<void>;
3297
+
3298
+ /**
3299
+ * Create Outlines: replace each selected text node with path nodes carrying
3300
+ * its glyph outlines, giving up editability for geometry — the destructive
3301
+ * conversion every vector editor has. One path per paint the text wears; one
3302
+ * undoable batch; the replacement takes the text node's slot, so stacking
3303
+ * order is unchanged.
3304
+ */
3305
+
3306
+ /** What a path minted by Create Outlines must carry — see
3307
+ * {@link CreateOutlinesAdapter.createPathNode}. */
3308
+ interface OutlinePathSpec {
3309
+ /** The fill these glyphs wear, resolved: their run's, else the node's,
3310
+ * else the default text fill. `null` is no fill. */
3311
+ fill: FillStyle | null;
3312
+ /** The stroke they wear, resolved the same way; absent for none. */
3313
+ stroke?: Stroke;
3314
+ /** The parent the path goes under: the text's own, or the container
3315
+ * minted to hold a multi-paint text's paths. */
3316
+ parent: string | null;
3317
+ }
3318
+ /** What `applyCreateOutlines` reads and writes through. */
3319
+ interface CreateOutlinesAdapter {
3320
+ getSelection(): readonly NodeId[] | readonly string[];
3321
+ /** The text node behind `id`, or `undefined` for anything else. */
3322
+ getTextSource(id: NodeId): TextNodeSource | undefined;
3323
+ /**
3324
+ * Mint one path node of text node `sourceId`'s outlines. `path` is in world
3325
+ * space. The node must wear `spec`'s fill and stroke — a text whose runs
3326
+ * differ in paint gets one path per paint — and sit under `spec.parent`.
3327
+ * The kit places it; only the consumer knows its data shape.
3328
+ */
3329
+ createPathNode(path: PolygonPath, sourceId: NodeId, spec: OutlinePathSpec): {
3330
+ id: string;
3331
+ };
3332
+ /**
3333
+ * Mint the container that holds a multi-paint text's paths, under `parent`.
3334
+ * `bounds` is the world envelope of the paths. The kit puts the container in
3335
+ * the text's slot and the paths inside it, in the text's order. Without
3336
+ * this, the paths are laid flat in that slot instead.
3337
+ */
3338
+ createContainerNode?(sourceId: NodeId, spec: {
3339
+ parent: string | null;
3340
+ bounds: Rect;
3341
+ }): {
3342
+ id: string;
3343
+ };
3344
+ /** Full node for `id`, so undo restores the text node whole. Without it the
3345
+ * delete captures an `{ id }` stub. */
3346
+ getNode?(id: string): {
3347
+ id: string;
3348
+ } | undefined | null;
3349
+ /** Parent and sibling order — the reorder contract. With both, each path is
3350
+ * inserted at its text node's index; without, where `insertNode` defaults. */
3351
+ getParent?(id: string): string | null;
3352
+ getChildren?(parentId: string | null): readonly string[];
3353
+ applyOps?(ops: Op[], label?: string): void;
3354
+ setSelection?(ids: NodeId[]): void;
3355
+ insertNode?(node: {
3356
+ id: string;
3357
+ }, index?: number): void;
3358
+ removeNode?(id: string): void;
3359
+ }
3360
+ /** Outcome of {@link applyCreateOutlines}. */
3361
+ type CreateOutlinesResult =
3362
+ /** `resultIds` are what replaced the text nodes at their level — a path,
3363
+ * a container, or a run of flat paths each — which is also what is now
3364
+ * selected in the text nodes' place. */
3365
+ {
3366
+ kind: 'applied';
3367
+ resultIds: string[];
3368
+ }
3369
+ /** Nothing selected is text with ink. */
3370
+ | {
3371
+ kind: 'noop';
3372
+ reason: 'no-text';
3373
+ }
3374
+ /** Some selected text has no outline geometry; nothing was changed. */
3375
+ | {
3376
+ kind: 'failed';
3377
+ reason: 'text-outlines';
3378
+ error: TextOutlinesError;
3379
+ };
3380
+ /**
3381
+ * Convert every text node in the selection to outlines, as one batch labeled
3382
+ * "Create Outlines". Other selected nodes are left alone and stay selected.
3383
+ * All or nothing: if any text node's face cannot supply outlines the scene is
3384
+ * untouched and the error comes back in the result.
3385
+ */
3386
+ declare function applyCreateOutlines(adapter: CreateOutlinesAdapter): CreateOutlinesResult;
2709
3387
 
2710
3388
  /** Boolean op identifiers — five Pathfinder primaries plus Crop. */
2711
3389
  type BooleanOp = 'union' | 'intersect' | 'subtract' | 'exclude' | 'divide' | 'crop';
2712
3390
  /**
2713
3391
  * z-position descriptor for a path node. `parentId` is the direct parent
2714
3392
  * (or `null` for a top-level node); `index` is the position within that
2715
- * parent's child order. Used by the optional `getZOrder` hook below to
2716
- * reposition the result of a boolean op at the topmost source's slot.
3393
+ * parent's child order — never a global render index.
2717
3394
  */
2718
3395
  /** @internal */
2719
3396
  interface BooleanZOrder {
@@ -2722,15 +3399,23 @@ interface BooleanZOrder {
2722
3399
  }
2723
3400
  /** Adapter the hook and the pure core both consume. */
2724
3401
  interface BooleansAdapter {
2725
- getSelection(): NodeId[];
3402
+ getSelection(): readonly NodeId[] | readonly string[];
2726
3403
  getWorldPath(id: NodeId): Path | undefined;
3404
+ /**
3405
+ * Optional: the text node behind `id`, for an id `getWorldPath` has no path
3406
+ * for. Its glyph outlines (`textToPath`) become the operand, so text can be
3407
+ * cut, united or intersected like any shape.
3408
+ */
3409
+ getTextSource?(id: NodeId): TextNodeSource | undefined;
2727
3410
  compareZ(a: NodeId, b: NodeId): number;
2728
3411
  /**
2729
3412
  * Mint a new node from a boolean-op result `Path`. `producedBy` names the
2730
3413
  * op that synthesized it — adapters that store provenance (e.g. for a
2731
- * layer-panel icon) record it; others ignore the arg.
3414
+ * layer-panel icon) record it; others ignore the arg. `sourceId` is the
3415
+ * topmost source, whose slot the result takes: give the node that source's
3416
+ * parent, or the kit's reorder cannot find it there.
2732
3417
  */
2733
- createPathNode(path: Path, producedBy: BooleanOp): {
3418
+ createPathNode(path: Path, producedBy: BooleanOp, sourceId: NodeId): {
2734
3419
  id: string;
2735
3420
  };
2736
3421
  /**
@@ -2745,12 +3430,22 @@ interface BooleansAdapter {
2745
3430
  id: string;
2746
3431
  } | undefined | null;
2747
3432
  /**
2748
- * Optional: return the parent + child-index of `id` so the result of a
2749
- * boolean op can be placed in the topmost source's z-slot. Adapters that
2750
- * also expose `getChildren`/`setChildOrder` (the `ReorderAdapter`
2751
- * contract) will have the kit emit a `createMoveToIndexOp` after the
2752
- * inserts. Adapters that omit this method get v1 behavior — the result
2753
- * lands wherever the adapter's plain `insertNode` defaults to.
3433
+ * Optional: the reorder contract. With `getChildren` (and `getParent`, or
3434
+ * every node reads as top-level) the kit reads each source's slot among its
3435
+ * siblings, and with `setChildOrder` as well it moves the result into the
3436
+ * topmost source's slot. Without them the result lands wherever
3437
+ * `insertNode` defaults to. `defaultCommitAdapter` supplies all three.
3438
+ */
3439
+ getParent?(id: string): string | null;
3440
+ getChildren?(parentId: string | null): readonly string[];
3441
+ setChildOrder?(parentId: string | null, ids: string[]): void;
3442
+ /**
3443
+ * Optional override for the slot the kit otherwise reads through
3444
+ * `getParent` / `getChildren`: `id`'s parent and its index in that
3445
+ * parent's child order.
3446
+ *
3447
+ * @deprecated Supply `getParent` and `getChildren` instead, and the kit
3448
+ * derives this.
2754
3449
  */
2755
3450
  getZOrder?(id: NodeId): BooleanZOrder | undefined;
2756
3451
  applyOps?(ops: Op[], label?: string): void;
@@ -2767,6 +3462,13 @@ type BooleanOpResult = {
2767
3462
  } | {
2768
3463
  kind: 'noop';
2769
3464
  reason: 'no-paths' | 'too-few-for-subtract' | 'empty-result';
3465
+ }
3466
+ /** A text operand had no outline geometry. Nothing was changed: an op that
3467
+ * quietly dropped the operand would commit a different shape than asked. */
3468
+ | {
3469
+ kind: 'failed';
3470
+ reason: 'text-outlines';
3471
+ error: TextOutlinesError;
2770
3472
  };
2771
3473
  /**
2772
3474
  * Run one Boolean operation over the selected paths and commit the result as a
@@ -2844,6 +3546,33 @@ interface ContentHandlerEntry {
2844
3546
  /** Register a content handler. Returns a disposer that removes it. */
2845
3547
  declare function registerContentHandler(entry: ContentHandlerEntry): () => void;
2846
3548
 
3549
+ /**
3550
+ * The lifecycle the ongoing transform actions (`move`, `resize`, `rotate`)
3551
+ * share: what their committed batch is called in history, whether it is
3552
+ * recorded at all, and the callbacks fired as the gesture opens and closes.
3553
+ *
3554
+ * Move and rotate read it from their binding's params; resize reads it from
3555
+ * the `resizePolicy` dep, where the rest of its options already live.
3556
+ */
3557
+
3558
+ /** The lifecycle options, as a binding's params or the resize policy carry
3559
+ * them. */
3560
+ interface GestureLifecycleOptions {
3561
+ /** History label for the committed batch. Unset, the batch takes its first
3562
+ * op's label (a layout drop or a behavior names its own), else the
3563
+ * action's. */
3564
+ label?: string;
3565
+ /** Commit through `scene.untracked`: the edit lands, but no undo entry
3566
+ * records it and the consumer `applyOps` hook is bypassed. Unset, any
3567
+ * behavior's `defaultTransient: true` turns it on. */
3568
+ transient?: boolean;
3569
+ /** Fired once the gesture starts changing poses, with the ids it moves. */
3570
+ onGestureStart?(ids: string[]): void;
3571
+ /** Fired once per `onGestureStart`: `true` when the gesture wrote to the
3572
+ * document, `false` on cancel, abort, or a release with nothing to write. */
3573
+ onGestureEnd?(committed: boolean): void;
3574
+ }
3575
+
2847
3576
  /** Optional consumer seam: given a node and the affine `m` that a pose-transform
2848
3577
  * action applied to the node's POSE, return updated `data` with the node's
2849
3578
  * data-held geometry transformed by `m`, or `null` if this node has no
@@ -2860,6 +3589,10 @@ interface GeometryProjection {
2860
3589
  interface ViewApi {
2861
3590
  get(): View;
2862
3591
  set(v: View): void;
3592
+ /** How this camera's world maps into the world the invocation edits in,
3593
+ * when that is a parallax plane — set by `inPlane` on the view it hands a
3594
+ * wrapped action. Absent or null: the camera's own world. */
3595
+ plane?(): PlaneMap | null;
2863
3596
  /** Optional recenter callback. When wired, `viewportZoomAction`'s `reset`
2864
3597
  * branch (Cmd-0) calls this instead of resetting to identity — letting
2865
3598
  * consumers re-fit the page (or other reference bounds) into the workspace.
@@ -2892,8 +3625,9 @@ interface ViewApi {
2892
3625
  * pass over what the asking view does not paint. */
2893
3626
  layerIsPainted?(layerId: string): boolean;
2894
3627
  }
2895
- /** The part of the asking view a region hit-test consults. */
2896
- type HitTestView = Pick<ViewApi, 'layerIsPainted'>;
3628
+ /** The part of the asking view a region hit-test consults. `get` is its
3629
+ * camera, which a parallax layer is picked through. */
3630
+ type HitTestView = RegionPickView;
2897
3631
  /**
2898
3632
  * Adapter dep for `areaSelectAction`.
2899
3633
  *
@@ -3222,6 +3956,10 @@ interface InsertDep {
3222
3956
  width: number;
3223
3957
  height: number;
3224
3958
  }, extras: InsertExtras): NodeId | null;
3959
+ /** The scene layer `commit` puts the node on. An insert on a layer carrying
3960
+ * `parallax` is dragged out in that plane's world, so `bounds` arrive
3961
+ * there too. Omitted: the camera's world. */
3962
+ layer?(): string;
3225
3963
  }
3226
3964
  /**
3227
3965
  * Adapter dep for `resizeAction`.
@@ -3229,7 +3967,7 @@ interface InsertDep {
3229
3967
  * Carries the behavior-shaping options the legacy `useResize` hook
3230
3968
  * exposed through `UseResizeOptions`: bounds-frame behaviors (e.g.
3231
3969
  * `lockAspectWithModifier`), world-space anchor-point snap behaviors (e.g.
3232
- * `pointSnapToGrid`), and group-expansion (`expandIds`).
3970
+ * `@weasel-js/guides`' `pointSnapToGrid`), and group-expansion (`expandIds`).
3233
3971
  *
3234
3972
  * Optional in `DepSchema`: when absent, `resizeAction` falls back to
3235
3973
  * identity defaults (no behaviors, identity expandIds). Consumers wire the
@@ -3239,7 +3977,7 @@ interface InsertDep {
3239
3977
  * The generic is erased to `unknown` at the schema entry; consumers cast at
3240
3978
  * the call site (mirrors the `scene` entry's convention).
3241
3979
  */
3242
- interface ResizePolicy<TPose> {
3980
+ interface ResizePolicy<TPose> extends GestureLifecycleOptions {
3243
3981
  /** Bounds-frame constraints. Constrained to `TPose extends Bounds` since
3244
3982
  * constraints read/write `{x,y,width,height}`. For non-rect TPose pass `[]`. */
3245
3983
  constraints: TPose extends Bounds ? BoundsConstraint<TPose>[] : never[];
@@ -3261,6 +3999,8 @@ interface LayoutDep {
3261
3999
  /** Which container wins when several contain the drop point. Default
3262
4000
  * `'innermost'`. */
3263
4001
  dropTarget?: LayoutDropTargetMode;
4002
+ /** Carries displaced siblings to their slots over time. Absent, they snap. */
4003
+ reflow?: ReflowTransition<unknown> | null;
3264
4004
  }
3265
4005
  /**
3266
4006
  * Dep for `enterTextEditAction`.
@@ -3307,12 +4047,15 @@ interface ClipboardDep {
3307
4047
  isEmpty(): boolean;
3308
4048
  }
3309
4049
  /**
3310
- * Consumer-supplied commit for the Slice action. `commit` receives the finite
3311
- * slice segment (world coords); the consumer scans the scene, splits crossed
3312
- * paths via `splitPathByLine`, and applies the result as one undoable batch.
4050
+ * The commit behind the Slice action. `commit` receives the cut as a polyline
4051
+ * of at least two points (world coords): the drag's two ends for a straight
4052
+ * cut, its whole trail for a freehand one, the placed points for a
4053
+ * click-by-click one, whose last point equals its first when it closes into
4054
+ * a loop. `<SceneCanvas>` publishes one over its scene (`useSliceDepSource`);
4055
+ * a consumer replaces it with `useSliceDep`.
3313
4056
  */
3314
4057
  interface SliceDep {
3315
- commit(a: Point2, b: Point2): void;
4058
+ commit(cut: ReadonlyArray<Point2>): void;
3316
4059
  }
3317
4060
  /**
3318
4061
  * The names an action may declare in `requires`, and what each resolves to.
@@ -3320,7 +4063,7 @@ interface SliceDep {
3320
4063
  * This is the whole vocabulary of things an action can reach — selection,
3321
4064
  * scene, view, history, and the rest. The interface itself is declared empty
3322
4065
  * in `@weasel-js/routing`, which knows that an action names its dependencies
3323
- * but not what any of them are; these 24 entries are the kit's, merged in from
4066
+ * but not what any of them are; these entries are the kit's, merged in from
3324
4067
  * outside exactly the way a consumer merges its own
3325
4068
  * (`declare module '@weasel-js/core'`).
3326
4069
  */
@@ -3372,6 +4115,12 @@ declare module '@weasel-js/routing' {
3372
4115
  * absent means no snapping (identity).
3373
4116
  */
3374
4117
  snap?: SnapDep;
4118
+ /**
4119
+ * The canvas's debug sink — the one tools reach as `ToolCtx.debug`.
4120
+ * Sourced by `<SceneCanvas>`; absent while its `debug` overlay is off.
4121
+ * Actions report what they did here, and the overlay draws it.
4122
+ */
4123
+ debug?: DebugSink;
3375
4124
  /**
3376
4125
  * Lasso-select dep — polygon hit-test + selection read/write.
3377
4126
  *
@@ -3428,6 +4177,13 @@ declare module '@weasel-js/routing' {
3428
4177
  * invoker reads `deps.booleansAdapter` to execute the op.
3429
4178
  */
3430
4179
  booleansAdapter?: BooleansAdapter;
4180
+ /**
4181
+ * Create Outlines adapter — read selection ids, resolve text nodes, and
4182
+ * mint the path nodes that replace them. Consumers wire it with
4183
+ * `useCreateOutlinesAdapter(adapter)`; the `createOutlines` action reads it
4184
+ * in both its `enabled` predicate and its invoker.
4185
+ */
4186
+ createOutlinesAdapter?: CreateOutlinesAdapter;
3431
4187
  /**
3432
4188
  * Gesture dispatcher control surface — exposes `cancelAll(reason)` so
3433
4189
  * actions that need to abort an in-flight handle (Escape cancels a
@@ -3443,11 +4199,8 @@ declare module '@weasel-js/routing' {
3443
4199
  */
3444
4200
  layout?: LayoutDep;
3445
4201
  /**
3446
- * Slice dep — consumer-supplied commit for the Slice action.
3447
- *
3448
- * Receives the finite slice segment in world coordinates; the consumer
3449
- * scans the scene, splits crossed paths via `splitPathByLine`, and
3450
- * applies the result as one undoable batch.
4202
+ * Slice dep — the commit for the Slice action. `<SceneCanvas>` publishes
4203
+ * `useSliceDepSource`; a consumer overrides it with `useSliceDep`.
3451
4204
  *
3452
4205
  * Optional: when absent, `sliceAction` is a no-op.
3453
4206
  */
@@ -3510,8 +4263,48 @@ declare module '@weasel-js/routing' {
3510
4263
  * by every surface under one `<PointerContextProvider>`.
3511
4264
  */
3512
4265
  pointer?: PointerContextValue;
4266
+ /**
4267
+ * The touch or pen long-press being held, if any: where, since when, how
4268
+ * far through, and whether any binding would fire on it. Sourced by
4269
+ * `<SceneCanvas>` from its gesture dispatcher; press feedback reads it.
4270
+ */
4271
+ longPress?: LongPressState;
4272
+ }
4273
+ }
4274
+
4275
+ /**
4276
+ * The routing types that carry an overlay, bound to the kit's `RenderLayer`.
4277
+ *
4278
+ * `@weasel-js/routing` never reads an overlay — it collects the live ones and
4279
+ * hands them back in scope order — so it leaves the element type open. What a
4280
+ * weasel canvas draws is a `RenderLayer`, and every kit call site should see
4281
+ * that rather than `unknown`, so core binds the parameter once, here, and
4282
+ * re-exports these names under the ones they have always had.
4283
+ */
4284
+
4285
+ /** What a canvas overlay is, at this layer. */
4286
+ type Overlay = RenderLayer<unknown>;
4287
+ declare module '@weasel-js/routing' {
4288
+ interface OverlaySchema {
4289
+ overlay: RenderLayer<unknown>;
3513
4290
  }
3514
4291
  }
4292
+ /** Routing's `Contribution`, with overlays typed as `RenderLayer`. */
4293
+ type Contribution = Contribution$1<Overlay>;
4294
+ /** Routing's `ContributionChrome`, with overlays typed as `RenderLayer`. */
4295
+ type ContributionChrome = ContributionChrome$1<Overlay>;
4296
+ /** Routing's `Tool`, with overlays typed as `RenderLayer`. */
4297
+ type Tool<TScratch = unknown> = Tool$1<TScratch, Overlay>;
4298
+ /** A `Tool` of any scratch type: the element type for a list of mixed tools. */
4299
+ type AnyTool = AnyToolOf<Overlay>;
4300
+ /** Routing's `ToolDef` (what `defineTool` takes), with overlays typed as `RenderLayer`. */
4301
+ type ToolDef<TScratch = void> = ToolDef$1<TScratch, Overlay>;
4302
+ /** Routing's `ToolsApi`, with overlays typed as `RenderLayer`. */
4303
+ type ToolsApi = ToolsApi$1<Overlay>;
4304
+ /** Routing's `UseToolsOptions`, with overlays typed as `RenderLayer`. */
4305
+ type UseToolsOptions = UseToolsOptions$1<Overlay>;
4306
+ /** Routing's `useTools`, typed for `RenderLayer` overlays. */
4307
+ declare const useTools: (opts: UseToolsOptions) => ToolsApi;
3515
4308
 
3516
4309
  /** Options for stroke tessellation. */
3517
4310
  interface StrokeOptions {
@@ -3572,4 +4365,4 @@ declare function vignette({ amount, feather }: {
3572
4365
  feather?: number;
3573
4366
  }): Effect[];
3574
4367
 
3575
- export { type DerivedDep as $, type SliceDep as A, type VertexColorChannel as B, type CullRect as C, type DrawCommand as D, type Effect as E, type InsertExtras as F, type GlMat3 as G, type SerializedScene as H, IDENTITY_COLOR_MATRIX as I, type GeometryProjection as J, type ContentHandlerEntry as K, type SvgIngestOptions as L, type Mesh as M, type Node as N, type PanBounds as O, type PathDrawCommand as P, type Animator as Q, type RenderTarget as R, SPRITE_STRIDE as S, type TextDrawCommand as T, ColorOverrideRegistry as U, type ViewAnimationOptions as V, WeaselRenderer as W, type UseSceneOptions as X, type SceneRegistry as Y, type RegisteredOp as Z, type PoseOverrides as _, type GroupDrawCommand as a, type StaggerDelay as a$, type ViewportDims as a0, type ViewApi as a1, ShaderProgram as a2, type BooleansAdapter as a3, type UseAnimatorOptions as a4, type SpringPresetName as a5, type EasingSpec as a6, type AnimationHandle as a7, type SampledTrack as a8, type AddLayerSpec as a9, type InterpolatorFactory as aA, type Keyframe as aB, type LassoSelectDep as aC, type LayerRecord as aD, type LayoutDep as aE, type LeafNode as aF, type LoopFactory as aG, type LoopOptions as aH, type NestedTimeline as aI, type NodeAtPointDep as aJ, type PhysicsHandle as aK, type PhysicsOptions as aL, PointerContextProvider as aM, type PointerContextValue as aN, type PointerWorldPos as aO, type PoseAdapter as aP, type PoseClosure as aQ, type PoseOverride as aR, RECT_POSE_COMPOSITION as aS, RIGID_POSE_COMPOSITION as aT, type ResizePolicy as aU, SPRING_PRESETS as aV, type SerializedNode as aW, type SnapDep as aX, type SpringOptions as aY, type SpringPreset as aZ, type StaggerBuilder as a_, type AddNodeSpec as aa, type AnimateToBoundsOptions as ab, type AreaSelectDep as ac, type BezierEasing as ad, type BooleanOp as ae, type BooleanOpResult as af, type ClipboardDep as ag, type ClipboardIngestCtx as ah, type ColorOverride as ai, type ColorOverrideFn as aj, type ContainerNode as ak, type DecayLoopConfig as al, type DecayOptions as am, EASINGS as an, type EasingFn as ao, type EasingName as ap, type EditAnchorsDep as aq, type EventBooking as ar, type EventBookingHandle as as, type EventTrack as at, type FitViewToBoundsOptions as au, IDENTITY_POSE_COMPOSITION as av, type IngestCtx as aw, type IngestionDep as ax, type InsertDep as ay, type Interpolate as az, type ImageDrawCommand as b, fitViewToBounds as b$, type StaggerFactory as b0, type StaggerOptions as b1, type StaggerPerItem as b2, type StaggerSpringPoseOptions as b3, type StaggerTweenOptions as b4, type SvgUnpacker as b5, type SystemLayerRecord as b6, type SystemLayerSpec as b7, type TextEditDep as b8, type TimelineClock as b9, easeInExpo as bA, easeInOut as bB, easeInOutBack as bC, easeInOutBounce as bD, easeInOutCirc as bE, easeInOutCubic as bF, easeInOutElastic as bG, easeInOutExpo as bH, easeInOutQuad as bI, easeInOutQuart as bJ, easeInOutQuint as bK, easeInOutSine as bL, easeInQuad as bM, easeInQuart as bN, easeInQuint as bO, easeInSine as bP, easeOut as bQ, easeOutBack as bR, easeOutBounce as bS, easeOutCirc as bT, easeOutCubic as bU, easeOutElastic as bV, easeOutExpo as bW, easeOutQuad as bX, easeOutQuart as bY, easeOutQuint as bZ, easeOutSine as b_, type TimelineEvent as ba, type TimelineHandle as bb, type TimelineOptions as bc, type TimelineTrack as bd, type Track as be, type TweenLoopOptions as bf, type TweenOptions as bg, type UserLayerRecord as bh, VIEW_ANIMATION_KEY as bi, type ViewAnimationApi as bj, type ViewChannel as bk, applyBooleanOp as bl, asNodeId as bm, composeRectPose as bn, composeRigidPose as bo, composeWorldPose as bp, createPointerStore as bq, cubicBezierEasing as br, decomposeRectPose as bs, decomposeRigidPose as bt, easeIn as bu, easeInBack as bv, easeInBounce as bw, easeInCirc as bx, easeInCubic as by, easeInElastic as bz, type ImageMinification as c, linear as c0, rebaseLocalPose as c1, registerContentHandler as c2, resolveEasing as c3, resolveStrokeWidth as c4, translateRectPose as c5, useDecayLoop as c6, usePointerContext as c7, usePointerPosition as c8, useViewAnimation as c9, useViewAnimationOn as ca, worldPoseLookup as cb, ShaderCompileError as d, type ShaderDrawCommand as e, type ShaderProgramHandle as f, type ShaderUniform as g, type SolidPaint as h, type SpriteSheet as i, type SpritesDrawCommand as j, type StrokeOptions as k, type WeaselRendererOptions as l, blur as m, buildGradientRamp as n, cullDrawCommands as o, frameRect as p, mat3 as q, registerEffect as r, registerProgram as s, tessellateStroke as t, vignette as u, viewToMat3 as v, type Scene as w, type RectPose as x, type InertiaConfig as y, type PoseComposition as z };
4368
+ export { type SvgIngestOptions as $, type PoseComposition as A, type PoseAdapter as B, type CullRect as C, type DrawCommand as D, type Effect as E, type GestureLifecycleOptions as F, type GroupDrawCommand as G, type SliceDep as H, IDENTITY_COLOR_MATRIX as I, type ToolsApi as J, type Tool as K, type Contribution as L, type LayerHit as M, type Node as N, type ChromeState as O, type PathDrawCommand as P, type VertexColorChannel as Q, type RenderOptions as R, SPRITE_STRIDE as S, type TextDrawCommand as T, type LayerGroup as U, type ViewAnimationOptions as V, WeaselRenderer as W, type InsertExtras as X, type SerializedScene as Y, type GeometryProjection as Z, type ContentHandlerEntry as _, type ImageDrawCommand as a, type LayoutMove as a$, type AnyTool as a0, type PanBounds as a1, type Animator as a2, ColorOverrideRegistry as a3, type UseSceneOptions as a4, type SceneRegistry as a5, type RegisteredOp as a6, type PoseOverrides as a7, type DerivedDep as a8, type ViewportDims as a9, type ContainerNode as aA, type ContributionChrome as aB, type CreateOutlinesResult as aC, type CustomPaintContext as aD, type DecayLoopConfig as aE, type DecayOptions as aF, type DerivePathFn as aG, type EditAnchorsDep as aH, type EventBooking as aI, type EventBookingHandle as aJ, type EventTrack as aK, type FitViewToBoundsOptions as aL, type HitTestView as aM, IDENTITY_POSE_COMPOSITION as aN, type IngestCtx as aO, type IngestionDep as aP, type InsertDep as aQ, type Interpolate as aR, type InterpolatorFactory as aS, type Keyframe as aT, type LassoSelectDep as aU, type LayerCommandCache as aV, type LayerDrawFailure as aW, type LayerDrawSpan as aX, type LayerRecord as aY, type LayoutDep as aZ, type LayoutFrame as a_, type ViewApi as aa, type Affordance as ab, type AffordanceRegion as ac, type AffordanceBinding as ad, type CommonAffordanceScratch as ae, type DerivePoseFn as af, type BooleansAdapter as ag, type CreateOutlinesAdapter as ah, type UseAnimatorOptions as ai, type AnimationHandle as aj, type SampledTrack as ak, type SceneArrivalHandler as al, type AddLayerSpec as am, type AddNodeSpec as an, type AnimateToBoundsOptions as ao, type AnimationInfo as ap, type AnimationKind as aq, type AnimatorEvent as ar, type AnimatorListener as as, type AreaSelectDep as at, type BooleanOp as au, type BooleanOpResult as av, type ClipboardDep as aw, type ClipboardIngestCtx as ax, type ColorOverride as ay, type ColorOverrideFn as az, type ImageMinification as b, loadTextOutlines as b$, type LeafNode as b0, type LiveAnimation as b1, type LoopFactory as b2, type LoopOptions as b3, type NestedTimeline as b4, type NodeAtPointDep as b5, type OutlinePathSpec as b6, type Overlay as b7, type PathInWorldPose as b8, type PhysicsHandle as b9, type TextPaintPath as bA, type TextToPathOptions as bB, type TimelineClock as bC, type TimelineEvent as bD, type TimelineHandle as bE, type TimelineOptions as bF, type TimelineTrack as bG, type ToolDef as bH, type Track as bI, type TweenLoopOptions as bJ, type TweenOptions as bK, type UseToolsOptions as bL, type UserLayerRecord as bM, VIEW_ANIMATION_KEY as bN, type ViewAnimationApi as bO, type ViewChannel as bP, applyBooleanOp as bQ, applyCreateOutlines as bR, asNodeId as bS, composeWorldPose as bT, createPointerStore as bU, depsUnchanged as bV, drawLayers as bW, drawOneLayer as bX, fitViewToBounds as bY, isLayerPainted as bZ, isLayerVisible as b_, type PhysicsOptions as ba, PointerContextProvider as bb, type PointerContextValue as bc, type PointerWorldPos as bd, type PoseClosure as be, type PoseOverride as bf, type ResizePolicy as bg, type SerializedLayer as bh, type SerializedNode as bi, type SnapDep as bj, type SpringOptions as bk, type StaggerBuilder as bl, type StaggerDelay as bm, type StaggerFactory as bn, type StaggerOptions as bo, type StaggerPerItem as bp, type StaggerSpringPoseOptions as bq, type StaggerTweenOptions as br, type SvgUnpacker as bs, type SystemLayerRecord as bt, type SystemLayerSpec as bu, type TextEditDep as bv, type TextNodeSource as bw, type TextOutlineSource as bx, TextOutlinesError as by, type TextOutlinesFailure as bz, type RenderSpan as c, pathInPoseFrame as c0, pathInWorld as c1, rebaseLocalPose as c2, registerContentHandler as c3, resolveStrokeWidth as c4, subscribeToSources as c5, textToPath as c6, textToPathsByPaint as c7, useDecayLoop as c8, usePointerContext as c9, usePointerPosition as ca, useTools as cb, useViewAnimation as cc, useViewAnimationOn as cd, worldEditToStorage as ce, type RenderSpanStats as d, type RenderStats as e, type RenderTarget as f, type ShaderDrawCommand as g, type SolidPaint as h, type SpriteSheet as i, type SpritesDrawCommand as j, type StrokeOptions as k, type WeaselRendererOptions as l, blur as m, buildGradientRamp as n, cullDrawCommands as o, frameRect as p, vignette as q, registerEffect as r, type RenderLayer as s, tessellateStroke as t, type Dims as u, viewToMat3 as v, type RedrawSource as w, type Scene as x, type RectPose as y, type InertiaConfig as z };