@weasel-js/labkit 1.5.2 → 1.6.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 (139) hide show
  1. package/README.md +3 -7
  2. package/dist/_dts/{CanvasStackContext-CMMo180l.d.ts → CanvasStackContext-DQgcH1ny.d.ts} +1 -1
  3. package/dist/_dts/LayerList.d-2c9yup5Y.d.ts +83 -0
  4. package/dist/_dts/{PrefsForm.d-DPy9I8It.d.ts → PrefsRow.d-DFpPIeIC.d.ts} +16 -1
  5. package/dist/_dts/{Select.d-ZTiwzYyT.d.ts → Select.d-BchGMC2Y.d.ts} +102 -11
  6. package/dist/_dts/{frac-B4hFJMiN.d.ts → frac-DTRq7Xpb.d.ts} +18 -10
  7. package/dist/_dts/inDialog-D5ZKGjiD.d.ts +23 -0
  8. package/dist/_dts/{index-DlKolEIZ.d.ts → index-B0--8PEM.d.ts} +2 -2
  9. package/dist/_dts/index-DINmCuLA.d.ts +453 -0
  10. package/dist/_dts/number.d-OeQYQoUO.d.ts +28 -0
  11. package/dist/_dts/{types-Db-3NNk1.d.ts → types-B7y8hX1D.d.ts} +2 -2
  12. package/dist/_dts/{usePanZoom-SSTZe410.d.ts → usePanZoom-Bq73pwFe.d.ts} +2 -2
  13. package/dist/_dts/{useTrialState-pnAE-UBD.d.ts → useTrialState-CP4jfuKl.d.ts} +1 -1
  14. package/dist/canvas/index.d.ts +6 -5
  15. package/dist/chrome/index.d.ts +5 -4
  16. package/dist/chrome/index.js +7 -7
  17. package/dist/chunk-2RVCB2PT.js +3 -0
  18. package/dist/chunk-2RVCB2PT.js.map +1 -0
  19. package/dist/{chunk-753Y6HE6.js → chunk-3FI7Y4R4.js} +4 -4
  20. package/dist/chunk-3FI7Y4R4.js.map +1 -0
  21. package/dist/{chunk-REOBGYMC.js → chunk-AWH3SRPW.js} +31 -5
  22. package/dist/chunk-AWH3SRPW.js.map +1 -0
  23. package/dist/{chunk-A2ACAGW6.js → chunk-BVL7Y574.js} +22 -5
  24. package/dist/chunk-BVL7Y574.js.map +1 -0
  25. package/dist/{chunk-CKUKF72R.js → chunk-H5VIV7MQ.js} +26 -22
  26. package/dist/chunk-H5VIV7MQ.js.map +1 -0
  27. package/dist/chunk-HFRE4QQV.js +400 -0
  28. package/dist/chunk-HFRE4QQV.js.map +1 -0
  29. package/dist/{chunk-LRI3MBGR.js → chunk-MOLIUNVH.js} +4 -4
  30. package/dist/{chunk-LRI3MBGR.js.map → chunk-MOLIUNVH.js.map} +1 -1
  31. package/dist/chunk-USO6TERP.js +90 -0
  32. package/dist/chunk-USO6TERP.js.map +1 -0
  33. package/dist/{chunk-EMXAIRUJ.js → chunk-VQ47KWD5.js} +3 -3
  34. package/dist/{chunk-EMXAIRUJ.js.map → chunk-VQ47KWD5.js.map} +1 -1
  35. package/dist/chunk-WUJXJC5O.js +14568 -0
  36. package/dist/chunk-WUJXJC5O.js.map +1 -0
  37. package/dist/{chunk-KJCUERQF.js → chunk-ZORVNOKX.js} +6 -25
  38. package/dist/chunk-ZORVNOKX.js.map +1 -0
  39. package/dist/config/index.d.ts +50 -7
  40. package/dist/config/index.js +5 -5
  41. package/dist/controls/index.d.ts +6 -3
  42. package/dist/controls/index.js +4 -4
  43. package/dist/dragdrop/index.d.ts +4 -3
  44. package/dist/index.d.ts +83 -102
  45. package/dist/index.js +430 -458
  46. package/dist/index.js.map +1 -1
  47. package/dist/layers/index.d.ts +6 -35
  48. package/dist/layers/index.js +2 -3
  49. package/dist/loupe/index.d.ts +6 -5
  50. package/dist/passthrough/weasel-ui.d.ts +407 -204
  51. package/dist/passthrough/weasel-ui.js +1 -1
  52. package/dist/primitives/index.d.ts +2 -13
  53. package/dist/primitives/index.js +4 -4
  54. package/dist/state/index.d.ts +6 -5
  55. package/dist/state/index.js +5 -5
  56. package/dist/styles.css +298 -174
  57. package/dist/undo/index.d.ts +4 -3
  58. package/package.json +9 -13
  59. package/src/annotations/frac.test.ts +7 -0
  60. package/src/annotations/paint.test.ts +21 -0
  61. package/src/annotations/paint.ts +12 -0
  62. package/src/annotations/store.test.ts +31 -0
  63. package/src/annotations/types.ts +3 -2
  64. package/src/canvas/Stage.test.tsx +18 -0
  65. package/src/chrome/regions/SidebarRegion.less +197 -0
  66. package/src/chrome/regions/SidebarRegion.test.tsx +20 -0
  67. package/src/chrome/regions/SidebarRegion.tsx +7 -2
  68. package/src/chrome/types.ts +5 -2
  69. package/src/config/autoConfig.ts +2 -2
  70. package/src/config/builder.ts +20 -1
  71. package/src/config/entry.test.ts +8 -0
  72. package/src/config/index.ts +2 -0
  73. package/src/config/rules.ts +2 -0
  74. package/src/config/sectionTree.test.ts +146 -0
  75. package/src/config/sectionTree.ts +124 -0
  76. package/src/controls/ControlPanel.less +4 -0
  77. package/src/controls/ControlPanel.stories.tsx +55 -2
  78. package/src/controls/ControlPanel.test.tsx +30 -3
  79. package/src/controls/ControlPanel.tsx +116 -337
  80. package/src/controls/inDialog.test.tsx +82 -0
  81. package/src/controls/inDialog.tsx +46 -0
  82. package/src/controls/index.ts +1 -0
  83. package/src/index.ts +11 -26
  84. package/src/instrument/types.ts +5 -2
  85. package/src/lab/Lab.nebula.test.tsx +31 -0
  86. package/src/lab/Lab.tsx +38 -15
  87. package/src/lab/LabBoundary.test.tsx +66 -0
  88. package/src/lab/LabBoundary.tsx +56 -0
  89. package/src/lab/LabHeader.tsx +4 -23
  90. package/src/lab/LabRoot.tsx +2 -3
  91. package/src/lab/LabShell.less +0 -1
  92. package/src/lab/LabShell.stories.tsx +15 -0
  93. package/src/lab/LabShell.test.tsx +18 -0
  94. package/src/lab/LabShell.tsx +14 -1
  95. package/src/lab/LabSwitcher.less +1 -1
  96. package/src/lab/LabSwitcher.test.tsx +41 -0
  97. package/src/lab/LabSwitcher.tsx +30 -8
  98. package/src/lab/index.ts +1 -0
  99. package/src/layers/AGENTS.md +18 -74
  100. package/src/layers/index.ts +4 -2
  101. package/src/passthrough/weasel-ui.ts +25 -10
  102. package/src/primitives/index.ts +0 -2
  103. package/src/specimen/Specimen.tsx +42 -56
  104. package/src/state/types.ts +2 -1
  105. package/src/styles.less +4 -2
  106. package/src/theme/Interstellar.stories.tsx +8 -9
  107. package/src/theme/base.less +3 -20
  108. package/src/theme/interstellar.test.ts +6 -3
  109. package/src/theme/interstellar.theme.json +0 -56
  110. package/src/theme/interstellar.ts +2 -2
  111. package/src/trial/Trial.canvas.test.tsx +1 -1
  112. package/src/trial/Trial.tsx +30 -8
  113. package/dist/_dts/index-8LiKe3A-.d.ts +0 -410
  114. package/dist/chunk-6BUQ77ZV.js +0 -18
  115. package/dist/chunk-6BUQ77ZV.js.map +0 -1
  116. package/dist/chunk-753Y6HE6.js.map +0 -1
  117. package/dist/chunk-A2ACAGW6.js.map +0 -1
  118. package/dist/chunk-CKUKF72R.js.map +0 -1
  119. package/dist/chunk-D35PFTS7.js +0 -170
  120. package/dist/chunk-D35PFTS7.js.map +0 -1
  121. package/dist/chunk-FKLT3ITC.js +0 -590
  122. package/dist/chunk-FKLT3ITC.js.map +0 -1
  123. package/dist/chunk-KJCUERQF.js.map +0 -1
  124. package/dist/chunk-LASCBWW7.js +0 -13456
  125. package/dist/chunk-LASCBWW7.js.map +0 -1
  126. package/dist/chunk-REOBGYMC.js.map +0 -1
  127. package/dist/ui/layers/index.d.ts +0 -66
  128. package/dist/ui/layers/index.js +0 -3
  129. package/dist/ui/layers/index.js.map +0 -1
  130. package/src/lab/useSystemMode.ts +0 -30
  131. package/src/layers/LayerList.less +0 -93
  132. package/src/layers/LayerList.stories.tsx +0 -66
  133. package/src/layers/LayerList.test.tsx +0 -232
  134. package/src/layers/LayerList.tsx +0 -268
  135. package/src/primitives/Sidebar.less +0 -112
  136. package/src/primitives/Sidebar.stories.tsx +0 -38
  137. package/src/primitives/Sidebar.test.tsx +0 -74
  138. package/src/primitives/Sidebar.tsx +0 -35
  139. package/src/ui/layers/index.ts +0 -5
package/dist/index.js CHANGED
@@ -7,26 +7,27 @@ import { useTiledSurface } from './chunk-IJJUK4FU.js';
7
7
  export { composeRects, rectsEqual, toDeviceRect, useTiledSurface } from './chunk-IJJUK4FU.js';
8
8
  import { useJob } from './chunk-HXXTULDN.js';
9
9
  export { useJob } from './chunk-HXXTULDN.js';
10
- import { suppressContributions, mergeContributions, builtinContributions, TitleBarRegion, ToolbarRegion, PaletteRegion, ViewportRegion, SidebarRegion, StatusRegion, resolveLabTool, AnnotationsContext, useLabChromeContext, labContributions, LabHeaderRegion, LabFooterRegion, LabAsideRegion, LabSidebarRegion } from './chunk-CKUKF72R.js';
11
- export { AnnotationsContext, ExportMenu, LabAsideRegion, LabFooterRegion, LabHeaderRegion, LabSidebarRegion, MarkList, PaletteRegion, SidebarRegion, StatusRegion, TitleBarRegion, ToolbarRegion, ViewportRegion, builtinContributions, contributionsIn, labContributions, mergeContributions, suppressContributions, toolContributions, useAnnotations, useAnnotationsOptional, useLabChromeContext } from './chunk-CKUKF72R.js';
12
- import { Split, JobProgress, Sidebar, Legend, FloatingPanel } from './chunk-KJCUERQF.js';
13
- export { FloatingPanel, JobProgress, Legend, Sidebar, Split } from './chunk-KJCUERQF.js';
14
- import { Toolbar, StatusBar, ScaleIndicator, ZoomControl } from './chunk-753Y6HE6.js';
15
- export { FpsMeter, ScaleIndicator, StatusBar, Toolbar, ZoomControl } from './chunk-753Y6HE6.js';
16
- import { unruledConfigSchema, createLabStore, openLabStore, panelKey } from './chunk-LRI3MBGR.js';
17
- export { CURRENT_DOCUMENT_VERSION, dockPanel, labDocumentKey, openLabStore, panelKey, quarantineKey, undockPanel, useTrialState } from './chunk-LRI3MBGR.js';
10
+ import { suppressContributions, mergeContributions, builtinContributions, TitleBarRegion, ToolbarRegion, PaletteRegion, ViewportRegion, SidebarRegion, StatusRegion, resolveLabTool, AnnotationsContext, useLabChromeContext, labContributions, LabHeaderRegion, LabFooterRegion, LabAsideRegion, LabSidebarRegion } from './chunk-H5VIV7MQ.js';
11
+ export { AnnotationsContext, ExportMenu, LabAsideRegion, LabFooterRegion, LabHeaderRegion, LabSidebarRegion, MarkList, PaletteRegion, SidebarRegion, StatusRegion, TitleBarRegion, ToolbarRegion, ViewportRegion, builtinContributions, contributionsIn, labContributions, mergeContributions, suppressContributions, toolContributions, useAnnotations, useAnnotationsOptional, useLabChromeContext } from './chunk-H5VIV7MQ.js';
12
+ import { Split, JobProgress, Legend, FloatingPanel } from './chunk-ZORVNOKX.js';
13
+ export { FloatingPanel, JobProgress, Legend, Split } from './chunk-ZORVNOKX.js';
14
+ import { Toolbar, StatusBar, ScaleIndicator, ZoomControl } from './chunk-3FI7Y4R4.js';
15
+ export { FpsMeter, ScaleIndicator, StatusBar, Toolbar, ZoomControl } from './chunk-3FI7Y4R4.js';
16
+ import './chunk-SBXNQW4G.js';
17
+ import { unruledConfigSchema, createLabStore, openLabStore, panelKey } from './chunk-MOLIUNVH.js';
18
+ export { CURRENT_DOCUMENT_VERSION, dockPanel, labDocumentKey, openLabStore, panelKey, quarantineKey, undockPanel, useTrialState } from './chunk-MOLIUNVH.js';
18
19
  import { newId, useWarnIgnoredChange, useOpenOnce, PersistenceContext, createRecordCache, noneAdapter, defaultStorage, usePersistedState } from './chunk-RWNDDKOH.js';
19
20
  export { Persistence, createIndexedDbAdapter, createMemoryAdapter, indexedDbAdapter, localStorageAdapter, noneAdapter, sessionStorageAdapter, urlHashAdapter, usePersistedState } from './chunk-RWNDDKOH.js';
20
- export { ControlPanel } from './chunk-FKLT3ITC.js';
21
- import { useConfigSchema } from './chunk-6BUQ77ZV.js';
22
- export { useConfigSchema } from './chunk-6BUQ77ZV.js';
21
+ export { ControlPanel } from './chunk-HFRE4QQV.js';
22
+ import { useConfigSchema } from './chunk-USO6TERP.js';
23
+ export { sectionTree, useConfigSchema } from './chunk-USO6TERP.js';
23
24
  import { useLabContext, LabContext } from './chunk-Z76KEZAX.js';
24
25
  export { LabContext, useLabContext } from './chunk-Z76KEZAX.js';
25
- import { useResolvedConfig } from './chunk-A2ACAGW6.js';
26
- export { BaseNode, BooleanNode, ColorNode, CustomNode, EnumNode, GroupNode, NumberNode, StringNode, ValueNode, applyRules, builtinRules, f, isConfigBranch, resolveConfigSchema, titleCase, useResolvedConfig } from './chunk-A2ACAGW6.js';
27
- export { fromConfigFields, isLeafVisible } from './chunk-EMXAIRUJ.js';
28
- import { hasConfigPath, schemaNodeAtPath, applyConfigWrite, resolveAutoConfig, isAuto, isRecord, autoPathsOf, fillConfigDefaults } from './chunk-REOBGYMC.js';
29
- export { auto, autoPathsOf, fillConfigDefaults, hasConfigPath, isAuto, resolveAutoConfig, schemaNodeAtPath, valueAtPath, withValueAtPath } from './chunk-REOBGYMC.js';
26
+ import { useResolvedConfig } from './chunk-BVL7Y574.js';
27
+ export { BaseNode, BooleanNode, ColorNode, CustomNode, EnumNode, GroupNode, ListNode, NumberNode, StringNode, ValueNode, applyRules, builtinRules, f, isConfigBranch, resolveConfigSchema, titleCase, useResolvedConfig } from './chunk-BVL7Y574.js';
28
+ export { fromConfigFields, isLeafVisible } from './chunk-VQ47KWD5.js';
29
+ import { hasConfigPath, schemaNodeAtPath, applyConfigWrite, resolveAutoConfig, isAuto, isRecord, autoPathsOf, fillConfigDefaults } from './chunk-AWH3SRPW.js';
30
+ export { auto, autoPathsOf, fillConfigDefaults, hasConfigPath, inDialog, isAuto, resolveAutoConfig, schemaNodeAtPath, summarizeValue, valueAtPath, withValueAtPath } from './chunk-AWH3SRPW.js';
30
31
  import { CameraWheelContext, as2DView, DEFAULT_VIEW, CanvasStack, Stage, withZoom, fitStage } from './chunk-TT5C5S6R.js';
31
32
  export { CanvasStack, DEFAULT_VIEW, Stage, as2DView, fitStage, usePanZoom } from './chunk-TT5C5S6R.js';
32
33
  export { centerOn, zoomAt } from './chunk-H6ZAOWNE.js';
@@ -34,21 +35,20 @@ import { applyCamera } from './chunk-2AYGEN57.js';
34
35
  export { DEFAULT_FRAME, applyCamera, resolveFrame, screenToWorld, worldToScreen } from './chunk-2AYGEN57.js';
35
36
  import { useSurfaceOptional, useSurfaceCanvas, useTileId, SurfaceContext, SurfaceCanvasContext } from './chunk-WIG6XHJ7.js';
36
37
  export { SurfaceCanvasContext, SurfaceContext, useSurface, useSurfaceCanvas, useSurfaceOptional, useSurfaceTile, useTileId } from './chunk-WIG6XHJ7.js';
38
+ import { CanvasStackContext } from './chunk-CQLQPQ4P.js';
37
39
  export { CanvasStackContext } from './chunk-CQLQPQ4P.js';
38
- import { LabStoreContext, TrialIdProvider } from './chunk-2YILQ7Y5.js';
40
+ import { LabStoreContext, TrialIdProvider, TrialIdContext } from './chunk-2YILQ7Y5.js';
39
41
  export { LabStoreContext, LabStoreProvider, TrialIdContext, TrialIdProvider, useLabStore, useTrialId } from './chunk-2YILQ7Y5.js';
40
- import { LayerList } from './chunk-D35PFTS7.js';
41
- export { LayerList } from './chunk-D35PFTS7.js';
42
- import './chunk-SBXNQW4G.js';
43
- import { E, w, T, a2, p, u, c, n, f, r, h, serializeSvg, C, l7, r5, a5, Lt, o2, a3, l3, u3, r7, r8, r6, o5, s5, c7, l6, c3, s3, u2, g, b2, y2, l4, b3, c8, r3, l2, C2, S, D, O, I2, z2, U, W, G2, H, B, X, A2, c4, n5, s4, m2, c2, l, g2, l5, S4, r9, n6, r10, i5, i4, s2, n7, o4, c5, c6, w2, L2, n8, k3, $2 } from './chunk-LASCBWW7.js';
44
- export { a5 as Button, B as CheckboxRow, y as CloseIcon, $ as CollapseIcon, z2 as ColorRow, S2 as CurveField, q as EffectCard, Y as EffectCardList, te as ExpandIcon, o as Icon, u2 as Input, l9 as Jog, c4 as LayerStack, U as NumberRow, I as PauseIcon, F as PlayIcon, X as PropertyGroup, O as PropertyList, D as PropertyPanel, j2 as PropertyRow, k2 as PropertySpan, v as ResetIcon, b2 as Select, W as SelectRow, I2 as SliderRow, R as StepBackIcon, z as StepForwardIcon, L as StopIcon, K as Subpanel, H as TextRow, r5 as ToggleBar, G2 as ToggleRow, oe as TokenPanel, H2 as inferTokenType, O2 as refitScale } from './chunk-LASCBWW7.js';
45
- import { textCommand, linePath, markerDrawCommands, ellipsePath, rectPath, createScene, asNodeId as asNodeId$1, WeaselProvider, SceneCanvas, sceneFromJSON, PathBuilder, renderSceneToPixels, useActiveToolContext } from '@weasel-js/core';
42
+ import './chunk-2RVCB2PT.js';
43
+ import { y, I, A, T, i2, P, m, H, serializeSvg, D, S2, oe, d2, s3, c, Ht, o2, a6, l5, u5, a5, r3, a7, i3, o4, s6, c5, l7, p, f2, u4, g, T2, y2, l8, b, c6, i4, l4, C, S, ae, oe2, B, b2, A2, n6, s5, m4, l2, u, g2, u3, S4, r4, n7, r5, i5, p2, f, n8, o3, c3, c4, w, L, n9, k, $2 } from './chunk-WUJXJC5O.js';
44
+ export { c as Button, re as CloseIcon, Pe as CollapseIcon, _ as CurveField, Fe as ExpandIcon, l as Icon, u4 as Input, l9 as Jog, D as LayerList, ge as PauseIcon, he as PlayIcon, V as PropertyControl, B as PropertyField, b2 as PropertyGroup, oe2 as PropertyList, ae as PropertyPanel, L3 as PropertyRow, se as PropertySpan, Z as ResetIcon, T2 as Select, ve as StepBackIcon, $ as StepForwardIcon, _e as StopIcon, x as Subpanel, a5 as ToggleBar, oe3 as TokenPanel, H2 as inferTokenType, S2 as moveLayers, O as refitScale } from './chunk-WUJXJC5O.js';
45
+ import { textCommand, ellipsePath, linePath, markerDrawCommands, rectPath, createScene, asNodeId as asNodeId$1, WeaselProvider, SceneCanvas, sceneFromJSON, PathBuilder, renderSceneToPixels, useActiveToolContext } from '@weasel-js/core';
46
46
  import { createContext, useState, useRef, useEffect, useCallback, useContext, useMemo, useId, Children, useLayoutEffect, useSyncExternalStore } from 'react';
47
47
  import { flushSync, createPortal } from 'react-dom';
48
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
49
- import { useThemeOptional, ThemeProvider } from '@weasel-js/theme/react';
48
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
49
+ import { defineTheme, weaselTheme, colorCount, resolveTheme, colorAt } from '@weasel-js/theme';
50
+ import { useResolvedColorMode, useThemeOptional, ThemeProvider, ThemeContext } from '@weasel-js/theme/react';
50
51
  import { useStore } from 'zustand/react';
51
- import { defineTheme, weaselTheme } from '@weasel-js/theme';
52
52
  import { Provider, StrategyRegistryProvider, DragProvider, Container, useDragHandle } from 'windease/react';
53
53
  import { asNodeId, Store, createNode, floatingStrategy, gridStrategy } from 'windease';
54
54
  import { Focusable } from 'react-aria-components';
@@ -56,17 +56,18 @@ import { Focusable } from 'react-aria-components';
56
56
  var MARK_COLOR = "#e5484d";
57
57
  var MARK_WIDTH = 2;
58
58
  var TEXT_SIZE = 14;
59
- var toWorld = (p2, content) => ({
60
- x: p2.x * content.w,
61
- y: p2.y * content.h
59
+ var POINT_RADIUS = 4;
60
+ var toWorld = (p3, content) => ({
61
+ x: p3.x * content.w,
62
+ y: p3.y * content.h
62
63
  });
63
- function vertices(m2, content) {
64
- const stored = m2.data.points;
65
- if (stored && stored.length >= 2) return stored.map((p2) => toWorld(p2, content));
66
- const { x, y: y3, width, height } = m2.pose;
64
+ function vertices(m3, content) {
65
+ const stored = m3.data.points;
66
+ if (stored && stored.length >= 2) return stored.map((p3) => toWorld(p3, content));
67
+ const { x: x2, y: y3, width, height } = m3.pose;
67
68
  return [
68
- { x, y: y3 },
69
- { x: x + width, y: y3 + height }
69
+ { x: x2, y: y3 },
70
+ { x: x2 + width, y: y3 + height }
70
71
  ];
71
72
  }
72
73
  function polyline(points) {
@@ -74,10 +75,10 @@ function polyline(points) {
74
75
  const first = points[0];
75
76
  if (!first) return rectPath(0, 0, 0, 0);
76
77
  b3.moveTo(first.x, first.y);
77
- for (const p2 of points.slice(1)) b3.lineTo(p2.x, p2.y);
78
+ for (const p3 of points.slice(1)) b3.lineTo(p3.x, p3.y);
78
79
  return b3.build();
79
80
  }
80
- function markCommands(m2, content, style = {}) {
81
+ function markCommands(m3, content, style = {}) {
81
82
  const color = style.color ?? MARK_COLOR;
82
83
  const stroke = {
83
84
  paint: { color },
@@ -86,19 +87,19 @@ function markCommands(m2, content, style = {}) {
86
87
  join: "round",
87
88
  ...style.stale ? { dash: [6, 4] } : {}
88
89
  };
89
- switch (m2.data.kind) {
90
+ switch (m3.data.kind) {
90
91
  case "rect":
91
92
  return [
92
- { kind: "path", path: rectPath(m2.pose.x, m2.pose.y, m2.pose.width, m2.pose.height), stroke }
93
+ { kind: "path", path: rectPath(m3.pose.x, m3.pose.y, m3.pose.width, m3.pose.height), stroke }
93
94
  ];
94
95
  case "ellipse":
95
- return [{ kind: "path", path: ellipsePath(m2.pose), stroke }];
96
+ return [{ kind: "path", path: ellipsePath(m3.pose), stroke }];
96
97
  case "line": {
97
- const [a4, b3] = vertices(m2, content);
98
+ const [a4, b3] = vertices(m3, content);
98
99
  return [{ kind: "path", path: linePath(a4, b3), stroke }];
99
100
  }
100
101
  case "arrow": {
101
- const [a4, b3] = vertices(m2, content);
102
+ const [a4, b3] = vertices(m3, content);
102
103
  const marked = { ...stroke, markerEnd: "arrow" };
103
104
  const path = linePath(a4, b3);
104
105
  return [
@@ -107,14 +108,25 @@ function markCommands(m2, content, style = {}) {
107
108
  ];
108
109
  }
109
110
  case "stroke":
110
- return [{ kind: "path", path: polyline(vertices(m2, content)), stroke }];
111
+ return [{ kind: "path", path: polyline(vertices(m3, content)), stroke }];
112
+ case "point": {
113
+ const stored = m3.data.points?.[0];
114
+ const c6 = stored ? toWorld(stored, content) : { x: m3.pose.x, y: m3.pose.y };
115
+ const ring = {
116
+ x: c6.x - POINT_RADIUS,
117
+ y: c6.y - POINT_RADIUS,
118
+ width: 2 * POINT_RADIUS,
119
+ height: 2 * POINT_RADIUS
120
+ };
121
+ return [{ kind: "path", path: ellipsePath(ring), stroke }];
122
+ }
111
123
  case "text": {
112
- const text = m2.data.title;
124
+ const text = m3.data.title;
113
125
  if (!text) return [];
114
126
  return [
115
127
  textCommand(
116
- m2.pose.x,
117
- m2.pose.y,
128
+ m3.pose.x,
129
+ m3.pose.y,
118
130
  text,
119
131
  { fontSize: TEXT_SIZE },
120
132
  void 0,
@@ -134,8 +146,8 @@ function seenFrom(config, keys) {
134
146
  const out = {};
135
147
  if (config === null || typeof config !== "object") return out;
136
148
  const src = config;
137
- for (const k3 of keys) {
138
- if (k3 in src) out[k3] = src[k3];
149
+ for (const k2 of keys) {
150
+ if (k2 in src) out[k2] = src[k2];
139
151
  }
140
152
  return out;
141
153
  }
@@ -143,9 +155,9 @@ function isStale(seen, config, keys) {
143
155
  if (!seen || keys.length === 0) return false;
144
156
  if (config === null || typeof config !== "object") return false;
145
157
  const src = config;
146
- for (const k3 of keys) {
147
- if (!(k3 in seen)) continue;
148
- if (!Object.is(seen[k3], src[k3])) return true;
158
+ for (const k2 of keys) {
159
+ if (!(k2 in seen)) continue;
160
+ if (!Object.is(seen[k2], src[k2])) return true;
149
161
  }
150
162
  return false;
151
163
  }
@@ -156,7 +168,7 @@ function createMarkDrawOne(opts) {
156
168
  }
157
169
  function resolveMarkStyle(data, opts) {
158
170
  return {
159
- color: opts.meaning?.statuses?.find((s5) => s5.id === data.status)?.color,
171
+ color: opts.meaning?.statuses?.find((s4) => s4.id === data.status)?.color,
160
172
  // Read off the node rather than through the store's `isStale`, which
161
173
  // wants a projected Annotation this path does not have.
162
174
  stale: isStale(data.seen, opts.config, opts.positionDependsOn ?? [])
@@ -187,7 +199,7 @@ function toSvgStroke(stroke) {
187
199
  ...stroke.align ? { align: stroke.align } : {}
188
200
  };
189
201
  }
190
- function toSvgNode(cmd, m2) {
202
+ function toSvgNode(cmd, m3) {
191
203
  if (cmd.kind === "path") {
192
204
  return {
193
205
  kind: "path",
@@ -201,8 +213,8 @@ function toSvgNode(cmd, m2) {
201
213
  kind: "text",
202
214
  x: cmd.x,
203
215
  y: cmd.y,
204
- width: m2.pose.width,
205
- height: m2.pose.height,
216
+ width: m3.pose.width,
217
+ height: m3.pose.height,
206
218
  text: cmd.runs.map((run) => run.text).join(""),
207
219
  style: cmd.style,
208
220
  ...cmd.runs[0]?.fill ? { fill: cmd.runs[0].fill } : {}
@@ -210,8 +222,8 @@ function toSvgNode(cmd, m2) {
210
222
  }
211
223
  throw new Error(`[labkit] a mark drew a '${cmd.kind}' command, which has no vector form`);
212
224
  }
213
- function markSvgNodes(m2, content, style = {}) {
214
- return markCommands(m2, content, style).map((cmd) => toSvgNode(cmd, m2));
225
+ function markSvgNodes(m3, content, style = {}) {
226
+ return markCommands(m3, content, style).map((cmd) => toSvgNode(cmd, m3));
215
227
  }
216
228
 
217
229
  // src/annotations/capture.ts
@@ -220,7 +232,7 @@ function capturePlan(base, format) {
220
232
  if (format === "svg") return "svg-document";
221
233
  return base?.kind === "svg" ? "svg-document" : "raster-stack";
222
234
  }
223
- function nestBaseSvg(markup, w3, h2) {
235
+ function nestBaseSvg(markup, w2, h) {
224
236
  const doc = new DOMParser().parseFromString(markup, "image/svg+xml");
225
237
  const root = doc.documentElement;
226
238
  if (doc.getElementsByTagName("parsererror").length > 0 || root.localName !== "svg") {
@@ -228,17 +240,17 @@ function nestBaseSvg(markup, w3, h2) {
228
240
  }
229
241
  root.setAttribute("x", "0");
230
242
  root.setAttribute("y", "0");
231
- root.setAttribute("width", String(w3));
232
- root.setAttribute("height", String(h2));
243
+ root.setAttribute("width", String(w2));
244
+ root.setAttribute("height", String(h));
233
245
  return new XMLSerializer().serializeToString(root);
234
246
  }
235
- function embedRasterBase(base, w3, h2, onWarn) {
247
+ function embedRasterBase(base, w2, h, onWarn) {
236
248
  const href = base.kind === "canvas" ? base.canvas.toDataURL() : base.kind === "image" ? base.src : "";
237
249
  if (base.kind === "image" && !href.startsWith("data:")) {
238
250
  onWarn?.(`base image '${href}' is a reference, so this SVG is not self-contained`);
239
251
  }
240
- return serializeSvg([{ kind: "image", href, x: 0, y: 0, width: w3, height: h2 }], {
241
- viewBox: { x: 0, y: 0, width: w3, height: h2 }
252
+ return serializeSvg([{ kind: "image", href, x: 0, y: 0, width: w2, height: h }], {
253
+ viewBox: { x: 0, y: 0, width: w2, height: h }
242
254
  });
243
255
  }
244
256
  function markNodesOf(scene, draw) {
@@ -254,15 +266,15 @@ function markNodesOf(scene, draw) {
254
266
  }
255
267
  function composeCaptureSvg(args) {
256
268
  const { base, scene, draw, scale, onWarn } = args;
257
- const { w: w3, h: h2 } = draw.content;
258
- const baseXml = base === void 0 ? "" : base.kind === "svg" ? nestBaseSvg(base.markup, w3, h2) : embedRasterBase(base, w3, h2, onWarn);
269
+ const { w: w2, h } = draw.content;
270
+ const baseXml = base === void 0 ? "" : base.kind === "svg" ? nestBaseSvg(base.markup, w2, h) : embedRasterBase(base, w2, h, onWarn);
259
271
  const marksXml = serializeSvg(markNodesOf(scene, draw), {
260
- viewBox: { x: 0, y: 0, width: w3, height: h2 },
272
+ viewBox: { x: 0, y: 0, width: w2, height: h },
261
273
  onWarn
262
274
  });
263
- const outW = Math.max(1, Math.round(w3 * scale));
264
- const outH = Math.max(1, Math.round(h2 * scale));
265
- return `<svg xmlns="${SVG_NS}" width="${outW}" height="${outH}" viewBox="0 0 ${w3} ${h2}">${baseXml}${marksXml}</svg>`;
275
+ const outW = Math.max(1, Math.round(w2 * scale));
276
+ const outH = Math.max(1, Math.round(h * scale));
277
+ return `<svg xmlns="${SVG_NS}" width="${outW}" height="${outH}" viewBox="0 0 ${w2} ${h}">${baseXml}${marksXml}</svg>`;
266
278
  }
267
279
  function context2d(width, height) {
268
280
  const canvas = document.createElement("canvas");
@@ -356,26 +368,26 @@ async function captureTarget(args, opts = {}) {
356
368
  }
357
369
 
358
370
  // src/annotations/frac.ts
359
- function fracToWorld(f3, content) {
371
+ function fracToWorld(f4, content) {
360
372
  return {
361
- x: f3.x * content.w,
362
- y: f3.y * content.h,
363
- width: f3.w * content.w,
364
- height: f3.h * content.h
373
+ x: f4.x * content.w,
374
+ y: f4.y * content.h,
375
+ width: f4.w * content.w,
376
+ height: f4.h * content.h
365
377
  };
366
378
  }
367
- function worldToFrac(r9, content) {
379
+ function worldToFrac(r4, content) {
368
380
  const sx = content.w === 0 ? 0 : 1 / content.w;
369
381
  const sy = content.h === 0 ? 0 : 1 / content.h;
370
- return { x: r9.x * sx, y: r9.y * sy, w: r9.width * sx, h: r9.height * sy };
382
+ return { x: r4.x * sx, y: r4.y * sy, w: r4.width * sx, h: r4.height * sy };
371
383
  }
372
384
  var DP = 1e4;
373
- function roundFrac(f3) {
385
+ function roundFrac(f4) {
374
386
  return {
375
- x: Math.round(f3.x * DP) / DP,
376
- y: Math.round(f3.y * DP) / DP,
377
- w: Math.round(f3.w * DP) / DP,
378
- h: Math.round(f3.h * DP) / DP
387
+ x: Math.round(f4.x * DP) / DP,
388
+ y: Math.round(f4.y * DP) / DP,
389
+ w: Math.round(f4.w * DP) / DP,
390
+ h: Math.round(f4.h * DP) / DP
379
391
  };
380
392
  }
381
393
  function fracContains(box, pt, tol = 0) {
@@ -417,8 +429,8 @@ var MarkHistory = class {
417
429
  /** The target `undo` would act on, skipping any whose scene has nothing
418
430
  * left — a scene can drop entries this ordering still lists. */
419
431
  next(stack, can, at) {
420
- for (let i3 = stack.length - 1; i3 >= 0; i3--) {
421
- const target = stack[i3];
432
+ for (let i5 = stack.length - 1; i5 >= 0; i5--) {
433
+ const target = stack[i5];
422
434
  if (target === void 0) continue;
423
435
  const scene = at(target);
424
436
  if (scene && can(scene)) return target;
@@ -426,13 +438,13 @@ var MarkHistory = class {
426
438
  return null;
427
439
  }
428
440
  canUndo(at) {
429
- return this.next(this.undoable, (s5) => s5.canUndo(), at) !== null;
441
+ return this.next(this.undoable, (s4) => s4.canUndo(), at) !== null;
430
442
  }
431
443
  canRedo(at) {
432
- return this.next(this.redoable, (s5) => s5.canRedo(), at) !== null;
444
+ return this.next(this.redoable, (s4) => s4.canRedo(), at) !== null;
433
445
  }
434
446
  undo(at) {
435
- const target = this.next(this.undoable, (s5) => s5.canUndo(), at);
447
+ const target = this.next(this.undoable, (s4) => s4.canUndo(), at);
436
448
  const scene = target === null ? void 0 : at(target);
437
449
  if (!scene) return false;
438
450
  this.replaying = "undo";
@@ -443,7 +455,7 @@ var MarkHistory = class {
443
455
  }
444
456
  }
445
457
  redo(at) {
446
- const target = this.next(this.redoable, (s5) => s5.canRedo(), at);
458
+ const target = this.next(this.redoable, (s4) => s4.canRedo(), at);
447
459
  const scene = target === null ? void 0 : at(target);
448
460
  if (!scene) return false;
449
461
  this.replaying = "redo";
@@ -455,9 +467,9 @@ var MarkHistory = class {
455
467
  }
456
468
  };
457
469
  function drop(stack, value) {
458
- for (let i3 = stack.length - 1; i3 >= 0; i3--) {
459
- if (stack[i3] === value) {
460
- stack.splice(i3, 1);
470
+ for (let i5 = stack.length - 1; i5 >= 0; i5--) {
471
+ if (stack[i5] === value) {
472
+ stack.splice(i5, 1);
461
473
  return;
462
474
  }
463
475
  }
@@ -524,15 +536,15 @@ function createAnnotationStore(opts) {
524
536
  return out;
525
537
  };
526
538
  const all = () => liveTargets().flatMap(marksOn);
527
- const matches = (a4, q2) => {
528
- if (q2.target !== void 0 && a4.target !== q2.target) return false;
529
- if (q2.kind !== void 0 && a4.kind !== q2.kind) return false;
530
- if (q2.status !== void 0 && a4.status !== q2.status) return false;
531
- if (q2.tags !== void 0) {
539
+ const matches = (a4, q) => {
540
+ if (q.target !== void 0 && a4.target !== q.target) return false;
541
+ if (q.kind !== void 0 && a4.kind !== q.kind) return false;
542
+ if (q.status !== void 0 && a4.status !== q.status) return false;
543
+ if (q.tags !== void 0) {
532
544
  const have = a4.tags ?? [];
533
- for (const t of q2.tags) if (!have.includes(t)) return false;
545
+ for (const t of q.tags) if (!have.includes(t)) return false;
534
546
  }
535
- if (q2.where && !q2.where(a4)) return false;
547
+ if (q.where && !q.where(a4)) return false;
536
548
  return true;
537
549
  };
538
550
  const nodeOf = (id) => {
@@ -549,8 +561,8 @@ function createAnnotationStore(opts) {
549
561
  const parts = splitId(id);
550
562
  return parts ? project(parts.target, parts.node) : void 0;
551
563
  },
552
- query(q2) {
553
- return q2 ? all().filter((a4) => matches(a4, q2)) : all();
564
+ query(q) {
565
+ return q ? all().filter((a4) => matches(a4, q)) : all();
554
566
  },
555
567
  hitTest(target, pt, tol = 0) {
556
568
  return marksOn(target).filter((a4) => fracContains(a4.frac, pt, tol)).reverse();
@@ -598,7 +610,7 @@ function createAnnotationStore(opts) {
598
610
  for (const [target, scene] of scenes) {
599
611
  const next = wanted.get(target) ?? [];
600
612
  const now = scene.getSelection();
601
- if (now.length === next.length && next.every((n6, i3) => String(now[i3]) === n6)) continue;
613
+ if (now.length === next.length && next.every((n5, i5) => String(now[i5]) === n5)) continue;
602
614
  scene.setSelection(next.map(asNodeId$1));
603
615
  }
604
616
  },
@@ -695,14 +707,14 @@ var TOOLS = {
695
707
  };
696
708
  var ANNOTATION_TOOLS = [
697
709
  // Not in `TOOLS`: an id the map does not carry is what leaves the overlay idle.
698
- { id: "pointer", label: "Interact", icon: a2, group: "annotate" },
699
- { id: "select", label: "Select", icon: p, group: "annotate" },
700
- { id: "stroke", label: "Freehand", icon: u, group: "annotate" },
701
- { id: "line", label: "Line", icon: c, group: "annotate" },
702
- { id: "arrow", label: "Arrow", icon: n, group: "annotate" },
703
- { id: "rect", label: "Rectangle", icon: f, group: "annotate" },
704
- { id: "ellipse", label: "Ellipse", icon: r, group: "annotate" },
705
- { id: "text", label: "Text", icon: h, group: "annotate" }
710
+ { id: "pointer", label: "Interact", icon: y, group: "annotate" },
711
+ { id: "select", label: "Select", icon: I, group: "annotate" },
712
+ { id: "stroke", label: "Freehand", icon: A, group: "annotate" },
713
+ { id: "line", label: "Line", icon: T, group: "annotate" },
714
+ { id: "arrow", label: "Arrow", icon: i2, group: "annotate" },
715
+ { id: "rect", label: "Rectangle", icon: P, group: "annotate" },
716
+ { id: "ellipse", label: "Ellipse", icon: m, group: "annotate" },
717
+ { id: "text", label: "Text", icon: H, group: "annotate" }
706
718
  ];
707
719
  function annotationToolInfo(id) {
708
720
  return id === null ? void 0 : TOOLS[id];
@@ -712,11 +724,11 @@ var ANNOTATION_WEASEL_TOOLS = [
712
724
  ];
713
725
 
714
726
  // src/annotations/view.ts
715
- function toWeaselView(v2) {
716
- return { x: v2.pan.x, y: v2.pan.y, scale: { x: v2.zoom, y: v2.zoom } };
727
+ function toWeaselView(v) {
728
+ return { x: v.pan.x, y: v.pan.y, scale: { x: v.zoom, y: v.zoom } };
717
729
  }
718
- function fromWeaselView(v2) {
719
- return { zoom: v2.scale.x, pan: { x: v2.x, y: v2.y } };
730
+ function fromWeaselView(v) {
731
+ return { zoom: v.scale.x, pan: { x: v.x, y: v.y } };
720
732
  }
721
733
  function fitView(content, pane) {
722
734
  const zoom = content.w > 0 && content.h > 0 ? Math.min(pane.w / content.w, pane.h / content.h) : 1;
@@ -732,9 +744,9 @@ function ToolBridge({ toolId }) {
732
744
  return null;
733
745
  }
734
746
  function pointsOf(extras, content) {
735
- const toFrac = (p2) => ({
736
- x: content.w === 0 ? 0 : p2.x / content.w,
737
- y: content.h === 0 ? 0 : p2.y / content.h
747
+ const toFrac = (p3) => ({
748
+ x: content.w === 0 ? 0 : p3.x / content.w,
749
+ y: content.h === 0 ? 0 : p3.y / content.h
738
750
  });
739
751
  if (extras.kind === "line") {
740
752
  return [toFrac(extras.a), toFrac(extras.b)];
@@ -997,10 +1009,6 @@ var interstellar_theme_default = {
997
1009
  dark: {
998
1010
  value: "#0a0a14",
999
1011
  type: "color"
1000
- },
1001
- light: {
1002
- value: "#fafaf7",
1003
- type: "color"
1004
1012
  }
1005
1013
  },
1006
1014
  "surface-raised": {
@@ -1008,10 +1016,6 @@ var interstellar_theme_default = {
1008
1016
  dark: {
1009
1017
  value: "rgba(20, 20, 36, 0.55)",
1010
1018
  type: "color"
1011
- },
1012
- light: {
1013
- value: "#ffffff",
1014
- type: "color"
1015
1019
  }
1016
1020
  },
1017
1021
  "surface-sunken": {
@@ -1019,10 +1023,6 @@ var interstellar_theme_default = {
1019
1023
  dark: {
1020
1024
  value: "#02020a",
1021
1025
  type: "color"
1022
- },
1023
- light: {
1024
- value: "#f0ebe2",
1025
- type: "color"
1026
1026
  }
1027
1027
  },
1028
1028
  border: {
@@ -1030,10 +1030,6 @@ var interstellar_theme_default = {
1030
1030
  dark: {
1031
1031
  value: "rgba(255, 255, 255, 0.14)",
1032
1032
  type: "color"
1033
- },
1034
- light: {
1035
- value: "#c9bba5",
1036
- type: "color"
1037
1033
  }
1038
1034
  },
1039
1035
  "line-subtle": {
@@ -1041,10 +1037,6 @@ var interstellar_theme_default = {
1041
1037
  dark: {
1042
1038
  value: "rgba(255, 255, 255, 0.08)",
1043
1039
  type: "color"
1044
- },
1045
- light: {
1046
- value: "rgba(0, 0, 0, 0.08)",
1047
- type: "color"
1048
1040
  }
1049
1041
  },
1050
1042
  fg: {
@@ -1052,10 +1044,6 @@ var interstellar_theme_default = {
1052
1044
  dark: {
1053
1045
  value: "#e8e8f0",
1054
1046
  type: "color"
1055
- },
1056
- light: {
1057
- value: "#2a2018",
1058
- type: "color"
1059
1047
  }
1060
1048
  },
1061
1049
  "fg-muted": {
@@ -1063,10 +1051,6 @@ var interstellar_theme_default = {
1063
1051
  dark: {
1064
1052
  value: "#a8a8c0",
1065
1053
  type: "color"
1066
- },
1067
- light: {
1068
- value: "#6b5c4a",
1069
- type: "color"
1070
1054
  }
1071
1055
  },
1072
1056
  "fg-subtle": {
@@ -1074,10 +1058,6 @@ var interstellar_theme_default = {
1074
1058
  dark: {
1075
1059
  value: "#5a5a78",
1076
1060
  type: "color"
1077
- },
1078
- light: {
1079
- value: "#a89b85",
1080
- type: "color"
1081
1061
  }
1082
1062
  },
1083
1063
  accent: {
@@ -1085,10 +1065,6 @@ var interstellar_theme_default = {
1085
1065
  dark: {
1086
1066
  value: "#b08adb",
1087
1067
  type: "color"
1088
- },
1089
- light: {
1090
- value: "#a86f3c",
1091
- type: "color"
1092
1068
  }
1093
1069
  },
1094
1070
  "accent-hover": {
@@ -1096,10 +1072,6 @@ var interstellar_theme_default = {
1096
1072
  dark: {
1097
1073
  value: "#c6a3ee",
1098
1074
  type: "color"
1099
- },
1100
- light: {
1101
- value: "#c2854f",
1102
- type: "color"
1103
1075
  }
1104
1076
  },
1105
1077
  "focus-ring": {
@@ -1107,10 +1079,6 @@ var interstellar_theme_default = {
1107
1079
  dark: {
1108
1080
  value: "rgba(176, 138, 219, 0.45)",
1109
1081
  type: "color"
1110
- },
1111
- light: {
1112
- value: "rgba(168, 111, 60, 0.35)",
1113
- type: "color"
1114
1082
  }
1115
1083
  },
1116
1084
  shadow: {
@@ -1118,10 +1086,6 @@ var interstellar_theme_default = {
1118
1086
  dark: {
1119
1087
  value: "rgba(0, 0, 0, 0.7)",
1120
1088
  type: "color"
1121
- },
1122
- light: {
1123
- value: "rgba(80, 60, 40, 0.18)",
1124
- type: "color"
1125
1089
  }
1126
1090
  },
1127
1091
  "border-strong": {
@@ -1129,10 +1093,6 @@ var interstellar_theme_default = {
1129
1093
  dark: {
1130
1094
  value: "rgba(255, 255, 255, 0.36)",
1131
1095
  type: "color"
1132
- },
1133
- light: {
1134
- value: "#9e8b71",
1135
- type: "color"
1136
1096
  }
1137
1097
  },
1138
1098
  backdrop: {
@@ -1140,10 +1100,6 @@ var interstellar_theme_default = {
1140
1100
  dark: {
1141
1101
  value: "radial-gradient(ellipse 60% 80% at 18% 30%, rgba(150, 80, 200, 0.22), transparent 70%), radial-gradient(ellipse 55% 90% at 78% 70%, rgba(220, 100, 140, 0.18), transparent 65%), radial-gradient(ellipse 50% 70% at 50% 50%, rgba(60, 110, 200, 0.18), transparent 75%), radial-gradient(ellipse at center, #0a0a18 0%, #02020a 100%)",
1142
1102
  type: "gradient"
1143
- },
1144
- light: {
1145
- value: "none",
1146
- type: "gradient"
1147
1103
  }
1148
1104
  }
1149
1105
  }
@@ -1250,7 +1206,7 @@ function Portalled({
1250
1206
  }
1251
1207
  function UndockedSections({ trialId, sections, onDock }) {
1252
1208
  if (sections.length === 0) return null;
1253
- return /* @__PURE__ */ jsx(Fragment, { children: sections.map((c9) => /* @__PURE__ */ jsx(Portalled, { trialId, contribution: c9, onDock }, c9.id)) });
1209
+ return /* @__PURE__ */ jsx(Fragment, { children: sections.map((c6) => /* @__PURE__ */ jsx(Portalled, { trialId, contribution: c6, onDock }, c6.id)) });
1254
1210
  }
1255
1211
  var NO_OP = () => {
1256
1212
  };
@@ -1273,17 +1229,17 @@ function TrialChrome({
1273
1229
  const lab = useLabContext();
1274
1230
  const storeCtx = useContext(LabStoreContext);
1275
1231
  if (!storeCtx) throw new Error("[labkit] TrialChrome requires <LabStoreProvider>");
1276
- const updateTrialView = useStore(storeCtx.store, (s5) => s5.updateTrialView);
1277
- const updateTrialSidebarWidth = useStore(storeCtx.store, (s5) => s5.updateTrialSidebarWidth);
1278
- const setTrialTitle = useStore(storeCtx.store, (s5) => s5.setTrialTitle);
1279
- const setTrialSectionCollapsed = useStore(storeCtx.store, (s5) => s5.setTrialSectionCollapsed);
1280
- const updateTrialConfig = useStore(storeCtx.store, (s5) => s5.updateTrialConfig);
1281
- const updateTrialState = useStore(storeCtx.store, (s5) => s5.updateTrialState);
1282
- const undockPanelAction = useStore(storeCtx.store, (s5) => s5.undockPanel);
1283
- const dockPanelAction = useStore(storeCtx.store, (s5) => s5.dockPanel);
1284
- const undockedPanels = useStore(storeCtx.store, (s5) => s5.undockedPanels);
1232
+ const updateTrialView = useStore(storeCtx.store, (s4) => s4.updateTrialView);
1233
+ const updateTrialSidebarWidth = useStore(storeCtx.store, (s4) => s4.updateTrialSidebarWidth);
1234
+ const setTrialTitle = useStore(storeCtx.store, (s4) => s4.setTrialTitle);
1235
+ const setTrialSectionCollapsed = useStore(storeCtx.store, (s4) => s4.setTrialSectionCollapsed);
1236
+ const updateTrialConfig = useStore(storeCtx.store, (s4) => s4.updateTrialConfig);
1237
+ const updateTrialState = useStore(storeCtx.store, (s4) => s4.updateTrialState);
1238
+ const undockPanelAction = useStore(storeCtx.store, (s4) => s4.undockPanel);
1239
+ const dockPanelAction = useStore(storeCtx.store, (s4) => s4.dockPanel);
1240
+ const undockedPanels = useStore(storeCtx.store, (s4) => s4.undockedPanels);
1285
1241
  const undockedIds = useMemo(
1286
- () => Object.values(undockedPanels).filter((p2) => p2.trialId === trialId).map((p2) => p2.sectionId),
1242
+ () => Object.values(undockedPanels).filter((p3) => p3.trialId === trialId).map((p3) => p3.sectionId),
1287
1243
  [undockedPanels, trialId]
1288
1244
  );
1289
1245
  const view2d = as2DView(record.view);
@@ -1296,9 +1252,9 @@ function TrialChrome({
1296
1252
  const title = record.title ?? instrument.title ?? instrument.name;
1297
1253
  const collapsedSections = record.collapsedSections ?? NO_SECTIONS;
1298
1254
  const ctx = useMemo(() => {
1299
- const setZoom = (z3) => {
1255
+ const setZoom = (z) => {
1300
1256
  if (!view2d) return;
1301
- updateTrialView(trialId, withZoom(view2d, z3));
1257
+ updateTrialView(trialId, withZoom(view2d, z));
1302
1258
  };
1303
1259
  return {
1304
1260
  trialId,
@@ -1338,7 +1294,7 @@ function TrialChrome({
1338
1294
  undockedPanels: undockedIds,
1339
1295
  undockPanel: (sectionId, as) => undockPanelAction(trialId, sectionId, as),
1340
1296
  dockPanel: (sectionId) => dockPanelAction(trialId, sectionId),
1341
- savedSnapshots: lab.savedSnapshots.filter((s5) => s5.trialId === trialId),
1297
+ savedSnapshots: lab.savedSnapshots.filter((s4) => s4.trialId === trialId),
1342
1298
  saveSnapshot: (name) => lab.saveSnapshot(trialId, name),
1343
1299
  loadSnapshot: (snapshotId) => lab.loadSnapshot(trialId, snapshotId),
1344
1300
  clone: () => lab.cloneTrial(trialId),
@@ -1384,7 +1340,7 @@ function TrialChrome({
1384
1340
  ),
1385
1341
  [instrument, ctx, trialChrome, chrome, suppress, lab.controls]
1386
1342
  );
1387
- const inRegion = (region) => contributions.filter((c9) => c9.region === region);
1343
+ const inRegion = (region) => contributions.filter((c6) => c6.region === region);
1388
1344
  const handleKeyDown = (e) => {
1389
1345
  const mod = e.metaKey || e.ctrlKey;
1390
1346
  if (!mod) return;
@@ -1422,7 +1378,7 @@ function TrialChrome({
1422
1378
  TrialBody,
1423
1379
  {
1424
1380
  width: record.sidebarWidth,
1425
- onWidthChange: (w3) => updateTrialSidebarWidth(trialId, w3),
1381
+ onWidthChange: (w2) => updateTrialSidebarWidth(trialId, w2),
1426
1382
  contentClassName: instrument.canvas || instrument.stage ? "lk-trial__content--flush" : void 0,
1427
1383
  sidebar: /* @__PURE__ */ jsxs(Fragment, { children: [
1428
1384
  /* @__PURE__ */ jsx(SidebarRegion, { contributions: inRegion("sidebar"), ctx }),
@@ -1430,7 +1386,7 @@ function TrialChrome({
1430
1386
  UndockedSections,
1431
1387
  {
1432
1388
  trialId,
1433
- sections: inRegion("sidebar").filter((c9) => undockedIds.includes(c9.id)),
1389
+ sections: inRegion("sidebar").filter((c6) => undockedIds.includes(c6.id)),
1434
1390
  onDock: ctx.dockPanel
1435
1391
  }
1436
1392
  )
@@ -1454,9 +1410,9 @@ function Trial({ id, chrome, suppress }) {
1454
1410
  const lab = useLabContext();
1455
1411
  const storeCtx = useContext(LabStoreContext);
1456
1412
  if (!storeCtx) throw new Error("[labkit] <Trial> requires <LabStoreProvider>");
1457
- const instruments = useStore(storeCtx.store, (s5) => s5.instruments) ?? lab.instruments;
1458
- const record = useStore(storeCtx.store, (s5) => s5.trials.find((w3) => w3.id === id));
1459
- const instrument = record ? instruments.find((i3) => i3.name === record.instrumentName) : void 0;
1413
+ const instruments = useStore(storeCtx.store, (s4) => s4.instruments) ?? lab.instruments;
1414
+ const record = useStore(storeCtx.store, (s4) => s4.trials.find((w2) => w2.id === id));
1415
+ const instrument = record ? instruments.find((i5) => i5.name === record.instrumentName) : void 0;
1460
1416
  const kept = useKeptMarks(instrument?.annotations?.storage, id);
1461
1417
  if (!record) {
1462
1418
  return /* @__PURE__ */ jsxs("div", { className: "lk-trial lk-trial--unknown", children: [
@@ -1522,14 +1478,14 @@ function TrialRuntime({
1522
1478
  const wheelSlot = useRef(null);
1523
1479
  const canvasContainerRef = useRef(null);
1524
1480
  const loupeHostRef = useRef(null);
1525
- const updateTrialState = useStore(store, (s5) => s5.updateTrialState);
1526
- const updateTrialConfig = useStore(store, (s5) => s5.updateTrialConfig);
1527
- const updateTrialView = useStore(store, (s5) => s5.updateTrialView);
1528
- const updateTrialUndoStack = useStore(store, (s5) => s5.updateTrialUndoStack);
1529
- const updateTrialAnnotations = useStore(store, (s5) => s5.updateTrialAnnotations);
1530
- const labToolId = useStore(store, (s5) => s5.activeToolId);
1531
- const setLabTool = useStore(store, (s5) => s5.setLabTool);
1532
- const setTrialTool = useStore(store, (s5) => s5.setTrialTool);
1481
+ const updateTrialState = useStore(store, (s4) => s4.updateTrialState);
1482
+ const updateTrialConfig = useStore(store, (s4) => s4.updateTrialConfig);
1483
+ const updateTrialView = useStore(store, (s4) => s4.updateTrialView);
1484
+ const updateTrialUndoStack = useStore(store, (s4) => s4.updateTrialUndoStack);
1485
+ const updateTrialAnnotations = useStore(store, (s4) => s4.updateTrialAnnotations);
1486
+ const labToolId = useStore(store, (s4) => s4.activeToolId);
1487
+ const setLabTool = useStore(store, (s4) => s4.setLabTool);
1488
+ const setTrialTool = useStore(store, (s4) => s4.setTrialTool);
1533
1489
  const schema = useConfigSchema(instrument);
1534
1490
  const { config } = useResolvedConfig(schema, record.config, record.auto);
1535
1491
  const busRef = useRef(null);
@@ -1539,7 +1495,7 @@ function TrialRuntime({
1539
1495
  const [layerOrder, setLayerOrder] = useState(null);
1540
1496
  const [loupeOn, setLoupeOn] = useState(false);
1541
1497
  const visibleLayers = useMemo(
1542
- () => (instrument.canvas?.layers ?? []).filter((l9) => layerVisibility[l9.id] !== false).map((l9) => l9.id),
1498
+ () => (instrument.canvas?.layers ?? []).filter((l8) => layerVisibility[l8.id] !== false).map((l8) => l8.id),
1543
1499
  [instrument.canvas, layerVisibility]
1544
1500
  );
1545
1501
  const undoCap = instrument.undo;
@@ -1547,12 +1503,12 @@ function TrialRuntime({
1547
1503
  const maxDepth = undoCap?.maxDepth ?? 50;
1548
1504
  const snapshotIfNeeded = (event) => {
1549
1505
  if (!undoCap || !undoEvents.has(event)) return;
1550
- const current = store.getState().trials.find((w3) => w3.id === record.id);
1506
+ const current = store.getState().trials.find((w2) => w2.id === record.id);
1551
1507
  if (!current) return;
1552
1508
  const snap = structuredClone(current.state);
1553
1509
  updateTrialUndoStack(record.id, (prev) => pushSnapshot(prev, snap, maxDepth));
1554
1510
  };
1555
- const setView = (v2) => updateTrialView(record.id, v2);
1511
+ const setView = (v) => updateTrialView(record.id, v);
1556
1512
  const stage = instrument.canvas ? void 0 : instrument.stage;
1557
1513
  const placeView = (size) => {
1558
1514
  const declared = instrument.canvas?.initialView ?? (stage ? stage.initialView ?? ((vp) => fitStage(stage.size, vp)) : void 0);
@@ -1654,9 +1610,9 @@ function TrialRuntime({
1654
1610
  view: record.view,
1655
1611
  setView,
1656
1612
  zoom: view2d?.zoom ?? 1,
1657
- setZoom: (z3) => {
1613
+ setZoom: (z) => {
1658
1614
  if (!view2d) return;
1659
- updateTrialView(record.id, withZoom(view2d, z3));
1615
+ updateTrialView(record.id, withZoom(view2d, z));
1660
1616
  },
1661
1617
  activeToolId: resolvedToolId,
1662
1618
  visibleLayers
@@ -1696,7 +1652,7 @@ function TrialRuntime({
1696
1652
  if (declared == null) return null;
1697
1653
  return resolveLoupe(typeof declared === "function" ? declared(config) : declared);
1698
1654
  }, [instrument.loupe, config]);
1699
- const loupeBindings = loupeCap ? { on: loupeOn, toggle: () => setLoupeOn((v2) => !v2) } : void 0;
1655
+ const loupeBindings = loupeCap ? { on: loupeOn, toggle: () => setLoupeOn((v) => !v) } : void 0;
1700
1656
  const canvasLayers = useMemo(() => {
1701
1657
  if (!instrument.canvas) return [];
1702
1658
  const baseLayers = instrument.canvas.layers;
@@ -1712,10 +1668,23 @@ function TrialRuntime({
1712
1668
  }, [instrument.canvas, record.state, config, layerVisibility, layerOrder]);
1713
1669
  const layerDescriptors = useMemo(() => {
1714
1670
  if (!instrument.layers) return [];
1715
- return instrument.layers.ids.map((l9) => typeof l9 === "string" ? { id: l9, label: l9 } : l9);
1671
+ return instrument.layers.ids.map((l8) => typeof l8 === "string" ? { id: l8, label: l8 } : l8);
1716
1672
  }, [instrument.layers]);
1673
+ const layerItems = useMemo(() => {
1674
+ const ordered = layerOrder ? [...layerDescriptors].sort((a4, b3) => layerOrder.indexOf(a4.id) - layerOrder.indexOf(b3.id)) : layerDescriptors;
1675
+ const pinnedLast = [
1676
+ ...ordered.filter((l8) => !l8.alwaysOn),
1677
+ ...ordered.filter((l8) => l8.alwaysOn)
1678
+ ];
1679
+ return pinnedLast.map((l8) => ({
1680
+ id: l8.id,
1681
+ label: l8.label,
1682
+ locked: l8.alwaysOn === true,
1683
+ visible: l8.alwaysOn === true || layerVisibility[l8.id] !== false
1684
+ }));
1685
+ }, [layerDescriptors, layerOrder, layerVisibility]);
1717
1686
  const dragDropResult = useDragDrop({
1718
- capability: instrument.dragDrop ?? { palette: [], onDrop: (_p, _i, s5) => s5 },
1687
+ capability: instrument.dragDrop ?? { palette: [], onDrop: (_p, _i, s4) => s4 },
1719
1688
  canvasContainerRef,
1720
1689
  view: view2d ?? DEFAULT_VIEW,
1721
1690
  worldSpec: instrument.canvas?.worldSpec,
@@ -1732,8 +1701,8 @@ function TrialRuntime({
1732
1701
  });
1733
1702
  const paletteItems = useMemo(() => {
1734
1703
  if (!instrument.dragDrop) return [];
1735
- const p2 = instrument.dragDrop.palette;
1736
- return typeof p2 === "function" ? p2(record.state, config) : p2;
1704
+ const p3 = instrument.dragDrop.palette;
1705
+ return typeof p3 === "function" ? p3(record.state, config) : p3;
1737
1706
  }, [instrument.dragDrop, record.state, config]);
1738
1707
  const layersWithFeedback = useMemo(() => {
1739
1708
  if (!dragDropResult.drag?.feedback) return canvasLayers;
@@ -1747,12 +1716,12 @@ function TrialRuntime({
1747
1716
  render: (ctx) => {
1748
1717
  const el = canvasContainerRef.current;
1749
1718
  if (!el) return;
1750
- const r9 = el.getBoundingClientRect();
1719
+ const r4 = el.getBoundingClientRect();
1751
1720
  ctx.save();
1752
1721
  ctx.strokeStyle = fb.ok ? "#3a7" : "#c44";
1753
1722
  ctx.lineWidth = 2;
1754
1723
  ctx.beginPath();
1755
- ctx.arc(screen.x - r9.left, screen.y - r9.top, 16, 0, Math.PI * 2);
1724
+ ctx.arc(screen.x - r4.left, screen.y - r4.top, 16, 0, Math.PI * 2);
1756
1725
  ctx.stroke();
1757
1726
  ctx.restore();
1758
1727
  }
@@ -1803,7 +1772,10 @@ function TrialRuntime({
1803
1772
  minZoom: stage.minZoom,
1804
1773
  maxZoom: stage.maxZoom,
1805
1774
  hostRef: loupeHostRef,
1806
- overlay: lens,
1775
+ overlay: /* @__PURE__ */ jsxs(Fragment, { children: [
1776
+ stage.overlay?.(renderCtx),
1777
+ lens
1778
+ ] }),
1807
1779
  children: instrument.render(renderCtx)
1808
1780
  }
1809
1781
  );
@@ -1822,21 +1794,20 @@ function TrialRuntime({
1822
1794
  );
1823
1795
  const layerListNode = useMemo(
1824
1796
  () => instrument.layers && layerDescriptors.length > 0 ? /* @__PURE__ */ jsx(
1825
- LayerList,
1797
+ D,
1826
1798
  {
1827
- layers: layerDescriptors,
1828
- visibility: layerVisibility,
1829
- onReorder: (next) => {
1830
- setLayerOrder(next.map((l9) => l9.id));
1799
+ items: layerItems,
1800
+ onReorder: (move) => {
1801
+ setLayerOrder(S2(layerItems, move).map((l8) => l8.id));
1831
1802
  bus.emit("layers.reorder");
1832
1803
  },
1833
- onToggle: (lid, visible) => {
1804
+ onVisibilityChange: (lid, visible) => {
1834
1805
  setLayerVisibility((prev) => ({ ...prev, [lid]: visible }));
1835
1806
  bus.emit("layers.toggle");
1836
1807
  }
1837
1808
  }
1838
1809
  ) : null,
1839
- [instrument.layers, layerDescriptors, layerVisibility, bus]
1810
+ [instrument.layers, layerDescriptors, layerItems, bus]
1840
1811
  );
1841
1812
  const extraChrome = useMemo(() => {
1842
1813
  const out = [];
@@ -1893,7 +1864,7 @@ function TrialRuntime({
1893
1864
  // src/trial/trialOps.ts
1894
1865
  var DEFAULT_VIEW2 = { zoom: 1, pan: { x: 0, y: 0 } };
1895
1866
  function findInstrument(instruments, name) {
1896
- const found = instruments.find((i3) => i3.name === name);
1867
+ const found = instruments.find((i5) => i5.name === name);
1897
1868
  if (!found) {
1898
1869
  throw new Error(`[labkit] Unknown instrument: "${name}"`);
1899
1870
  }
@@ -1949,7 +1920,7 @@ function addTrial(trials, instruments, instrumentName, options = {}) {
1949
1920
  return [...trials, record];
1950
1921
  }
1951
1922
  function cloneTrial(trials, id) {
1952
- const sourceIdx = trials.findIndex((w3) => w3.id === id);
1923
+ const sourceIdx = trials.findIndex((w2) => w2.id === id);
1953
1924
  const source = trials[sourceIdx];
1954
1925
  if (!source) return trials;
1955
1926
  const clone = {
@@ -1964,11 +1935,11 @@ function cloneTrial(trials, id) {
1964
1935
  }
1965
1936
  function closeTrial(trials, id) {
1966
1937
  if (trials.length <= 1) return trials;
1967
- const next = trials.filter((w3) => w3.id !== id);
1938
+ const next = trials.filter((w2) => w2.id !== id);
1968
1939
  return next.length === trials.length ? trials : next;
1969
1940
  }
1970
1941
  function resetTrial(trials, id, instruments) {
1971
- const idx = trials.findIndex((w3) => w3.id === id);
1942
+ const idx = trials.findIndex((w2) => w2.id === id);
1972
1943
  const current = trials[idx];
1973
1944
  if (!current) return trials;
1974
1945
  const instrument = findInstrument(instruments, current.instrumentName);
@@ -1986,7 +1957,7 @@ function resetTrial(trials, id, instruments) {
1986
1957
  return [...trials.slice(0, idx), reset, ...trials.slice(idx + 1)];
1987
1958
  }
1988
1959
  function swapTrial(trials, instruments, id, instrumentName, options = {}) {
1989
- const idx = trials.findIndex((w3) => w3.id === id);
1960
+ const idx = trials.findIndex((w2) => w2.id === id);
1990
1961
  const current = trials[idx];
1991
1962
  if (!current) return trials;
1992
1963
  const [record] = addTrial([], instruments, instrumentName, options);
@@ -1994,25 +1965,25 @@ function swapTrial(trials, instruments, id, instrumentName, options = {}) {
1994
1965
  return [...trials.slice(0, idx), record, ...trials.slice(idx + 1)];
1995
1966
  }
1996
1967
  function reorderTrials(trials, ids) {
1997
- const byId = new Map(trials.map((w3) => [w3.id, w3]));
1998
- const named = ids.map((id) => byId.get(id)).filter((w3) => w3 !== void 0);
1999
- const seen = new Set(named.map((w3) => w3.id));
2000
- const rest = trials.filter((w3) => !seen.has(w3.id));
1968
+ const byId = new Map(trials.map((w2) => [w2.id, w2]));
1969
+ const named = ids.map((id) => byId.get(id)).filter((w2) => w2 !== void 0);
1970
+ const seen = new Set(named.map((w2) => w2.id));
1971
+ const rest = trials.filter((w2) => !seen.has(w2.id));
2001
1972
  return [...named, ...rest];
2002
1973
  }
2003
1974
  function findOvershoot(bound, items, tolerance = 1) {
2004
1975
  let worst = null;
2005
1976
  for (const { item, edges } of items) {
2006
1977
  const y3 = edges.bottom - bound.bottom;
2007
- const x = edges.right - bound.right;
2008
- const by = Math.max(x, y3);
1978
+ const x2 = edges.right - bound.right;
1979
+ const by = Math.max(x2, y3);
2009
1980
  if (by <= tolerance) continue;
2010
- if (!worst || by > worst.by) worst = { item, by, axis: y3 >= x ? "y" : "x" };
1981
+ if (!worst || by > worst.by) worst = { item, by, axis: y3 >= x2 ? "y" : "x" };
2011
1982
  }
2012
1983
  return worst;
2013
1984
  }
2014
1985
  function tagAndClasses(el) {
2015
- return el.tagName.toLowerCase() + [...el.classList].map((c9) => `.${c9}`).join("");
1986
+ return el.tagName.toLowerCase() + [...el.classList].map((c6) => `.${c6}`).join("");
2016
1987
  }
2017
1988
  function describeElement(el) {
2018
1989
  if (el.classList.length > 0) return tagAndClasses(el);
@@ -2021,8 +1992,8 @@ function describeElement(el) {
2021
1992
  return up ? `${tagAndClasses(el)} in ${tagAndClasses(up)}` : tagAndClasses(el);
2022
1993
  }
2023
1994
  function edgesOf(el) {
2024
- const r9 = el.getBoundingClientRect();
2025
- return { top: r9.top, left: r9.left, bottom: r9.bottom, right: r9.right };
1995
+ const r4 = el.getBoundingClientRect();
1996
+ return { top: r4.top, left: r4.left, bottom: r4.bottom, right: r4.right };
2026
1997
  }
2027
1998
  function* candidates(root) {
2028
1999
  yield { item: root, edges: edgesOf(root) };
@@ -2033,24 +2004,24 @@ function overflows(el) {
2033
2004
  }
2034
2005
  function explainLabScroll(lab, shellBody) {
2035
2006
  if (overflows(shellBody)) {
2036
- const r10 = shellBody.getBoundingClientRect();
2007
+ const r5 = shellBody.getBoundingClientRect();
2037
2008
  const bound2 = {
2038
- top: r10.top,
2039
- left: r10.left,
2040
- bottom: r10.top + shellBody.clientHeight,
2041
- right: r10.left + shellBody.clientWidth
2009
+ top: r5.top,
2010
+ left: r5.left,
2011
+ bottom: r5.top + shellBody.clientHeight,
2012
+ right: r5.left + shellBody.clientWidth
2042
2013
  };
2043
2014
  const hit2 = findOvershoot(bound2, candidates(shellBody));
2044
2015
  return hit2 ? `.lk-shell-body scrolls: ${describeElement(hit2.item)} reaches ${Math.round(hit2.by)}px past it (${hit2.axis})` : ".lk-shell-body scrolls";
2045
2016
  }
2046
2017
  const doc = document.scrollingElement ?? document.documentElement;
2047
2018
  if (!overflows(doc)) return null;
2048
- const r9 = lab.getBoundingClientRect();
2019
+ const r4 = lab.getBoundingClientRect();
2049
2020
  const bound = {
2050
- top: r9.top,
2051
- left: r9.left,
2052
- bottom: r9.top + Math.min(r9.height, doc.clientHeight),
2053
- right: r9.left + Math.min(r9.width, doc.clientWidth)
2021
+ top: r4.top,
2022
+ left: r4.left,
2023
+ bottom: r4.top + Math.min(r4.height, doc.clientHeight),
2024
+ right: r4.left + Math.min(r4.width, doc.clientWidth)
2054
2025
  };
2055
2026
  const hit = findOvershoot(bound, candidates(lab));
2056
2027
  return hit ? `the page scrolls: ${describeElement(hit.item)} reaches ${Math.round(hit.by)}px past the lab's box (${hit.axis})` : null;
@@ -2080,16 +2051,6 @@ function useLabFitWarning(labBody) {
2080
2051
  };
2081
2052
  }, [labBody]);
2082
2053
  }
2083
- var MODES = [
2084
- { value: "auto", label: "Auto", glyph: /* @__PURE__ */ jsx(E, { size: 14 }) },
2085
- { value: "light", label: "Light", glyph: /* @__PURE__ */ jsx(w, { size: 14 }) },
2086
- { value: "dark", label: "Dark", glyph: /* @__PURE__ */ jsx(T, { size: 14 }) }
2087
- ];
2088
- var MODE_ITEMS = MODES.map(({ value, label, glyph }) => ({
2089
- value,
2090
- label: glyph,
2091
- ariaLabel: label
2092
- }));
2093
2054
  function LabHeader({ addTrial: addTrial2 = true }) {
2094
2055
  const lab = useLabContext();
2095
2056
  const only = lab.instruments.length === 1 ? lab.instruments[0] : null;
@@ -2101,30 +2062,26 @@ function LabHeader({ addTrial: addTrial2 = true }) {
2101
2062
  className: "lk-lab-header__add",
2102
2063
  onClick: () => lab.addTrial(only.name),
2103
2064
  children: [
2104
- /* @__PURE__ */ jsx(C, { size: 16 }),
2065
+ /* @__PURE__ */ jsx(oe, { size: 16 }),
2105
2066
  /* @__PURE__ */ jsx("span", { children: "Add trial" })
2106
2067
  ]
2107
2068
  }
2108
2069
  ) : /* @__PURE__ */ jsx(
2109
- l7,
2070
+ d2,
2110
2071
  {
2111
2072
  "aria-label": "Add trial",
2112
2073
  label: "Add trial\u2026",
2113
- items: lab.instruments.map((i3) => ({ value: i3.name, label: i3.title ?? i3.name })),
2074
+ items: lab.instruments.map((i5) => ({ value: i5.name, label: i5.title ?? i5.name })),
2114
2075
  onAction: (name) => lab.addTrial(name)
2115
2076
  }
2116
2077
  ),
2117
2078
  /* @__PURE__ */ jsx(
2118
- r5,
2079
+ s3,
2119
2080
  {
2120
2081
  className: "lk-lab-header__mode",
2121
- ariaLabel: "Color mode",
2122
2082
  variant: "flat",
2123
- items: MODE_ITEMS,
2124
2083
  value: lab.mode,
2125
- onChange: (next) => {
2126
- if (next) lab.setMode(next);
2127
- }
2084
+ onChange: lab.setMode
2128
2085
  }
2129
2086
  )
2130
2087
  ] });
@@ -2132,42 +2089,39 @@ function LabHeader({ addTrial: addTrial2 = true }) {
2132
2089
  function LabPalette({ tools, contributions }) {
2133
2090
  const ctx = useLabChromeContext();
2134
2091
  const all = labContributions(tools, contributions);
2135
- return /* @__PURE__ */ jsx(PaletteRegion, { contributions: all.filter((c9) => c9.region === "palette"), ctx });
2136
- }
2137
- function query() {
2138
- if (typeof window === "undefined" || !window.matchMedia) return null;
2139
- return window.matchMedia("(prefers-color-scheme: light)");
2140
- }
2141
- function useResolvedMode(mode) {
2142
- const [system, setSystem] = useState(
2143
- () => query()?.matches ? "light" : "dark"
2144
- );
2145
- useEffect(() => {
2146
- if (mode !== "auto") return;
2147
- const mq = query();
2148
- if (!mq) return;
2149
- const onChange = (e) => setSystem(e.matches ? "light" : "dark");
2150
- mq.addEventListener("change", onChange);
2151
- return () => mq.removeEventListener("change", onChange);
2152
- }, [mode]);
2153
- return mode === "auto" ? system : mode;
2092
+ return /* @__PURE__ */ jsx(PaletteRegion, { contributions: all.filter((c6) => c6.region === "palette"), ctx });
2154
2093
  }
2155
2094
  function LabRoot({ children, mode = "auto", className }) {
2156
- const resolved = useResolvedMode(mode);
2095
+ const resolved = useResolvedColorMode(mode);
2157
2096
  const outer = useThemeOptional();
2158
2097
  const root = /* @__PURE__ */ jsx("div", { className: className ? `lk-root ${className}` : "lk-root", "data-wzl-portal-host": "", children });
2159
2098
  return outer ? root : /* @__PURE__ */ jsx(ThemeProvider, { theme: interstellarTheme, selection: { mode: resolved }, children: root });
2160
2099
  }
2100
+ function locate(url) {
2101
+ const hash = url.indexOf("#");
2102
+ const trim = (part) => part.replace(/\?.*$/, "").replace(/\/$/, "");
2103
+ return {
2104
+ doc: trim(hash < 0 ? url : url.slice(0, hash)).replace(/\.html$/, ""),
2105
+ route: hash < 0 ? "" : trim(url.slice(hash + 1))
2106
+ };
2107
+ }
2161
2108
  function currentPage(path, pages) {
2162
- const here = path.replace(/[?#].*$/, "").replace(/\/$/, "").replace(/\.html$/, "");
2163
- return pages.findIndex((p2) => here.endsWith(p2.href.replace(/\.html$/, "")));
2109
+ const here = locate(path);
2110
+ const onDoc = (doc) => here.doc.endsWith(doc);
2111
+ const routed = pages.findIndex((p3) => {
2112
+ if (!p3.href.includes("#")) return false;
2113
+ const page = locate(p3.href);
2114
+ return onDoc(page.doc) && (here.route === page.route || here.route.startsWith(`${page.route}/`));
2115
+ });
2116
+ if (routed >= 0) return routed;
2117
+ return pages.findIndex((p3) => !p3.href.includes("#") && onDoc(locate(p3.href).doc));
2164
2118
  }
2165
2119
  function LabSwitcher({ title, pages, path, className }) {
2166
2120
  const [open, setOpen] = useState(false);
2167
2121
  const root = useRef(null);
2168
2122
  const menuId = useId();
2169
2123
  const here = currentPage(
2170
- path ?? (typeof window === "undefined" ? "" : window.location.pathname),
2124
+ path ?? (typeof window === "undefined" ? "" : window.location.pathname + window.location.hash),
2171
2125
  pages
2172
2126
  );
2173
2127
  const close = useCallback(() => setOpen(false), []);
@@ -2208,13 +2162,13 @@ function LabSwitcher({ title, pages, path, className }) {
2208
2162
  ]
2209
2163
  }
2210
2164
  ) }),
2211
- open && /* @__PURE__ */ jsx("div", { className: "lk-switcher-menu", id: menuId, role: "menu", children: pages.map((page, i3) => /* @__PURE__ */ jsx(
2165
+ open && /* @__PURE__ */ jsx("div", { className: "lk-switcher-menu", id: menuId, role: "menu", children: pages.map((page, i5) => /* @__PURE__ */ jsx(
2212
2166
  "a",
2213
2167
  {
2214
2168
  href: page.href,
2215
2169
  role: "menuitem",
2216
2170
  className: "lk-switcher-item",
2217
- "aria-current": i3 === here ? "page" : void 0,
2171
+ "aria-current": i5 === here ? "page" : void 0,
2218
2172
  onClick: close,
2219
2173
  children: page.label
2220
2174
  },
@@ -2229,8 +2183,17 @@ function LabShell({
2229
2183
  footer,
2230
2184
  mode = "auto",
2231
2185
  pages,
2232
- path
2186
+ path,
2187
+ documentTitle
2233
2188
  }) {
2189
+ useEffect(() => {
2190
+ if (documentTitle === void 0) return;
2191
+ const previous = document.title;
2192
+ document.title = documentTitle;
2193
+ return () => {
2194
+ document.title = previous;
2195
+ };
2196
+ }, [documentTitle]);
2234
2197
  return /* @__PURE__ */ jsxs(LabRoot, { mode, className: "lk-shell", children: [
2235
2198
  /* @__PURE__ */ jsxs("header", { className: "lk-shell-header", children: [
2236
2199
  pages && pages.length > 0 ? /* @__PURE__ */ jsx(LabSwitcher, { title, pages, path, className: "lk-shell-title" }) : /* @__PURE__ */ jsx("h1", { className: "lk-shell-title", children: title }),
@@ -2246,11 +2209,11 @@ var FLOAT_ZONE_ID = asNodeId("lk-workspace-floating");
2246
2209
  var PANEL_KIND = "panel";
2247
2210
  var KIND = "trial";
2248
2211
  function extentOf(store, id) {
2249
- const p2 = store.getNode(id)?.membership?.placement;
2250
- if (!p2) return null;
2212
+ const p3 = store.getNode(id)?.membership?.placement;
2213
+ if (!p3) return null;
2251
2214
  const out = {};
2252
- if (p2.size) out.size = p2.size;
2253
- if (p2.span) out.span = p2.span;
2215
+ if (p3.size) out.size = p3.size;
2216
+ if (p3.span) out.span = p3.span;
2254
2217
  return Object.keys(out).length > 0 ? out : null;
2255
2218
  }
2256
2219
  function PanelFrame({ panel, floating = false }) {
@@ -2271,11 +2234,11 @@ function Workspace({
2271
2234
  viewport
2272
2235
  }) {
2273
2236
  const items = Children.toArray(children);
2274
- const tilePanels = useMemo(() => (panels ?? []).filter((p2) => p2.as === "tile"), [panels]);
2275
- const floatPanels = useMemo(() => (panels ?? []).filter((p2) => p2.as === "floating"), [panels]);
2237
+ const tilePanels = useMemo(() => (panels ?? []).filter((p3) => p3.as === "tile"), [panels]);
2238
+ const floatPanels = useMemo(() => (panels ?? []).filter((p3) => p3.as === "floating"), [panels]);
2276
2239
  const wantedIds = [
2277
- ...items.map((_, i3) => ids?.[i3] ?? `lk-ws-${i3}`),
2278
- ...tilePanels.map((p2) => `lk-panel-${p2.key}`)
2240
+ ...items.map((_2, i5) => ids?.[i5] ?? `lk-ws-${i5}`),
2241
+ ...tilePanels.map((p3) => `lk-panel-${p3.key}`)
2279
2242
  ];
2280
2243
  const idKey = wantedIds.join(",");
2281
2244
  const idKeyRef = useRef(null);
@@ -2350,9 +2313,9 @@ function Workspace({
2350
2313
  [onReorder]
2351
2314
  );
2352
2315
  const chrome = useMemo(() => {
2353
- const byId = new Map(nodeIds.map((id, i3) => [id, items[i3]]));
2316
+ const byId = new Map(nodeIds.map((id, i5) => [id, items[i5]]));
2354
2317
  const panelByNode = new Map(
2355
- tilePanels.map((p2) => [`lk-panel-${p2.key}`, p2])
2318
+ tilePanels.map((p3) => [`lk-panel-${p3.key}`, p3])
2356
2319
  );
2357
2320
  return {
2358
2321
  [PANEL_KIND]: ({ node }) => {
@@ -2370,7 +2333,7 @@ function Workspace({
2370
2333
  }
2371
2334
  };
2372
2335
  }, [nodeIds, items, reorderable, tilePanels]);
2373
- const floatingLayer = floatPanels.length === 0 ? null : /* @__PURE__ */ jsx("div", { className: "lk-workspace__floating", children: floatPanels.map((p2) => /* @__PURE__ */ jsx(PanelFrame, { panel: p2, floating: true }, p2.key)) });
2336
+ const floatingLayer = floatPanels.length === 0 ? null : /* @__PURE__ */ jsx("div", { className: "lk-workspace__floating", children: floatPanels.map((p3) => /* @__PURE__ */ jsx(PanelFrame, { panel: p3, floating: true }, p3.key)) });
2374
2337
  const grid = /* @__PURE__ */ jsx(
2375
2338
  Container,
2376
2339
  {
@@ -2416,7 +2379,7 @@ async function openStoredLab({ instruments, defaultInstrument, mode }, storageKe
2416
2379
  const marks = /* @__PURE__ */ new Map();
2417
2380
  await Promise.all(
2418
2381
  opened.store.getState().trials.map(async (trial) => {
2419
- const kept = instruments.find((i3) => i3.name === trial.instrumentName)?.annotations?.storage;
2382
+ const kept = instruments.find((i5) => i5.name === trial.instrumentName)?.annotations?.storage;
2420
2383
  if (!kept) return;
2421
2384
  try {
2422
2385
  marks.set(trial.id, await kept.load());
@@ -2432,14 +2395,15 @@ function LabFallback({
2432
2395
  title,
2433
2396
  mode,
2434
2397
  density,
2398
+ theme = interstellarTheme,
2435
2399
  pages,
2436
2400
  path
2437
2401
  }) {
2438
- const resolvedMode = useResolvedMode(mode ?? "auto");
2402
+ const resolvedMode = useResolvedColorMode(mode ?? "auto");
2439
2403
  return /* @__PURE__ */ jsx(
2440
2404
  ThemeProvider,
2441
2405
  {
2442
- theme: interstellarTheme,
2406
+ theme,
2443
2407
  selection: { mode: resolvedMode, density: density ?? "comfortable" },
2444
2408
  className: "lk-lab",
2445
2409
  children: /* @__PURE__ */ jsx(
@@ -2462,10 +2426,13 @@ var NEBULA_SLOTS = [
2462
2426
  { cx: "12%", cy: "82%", sx: "50%", sy: "70%", stop: "70%" },
2463
2427
  { cx: "85%", cy: "18%", sx: "55%", sy: "80%", stop: "70%" }
2464
2428
  ];
2465
- function buildNebula(colors) {
2466
- const blobs = colors.map((c9, i3) => {
2467
- const p2 = NEBULA_SLOTS[i3 % NEBULA_SLOTS.length];
2468
- return `radial-gradient(ellipse ${p2.sx} ${p2.sy} at ${p2.cx} ${p2.cy}, color-mix(in srgb, ${c9} 22%, transparent), transparent ${p2.stop})`;
2429
+ function buildNebula(list, theme, mode, density) {
2430
+ const ctx = { theme, resolved: resolveTheme(theme, { mode, density }) };
2431
+ const n5 = colorCount(list, ctx) ?? NEBULA_SLOTS.length;
2432
+ const colors = Array.from({ length: n5 }, (_2, i5) => colorAt(list, i5, ctx));
2433
+ const blobs = colors.map((c6, i5) => {
2434
+ const p3 = NEBULA_SLOTS[i5 % NEBULA_SLOTS.length];
2435
+ return `radial-gradient(ellipse ${p3.sx} ${p3.sy} at ${p3.cx} ${p3.cy}, color-mix(in srgb, ${c6} 22%, transparent), transparent ${p3.stop})`;
2469
2436
  });
2470
2437
  blobs.push("radial-gradient(ellipse at center, #0a0a18 0%, #02020a 100%)");
2471
2438
  return blobs.join(", ");
@@ -2485,7 +2452,7 @@ function LabPanes({
2485
2452
  void 0,
2486
2453
  { scope: "lab" }
2487
2454
  );
2488
- const main = contributions.some((c9) => c9.region === "aside") ? /* @__PURE__ */ jsx(
2455
+ const main = contributions.some((c6) => c6.region === "aside") ? /* @__PURE__ */ jsx(
2489
2456
  Split,
2490
2457
  {
2491
2458
  className: "lk-lab__panes",
@@ -2495,15 +2462,15 @@ function LabPanes({
2495
2462
  label: "Lab aside",
2496
2463
  defaultWidth: 320,
2497
2464
  width: asideWidth,
2498
- onWidthChange: (w3) => {
2499
- setAsideWidth(w3);
2465
+ onWidthChange: (w2) => {
2466
+ setAsideWidth(w2);
2500
2467
  surface?.invalidateRects();
2501
2468
  },
2502
2469
  sidebar: /* @__PURE__ */ jsx(LabAsideRegion, { contributions }),
2503
2470
  children
2504
2471
  }
2505
2472
  ) : children;
2506
- if (!contributions.some((c9) => c9.region === "sidebar")) return main;
2473
+ if (!contributions.some((c6) => c6.region === "sidebar")) return main;
2507
2474
  return /* @__PURE__ */ jsx(
2508
2475
  Split,
2509
2476
  {
@@ -2513,8 +2480,8 @@ function LabPanes({
2513
2480
  label: "Lab sidebar",
2514
2481
  defaultWidth: 260,
2515
2482
  width: sidebarWidth,
2516
- onWidthChange: (w3) => {
2517
- setSidebarWidth(w3);
2483
+ onWidthChange: (w2) => {
2484
+ setSidebarWidth(w2);
2518
2485
  surface?.invalidateRects();
2519
2486
  },
2520
2487
  sidebar: /* @__PURE__ */ jsx(LabSidebarRegion, { contributions }),
@@ -2539,6 +2506,7 @@ function Lab(props) {
2539
2506
  title: props.title,
2540
2507
  mode: props.mode,
2541
2508
  density: props.density,
2509
+ ...props.theme ? { theme: props.theme } : {},
2542
2510
  pages: props.pages,
2543
2511
  path: props.path
2544
2512
  }
@@ -2550,6 +2518,7 @@ function LabRuntime({
2550
2518
  instruments,
2551
2519
  mode,
2552
2520
  density,
2521
+ theme = interstellarTheme,
2553
2522
  nebula,
2554
2523
  title,
2555
2524
  pages,
@@ -2569,13 +2538,13 @@ function LabRuntime({
2569
2538
  useLayoutEffect(() => {
2570
2539
  store.getState().setInstruments(instruments);
2571
2540
  }, [instruments, store]);
2572
- const trials = useStore(store, (s5) => s5.trials);
2541
+ const trials = useStore(store, (s4) => s4.trials);
2573
2542
  const [focusPick, setFocusPick] = useState(null);
2574
2543
  const focusedTrialId = trials.some((t) => t.id === focusPick) ? focusPick : trials[0]?.id ?? null;
2575
- const savedSnapshots = useStore(store, (s5) => s5.savedSnapshots);
2576
- const modeValue = useStore(store, (s5) => s5.mode);
2577
- const layout = useStore(store, (s5) => s5.layout);
2578
- const undockedPanels = useStore(store, (s5) => s5.undockedPanels);
2544
+ const savedSnapshots = useStore(store, (s4) => s4.savedSnapshots);
2545
+ const modeValue = useStore(store, (s4) => s4.mode);
2546
+ const layout = useStore(store, (s4) => s4.layout);
2547
+ const undockedPanels = useStore(store, (s4) => s4.undockedPanels);
2579
2548
  const panelHostsRef = useRef(null);
2580
2549
  if (panelHostsRef.current === null) panelHostsRef.current = createPanelHostRegistry();
2581
2550
  const outerSurface = useSurfaceOptional();
@@ -2588,17 +2557,17 @@ function LabRuntime({
2588
2557
  const bufferRef = useRef({ w: 0, h: 0 });
2589
2558
  const surfaceRef = useRef(null);
2590
2559
  const onFrame = useCallback((frame) => {
2591
- const canvases = [ownUnderRef.current, ownOverRef.current].filter((c9) => c9 !== null);
2560
+ const canvases = [ownUnderRef.current, ownOverRef.current].filter((c6) => c6 !== null);
2592
2561
  if (canvases.length === 0) return;
2593
- const w3 = Math.round(frame.size.width * frame.dpr);
2594
- const h2 = Math.round(frame.size.height * frame.dpr);
2595
- if (bufferRef.current.w !== w3 || bufferRef.current.h !== h2) {
2596
- bufferRef.current = { w: w3, h: h2 };
2597
- for (const c9 of canvases) {
2598
- c9.width = w3;
2599
- c9.height = h2;
2600
- c9.style.width = `${frame.size.width}px`;
2601
- c9.style.height = `${frame.size.height}px`;
2562
+ const w2 = Math.round(frame.size.width * frame.dpr);
2563
+ const h = Math.round(frame.size.height * frame.dpr);
2564
+ if (bufferRef.current.w !== w2 || bufferRef.current.h !== h) {
2565
+ bufferRef.current = { w: w2, h };
2566
+ for (const c6 of canvases) {
2567
+ c6.width = w2;
2568
+ c6.height = h;
2569
+ c6.style.width = `${frame.size.width}px`;
2570
+ c6.style.height = `${frame.size.height}px`;
2602
2571
  }
2603
2572
  surfaceRef.current?.invalidateAll();
2604
2573
  return;
@@ -2656,14 +2625,14 @@ function LabRuntime({
2656
2625
  })),
2657
2626
  [undockedPanels]
2658
2627
  );
2659
- const resolvedMode = useResolvedMode(modeValue);
2660
- const annotates = instruments.some((i3) => i3.annotations != null);
2628
+ const resolvedMode = useResolvedColorMode(modeValue);
2629
+ const annotates = instruments.some((i5) => i5.annotations != null);
2661
2630
  const labChromeAll = useMemo(
2662
2631
  () => labContributions([...annotates ? ANNOTATION_TOOLS : [], ...tools ?? []], labChrome),
2663
2632
  [annotates, tools, labChrome]
2664
2633
  );
2665
- const hasFooterChrome = labChromeAll.some((c9) => c9.region === "footer");
2666
- const hasPaneChrome = labChromeAll.some((c9) => c9.region === "sidebar" || c9.region === "aside");
2634
+ const hasFooterChrome = labChromeAll.some((c6) => c6.region === "footer");
2635
+ const hasPaneChrome = labChromeAll.some((c6) => c6.region === "sidebar" || c6.region === "aside");
2667
2636
  useEffect(() => {
2668
2637
  if (mode && mode !== store.getState().mode) {
2669
2638
  store.getState().setMode(mode);
@@ -2671,14 +2640,14 @@ function LabRuntime({
2671
2640
  }, [mode, store]);
2672
2641
  const contextValue = useMemo(() => {
2673
2642
  const replaceTrials = (next) => {
2674
- const currentById = new Map(store.getState().trials.map((w3) => [w3.id, w3]));
2675
- const merged = next.map((w3) => currentById.get(w3.id) ?? w3);
2643
+ const currentById = new Map(store.getState().trials.map((w2) => [w2.id, w2]));
2644
+ const merged = next.map((w2) => currentById.get(w2.id) ?? w2);
2676
2645
  store.setState({ trials: merged });
2677
2646
  };
2678
2647
  const replaceAndFocusAdded = (next) => {
2679
- const before = new Set(store.getState().trials.map((w3) => w3.id));
2648
+ const before = new Set(store.getState().trials.map((w2) => w2.id));
2680
2649
  replaceTrials(next);
2681
- const added = next.find((w3) => !before.has(w3.id));
2650
+ const added = next.find((w2) => !before.has(w2.id));
2682
2651
  if (added) setFocusPick(added.id);
2683
2652
  };
2684
2653
  return {
@@ -2703,7 +2672,7 @@ function LabRuntime({
2703
2672
  const current = store.getState();
2704
2673
  const next = swapTrial(current.trials, instruments, id, instrumentName, options);
2705
2674
  if (next === current.trials) return;
2706
- const record = next[current.trials.findIndex((w3) => w3.id === id)];
2675
+ const record = next[current.trials.findIndex((w2) => w2.id === id)];
2707
2676
  const { [id]: extent, ...layoutRest } = current.layout;
2708
2677
  if (extent) current.setLayout({ ...layoutRest, [record.id]: extent });
2709
2678
  replaceTrials(next);
@@ -2713,17 +2682,17 @@ function LabRuntime({
2713
2682
  focusTrial: (id) => setFocusPick(id),
2714
2683
  resetTrial: (id) => {
2715
2684
  const next = resetTrial(store.getState().trials, id, instruments);
2716
- const record = next.find((w3) => w3.id === id);
2685
+ const record = next.find((w2) => w2.id === id);
2717
2686
  if (!record) return;
2718
- store.setState((s5) => ({
2719
- trials: s5.trials.map(
2720
- (w3) => w3.id === id ? { ...w3, config: record.config, state: record.state, view: record.view } : w3
2687
+ store.setState((s4) => ({
2688
+ trials: s4.trials.map(
2689
+ (w2) => w2.id === id ? { ...w2, config: record.config, state: record.state, view: record.view } : w2
2721
2690
  )
2722
2691
  }));
2723
2692
  },
2724
2693
  savedSnapshots,
2725
2694
  saveSnapshot: (trialId, name) => {
2726
- const taken = store.getState().savedSnapshots.filter((s5) => s5.trialId === trialId).length;
2695
+ const taken = store.getState().savedSnapshots.filter((s4) => s4.trialId === trialId).length;
2727
2696
  store.getState().saveSnapshot(trialId, name ?? `Snapshot ${taken + 1}`);
2728
2697
  },
2729
2698
  loadSnapshot: (trialId, snapshotId) => {
@@ -2733,8 +2702,8 @@ function LabRuntime({
2733
2702
  store.getState().deleteSnapshot(snapshotId);
2734
2703
  },
2735
2704
  mode: modeValue,
2736
- setMode: (m2) => {
2737
- store.getState().setMode(m2);
2705
+ setMode: (m3) => {
2706
+ store.getState().setMode(m3);
2738
2707
  },
2739
2708
  configRules,
2740
2709
  controls
@@ -2749,24 +2718,31 @@ function LabRuntime({
2749
2718
  configRules,
2750
2719
  controls
2751
2720
  ]);
2752
- const backdropStyle = resolvedMode === "dark" && nebula && nebula.length > 0 ? { ["--wzl-backdrop"]: buildNebula(nebula) } : void 0;
2721
+ const backdropStyle = resolvedMode === "dark" && nebula && colorCount(nebula) !== 0 ? {
2722
+ ["--wzl-backdrop"]: buildNebula(
2723
+ nebula,
2724
+ theme,
2725
+ resolvedMode,
2726
+ density ?? "comfortable"
2727
+ )
2728
+ } : void 0;
2753
2729
  const workspace = /* @__PURE__ */ jsx(
2754
2730
  Workspace,
2755
2731
  {
2756
2732
  panels: workspacePanels,
2757
- ids: trials.map((w3) => w3.id),
2733
+ ids: trials.map((w2) => w2.id),
2758
2734
  resizable: true,
2759
2735
  reorderable: true,
2760
2736
  onReorder: (ids) => contextValue.reorderTrials(ids),
2761
2737
  layout,
2762
2738
  onLayoutChange: (next) => store.getState().setLayout(next),
2763
- children: trials.map((w3) => /* @__PURE__ */ jsx(Trial, { id: w3.id, chrome, suppress }, w3.id))
2739
+ children: trials.map((w2) => /* @__PURE__ */ jsx(Trial, { id: w2.id, chrome, suppress }, w2.id))
2764
2740
  }
2765
2741
  );
2766
2742
  return /* @__PURE__ */ jsx(LabStoreContext.Provider, { value: { store }, children: /* @__PURE__ */ jsx(PersistenceContext.Provider, { value: opened.records, children: /* @__PURE__ */ jsx(AnnotationPreloadContext.Provider, { value: opened.marks, children: /* @__PURE__ */ jsx(LabContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(
2767
2743
  ThemeProvider,
2768
2744
  {
2769
- theme: interstellarTheme,
2745
+ theme,
2770
2746
  selection: { mode: resolvedMode, density: density ?? "comfortable" },
2771
2747
  className: "lk-lab",
2772
2748
  style: backdropStyle,
@@ -2829,6 +2805,9 @@ function LabRuntime({
2829
2805
  }
2830
2806
  ) }) }) }) });
2831
2807
  }
2808
+ function LabBoundary({ children }) {
2809
+ return /* @__PURE__ */ jsx(LabStoreContext.Provider, { value: null, children: /* @__PURE__ */ jsx(PersistenceContext.Provider, { value: null, children: /* @__PURE__ */ jsx(AnnotationPreloadContext.Provider, { value: null, children: /* @__PURE__ */ jsx(LabContext.Provider, { value: null, children: /* @__PURE__ */ jsx(PanelHostContext.Provider, { value: null, children: /* @__PURE__ */ jsx(SurfaceContext.Provider, { value: null, children: /* @__PURE__ */ jsx(SurfaceCanvasContext.Provider, { value: { over: null, under: null }, children: /* @__PURE__ */ jsx(TrialIdContext.Provider, { value: null, children: /* @__PURE__ */ jsx(AnnotationsContext.Provider, { value: null, children: /* @__PURE__ */ jsx(CameraWheelContext.Provider, { value: null, children: /* @__PURE__ */ jsx(CanvasStackContext.Provider, { value: null, children: /* @__PURE__ */ jsx(TrialDragContext.Provider, { value: null, children: /* @__PURE__ */ jsx(ThemeContext.Provider, { value: null, children }) }) }) }) }) }) }) }) }) }) }) }) });
2810
+ }
2832
2811
  var SPECIMEN_SECTIONS = [
2833
2812
  "Buttons & toggles",
2834
2813
  "Fields & pickers",
@@ -2922,32 +2901,32 @@ function ButtonsAndToggles() {
2922
2901
  const [open, setOpen] = useState(true);
2923
2902
  return /* @__PURE__ */ jsxs(Section, { title: "Buttons & toggles", children: [
2924
2903
  /* @__PURE__ */ jsx(Cell, { label: "Button", children: /* @__PURE__ */ jsxs("div", { className: "lk-specimen__row", children: [
2925
- /* @__PURE__ */ jsx(a5, { variant: "primary", children: "Save" }),
2926
- /* @__PURE__ */ jsx(a5, { variant: "secondary", children: "Cancel" }),
2927
- /* @__PURE__ */ jsx(a5, { variant: "ghost", children: "Ghost" }),
2928
- /* @__PURE__ */ jsx(a5, { variant: "secondary", disabled: true, children: "Disabled" }),
2929
- /* @__PURE__ */ jsx(a5, { variant: "secondary", iconOnly: true, ariaLabel: "Add", children: /* @__PURE__ */ jsx(Dot, {}) })
2904
+ /* @__PURE__ */ jsx(c, { variant: "primary", children: "Save" }),
2905
+ /* @__PURE__ */ jsx(c, { variant: "secondary", children: "Cancel" }),
2906
+ /* @__PURE__ */ jsx(c, { variant: "ghost", children: "Ghost" }),
2907
+ /* @__PURE__ */ jsx(c, { variant: "secondary", disabled: true, children: "Disabled" }),
2908
+ /* @__PURE__ */ jsx(c, { variant: "secondary", iconOnly: true, ariaLabel: "Add", children: /* @__PURE__ */ jsx(Dot, {}) })
2930
2909
  ] }) }),
2931
2910
  /* @__PURE__ */ jsx(Cell, { label: "Badge", children: /* @__PURE__ */ jsxs("div", { className: "lk-specimen__row", children: [
2932
- /* @__PURE__ */ jsx(Lt, { shape: "pill", tone: "accent", variant: "outline", size: "sm", children: "ACCENT" }),
2933
- /* @__PURE__ */ jsx(Lt, { tone: "info", variant: "subtle", children: "INFO" }),
2934
- /* @__PURE__ */ jsx(Lt, { tone: "warn", variant: "solid", children: "WARN" }),
2935
- /* @__PURE__ */ jsx(Lt, { tone: "danger", variant: "solid", children: "DANGER" }),
2936
- /* @__PURE__ */ jsx(Lt, { tone: "muted", children: "MUTED" })
2911
+ /* @__PURE__ */ jsx(Ht, { shape: "pill", status: "accent", variant: "outline", size: "sm", children: "ACCENT" }),
2912
+ /* @__PURE__ */ jsx(Ht, { status: "info", variant: "subtle", children: "INFO" }),
2913
+ /* @__PURE__ */ jsx(Ht, { status: "warn", variant: "solid", children: "WARN" }),
2914
+ /* @__PURE__ */ jsx(Ht, { status: "danger", variant: "solid", children: "DANGER" }),
2915
+ /* @__PURE__ */ jsx(Ht, { status: "muted", children: "MUTED" })
2937
2916
  ] }) }),
2938
2917
  /* @__PURE__ */ jsx(Cell, { label: "Checkbox, Switch", children: /* @__PURE__ */ jsxs("div", { className: "lk-specimen__row", children: [
2939
2918
  /* @__PURE__ */ jsx(o2, { isSelected: snap, onChange: setSnap, children: "Snap to grid" }),
2940
2919
  /* @__PURE__ */ jsx(o2, { isIndeterminate: true, children: "Mixed" }),
2941
- /* @__PURE__ */ jsx(a3, { isSelected: wifi, onChange: setWifi, children: "Wifi" })
2920
+ /* @__PURE__ */ jsx(a6, { isSelected: wifi, onChange: setWifi, children: "Wifi" })
2942
2921
  ] }) }),
2943
- /* @__PURE__ */ jsx(Cell, { label: "RadioGroup", children: /* @__PURE__ */ jsxs(l3, { label: "Snap mode", orientation: "horizontal", defaultValue: "grid", children: [
2944
- /* @__PURE__ */ jsx(u3, { value: "off", children: "Off" }),
2945
- /* @__PURE__ */ jsx(u3, { value: "grid", children: "Grid" }),
2946
- /* @__PURE__ */ jsx(u3, { value: "pixel", children: "Pixel" })
2922
+ /* @__PURE__ */ jsx(Cell, { label: "RadioGroup", children: /* @__PURE__ */ jsxs(l5, { label: "Snap mode", orientation: "horizontal", defaultValue: "grid", children: [
2923
+ /* @__PURE__ */ jsx(u5, { value: "off", children: "Off" }),
2924
+ /* @__PURE__ */ jsx(u5, { value: "grid", children: "Grid" }),
2925
+ /* @__PURE__ */ jsx(u5, { value: "pixel", children: "Pixel" })
2947
2926
  ] }) }),
2948
2927
  /* @__PURE__ */ jsxs(Cell, { label: "ToggleBar", children: [
2949
2928
  /* @__PURE__ */ jsx(
2950
- r5,
2929
+ a5,
2951
2930
  {
2952
2931
  ariaLabel: "Align",
2953
2932
  value: align,
@@ -2960,7 +2939,7 @@ function ButtonsAndToggles() {
2960
2939
  }
2961
2940
  ),
2962
2941
  /* @__PURE__ */ jsx(
2963
- r5,
2942
+ a5,
2964
2943
  {
2965
2944
  ariaLabel: "Align, flat",
2966
2945
  variant: "flat",
@@ -2974,9 +2953,9 @@ function ButtonsAndToggles() {
2974
2953
  }
2975
2954
  )
2976
2955
  ] }),
2977
- /* @__PURE__ */ jsx(Cell, { label: "OptionsBar, ActionsBar", children: /* @__PURE__ */ jsxs("div", { className: "lk-specimen__row", children: [
2956
+ /* @__PURE__ */ jsx(Cell, { label: "OptionsBar, ButtonBar", children: /* @__PURE__ */ jsxs("div", { className: "lk-specimen__row", children: [
2978
2957
  /* @__PURE__ */ jsx(
2979
- r7,
2958
+ r3,
2980
2959
  {
2981
2960
  ariaLabel: "Text style",
2982
2961
  items: [
@@ -2986,7 +2965,7 @@ function ButtonsAndToggles() {
2986
2965
  }
2987
2966
  ),
2988
2967
  /* @__PURE__ */ jsx(
2989
- r8,
2968
+ a7,
2990
2969
  {
2991
2970
  items: [
2992
2971
  { value: "undo", label: "Undo", onAction: () => {
@@ -2999,7 +2978,7 @@ function ButtonsAndToggles() {
2999
2978
  ] }) }),
3000
2979
  /* @__PURE__ */ jsx(Cell, { label: "MenuButton, Disclosure", children: /* @__PURE__ */ jsxs("div", { className: "lk-specimen__row", children: [
3001
2980
  /* @__PURE__ */ jsx(
3002
- l7,
2981
+ d2,
3003
2982
  {
3004
2983
  label: "Add trial\u2026",
3005
2984
  onAction: () => {
@@ -3010,24 +2989,22 @@ function ButtonsAndToggles() {
3010
2989
  ]
3011
2990
  }
3012
2991
  ),
3013
- /* @__PURE__ */ jsx(r6, { open, onToggle: () => setOpen((o5) => !o5), label: "Shapes" }),
3014
- /* @__PURE__ */ jsx(r6, { open: false, onToggle: () => {
3015
- }, label: "Down", direction: "down" })
2992
+ /* @__PURE__ */ jsx(i3, { open, onToggle: () => setOpen((o4) => !o4), label: "Shapes" })
3016
2993
  ] }) }),
3017
- /* @__PURE__ */ jsx(Cell, { label: "Tabs", children: /* @__PURE__ */ jsxs(o5, { children: [
3018
- /* @__PURE__ */ jsxs(s5, { "aria-label": "Sections", children: [
3019
- /* @__PURE__ */ jsx(c7, { id: "props", children: "Props" }),
3020
- /* @__PURE__ */ jsx(c7, { id: "events", children: "Events" }),
3021
- /* @__PURE__ */ jsx(c7, { id: "snapshot", children: "Snapshot" })
2994
+ /* @__PURE__ */ jsx(Cell, { label: "Tabs", children: /* @__PURE__ */ jsxs(o4, { children: [
2995
+ /* @__PURE__ */ jsxs(s6, { "aria-label": "Sections", children: [
2996
+ /* @__PURE__ */ jsx(c5, { id: "props", children: "Props" }),
2997
+ /* @__PURE__ */ jsx(c5, { id: "events", children: "Events" }),
2998
+ /* @__PURE__ */ jsx(c5, { id: "snapshot", children: "Snapshot" })
3022
2999
  ] }),
3023
- /* @__PURE__ */ jsx(l6, { id: "props", children: "Props panel." }),
3024
- /* @__PURE__ */ jsx(l6, { id: "events", children: "Events panel." }),
3025
- /* @__PURE__ */ jsx(l6, { id: "snapshot", children: "Snapshot panel." })
3000
+ /* @__PURE__ */ jsx(l7, { id: "props", children: "Props panel." }),
3001
+ /* @__PURE__ */ jsx(l7, { id: "events", children: "Events panel." }),
3002
+ /* @__PURE__ */ jsx(l7, { id: "snapshot", children: "Snapshot panel." })
3026
3003
  ] }) }),
3027
3004
  /* @__PURE__ */ jsx(Cell, { label: "Keycaps", children: /* @__PURE__ */ jsxs("div", { className: "lk-specimen__row", children: [
3028
- /* @__PURE__ */ jsx(c3, { keys: [{ label: "\u2318" }, { label: "\u21E7" }, { label: "K" }], separator: "+" }),
3029
- /* @__PURE__ */ jsx(s3, { label: "K" }),
3030
- /* @__PURE__ */ jsx(s3, { label: "\u2325", variant: "minimal" })
3005
+ /* @__PURE__ */ jsx(p, { keys: [{ label: "\u2318" }, { label: "\u21E7" }, { label: "K" }], separator: "+" }),
3006
+ /* @__PURE__ */ jsx(f2, { label: "K" }),
3007
+ /* @__PURE__ */ jsx(f2, { label: "\u2325", variant: "minimal" })
3031
3008
  ] }) })
3032
3009
  ] });
3033
3010
  }
@@ -3048,9 +3025,9 @@ function FieldsAndPickers() {
3048
3025
  const [paint, setPaint] = useState({ fill: "solid", color: "#b08adb" });
3049
3026
  return /* @__PURE__ */ jsxs(Section, { title: "Fields & pickers", children: [
3050
3027
  /* @__PURE__ */ jsxs(Cell, { label: "Input", children: [
3051
- /* @__PURE__ */ jsx(u2, { label: "Name", placeholder: "e.g. Pico" }),
3028
+ /* @__PURE__ */ jsx(u4, { label: "Name", placeholder: "e.g. Pico" }),
3052
3029
  /* @__PURE__ */ jsx(
3053
- u2,
3030
+ u4,
3054
3031
  {
3055
3032
  label: "Size",
3056
3033
  leadingAdornment: /* @__PURE__ */ jsx("span", { children: "W" }),
@@ -3058,12 +3035,12 @@ function FieldsAndPickers() {
3058
3035
  defaultValue: "120"
3059
3036
  }
3060
3037
  ),
3061
- /* @__PURE__ */ jsx(u2, { label: "Required", isInvalid: true, errorMessage: "Name is required." })
3038
+ /* @__PURE__ */ jsx(u4, { label: "Required", isInvalid: true, errorMessage: "Name is required." })
3062
3039
  ] }),
3063
3040
  /* @__PURE__ */ jsxs(Cell, { label: "NumberField, Select, ComboBox", children: [
3064
3041
  /* @__PURE__ */ jsx(g, { label: "Opacity", minValue: 0, maxValue: 100, step: 5, defaultValue: 80 }),
3065
3042
  /* @__PURE__ */ jsx(
3066
- b2,
3043
+ T2,
3067
3044
  {
3068
3045
  label: "Color",
3069
3046
  defaultSelectedKey: "g",
@@ -3087,19 +3064,19 @@ function FieldsAndPickers() {
3087
3064
  )
3088
3065
  ] }),
3089
3066
  /* @__PURE__ */ jsxs(Cell, { label: "RangeSlider, Slider", children: [
3090
- /* @__PURE__ */ jsx(l4, { label: "Range", defaultValue: [20, 80], minValue: 0, maxValue: 100 }),
3067
+ /* @__PURE__ */ jsx(l8, { label: "Range", defaultValue: [20, 80], minValue: 0, maxValue: 100 }),
3091
3068
  /* @__PURE__ */ jsx(
3092
- l4,
3069
+ l8,
3093
3070
  {
3094
3071
  label: "Opacity",
3095
3072
  defaultValue: 75,
3096
3073
  minValue: 0,
3097
3074
  maxValue: 100,
3098
- formatOutput: (v2) => `${v2}%`
3075
+ formatOutput: (v) => `${v}%`
3099
3076
  }
3100
3077
  ),
3101
3078
  /* @__PURE__ */ jsx(
3102
- b3,
3079
+ b,
3103
3080
  {
3104
3081
  ariaLabel: "Pair",
3105
3082
  min: 0,
@@ -3114,18 +3091,18 @@ function FieldsAndPickers() {
3114
3091
  ] }),
3115
3092
  /* @__PURE__ */ jsxs(Cell, { label: "DetentSlider, InlineRange", children: [
3116
3093
  /* @__PURE__ */ jsx(
3117
- c8,
3094
+ c6,
3118
3095
  {
3119
3096
  items: [0.25, 0.5, 1, 2, 4],
3120
3097
  value: rate,
3121
3098
  onChange: setRate,
3122
- formatLabel: (r9) => `${r9}\xD7`,
3099
+ formatLabel: (r4) => `${r4}\xD7`,
3123
3100
  labels: "all",
3124
3101
  ariaLabel: "Playback rate"
3125
3102
  }
3126
3103
  ),
3127
3104
  /* @__PURE__ */ jsx(
3128
- r3,
3105
+ i4,
3129
3106
  {
3130
3107
  "aria-label": "Width",
3131
3108
  min: 0,
@@ -3136,8 +3113,8 @@ function FieldsAndPickers() {
3136
3113
  )
3137
3114
  ] }),
3138
3115
  /* @__PURE__ */ jsxs(Cell, { label: "ColorField, GradientEditor", children: [
3139
- /* @__PURE__ */ jsx(l2, { value: color, alpha: true, onInput: setColor, onChange: setColor, "aria-label": "Color" }),
3140
- /* @__PURE__ */ jsx(C2, { value: gradient, onInput: setGradient, onChange: setGradient, kindSwitch: true })
3116
+ /* @__PURE__ */ jsx(l4, { value: color, alpha: true, onInput: setColor, onChange: setColor, "aria-label": "Color" }),
3117
+ /* @__PURE__ */ jsx(C, { value: gradient, onInput: setGradient, onChange: setGradient, kindSwitch: true })
3141
3118
  ] }),
3142
3119
  /* @__PURE__ */ jsx(Cell, { label: "PaintInput", children: /* @__PURE__ */ jsx(
3143
3120
  S,
@@ -3169,10 +3146,12 @@ function PanelsAndRows() {
3169
3146
  ]);
3170
3147
  const [panelCollapsed, setPanelCollapsed] = useState(false);
3171
3148
  return /* @__PURE__ */ jsxs(Section, { title: "Panels & property rows", children: [
3172
- /* @__PURE__ */ jsx(Cell, { label: "PropertyPanel", children: /* @__PURE__ */ jsx(D, { title: "Shape", children: /* @__PURE__ */ jsxs(O, { children: [
3149
+ /* @__PURE__ */ jsx(Cell, { label: "PropertyPanel", children: /* @__PURE__ */ jsx(ae, { title: "Shape", children: /* @__PURE__ */ jsxs(oe2, { children: [
3173
3150
  /* @__PURE__ */ jsx(
3174
- I2,
3151
+ B,
3175
3152
  {
3153
+ kind: "number",
3154
+ control: "slider",
3176
3155
  label: "Opacity",
3177
3156
  value: opacity,
3178
3157
  min: 0,
@@ -3182,8 +3161,10 @@ function PanelsAndRows() {
3182
3161
  }
3183
3162
  ),
3184
3163
  /* @__PURE__ */ jsx(
3185
- I2,
3164
+ B,
3186
3165
  {
3166
+ kind: "number",
3167
+ control: "slider",
3187
3168
  label: "Radius",
3188
3169
  value: radius,
3189
3170
  min: 0,
@@ -3193,8 +3174,9 @@ function PanelsAndRows() {
3193
3174
  }
3194
3175
  ),
3195
3176
  /* @__PURE__ */ jsx(
3196
- z2,
3177
+ B,
3197
3178
  {
3179
+ kind: "color",
3198
3180
  label: "Fill",
3199
3181
  value: fill,
3200
3182
  onChange: setFill,
@@ -3202,11 +3184,12 @@ function PanelsAndRows() {
3202
3184
  onAlphaChange: setAlpha
3203
3185
  }
3204
3186
  ),
3205
- /* @__PURE__ */ jsx(z2, { label: "Stroke", value: stroke, onChange: setStroke }),
3206
- /* @__PURE__ */ jsx(U, { label: "Count", value: count, min: 0, max: 100, step: 1, onChange: setCount }),
3187
+ /* @__PURE__ */ jsx(B, { kind: "color", label: "Stroke", value: stroke, onChange: setStroke }),
3188
+ /* @__PURE__ */ jsx(B, { kind: "number", label: "Count", value: count, min: 0, max: 100, step: 1, onChange: setCount }),
3207
3189
  /* @__PURE__ */ jsx(
3208
- W,
3190
+ B,
3209
3191
  {
3192
+ kind: "enum",
3210
3193
  label: "Line cap",
3211
3194
  value: cap,
3212
3195
  onChange: setCap,
@@ -3217,8 +3200,10 @@ function PanelsAndRows() {
3217
3200
  }
3218
3201
  ),
3219
3202
  /* @__PURE__ */ jsx(
3220
- G2,
3203
+ B,
3221
3204
  {
3205
+ kind: "enum",
3206
+ control: "toggle",
3222
3207
  label: "Align",
3223
3208
  value: side,
3224
3209
  onChange: setSide,
@@ -3229,9 +3214,9 @@ function PanelsAndRows() {
3229
3214
  ]
3230
3215
  }
3231
3216
  ),
3232
- /* @__PURE__ */ jsx(H, { label: "Label", value: label, onChange: setLabel }),
3233
- /* @__PURE__ */ jsx(B, { label: "Visible", value: visible, onChange: setVisible }),
3234
- /* @__PURE__ */ jsx(X, { title: "Bevel", defaultCollapsed: true, children: /* @__PURE__ */ jsx(I2, { label: "Rings", value: 32, min: 4, max: 96, step: 1, onChange: () => {
3217
+ /* @__PURE__ */ jsx(B, { kind: "string", label: "Label", value: label, onChange: setLabel }),
3218
+ /* @__PURE__ */ jsx(B, { kind: "boolean", label: "Visible", value: visible, onChange: setVisible }),
3219
+ /* @__PURE__ */ jsx(b2, { title: "Bevel", defaultCollapsed: true, children: /* @__PURE__ */ jsx(B, { kind: "number", control: "slider", label: "Rings", value: 32, min: 4, max: 96, step: 1, onChange: () => {
3235
3220
  } }) })
3236
3221
  ] }) }) }),
3237
3222
  /* @__PURE__ */ jsx(Cell, { label: "PrefsForm", children: /* @__PURE__ */ jsx(
@@ -3242,23 +3227,23 @@ function PanelsAndRows() {
3242
3227
  onChange: (path, value) => setPrefs((prev) => setAt(prev, path, value))
3243
3228
  }
3244
3229
  ) }),
3245
- /* @__PURE__ */ jsx(Cell, { label: "LayerStack", children: /* @__PURE__ */ jsx(
3246
- c4,
3230
+ /* @__PURE__ */ jsx(Cell, { label: "LayerList", children: /* @__PURE__ */ jsx(
3231
+ D,
3247
3232
  {
3248
3233
  items: layers,
3249
- onReorder: (ids) => setLayers(ids.flatMap((id) => layers.filter((item) => item.id === id))),
3234
+ onReorder: (move) => setLayers(S2(layers, move)),
3250
3235
  renderBody: (item) => /* @__PURE__ */ jsxs("div", { children: [
3251
3236
  "settings for ",
3252
3237
  item.label
3253
3238
  ] })
3254
3239
  }
3255
3240
  ) }),
3256
- /* @__PURE__ */ jsx(Cell, { label: "Sidebar, SidebarPanel", children: /* @__PURE__ */ jsx("div", { className: "lk-specimen__box", children: /* @__PURE__ */ jsx(n5, { side: "right", ariaLabel: "Specimen sidebar", children: /* @__PURE__ */ jsx(
3257
- s4,
3241
+ /* @__PURE__ */ jsx(Cell, { label: "Sidebar, SidebarPanel", children: /* @__PURE__ */ jsx("div", { className: "lk-specimen__box", children: /* @__PURE__ */ jsx(n6, { side: "right", ariaLabel: "Specimen sidebar", children: /* @__PURE__ */ jsx(
3242
+ s5,
3258
3243
  {
3259
3244
  title: "Selection",
3260
3245
  collapsed: panelCollapsed,
3261
- onToggleCollapse: () => setPanelCollapsed((v2) => !v2),
3246
+ onToggleCollapse: () => setPanelCollapsed((v) => !v),
3262
3247
  onHide: () => {
3263
3248
  },
3264
3249
  children: /* @__PURE__ */ jsx("div", { className: "lk-specimen__pad", children: "2 items selected" })
@@ -3270,12 +3255,12 @@ function OverlaysAndFeedback() {
3270
3255
  const calloutAnchor = useRef(null);
3271
3256
  const [calloutOpen, setCalloutOpen] = useState(false);
3272
3257
  const [dialogOpen, setDialogOpen] = useState(false);
3273
- const toasts = useMemo(() => m2(), []);
3258
+ const toasts = useMemo(() => m4(), []);
3274
3259
  return /* @__PURE__ */ jsxs(Section, { title: "Overlays & feedback", children: [
3275
3260
  /* @__PURE__ */ jsx(Cell, { label: "Tooltip, Callout, Dialog, Toast", children: /* @__PURE__ */ jsxs("div", { className: "lk-specimen__row", children: [
3276
- /* @__PURE__ */ jsxs(c2, { children: [
3261
+ /* @__PURE__ */ jsxs(l2, { children: [
3277
3262
  /* @__PURE__ */ jsx(Focusable, { children: /* @__PURE__ */ jsx("button", { type: "button", children: "Hover me" }) }),
3278
- /* @__PURE__ */ jsx(l, { placement: "bottom", children: "Duplicates the selected layer" })
3263
+ /* @__PURE__ */ jsx(u, { placement: "bottom", children: "Duplicates the selected layer" })
3279
3264
  ] }),
3280
3265
  /* @__PURE__ */ jsx("button", { type: "button", ref: calloutAnchor, onClick: () => setCalloutOpen(true), children: "Callout" }),
3281
3266
  /* @__PURE__ */ jsx(
@@ -3284,24 +3269,24 @@ function OverlaysAndFeedback() {
3284
3269
  triggerRef: calloutAnchor,
3285
3270
  isOpen: calloutOpen,
3286
3271
  onOpenChange: setCalloutOpen,
3287
- tone: "info",
3288
- title: "Info",
3272
+ stance: "notice",
3273
+ title: "Notice",
3289
3274
  children: "Neutral guidance."
3290
3275
  }
3291
3276
  ),
3292
- /* @__PURE__ */ jsx(a5, { onClick: () => setDialogOpen(true), children: "Dialog" }),
3277
+ /* @__PURE__ */ jsx(c, { onClick: () => setDialogOpen(true), children: "Dialog" }),
3293
3278
  /* @__PURE__ */ jsx(
3294
- l5,
3279
+ u3,
3295
3280
  {
3296
3281
  isOpen: dialogOpen,
3297
3282
  onOpenChange: setDialogOpen,
3298
3283
  title: "Preferences",
3299
- footer: /* @__PURE__ */ jsx(a5, { variant: "primary", onClick: () => setDialogOpen(false), children: "OK" }),
3284
+ footer: /* @__PURE__ */ jsx(c, { variant: "primary", onClick: () => setDialogOpen(false), children: "OK" }),
3300
3285
  children: /* @__PURE__ */ jsx("p", { children: "Dialog body." })
3301
3286
  }
3302
3287
  ),
3303
3288
  /* @__PURE__ */ jsx(
3304
- a5,
3289
+ c,
3305
3290
  {
3306
3291
  onClick: () => toasts.add("success", "Saved", { description: "All changes stored.", ttlMs: null }),
3307
3292
  children: "Toast"
@@ -3310,29 +3295,29 @@ function OverlaysAndFeedback() {
3310
3295
  /* @__PURE__ */ jsx(S4, { queue: toasts, placement: "bottom-right" })
3311
3296
  ] }) }),
3312
3297
  /* @__PURE__ */ jsx(Cell, { label: "Powerline", children: /* @__PURE__ */ jsx(
3313
- r9,
3298
+ r4,
3314
3299
  {
3315
3300
  variant: "solid",
3316
3301
  size: "sm",
3317
3302
  segments: [
3318
- { text: "main", tone: "accent", endCap: "chevron" },
3319
- { text: "\u2713 12", tone: "info", endCap: "slant" },
3320
- { text: "~/proj", tone: "muted" }
3303
+ { text: "main", status: "accent", endCap: "chevron" },
3304
+ { text: "\u2713 12", status: "info", endCap: "slant" },
3305
+ { text: "~/proj", status: "muted" }
3321
3306
  ]
3322
3307
  }
3323
3308
  ) }),
3324
- /* @__PURE__ */ jsx(Cell, { label: "StatusBar", children: /* @__PURE__ */ jsxs(n6, { ariaLabel: "Editor status", children: [
3325
- /* @__PURE__ */ jsx(r10, { children: "tool: select" }),
3326
- /* @__PURE__ */ jsx(r10, { children: "sel: 3" }),
3309
+ /* @__PURE__ */ jsx(Cell, { label: "StatusBar", children: /* @__PURE__ */ jsxs(n7, { ariaLabel: "Editor status", children: [
3310
+ /* @__PURE__ */ jsx(r5, { children: "tool: select" }),
3311
+ /* @__PURE__ */ jsx(r5, { children: "sel: 3" }),
3327
3312
  /* @__PURE__ */ jsx(i5, {}),
3328
- /* @__PURE__ */ jsx(r10, { muted: true, children: "0.7.0" })
3313
+ /* @__PURE__ */ jsx(r5, { muted: true, children: "0.7.0" })
3329
3314
  ] }) })
3330
3315
  ] });
3331
3316
  }
3332
3317
  function ListsAndData() {
3333
3318
  return /* @__PURE__ */ jsxs(Section, { title: "Lists & data", children: [
3334
3319
  /* @__PURE__ */ jsx(Cell, { label: "ItemList", children: /* @__PURE__ */ jsx(
3335
- i4,
3320
+ p2,
3336
3321
  {
3337
3322
  rows: [
3338
3323
  { id: "a", label: "Draw rect" },
@@ -3343,7 +3328,7 @@ function ListsAndData() {
3343
3328
  }
3344
3329
  ) }),
3345
3330
  /* @__PURE__ */ jsx(Cell, { label: "DataGrid", children: /* @__PURE__ */ jsx(
3346
- s2,
3331
+ f,
3347
3332
  {
3348
3333
  rows: [
3349
3334
  { id: "1", name: "accent", count: 3 },
@@ -3351,8 +3336,8 @@ function ListsAndData() {
3351
3336
  { id: "3", name: "danger", count: 2 }
3352
3337
  ],
3353
3338
  columns: [
3354
- { id: "name", header: "name", accessor: (r9) => r9.name, sortable: true },
3355
- { id: "count", header: "count", accessor: (r9) => r9.count, sortable: true }
3339
+ { id: "name", header: "name", accessor: (r4) => r4.name, sortable: true },
3340
+ { id: "count", header: "count", accessor: (r4) => r4.count, sortable: true }
3356
3341
  ],
3357
3342
  defaultSort: { columnId: "name", direction: "asc" }
3358
3343
  }
@@ -3363,8 +3348,8 @@ function ToolChrome() {
3363
3348
  const [tool, setTool] = useState("select");
3364
3349
  const [paneWidth, setPaneWidth] = useState(160);
3365
3350
  return /* @__PURE__ */ jsxs(Section, { title: "Tool chrome", children: [
3366
- /* @__PURE__ */ jsx(Cell, { label: "ToolGroup, ToolButton", children: /* @__PURE__ */ jsx(n7, { orientation: "horizontal", ariaLabel: "Tools", children: ["select", "rect", "ellipse"].map((id) => /* @__PURE__ */ jsx(
3367
- o4,
3351
+ /* @__PURE__ */ jsx(Cell, { label: "ToolGroup, ToolButton", children: /* @__PURE__ */ jsx(n8, { orientation: "horizontal", ariaLabel: "Tools", children: ["select", "rect", "ellipse"].map((id) => /* @__PURE__ */ jsx(
3352
+ o3,
3368
3353
  {
3369
3354
  icon: /* @__PURE__ */ jsx(Dot, {}),
3370
3355
  label: id,
@@ -3375,14 +3360,14 @@ function ToolChrome() {
3375
3360
  },
3376
3361
  id
3377
3362
  )) }) }),
3378
- /* @__PURE__ */ jsx(Cell, { label: "ToolOptionsBar", children: /* @__PURE__ */ jsxs(c5, { label: "Text", children: [
3379
- /* @__PURE__ */ jsx(a5, { size: "sm", variant: "ghost", iconOnly: true, ariaLabel: "Bold", children: "B" }),
3380
- /* @__PURE__ */ jsx(a5, { size: "sm", variant: "ghost", iconOnly: true, ariaLabel: "Italic", children: "I" })
3363
+ /* @__PURE__ */ jsx(Cell, { label: "ToolOptionsBar", children: /* @__PURE__ */ jsxs(c3, { label: "Text", children: [
3364
+ /* @__PURE__ */ jsx(c, { size: "sm", variant: "ghost", iconOnly: true, ariaLabel: "Bold", children: "B" }),
3365
+ /* @__PURE__ */ jsx(c, { size: "sm", variant: "ghost", iconOnly: true, ariaLabel: "Italic", children: "I" })
3381
3366
  ] }) }),
3382
3367
  /* @__PURE__ */ jsx(Cell, { label: "ResizeHandle", children: /* @__PURE__ */ jsxs("div", { className: "lk-specimen__box", children: [
3383
3368
  /* @__PURE__ */ jsx("div", { className: "lk-specimen__box-main", children: "content" }),
3384
3369
  /* @__PURE__ */ jsx(
3385
- c6,
3370
+ c4,
3386
3371
  {
3387
3372
  value: paneWidth,
3388
3373
  min: 100,
@@ -3451,7 +3436,7 @@ function EditorsAndPlots() {
3451
3436
  const [playhead, setPlayhead] = useState(0);
3452
3437
  return /* @__PURE__ */ jsxs(Section, { title: "Editors & plots", children: [
3453
3438
  /* @__PURE__ */ jsx(Cell, { label: "Plot2D", children: /* @__PURE__ */ jsx(
3454
- w2,
3439
+ w,
3455
3440
  {
3456
3441
  width: 260,
3457
3442
  height: 130,
@@ -3462,7 +3447,7 @@ function EditorsAndPlots() {
3462
3447
  }
3463
3448
  ) }),
3464
3449
  /* @__PURE__ */ jsx(Cell, { label: "CurveEditor", children: /* @__PURE__ */ jsx(
3465
- L2,
3450
+ L,
3466
3451
  {
3467
3452
  value: curve,
3468
3453
  onInput: setCurve,
@@ -3477,7 +3462,7 @@ function EditorsAndPlots() {
3477
3462
  }
3478
3463
  ) }),
3479
3464
  /* @__PURE__ */ jsx(Cell, { label: "PointPlotter", children: /* @__PURE__ */ jsx(
3480
- n8,
3465
+ n9,
3481
3466
  {
3482
3467
  value: points,
3483
3468
  onInput: setPoints,
@@ -3491,7 +3476,7 @@ function EditorsAndPlots() {
3491
3476
  }
3492
3477
  ) }),
3493
3478
  /* @__PURE__ */ jsx(Cell, { label: "BandEditor", wide: true, children: /* @__PURE__ */ jsx(
3494
- k3,
3479
+ k,
3495
3480
  {
3496
3481
  min: 1 / 64,
3497
3482
  max: 1 / 2,
@@ -3518,7 +3503,6 @@ function EditorsAndPlots() {
3518
3503
  ] });
3519
3504
  }
3520
3505
  function LabChrome() {
3521
- const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
3522
3506
  const [zoom, setZoom] = useState(1);
3523
3507
  return /* @__PURE__ */ jsxs(Section, { title: "Lab chrome", children: [
3524
3508
  /* @__PURE__ */ jsx(Cell, { label: "Toolbar", wide: true, children: /* @__PURE__ */ jsxs(Toolbar, { "aria-label": "Trial actions", children: [
@@ -3536,18 +3520,6 @@ function LabChrome() {
3536
3520
  /* @__PURE__ */ jsx(StatusBar.Section, { children: "Items: 12" }),
3537
3521
  /* @__PURE__ */ jsx(StatusBar.Section, { children: "Zoom: 100%" })
3538
3522
  ] }) }),
3539
- /* @__PURE__ */ jsx(Cell, { label: "Sidebar", children: /* @__PURE__ */ jsxs("div", { className: "lk-specimen__box", children: [
3540
- /* @__PURE__ */ jsx("div", { className: "lk-specimen__box-main", children: "main" }),
3541
- /* @__PURE__ */ jsx(
3542
- Sidebar,
3543
- {
3544
- title: "Controls",
3545
- collapsed: sidebarCollapsed,
3546
- onToggle: () => setSidebarCollapsed((v2) => !v2),
3547
- children: /* @__PURE__ */ jsx("p", { children: "One slider" })
3548
- }
3549
- )
3550
- ] }) }),
3551
3523
  /* @__PURE__ */ jsxs(Cell, { label: "Legend, JobProgress", children: [
3552
3524
  /* @__PURE__ */ jsx(Legend, { entries: LEGEND }),
3553
3525
  /* @__PURE__ */ jsx(JobProgress, { job: JOB })
@@ -3582,6 +3554,6 @@ function Specimen({ className }) {
3582
3554
  ] });
3583
3555
  }
3584
3556
 
3585
- export { ANNOTATION_TOOLS, ANNOTATION_WEASEL_TOOLS, AnnotationOverlay, AnnotationTargets, Lab, LabPalette, LabRoot, LabShell, LabSwitcher, SPECIMEN_SECTIONS, Specimen, Trial, TrialBody, TrialChrome, Workspace, addTrial, annotationToolInfo, annotationsFromJSON, capturePlan, captureTarget, cloneTrial, closeTrial, composeCaptureSvg, createAnnotationScene, createAnnotationStore, createMarkDrawOne, currentPage, defineInstrument, fitView, fracContains, fracEncloses, fracToWorld, fromWeaselView, interstellarTheme, isStale, markCommands, markSvgNodes, reorderTrials, resetTrial, resolveMarkStyle, roundFrac, seenFrom, toWeaselView, validateConfigSchema, worldToFrac };
3557
+ export { ANNOTATION_TOOLS, ANNOTATION_WEASEL_TOOLS, AnnotationOverlay, AnnotationTargets, Lab, LabBoundary, LabPalette, LabRoot, LabShell, LabSwitcher, SPECIMEN_SECTIONS, Specimen, Trial, TrialBody, TrialChrome, Workspace, addTrial, annotationToolInfo, annotationsFromJSON, capturePlan, captureTarget, cloneTrial, closeTrial, composeCaptureSvg, createAnnotationScene, createAnnotationStore, createMarkDrawOne, currentPage, defineInstrument, fitView, fracContains, fracEncloses, fracToWorld, fromWeaselView, interstellarTheme, isStale, markCommands, markSvgNodes, reorderTrials, resetTrial, resolveMarkStyle, roundFrac, seenFrom, toWeaselView, validateConfigSchema, worldToFrac };
3586
3558
  //# sourceMappingURL=index.js.map
3587
3559
  //# sourceMappingURL=index.js.map