@weasel-js/core 1.11.0 → 1.11.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 (365) hide show
  1. package/CHANGELOG.md +427 -0
  2. package/README.md +1 -1
  3. package/dist/animation/index.js +3 -3
  4. package/dist/animation/rig/bindRig.js +1 -1
  5. package/dist/animation/rig/rigNode.js.map +1 -1
  6. package/dist/barrel/canvas.js +7 -3
  7. package/dist/barrel/interactions.js +5 -4
  8. package/dist/barrel/paths.js +3 -3
  9. package/dist/barrel/renderer.js +3 -2
  10. package/dist/barrel/routing.js +6 -11
  11. package/dist/barrel/scene.js +8 -5
  12. package/dist/barrel/viewport.js +4 -3
  13. package/dist/canvas/Canvas.js +3 -1
  14. package/dist/canvas/Canvas.js.map +1 -1
  15. package/dist/canvas/SceneCanvas/SceneCanvasInput.js +17 -3
  16. package/dist/canvas/SceneCanvas/SceneCanvasInput.js.map +1 -1
  17. package/dist/canvas/SceneCanvas/builtinToolSets.js +30 -0
  18. package/dist/canvas/SceneCanvas/builtinToolSets.js.map +1 -0
  19. package/dist/canvas/SceneCanvas/canvasPassThrough.js +1 -0
  20. package/dist/canvas/SceneCanvas/canvasPassThrough.js.map +1 -1
  21. package/dist/canvas/SceneCanvas/coordTrace.js +5 -16
  22. package/dist/canvas/SceneCanvas/coordTrace.js.map +1 -1
  23. package/dist/canvas/SceneCanvas/defaultNodeProperties.js +5 -0
  24. package/dist/canvas/SceneCanvas/defaultNodeProperties.js.map +1 -1
  25. package/dist/canvas/SceneCanvas/features.js +45 -5
  26. package/dist/canvas/SceneCanvas/features.js.map +1 -1
  27. package/dist/canvas/SceneCanvas/props.js +1 -11
  28. package/dist/canvas/SceneCanvas/props.js.map +1 -1
  29. package/dist/canvas/SceneCanvas/toolRegistry.js +8 -4
  30. package/dist/canvas/SceneCanvas/toolRegistry.js.map +1 -1
  31. package/dist/canvas/SceneCanvas/useActionsPropResolver.js +1 -11
  32. package/dist/canvas/SceneCanvas/useActionsPropResolver.js.map +1 -1
  33. package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js.map +1 -1
  34. package/dist/canvas/SceneCanvas/useBuiltinTools.js +2 -9
  35. package/dist/canvas/SceneCanvas/useBuiltinTools.js.map +1 -1
  36. package/dist/canvas/SceneCanvas/useCanvasDevtoolsRoot.js +93 -0
  37. package/dist/canvas/SceneCanvas/useCanvasDevtoolsRoot.js.map +1 -0
  38. package/dist/canvas/SceneCanvas/useCanvasSelection.js +7 -2
  39. package/dist/canvas/SceneCanvas/useCanvasSelection.js.map +1 -1
  40. package/dist/canvas/SceneCanvas/useCanvasTools.js +8 -8
  41. package/dist/canvas/SceneCanvas/useCanvasTools.js.map +1 -1
  42. package/dist/canvas/SceneCanvas/useNodeKinds.js +1 -1
  43. package/dist/canvas/SceneCanvas/useNodeKinds.js.map +1 -1
  44. package/dist/canvas/SceneCanvas/useSceneCanvasLayers.js +13 -2
  45. package/dist/canvas/SceneCanvas/useSceneCanvasLayers.js.map +1 -1
  46. package/dist/canvas/SceneCanvas/useSceneCanvasTools.js +1 -3
  47. package/dist/canvas/SceneCanvas/useSceneCanvasTools.js.map +1 -1
  48. package/dist/canvas/SceneCanvas/useSceneChrome.js +6 -7
  49. package/dist/canvas/SceneCanvas/useSceneChrome.js.map +1 -1
  50. package/dist/canvas/SceneCanvas/useSceneGestureDispatcher.js +5 -3
  51. package/dist/canvas/SceneCanvas/useSceneGestureDispatcher.js.map +1 -1
  52. package/dist/canvas/SceneCanvas/useScenePicking.js +2 -3
  53. package/dist/canvas/SceneCanvas/useScenePicking.js.map +1 -1
  54. package/dist/canvas/SceneCanvas/useSceneSelectTool.js +2 -1
  55. package/dist/canvas/SceneCanvas/useSceneSelectTool.js.map +1 -1
  56. package/dist/canvas/SceneCanvas/useSceneStandardActions.js +3 -4
  57. package/dist/canvas/SceneCanvas/useSceneStandardActions.js.map +1 -1
  58. package/dist/canvas/SceneCanvas.js +16 -14
  59. package/dist/canvas/SceneCanvas.js.map +1 -1
  60. package/dist/canvas/SurfaceCanvas.js +5 -22
  61. package/dist/canvas/SurfaceCanvas.js.map +1 -1
  62. package/dist/canvas/canvasRenderer.js +9 -5
  63. package/dist/canvas/canvasRenderer.js.map +1 -1
  64. package/dist/canvas/contextAttributes.js +14 -0
  65. package/dist/canvas/contextAttributes.js.map +1 -0
  66. package/dist/canvas/deps/editAnchors.js +9 -113
  67. package/dist/canvas/deps/editAnchors.js.map +1 -1
  68. package/dist/canvas/deps/insert.js +4 -2
  69. package/dist/canvas/deps/insert.js.map +1 -1
  70. package/dist/canvas/deps/pathEditCommits.js +193 -0
  71. package/dist/canvas/deps/pathEditCommits.js.map +1 -0
  72. package/dist/canvas/deps/snap.js +12 -9
  73. package/dist/canvas/deps/snap.js.map +1 -1
  74. package/dist/canvas/deps/transformFollowers.js +20 -0
  75. package/dist/canvas/deps/transformFollowers.js.map +1 -0
  76. package/dist/canvas/derivedPath.js +20 -1
  77. package/dist/canvas/derivedPath.js.map +1 -1
  78. package/dist/canvas/drawnBounds.js +29 -3
  79. package/dist/canvas/drawnBounds.js.map +1 -1
  80. package/dist/canvas/nodeShapes/derivedPainter.js +9 -1
  81. package/dist/canvas/nodeShapes/derivedPainter.js.map +1 -1
  82. package/dist/canvas/nodeShapes/pathPainter.js +3 -2
  83. package/dist/canvas/nodeShapes/pathPainter.js.map +1 -1
  84. package/dist/canvas/nodeShapes/shapePainter.js +1 -1
  85. package/dist/canvas/overlayRoleStrokes.js +12 -0
  86. package/dist/canvas/overlayRoleStrokes.js.map +1 -1
  87. package/dist/canvas/pathOverlay.js +27 -7
  88. package/dist/canvas/pathOverlay.js.map +1 -1
  89. package/dist/canvas/renderDebugSnapshot.js +1 -0
  90. package/dist/canvas/renderDebugSnapshot.js.map +1 -1
  91. package/dist/canvas/renderSceneToPixels.js +6 -5
  92. package/dist/canvas/renderSceneToPixels.js.map +1 -1
  93. package/dist/canvas/sceneAdapter.js.map +1 -1
  94. package/dist/canvas/useCanvasPaint.js +2 -1
  95. package/dist/canvas/useCanvasPaint.js.map +1 -1
  96. package/dist/canvas/useInFlightBounds.js +52 -0
  97. package/dist/canvas/useInFlightBounds.js.map +1 -0
  98. package/dist/canvas/useViewHelpers.js +7 -9
  99. package/dist/canvas/useViewHelpers.js.map +1 -1
  100. package/dist/clipboard.d.ts +3 -2
  101. package/dist/{clone-DZDrfIlU.d.ts → clone-C3e0OTuF.d.ts} +8 -21
  102. package/dist/clone.d.ts +4 -3
  103. package/dist/core/geometry/autoPoseDescriptor.js +1 -1
  104. package/dist/core/ops/setDependsOn.js +37 -0
  105. package/dist/core/ops/setDependsOn.js.map +1 -0
  106. package/dist/core/ops/writtenBy.js +53 -0
  107. package/dist/core/ops/writtenBy.js.map +1 -0
  108. package/dist/core/pages/fitViewToPage.js +12 -1
  109. package/dist/core/pages/fitViewToPage.js.map +1 -1
  110. package/dist/core/pages/pageEdits.js +164 -0
  111. package/dist/core/pages/pageEdits.js.map +1 -0
  112. package/dist/core/pages/pages.js +30 -1
  113. package/dist/core/pages/pages.js.map +1 -1
  114. package/dist/core/scene/NodeRouting.js +8 -3
  115. package/dist/core/scene/NodeRouting.js.map +1 -1
  116. package/dist/core/scene/arrivalWindow.js.map +1 -1
  117. package/dist/core/scene/carryDescendants.js +51 -0
  118. package/dist/core/scene/carryDescendants.js.map +1 -0
  119. package/dist/core/scene/docValues.js +57 -0
  120. package/dist/core/scene/docValues.js.map +1 -0
  121. package/dist/core/scene/editPass.js +111 -0
  122. package/dist/core/scene/editPass.js.map +1 -0
  123. package/dist/core/scene/effectivePose.js +7 -1
  124. package/dist/core/scene/effectivePose.js.map +1 -1
  125. package/dist/core/scene/fieldEdits.js +4 -1
  126. package/dist/core/scene/fieldEdits.js.map +1 -1
  127. package/dist/core/scene/historyFacade.js +1 -0
  128. package/dist/core/scene/historyFacade.js.map +1 -1
  129. package/dist/core/scene/layoutPass.js +28 -3
  130. package/dist/core/scene/layoutPass.js.map +1 -1
  131. package/dist/core/scene/recorder.js +28 -19
  132. package/dist/core/scene/recorder.js.map +1 -1
  133. package/dist/core/scene/scene.js +15 -9
  134. package/dist/core/scene/scene.js.map +1 -1
  135. package/dist/core/scene/sceneChanges.js +13 -0
  136. package/dist/core/scene/sceneChanges.js.map +1 -0
  137. package/dist/core/scene/sceneEdits.js +8 -1
  138. package/dist/core/scene/sceneEdits.js.map +1 -1
  139. package/dist/core/scene/sceneMutators.js +1 -0
  140. package/dist/core/scene/sceneMutators.js.map +1 -1
  141. package/dist/core/scene/sceneRecording.js +20 -3
  142. package/dist/core/scene/sceneRecording.js.map +1 -1
  143. package/dist/core/scene/sceneSelection.js +4 -1
  144. package/dist/core/scene/sceneSelection.js.map +1 -1
  145. package/dist/core/scene/sceneState.js +11 -5
  146. package/dist/core/scene/sceneState.js.map +1 -1
  147. package/dist/core/scene/serialization.js +5 -3
  148. package/dist/core/scene/serialization.js.map +1 -1
  149. package/dist/core/scene/types.js.map +1 -1
  150. package/dist/core/scene/unitScopes.js +19 -1
  151. package/dist/core/scene/unitScopes.js.map +1 -1
  152. package/dist/core/selection/usePublishSceneSelection.js +6 -12
  153. package/dist/core/selection/usePublishSceneSelection.js.map +1 -1
  154. package/dist/core/shapeKinds.js +25 -11
  155. package/dist/core/shapeKinds.js.map +1 -1
  156. package/dist/{cornerHandles-Camw_yeu.d.ts → cornerHandles-BHuoMs1o.d.ts} +1 -1
  157. package/dist/debug/createDebugOverlayLayer.js +16 -111
  158. package/dist/debug/createDebugOverlayLayer.js.map +1 -1
  159. package/dist/debug/createDebugSink.js +2 -1
  160. package/dist/debug/createDebugSink.js.map +1 -1
  161. package/dist/debug/defaultTheme.js +4 -2
  162. package/dist/debug/defaultTheme.js.map +1 -1
  163. package/dist/debug/features.js +17 -0
  164. package/dist/debug/features.js.map +1 -0
  165. package/dist/debug/overlayPanels.js +117 -0
  166. package/dist/debug/overlayPanels.js.map +1 -0
  167. package/dist/debug/parseDebugFlags.js +4 -13
  168. package/dist/debug/parseDebugFlags.js.map +1 -1
  169. package/dist/{depSchema-Cgfu_G9s.d.ts → depSchema-BpZNOv7q.d.ts} +114 -892
  170. package/dist/devtools/handlers.js +112 -0
  171. package/dist/devtools/handlers.js.map +1 -0
  172. package/dist/devtools/history.js +71 -0
  173. package/dist/devtools/history.js.map +1 -0
  174. package/dist/devtools/hook.js +74 -0
  175. package/dist/devtools/hook.js.map +1 -0
  176. package/dist/devtools/label.js +25 -0
  177. package/dist/devtools/label.js.map +1 -0
  178. package/dist/devtools/notices.js +58 -0
  179. package/dist/devtools/notices.js.map +1 -0
  180. package/dist/devtools/protocol.js +7 -0
  181. package/dist/devtools/protocol.js.map +1 -0
  182. package/dist/devtools/registry.js +90 -0
  183. package/dist/devtools/registry.js.map +1 -0
  184. package/dist/devtools/root.js +80 -0
  185. package/dist/devtools/root.js.map +1 -0
  186. package/dist/devtools/serialize.js +86 -0
  187. package/dist/devtools/serialize.js.map +1 -0
  188. package/dist/devtools/session.js +111 -0
  189. package/dist/devtools/session.js.map +1 -0
  190. package/dist/devtools/transport.js +67 -0
  191. package/dist/devtools/transport.js.map +1 -0
  192. package/dist/devtools/useDevtoolsRoot.js +81 -0
  193. package/dist/devtools/useDevtoolsRoot.js.map +1 -0
  194. package/dist/devtools-protocol.d.ts +435 -0
  195. package/dist/devtools-protocol.js +7 -0
  196. package/dist/devtools.d.ts +8 -0
  197. package/dist/devtools.js +12 -0
  198. package/dist/devtools.js.map +1 -0
  199. package/dist/features/chrome-caps/useHoverTracking.js +16 -10
  200. package/dist/features/chrome-caps/useHoverTracking.js.map +1 -1
  201. package/dist/features/ingestion/contentHandlers.js +25 -2
  202. package/dist/features/ingestion/contentHandlers.js.map +1 -1
  203. package/dist/features/measure/measureCommands.js +7 -5
  204. package/dist/features/measure/measureCommands.js.map +1 -1
  205. package/dist/features/paths/index.js +2 -2
  206. package/dist/features/paths/pathEditExtension.js.map +1 -1
  207. package/dist/features/paths/pathSnap/pathSnapSource.js +5 -5
  208. package/dist/features/paths/pathSnap/pathSnapSource.js.map +1 -1
  209. package/dist/features/paths/pathSnap/sceneIndex.js +10 -3
  210. package/dist/features/paths/pathSnap/sceneIndex.js.map +1 -1
  211. package/dist/features/selection/selectionPose.js +4 -1
  212. package/dist/features/selection/selectionPose.js.map +1 -1
  213. package/dist/features/snap/gather.js +9 -1
  214. package/dist/features/snap/gather.js.map +1 -1
  215. package/dist/features/snap/lazySession.js +17 -0
  216. package/dist/features/snap/lazySession.js.map +1 -0
  217. package/dist/features/snap/marks.js.map +1 -1
  218. package/dist/features/snap/probes2d.js +27 -19
  219. package/dist/features/snap/probes2d.js.map +1 -1
  220. package/dist/features/snap/readoutLayer.js.map +1 -1
  221. package/dist/features/snap/roles.js +2 -1
  222. package/dist/features/snap/roles.js.map +1 -1
  223. package/dist/features/snap/rotationSource.js +25 -8
  224. package/dist/features/snap/rotationSource.js.map +1 -1
  225. package/dist/features/snap/sceneSession2d.js +6 -4
  226. package/dist/features/snap/sceneSession2d.js.map +1 -1
  227. package/dist/features/snap/session2d.js +37 -23
  228. package/dist/features/snap/session2d.js.map +1 -1
  229. package/dist/features/snap/spanSnap.js +5 -2
  230. package/dist/features/snap/spanSnap.js.map +1 -1
  231. package/dist/icons.table.js +1 -1
  232. package/dist/icons.table.js.map +1 -1
  233. package/dist/icons.table.json +0 -10
  234. package/dist/index.d.ts +701 -696
  235. package/dist/index.js +35 -29
  236. package/dist/interactions/actions/align/action.js +6 -4
  237. package/dist/interactions/actions/align/action.js.map +1 -1
  238. package/dist/interactions/actions/align/align.js.map +1 -1
  239. package/dist/interactions/actions/booleans/action.js +7 -1
  240. package/dist/interactions/actions/booleans/action.js.map +1 -1
  241. package/dist/interactions/actions/clone/action.js +1 -1
  242. package/dist/interactions/actions/clone/behaviors.js +4 -4
  243. package/dist/interactions/actions/clone/behaviors.js.map +1 -1
  244. package/dist/interactions/actions/defaults/bendSegment.js +1 -1
  245. package/dist/interactions/actions/defaults/bendSegment.js.map +1 -1
  246. package/dist/interactions/actions/defaults/createPaintAction.js +1 -1
  247. package/dist/interactions/actions/defaults/delete.js +48 -39
  248. package/dist/interactions/actions/defaults/delete.js.map +1 -1
  249. package/dist/interactions/actions/defaults/duplicate.js +1 -1
  250. package/dist/interactions/actions/defaults/group.js +2 -2
  251. package/dist/interactions/actions/defaults/ingest.js +7 -5
  252. package/dist/interactions/actions/defaults/ingest.js.map +1 -1
  253. package/dist/interactions/actions/defaults/nudge.js +13 -38
  254. package/dist/interactions/actions/defaults/nudge.js.map +1 -1
  255. package/dist/interactions/actions/distribute/action.js +6 -4
  256. package/dist/interactions/actions/distribute/action.js.map +1 -1
  257. package/dist/interactions/actions/drawnBoxes.js +2 -1
  258. package/dist/interactions/actions/drawnBoxes.js.map +1 -1
  259. package/dist/interactions/actions/edit-anchors/action.js +3 -6
  260. package/dist/interactions/actions/edit-anchors/action.js.map +1 -1
  261. package/dist/interactions/actions/edit-anchors/preview.js +41 -8
  262. package/dist/interactions/actions/edit-anchors/preview.js.map +1 -1
  263. package/dist/interactions/actions/flip/action.js +6 -4
  264. package/dist/interactions/actions/flip/action.js.map +1 -1
  265. package/dist/interactions/actions/gestureLifecycle.js +5 -2
  266. package/dist/interactions/actions/gestureLifecycle.js.map +1 -1
  267. package/dist/interactions/actions/insert/action.js +1 -2
  268. package/dist/interactions/actions/insert/action.js.map +1 -1
  269. package/dist/interactions/actions/insert/commit.js +1 -1
  270. package/dist/interactions/actions/insert/parent.js +11 -0
  271. package/dist/interactions/actions/insert/parent.js.map +1 -0
  272. package/dist/interactions/actions/insert/placeAction.js +7 -2
  273. package/dist/interactions/actions/insert/placeAction.js.map +1 -1
  274. package/dist/interactions/actions/insert/session.js +5 -1
  275. package/dist/interactions/actions/insert/session.js.map +1 -1
  276. package/dist/interactions/actions/move/action.js +8 -4
  277. package/dist/interactions/actions/move/action.js.map +1 -1
  278. package/dist/interactions/actions/move/behaviors/layoutDrop.js +0 -1
  279. package/dist/interactions/actions/move/behaviors/layoutDrop.js.map +1 -1
  280. package/dist/interactions/actions/move/behaviors/snapToContainer.js +1 -1
  281. package/dist/interactions/actions/move/capture.js +1 -1
  282. package/dist/interactions/actions/move/commit/index.js +0 -2
  283. package/dist/interactions/actions/move/commit/index.js.map +1 -1
  284. package/dist/interactions/actions/move/commit/layoutDrop.js +2 -2
  285. package/dist/interactions/actions/move/commit/layoutRelease.js +2 -2
  286. package/dist/interactions/actions/move/commit/reparent.js +11 -5
  287. package/dist/interactions/actions/move/commit/reparent.js.map +1 -1
  288. package/dist/interactions/actions/move/frame.js +4 -10
  289. package/dist/interactions/actions/move/frame.js.map +1 -1
  290. package/dist/interactions/actions/move/landedDescendants.js +20 -17
  291. package/dist/interactions/actions/move/landedDescendants.js.map +1 -1
  292. package/dist/interactions/actions/move/layout/container.js +2 -1
  293. package/dist/interactions/actions/move/layout/container.js.map +1 -1
  294. package/dist/interactions/actions/move/layout/dragged.js +1 -1
  295. package/dist/interactions/actions/move/layout/dropPass.js +18 -1
  296. package/dist/interactions/actions/move/layout/dropPass.js.map +1 -1
  297. package/dist/interactions/actions/move/layout/exits.js +5 -5
  298. package/dist/interactions/actions/move/layout/exits.js.map +1 -1
  299. package/dist/interactions/actions/move/session.js +14 -3
  300. package/dist/interactions/actions/move/session.js.map +1 -1
  301. package/dist/interactions/actions/move/translate.js +8 -37
  302. package/dist/interactions/actions/move/translate.js.map +1 -1
  303. package/dist/interactions/actions/moveNodes.js +87 -0
  304. package/dist/interactions/actions/moveNodes.js.map +1 -0
  305. package/dist/interactions/actions/planeInput.js.map +1 -1
  306. package/dist/interactions/actions/resize/action.js +83 -72
  307. package/dist/interactions/actions/resize/action.js.map +1 -1
  308. package/dist/interactions/actions/resize/commit.js +2 -1
  309. package/dist/interactions/actions/resize/commit.js.map +1 -1
  310. package/dist/interactions/actions/resize/session.js +2 -0
  311. package/dist/interactions/actions/resize/session.js.map +1 -1
  312. package/dist/interactions/actions/resolvePreviews.js +3 -3
  313. package/dist/interactions/actions/resolvePreviews.js.map +1 -1
  314. package/dist/interactions/actions/rotate/action.js +7 -4
  315. package/dist/interactions/actions/rotate/action.js.map +1 -1
  316. package/dist/interactions/actions/rotate/commit.js +2 -1
  317. package/dist/interactions/actions/rotate/commit.js.map +1 -1
  318. package/dist/interactions/actions/rotate/session.js +2 -0
  319. package/dist/interactions/actions/rotate/session.js.map +1 -1
  320. package/dist/interactions/actions/selectionSubtree.js +13 -2
  321. package/dist/interactions/actions/selectionSubtree.js.map +1 -1
  322. package/dist/interactions/actions/testUtils.js.map +1 -1
  323. package/dist/interactions/actions/transform-again/action.js +5 -6
  324. package/dist/interactions/actions/transform-again/action.js.map +1 -1
  325. package/dist/interactions/actions/transformFinish.js +106 -0
  326. package/dist/interactions/actions/transformFinish.js.map +1 -0
  327. package/dist/kitSettingsSchema.js +0 -4
  328. package/dist/kitSettingsSchema.js.map +1 -1
  329. package/dist/move.d.ts +5 -4
  330. package/dist/{options-p9GZMXbY.d.ts → options-DBxEryYq.d.ts} +1 -1
  331. package/dist/resize.d.ts +4 -3
  332. package/dist/routing.d.ts +1 -1
  333. package/dist/routing.js +2 -2
  334. package/dist/test-hook/createTestHook.js +1 -1
  335. package/dist/test-hook/createTestHook.js.map +1 -1
  336. package/dist/test-hook/useTestHook.js +2 -1
  337. package/dist/test-hook/useTestHook.js.map +1 -1
  338. package/dist/test-seams.d.ts +9 -5
  339. package/dist/tools/builtin/pen/penHandle.js +3 -5
  340. package/dist/tools/builtin/pen/penHandle.js.map +1 -1
  341. package/dist/tools/index.js +26 -0
  342. package/dist/{types-CHVXGfYm.d.ts → types-7puAuVD2.d.ts} +3 -262
  343. package/dist/types-BN9hbdMI.d.ts +184 -0
  344. package/dist/types-CniVctmk.d.ts +949 -0
  345. package/dist/types-oFeQ5VjV.d.ts +264 -0
  346. package/dist/version.js +1 -1
  347. package/package.json +35 -25
  348. package/dist/canvas/SceneCanvas/useBuiltinRigTools.js +0 -65
  349. package/dist/canvas/SceneCanvas/useBuiltinRigTools.js.map +0 -1
  350. package/dist/tools/builtin/bone/boneActions.js +0 -156
  351. package/dist/tools/builtin/bone/boneActions.js.map +0 -1
  352. package/dist/tools/builtin/bone/boneOverlay.js +0 -71
  353. package/dist/tools/builtin/bone/boneOverlay.js.map +0 -1
  354. package/dist/tools/builtin/bone/placedRig.js +0 -28
  355. package/dist/tools/builtin/bone/placedRig.js.map +0 -1
  356. package/dist/tools/builtin/bone/rigEditState.js +0 -30
  357. package/dist/tools/builtin/bone/rigEditState.js.map +0 -1
  358. package/dist/tools/builtin/bone/useBoneTool.js +0 -125
  359. package/dist/tools/builtin/bone/useBoneTool.js.map +0 -1
  360. package/dist/tools/builtin/weight/useWeightTool.js +0 -101
  361. package/dist/tools/builtin/weight/useWeightTool.js.map +0 -1
  362. package/dist/tools/builtin/weight/weightActions.js +0 -140
  363. package/dist/tools/builtin/weight/weightActions.js.map +0 -1
  364. package/dist/tools/builtin/weight/weightOverlay.js +0 -78
  365. package/dist/tools/builtin/weight/weightOverlay.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,432 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.11.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 70b12d1: An action can carry a settings form: `Action.settings` holds a prefs schema, a `read` that gives
8
+ the selection's current values (and which fields it disagrees on), and an optional `params` that
9
+ turns one field's change into the params the action is triggered with. Every surface that lists
10
+ actions draws such an action as its form instead of a button that triggers it bare: a bar or a
11
+ panel opens it in a popover under the action's button, a menu shows it as a submenu of its fields,
12
+ and the command palette opens it in a dialog. Each change is one trigger, so one undo step. The
13
+ form is disabled while the action's `enabled` says no. `readActionSettings` and
14
+ `actionSettingsParams` are what the surfaces read it through; `useActionSettings`,
15
+ `ActionSettingsPopover` and `ActionSettingsDialog` are in `@weasel-js/ui/components/ActionSettings`.
16
+ `BarActionButton` takes `expanded` for a button that opens a dialog.
17
+
18
+ Warp Settings (`configureWarp`) and Edit Path Effect (`editPathEffect`) carry one each, so Warp
19
+ Settings on a bar now opens Mode, Rows, Columns, Mapping and Tolerance for the selected warps
20
+ rather than doing nothing, and both are disabled with nothing they apply to selected.
21
+ `editPathEffect` takes an optional `kind`, limiting an edit to effects of that kind, and now reads
22
+ `selection`. The forms are exported as `warpSettingsForm` and `pathEffectSettingsForm`.
23
+ - 3b5750f: Set, swap, or release the spine of a blend that already exists. `setBlendSpineAction`
24
+ (`setBlendSpine`) lays the selected blend along the other selected path, in either selection order,
25
+ replacing any spine it had; `releaseBlendSpineAction` (`releaseBlendSpine`) puts each selected
26
+ blend back on a straight run between its two shapes and selects the spines, ordinary paths where
27
+ they were. Both are in `pathEffectsPreset` and the `pathEffects` group, and each is one undo step.
28
+
29
+ Core adds `createSetDependsOnOp`, an undoable retarget of a derived node's `dependsOn`, and the
30
+ `setDependsOn` write it goes through on `SceneMutators` and the scene-backed adapter.
31
+ - 768be71: Depend on `@msb235/blits` 0.11.0, where stopping an animation no longer costs time in step with how many are running. blits' `loop` now defaults to one pass; no voice weasel cues depends on it, since each is either a motion (a tween or a spring) or a patch with no duration, and blits ignores `loop` for both.
32
+ - 9390be4: `CANVAS_CONTEXT_ATTRIBUTES` is the WebGL2 context attributes a weasel canvas is opened with. A
33
+ context keeps the attributes of whoever opens it first and the renderer refuses one without a
34
+ stencil buffer, so anything that may open the canvas before its first paint, such as a pixel reader
35
+ or a tenant sharing the buffer, passes these.
36
+ - 1dd65f5: `<Canvas>` and `<SceneCanvas>` take an `imageMinification` prop, forwarded to the renderer: `'auto'` builds an image's mipmaps the first time a frame draws it at half size or smaller, so a large bitmap drawn small stops aliasing. The default stays `'linear'`. `WeaselRenderer.setImageMinification` changes the strategy after construction; a change frees every image texture, and each re-uploads when next drawn.
37
+ - 411b629: A `carry` spec takes a `target`, matched against what is under the carry the way a click's is: a binding can now say "dropped onto a selected body" or onto an affordance. An immediate action with a target fires only on a release over it; an ongoing one starts on the first step over its target, as the carry comes over or as it moves on. The route grammar reads `carry(lab/*) => selected-body`. A carry's immediate params carry `affordance`, `bodyTarget`, and `bodyKind`.
38
+
39
+ `Action.enabled`'s `carried` argument is now the exported `Carried` type and sees a carry too: `{ items: [], carry: { type, value } }`, so an action can refuse a payload it would not take.
40
+ - 267d5e4: Connectors can route around shapes. The `avoid` router draws a connector orthogonal, with few bends,
41
+ clear of every shape, and with parallel runs spread apart. Its route is computed when the scene is
42
+ edited and stored on the edge as `diagram.route`, so a saved file draws it without rerouting and
43
+ undo restores it exactly; a stored route that no longer fits its ends draws as `orthogonal`.
44
+ `useAvoidRouting(scene)` (or `installAvoidRouting` outside React) reroutes whatever each edit
45
+ disturbed in that edit's own undo entry, and reroutes the connectors near a dragged shape every
46
+ frame. Containers, pools, and group boxes are in the way only of connectors with neither end inside
47
+ them; lane bodies never are; headers always are. Dragging a segment of an `avoid` connector pins
48
+ only that segment. `DiagramView` takes `router="avoid"`, and `createAvoidRouter` — the search alone,
49
+ over plain boxes and ports — is in `@weasel-js/diagram/layout`. New commands set the selected
50
+ connectors' router (`SET_ROUTER_ACTION_IDS`), and layout no longer writes waypoints to an `avoid`
51
+ connector.
52
+
53
+ Core adds scene edit passes: `scene.addEditPass(pass)` hears each live edit's added, removed,
54
+ posed, re-parented, and data-changed ids once its own mutations and the arrival handler have run,
55
+ and its ops join the same undo entry. Passes never re-trigger on their own writes, and undo, redo,
56
+ and history replay never run them. While any pass is added, a bare scene call runs as an edit of
57
+ its own.
58
+
59
+ weaselchart's connector tool draws connectors that route around shapes, and Format › Connector
60
+ picks Around shapes, Orthogonal, Straight, or Curved for the selected connectors. Charts saved
61
+ before keep the router they have.
62
+ - 922cddf: Diagrams get containers and swimlane pools, and core's layouts and drops carry and filter nested nodes.
63
+
64
+ - core: a layout pass that moves a child container now takes that container's descendants along, under absolute poses, in the same edit; so does a layout drop that shifts siblings, in its preview and its commit. `carriedDescendants(source, root, translate)` and `sceneCarrySource(scene)` are the helper behind both. A new optional `canDropInto(parent, ids)` dep (`CanDropIntoDep`) decides which containers a move may drop into: reparent-on-drop passes over a refused container, the layout drop skips it, and a child leaving its layout container does not land in it.
65
+ - diagram: `CONTAINER_STENCILS` offers Container, Pool (rows), and Pool (columns). A container is a titled box whose members move with it and stay put when it is resized; a pool stacks lanes that reorder by their headers, resize by the boundary after each (`diagram.resizeLane`), and grow by the button past the stack (`diagram.addLane`). `diagram.releaseMembers` removes a container and keeps what it holds. `diagramCanDropInto(scene)` is the drop filter, `diagramContainers` returns the lane layer and the contribution, and `diagramContainerLayout` and `laneStackLayout` register through `withDiagramRegistry`. `useStencilInsert` takes `containers`, and a stencil drawn inside a container or a lane becomes its member. Lanes take no connectors, and `diagramResizable` refuses them.
66
+ - core: a container with a layout is arranged again whenever one of its children's poses is written — a nudge, an align, a panel edit — not only when its children or its size change, in the same undo entry as the write.
67
+ - d5a4102: Breaking at the type level for custom `commit` and `canConnect` callbacks: the ends of a `PendingEdge` and the arguments of `CanConnect` are now a `ConnectEnd`, which is a port or a shape's body, where they were always a port.
68
+
69
+ `@weasel-js/diagram` gains editing surface. Edges connect onto a shape's body (`connectBodies`, the `bodies` option, and a connector tool), and a selected edge's ends reconnect by dragging a handle. A label action (`editEdgeLabelAction`, `edgeLabelSpec`, `labelSize`) creates and edits an edge's label. Stencils (`FLOWCHART_STENCILS`) come with `useStencilInsert` and `useStencilTool`. `DiagramView` takes `onReconnect`, `onDelete`, `onEditLabel`, `connectBodies` and `ambient`, and its ref has `worldAt`. `diagramResizable` keeps resize handles off edges and labels. `DataEdge` and `EffectWire` take an optional `id`, and the `ellipse` outline is new. For effect pipelines there is an edit model, stage types with typed params, and `EffectEditor`, an editable node graph.
70
+
71
+ `@weasel-js/core` exports `createDeleteAction` and `commitDeleteToScene`, so a consumer can swap how a delete commits.
72
+ - 9cd12f7: Edge labels are obstacles, and they dodge. An `avoid` connector now routes around every other
73
+ connector's label, 4 world units clear (`labelClearance`), and never around its own; within one
74
+ commit a label is restationed on its connector's new route before the next connector routes.
75
+ `AvoidEdge.label` carries it, filled from the scene and from `DiagramView`'s specs. An obstacle's
76
+ `kind` may now be `'label'`.
77
+
78
+ After any edit, `useLabelPlacement(scene)` (or `installLabelPlacement` outside React) moves a label
79
+ that sits on a shape, another label, or another connector along its own connector, or across it,
80
+ to the nearest clear station, in that edit's own undo entry, and sizes a label to the text an edit
81
+ gives it. The chosen station is stored on the label trait as `placed`, which `labelDerivePose`
82
+ reads before `at` and `offset`; `dodge: false` opts a label out. Labels hold still during a drag
83
+ and settle on release. `DiagramView` takes `labels="dodge"`, `createSpecLabelPlacer` is that step
84
+ on its own, and `placeLabels` — the placement alone, over plain boxes and routes — is in
85
+ `@weasel-js/diagram/layout` with `labelCenter`.
86
+
87
+ Core adds `documentDepOf(scene, id)`: a dependency at the pose and path the document holds, with
88
+ no override counted, for a reader such as an edit pass.
89
+
90
+ weaselchart places edge labels, so a shape dropped on a label moves the label off it on release.
91
+ - e5ba382: Connectors can jump each other. While a scene's `HOPS_DOC_KEY` document value is set, wherever two
92
+ connectors cross, the one later in render order bows over the other in a half circle of the value's
93
+ `size`. A hop bulges toward −y on a horizontal run and toward −x on a vertical one, whichever way the
94
+ connector travels, and to the left of travel on a diagonal. Crossings near either connector's ends
95
+ or a bend, and collinear overlaps, make no hop, and hops closer than twice their radius merge into
96
+ one longer hop. A connector split across pages neither hops nor is hopped over. Each connector stores its hops as `diagram.hops`, so a saved file draws them with no
97
+ pass running, and a hop no longer on its connector's route does not draw.
98
+
99
+ `useHops(scene)` (or `installHops` outside React) recomputes the hops an edit disturbed in that
100
+ edit's own undo entry, and turning the value on or off recomputes or clears them all in the one
101
+ entry that sets it. While a drag is in progress, the connectors it moves, and those hopping over
102
+ them, draw without hops until release. `diagramWaypoints` carries a Line jumps toggle
103
+ (`SET_HOPS_ACTION_ID`), `DiagramView` takes `hops`, a radius, and `edgeHops`, the crossing finder
104
+ over plain polylines, is in `@weasel-js/diagram/layout`.
105
+
106
+ Core's `TransformFollower.preview` gets a second argument: the data the followers before it
107
+ previewed, by id, so a follower can build on a route an earlier one previewed. A follower that
108
+ calls `preview` itself now passes it. `useAvoidRouting`'s drag preview reads the waypoints a
109
+ `waypointFollower` registered before it carried, rather than carrying them itself, so without one
110
+ the preview leaves waypoints where the commit will.
111
+
112
+ weaselchart adds Format › Connector › Line jumps.
113
+ - 8e317f5: Off-page reference markers. On a scene with pages, a connector whose two shapes sit on different
114
+ pages no longer draws across the gap: each end draws a short stub out of its shape, ending at a tag
115
+ that reads the other page's name and a reference letter, such as "Page 2 · A".
116
+ `useOffPageMarkers` (or `installOffPageMarkers` without React) splits and joins connectors as edits
117
+ move their ends or change the pages, in that edit's own undo entry, and writes
118
+ `DiagramEdge.offPage`. The tags are text nodes with a background (`offPageTagSpec`, registry key
119
+ `diagram:offPageTag`), colored by the theme. `diagramOffPage()` binds a double-click on a tag to
120
+ selecting the shape at the far end and fitting the view to its page. `offPageSplits` is the split
121
+ rule as arithmetic, and `offPageOps` runs the pass over named connectors.
122
+
123
+ A split connector's `ResolvedRoute` carries its two `stubs`, it shows no route handles, and the
124
+ `avoid` router leaves it out until it joins again. An edge label on a path with several subpaths
125
+ sits on the first (`subpathOf`).
126
+
127
+ `pageName` (core) is the name a page shows, its own or "Page" and its place, and `PageTabs` uses it.
128
+ - abf41a7: Scenes hold document values, and a document's pages are one of them.
129
+
130
+ - core: `scene.doc` holds named JSON values beside the tree (`get`, `set`, `keys`). A `set` is undoable, joins an enclosing `batch`, is skipped when the value is deep-equal, and notifies subscribers. `SerializedScene.doc` carries them, `sceneFromJSON` and `loadState` read them back, and `createScene` and `useScene` take `doc` for the starting values. The field is additive: a snapshot without it loads as before. New types: `SceneDoc`, `SceneDocValues`, `SerializedDoc`.
131
+ - core: the page list is the `core:pages` document value (`PAGES_DOC_KEY`, `PagesDoc`, `pagesOf`, `placedPagesOf`). `setPages` replaces it and moves each page's root nodes, with their descendants, by however far their page moved, in one undo entry; `addPage`, `removePage` (which deletes what is on the page and what derives from that), `movePage`, `resizePage`, and `renamePage` are built on it, with `pageMembers` and `nextPageId` beside them. `pageInView` answers the page a view shows most of.
132
+ - ui: `PageTabs` is a strip of tabs over any page list, built on `Tabs`: press to go to a page, press twice to rename, drag or Alt+arrow to reorder, + to add, and a right-click reported for a context menu. `useReorderDragList` takes `axis: 'x'` for a row of items, and `TabList` takes a `ref`.
133
+ - 312eb35: Themes can be edited. `forkTheme`, `setThemeValue` (by a `ThemePath` such as
134
+ `['roles', 'accent', 'fill']` or `['series', 2]`), `addThemeRole`, `renameThemeRole`, and
135
+ `removeThemeRole` return a new theme and leave the one given alone, so a shipped theme is never
136
+ changed; `editableTheme` forks a shipped theme and passes a custom one through. `DiagramTheme` takes
137
+ `roleLabels`, the names of roles beyond the shipped six, and `themeRoles(theme)` lists every role
138
+ with its name. A removed role's shapes are drawn in the default role. `parseDiagramTheme` and
139
+ `themeToJson` read and write `.weasel-theme.json` files, and a bad file comes back as errors naming
140
+ each bad value by its path. `applyDiagramTheme` takes `{ coalesceKey, from }`.
141
+
142
+ Applying a theme whose font size differs from the scene's moves existing text by the step between
143
+ them: shape rows, titles, and connector labels keep their offset from the body size.
144
+ `setDiagramFontSize(scene, ids, size)` sets a shape's or connector's text size by hand and records
145
+ it in the trait's new `ownFont` (`FontField`), which a theme's size change then leaves and choosing
146
+ a role keeps. A body whose text changes size is laid out again in the same undo entry: it grows
147
+ to fit its rows and never shrinks. A body built from text rows alone records how it stacks them
148
+ as `DiagramNode.body`, its rows carrying `bodyRow`; `relayoutBodies` lays such bodies out again,
149
+ and `rendererMeasure` measures text from the registered font as the renderer draws it.
150
+
151
+ Core's `scene.batch(label, fn, { coalesceKey })` folds a batch into the undo entry before it when
152
+ that one was recorded under the same key and nothing came between, so a run of batches, such as a
153
+ color dragged, undoes as one entry back to the state before the first. Unlike an op's own key it
154
+ needs no `coalesceWindowMs`; `scene.history.seal()` ends the run. `@weasel-js/history`'s
155
+ `recordEntry` takes the same `coalesceKey`.
156
+
157
+ weaselchart's Format › Theme › Edit Theme… opens a Theme panel: every role's colors, with roles
158
+ added, renamed, and removed (not the default), the connector, label, container, lane, page, and
159
+ series colors, and the font. The Style panel gains Text size. The chart recolors as a color is dragged, and one undo takes back the
160
+ drag. The first edit to a shipped theme copies it into the chart as "<name> (edited)". Import
161
+ Theme… and Export Theme… move a theme between charts.
162
+ - 7ffc196: Connector routes are editable, and whole-node transforms carry other nodes along through one dep.
163
+
164
+ - core: a `transformFollowers` dep holds every `TransformFollower`, `{ preview(frame), finish(ops, label) }`, and each whole-node transform (move, resize, rotate, flip, align, distribute, nudge, transform again) finishes its batch and previews its frame through all of them in order. `useTransformFollower` adds one. Path edit's constraint links are now one of them, so `EditAnchorsDep.transformOps` and `EditAnchorsDep.transformPreview` are gone; that is breaking for anyone who called them. `writtenBy(scene, ops)` reads the pose and data a batch leaves each node it writes.
165
+ - diagram: a selected edge shows handles along its route. Under `straight` and `bezier`, a dot on each waypoint moves it and a hollow dot in each leg inserts one; under `orthogonal`, a bar slides its segment, jogging where it touches a port. A double-click removes a waypoint or straightens a jog. Drags snap into line with neighboring stops and port axes. `diagramWaypoints` returns the handle layer and a contribution carrying the drag, the double-click, and the `diagram.resetRoute` command; the math is exported on its own (`routeHandles`, `dragSegment`, `simplifyStops`, and the rest). `waypointFollower(scene)` carries waypoints along with a move of both ends. `DiagramView` takes `onEditRoute`, and `EffectEditor` keeps wire routes in `EffectDoc.routes` (`setWireRoute`). `edgeRouter` answers an edge's resolved route, as `edgeDerivePath` draws it.
166
+ - 25a112b: Constraint links follow whole-node drags live, and broken ones are drawn.
167
+
168
+ - core: move, resize and rotate preview the nodes a constraint link ties as they will commit, every frame, through the same finishing the commit runs, and `transformPreviewFields` gives a drag its preview fields with them added.
169
+ - path-tools: `createConstraintLinkMarks(style)` is a screen-space layer, carried by `constraintsPreset`, that draws every broken link: its constraint's mark by the anchor it holds and a dashed line to where it wants that anchor, in the conflict color. `brokenConstraintLink(scene, id)` and `brokenConstraintLinks(scene)` read the links that do not hold, `constraintLinkMarks` draws a list of them, and `DEFAULT_CONSTRAINT_STYLE` is exported.
170
+ - 4d99526: Constraint links now hold through whole-node transforms, preview through every path-edit drag, and have a gesture that makes them.
171
+
172
+ - core: `PathEditExtension.finishTransform(ctx: PathTransformFinishCtx)` answers the other nodes a move, resize, rotate, flip, nudge or transform-again changes along with the ones it transforms — align and distribute too — committed in the same history entry; the `editAnchors` dep runs it as `transformOps(ops, label)`, and those actions now declare `editAnchors`. An extension may refuse a transform by answering null.
173
+ - core: `pathEditPreview` finishes each frame itself through the new `finishPathEditFrame`, so bend segment and the path-tools drags preview the node's constraints and linked nodes as they will commit. Breaking: its `current` thunk now answers a `PathEditFrame` (`{ path, origins? }`) instead of a bare path.
174
+ - geom: `PathsEditItem.yields` lets a path the edit left alone give way freely.
175
+ - path-tools: the constraints extension carries linked nodes through whole-node transforms; `constraintLinkConflictsOf(scene, id)` reports the links tying a node that do not hold; `linkAnchorAction` (in `constraintsPreset`) links an anchor Alt-dragged onto another node's anchor (`coincident`) or segment (`onPath`), with `linkTargetAt` and `linkConstraint` beside it.
176
+ - 853ce69: A dep source is handed `below`, which reads the source it displaced, in its own scope or one above, so a source can handle part of a dep and pass the rest to the default (`DepSource`, accepted by `useDepSource` and `DepRegistry.register`). A source taking no argument works as before. `useStencilInsert` uses it: a kind no stencil names goes to the `insert` dep beneath it, so core's rect, ellipse and text tools work beside stencils.
177
+ - 8c1861a: Add a devtools hook. Each mounted `<SceneCanvas>` registers a root on `window.__weaselDevtools__`,
178
+ which serves a panel over a versioned message protocol: the scene tree a level at a time, a node's
179
+ pose and data, selection, view, tools, probes, the dispatch trace and frame stats, plus select,
180
+ highlight, set-tool and debug-overlay commands. A dev build installs the hook itself; a production
181
+ build installs it only when the app imports the new `@weasel-js/core/devtools` subpath, which also
182
+ exports the protocol types and the in-page and `postMessage` transports. See `docs/devtools.md`.
183
+
184
+ The debug overlay gains a `highlight` feature (`debug={{ highlight: ids }}`), and `<Canvas>` and
185
+ `<SceneCanvas>` take an `aria-label`.
186
+
187
+ Breaking: the dispatch trace is per canvas now. `window.__weaselDispatchLog__`,
188
+ `window.__weaselDispatchLive__` and `window.__weaselCoordLog__` are gone, and so are routing's
189
+ `recordModeSwitch` and `publishLiveDispatch`. A dispatcher records into `DispatcherContext.trace`
190
+ (`createDispatchTrace`), which `useGestureDispatcher` creates or takes as its `trace` option and
191
+ publishes as the `dispatchTrace` dep; record a mode switch with
192
+ `deps.get('dispatchTrace')?.recordModeSwitch(…)`.
193
+ - 6440997: Add `<DevtoolsLabel value>`, which names the canvases beneath it in a devtools panel ahead of any
194
+ labeled element nearer to them. A labkit trial wraps its content in one with its title, so a plain
195
+ `<SceneCanvas>` in a trial, a forge story's included, is listed by the trial's title rather than as
196
+ "Content", the pane it sits in.
197
+ - 44cf2c5: The devtools panel fits a narrow container: below 480 px wide its tabs wrap and the Scene and
198
+ Registry tabs stack their list above the detail. Its header keeps the canvas picker at the left and
199
+ the version at the right, a selected tree row is marked in the accent color, and the node detail's
200
+ values line up.
201
+
202
+ A `<SceneCanvas>` with no `aria-label` or id of its own is listed in devtools by the `aria-label` of
203
+ its nearest labeled ancestor. labkit's `TrialSceneCanvas` labels its canvas with the trial's title.
204
+ `Tree` reads the new `--wzl-tree-selected` hook for a selected row's background.
205
+ - 8ff750f: The devtools panel gains a Registry tab, listing a canvas's tools, actions and deps under a name
206
+ filter, each opening to its details and its bindings drawn in the route grammar, and a History tab,
207
+ following the scene's history steps with each entry's ops, where the history stands with whether it
208
+ can undo or redo, and the checkpoint stack on request. `followHistory` reads `get-history` through
209
+ its cursor without React.
210
+
211
+ A scene gains `getContentVersion()`, which moves on every change but one that only changed the
212
+ selection. The devtools hook uses it, so a selection change is no longer also announced as a
213
+ `scene` change.
214
+ - 161c9c4: Add `@weasel-js/devtools`, a panel that reads and steers every `<SceneCanvas>` on a page over the
215
+ devtools hook. `DevtoolsPanel({ transport })` shows a picker for the page's canvases and four tabs:
216
+ Scene (the node tree, loaded a level at a time, and a picked node's parent, pose and data; hovering a
217
+ row outlines the node on the canvas), State (selection, view, active tool, debug overlay flags and
218
+ probes, with the tool and the flags settable), Dispatch (the dispatch trace, newest first, under what
219
+ a press at the pointer would do, filterable by handled and unhandled, each decision opening to its
220
+ path and its fallthrough diagram; coord records behind a toggle), and Frame (the last paint's cost
221
+ while the `fps` overlay is on). `createInPagePanelTransport()` connects it to the page's own hook.
222
+ `connectDevtools` and `followTrace` are the protocol client underneath, without React. Import
223
+ `@weasel-js/devtools/style.css` beside it.
224
+
225
+ Core exports `DEBUG_FEATURES`, every debug overlay feature a `DebugConfig` flag turns on;
226
+ `DebugFeature` is now derived from it.
227
+ - 33fa471: Add `@weasel-js/core/devtools-protocol`: everything `@weasel-js/core/devtools` exports — the
228
+ protocol types, `DEVTOOLS_PROTOCOL`, the envelope tag, the transports, and the hook's constructors —
229
+ without installing a hook on import. `@weasel-js/core/devtools` re-exports it and still installs one.
230
+ `@weasel-js/devtools` now imports from the new entry, so mounting the panel no longer puts a hook in
231
+ the panel's own window; `createInPagePanelTransport()` still installs one when called.
232
+ - 2eb0370: The devtools hook serves two more requests, still under protocol 1. `get-registry` describes what a
233
+ canvas has registered: its tools and preset contributions with their bindings, its actions, the dep
234
+ names its registry answers, and its node routing kinds. `get-history` hands back the scene's history
235
+ steps since a cursor — each push, merge, undo, redo or jump, with the ops it carried and where the
236
+ history stood — from a rolling buffer of 200 that records in dev builds and in production while a
237
+ panel is connected. `changed` reports both as the new `registry` and `history` areas. See
238
+ `docs/devtools.md`.
239
+
240
+ `History` gains `observe(listener)`, which hears what each change to the stacks was, and
241
+ `touchedIdsFromOps` is exported from `@weasel-js/history`. A hand-written `History` implementation
242
+ must add `observe`. `DepRegistry` gains an optional `list()` naming every dep it answers.
243
+ - c726003: A `<SceneCanvas>`'s devtools root no longer announces a `registry` change on every selection
244
+ change. The dep registry also notifies when a source's value changes, which the selection does on
245
+ every change, so the root now announces only when the deps it lists come or go.
246
+ - e30f4df: `DiagramView` can hold DOM against its nodes, groups and edges, report what the pointer is over, and let a group's members be dragged into a new order. All three are additive.
247
+
248
+ - `overlays` places each `DiagramOverlay` against its target after every paint: centered on it, or beside it through geom's `placeRect`, flipping inside the view. An edge's place is the midpoint along its route. The view now renders a box around its canvas to hold them, and `className` goes on that box rather than on the canvas.
249
+ - `onHover` reports the node, group or edge under the pointer; `pickEdges` lets a click or a hover land on an edge whatever editing callbacks are set. `rectOf(id)` and `subscribeFrame` on the ref give a target's client rect and when to read it again.
250
+ - A `DataGroup` with `reorder: 'x' | 'y'` lets `onReorder` drag any member along that axis, carrying everything inside a member that is a group, or step the picked one with Alt and an arrow key. It reports `{ group, order }` and moves nothing. `layered` keeps such a group's members in the order given across every rank instead of sorting them by crossings. `createReorderAction`, `createStepReorderAction`, `reorderBindings` and `reorderContribution` are exported for use outside `DiagramView`.
251
+
252
+ `SceneCanvas` takes `onHover`, called when the topmost pickable node under the pointer changes. `@weasel-js/react` exports `adoptCss`, `adoptCssOnce` and `styleRootOf`, the stylesheet adoption core's canvas and `KitSettingsFromPrefs` now share.
253
+ - 8c2a9a9: `DiagramView` takes `onResize`. With it set, a selected node shows resize handles; the box resizes
254
+ live under the drag, and on release the view reports `{ id, x, y, width, height }` for each resized
255
+ node and changes nothing until the specs follow. Store the box as the data node's `width`, `height`,
256
+ and `at`; the size is a minimum, so a box dragged smaller than its rows grows back to them.
257
+ `diagramResizable` now refuses a group's box, whose size comes from its members.
258
+
259
+ Core adds `createResizeAction({ commit })`, the resize action with its commit swapped: `commit` is
260
+ handed each resized node's pose at release, and the scene is left as it was.
261
+ - 1156d63: A node that shows a derived path is boxed around that path, stroke included, wherever the kit measures a drawn box: selection chrome, its hit regions, and the actions that read `drawnBoxes`. Its zero-size placeholder pose no longer drags the box back to the origin. `DrawnBoundsScene` takes an optional `derivedPathOf`, and `drawnBoundsScene(scene)` supplies it for a `Scene`; pass a scene through it to `useAlign`'s `scene` for the same box there.
262
+ - adadf5e: Scene edit passes now compose. `scene.addEditPass(pass, { order })` runs passes by ascending
263
+ `order` (default 0), ties in the order they were added, and each pass hears the edit's own changes
264
+ plus every write the passes before it made; it still runs once per edit, and undo, redo, and
265
+ history replay still run none. This changes what a second pass hears: it used to miss the first
266
+ pass's writes. `SceneEditSummary.docChanged` lists the document-value keys an edit set.
267
+
268
+ Diagram exports `DIAGRAM_PASS_ORDER`, where each of its passes runs, and avoid routing installs its
269
+ pass at `DIAGRAM_PASS_ORDER.avoid`. The routers (`straight`, `orthogonal`, `bezier`, `avoid`,
270
+ `ROUTERS`) moved to their own module; the package exports them as before.
271
+ - b3aa7cb: `documentFromScene` exports a shape sitting in the gap between pages on the nearest page rather
272
+ than the first, and marks a connector cross-page exactly when the scene's off-page split does. A
273
+ connector from a gap shape to another page stays whole, keeping its waypoints in world
274
+ coordinates. core gains `pageHolding`, the page a box is on, else the nearest one.
275
+ diagram gains `documentBoundsOf`, the box a node has in document space, which off-page splitting and
276
+ export now both read.
277
+ - ee2f0fc: `GroupTransform` is now only `{ kind: 'translate', dx, dy }`. Its `scale` and `rotate` arms are gone: no gesture produced them, and the move and clone actions ignored a behavior that answered one. A move behavior that switched on `kind` to handle them no longer needs those branches; resize and rotate behaviors answer through `ResizeMoveResult` and `RotateMoveResult` as before. Breaking for code that names the removed arms.
278
+ - ee4cf85: A drop or paste now keeps string flavors of any exact MIME a registered content handler names in its `match` or `types`, for as long as it stays registered, so a handler can claim a drag from the app's own UI by a type of its own instead of tagged `text/plain`. Globs and `application/octet-stream` admit nothing. `admitIngestMime(mime)` (routing, re-exported from core's ingestion module) does the same for code outside the handler registry and returns a release. The kit weasel-JSON handler's `application/x-weasel-clipboard+json` flavor now reaches it on paste as well.
279
+ - d892435: A content handler's `IngestCtx` now carries the canvas's `snap` dep as `ctx.snap`, so a handler can place what it inserts where a gesture would: begin a `'point'` session at the would-be position, take `at()`, and `end()` it. The `ingest` and `clipboard.pasteEvent` actions declare `snap` among their `requires`.
280
+ - 1a1bb83: Drawing or click-placing a node into a container with a unit scope now snaps on that scope's grid
281
+ pitch, not the root's.
282
+
283
+ - `SnapBegin` and `SnapCollect` take `parent`: the container a subject not yet in the scene lands
284
+ in. `insertAction` and `placeAction` pass the container the `insertInto` dep names, the same one
285
+ the `insert` dep puts the node in; an id naming no container passes nothing.
286
+ - `gridSnapSource({ scopes })` reads the scope from `ids` when the gesture has a subject, else from
287
+ `parent`, else the root.
288
+ - kernel3d's `createSnap` passes `parent` on to its sources, as it does `ids`.
289
+ - `placeAction` now requires the `insertInto` and `scene` deps, both optional.
290
+ - 0e24110: A key binding can now carry `opts: { over: true }`: it is live while the pointer is over its canvas, whichever canvas holds the keys, and only then. The loupe's peek key uses it, so with two loupes on a page the key peeks the one under the pointer rather than the one last pressed in, or none before anything was pressed. A `<LoupeGestures>` outside a camera now mounts its own input scope, so two of them under one provider no longer stack their actions on one id.
291
+ - 4bf5dec: `moveNodes(deps, ids, { dx, dy }, label?)` moves nodes the way a drag of them commits: derived nodes through what they derive from, every descendant not carried by a moving frame, each translated in the frame it is stored in, finished by the `transformFollowers` and committed as one undo entry (inside an open `scene.batch`, as part of it). `moveNodesOps` builds the same ops without committing them, and `MOVE_NODES_REQUIRES` names the deps an action calling `moveNodes` declares. The move action, nudge, Transform Again and the measure tool's Move By all build their translate ops through it.
292
+
293
+ The ingest action now also requires `poseDescriptor`, `geometryProjection` and `transformFollowers`, so a content handler can move what it inserts with `moveNodes(ctx.deps, …)`.
294
+ - fe2a8c5: A node's kind has one answer: its routing kind. `<SceneCanvas>` now publishes each selected node's
295
+ routing kind with the selection, so the command palette says "3 rects selected" or "2 groups
296
+ selected"; a node its routing table calls `'unknown'` publishes no kind, and the palette says
297
+ "objects". Before, the default label read `'group'` for a container, `'path'` for a pose carrying a
298
+ `kind`, and nothing for anything else. `describeKind` still replaces the label outright.
299
+
300
+ `SelectionPanel`'s `classifyKind` classifies through the new `routeKind` export, the function behind
301
+ `NodeRouting.classify`, and hands each routing entry the node beside its data. It no longer calls a
302
+ container `'group'` on its own: pass a table carrying `groupNodeRouting`, as `inferredNodeRouting`
303
+ does, for that. This changes behavior for a panel given a table without it, such as
304
+ `defaultNodeRouting` alone.
305
+ - b7e6edc: A Pathfinder action's preview now draws each piece in the paint it would wear — its source's paint, or the paint a counted stroke leaves it — with the overlay's outline over it, rather than as a plain outline. `TransientPath` takes an optional `paint` (a `PathPaint`) to do this for any path an overlay shows.
306
+ - 87cded1: `<SceneCanvas tools>` no longer warns when a patch tool replaces one a preset brings — a custom `hand` under the `view` preset, say. That replacement is the documented way to restyle a preset's tool, and the patched tool still takes the preset tool's place in the palette. The dev warning now fires only when the id is also listed in `defaultTools`, where asking for the built-in and replacing it in the same breath is likely a mistake. Since 1.11.0 the warning reached npm consumers in development (earlier builds shipped it disabled), and it logged on every render.
307
+ - 24267d3: `renderSceneToPixels`, `createRasterSession().render` and `planPixelRender` now leave a scene's annotation layers (measurements, notes) out of the raster, as the SVG export does. Pass `annotations: true` to draw them. `renderDebugSnapshot` draws them by default, since it reproduces the canvas; pass `annotations: false` to leave them out.
308
+ - 683dea0: New package, `@weasel-js/rig`: the bone and weight tools, with the actions they bind, moved out of
309
+ core. `useRigTools({ scene })` builds both for `<SceneCanvas tools>`, keyed by the ids `RIG_TOOLS`
310
+ names; they act on the rig the scene's selection names unless given `selection` or `rig`, and take
311
+ `state`, `reach` and `radius` as `toolOptions.rig` and `toolOptions.weight` used to. `useBoneTool`,
312
+ `useWeightTool`, `createRigEditState`, `placedRig`, `rigOfSelection`, the two overlays and
313
+ `weighedPaths` come from it too, and its glyphs are `rig:bone` and `rig:weight`.
314
+
315
+ **Breaking for core:** `<SceneCanvas>` no longer mounts the rig tools. `'bone'` and `'weight'` are
316
+ gone from `BuiltinToolId`, `BUILTIN_TOOLS` and `BUILTIN_TOOL_IDS`, `RIG_TOOLS` and every name above
317
+ are gone from core's barrel, and so are `toolOptions.rig`, `toolOptions.weight` and the
318
+ `core:bone` and `core:weight` glyphs. The kit settings `targets.boneJointRadiusPx` and
319
+ `targets.weightPointRadiusPx` keep their paths, but are declared by `@weasel-js/rig` and listed in
320
+ its `rigKitSettingsSchema` rather than `coreKitSettingsSchema`. Core keeps the rig itself:
321
+ `useRigNode`, `bindRig`, `placeSkeleton` and the rest bind a skeleton from scene data as before.
322
+ - 61e7b0c: `<SceneCanvas selectTool={{ rotate: false }}>` now turns off only the select tool's rotation: the
323
+ selection's rotation handle is hidden and bound to nothing. The `rotate` action stays registered, so a
324
+ tool of your own that binds `rotate` turns the selection, and a partial `actions.rotate` merges onto
325
+ the kit's action as it does on any other canvas. A `chromeVisibility` rule that shows the handle again
326
+ shows a handle a drag does nothing on, with no dispatcher warning. Before, the action was muted on the
327
+ whole canvas, which also stopped a consumer's tool from rotating.
328
+ - 5053f5b: `SnapBegin` takes `sources` and `omit`, so one gesture can ask snap sources the canvas does not list, or skip ones it does (a listed, registered or default source, by id), without changing the canvas. Gesture sources are ranked with the canvas's own, and one sharing an id with a source still asked throws. Gesture sources are 2D: kernel3d's `createSnap` honors `omit` but does not ask a gesture's `sources`, and warns once in dev when it is given some.
329
+ - 2b267d5: Snap pipeline follow-ups.
330
+
331
+ - kernel3d's `createSnap` takes `kitSettings` and reads its reach from `targets.snapPx` there, as a canvas does (`reachPx` still overrides it).
332
+ - Two snap sources sharing an id now throw, on a canvas when a gesture begins and in kernel3d's `createSnap`, where before the later one silently replaced the earlier: a `<SceneCanvas snap>` source and a preset's alignment source were the likely pair, and the page box went with it. A source still replaces one of the canvas's defaults (`'rotation'`, `'path-snap'`) by taking its id. Core exports the check as `assertSnapSourceIds`.
333
+ - The symmetry axis knob and a repeat's step handle turn through a `rotate` session on the `snap` dep: they now snap to quarter turns and other nodes' angles without Shift, Shift keeps the 15° steps, Ctrl suspends snapping, and the angle readout draws. Breaking: `handleChange` takes a `SymmetryHandleSnap` (`{ point, angle }`, new export) in place of its `stepped` flag and point function. Without a `snap` dep the handles do not snap, Shift included.
334
+ - `resolveSnap` keeps every required candidate past `poolSize`, so Shift's steps can no longer be crowded out by 24 nearer targets, and drops a candidate with a non-finite locus direction instead of treating its line as a point.
335
+ - A move begins its snap session once the drag passes its threshold, so a click on a selected body reads nothing for snapping, and its `geometry` probe is placed within the canvas's reach rather than a fixed 8px.
336
+ - ac892f8: `EffectEditor` takes `look`: `'nodeGraph'` (default), `'rack'`, or `'lanes'`, with that look's options. Under rack and lanes, connecting, reconnecting, and deleting work as under node graph, and a stage on the main line drags along it to another place, which rewires the pipeline (`'Reorder'`). Under lanes a lane drags by its label (`'Reorder lanes'`). `editorScene(doc, look, options)` replaces the node-graph-only signature, which is breaking for a caller that passed options second.
337
+
338
+ The effect model gains `chainLinks`, `moveInChain`, and `canMoveInChain`; `EffectDoc.laneOrder` with `setLaneOrder`; `laneTypeOf`; and `order` and `laneOrder` on `EffectLookResult`, which `rack` and `lanes` fill. `@weasel-js/diagram` adds `createSlotReorderAction`, `slotReorderContribution`, and `sequenceSlots`, which drag one item of any drawn sequence along its axis and draw an insertion bar. Core's overlay strokes and routing's `OverlayRole` add the `insert` and `refused` roles that bar draws in.
339
+ - 71d4416: Synthetic-bold text reaches the outline tier. Past the outline threshold, a glyph faked bold from a
340
+ lighter face used to stay on the distance field; it is now drawn as geometry, its outline grown by
341
+ the distance the field's threshold shift moves the edge, so it is as heavy on either side of the
342
+ threshold. A stroked synthetic-bold run, which stayed on the atlas unstroked, is now stroked. A
343
+ grown glyph's `LaidOutOutlineGlyph.d` holds the grown outline, and its `key` names the growth.
344
+
345
+ `@weasel-js/geom` gains `pathToD`, the inverse of `pathFromD`, also exported from `@weasel-js/core`.
346
+ `@weasel-js/svg`'s `serializePathD` is now that function.
347
+ - 1bb4752: Tool sets: a `ToolSet` names a group of tool ids and other sets as one unit (`toolSet`, `toolIdsOf`, `withoutTools`, `toolSetHas`). `<SceneCanvas defaultTools>`, a preset's `tools`, and `ToolPalette`'s `include` each take sets. Core exports one per family, `SELECT_TOOLS`, `VIEW_TOOLS`, `SHAPE_TOOLS`, `DRAW_TOOLS`, `TYPE_TOOLS`, `PAGE_TOOLS` and `RIG_TOOLS`, with `BUILTIN_TOOLS` over them all; `BUILTIN_TOOL_IDS` is derived from it, and a shape kind's new `family` field says which set names it. `@weasel-js/path-tools` exports `WARP_TOOLS`, `RESHAPE_TOOLS`, `PATH_TOOLS_TOOLS`, and `usePathToolsTools()`, which builds every one of its tools keyed by id.
348
+ - e9404d0: A move, resize or rotate keeps its in-flight poses in one place: the scene's pose overrides.
349
+ Their handles no longer answer `previewPose`; `previewIds` still names the nodes in flight, and
350
+ `previewData` still carries what a transform follower previews. The preview ghost
351
+ (`resolvePreviews`) and the selection chrome resolve a previewed id with no `previewPose` through
352
+ `effectivePose`, so they read the same pose picking and derived geometry already did. Code that
353
+ read `previewPose` off one of these handles reads `effectivePose(scene, node)` instead. A
354
+ transform follower that previews a node at a pose other than its own now publishes that pose to
355
+ the overrides too; one answering the node's own pose pins nothing, so a derived node keeps
356
+ deriving.
357
+ - 433540d: A container's unit scope (`ContainerNode.units`) now reaches grid snapping and node property
358
+ fields. A scope converts what is shown, typed and snapped to; every pose is still stored in world
359
+ units, and pose composition does not scale by it.
360
+
361
+ - `gridSnapSource({ scopes: { root, spacing? } })` snaps the subject on the pitch of the unit
362
+ scope its nodes share, so a node inside a millimeter sub-assembly snaps on millimeter spacing.
363
+ `spacing` is read in that scope's units unless `scopes.spacing` gives a pitch per scope.
364
+ `scopedGridPitch` answers the pitch for a chain of scopes.
365
+ - A snap source is told the gesture's subject: `SnapCollect.ids`.
366
+ - `sceneSharedUnitScopes(scene, ids, root)` is the run of unit scopes every node of `ids` sits in.
367
+ - A number leaf takes `measure: 'length'` for a length stored in world units.
368
+ `prefLeafInScopes(leaf, scopes)` gives such a leaf the unit of the scopes it is shown in, built by
369
+ `scopedPrefUnit(scopes)`: shown in the innermost scope's base unit, with every unit of its system
370
+ accepted as typed text. The kit's node schemas mark X, Y, W, H and text padding as lengths.
371
+ - `SelectionPanel` takes `units`, the scene's outermost scope; given it, a length field shows the
372
+ selected nodes' shared scope.
373
+ - Updated dependencies [70b12d1]
374
+ - Updated dependencies [768be71]
375
+ - Updated dependencies [1dd65f5]
376
+ - Updated dependencies [411b629]
377
+ - Updated dependencies [312eb35]
378
+ - Updated dependencies [4d99526]
379
+ - Updated dependencies [853ce69]
380
+ - Updated dependencies [5cdc3d0]
381
+ - Updated dependencies [8c1861a]
382
+ - Updated dependencies [2eb0370]
383
+ - Updated dependencies [e30f4df]
384
+ - Updated dependencies [13fc67f]
385
+ - Updated dependencies [50da815]
386
+ - Updated dependencies [995eac7]
387
+ - Updated dependencies [716561f]
388
+ - Updated dependencies [ee4cf85]
389
+ - Updated dependencies [c497405]
390
+ - Updated dependencies [0e24110]
391
+ - Updated dependencies [c2dfd4e]
392
+ - Updated dependencies [0f455dc]
393
+ - Updated dependencies [15efc86]
394
+ - Updated dependencies [8cd81e7]
395
+ - Updated dependencies [c29ac84]
396
+ - Updated dependencies [07b686c]
397
+ - Updated dependencies [041bc38]
398
+ - Updated dependencies [f819e61]
399
+ - Updated dependencies [2b267d5]
400
+ - Updated dependencies [8f2c044]
401
+ - Updated dependencies [ac892f8]
402
+ - Updated dependencies [71d4416]
403
+ - Updated dependencies [cee04b9]
404
+ - Updated dependencies [e1eeb08]
405
+ - Updated dependencies [f148f50]
406
+ - Updated dependencies [1bb4752]
407
+ - Updated dependencies [e9404d0]
408
+ - Updated dependencies [433540d]
409
+ - @weasel-js/routing@1.11.1
410
+ - @weasel-js/animator@1.11.1
411
+ - @weasel-js/renderer@1.11.1
412
+ - @weasel-js/gestures@1.11.1
413
+ - @weasel-js/history@1.11.1
414
+ - @weasel-js/geom@1.11.1
415
+ - @weasel-js/react@1.11.1
416
+ - @weasel-js/prefs@1.11.1
417
+ - @weasel-js/stroke@1.11.1
418
+ - @weasel-js/font@1.11.1
419
+ - @weasel-js/text@1.11.1
420
+ - @weasel-js/icons@1.11.1
421
+ - @weasel-js/quantity@1.11.1
422
+ - @weasel-js/simulation@1.11.1
423
+ - @weasel-js/text-dom@1.11.1
424
+ - @weasel-js/cursor@1.11.1
425
+ - @weasel-js/modes@1.11.1
426
+ - @weasel-js/paint@1.11.1
427
+ - @weasel-js/registry@1.11.1
428
+ - @weasel-js/select@1.11.1
429
+
3
430
  ## 1.11.0
4
431
 
5
432
  ### Minor Changes
package/README.md CHANGED
@@ -72,7 +72,7 @@ export function Editor() {
72
72
  const selection = useSelection({ mode: 'multi' });
73
73
 
74
74
  // Click to select, drag to move, handles to resize and rotate, the shape and
75
- // text tools, sticky notes, the knife, the bone and weight tools, and the
75
+ // text tools, sticky notes, the knife, and the
76
76
  // standard keyboard actions (Cmd+A, Cmd+Z, Delete, …), all snapping to the grid:
77
77
  return (
78
78
  <SceneCanvas
@@ -1,8 +1,5 @@
1
1
  import { createPoseTarget, poseAxes, scenePoseTarget } from "./poseTarget.js";
2
2
  import { dataRestPath } from "./rig/skinBinding.js";
3
- import { bindRig, rigidRigApply } from "./rig/bindRig.js";
4
- import { useRig } from "./rig/useRig.js";
5
- import { placeSkeleton, rigFromNode, unplaceSkeleton, useRigNode } from "./rig/rigNode.js";
6
3
  import { createDepartures } from "./departures.js";
7
4
  import { bindPoseTransition, glidesByDefault, usePoseTransition } from "./poseTransition.js";
8
5
  import { createWrittenPoseTarget } from "./writtenPoseTarget.js";
@@ -12,6 +9,9 @@ import { animateOnSetPose } from "./wrappers/animateOnSetPose.js";
12
9
  import { animateLifecycle } from "./wrappers/animateLifecycle.js";
13
10
  import { createReflowTransition, useAnimatedReflow } from "./reflow.js";
14
11
  import { momentum } from "./behaviors/momentum.js";
12
+ import { bindRig, rigidRigApply } from "./rig/bindRig.js";
13
+ import { useRig } from "./rig/useRig.js";
14
+ import { placeSkeleton, rigFromNode, unplaceSkeleton, useRigNode } from "./rig/rigNode.js";
15
15
  import { EASINGS, SPRING_PRESETS, cubicBezierEasing, easeIn, easeInBack, easeInBounce, easeInCirc, easeInCubic, easeInElastic, easeInExpo, easeInOut, easeInOutBack, easeInOutBounce, easeInOutCirc, easeInOutCubic, easeInOutElastic, easeInOutExpo, easeInOutQuad, easeInOutQuart, easeInOutQuint, easeInOutSine, easeInQuad, easeInQuart, easeInQuint, easeInSine, easeOut as easeOut$1, easeOutBack, easeOutBounce, easeOutCirc, easeOutCubic as easeOutCubic$1, easeOutElastic, easeOutExpo, easeOutQuad, easeOutQuart, easeOutQuint, easeOutSine, linear, resolveEasing as resolveEasing$1 } from "@weasel-js/geom";
16
16
  import { hexToOklchDeg, hslToSrgb, interpolateSrgb, lerpColorArray, lerpOklab, lerpOklch, linearSrgbToOklab, linearToSrgb, oklabToLinearSrgb, oklabToOklch, oklabToSrgbU8, oklchDegToHex, oklchToOklab, srgbFloatToOklab, srgbToHsl, srgbToLinear, srgbU8ToOklab } from "@weasel-js/paint";
17
17
 
@@ -1,6 +1,6 @@
1
1
  import { AUTO_POSE_DESCRIPTOR } from "../../core/geometry/autoPoseDescriptor.js";
2
- import { createRigSeat } from "./rigSeat.js";
3
2
  import { bindSkins, dataRestPath } from "./skinBinding.js";
3
+ import { createRigSeat } from "./rigSeat.js";
4
4
  import { mat3 } from "@weasel-js/geom";
5
5
  import { resolveSkeleton } from "@weasel-js/animator";
6
6
 
@@ -1 +1 @@
1
- {"version":3,"file":"rigNode.js","names":[],"sources":["../../../src/animation/rig/rigNode.ts"],"sourcesContent":["import { useMemo, useState, useSyncExternalStore } from 'react';\nimport { poseFrameInverseOf, poseFrameOf } from '@weasel-js/geom';\nimport { AUTO_POSE_DESCRIPTOR } from 'core/geometry/autoPoseDescriptor';\nimport type { PoseDescriptor } from '../../core/geometry/poseDescriptor';\nimport type { NodeId } from '../../core/scene/types';\nimport type { BindRigOptions, Rig, RigScene } from './bindRig';\nimport type { Skin } from '@weasel-js/animator';\nimport type { Skeleton } from '@weasel-js/animator';\nimport { createRigSeat } from './rigSeat';\nimport { useSeatedRig } from './useRig';\n\n/** What a rig reads from node data: a `skeleton` on the node that is the rig, and on the nodes\n * under it a `skin` for a path that bends or a `joint` for a node that rides one whole. */\nexport interface RigNodeData {\n /** Joints relative to the node's pose: its box's top-left corner, turned as the node is. */\n skeleton?: Skeleton;\n skin?: Skin;\n joint?: string;\n}\n\n/** Weights to bind in place of the document's, and word of when they change. A `RigEditState`\n * is one: it holds what a stroke of the weight tool has painted and not yet written. */\nexport interface PaintedSkins {\n /** By node. A new map whenever the weights change. */\n painted(): ReadonlyMap<NodeId, Skin>;\n listen(fn: () => void): () => void;\n}\n\n/** The part of a scene `rigFromNode` reads. */\nexport interface RigNodeSource<TPose> {\n get(id: NodeId): { pose: TPose; data?: unknown } | undefined;\n childrenOf(id: NodeId): readonly NodeId[];\n}\n\n/** The skeleton, bindings, and skins a rig node declares, as `bindRig` takes them. */\nexport interface RigNodeParts {\n skeleton: Skeleton;\n bindings: Record<string, NodeId[]>;\n skins: Record<NodeId, Skin>;\n}\n\ninterface Reading extends RigNodeParts {\n /** Every node, pose, and data object the parts were read from, to tell when they are stale. */\n refs: unknown[];\n}\n\ntype Affine = readonly [number, number, number, number, number, number];\nconst through = (m: Affine | null, x: number, y: number): [number, number] =>\n (m ? [m[0] * x + m[2] * y + m[4], m[1] * x + m[3] * y + m[5]] : [x, y]);\n\n/**\n * A skeleton as a rig node's data keeps it, moved to where the node's pose puts it: its root\n * joints are offset from the pose box's top-left corner and turned as the node is. Joints\n * under a root are relative to their parents and are left as they are.\n */\nexport function placeSkeleton<TPose>(\n skeleton: Skeleton,\n pose: TPose,\n descriptor: PoseDescriptor<TPose> = AUTO_POSE_DESCRIPTOR as PoseDescriptor<TPose>,\n): Skeleton {\n const box = descriptor.getBounds(pose);\n const frame = poseFrameOf(pose);\n const turn = descriptor.getRotation?.(pose) ?? 0;\n return {\n joints: skeleton.joints.map((joint) => {\n if (joint.parent != null) return joint;\n const [x, y] = through(frame, box.x + joint.bind.x, box.y + joint.bind.y);\n return { ...joint, bind: { ...joint.bind, x, y, rotation: joint.bind.rotation + turn } };\n }),\n };\n}\n\n/** The inverse of {@link placeSkeleton}: a skeleton in the scene's space, as the node at\n * `pose` would keep it in its data. */\nexport function unplaceSkeleton<TPose>(\n skeleton: Skeleton,\n pose: TPose,\n descriptor: PoseDescriptor<TPose> = AUTO_POSE_DESCRIPTOR as PoseDescriptor<TPose>,\n): Skeleton {\n const box = descriptor.getBounds(pose);\n const inverse = poseFrameInverseOf(pose);\n const turn = descriptor.getRotation?.(pose) ?? 0;\n return {\n joints: skeleton.joints.map((joint) => {\n if (joint.parent != null) return joint;\n const [x, y] = through(inverse, joint.bind.x, joint.bind.y);\n return { ...joint, bind: { ...joint.bind, x: x - box.x, y: y - box.y, rotation: joint.bind.rotation - turn } };\n }),\n };\n}\n\nconst UNPAINTED: ReadonlyMap<NodeId, Skin> = new Map();\nconst noWord = (): (() => void) => () => {};\nconst unpainted = (): ReadonlyMap<NodeId, Skin> => UNPAINTED;\n\nfunction read<TPose>(\n scene: RigNodeSource<TPose>,\n id: NodeId,\n descriptor: PoseDescriptor<TPose>,\n painted: ReadonlyMap<NodeId, Skin> = UNPAINTED,\n): Reading {\n const node = scene.get(id);\n if (!node) throw new Error(`rigFromNode: the rig is node \"${id}\", which the scene lacks.`);\n const local = (node.data as RigNodeData | null | undefined)?.skeleton;\n if (!local) throw new Error(`rigFromNode: node \"${id}\" has no skeleton in its data.`);\n\n const skeleton = placeSkeleton(local, node.pose, descriptor);\n\n const out: Reading = { skeleton, bindings: {}, skins: {}, refs: [node.pose, node.data] };\n const walk = (parent: NodeId): void => {\n for (const child of scene.childrenOf(parent)) {\n const n = scene.get(child);\n if (!n) continue;\n const data = n.data as RigNodeData | null | undefined;\n const skin = painted.get(child) ?? data?.skin;\n out.refs.push(child, n.pose, n.data, skin);\n if (skin) out.skins[child] = skin;\n else if (data?.joint !== undefined) (out.bindings[data.joint] ??= []).push(child);\n walk(child);\n }\n };\n walk(id);\n return out;\n}\n\nconst sameRefs = (a: Reading, b: Reading): boolean =>\n a === b || (a.refs.length === b.refs.length && a.refs.every((r, i) => r === b.refs[i]));\n\n/**\n * Read a rig out of the scene: the skeleton in `id`'s `data.skeleton`, placed by that node's\n * pose, and under it every node whose data has a `skin` or names a `joint`.\n */\nexport function rigFromNode<TPose>(\n scene: RigNodeSource<TPose>,\n id: NodeId,\n descriptor: PoseDescriptor<TPose> = AUTO_POSE_DESCRIPTOR as PoseDescriptor<TPose>,\n): RigNodeParts {\n const { skeleton, bindings, skins } = read(scene, id, descriptor);\n return { skeleton, bindings, skins };\n}\n\n/** Options for `useRigNode`. */\nexport interface UseRigNodeOptions<TPose>\n extends Pick<BindRigOptions<TPose>, 'apply' | 'descriptor' | 'restPath'> {\n scene: RigScene<TPose> & RigNodeSource<TPose> & {\n subscribe(listener: () => void): () => void;\n getVersion(): number;\n };\n /** The node whose data holds the skeleton. */\n node: NodeId;\n /** Weights bound in place of a node's `data.skin` while they are held. Give it the\n * `RigEditState` the weight tool has, and a stroke bends the path as it is painted. */\n painting?: PaintedSkins;\n}\n\n/**\n * A {@link Rig} read from a node, as {@link rigFromNode} reads it. It is bound again when the\n * rig node or a node under it changes its pose or data, or when nodes under it come or go; an\n * edit elsewhere in the scene leaves it alone. A rig bound again keeps its `target`, with the\n * animations running on it, its committed pose, and its placement, unless the skeleton's\n * joints were added, removed, renamed, or reordered. Then it has a new `target`, which takes\n * over the placement and the pose of every joint the skeleton still names. Animations go on\n * running on the target they were started on and show through the new one, so a joint that\n * was renamed stops moving.\n */\nexport function useRigNode<TPose>(options: UseRigNodeOptions<TPose>): Rig {\n const { scene, node, apply, descriptor, restPath, painting } = options;\n const version = useSyncExternalStore(scene.subscribe, scene.getVersion);\n const painted = useSyncExternalStore(painting?.listen ?? noWord, painting?.painted ?? unpainted);\n const next = useMemo(\n () => read(scene, node, descriptor ?? (AUTO_POSE_DESCRIPTOR as PoseDescriptor<TPose>), painted),\n // `version` is what says the scene may answer differently.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [scene, node, descriptor, version, painted],\n );\n // Each read makes new objects; the rig must outlive a read that found nothing changed.\n const [held, setHeld] = useState(next);\n const parts = sameRefs(held, next) ? held : next;\n if (parts !== held) setHeld(next);\n const joints = JSON.stringify(parts.skeleton.joints.map((joint) => joint.name));\n // A pose target's axes are its joints' names in order, so the seat holds while those do,\n // and the next one takes over from it.\n const [seated, setSeated] = useState(() => ({ joints, seat: createRigSeat(parts.skeleton) }));\n let { seat } = seated;\n if (seated.joints !== joints) {\n seat = createRigSeat(parts.skeleton, seated.seat);\n setSeated({ joints, seat });\n }\n return useSeatedRig({\n scene, skeleton: parts.skeleton, bindings: parts.bindings, skins: parts.skins, apply, descriptor, restPath,\n }, seat);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"rigNode.js","names":[],"sources":["../../../src/animation/rig/rigNode.ts"],"sourcesContent":["import { useMemo, useState, useSyncExternalStore } from 'react';\nimport { poseFrameInverseOf, poseFrameOf } from '@weasel-js/geom';\nimport { AUTO_POSE_DESCRIPTOR } from 'core/geometry/autoPoseDescriptor';\nimport type { PoseDescriptor } from '../../core/geometry/poseDescriptor';\nimport type { NodeId } from '../../core/scene/types';\nimport type { BindRigOptions, Rig, RigScene } from './bindRig';\nimport type { Skin } from '@weasel-js/animator';\nimport type { Skeleton } from '@weasel-js/animator';\nimport { createRigSeat } from './rigSeat';\nimport { useSeatedRig } from './useRig';\n\n/** What a rig reads from node data: a `skeleton` on the node that is the rig, and on the nodes\n * under it a `skin` for a path that bends or a `joint` for a node that rides one whole. */\nexport interface RigNodeData {\n /** Joints relative to the node's pose: its box's top-left corner, turned as the node is. */\n skeleton?: Skeleton;\n skin?: Skin;\n joint?: string;\n}\n\n/** Weights to bind in place of the document's, and word of when they change. `@weasel-js/rig`'s\n * `RigEditState` is one: it holds what a stroke of the weight tool has painted and not yet written. */\nexport interface PaintedSkins {\n /** By node. A new map whenever the weights change. */\n painted(): ReadonlyMap<NodeId, Skin>;\n listen(fn: () => void): () => void;\n}\n\n/** The part of a scene `rigFromNode` reads. */\nexport interface RigNodeSource<TPose> {\n get(id: NodeId): { pose: TPose; data?: unknown } | undefined;\n childrenOf(id: NodeId): readonly NodeId[];\n}\n\n/** The skeleton, bindings, and skins a rig node declares, as `bindRig` takes them. */\nexport interface RigNodeParts {\n skeleton: Skeleton;\n bindings: Record<string, NodeId[]>;\n skins: Record<NodeId, Skin>;\n}\n\ninterface Reading extends RigNodeParts {\n /** Every node, pose, and data object the parts were read from, to tell when they are stale. */\n refs: unknown[];\n}\n\ntype Affine = readonly [number, number, number, number, number, number];\nconst through = (m: Affine | null, x: number, y: number): [number, number] =>\n (m ? [m[0] * x + m[2] * y + m[4], m[1] * x + m[3] * y + m[5]] : [x, y]);\n\n/**\n * A skeleton as a rig node's data keeps it, moved to where the node's pose puts it: its root\n * joints are offset from the pose box's top-left corner and turned as the node is. Joints\n * under a root are relative to their parents and are left as they are.\n */\nexport function placeSkeleton<TPose>(\n skeleton: Skeleton,\n pose: TPose,\n descriptor: PoseDescriptor<TPose> = AUTO_POSE_DESCRIPTOR as PoseDescriptor<TPose>,\n): Skeleton {\n const box = descriptor.getBounds(pose);\n const frame = poseFrameOf(pose);\n const turn = descriptor.getRotation?.(pose) ?? 0;\n return {\n joints: skeleton.joints.map((joint) => {\n if (joint.parent != null) return joint;\n const [x, y] = through(frame, box.x + joint.bind.x, box.y + joint.bind.y);\n return { ...joint, bind: { ...joint.bind, x, y, rotation: joint.bind.rotation + turn } };\n }),\n };\n}\n\n/** The inverse of {@link placeSkeleton}: a skeleton in the scene's space, as the node at\n * `pose` would keep it in its data. */\nexport function unplaceSkeleton<TPose>(\n skeleton: Skeleton,\n pose: TPose,\n descriptor: PoseDescriptor<TPose> = AUTO_POSE_DESCRIPTOR as PoseDescriptor<TPose>,\n): Skeleton {\n const box = descriptor.getBounds(pose);\n const inverse = poseFrameInverseOf(pose);\n const turn = descriptor.getRotation?.(pose) ?? 0;\n return {\n joints: skeleton.joints.map((joint) => {\n if (joint.parent != null) return joint;\n const [x, y] = through(inverse, joint.bind.x, joint.bind.y);\n return { ...joint, bind: { ...joint.bind, x: x - box.x, y: y - box.y, rotation: joint.bind.rotation - turn } };\n }),\n };\n}\n\nconst UNPAINTED: ReadonlyMap<NodeId, Skin> = new Map();\nconst noWord = (): (() => void) => () => {};\nconst unpainted = (): ReadonlyMap<NodeId, Skin> => UNPAINTED;\n\nfunction read<TPose>(\n scene: RigNodeSource<TPose>,\n id: NodeId,\n descriptor: PoseDescriptor<TPose>,\n painted: ReadonlyMap<NodeId, Skin> = UNPAINTED,\n): Reading {\n const node = scene.get(id);\n if (!node) throw new Error(`rigFromNode: the rig is node \"${id}\", which the scene lacks.`);\n const local = (node.data as RigNodeData | null | undefined)?.skeleton;\n if (!local) throw new Error(`rigFromNode: node \"${id}\" has no skeleton in its data.`);\n\n const skeleton = placeSkeleton(local, node.pose, descriptor);\n\n const out: Reading = { skeleton, bindings: {}, skins: {}, refs: [node.pose, node.data] };\n const walk = (parent: NodeId): void => {\n for (const child of scene.childrenOf(parent)) {\n const n = scene.get(child);\n if (!n) continue;\n const data = n.data as RigNodeData | null | undefined;\n const skin = painted.get(child) ?? data?.skin;\n out.refs.push(child, n.pose, n.data, skin);\n if (skin) out.skins[child] = skin;\n else if (data?.joint !== undefined) (out.bindings[data.joint] ??= []).push(child);\n walk(child);\n }\n };\n walk(id);\n return out;\n}\n\nconst sameRefs = (a: Reading, b: Reading): boolean =>\n a === b || (a.refs.length === b.refs.length && a.refs.every((r, i) => r === b.refs[i]));\n\n/**\n * Read a rig out of the scene: the skeleton in `id`'s `data.skeleton`, placed by that node's\n * pose, and under it every node whose data has a `skin` or names a `joint`.\n */\nexport function rigFromNode<TPose>(\n scene: RigNodeSource<TPose>,\n id: NodeId,\n descriptor: PoseDescriptor<TPose> = AUTO_POSE_DESCRIPTOR as PoseDescriptor<TPose>,\n): RigNodeParts {\n const { skeleton, bindings, skins } = read(scene, id, descriptor);\n return { skeleton, bindings, skins };\n}\n\n/** Options for `useRigNode`. */\nexport interface UseRigNodeOptions<TPose>\n extends Pick<BindRigOptions<TPose>, 'apply' | 'descriptor' | 'restPath'> {\n scene: RigScene<TPose> & RigNodeSource<TPose> & {\n subscribe(listener: () => void): () => void;\n getVersion(): number;\n };\n /** The node whose data holds the skeleton. */\n node: NodeId;\n /** Weights bound in place of a node's `data.skin` while they are held. Give it the\n * `RigEditState` `@weasel-js/rig`'s weight tool has, and a stroke bends the path as it is painted. */\n painting?: PaintedSkins;\n}\n\n/**\n * A {@link Rig} read from a node, as {@link rigFromNode} reads it. It is bound again when the\n * rig node or a node under it changes its pose or data, or when nodes under it come or go; an\n * edit elsewhere in the scene leaves it alone. A rig bound again keeps its `target`, with the\n * animations running on it, its committed pose, and its placement, unless the skeleton's\n * joints were added, removed, renamed, or reordered. Then it has a new `target`, which takes\n * over the placement and the pose of every joint the skeleton still names. Animations go on\n * running on the target they were started on and show through the new one, so a joint that\n * was renamed stops moving.\n */\nexport function useRigNode<TPose>(options: UseRigNodeOptions<TPose>): Rig {\n const { scene, node, apply, descriptor, restPath, painting } = options;\n const version = useSyncExternalStore(scene.subscribe, scene.getVersion);\n const painted = useSyncExternalStore(painting?.listen ?? noWord, painting?.painted ?? unpainted);\n const next = useMemo(\n () => read(scene, node, descriptor ?? (AUTO_POSE_DESCRIPTOR as PoseDescriptor<TPose>), painted),\n // `version` is what says the scene may answer differently.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [scene, node, descriptor, version, painted],\n );\n // Each read makes new objects; the rig must outlive a read that found nothing changed.\n const [held, setHeld] = useState(next);\n const parts = sameRefs(held, next) ? held : next;\n if (parts !== held) setHeld(next);\n const joints = JSON.stringify(parts.skeleton.joints.map((joint) => joint.name));\n // A pose target's axes are its joints' names in order, so the seat holds while those do,\n // and the next one takes over from it.\n const [seated, setSeated] = useState(() => ({ joints, seat: createRigSeat(parts.skeleton) }));\n let { seat } = seated;\n if (seated.joints !== joints) {\n seat = createRigSeat(parts.skeleton, seated.seat);\n setSeated({ joints, seat });\n }\n return useSeatedRig({\n scene, skeleton: parts.skeleton, bindings: parts.bindings, skins: parts.skins, apply, descriptor, restPath,\n }, seat);\n}\n"],"mappings":"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"}
@@ -6,12 +6,15 @@ import { OVERLAY_ROLE_STROKES } from "../canvas/overlayRoleStrokes.js";
6
6
  import { DEFAULT_INK, findNodeShape, findShapeBounds, findShapeInk, findShapeSilhouette, getNodeShapes, registerNodeShape, shapeCoversPoint } from "../canvas/NodeShape.js";
7
7
  import { drawnAABBOf, drawnBoundsOf, findShapeDrawnBounds, inkExtentsOf } from "../canvas/drawnBounds.js";
8
8
  import { insertPreviewExtent } from "../canvas/insertPreviewExtent.js";
9
+ import { CANVAS_CONTEXT_ATTRIBUTES } from "../canvas/contextAttributes.js";
9
10
  import { isOverChildren, overChildren, splitOverChildren } from "../canvas/overChildren.js";
11
+ import { drawnBoundsScene } from "../canvas/derivedPath.js";
10
12
  import { sceneToAdapter } from "../canvas/sceneAdapter.js";
11
13
  import { defaultDrawOne, defaultPaintBounds } from "../canvas/defaultDrawOne.js";
12
14
  import { DEFAULT_DEBUG_STROKES, DEFAULT_DEBUG_THEME } from "../debug/defaultTheme.js";
13
15
  import { buildDebugOverlayCommands, createDebugOverlayLayer } from "../debug/createDebugOverlayLayer.js";
14
16
  import { minSizeOf } from "../core/scene/minSize.js";
17
+ import { DEBUG_FEATURES } from "../debug/features.js";
15
18
  import { parseDebugFlags } from "../debug/parseDebugFlags.js";
16
19
  import { createDebugSink } from "../debug/createDebugSink.js";
17
20
  import { registerContentHandler } from "../features/ingestion/contentHandlers.js";
@@ -20,12 +23,13 @@ import { useHostAnchor } from "../canvas/useHostAnchor.js";
20
23
  import { CursorCoordsHud } from "../canvas/CursorCoordsHud.js";
21
24
  import { PickHud } from "../canvas/PickHud.js";
22
25
  import { PATH_OVERLAY_ROLES, createPathOverlay } from "../canvas/pathOverlay.js";
26
+ import { DevtoolsLabel, useDevtoolsLabel } from "../devtools/label.js";
27
+ import { defaultNodeRouting, groupNodeRouting, inferredNodeRouting } from "../canvas/SceneCanvas/defaultNodeRouting.js";
23
28
  import { DEFAULT_HANDLE_SIZE } from "../canvas/SceneCanvas/props.js";
24
29
  import { resolveOverlays } from "../interactions/actions/resolveOverlays.js";
25
30
  import { flattenPreviews, resolvePreviews } from "../interactions/actions/resolvePreviews.js";
26
31
  import { useSceneAdapter } from "../canvas/useSceneAdapter.js";
27
- import { createNodeRouting } from "../core/scene/NodeRouting.js";
28
- import { defaultNodeRouting, groupNodeRouting, inferredNodeRouting } from "../canvas/SceneCanvas/defaultNodeRouting.js";
32
+ import { createNodeRouting, routeKind } from "../core/scene/NodeRouting.js";
29
33
  import { SceneCanvas } from "../canvas/SceneCanvas.js";
30
34
  import { LeanSceneCanvas } from "../canvas/LeanSceneCanvas.js";
31
35
  import { createNodeProperties } from "../core/scene/NodeProperties.js";
@@ -38,4 +42,4 @@ import { modeTriggers } from "../features/modes/modeTriggers.js";
38
42
  import { createChildrenLayer } from "../core/layers/children.js";
39
43
  import { bitmapSrc, getImageBitmap as getImageBitmap$1, imageStatus as imageStatus$1, isVectorImageSrc, releaseImage, retryImage, setImageCacheBudget, subscribeImageReady as subscribeImageReady$1 } from "@weasel-js/renderer";
40
44
 
41
- export { CursorCoordsHud, DEFAULT_DEBUG_STROKES, DEFAULT_DEBUG_THEME, DEFAULT_HANDLE_SIZE, DEFAULT_INK, DEFAULT_LAYER_RETAIN, LeanSceneCanvas, OVERLAY_ROLE_STROKES, PATH_OVERLAY_ROLES, PickHud, SceneCanvas, WeaselProvider, bitmapSrc, buildDebugOverlayCommands, createChildrenLayer, createDebugOverlayLayer, createDebugSink, createNodeProperties, createNodeRouting, createPathOverlay, defaultDrawOne, defaultNodeProperties, defaultNodeRouting, defaultPaintBounds, depsUnchanged, dlog, drawLayers, drawOneLayer, drawnAABBOf, drawnBoundsOf, dwarn, findNodeShape, findShapeBounds, findShapeDrawnBounds, findShapeInk, findShapeSilhouette, flattenPreviews, getImageBitmap$1 as getImageBitmap, getNodeShapes, groupNodeRouting, hostAnchorCss, hostAnchorRect, imageStatus$1 as imageStatus, inferredNodeProperties, inferredNodeRouting, inkExtentsOf, insertPreviewExtent, isDebugEnabled, isLayerPainted, isLayerVisible, isOverChildren, isVectorImageSrc, kitTextHandler, minSizeOf, modeDecorationLayer, modeTriggers, openFilePicker, overChildren, paintedLayers, parseDebugFlags, registerContentHandler, registerNodeShape, releaseImage, resolveOverlays, resolvePreviews, retryImage, rotationDegreesUnit, sceneToAdapter, setImageCacheBudget, shapeCoversPoint, splitOverChildren, subscribeImageReady$1 as subscribeImageReady, subscribeToSources, useHostAnchor, useSceneAdapter, workspaceTintLayer };
45
+ export { CANVAS_CONTEXT_ATTRIBUTES, CursorCoordsHud, DEBUG_FEATURES, DEFAULT_DEBUG_STROKES, DEFAULT_DEBUG_THEME, DEFAULT_HANDLE_SIZE, DEFAULT_INK, DEFAULT_LAYER_RETAIN, DevtoolsLabel, LeanSceneCanvas, OVERLAY_ROLE_STROKES, PATH_OVERLAY_ROLES, PickHud, SceneCanvas, WeaselProvider, bitmapSrc, buildDebugOverlayCommands, createChildrenLayer, createDebugOverlayLayer, createDebugSink, createNodeProperties, createNodeRouting, createPathOverlay, defaultDrawOne, defaultNodeProperties, defaultNodeRouting, defaultPaintBounds, depsUnchanged, dlog, drawLayers, drawOneLayer, drawnAABBOf, drawnBoundsOf, drawnBoundsScene, dwarn, findNodeShape, findShapeBounds, findShapeDrawnBounds, findShapeInk, findShapeSilhouette, flattenPreviews, getImageBitmap$1 as getImageBitmap, getNodeShapes, groupNodeRouting, hostAnchorCss, hostAnchorRect, imageStatus$1 as imageStatus, inferredNodeProperties, inferredNodeRouting, inkExtentsOf, insertPreviewExtent, isDebugEnabled, isLayerPainted, isLayerVisible, isOverChildren, isVectorImageSrc, kitTextHandler, minSizeOf, modeDecorationLayer, modeTriggers, openFilePicker, overChildren, paintedLayers, parseDebugFlags, registerContentHandler, registerNodeShape, releaseImage, resolveOverlays, resolvePreviews, retryImage, rotationDegreesUnit, routeKind, sceneToAdapter, setImageCacheBudget, shapeCoversPoint, splitOverChildren, subscribeImageReady$1 as subscribeImageReady, subscribeToSources, useDevtoolsLabel, useHostAnchor, useSceneAdapter, workspaceTintLayer };