@weasel-js/core 1.15.0 → 1.15.2

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 (838) hide show
  1. package/CHANGELOG.md +199 -0
  2. package/dist/WeaselProvider.js +4 -5
  3. package/dist/affordances/composeAffordanceLayer.js +1 -2
  4. package/dist/affordances/cornerResize.js +4 -5
  5. package/dist/affordances/hitAffordanceRegions.js +1 -2
  6. package/dist/affordances/pathAnchors.js +1 -2
  7. package/dist/affordances/rotateCursor.js +1 -2
  8. package/dist/affordances/rotationHandle.js +2 -3
  9. package/dist/animation/behaviors/coast.js +1 -2
  10. package/dist/animation/behaviors/coastByWrite.js +2 -3
  11. package/dist/animation/behaviors/coastOnTargets.js +2 -3
  12. package/dist/animation/behaviors/momentum.js +1 -2
  13. package/dist/animation/clipTargets.js +1 -2
  14. package/dist/animation/departures.js +2 -3
  15. package/dist/animation/poseHelpers.js +2 -3
  16. package/dist/animation/poseTarget.js +5 -6
  17. package/dist/animation/poseTarget.js.map +1 -1
  18. package/dist/animation/poseTransition.js +1 -2
  19. package/dist/animation/reflow.js +9 -10
  20. package/dist/animation/reflow.js.map +1 -1
  21. package/dist/animation/rewind.js +1 -2
  22. package/dist/animation/rig/bindRig.js +2 -3
  23. package/dist/animation/rig/rigNode.js +3 -4
  24. package/dist/animation/rig/rigNode.js.map +1 -1
  25. package/dist/animation/rig/rigSeat.js +1 -2
  26. package/dist/animation/rig/skinBinding.js +1 -2
  27. package/dist/animation/rig/useRig.js +2 -3
  28. package/dist/animation/wrappers/animateLifecycle.js +1 -2
  29. package/dist/animation/wrappers/animateOnSetPose.js +1 -2
  30. package/dist/animation/wrappers/instantPose.js +1 -2
  31. package/dist/animation/writtenPoseTarget.js +1 -2
  32. package/dist/barrel/input.js +2 -1
  33. package/dist/barrel/interactions.js +2 -1
  34. package/dist/barrel/paint.js +2 -2
  35. package/dist/barrel/routing.js +2 -2
  36. package/dist/barrel/scene.js +2 -2
  37. package/dist/barrel/viewport.js +3 -3
  38. package/dist/canvas/Canvas.js +5 -6
  39. package/dist/canvas/CanvasView.js +6 -7
  40. package/dist/canvas/CursorCoordsHud.js +2 -3
  41. package/dist/canvas/DrawCanvas.js +3 -4
  42. package/dist/canvas/GestureReason.js +1 -2
  43. package/dist/canvas/GestureReason.module.js +1 -2
  44. package/dist/canvas/LeanSceneCanvas.js +2 -3
  45. package/dist/canvas/ModalityHud.js +2 -3
  46. package/dist/canvas/NodeShape.js +3 -4
  47. package/dist/canvas/PickHud.js +2 -3
  48. package/dist/canvas/SceneCanvas/ActionsProviderIfRoot.js +1 -2
  49. package/dist/canvas/SceneCanvas/CanvasKitProviders.js +3 -4
  50. package/dist/canvas/SceneCanvas/DepRegistryProviderIfRoot.js +1 -2
  51. package/dist/canvas/SceneCanvas/DevHuds.js +1 -2
  52. package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js +18 -66
  53. package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js.map +1 -1
  54. package/dist/canvas/SceneCanvas/SceneCanvasInput.js +4 -5
  55. package/dist/canvas/SceneCanvas/SurfaceDeclarations.js +1 -2
  56. package/dist/canvas/SceneCanvas/brushOverlay.js +1 -2
  57. package/dist/canvas/SceneCanvas/builtinToolSets.js +1 -2
  58. package/dist/canvas/SceneCanvas/canvasPassThrough.js +1 -2
  59. package/dist/canvas/SceneCanvas/contributionFrameHooks.js +1 -2
  60. package/dist/canvas/SceneCanvas/coordTrace.js +1 -2
  61. package/dist/canvas/SceneCanvas/defaultNodeProperties.js +3 -4
  62. package/dist/canvas/SceneCanvas/defaultNodeRouting.js +1 -2
  63. package/dist/canvas/SceneCanvas/defaultTextEditor.js +4 -5
  64. package/dist/canvas/SceneCanvas/describePresets.js +1 -2
  65. package/dist/canvas/SceneCanvas/dispatcherGestureBounds.js +1 -2
  66. package/dist/canvas/SceneCanvas/features.js +1 -2
  67. package/dist/canvas/SceneCanvas/insertPreviewCommands.js +1 -2
  68. package/dist/canvas/SceneCanvas/mergeLayers.js +1 -2
  69. package/dist/canvas/SceneCanvas/namedPresets.js +5 -6
  70. package/dist/canvas/SceneCanvas/poseGeometry.js +1 -2
  71. package/dist/canvas/SceneCanvas/poseRegistrars.js +1 -2
  72. package/dist/canvas/SceneCanvas/presets/arrange.js +2 -3
  73. package/dist/canvas/SceneCanvas/presets/baseline.js +1 -2
  74. package/dist/canvas/SceneCanvas/presets/chrome.js +1 -2
  75. package/dist/canvas/SceneCanvas/presets/composites.js +1 -2
  76. package/dist/canvas/SceneCanvas/presets/edit.js +4 -5
  77. package/dist/canvas/SceneCanvas/presets/ingest.js +1 -2
  78. package/dist/canvas/SceneCanvas/presets/paths.js +3 -4
  79. package/dist/canvas/SceneCanvas/presets/select.js +1 -2
  80. package/dist/canvas/SceneCanvas/presets/toolDriven.js +2 -3
  81. package/dist/canvas/SceneCanvas/presets/tools.js +1 -2
  82. package/dist/canvas/SceneCanvas/presets/transform.js +2 -3
  83. package/dist/canvas/SceneCanvas/presets/view.js +2 -3
  84. package/dist/canvas/SceneCanvas/props.js +1 -2
  85. package/dist/canvas/SceneCanvas/scenePointQuery.js +2 -3
  86. package/dist/canvas/SceneCanvas/shapeGeneratorProperties.js +1 -2
  87. package/dist/canvas/SceneCanvas/toolRegistry.js +2 -3
  88. package/dist/canvas/SceneCanvas/useActionTunings.js +1 -2
  89. package/dist/canvas/SceneCanvas/useActionsPropResolver.js +1 -2
  90. package/dist/canvas/SceneCanvas/useBakedScene.js +2 -3
  91. package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js +7 -8
  92. package/dist/canvas/SceneCanvas/useBuiltinTools.js +2 -3
  93. package/dist/canvas/SceneCanvas/useCanvasCamera.js +2 -3
  94. package/dist/canvas/SceneCanvas/useCanvasDevtoolsRoot.js +1 -2
  95. package/dist/canvas/SceneCanvas/useCanvasDispatcher.js +1 -2
  96. package/dist/canvas/SceneCanvas/useCanvasSelection.js +8 -6
  97. package/dist/canvas/SceneCanvas/useCanvasSelection.js.map +1 -1
  98. package/dist/canvas/SceneCanvas/useCanvasTools.js +2 -3
  99. package/dist/canvas/SceneCanvas/useChromeAffordances.js +2 -3
  100. package/dist/canvas/SceneCanvas/useContributionRoles.js +1 -2
  101. package/dist/canvas/SceneCanvas/useDepartureGhostLayer.js +4 -5
  102. package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js +2 -3
  103. package/dist/canvas/SceneCanvas/useHeldModifiers.js +1 -2
  104. package/dist/canvas/SceneCanvas/useMagnificationCheck.js +41 -0
  105. package/dist/canvas/SceneCanvas/useMagnificationCheck.js.map +1 -0
  106. package/dist/canvas/SceneCanvas/useNodeAtPoint.js +1 -2
  107. package/dist/canvas/SceneCanvas/useNodeKinds.js +2 -3
  108. package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js +10 -11
  109. package/dist/canvas/SceneCanvas/useSceneCanvasHandle.js +1 -2
  110. package/dist/canvas/SceneCanvas/useSceneCanvasLayers.js +6 -7
  111. package/dist/canvas/SceneCanvas/useSceneCanvasPathEdit.js +1 -2
  112. package/dist/canvas/SceneCanvas/useSceneCanvasTools.js +1 -2
  113. package/dist/canvas/SceneCanvas/useSceneChrome.js +5 -6
  114. package/dist/canvas/SceneCanvas/useSceneGestureDispatcher.js +6 -7
  115. package/dist/canvas/SceneCanvas/useScenePicking.js +5 -6
  116. package/dist/canvas/SceneCanvas/useSceneRedrawSources.js +1 -2
  117. package/dist/canvas/SceneCanvas/useSceneSelectTool.js +7 -8
  118. package/dist/canvas/SceneCanvas/useSceneSlotLayers.js +2 -3
  119. package/dist/canvas/SceneCanvas/useSceneStandardActions.js +26 -18
  120. package/dist/canvas/SceneCanvas/useSceneStandardActions.js.map +1 -1
  121. package/dist/canvas/SceneCanvas/useSelectionOverlayLayer.js +2 -3
  122. package/dist/canvas/SceneCanvas/useSurfaceRouting.js +1 -2
  123. package/dist/canvas/SceneCanvas/useSurfaceViewInputs.js +1 -2
  124. package/dist/canvas/SceneCanvas/useToolKeybindings.js +1 -2
  125. package/dist/canvas/SceneCanvas/useViewportActions.js +3 -4
  126. package/dist/canvas/SceneCanvas/worldPointAt.js +1 -2
  127. package/dist/canvas/SceneCanvas.js +18 -17
  128. package/dist/canvas/SceneCanvas.js.map +1 -1
  129. package/dist/canvas/SceneViewCanvas.js +2 -3
  130. package/dist/canvas/SurfaceCanvas.js +1 -2
  131. package/dist/canvas/ViewMarker.js +1 -2
  132. package/dist/canvas/accentColor.js +4 -5
  133. package/dist/canvas/accentColor.js.map +1 -1
  134. package/dist/canvas/adapterDerivedPath.js +2 -3
  135. package/dist/canvas/adapterPickSource.js +1 -2
  136. package/dist/canvas/affordanceAt.js +2 -3
  137. package/dist/canvas/buildSceneLayer.js +4 -5
  138. package/dist/canvas/buildSceneTree.js +4 -5
  139. package/dist/canvas/canvasRenderer.js +1 -2
  140. package/dist/canvas/colorOverrides.js +1 -2
  141. package/dist/canvas/contextAttributes.js +1 -2
  142. package/dist/canvas/copiesAbove.js +1 -2
  143. package/dist/canvas/defaultDrawOne.js +1 -2
  144. package/dist/canvas/deps/areaSelect.js +5 -3
  145. package/dist/canvas/deps/areaSelect.js.map +1 -1
  146. package/dist/canvas/deps/booleans.js +5 -6
  147. package/dist/canvas/deps/changes.js +1 -2
  148. package/dist/canvas/deps/chromeRules.js +1 -2
  149. package/dist/canvas/deps/debug.js +1 -2
  150. package/dist/canvas/deps/dispatchSources.js +1 -2
  151. package/dist/canvas/deps/dispatcher.js +1 -2
  152. package/dist/canvas/deps/editAnchors.js +3 -4
  153. package/dist/canvas/deps/enteredGroup.js +6 -6
  154. package/dist/canvas/deps/enteredGroup.js.map +1 -1
  155. package/dist/canvas/deps/geometryProjection.js +1 -2
  156. package/dist/canvas/deps/hitTestArea.js +4 -5
  157. package/dist/canvas/deps/ingestion.js +1 -2
  158. package/dist/canvas/deps/insert.js +3 -4
  159. package/dist/canvas/deps/insertSite.js +3 -4
  160. package/dist/canvas/deps/kitSettings.js +1 -2
  161. package/dist/canvas/deps/lassoSelect.js +5 -3
  162. package/dist/canvas/deps/lassoSelect.js.map +1 -1
  163. package/dist/canvas/deps/layout.js +1 -2
  164. package/dist/canvas/deps/modeDefaultTool.js +1 -2
  165. package/dist/canvas/deps/nodeAtPoint.js +1 -2
  166. package/dist/canvas/deps/pathEditCommits.js +4 -5
  167. package/dist/canvas/deps/pathLeaf.js +1 -2
  168. package/dist/canvas/deps/pathLeafDeps.js +2 -3
  169. package/dist/canvas/deps/poseDescriptor.js +1 -2
  170. package/dist/canvas/deps/previewPaths.js +1 -2
  171. package/dist/canvas/deps/resizePolicy.js +1 -2
  172. package/dist/canvas/deps/selectionSnapshot.js +8 -4
  173. package/dist/canvas/deps/selectionSnapshot.js.map +1 -1
  174. package/dist/canvas/deps/slice.js +5 -6
  175. package/dist/canvas/deps/snap.js +3 -4
  176. package/dist/canvas/deps/surface.js +1 -2
  177. package/dist/canvas/deps/textEdit.js +1 -2
  178. package/dist/canvas/deps/transformFollowers.js +1 -2
  179. package/dist/canvas/deps/view.js +1 -2
  180. package/dist/canvas/derivedPath.js +6 -7
  181. package/dist/canvas/doubleClickTarget.js +1 -2
  182. package/dist/canvas/drawEnvelope.js +1 -2
  183. package/dist/canvas/drawnBounds.js +4 -5
  184. package/dist/canvas/getNodeAtPoint.js +1 -2
  185. package/dist/canvas/hostAnchor.js +1 -2
  186. package/dist/canvas/hud.module.js +1 -2
  187. package/dist/canvas/inheritedPaints.js +1 -2
  188. package/dist/canvas/insertPreviewExtent.js +1 -2
  189. package/dist/canvas/kitRequirements.js +1 -2
  190. package/dist/canvas/layerHover.js +1 -2
  191. package/dist/canvas/layerOrder.js +1 -2
  192. package/dist/canvas/layerSlots.js +1 -2
  193. package/dist/canvas/mountedCanvases.js +1 -2
  194. package/dist/canvas/nodeShapes/derivedPainter.js +2 -3
  195. package/dist/canvas/nodeShapes/imagePainter.js +1 -2
  196. package/dist/canvas/nodeShapes/measurePainter.js +2 -3
  197. package/dist/canvas/nodeShapes/memo.js +1 -2
  198. package/dist/canvas/nodeShapes/nodePaint.js +1 -2
  199. package/dist/canvas/nodeShapes/pathPainter.js +3 -4
  200. package/dist/canvas/nodeShapes/poseBox.js +1 -2
  201. package/dist/canvas/nodeShapes/rectFallbackPainter.js +1 -2
  202. package/dist/canvas/nodeShapes/shapePainter.js +2 -3
  203. package/dist/canvas/nodeShapes/strokedBounds.js +1 -2
  204. package/dist/canvas/nodeShapes/textPainter.js +1 -2
  205. package/dist/canvas/overChildren.js +1 -2
  206. package/dist/canvas/overlayRoleStrokes.js +1 -2
  207. package/dist/canvas/ownClip.js +1 -2
  208. package/dist/canvas/paintCull.js +1 -2
  209. package/dist/canvas/paintedCursorLayer.js +1 -2
  210. package/dist/canvas/pathOverlay.js +1 -2
  211. package/dist/canvas/pickIndex/nodeBroadBox.js +3 -4
  212. package/dist/canvas/pickIndex/scenePickIndex.js +3 -4
  213. package/dist/canvas/pickReach.js +1 -2
  214. package/dist/canvas/pickWalk.js +2 -3
  215. package/dist/canvas/planeClips.js +1 -2
  216. package/dist/canvas/poseRotation.js +1 -2
  217. package/dist/canvas/publishPreviews.js +1 -2
  218. package/dist/canvas/rasterReadback.js +1 -2
  219. package/dist/canvas/rasterToPng.js +1 -2
  220. package/dist/canvas/renderDebugSnapshot.js +1 -2
  221. package/dist/canvas/renderNeeds.js +1 -2
  222. package/dist/canvas/renderSceneToPixels.js +5 -6
  223. package/dist/canvas/sceneAdapter.js +37 -27
  224. package/dist/canvas/sceneAdapter.js.map +1 -1
  225. package/dist/canvas/sceneClipboard.js +19 -7
  226. package/dist/canvas/sceneClipboard.js.map +1 -1
  227. package/dist/canvas/sceneLayerPaint.js +1 -2
  228. package/dist/canvas/scenePickReads.js +1 -2
  229. package/dist/canvas/scenePickSource.js +5 -6
  230. package/dist/canvas/sceneSlotWiring.js +2 -3
  231. package/dist/canvas/sceneViewRender.js +5 -6
  232. package/dist/canvas/shownNodes.js +1 -2
  233. package/dist/canvas/slopsDebugLayer.js +9 -4
  234. package/dist/canvas/slopsDebugLayer.js.map +1 -1
  235. package/dist/canvas/surfaceContribution.js +1 -2
  236. package/dist/canvas/useCanvasElements.js +1 -2
  237. package/dist/canvas/useCanvasHandle.js +1 -2
  238. package/dist/canvas/useCanvasPaint.js +2 -3
  239. package/dist/canvas/useCanvasRenderer.js +1 -2
  240. package/dist/canvas/useCanvasSurface.js +1 -2
  241. package/dist/canvas/useCanvasView.js +2 -3
  242. package/dist/canvas/useClientToWorld.js +1 -2
  243. package/dist/canvas/useExtraLayers.js +1 -2
  244. package/dist/canvas/useFrameLoop.js +1 -2
  245. package/dist/canvas/useHitObserver.js +1 -2
  246. package/dist/canvas/useHostAnchor.js +1 -2
  247. package/dist/canvas/useInFlightBounds.js +6 -6
  248. package/dist/canvas/useInFlightBounds.js.map +1 -1
  249. package/dist/canvas/useLateContentRedraw.js +1 -2
  250. package/dist/canvas/useLayerStack.js +2 -3
  251. package/dist/canvas/usePaintedCursor.js +1 -2
  252. package/dist/canvas/useRedrawOn.js +1 -2
  253. package/dist/canvas/useSceneAdapter.js +1 -2
  254. package/dist/canvas/useSceneLayerList.js +1 -2
  255. package/dist/canvas/useSurfaceInput.js +1 -2
  256. package/dist/canvas/useSurfaceSize.js +1 -2
  257. package/dist/canvas/useToolCursor.js +1 -2
  258. package/dist/canvas/useViewAim.js +2 -3
  259. package/dist/canvas/useViewHelpers.js +5 -4
  260. package/dist/canvas/useViewHelpers.js.map +1 -1
  261. package/dist/canvas/useViewLayerGate.js +1 -2
  262. package/dist/canvas/useViewNesting.js +1 -2
  263. package/dist/canvas/useViewRegistrySurface.js +7 -5
  264. package/dist/canvas/useViewRegistrySurface.js.map +1 -1
  265. package/dist/canvas/viewInputs.js +1 -2
  266. package/dist/canvas/viewMarkers.js +1 -2
  267. package/dist/canvas/viewRegistry.js +6 -7
  268. package/dist/canvas/viewRegistry.js.map +1 -1
  269. package/dist/canvas/viewSnap.js +1 -2
  270. package/dist/canvas/watchElementMove.js +1 -2
  271. package/dist/canvas/wrapNodeOutput.js +1 -2
  272. package/dist/core/adapters/testing/rootsTree.js +1 -2
  273. package/dist/core/applyOps.js +1 -2
  274. package/dist/core/device/targets.js +1 -2
  275. package/dist/core/device/useDeviceProfile.js +1 -2
  276. package/dist/core/device/useTargetBasePx.js +1 -2
  277. package/dist/core/device/watchDevicePixelRatio.js +1 -2
  278. package/dist/core/geometry/autoPoseDescriptor.js +2 -3
  279. package/dist/core/geometry/booleanOfPaths.js +1 -2
  280. package/dist/core/geometry/inkExtents.js +1 -2
  281. package/dist/core/geometry/pathPoseDescriptor.js +1 -2
  282. package/dist/core/geometry/poseDescriptor.js +1 -2
  283. package/dist/core/geometry/regionHit.js +1 -2
  284. package/dist/core/geometry/targetFrame.js +1 -2
  285. package/dist/core/geometry/unionBounds.js +1 -2
  286. package/dist/core/layers/backgroundFill.js +1 -2
  287. package/dist/core/layers/children.js +1 -2
  288. package/dist/core/layers/gateLayer.js +1 -2
  289. package/dist/core/layers/layerGroup.js +1 -2
  290. package/dist/core/layers/redrawSource.js +1 -2
  291. package/dist/core/layers/render.js +1 -2
  292. package/dist/core/layers/retain.js +1 -2
  293. package/dist/core/ops/arrange.js +1 -2
  294. package/dist/core/ops/create.js +2 -3
  295. package/dist/core/ops/createHistory.js +2 -3
  296. package/dist/core/ops/delete.js +2 -3
  297. package/dist/core/ops/nodeFlags.js +1 -2
  298. package/dist/core/ops/registry.js +1 -2
  299. package/dist/core/ops/reorder/algorithms.js +1 -2
  300. package/dist/core/ops/reorder/index.js +3 -8
  301. package/dist/core/ops/reorder/index.js.map +1 -1
  302. package/dist/core/ops/reorder/setChildOrder.js +1 -2
  303. package/dist/core/ops/reparent.js +1 -2
  304. package/dist/core/ops/select.js +1 -2
  305. package/dist/core/ops/setData.js +1 -2
  306. package/dist/core/ops/setDependsOn.js +1 -2
  307. package/dist/core/ops/setLayer.js +1 -2
  308. package/dist/core/ops/setLayout.js +1 -2
  309. package/dist/core/ops/setPath.js +1 -2
  310. package/dist/core/ops/setText.js +1 -2
  311. package/dist/core/ops/slot.js +1 -2
  312. package/dist/core/ops/transform.js +1 -2
  313. package/dist/core/ops/writtenBy.js +1 -2
  314. package/dist/core/pages/fitViewToPage.js +3 -9
  315. package/dist/core/pages/fitViewToPage.js.map +1 -1
  316. package/dist/core/pages/pageEdits.js +3 -4
  317. package/dist/core/pages/pages.js +4 -11
  318. package/dist/core/pages/pages.js.map +1 -1
  319. package/dist/core/pages/pagesLayer.js +1 -2
  320. package/dist/core/paint/meshKind.js +1 -2
  321. package/dist/core/paint/meshKindLazy.js +18 -23
  322. package/dist/core/paint/meshKindLazy.js.map +1 -1
  323. package/dist/core/paint/paintKindEntry.js +1 -2
  324. package/dist/core/paint/paintKinds.js +1 -2
  325. package/dist/core/paint/registerMesh.js +1 -2
  326. package/dist/core/scene/NodeProperties.js +1 -2
  327. package/dist/core/scene/NodeRouting.js +1 -2
  328. package/dist/core/scene/annotation.js +1 -2
  329. package/dist/core/scene/appliedLog.js +1 -2
  330. package/dist/core/scene/arrivalWindow.js +2 -3
  331. package/dist/core/scene/arrivals.js +1 -2
  332. package/dist/core/scene/booleanGroup.js +1 -2
  333. package/dist/core/scene/booleanOfChildren.js +1 -2
  334. package/dist/core/scene/boundOps.js +1 -2
  335. package/dist/core/scene/carryDescendants.js +2 -3
  336. package/dist/core/scene/clipNothing.js +1 -2
  337. package/dist/core/scene/composeFrame.js +1 -2
  338. package/dist/core/scene/composePose.js +1 -2
  339. package/dist/core/scene/declaredFieldSetters.js +1 -2
  340. package/dist/core/scene/depFrame.js +1 -2
  341. package/dist/core/scene/depMemo.js +1 -2
  342. package/dist/core/scene/dependents.js +1 -2
  343. package/dist/core/scene/derivedParts.js +1 -2
  344. package/dist/core/scene/derivedPath.js +2 -3
  345. package/dist/core/scene/docValues.js +1 -2
  346. package/dist/core/scene/documentOf.js +1 -2
  347. package/dist/core/scene/editMode.js +1 -2
  348. package/dist/core/scene/editPass.js +1 -2
  349. package/dist/core/scene/effectivePose.js +3 -4
  350. package/dist/core/scene/fieldEdits.js +1 -2
  351. package/dist/core/scene/fontReads.js +1 -2
  352. package/dist/core/scene/historyFacade.js +1 -2
  353. package/dist/core/scene/historyForm.js +1 -2
  354. package/dist/core/scene/inheritedPaint.js +1 -2
  355. package/dist/core/scene/kitOps.js +16 -15
  356. package/dist/core/scene/kitOps.js.map +1 -1
  357. package/dist/core/scene/kitRegistry.js +2 -3
  358. package/dist/core/scene/layerOps.js +1 -2
  359. package/dist/core/scene/layerStack.js +1 -2
  360. package/dist/core/scene/layoutPass.js +4 -5
  361. package/dist/core/scene/lockGuard.js +1 -2
  362. package/dist/core/scene/minSize.js +1 -2
  363. package/dist/core/scene/nestedHit.js +1 -2
  364. package/dist/core/scene/nodeAsShown.js +1 -2
  365. package/dist/core/scene/nodeFlags.js +1 -2
  366. package/dist/core/scene/nodeFnFields.js +1 -2
  367. package/dist/core/scene/nodeGates.js +1 -2
  368. package/dist/core/scene/nodeMemo.js +1 -2
  369. package/dist/core/scene/nodeStore.js +2 -3
  370. package/dist/core/scene/notifier.js +1 -2
  371. package/dist/core/scene/opTable.js +1 -2
  372. package/dist/core/scene/outerOps.js +1 -2
  373. package/dist/core/scene/pathEffects/blend.js +3 -4
  374. package/dist/core/scene/pathEffects/blend.js.map +1 -1
  375. package/dist/core/scene/pathEffects/derive.js +2 -3
  376. package/dist/core/scene/pathEffects/effects.js +1 -2
  377. package/dist/core/scene/pathEffects/foundHidden.js +1 -2
  378. package/dist/core/scene/pathEffects/textAlong.js +6 -6
  379. package/dist/core/scene/pathEffects/textAlong.js.map +1 -1
  380. package/dist/core/scene/pathEffects/textAlongBands.js +1 -2
  381. package/dist/core/scene/plyStacks.js +1 -2
  382. package/dist/core/scene/poseFeed.js +1 -2
  383. package/dist/core/scene/poseHold.js +1 -2
  384. package/dist/core/scene/poseOverrides.js +1 -2
  385. package/dist/core/scene/posePlies.js +1 -2
  386. package/dist/core/scene/poseRemovals.js +1 -2
  387. package/dist/core/scene/poseSnapshot.js +1 -2
  388. package/dist/core/scene/poseWrites.js +1 -2
  389. package/dist/core/scene/reconcileSpecs.js +26 -3
  390. package/dist/core/scene/reconcileSpecs.js.map +1 -1
  391. package/dist/core/scene/recorder.js +1 -2
  392. package/dist/core/scene/renderOrder.js +1 -2
  393. package/dist/core/scene/sameValue.js +1 -2
  394. package/dist/core/scene/scene.js +23 -13
  395. package/dist/core/scene/scene.js.map +1 -1
  396. package/dist/core/scene/sceneChanges.js +1 -2
  397. package/dist/core/scene/sceneEdits.js +1 -2
  398. package/dist/core/scene/sceneJournals.js +1 -2
  399. package/dist/core/scene/sceneMutators.js +2 -3
  400. package/dist/core/scene/scenePoseAdapter.js +1 -2
  401. package/dist/core/scene/sceneRecording.js +1 -2
  402. package/dist/core/scene/sceneSelection.js +8 -5
  403. package/dist/core/scene/sceneSelection.js.map +1 -1
  404. package/dist/core/scene/sceneState.js +3 -4
  405. package/dist/core/scene/scrollOffsets.js +1 -2
  406. package/dist/core/scene/serialization.js +2 -3
  407. package/dist/core/scene/staleReplay.js +1 -2
  408. package/dist/core/scene/statedFields.js +1 -2
  409. package/dist/core/scene/strategyView.js +1 -2
  410. package/dist/core/scene/treeEdits.js +2 -3
  411. package/dist/core/scene/treeOrder.js +1 -2
  412. package/dist/core/scene/treeReads.js +1 -2
  413. package/dist/core/scene/treeShape.js +1 -2
  414. package/dist/core/scene/types.js +1 -2
  415. package/dist/core/scene/types.js.map +1 -1
  416. package/dist/core/scene/unionOfChildren.js +1 -2
  417. package/dist/core/scene/unitScopes.js +20 -4
  418. package/dist/core/scene/unitScopes.js.map +1 -1
  419. package/dist/core/scene/useScene.js +2 -3
  420. package/dist/core/scene/worldSave.js +2 -3
  421. package/dist/core/selection/chromeState.js +1 -2
  422. package/dist/core/selection/outermostSelection.js +56 -0
  423. package/dist/core/selection/outermostSelection.js.map +1 -0
  424. package/dist/core/selection/readOnlySelection.js +1 -2
  425. package/dist/core/selection/selectionTarget.js +1 -2
  426. package/dist/core/selection/usePublishSceneSelection.js +1 -2
  427. package/dist/core/selection/useSelection.js +1 -2
  428. package/dist/core/shapeKinds.js +1 -2
  429. package/dist/core/stableStringify.js +1 -2
  430. package/dist/core/stylus/stylus.js +1 -2
  431. package/dist/core/stylus/usePointerStylus.js +1 -2
  432. package/dist/core/usePaintKinds.js +1 -2
  433. package/dist/core/viewport/clampView.js +1 -2
  434. package/dist/core/viewport/clientToWorld.js +8 -3
  435. package/dist/core/viewport/clientToWorld.js.map +1 -1
  436. package/dist/core/viewport/createVelocityTracker.js +1 -2
  437. package/dist/core/viewport/fitToBounds.js +1 -2
  438. package/dist/core/viewport/fitViewToBounds.js +1 -2
  439. package/dist/core/viewport/interpolateView.js +1 -2
  440. package/dist/core/viewport/parallax.js +1 -2
  441. package/dist/core/viewport/sceneNodeClientRect.js +1 -2
  442. package/dist/core/viewport/screenSlop.js +1 -2
  443. package/dist/core/viewport/useAutoCenter.js +1 -2
  444. package/dist/core/viewport/useCanvasSize.js +1 -2
  445. package/dist/core/viewport/useDecayLoop.js +1 -2
  446. package/dist/core/viewport/useNodeOverlayFrame.js +1 -2
  447. package/dist/core/viewport/useVelocityTracker.js +1 -2
  448. package/dist/core/viewport/useViewAnimation.js +3 -4
  449. package/dist/core/viewport/view.js +1 -2
  450. package/dist/core/viewport/viewTransform.js +1 -2
  451. package/dist/core/viewport/viewportWorldRect.js +1 -2
  452. package/dist/core/viewport/wheelHandler.js +1 -2
  453. package/dist/core/viewport/zoomAt.js +7 -8
  454. package/dist/core/viewport/zoomAt.js.map +1 -1
  455. package/dist/core/viewport/zoomBounds.js +1 -2
  456. package/dist/debug/createDebugOverlayLayer.js +1 -2
  457. package/dist/debug/createDebugSink.js +1 -2
  458. package/dist/debug/defaultTheme.js +1 -2
  459. package/dist/debug/features.js +1 -2
  460. package/dist/debug/frameStats.js +1 -2
  461. package/dist/debug/overlayPanels.js +1 -2
  462. package/dist/debug/parseDebugFlags.js +1 -2
  463. package/dist/debug/useDebugSink.js +2 -3
  464. package/dist/{depSchema-ChQPzEkW.d.ts → depSchema-C7a_OMt-.d.ts} +61 -52
  465. package/dist/devtools/handlers.js +1 -2
  466. package/dist/devtools/history.js +1 -2
  467. package/dist/devtools/hook.js +1 -2
  468. package/dist/devtools/label.js +1 -2
  469. package/dist/devtools/notices.js +1 -2
  470. package/dist/devtools/protocol.js +1 -2
  471. package/dist/devtools/registry.js +1 -2
  472. package/dist/devtools/root.js +12 -6
  473. package/dist/devtools/root.js.map +1 -1
  474. package/dist/devtools/serialize.js +1 -2
  475. package/dist/devtools/session.js +2 -3
  476. package/dist/devtools/transport.js +13 -18
  477. package/dist/devtools/transport.js.map +1 -1
  478. package/dist/devtools/useDevtoolsRoot.js +1 -2
  479. package/dist/devtools-protocol.d.ts +1 -12
  480. package/dist/devtools-protocol.js +2 -2
  481. package/dist/devtools.d.ts +1 -1
  482. package/dist/devtools.js +1 -2
  483. package/dist/domains/chrome-caps/buildChromeCtx.js +1 -2
  484. package/dist/domains/chrome-caps/conditions.js +1 -2
  485. package/dist/domains/chrome-caps/defaults.js +1 -2
  486. package/dist/domains/chrome-caps/resolve.js +2 -3
  487. package/dist/domains/chrome-caps/useChromeCaps.js +1 -2
  488. package/dist/domains/chrome-caps/useHoverTracking.js +1 -2
  489. package/dist/domains/ingestion/contentHandlers.js +1 -2
  490. package/dist/domains/ingestion/ghost.js +2 -3
  491. package/dist/domains/ingestion/imageHandler.js +1 -2
  492. package/dist/domains/ingestion/kitHandlers.js +2 -3
  493. package/dist/domains/ingestion/openFilePicker.js +1 -2
  494. package/dist/domains/ingestion/placement.js +1 -2
  495. package/dist/domains/ingestion/svgHandler.js +1 -2
  496. package/dist/domains/ingestion/textHandler.js +1 -2
  497. package/dist/domains/ingestion/useCanvasIngestion.js +1 -2
  498. package/dist/domains/ingestion/weaselJsonHandler.js +2 -3
  499. package/dist/domains/longPress/longPressFeedback.js +1 -2
  500. package/dist/domains/measure/actionIds.js +1 -2
  501. package/dist/domains/measure/measureCommands.js +6 -7
  502. package/dist/domains/measure/measureContribution.js +3 -4
  503. package/dist/domains/measure/measureEdits.js +3 -4
  504. package/dist/domains/measure/measureGestures.js +2 -3
  505. package/dist/domains/measure/measureHit.js +5 -12
  506. package/dist/domains/measure/measureHit.js.map +1 -1
  507. package/dist/domains/measure/measureLayer.js +3 -4
  508. package/dist/domains/measure/measurement.js +1 -2
  509. package/dist/domains/measure/measurements.js +1 -2
  510. package/dist/domains/modes/modeLayers.js +1 -2
  511. package/dist/domains/modes/modeTriggers.js +1 -2
  512. package/dist/domains/pathEffects/effectSources.js +2 -3
  513. package/dist/domains/pathEffects/index.js +1 -2
  514. package/dist/domains/pathEffects/readSource.js +3 -4
  515. package/dist/domains/pathEffects/textItems.js +1 -2
  516. package/dist/domains/pathEffects/useEffectSourcesLayer.js +3 -4
  517. package/dist/domains/paths/anchorData.js +1 -2
  518. package/dist/domains/paths/anchorMarkers.js +6 -13
  519. package/dist/domains/paths/anchorMarkers.js.map +1 -1
  520. package/dist/domains/paths/editablePath.js +3 -4
  521. package/dist/domains/paths/originProjection.js +1 -2
  522. package/dist/domains/paths/pathEditExtension.js +1 -2
  523. package/dist/domains/paths/pathEditState.js +1 -2
  524. package/dist/domains/paths/pathEditingOverlayLayer.js +7 -12
  525. package/dist/domains/paths/pathEditingOverlayLayer.js.map +1 -1
  526. package/dist/domains/paths/pathLayer.js +1 -2
  527. package/dist/domains/paths/pathRepresentation.js +1 -2
  528. package/dist/domains/paths/pathSnap/glyphs.js +1 -2
  529. package/dist/domains/paths/pathSnap/pathSnapSource.js +1 -2
  530. package/dist/domains/paths/pathSnap/sceneIndex.js +1 -2
  531. package/dist/domains/paths/pathSnap/snapGeometry.js +2 -3
  532. package/dist/domains/paths/penPreviewLayer.js +10 -14
  533. package/dist/domains/paths/penPreviewLayer.js.map +1 -1
  534. package/dist/domains/paths/shapeGenerator.js +2 -4
  535. package/dist/domains/paths/shapeGenerator.js.map +1 -1
  536. package/dist/domains/paths/strokeOutline.js +2 -3
  537. package/dist/domains/paths/useAnchorFields.js +1 -2
  538. package/dist/domains/paths/usePathEdit.js +2 -3
  539. package/dist/domains/poseRun/usePoseRun.js +1 -2
  540. package/dist/domains/selection/enteredGroupFrame.js +1 -2
  541. package/dist/domains/selection/enteredGroupScope.js +1 -2
  542. package/dist/domains/selection/enteredOperands.js +1 -2
  543. package/dist/domains/selection/handleCommands.js +2 -3
  544. package/dist/domains/selection/overlay.js +6 -7
  545. package/dist/domains/selection/selectionPose.js +2 -3
  546. package/dist/domains/snap/angle2d.js +3 -3
  547. package/dist/domains/snap/angle2d.js.map +1 -1
  548. package/dist/domains/snap/debugCandidates.js +1 -2
  549. package/dist/domains/snap/gather.js +1 -2
  550. package/dist/domains/snap/inputSubspace.js +2 -3
  551. package/dist/domains/snap/lazySession.js +1 -2
  552. package/dist/domains/snap/marks.js +1 -2
  553. package/dist/domains/snap/outcomeStore.js +6 -10
  554. package/dist/domains/snap/outcomeStore.js.map +1 -1
  555. package/dist/domains/snap/pointSnap.js +1 -2
  556. package/dist/domains/snap/probes2d.js +1 -2
  557. package/dist/domains/snap/readoutDraw.js +1 -2
  558. package/dist/domains/snap/readoutLayer.js +1 -2
  559. package/dist/domains/snap/registry.js +1 -2
  560. package/dist/domains/snap/resizeBox.js +1 -2
  561. package/dist/domains/snap/roles.js +1 -2
  562. package/dist/domains/snap/rotationSource.js +1 -2
  563. package/dist/domains/snap/sceneReads.js +2 -3
  564. package/dist/domains/snap/sceneSession2d.js +2 -3
  565. package/dist/domains/snap/screen.js +2 -3
  566. package/dist/domains/snap/session2d.js +4 -5
  567. package/dist/domains/snap/spanSnap.js +1 -2
  568. package/dist/domains/snap/stepAngles.js +1 -2
  569. package/dist/domains/text/editingDrawOne.js +1 -2
  570. package/dist/domains/text/hostTextEditors.js +1 -2
  571. package/dist/domains/text/sceneTextDrafts.js +1 -2
  572. package/dist/domains/text/textHitAt.js +4 -5
  573. package/dist/domains/text/textLayer.js +12 -2
  574. package/dist/domains/text/textLayer.js.map +1 -1
  575. package/dist/domains/text/useSceneTextEdit.js +13 -9
  576. package/dist/domains/text/useSceneTextEdit.js.map +1 -1
  577. package/dist/domains/viewports/aim.js +6 -12
  578. package/dist/domains/viewports/aim.js.map +1 -1
  579. package/dist/domains/viewports/viewMarker.js +1 -2
  580. package/dist/domains/viewports/viewMarkerDrag.js +1 -2
  581. package/dist/domains/viewports/viewResolver.js +6 -5
  582. package/dist/domains/viewports/viewResolver.js.map +1 -1
  583. package/dist/domains/viewports/viewportLayer.js +1 -2
  584. package/dist/iconRegistry/IconRegistryProvider.js +1 -2
  585. package/dist/iconRegistry/useIconGlyph.js +1 -2
  586. package/dist/iconRegistry/useIconVariant.js +1 -2
  587. package/dist/icons.table.js +1 -2
  588. package/dist/icons2.table.js +1 -2
  589. package/dist/index.d.ts +70 -27
  590. package/dist/index.js +7 -5
  591. package/dist/input/keyState.js +1 -2
  592. package/dist/input/useKeyModifiers.js +1 -2
  593. package/dist/input/useKeyState.js +1 -2
  594. package/dist/input/usePublishPointer.js +59 -0
  595. package/dist/input/usePublishPointer.js.map +1 -0
  596. package/dist/interactions/actions/admitsChild.js +1 -2
  597. package/dist/interactions/actions/align/action.js +6 -7
  598. package/dist/interactions/actions/align/align.js +6 -7
  599. package/dist/interactions/actions/booleans/action.js +1 -2
  600. package/dist/interactions/actions/booleans/booleanGroupAction.js +2 -3
  601. package/dist/interactions/actions/booleans/booleans.js +1 -2
  602. package/dist/interactions/actions/booleans/commit.js +4 -5
  603. package/dist/interactions/actions/booleans/custom.js +2 -3
  604. package/dist/interactions/actions/booleans/keymap.js +1 -2
  605. package/dist/interactions/actions/booleans/operands.js +1 -2
  606. package/dist/interactions/actions/booleans/pieces.js +1 -2
  607. package/dist/interactions/actions/booleans/placement.js +1 -2
  608. package/dist/interactions/actions/booleans/useBooleans.js +1 -2
  609. package/dist/interactions/actions/booleans/useBooleansAdapter.js +1 -2
  610. package/dist/interactions/actions/clipboard/action.js +2 -3
  611. package/dist/interactions/actions/clipboard/clipboardOps.js +2 -3
  612. package/dist/interactions/actions/clipboard/materializePaste.js +1 -2
  613. package/dist/interactions/actions/clipboard/wireFormat.js +1 -2
  614. package/dist/interactions/actions/clone/action.js +7 -8
  615. package/dist/interactions/actions/clone/behaviors.js +4 -5
  616. package/dist/interactions/actions/defaultCommitAdapter.js +2 -3
  617. package/dist/interactions/actions/defaults/anchorEditing.js +3 -4
  618. package/dist/interactions/actions/defaults/anchorFields.js +1 -2
  619. package/dist/interactions/actions/defaults/anchorHandles.js +2 -3
  620. package/dist/interactions/actions/defaults/anchorJoin.js +2 -3
  621. package/dist/interactions/actions/defaults/areaSelect.js +6 -6
  622. package/dist/interactions/actions/defaults/areaSelect.js.map +1 -1
  623. package/dist/interactions/actions/defaults/bendSegment.js +3 -4
  624. package/dist/interactions/actions/defaults/cancelGesture.js +1 -2
  625. package/dist/interactions/actions/defaults/clearSelection.js +1 -2
  626. package/dist/interactions/actions/defaults/containerScroll.js +13 -8
  627. package/dist/interactions/actions/defaults/containerScroll.js.map +1 -1
  628. package/dist/interactions/actions/defaults/contextMenu.js +6 -7
  629. package/dist/interactions/actions/defaults/copySubtree.js +2 -3
  630. package/dist/interactions/actions/defaults/createPaintAction.js +3 -4
  631. package/dist/interactions/actions/defaults/delete.js +2 -3
  632. package/dist/interactions/actions/defaults/duplicate.js +5 -6
  633. package/dist/interactions/actions/defaults/enterGroup.js +5 -6
  634. package/dist/interactions/actions/defaults/enterGroup.js.map +1 -1
  635. package/dist/interactions/actions/defaults/enterPathEdit.js +1 -2
  636. package/dist/interactions/actions/defaults/enterTextEdit.js +1 -2
  637. package/dist/interactions/actions/defaults/escape.js +1 -2
  638. package/dist/interactions/actions/defaults/exitPathEdit.js +1 -2
  639. package/dist/interactions/actions/defaults/group.js +6 -7
  640. package/dist/interactions/actions/defaults/ingest.js +3 -4
  641. package/dist/interactions/actions/defaults/insertPathAnchor.js +2 -3
  642. package/dist/interactions/actions/defaults/nudge.js +3 -4
  643. package/dist/interactions/actions/defaults/nudgeSteps.js +2 -3
  644. package/dist/interactions/actions/defaults/nudgeSteps.js.map +1 -1
  645. package/dist/interactions/actions/defaults/pathEditMarks.js +3 -7
  646. package/dist/interactions/actions/defaults/pathEditMarks.js.map +1 -1
  647. package/dist/interactions/actions/defaults/pinchZoom.js +3 -4
  648. package/dist/interactions/actions/defaults/reorder.js +2 -3
  649. package/dist/interactions/actions/defaults/requiresSelection.js +1 -2
  650. package/dist/interactions/actions/defaults/segmentUnder.js +1 -2
  651. package/dist/interactions/actions/defaults/selectAll.js +1 -2
  652. package/dist/interactions/actions/defaults/selectDeep.js +1 -2
  653. package/dist/interactions/actions/defaults/setFill.js +1 -2
  654. package/dist/interactions/actions/defaults/setFillOpacity.js +1 -2
  655. package/dist/interactions/actions/defaults/setStroke.js +1 -2
  656. package/dist/interactions/actions/defaults/setStrokeOpacity.js +1 -2
  657. package/dist/interactions/actions/defaults/slice.js +1 -2
  658. package/dist/interactions/actions/defaults/sliceOps.js +1 -2
  659. package/dist/interactions/actions/defaults/toolActivate.js +1 -2
  660. package/dist/interactions/actions/defaults/toolResetToDefault.js +1 -2
  661. package/dist/interactions/actions/defaults/undoRedo.js +1 -2
  662. package/dist/interactions/actions/defaults/viewportDragPan.js +1 -2
  663. package/dist/interactions/actions/defaults/viewportWheelPan.js +1 -2
  664. package/dist/interactions/actions/defaults/viewportZoom.js +3 -4
  665. package/dist/interactions/actions/distribute/action.js +4 -5
  666. package/dist/interactions/actions/distribute/distribute.js +5 -6
  667. package/dist/interactions/actions/distribute/plan.js +1 -2
  668. package/dist/interactions/actions/drawnBoxes.js +4 -5
  669. package/dist/interactions/actions/dropVerdict.js +1 -2
  670. package/dist/interactions/actions/edit-anchors/action.js +4 -5
  671. package/dist/interactions/actions/edit-anchors/extensionDrags.js +1 -2
  672. package/dist/interactions/actions/edit-anchors/geometry.js +1 -2
  673. package/dist/interactions/actions/edit-anchors/handleDrag.js +5 -9
  674. package/dist/interactions/actions/edit-anchors/handleDrag.js.map +1 -1
  675. package/dist/interactions/actions/edit-anchors/handles.js +1 -2
  676. package/dist/interactions/actions/edit-anchors/params.js +1 -2
  677. package/dist/interactions/actions/edit-anchors/preview.js +1 -2
  678. package/dist/interactions/actions/edit-anchors/symmetry.js +1 -2
  679. package/dist/interactions/actions/flip/action.js +8 -9
  680. package/dist/interactions/actions/flip/helpers.js +1 -2
  681. package/dist/interactions/actions/geometryProjection.js +1 -2
  682. package/dist/interactions/actions/gestureFrames.js +3 -4
  683. package/dist/interactions/actions/gestureLifecycle.js +1 -2
  684. package/dist/interactions/actions/hitSelection.js +7 -3
  685. package/dist/interactions/actions/hitSelection.js.map +1 -1
  686. package/dist/interactions/actions/insert/action.js +6 -7
  687. package/dist/interactions/actions/insert/commit.js +2 -3
  688. package/dist/interactions/actions/insert/extras.js +1 -2
  689. package/dist/interactions/actions/insert/frame.js +1 -2
  690. package/dist/interactions/actions/insert/geometry.js +1 -2
  691. package/dist/interactions/actions/insert/params.js +2 -3
  692. package/dist/interactions/actions/insert/parent.js +1 -2
  693. package/dist/interactions/actions/insert/placeAction.js +5 -6
  694. package/dist/interactions/actions/insert/repositionAction.js +1 -2
  695. package/dist/interactions/actions/insert/rotateAction.js +1 -2
  696. package/dist/interactions/actions/insert/session.js +5 -6
  697. package/dist/interactions/actions/insert/shape.js +2 -3
  698. package/dist/interactions/actions/lasso-select/action.js +9 -9
  699. package/dist/interactions/actions/lasso-select/action.js.map +1 -1
  700. package/dist/interactions/actions/lasso-select/behaviors/selectFromLasso.js +2 -3
  701. package/dist/interactions/actions/magnification.js +37 -0
  702. package/dist/interactions/actions/magnification.js.map +1 -0
  703. package/dist/interactions/actions/move/action.js +2 -3
  704. package/dist/interactions/actions/move/behaviors/clampMove.js +42 -0
  705. package/dist/interactions/actions/move/behaviors/clampMove.js.map +1 -0
  706. package/dist/interactions/actions/move/behaviors/layoutDrop.js +2 -3
  707. package/dist/interactions/actions/move/behaviors/reparentOnDrop.js +2 -3
  708. package/dist/interactions/actions/move/behaviors/snapBackOrDelete.js +1 -2
  709. package/dist/interactions/actions/move/behaviors/snapToContainer.js +2 -3
  710. package/dist/interactions/actions/move/capture.js +6 -7
  711. package/dist/interactions/actions/move/commit/index.js +2 -3
  712. package/dist/interactions/actions/move/commit/layoutDrop.js +4 -5
  713. package/dist/interactions/actions/move/commit/layoutRelease.js +7 -8
  714. package/dist/interactions/actions/move/commit/rebase.js +2 -3
  715. package/dist/interactions/actions/move/commit/reparent.js +5 -6
  716. package/dist/interactions/actions/move/delta.js +2 -3
  717. package/dist/interactions/actions/move/frame.js +2 -3
  718. package/dist/interactions/actions/move/gestureAdapter.js +1 -2
  719. package/dist/interactions/actions/move/landedDescendants.js +2 -3
  720. package/dist/interactions/actions/move/layout/container.js +6 -10
  721. package/dist/interactions/actions/move/layout/container.js.map +1 -1
  722. package/dist/interactions/actions/move/layout/dragged.js +2 -3
  723. package/dist/interactions/actions/move/layout/dropPass.js +5 -6
  724. package/dist/interactions/actions/move/layout/exits.js +4 -5
  725. package/dist/interactions/actions/move/layout/exits.js.map +1 -1
  726. package/dist/interactions/actions/move/layout/glide.js +2 -3
  727. package/dist/interactions/actions/move/layout/view.js +1 -2
  728. package/dist/interactions/actions/move/refusal.js +2 -3
  729. package/dist/interactions/actions/move/session.js +4 -5
  730. package/dist/interactions/actions/move/translate.js +2 -3
  731. package/dist/interactions/actions/moveNodes.js +5 -6
  732. package/dist/interactions/actions/notices.js +1 -2
  733. package/dist/interactions/actions/outlines/createOutlines.js +1 -2
  734. package/dist/interactions/actions/outlines/createOutlinesAction.js +2 -3
  735. package/dist/interactions/actions/outlines/outlineStroke.js +2 -3
  736. package/dist/interactions/actions/outlines/outlineStrokeAction.js +2 -3
  737. package/dist/interactions/actions/outlines/replaceWithPaths.js +5 -6
  738. package/dist/interactions/actions/outlines/strokeRegion.js +1 -2
  739. package/dist/interactions/actions/outlines/useCreateOutlinesAdapter.js +1 -2
  740. package/dist/interactions/actions/pathCommands/cutJoin.js +3 -4
  741. package/dist/interactions/actions/pathCommands/livePathEdit.js +3 -4
  742. package/dist/interactions/actions/pathCommands/pathNodes.js +3 -4
  743. package/dist/interactions/actions/pathCommands/simplifyOffset.js +2 -3
  744. package/dist/interactions/actions/pathGestureTags.js +1 -2
  745. package/dist/interactions/actions/planeInput.js +2 -3
  746. package/dist/interactions/actions/pointerState.js +1 -2
  747. package/dist/interactions/actions/poseDescriptorDep.js +1 -2
  748. package/dist/interactions/actions/poseFrame.js +3 -4
  749. package/dist/interactions/actions/resize/action.js +3 -4
  750. package/dist/interactions/actions/resize/aspect.js +1 -2
  751. package/dist/interactions/actions/resize/behaviors/clampMinSize.js +1 -2
  752. package/dist/interactions/actions/resize/boxFrame.js +1 -2
  753. package/dist/interactions/actions/resize/capture.js +7 -8
  754. package/dist/interactions/actions/resize/commit.js +3 -4
  755. package/dist/interactions/actions/resize/cornerHandles.js +1 -2
  756. package/dist/interactions/actions/resize/frame.js +7 -8
  757. package/dist/interactions/actions/resize/held.js +2 -3
  758. package/dist/interactions/actions/resize/minimum.js +1 -2
  759. package/dist/interactions/actions/resize/replay.js +1 -2
  760. package/dist/interactions/actions/resize/ruleBounds.js +1 -2
  761. package/dist/interactions/actions/resize/session.js +9 -10
  762. package/dist/interactions/actions/resolveOverlays.js +1 -2
  763. package/dist/interactions/actions/resolvePreviews.js +3 -4
  764. package/dist/interactions/actions/rotate/action.js +5 -6
  765. package/dist/interactions/actions/rotate/commit.js +2 -3
  766. package/dist/interactions/actions/rotate/frame.js +3 -4
  767. package/dist/interactions/actions/rotate/geometry.js +1 -2
  768. package/dist/interactions/actions/rotate/handle.js +2 -3
  769. package/dist/interactions/actions/rotate/replay.js +2 -3
  770. package/dist/interactions/actions/rotate/session.js +10 -11
  771. package/dist/interactions/actions/selectionSubtree.js +7 -22
  772. package/dist/interactions/actions/selectionSubtree.js.map +1 -1
  773. package/dist/interactions/actions/spatialReference.js +1 -2
  774. package/dist/interactions/actions/testUtils.js +1 -2
  775. package/dist/interactions/actions/transform-again/action.js +5 -6
  776. package/dist/interactions/actions/transform-again/memory.js +3 -4
  777. package/dist/interactions/actions/transform-again/memory.js.map +1 -1
  778. package/dist/interactions/actions/transformFinish.js +1 -2
  779. package/dist/interactions/actions/useActionSet.js +1 -2
  780. package/dist/interactions/actions/useNotices.js +1 -2
  781. package/dist/interactions/actions/useStandardActions.js +1 -2
  782. package/dist/interactions/gestures/dragGesture/dragGesture.js +1 -2
  783. package/dist/interactions/gestures/dragGesture/dragPointOf.js +1 -2
  784. package/dist/interactions/gestures/dragRadial/dragRadial.js +2 -3
  785. package/dist/interactions/gestures/dragRect/dragRect.js +2 -3
  786. package/dist/interactions/gestures/handleDrag/handleDrag.js +1 -2
  787. package/dist/interactions/gestures/pointerDrag/pointerDrag.js +1 -2
  788. package/dist/interactions/gestures/shared/originProjection.js +1 -2
  789. package/dist/interactions/gestures/shared/screenTolerance.js +1 -2
  790. package/dist/interactions/gestures/thresholdDrag/thresholdDrag.js +1 -2
  791. package/dist/kitSettingsSchema.js +4 -5
  792. package/dist/move.d.ts +18 -3
  793. package/dist/move.js +2 -1
  794. package/dist/test-hook/createTestHook.js +1 -2
  795. package/dist/test-hook/install.js +1 -2
  796. package/dist/test-hook/useTestHook.js +1 -2
  797. package/dist/test-seams.d.ts +4 -4
  798. package/dist/test-seams.js +2 -2
  799. package/dist/tools/builtin/anchors/anchorsTool.js +1 -2
  800. package/dist/tools/builtin/ellipse/useEllipseTool.js +2 -3
  801. package/dist/tools/builtin/eyedropper/useEyedropperTool.js +1 -2
  802. package/dist/tools/builtin/hand/dragPanContribution.js +1 -2
  803. package/dist/tools/builtin/hand/useHandTool.js +1 -2
  804. package/dist/tools/builtin/image/useImageTool.js +1 -2
  805. package/dist/tools/builtin/lasso/useLassoTool.js +1 -2
  806. package/dist/tools/builtin/line/useLineTool.js +2 -3
  807. package/dist/tools/builtin/measure/useMeasureTool.js +2 -3
  808. package/dist/tools/builtin/pen/penHandle.js +1 -2
  809. package/dist/tools/builtin/pen/usePenTool.js +6 -7
  810. package/dist/tools/builtin/pencil/usePencilTool.js +1 -2
  811. package/dist/tools/builtin/pickTopMostHit.js +1 -2
  812. package/dist/tools/builtin/polygon/usePolygonTool.js +3 -4
  813. package/dist/tools/builtin/pressTarget.js +1 -2
  814. package/dist/tools/builtin/rect/useRectTool.js +2 -3
  815. package/dist/tools/builtin/select/adapterPointQuery.js +3 -4
  816. package/dist/tools/builtin/select/collapseDeferred.js +1 -2
  817. package/dist/tools/builtin/select/groupEntry.js +2 -3
  818. package/dist/tools/builtin/select/pressDecision.js +3 -4
  819. package/dist/tools/builtin/select/pressDecision.js.map +1 -1
  820. package/dist/tools/builtin/select/selectionContributions.js +1 -2
  821. package/dist/tools/builtin/select/useSelectTool.js +5 -6
  822. package/dist/tools/builtin/shared/insertToolOptions.js +1 -2
  823. package/dist/tools/builtin/shared/pointerFollower.js +1 -2
  824. package/dist/tools/builtin/slice/useSliceTool.js +5 -6
  825. package/dist/tools/builtin/star/useStarTool.js +3 -4
  826. package/dist/tools/builtin/sticky/stickyNode.js +1 -2
  827. package/dist/tools/builtin/sticky/useStickyTool.js +2 -3
  828. package/dist/tools/builtin/text/useTextTool.js +1 -2
  829. package/dist/tools/index.js +2 -2
  830. package/dist/tools/overlayBinding.js +1 -2
  831. package/dist/tools/toolOptions.js +17 -4
  832. package/dist/tools/toolOptions.js.map +1 -1
  833. package/dist/tools/useKeybindings.js +1 -2
  834. package/dist/{types-DW14eu9B.d.ts → types-BUvUXZe5.d.ts} +3 -3
  835. package/dist/util/color.js +1 -2
  836. package/dist/util/paint.js +1 -2
  837. package/dist/version.js +2 -3
  838. package/package.json +27 -27
@@ -1,10 +1,10 @@
1
1
  import { isRectPose } from "../../../core/geometry/autoPoseDescriptor.js";
2
- import { findNodeShape } from "../../../canvas/NodeShape.js";
3
2
  import { poseOutline } from "../../../core/geometry/regionHit.js";
3
+ import { findNodeShape } from "../../../canvas/NodeShape.js";
4
4
  import { nodeOutline } from "../strokeOutline.js";
5
5
  import { worldCoords } from "@weasel-js/geom";
6
6
 
7
- //#region src/domains/paths/pathSnap/snapGeometry.ts
7
+ // src/domains/paths/pathSnap/snapGeometry.ts
8
8
  /**
9
9
  * The geometry `node` snaps to. A painter that `snapsToBox` — text, an image
10
10
  * — gives its pose box through the pose's frame, and the box's center. Any
@@ -43,6 +43,5 @@ function boxCenter(path) {
43
43
  };
44
44
  }
45
45
 
46
- //#endregion
47
46
  export { nodeSnapGeometry };
48
47
  //# sourceMappingURL=snapGeometry.js.map
@@ -1,6 +1,6 @@
1
- import { PATH_C, PATH_L, PATH_M, anchorsToPath, circlePath } from "@weasel-js/geom";
1
+ import { PATH_C, PATH_L, PATH_M, anchorsToPath, circlePath, viewWorldToScreen } from "@weasel-js/geom";
2
2
 
3
- //#region src/domains/paths/penPreviewLayer.ts
3
+ // src/domains/paths/penPreviewLayer.ts
4
4
  var DEFAULT_STYLE = {
5
5
  anchorFill: "#d4c4a8",
6
6
  anchorStroke: "#d4c4a8",
@@ -21,9 +21,6 @@ var radiiOf = (kit) => ({
21
21
  handleDot: kit?.get("targets.penHandleDotRadiusPx") ?? HANDLE_DOT_RADIUS_PX,
22
22
  closeHint: kit?.get("targets.penCloseHintRadiusPx") ?? CLOSE_HINT_RADIUS_PX
23
23
  });
24
- function w2s(wx, wy, view) {
25
- return [(wx - view.x) * view.scale.x, (wy - view.y) * view.scale.y];
26
- }
27
24
  function approximateCircle(cx, cy, r) {
28
25
  return circlePath(cx, cy, r);
29
26
  }
@@ -32,7 +29,7 @@ function approximateCircle(cx, cy, r) {
32
29
  function subpathToPath(sp, view) {
33
30
  if (sp.anchors.length === 0) return null;
34
31
  const pt = (p) => {
35
- const [x, y] = w2s(p.x, p.y, view);
32
+ const { x, y } = viewWorldToScreen(view, p);
36
33
  return {
37
34
  x,
38
35
  y
@@ -95,11 +92,11 @@ function createPenPreviewLayer(opts) {
95
92
  if (cur && cur.anchors.length > 0 && s.cursor && s.draggingHandleAt === null) {
96
93
  const last = cur.anchors[cur.anchors.length - 1];
97
94
  const out2 = last.outHandle;
98
- const [sx, sy] = w2s(last.x, last.y, view);
99
- const [cx, cy] = w2s(s.cursor.x, s.cursor.y, view);
95
+ const { x: sx, y: sy } = viewWorldToScreen(view, last);
96
+ const { x: cx, y: cy } = viewWorldToScreen(view, s.cursor);
100
97
  let path;
101
98
  if (out2) {
102
- const [c1x, c1y] = w2s(out2.x, out2.y, view);
99
+ const { x: c1x, y: c1y } = viewWorldToScreen(view, out2);
103
100
  path = {
104
101
  kind: "polygon",
105
102
  commands: new Uint8Array([PATH_M, PATH_C]),
@@ -141,7 +138,7 @@ function createPenPreviewLayer(opts) {
141
138
  if (cur) {
142
139
  for (let i = 0; i < cur.anchors.length; i++) {
143
140
  const a = cur.anchors[i];
144
- const [ax, ay] = w2s(a.x, a.y, view);
141
+ const { x: ax, y: ay } = viewWorldToScreen(view, a);
145
142
  out.push({
146
143
  kind: "path",
147
144
  path: approximateCircle(ax, ay, r.anchor),
@@ -158,7 +155,7 @@ function createPenPreviewLayer(opts) {
158
155
  }
159
156
  });
160
157
  if (i === cur.anchors.length - 1 && a.outHandle) {
161
- const [hx, hy] = w2s(a.outHandle.x, a.outHandle.y, view);
158
+ const { x: hx, y: hy } = viewWorldToScreen(view, a.outHandle);
162
159
  const linePath = {
163
160
  kind: "polygon",
164
161
  commands: new Uint8Array([PATH_M, PATH_L]),
@@ -191,7 +188,7 @@ function createPenPreviewLayer(opts) {
191
188
  });
192
189
  const inSide = a.inHandle;
193
190
  if (inSide) {
194
- const [mx, my] = w2s(inSide.x, inSide.y, view);
191
+ const { x: mx, y: my } = viewWorldToScreen(view, inSide);
195
192
  const inLine = {
196
193
  kind: "polygon",
197
194
  commands: new Uint8Array([PATH_M, PATH_L]),
@@ -227,7 +224,7 @@ function createPenPreviewLayer(opts) {
227
224
  }
228
225
  if (s.closeHintActive && cur.anchors.length >= 3) {
229
226
  const first = cur.anchors[0];
230
- const [fx, fy] = w2s(first.x, first.y, view);
227
+ const { x: fx, y: fy } = viewWorldToScreen(view, first);
231
228
  out.push({
232
229
  kind: "path",
233
230
  path: approximateCircle(fx, fy, r.closeHint),
@@ -246,6 +243,5 @@ function createPenPreviewLayer(opts) {
246
243
  };
247
244
  }
248
245
 
249
- //#endregion
250
246
  export { ANCHOR_RADIUS_PX, CLOSE_HINT_RADIUS_PX, HANDLE_DOT_RADIUS_PX, PEN_CLOSE_HIT_PX, createPenPreviewLayer, penReachOf };
251
247
  //# sourceMappingURL=penPreviewLayer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"penPreviewLayer.js","names":[],"sources":["../../../src/domains/paths/penPreviewLayer.ts"],"sourcesContent":["/**\n * Screen-space preview layer for `usePenTool`. Reads the pen's state each\n * frame and renders the in-progress path: finished\n * subpaths (faded), the current subpath (bright + anchor dots + handles),\n * a rubber-band segment from the latest anchor to the cursor, and a\n * close-hint ring on the first anchor when the tool flags it as hot.\n *\n * Runs in screen space so anchor/handle sizes stay constant under zoom.\n * All world-space coords go through `worldToScreen` via the layer's `view`\n * argument.\n */\n\nimport type { DrawCommand } from '@weasel-js/renderer';\nimport type { RenderLayer } from 'core/layers/render';\nimport type { KitSettingsStore } from '@weasel-js/react';\nimport type { PenScratch, PenAnchor, PenSubpath } from 'tools/builtin/pen';\nimport { PATH_C, PATH_L, PATH_M, type PolygonPath, anchorsToPath, circlePath } from '@weasel-js/geom';\n\n/** Appearance of the pen tool's in-progress path. */\nexport interface PenPreviewStyle {\n anchorFill?: string;\n anchorStroke?: string;\n handleStroke?: string;\n rubberBandStroke?: string;\n closeHintFill?: string;\n finishedSubpathStroke?: string;\n}\n\n/** Options for `createPenPreviewLayer`. */\nexport interface CreatePenPreviewLayerOptions {\n /** The pen's state. One object for the pen's life, changed in place, so\n * the layer reads the same one on every frame. */\n state: PenScratch;\n style?: PenPreviewStyle;\n /** The kit settings whose `targets.pen*RadiusPx` size the dots, read each frame. */\n kitSettings?: () => KitSettingsStore;\n}\n\nconst DEFAULT_STYLE: Required<PenPreviewStyle> = {\n anchorFill: '#d4c4a8',\n anchorStroke: '#d4c4a8',\n handleStroke: '#d4c4a8',\n rubberBandStroke: '#d4c4a8',\n closeHintFill: '#d4c4a8',\n finishedSubpathStroke: '#8a7a5e',\n};\n\nexport const ANCHOR_RADIUS_PX = 4;\nexport const HANDLE_DOT_RADIUS_PX = 3;\nexport const CLOSE_HINT_RADIUS_PX = 8;\n\n/** How near the pen's first anchor, in screen px, a click closes the subpath. */\nexport const PEN_CLOSE_HIT_PX = 8;\n\n/** The pen's reach in screen px: its own option, else the kit setting, else the constant. */\nexport const penReachOf = (o: { closeHitRadius?: number; kitSettings?: KitSettingsStore }) => ({\n close: o.closeHitRadius ?? o.kitSettings?.get('targets.penCloseHitPx') ?? PEN_CLOSE_HIT_PX,\n});\n\nconst radiiOf = (kit: KitSettingsStore | undefined) => ({\n anchor: kit?.get('targets.penAnchorRadiusPx') ?? ANCHOR_RADIUS_PX,\n handleDot: kit?.get('targets.penHandleDotRadiusPx') ?? HANDLE_DOT_RADIUS_PX,\n closeHint: kit?.get('targets.penCloseHintRadiusPx') ?? CLOSE_HINT_RADIUS_PX,\n});\n\nfunction w2s(wx: number, wy: number, view: { x: number; y: number; scale: { x: number; y: number } }): [number, number] {\n return [(wx - view.x) * view.scale.x, (wy - view.y) * view.scale.y];\n}\n\n// approximateCircle has moved to `./markers.ts` as `circlePath`. Re-exported\n// locally so we don't rename callers in this file.\nfunction approximateCircle(cx: number, cy: number, r: number): PolygonPath {\n return circlePath(cx, cy, r);\n}\n\n/** A pen subpath as a screen-space `PolygonPath`, segmented by the same rule\n * the pen commits with. */\nfunction subpathToPath(\n sp: PenSubpath,\n view: { x: number; y: number; scale: { x: number; y: number } },\n): PolygonPath | null {\n if (sp.anchors.length === 0) return null;\n const pt = (p: { x: number; y: number }) => {\n const [x, y] = w2s(p.x, p.y, view);\n return { x, y };\n };\n const anchors = sp.anchors.map((a: PenAnchor) => ({\n ...pt(a),\n ...(a.inHandle ? { inHandle: pt(a.inHandle) } : {}),\n ...(a.outHandle ? { outHandle: pt(a.outHandle) } : {}),\n }));\n return anchorsToPath([anchors], [sp.closed]);\n}\n\n/** Render layer that draws the pen tool's path as it is being placed —\n * committed anchors, the rubber band to the cursor, and the close hint. Draws\n * nothing when the pen is idle. */\nexport function createPenPreviewLayer(\n opts: CreatePenPreviewLayerOptions,\n): RenderLayer<unknown> {\n const style = { ...DEFAULT_STYLE, ...(opts.style ?? {}) };\n const s = opts.state;\n\n return {\n id: 'penPreview',\n label: 'Pen preview',\n space: 'screen',\n draw: (_data, view) => {\n const out: DrawCommand[] = [];\n const r = radiiOf(opts.kitSettings?.());\n // (1) Finished subpaths — faded outline.\n for (const sp of s.finishedSubpaths) {\n const path = subpathToPath(sp, view);\n if (path === null) continue;\n out.push({\n kind: 'path',\n path,\n stroke: { paint: { kind: 'solid', color: style.finishedSubpathStroke }, width: 1 },\n });\n }\n\n const cur = s.current;\n if (!cur && s.cursor === null) return out;\n\n // (2) Current subpath — bright outline.\n if (cur) {\n const path = subpathToPath(cur, view);\n if (path !== null) {\n out.push({\n kind: 'path',\n path,\n stroke: { paint: { kind: 'solid', color: style.rubberBandStroke }, width: 1 },\n });\n }\n }\n\n // (3) Rubber-band from latest anchor to cursor.\n if (cur && cur.anchors.length > 0 && s.cursor && s.draggingHandleAt === null) {\n const last = cur.anchors[cur.anchors.length - 1];\n const out2 = last.outHandle;\n const [sx, sy] = w2s(last.x, last.y, view);\n const [cx, cy] = w2s(s.cursor.x, s.cursor.y, view);\n let path: PolygonPath;\n if (out2) {\n const [c1x, c1y] = w2s(out2.x, out2.y, view);\n path = {\n kind: 'polygon',\n commands: new Uint8Array([PATH_M, PATH_C]),\n coords: new Float32Array([sx, sy, c1x, c1y, cx, cy, cx, cy]),\n fillRule: 'nonzero',\n };\n } else {\n path = {\n kind: 'polygon',\n commands: new Uint8Array([PATH_M, PATH_L]),\n coords: new Float32Array([sx, sy, cx, cy]),\n fillRule: 'nonzero',\n };\n }\n out.push({\n kind: 'path',\n path,\n stroke: { paint: { kind: 'solid', color: style.rubberBandStroke }, width: 1 },\n });\n }\n\n // (4) Anchor dots + handles.\n if (cur) {\n for (let i = 0; i < cur.anchors.length; i++) {\n const a = cur.anchors[i];\n const [ax, ay] = w2s(a.x, a.y, view);\n out.push({\n kind: 'path',\n path: approximateCircle(ax, ay, r.anchor),\n fill: { paint: { kind: 'solid', color: style.anchorFill } },\n stroke: { paint: { kind: 'solid', color: style.anchorStroke }, width: 1 },\n });\n // Handle line + dot (only the latest anchor, per spec).\n if (i === cur.anchors.length - 1 && a.outHandle) {\n const [hx, hy] = w2s(a.outHandle.x, a.outHandle.y, view);\n const linePath: PolygonPath = {\n kind: 'polygon',\n commands: new Uint8Array([PATH_M, PATH_L]),\n coords: new Float32Array([ax, ay, hx, hy]),\n fillRule: 'nonzero',\n };\n out.push({\n kind: 'path',\n path: linePath,\n stroke: { paint: { kind: 'solid', color: style.handleStroke }, width: 1 },\n });\n out.push({\n kind: 'path',\n path: approximateCircle(hx, hy, r.handleDot),\n fill: { paint: { kind: 'solid', color: style.handleStroke } },\n });\n const inSide = a.inHandle;\n if (inSide) {\n const [mx, my] = w2s(inSide.x, inSide.y, view);\n const inLine: PolygonPath = {\n kind: 'polygon',\n commands: new Uint8Array([PATH_M, PATH_L]),\n coords: new Float32Array([ax, ay, mx, my]),\n fillRule: 'nonzero',\n };\n out.push({\n kind: 'path',\n path: inLine,\n stroke: { paint: { kind: 'solid', color: style.handleStroke }, width: 1 },\n });\n out.push({\n kind: 'path',\n path: approximateCircle(mx, my, r.handleDot),\n fill: { paint: { kind: 'solid', color: style.handleStroke } },\n });\n }\n }\n }\n\n // (5) Close-hint ring on first anchor.\n if (s.closeHintActive && cur.anchors.length >= 3) {\n const first = cur.anchors[0];\n const [fx, fy] = w2s(first.x, first.y, view);\n out.push({\n kind: 'path',\n path: approximateCircle(fx, fy, r.closeHint),\n stroke: { paint: { kind: 'solid', color: style.closeHintFill }, width: 1.5 },\n });\n }\n }\n\n return out;\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"penPreviewLayer.js","names":[],"sources":["../../../src/domains/paths/penPreviewLayer.ts"],"sourcesContent":["/**\n * Screen-space preview layer for `usePenTool`. Reads the pen's state each\n * frame and renders the in-progress path: finished\n * subpaths (faded), the current subpath (bright + anchor dots + handles),\n * a rubber-band segment from the latest anchor to the cursor, and a\n * close-hint ring on the first anchor when the tool flags it as hot.\n *\n * Runs in screen space so anchor/handle sizes stay constant under zoom.\n * All world-space coords go through `viewWorldToScreen` with the layer's `view`\n * argument.\n */\n\nimport type { DrawCommand } from '@weasel-js/renderer';\nimport type { RenderLayer } from 'core/layers/render';\nimport type { KitSettingsStore } from '@weasel-js/react';\nimport type { PenScratch, PenAnchor, PenSubpath } from 'tools/builtin/pen';\nimport { PATH_C, PATH_L, PATH_M, type PolygonPath, anchorsToPath, circlePath, viewWorldToScreen } from '@weasel-js/geom';\n\n/** Appearance of the pen tool's in-progress path. */\nexport interface PenPreviewStyle {\n anchorFill?: string;\n anchorStroke?: string;\n handleStroke?: string;\n rubberBandStroke?: string;\n closeHintFill?: string;\n finishedSubpathStroke?: string;\n}\n\n/** Options for `createPenPreviewLayer`. */\nexport interface CreatePenPreviewLayerOptions {\n /** The pen's state. One object for the pen's life, changed in place, so\n * the layer reads the same one on every frame. */\n state: PenScratch;\n style?: PenPreviewStyle;\n /** The kit settings whose `targets.pen*RadiusPx` size the dots, read each frame. */\n kitSettings?: () => KitSettingsStore;\n}\n\nconst DEFAULT_STYLE: Required<PenPreviewStyle> = {\n anchorFill: '#d4c4a8',\n anchorStroke: '#d4c4a8',\n handleStroke: '#d4c4a8',\n rubberBandStroke: '#d4c4a8',\n closeHintFill: '#d4c4a8',\n finishedSubpathStroke: '#8a7a5e',\n};\n\nexport const ANCHOR_RADIUS_PX = 4;\nexport const HANDLE_DOT_RADIUS_PX = 3;\nexport const CLOSE_HINT_RADIUS_PX = 8;\n\n/** How near the pen's first anchor, in screen px, a click closes the subpath. */\nexport const PEN_CLOSE_HIT_PX = 8;\n\n/** The pen's reach in screen px: its own option, else the kit setting, else the constant. */\nexport const penReachOf = (o: { closeHitRadius?: number; kitSettings?: KitSettingsStore }) => ({\n close: o.closeHitRadius ?? o.kitSettings?.get('targets.penCloseHitPx') ?? PEN_CLOSE_HIT_PX,\n});\n\nconst radiiOf = (kit: KitSettingsStore | undefined) => ({\n anchor: kit?.get('targets.penAnchorRadiusPx') ?? ANCHOR_RADIUS_PX,\n handleDot: kit?.get('targets.penHandleDotRadiusPx') ?? HANDLE_DOT_RADIUS_PX,\n closeHint: kit?.get('targets.penCloseHintRadiusPx') ?? CLOSE_HINT_RADIUS_PX,\n});\n\n// approximateCircle has moved to `./markers.ts` as `circlePath`. Re-exported\n// locally so we don't rename callers in this file.\nfunction approximateCircle(cx: number, cy: number, r: number): PolygonPath {\n return circlePath(cx, cy, r);\n}\n\n/** A pen subpath as a screen-space `PolygonPath`, segmented by the same rule\n * the pen commits with. */\nfunction subpathToPath(\n sp: PenSubpath,\n view: { x: number; y: number; scale: { x: number; y: number } },\n): PolygonPath | null {\n if (sp.anchors.length === 0) return null;\n const pt = (p: { x: number; y: number }) => {\n const { x: x, y: y } = viewWorldToScreen(view, p);\n return { x, y };\n };\n const anchors = sp.anchors.map((a: PenAnchor) => ({\n ...pt(a),\n ...(a.inHandle ? { inHandle: pt(a.inHandle) } : {}),\n ...(a.outHandle ? { outHandle: pt(a.outHandle) } : {}),\n }));\n return anchorsToPath([anchors], [sp.closed]);\n}\n\n/** Render layer that draws the pen tool's path as it is being placed —\n * committed anchors, the rubber band to the cursor, and the close hint. Draws\n * nothing when the pen is idle. */\nexport function createPenPreviewLayer(\n opts: CreatePenPreviewLayerOptions,\n): RenderLayer<unknown> {\n const style = { ...DEFAULT_STYLE, ...(opts.style ?? {}) };\n const s = opts.state;\n\n return {\n id: 'penPreview',\n label: 'Pen preview',\n space: 'screen',\n draw: (_data, view) => {\n const out: DrawCommand[] = [];\n const r = radiiOf(opts.kitSettings?.());\n // (1) Finished subpaths — faded outline.\n for (const sp of s.finishedSubpaths) {\n const path = subpathToPath(sp, view);\n if (path === null) continue;\n out.push({\n kind: 'path',\n path,\n stroke: { paint: { kind: 'solid', color: style.finishedSubpathStroke }, width: 1 },\n });\n }\n\n const cur = s.current;\n if (!cur && s.cursor === null) return out;\n\n // (2) Current subpath — bright outline.\n if (cur) {\n const path = subpathToPath(cur, view);\n if (path !== null) {\n out.push({\n kind: 'path',\n path,\n stroke: { paint: { kind: 'solid', color: style.rubberBandStroke }, width: 1 },\n });\n }\n }\n\n // (3) Rubber-band from latest anchor to cursor.\n if (cur && cur.anchors.length > 0 && s.cursor && s.draggingHandleAt === null) {\n const last = cur.anchors[cur.anchors.length - 1];\n const out2 = last.outHandle;\n const { x: sx, y: sy } = viewWorldToScreen(view, last);\n const { x: cx, y: cy } = viewWorldToScreen(view, s.cursor);\n let path: PolygonPath;\n if (out2) {\n const { x: c1x, y: c1y } = viewWorldToScreen(view, out2);\n path = {\n kind: 'polygon',\n commands: new Uint8Array([PATH_M, PATH_C]),\n coords: new Float32Array([sx, sy, c1x, c1y, cx, cy, cx, cy]),\n fillRule: 'nonzero',\n };\n } else {\n path = {\n kind: 'polygon',\n commands: new Uint8Array([PATH_M, PATH_L]),\n coords: new Float32Array([sx, sy, cx, cy]),\n fillRule: 'nonzero',\n };\n }\n out.push({\n kind: 'path',\n path,\n stroke: { paint: { kind: 'solid', color: style.rubberBandStroke }, width: 1 },\n });\n }\n\n // (4) Anchor dots + handles.\n if (cur) {\n for (let i = 0; i < cur.anchors.length; i++) {\n const a = cur.anchors[i];\n const { x: ax, y: ay } = viewWorldToScreen(view, a);\n out.push({\n kind: 'path',\n path: approximateCircle(ax, ay, r.anchor),\n fill: { paint: { kind: 'solid', color: style.anchorFill } },\n stroke: { paint: { kind: 'solid', color: style.anchorStroke }, width: 1 },\n });\n // Handle line + dot (only the latest anchor, per spec).\n if (i === cur.anchors.length - 1 && a.outHandle) {\n const { x: hx, y: hy } = viewWorldToScreen(view, a.outHandle);\n const linePath: PolygonPath = {\n kind: 'polygon',\n commands: new Uint8Array([PATH_M, PATH_L]),\n coords: new Float32Array([ax, ay, hx, hy]),\n fillRule: 'nonzero',\n };\n out.push({\n kind: 'path',\n path: linePath,\n stroke: { paint: { kind: 'solid', color: style.handleStroke }, width: 1 },\n });\n out.push({\n kind: 'path',\n path: approximateCircle(hx, hy, r.handleDot),\n fill: { paint: { kind: 'solid', color: style.handleStroke } },\n });\n const inSide = a.inHandle;\n if (inSide) {\n const { x: mx, y: my } = viewWorldToScreen(view, inSide);\n const inLine: PolygonPath = {\n kind: 'polygon',\n commands: new Uint8Array([PATH_M, PATH_L]),\n coords: new Float32Array([ax, ay, mx, my]),\n fillRule: 'nonzero',\n };\n out.push({\n kind: 'path',\n path: inLine,\n stroke: { paint: { kind: 'solid', color: style.handleStroke }, width: 1 },\n });\n out.push({\n kind: 'path',\n path: approximateCircle(mx, my, r.handleDot),\n fill: { paint: { kind: 'solid', color: style.handleStroke } },\n });\n }\n }\n }\n\n // (5) Close-hint ring on first anchor.\n if (s.closeHintActive && cur.anchors.length >= 3) {\n const first = cur.anchors[0];\n const { x: fx, y: fy } = viewWorldToScreen(view, first);\n out.push({\n kind: 'path',\n path: approximateCircle(fx, fy, r.closeHint),\n stroke: { paint: { kind: 'solid', color: style.closeHintFill }, width: 1.5 },\n });\n }\n }\n\n return out;\n },\n };\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
- import { boundsOfPath, boxToBox, originOf, poseFrameOf, regularPolygonPath, starPath, transformPath, worldCoords, worldEditToStorage } from "@weasel-js/geom";
1
+ import { boundsOfPath, boxToBox, clamp, originOf, poseFrameOf, regularPolygonPath, starPath, transformPath, worldCoords, worldEditToStorage } from "@weasel-js/geom";
2
2
 
3
- //#region src/domains/paths/shapeGenerator.ts
3
+ // src/domains/paths/shapeGenerator.ts
4
4
  /**
5
5
  * The parameters a polygon or star was drawn with, kept on the node beside the
6
6
  * geometry they made (`data.generator` beside `data.path`), so the shape stays
@@ -37,7 +37,6 @@ function shapeGeneratorOf(data) {
37
37
  const g = data?.generator;
38
38
  return isShapeGenerator(g) ? g : null;
39
39
  }
40
- var clamp = (v, lo, hi) => Math.min(hi, Math.max(lo, v));
41
40
  var count = (v) => clamp(Math.round(v), SHAPE_COUNT_RANGE.min, SHAPE_COUNT_RANGE.max);
42
41
  /** `g` with its counts rounded and every field held in range. */
43
42
  function clampShapeGenerator(g) {
@@ -138,6 +137,5 @@ function settleShapeGenerator(next, prev) {
138
137
  };
139
138
  }
140
139
 
141
- //#endregion
142
140
  export { SHAPE_COUNT_RANGE, STAR_RATIO_RANGE, clampShapeGenerator, isShapeGenerator, regenerateShape, settleShapeGenerator, shapeGeneratorOf, shapeGeneratorPath, withoutShapeGenerator };
143
141
  //# sourceMappingURL=shapeGenerator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"shapeGenerator.js","names":[],"sources":["../../../src/domains/paths/shapeGenerator.ts"],"sourcesContent":["/**\n * The parameters a polygon or star was drawn with, kept on the node beside the\n * geometry they made (`data.generator` beside `data.path`), so the shape stays\n * editable as a polygon or a star after it is drawn.\n *\n * `data.path` stays the geometry every reader uses; the generator only says how\n * to make it again. Editing the path itself turns the shape into plain\n * geometry: the generator is dropped, since it could no longer reproduce what\n * is drawn. A generator whose path no longer matches it (a writer that changed\n * the path without dropping it) is treated the same way.\n */\nimport {\n boundsOfPath,\n boxToBox,\n poseFrameOf,\n regularPolygonPath,\n starPath,\n transformPath,\n originOf,\n worldCoords,\n worldEditToStorage,\n type PathInWorldPose,\n type PolygonPath,\n} from '@weasel-js/geom';\n\n/** A regular polygon's parameters. `rotation` is the angle of its first\n * vertex, in radians, inside the pose's own rotation. */\nexport interface PolygonGenerator {\n kind: 'polygon';\n sides: number;\n rotation: number;\n}\n\n/** A star's parameters. `innerRadiusRatio` is the inner radius over the outer\n * one; `rotation` is the angle of its first point, in radians, inside the\n * pose's own rotation. */\nexport interface StarGenerator {\n kind: 'star';\n points: number;\n innerRadiusRatio: number;\n rotation: number;\n}\n\n/** The parameters a node's `data.path` was generated from. */\nexport type ShapeGenerator = PolygonGenerator | StarGenerator;\n\n/** The range of a polygon's side count and a star's point count. */\nexport const SHAPE_COUNT_RANGE = { min: 3, max: 32 } as const;\n\n/** The range of a star's `innerRadiusRatio`. */\nexport const STAR_RATIO_RANGE = { min: 0.01, max: 1 } as const;\n\nconst finite = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v);\n\n/** Whether `v` is a well-formed {@link ShapeGenerator}. */\nexport function isShapeGenerator(v: unknown): v is ShapeGenerator {\n if (v === null || typeof v !== 'object') return false;\n const g = v as Record<string, unknown>;\n if (!finite(g.rotation)) return false;\n if (g.kind === 'polygon') return finite(g.sides);\n if (g.kind === 'star') return finite(g.points) && finite(g.innerRadiusRatio);\n return false;\n}\n\n/** The generator a node's `data` holds, or `null`. */\nexport function shapeGeneratorOf(data: unknown): ShapeGenerator | null {\n const g = (data as { generator?: unknown } | null | undefined)?.generator;\n return isShapeGenerator(g) ? g : null;\n}\n\nconst clamp = (v: number, lo: number, hi: number): number => Math.min(hi, Math.max(lo, v));\nconst count = (v: number): number => clamp(Math.round(v), SHAPE_COUNT_RANGE.min, SHAPE_COUNT_RANGE.max);\n\n/** `g` with its counts rounded and every field held in range. */\nexport function clampShapeGenerator(g: ShapeGenerator): ShapeGenerator {\n if (g.kind === 'polygon') return { kind: 'polygon', sides: count(g.sides), rotation: g.rotation };\n return {\n kind: 'star',\n points: count(g.points),\n innerRadiusRatio: clamp(g.innerRadiusRatio, STAR_RATIO_RANGE.min, STAR_RATIO_RANGE.max),\n rotation: g.rotation,\n };\n}\n\n/** The shape `g` makes, on a circle of `radius` around `center`. */\nexport function shapeGeneratorPath(\n g: ShapeGenerator,\n center: { x: number; y: number } = { x: 0, y: 0 },\n radius = 1,\n): PolygonPath {\n const c = clampShapeGenerator(g);\n return c.kind === 'polygon'\n ? regularPolygonPath(center, radius, c.sides, c.rotation)\n : starPath(center, radius, c.points, radius * c.innerRadiusRatio, c.rotation);\n}\n\n/** `data` without its generator: the shape as plain geometry. */\nexport function withoutShapeGenerator<T>(data: T): T {\n if (data === null || typeof data !== 'object' || !('generator' in data)) return data;\n const { generator: _dropped, ...rest } = data as Record<string, unknown>;\n void _dropped;\n return rest as T;\n}\n\n/** Whether `path` is what `g` makes, up to the box-to-box map storage applies. */\nfunction pathMatches(path: unknown, g: ShapeGenerator): boolean {\n const p = path as PolygonPath | undefined;\n if (p?.kind !== 'polygon') return false;\n const unit = shapeGeneratorPath(g);\n if (p.coords.length !== unit.coords.length) return false;\n const u = boundsOfPath(unit);\n const b = boundsOfPath(p);\n const m = boxToBox(u.x, u.y, u.width, u.height, b.x, b.y, b.width, b.height);\n // Paths store float32 coordinates, so the slack scales with how far they are from the point they are measured from.\n const o = originOf(p);\n const tol = 1e-4 * Math.max(1, Math.abs(b.x - o.x) + b.width, Math.abs(b.y - o.y) + b.height);\n const at = worldCoords(p);\n for (let i = 0; i + 1 < unit.coords.length; i += 2) {\n const x = m[0] * unit.coords[i] + m[4];\n const y = m[3] * unit.coords[i + 1] + m[5];\n if (Math.abs(x - at[i]) > tol || Math.abs(y - at[i + 1]) > tol) return false;\n }\n return true;\n}\n\n/** A node's two halves, as a regeneration reads and writes them. */\nexport interface GeneratedShape<P extends PathInWorldPose = PathInWorldPose> {\n pose: P;\n data: unknown;\n}\n\n/**\n * `node` made again from `next`, in place: the new shape takes the box the old\n * one's circle had, under the same rotation and transform, so a star given\n * more points keeps its center and its size. Returns `null` when the node holds\n * no generator, or its path no longer matches the one it holds.\n */\nexport function regenerateShape<P extends PathInWorldPose>(\n node: GeneratedShape<P>,\n next: ShapeGenerator,\n): GeneratedShape<P> | null {\n const held = shapeGeneratorOf(node.data);\n if (!held || !pathMatches((node.data as { path?: unknown }).path, held)) return null;\n const g = clampShapeGenerator(next);\n const was = boundsOfPath(shapeGeneratorPath(held));\n const { pose } = node;\n // Where the unit circle of the held generator lands in the pose's local frame.\n const toLocal = boxToBox(was.x, was.y, was.width, was.height, pose.x, pose.y, pose.width, pose.height);\n const local = transformPath(shapeGeneratorPath(g), toLocal) as PolygonPath;\n const frame = poseFrameOf(pose);\n const world = frame ? (transformPath(local, frame) as PolygonPath) : local;\n const stored = worldEditToStorage(pose, world);\n return { pose: stored.pose, data: { ...(node.data as object), path: stored.path, generator: g } };\n}\n\n/**\n * What a write that left a node as `next`, from `prev`, stores: when the write\n * changed the generator, the shape made again from it. A generator written\n * onto a node that held none, or of another kind, or onto one whose path no\n * longer matches, is dropped, leaving the shape as plain geometry. Any other\n * write is stored as written. Fits `NodePropertiesEntry.settle`.\n */\nexport function settleShapeGenerator<N extends { pose: unknown; data: unknown }>(next: N, prev: N): N {\n const data = next.data as Record<string, unknown> | null;\n if (data === null || typeof data !== 'object' || !('generator' in data)) return next;\n const raw = data.generator;\n const held = shapeGeneratorOf(prev.data);\n if (held !== null && JSON.stringify(raw) === JSON.stringify(held)) return next;\n const regenerated = held !== null && isShapeGenerator(raw) && raw.kind === held.kind\n ? regenerateShape({ pose: next.pose as PathInWorldPose, data: { ...data, generator: held } }, raw)\n : null;\n return { ...next, ...(regenerated ?? { data: withoutShapeGenerator(next.data) }) };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"shapeGenerator.js","names":[],"sources":["../../../src/domains/paths/shapeGenerator.ts"],"sourcesContent":["/**\n * The parameters a polygon or star was drawn with, kept on the node beside the\n * geometry they made (`data.generator` beside `data.path`), so the shape stays\n * editable as a polygon or a star after it is drawn.\n *\n * `data.path` stays the geometry every reader uses; the generator only says how\n * to make it again. Editing the path itself turns the shape into plain\n * geometry: the generator is dropped, since it could no longer reproduce what\n * is drawn. A generator whose path no longer matches it (a writer that changed\n * the path without dropping it) is treated the same way.\n */\nimport {\n boundsOfPath,\n boxToBox,\n clamp,\n poseFrameOf,\n regularPolygonPath,\n starPath,\n transformPath,\n originOf,\n worldCoords,\n worldEditToStorage,\n type PathInWorldPose,\n type PolygonPath,\n} from '@weasel-js/geom';\n\n/** A regular polygon's parameters. `rotation` is the angle of its first\n * vertex, in radians, inside the pose's own rotation. */\nexport interface PolygonGenerator {\n kind: 'polygon';\n sides: number;\n rotation: number;\n}\n\n/** A star's parameters. `innerRadiusRatio` is the inner radius over the outer\n * one; `rotation` is the angle of its first point, in radians, inside the\n * pose's own rotation. */\nexport interface StarGenerator {\n kind: 'star';\n points: number;\n innerRadiusRatio: number;\n rotation: number;\n}\n\n/** The parameters a node's `data.path` was generated from. */\nexport type ShapeGenerator = PolygonGenerator | StarGenerator;\n\n/** The range of a polygon's side count and a star's point count. */\nexport const SHAPE_COUNT_RANGE = { min: 3, max: 32 } as const;\n\n/** The range of a star's `innerRadiusRatio`. */\nexport const STAR_RATIO_RANGE = { min: 0.01, max: 1 } as const;\n\nconst finite = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v);\n\n/** Whether `v` is a well-formed {@link ShapeGenerator}. */\nexport function isShapeGenerator(v: unknown): v is ShapeGenerator {\n if (v === null || typeof v !== 'object') return false;\n const g = v as Record<string, unknown>;\n if (!finite(g.rotation)) return false;\n if (g.kind === 'polygon') return finite(g.sides);\n if (g.kind === 'star') return finite(g.points) && finite(g.innerRadiusRatio);\n return false;\n}\n\n/** The generator a node's `data` holds, or `null`. */\nexport function shapeGeneratorOf(data: unknown): ShapeGenerator | null {\n const g = (data as { generator?: unknown } | null | undefined)?.generator;\n return isShapeGenerator(g) ? g : null;\n}\n\nconst count = (v: number): number => clamp(Math.round(v), SHAPE_COUNT_RANGE.min, SHAPE_COUNT_RANGE.max);\n\n/** `g` with its counts rounded and every field held in range. */\nexport function clampShapeGenerator(g: ShapeGenerator): ShapeGenerator {\n if (g.kind === 'polygon') return { kind: 'polygon', sides: count(g.sides), rotation: g.rotation };\n return {\n kind: 'star',\n points: count(g.points),\n innerRadiusRatio: clamp(g.innerRadiusRatio, STAR_RATIO_RANGE.min, STAR_RATIO_RANGE.max),\n rotation: g.rotation,\n };\n}\n\n/** The shape `g` makes, on a circle of `radius` around `center`. */\nexport function shapeGeneratorPath(\n g: ShapeGenerator,\n center: { x: number; y: number } = { x: 0, y: 0 },\n radius = 1,\n): PolygonPath {\n const c = clampShapeGenerator(g);\n return c.kind === 'polygon'\n ? regularPolygonPath(center, radius, c.sides, c.rotation)\n : starPath(center, radius, c.points, radius * c.innerRadiusRatio, c.rotation);\n}\n\n/** `data` without its generator: the shape as plain geometry. */\nexport function withoutShapeGenerator<T>(data: T): T {\n if (data === null || typeof data !== 'object' || !('generator' in data)) return data;\n const { generator: _dropped, ...rest } = data as Record<string, unknown>;\n void _dropped;\n return rest as T;\n}\n\n/** Whether `path` is what `g` makes, up to the box-to-box map storage applies. */\nfunction pathMatches(path: unknown, g: ShapeGenerator): boolean {\n const p = path as PolygonPath | undefined;\n if (p?.kind !== 'polygon') return false;\n const unit = shapeGeneratorPath(g);\n if (p.coords.length !== unit.coords.length) return false;\n const u = boundsOfPath(unit);\n const b = boundsOfPath(p);\n const m = boxToBox(u.x, u.y, u.width, u.height, b.x, b.y, b.width, b.height);\n // Paths store float32 coordinates, so the slack scales with how far they are from the point they are measured from.\n const o = originOf(p);\n const tol = 1e-4 * Math.max(1, Math.abs(b.x - o.x) + b.width, Math.abs(b.y - o.y) + b.height);\n const at = worldCoords(p);\n for (let i = 0; i + 1 < unit.coords.length; i += 2) {\n const x = m[0] * unit.coords[i] + m[4];\n const y = m[3] * unit.coords[i + 1] + m[5];\n if (Math.abs(x - at[i]) > tol || Math.abs(y - at[i + 1]) > tol) return false;\n }\n return true;\n}\n\n/** A node's two halves, as a regeneration reads and writes them. */\nexport interface GeneratedShape<P extends PathInWorldPose = PathInWorldPose> {\n pose: P;\n data: unknown;\n}\n\n/**\n * `node` made again from `next`, in place: the new shape takes the box the old\n * one's circle had, under the same rotation and transform, so a star given\n * more points keeps its center and its size. Returns `null` when the node holds\n * no generator, or its path no longer matches the one it holds.\n */\nexport function regenerateShape<P extends PathInWorldPose>(\n node: GeneratedShape<P>,\n next: ShapeGenerator,\n): GeneratedShape<P> | null {\n const held = shapeGeneratorOf(node.data);\n if (!held || !pathMatches((node.data as { path?: unknown }).path, held)) return null;\n const g = clampShapeGenerator(next);\n const was = boundsOfPath(shapeGeneratorPath(held));\n const { pose } = node;\n // Where the unit circle of the held generator lands in the pose's local frame.\n const toLocal = boxToBox(was.x, was.y, was.width, was.height, pose.x, pose.y, pose.width, pose.height);\n const local = transformPath(shapeGeneratorPath(g), toLocal) as PolygonPath;\n const frame = poseFrameOf(pose);\n const world = frame ? (transformPath(local, frame) as PolygonPath) : local;\n const stored = worldEditToStorage(pose, world);\n return { pose: stored.pose, data: { ...(node.data as object), path: stored.path, generator: g } };\n}\n\n/**\n * What a write that left a node as `next`, from `prev`, stores: when the write\n * changed the generator, the shape made again from it. A generator written\n * onto a node that held none, or of another kind, or onto one whose path no\n * longer matches, is dropped, leaving the shape as plain geometry. Any other\n * write is stored as written. Fits `NodePropertiesEntry.settle`.\n */\nexport function settleShapeGenerator<N extends { pose: unknown; data: unknown }>(next: N, prev: N): N {\n const data = next.data as Record<string, unknown> | null;\n if (data === null || typeof data !== 'object' || !('generator' in data)) return next;\n const raw = data.generator;\n const held = shapeGeneratorOf(prev.data);\n if (held !== null && JSON.stringify(raw) === JSON.stringify(held)) return next;\n const regenerated = held !== null && isShapeGenerator(raw) && raw.kind === held.kind\n ? regenerateShape({ pose: next.pose as PathInWorldPose, data: { ...data, generator: held } }, raw)\n : null;\n return { ...next, ...(regenerated ?? { data: withoutShapeGenerator(next.data) }) };\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
- import { findShapeSilhouette } from "../../canvas/NodeShape.js";
2
1
  import { isSilhouettePose } from "../../core/geometry/regionHit.js";
2
+ import { findShapeSilhouette } from "../../canvas/NodeShape.js";
3
3
 
4
- //#region src/domains/paths/strokeOutline.ts
4
+ // src/domains/paths/strokeOutline.ts
5
5
  /** The outline `node` is drawn with, in world coords: its pose when the pose
6
6
  * is a polygon, else its painter's silhouette. Null for a node with neither. */
7
7
  function nodeOutline(node) {
@@ -10,6 +10,5 @@ function nodeOutline(node) {
10
10
  return findShapeSilhouette(node, pose);
11
11
  }
12
12
 
13
- //#endregion
14
13
  export { nodeOutline };
15
14
  //# sourceMappingURL=strokeOutline.js.map
@@ -2,7 +2,7 @@ import { anchorFieldsOf } from "../../interactions/actions/defaults/anchorFields
2
2
  import { useMemo, useSyncExternalStore } from "react";
3
3
  import { useActionsRegistry, useOptionalDepRegistry } from "@weasel-js/routing/react";
4
4
 
5
- //#region src/domains/paths/useAnchorFields.ts
5
+ // src/domains/paths/useAnchorFields.ts
6
6
  /**
7
7
  * The anchor fields of the path being edited, for chrome beside the canvas:
8
8
  * a panel showing the selected anchors' numbers and writing typed ones back.
@@ -30,6 +30,5 @@ function useAnchorFields() {
30
30
  }), [json, actions]);
31
31
  }
32
32
 
33
- //#endregion
34
33
  export { useAnchorFields };
35
34
  //# sourceMappingURL=useAnchorFields.js.map
@@ -1,11 +1,11 @@
1
1
  import { rectFromPlane } from "../../core/viewport/parallax.js";
2
2
  import { liveAnchorMarkers, liveEditablePath } from "./editablePath.js";
3
- import { createPathEditState } from "./pathEditState.js";
4
3
  import { createPathEditingOverlayLayer } from "./pathEditingOverlayLayer.js";
4
+ import { createPathEditState } from "./pathEditState.js";
5
5
  import { useEffect, useMemo, useState } from "react";
6
6
  import { useLatest } from "@weasel-js/react";
7
7
 
8
- //#region src/domains/paths/usePathEdit.ts
8
+ // src/domains/paths/usePathEdit.ts
9
9
  /**
10
10
  * The path-edit state and its anchor overlay for one canvas surface.
11
11
  */
@@ -59,6 +59,5 @@ function usePathEditOverlayLayer(state, inputs, config) {
59
59
  ]);
60
60
  }
61
61
 
62
- //#endregion
63
62
  export { usePathEditOverlayLayer, usePathEditState };
64
63
  //# sourceMappingURL=usePathEdit.js.map
@@ -1,7 +1,7 @@
1
1
  import { useCallback, useEffect, useMemo, useRef } from "react";
2
2
  import { useLatest, useVisibleRaf } from "@weasel-js/react";
3
3
 
4
- //#region src/domains/poseRun/usePoseRun.ts
4
+ // src/domains/poseRun/usePoseRun.ts
5
5
  /**
6
6
  * A pose run: poses published per frame, committed once.
7
7
  *
@@ -124,6 +124,5 @@ function usePoseRun(opts) {
124
124
  }), [loop]);
125
125
  }
126
126
 
127
- //#endregion
128
127
  export { usePoseRun };
129
128
  //# sourceMappingURL=usePoseRun.js.map
@@ -5,7 +5,7 @@ import { enteredOperandOutlines } from "./enteredOperands.js";
5
5
  import { transformPath } from "@weasel-js/geom";
6
6
  import { useMemo } from "react";
7
7
 
8
- //#region src/domains/selection/enteredGroupFrame.ts
8
+ // src/domains/selection/enteredGroupFrame.ts
9
9
  /** The theme token the frame reads its color from, set on the canvas or any element above it. */
10
10
  var ENTERED_FRAME_TOKEN = "--wzl-entered-group";
11
11
  /** The frame's color where nothing sets {@link ENTERED_FRAME_TOKEN}. */
@@ -99,6 +99,5 @@ function useEnteredGroupFrameLayer(entered, boundsOf, color, scene) {
99
99
  ]);
100
100
  }
101
101
 
102
- //#endregion
103
102
  export { ENTERED_FRAME_COLOR, ENTERED_FRAME_TOKEN, createEnteredGroupFrameLayer, useEnteredGroupFrameLayer };
104
103
  //# sourceMappingURL=enteredGroupFrame.js.map
@@ -2,7 +2,7 @@ import { reachableInGroup } from "../../canvas/deps/enteredGroup.js";
2
2
  import { createEmitter } from "@weasel-js/registry";
3
3
  import { OUT_OF_SCOPE_ALPHA } from "@weasel-js/modes";
4
4
 
5
- //#region src/domains/selection/enteredGroupScope.ts
5
+ // src/domains/selection/enteredGroupScope.ts
6
6
  /**
7
7
  * The entered group as a scope: everything outside its subtree dims and stops taking hits, and
8
8
  * so does the group itself, whose empty box is empty canvas while it is entered. With nothing
@@ -39,6 +39,5 @@ function createEnteredGroupScope(opts) {
39
39
  };
40
40
  }
41
41
 
42
- //#endregion
43
42
  export { createEnteredGroupScope };
44
43
  //# sourceMappingURL=enteredGroupScope.js.map
@@ -1,7 +1,7 @@
1
1
  import { operandOf } from "../../core/scene/booleanOfChildren.js";
2
2
  import { sceneDepLookup } from "../../canvas/derivedPath.js";
3
3
 
4
- //#region src/domains/selection/enteredOperands.ts
4
+ // src/domains/selection/enteredOperands.ts
5
5
  /** The world outline of each shown node under the outermost node at or above `entered` that
6
6
  * consumes its children, a group's members each on their own; none when no such node is. */
7
7
  function enteredOperandOutlines(scene, entered) {
@@ -24,6 +24,5 @@ function enteredOperandOutlines(scene, entered) {
24
24
  return out;
25
25
  }
26
26
 
27
- //#endregion
28
27
  export { enteredOperandOutlines };
29
28
  //# sourceMappingURL=enteredOperands.js.map
@@ -1,13 +1,13 @@
1
+ import { angleOf, localToWorld, targetTransformOf } from "../../core/geometry/targetFrame.js";
1
2
  import { viewToTransform } from "../../core/viewport/view.js";
2
3
  import { worldToScreen } from "../../core/viewport/viewTransform.js";
3
4
  import { HANDLE_BASE_PX } from "../../core/device/targets.js";
4
- import { angleOf, localToWorld, targetTransformOf } from "../../core/geometry/targetFrame.js";
5
5
  import { handlePoint, resizeHandlesFor } from "../../interactions/actions/resize/cornerHandles.js";
6
6
  import { screenAngleOf } from "@weasel-js/geom";
7
7
  import { alignedStrokeRect } from "@weasel-js/paint";
8
8
  import { resolveStrokeWidth } from "@weasel-js/stroke";
9
9
 
10
- //#region src/domains/selection/handleCommands.ts
10
+ // src/domains/selection/handleCommands.ts
11
11
  var DEFAULT_HANDLE_FILL = { paint: {
12
12
  kind: "solid",
13
13
  color: "#d4c4a8"
@@ -111,6 +111,5 @@ function handleCommandsFor(ids, resolveBounds, handles, handlesOf, layoutOpts, v
111
111
  return out;
112
112
  }
113
113
 
114
- //#endregion
115
114
  export { handleCommandsFor, rectPathFor, resolveHandles };
116
115
  //# sourceMappingURL=handleCommands.js.map
@@ -1,17 +1,17 @@
1
- import { viewToTransform } from "../../core/viewport/view.js";
2
- import { worldToScreen } from "../../core/viewport/viewTransform.js";
3
- import { AUTO_POSE_DESCRIPTOR } from "../../core/geometry/autoPoseDescriptor.js";
4
- import { targetCorners, targetTransformOf } from "../../core/geometry/targetFrame.js";
5
- import { MULTI_RESIZE_TARGET_ID } from "../../core/selection/selectionTarget.js";
6
1
  import { composeSelectionPose, containerAwareBoundsResolver } from "./selectionPose.js";
2
+ import { targetCorners, targetTransformOf } from "../../core/geometry/targetFrame.js";
3
+ import { AUTO_POSE_DESCRIPTOR } from "../../core/geometry/autoPoseDescriptor.js";
7
4
  import { DEFAULT_ROTATION_HANDLE_DISTANCE, rotationHandle } from "../../interactions/actions/rotate/handle.js";
5
+ import { MULTI_RESIZE_TARGET_ID } from "../../core/selection/selectionTarget.js";
6
+ import { viewToTransform } from "../../core/viewport/view.js";
7
+ import { worldToScreen } from "../../core/viewport/viewTransform.js";
8
8
  import { handleCommandsFor, rectPathFor, resolveHandles } from "./handleCommands.js";
9
9
  import { mat3 } from "@weasel-js/renderer";
10
10
  import { PATH_L, PATH_M, PATH_Z } from "@weasel-js/geom";
11
11
  import { alignedStrokeRect } from "@weasel-js/paint";
12
12
  import { resolveStrokeWidth } from "@weasel-js/stroke";
13
13
 
14
- //#region src/domains/selection/overlay.ts
14
+ // src/domains/selection/overlay.ts
15
15
  /** Project world AABB into screen-space AABB using the active view. */
16
16
  function projectBounds(b, view) {
17
17
  const t = viewToTransform(view);
@@ -389,6 +389,5 @@ function asChromeState(data) {
389
389
  return null;
390
390
  }
391
391
 
392
- //#endregion
393
392
  export { composeSelectionPose, createSelectionHandlesLayer, createSelectionOutlineLayer, createSelectionOverlayLayer, rotationBadgeOf };
394
393
  //# sourceMappingURL=overlay.js.map
@@ -1,9 +1,9 @@
1
+ import { drawnAABBOf, drawnBoundsOf } from "../../canvas/drawnBounds.js";
1
2
  import { unionAABB } from "../../core/geometry/unionBounds.js";
2
3
  import { framedBounds, visualBoundsViaDescriptor } from "../../core/geometry/poseDescriptor.js";
3
4
  import { AUTO_POSE_DESCRIPTOR } from "../../core/geometry/autoPoseDescriptor.js";
4
- import { drawnAABBOf, drawnBoundsOf } from "../../canvas/drawnBounds.js";
5
5
 
6
- //#region src/domains/selection/selectionPose.ts
6
+ // src/domains/selection/selectionPose.ts
7
7
  /**
8
8
  * Transitive leaf ids under `id`. A childless node is a leaf only if it is not
9
9
  * itself a container: an empty container contributes no bounds, and its own
@@ -107,6 +107,5 @@ function containerAwareBoundsResolver(getPose, d, getChildren, isContainer, scen
107
107
  };
108
108
  }
109
109
 
110
- //#endregion
111
110
  export { composeSelectionPose, containerAwareBoundsResolver };
112
111
  //# sourceMappingURL=selectionPose.js.map
@@ -1,9 +1,10 @@
1
1
  import { distinct, markFromPlane } from "./marks.js";
2
2
  import { screenOf } from "./screen.js";
3
3
  import { stepAngles } from "./stepAngles.js";
4
+ import { wrapPositive } from "@weasel-js/geom";
4
5
  import { resolveSnap } from "@weasel-js/geom/nd";
5
6
 
6
- //#region src/domains/snap/angle2d.ts
7
+ // src/domains/snap/angle2d.ts
7
8
  /** A snap session's one-dimensional path: an angle about a pivot, snapped by
8
9
  * the same resolver as a point, with reach carried through the radius. */
9
10
  var TURN = Math.PI * 2;
@@ -140,7 +141,7 @@ function rayMarks(inputs, theta) {
140
141
  x: pivot.x + r * Math.cos(dir),
141
142
  y: pivot.y + r * Math.sin(dir)
142
143
  };
143
- const deg = (Math.round(theta * 180 / Math.PI) % 360 + 360) % 360;
144
+ const deg = wrapPositive(Math.round(theta * 180 / Math.PI), 360);
144
145
  return [{
145
146
  kind: "line",
146
147
  from: pivot,
@@ -153,6 +154,5 @@ function rayMarks(inputs, theta) {
153
154
  }];
154
155
  }
155
156
 
156
- //#endregion
157
157
  export { angleAt };
158
158
  //# sourceMappingURL=angle2d.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"angle2d.js","names":[],"sources":["../../../src/domains/snap/angle2d.ts"],"sourcesContent":["/** A snap session's one-dimensional path: an angle about a pivot, snapped by\n * the same resolver as a point, with reach carried through the radius. */\nimport { resolveSnap, type SnapCandidate } from '@weasel-js/geom/nd';\nimport type { SnapMods } from 'interactions/actions/snapDep';\nimport { distinct, markFromPlane } from './marks';\nimport { screenOf } from './screen';\nimport { stepAngles } from './stepAngles';\nimport type { Session2dInputs } from './session2d';\nimport type { AngleCollect, SnapMark, SnapMarks, SnapSource } from './types';\n\nconst TURN = Math.PI * 2;\nconst PROBE = 'angle';\n/** A press near the pivot turns px reach into a wide angle; it reaches no\n * further than this. */\nconst MAX_REACH_RAD = Math.PI / 6;\n\n/** Where `theta` lands, and what it met. Writes the marks to the store. */\nexport function angleAt(\n inputs: Session2dInputs, sources: readonly SnapSource[], theta: number, mods: SnapMods,\n): { theta: number; marks: readonly SnapMark[] } {\n const { req, store } = inputs;\n // Screen px per radian, or 1 when the gesture gives its reach in radians.\n const scale = req.reachRad !== undefined ? 1 : pressRadiusPx(inputs);\n const reachOf = (s: SnapSource) => req.reachRad\n ?? Math.min(s.reachPx ?? inputs.reachPx, MAX_REACH_RAD * scale);\n const candidates = collectAngles(inputs, sources, theta, mods, reachOf);\n if (candidates.length === 0) {\n store.set([]);\n return { theta, marks: [] };\n }\n const res = resolveSnap({\n probes: [{ id: PROBE, at: [0], role: 'pointer' }],\n input: { at: [0], dirs: [[1]] },\n delta0: [theta],\n candidates,\n // No radius, no reach: only a required angle can win.\n toScreen: ([t]) => [scale > 0 ? t * scale : NaN],\n });\n const out = res.delta[0];\n const marks = distinct(res.satisfied.flatMap((c) => {\n const m = c.mark ?? rayMarks(inputs, out);\n return 'kind' in m ? [m] : m;\n }));\n const plane = req.plane?.() ?? null;\n store.set(plane ? marks.map((m) => markFromPlane(m, plane)) : marks);\n return { theta: out, marks };\n}\n\nfunction collectAngles(\n inputs: Session2dInputs, sources: readonly SnapSource[], theta: number, mods: SnapMods,\n reachOf: (s: SnapSource) => number,\n): SnapCandidate<SnapMarks>[] {\n const { req } = inputs;\n const out: SnapCandidate<SnapMarks>[] = [];\n const c = req.constrain;\n if (mods.constrain && typeof c === 'object' && c.step > 0) {\n for (const at of stepAngles(theta, c.step)) {\n out.push({ probe: PROBE, locus: { at: [at], dirs: [] }, source: 'constrain', order: -1, tier: 'target', reachPx: 0, required: true });\n }\n }\n const theta0 = req.theta0 ?? 0;\n if (mods.hold) {\n const at = theta0 + TURN * Math.round((theta - theta0) / TURN);\n out.push({ probe: PROBE, locus: { at: [at], dirs: [] }, source: 'hold', order: -1, tier: 'target', reachPx: 0, required: true, mark: [] });\n }\n if (mods.suspend) return out;\n const q: AngleCollect = {\n pivot: req.pivot ?? req.press,\n press: req.press,\n theta0,\n theta,\n ids: req.ids ?? [],\n exclude: inputs.exclude ?? req.ids ?? [],\n mods,\n ...(req.also ? { also: req.also } : {}),\n ...(inputs.scene ? { scene: inputs.scene } : {}),\n ...(inputs.rotationOf ? { rotationOf: inputs.rotationOf } : {}),\n };\n // Runs across sources and their yields: an earlier source, then an earlier\n // yield, wins a tie.\n let order = 0;\n sources.forEach((source) => {\n if (!source.angles) return;\n const reachPx = reachOf(source);\n for (const a of source.angles(q)) {\n // The whole turn of the angle nearest `theta`: 0 catches 359°.\n const at = a.angle + TURN * Math.round((theta - a.angle) / TURN);\n out.push({\n probe: PROBE, locus: { at: [at], dirs: [] }, source: source.id, order: order++, tier: source.tier ?? 'target', reachPx,\n ...(a.required ? { required: true } : {}),\n ...(a.mark ? { mark: a.mark } : {}),\n });\n }\n });\n return out;\n}\n\n/** The screen distance from the pivot to the press: what turns reach in px\n * into radians. */\nfunction pressRadiusPx(inputs: Session2dInputs): number {\n const { req } = inputs;\n const pivot = req.pivot ?? req.press;\n const toScreen = screenOf(inputs.view(), req.plane?.() ?? null);\n const [ax, ay] = toScreen([pivot.x, pivot.y]);\n const [bx, by] = toScreen([req.press.x, req.press.y]);\n return Math.hypot(bx - ax, by - ay);\n}\n\n/** A ray from the pivot out to the press radius, along where the pointer\n * lands at `theta`, labeled with `theta` in degrees. */\nfunction rayMarks(inputs: Session2dInputs, theta: number): SnapMark[] {\n const { req } = inputs;\n const pivot = req.pivot ?? req.press;\n const r = Math.hypot(req.press.x - pivot.x, req.press.y - pivot.y);\n const dir = Math.atan2(req.press.y - pivot.y, req.press.x - pivot.x) + theta - (req.theta0 ?? 0);\n const end = { x: pivot.x + r * Math.cos(dir), y: pivot.y + r * Math.sin(dir) };\n const deg = ((Math.round(theta * 180 / Math.PI) % 360) + 360) % 360;\n return [\n { kind: 'line', from: pivot, to: end },\n { kind: 'point', at: end, glyph: 'quadrant', label: `${deg}°` },\n ];\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"angle2d.js","names":[],"sources":["../../../src/domains/snap/angle2d.ts"],"sourcesContent":["/** A snap session's one-dimensional path: an angle about a pivot, snapped by\n * the same resolver as a point, with reach carried through the radius. */\nimport { wrapPositive } from '@weasel-js/geom';\nimport { resolveSnap, type SnapCandidate } from '@weasel-js/geom/nd';\nimport type { SnapMods } from 'interactions/actions/snapDep';\nimport { distinct, markFromPlane } from './marks';\nimport { screenOf } from './screen';\nimport { stepAngles } from './stepAngles';\nimport type { Session2dInputs } from './session2d';\nimport type { AngleCollect, SnapMark, SnapMarks, SnapSource } from './types';\n\nconst TURN = Math.PI * 2;\nconst PROBE = 'angle';\n/** A press near the pivot turns px reach into a wide angle; it reaches no\n * further than this. */\nconst MAX_REACH_RAD = Math.PI / 6;\n\n/** Where `theta` lands, and what it met. Writes the marks to the store. */\nexport function angleAt(\n inputs: Session2dInputs, sources: readonly SnapSource[], theta: number, mods: SnapMods,\n): { theta: number; marks: readonly SnapMark[] } {\n const { req, store } = inputs;\n // Screen px per radian, or 1 when the gesture gives its reach in radians.\n const scale = req.reachRad !== undefined ? 1 : pressRadiusPx(inputs);\n const reachOf = (s: SnapSource) => req.reachRad\n ?? Math.min(s.reachPx ?? inputs.reachPx, MAX_REACH_RAD * scale);\n const candidates = collectAngles(inputs, sources, theta, mods, reachOf);\n if (candidates.length === 0) {\n store.set([]);\n return { theta, marks: [] };\n }\n const res = resolveSnap({\n probes: [{ id: PROBE, at: [0], role: 'pointer' }],\n input: { at: [0], dirs: [[1]] },\n delta0: [theta],\n candidates,\n // No radius, no reach: only a required angle can win.\n toScreen: ([t]) => [scale > 0 ? t * scale : NaN],\n });\n const out = res.delta[0];\n const marks = distinct(res.satisfied.flatMap((c) => {\n const m = c.mark ?? rayMarks(inputs, out);\n return 'kind' in m ? [m] : m;\n }));\n const plane = req.plane?.() ?? null;\n store.set(plane ? marks.map((m) => markFromPlane(m, plane)) : marks);\n return { theta: out, marks };\n}\n\nfunction collectAngles(\n inputs: Session2dInputs, sources: readonly SnapSource[], theta: number, mods: SnapMods,\n reachOf: (s: SnapSource) => number,\n): SnapCandidate<SnapMarks>[] {\n const { req } = inputs;\n const out: SnapCandidate<SnapMarks>[] = [];\n const c = req.constrain;\n if (mods.constrain && typeof c === 'object' && c.step > 0) {\n for (const at of stepAngles(theta, c.step)) {\n out.push({ probe: PROBE, locus: { at: [at], dirs: [] }, source: 'constrain', order: -1, tier: 'target', reachPx: 0, required: true });\n }\n }\n const theta0 = req.theta0 ?? 0;\n if (mods.hold) {\n const at = theta0 + TURN * Math.round((theta - theta0) / TURN);\n out.push({ probe: PROBE, locus: { at: [at], dirs: [] }, source: 'hold', order: -1, tier: 'target', reachPx: 0, required: true, mark: [] });\n }\n if (mods.suspend) return out;\n const q: AngleCollect = {\n pivot: req.pivot ?? req.press,\n press: req.press,\n theta0,\n theta,\n ids: req.ids ?? [],\n exclude: inputs.exclude ?? req.ids ?? [],\n mods,\n ...(req.also ? { also: req.also } : {}),\n ...(inputs.scene ? { scene: inputs.scene } : {}),\n ...(inputs.rotationOf ? { rotationOf: inputs.rotationOf } : {}),\n };\n // Runs across sources and their yields: an earlier source, then an earlier\n // yield, wins a tie.\n let order = 0;\n sources.forEach((source) => {\n if (!source.angles) return;\n const reachPx = reachOf(source);\n for (const a of source.angles(q)) {\n // The whole turn of the angle nearest `theta`: 0 catches 359°.\n const at = a.angle + TURN * Math.round((theta - a.angle) / TURN);\n out.push({\n probe: PROBE, locus: { at: [at], dirs: [] }, source: source.id, order: order++, tier: source.tier ?? 'target', reachPx,\n ...(a.required ? { required: true } : {}),\n ...(a.mark ? { mark: a.mark } : {}),\n });\n }\n });\n return out;\n}\n\n/** The screen distance from the pivot to the press: what turns reach in px\n * into radians. */\nfunction pressRadiusPx(inputs: Session2dInputs): number {\n const { req } = inputs;\n const pivot = req.pivot ?? req.press;\n const toScreen = screenOf(inputs.view(), req.plane?.() ?? null);\n const [ax, ay] = toScreen([pivot.x, pivot.y]);\n const [bx, by] = toScreen([req.press.x, req.press.y]);\n return Math.hypot(bx - ax, by - ay);\n}\n\n/** A ray from the pivot out to the press radius, along where the pointer\n * lands at `theta`, labeled with `theta` in degrees. */\nfunction rayMarks(inputs: Session2dInputs, theta: number): SnapMark[] {\n const { req } = inputs;\n const pivot = req.pivot ?? req.press;\n const r = Math.hypot(req.press.x - pivot.x, req.press.y - pivot.y);\n const dir = Math.atan2(req.press.y - pivot.y, req.press.x - pivot.x) + theta - (req.theta0 ?? 0);\n const end = { x: pivot.x + r * Math.cos(dir), y: pivot.y + r * Math.sin(dir) };\n const deg = wrapPositive(Math.round(theta * 180 / Math.PI), 360);\n return [\n { kind: 'line', from: pivot, to: end },\n { kind: 'point', at: end, glyph: 'quadrant', label: `${deg}°` },\n ];\n}\n"],"mappings":";;;;;;;;;AAWA,IAAM,OAAO,KAAK,KAAK;AACvB,IAAM,QAAQ;;;AAGd,IAAM,gBAAgB,KAAK,KAAK;;AAGhC,SAAgB,QACd,QAAyB,SAAgC,OAAe,MACzB;CAC/C,MAAM,EAAE,KAAK,UAAU;CAEvB,MAAM,QAAQ,IAAI,aAAa,SAAY,IAAI,cAAc,MAAM;CACnE,MAAM,WAAW,MAAkB,IAAI,YAClC,KAAK,IAAI,EAAE,WAAW,OAAO,SAAS,gBAAgB,KAAK;CAChE,MAAM,aAAa,cAAc,QAAQ,SAAS,OAAO,MAAM,OAAO;CACtE,IAAI,WAAW,WAAW,GAAG;EAC3B,MAAM,IAAI,CAAC,CAAC;EACZ,OAAO;GAAE;GAAO,OAAO,CAAC;EAAE;CAC5B;CACA,MAAM,MAAM,YAAY;EACtB,QAAQ,CAAC;GAAE,IAAI;GAAO,IAAI,CAAC,CAAC;GAAG,MAAM;EAAU,CAAC;EAChD,OAAO;GAAE,IAAI,CAAC,CAAC;GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;EAAE;EAC9B,QAAQ,CAAC,KAAK;EACd;EAEA,WAAW,CAAC,OAAO,CAAC,QAAQ,IAAI,IAAI,QAAQ,GAAG;CACjD,CAAC;CACD,MAAM,MAAM,IAAI,MAAM;CACtB,MAAM,QAAQ,SAAS,IAAI,UAAU,SAAS,MAAM;EAClD,MAAM,IAAI,EAAE,QAAQ,SAAS,QAAQ,GAAG;EACxC,OAAO,UAAU,IAAI,CAAC,CAAC,IAAI;CAC7B,CAAC,CAAC;CACF,MAAM,QAAQ,IAAI,QAAQ,KAAK;CAC/B,MAAM,IAAI,QAAQ,MAAM,KAAK,MAAM,cAAc,GAAG,KAAK,CAAC,IAAI,KAAK;CACnE,OAAO;EAAE,OAAO;EAAK;CAAM;AAC7B;AAEA,SAAS,cACP,QAAyB,SAAgC,OAAe,MACxE,SAC4B;CAC5B,MAAM,EAAE,QAAQ;CAChB,MAAM,MAAkC,CAAC;CACzC,MAAM,IAAI,IAAI;CACd,IAAI,KAAK,aAAa,OAAO,MAAM,YAAY,EAAE,OAAO,GACtD,KAAK,MAAM,MAAM,WAAW,OAAO,EAAE,IAAI,GACvC,IAAI,KAAK;EAAE,OAAO;EAAO,OAAO;GAAE,IAAI,CAAC,EAAE;GAAG,MAAM,CAAC;EAAE;EAAG,QAAQ;EAAa,OAAO;EAAI,MAAM;EAAU,SAAS;EAAG,UAAU;CAAK,CAAC;CAGxI,MAAM,SAAS,IAAI,UAAU;CAC7B,IAAI,KAAK,MAAM;EACb,MAAM,KAAK,SAAS,OAAO,KAAK,OAAO,QAAQ,UAAU,IAAI;EAC7D,IAAI,KAAK;GAAE,OAAO;GAAO,OAAO;IAAE,IAAI,CAAC,EAAE;IAAG,MAAM,CAAC;GAAE;GAAG,QAAQ;GAAQ,OAAO;GAAI,MAAM;GAAU,SAAS;GAAG,UAAU;GAAM,MAAM,CAAC;EAAE,CAAC;CAC3I;CACA,IAAI,KAAK,SAAS,OAAO;CACzB,MAAM,IAAkB;EACtB,OAAO,IAAI,SAAS,IAAI;EACxB,OAAO,IAAI;EACX;EACA;EACA,KAAK,IAAI,OAAO,CAAC;EACjB,SAAS,OAAO,WAAW,IAAI,OAAO,CAAC;EACvC;EACA,GAAI,IAAI,OAAO,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;EACrC,GAAI,OAAO,QAAQ,EAAE,OAAO,OAAO,MAAM,IAAI,CAAC;EAC9C,GAAI,OAAO,aAAa,EAAE,YAAY,OAAO,WAAW,IAAI,CAAC;CAC/D;CAGA,IAAI,QAAQ;CACZ,QAAQ,SAAS,WAAW;EAC1B,IAAI,CAAC,OAAO,QAAQ;EACpB,MAAM,UAAU,QAAQ,MAAM;EAC9B,KAAK,MAAM,KAAK,OAAO,OAAO,CAAC,GAAG;GAEhC,MAAM,KAAK,EAAE,QAAQ,OAAO,KAAK,OAAO,QAAQ,EAAE,SAAS,IAAI;GAC/D,IAAI,KAAK;IACP,OAAO;IAAO,OAAO;KAAE,IAAI,CAAC,EAAE;KAAG,MAAM,CAAC;IAAE;IAAG,QAAQ,OAAO;IAAI,OAAO;IAAS,MAAM,OAAO,QAAQ;IAAU;IAC/G,GAAI,EAAE,WAAW,EAAE,UAAU,KAAK,IAAI,CAAC;IACvC,GAAI,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;GACnC,CAAC;EACH;CACF,CAAC;CACD,OAAO;AACT;;;AAIA,SAAS,cAAc,QAAiC;CACtD,MAAM,EAAE,QAAQ;CAChB,MAAM,QAAQ,IAAI,SAAS,IAAI;CAC/B,MAAM,WAAW,SAAS,OAAO,KAAK,GAAG,IAAI,QAAQ,KAAK,IAAI;CAC9D,MAAM,CAAC,IAAI,MAAM,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;CAC5C,MAAM,CAAC,IAAI,MAAM,SAAS,CAAC,IAAI,MAAM,GAAG,IAAI,MAAM,CAAC,CAAC;CACpD,OAAO,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE;AACpC;;;AAIA,SAAS,SAAS,QAAyB,OAA2B;CACpE,MAAM,EAAE,QAAQ;CAChB,MAAM,QAAQ,IAAI,SAAS,IAAI;CAC/B,MAAM,IAAI,KAAK,MAAM,IAAI,MAAM,IAAI,MAAM,GAAG,IAAI,MAAM,IAAI,MAAM,CAAC;CACjE,MAAM,MAAM,KAAK,MAAM,IAAI,MAAM,IAAI,MAAM,GAAG,IAAI,MAAM,IAAI,MAAM,CAAC,IAAI,SAAS,IAAI,UAAU;CAC9F,MAAM,MAAM;EAAE,GAAG,MAAM,IAAI,IAAI,KAAK,IAAI,GAAG;EAAG,GAAG,MAAM,IAAI,IAAI,KAAK,IAAI,GAAG;CAAE;CAC7E,MAAM,MAAM,aAAa,KAAK,MAAM,QAAQ,MAAM,KAAK,EAAE,GAAG,GAAG;CAC/D,OAAO,CACL;EAAE,MAAM;EAAQ,MAAM;EAAO,IAAI;CAAI,GACrC;EAAE,MAAM;EAAS,IAAI;EAAK,OAAO;EAAY,OAAO,GAAG,IAAI;CAAG,CAChE;AACF"}
@@ -1,7 +1,7 @@
1
1
  import { fromPlane } from "../../core/viewport/parallax.js";
2
2
  import { closestOnFlat } from "@weasel-js/geom/nd";
3
3
 
4
- //#region src/domains/snap/debugCandidates.ts
4
+ // src/domains/snap/debugCandidates.ts
5
5
  /** Replaces the sink's snap records with one frame's candidates: where each
6
6
  * would put its probe, accepted when the result meets it. Camera world. */
7
7
  function recordSnapCandidates(debug, candidates, satisfied, probes, delta0, plane) {
@@ -22,6 +22,5 @@ function recordSnapCandidates(debug, candidates, satisfied, probes, delta0, plan
22
22
  }
23
23
  }
24
24
 
25
- //#endregion
26
25
  export { recordSnapCandidates };
27
26
  //# sourceMappingURL=debugCandidates.js.map
@@ -1,6 +1,6 @@
1
1
  import { distinct } from "./marks.js";
2
2
 
3
- //#region src/domains/snap/gather.ts
3
+ // src/domains/snap/gather.ts
4
4
  var DEFAULT_GESTURES = [
5
5
  "point",
6
6
  "move",
@@ -74,6 +74,5 @@ function marksOf(mark, delta) {
74
74
  return "kind" in m ? [m] : m;
75
75
  }
76
76
 
77
- //#endregion
78
77
  export { assertSnapSourceIds, gatherSnapCandidates, resolvedSnapMarks, snapSourcesFor };
79
78
  //# sourceMappingURL=gather.js.map
@@ -1,8 +1,8 @@
1
- import { SNAP_AXIS_STEP } from "./roles.js";
2
1
  import { diagonal, edgeAxis } from "./resizeBox.js";
2
+ import { SNAP_AXIS_STEP } from "./roles.js";
3
3
  import { stepLine } from "@weasel-js/geom/nd";
4
4
 
5
- //#region src/domains/snap/inputSubspace.ts
5
+ // src/domains/snap/inputSubspace.ts
6
6
  var PLANE = {
7
7
  at: [0, 0],
8
8
  dirs: [[1, 0], [0, 1]]
@@ -41,6 +41,5 @@ function inputFlat(req, mods, delta0, resize) {
41
41
  return stepLine([origin.x - req.press.x, origin.y - req.press.y], [delta0.x, delta0.y], AXES, c.step);
42
42
  }
43
43
 
44
- //#endregion
45
44
  export { inputFlat };
46
45
  //# sourceMappingURL=inputSubspace.js.map
@@ -1,4 +1,4 @@
1
- //#region src/domains/snap/lazySession.ts
1
+ // src/domains/snap/lazySession.ts
2
2
  /** A session of `dep` that begins on its first `at` or `angle`, so a press
3
3
  * that never moves reads nothing of the scene. Null without a dep. */
4
4
  function lazySnapSession(dep, req) {
@@ -12,6 +12,5 @@ function lazySnapSession(dep, req) {
12
12
  };
13
13
  }
14
14
 
15
- //#endregion
16
15
  export { lazySnapSession };
17
16
  //# sourceMappingURL=lazySession.js.map
@@ -1,6 +1,6 @@
1
1
  import { fromPlane } from "../../core/viewport/parallax.js";
2
2
 
3
- //#region src/domains/snap/marks.ts
3
+ // src/domains/snap/marks.ts
4
4
  /** `marks` with repeats dropped, so a target several probes meet is drawn once. */
5
5
  function distinct(marks) {
6
6
  const seen = /* @__PURE__ */ new Set();
@@ -24,6 +24,5 @@ function markFromPlane(m, plane) {
24
24
  };
25
25
  }
26
26
 
27
- //#endregion
28
27
  export { distinct, markFromPlane };
29
28
  //# sourceMappingURL=marks.js.map
@@ -1,25 +1,21 @@
1
- //#region src/domains/snap/outcomeStore.ts
1
+ import { createEmitter } from "@weasel-js/registry";
2
+
3
+ // src/domains/snap/outcomeStore.ts
2
4
  var NONE = [];
3
5
  /** An empty outcome store, which notifies only when the marks change. */
4
6
  function createSnapOutcomeStore() {
5
7
  let marks = NONE;
6
- const listeners = /* @__PURE__ */ new Set();
8
+ const changed = createEmitter();
7
9
  return {
8
10
  get: () => marks,
9
11
  set(next) {
10
12
  if (next.length === 0 && marks.length === 0) return;
11
13
  marks = next.length === 0 ? NONE : next;
12
- for (const l of [...listeners]) l();
14
+ changed.emit();
13
15
  },
14
- subscribe(listener) {
15
- listeners.add(listener);
16
- return () => {
17
- listeners.delete(listener);
18
- };
19
- }
16
+ subscribe: changed.subscribe
20
17
  };
21
18
  }
22
19
 
23
- //#endregion
24
20
  export { createSnapOutcomeStore };
25
21
  //# sourceMappingURL=outcomeStore.js.map