@weasel-js/core 1.9.2 → 1.9.4

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 (542) hide show
  1. package/CHANGELOG.md +393 -0
  2. package/README.md +2 -2
  3. package/dist/WeaselProvider.js +5 -5
  4. package/dist/affordances/composeAffordanceLayer.js +10 -20
  5. package/dist/affordances/composeAffordanceLayer.js.map +1 -1
  6. package/dist/affordances/cornerResize.js +25 -17
  7. package/dist/affordances/cornerResize.js.map +1 -1
  8. package/dist/affordances/hitAffordanceRegions.js +27 -20
  9. package/dist/affordances/hitAffordanceRegions.js.map +1 -1
  10. package/dist/affordances/rotationHandle.js +18 -18
  11. package/dist/affordances/rotationHandle.js.map +1 -1
  12. package/dist/animation/behaviors/momentum.js +93 -55
  13. package/dist/animation/behaviors/momentum.js.map +1 -1
  14. package/dist/animation/loop.js +10 -12
  15. package/dist/animation/loop.js.map +1 -1
  16. package/dist/animation/reflow.js +8 -8
  17. package/dist/animation/reflow.js.map +1 -1
  18. package/dist/animation/stagger.js +64 -56
  19. package/dist/animation/stagger.js.map +1 -1
  20. package/dist/animation/timeline/booking.js +62 -54
  21. package/dist/animation/timeline/booking.js.map +1 -1
  22. package/dist/animation/timeline/createTimeline.js +85 -76
  23. package/dist/animation/timeline/createTimeline.js.map +1 -1
  24. package/dist/animation/timeline/sampleTrack.js +13 -5
  25. package/dist/animation/timeline/sampleTrack.js.map +1 -1
  26. package/dist/animation/useAnimator.js +45 -35
  27. package/dist/animation/useAnimator.js.map +1 -1
  28. package/dist/animation/wrappers/animateLifecycle.js +31 -24
  29. package/dist/animation/wrappers/animateLifecycle.js.map +1 -1
  30. package/dist/animation/wrappers/animateOnSetPose.js +28 -26
  31. package/dist/animation/wrappers/animateOnSetPose.js.map +1 -1
  32. package/dist/animation/wrappers/instantPose.js +13 -0
  33. package/dist/animation/wrappers/instantPose.js.map +1 -0
  34. package/dist/{poseDescriptor-D-OH-tu5.d.ts → autoPoseDescriptor-Ct7yqivU.d.ts} +28 -3
  35. package/dist/barrel/chrome.js +16 -0
  36. package/dist/barrel/input.js +19 -0
  37. package/dist/barrel/interactions.js +42 -0
  38. package/dist/barrel/paint.js +18 -0
  39. package/dist/barrel/paths.js +19 -0
  40. package/dist/barrel/renderer.js +20 -0
  41. package/dist/barrel/routing.js +51 -0
  42. package/dist/barrel/text.js +18 -0
  43. package/dist/barrel/viewport.js +52 -0
  44. package/dist/builtins-DPcdghtB.d.ts +1223 -0
  45. package/dist/canvas/Canvas.js +363 -448
  46. package/dist/canvas/Canvas.js.map +1 -1
  47. package/dist/canvas/CanvasView.js +164 -165
  48. package/dist/canvas/CanvasView.js.map +1 -1
  49. package/dist/canvas/CursorCoordsHud.js +37 -32
  50. package/dist/canvas/CursorCoordsHud.js.map +1 -1
  51. package/dist/canvas/DrawCanvas.js +49 -43
  52. package/dist/canvas/DrawCanvas.js.map +1 -1
  53. package/dist/canvas/MinimapCanvas.js +26 -25
  54. package/dist/canvas/MinimapCanvas.js.map +1 -1
  55. package/dist/canvas/NodeShape.js +59 -377
  56. package/dist/canvas/NodeShape.js.map +1 -1
  57. package/dist/canvas/PickHud.js +50 -47
  58. package/dist/canvas/PickHud.js.map +1 -1
  59. package/dist/canvas/SceneCanvas/GestureDispatcherMounter.js +167 -0
  60. package/dist/canvas/SceneCanvas/GestureDispatcherMounter.js.map +1 -0
  61. package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js +13 -13
  62. package/dist/canvas/SceneCanvas/StandardActionsRegistrar.js +67 -0
  63. package/dist/canvas/SceneCanvas/StandardActionsRegistrar.js.map +1 -0
  64. package/dist/canvas/SceneCanvas/ToolKeybindingsMounter.js +16 -0
  65. package/dist/canvas/SceneCanvas/ToolKeybindingsMounter.js.map +1 -0
  66. package/dist/canvas/SceneCanvas/coordTrace.js +10 -0
  67. package/dist/canvas/SceneCanvas/coordTrace.js.map +1 -0
  68. package/dist/canvas/SceneCanvas/defaultNodeProperties.js +146 -92
  69. package/dist/canvas/SceneCanvas/defaultNodeProperties.js.map +1 -1
  70. package/dist/canvas/SceneCanvas/defaultNodeRouting.js +9 -8
  71. package/dist/canvas/SceneCanvas/defaultNodeRouting.js.map +1 -1
  72. package/dist/canvas/SceneCanvas/features.js +1 -0
  73. package/dist/canvas/SceneCanvas/features.js.map +1 -1
  74. package/dist/canvas/SceneCanvas/isDev.js +12 -0
  75. package/dist/canvas/SceneCanvas/isDev.js.map +1 -0
  76. package/dist/canvas/SceneCanvas/poseGeometry.js +29 -28
  77. package/dist/canvas/SceneCanvas/poseGeometry.js.map +1 -1
  78. package/dist/canvas/SceneCanvas/poseRegistrars.js +13 -0
  79. package/dist/canvas/SceneCanvas/poseRegistrars.js.map +1 -0
  80. package/dist/canvas/SceneCanvas/props.js +38 -0
  81. package/dist/canvas/SceneCanvas/props.js.map +1 -0
  82. package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js +21 -62
  83. package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js.map +1 -1
  84. package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js.map +1 -1
  85. package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js +46 -48
  86. package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js.map +1 -1
  87. package/dist/canvas/SceneCanvas/useSceneSelectTool.js +33 -33
  88. package/dist/canvas/SceneCanvas/useSceneSelectTool.js.map +1 -1
  89. package/dist/canvas/SceneCanvas.js +534 -788
  90. package/dist/canvas/SceneCanvas.js.map +1 -1
  91. package/dist/canvas/SceneViewCanvas.js +45 -43
  92. package/dist/canvas/SceneViewCanvas.js.map +1 -1
  93. package/dist/canvas/buildSceneLayer.js +91 -0
  94. package/dist/canvas/buildSceneLayer.js.map +1 -0
  95. package/dist/canvas/buildSceneTree.js +16 -19
  96. package/dist/canvas/buildSceneTree.js.map +1 -1
  97. package/dist/canvas/canvasRenderer.js +68 -52
  98. package/dist/canvas/canvasRenderer.js.map +1 -1
  99. package/dist/canvas/deps/changes.js +13 -0
  100. package/dist/canvas/deps/changes.js.map +1 -0
  101. package/dist/canvas/deps/editAnchors.js +28 -28
  102. package/dist/canvas/deps/insert.js +119 -91
  103. package/dist/canvas/deps/insert.js.map +1 -1
  104. package/dist/canvas/deps/slice.js +46 -45
  105. package/dist/canvas/deps/slice.js.map +1 -1
  106. package/dist/canvas/deps/textEdit.js +10 -9
  107. package/dist/canvas/deps/textEdit.js.map +1 -1
  108. package/dist/canvas/derivedPath.js +46 -23
  109. package/dist/canvas/derivedPath.js.map +1 -1
  110. package/dist/canvas/getNodeAtPoint.js +7 -7
  111. package/dist/canvas/getNodeAtPoint.js.map +1 -1
  112. package/dist/canvas/hud.module.js +1 -1
  113. package/dist/canvas/hud.module.js.map +1 -1
  114. package/dist/canvas/kitRequirements.js +2 -2
  115. package/dist/canvas/kitRequirements.js.map +1 -1
  116. package/dist/canvas/layerOrder.js +13 -6
  117. package/dist/canvas/layerOrder.js.map +1 -1
  118. package/dist/canvas/minimapMath.js +12 -10
  119. package/dist/canvas/minimapMath.js.map +1 -1
  120. package/dist/canvas/nodeShapes/derivedPainter.js +34 -0
  121. package/dist/canvas/nodeShapes/derivedPainter.js.map +1 -0
  122. package/dist/canvas/nodeShapes/imagePainter.js +87 -0
  123. package/dist/canvas/nodeShapes/imagePainter.js.map +1 -0
  124. package/dist/canvas/nodeShapes/memo.js +9 -0
  125. package/dist/canvas/nodeShapes/memo.js.map +1 -0
  126. package/dist/canvas/nodeShapes/nodePaint.js +57 -0
  127. package/dist/canvas/nodeShapes/nodePaint.js.map +1 -0
  128. package/dist/canvas/nodeShapes/pathPainter.js +38 -0
  129. package/dist/canvas/nodeShapes/pathPainter.js.map +1 -0
  130. package/dist/canvas/nodeShapes/poseBox.js +20 -0
  131. package/dist/canvas/nodeShapes/poseBox.js.map +1 -0
  132. package/dist/canvas/nodeShapes/rectFallbackPainter.js +38 -0
  133. package/dist/canvas/nodeShapes/rectFallbackPainter.js.map +1 -0
  134. package/dist/canvas/nodeShapes/shapePainter.js +72 -0
  135. package/dist/canvas/nodeShapes/shapePainter.js.map +1 -0
  136. package/dist/canvas/nodeShapes/textPainter.js +55 -0
  137. package/dist/canvas/nodeShapes/textPainter.js.map +1 -0
  138. package/dist/canvas/overlayRoleStrokes.js.map +1 -1
  139. package/dist/canvas/paintCull.js +10 -11
  140. package/dist/canvas/paintCull.js.map +1 -1
  141. package/dist/canvas/pickWalk.js +52 -63
  142. package/dist/canvas/pickWalk.js.map +1 -1
  143. package/dist/canvas/poseRotation.js +11 -23
  144. package/dist/canvas/poseRotation.js.map +1 -1
  145. package/dist/canvas/renderDebugSnapshot.js +5 -5
  146. package/dist/canvas/renderSceneToPixels.js +3 -1
  147. package/dist/canvas/renderSceneToPixels.js.map +1 -1
  148. package/dist/canvas/sceneAdapter.js +66 -148
  149. package/dist/canvas/sceneAdapter.js.map +1 -1
  150. package/dist/canvas/sceneClipboard.js +112 -0
  151. package/dist/canvas/sceneClipboard.js.map +1 -0
  152. package/dist/canvas/sceneSlotWiring.js +4 -4
  153. package/dist/canvas/sceneSlotWiring.js.map +1 -1
  154. package/dist/canvas/sceneViewRender.js +39 -40
  155. package/dist/canvas/sceneViewRender.js.map +1 -1
  156. package/dist/canvas/useCanvasRenderer.js +14 -6
  157. package/dist/canvas/useCanvasRenderer.js.map +1 -1
  158. package/dist/canvas/useCanvasView.js +58 -0
  159. package/dist/canvas/useCanvasView.js.map +1 -0
  160. package/dist/canvas/useFrameLoop.js +35 -26
  161. package/dist/canvas/useFrameLoop.js.map +1 -1
  162. package/dist/canvas/useSceneLayerList.js +21 -0
  163. package/dist/canvas/useSceneLayerList.js.map +1 -0
  164. package/dist/clipboard.d.ts +10 -6
  165. package/dist/clone.d.ts +4 -3
  166. package/dist/core/adapters/arrayAdapter.js +48 -39
  167. package/dist/core/adapters/arrayAdapter.js.map +1 -1
  168. package/dist/core/device/index.js +5 -4
  169. package/dist/core/device/useDeviceProfile.js +38 -44
  170. package/dist/core/device/useDeviceProfile.js.map +1 -1
  171. package/dist/core/device/watchDevicePixelRatio.js +17 -0
  172. package/dist/core/device/watchDevicePixelRatio.js.map +1 -0
  173. package/dist/core/fillInPoseFrame.js.map +1 -1
  174. package/dist/core/geometry/poseDescriptor.js +21 -19
  175. package/dist/core/geometry/poseDescriptor.js.map +1 -1
  176. package/dist/core/geometry/poseFrame.js +44 -0
  177. package/dist/core/geometry/poseFrame.js.map +1 -0
  178. package/dist/core/geometry/poseRotation.js.map +1 -1
  179. package/dist/core/geometry/regionHit.js +9 -10
  180. package/dist/core/geometry/regionHit.js.map +1 -1
  181. package/dist/core/geometry/unionBounds.js +31 -29
  182. package/dist/core/geometry/unionBounds.js.map +1 -1
  183. package/dist/core/isPlainObject.js +2 -11
  184. package/dist/core/ops/arrange.js +1 -0
  185. package/dist/core/ops/arrange.js.map +1 -1
  186. package/dist/core/ops/create.js +10 -5
  187. package/dist/core/ops/create.js.map +1 -1
  188. package/dist/core/ops/delete.js +12 -24
  189. package/dist/core/ops/delete.js.map +1 -1
  190. package/dist/core/ops/reorder/index.js +43 -40
  191. package/dist/core/ops/reorder/index.js.map +1 -1
  192. package/dist/core/ops/reorder/setChildOrder.js +34 -0
  193. package/dist/core/ops/reorder/setChildOrder.js.map +1 -0
  194. package/dist/core/paintKinds.js +5 -5
  195. package/dist/core/paintKinds.js.map +1 -1
  196. package/dist/core/scene/NodeProperties.js.map +1 -1
  197. package/dist/core/scene/appliedLog.js +37 -0
  198. package/dist/core/scene/appliedLog.js.map +1 -0
  199. package/dist/core/scene/arrivalWindow.js +101 -0
  200. package/dist/core/scene/arrivalWindow.js.map +1 -0
  201. package/dist/core/scene/derivedPath.js.map +1 -1
  202. package/dist/core/scene/historyFacade.js +84 -0
  203. package/dist/core/scene/historyFacade.js.map +1 -0
  204. package/dist/core/scene/kitOps.js +173 -0
  205. package/dist/core/scene/kitOps.js.map +1 -0
  206. package/dist/core/scene/layerStack.js +38 -0
  207. package/dist/core/scene/layerStack.js.map +1 -0
  208. package/dist/core/scene/lockGuard.js +37 -0
  209. package/dist/core/scene/lockGuard.js.map +1 -0
  210. package/dist/core/scene/nodeFnFields.js +5 -6
  211. package/dist/core/scene/nodeFnFields.js.map +1 -1
  212. package/dist/core/scene/nodeMemo.js +45 -19
  213. package/dist/core/scene/nodeMemo.js.map +1 -1
  214. package/dist/core/scene/nodeStore.js +126 -0
  215. package/dist/core/scene/nodeStore.js.map +1 -0
  216. package/dist/core/scene/pickability.js +6 -0
  217. package/dist/core/scene/pickability.js.map +1 -0
  218. package/dist/core/scene/poseFeed.js +38 -38
  219. package/dist/core/scene/poseFeed.js.map +1 -1
  220. package/dist/core/scene/poseOverrides.js +34 -38
  221. package/dist/core/scene/poseOverrides.js.map +1 -1
  222. package/dist/core/scene/renderOrder.js +84 -0
  223. package/dist/core/scene/renderOrder.js.map +1 -0
  224. package/dist/core/scene/scene.js +289 -866
  225. package/dist/core/scene/scene.js.map +1 -1
  226. package/dist/core/scene/serialization.js +68 -0
  227. package/dist/core/scene/serialization.js.map +1 -0
  228. package/dist/core/scene/treeOrder.js +13 -0
  229. package/dist/core/scene/treeOrder.js.map +1 -0
  230. package/dist/core/scene/types.js.map +1 -1
  231. package/dist/core/viewport/meanScale.js +1 -1
  232. package/dist/core/viewport/meanScale.js.map +1 -1
  233. package/dist/core/viewport/view.js +12 -12
  234. package/dist/core/viewport/view.js.map +1 -1
  235. package/dist/core/viewport/zoomBounds.js +10 -8
  236. package/dist/core/viewport/zoomBounds.js.map +1 -1
  237. package/dist/{cornerHandles-BCrDp_mH.d.ts → cornerHandles-CtCb8a3G.d.ts} +1 -1
  238. package/dist/debug/createDebugOverlayLayer.js +14 -14
  239. package/dist/debug/createDebugOverlayLayer.js.map +1 -1
  240. package/dist/debug/flag.js +2 -41
  241. package/dist/features/chrome-caps/useHoverTracking.js +22 -17
  242. package/dist/features/chrome-caps/useHoverTracking.js.map +1 -1
  243. package/dist/features/focus/gateLayer.js +3 -4
  244. package/dist/features/focus/gateLayer.js.map +1 -1
  245. package/dist/features/images/imageCache.js +19 -9
  246. package/dist/features/images/imageCache.js.map +1 -1
  247. package/dist/features/ingestion/contentHandlers.js +14 -11
  248. package/dist/features/ingestion/contentHandlers.js.map +1 -1
  249. package/dist/features/ingestion/index.js +1 -1
  250. package/dist/features/ingestion/registerKitHandlers.js +7 -7
  251. package/dist/features/ingestion/weaselJsonHandler.js +17 -14
  252. package/dist/features/ingestion/weaselJsonHandler.js.map +1 -1
  253. package/dist/features/meshPaint/lazyKind.js +201 -35
  254. package/dist/features/meshPaint/lazyKind.js.map +1 -1
  255. package/dist/features/meshPaint/meshPaint.js +82 -79
  256. package/dist/features/meshPaint/meshPaint.js.map +1 -1
  257. package/dist/features/minimap/createMinimapContribution.js +42 -42
  258. package/dist/features/minimap/layers.js +44 -62
  259. package/dist/features/minimap/layers.js.map +1 -1
  260. package/dist/features/parallax/createParallaxPlane.js +10 -14
  261. package/dist/features/parallax/createParallaxPlane.js.map +1 -1
  262. package/dist/features/paths/anchorEdits.js +19 -8
  263. package/dist/features/paths/anchorEdits.js.map +1 -1
  264. package/dist/features/paths/anchors.js +31 -26
  265. package/dist/features/paths/anchors.js.map +1 -1
  266. package/dist/features/paths/booleans.js +2 -2
  267. package/dist/features/paths/index.js +13 -11
  268. package/dist/features/paths/markerCommands.js +37 -36
  269. package/dist/features/paths/markerCommands.js.map +1 -1
  270. package/dist/features/paths/pathInWorld.js +19 -19
  271. package/dist/features/paths/pathInWorld.js.map +1 -1
  272. package/dist/features/paths/pathLayer.js.map +1 -1
  273. package/dist/features/paths/strokeToPath.js +40 -0
  274. package/dist/features/paths/strokeToPath.js.map +1 -0
  275. package/dist/features/paths/tessellate/stroke.js.map +1 -1
  276. package/dist/features/patterns/commandPaint.js +18 -0
  277. package/dist/features/patterns/commandPaint.js.map +1 -0
  278. package/dist/features/patterns/index.js +5 -17
  279. package/dist/features/patterns/index.js.map +1 -1
  280. package/dist/features/patterns/rasterizeTile.js +17 -0
  281. package/dist/features/patterns/rasterizeTile.js.map +1 -0
  282. package/dist/features/patterns/resolveSpec.js +52 -44
  283. package/dist/features/patterns/resolveSpec.js.map +1 -1
  284. package/dist/features/poseRun/usePoseRun.js +8 -3
  285. package/dist/features/poseRun/usePoseRun.js.map +1 -1
  286. package/dist/features/selection/SelectionContext.js +5 -0
  287. package/dist/features/selection/SelectionContext.js.map +1 -1
  288. package/dist/features/selection/overlay.js +18 -18
  289. package/dist/features/selection/overlay.js.map +1 -1
  290. package/dist/features/text/domOffsets.js +82 -0
  291. package/dist/features/text/domOffsets.js.map +1 -0
  292. package/dist/features/text/domRuns.js +103 -131
  293. package/dist/features/text/domRuns.js.map +1 -1
  294. package/dist/features/text/hitTest.js +5 -2
  295. package/dist/features/text/hitTest.js.map +1 -1
  296. package/dist/features/text/isTextData.js +8 -0
  297. package/dist/features/text/isTextData.js.map +1 -0
  298. package/dist/features/text/overlayDirection.js +15 -0
  299. package/dist/features/text/overlayDirection.js.map +1 -0
  300. package/dist/features/text/runs/rangeStyle.js +32 -34
  301. package/dist/features/text/runs/rangeStyle.js.map +1 -1
  302. package/dist/features/text/textCommand.js +34 -33
  303. package/dist/features/text/textCommand.js.map +1 -1
  304. package/dist/features/text/textToPath.js +40 -40
  305. package/dist/features/text/textToPath.js.map +1 -1
  306. package/dist/features/text/useSceneTextEdit.js +76 -82
  307. package/dist/features/text/useSceneTextEdit.js.map +1 -1
  308. package/dist/features/text/useTextEdit.js +184 -160
  309. package/dist/features/text/useTextEdit.js.map +1 -1
  310. package/dist/features/tiling/createTiledLayer.js +24 -22
  311. package/dist/features/tiling/createTiledLayer.js.map +1 -1
  312. package/dist/index.d.ts +11010 -7700
  313. package/dist/index.js +316 -309
  314. package/dist/input/keyState.js +42 -43
  315. package/dist/input/keyState.js.map +1 -1
  316. package/dist/input/useKeyModifiers.js +11 -0
  317. package/dist/input/useKeyModifiers.js.map +1 -0
  318. package/dist/interactions/actions/align/align.js +8 -8
  319. package/dist/interactions/actions/clipboard/clipboardOps.js +34 -32
  320. package/dist/interactions/actions/clipboard/clipboardOps.js.map +1 -1
  321. package/dist/interactions/actions/clipboard/materializePaste.js +10 -7
  322. package/dist/interactions/actions/clipboard/materializePaste.js.map +1 -1
  323. package/dist/interactions/actions/clipboard/wireFormat.js.map +1 -1
  324. package/dist/interactions/actions/clone/behaviors/cloneByAltDrag.js.map +1 -1
  325. package/dist/interactions/actions/defaultCommitAdapter.js +20 -18
  326. package/dist/interactions/actions/defaultCommitAdapter.js.map +1 -1
  327. package/dist/interactions/actions/defaults/align.js +9 -10
  328. package/dist/interactions/actions/defaults/align.js.map +1 -1
  329. package/dist/interactions/actions/defaults/anchorEditing.js +59 -81
  330. package/dist/interactions/actions/defaults/anchorEditing.js.map +1 -1
  331. package/dist/interactions/actions/defaults/areaSelect.js +35 -38
  332. package/dist/interactions/actions/defaults/areaSelect.js.map +1 -1
  333. package/dist/interactions/actions/defaults/clipboard.js +26 -10
  334. package/dist/interactions/actions/defaults/clipboard.js.map +1 -1
  335. package/dist/interactions/actions/defaults/clone.js +44 -60
  336. package/dist/interactions/actions/defaults/clone.js.map +1 -1
  337. package/dist/interactions/actions/defaults/copySubtree.js +40 -0
  338. package/dist/interactions/actions/defaults/copySubtree.js.map +1 -0
  339. package/dist/interactions/actions/defaults/distribute.js +14 -13
  340. package/dist/interactions/actions/defaults/distribute.js.map +1 -1
  341. package/dist/interactions/actions/defaults/duplicate.js +17 -57
  342. package/dist/interactions/actions/defaults/duplicate.js.map +1 -1
  343. package/dist/interactions/actions/defaults/editAnchors.js +18 -18
  344. package/dist/interactions/actions/defaults/enterTextEdit.js.map +1 -1
  345. package/dist/interactions/actions/defaults/flip.js +52 -46
  346. package/dist/interactions/actions/defaults/flip.js.map +1 -1
  347. package/dist/interactions/actions/defaults/group.js +43 -48
  348. package/dist/interactions/actions/defaults/group.js.map +1 -1
  349. package/dist/interactions/actions/defaults/ingest.js +35 -33
  350. package/dist/interactions/actions/defaults/ingest.js.map +1 -1
  351. package/dist/interactions/actions/defaults/insert.js +50 -51
  352. package/dist/interactions/actions/defaults/insert.js.map +1 -1
  353. package/dist/interactions/actions/defaults/insertPathAnchor.js +7 -7
  354. package/dist/interactions/actions/defaults/lassoSelect.js +67 -70
  355. package/dist/interactions/actions/defaults/lassoSelect.js.map +1 -1
  356. package/dist/interactions/actions/defaults/move.js +267 -249
  357. package/dist/interactions/actions/defaults/move.js.map +1 -1
  358. package/dist/interactions/actions/defaults/nudge.js +40 -68
  359. package/dist/interactions/actions/defaults/nudge.js.map +1 -1
  360. package/dist/interactions/actions/defaults/nudgeSteps.js +37 -0
  361. package/dist/interactions/actions/defaults/nudgeSteps.js.map +1 -0
  362. package/dist/interactions/actions/defaults/reorder.js +2 -0
  363. package/dist/interactions/actions/defaults/reorder.js.map +1 -1
  364. package/dist/interactions/actions/defaults/resize.js +104 -98
  365. package/dist/interactions/actions/defaults/resize.js.map +1 -1
  366. package/dist/interactions/actions/defaults/rotate.js +111 -110
  367. package/dist/interactions/actions/defaults/rotate.js.map +1 -1
  368. package/dist/interactions/actions/defaults/setFill.js +7 -7
  369. package/dist/interactions/actions/defaults/setFillOpacity.js +4 -4
  370. package/dist/interactions/actions/defaults/setStroke.js +12 -12
  371. package/dist/interactions/actions/defaults/setStrokeOpacity.js +6 -6
  372. package/dist/interactions/actions/defaults/sliceOps.js +19 -19
  373. package/dist/interactions/actions/defaults/viewportDragPan.js +37 -26
  374. package/dist/interactions/actions/defaults/viewportDragPan.js.map +1 -1
  375. package/dist/interactions/actions/edit-anchors/geometry.js +28 -23
  376. package/dist/interactions/actions/edit-anchors/geometry.js.map +1 -1
  377. package/dist/interactions/actions/flip/helpers.js +30 -17
  378. package/dist/interactions/actions/flip/helpers.js.map +1 -1
  379. package/dist/interactions/actions/hitSelection.js +8 -0
  380. package/dist/interactions/actions/hitSelection.js.map +1 -0
  381. package/dist/interactions/actions/lasso-select/behaviors/selectFromLasso.js +14 -18
  382. package/dist/interactions/actions/lasso-select/behaviors/selectFromLasso.js.map +1 -1
  383. package/dist/interactions/actions/move/behaviors/snapBackOrDelete.js +5 -5
  384. package/dist/interactions/actions/move/behaviors/snapBackOrDelete.js.map +1 -1
  385. package/dist/interactions/actions/move/behaviors/snapToContainer.js +32 -21
  386. package/dist/interactions/actions/move/behaviors/snapToContainer.js.map +1 -1
  387. package/dist/interactions/actions/move/gestureAdapter.js +32 -15
  388. package/dist/interactions/actions/move/gestureAdapter.js.map +1 -1
  389. package/dist/interactions/actions/move/landedDescendants.js +33 -0
  390. package/dist/interactions/actions/move/landedDescendants.js.map +1 -0
  391. package/dist/interactions/actions/outlines/createOutlines.js +18 -18
  392. package/dist/interactions/actions/poseDescriptorDep.js +16 -4
  393. package/dist/interactions/actions/poseDescriptorDep.js.map +1 -1
  394. package/dist/interactions/actions/poseFrame.js +11 -6
  395. package/dist/interactions/actions/poseFrame.js.map +1 -1
  396. package/dist/interactions/actions/previewOverrides.js +5 -5
  397. package/dist/interactions/actions/previewOverrides.js.map +1 -1
  398. package/dist/interactions/actions/selectionSubtree.js +69 -0
  399. package/dist/interactions/actions/selectionSubtree.js.map +1 -0
  400. package/dist/interactions/actions/useStandardActions.js +66 -62
  401. package/dist/interactions/actions/useStandardActions.js.map +1 -1
  402. package/dist/interactions/gestures/dragGesture/dragGesture.js +4 -7
  403. package/dist/interactions/gestures/dragGesture/dragGesture.js.map +1 -1
  404. package/dist/interactions/gestures/dragGesture/dragPointOf.js +23 -0
  405. package/dist/interactions/gestures/dragGesture/dragPointOf.js.map +1 -0
  406. package/dist/interactions/gestures/handleDrag/handleDrag.js +21 -26
  407. package/dist/interactions/gestures/handleDrag/handleDrag.js.map +1 -1
  408. package/dist/interactions/gestures/pointerDrag/pointerDrag.js +8 -6
  409. package/dist/interactions/gestures/pointerDrag/pointerDrag.js.map +1 -1
  410. package/dist/interactions/gestures/thresholdDrag/thresholdDrag.js +8 -4
  411. package/dist/interactions/gestures/thresholdDrag/thresholdDrag.js.map +1 -1
  412. package/dist/{math-Drrw4ewZ.d.ts → math-J-ACHyEg.d.ts} +1 -2
  413. package/dist/math.d.ts +2 -3
  414. package/dist/move.d.ts +12 -11
  415. package/dist/{originProjection-DEklpDc_.d.ts → originProjection-gHnOup4e.d.ts} +1 -1
  416. package/dist/{registerProgram-BMZRDgrh.d.ts → registerProgram-T9S_PfAX.d.ts} +18 -7
  417. package/dist/renderer/DrawCommand.js.map +1 -1
  418. package/dist/renderer/WeaselRenderer.js +75 -73
  419. package/dist/renderer/WeaselRenderer.js.map +1 -1
  420. package/dist/renderer/cache/GLImageCache.js +15 -5
  421. package/dist/renderer/cache/GLImageCache.js.map +1 -1
  422. package/dist/renderer/cache/GLMeshCache.js +23 -23
  423. package/dist/renderer/cache/GLMeshCache.js.map +1 -1
  424. package/dist/renderer/cache/GLTextureCache.js +18 -1
  425. package/dist/renderer/cache/GLTextureCache.js.map +1 -1
  426. package/dist/renderer/cache/cache.js.map +1 -1
  427. package/dist/renderer/cache/markerCommandCache.js.map +1 -1
  428. package/dist/renderer/cache/strokeMeshCache.js.map +1 -1
  429. package/dist/renderer/cullDrawCommands.js +11 -11
  430. package/dist/renderer/draw/batch.js +133 -0
  431. package/dist/renderer/draw/batch.js.map +1 -0
  432. package/dist/renderer/draw/clip.js +89 -0
  433. package/dist/renderer/draw/clip.js.map +1 -0
  434. package/dist/renderer/draw/customShader.js +230 -0
  435. package/dist/renderer/draw/customShader.js.map +1 -0
  436. package/dist/renderer/draw/drawTriangles.js +8 -0
  437. package/dist/renderer/draw/drawTriangles.js.map +1 -0
  438. package/dist/renderer/draw/effects.js +28 -0
  439. package/dist/renderer/draw/effects.js.map +1 -0
  440. package/dist/renderer/draw/flushBatch.js +35 -0
  441. package/dist/renderer/draw/flushBatch.js.map +1 -0
  442. package/dist/renderer/draw/gradient.js +90 -0
  443. package/dist/renderer/draw/gradient.js.map +1 -0
  444. package/dist/renderer/draw/image.js +38 -0
  445. package/dist/renderer/draw/image.js.map +1 -0
  446. package/dist/renderer/draw/mesh.js +16 -0
  447. package/dist/renderer/draw/mesh.js.map +1 -0
  448. package/dist/renderer/draw/paintBind.js +70 -0
  449. package/dist/renderer/draw/paintBind.js.map +1 -0
  450. package/dist/renderer/draw/pathPaint.js +142 -0
  451. package/dist/renderer/draw/pathPaint.js.map +1 -0
  452. package/dist/renderer/draw/scratchPass.js +83 -0
  453. package/dist/renderer/draw/scratchPass.js.map +1 -0
  454. package/dist/renderer/draw/stencil.js +28 -0
  455. package/dist/renderer/draw/stencil.js.map +1 -0
  456. package/dist/renderer/draw/text.js +167 -0
  457. package/dist/renderer/draw/text.js.map +1 -0
  458. package/dist/renderer/draw/uniforms.js +77 -0
  459. package/dist/renderer/draw/uniforms.js.map +1 -0
  460. package/dist/renderer/draw.js +60 -1116
  461. package/dist/renderer/draw.js.map +1 -1
  462. package/dist/renderer/effects/EffectTargets.js +3 -0
  463. package/dist/renderer/effects/EffectTargets.js.map +1 -1
  464. package/dist/renderer/effects/composite.js +7 -5
  465. package/dist/renderer/effects/composite.js.map +1 -1
  466. package/dist/renderer/index.js +18 -17
  467. package/dist/renderer/math/color.js +63 -83
  468. package/dist/renderer/math/color.js.map +1 -1
  469. package/dist/renderer/math/mat3.js +15 -11
  470. package/dist/renderer/math/mat3.js.map +1 -1
  471. package/dist/renderer/math/viewToMat3.js +1 -1
  472. package/dist/renderer/math/viewToMat3.js.map +1 -1
  473. package/dist/renderer/shaders/ShaderProgram.js +13 -13
  474. package/dist/renderer/shaders/ShaderProgram.js.map +1 -1
  475. package/dist/renderer/shaders/glyphPaint.js +3 -3
  476. package/dist/renderer/shaders/glyphPaint.js.map +1 -1
  477. package/dist/renderer/shaders/gradFill.js +2 -1
  478. package/dist/renderer/shaders/gradFill.js.map +1 -1
  479. package/dist/renderer/shaders/pathFill.js +2 -1
  480. package/dist/renderer/shaders/pathFill.js.map +1 -1
  481. package/dist/renderer/shaders/patternFill.js +2 -1
  482. package/dist/renderer/shaders/patternFill.js.map +1 -1
  483. package/dist/renderer/shaders/registerProgram.js.map +1 -1
  484. package/dist/renderer/strokeLengths.js.map +1 -1
  485. package/dist/renderer/textures/registerTexture.js +25 -5
  486. package/dist/renderer/textures/registerTexture.js.map +1 -1
  487. package/dist/renderer.d.ts +16 -15
  488. package/dist/renderer.js +17 -16
  489. package/dist/resize.d.ts +5 -6
  490. package/dist/resize.js +5 -5
  491. package/dist/style.css +1 -1
  492. package/dist/test-hook/install.js +12 -6
  493. package/dist/test-hook/install.js.map +1 -1
  494. package/dist/{test-seams-CuIxe0xY.d.ts → test-seams-DM2B87-g.d.ts} +4 -4
  495. package/dist/test-seams.d.ts +2 -2
  496. package/dist/tools/builtin/ellipse/useEllipseTool.js +1 -0
  497. package/dist/tools/builtin/ellipse/useEllipseTool.js.map +1 -1
  498. package/dist/tools/builtin/hand/useHandTool.js +1 -0
  499. package/dist/tools/builtin/hand/useHandTool.js.map +1 -1
  500. package/dist/tools/builtin/lasso/useLassoTool.js +11 -11
  501. package/dist/tools/builtin/lasso/useLassoTool.js.map +1 -1
  502. package/dist/tools/builtin/line/useLineTool.js +1 -0
  503. package/dist/tools/builtin/line/useLineTool.js.map +1 -1
  504. package/dist/tools/builtin/pen/usePenTool.js +153 -103
  505. package/dist/tools/builtin/pen/usePenTool.js.map +1 -1
  506. package/dist/tools/builtin/pencil/usePencilTool.js +1 -0
  507. package/dist/tools/builtin/pencil/usePencilTool.js.map +1 -1
  508. package/dist/tools/builtin/polygon/usePolygonTool.js +13 -8
  509. package/dist/tools/builtin/polygon/usePolygonTool.js.map +1 -1
  510. package/dist/tools/builtin/rect/useRectTool.js +1 -0
  511. package/dist/tools/builtin/rect/useRectTool.js.map +1 -1
  512. package/dist/tools/builtin/select/selectionContributions.js +24 -23
  513. package/dist/tools/builtin/select/selectionContributions.js.map +1 -1
  514. package/dist/tools/builtin/select/useSelectTool.js +51 -48
  515. package/dist/tools/builtin/select/useSelectTool.js.map +1 -1
  516. package/dist/tools/builtin/shared/pointerFollower.js +17 -0
  517. package/dist/tools/builtin/shared/pointerFollower.js.map +1 -0
  518. package/dist/tools/builtin/slice/useSliceTool.js +49 -54
  519. package/dist/tools/builtin/slice/useSliceTool.js.map +1 -1
  520. package/dist/tools/builtin/star/useStarTool.js +22 -16
  521. package/dist/tools/builtin/star/useStarTool.js.map +1 -1
  522. package/dist/tools/builtin/text/useTextTool.js +13 -2
  523. package/dist/tools/builtin/text/useTextTool.js.map +1 -1
  524. package/dist/tools/useKeybindings.js +14 -30
  525. package/dist/tools/useKeybindings.js.map +1 -1
  526. package/dist/{types-B_9g6hMM.d.ts → types-B4iJRHC3.d.ts} +5 -1
  527. package/dist/{types-A37hYkeR.d.ts → types-k-5Oqh-U.d.ts} +31 -7
  528. package/dist/util/color.js +3 -3
  529. package/dist/util/color.js.map +1 -1
  530. package/dist/util/paint.js.map +1 -1
  531. package/dist/version.js +1 -1
  532. package/package.json +20 -18
  533. package/dist/autoPoseDescriptor-vCdt55xm.d.ts +0 -27
  534. package/dist/builtins-C-VgUlWI.d.ts +0 -4514
  535. package/dist/core/isPlainObject.js.map +0 -1
  536. package/dist/debug/flag.js.map +0 -1
  537. package/dist/interactions/actions/defaults/freshNodeId.js +0 -10
  538. package/dist/interactions/actions/defaults/freshNodeId.js.map +0 -1
  539. package/dist/renderer/shaders/imageFill.js +0 -14
  540. package/dist/renderer/shaders/imageFill.js.map +0 -1
  541. package/dist/tools/prefs.js +0 -47
  542. package/dist/tools/prefs.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"pointerDrag.js","names":["dropZones","activeDrag","registerDropZone","zone","findZone","el","x","y","z","kind","defaultGhost","rect","source","clone","payload","badge","positionGhost","beginPointerDrag","ghost","ghostFn","startX","startY","teardown","e","dropped","err","useDragHandle","optsRef","useLatest","options","live","useRef","useEffect","useCallback","target","start","past","openPointerSession","ev","pastDragThreshold","getPayload","ce","useDropZone","opts","cleanupRef","k","p","a"],"sources":["../../../../src/interactions/gestures/pointerDrag/pointerDrag.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\nimport { useLatest } from '@weasel-js/react';\nimport { openPointerSession, pastDragThreshold, type PointerSession } from '@weasel-js/routing';\n\n/** Payload carried by an in-flight pointer drag — `kind` routes to drop zones, `ids` lists the dragged items. */\nexport interface DragPayload {\n kind: string;\n ids: string[];\n data?: unknown;\n}\n\ninterface DropZone {\n el: HTMLElement;\n accepts: (kind: string) => boolean;\n onDrop: (payload: DragPayload, clientX: number, clientY: number) => void;\n onOver?: (active: boolean) => void;\n onMove?: (payload: DragPayload, clientX: number, clientY: number) => void;\n}\n\nconst dropZones = new Set<DropZone>();\nlet activeDrag: { payload: DragPayload; ghost: HTMLElement; lastZone: DropZone | null } | null = null;\n\nfunction registerDropZone(zone: DropZone): () => void {\n dropZones.add(zone);\n return () => {\n if (activeDrag?.lastZone === zone) activeDrag.lastZone = null;\n dropZones.delete(zone);\n };\n}\n\nfunction findZone(x: number, y: number, kind: string): DropZone | null {\n const el = document.elementFromPoint(x, y);\n if (!el) return null;\n for (const z of dropZones) {\n if (z.el.contains(el) && z.accepts(kind)) return z;\n }\n return null;\n}\n\nfunction defaultGhost(source: HTMLElement, payload: DragPayload): HTMLElement {\n const rect = source.getBoundingClientRect();\n const clone = source.cloneNode(true) as HTMLElement;\n clone.style.position = 'fixed';\n clone.style.left = '0';\n clone.style.top = '0';\n clone.style.width = `${rect.width}px`;\n clone.style.height = `${rect.height}px`;\n clone.style.margin = '0';\n clone.style.pointerEvents = 'none';\n clone.style.opacity = '0.85';\n clone.style.zIndex = '10000';\n clone.style.transition = 'none';\n clone.style.transformOrigin = 'center center';\n if (payload.ids.length > 1) {\n const badge = document.createElement('div');\n badge.textContent = String(payload.ids.length);\n badge.style.position = 'absolute';\n badge.style.top = '-6px';\n badge.style.right = '-6px';\n badge.style.background = '#FFC857';\n badge.style.color = '#000';\n badge.style.borderRadius = '999px';\n badge.style.padding = '2px 8px';\n badge.style.fontWeight = 'bold';\n badge.style.fontSize = '12px';\n badge.style.boxShadow = '0 2px 6px rgba(0,0,0,0.4)';\n clone.appendChild(badge);\n }\n return clone;\n}\n\nfunction positionGhost(el: HTMLElement, x: number, y: number) {\n el.style.transform = `translate(${x - el.offsetWidth / 2}px, ${y - el.offsetHeight / 2}px) scale(0.92)`;\n}\n\n/** The ghost-and-zones half of a drag, driven by whoever owns the pointer. */\ninterface GhostDrag {\n move: (e: PointerEvent) => void;\n drop: (e: PointerEvent) => void;\n cancel: () => void;\n}\n\nfunction beginPointerDrag(\n payload: DragPayload,\n source: HTMLElement,\n startX: number,\n startY: number,\n ghostFn: (source: HTMLElement, payload: DragPayload) => HTMLElement,\n): GhostDrag | null {\n if (activeDrag) return null;\n const ghost = ghostFn(source, payload);\n document.body.appendChild(ghost);\n positionGhost(ghost, startX, startY);\n activeDrag = { payload, ghost, lastZone: null };\n\n const teardown = () => {\n activeDrag?.ghost.remove();\n activeDrag = null;\n };\n\n return {\n move(e) {\n if (!activeDrag) return;\n positionGhost(activeDrag.ghost, e.clientX, e.clientY);\n const zone = findZone(e.clientX, e.clientY, payload.kind);\n if (zone !== activeDrag.lastZone) {\n activeDrag.lastZone?.onOver?.(false);\n zone?.onOver?.(true);\n activeDrag.lastZone = zone;\n }\n zone?.onMove?.(payload, e.clientX, e.clientY);\n },\n drop(e) {\n if (!activeDrag) return;\n const zone = findZone(e.clientX, e.clientY, payload.kind);\n const dropped = activeDrag.payload;\n activeDrag.lastZone?.onOver?.(false);\n // `activeDrag` is module state and gates every future drag, so a throwing\n // consumer `onDrop` must not be able to strand it.\n try {\n if (zone) zone.onDrop(dropped, e.clientX, e.clientY);\n } catch (err) {\n console.error('weasel pointerDrag: drop zone onDrop threw', err);\n } finally {\n teardown();\n }\n },\n cancel() {\n activeDrag?.lastZone?.onOver?.(false);\n teardown();\n },\n };\n}\n\n/** Options for `useDragHandle`; supply `createGhost` to override the default DOM-clone ghost. */\nexport interface DragHandleOptions {\n createGhost?: (source: HTMLElement, payload: DragPayload) => HTMLElement;\n}\n\n/** Attach a pointer-driven drag handle: `getPayload` is read at threshold-cross time and a ghost follows the pointer. */\nexport function useDragHandle(\n getPayload: () => DragPayload | null,\n options?: DragHandleOptions,\n) {\n const optsRef = useLatest(options);\n // One session spans the whole press, threshold and all, so a release that\n // never arrives — the row unmounts under the pointer — cannot strand the\n // ghost or its listeners. Before, the two phases owned separate listener\n // triples and only the pre-threshold one was torn down on unmount.\n const live = useRef<PointerSession | null>(null);\n useEffect(() => () => { live.current?.cancel(); }, []);\n\n const onPointerDown = useCallback((e: React.PointerEvent<HTMLElement>) => {\n if (e.pointerType === 'mouse' && e.button !== 0) return;\n const target = e.currentTarget as HTMLElement;\n if (e.target instanceof HTMLElement && e.target.closest('input, button, select, textarea')) return;\n const start = { clientX: e.clientX, clientY: e.clientY };\n let ghost: GhostDrag | null = null;\n let past = false;\n\n // No pointer capture: zones are resolved with `document.elementFromPoint`,\n // which capture would not help, and the source row is free to be removed\n // and re-rendered under the drag.\n live.current = openPointerSession(target, e, {\n onMove: (ev) => {\n if (ghost) { ghost.move(ev); return; }\n if (past) return;\n if (!pastDragThreshold(start, ev)) return;\n past = true;\n const payload = getPayload();\n if (!payload) return;\n target.addEventListener(\n 'click',\n (ce) => { ce.stopPropagation(); ce.preventDefault(); },\n { capture: true, once: true },\n );\n ghost = beginPointerDrag(\n payload, target, ev.clientX, ev.clientY,\n optsRef.current?.createGhost ?? defaultGhost,\n );\n },\n onEnd: (ev) => { live.current = null; ghost?.drop(ev); },\n onCancel: () => { live.current = null; ghost?.cancel(); },\n }, { capture: false });\n }, [getPayload, optsRef]);\n\n return { onPointerDown, style: { touchAction: 'none' as const } };\n}\n\n/** Options for `useDropZone`; `accepts` filters by `payload.kind`. */\nexport interface DropZoneOptions {\n accepts: (kind: string) => boolean;\n onDrop: (payload: DragPayload, clientX: number, clientY: number) => void;\n onOver?: (active: boolean) => void;\n onMove?: (payload: DragPayload, clientX: number, clientY: number) => void;\n}\n\n/** Register an element as a drop zone for `useDragHandle` payloads. Returns a ref-callback. */\nexport function useDropZone<T extends HTMLElement>(opts: DropZoneOptions): (el: T | null) => void {\n const optsRef = useLatest(opts);\n const cleanupRef = useRef<(() => void) | null>(null);\n return useCallback((el: T | null) => {\n cleanupRef.current?.();\n cleanupRef.current = null;\n if (!el) return;\n cleanupRef.current = registerDropZone({\n el,\n accepts: (k) => optsRef.current.accepts(k),\n onDrop: (p, x, y) => optsRef.current.onDrop(p, x, y),\n onOver: (a) => optsRef.current.onOver?.(a),\n onMove: (p, x, y) => optsRef.current.onMove?.(p, x, y),\n });\n }, [optsRef]);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"pointerDrag.js","names":["dropZones","activeDrag","registerDropZone","zone","findZone","el","x","y","z","kind","defaultGhost","rect","source","clone","payload","badge","positionGhost","beginPointerDrag","ghost","ghostFn","startX","startY","teardown","e","dropped","err","useDragHandle","optsRef","useLatest","options","live","useRef","useEffect","useCallback","target","start","past","dropClickGuard","openPointerSession","ev","pastDragThreshold","getPayload","swallowClick","ce","useDropZone","opts","cleanupRef","k","p","a"],"sources":["../../../../src/interactions/gestures/pointerDrag/pointerDrag.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\nimport { useLatest } from '@weasel-js/react';\nimport { openPointerSession, pastDragThreshold, type PointerSession } from '@weasel-js/routing';\n\n/** Payload carried by an in-flight pointer drag — `kind` routes to drop zones, `ids` lists the dragged items. */\nexport interface DragPayload {\n kind: string;\n ids: string[];\n data?: unknown;\n}\n\ninterface DropZone {\n el: HTMLElement;\n accepts: (kind: string) => boolean;\n onDrop: (payload: DragPayload, clientX: number, clientY: number) => void;\n onOver?: (active: boolean) => void;\n onMove?: (payload: DragPayload, clientX: number, clientY: number) => void;\n}\n\nconst dropZones = new Set<DropZone>();\nlet activeDrag: { payload: DragPayload; ghost: HTMLElement; lastZone: DropZone | null } | null = null;\n\nfunction registerDropZone(zone: DropZone): () => void {\n dropZones.add(zone);\n return () => {\n if (activeDrag?.lastZone === zone) activeDrag.lastZone = null;\n dropZones.delete(zone);\n };\n}\n\nfunction findZone(x: number, y: number, kind: string): DropZone | null {\n const el = document.elementFromPoint(x, y);\n if (!el) return null;\n for (const z of dropZones) {\n if (z.el.contains(el) && z.accepts(kind)) return z;\n }\n return null;\n}\n\nfunction defaultGhost(source: HTMLElement, payload: DragPayload): HTMLElement {\n const rect = source.getBoundingClientRect();\n const clone = source.cloneNode(true) as HTMLElement;\n clone.style.position = 'fixed';\n clone.style.left = '0';\n clone.style.top = '0';\n clone.style.width = `${rect.width}px`;\n clone.style.height = `${rect.height}px`;\n clone.style.margin = '0';\n clone.style.pointerEvents = 'none';\n clone.style.opacity = '0.85';\n clone.style.zIndex = '10000';\n clone.style.transition = 'none';\n clone.style.transformOrigin = 'center center';\n if (payload.ids.length > 1) {\n const badge = document.createElement('div');\n badge.textContent = String(payload.ids.length);\n badge.style.position = 'absolute';\n badge.style.top = '-6px';\n badge.style.right = '-6px';\n badge.style.background = '#FFC857';\n badge.style.color = '#000';\n badge.style.borderRadius = '999px';\n badge.style.padding = '2px 8px';\n badge.style.fontWeight = 'bold';\n badge.style.fontSize = '12px';\n badge.style.boxShadow = '0 2px 6px rgba(0,0,0,0.4)';\n clone.appendChild(badge);\n }\n return clone;\n}\n\nfunction positionGhost(el: HTMLElement, x: number, y: number) {\n el.style.transform = `translate(${x - el.offsetWidth / 2}px, ${y - el.offsetHeight / 2}px) scale(0.92)`;\n}\n\n/** The ghost-and-zones half of a drag, driven by whoever owns the pointer. */\ninterface GhostDrag {\n move: (e: PointerEvent) => void;\n drop: (e: PointerEvent) => void;\n cancel: () => void;\n}\n\nfunction beginPointerDrag(\n payload: DragPayload,\n source: HTMLElement,\n startX: number,\n startY: number,\n ghostFn: (source: HTMLElement, payload: DragPayload) => HTMLElement,\n): GhostDrag | null {\n if (activeDrag) return null;\n const ghost = ghostFn(source, payload);\n document.body.appendChild(ghost);\n positionGhost(ghost, startX, startY);\n activeDrag = { payload, ghost, lastZone: null };\n\n const teardown = () => {\n activeDrag?.ghost.remove();\n activeDrag = null;\n };\n\n return {\n move(e) {\n if (!activeDrag) return;\n positionGhost(activeDrag.ghost, e.clientX, e.clientY);\n const zone = findZone(e.clientX, e.clientY, payload.kind);\n if (zone !== activeDrag.lastZone) {\n activeDrag.lastZone?.onOver?.(false);\n zone?.onOver?.(true);\n activeDrag.lastZone = zone;\n }\n zone?.onMove?.(payload, e.clientX, e.clientY);\n },\n drop(e) {\n if (!activeDrag) return;\n const zone = findZone(e.clientX, e.clientY, payload.kind);\n const dropped = activeDrag.payload;\n activeDrag.lastZone?.onOver?.(false);\n // `activeDrag` is module state and gates every future drag, so a throwing\n // consumer `onDrop` must not be able to strand it.\n try {\n if (zone) zone.onDrop(dropped, e.clientX, e.clientY);\n } catch (err) {\n console.error('weasel pointerDrag: drop zone onDrop threw', err);\n } finally {\n teardown();\n }\n },\n cancel() {\n activeDrag?.lastZone?.onOver?.(false);\n teardown();\n },\n };\n}\n\n/** Options for `useDragHandle`; supply `createGhost` to override the default DOM-clone ghost. */\nexport interface DragHandleOptions {\n createGhost?: (source: HTMLElement, payload: DragPayload) => HTMLElement;\n}\n\n/** Attach a pointer-driven drag handle: `getPayload` is read at threshold-cross time and a ghost follows the pointer. */\nexport function useDragHandle(\n getPayload: () => DragPayload | null,\n options?: DragHandleOptions,\n) {\n const optsRef = useLatest(options);\n // One session spans the whole press, threshold and all, so a release that\n // never arrives — the row unmounts under the pointer — cannot strand the\n // ghost or its listeners. Before, the two phases owned separate listener\n // triples and only the pre-threshold one was torn down on unmount.\n const live = useRef<PointerSession | null>(null);\n useEffect(() => () => { live.current?.cancel(); }, []);\n\n const onPointerDown = useCallback((e: React.PointerEvent<HTMLElement>) => {\n if (e.pointerType === 'mouse' && e.button !== 0) return;\n const target = e.currentTarget as HTMLElement;\n if (e.target instanceof HTMLElement && e.target.closest('input, button, select, textarea')) return;\n const start = { clientX: e.clientX, clientY: e.clientY };\n let ghost: GhostDrag | null = null;\n let past = false;\n let dropClickGuard: (() => void) | null = null;\n\n // No pointer capture: zones are resolved with `document.elementFromPoint`,\n // which capture would not help, and the source row is free to be removed\n // and re-rendered under the drag.\n live.current = openPointerSession(target, e, {\n onMove: (ev) => {\n if (ghost) { ghost.move(ev); return; }\n if (past) return;\n if (!pastDragThreshold(start, ev)) return;\n past = true;\n const payload = getPayload();\n if (!payload) return;\n const swallowClick = (ce: MouseEvent) => { ce.stopPropagation(); ce.preventDefault(); };\n target.addEventListener('click', swallowClick, { capture: true, once: true });\n dropClickGuard = () => target.removeEventListener('click', swallowClick, { capture: true });\n ghost = beginPointerDrag(\n payload, target, ev.clientX, ev.clientY,\n optsRef.current?.createGhost ?? defaultGhost,\n );\n },\n onEnd: (ev) => {\n live.current = null;\n ghost?.drop(ev);\n // A release away from the source sends it no click, and the guard\n // would eat the next real one. Any click this release does bring is\n // dispatched before a timer runs.\n if (dropClickGuard) setTimeout(dropClickGuard, 0);\n },\n onCancel: () => { live.current = null; ghost?.cancel(); dropClickGuard?.(); },\n }, { capture: false });\n }, [getPayload, optsRef]);\n\n return { onPointerDown, style: { touchAction: 'none' as const } };\n}\n\n/** Options for `useDropZone`; `accepts` filters by `payload.kind`. */\nexport interface DropZoneOptions {\n accepts: (kind: string) => boolean;\n onDrop: (payload: DragPayload, clientX: number, clientY: number) => void;\n onOver?: (active: boolean) => void;\n onMove?: (payload: DragPayload, clientX: number, clientY: number) => void;\n}\n\n/** Register an element as a drop zone for `useDragHandle` payloads. Returns a ref-callback. */\nexport function useDropZone<T extends HTMLElement>(opts: DropZoneOptions): (el: T | null) => void {\n const optsRef = useLatest(opts);\n const cleanupRef = useRef<(() => void) | null>(null);\n return useCallback((el: T | null) => {\n cleanupRef.current?.();\n cleanupRef.current = null;\n if (!el) return;\n cleanupRef.current = registerDropZone({\n el,\n accepts: (k) => optsRef.current.accepts(k),\n onDrop: (p, x, y) => optsRef.current.onDrop(p, x, y),\n onOver: (a) => optsRef.current.onOver?.(a),\n onMove: (p, x, y) => optsRef.current.onMove?.(p, x, y),\n });\n }, [optsRef]);\n}\n"],"mappings":";;;;AAmBA,IAAMA,oBAAY,IAAI,IAAc,GAChCC,IAA6F;AAEjG,SAASC,EAAiB,GAA4B;CAEpD,OADAF,EAAU,IAAIG,CAAI,SACL;EAEX,AADIF,GAAY,aAAaE,MAAM,EAAW,WAAW,OACzDH,EAAU,OAAOG,CAAI;CACvB;AACF;AAEA,SAASC,EAAS,GAAW,GAAW,GAA+B;CACrE,IAAMC,IAAK,SAAS,iBAAiBC,GAAGC,CAAC;CACzC,IAAI,CAACF,GAAI,OAAO;CAChB,KAAK,IAAMG,KAAKR,GACd,IAAIQ,EAAE,GAAG,SAASH,CAAE,KAAKG,EAAE,QAAQC,CAAI,GAAG,OAAOD;CAEnD,OAAO;AACT;AAEA,SAASE,EAAa,GAAqB,GAAmC;CAC5E,IAAMC,IAAOC,EAAO,sBAAsB,GACpCC,IAAQD,EAAO,UAAU,EAAI;CAYnC,IAXA,EAAM,MAAM,WAAW,SACvB,EAAM,MAAM,OAAO,KACnB,EAAM,MAAM,MAAM,KAClB,EAAM,MAAM,QAAQ,GAAGD,EAAK,MAAM,KAClC,EAAM,MAAM,SAAS,GAAGA,EAAK,OAAO,KACpC,EAAM,MAAM,SAAS,KACrB,EAAM,MAAM,gBAAgB,QAC5B,EAAM,MAAM,UAAU,QACtB,EAAM,MAAM,SAAS,SACrB,EAAM,MAAM,aAAa,QACzB,EAAM,MAAM,kBAAkB,iBAC1BG,EAAQ,IAAI,SAAS,GAAG;EAC1B,IAAMC,IAAQ,SAAS,cAAc,KAAK;EAY1C,AAXA,EAAM,cAAc,OAAOD,EAAQ,IAAI,MAAM,GAC7C,EAAM,MAAM,WAAW,YACvB,EAAM,MAAM,MAAM,QAClB,EAAM,MAAM,QAAQ,QACpB,EAAM,MAAM,aAAa,WACzB,EAAM,MAAM,QAAQ,QACpB,EAAM,MAAM,eAAe,SAC3B,EAAM,MAAM,UAAU,WACtB,EAAM,MAAM,aAAa,QACzB,EAAM,MAAM,WAAW,QACvB,EAAM,MAAM,YAAY,6BACxBD,EAAM,YAAYE,CAAK;CACzB;CACA,OAAOF;AACT;AAEA,SAASG,EAAc,GAAiB,GAAW,GAAW;CAC5D,EAAG,MAAM,YAAY,aAAaV,IAAID,EAAG,cAAc,EAAE,MAAME,IAAIF,EAAG,eAAe,EAAE;AACzF;AASA,SAASY,EACP,GACA,GACA,GACA,GACA,GACkB;CAClB,IAAIhB,GAAY,OAAO;CACvB,IAAMiB,IAAQC,EAAQP,GAAQE,CAAO;CAGrC,AAFA,SAAS,KAAK,YAAYI,CAAK,GAC/BF,EAAcE,GAAOE,GAAQC,CAAM,GACnC,IAAa;EAAE;EAAS;EAAO,UAAU;CAAK;CAE9C,IAAMC,UAAiB;EAErB,AADArB,GAAY,MAAM,OAAO,GACzB,IAAa;CACf;CAEA,OAAO;EACL,KAAK,GAAG;GACN,IAAI,CAACA,GAAY;GACjB,EAAcA,EAAW,OAAOsB,EAAE,SAASA,EAAE,OAAO;GACpD,IAAMpB,IAAOC,EAASmB,EAAE,SAASA,EAAE,SAAST,EAAQ,IAAI;GAMxD,AALIX,MAASF,EAAW,aACtBA,EAAW,UAAU,SAAS,EAAK,GACnCE,GAAM,SAAS,EAAI,GACnB,EAAW,WAAWA,IAExBA,GAAM,SAASW,GAASS,EAAE,SAASA,EAAE,OAAO;EAC9C;EACA,KAAK,GAAG;GACN,IAAI,CAACtB,GAAY;GACjB,IAAME,IAAOC,EAASmB,EAAE,SAASA,EAAE,SAAST,EAAQ,IAAI,GAClDU,IAAUvB,EAAW;GAC3B,EAAW,UAAU,SAAS,EAAK;GAGnC,IAAI;IACF,AAAIE,KAAMA,EAAK,OAAOqB,GAASD,EAAE,SAASA,EAAE,OAAO;GACrD,SAASE,GAAK;IACZ,QAAQ,MAAM,8CAA8CA,CAAG;GACjE,UAAU;IACR,EAAS;GACX;EACF;EACA,SAAS;GAEP,AADAxB,GAAY,UAAU,SAAS,EAAK,GACpCqB,EAAS;EACX;CACF;AACF;AAQA,SAAgBI,EACd,GACA,GACA;CACA,IAAMC,IAAUC,EAAUC,CAAO,GAK3BC,IAAOC,EAA8B,IAAI;CA2C/C,OA1CAC,cAAsB;EAAE,EAAK,SAAS,OAAO;CAAG,GAAG,CAAC,CAAC,GA0C9C;EAAE,eAxCaC,GAAa,MAAuC;GACxE,IAAI,EAAE,gBAAgB,WAAW,EAAE,WAAW,GAAG;GACjD,IAAMC,IAAS,EAAE;GACjB,IAAI,EAAE,kBAAkB,eAAe,EAAE,OAAO,QAAQ,iCAAiC,GAAG;GAC5F,IAAMC,IAAQ;IAAE,SAAS,EAAE;IAAS,SAAS,EAAE;GAAQ,GACnDjB,IAA0B,MAC1BkB,IAAO,IACPC,IAAsC;GAK1C,EAAK,UAAUC,EAAmBJ,GAAQ,GAAG;IAC3C,SAAS,MAAO;KACd,IAAIhB,GAAO;MAAE,EAAM,KAAKqB,CAAE;MAAG;KAAQ;KAErC,IADIH,KACA,CAACI,EAAkBL,GAAOI,CAAE,GAAG;KACnC,IAAO;KACP,IAAMzB,IAAU2B,EAAW;KAC3B,IAAI,CAAC3B,GAAS;KACd,IAAM4B,KAAgB,MAAmB;MAAwB,AAAtBC,EAAG,gBAAgB,GAAGA,EAAG,eAAe;KAAG;KAGtF,AAFAT,EAAO,iBAAiB,SAASQ,GAAc;MAAE,SAAS;MAAM,MAAM;KAAK,CAAC,GAC5E,UAAuBR,EAAO,oBAAoB,SAASQ,GAAc,EAAE,SAAS,GAAK,CAAC,GAC1F,IAAQzB,EACNH,GAASoB,GAAQK,EAAG,SAASA,EAAG,SAChCZ,EAAQ,SAAS,eAAejB,CAClC;IACF;IACA,QAAQ,MAAO;KAMb,AALA,EAAK,UAAU,MACfQ,GAAO,KAAKqB,CAAE,GAIVF,KAAgB,WAAWA,GAAgB,CAAC;IAClD;IACA,gBAAgB;KAAwC,AAAtC,EAAK,UAAU,MAAMnB,GAAO,OAAO,GAAGmB,IAAiB;IAAG;GAC9E,GAAG,EAAE,SAAS,GAAM,CAAC;EACvB,GAAG,CAACI,GAAYd,CAAO,CAEd;EAAe,OAAO,EAAE,aAAa,OAAgB;CAAE;AAClE;AAWA,SAAgBiB,EAAmC,GAA+C;CAChG,IAAMjB,IAAUC,EAAUiB,CAAI,GACxBC,IAAaf,EAA4B,IAAI;CACnD,OAAOE,GAAa,MAAiB;EAGnC,AAFAa,EAAW,UAAU,GACrB,EAAW,UAAU,MAChBzC,MACL,EAAW,UAAUH,EAAiB;GACpC;GACA,UAAU,MAAMyB,EAAQ,QAAQ,QAAQoB,CAAC;GACzC,SAAS,GAAG,GAAG,MAAMpB,EAAQ,QAAQ,OAAOqB,GAAG1C,GAAGC,CAAC;GACnD,SAAS,MAAMoB,EAAQ,QAAQ,SAASsB,CAAC;GACzC,SAAS,GAAG,GAAG,MAAMtB,EAAQ,QAAQ,SAASqB,GAAG1C,GAAGC,CAAC;EACvD,CAAC;CACH,GAAG,CAACoB,CAAO,CAAC;AACd"}
@@ -6,21 +6,25 @@ function n(n, r) {
6
6
  clientY: n.clientY
7
7
  }, a = !1, o = (e) => {
8
8
  a || t(i, e, r.threshold) && (a = !0, r.onActivate?.(e));
9
- }, s = e(r.origin ?? n.currentTarget, n, {
9
+ }, s = r.origin ?? n.currentTarget, c = s.ownerDocument.defaultView ?? s.ownerDocument, l = (e) => {
10
+ a && e.key === "Escape" && (e.preventDefault(), e.stopPropagation(), d.cancel());
11
+ }, u = () => c.removeEventListener("keydown", l, !0);
12
+ c.addEventListener("keydown", l, !0);
13
+ let d = e(s, n, {
10
14
  onMove: (e) => {
11
15
  o(e), a && r.onMove(e);
12
16
  },
13
17
  onEnd: (e) => {
14
- a ? r.onCommit(e) : r.onClick?.(e);
18
+ u(), a ? r.onCommit(e) : r.onClick?.(e);
15
19
  },
16
20
  onCancel: () => {
17
- r.onCancel?.();
21
+ u(), r.onCancel?.();
18
22
  }
19
23
  });
20
24
  return {
21
25
  isDragging: () => a,
22
26
  cancel: () => {
23
- s.cancel();
27
+ d.cancel();
24
28
  }
25
29
  };
26
30
  }
@@ -1 +1 @@
1
- {"version":3,"file":"thresholdDrag.js","names":["startThresholdDrag","start","e","activated","maybeActivate","pastDragThreshold","ev","opts","session","openPointerSession"],"sources":["../../../../src/interactions/gestures/thresholdDrag/thresholdDrag.ts"],"sourcesContent":["import { openPointerSession, pastDragThreshold } from '@weasel-js/routing';\n\n/**\n * A drag that does not start until the pointer has moved far enough to mean\n * it. Below the threshold the gesture is still a click; above it, `onActivate`\n * fires once and every later move is a drag.\n *\n * The pointer lifecycle underneath — capture, pointer identity, lost-capture\n * and missed-release recovery, teardown — belongs to `openPointerSession`.\n */\nexport interface ThresholdDragOptions {\n /** Travel, in CSS pixels, that makes the press a drag. Default `DRAG_THRESHOLD_PX`. */\n threshold?: number;\n /** Element the session opens on. Defaults to `e.currentTarget`; a list must\n * pass its container, since a grabbed row unmounting drops capture. */\n origin?: Element;\n onActivate?: (e: PointerEvent) => void;\n onMove: (e: PointerEvent) => void;\n onCommit: (e: PointerEvent) => void;\n /** Released below the threshold — the click the press turned out to be. */\n onClick?: (e: PointerEvent) => void;\n /** Ended without a release: pointercancel, lost capture, or `cancel()`. */\n onCancel?: () => void;\n}\n\n/** Handle returned by `startThresholdDrag` exposing live gesture state. */\nexport interface ThresholdDragHandle {\n /** True after the pointer has moved past `threshold` and the drag is live. */\n isDragging: () => boolean;\n /** End the gesture now, as a cancel. For an unmount, an Escape, or any other\n * rule the caller owns. */\n cancel: () => void;\n}\n\n/** Begin a threshold-gated drag from a React PointerDown event; returns a handle exposing live state. */\nexport function startThresholdDrag(\n e: React.PointerEvent,\n opts: ThresholdDragOptions,\n): ThresholdDragHandle {\n const start = { clientX: e.clientX, clientY: e.clientY };\n let activated = false;\n\n const maybeActivate = (ev: PointerEvent) => {\n if (activated) return;\n if (!pastDragThreshold(start, ev, opts.threshold)) return;\n activated = true;\n opts.onActivate?.(ev);\n };\n\n const session = openPointerSession(opts.origin ?? (e.currentTarget as Element), e, {\n onMove: (ev) => {\n maybeActivate(ev);\n if (activated) opts.onMove(ev);\n },\n onEnd: (ev) => {\n if (activated) opts.onCommit(ev);\n else opts.onClick?.(ev);\n },\n onCancel: () => { opts.onCancel?.(); },\n });\n\n return {\n isDragging: () => activated,\n cancel: () => { session.cancel(); },\n };\n}\n"],"mappings":";;AAmCA,SAAgBA,EACd,GACA,GACqB;CACrB,IAAMC,IAAQ;EAAE,SAASC,EAAE;EAAS,SAASA,EAAE;CAAQ,GACnDC,IAAY,IAEVC,KAAiB,MAAqB;EAC1C,AAAID,KACCE,EAAkBJ,GAAOK,GAAIC,EAAK,SAAS,MAChD,IAAY,IACZA,EAAK,aAAaD,CAAE;CACtB,GAEME,IAAUC,EAAmBF,EAAK,UAAWL,EAAE,eAA2BA,GAAG;EACjF,SAAS,MAAO;GAEd,AADAE,EAAcE,CAAE,GACZH,KAAWI,EAAK,OAAOD,CAAE;EAC/B;EACA,QAAQ,MAAO;GACb,AAAIH,IAAWI,EAAK,SAASD,CAAE,IAC1BC,EAAK,UAAUD,CAAE;EACxB;EACA,gBAAgB;GAAE,EAAK,WAAW;EAAG;CACvC,CAAC;CAED,OAAO;EACL,kBAAkBH;EAClB,cAAc;GAAE,EAAQ,OAAO;EAAG;CACpC;AACF"}
1
+ {"version":3,"file":"thresholdDrag.js","names":["startThresholdDrag","start","e","activated","maybeActivate","pastDragThreshold","ev","opts","origin","keys","onKey","session","unlisten","openPointerSession"],"sources":["../../../../src/interactions/gestures/thresholdDrag/thresholdDrag.ts"],"sourcesContent":["import { openPointerSession, pastDragThreshold } from '@weasel-js/routing';\n\n/**\n * A drag that does not start until the pointer has moved far enough to mean\n * it. Below the threshold the gesture is still a click; above it, `onActivate`\n * fires once and every later move is a drag.\n *\n * The pointer lifecycle underneath — capture, pointer identity, lost-capture\n * and missed-release recovery, teardown — belongs to `openPointerSession`.\n */\nexport interface ThresholdDragOptions {\n /** Travel, in CSS pixels, that makes the press a drag. Default `DRAG_THRESHOLD_PX`. */\n threshold?: number;\n /** Element the session opens on. Defaults to `e.currentTarget`; a list must\n * pass its container, since a grabbed row unmounting drops capture. */\n origin?: Element;\n onActivate?: (e: PointerEvent) => void;\n onMove: (e: PointerEvent) => void;\n onCommit: (e: PointerEvent) => void;\n /** Released below the threshold — the click the press turned out to be. */\n onClick?: (e: PointerEvent) => void;\n /** Ended without a release: pointercancel, lost capture, Escape during the drag, or `cancel()`. */\n onCancel?: () => void;\n}\n\n/** Handle returned by `startThresholdDrag` exposing live gesture state. */\nexport interface ThresholdDragHandle {\n /** True after the pointer has moved past `threshold` and the drag is live. */\n isDragging: () => boolean;\n /** End the gesture now, as a cancel. For an unmount, or any other rule the caller owns. */\n cancel: () => void;\n}\n\n/** Begin a threshold-gated drag from a React PointerDown event; returns a handle exposing live state. */\nexport function startThresholdDrag(\n e: React.PointerEvent,\n opts: ThresholdDragOptions,\n): ThresholdDragHandle {\n const start = { clientX: e.clientX, clientY: e.clientY };\n let activated = false;\n\n const maybeActivate = (ev: PointerEvent) => {\n if (activated) return;\n if (!pastDragThreshold(start, ev, opts.threshold)) return;\n activated = true;\n opts.onActivate?.(ev);\n };\n\n const origin = opts.origin ?? (e.currentTarget as Element);\n const keys: EventTarget = origin.ownerDocument.defaultView ?? origin.ownerDocument;\n // Window capture, and stopped there: the Escape that ends a drag must not also close the dialog the drag is in.\n const onKey = (ev: Event) => {\n if (!activated || (ev as KeyboardEvent).key !== 'Escape') return;\n ev.preventDefault();\n ev.stopPropagation();\n session.cancel();\n };\n const unlisten = () => keys.removeEventListener('keydown', onKey, true);\n keys.addEventListener('keydown', onKey, true);\n\n const session = openPointerSession(origin, e, {\n onMove: (ev) => {\n maybeActivate(ev);\n if (activated) opts.onMove(ev);\n },\n onEnd: (ev) => {\n unlisten();\n if (activated) opts.onCommit(ev);\n else opts.onClick?.(ev);\n },\n onCancel: () => {\n unlisten();\n opts.onCancel?.();\n },\n });\n\n return {\n isDragging: () => activated,\n cancel: () => { session.cancel(); },\n };\n}\n"],"mappings":";;AAkCA,SAAgBA,EACd,GACA,GACqB;CACrB,IAAMC,IAAQ;EAAE,SAASC,EAAE;EAAS,SAASA,EAAE;CAAQ,GACnDC,IAAY,IAEVC,KAAiB,MAAqB;EAC1C,AAAID,KACCE,EAAkBJ,GAAOK,GAAIC,EAAK,SAAS,MAChD,IAAY,IACZA,EAAK,aAAaD,CAAE;CACtB,GAEME,IAASD,EAAK,UAAWL,EAAE,eAC3BO,IAAoBD,EAAO,cAAc,eAAeA,EAAO,eAE/DE,KAAS,MAAc;EAC3B,AAAKP,KAAcG,EAAqB,QAAQ,aAChDA,EAAG,eAAe,GAClBA,EAAG,gBAAgB,GACnBK,EAAQ,OAAO;CACjB,GACMC,UAAiBH,EAAK,oBAAoB,WAAWC,GAAO,EAAI;CACtE,EAAK,iBAAiB,WAAWA,GAAO,EAAI;CAE5C,IAAMC,IAAUE,EAAmBL,GAAQN,GAAG;EAC5C,SAAS,MAAO;GAEd,AADAE,EAAcE,CAAE,GACZH,KAAWI,EAAK,OAAOD,CAAE;EAC/B;EACA,QAAQ,MAAO;GAEb,AADAM,EAAS,GACLT,IAAWI,EAAK,SAASD,CAAE,IAC1BC,EAAK,UAAUD,CAAE;EACxB;EACA,gBAAgB;GAEd,AADAM,EAAS,GACTL,EAAK,WAAW;EAClB;CACF,CAAC;CAED,OAAO;EACL,kBAAkBJ;EAClB,cAAc;GAAE,EAAQ,OAAO;EAAG;CACpC;AACF"}
@@ -1,7 +1,6 @@
1
1
  import '@weasel-js/geom';
2
2
  import { Bounds } from '@weasel-js/routing';
3
- import { b as RotatedPose } from './poseDescriptor-D-OH-tu5.js';
4
- import './autoPoseDescriptor-vCdt55xm.js';
3
+ import { c as RotatedPose } from './autoPoseDescriptor-Ct7yqivU.js';
5
4
 
6
5
  /**
7
6
  * Minimal node interface for the simulation primitive. Matches d3-force's
package/dist/math.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  export { DEFAULT_FLATTEN_TOLERANCE, PATH_C, PATH_CMD_LENGTHS, PATH_L, PATH_M, PATH_Q, PATH_Z, Path, PathBuilder, PathFillRule, PolygonPath, RectPath, flattenCubic, flattenCubicWithArcLen, flattenQuadratic, flattenQuadraticWithArcLen, pathCommandCoordCount, pointAlongPath, polygonFromPoints, polylineFromPoints, rectPath } from '@weasel-js/geom';
2
2
  export { Point2 as Vec2 } from '@weasel-js/routing';
3
- export { P as PoseDescriptor, t as translatePoseViaDescriptor } from './poseDescriptor-D-OH-tu5.js';
4
- export { a as Simulation, d as SimulationCore, e as SimulationForce, S as SimulationNode, f as SimulationOptions, h as createSimulation, i as rotatePoint } from './math-Drrw4ewZ.js';
5
- export { A as AUTO_POSE_DESCRIPTOR } from './autoPoseDescriptor-vCdt55xm.js';
3
+ export { A as AUTO_POSE_DESCRIPTOR, P as PoseDescriptor, t as translatePoseViaDescriptor } from './autoPoseDescriptor-Ct7yqivU.js';
4
+ export { a as Simulation, d as SimulationCore, e as SimulationForce, S as SimulationNode, f as SimulationOptions, h as createSimulation, i as rotatePoint } from './math-J-ACHyEg.js';
package/dist/move.d.ts CHANGED
@@ -1,15 +1,16 @@
1
- import { O as OriginProjection } from './originProjection-DEklpDc_.js';
2
- export { U as UseMoveOptions } from './originProjection-DEklpDc_.js';
3
- import { S as SnapTarget } from './types-A37hYkeR.js';
4
- import { M as MoveBehavior } from './types-B_9g6hMM.js';
1
+ import { O as OriginProjection } from './originProjection-gHnOup4e.js';
2
+ export { U as UseMoveOptions } from './originProjection-gHnOup4e.js';
3
+ import { S as SnapTarget } from './types-k-5Oqh-U.js';
4
+ import { M as MoveBehavior } from './types-B4iJRHC3.js';
5
5
  import '@weasel-js/history';
6
6
  import '@weasel-js/geom';
7
7
  import '@weasel-js/routing';
8
8
 
9
9
  /**
10
- * Move behavior that drops the dragged node into a container it hovers over
11
- * for `dwellMs`, reparenting it and taking the pose the container's layout
12
- * assigns.
10
+ * Move behavior that drops the dragged nodes into a container the pointer
11
+ * hovers over for `dwellMs`, reparenting each and giving it the slot
12
+ * `findTarget` answers for its id. A node `findTarget` has no slot for in
13
+ * that container rides along with the first, at its offset from it.
13
14
  *
14
15
  * The dwell is what keeps a drag that merely passes over a container from
15
16
  * being captured by it.
@@ -24,10 +25,10 @@ declare function snapToContainer<TPose>(args: {
24
25
 
25
26
  /**
26
27
  * Move behavior for a drag that is only meaningful near where it started:
27
- * release inside `radius` and the node returns to its original pose; release
28
- * outside it and the node either springs back anyway or is deleted, per
29
- * `onFreeRelease`. A deletion is recorded as an undoable op with paint order
30
- * preserved.
28
+ * release inside `radius` and every dragged node returns to its original
29
+ * pose; release outside it and they all either spring back anyway or are
30
+ * deleted, per `onFreeRelease`. The distance is the first dragged node's. A
31
+ * deletion is recorded as undoable ops with paint order preserved.
31
32
  */
32
33
  declare function snapBackOrDelete<TPose extends {
33
34
  x: number;
@@ -1,4 +1,4 @@
1
- import { M as MoveBehavior } from './types-B_9g6hMM.js';
1
+ import { M as MoveBehavior } from './types-B4iJRHC3.js';
2
2
 
3
3
  /** Option surface for the `move` action. */
4
4
 
@@ -3,9 +3,9 @@ import { Reflection } from '@weasel-js/registry';
3
3
  import { TextureHandle } from '@weasel-js/paint';
4
4
 
5
5
  /**
6
- * 2D affine matrix utilities. Column-major 9-element Float32Array, matching
7
- * `WebGL2RenderingContext.uniformMatrix3fv` byte order so we can pass the
8
- * array directly without a transpose flag.
6
+ * 2D affine matrix utilities. Column-major 9 elements, matching
7
+ * `WebGL2RenderingContext.uniformMatrix3fv` element order so an upload needs
8
+ * no transpose flag.
9
9
  *
10
10
  * Layout (column-major):
11
11
  * [m00, m10, 0,
@@ -16,8 +16,15 @@ import { TextureHandle } from '@weasel-js/paint';
16
16
  * m10*x + m11*y + ty]`.
17
17
  */
18
18
 
19
- /** A 2D affine transform as a column-major 9-element `Float32Array`, laid out as above. */
20
- type GlMat3 = Float32Array;
19
+ /**
20
+ * A 2D affine transform as a column-major 9-element array, laid out as above.
21
+ *
22
+ * Every matrix the kit builds is a `Float64Array`: a view translation far
23
+ * from the origin at high zoom needs more than a float32's 24 bits to hold a
24
+ * fraction of a pixel. A `Float32Array` is accepted wherever one is read.
25
+ * `mat3.toUniform` makes the float32 copy a GL uniform upload wants.
26
+ */
27
+ type GlMat3 = Float32Array | Float64Array;
21
28
  declare function identity(): GlMat3;
22
29
  declare function multiply(out: GlMat3, m: GlMat3): GlMat3;
23
30
  /** `m · T(tx, ty)`: composes onto `m`, where `@weasel-js/geom`'s `translate`
@@ -36,6 +43,8 @@ declare function fromAffine(a: Mat3): GlMat3;
36
43
  /** Inverse of an affine matrix, or `null` when `@weasel-js/geom`'s `invert`
37
44
  * finds it singular — the same rule, read through this layout. */
38
45
  declare function invert(m: GlMat3): GlMat3 | null;
46
+ /** A float32 copy of `m`, for `uniformMatrix3fv` or a shader uniform value. */
47
+ declare function toUniform(m: GlMat3): Float32Array;
39
48
  declare function apply(m: GlMat3, x: number, y: number): [number, number];
40
49
  /**
41
50
  * Map screen pixel coords (0..width on X, 0..height on Y, top-left origin)
@@ -54,7 +63,7 @@ declare function meanScaleOf(m: GlMat3): number;
54
63
  * value. What a screen length is worth in world units, at most. */
55
64
  declare function minScaleOf(m: GlMat3): number;
56
65
  /** The renderer's 3x3 matrix operations, as one namespace. These work on the
57
- * 9-element `Float32Array` form the GL uniform upload wants — distinct from
66
+ * 9-element form the GL uniform upload wants — distinct from
58
67
  * `@weasel-js/geom`'s 6-element affine `GlMat3`, though the logical element
59
68
  * order is the same. */
60
69
  declare const mat3: {
@@ -65,6 +74,7 @@ declare const mat3: {
65
74
  translated: typeof translated;
66
75
  scaled: typeof scaled;
67
76
  invert: typeof invert;
77
+ toUniform: typeof toUniform;
68
78
  apply: typeof apply;
69
79
  screenToClip: typeof screenToClip;
70
80
  meanScaleOf: typeof meanScaleOf;
@@ -144,6 +154,7 @@ interface ShaderProgramHandle {
144
154
  * | [n, n, n] | uniform3fv |
145
155
  * | [n, n, n, n] | uniform4fv |
146
156
  * | Float32Array length 9 | uniformMatrix3fv (column-major) |
157
+ * | Float64Array | as the Float32Array of its values |
147
158
  * | Float32Array length 16 | uniformMatrix4fv (column-major) |
148
159
  * | TextureHandle | bind to next tex unit + uniform1i |
149
160
  *
@@ -156,7 +167,7 @@ interface ShaderProgramHandle {
156
167
  * size; a shorter value leaves the remaining slots as they were. Per-slot
157
168
  * keys (`u_ripples[2]`) keep working and take the table above.
158
169
  */
159
- type ShaderUniform = number | [number, number] | [number, number, number] | [number, number, number, number] | readonly number[] | Float32Array | Int32Array | Uint32Array | TextureHandle;
170
+ type ShaderUniform = number | [number, number] | [number, number, number] | [number, number, number, number] | readonly number[] | Float32Array | Float64Array | Int32Array | Uint32Array | TextureHandle;
160
171
  /** A registered program's GLSL source. An empty `vert` means the kit's default vertex shader. */
161
172
  interface ProgramSource {
162
173
  vert: string;
@@ -1 +1 @@
1
- {"version":3,"file":"DrawCommand.js","names":["SPRITE_STRIDE"],"sources":["../../src/renderer/DrawCommand.ts"],"sourcesContent":["// Import the source types directly, NOT through the `@weasel-js/core` self-barrel.\n// `src/index.ts` reexports `renderer/index.ts`, which reexports this module — so a\n// barrel import here forms a DrawCommand.ts → index.ts → renderer/index.ts → DrawCommand.ts\n// cycle that makes the dts bundler split them into mutually-dependent chunks and warn.\nimport type { Path } from '@weasel-js/geom';\nimport type { FillStyle, Stroke } from '@weasel-js/paint';\nimport type { TextStyle } from '@weasel-js/text';\nimport type { ResolvedRun } from '@weasel-js/text';\nimport type { TextVerticalAlign } from '@weasel-js/text';\nimport type { GlMat3 } from './math/mat3';\nimport type { ShaderProgramHandle, ShaderUniform } from './shaders/registerProgram';\nimport type { Effect } from './effects/types';\n\n/**\n * Solid-fill paint variant (subset of the full `FillStyle` union from\n * `@weasel-js/core`). Kept for back-compat with step-1/2 consumers and\n * because some code reads `fill.color` directly. Through step 4, fills can\n * be any `FillStyle` variant — solid, pattern, or gradient.\n */\nexport interface SolidPaint {\n fill?: 'solid';\n /** Any CSS color string accepted by `parseColor`: hex, `rgb()`/`rgba()`, `hsl()`/`hsla()`, named, or `transparent`. */\n color: string;\n opacity?: number;\n}\n\n/** DrawCommand variants implemented through step 6. */\nexport type DrawCommand =\n | PathDrawCommand\n | GroupDrawCommand\n | TextDrawCommand\n | ImageDrawCommand\n | SpritesDrawCommand\n | ShaderDrawCommand;\n\n/** Draw a path, filled and/or stroked. The workhorse command: every shape the\n * kit draws that is not text, an image, or a custom shader is one of these. */\nexport interface PathDrawCommand {\n kind: 'path';\n path: Path;\n /** Any `FillStyle` variant: solid, pattern, or gradient (linear/radial/conic). */\n fill?: FillStyle;\n /** Stroke spec. Only solid `paint` supported through step 4. */\n stroke?: Stroke;\n /**\n * Optional flat RGBA-per-path-anchor color array (length =\n * `4 × countPathAnchors(path)`, floats in 0..1). The renderer\n * arc-length-interpolates these per-anchor colors across the\n * flattened/triangulated mesh between consecutive anchors using the\n * mesh's `anchorA` / `anchorB` / `anchorT` parameterization.\n *\n * **`fill` must also be set when using `vertexColors`.** The renderer\n * only enters the per-vertex shader path when the command has a fill\n * (the fill provides the opacity uniform; the vertex colors override\n * the fill's color). Pass any solid `fill` (e.g. `{ color: '#fff' }`)\n * as the placeholder; the per-vertex colors win in the shader.\n */\n vertexColors?: number[];\n}\n\n/** Draw a list of commands under a shared transform, opacity, color matrix\n * and clip. Groups nest, and their effects accumulate down the stack — this\n * is how a container node's transform reaches its descendants. */\nexport interface GroupDrawCommand {\n kind: 'group';\n transform?: GlMat3;\n alpha?: number;\n /**\n * Optional 4×5 color matrix (row-major, 20 numbers) — `out = M₄ₓ₄ * in + bias`.\n * Accumulated multiplicatively down the group stack. Defaults to identity.\n */\n colorMatrix?: number[];\n /** Optional clip path. When set, the renderer rasterizes this path into\n * the stencil buffer before drawing `children`; the children paint only\n * where the clip covers. Nested groups with clips intersect — a child\n * cannot escape an ancestor's clip. Max 7 nesting levels; the renderer\n * throws if exceeded. */\n clip?: Path;\n /**\n * Full-screen passes run over this group's own pixels, in order, before it\n * is composited into its parent.\n *\n * Unlike every other field here, this does not accumulate down the group\n * stack — it is a render-target boundary. The children draw into a buffer of\n * their own, each effect reads the previous one's output, and the result is\n * composited back under this group's `transform`, `alpha`, `colorMatrix` and\n * whatever clip encloses it. So a blur here blurs this group and nothing\n * around it, which is what a CSS `filter` on the canvas cannot do.\n *\n * An empty or absent list costs nothing: no buffer is allocated until a\n * group asks for one.\n */\n effects?: readonly Effect[];\n children: DrawCommand[];\n}\n\n/**\n * Text draw command. Renders one or more runs at (`x`, `y`) in screen\n * space, optionally word-wrapping at `maxWidth`. The renderer resolves\n * each run's `(fontFamily, fontWeight, fontStyle)` to an MSDF atlas via\n * `resolveFontVariant` and bucket-draws by atlas + color group.\n *\n * `style` carries node-level defaults (`lineHeight`, anti-alias width)\n * that don't belong on individual runs.\n */\nexport interface TextDrawCommand {\n kind: 'text';\n x: number;\n y: number;\n runs: ResolvedRun[];\n /** Wrap width. Absent never wraps. */\n maxWidth?: number;\n align?: 'left' | 'center' | 'right';\n /** Spread each wrapped line across `width` — see `LayoutRunsOpts.justify`.\n * `align` then sets only the lines it does not spread. Default `false`. */\n justify?: boolean;\n /** Box width `align` resolves within, from `x`. Default `maxWidth`; with\n * neither, `x` is the line's left edge, midpoint or right edge. */\n width?: number;\n style: TextStyle;\n /** Box height for vertical alignment. When set with `verticalAlign`,\n * the laid-out block shifts within `[y, y+height]`. */\n height?: number;\n /** Default 'top' — the legacy top-anchored behavior. */\n verticalAlign?: TextVerticalAlign;\n}\n\n/**\n * Image draw command — renders `image` at screen-space rect (x, y, w, h).\n * The image is stretched to fit; no tiling. Use a pattern FillStyle on a path\n * for tiling.\n */\nexport interface ImageDrawCommand {\n kind: 'image';\n image: ImageBitmap;\n x: number;\n y: number;\n w: number;\n h: number;\n opacity?: number;\n /** Magnification filter. `'linear'` (default) smooths; `'nearest'` shows\n * device pixels as hard squares — required by anything magnifying a\n * framebuffer readback, where blur destroys the point of the readback. */\n sampling?: 'linear' | 'nearest';\n /** Sub-rectangle of `image` to draw, in bitmap pixels from the top-left.\n * Omitted draws the whole bitmap. Not range-checked: a rect past the edge\n * samples outside [0..1], which CLAMP_TO_EDGE smears. With\n * `sampling: 'linear'` the filter reaches half a texel beyond `source`, so\n * atlas frames need a gutter (see `SpriteSheet.spacing`) or `'nearest'`. */\n source?: { x: number; y: number; w: number; h: number };\n /** Mirror the sampled region within the destination rect. The quad does not\n * move — a flipped draw covers exactly the pixels an unflipped one does. */\n flipX?: boolean;\n flipY?: boolean;\n}\n\n/** Floats per sprite in `SpritesDrawCommand.sprites`. */\nexport const SPRITE_STRIDE = 9;\n\n/**\n * Draw many quads sampling one bitmap — an atlas, a sprite sheet, a wall of\n * thumbnails. The same picture as a run of `ImageDrawCommand`s the renderer\n * would coalesce anyway, handed over already packed so it never walks a\n * command object per quad.\n *\n * Reach for it past a few thousand sprites. Below that a plain run of image\n * commands merges into the same single draw and reads better; the packed form\n * exists because at 20,000 the object walk is about half the frame.\n *\n * The sprites are one run: they share a texture, a filter, and whatever group\n * transform, alpha, color matrix and clip are live, exactly as a merged run of\n * image commands would. Anything varying per sprite is in the array.\n */\nexport interface SpritesDrawCommand {\n kind: 'sprites';\n image: ImageBitmap;\n /** Magnification filter for the whole run, as `ImageDrawCommand.sampling`. */\n sampling?: 'linear' | 'nearest';\n /**\n * `SPRITE_STRIDE` floats per sprite:\n * `dx, dy, dw, dh, sx, sy, sw, sh, opacity`.\n *\n * Destination is in the group's coordinates; source is in bitmap pixels,\n * like `ImageDrawCommand.source`. A negative `sw` or `sh` mirrors that axis\n * within the source rect, which is what `flipX` / `flipY` do. A trailing\n * partial sprite is ignored.\n */\n sprites: Float32Array;\n}\n\n/**\n * Custom shader draw command. The renderer generates a quad over `bounds`\n * and dispatches the consumer's fragment shader with the kit's vertex prelude.\n *\n * `uniforms` keys must match names declared in the consumer's fragment shader.\n * The kit automatically sets `u_bounds`, `u_view`, and `u_proj` — do not\n * declare those in `uniforms`.\n *\n * @experimental API may change before v2.\n */\nexport interface ShaderDrawCommand {\n kind: 'shader';\n program: ShaderProgramHandle;\n uniforms: Record<string, ShaderUniform>;\n /** Screen-space bounding rect in CSS pixels. */\n bounds: { x: number; y: number; w: number; h: number };\n}\n"],"mappings":";AA6JA,IAAaA,IAAgB"}
1
+ {"version":3,"file":"DrawCommand.js","names":["SPRITE_STRIDE"],"sources":["../../src/renderer/DrawCommand.ts"],"sourcesContent":["// Import the source types directly, NOT through the `@weasel-js/core` self-barrel.\n// `src/index.ts` reexports `renderer/index.ts`, which reexports this module — so a\n// barrel import here forms a DrawCommand.ts → index.ts → renderer/index.ts → DrawCommand.ts\n// cycle that makes the dts bundler split them into mutually-dependent chunks and warn.\nimport type { Path } from '@weasel-js/geom';\nimport type { CommandFill, CommandStroke } from '@weasel-js/paint';\nimport type { TextAlign, TextDirection, TextStyle } from '@weasel-js/text';\nimport type { ResolvedRun } from '@weasel-js/text';\nimport type { TextVerticalAlign } from '@weasel-js/text';\nimport type { GlMat3 } from './math/mat3';\nimport type { ShaderProgramHandle, ShaderUniform } from './shaders/registerProgram';\nimport type { Effect } from './effects/types';\n\n/**\n * Solid-fill paint variant (subset of the full `FillStyle` union from\n * `@weasel-js/core`). Kept for back-compat with step-1/2 consumers and\n * because some code reads `fill.color` directly. Through step 4, fills can\n * be any `FillStyle` variant — solid, pattern, or gradient.\n */\nexport interface SolidPaint {\n fill?: 'solid';\n /** Any CSS color string accepted by `parseColor`: hex, `rgb()`/`rgba()`, `hsl()`/`hsla()`, named, or `transparent`. */\n color: string;\n opacity?: number;\n}\n\n/** DrawCommand variants implemented through step 6. */\nexport type DrawCommand =\n | PathDrawCommand\n | GroupDrawCommand\n | TextDrawCommand\n | ImageDrawCommand\n | SpritesDrawCommand\n | ShaderDrawCommand;\n\n/** Draw a path, filled and/or stroked. The workhorse command: every shape the\n * kit draws that is not text, an image, or a custom shader is one of these. */\nexport interface PathDrawCommand {\n kind: 'path';\n path: Path;\n /** Solid, pattern, or gradient (linear/radial/conic), resolved for the\n * renderer: `commandFill` makes one from a node's `FillStyle`. */\n fill?: CommandFill;\n /** Stroke spec. Its `paint` takes what `fill` does. */\n stroke?: CommandStroke;\n /**\n * Optional flat RGBA-per-path-anchor color array (length =\n * `4 × countPathAnchors(path)`, floats in 0..1). The renderer\n * arc-length-interpolates these per-anchor colors across the\n * flattened/triangulated mesh between consecutive anchors using the\n * mesh's `anchorA` / `anchorB` / `anchorT` parameterization.\n *\n * **`fill` must also be set when using `vertexColors`.** The renderer\n * only enters the per-vertex shader path when the command has a fill\n * (the fill provides the opacity uniform; the vertex colors override\n * the fill's color). Pass any solid `fill` (e.g. `{ color: '#fff' }`)\n * as the placeholder; the per-vertex colors win in the shader.\n */\n vertexColors?: number[];\n}\n\n/** Draw a list of commands under a shared transform, opacity, color matrix\n * and clip. Groups nest, and their effects accumulate down the stack — this\n * is how a container node's transform reaches its descendants. */\nexport interface GroupDrawCommand {\n kind: 'group';\n transform?: GlMat3;\n alpha?: number;\n /**\n * Optional 4×5 color matrix (row-major, 20 numbers) — `out = M₄ₓ₄ * in + bias`.\n * Accumulated multiplicatively down the group stack. Defaults to identity.\n */\n colorMatrix?: number[];\n /** Optional clip path. When set, the renderer rasterizes this path into\n * the stencil buffer before drawing `children`; the children paint only\n * where the clip covers. Nested groups with clips intersect — a child\n * cannot escape an ancestor's clip. Max 7 nesting levels; the renderer\n * throws if exceeded. */\n clip?: Path;\n /**\n * Full-screen passes run over this group's own pixels, in order, before it\n * is composited into its parent.\n *\n * Unlike every other field here, this does not accumulate down the group\n * stack — it is a render-target boundary. The children draw into a buffer of\n * their own, each effect reads the previous one's output, and the result is\n * composited back under this group's `transform`, `alpha`, `colorMatrix` and\n * whatever clip encloses it. So a blur here blurs this group and nothing\n * around it, which is what a CSS `filter` on the canvas cannot do.\n *\n * An empty or absent list costs nothing: no buffer is allocated until a\n * group asks for one.\n */\n effects?: readonly Effect[];\n children: DrawCommand[];\n}\n\n/**\n * Text draw command. Renders one or more runs at (`x`, `y`) in screen\n * space, optionally word-wrapping at `maxWidth`. The renderer resolves\n * each run's `(fontFamily, fontWeight, fontStyle)` to an MSDF atlas via\n * `resolveFontVariant` and bucket-draws by atlas + color group.\n *\n * `style` carries node-level defaults (`lineHeight`, anti-alias width)\n * that don't belong on individual runs.\n */\nexport interface TextDrawCommand {\n kind: 'text';\n x: number;\n y: number;\n runs: ResolvedRun[];\n /** Wrap width. Absent never wraps. */\n maxWidth?: number;\n align?: TextAlign;\n /** What `start` / `end` resolve against, and the base direction of bidi\n * reordering — see `LayoutRunsOpts.direction`. Default `style`'s. */\n direction?: TextDirection | 'auto';\n /** Spread each wrapped line across `width` — see `LayoutRunsOpts.justify`.\n * `align` then sets only the lines it does not spread. Default `false`. */\n justify?: boolean;\n /** Box width `align` resolves within, from `x`. Default `maxWidth`; with\n * neither, `x` is the line's left edge, midpoint or right edge. */\n width?: number;\n style: TextStyle;\n /** Box height for vertical alignment. When set with `verticalAlign`,\n * the laid-out block shifts within `[y, y+height]`. */\n height?: number;\n /** Default 'top' — the legacy top-anchored behavior. */\n verticalAlign?: TextVerticalAlign;\n}\n\n/**\n * Image draw command — renders `image` at screen-space rect (x, y, w, h).\n * The image is stretched to fit; no tiling. Use a pattern FillStyle on a path\n * for tiling.\n */\nexport interface ImageDrawCommand {\n kind: 'image';\n image: ImageBitmap;\n x: number;\n y: number;\n w: number;\n h: number;\n opacity?: number;\n /** Magnification filter. `'linear'` (default) smooths; `'nearest'` shows\n * device pixels as hard squares — required by anything magnifying a\n * framebuffer readback, where blur destroys the point of the readback. */\n sampling?: 'linear' | 'nearest';\n /** Sub-rectangle of `image` to draw, in bitmap pixels from the top-left.\n * Omitted draws the whole bitmap. Not range-checked: a rect past the edge\n * samples outside [0..1], which CLAMP_TO_EDGE smears. With\n * `sampling: 'linear'` the filter reaches half a texel beyond `source`, so\n * atlas frames need a gutter (see `SpriteSheet.spacing`) or `'nearest'`. */\n source?: { x: number; y: number; w: number; h: number };\n /** Mirror the sampled region within the destination rect. The quad does not\n * move — a flipped draw covers exactly the pixels an unflipped one does. */\n flipX?: boolean;\n flipY?: boolean;\n}\n\n/** Floats per sprite in `SpritesDrawCommand.sprites`. */\nexport const SPRITE_STRIDE = 9;\n\n/**\n * Draw many quads sampling one bitmap — an atlas, a sprite sheet, a wall of\n * thumbnails. The same picture as a run of `ImageDrawCommand`s the renderer\n * would coalesce anyway, handed over already packed so it never walks a\n * command object per quad.\n *\n * Reach for it past a few thousand sprites. Below that a plain run of image\n * commands merges into the same single draw and reads better; the packed form\n * exists because at 20,000 the object walk is about half the frame.\n *\n * The sprites are one run: they share a texture, a filter, and whatever group\n * transform, alpha, color matrix and clip are live, exactly as a merged run of\n * image commands would. Anything varying per sprite is in the array.\n */\nexport interface SpritesDrawCommand {\n kind: 'sprites';\n image: ImageBitmap;\n /** Magnification filter for the whole run, as `ImageDrawCommand.sampling`. */\n sampling?: 'linear' | 'nearest';\n /**\n * `SPRITE_STRIDE` floats per sprite:\n * `dx, dy, dw, dh, sx, sy, sw, sh, opacity`.\n *\n * Destination is in the group's coordinates; source is in bitmap pixels,\n * like `ImageDrawCommand.source`. A negative `sw` or `sh` mirrors that axis\n * within the source rect, which is what `flipX` / `flipY` do. A trailing\n * partial sprite is ignored.\n */\n sprites: Float32Array;\n}\n\n/**\n * Custom shader draw command. The renderer generates a quad over `bounds`\n * and dispatches the consumer's fragment shader with the kit's vertex prelude.\n *\n * `uniforms` keys must match names declared in the consumer's fragment shader.\n * The kit automatically sets `u_bounds`, `u_view`, and `u_proj` — do not\n * declare those in `uniforms`.\n *\n * @experimental API may change before v2.\n */\nexport interface ShaderDrawCommand {\n kind: 'shader';\n program: ShaderProgramHandle;\n uniforms: Record<string, ShaderUniform>;\n /** Screen-space bounding rect in CSS pixels. */\n bounds: { x: number; y: number; w: number; h: number };\n}\n"],"mappings":";AAiKA,IAAaA,IAAgB"}
@@ -1,44 +1,46 @@
1
1
  import { createPaintResources as e } from "./paintResources.js";
2
2
  import { ShaderProgram as t } from "./shaders/ShaderProgram.js";
3
3
  import { FRAG_SRC as n, PATH_FILL_ATTRIBUTES as r, PATH_FILL_UNIFORMS as i, PATH_FILL_VCOLOR_ATTRIBUTES as a, VCOLOR_FRAG_SRC as o, VCOLOR_VERT_SRC as s, VERT_SRC as c } from "./shaders/pathFill.js";
4
- import { IMAGE_FILL_ATTRIBUTES as l, IMAGE_FILL_UNIFORMS as u, IMAGE_FRAG_SRC as d, IMAGE_VERT_SRC as f } from "./shaders/imageFill.js";
5
- import { BATCH_FILL_ATTRIBUTES as p, BATCH_FILL_UNIFORMS as m, BATCH_FRAG_SRC as h, BATCH_VERT_SRC as g } from "./shaders/batchFill.js";
6
- import { GRAD_FILL_ATTRIBUTES as _, GRAD_FILL_UNIFORMS as v, GRAD_FRAG_SRC as y, GRAD_VERT_SRC as b } from "./shaders/gradFill.js";
7
- import { PATTERN_FILL_ATTRIBUTES as x, PATTERN_FILL_UNIFORMS as S, PATTERN_FRAG_SRC as C, PATTERN_VERT_SRC as w } from "./shaders/patternFill.js";
8
- import { GLYPH_GRAD_FRAG_SRC as T, GLYPH_GRAD_UNIFORMS as E, GLYPH_PAINT_ATTRIBUTES as D, GLYPH_PAINT_VERT_SRC as O, GLYPH_PATTERN_FRAG_SRC as k, GLYPH_PATTERN_UNIFORMS as A, GLYPH_TEXTURE_FRAG_SRC as j, GLYPH_TEXTURE_UNIFORMS as ee } from "./shaders/glyphPaint.js";
4
+ import { BATCH_FILL_ATTRIBUTES as l, BATCH_FILL_UNIFORMS as u, BATCH_FRAG_SRC as d, BATCH_VERT_SRC as f } from "./shaders/batchFill.js";
5
+ import { GRAD_FILL_ATTRIBUTES as p, GRAD_FILL_UNIFORMS as m, GRAD_FRAG_SRC as h, GRAD_VERT_SRC as g } from "./shaders/gradFill.js";
6
+ import { PATTERN_FILL_ATTRIBUTES as _, PATTERN_FILL_UNIFORMS as v, PATTERN_FRAG_SRC as y, PATTERN_VERT_SRC as b } from "./shaders/patternFill.js";
7
+ import { GLYPH_GRAD_FRAG_SRC as x, GLYPH_GRAD_UNIFORMS as S, GLYPH_PAINT_ATTRIBUTES as C, GLYPH_PAINT_VERT_SRC as w, GLYPH_PATTERN_FRAG_SRC as T, GLYPH_PATTERN_UNIFORMS as E, GLYPH_TEXTURE_FRAG_SRC as D, GLYPH_TEXTURE_UNIFORMS as ee } from "./shaders/glyphPaint.js";
9
8
  import { PaintScratch as te } from "./paintScratch.js";
10
- import { GLMeshCache as M } from "./cache/GLMeshCache.js";
11
- import { GLTextureCache as N } from "./cache/GLTextureCache.js";
12
- import { GLImageCache as P } from "./cache/GLImageCache.js";
13
- import { GradientRampAtlas as F } from "./cache/GradientRampAtlas.js";
14
- import { GroupState as I } from "./state/GroupState.js";
15
- import { getProgramSource as L } from "./shaders/registerProgram.js";
9
+ import { GLMeshCache as O } from "./cache/GLMeshCache.js";
10
+ import { GLTextureCache as k } from "./cache/GLTextureCache.js";
11
+ import { textureRegistry as A } from "./textures/registerTexture.js";
12
+ import { GLImageCache as j } from "./cache/GLImageCache.js";
13
+ import { GradientRampAtlas as M } from "./cache/GradientRampAtlas.js";
14
+ import { GroupState as N } from "./state/GroupState.js";
15
+ import { getProgramSource as P } from "./shaders/registerProgram.js";
16
+ import { flushBatch as F } from "./draw/flushBatch.js";
17
+ import { OUTLINE_MIN_SCREEN_PX as I } from "./draw/text.js";
18
+ import { dispatch as L } from "./draw.js";
16
19
  import { DrawBatch as R } from "./drawBatch.js";
17
- import { OUTLINE_MIN_SCREEN_PX as ne, dispatch as z, flushBatch as B } from "./draw.js";
18
- import { CUSTOM_ATTRIBUTES as V, CUSTOM_KIT_UNIFORMS as H, CUSTOM_VERT_SRC as U, QUAD_INDICES as W, QUAD_VERTICES as G } from "./shaders/customPrelude.js";
19
- import { EffectTargets as K } from "./effects/EffectTargets.js";
20
- import { extractUniformArrays as q, extractUniformNames as J } from "./shaders/extractUniformNames.js";
21
- import { DEFAULT_BAKE_BUDGET as Y, markAllFontsNotUploaded as X, resetBakeBudget as re } from "@weasel-js/font";
20
+ import { CUSTOM_ATTRIBUTES as z, CUSTOM_KIT_UNIFORMS as B, CUSTOM_VERT_SRC as V, QUAD_INDICES as H, QUAD_VERTICES as U } from "./shaders/customPrelude.js";
21
+ import { EffectTargets as W } from "./effects/EffectTargets.js";
22
+ import { extractUniformArrays as G, extractUniformNames as K } from "./shaders/extractUniformNames.js";
23
+ import { DEFAULT_BAKE_BUDGET as q, markAllFontsNotUploaded as J, resetBakeBudget as Y } from "@weasel-js/font";
22
24
  //#region src/renderer/WeaselRenderer.ts
23
- function ie(e, t) {
25
+ function X(e, t) {
24
26
  return [
25
- ...H,
26
- ...J(e),
27
- ...J(t)
27
+ ...B,
28
+ ...K(e),
29
+ ...K(t)
28
30
  ];
29
31
  }
30
32
  function Z(e, n) {
31
- let r = n.vert === "" ? U : n.vert, i = new t(e, r, n.frag);
32
- return i.lookupUniforms(ie(r, n.frag)), i.lookupUniformArrays(new Map([...q(r), ...q(n.frag)])), i.lookupAttributes(V), i;
33
+ let r = n.vert === "" ? V : n.vert, i = new t(e, r, n.frag);
34
+ return i.lookupUniforms(X(r, n.frag)), i.lookupUniformArrays(new Map([...G(r), ...G(n.frag)])), i.lookupAttributes(z), i;
33
35
  }
34
36
  function Q() {
35
37
  return typeof performance < "u" ? performance.now() : Date.now();
36
38
  }
37
- var ae = {
38
- pattern: [k, A],
39
- gradient: [T, E],
40
- texture: [j, ee]
41
- }, oe = class {
39
+ var ne = {
40
+ pattern: [T, E],
41
+ gradient: [x, S],
42
+ texture: [D, ee]
43
+ }, re = class {
42
44
  gl;
43
45
  stats = {
44
46
  drawCalls: 0,
@@ -47,7 +49,6 @@ var ae = {
47
49
  };
48
50
  pathFill;
49
51
  pathFillVColor;
50
- imageFill;
51
52
  batchFill;
52
53
  gradFill;
53
54
  patternFill;
@@ -62,11 +63,12 @@ var ae = {
62
63
  quadIbo = null;
63
64
  drawBatch;
64
65
  whiteTexture = null;
65
- groupState = new I();
66
+ groupState = new N();
66
67
  widthCss;
67
68
  heightCss;
68
69
  dpr;
69
70
  canvas = null;
71
+ lossTarget = null;
70
72
  target = null;
71
73
  effectTargets;
72
74
  paintScratch;
@@ -81,24 +83,23 @@ var ae = {
81
83
  paintResources = e();
82
84
  constructor(e) {
83
85
  if (!e.gl && !e.canvas) throw Error("WeaselRenderer requires either gl or canvas");
84
- let T = e.gl ?? e.canvas.getContext("webgl2", { stencil: !0 });
85
- if (!T) throw Error("WeaselRenderer: WebGL2 not available");
86
- this.gl = T, this.effectTargets = new K(this.gl), this.paintScratch = new te(this.gl);
87
- let E = typeof this.gl.getContextAttributes == "function" ? this.gl.getContextAttributes() : null;
88
- if (E && E.stencil === !1) throw Error("WeaselRenderer: the supplied WebGL2 context has no stencil buffer. Create it with { stencil: true } — clips and even-odd fills need one.");
89
- this.widthCss = e.width, this.heightCss = e.height, this.dpr = e.dpr, this.imageMinification = e.imageMinification ?? "linear", this.flattenTolerance = e.flattenTolerance, this.bakeBudget = e.bakeBudget ?? Y, this.textOutlineMinScreenSize = e.textOutlineMinScreenSize ?? ne, this.canvas = e.canvas ?? null, this.canvas && (this.canvas.width = Math.round(e.width * e.dpr), this.canvas.height = Math.round(e.height * e.dpr), this.canvas.style && (this.canvas.style.width = `${e.width}px`, this.canvas.style.height = `${e.height}px`), this.canvas.addEventListener("webglcontextlost", this.boundOnLost), this.canvas.addEventListener("webglcontextrestored", this.boundOnRestored)), this.applyGlState(), this.applyTarget(), this.pathFill = new t(this.gl, c, n), this.pathFill.lookupUniforms(i), this.pathFill.lookupAttributes(r), this.pathFillVColor = new t(this.gl, s, o), this.pathFillVColor.lookupUniforms(i), this.pathFillVColor.lookupAttributes(a), this.imageFill = new t(this.gl, f, d), this.imageFill.lookupUniforms(u), this.imageFill.lookupAttributes(l), this.batchFill = new t(this.gl, g, h), this.batchFill.lookupUniforms(m), this.batchFill.lookupAttributes(p), this.gradFill = new t(this.gl, b, y), this.gradFill.lookupUniforms(v), this.gradFill.lookupAttributes(_), this.patternFill = new t(this.gl, w, C), this.patternFill.lookupUniforms(S), this.patternFill.lookupAttributes(x);
90
- let D = this.pathFill.attribute("a_position");
91
- if (D === void 0) throw Error("WeaselRenderer: a_position not found in path-fill shader");
92
- this.meshCache = new M(this.gl, D), this.textureCache = new N(this.gl), this.imageCache = new P(this.gl, this.imageMinification), this.gradRamps = new F(this.gl), this.uploadQuadGeometry(), this.drawBatch = new R(this.gl, this.batchFill), this.whiteTexture = $(this.gl);
86
+ let x = e.gl ?? e.canvas.getContext("webgl2", { stencil: !0 });
87
+ if (!x) throw Error("WeaselRenderer: WebGL2 not available");
88
+ this.gl = x, this.effectTargets = new W(this.gl), this.paintScratch = new te(this.gl);
89
+ let S = typeof this.gl.getContextAttributes == "function" ? this.gl.getContextAttributes() : null;
90
+ if (S && S.stencil === !1) throw Error("WeaselRenderer: the supplied WebGL2 context has no stencil buffer. Create it with { stencil: true } — clips and even-odd fills need one.");
91
+ this.widthCss = e.width, this.heightCss = e.height, this.dpr = e.dpr, this.imageMinification = e.imageMinification ?? "linear", this.flattenTolerance = e.flattenTolerance, this.bakeBudget = e.bakeBudget ?? q, this.textOutlineMinScreenSize = e.textOutlineMinScreenSize ?? I, this.canvas = e.canvas ?? null, this.canvas && (this.canvas.width = Math.round(e.width * e.dpr), this.canvas.height = Math.round(e.height * e.dpr), this.canvas.style && (this.canvas.style.width = `${e.width}px`, this.canvas.style.height = `${e.height}px`));
92
+ let C = this.canvas ?? this.gl.canvas ?? null;
93
+ C && typeof C.addEventListener == "function" && (this.lossTarget = C, this.lossTarget.addEventListener("webglcontextlost", this.boundOnLost), this.lossTarget.addEventListener("webglcontextrestored", this.boundOnRestored)), this.applyGlState(), this.applyTarget(), this.pathFill = new t(this.gl, c, n), this.pathFill.lookupUniforms(i), this.pathFill.lookupAttributes(r), this.pathFillVColor = new t(this.gl, s, o), this.pathFillVColor.lookupUniforms(i), this.pathFillVColor.lookupAttributes(a), this.batchFill = new t(this.gl, f, d), this.batchFill.lookupUniforms(u), this.batchFill.lookupAttributes(l), this.gradFill = new t(this.gl, g, h), this.gradFill.lookupUniforms(m), this.gradFill.lookupAttributes(p), this.patternFill = new t(this.gl, b, y), this.patternFill.lookupUniforms(v), this.patternFill.lookupAttributes(_), this.meshCache = new O(this.gl), this.textureCache = new k(this.gl), this.imageCache = new j(this.gl, this.imageMinification), this.gradRamps = new M(this.gl), this.uploadQuadGeometry(), this.drawBatch = new R(this.gl, this.batchFill), this.whiteTexture = $(this.gl);
93
94
  }
94
95
  uploadQuadGeometry() {
95
96
  let e = this.gl;
96
97
  if (this.quadVbo = e.createBuffer(), this.quadIbo = e.createBuffer(), !this.quadVbo || !this.quadIbo) throw Error("WeaselRenderer: failed to create quad geometry buffers");
97
- e.bindBuffer(e.ARRAY_BUFFER, this.quadVbo), e.bufferData(e.ARRAY_BUFFER, G, e.STATIC_DRAW), e.bindBuffer(e.ARRAY_BUFFER, null), e.bindBuffer(e.ELEMENT_ARRAY_BUFFER, this.quadIbo), e.bufferData(e.ELEMENT_ARRAY_BUFFER, W, e.STATIC_DRAW), e.bindBuffer(e.ELEMENT_ARRAY_BUFFER, null);
98
+ e.bindBuffer(e.ARRAY_BUFFER, this.quadVbo), e.bufferData(e.ARRAY_BUFFER, U, e.STATIC_DRAW), e.bindBuffer(e.ARRAY_BUFFER, null), e.bindBuffer(e.ELEMENT_ARRAY_BUFFER, this.quadIbo), e.bufferData(e.ELEMENT_ARRAY_BUFFER, H, e.STATIC_DRAW), e.bindBuffer(e.ELEMENT_ARRAY_BUFFER, null);
98
99
  }
99
100
  registerProgram(e) {
100
101
  if (this.disposed) return;
101
- let t = L(e.id);
102
+ let t = P(e.id);
102
103
  if (!t) throw Error(`WeaselRenderer.registerProgram: program "${e.id}" not found in source registry. Call the module-level registerProgram() first.`);
103
104
  this.installProgram(e.id, t, Z(this.gl, t));
104
105
  }
@@ -108,7 +109,7 @@ var ae = {
108
109
  }
109
110
  refreshPrograms() {
110
111
  for (let [e, t] of this.programSources) {
111
- let n = L(e);
112
+ let n = P(e);
112
113
  if (n && n !== t) {
113
114
  if (n.vert === t.vert && n.frag === t.frag) {
114
115
  this.programSources.set(e, n);
@@ -125,7 +126,7 @@ var ae = {
125
126
  ensureProgram(e) {
126
127
  let t = this.programRegistry.get(e);
127
128
  if (t) return t;
128
- if (this.disposed || !L(e)) return null;
129
+ if (this.disposed || !P(e)) return null;
129
130
  try {
130
131
  this.registerProgram({ id: e });
131
132
  } catch (t) {
@@ -136,21 +137,30 @@ var ae = {
136
137
  glyphPaintProgram(e) {
137
138
  let n = this.glyphPaintPrograms.get(e);
138
139
  if (n) return n;
139
- let [r, i] = ae[e], a = new t(this.gl, O, r);
140
- return a.lookupUniforms(i), a.lookupAttributes(D), this.glyphPaintPrograms.set(e, a), a;
140
+ let [r, i] = ne[e], a = new t(this.gl, w, r);
141
+ return a.lookupUniforms(i), a.lookupAttributes(C), this.glyphPaintPrograms.set(e, a), a;
141
142
  }
142
143
  applyGlState() {
143
144
  let e = this.gl;
144
- e.enable(e.BLEND), e.blendFunc(e.ONE, e.ONE_MINUS_SRC_ALPHA), e.disable(e.DEPTH_TEST), e.disable(e.CULL_FACE), e.clearColor(0, 0, 0, 0);
145
+ e.enable(e.BLEND), e.blendFunc(e.ONE, e.ONE_MINUS_SRC_ALPHA), e.disable(e.DEPTH_TEST), e.disable(e.CULL_FACE), e.clearColor(0, 0, 0, 0), e.colorMask(!0, !0, !0, !0), e.bindVertexArray(null), e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL, !1);
146
+ }
147
+ deviceRect() {
148
+ let e = this.target?.origin.x ?? 0, t = this.target?.origin.y ?? 0, n = Math.round(e * this.dpr), r = Math.round(t * this.dpr);
149
+ return {
150
+ x: n,
151
+ y: r,
152
+ width: Math.round((e + this.widthCss) * this.dpr) - n,
153
+ height: Math.round((t + this.heightCss) * this.dpr) - r
154
+ };
145
155
  }
146
156
  applyTarget() {
147
- let e = this.gl, t = Math.round(this.widthCss * this.dpr), n = Math.round(this.heightCss * this.dpr);
157
+ let e = this.gl, { x: t, y: n, width: r, height: i } = this.deviceRect();
148
158
  if (!this.target) {
149
- e.disable(e.SCISSOR_TEST), e.viewport(0, 0, t, n);
159
+ e.disable(e.SCISSOR_TEST), e.viewport(0, 0, r, i);
150
160
  return;
151
161
  }
152
- let r = Math.round(this.target.origin.x * this.dpr), i = e.drawingBufferHeight - Math.round(this.target.origin.y * this.dpr) - n;
153
- e.viewport(r, i, t, n), e.scissor(r, i, t, n), e.enable(e.SCISSOR_TEST);
162
+ let a = e.drawingBufferHeight - n - i;
163
+ e.viewport(t, a, r, i), e.scissor(t, a, r, i), e.enable(e.SCISSOR_TEST);
154
164
  }
155
165
  setTarget(e) {
156
166
  this.target = e, this.applyTarget();
@@ -165,12 +175,9 @@ var ae = {
165
175
  e.preventDefault(), this.contextLost = !0;
166
176
  }
167
177
  onContextRestored() {
168
- this.contextLost = !1, this.applyGlState(), this.applyTarget(), this.effectTargets.releaseAll(), this.paintScratch.release(), this.paintResources.release(), this.paintResources = e(), this.pathFill = new t(this.gl, c, n), this.pathFill.lookupUniforms(i), this.pathFill.lookupAttributes(r), this.pathFillVColor = new t(this.gl, s, o), this.pathFillVColor.lookupUniforms(i), this.pathFillVColor.lookupAttributes(a), this.imageFill = new t(this.gl, f, d), this.imageFill.lookupUniforms(u), this.imageFill.lookupAttributes(l), this.batchFill = new t(this.gl, g, h), this.batchFill.lookupUniforms(m), this.batchFill.lookupAttributes(p), this.gradFill = new t(this.gl, b, y), this.gradFill.lookupUniforms(v), this.gradFill.lookupAttributes(_), this.patternFill = new t(this.gl, w, C), this.patternFill.lookupUniforms(S), this.patternFill.lookupAttributes(x), this.glyphPaintPrograms.clear();
169
- let T = this.pathFill.attribute("a_position");
170
- if (T === void 0) throw Error("a_position missing after restore");
171
- this.meshCache = new M(this.gl, T), this.textureCache = new N(this.gl), this.imageCache.abandon(), this.imageCache = new P(this.gl, this.imageMinification), this.gradRamps = new F(this.gl), X(), this.uploadQuadGeometry(), this.drawBatch = new R(this.gl, this.batchFill), this.whiteTexture = $(this.gl);
178
+ this.contextLost = !1, this.applyGlState(), this.applyTarget(), this.effectTargets.releaseAll(), this.paintScratch.release(), this.paintResources.release(), this.paintResources = e(), this.pathFill = new t(this.gl, c, n), this.pathFill.lookupUniforms(i), this.pathFill.lookupAttributes(r), this.pathFillVColor = new t(this.gl, s, o), this.pathFillVColor.lookupUniforms(i), this.pathFillVColor.lookupAttributes(a), this.batchFill = new t(this.gl, f, d), this.batchFill.lookupUniforms(u), this.batchFill.lookupAttributes(l), this.gradFill = new t(this.gl, g, h), this.gradFill.lookupUniforms(m), this.gradFill.lookupAttributes(p), this.patternFill = new t(this.gl, b, y), this.patternFill.lookupUniforms(v), this.patternFill.lookupAttributes(_), this.glyphPaintPrograms.clear(), this.meshCache = new O(this.gl), this.textureCache = new k(this.gl), this.imageCache.abandon(), this.imageCache = new j(this.gl, this.imageMinification), this.gradRamps = new M(this.gl), J(), this.uploadQuadGeometry(), this.drawBatch = new R(this.gl, this.batchFill), this.whiteTexture = $(this.gl);
172
179
  for (let e of this.programRegistry.keys()) {
173
- let t = L(e);
180
+ let t = P(e);
174
181
  if (t) try {
175
182
  this.programRegistry.set(e, Z(this.gl, t)), this.programSources.set(e, t);
176
183
  } catch (t) {
@@ -182,11 +189,10 @@ var ae = {
182
189
  if (this.disposed) return;
183
190
  this.disposed = !0;
184
191
  let e = this.gl;
185
- this.canvas && (this.canvas.removeEventListener("webglcontextlost", this.boundOnLost), this.canvas.removeEventListener("webglcontextrestored", this.boundOnRestored)), this.meshCache.dispose(), this.paintResources.release();
192
+ this.lossTarget && (this.lossTarget.removeEventListener("webglcontextlost", this.boundOnLost), this.lossTarget.removeEventListener("webglcontextrestored", this.boundOnRestored)), this.meshCache.dispose(), this.paintResources.release();
186
193
  for (let t of [
187
194
  this.pathFill,
188
195
  this.pathFillVColor,
189
- this.imageFill,
190
196
  this.batchFill,
191
197
  this.gradFill,
192
198
  this.patternFill,
@@ -205,12 +211,11 @@ var ae = {
205
211
  spans: a
206
212
  };
207
213
  let o = this.gl;
208
- this.meshCache.drainPendingDeletes(), this.refreshPrograms(), re(this.bakeBudget), this.groupState.reset(), this.applyGlState(), this.applyTarget(), this.target?.clear !== !1 && (o.stencilMask(255), o.clear(o.COLOR_BUFFER_BIT | o.STENCIL_BUFFER_BIT));
209
- let s = {
214
+ this.meshCache.drainPendingDeletes(), this.imageCache.drainPendingDeletes(), this.textureCache.sweep(A), this.refreshPrograms(), Y(this.bakeBudget), this.groupState.reset(), this.drawBatch.reset(), this.effectTargets.reclaim(), o.bindFramebuffer(o.FRAMEBUFFER, null), this.applyGlState(), this.applyTarget(), this.target?.clear !== !1 && (o.stencilMask(255), o.clear(o.COLOR_BUFFER_BIT | o.STENCIL_BUFFER_BIT));
215
+ let s = this.deviceRect(), c = {
210
216
  gl: o,
211
217
  pathFill: this.pathFill,
212
218
  pathFillVColor: this.pathFillVColor,
213
- imageFill: this.imageFill,
214
219
  batchFill: this.batchFill,
215
220
  gradFill: this.gradFill,
216
221
  patternFill: this.patternFill,
@@ -236,27 +241,27 @@ var ae = {
236
241
  effectTargets: this.effectTargets,
237
242
  paintScratch: this.paintScratch,
238
243
  renderTarget: null,
239
- deviceWidth: Math.round(this.widthCss * this.dpr),
240
- deviceHeight: Math.round(this.heightCss * this.dpr),
244
+ deviceWidth: s.width,
245
+ deviceHeight: s.height,
241
246
  restoreTargetRect: () => this.applyTarget(),
242
247
  paintResources: this.paintResources,
243
248
  stats: i
244
249
  };
245
250
  this.drawBatch.clip = null;
246
- let c = n?.spans ?? [], l = 0;
247
- for (let t = 0; t < c.length; t++) {
248
- let n = c[t];
249
- for (; l < n.start; l++) z(s, e[l]);
251
+ let l = n?.spans ?? [], u = 0;
252
+ for (let t = 0; t < l.length; t++) {
253
+ let n = l[t];
254
+ for (; u < n.start; u++) L(c, e[u]);
250
255
  let r = i.drawCalls, o = Q();
251
- for (; l < n.end; l++) z(s, e[l]);
252
- t === c.length - 1 && l >= e.length && B(s), a.push({
256
+ for (; u < n.end; u++) L(c, e[u]);
257
+ t === l.length - 1 && u >= e.length && F(c), a.push({
253
258
  id: n.id,
254
259
  drawCalls: i.drawCalls - r,
255
260
  ms: Q() - o
256
261
  });
257
262
  }
258
- for (; l < e.length; l++) z(s, e[l]);
259
- B(s), this.meshCache.freeTransient(), this.stats.drawCalls = i.drawCalls, this.stats.ms = Q() - r;
263
+ for (; u < e.length; u++) L(c, e[u]);
264
+ F(c), this.meshCache.freeTransient(), this.stats.drawCalls = i.drawCalls, this.stats.ms = Q() - r;
260
265
  }
261
266
  lastFrameStats() {
262
267
  return this.stats;
@@ -279,9 +284,6 @@ var ae = {
279
284
  _drawBatch() {
280
285
  return this.drawBatch;
281
286
  }
282
- _imageFill() {
283
- return this.imageFill;
284
- }
285
287
  _batchFill() {
286
288
  return this.batchFill;
287
289
  }
@@ -326,6 +328,6 @@ function $(e) {
326
328
  ])), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, e.NEAREST), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, e.NEAREST), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_S, e.CLAMP_TO_EDGE), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_T, e.CLAMP_TO_EDGE), e.bindTexture(e.TEXTURE_2D, null), t) : null;
327
329
  }
328
330
  //#endregion
329
- export { oe as WeaselRenderer };
331
+ export { re as WeaselRenderer };
330
332
 
331
333
  //# sourceMappingURL=WeaselRenderer.js.map