@weasel-js/labkit 1.6.1 → 1.7.0

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 (162) hide show
  1. package/dist/_dts/{CanvasStackContext-Wo6OwIVM.d.ts → CanvasStackContext-D2jnIwfk.d.ts} +1 -1
  2. package/dist/_dts/{LayerList.d-BoELAMsM.d.ts → LayerList.d-DiuEArKq.d.ts} +2 -2
  3. package/dist/_dts/PrefsRow.d-TOZ7BgD9.d.ts +79 -0
  4. package/dist/_dts/PropertyPanel.d-D-1paCbE.d.ts +141 -0
  5. package/dist/_dts/{Select.d-Cr8-zoup.d.ts → Select.d-Bensr_MT.d.ts} +11 -1
  6. package/dist/_dts/{Stage-DWBBi8IU.d.ts → Stage-CCWfQQWM.d.ts} +58 -18
  7. package/dist/_dts/index-B2Yj5aA0.d.ts +274 -0
  8. package/dist/_dts/{index-CKyX0ME_.d.ts → index-CsYqUHD3.d.ts} +2 -2
  9. package/dist/_dts/{types-DTuViBvc.d.ts → types-CRPSGFAp.d.ts} +13 -4
  10. package/dist/_dts/{types-B7yBTTF9.d.ts → types-CSm9jgol.d.ts} +2 -2
  11. package/dist/_dts/{useTrialState-CMaV6UD4.d.ts → useTrialState-CTZPgeZ7.d.ts} +1 -1
  12. package/dist/canvas/index.d.ts +6 -6
  13. package/dist/canvas/index.js +2 -2
  14. package/dist/chrome/index.d.ts +5 -5
  15. package/dist/chrome/index.js +8 -8
  16. package/dist/{chunk-QGMOA2YE.js → chunk-275JRRVD.js} +67 -70
  17. package/dist/chunk-275JRRVD.js.map +1 -0
  18. package/dist/{chunk-KHK5FGER.js → chunk-4LJSC7MB.js} +8 -10
  19. package/dist/chunk-4LJSC7MB.js.map +1 -0
  20. package/dist/{chunk-SLAQPUI4.js → chunk-7BO7HNGF.js} +5 -5
  21. package/dist/{chunk-SLAQPUI4.js.map → chunk-7BO7HNGF.js.map} +1 -1
  22. package/dist/chunk-CZZPXUOU.js +3 -0
  23. package/dist/{chunk-SBXNQW4G.js.map → chunk-CZZPXUOU.js.map} +1 -1
  24. package/dist/{chunk-6FLXL3I7.js → chunk-FMK7UQ6V.js} +19 -4
  25. package/dist/chunk-FMK7UQ6V.js.map +1 -0
  26. package/dist/{chunk-O6FFFOHS.js → chunk-FZ7YFQN7.js} +16 -8
  27. package/dist/chunk-FZ7YFQN7.js.map +1 -0
  28. package/dist/{chunk-GHGO52SO.js → chunk-GOZLNM4L.js} +5 -5
  29. package/dist/{chunk-GHGO52SO.js.map → chunk-GOZLNM4L.js.map} +1 -1
  30. package/dist/{chunk-4TT3PNPR.js → chunk-I5DUQ5HM.js} +33 -36
  31. package/dist/chunk-I5DUQ5HM.js.map +1 -0
  32. package/dist/{chunk-NEXR37YJ.js → chunk-J7OWWTCW.js} +4 -5
  33. package/dist/chunk-J7OWWTCW.js.map +1 -0
  34. package/dist/{chunk-IRTGUQ5O.js → chunk-KMJ7RWD3.js} +16 -6
  35. package/dist/chunk-KMJ7RWD3.js.map +1 -0
  36. package/dist/{chunk-S4NCI32V.js → chunk-M7HP3FTK.js} +4 -4
  37. package/dist/{chunk-S4NCI32V.js.map → chunk-M7HP3FTK.js.map} +1 -1
  38. package/dist/chunk-MIM5R4ZT.js +14972 -0
  39. package/dist/chunk-MIM5R4ZT.js.map +1 -0
  40. package/dist/{chunk-ASOK76ZH.js → chunk-T5IBSPAM.js} +59 -26
  41. package/dist/chunk-T5IBSPAM.js.map +1 -0
  42. package/dist/{chunk-DWMSB4CA.js → chunk-UNAZSLWE.js} +82 -16
  43. package/dist/chunk-UNAZSLWE.js.map +1 -0
  44. package/dist/{chunk-TJ77A4A3.js → chunk-Y23G2VZL.js} +5 -9
  45. package/dist/chunk-Y23G2VZL.js.map +1 -0
  46. package/dist/{chunk-HKV7LRHY.js → chunk-YT75VYRD.js} +4 -4
  47. package/dist/{chunk-HKV7LRHY.js.map → chunk-YT75VYRD.js.map} +1 -1
  48. package/dist/{chunk-CGHF6RZV.js → chunk-ZIFPHIWZ.js} +9 -7
  49. package/dist/chunk-ZIFPHIWZ.js.map +1 -0
  50. package/dist/config/index.d.ts +16 -9
  51. package/dist/config/index.js +4 -4
  52. package/dist/controls/index.d.ts +2 -2
  53. package/dist/controls/index.js +5 -5
  54. package/dist/dragdrop/index.d.ts +3 -3
  55. package/dist/index.d.ts +263 -24
  56. package/dist/index.js +376 -237
  57. package/dist/index.js.map +1 -1
  58. package/dist/layers/index.d.ts +4 -4
  59. package/dist/layers/index.js +2 -2
  60. package/dist/loupe/index.d.ts +4 -4
  61. package/dist/loupe/index.js +2 -2
  62. package/dist/overview/index.d.ts +2 -2
  63. package/dist/overview/index.js +9 -8
  64. package/dist/overview/index.js.map +1 -1
  65. package/dist/passthrough/weasel-ui.d.ts +208 -38
  66. package/dist/passthrough/weasel-ui.js +3 -3
  67. package/dist/primitives/index.d.ts +3 -178
  68. package/dist/primitives/index.js +6 -6
  69. package/dist/state/index.d.ts +5 -5
  70. package/dist/state/index.js +4 -4
  71. package/dist/styles.css +91 -83
  72. package/dist/undo/index.d.ts +3 -3
  73. package/package.json +13 -12
  74. package/src/annotations/AnnotationOverlay.tsx +2 -2
  75. package/src/annotations/Annotations.less +0 -10
  76. package/src/annotations/MarkList.tsx +4 -8
  77. package/src/annotations/paint.test.ts +3 -14
  78. package/src/annotations/paint.ts +3 -19
  79. package/src/annotations/svgNodes.test.ts +6 -9
  80. package/src/annotations/svgNodes.ts +3 -3
  81. package/src/canvas/AGENTS.md +1 -0
  82. package/src/canvas/CameraInput.tsx +44 -33
  83. package/src/canvas/CanvasStack.tsx +6 -1
  84. package/src/canvas/LinkedCursor.less +1 -1
  85. package/src/canvas/Stage.test.tsx +33 -4
  86. package/src/canvas/Stage.tsx +6 -1
  87. package/src/canvas/cameraRegistry.test.ts +55 -0
  88. package/src/canvas/cameraRegistry.ts +86 -0
  89. package/src/canvas/cameraZoom.test.ts +46 -0
  90. package/src/canvas/cameraZoom.ts +24 -0
  91. package/src/canvas/index.ts +14 -2
  92. package/src/canvas/sharedScope.test.tsx +94 -0
  93. package/src/chrome/ChromeRegions.stories.tsx +1 -0
  94. package/src/chrome/regions/PaletteRegion.less +0 -7
  95. package/src/chrome/regions/SidebarRegion.less +12 -2
  96. package/src/config/builder.test.ts +2 -1
  97. package/src/config/builder.ts +12 -5
  98. package/src/config/fromConfigField.test.ts +14 -0
  99. package/src/config/fromConfigField.ts +18 -4
  100. package/src/config/path.ts +2 -5
  101. package/src/config/resolve.ts +4 -0
  102. package/src/config/types.ts +13 -9
  103. package/src/controls/ControlPanel.less +1 -1
  104. package/src/controls/ControlPanel.stories.tsx +3 -2
  105. package/src/controls/ControlPanel.test.tsx +64 -11
  106. package/src/controls/ControlPanel.tsx +52 -2
  107. package/src/index.ts +15 -1
  108. package/src/lab/Lab.tsx +83 -72
  109. package/src/lab/{LabFit.stories.less → LabFit.browser.test.less} +1 -1
  110. package/src/lab/{LabFit.stories.tsx → LabFit.browser.test.tsx} +41 -63
  111. package/src/lab/LabFullChrome.stories.tsx +1 -0
  112. package/src/lab/LabHeader.test.tsx +24 -14
  113. package/src/lab/LabHeader.tsx +11 -12
  114. package/src/lab/LabShell.less +8 -17
  115. package/src/lab/LabSwitcher.less +6 -6
  116. package/src/lab/LabZoom.test.tsx +223 -0
  117. package/src/lab/LabZoom.tsx +170 -0
  118. package/src/lab/index.ts +1 -0
  119. package/src/loupe/LoupeGestures.tsx +1 -1
  120. package/src/overview/TrialOverview.tsx +7 -5
  121. package/src/passthrough/weasel-ui.test.ts +2 -0
  122. package/src/passthrough/weasel-ui.ts +16 -4
  123. package/src/primitives/FloatingPanel.test.tsx +11 -0
  124. package/src/primitives/FloatingPanel.tsx +2 -5
  125. package/src/primitives/JobProgress.less +1 -1
  126. package/src/primitives/Legend.stories.tsx +1 -0
  127. package/src/primitives/Readout.browser.test.tsx +137 -0
  128. package/src/primitives/Readout.less +12 -0
  129. package/src/primitives/Readout.stories.tsx +58 -0
  130. package/src/primitives/Readout.test.tsx +93 -0
  131. package/src/primitives/Readout.tsx +56 -0
  132. package/src/primitives/index.ts +2 -0
  133. package/src/specimen/Specimen.stories.tsx +1 -0
  134. package/src/specimen/Specimen.tsx +2 -2
  135. package/src/state/Persistence.browser.test.tsx +47 -0
  136. package/src/state/store.test.ts +5 -1
  137. package/src/state/usePersistedState.test.tsx +1 -1
  138. package/src/styles.less +1 -0
  139. package/src/theme/Interstellar.stories.tsx +3 -1
  140. package/src/theme/base.less +21 -47
  141. package/src/theme/interstellar.test.ts +1 -1
  142. package/src/theme/interstellar.theme.json +10 -3
  143. package/src/trial/Trial.less +0 -13
  144. package/src/trial/Trial.tsx +12 -6
  145. package/src/trial/TrialChrome.tsx +21 -3
  146. package/dist/_dts/PrefsRow.d-DFpPIeIC.d.ts +0 -39
  147. package/dist/_dts/PropertyField.d-D0ndfIIt.d.ts +0 -404
  148. package/dist/chunk-4TT3PNPR.js.map +0 -1
  149. package/dist/chunk-6FLXL3I7.js.map +0 -1
  150. package/dist/chunk-ASOK76ZH.js.map +0 -1
  151. package/dist/chunk-CGHF6RZV.js.map +0 -1
  152. package/dist/chunk-DWMSB4CA.js.map +0 -1
  153. package/dist/chunk-IRTGUQ5O.js.map +0 -1
  154. package/dist/chunk-KHK5FGER.js.map +0 -1
  155. package/dist/chunk-NEXR37YJ.js.map +0 -1
  156. package/dist/chunk-O6FFFOHS.js.map +0 -1
  157. package/dist/chunk-QGMOA2YE.js.map +0 -1
  158. package/dist/chunk-SBXNQW4G.js +0 -3
  159. package/dist/chunk-TJ77A4A3.js.map +0 -1
  160. package/dist/chunk-TYN6MLXX.js +0 -13864
  161. package/dist/chunk-TYN6MLXX.js.map +0 -1
  162. package/src/state/Persistence.stories.tsx +0 -75
@@ -1,8 +1,8 @@
1
- export { L as LayerList, a as LayerListItem, b as LayerListProps, c as LayerMove, m as moveLayers } from '../_dts/LayerList.d-BoELAMsM.js';
2
- export { L as LayerCapability, a as LayerDescriptor } from '../_dts/types-B7yBTTF9.js';
1
+ export { L as LayerList, a as LayerListItem, b as LayerListProps, c as LayerMove, m as moveLayers } from '../_dts/LayerList.d-DiuEArKq.js';
2
+ export { L as LayerCapability, a as LayerDescriptor } from '../_dts/types-CSm9jgol.js';
3
3
  import 'react';
4
- import '../_dts/PrefsRow.d-DFpPIeIC.js';
4
+ import '../_dts/PrefsRow.d-TOZ7BgD9.js';
5
5
  import '@weasel-js/theme';
6
6
  import '@weasel-js/core';
7
- import '../_dts/types-DTuViBvc.js';
7
+ import '../_dts/types-CRPSGFAp.js';
8
8
  import '../_dts/types-DJ79Tg5J.js';
@@ -1,5 +1,5 @@
1
1
  import '../chunk-2RVCB2PT.js';
2
- export { D as LayerList, S2 as moveLayers } from '../chunk-TYN6MLXX.js';
3
- import '../chunk-QGMOA2YE.js';
2
+ export { E3 as LayerList, x3 as moveLayers } from '../chunk-MIM5R4ZT.js';
3
+ import '../chunk-275JRRVD.js';
4
4
  //# sourceMappingURL=index.js.map
5
5
  //# sourceMappingURL=index.js.map
@@ -1,14 +1,14 @@
1
- import { ai as LoupePoint, ah as LoupeMode, aj as LoupeRenderArgs, am as ResolvedLoupe } from '../_dts/types-B7yBTTF9.js';
1
+ import { ai as LoupePoint, ah as LoupeMode, aj as LoupeRenderArgs, am as ResolvedLoupe } from '../_dts/types-CSm9jgol.js';
2
2
  import { WorldFrame, WorldSpec, ViewportSize } from '../canvas/index.js';
3
3
  import { ViewTransform } from '../index.js';
4
- export { ae as LOUPE_DEFAULTS, af as LoupeCapability, ag as LoupeDeclaration, aK as resolveLoupe } from '../_dts/types-B7yBTTF9.js';
4
+ export { ae as LOUPE_DEFAULTS, af as LoupeCapability, ag as LoupeDeclaration, aK as resolveLoupe } from '../_dts/types-CSm9jgol.js';
5
5
  import * as react from 'react';
6
6
  import { RefObject, ReactNode } from 'react';
7
7
  import { CanvasStackSurface, CanvasLayerDescriptor } from '../canvas/index.js';
8
8
  import { Action } from '@weasel-js/core';
9
- import '../_dts/PrefsRow.d-DFpPIeIC.js';
9
+ import '../_dts/PrefsRow.d-TOZ7BgD9.js';
10
10
  import '@weasel-js/theme';
11
- import '../_dts/types-DTuViBvc.js';
11
+ import '../_dts/types-CRPSGFAp.js';
12
12
  import '../_dts/types-DJ79Tg5J.js';
13
13
 
14
14
  /** Props for `<CanvasLoupe>`. */
@@ -1,7 +1,7 @@
1
- export { CanvasLoupe, DomLoupe, LOUPE_DEFAULTS, LOUPE_MAGNIFY_ID, LOUPE_PEEK_ID, LoupeBubble, LoupeGestures, TrialLoupe, createLoupeActions, drawCanvasLens, lensCamera, lensSourceRect, resolveLoupe, sampleStack, useLoupe } from '../chunk-S4NCI32V.js';
1
+ export { CanvasLoupe, DomLoupe, LOUPE_DEFAULTS, LOUPE_MAGNIFY_ID, LOUPE_PEEK_ID, LoupeBubble, LoupeGestures, TrialLoupe, createLoupeActions, drawCanvasLens, lensCamera, lensSourceRect, resolveLoupe, sampleStack, useLoupe } from '../chunk-M7HP3FTK.js';
2
2
  import '../chunk-JVBYV6TL.js';
3
3
  import '../chunk-AWQG7FCC.js';
4
- import '../chunk-DWMSB4CA.js';
4
+ import '../chunk-UNAZSLWE.js';
5
5
  import '../chunk-24W5VEJW.js';
6
6
  import '../chunk-CQLQPQ4P.js';
7
7
  //# sourceMappingURL=index.js.map
@@ -3,9 +3,9 @@ import { ReactNode } from 'react';
3
3
  import { ViewportSize } from '../canvas/index.js';
4
4
  import { FloatingPanelProps } from '../index.js';
5
5
  import '@weasel-js/core';
6
- import '../_dts/PrefsRow.d-DFpPIeIC.js';
6
+ import '../_dts/PrefsRow.d-TOZ7BgD9.js';
7
7
  import '@weasel-js/theme';
8
- import '../_dts/types-DTuViBvc.js';
8
+ import '../_dts/types-CRPSGFAp.js';
9
9
  import '../_dts/types-DJ79Tg5J.js';
10
10
  import 'windease';
11
11
 
@@ -1,12 +1,12 @@
1
- import { markSvgNodes } from '../chunk-KHK5FGER.js';
1
+ import { markSvgNodes } from '../chunk-4LJSC7MB.js';
2
2
  import { useAnnotationsOptional } from '../chunk-3RY6WL5T.js';
3
- import { FloatingPanel } from '../chunk-NEXR37YJ.js';
3
+ import { FloatingPanel } from '../chunk-J7OWWTCW.js';
4
4
  import '../chunk-RWNDDKOH.js';
5
- import { CameraContext, fromCameraView, pointerElsewhere, usePublishPointer } from '../chunk-DWMSB4CA.js';
5
+ import { CameraContext, fromCameraView, pointerElsewhere, usePublishPointer } from '../chunk-UNAZSLWE.js';
6
6
  import '../chunk-24W5VEJW.js';
7
7
  import { CanvasStackContext } from '../chunk-CQLQPQ4P.js';
8
8
  import '../chunk-2YILQ7Y5.js';
9
- import { serializeSvg } from '../chunk-QGMOA2YE.js';
9
+ import { serializeSvg } from '../chunk-275JRRVD.js';
10
10
  import { usePointerPosition, crosshairRects, DepRegistryProvider, ActionsProvider, ActiveToolContextProvider, useActionsRegistry, useDepSource, minimapCenterAction, minimapPanAction, useGestureDispatcher, MINIMAP_CENTER, MINIMAP_PAN } from '@weasel-js/core';
11
11
  import { useContext, useMemo, useRef, useLayoutEffect, useEffect, useReducer } from 'react';
12
12
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -123,10 +123,11 @@ function Overview({
123
123
  }) {
124
124
  const size = useMemo(() => ({ width, height }), [width, height]);
125
125
  const content = bounds ? toLocalRect(bounds, camera.frame) : camera.content;
126
- const contentKey = content ? `${content.x},${content.y},${content.width},${content.height}` : "";
126
+ const framed = content !== null && content !== void 0;
127
+ const { x = 0, y = 0, width: w = 0, height: h = 0 } = content ?? {};
127
128
  const fit = useMemo(
128
- () => content ? fitRect(content, size) : { x: 0, y: 0, scale: { x: 1, y: 1 } },
129
- [contentKey, size]
129
+ () => framed ? fitRect({ x, y, width: w, height: h }, size) : { x: 0, y: 0, scale: { x: 1, y: 1 } },
130
+ [framed, x, y, w, h, size]
130
131
  );
131
132
  const boxRef = useRef(null);
132
133
  return /* @__PURE__ */ jsxs(
@@ -256,7 +257,7 @@ function OverviewDispatch({
256
257
  canvasRef: boxRef,
257
258
  // Always present: `OverviewInput` mounts the provider directly above.
258
259
  actions: registry,
259
- toolsById: TOOLS_BY_ID,
260
+ entriesById: TOOLS_BY_ID,
260
261
  clientToWorld: clientToLocal,
261
262
  keyboard: false,
262
263
  channels: CHANNELS
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/overview/OverviewMarks.tsx","../../src/overview/TrialOverview.tsx"],"names":["jsx","useEffect"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Every annotation target's marks, drawn read-only on the overview through the\n * export's own vector path: `markSvgNodes`, then `serializeSvg`.\n */\nimport type { View } from '@weasel-js/core';\nimport { serializeSvg } from '@weasel-js/svg';\nimport { type CSSProperties, type RefObject, useEffect, useReducer } from 'react';\nimport { useAnnotationsOptional } from '../annotations/AnnotationsContext';\nimport { markSvgNodes } from '../annotations/svgNodes';\nimport type { AnnotationsApi } from '../annotations/types';\nimport type { CameraContextValue } from '../canvas/CameraInput';\n\n/** A target's box, in the camera's frame-local units. */\ninterface LocalRect {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\n/** Where `el` sits in the camera's frame-local units: its screen rect,\n * measured against the camera's element, through the camera. */\nfunction localRectOf(el: HTMLElement, camera: CameraContextValue): LocalRect | null {\n const host = camera.element();\n if (!host) return null;\n const r = el.getBoundingClientRect();\n const h = host.getBoundingClientRect();\n const v = camera.view.get();\n return {\n x: (r.left - h.left) / v.scale.x + v.x,\n y: (r.top - h.top) / v.scale.y + v.y,\n w: r.width / v.scale.x,\n h: r.height / v.scale.y,\n };\n}\n\n/** The element a target's marks sit on. The capability's targets carry their\n * `ref`; the store's type names only the half it reads. */\nfunction elementOf(target: object): HTMLElement | null {\n return (target as { ref?: RefObject<HTMLElement | null> }).ref?.current ?? null;\n}\n\nfunction markupOf(api: AnnotationsApi, target: string, content: { w: number; h: number }): string {\n const painted = api.paintedMarks(target);\n if (painted.length === 0) return '';\n const nodes = painted.flatMap(({ mark, style }) => markSvgNodes(mark, content, style));\n return serializeSvg(nodes, { viewBox: { x: 0, y: 0, width: content.w, height: content.h } });\n}\n\n/** Props for `<OverviewMarks>`. */\nexport interface OverviewMarksProps {\n fit: View;\n camera: CameraContextValue;\n}\n\n/**\n * The marks of every target in the annotations store in scope, placed where\n * each target's element sits on the stage. Draws nothing outside an annotating\n * trial, and takes no input.\n */\nexport function OverviewMarks({ fit, camera }: OverviewMarksProps) {\n const api = useAnnotationsOptional();\n const [, redraw] = useReducer((n: number) => n + 1, 0);\n useEffect(() => api?.subscribe(redraw), [api]);\n if (!api) return null;\n const s = fit.scale.x;\n return (\n <>\n {api.targets().map((t) => {\n const el = elementOf(t);\n const box = el ? localRectOf(el, camera) : null;\n const markup = box ? markupOf(api, t.id, t.content) : '';\n if (!box || !markup) return null;\n const place = {\n ['--lk-overview-mx' as string]: `${(box.x - fit.x) * s}px`,\n ['--lk-overview-my' as string]: `${(box.y - fit.y) * s}px`,\n ['--lk-overview-mw' as string]: `${box.w * s}px`,\n ['--lk-overview-mh' as string]: `${box.h * s}px`,\n } as CSSProperties;\n return (\n <div\n key={t.id}\n className=\"lk-overview__marks\"\n style={place}\n data-target={t.id}\n // biome-ignore lint/security/noDangerouslySetInnerHtml: the export's SVG serializer is the one vector path marks have; re-deriving React nodes would be a second.\n dangerouslySetInnerHTML={{ __html: markup }}\n />\n );\n })}\n </>\n );\n}\n","/**\n * `<TrialOverview>` — the whole of a trial's content at a glance, in a panel\n * that floats over the stage: the visible rect, a crosshair where the pointer\n * is on the stage, and a press or drag that moves the stage's camera there.\n *\n * It is the labkit form of core's minimap contribution: the same\n * `minimap.center` / `minimap.pan` actions, run on a dispatcher of its own with\n * the trial's camera as `rootView`, and the same crosshair geometry.\n */\nimport {\n ActionsProvider,\n ActiveToolContextProvider,\n crosshairRects,\n DepRegistryProvider,\n MINIMAP_CENTER,\n MINIMAP_PAN,\n minimapCenterAction,\n minimapPanAction,\n type Tool,\n useActionsRegistry,\n useDepSource,\n useGestureDispatcher,\n usePointerPosition,\n type View,\n type ViewApi,\n} from '@weasel-js/core';\nimport {\n type CSSProperties,\n type ReactNode,\n type RefObject,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n} from 'react';\nimport {\n CameraContext,\n type CameraContextValue,\n pointerElsewhere,\n usePublishPointer,\n} from '../canvas/CameraInput';\nimport { CanvasStackContext } from '../canvas/CanvasStackContext';\nimport { fromCameraView } from '../canvas/cameraView';\nimport type { ViewportSize, WorldFrame } from '../canvas/worldSpec';\nimport { FloatingPanel, type FloatingPanelProps } from '../primitives/FloatingPanel';\nimport { OverviewMarks } from './OverviewMarks';\n\n/** The view id the overview publishes its pointer under. */\nexport const OVERVIEW_VIEW_ID = 'overview';\n\n/** A rect in the instrument's world. */\nexport interface OverviewBounds {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/** What an overview's `render` is handed. */\nexport interface OverviewRenderArgs {\n /** The content's own size in CSS pixels, at zoom 1 — lay out at this size\n * and the overview scales it to fit. */\n size: ViewportSize;\n}\n\n/** Props for `<TrialOverview>`. */\nexport interface TrialOverviewProps {\n /** The overview box, in CSS pixels. */\n width: number;\n height: number;\n /**\n * DOM content for the overview, laid out at the content's own size — for a\n * `stage` instrument, typically a lighter copy of what its `render` draws.\n * Never the instrument's own `render`: its effects would run twice. A canvas\n * instrument omits it, and the overview redraws the canvas's layers.\n */\n render?: (args: OverviewRenderArgs) => ReactNode;\n /** What to frame, in the instrument's world. Defaults to a stage's content\n * rect; a canvas instrument, whose world has no edge, names one. */\n bounds?: OverviewBounds;\n /** Panel title. */\n title?: string;\n anchor?: FloatingPanelProps['anchor'];\n persist?: string;\n className?: string;\n}\n\nconst PADDING = 6;\nconst OVERVIEW_INPUT: Tool = {\n id: 'overview',\n eligibility: { always: true },\n bindings: [\n { spec: { kind: 'pointerDown' }, actionId: MINIMAP_CENTER },\n { spec: { kind: 'drag' }, actionId: MINIMAP_PAN },\n ],\n};\nconst TOOLS_BY_ID: ReadonlyMap<string, Tool> = new Map([[OVERVIEW_INPUT.id, OVERVIEW_INPUT]]);\nconst CHANNELS = { wheel: false, pinch: false, contextMenu: false, ingest: false } as const;\n\n/** A world rect as a frame-local one. */\nfunction toLocalRect(b: OverviewBounds, frame: WorldFrame): OverviewBounds {\n if (frame.yDir === 1) return b;\n return { x: b.x, y: -(b.y + b.height), width: b.width, height: b.height };\n}\n\n/** The camera that fits `rect` into `size`, `PADDING` in from every edge. */\nfunction fitRect(rect: OverviewBounds, size: ViewportSize): View {\n const s = Math.min(\n Math.max(1, size.width - 2 * PADDING) / Math.max(rect.width, 1e-9),\n Math.max(1, size.height - 2 * PADDING) / Math.max(rect.height, 1e-9),\n );\n return {\n x: rect.x + rect.width / 2 - size.width / (2 * s),\n y: rect.y + rect.height / 2 - size.height / (2 * s),\n scale: { x: s, y: s },\n };\n}\n\n/** A canvas's 2D context sized to `size` at the device pixel ratio. */\nfunction prepare(\n canvas: HTMLCanvasElement | null,\n size: ViewportSize,\n): CanvasRenderingContext2D | null {\n const ctx = canvas?.getContext('2d') ?? null;\n if (!canvas || !ctx) return null;\n const dpr = window.devicePixelRatio || 1;\n const w = Math.round(size.width * dpr);\n const h = Math.round(size.height * dpr);\n if (canvas.width !== w) canvas.width = w;\n if (canvas.height !== h) canvas.height = h;\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n ctx.clearRect(0, 0, size.width, size.height);\n return ctx;\n}\n\nfunction cssVar(el: Element | null, name: string, fallback: string): string {\n if (!el) return fallback;\n return getComputedStyle(el).getPropertyValue(name).trim() || fallback;\n}\n\n/**\n * A trial's overview. Mount it from an instrument's `render` (a canvas\n * instrument) or `stage.overlay` (a DOM stage) — anywhere inside the trial's\n * camera.\n */\nexport function TrialOverview(props: TrialOverviewProps) {\n const camera = useContext(CameraContext);\n if (!camera) return null;\n return <Overview {...props} camera={camera} />;\n}\n\nfunction Overview({\n width,\n height,\n render,\n bounds,\n title = 'Overview',\n anchor = 'bottom-left',\n persist,\n className,\n camera,\n}: TrialOverviewProps & { camera: CameraContextValue }) {\n const size = useMemo(() => ({ width, height }), [width, height]);\n const content = bounds ? toLocalRect(bounds, camera.frame) : camera.content;\n const contentKey = content ? `${content.x},${content.y},${content.width},${content.height}` : '';\n // biome-ignore lint/correctness/useExhaustiveDependencies: `content` is rebuilt every render; its numbers, in `contentKey`, are what the fit depends on.\n const fit = useMemo(\n () => (content ? fitRect(content, size) : { x: 0, y: 0, scale: { x: 1, y: 1 } }),\n [contentKey, size],\n );\n const boxRef = useRef<HTMLDivElement | null>(null);\n\n return (\n <FloatingPanel\n anchor={anchor}\n className={className ? `lk-overview ${className}` : 'lk-overview'}\n {...(persist ? { persist } : {})}\n >\n <div className=\"lk-overview__title\">{title}</div>\n <div ref={boxRef} className=\"lk-overview__box\" data-no-drag style={boxVars(size)}>\n {render && content ? (\n <div className=\"lk-overview__content\" style={contentVars(fit, content)}>\n {render({ size: { width: content.width, height: content.height } })}\n </div>\n ) : null}\n {render ? null : <LayersCanvas fit={fit} size={size} frame={camera.frame} />}\n <OverviewMarks fit={fit} camera={camera} />\n <ChromeCanvas fit={fit} size={size} camera={camera} />\n <OverviewInput boxRef={boxRef} fit={fit} camera={camera} />\n </div>\n </FloatingPanel>\n );\n}\n\n// The box's size and the content's camera change with props, and a transform\n// has nowhere to live but the element's own style: set as custom properties\n// the stylesheet reads, as `<Stage>` does.\nfunction boxVars(size: ViewportSize): CSSProperties {\n return {\n ['--lk-overview-w' as string]: `${size.width}px`,\n ['--lk-overview-h' as string]: `${size.height}px`,\n } as CSSProperties;\n}\n\nfunction contentVars(fit: View, content: OverviewBounds): CSSProperties {\n const s = fit.scale.x;\n return {\n ['--lk-overview-x' as string]: `${(content.x - fit.x) * s}px`,\n ['--lk-overview-y' as string]: `${(content.y - fit.y) * s}px`,\n ['--lk-overview-zoom' as string]: String(s),\n ['--lk-overview-cw' as string]: `${content.width}px`,\n ['--lk-overview-ch' as string]: `${content.height}px`,\n } as CSSProperties;\n}\n\n/** A canvas instrument's layers, redrawn through the fit camera. */\nfunction LayersCanvas({ fit, size, frame }: { fit: View; size: ViewportSize; frame: WorldFrame }) {\n const stack = useContext(CanvasStackContext);\n const ref = useRef<HTMLCanvasElement | null>(null);\n const layers = stack?.surface?.layers;\n useLayoutEffect(() => {\n const ctx = prepare(ref.current, size);\n if (!ctx || !layers) return;\n const local: WorldFrame = { originPx: { x: 0, y: 0 }, yDir: frame.yDir };\n const view = fromCameraView(fit, local);\n for (const layer of layers) {\n if (!layer.visible || layer.id.startsWith('__lk_')) continue;\n ctx.save();\n layer.render(ctx, view, local);\n ctx.restore();\n }\n }, [layers, fit, size, frame.yDir]);\n return <canvas ref={ref} className=\"lk-overview__canvas\" />;\n}\n\n/** The visible-rect indicator and the linked crosshair. */\nfunction ChromeCanvas({\n fit,\n size,\n camera,\n}: {\n fit: View;\n size: ViewportSize;\n camera: CameraContextValue;\n}) {\n const ref = useRef<HTMLCanvasElement | null>(null);\n const pointer = usePointerPosition();\n const root = camera.view.get();\n const host = camera.view.hostSize?.() ?? null;\n // No dependency list: this renders only when the pointer or the trial's\n // camera moved, and either one moves the chrome.\n useLayoutEffect(() => {\n const ctx = prepare(ref.current, size);\n if (!ctx) return;\n const s = fit.scale.x;\n const px = (x: number, y: number) => ({ x: (x - fit.x) * s, y: (y - fit.y) * s });\n if (host) {\n const a = px(root.x, root.y);\n ctx.strokeStyle = cssVar(ref.current, '--wzl-fg', '#ffffff');\n ctx.lineWidth = 1;\n ctx.setLineDash([2, 3]);\n ctx.strokeRect(\n a.x + 0.5,\n a.y + 0.5,\n (host.width / root.scale.x) * s,\n (host.height / root.scale.y) * s,\n );\n ctx.setLineDash([]);\n }\n const world = pointerElsewhere(pointer, OVERVIEW_VIEW_ID, camera.frame);\n if (world) {\n // Back to frame-local: the map is its own inverse.\n const at = px(world.x, world.y * camera.frame.yDir);\n const { halo, bars } = crosshairRects(at.x, at.y, 1);\n ctx.fillStyle = 'rgb(0 0 0 / 60%)';\n for (const r of halo) ctx.fillRect(r.x, r.y, r.w, r.h);\n ctx.fillStyle = cssVar(ref.current, '--wzl-accent', '#4c8dff');\n for (const r of bars) ctx.fillRect(r.x, r.y, r.w, r.h);\n }\n });\n return <canvas ref={ref} className=\"lk-overview__canvas lk-overview__chrome\" />;\n}\n\n/**\n * The overview's input, on a dispatcher of its own: its actions and deps are\n * isolated from the trial's, its pointer store is shared with it.\n */\nfunction OverviewInput(props: {\n boxRef: RefObject<HTMLDivElement | null>;\n fit: View;\n camera: CameraContextValue;\n}) {\n return (\n <DepRegistryProvider>\n <ActionsProvider>\n <ActiveToolContextProvider>\n <OverviewDispatch {...props} />\n </ActiveToolContextProvider>\n </ActionsProvider>\n </DepRegistryProvider>\n );\n}\n\nfunction OverviewDispatch({\n boxRef,\n fit,\n camera,\n}: {\n boxRef: RefObject<HTMLDivElement | null>;\n fit: View;\n camera: CameraContextValue;\n}) {\n const registry = useActionsRegistry();\n const fitRef = useRef(fit);\n fitRef.current = fit;\n const root = camera.view;\n useDepSource('rootView', () => root as ViewApi);\n\n useEffect(() => {\n if (!registry) return;\n const offs = [registry.register(minimapCenterAction()), registry.register(minimapPanAction())];\n return () => {\n for (const off of offs) off();\n };\n }, [registry]);\n\n const clientToLocal = useMemo(\n () => (cx: number, cy: number) => {\n const r = boxRef.current?.getBoundingClientRect();\n const f = fitRef.current;\n return {\n x: (cx - (r?.left ?? 0)) / f.scale.x + f.x,\n y: (cy - (r?.top ?? 0)) / f.scale.y + f.y,\n };\n },\n [boxRef],\n );\n\n useGestureDispatcher({\n canvasRef: boxRef,\n // Always present: `OverviewInput` mounts the provider directly above.\n actions: registry as NonNullable<typeof registry>,\n toolsById: TOOLS_BY_ID,\n clientToWorld: clientToLocal,\n keyboard: false,\n channels: CHANNELS,\n });\n\n usePublishPointer(boxRef, clientToLocal, camera.frame, OVERVIEW_VIEW_ID);\n\n // The box sits inside the stage's element, whose own dispatcher, loupe and\n // pointer publisher would otherwise take every event that bubbles out of it.\n useEffect(() => {\n const el = boxRef.current;\n if (!el) return;\n const stop = (e: Event): void => e.stopPropagation();\n const kinds = [\n 'pointerdown',\n 'pointermove',\n 'pointerup',\n 'click',\n 'wheel',\n 'dblclick',\n 'contextmenu',\n ];\n for (const k of kinds) el.addEventListener(k, stop);\n return () => {\n for (const k of kinds) el.removeEventListener(k, stop);\n };\n }, [boxRef]);\n\n return null;\n}\n"]}
1
+ {"version":3,"sources":["../../src/overview/OverviewMarks.tsx","../../src/overview/TrialOverview.tsx"],"names":["jsx","useEffect"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Every annotation target's marks, drawn read-only on the overview through the\n * export's own vector path: `markSvgNodes`, then `serializeSvg`.\n */\nimport type { View } from '@weasel-js/core';\nimport { serializeSvg } from '@weasel-js/svg';\nimport { type CSSProperties, type RefObject, useEffect, useReducer } from 'react';\nimport { useAnnotationsOptional } from '../annotations/AnnotationsContext';\nimport { markSvgNodes } from '../annotations/svgNodes';\nimport type { AnnotationsApi } from '../annotations/types';\nimport type { CameraContextValue } from '../canvas/CameraInput';\n\n/** A target's box, in the camera's frame-local units. */\ninterface LocalRect {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\n/** Where `el` sits in the camera's frame-local units: its screen rect,\n * measured against the camera's element, through the camera. */\nfunction localRectOf(el: HTMLElement, camera: CameraContextValue): LocalRect | null {\n const host = camera.element();\n if (!host) return null;\n const r = el.getBoundingClientRect();\n const h = host.getBoundingClientRect();\n const v = camera.view.get();\n return {\n x: (r.left - h.left) / v.scale.x + v.x,\n y: (r.top - h.top) / v.scale.y + v.y,\n w: r.width / v.scale.x,\n h: r.height / v.scale.y,\n };\n}\n\n/** The element a target's marks sit on. The capability's targets carry their\n * `ref`; the store's type names only the half it reads. */\nfunction elementOf(target: object): HTMLElement | null {\n return (target as { ref?: RefObject<HTMLElement | null> }).ref?.current ?? null;\n}\n\nfunction markupOf(api: AnnotationsApi, target: string, content: { w: number; h: number }): string {\n const painted = api.paintedMarks(target);\n if (painted.length === 0) return '';\n const nodes = painted.flatMap(({ mark, style }) => markSvgNodes(mark, content, style));\n return serializeSvg(nodes, { viewBox: { x: 0, y: 0, width: content.w, height: content.h } });\n}\n\n/** Props for `<OverviewMarks>`. */\nexport interface OverviewMarksProps {\n fit: View;\n camera: CameraContextValue;\n}\n\n/**\n * The marks of every target in the annotations store in scope, placed where\n * each target's element sits on the stage. Draws nothing outside an annotating\n * trial, and takes no input.\n */\nexport function OverviewMarks({ fit, camera }: OverviewMarksProps) {\n const api = useAnnotationsOptional();\n const [, redraw] = useReducer((n: number) => n + 1, 0);\n useEffect(() => api?.subscribe(redraw), [api]);\n if (!api) return null;\n const s = fit.scale.x;\n return (\n <>\n {api.targets().map((t) => {\n const el = elementOf(t);\n const box = el ? localRectOf(el, camera) : null;\n const markup = box ? markupOf(api, t.id, t.content) : '';\n if (!box || !markup) return null;\n const place = {\n ['--lk-overview-mx' as string]: `${(box.x - fit.x) * s}px`,\n ['--lk-overview-my' as string]: `${(box.y - fit.y) * s}px`,\n ['--lk-overview-mw' as string]: `${box.w * s}px`,\n ['--lk-overview-mh' as string]: `${box.h * s}px`,\n } as CSSProperties;\n return (\n <div\n key={t.id}\n className=\"lk-overview__marks\"\n style={place}\n data-target={t.id}\n // biome-ignore lint/security/noDangerouslySetInnerHtml: the export's SVG serializer is the one vector path marks have; re-deriving React nodes would be a second.\n dangerouslySetInnerHTML={{ __html: markup }}\n />\n );\n })}\n </>\n );\n}\n","/**\n * `<TrialOverview>` — the whole of a trial's content at a glance, in a panel\n * that floats over the stage: the visible rect, a crosshair where the pointer\n * is on the stage, and a press or drag that moves the stage's camera there.\n *\n * It is the labkit form of core's minimap contribution: the same\n * `minimap.center` / `minimap.pan` actions, run on a dispatcher of its own with\n * the trial's camera as `rootView`, and the same crosshair geometry.\n */\nimport {\n ActionsProvider,\n ActiveToolContextProvider,\n crosshairRects,\n DepRegistryProvider,\n MINIMAP_CENTER,\n MINIMAP_PAN,\n minimapCenterAction,\n minimapPanAction,\n type Tool,\n useActionsRegistry,\n useDepSource,\n useGestureDispatcher,\n usePointerPosition,\n type View,\n type ViewApi,\n} from '@weasel-js/core';\nimport {\n type CSSProperties,\n type ReactNode,\n type RefObject,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n} from 'react';\nimport {\n CameraContext,\n type CameraContextValue,\n pointerElsewhere,\n usePublishPointer,\n} from '../canvas/CameraInput';\nimport { CanvasStackContext } from '../canvas/CanvasStackContext';\nimport { fromCameraView } from '../canvas/cameraView';\nimport type { ViewportSize, WorldFrame } from '../canvas/worldSpec';\nimport { FloatingPanel, type FloatingPanelProps } from '../primitives/FloatingPanel';\nimport { OverviewMarks } from './OverviewMarks';\n\n/** The view id the overview publishes its pointer under. */\nexport const OVERVIEW_VIEW_ID = 'overview';\n\n/** A rect in the instrument's world. */\nexport interface OverviewBounds {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/** What an overview's `render` is handed. */\nexport interface OverviewRenderArgs {\n /** The content's own size in CSS pixels, at zoom 1 — lay out at this size\n * and the overview scales it to fit. */\n size: ViewportSize;\n}\n\n/** Props for `<TrialOverview>`. */\nexport interface TrialOverviewProps {\n /** The overview box, in CSS pixels. */\n width: number;\n height: number;\n /**\n * DOM content for the overview, laid out at the content's own size — for a\n * `stage` instrument, typically a lighter copy of what its `render` draws.\n * Never the instrument's own `render`: its effects would run twice. A canvas\n * instrument omits it, and the overview redraws the canvas's layers.\n */\n render?: (args: OverviewRenderArgs) => ReactNode;\n /** What to frame, in the instrument's world. Defaults to a stage's content\n * rect; a canvas instrument, whose world has no edge, names one. */\n bounds?: OverviewBounds;\n /** Panel title. */\n title?: string;\n anchor?: FloatingPanelProps['anchor'];\n persist?: string;\n className?: string;\n}\n\nconst PADDING = 6;\nconst OVERVIEW_INPUT: Tool = {\n id: 'overview',\n eligibility: { always: true },\n bindings: [\n { spec: { kind: 'pointerDown' }, actionId: MINIMAP_CENTER },\n { spec: { kind: 'drag' }, actionId: MINIMAP_PAN },\n ],\n};\nconst TOOLS_BY_ID: ReadonlyMap<string, Tool> = new Map([[OVERVIEW_INPUT.id, OVERVIEW_INPUT]]);\nconst CHANNELS = { wheel: false, pinch: false, contextMenu: false, ingest: false } as const;\n\n/** A world rect as a frame-local one. */\nfunction toLocalRect(b: OverviewBounds, frame: WorldFrame): OverviewBounds {\n if (frame.yDir === 1) return b;\n return { x: b.x, y: -(b.y + b.height), width: b.width, height: b.height };\n}\n\n/** The camera that fits `rect` into `size`, `PADDING` in from every edge. */\nfunction fitRect(rect: OverviewBounds, size: ViewportSize): View {\n const s = Math.min(\n Math.max(1, size.width - 2 * PADDING) / Math.max(rect.width, 1e-9),\n Math.max(1, size.height - 2 * PADDING) / Math.max(rect.height, 1e-9),\n );\n return {\n x: rect.x + rect.width / 2 - size.width / (2 * s),\n y: rect.y + rect.height / 2 - size.height / (2 * s),\n scale: { x: s, y: s },\n };\n}\n\n/** A canvas's 2D context sized to `size` at the device pixel ratio. */\nfunction prepare(\n canvas: HTMLCanvasElement | null,\n size: ViewportSize,\n): CanvasRenderingContext2D | null {\n const ctx = canvas?.getContext('2d') ?? null;\n if (!canvas || !ctx) return null;\n const dpr = window.devicePixelRatio || 1;\n const w = Math.round(size.width * dpr);\n const h = Math.round(size.height * dpr);\n if (canvas.width !== w) canvas.width = w;\n if (canvas.height !== h) canvas.height = h;\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n ctx.clearRect(0, 0, size.width, size.height);\n return ctx;\n}\n\nfunction cssVar(el: Element | null, name: string, fallback: string): string {\n if (!el) return fallback;\n return getComputedStyle(el).getPropertyValue(name).trim() || fallback;\n}\n\n/**\n * A trial's overview. Mount it from an instrument's `render` (a canvas\n * instrument) or `stage.overlay` (a DOM stage) — anywhere inside the trial's\n * camera.\n */\nexport function TrialOverview(props: TrialOverviewProps) {\n const camera = useContext(CameraContext);\n if (!camera) return null;\n return <Overview {...props} camera={camera} />;\n}\n\nfunction Overview({\n width,\n height,\n render,\n bounds,\n title = 'Overview',\n anchor = 'bottom-left',\n persist,\n className,\n camera,\n}: TrialOverviewProps & { camera: CameraContextValue }) {\n const size = useMemo(() => ({ width, height }), [width, height]);\n const content = bounds ? toLocalRect(bounds, camera.frame) : camera.content;\n // `content` is rebuilt every render, so the fit keys on its numbers.\n const framed = content !== null && content !== undefined;\n const { x = 0, y = 0, width: w = 0, height: h = 0 } = content ?? {};\n const fit = useMemo(\n () =>\n framed ? fitRect({ x, y, width: w, height: h }, size) : { x: 0, y: 0, scale: { x: 1, y: 1 } },\n [framed, x, y, w, h, size],\n );\n const boxRef = useRef<HTMLDivElement | null>(null);\n\n return (\n <FloatingPanel\n anchor={anchor}\n className={className ? `lk-overview ${className}` : 'lk-overview'}\n {...(persist ? { persist } : {})}\n >\n <div className=\"lk-overview__title\">{title}</div>\n <div ref={boxRef} className=\"lk-overview__box\" data-no-drag style={boxVars(size)}>\n {render && content ? (\n <div className=\"lk-overview__content\" style={contentVars(fit, content)}>\n {render({ size: { width: content.width, height: content.height } })}\n </div>\n ) : null}\n {render ? null : <LayersCanvas fit={fit} size={size} frame={camera.frame} />}\n <OverviewMarks fit={fit} camera={camera} />\n <ChromeCanvas fit={fit} size={size} camera={camera} />\n <OverviewInput boxRef={boxRef} fit={fit} camera={camera} />\n </div>\n </FloatingPanel>\n );\n}\n\n// The box's size and the content's camera change with props, and a transform\n// has nowhere to live but the element's own style: set as custom properties\n// the stylesheet reads, as `<Stage>` does.\nfunction boxVars(size: ViewportSize): CSSProperties {\n return {\n ['--lk-overview-w' as string]: `${size.width}px`,\n ['--lk-overview-h' as string]: `${size.height}px`,\n } as CSSProperties;\n}\n\nfunction contentVars(fit: View, content: OverviewBounds): CSSProperties {\n const s = fit.scale.x;\n return {\n ['--lk-overview-x' as string]: `${(content.x - fit.x) * s}px`,\n ['--lk-overview-y' as string]: `${(content.y - fit.y) * s}px`,\n ['--lk-overview-zoom' as string]: String(s),\n ['--lk-overview-cw' as string]: `${content.width}px`,\n ['--lk-overview-ch' as string]: `${content.height}px`,\n } as CSSProperties;\n}\n\n/** A canvas instrument's layers, redrawn through the fit camera. */\nfunction LayersCanvas({ fit, size, frame }: { fit: View; size: ViewportSize; frame: WorldFrame }) {\n const stack = useContext(CanvasStackContext);\n const ref = useRef<HTMLCanvasElement | null>(null);\n const layers = stack?.surface?.layers;\n useLayoutEffect(() => {\n const ctx = prepare(ref.current, size);\n if (!ctx || !layers) return;\n const local: WorldFrame = { originPx: { x: 0, y: 0 }, yDir: frame.yDir };\n const view = fromCameraView(fit, local);\n for (const layer of layers) {\n if (!layer.visible || layer.id.startsWith('__lk_')) continue;\n ctx.save();\n layer.render(ctx, view, local);\n ctx.restore();\n }\n }, [layers, fit, size, frame.yDir]);\n return <canvas ref={ref} className=\"lk-overview__canvas\" />;\n}\n\n/** The visible-rect indicator and the linked crosshair. */\nfunction ChromeCanvas({\n fit,\n size,\n camera,\n}: {\n fit: View;\n size: ViewportSize;\n camera: CameraContextValue;\n}) {\n const ref = useRef<HTMLCanvasElement | null>(null);\n const pointer = usePointerPosition();\n const root = camera.view.get();\n const host = camera.view.hostSize?.() ?? null;\n // No dependency list: this renders only when the pointer or the trial's\n // camera moved, and either one moves the chrome.\n useLayoutEffect(() => {\n const ctx = prepare(ref.current, size);\n if (!ctx) return;\n const s = fit.scale.x;\n const px = (x: number, y: number) => ({ x: (x - fit.x) * s, y: (y - fit.y) * s });\n if (host) {\n const a = px(root.x, root.y);\n ctx.strokeStyle = cssVar(ref.current, '--wzl-fg', '#ffffff');\n ctx.lineWidth = 1;\n ctx.setLineDash([2, 3]);\n ctx.strokeRect(\n a.x + 0.5,\n a.y + 0.5,\n (host.width / root.scale.x) * s,\n (host.height / root.scale.y) * s,\n );\n ctx.setLineDash([]);\n }\n const world = pointerElsewhere(pointer, OVERVIEW_VIEW_ID, camera.frame);\n if (world) {\n // Back to frame-local: the map is its own inverse.\n const at = px(world.x, world.y * camera.frame.yDir);\n const { halo, bars } = crosshairRects(at.x, at.y, 1);\n ctx.fillStyle = 'rgb(0 0 0 / 60%)';\n for (const r of halo) ctx.fillRect(r.x, r.y, r.w, r.h);\n ctx.fillStyle = cssVar(ref.current, '--wzl-accent', '#4c8dff');\n for (const r of bars) ctx.fillRect(r.x, r.y, r.w, r.h);\n }\n });\n return <canvas ref={ref} className=\"lk-overview__canvas lk-overview__chrome\" />;\n}\n\n/**\n * The overview's input, on a dispatcher of its own: its actions and deps are\n * isolated from the trial's, its pointer store is shared with it.\n */\nfunction OverviewInput(props: {\n boxRef: RefObject<HTMLDivElement | null>;\n fit: View;\n camera: CameraContextValue;\n}) {\n return (\n <DepRegistryProvider>\n <ActionsProvider>\n <ActiveToolContextProvider>\n <OverviewDispatch {...props} />\n </ActiveToolContextProvider>\n </ActionsProvider>\n </DepRegistryProvider>\n );\n}\n\nfunction OverviewDispatch({\n boxRef,\n fit,\n camera,\n}: {\n boxRef: RefObject<HTMLDivElement | null>;\n fit: View;\n camera: CameraContextValue;\n}) {\n const registry = useActionsRegistry();\n const fitRef = useRef(fit);\n fitRef.current = fit;\n const root = camera.view;\n useDepSource('rootView', () => root as ViewApi);\n\n useEffect(() => {\n if (!registry) return;\n const offs = [registry.register(minimapCenterAction()), registry.register(minimapPanAction())];\n return () => {\n for (const off of offs) off();\n };\n }, [registry]);\n\n const clientToLocal = useMemo(\n () => (cx: number, cy: number) => {\n const r = boxRef.current?.getBoundingClientRect();\n const f = fitRef.current;\n return {\n x: (cx - (r?.left ?? 0)) / f.scale.x + f.x,\n y: (cy - (r?.top ?? 0)) / f.scale.y + f.y,\n };\n },\n [boxRef],\n );\n\n useGestureDispatcher({\n canvasRef: boxRef,\n // Always present: `OverviewInput` mounts the provider directly above.\n actions: registry as NonNullable<typeof registry>,\n entriesById: TOOLS_BY_ID,\n clientToWorld: clientToLocal,\n keyboard: false,\n channels: CHANNELS,\n });\n\n usePublishPointer(boxRef, clientToLocal, camera.frame, OVERVIEW_VIEW_ID);\n\n // The box sits inside the stage's element, whose own dispatcher, loupe and\n // pointer publisher would otherwise take every event that bubbles out of it.\n useEffect(() => {\n const el = boxRef.current;\n if (!el) return;\n const stop = (e: Event): void => e.stopPropagation();\n const kinds = [\n 'pointerdown',\n 'pointermove',\n 'pointerup',\n 'click',\n 'wheel',\n 'dblclick',\n 'contextmenu',\n ];\n for (const k of kinds) el.addEventListener(k, stop);\n return () => {\n for (const k of kinds) el.removeEventListener(k, stop);\n };\n }, [boxRef]);\n\n return null;\n}\n"]}