@weasel-js/labkit 1.4.4 → 1.5.1
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.
- package/README.md +54 -6
- package/dist/_dts/{CanvasStackContext-kTEZvEgE.d.ts → CanvasStackContext-CJNMS6mz.d.ts} +1 -1
- package/dist/_dts/{PrefsForm.d-DDHFANkc.d.ts → PrefsForm.d-DPy9I8It.d.ts} +4 -0
- package/dist/_dts/Select.d-Gwr8fLpK.d.ts +453 -0
- package/dist/_dts/{frac-z7ker2Vx.d.ts → frac-B4okC2lX.d.ts} +291 -31
- package/dist/_dts/{index-Blv9uQzu.d.ts → index-BNdz-tNd.d.ts} +105 -17
- package/dist/_dts/index-CSJoj4LC.d.ts +248 -0
- package/dist/_dts/{types-B9_zrHmb.d.ts → types-DzoNY1pO.d.ts} +91 -4
- package/dist/_dts/usePanZoom-Pzf9f2jh.d.ts +160 -0
- package/dist/_dts/useTrialState-uLlmaccn.d.ts +212 -0
- package/dist/canvas/index.d.ts +18 -129
- package/dist/canvas/index.js +4 -2
- package/dist/chrome/index.d.ts +5 -93
- package/dist/chrome/index.js +10 -6
- package/dist/chunk-7PFH3CNM.js +150 -0
- package/dist/chunk-7PFH3CNM.js.map +1 -0
- package/dist/{chunk-I6JCVE24.js → chunk-CEIUBPPW.js} +143 -17
- package/dist/chunk-CEIUBPPW.js.map +1 -0
- package/dist/chunk-EH7UEQV7.js +590 -0
- package/dist/chunk-EH7UEQV7.js.map +1 -0
- package/dist/{chunk-MOM3GOVY.js → chunk-EHGVROVV.js} +125 -27
- package/dist/chunk-EHGVROVV.js.map +1 -0
- package/dist/{chunk-TJ7QY3OC.js → chunk-ERFMC6WU.js} +160 -78
- package/dist/chunk-ERFMC6WU.js.map +1 -0
- package/dist/{chunk-CTRKTLYZ.js → chunk-H6ZAOWNE.js} +11 -11
- package/dist/chunk-H6ZAOWNE.js.map +1 -0
- package/dist/{chunk-64ZCN3DA.js → chunk-IHUVQ3TX.js} +250 -160
- package/dist/chunk-IHUVQ3TX.js.map +1 -0
- package/dist/{chunk-FQMJUVHJ.js → chunk-IJJUK4FU.js} +53 -46
- package/dist/chunk-IJJUK4FU.js.map +1 -0
- package/dist/chunk-IXTQI7JX.js +737 -0
- package/dist/chunk-IXTQI7JX.js.map +1 -0
- package/dist/{chunk-BKFVHKJH.js → chunk-MDVTK5U3.js} +4 -4
- package/dist/{chunk-BKFVHKJH.js.map → chunk-MDVTK5U3.js.map} +1 -1
- package/dist/chunk-PHK4W562.js +72 -0
- package/dist/chunk-PHK4W562.js.map +1 -0
- package/dist/chunk-PJ7WEQBJ.js +18 -0
- package/dist/chunk-PJ7WEQBJ.js.map +1 -0
- package/dist/chunk-RWNDDKOH.js +682 -0
- package/dist/chunk-RWNDDKOH.js.map +1 -0
- package/dist/chunk-T3EC2DXD.js +12628 -0
- package/dist/chunk-T3EC2DXD.js.map +1 -0
- package/dist/{chunk-SMHP6XZ4.js → chunk-UN4U4P63.js} +10 -8
- package/dist/chunk-UN4U4P63.js.map +1 -0
- package/dist/chunk-WIG6XHJ7.js +35 -0
- package/dist/chunk-WIG6XHJ7.js.map +1 -0
- package/dist/chunk-Z76KEZAX.js +15 -0
- package/dist/chunk-Z76KEZAX.js.map +1 -0
- package/dist/chunk-ZDHY47EV.js +363 -0
- package/dist/chunk-ZDHY47EV.js.map +1 -0
- package/dist/config/index.d.ts +276 -0
- package/dist/config/index.js +8 -0
- package/dist/config/index.js.map +1 -0
- package/dist/controls/index.d.ts +3 -4
- package/dist/controls/index.js +4 -3
- package/dist/dragdrop/index.d.ts +3 -5
- package/dist/index.d.ts +266 -413
- package/dist/index.js +1775 -2251
- package/dist/index.js.map +1 -1
- package/dist/layers/index.d.ts +4 -6
- package/dist/layers/index.js +2 -2
- package/dist/loupe/index.d.ts +69 -20
- package/dist/loupe/index.js +2 -2
- package/dist/passthrough/weasel-ui.d.ts +175 -309
- package/dist/passthrough/weasel-ui.js +1 -1
- package/dist/primitives/index.d.ts +55 -6
- package/dist/primitives/index.js +6 -4
- package/dist/state/index.d.ts +13 -8
- package/dist/state/index.js +18 -13
- package/dist/state/index.js.map +1 -1
- package/dist/styles.css +223 -76
- package/dist/surface/index.d.ts +44 -7
- package/dist/surface/index.js +2 -1
- package/dist/ui/layers/index.js +1 -1
- package/dist/undo/index.d.ts +3 -5
- package/package.json +15 -8
- package/src/annotations/AnnotationOverlay.tsx +56 -5
- package/src/annotations/Annotations.less +4 -0
- package/src/annotations/Annotations.overlay.test.tsx +105 -6
- package/src/annotations/drawOne.test.ts +1 -1
- package/src/annotations/drawOne.ts +2 -2
- package/src/annotations/paint.test.ts +2 -2
- package/src/annotations/paint.ts +1 -1
- package/src/annotations/preload.ts +6 -0
- package/src/annotations/store.test.ts +18 -0
- package/src/annotations/store.ts +5 -4
- package/src/annotations/svgNodes.test.ts +2 -2
- package/src/annotations/svgNodes.ts +1 -0
- package/src/annotations/toolMap.test.ts +9 -5
- package/src/annotations/toolMap.ts +6 -3
- package/src/annotations/types.ts +6 -3
- package/src/canvas/CameraWheelContext.ts +12 -0
- package/src/canvas/CanvasStack.stories.tsx +1 -1
- package/src/canvas/CanvasStack.test.tsx +25 -0
- package/src/canvas/CanvasStack.tsx +31 -4
- package/src/canvas/Stage.less +18 -0
- package/src/canvas/Stage.test.tsx +186 -0
- package/src/canvas/Stage.tsx +134 -0
- package/src/canvas/camera.test.ts +17 -2
- package/src/canvas/camera.ts +9 -9
- package/src/canvas/index.ts +4 -0
- package/src/canvas/usePanZoom.test.ts +28 -0
- package/src/canvas/usePanZoom.ts +21 -9
- package/src/chrome/ChromeRegions.stories.tsx +1 -4
- package/src/chrome/LabChrome.tsx +130 -0
- package/src/chrome/builtins.test.ts +1 -0
- package/src/chrome/builtins.tsx +21 -31
- package/src/chrome/index.ts +16 -0
- package/src/chrome/labRegions.test.tsx +208 -0
- package/src/chrome/labTypes.ts +50 -0
- package/src/chrome/merge.ts +7 -9
- package/src/chrome/regions/PaletteRegion.test.tsx +6 -4
- package/src/chrome/regions/PaletteRegion.tsx +16 -9
- package/src/chrome/regions/SidebarRegion.stories.tsx +44 -0
- package/src/chrome/regions/SidebarRegion.tsx +25 -13
- package/src/chrome/regions/StatusRegion.tsx +15 -8
- package/src/chrome/regions/ToolbarRegion.tsx +34 -16
- package/src/chrome/types.ts +50 -20
- package/src/config/auto.test.ts +12 -0
- package/src/config/auto.ts +15 -0
- package/src/config/autoConfig.test.ts +107 -0
- package/src/config/autoConfig.ts +153 -0
- package/src/config/builder.test.ts +42 -0
- package/src/config/builder.ts +68 -17
- package/src/config/declarationEmit.fixture.ts +11 -0
- package/src/config/declarationEmit.test.ts +51 -0
- package/src/config/entry.test.ts +46 -0
- package/src/config/index.ts +16 -1
- package/src/config/nodeClasses.test.ts +18 -0
- package/src/config/path.ts +7 -2
- package/src/config/resolve.test.ts +25 -0
- package/src/config/resolve.ts +17 -1
- package/src/config/types.ts +34 -2
- package/src/config/useResolvedConfig.ts +26 -0
- package/src/controls/AutoControls.stories.tsx +88 -0
- package/src/controls/ControlPanel.stories.tsx +42 -1
- package/src/controls/ControlPanel.test.tsx +530 -4
- package/src/controls/ControlPanel.tsx +562 -82
- package/src/fake-indexeddb-auto.d.ts +5 -0
- package/src/index.test.ts +7 -0
- package/src/index.ts +66 -5
- package/src/instrument/serializers.test.ts +22 -0
- package/src/instrument/serializers.ts +40 -1
- package/src/instrument/types.ts +25 -1
- package/src/lab/Lab.chrome.test.tsx +16 -0
- package/src/lab/Lab.less +4 -13
- package/src/lab/Lab.persist.test.tsx +147 -0
- package/src/lab/Lab.stories.tsx +1 -3
- package/src/lab/Lab.surface.test.tsx +71 -3
- package/src/lab/Lab.test.tsx +168 -16
- package/src/lab/Lab.tsx +434 -129
- package/src/lab/LabContext.ts +8 -0
- package/src/lab/LabFit.stories.less +18 -0
- package/src/lab/LabFit.stories.tsx +219 -0
- package/src/lab/LabFullChrome.stories.tsx +1 -4
- package/src/lab/LabHeader.test.tsx +40 -9
- package/src/lab/LabHeader.tsx +7 -14
- package/src/lab/LabPalette.tsx +13 -26
- package/src/lab/LabRoot.test.tsx +56 -0
- package/src/lab/LabRoot.tsx +47 -0
- package/src/lab/LabShell.less +73 -15
- package/src/lab/LabShell.stories.tsx +50 -1
- package/src/lab/LabShell.tsx +18 -27
- package/src/lab/LabSwitcher.less +18 -11
- package/src/lab/LabSwitcher.test.tsx +14 -9
- package/src/lab/LabSwitcher.tsx +8 -4
- package/src/lab/Workspace.less +1 -1
- package/src/lab/Workspace.stories.tsx +1 -1
- package/src/lab/Workspace.surface.test.tsx +1 -0
- package/src/lab/fitCheck.test.ts +57 -0
- package/src/lab/fitCheck.ts +125 -0
- package/src/lab/index.ts +2 -0
- package/src/layers/LayerList.stories.tsx +1 -1
- package/src/loupe/AGENTS.md +17 -5
- package/src/loupe/Loupe.less +1 -1
- package/src/loupe/LoupeGestures.tsx +67 -0
- package/src/loupe/TrialLoupe.tsx +43 -28
- package/src/loupe/canvasLens.ts +1 -1
- package/src/loupe/index.ts +4 -0
- package/src/loupe/loupeActions.ts +98 -0
- package/src/loupe/types.ts +1 -1
- package/src/loupe/useLoupe.test.tsx +60 -3
- package/src/loupe/useLoupe.ts +29 -49
- package/src/passthrough/weasel-ui.ts +9 -0
- package/src/primitives/FloatingPanel.stories.tsx +14 -2
- package/src/primitives/FloatingPanel.test.tsx +47 -16
- package/src/primitives/FloatingPanel.tsx +11 -25
- package/src/primitives/FpsMeter.stories.tsx +1 -1
- package/src/primitives/JobProgress.stories.tsx +1 -1
- package/src/primitives/Legend.stories.tsx +1 -1
- package/src/primitives/ScaleIndicator.stories.tsx +1 -1
- package/src/primitives/Sidebar.less +7 -0
- package/src/primitives/Sidebar.stories.tsx +1 -1
- package/src/primitives/Split.less +14 -0
- package/src/primitives/Split.test.tsx +133 -0
- package/src/primitives/Split.tsx +175 -0
- package/src/primitives/StatusBar.stories.tsx +1 -1
- package/src/primitives/Toolbar.stories.tsx +1 -1
- package/src/primitives/ZoomControl.tsx +5 -2
- package/src/primitives/index.ts +2 -0
- package/src/specimen/Specimen.less +95 -0
- package/src/specimen/Specimen.stories.tsx +13 -0
- package/src/specimen/Specimen.test.tsx +13 -0
- package/src/specimen/Specimen.tsx +888 -0
- package/src/state/Persistence.stories.tsx +75 -0
- package/src/state/Persistence.tsx +33 -0
- package/src/state/SingletonExperiment.test.tsx +47 -53
- package/src/state/SingletonExperiment.tsx +24 -13
- package/src/state/adapterContract.ts +116 -0
- package/src/state/adapters.test.ts +113 -61
- package/src/state/adapters.ts +328 -69
- package/src/state/document.test.ts +71 -96
- package/src/state/document.ts +66 -52
- package/src/state/helpers.test.ts +1 -1
- package/src/state/index.ts +8 -0
- package/src/state/labRecords.test.ts +105 -0
- package/src/state/labRecords.ts +160 -0
- package/src/state/openLabStore.test.ts +658 -0
- package/src/state/openLabStore.ts +403 -0
- package/src/state/records.test.ts +234 -0
- package/src/state/records.ts +219 -0
- package/src/state/store.test.ts +169 -635
- package/src/state/store.ts +146 -163
- package/src/state/toolSlot.test.ts +1 -1
- package/src/state/types.ts +65 -17
- package/src/state/useOpenOnce.ts +68 -0
- package/src/state/usePersistedState.test.tsx +125 -0
- package/src/state/usePersistedState.ts +66 -0
- package/src/state/useTrialState.test.tsx +87 -3
- package/src/state/useTrialState.ts +9 -1
- package/src/state/view.test.ts +49 -15
- package/src/state/view.ts +18 -1
- package/src/styles.less +3 -0
- package/src/surface/AGENTS.md +39 -7
- package/src/surface/SurfaceContext.ts +26 -3
- package/src/surface/index.ts +2 -0
- package/src/surface/useSurfaceTile.test.tsx +1 -0
- package/src/surface/useSurfaceTile.ts +6 -5
- package/src/surface/useTiledSurface.test.tsx +231 -1
- package/src/surface/useTiledSurface.ts +76 -15
- package/src/theme/Interstellar.stories.tsx +9 -9
- package/src/theme/interstellar.test.ts +17 -6
- package/src/theme/interstellar.theme.json +180 -0
- package/src/theme/interstellar.ts +8 -5
- package/src/tools/labTool.ts +11 -0
- package/src/trial/Trial.annotations.persist.test.tsx +100 -58
- package/src/trial/Trial.annotations.test.tsx +59 -7
- package/src/trial/Trial.canvas.test.tsx +32 -0
- package/src/trial/Trial.config.test.tsx +75 -2
- package/src/trial/Trial.job.test.tsx +3 -3
- package/src/trial/Trial.less +5 -26
- package/src/trial/Trial.stories.tsx +5 -3
- package/src/trial/Trial.test.tsx +31 -4
- package/src/trial/Trial.trialId.test.tsx +23 -1
- package/src/trial/Trial.tsx +139 -52
- package/src/trial/TrialBody.tsx +17 -141
- package/src/trial/TrialChrome.tsx +24 -7
- package/src/trial/trialOps.test.ts +101 -1
- package/src/trial/trialOps.ts +67 -7
- package/dist/_dts/types-BP2OCcpg.d.ts +0 -155
- package/dist/_dts/types-x92Kfeme.d.ts +0 -62
- package/dist/_dts/useTrialState-D6Vb3T-g.d.ts +0 -99
- package/dist/chunk-2P6PP5N4.js +0 -553
- package/dist/chunk-2P6PP5N4.js.map +0 -1
- package/dist/chunk-64ZCN3DA.js.map +0 -1
- package/dist/chunk-CTRKTLYZ.js.map +0 -1
- package/dist/chunk-E44SU6XS.js +0 -50
- package/dist/chunk-E44SU6XS.js.map +0 -1
- package/dist/chunk-FQMJUVHJ.js.map +0 -1
- package/dist/chunk-I6JCVE24.js.map +0 -1
- package/dist/chunk-MOM3GOVY.js.map +0 -1
- package/dist/chunk-SMHP6XZ4.js.map +0 -1
- package/dist/chunk-TJ7QY3OC.js.map +0 -1
- package/dist/chunk-U3IYHIAE.js +0 -343
- package/dist/chunk-U3IYHIAE.js.map +0 -1
- package/dist/chunk-W3ECWC2K.js +0 -7335
- package/dist/chunk-W3ECWC2K.js.map +0 -1
- package/src/theme/interstellar.tokens.json +0 -61
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { ComponentType, ReactNode, RefObject } from 'react';
|
|
2
|
-
import { R as ResolvedConfig, a as
|
|
3
|
-
import { C as ConfigField } from './types-x92Kfeme.js';
|
|
4
|
-
import { c as SavedSnapshot, i as TrialInfo } from './types-BP2OCcpg.js';
|
|
2
|
+
import { R as ResolvedConfig, C as ConfigPath, V as ValueAtPath, a as ConfigField, b as ConfigSchema } from './types-DzoNY1pO.js';
|
|
5
3
|
import { J as JobHandle, a as JobCapability } from './types-DJ79Tg5J.js';
|
|
6
4
|
import { Scene } from '@weasel-js/core';
|
|
7
5
|
|
|
@@ -33,15 +31,223 @@ declare function resolveFrame(spec: WorldSpec | undefined, size: ViewportSize):
|
|
|
33
31
|
* `draw` works in them. Must stay the exact inverse of `screenToWorld`. */
|
|
34
32
|
declare function applyCamera(ctx: CanvasRenderingContext2D, view: ViewTransform, frame?: WorldFrame): void;
|
|
35
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Written at a config path to mean "do not pin this — let the instrument
|
|
36
|
+
* decide". Accepted by `setConfig`, by a trial's `configSeed`, and by
|
|
37
|
+
* `.initial()` in a schema. It is normalized into the trial's set of unpinned
|
|
38
|
+
* paths on the way into the store and is never itself stored, so a serialized
|
|
39
|
+
* trial contains no sentinel and the last pinned value survives.
|
|
40
|
+
*/
|
|
41
|
+
declare const auto: unique symbol;
|
|
42
|
+
/** The type of the `auto` sentinel, for widening a value parameter. */
|
|
43
|
+
type Auto = typeof auto;
|
|
44
|
+
declare function isAuto(value: unknown): value is Auto;
|
|
45
|
+
|
|
46
|
+
/** A sidebar section torn out of its trial, and where it went. */
|
|
47
|
+
interface UndockedPanel {
|
|
48
|
+
trialId: string;
|
|
49
|
+
sectionId: string;
|
|
50
|
+
as: 'tile' | 'floating';
|
|
51
|
+
}
|
|
52
|
+
/** Undocked panels, keyed by {@link panelKey}. */
|
|
53
|
+
type UndockedPanels = Record<string, UndockedPanel>;
|
|
54
|
+
declare function panelKey(trialId: string, sectionId: string): string;
|
|
55
|
+
declare function undockPanel(panels: UndockedPanels, trialId: string, sectionId: string, as?: UndockedPanel['as']): UndockedPanels;
|
|
56
|
+
/** Dock one section back, or — with no `sectionId` — every panel the trial
|
|
57
|
+
* owns, which is what closing a trial wants. */
|
|
58
|
+
declare function dockPanel(panels: UndockedPanels, trialId: string, sectionId?: string): UndockedPanels;
|
|
59
|
+
|
|
60
|
+
/** A trial's undo history, as snapshots of its state either side of the
|
|
61
|
+
* present. */
|
|
62
|
+
interface UndoStack {
|
|
63
|
+
past: unknown[];
|
|
64
|
+
future: unknown[];
|
|
65
|
+
}
|
|
66
|
+
/** The trial a per-trial call is coming from. `id` is the id `useTileId`
|
|
67
|
+
* scopes a surface tile under, so a consumer keying its own per-trial
|
|
68
|
+
* registry and labkit's tiles agree on the key. */
|
|
69
|
+
interface TrialInfo<TV = unknown> {
|
|
70
|
+
id: string;
|
|
71
|
+
/** The trial's view, in whatever shape the instrument keeps it. */
|
|
72
|
+
view: TV;
|
|
73
|
+
}
|
|
74
|
+
/** One trial as the store holds it: which instrument it runs, that
|
|
75
|
+
* instrument's config and state, the camera, and the undo history. */
|
|
76
|
+
interface TrialRecord<TS = unknown, TC = unknown, TV = unknown> {
|
|
77
|
+
id: string;
|
|
78
|
+
instrumentName: string;
|
|
79
|
+
config: TC;
|
|
80
|
+
state: TS;
|
|
81
|
+
/** Opaque to labkit: persisted, restored on Reset and handed to the instrument,
|
|
82
|
+
* but never read into. A 3D lab puts an orbit here and keeps all three. */
|
|
83
|
+
view: TV;
|
|
84
|
+
/** The config `addTrial` opened this trial on, overlaid on the instrument's
|
|
85
|
+
* defaults. Kept so Reset restores the trial's own subject rather than the
|
|
86
|
+
* bare defaults. */
|
|
87
|
+
configSeed?: Partial<TC>;
|
|
88
|
+
/** Dotted paths the trial's seed config opened as auto. Kept beside
|
|
89
|
+
* `configSeed`, which cannot carry them: the sentinel is stripped on the way
|
|
90
|
+
* in, so Reset would otherwise have no way back to the state the trial
|
|
91
|
+
* opened in. Absent means none. */
|
|
92
|
+
autoSeed?: readonly string[];
|
|
93
|
+
/** Dotted paths this trial has unpinned. The value at such a path stays in
|
|
94
|
+
* `config` — it is what the field pins back to — but the instrument reads
|
|
95
|
+
* the resolver's value, or `undefined`, instead. Absent means none. */
|
|
96
|
+
auto?: readonly string[];
|
|
97
|
+
/** This trial's own tool slot. Undefined means it reads the lab's. */
|
|
98
|
+
activeToolId?: string | null;
|
|
99
|
+
/** The extent the trial's sidebar was last dragged to, in pixels. Undefined
|
|
100
|
+
* until someone moves the seam. */
|
|
101
|
+
sidebarWidth?: number;
|
|
102
|
+
/** What the title bar reads. Undefined — the state a trial opens in, and the
|
|
103
|
+
* one `setTitle(null)` returns it to — means the instrument's name. */
|
|
104
|
+
title?: string | null;
|
|
105
|
+
/** Which of the trial's collapsible sections are folded, keyed as
|
|
106
|
+
* `TrialChromeContext.collapsedSections` describes. A key that is absent
|
|
107
|
+
* takes the section's own default. */
|
|
108
|
+
collapsedSections?: Record<string, boolean>;
|
|
109
|
+
/** The marks on this trial's annotation targets, as `AnnotationsApi.toJSON`
|
|
110
|
+
* wrote them. Opaque here, and absent for a trial whose instrument declares
|
|
111
|
+
* no `annotations` — or declares its own `storage`. Not in `state`, which
|
|
112
|
+
* belongs to the instrument and is typed as such. */
|
|
113
|
+
annotations?: unknown;
|
|
114
|
+
undoStack: UndoStack;
|
|
115
|
+
}
|
|
116
|
+
/** A named, saved copy of a trial's config and state, restorable into any
|
|
117
|
+
* trial running the same instrument. */
|
|
118
|
+
interface SavedSnapshot {
|
|
119
|
+
id: string;
|
|
120
|
+
name: string;
|
|
121
|
+
trialId: string;
|
|
122
|
+
instrumentName: string;
|
|
123
|
+
config: unknown;
|
|
124
|
+
state: unknown;
|
|
125
|
+
/** The trial's `auto` paths when saved; empty means every field was pinned.
|
|
126
|
+
* Absent on a snapshot saved before snapshots carried them, which loads
|
|
127
|
+
* over the trial's current set rather than guessing one. */
|
|
128
|
+
auto?: readonly string[];
|
|
129
|
+
savedAt: number;
|
|
130
|
+
}
|
|
131
|
+
/** `auto` follows the OS; the other two are an explicit choice. */
|
|
132
|
+
type LabMode = 'auto' | 'light' | 'dark';
|
|
133
|
+
/** Everything a lab persists: its trials, its saved snapshots, and the
|
|
134
|
+
* chosen color mode. */
|
|
135
|
+
interface LabStoreState {
|
|
136
|
+
trials: TrialRecord[];
|
|
137
|
+
savedSnapshots: SavedSnapshot[];
|
|
138
|
+
mode: LabMode;
|
|
139
|
+
/** The lab's tool slot — what a trial with no slot of its own resolves to. */
|
|
140
|
+
activeToolId: string | null;
|
|
141
|
+
/** Per-trial tile extents, keyed by trial id. Opaque here — the
|
|
142
|
+
* shape belongs to whatever lays the trials out. */
|
|
143
|
+
layout: Record<string, unknown>;
|
|
144
|
+
/** Sidebar sections torn out of their trial. A panel here is not rendered in
|
|
145
|
+
* its trial's sidebar; the workspace renders it instead. */
|
|
146
|
+
undockedPanels: UndockedPanels;
|
|
147
|
+
/** The instruments this store serializes, migrates and fills configs for.
|
|
148
|
+
* Null for a store built without them, whose trials look their instrument
|
|
149
|
+
* up on the lab instead. Not persisted. */
|
|
150
|
+
instruments: InstrumentList | null;
|
|
151
|
+
}
|
|
152
|
+
/** A change someone else made to one record: its new value, or `undefined`
|
|
153
|
+
* when it was deleted. */
|
|
154
|
+
type StorageChange = [key: string, value: unknown];
|
|
155
|
+
/** Where a lab persists itself: asynchronous keyed storage of
|
|
156
|
+
* structured-clone values, so IndexedDB, the URL, memory or a server can all
|
|
157
|
+
* back one. */
|
|
158
|
+
interface StorageAdapter {
|
|
159
|
+
/** `undefined` when the key is absent. */
|
|
160
|
+
get(key: string): Promise<unknown>;
|
|
161
|
+
list(prefix: string): Promise<[string, unknown][]>;
|
|
162
|
+
/** Rejects when the value did not land. */
|
|
163
|
+
set(key: string, value: unknown): Promise<void>;
|
|
164
|
+
delete(key: string): Promise<void>;
|
|
165
|
+
/** Reports writes under `prefix` made by anyone but this adapter — another
|
|
166
|
+
* tab, another instance, a server. Omit when the substrate cannot tell. */
|
|
167
|
+
subscribe?(prefix: string, on: (changes: StorageChange[]) => void): () => void;
|
|
168
|
+
}
|
|
169
|
+
/** What `useTrialState` hands an instrument: its state and config, with
|
|
170
|
+
* a setter for each. */
|
|
171
|
+
interface TrialStateHandle<TS, TC> {
|
|
172
|
+
state: TS;
|
|
173
|
+
setState: (next: TS | ((prev: TS) => TS)) => void;
|
|
174
|
+
config: TC;
|
|
175
|
+
/** The config as stored, before any auto path is resolved. What the control
|
|
176
|
+
* panel renders, so a ghosted control sits at the value it pins back to. */
|
|
177
|
+
raw: TC;
|
|
178
|
+
/** Dotted paths this trial has unpinned. */
|
|
179
|
+
auto: ReadonlySet<string>;
|
|
180
|
+
/** Write one config value, by dotted path — `'grid.size'` for a leaf under
|
|
181
|
+
* an `f.group`, `'cellSize'` for one at the root. */
|
|
182
|
+
setConfig: <P extends ConfigPath<TC> & string>(path: P, value: ValueAtPath<TC, P> | Auto) => void;
|
|
183
|
+
}
|
|
184
|
+
/** Options for `createLabStore`, which knows nothing about storage. */
|
|
185
|
+
interface CreateLabStoreOptions {
|
|
186
|
+
/** A document already read and migrated — what `openLabStore` hands over. */
|
|
187
|
+
initial?: LabDocument;
|
|
188
|
+
initialMode?: LabMode;
|
|
189
|
+
/** Each instrument's default config, keyed by instrument name, used to fill
|
|
190
|
+
* the gaps in a stored one. A config saved before its schema grew a branch
|
|
191
|
+
* arrives holding that branch's defaults rather than `undefined`, and keeps
|
|
192
|
+
* whatever keys the schema has since stopped naming. */
|
|
193
|
+
configDefaults?: Record<string, () => unknown>;
|
|
194
|
+
/** Each instrument's `migrateConfig`, keyed by instrument name, run on a
|
|
195
|
+
* stored config before its defaults fill it. */
|
|
196
|
+
configMigrations?: Record<string, (stored: unknown) => unknown>;
|
|
197
|
+
/** Each instrument's resolved config schema, keyed by instrument name. What
|
|
198
|
+
* a trial's auto paths are read against, away from the lab that would
|
|
199
|
+
* otherwise supply the rules. */
|
|
200
|
+
configSchemas?: Record<string, ResolvedConfig>;
|
|
201
|
+
/** How each instrument's state survives a reload. Hydration is the first
|
|
202
|
+
* thing `createLabStore` does, so these have to arrive with the store. */
|
|
203
|
+
serializers?: InstrumentSerializers;
|
|
204
|
+
/** The instruments to serialize, migrate and fill configs for. Given, it
|
|
205
|
+
* supplies all three and the three fields above are ignored. */
|
|
206
|
+
instruments?: InstrumentList;
|
|
207
|
+
}
|
|
208
|
+
/** What a store does per instrument on the way in and out. */
|
|
209
|
+
interface InstrumentHooks {
|
|
210
|
+
serializers: InstrumentSerializers;
|
|
211
|
+
configDefaults: Record<string, () => unknown>;
|
|
212
|
+
configMigrations: Record<string, (stored: unknown) => unknown>;
|
|
213
|
+
configSchemas: Record<string, ResolvedConfig>;
|
|
214
|
+
}
|
|
215
|
+
/** Per-instrument serialize/deserialize hooks, keyed by instrument name. An
|
|
216
|
+
* instrument whose state is already JSON-safe needs no entry. `deserialize`
|
|
217
|
+
* is handed the config the state was saved against — a trial's own for a
|
|
218
|
+
* reload, the snapshot's for a load — since a state rebuilt without it can
|
|
219
|
+
* disagree with the settings sitting next to it. */
|
|
220
|
+
type InstrumentSerializers = Record<string, {
|
|
221
|
+
serialize?: (state: unknown) => unknown;
|
|
222
|
+
deserialize?: (data: unknown, config: unknown) => unknown;
|
|
223
|
+
} | undefined>;
|
|
224
|
+
/** A trial as it is persisted: everything but the undo history, which is
|
|
225
|
+
* session-only. */
|
|
226
|
+
type SerializedTrial = Omit<TrialRecord, 'undoStack'>;
|
|
227
|
+
/** Everything a lab persists, under one key, at a known version. */
|
|
228
|
+
interface LabDocument {
|
|
229
|
+
version: number;
|
|
230
|
+
trials: SerializedTrial[];
|
|
231
|
+
saves: SavedSnapshot[];
|
|
232
|
+
layout: Record<string, unknown>;
|
|
233
|
+
/** Sidebar sections torn out of their trial, keyed by trial and section. */
|
|
234
|
+
undockedPanels: UndockedPanels;
|
|
235
|
+
mode: LabMode;
|
|
236
|
+
}
|
|
237
|
+
/** Migrates a document one version forward. Index `i` in the chain takes a
|
|
238
|
+
* version-`i` document to version `i + 1`. */
|
|
239
|
+
type Migration = (doc: Record<string, unknown>) => Record<string, unknown>;
|
|
240
|
+
|
|
36
241
|
/** A named position in a trial's chrome. Content is not a region — that is
|
|
37
|
-
* the instrument. */
|
|
242
|
+
* the instrument. The lab's own boxes are named in `LabRegion`. */
|
|
38
243
|
type TrialRegion = 'titlebar' | 'toolbar' | 'palette' | 'sidebar' | 'viewport' | 'status';
|
|
39
244
|
/** An icon component taking a pixel size, as `@weasel-js/ui` glyphs do. */
|
|
40
245
|
type IconComponent = ComponentType<{
|
|
41
246
|
size?: number;
|
|
42
247
|
}>;
|
|
43
|
-
/** A button in
|
|
44
|
-
|
|
248
|
+
/** A button in a toolbar. `TCtx` is the chrome context its `onActivate` is
|
|
249
|
+
* handed — a trial's, or the lab's for a lab-level bar. */
|
|
250
|
+
interface ToolbarItem<TCtx = TrialChromeContext> {
|
|
45
251
|
icon: IconComponent;
|
|
46
252
|
label: string;
|
|
47
253
|
/** Shown in the tooltip. Not bound here — the trial owns its keymap. */
|
|
@@ -54,10 +260,10 @@ interface ToolbarItem {
|
|
|
54
260
|
pressed?: boolean;
|
|
55
261
|
/** Render the label beside the glyph rather than only in the tooltip. */
|
|
56
262
|
showLabel?: boolean;
|
|
57
|
-
/** Handed the
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
onActivate: (ctx:
|
|
263
|
+
/** Handed the chrome context it was declared against, so a contribution can
|
|
264
|
+
* reach `ctx.saveSnapshot()` and the rest without the `render` escape. A
|
|
265
|
+
* zero-argument handler stays valid. */
|
|
266
|
+
onActivate: (ctx: TCtx) => void;
|
|
61
267
|
}
|
|
62
268
|
/** A selectable tool in the palette region. */
|
|
63
269
|
interface ToolItem {
|
|
@@ -79,12 +285,12 @@ interface SidebarSection {
|
|
|
79
285
|
body: ReactNode;
|
|
80
286
|
}
|
|
81
287
|
/** A control acting on the view of the trial, not on the trial. */
|
|
82
|
-
interface ViewportControl {
|
|
288
|
+
interface ViewportControl<TCtx = TrialChromeContext> {
|
|
83
289
|
icon: IconComponent;
|
|
84
290
|
label: string;
|
|
85
291
|
disabled?: boolean;
|
|
86
292
|
/** Handed the trial's chrome context, as `ToolbarItem.onActivate` is. */
|
|
87
|
-
onActivate: (ctx:
|
|
293
|
+
onActivate: (ctx: TCtx) => void;
|
|
88
294
|
}
|
|
89
295
|
/** A readout in the status bar. */
|
|
90
296
|
interface StatusReadout {
|
|
@@ -93,7 +299,7 @@ interface StatusReadout {
|
|
|
93
299
|
/** Tooltip. */
|
|
94
300
|
title?: string;
|
|
95
301
|
}
|
|
96
|
-
/** What every contribution shares. */
|
|
302
|
+
/** What every contribution shares, whichever chrome it is declared against. */
|
|
97
303
|
interface ContributionBase {
|
|
98
304
|
id: string;
|
|
99
305
|
/** Groups sort by first appearance; items sort within a group by
|
|
@@ -136,18 +342,46 @@ type TrialContribution = (ContributionBase & {
|
|
|
136
342
|
item?: never;
|
|
137
343
|
render: (ctx: TrialChromeContext) => ReactNode;
|
|
138
344
|
});
|
|
345
|
+
/**
|
|
346
|
+
* A tool slot a region can reflect and write. Both chrome contexts carry one:
|
|
347
|
+
* a trial's resolves to the lab's when its instrument declares no tools.
|
|
348
|
+
*/
|
|
349
|
+
interface ToolSlotContext {
|
|
350
|
+
activeToolId: string | null;
|
|
351
|
+
setActiveTool: (id: string) => void;
|
|
352
|
+
}
|
|
353
|
+
/** What a sidebar region reflects and writes: which sections are folded, and —
|
|
354
|
+
* where the chrome can tear a section out — where it goes. A trial supplies
|
|
355
|
+
* all four; a lab supplies the fold state only. */
|
|
356
|
+
interface SidebarSlotContext {
|
|
357
|
+
collapsedSections: Readonly<Record<string, boolean>>;
|
|
358
|
+
setSectionCollapsed: (key: string, collapsed: boolean) => void;
|
|
359
|
+
undockedPanels?: readonly string[];
|
|
360
|
+
undockPanel?: (sectionId: string, as?: 'tile' | 'floating') => void;
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* A contribution as a region renderer sees it. A renderer checks the region
|
|
364
|
+
* name against its own and narrows `item` itself, which is what lets one
|
|
365
|
+
* renderer serve both chromes — the trial's and the lab's — without knowing
|
|
366
|
+
* which context it was handed.
|
|
367
|
+
*/
|
|
368
|
+
interface RegionContribution<TCtx> extends ContributionBase {
|
|
369
|
+
region: string;
|
|
370
|
+
item?: unknown;
|
|
371
|
+
render?: (ctx: TCtx) => ReactNode;
|
|
372
|
+
}
|
|
139
373
|
/**
|
|
140
374
|
* Everything a contribution can read about the trial it is being rendered
|
|
141
375
|
* into. Replaces the three separate slot contexts, which each carried a
|
|
142
376
|
* hand-picked subset.
|
|
143
377
|
*/
|
|
144
|
-
interface TrialChromeContext {
|
|
378
|
+
interface TrialChromeContext extends ToolSlotContext, SidebarSlotContext {
|
|
145
379
|
trialId: string;
|
|
146
380
|
instrumentName: string;
|
|
147
|
-
/** What the title bar reads, which is the instrument's
|
|
148
|
-
* calls `setTitle`. */
|
|
381
|
+
/** What the title bar reads, which is the instrument's title (or, lacking
|
|
382
|
+
* one, its name) until something calls `setTitle`. */
|
|
149
383
|
title: string;
|
|
150
|
-
/** Retitle this trial; `null` restores the instrument
|
|
384
|
+
/** Retitle this trial; `null` restores the instrument's title. Persisted with
|
|
151
385
|
* the trial, so a title survives a reload. */
|
|
152
386
|
setTitle: (title: string | null) => void;
|
|
153
387
|
isLastTrial: boolean;
|
|
@@ -169,6 +403,9 @@ interface TrialChromeContext {
|
|
|
169
403
|
* `config`, since a builder schema has no `ConfigField[]` form. */
|
|
170
404
|
configFields: ConfigField[];
|
|
171
405
|
config: unknown;
|
|
406
|
+
/** The trial's unpinned paths. `config` stays raw, so a control drawn from
|
|
407
|
+
* it sits at the value un-pinning writes back. */
|
|
408
|
+
auto: ReadonlySet<string>;
|
|
172
409
|
setConfig: (key: string, value: unknown) => void;
|
|
173
410
|
/** Which of this trial's collapsible sections are folded. A sidebar
|
|
174
411
|
* section's key is its contribution id; a section *inside* a contribution —
|
|
@@ -189,10 +426,6 @@ interface TrialChromeContext {
|
|
|
189
426
|
clone: () => void;
|
|
190
427
|
reset: () => void;
|
|
191
428
|
close: () => void;
|
|
192
|
-
/** Resolved active tool: the trial's slot, or the lab's when the trial has
|
|
193
|
-
* none. Null when neither holds one. */
|
|
194
|
-
activeToolId: string | null;
|
|
195
|
-
setActiveTool: (id: string) => void;
|
|
196
429
|
}
|
|
197
430
|
|
|
198
431
|
/** A point on the magnified surface, in its own CSS pixels. */
|
|
@@ -245,7 +478,7 @@ interface LoupeCapability<TS = unknown, TC = unknown> {
|
|
|
245
478
|
/** Held for a momentary peek while the loupe is off. Default `'Alt'`; `null`
|
|
246
479
|
* turns hold-to-peek off. Matched against `KeyboardEvent.key`. */
|
|
247
480
|
peekKey?: string | null;
|
|
248
|
-
/** Called with the
|
|
481
|
+
/** Called with the color under the aim, wherever the surface can say. The
|
|
249
482
|
* canvas painter reads it back; a DOM loupe has no pixels to sample. */
|
|
250
483
|
onColorChange?: (hex: string) => void;
|
|
251
484
|
}
|
|
@@ -353,6 +586,18 @@ interface CanvasCapability<TS = unknown, TC = unknown> {
|
|
|
353
586
|
minZoom?: number;
|
|
354
587
|
maxZoom?: number;
|
|
355
588
|
}
|
|
589
|
+
/** Declares that an instrument's DOM is content of a fixed size, which the
|
|
590
|
+
* trial pans and zooms the way it does a canvas's layers. Not combined with
|
|
591
|
+
* `canvas`: there the DOM is an unzoomed overlay, and `canvas` wins. */
|
|
592
|
+
interface StageCapability {
|
|
593
|
+
/** The content's own size in CSS pixels, at zoom 1. */
|
|
594
|
+
size: ViewportSize;
|
|
595
|
+
/** Where the view starts. Omitted, the content opens centered and shrunk to
|
|
596
|
+
* fit (`fitStage`). A function is called once the stage knows its size. */
|
|
597
|
+
initialView?: ViewTransform | ((viewport: ViewportSize) => ViewTransform);
|
|
598
|
+
minZoom?: number;
|
|
599
|
+
maxZoom?: number;
|
|
600
|
+
}
|
|
356
601
|
/** Declares which of an instrument's layers the trial should offer
|
|
357
602
|
* show/hide controls for. */
|
|
358
603
|
interface LayerCapability {
|
|
@@ -391,7 +636,8 @@ type HitResult = {
|
|
|
391
636
|
layerId?: string;
|
|
392
637
|
pointId?: string;
|
|
393
638
|
};
|
|
394
|
-
/** A trial's camera.
|
|
639
|
+
/** A trial's camera. `zoom` is always positive and finite once labkit holds
|
|
640
|
+
* it — see `normalize2DView`. */
|
|
395
641
|
type ViewTransform = {
|
|
396
642
|
zoom: number;
|
|
397
643
|
pan: Point;
|
|
@@ -424,7 +670,10 @@ type DragFeedback = {
|
|
|
424
670
|
* is what makes the trial provide the corresponding chrome.
|
|
425
671
|
*/
|
|
426
672
|
interface Instrument<TS = unknown, TC = unknown, TItem = unknown> {
|
|
673
|
+
/** The id a trial record names its instrument by. */
|
|
427
674
|
name: string;
|
|
675
|
+
/** What a trial of this instrument and the add-trial menu read. Default: `name`. */
|
|
676
|
+
title?: string;
|
|
428
677
|
defaultConfig: () => TC;
|
|
429
678
|
initialState: (config: TC) => TS;
|
|
430
679
|
/** The instrument's config, declared once: values, types and controls.
|
|
@@ -438,9 +687,16 @@ interface Instrument<TS = unknown, TC = unknown, TItem = unknown> {
|
|
|
438
687
|
* layers rather than instead of them; return `null` for canvas only. */
|
|
439
688
|
render: (ctx: RenderContext<TS, TC>) => ReactNode;
|
|
440
689
|
onConfigChange?: (config: TC, prev: TC, state: TS) => TS;
|
|
690
|
+
/** Moves a stored config's values to where the current schema keeps them —
|
|
691
|
+
* `gridSize` to `grid.size` — before the defaults fill its gaps, so it
|
|
692
|
+
* returns only what it moved and leaves the rest to them. It runs on every
|
|
693
|
+
* read of a stored config, including one already moved, so it must hand
|
|
694
|
+
* back a current config unchanged. */
|
|
695
|
+
migrateConfig?: (stored: unknown) => unknown;
|
|
441
696
|
serialize?: (state: TS) => unknown;
|
|
442
697
|
deserialize?: (data: unknown, config: TC) => TS;
|
|
443
698
|
canvas?: CanvasCapability<TS, TC>;
|
|
699
|
+
stage?: StageCapability;
|
|
444
700
|
layers?: LayerCapability;
|
|
445
701
|
dragDrop?: DragDropCapability<TS, TC>;
|
|
446
702
|
undo?: UndoCapability;
|
|
@@ -479,9 +735,10 @@ interface AnnotationStoreOptions {
|
|
|
479
735
|
targets: () => readonly AnnotationTargetInfo[];
|
|
480
736
|
/** Serialized scenes from a previous `toJSON`, keyed by target. */
|
|
481
737
|
restore?: Readonly<Record<string, unknown>>;
|
|
482
|
-
/** The instrument's vocabulary, so an export draws a mark in the
|
|
483
|
-
* status gives it.
|
|
484
|
-
|
|
738
|
+
/** The instrument's vocabulary, so an export draws a mark in the color its
|
|
739
|
+
* status gives it. A thunk is read at each capture, for a vocabulary that
|
|
740
|
+
* changes under a store built once. */
|
|
741
|
+
meaning?: AnnotationMeaning | (() => AnnotationMeaning | undefined);
|
|
485
742
|
/** The trial's live config. A getter for the same reason `targets` is: the
|
|
486
743
|
* store is built once and the config changes under it. */
|
|
487
744
|
config?: () => unknown;
|
|
@@ -535,7 +792,7 @@ interface AnnotationStatus {
|
|
|
535
792
|
id: string;
|
|
536
793
|
label: string;
|
|
537
794
|
/** What a mark in this status is drawn in. Omitted, it takes the default
|
|
538
|
-
* mark
|
|
795
|
+
* mark color — a status is allowed to be a label and nothing more. */
|
|
539
796
|
color?: string;
|
|
540
797
|
}
|
|
541
798
|
/** The optional meaning tier: what a mark means, as opposed to where it is.
|
|
@@ -651,9 +908,10 @@ interface AnnotationTarget extends AnnotationTargetInfo {
|
|
|
651
908
|
/** Where an instrument keeps its own marks. Declaring this means labkit never
|
|
652
909
|
* writes its trial slot — for an instrument whose marks belong in a format it
|
|
653
910
|
* already owns. Both halves are called outside React; `save` is already
|
|
654
|
-
* debounced by the time it arrives.
|
|
911
|
+
* debounced by the time it arrives. A trial shows an empty body until `load`
|
|
912
|
+
* settles. */
|
|
655
913
|
interface AnnotationStorage {
|
|
656
|
-
load: () => SerializedAnnotations | null | undefined
|
|
914
|
+
load: () => Promise<SerializedAnnotations | null | undefined>;
|
|
657
915
|
save: (doc: SerializedAnnotations) => void;
|
|
658
916
|
}
|
|
659
917
|
/** Declares that an instrument accepts marks: which regions take them,
|
|
@@ -663,6 +921,8 @@ interface AnnotationsCapability<TS = unknown, TC = unknown> {
|
|
|
663
921
|
* is called once per trial, and its targets are that trial's own. */
|
|
664
922
|
targets: (state: TS, config: TC, trial: TrialInfo) => readonly AnnotationTarget[];
|
|
665
923
|
meaning?: AnnotationMeaning;
|
|
924
|
+
/** An instrument replacing this one under a live trial must pass the same
|
|
925
|
+
* object: the trial keeps the marks it loaded from the first. */
|
|
666
926
|
storage?: AnnotationStorage;
|
|
667
927
|
/** Fires after every finished export, labkit's own chrome included. A
|
|
668
928
|
* notification, not an interception: a host wanting its own flow calls
|
|
@@ -758,5 +1018,5 @@ declare function fracContains(box: FracRect, pt: FracPoint, tol?: number): boole
|
|
|
758
1018
|
* answers false for two rects that merely overlap. */
|
|
759
1019
|
declare function fracEncloses(outer: FracRect, inner: FracRect): boolean;
|
|
760
1020
|
|
|
761
|
-
export { LOUPE_DEFAULTS as
|
|
762
|
-
export type {
|
|
1021
|
+
export { DEFAULT_FRAME as D, LOUPE_DEFAULTS as a8, fracEncloses as aA, fracToWorld as aB, isAuto as aC, resolveLoupe as aD, roundFrac as aE, worldToFrac as aF, annotationsFromJSON as av, auto as aw, createAnnotationScene as ax, createAnnotationStore as ay, fracContains as az, applyCamera as b, dockPanel as j, panelKey as p, resolveFrame as r, undockPanel as u };
|
|
1022
|
+
export type { Auto as $, AnnotationData as A, AnnotationTarget as B, CreateLabStoreOptions as C, AnnotationsApi as E, AnnotationsCapability as F, TrialInfo as G, TrialTool as H, InstrumentSerializers as I, AnnotationKind as J, Instrument as K, LabDocument as L, Migration as M, TrialContribution as N, Annotation as O, PaletteItem as P, AnnotationInit as Q, AnnotationPatch as R, SerializedTrial as S, TrialRecord as T, UndoStack as U, ViewportSize as V, WorldFrame as W, AnnotationQuery as X, AnnotationStatus as Y, AnnotationStoreOptions as Z, AnnotationTargetInfo as _, WorldSpec as a, CanvasCapability as a0, CanvasLayer as a1, CaptureDeps as a2, ContributionBase as a3, FracPoint as a4, FracRect as a5, HitResult as a6, IconComponent as a7, LayerCapability as a9, LoupePoint as aG, LoupeMode as aH, LayerDescriptor as aa, LoupeCapability as ab, LoupeDeclaration as ac, LoupeRenderArgs as ad, RegionContribution as ae, RenderContext as af, ResolvedLoupe as ag, SerializedAnnotations as ah, SidebarSection as ai, SidebarSlotContext as aj, StageCapability as ak, StatusReadout as al, SystemEvent as am, ToolCapability as an, ToolItem as ao, ToolSlotContext as ap, ToolbarItem as aq, TrialChromeContext as ar, TrialRegion as as, UndoCapability as at, ViewportControl as au, StorageAdapter as c, LabStoreState as d, SavedSnapshot as e, StorageChange as f, TrialStateHandle as g, UndockedPanel as h, UndockedPanels as i, ViewTransform as k, Point as l, DragFeedback as m, DragDropCapability as n, LabMode as o, InstrumentList as q, InstrumentHooks as s, WorldRect as t, AnnotationMeaning as v, MarkScene as w, CaptureSource as x, CaptureOptions as y, CaptureResult as z };
|