@weasel-js/labkit 1.4.1 → 1.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/README.md +8 -0
  2. package/dist/_dts/{CanvasStackContext-BIRUVVGH.d.ts → CanvasStackContext-kjILVnPj.d.ts} +1 -1
  3. package/dist/_dts/{frac-X7mWgd7y.d.ts → frac-A4R6v4ld.d.ts} +27 -10
  4. package/dist/_dts/{index-FEa1MudK.d.ts → index-CsU9WhjM.d.ts} +89 -29
  5. package/dist/_dts/{types-ChVJJHvk.d.ts → types-BbXpvQa8.d.ts} +20 -1
  6. package/dist/_dts/{useTrialState-Cdm13fvl.d.ts → useTrialState-DKjqpv20.d.ts} +5 -1
  7. package/dist/canvas/index.d.ts +5 -5
  8. package/dist/canvas/index.js +2 -2
  9. package/dist/chrome/index.d.ts +12 -6
  10. package/dist/chrome/index.js +5 -5
  11. package/dist/{chunk-DG2IFMLA.js → chunk-54ZWZ5FQ.js} +127 -100
  12. package/dist/chunk-54ZWZ5FQ.js.map +1 -0
  13. package/dist/{chunk-RLOXQZW3.js → chunk-D5KQ5OY6.js} +3 -3
  14. package/dist/{chunk-RLOXQZW3.js.map → chunk-D5KQ5OY6.js.map} +1 -1
  15. package/dist/{chunk-PP7ZWAMV.js → chunk-FJG4PHTL.js} +3 -3
  16. package/dist/{chunk-PP7ZWAMV.js.map → chunk-FJG4PHTL.js.map} +1 -1
  17. package/dist/chunk-ISSVF5PT.js +7263 -0
  18. package/dist/chunk-ISSVF5PT.js.map +1 -0
  19. package/dist/chunk-NSOVI3AZ.js +170 -0
  20. package/dist/chunk-NSOVI3AZ.js.map +1 -0
  21. package/dist/{chunk-D7QIPGEB.js → chunk-TN7YSJVU.js} +62 -60
  22. package/dist/chunk-TN7YSJVU.js.map +1 -0
  23. package/dist/{chunk-7TRFMIWX.js → chunk-UDXOYZEC.js} +4 -4
  24. package/dist/{chunk-7TRFMIWX.js.map → chunk-UDXOYZEC.js.map} +1 -1
  25. package/dist/{chunk-LJSIUFYD.js → chunk-ULDW42CR.js} +23 -2
  26. package/dist/chunk-ULDW42CR.js.map +1 -0
  27. package/dist/{chunk-MSR7EVS6.js → chunk-UTOEDPNU.js} +5 -5
  28. package/dist/{chunk-MSR7EVS6.js.map → chunk-UTOEDPNU.js.map} +1 -1
  29. package/dist/{chunk-BMQWLKOL.js → chunk-W2FJR5FF.js} +35 -22
  30. package/dist/chunk-W2FJR5FF.js.map +1 -0
  31. package/dist/{chunk-OFCBEZMU.js → chunk-WS6ZRV75.js} +3 -3
  32. package/dist/{chunk-OFCBEZMU.js.map → chunk-WS6ZRV75.js.map} +1 -1
  33. package/dist/{chunk-53AZ2O2N.js → chunk-XKENZTNE.js} +45 -14
  34. package/dist/chunk-XKENZTNE.js.map +1 -0
  35. package/dist/controls/index.d.ts +1 -1
  36. package/dist/controls/index.js +3 -3
  37. package/dist/dragdrop/index.d.ts +5 -5
  38. package/dist/dragdrop/index.js +2 -2
  39. package/dist/index.d.ts +71 -43
  40. package/dist/index.js +146 -113
  41. package/dist/index.js.map +1 -1
  42. package/dist/layers/index.d.ts +23 -8
  43. package/dist/layers/index.js +3 -3
  44. package/dist/loupe/index.d.ts +4 -4
  45. package/dist/loupe/index.js +2 -2
  46. package/dist/passthrough/weasel-canvas.js +1 -1
  47. package/dist/passthrough/weasel-ui.d.ts +84 -3
  48. package/dist/passthrough/weasel-ui.js +2 -2
  49. package/dist/primitives/index.js +4 -4
  50. package/dist/state/index.d.ts +3 -3
  51. package/dist/state/index.js +2 -2
  52. package/dist/styles.css +20 -3
  53. package/dist/surface/index.js +2 -2
  54. package/dist/ui/layers/index.d.ts +22 -9
  55. package/dist/ui/layers/index.js +2 -2
  56. package/dist/undo/index.d.ts +2 -2
  57. package/package.json +7 -7
  58. package/src/annotations/AnnotationTargets.tsx +6 -1
  59. package/src/annotations/Annotations.overlay.test.tsx +2 -0
  60. package/src/annotations/types.ts +4 -1
  61. package/src/canvas/useOrbit.test.ts +7 -3
  62. package/src/canvas/usePanZoom.test.ts +7 -3
  63. package/src/chrome/ChromeRegions.stories.tsx +42 -1
  64. package/src/chrome/builtins.test.ts +4 -0
  65. package/src/chrome/builtins.tsx +18 -0
  66. package/src/chrome/index.ts +1 -1
  67. package/src/chrome/regions/SidebarRegion.tsx +7 -6
  68. package/src/chrome/regions/TitleBarRegion.test.tsx +64 -0
  69. package/src/chrome/regions/TitleBarRegion.tsx +16 -7
  70. package/src/chrome/regions/ToolbarRegion.test.tsx +14 -0
  71. package/src/chrome/regions/ToolbarRegion.tsx +2 -2
  72. package/src/chrome/regions/ViewportRegion.tsx +2 -2
  73. package/src/chrome/regions/regions.test.tsx +45 -1
  74. package/src/chrome/types.ts +21 -3
  75. package/src/controls/ControlPanel.test.tsx +38 -0
  76. package/src/controls/ControlPanel.tsx +51 -6
  77. package/src/dragdrop/DragDropRuntime.tsx +74 -61
  78. package/src/dragdrop/Palette.tsx +4 -3
  79. package/src/dragdrop/dragDrop.test.tsx +35 -12
  80. package/src/index.ts +2 -1
  81. package/src/instrument/types.ts +4 -5
  82. package/src/lab/Lab.test.tsx +7 -0
  83. package/src/lab/Lab.tsx +2 -2
  84. package/src/lab/LabContext.ts +5 -1
  85. package/src/lab/LabShell.less +17 -2
  86. package/src/layers/AGENTS.md +29 -7
  87. package/src/layers/LayerList.less +16 -0
  88. package/src/layers/LayerList.stories.tsx +66 -0
  89. package/src/layers/LayerList.test.tsx +117 -5
  90. package/src/layers/LayerList.tsx +192 -53
  91. package/src/layers/index.ts +1 -1
  92. package/src/passthrough/weasel-ui.ts +5 -0
  93. package/src/primitives/FloatingPanel.test.tsx +8 -3
  94. package/src/state/store.test.ts +78 -0
  95. package/src/state/store.ts +27 -0
  96. package/src/state/types.ts +20 -0
  97. package/src/trial/Trial.less +4 -0
  98. package/src/trial/Trial.targets.test.tsx +96 -0
  99. package/src/trial/Trial.test.tsx +171 -14
  100. package/src/trial/Trial.tsx +4 -1
  101. package/src/trial/TrialChrome.tsx +22 -2
  102. package/src/trial/TrialTitleBar.tsx +7 -3
  103. package/src/trial/index.ts +1 -0
  104. package/src/trial/trialOps.test.ts +49 -1
  105. package/src/trial/trialOps.ts +28 -6
  106. package/dist/chunk-53AZ2O2N.js.map +0 -1
  107. package/dist/chunk-BMQWLKOL.js.map +0 -1
  108. package/dist/chunk-D7QIPGEB.js.map +0 -1
  109. package/dist/chunk-DG2IFMLA.js.map +0 -1
  110. package/dist/chunk-J6SBFZYT.js +0 -7121
  111. package/dist/chunk-J6SBFZYT.js.map +0 -1
  112. package/dist/chunk-LJSIUFYD.js.map +0 -1
  113. package/dist/chunk-MIT3ISW4.js +0 -100
  114. package/dist/chunk-MIT3ISW4.js.map +0 -1
@@ -2978,7 +2978,7 @@ var TEXT_SDF_UNIFORMS = [
2978
2978
  ];
2979
2979
  var TEXT_SDF_ATTRIBUTES = ["a_position", "a_uv", "a_baselineY"];
2980
2980
 
2981
- // ../text/dist/chunk-BYL6KOD4.js
2981
+ // ../text/dist/chunk-7ZHZKQEH.js
2982
2982
  function resolveAlign(align, direction) {
2983
2983
  if (align === "start") return direction === "rtl" ? "right" : "left";
2984
2984
  if (align === "end") return direction === "rtl" ? "left" : "right";
@@ -3548,7 +3548,7 @@ function layoutRuns(runs, opts) {
3548
3548
  cells[pos] = cell;
3549
3549
  const step = e.advance + e.tracking;
3550
3550
  const scale2 = e.fontSize / e.metrics.size;
3551
- const baselineY = lineBaselineY - e.run.baselineShift;
3551
+ const baselineY = lineBaselineY - (e.run.baselineShift ?? 0);
3552
3552
  if (e.run.underline || e.run.strikethrough || e.run.overline) {
3553
3553
  if (span !== null && span.underline === e.run.underline && span.strikethrough === e.run.strikethrough && span.overline === e.run.overline && span.fontSize === e.fontSize && span.baselineY === baselineY && sameFill(span.fill, e.run.fill)) {
3554
3554
  span.x1 = penX + step;
@@ -4670,7 +4670,7 @@ function serialToEntry(se, custom, logger) {
4670
4670
  };
4671
4671
  }
4672
4672
 
4673
- // ../core/dist/chunk-NU7D64RL.js
4673
+ // ../core/dist/chunk-KIVJXUYE.js
4674
4674
  function worldToScreen(worldX, worldY, view) {
4675
4675
  return [view.panX + worldX * view.zoom.x, view.panY + worldY * view.zoom.y];
4676
4676
  }
@@ -10200,7 +10200,8 @@ function openPointerSession(origin, down, cb, opts = {}) {
10200
10200
  if (mine(e)) abort("superseded");
10201
10201
  }
10202
10202
  function onLostCapture(e) {
10203
- if (e.pointerId === pointerId) abort("lostcapture");
10203
+ if (e.pointerId !== pointerId) return;
10204
+ if (!origin.isConnected) abort("lostcapture");
10204
10205
  }
10205
10206
  if (opts.capture !== false) {
10206
10207
  try {
@@ -10221,6 +10222,39 @@ function openPointerSession(origin, down, cb, opts = {}) {
10221
10222
  cancel: () => abort("aborted")
10222
10223
  };
10223
10224
  }
10225
+ function startThresholdDrag(e, opts) {
10226
+ const startX = e.clientX;
10227
+ const startY = e.clientY;
10228
+ const threshold = opts.threshold ?? 4;
10229
+ let activated = false;
10230
+ const maybeActivate = (ev) => {
10231
+ if (activated) return;
10232
+ const dx = ev.clientX - startX;
10233
+ const dy = ev.clientY - startY;
10234
+ if (dx * dx + dy * dy < threshold * threshold) return;
10235
+ activated = true;
10236
+ opts.onActivate?.(ev);
10237
+ };
10238
+ const session = openPointerSession(opts.origin ?? e.currentTarget, e, {
10239
+ onMove: (ev) => {
10240
+ maybeActivate(ev);
10241
+ if (activated) opts.onMove(ev);
10242
+ },
10243
+ onEnd: (ev) => {
10244
+ if (activated) opts.onCommit(ev);
10245
+ else opts.onClick?.(ev);
10246
+ },
10247
+ onCancel: () => {
10248
+ opts.onCancel?.();
10249
+ }
10250
+ });
10251
+ return {
10252
+ isDragging: () => activated,
10253
+ cancel: () => {
10254
+ session.cancel();
10255
+ }
10256
+ };
10257
+ }
10224
10258
  var BASE_PX = {
10225
10259
  handle: 8,
10226
10260
  anchor: 8,
@@ -16596,7 +16630,7 @@ function withViewDeps(base, overlay) {
16596
16630
  };
16597
16631
  }
16598
16632
  function computeMultiTouchGeometry(positions) {
16599
- const pts = [...positions.values()];
16633
+ const pts = [...positions];
16600
16634
  if (pts.length < 2) {
16601
16635
  return { centroid: { x: 0, y: 0 }, spread: 0 };
16602
16636
  }
@@ -16723,14 +16757,13 @@ function useGestureDispatcher(opts) {
16723
16757
  return result;
16724
16758
  };
16725
16759
  const heldKeys = /* @__PURE__ */ new Set();
16726
- const activePointers = /* @__PURE__ */ new Set();
16727
- const buttonsReportedFor = /* @__PURE__ */ new Set();
16728
- const pointerPositions = /* @__PURE__ */ new Map();
16760
+ const held = /* @__PURE__ */ new Map();
16761
+ const heldGeometry = () => computeMultiTouchGeometry(
16762
+ [...held.values()].map((p) => p.pos)
16763
+ );
16729
16764
  let multiTouchStart = null;
16730
16765
  const TAP_THRESHOLD_PX = 8;
16731
16766
  const DRAG_THRESHOLD_PX = 4;
16732
- const bufferedDown = /* @__PURE__ */ new Map();
16733
- const lastPointerDown = /* @__PURE__ */ new Map();
16734
16767
  const LONG_PRESS_MS = 500;
16735
16768
  const longPressTimers = /* @__PURE__ */ new Map();
16736
16769
  const cancelLongPress = (pointerId) => {
@@ -16745,7 +16778,7 @@ function useGestureDispatcher(opts) {
16745
16778
  longPressTimers.clear();
16746
16779
  };
16747
16780
  const fireLongPress = (pointerId) => {
16748
- const down = lastPointerDown.get(pointerId);
16781
+ const down = held.get(pointerId)?.down;
16749
16782
  if (!down) return;
16750
16783
  const shared = {
16751
16784
  target: down.target,
@@ -16867,15 +16900,8 @@ function useGestureDispatcher(opts) {
16867
16900
  };
16868
16901
  const onPointerDown = (e) => {
16869
16902
  if ((e.button ?? 0) !== 0) return;
16870
- if (activePointers.has(e.pointerId)) onPointerUp(e);
16903
+ if (!canvas) return;
16871
16904
  routeDown(e.pointerId, e.clientX, e.clientY);
16872
- activePointers.add(e.pointerId);
16873
- if (reportsButtons(e)) buttonsReportedFor.add(e.pointerId);
16874
- pointerPositions.set(e.pointerId, { x: e.clientX, y: e.clientY });
16875
- try {
16876
- canvas?.setPointerCapture?.(e.pointerId);
16877
- } catch {
16878
- }
16879
16905
  const worldPoint = { x: e.clientX, y: e.clientY };
16880
16906
  const affordance = target().affordanceAt?.(worldPoint) ?? void 0;
16881
16907
  const body = target().classifyTarget?.(worldPoint);
@@ -16899,23 +16925,35 @@ function useGestureDispatcher(opts) {
16899
16925
  ...bodyTarget !== void 0 ? { bodyTarget } : {},
16900
16926
  ...bodyKind !== void 0 ? { bodyKind } : {}
16901
16927
  };
16902
- bufferedDown.set(e.pointerId, { ev, clientX: e.clientX, clientY: e.clientY });
16903
- dispatch2({ ...ev, stage: "press" });
16904
- lastPointerDown.set(e.pointerId, {
16905
- target: e.target,
16906
- clientX: e.clientX,
16907
- clientY: e.clientY,
16908
- worldX: w.x,
16909
- worldY: w.y,
16910
- affordance,
16911
- bodyTarget,
16912
- bodyKind,
16913
- altKey: e.altKey,
16914
- ctrlKey: e.ctrlKey,
16915
- metaKey: e.metaKey,
16916
- shiftKey: e.shiftKey
16928
+ held.set(e.pointerId, {
16929
+ session: openPointerSession(canvas, e, {
16930
+ onMove: onPointerMove,
16931
+ onEnd: onPointerUp,
16932
+ onCancel: () => {
16933
+ onPointerCancel(e.pointerId);
16934
+ }
16935
+ }),
16936
+ pos: { x: e.clientX, y: e.clientY },
16937
+ // Deferred until the first past-threshold pointermove: a bare
16938
+ // press-and-release should fire `click`, not start a drag action.
16939
+ buffered: { ev, clientX: e.clientX, clientY: e.clientY },
16940
+ down: {
16941
+ target: e.target,
16942
+ clientX: e.clientX,
16943
+ clientY: e.clientY,
16944
+ worldX: w.x,
16945
+ worldY: w.y,
16946
+ affordance,
16947
+ bodyTarget,
16948
+ bodyKind,
16949
+ altKey: e.altKey,
16950
+ ctrlKey: e.ctrlKey,
16951
+ metaKey: e.metaKey,
16952
+ shiftKey: e.shiftKey
16953
+ }
16917
16954
  });
16918
- if ((e.pointerType === "touch" || e.pointerType === "pen") && activePointers.size === 1) {
16955
+ dispatch2({ ...ev, stage: "press" });
16956
+ if ((e.pointerType === "touch" || e.pointerType === "pen") && held.size === 1) {
16919
16957
  cancelLongPress(e.pointerId);
16920
16958
  longPressTimers.set(
16921
16959
  e.pointerId,
@@ -16926,18 +16964,18 @@ function useGestureDispatcher(opts) {
16926
16964
  }, LONG_PRESS_MS)
16927
16965
  );
16928
16966
  }
16929
- if (activePointers.size >= 2) {
16967
+ if (held.size >= 2) {
16930
16968
  cancelAllLongPress();
16931
- for (const id of activePointers) bufferedDown.delete(id);
16932
- const { centroid, spread } = computeMultiTouchGeometry(pointerPositions);
16969
+ for (const p of held.values()) p.buffered = null;
16970
+ const { centroid, spread } = heldGeometry();
16933
16971
  if (!multiTouchStart) {
16934
- multiTouchStart = { fingers: activePointers.size, centroid: { ...centroid } };
16972
+ multiTouchStart = { fingers: held.size, centroid: { ...centroid } };
16935
16973
  } else {
16936
- multiTouchStart.fingers = activePointers.size;
16974
+ multiTouchStart.fingers = held.size;
16937
16975
  }
16938
16976
  const mt = {
16939
16977
  kind: "multitouch",
16940
- fingers: activePointers.size,
16978
+ fingers: held.size,
16941
16979
  altKey: e.altKey,
16942
16980
  ctrlKey: e.ctrlKey,
16943
16981
  metaKey: e.metaKey,
@@ -16949,30 +16987,25 @@ function useGestureDispatcher(opts) {
16949
16987
  }
16950
16988
  };
16951
16989
  const onPointerMove = (e) => {
16952
- if (activePointers.has(e.pointerId) && buttonsReportedFor.has(e.pointerId) && isMissedRelease(e)) {
16953
- onPointerUp(e);
16954
- return;
16955
- }
16956
16990
  routeAt(e.pointerId, e.clientX, e.clientY);
16957
- if (activePointers.has(e.pointerId)) {
16958
- pointerPositions.set(e.pointerId, { x: e.clientX, y: e.clientY });
16959
- }
16960
- const buffered = bufferedDown.get(e.pointerId);
16961
- if (buffered) {
16991
+ const rec = held.get(e.pointerId);
16992
+ if (rec) rec.pos = { x: e.clientX, y: e.clientY };
16993
+ const buffered = rec?.buffered;
16994
+ if (rec && buffered) {
16962
16995
  const dx = e.clientX - buffered.clientX;
16963
16996
  const dy = e.clientY - buffered.clientY;
16964
16997
  if (Math.hypot(dx, dy) >= DRAG_THRESHOLD_PX) {
16965
- bufferedDown.delete(e.pointerId);
16998
+ rec.buffered = null;
16966
16999
  cancelLongPress(e.pointerId);
16967
17000
  dispatch2(buffered.ev);
16968
17001
  }
16969
17002
  }
16970
- const mtGestureId = `multitouch-${activePointers.size}`;
16971
- if (activePointers.size >= 2 && dispatcherNow().inFlight().has(mtGestureId)) {
16972
- const { centroid, spread } = computeMultiTouchGeometry(pointerPositions);
17003
+ const mtGestureId = `multitouch-${held.size}`;
17004
+ if (held.size >= 2 && dispatcherNow().inFlight().has(mtGestureId)) {
17005
+ const { centroid, spread } = heldGeometry();
16973
17006
  const mtEv = {
16974
17007
  kind: "multitouch",
16975
- fingers: activePointers.size,
17008
+ fingers: held.size,
16976
17009
  altKey: e.altKey,
16977
17010
  ctrlKey: e.ctrlKey,
16978
17011
  metaKey: e.metaKey,
@@ -17044,7 +17077,7 @@ function useGestureDispatcher(opts) {
17044
17077
  }
17045
17078
  function resolveHoverCursor() {
17046
17079
  if (!canvas || !lastHover) return;
17047
- if (activePointers.size > 0 || dispatcherNow().inFlight().size > 0) {
17080
+ if (held.size > 0 || dispatcherNow().inFlight().size > 0) {
17048
17081
  applyHoverCursor(dispatcherNow().inFlightCursor());
17049
17082
  return;
17050
17083
  }
@@ -17092,6 +17125,10 @@ function useGestureDispatcher(opts) {
17092
17125
  if (!disposed) refreshHoverCursor();
17093
17126
  }, 0);
17094
17127
  };
17128
+ const onHoverMove = (e) => {
17129
+ if (held.has(e.pointerId)) return;
17130
+ onPointerMove(e);
17131
+ };
17095
17132
  const onHoverPointerLeave = () => {
17096
17133
  lastHover = null;
17097
17134
  paintedCursorRef.current?.()?.clearPointer();
@@ -17100,21 +17137,21 @@ function useGestureDispatcher(opts) {
17100
17137
  const onPointerUp = (e) => {
17101
17138
  routeAt(e.pointerId, e.clientX, e.clientY);
17102
17139
  cancelLongPress(e.pointerId);
17103
- const prevSize = activePointers.size;
17104
- activePointers.delete(e.pointerId);
17105
- buttonsReportedFor.delete(e.pointerId);
17106
- pointerPositions.delete(e.pointerId);
17107
- const staysUnderThreshold = bufferedDown.delete(e.pointerId);
17108
- if (prevSize >= 2 && activePointers.size < 2) {
17140
+ const prevSize = held.size;
17141
+ const rec = held.get(e.pointerId);
17142
+ held.delete(e.pointerId);
17143
+ const staysUnderThreshold = rec?.buffered != null;
17144
+ if (prevSize >= 2 && held.size < 2) {
17109
17145
  const mtGestureId = `multitouch-${prevSize}`;
17110
17146
  if (dispatcherNow().inFlight().has(mtGestureId)) {
17111
17147
  dispatcherNow().cancelAll("commit");
17112
17148
  }
17113
17149
  const start = multiTouchStart;
17114
17150
  if (start) {
17115
- const finalPositions = new Map(pointerPositions);
17116
- finalPositions.set(e.pointerId, { x: e.clientX, y: e.clientY });
17117
- const { centroid } = computeMultiTouchGeometry(finalPositions);
17151
+ const { centroid } = computeMultiTouchGeometry([
17152
+ ...[...held.values()].map((p) => p.pos),
17153
+ { x: e.clientX, y: e.clientY }
17154
+ ]);
17118
17155
  const dx = centroid.x - start.centroid.x;
17119
17156
  const dy = centroid.y - start.centroid.y;
17120
17157
  if (Math.hypot(dx, dy) <= TAP_THRESHOLD_PX) {
@@ -17131,8 +17168,7 @@ function useGestureDispatcher(opts) {
17131
17168
  multiTouchStart = null;
17132
17169
  }
17133
17170
  }
17134
- const downForClick = lastPointerDown.get(e.pointerId);
17135
- const movedDuringDrag = downForClick ? downForClick.clientX !== e.clientX || downForClick.clientY !== e.clientY : true;
17171
+ const movedDuringDrag = rec ? rec.down.clientX !== e.clientX || rec.down.clientY !== e.clientY : true;
17136
17172
  const hadDragInFlight = dispatcherNow().inFlight().has(pointerGestureId(e.pointerId)) && movedDuringDrag;
17137
17173
  const wUp = toWorld2(e.clientX, e.clientY);
17138
17174
  const ev = {
@@ -17148,8 +17184,7 @@ function useGestureDispatcher(opts) {
17148
17184
  shiftKey: e.shiftKey
17149
17185
  };
17150
17186
  dispatch2(ev);
17151
- const down = lastPointerDown.get(e.pointerId);
17152
- lastPointerDown.delete(e.pointerId);
17187
+ const down = rec?.down;
17153
17188
  if (!hadDragInFlight && staysUnderThreshold && down) {
17154
17189
  const wClick = toWorld2(e.clientX, e.clientY);
17155
17190
  const clickEv = {
@@ -17206,30 +17241,24 @@ function useGestureDispatcher(opts) {
17206
17241
  if (!disposed) refreshHoverCursor();
17207
17242
  }, 0);
17208
17243
  };
17209
- const onPointerCancel = (e) => {
17210
- routeAt(e.pointerId, e.clientX, e.clientY);
17211
- cancelLongPress(e.pointerId);
17212
- activePointers.delete(e.pointerId);
17213
- buttonsReportedFor.delete(e.pointerId);
17214
- pointerPositions.delete(e.pointerId);
17215
- lastPointerDown.delete(e.pointerId);
17216
- bufferedDown.delete(e.pointerId);
17244
+ const onPointerCancel = (pointerId) => {
17245
+ if (disposed) return;
17246
+ const rec = held.get(pointerId);
17247
+ if (!rec) return;
17248
+ held.delete(pointerId);
17249
+ routeAt(pointerId, rec.pos.x, rec.pos.y);
17250
+ cancelLongPress(pointerId);
17217
17251
  multiTouchStart = null;
17218
17252
  const ev = {
17219
17253
  kind: "pointercancel",
17220
- pointerId: e.pointerId,
17221
- altKey: e.altKey,
17222
- ctrlKey: e.ctrlKey,
17223
- metaKey: e.metaKey,
17224
- shiftKey: e.shiftKey
17254
+ pointerId,
17255
+ altKey: rec.down.altKey,
17256
+ ctrlKey: rec.down.ctrlKey,
17257
+ metaKey: rec.down.metaKey,
17258
+ shiftKey: rec.down.shiftKey
17225
17259
  };
17226
17260
  dispatch2(ev);
17227
- routeRelease(e.pointerId);
17228
- };
17229
- const onLostCapture = (e) => {
17230
- const pe = e;
17231
- if (!activePointers.has(pe.pointerId)) return;
17232
- onPointerCancel(pe);
17261
+ routeRelease(pointerId);
17233
17262
  };
17234
17263
  const onContextMenu = (e) => {
17235
17264
  e.preventDefault();
@@ -17317,10 +17346,7 @@ function useGestureDispatcher(opts) {
17317
17346
  canvas?.addEventListener("pointerleave", onHoverPointerLeave);
17318
17347
  canvas?.addEventListener("wheel", onWheel, { passive: false });
17319
17348
  canvas?.addEventListener("pointerdown", onPointerDown);
17320
- canvas?.addEventListener("pointermove", onPointerMove);
17321
- canvas?.addEventListener("pointerup", onPointerUp);
17322
- canvas?.addEventListener("pointercancel", onPointerCancel);
17323
- canvas?.addEventListener(LOST_CAPTURE_EVENT, onLostCapture);
17349
+ canvas?.addEventListener("pointermove", onHoverMove);
17324
17350
  canvas?.addEventListener("contextmenu", onContextMenu);
17325
17351
  canvas?.addEventListener("dragenter", onDragOver);
17326
17352
  canvas?.addEventListener("dragover", onDragOver);
@@ -17338,10 +17364,7 @@ function useGestureDispatcher(opts) {
17338
17364
  canvas?.removeEventListener("pointerleave", onHoverPointerLeave);
17339
17365
  canvas?.removeEventListener("wheel", onWheel);
17340
17366
  canvas?.removeEventListener("pointerdown", onPointerDown);
17341
- canvas?.removeEventListener("pointermove", onPointerMove);
17342
- canvas?.removeEventListener("pointerup", onPointerUp);
17343
- canvas?.removeEventListener("pointercancel", onPointerCancel);
17344
- canvas?.removeEventListener(LOST_CAPTURE_EVENT, onLostCapture);
17367
+ canvas?.removeEventListener("pointermove", onHoverMove);
17345
17368
  canvas?.removeEventListener("contextmenu", onContextMenu);
17346
17369
  canvas?.removeEventListener("dragenter", onDragOver);
17347
17370
  canvas?.removeEventListener("dragover", onDragOver);
@@ -17352,6 +17375,8 @@ function useGestureDispatcher(opts) {
17352
17375
  clearHoverCursor();
17353
17376
  cancelAllLongPress();
17354
17377
  disposed = true;
17378
+ for (const p of held.values()) p.session.cancel();
17379
+ held.clear();
17355
17380
  for (const d of allDispatchers()) d.cancelAll("cancel");
17356
17381
  };
17357
17382
  }, [enabled, keyboard, canvasRef]);
@@ -28232,7 +28257,6 @@ function SceneCanvasInner(props, ref) {
28232
28257
  () => isSerialized(sceneInput) ? sceneFromJSON(sceneInput, {}) : null
28233
28258
  );
28234
28259
  const scene = bakedScene ?? sceneInput;
28235
- useSyncExternalStore(scene.subscribe, scene.getVersion, scene.getVersion);
28236
28260
  const { view: viewProp, onViewChange: onViewChangeProp, defaultView, ...restProps } = rest;
28237
28261
  const internalCanvasRef = useRef(null);
28238
28262
  const canvasApiRef = useRef(null);
@@ -28263,6 +28287,9 @@ function SceneCanvasInner(props, ref) {
28263
28287
  useEffect(() => scene.overrides.subscribe(() => {
28264
28288
  canvasApiRef.current?.requestRedraw?.();
28265
28289
  }), [scene]);
28290
+ useEffect(() => scene.subscribe(() => {
28291
+ canvasApiRef.current?.requestRedraw?.();
28292
+ }), [scene]);
28266
28293
  const currentViewRef = useRef(
28267
28294
  viewProp ?? defaultView ?? { x: 0, y: 0, scale: { x: 1, y: 1 } }
28268
28295
  );
@@ -29965,6 +29992,6 @@ function oklchToOklab(L, C, h) {
29965
29992
  return [L, C * Math.cos(h), C * Math.sin(h)];
29966
29993
  }
29967
29994
 
29968
- export { ArrowIcon, EllipseIcon, FALLBACK_FIT_VIEW, LineIcon, MinimapCanvas, PATH_C, PATH_L, PATH_M, PATH_Q, PATH_Z, PathBuilder, PencilIcon, RectIcon, SCRIPT_METRICS, SceneCanvas, SceneViewCanvas, SelectIcon, TextIcon, UnknownIcon, WeaselProvider, asNodeId, boundsOfPath, buildSceneViewCommands, computeFitView, computeIndicatorCommand, createScene, eligibleContribution, ellipsePath, evaluateEnabled, getMarker, getPaintKind, isBuiltinToolPref, linePath, markerDrawCommands, oklabToSrgbU8, oklchToOklab, openPointerSession, rectPath, renderSceneToCanvas, renderSceneToPixels, resolveStrokeWidth, rgbaToHex, sceneFromJSON, textCommand, tileGeometry, useActionsRegistry, useActiveToolContext, useOptionalDepRegistry, useVisibleRaf };
29969
- //# sourceMappingURL=chunk-DG2IFMLA.js.map
29970
- //# sourceMappingURL=chunk-DG2IFMLA.js.map
29995
+ export { ArrowIcon, EllipseIcon, FALLBACK_FIT_VIEW, LineIcon, MinimapCanvas, PATH_C, PATH_L, PATH_M, PATH_Q, PATH_Z, PathBuilder, PencilIcon, RectIcon, SCRIPT_METRICS, SceneCanvas, SceneViewCanvas, SelectIcon, TextIcon, UnknownIcon, WeaselProvider, asNodeId, boundsOfPath, buildSceneViewCommands, computeFitView, computeIndicatorCommand, createScene, eligibleContribution, ellipsePath, evaluateEnabled, getMarker, getPaintKind, isBuiltinToolPref, linePath, markerDrawCommands, oklabToSrgbU8, oklchToOklab, openPointerSession, rectPath, renderSceneToCanvas, renderSceneToPixels, resolveStrokeWidth, rgbaToHex, sceneFromJSON, startThresholdDrag, textCommand, tileGeometry, useActionsRegistry, useActiveToolContext, useOptionalDepRegistry, useVisibleRaf };
29996
+ //# sourceMappingURL=chunk-54ZWZ5FQ.js.map
29997
+ //# sourceMappingURL=chunk-54ZWZ5FQ.js.map