@n-uf/placement 26.11.8 → 26.11.9

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.
@@ -0,0 +1,138 @@
1
+ import {
2
+ SIDES,
3
+ defOf,
4
+ floatSize
5
+ } from "./chunk-PWQWD2CS.js";
6
+
7
+ // src/panels/store.ts
8
+ function storePanels(state) {
9
+ const column = (c) => ({
10
+ panels: [...c.panels],
11
+ width: c.width,
12
+ ...c.show === "tabs" ? { show: "tabs" } : {},
13
+ ...c.active !== void 0 ? { active: c.active } : {}
14
+ });
15
+ const sides = Object.fromEntries(SIDES.map((s) => [s, state.sides[s].map(column)]));
16
+ return {
17
+ v: 1,
18
+ sides,
19
+ floats: state.floats.map((f) => ({ id: f.id, rect: { x: f.rect.x, y: f.rect.y, width: f.rect.width, height: f.rect.height }, pinned: !!f.pinned })),
20
+ folded: [...state.folded],
21
+ kept: [...state.kept],
22
+ closed: [...state.closed],
23
+ clock: Object.fromEntries(Object.entries(state.clock).map(([k, c]) => [k, { opened: c.opened, used: c.used }]))
24
+ };
25
+ }
26
+ var isObject = (x) => typeof x === "object" && x !== null && !Array.isArray(x);
27
+ var finite = (x) => typeof x === "number" && Number.isFinite(x);
28
+ function readPanels(data, defs) {
29
+ try {
30
+ return read(data, defs);
31
+ } catch (e) {
32
+ return { ok: false, error: `unreadable: ${e instanceof Error ? e.message : typeof e}` };
33
+ }
34
+ }
35
+ function read(data, defs) {
36
+ if (!isObject(data)) return { ok: false, error: "not an object" };
37
+ if (data.v !== 1) return { ok: false, error: `unknown version ${typeof data.v === "number" || typeof data.v === "string" ? String(data.v) : typeof data.v} (this reads version 1)` };
38
+ if (!isObject(data.sides)) return { ok: false, error: "sides is missing" };
39
+ const dropped = [];
40
+ const drop = (what) => {
41
+ if (!dropped.includes(what)) dropped.push(what);
42
+ };
43
+ const seen = /* @__PURE__ */ new Set();
44
+ const take = (x) => {
45
+ if (typeof x !== "string") {
46
+ drop(`a ${typeof x} where an id goes`);
47
+ return null;
48
+ }
49
+ if (defs && !defOf(defs, x) || seen.has(x)) {
50
+ drop(x);
51
+ return null;
52
+ }
53
+ seen.add(x);
54
+ return x;
55
+ };
56
+ const extra = (o, known, prefix) => {
57
+ for (const k of Object.keys(o)) if (!known.includes(k)) drop(`${prefix}${k}`);
58
+ };
59
+ extra(data, ["v", "sides", "floats", "folded", "kept", "closed", "clock"], "");
60
+ extra(data.sides, SIDES, "sides.");
61
+ const sides = { left: [], right: [] };
62
+ for (const side of SIDES) {
63
+ const cols = data.sides[side];
64
+ if (cols === void 0) continue;
65
+ if (!Array.isArray(cols)) {
66
+ drop(`sides.${side}`);
67
+ continue;
68
+ }
69
+ for (const c of cols) {
70
+ if (!isObject(c) || !Array.isArray(c.panels)) {
71
+ drop(`a column on the ${side}`);
72
+ continue;
73
+ }
74
+ extra(c, ["panels", "width", "show", "active"], "column.");
75
+ const panels = c.panels.map(take).filter((x) => x !== null);
76
+ if (panels.length === 0) continue;
77
+ const ds = defs ? panels.map((id) => defOf(defs, id)) : [];
78
+ const lo = Math.max(0, ...ds.map((d) => d.width.min));
79
+ const hi = Math.max(lo, Math.min(...ds.map((d) => d.width.max)));
80
+ const natural = ds.length ? Math.max(...ds.map((d) => d.width.natural)) : 0;
81
+ const width = finite(c.width) ? c.width : natural;
82
+ if (c.show !== void 0 && c.show !== "tabs" && c.show !== "stack") drop("column.show");
83
+ if (c.active !== void 0 && !(typeof c.active === "string" && panels.includes(c.active))) drop(`column.active:${typeof c.active === "string" ? c.active : typeof c.active}`);
84
+ const tabs = c.show === "tabs" ? { show: "tabs" } : {};
85
+ const active = typeof c.active === "string" && panels.includes(c.active) ? { active: c.active } : {};
86
+ sides[side].push({ panels, width: defs ? Math.min(Math.max(width, lo), hi) : Math.max(0, width), ...tabs, ...active });
87
+ }
88
+ }
89
+ const floats = [];
90
+ for (const f of Array.isArray(data.floats) ? data.floats : []) {
91
+ const r = isObject(f) ? f.rect : void 0;
92
+ if (!isObject(f) || !isObject(r) || !finite(r.x) || !finite(r.y) || !finite(r.width) || !finite(r.height)) {
93
+ drop(isObject(f) && typeof f.id === "string" ? f.id : "a float");
94
+ continue;
95
+ }
96
+ extra(f, ["id", "rect", "pinned"], "float.");
97
+ const id = take(f.id);
98
+ if (id === null) continue;
99
+ const min = defs ? floatSize(defOf(defs, id)).min : { width: 0, height: 0 };
100
+ floats.push({ id, rect: { x: r.x, y: r.y, width: Math.max(min.width, r.width), height: Math.max(min.height, r.height) }, ...f.pinned === true ? { pinned: true } : {} });
101
+ }
102
+ if (data.floats !== void 0 && !Array.isArray(data.floats)) drop("floats");
103
+ const placed = (key) => {
104
+ const x = data[key];
105
+ if (x === void 0) return [];
106
+ if (!Array.isArray(x)) {
107
+ drop(key);
108
+ return [];
109
+ }
110
+ const out = [];
111
+ for (const id of x) {
112
+ if (typeof id === "string" && seen.has(id)) {
113
+ if (!out.includes(id)) out.push(id);
114
+ } else drop(typeof id === "string" ? id : `a ${typeof id} in ${key}`);
115
+ }
116
+ return out;
117
+ };
118
+ const floating = new Set(floats.map((f) => f.id));
119
+ const kept = placed("kept").filter((id) => {
120
+ if (floating.has(id)) drop(id);
121
+ return !floating.has(id);
122
+ });
123
+ const clock = {};
124
+ if (isObject(data.clock)) {
125
+ for (const id of Object.keys(data.clock)) if (!seen.has(id)) drop(`clock.${id}`);
126
+ for (const id of seen) {
127
+ const c = data.clock[id];
128
+ clock[id] = isObject(c) && finite(c.opened) && finite(c.used) ? { opened: c.opened, used: c.used } : { opened: 0, used: 0 };
129
+ }
130
+ }
131
+ return { ok: true, state: { sides, floats, folded: placed("folded"), kept, closed: placed("closed"), clock }, dropped };
132
+ }
133
+
134
+ export {
135
+ storePanels,
136
+ readPanels
137
+ };
138
+ //# sourceMappingURL=chunk-XUV6MJ2P.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/panels/store.ts"],"sourcesContent":["/**\n * The panels' stored form: `storePanels(state)` gives plain JSON-safe data (`{ v: 1, … }`); `readPanels(data, defs?)`\n * reads parsed data back and never throws. As with the toolbar's `readArrangement`: anything but an object of\n * version 1 is `{ ok: false, error }`. Inside one, it is lenient: an unknown id (with `defs`), a repeated one or a\n * malformed entry is dropped and listed in `dropped`; widths and float sizes are clamped to the defs. A panel the\n * consumer has but the stored state lacks is no error: the consumer places it (`open` with a place, say).\n *\n * Version 1 only gains optional fields. A field this reader doesn't know (a newer writer's, say) is no error either:\n * it is skipped and reported in `dropped` (`\"<field>\"` at the top, `\"sides.<key>\"`, `\"column.<field>\"`,\n * `\"float.<field>\"`; a clock entry for a panel that isn't placed as `\"clock.<id>\"`), so a consumer can tell that\n * something was left out. A column's `show` (\"tabs\") and `active` are such optional fields: an unknown `show` is\n * dropped as `\"column.show\"`, an `active` that isn't one of the column's panels as `\"column.active:<id>\"`.\n */\nimport type { Rect } from \"../geometry\";\nimport { SIDES, defOf, floatSize, type Clock, type Column, type FloatAt, type PanelDef, type PanelsState, type Side } from \"./model\";\n\nexport interface StoredPanels {\n readonly v: 1;\n /** A column's `show` and `active` only when it is tabbed / has one (optional fields of v1). */\n readonly sides: Record<Side, { panels: string[]; width: number; show?: \"tabs\"; active?: string }[]>;\n readonly floats: { id: string; rect: Rect; pinned: boolean }[];\n readonly folded: string[];\n readonly kept: string[];\n readonly closed: string[];\n readonly clock: Record<string, Clock>;\n}\n\nexport type PanelsRead = { readonly ok: true; readonly state: PanelsState; readonly dropped: readonly string[] } | { readonly ok: false; readonly error: string };\n\nexport function storePanels(state: PanelsState): StoredPanels {\n const column = (c: Column): StoredPanels[\"sides\"][\"left\"][number] => ({\n panels: [...c.panels],\n width: c.width,\n ...(c.show === \"tabs\" ? { show: \"tabs\" as const } : {}),\n ...(c.active !== undefined ? { active: c.active } : {}),\n });\n const sides = Object.fromEntries(SIDES.map((s) => [s, state.sides[s].map(column)])) as StoredPanels[\"sides\"];\n return {\n v: 1,\n sides,\n floats: state.floats.map((f) => ({ id: f.id, rect: { x: f.rect.x, y: f.rect.y, width: f.rect.width, height: f.rect.height }, pinned: !!f.pinned })),\n folded: [...state.folded],\n kept: [...state.kept],\n closed: [...state.closed],\n clock: Object.fromEntries(Object.entries(state.clock).map(([k, c]) => [k, { opened: c.opened, used: c.used }])),\n };\n}\n\nconst isObject = (x: unknown): x is Record<string, unknown> => typeof x === \"object\" && x !== null && !Array.isArray(x);\nconst finite = (x: unknown): x is number => typeof x === \"number\" && Number.isFinite(x);\n\nexport function readPanels(data: unknown, defs?: readonly PanelDef[]): PanelsRead {\n try {\n return read(data, defs);\n } catch (e) {\n // A getter that throws, a proxy: still no throw.\n return { ok: false, error: `unreadable: ${e instanceof Error ? e.message : typeof e}` };\n }\n}\n\nfunction read(data: unknown, defs?: readonly PanelDef[]): PanelsRead {\n if (!isObject(data)) return { ok: false, error: \"not an object\" };\n // Named without serialising it: a BigInt or a circular value must not throw.\n if (data.v !== 1) return { ok: false, error: `unknown version ${typeof data.v === \"number\" || typeof data.v === \"string\" ? String(data.v) : typeof data.v} (this reads version 1)` };\n if (!isObject(data.sides)) return { ok: false, error: \"sides is missing\" };\n const dropped: string[] = [];\n const drop = (what: string): void => {\n if (!dropped.includes(what)) dropped.push(what);\n };\n const seen = new Set<string>();\n // An id the consumer has, not placed yet.\n const take = (x: unknown): string | null => {\n if (typeof x !== \"string\") {\n drop(`a ${typeof x} where an id goes`);\n return null;\n }\n if ((defs && !defOf(defs, x)) || seen.has(x)) {\n drop(x);\n return null;\n }\n seen.add(x);\n return x;\n };\n // Fields this version doesn't know: skipped, and reported.\n const extra = (o: Record<string, unknown>, known: readonly string[], prefix: string): void => {\n for (const k of Object.keys(o)) if (!known.includes(k)) drop(`${prefix}${k}`);\n };\n extra(data, [\"v\", \"sides\", \"floats\", \"folded\", \"kept\", \"closed\", \"clock\"], \"\");\n extra(data.sides, SIDES, \"sides.\");\n const sides = { left: [] as Column[], right: [] as Column[] };\n for (const side of SIDES) {\n const cols = data.sides[side];\n if (cols === undefined) continue;\n if (!Array.isArray(cols)) {\n drop(`sides.${side}`);\n continue;\n }\n for (const c of cols as unknown[]) {\n if (!isObject(c) || !Array.isArray(c.panels)) {\n drop(`a column on the ${side}`);\n continue;\n }\n extra(c, [\"panels\", \"width\", \"show\", \"active\"], \"column.\");\n const panels = (c.panels as unknown[]).map(take).filter((x): x is string => x !== null);\n if (panels.length === 0) continue;\n const ds = defs ? panels.map((id) => defOf(defs, id)!) : [];\n const lo = Math.max(0, ...ds.map((d) => d.width.min));\n const hi = Math.max(lo, Math.min(...ds.map((d) => d.width.max)));\n const natural = ds.length ? Math.max(...ds.map((d) => d.width.natural)) : 0;\n const width = finite(c.width) ? c.width : natural;\n // `show`: \"tabs\" or \"stack\" (a stack is the default, so not kept); `active`: a panel of this column.\n if (c.show !== undefined && c.show !== \"tabs\" && c.show !== \"stack\") drop(\"column.show\");\n if (c.active !== undefined && !(typeof c.active === \"string\" && panels.includes(c.active))) drop(`column.active:${typeof c.active === \"string\" ? c.active : typeof c.active}`);\n const tabs = c.show === \"tabs\" ? { show: \"tabs\" as const } : {};\n const active = typeof c.active === \"string\" && panels.includes(c.active) ? { active: c.active } : {};\n sides[side].push({ panels, width: defs ? Math.min(Math.max(width, lo), hi) : Math.max(0, width), ...tabs, ...active });\n }\n }\n const floats: FloatAt[] = [];\n for (const f of Array.isArray(data.floats) ? (data.floats as unknown[]) : []) {\n const r = isObject(f) ? f.rect : undefined;\n if (!isObject(f) || !isObject(r) || !finite(r.x) || !finite(r.y) || !finite(r.width) || !finite(r.height)) {\n drop(isObject(f) && typeof f.id === \"string\" ? f.id : \"a float\");\n continue;\n }\n extra(f, [\"id\", \"rect\", \"pinned\"], \"float.\");\n const id = take(f.id);\n if (id === null) continue;\n const min = defs ? floatSize(defOf(defs, id)).min : { width: 0, height: 0 };\n floats.push({ id, rect: { x: r.x, y: r.y, width: Math.max(min.width, r.width), height: Math.max(min.height, r.height) }, ...(f.pinned === true ? { pinned: true } : {}) });\n }\n if (data.floats !== undefined && !Array.isArray(data.floats)) drop(\"floats\");\n // The lists keep only ids that are placed (a closed panel keeps its place).\n const placed = (key: \"folded\" | \"kept\" | \"closed\"): string[] => {\n const x = data[key];\n if (x === undefined) return [];\n if (!Array.isArray(x)) {\n drop(key);\n return [];\n }\n const out: string[] = [];\n for (const id of x as unknown[]) {\n if (typeof id === \"string\" && seen.has(id)) {\n if (!out.includes(id)) out.push(id);\n } else drop(typeof id === \"string\" ? id : `a ${typeof id} in ${key}`);\n }\n return out;\n };\n const floating = new Set(floats.map((f) => f.id));\n // Only a docked panel is kept open.\n const kept = placed(\"kept\").filter((id) => {\n if (floating.has(id)) drop(id);\n return !floating.has(id);\n });\n const clock: Record<string, Clock> = {};\n if (isObject(data.clock)) {\n for (const id of Object.keys(data.clock)) if (!seen.has(id)) drop(`clock.${id}`);\n for (const id of seen) {\n const c = data.clock[id];\n clock[id] = isObject(c) && finite(c.opened) && finite(c.used) ? { opened: c.opened, used: c.used } : { opened: 0, used: 0 };\n }\n }\n return { ok: true, state: { sides, floats, folded: placed(\"folded\"), kept, closed: placed(\"closed\"), clock }, dropped };\n}\n"],"mappings":"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","names":[]}
package/dist/desk.d.ts ADDED
@@ -0,0 +1,42 @@
1
+ import { P as PanelsOptions, a as PanelDef, b as PanelsState, c as PanelTargetInput, d as PanelTarget, p as panelDrop, e as PanelDrop, l as layoutPanels, f as PanelsLayout } from './targets-DwOTs4UC.js';
2
+ import './geometry-mL-GTRti.js';
3
+
4
+ /**
5
+ * @n-uf/placement/desk: desk presets as data on `@n-uf/placement/panels`. A preset is options for the panels engine
6
+ * and a start state; it carries no titles, no words and no toolbar wiring (the app names presets and wires its
7
+ * toolbar). It imports only the panels entry's public index, so an app that imports only `./panels` loads none of it.
8
+ *
9
+ * - `docks`: one stack column per side; sections at their natural heights when the defs give `height`; short of width a
10
+ * column folds to its side's rail. No floats.
11
+ * - `dockTear`: as docks, and panels may float (tear-off and dock-back); one panel floats in the start state.
12
+ * - `navigator`: a tabbed column on the left, a stack column on the right. No floats.
13
+ */
14
+
15
+ type PresetId = "docks" | "dockTear" | "navigator";
16
+ /** Which panels start on which side (ids in order); the others are placed by the preset. */
17
+ interface DeskHint {
18
+ readonly left?: readonly string[];
19
+ readonly right?: readonly string[];
20
+ }
21
+ interface DeskPreset {
22
+ readonly id: PresetId;
23
+ /** The panels options the preset lays out with (the caller's own options go over them). */
24
+ readonly options: Partial<PanelsOptions>;
25
+ /** Whether its panels may float: when not, `presetTargets` offers no float target. */
26
+ readonly floats: boolean;
27
+ /** Its start state for these panels. */
28
+ start(defs: readonly PanelDef[], hint?: DeskHint): PanelsState;
29
+ }
30
+ type Stage = Parameters<typeof layoutPanels>[2];
31
+ type Point = Parameters<typeof panelDrop>[2];
32
+ declare const PRESETS: Readonly<Record<PresetId, DeskPreset>>;
33
+ /** `layoutPanels` with the preset's options under the caller's. */
34
+ declare function presetLayout(preset: DeskPreset, defs: readonly PanelDef[], state: PanelsState, stage: Stage, options?: Partial<PanelsOptions>): PanelsLayout;
35
+ /** The target input with the preset's options under the caller's, and only the places the preset allows. */
36
+ declare function presetInput(preset: DeskPreset, input: PanelTargetInput): PanelTargetInput;
37
+ /** `panelTargets` with the preset's options under the caller's, and only the places the preset allows. */
38
+ declare function presetTargets(preset: DeskPreset, input: PanelTargetInput): PanelTarget[];
39
+ /** `panelDrop` laid out with the preset's options (so the slot is where the preset lays the panel). */
40
+ declare function presetDrop(preset: DeskPreset, input: PanelTargetInput, target: PanelTarget, point: Point, grab: Point): PanelDrop;
41
+
42
+ export { type DeskHint, type DeskPreset, PRESETS, type PresetId, presetDrop, presetInput, presetLayout, presetTargets };
package/dist/desk.js ADDED
@@ -0,0 +1,83 @@
1
+ import "./chunk-XUV6MJ2P.js";
2
+ import {
3
+ createPanels,
4
+ floatSize,
5
+ layoutPanels,
6
+ panelDrop,
7
+ panelTargets,
8
+ showTabs
9
+ } from "./chunk-PWQWD2CS.js";
10
+ import "./chunk-QMTNB2C3.js";
11
+
12
+ // src/desk/index.ts
13
+ function split(defs, hint = {}) {
14
+ const known = new Set(defs.map((d) => d.id));
15
+ const left = (hint.left ?? []).filter((id) => known.has(id));
16
+ const right = (hint.right ?? []).filter((id) => known.has(id) && !left.includes(id));
17
+ const rest = defs.filter((d) => !left.includes(d.id) && !right.includes(d.id));
18
+ const half = Math.ceil(defs.length / 2);
19
+ for (const d of rest) {
20
+ const mayL = !d.sides || d.sides.includes("left");
21
+ const mayR = !d.sides || d.sides.includes("right");
22
+ if (mayL && (left.length < half || !mayR)) left.push(d.id);
23
+ else if (mayR) right.push(d.id);
24
+ else left.push(d.id);
25
+ }
26
+ return { left, right };
27
+ }
28
+ var columns = (ids) => ids.length ? [[...ids]] : [];
29
+ var docksStart = (defs, hint) => {
30
+ const { left, right } = split(defs, hint);
31
+ return createPanels(defs, { left: columns(left), right: columns(right) });
32
+ };
33
+ var docks = { id: "docks", options: { fold: "rail" }, floats: false, start: docksStart };
34
+ var dockTear = {
35
+ id: "dockTear",
36
+ options: { fold: "rail", floats: "clamp" },
37
+ floats: true,
38
+ // As docks, with the right side's last panel that may float torn off, next to the left column.
39
+ start(defs, hint) {
40
+ const { left, right } = split(defs, hint);
41
+ const can = (id) => defs.find((d) => d.id === id)?.floats !== false;
42
+ const torn = [...right].reverse().find(can) ?? [...left].reverse().find(can);
43
+ const keep = (ids) => ids.filter((id) => id !== torn);
44
+ const leftW = Math.max(0, ...keep(left).map((id) => defs.find((d) => d.id === id).width.natural));
45
+ const size = floatSize(defs.find((d) => d.id === torn));
46
+ return createPanels(defs, {
47
+ left: columns(keep(left)),
48
+ right: columns(keep(right)),
49
+ ...torn ? { floats: [{ id: torn, x: leftW + 24, y: 24, width: size.natural.width, height: size.natural.height }] } : {}
50
+ });
51
+ }
52
+ };
53
+ var navigator = {
54
+ id: "navigator",
55
+ options: { fold: "rail" },
56
+ floats: false,
57
+ start(defs, hint) {
58
+ const s = docksStart(defs, hint);
59
+ return s.sides.left.length ? showTabs(s, "left", 0, true) : s;
60
+ }
61
+ };
62
+ var PRESETS = { docks, dockTear, navigator };
63
+ function presetLayout(preset, defs, state, stage, options = {}) {
64
+ return layoutPanels(defs, state, stage, { ...preset.options, ...options });
65
+ }
66
+ function presetInput(preset, input) {
67
+ const allows = (id, place) => (place.kind !== "float" || preset.floats) && (input.allows?.(id, place) ?? true);
68
+ return { ...input, options: { ...preset.options, ...input.options }, allows };
69
+ }
70
+ function presetTargets(preset, input) {
71
+ return panelTargets(presetInput(preset, input));
72
+ }
73
+ function presetDrop(preset, input, target, point, grab) {
74
+ return panelDrop(presetInput(preset, input), target, point, grab);
75
+ }
76
+ export {
77
+ PRESETS,
78
+ presetDrop,
79
+ presetInput,
80
+ presetLayout,
81
+ presetTargets
82
+ };
83
+ //# sourceMappingURL=desk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/desk/index.ts"],"sourcesContent":["/**\n * @n-uf/placement/desk: desk presets as data on `@n-uf/placement/panels`. A preset is options for the panels engine\n * and a start state; it carries no titles, no words and no toolbar wiring (the app names presets and wires its\n * toolbar). It imports only the panels entry's public index, so an app that imports only `./panels` loads none of it.\n *\n * - `docks`: one stack column per side; sections at their natural heights when the defs give `height`; short of width a\n * column folds to its side's rail. No floats.\n * - `dockTear`: as docks, and panels may float (tear-off and dock-back); one panel floats in the start state.\n * - `navigator`: a tabbed column on the left, a stack column on the right. No floats.\n */\nimport {\n createPanels,\n floatSize,\n layoutPanels,\n panelDrop,\n panelTargets,\n showTabs,\n type PanelDef,\n type PanelDrop,\n type PanelPlace,\n type PanelTarget,\n type PanelTargetInput,\n type PanelsLayout,\n type PanelsOptions,\n type PanelsState,\n} from \"../panels\";\n\nexport type PresetId = \"docks\" | \"dockTear\" | \"navigator\";\n\n/** Which panels start on which side (ids in order); the others are placed by the preset. */\nexport interface DeskHint {\n readonly left?: readonly string[];\n readonly right?: readonly string[];\n}\n\nexport interface DeskPreset {\n readonly id: PresetId;\n /** The panels options the preset lays out with (the caller's own options go over them). */\n readonly options: Partial<PanelsOptions>;\n /** Whether its panels may float: when not, `presetTargets` offers no float target. */\n readonly floats: boolean;\n /** Its start state for these panels. */\n start(defs: readonly PanelDef[], hint?: DeskHint): PanelsState;\n}\n\ntype Stage = Parameters<typeof layoutPanels>[2];\ntype Point = Parameters<typeof panelDrop>[2];\n\n/**\n * Split the panels between the sides: the hint's first, then the rest in order, each to a side it may dock on, the\n * left side taking the first half of them.\n */\nfunction split(defs: readonly PanelDef[], hint: DeskHint = {}): { left: string[]; right: string[] } {\n const known = new Set(defs.map((d) => d.id));\n const left = (hint.left ?? []).filter((id) => known.has(id));\n const right = (hint.right ?? []).filter((id) => known.has(id) && !left.includes(id));\n const rest = defs.filter((d) => !left.includes(d.id) && !right.includes(d.id));\n const half = Math.ceil(defs.length / 2);\n for (const d of rest) {\n const mayL = !d.sides || d.sides.includes(\"left\");\n const mayR = !d.sides || d.sides.includes(\"right\");\n if (mayL && (left.length < half || !mayR)) left.push(d.id);\n else if (mayR) right.push(d.id);\n else left.push(d.id);\n }\n return { left, right };\n}\n\nconst columns = (ids: readonly string[]): string[][] => (ids.length ? [[...ids]] : []);\n\nconst docksStart = (defs: readonly PanelDef[], hint?: DeskHint): PanelsState => {\n const { left, right } = split(defs, hint);\n return createPanels(defs, { left: columns(left), right: columns(right) });\n};\n\nconst docks: DeskPreset = { id: \"docks\", options: { fold: \"rail\" }, floats: false, start: docksStart };\n\nconst dockTear: DeskPreset = {\n id: \"dockTear\",\n options: { fold: \"rail\", floats: \"clamp\" },\n floats: true,\n // As docks, with the right side's last panel that may float torn off, next to the left column.\n start(defs, hint) {\n const { left, right } = split(defs, hint);\n const can = (id: string): boolean => defs.find((d) => d.id === id)?.floats !== false;\n const torn = [...right].reverse().find(can) ?? [...left].reverse().find(can);\n const keep = (ids: readonly string[]): string[] => ids.filter((id) => id !== torn);\n const leftW = Math.max(0, ...keep(left).map((id) => defs.find((d) => d.id === id)!.width.natural));\n const size = floatSize(defs.find((d) => d.id === torn));\n return createPanels(defs, {\n left: columns(keep(left)),\n right: columns(keep(right)),\n ...(torn ? { floats: [{ id: torn, x: leftW + 24, y: 24, width: size.natural.width, height: size.natural.height }] } : {}),\n });\n },\n};\n\nconst navigator: DeskPreset = {\n id: \"navigator\",\n options: { fold: \"rail\" },\n floats: false,\n start(defs, hint) {\n const s = docksStart(defs, hint);\n return s.sides.left.length ? showTabs(s, \"left\", 0, true) : s;\n },\n};\n\nexport const PRESETS: Readonly<Record<PresetId, DeskPreset>> = { docks, dockTear, navigator };\n\n/** `layoutPanels` with the preset's options under the caller's. */\nexport function presetLayout(preset: DeskPreset, defs: readonly PanelDef[], state: PanelsState, stage: Stage, options: Partial<PanelsOptions> = {}): PanelsLayout {\n return layoutPanels(defs, state, stage, { ...preset.options, ...options });\n}\n\n/** The target input with the preset's options under the caller's, and only the places the preset allows. */\nexport function presetInput(preset: DeskPreset, input: PanelTargetInput): PanelTargetInput {\n const allows = (id: string, place: PanelPlace): boolean => (place.kind !== \"float\" || preset.floats) && (input.allows?.(id, place) ?? true);\n return { ...input, options: { ...preset.options, ...input.options }, allows };\n}\n\n/** `panelTargets` with the preset's options under the caller's, and only the places the preset allows. */\nexport function presetTargets(preset: DeskPreset, input: PanelTargetInput): PanelTarget[] {\n return panelTargets(presetInput(preset, input));\n}\n\n/** `panelDrop` laid out with the preset's options (so the slot is where the preset lays the panel). */\nexport function presetDrop(preset: DeskPreset, input: PanelTargetInput, target: PanelTarget, point: Point, grab: Point): PanelDrop {\n return panelDrop(presetInput(preset, input), target, point, grab);\n}\n"],"mappings":";;;;;;;;;;;;AAoDA,SAAS,MAAM,MAA2B,OAAiB,CAAC,GAAwC;AAClG,QAAM,QAAQ,IAAI,IAAI,KAAK,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAC3C,QAAM,QAAQ,KAAK,QAAQ,CAAC,GAAG,OAAO,CAAC,OAAO,MAAM,IAAI,EAAE,CAAC;AAC3D,QAAM,SAAS,KAAK,SAAS,CAAC,GAAG,OAAO,CAAC,OAAO,MAAM,IAAI,EAAE,KAAK,CAAC,KAAK,SAAS,EAAE,CAAC;AACnF,QAAM,OAAO,KAAK,OAAO,CAAC,MAAM,CAAC,KAAK,SAAS,EAAE,EAAE,KAAK,CAAC,MAAM,SAAS,EAAE,EAAE,CAAC;AAC7E,QAAM,OAAO,KAAK,KAAK,KAAK,SAAS,CAAC;AACtC,aAAW,KAAK,MAAM;AACpB,UAAM,OAAO,CAAC,EAAE,SAAS,EAAE,MAAM,SAAS,MAAM;AAChD,UAAM,OAAO,CAAC,EAAE,SAAS,EAAE,MAAM,SAAS,OAAO;AACjD,QAAI,SAAS,KAAK,SAAS,QAAQ,CAAC,MAAO,MAAK,KAAK,EAAE,EAAE;AAAA,aAChD,KAAM,OAAM,KAAK,EAAE,EAAE;AAAA,QACzB,MAAK,KAAK,EAAE,EAAE;AAAA,EACrB;AACA,SAAO,EAAE,MAAM,MAAM;AACvB;AAEA,IAAM,UAAU,CAAC,QAAwC,IAAI,SAAS,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC;AAEpF,IAAM,aAAa,CAAC,MAA2B,SAAiC;AAC9E,QAAM,EAAE,MAAM,MAAM,IAAI,MAAM,MAAM,IAAI;AACxC,SAAO,aAAa,MAAM,EAAE,MAAM,QAAQ,IAAI,GAAG,OAAO,QAAQ,KAAK,EAAE,CAAC;AAC1E;AAEA,IAAM,QAAoB,EAAE,IAAI,SAAS,SAAS,EAAE,MAAM,OAAO,GAAG,QAAQ,OAAO,OAAO,WAAW;AAErG,IAAM,WAAuB;AAAA,EAC3B,IAAI;AAAA,EACJ,SAAS,EAAE,MAAM,QAAQ,QAAQ,QAAQ;AAAA,EACzC,QAAQ;AAAA;AAAA,EAER,MAAM,MAAM,MAAM;AAChB,UAAM,EAAE,MAAM,MAAM,IAAI,MAAM,MAAM,IAAI;AACxC,UAAM,MAAM,CAAC,OAAwB,KAAK,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,WAAW;AAC/E,UAAM,OAAO,CAAC,GAAG,KAAK,EAAE,QAAQ,EAAE,KAAK,GAAG,KAAK,CAAC,GAAG,IAAI,EAAE,QAAQ,EAAE,KAAK,GAAG;AAC3E,UAAM,OAAO,CAAC,QAAqC,IAAI,OAAO,CAAC,OAAO,OAAO,IAAI;AACjF,UAAM,QAAQ,KAAK,IAAI,GAAG,GAAG,KAAK,IAAI,EAAE,IAAI,CAAC,OAAO,KAAK,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,EAAG,MAAM,OAAO,CAAC;AACjG,UAAM,OAAO,UAAU,KAAK,KAAK,CAAC,MAAM,EAAE,OAAO,IAAI,CAAC;AACtD,WAAO,aAAa,MAAM;AAAA,MACxB,MAAM,QAAQ,KAAK,IAAI,CAAC;AAAA,MACxB,OAAO,QAAQ,KAAK,KAAK,CAAC;AAAA,MAC1B,GAAI,OAAO,EAAE,QAAQ,CAAC,EAAE,IAAI,MAAM,GAAG,QAAQ,IAAI,GAAG,IAAI,OAAO,KAAK,QAAQ,OAAO,QAAQ,KAAK,QAAQ,OAAO,CAAC,EAAE,IAAI,CAAC;AAAA,IACzH,CAAC;AAAA,EACH;AACF;AAEA,IAAM,YAAwB;AAAA,EAC5B,IAAI;AAAA,EACJ,SAAS,EAAE,MAAM,OAAO;AAAA,EACxB,QAAQ;AAAA,EACR,MAAM,MAAM,MAAM;AAChB,UAAM,IAAI,WAAW,MAAM,IAAI;AAC/B,WAAO,EAAE,MAAM,KAAK,SAAS,SAAS,GAAG,QAAQ,GAAG,IAAI,IAAI;AAAA,EAC9D;AACF;AAEO,IAAM,UAAkD,EAAE,OAAO,UAAU,UAAU;AAGrF,SAAS,aAAa,QAAoB,MAA2B,OAAoB,OAAc,UAAkC,CAAC,GAAiB;AAChK,SAAO,aAAa,MAAM,OAAO,OAAO,EAAE,GAAG,OAAO,SAAS,GAAG,QAAQ,CAAC;AAC3E;AAGO,SAAS,YAAY,QAAoB,OAA2C;AACzF,QAAM,SAAS,CAAC,IAAY,WAAgC,MAAM,SAAS,WAAW,OAAO,YAAY,MAAM,SAAS,IAAI,KAAK,KAAK;AACtI,SAAO,EAAE,GAAG,OAAO,SAAS,EAAE,GAAG,OAAO,SAAS,GAAG,MAAM,QAAQ,GAAG,OAAO;AAC9E;AAGO,SAAS,cAAc,QAAoB,OAAwC;AACxF,SAAO,aAAa,YAAY,QAAQ,KAAK,CAAC;AAChD;AAGO,SAAS,WAAW,QAAoB,OAAyB,QAAqB,OAAc,MAAwB;AACjI,SAAO,UAAU,YAAY,QAAQ,KAAK,GAAG,QAAQ,OAAO,IAAI;AAClE;","names":[]}
package/dist/panels.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { P as PanelsState, S as Side, C as Clock, a as PanelDef } from './targets-DqhZf3XZ.js';
2
- export { b as COLUMN_REACH, c as Column, D as DEFAULT_PANELS_OPTIONS, d as DockOptions, F as FLOAT_HEIGHT, e as FLOAT_MIN, f as FloatAt, G as GiveWay, I as IDENTITY_VIEW, g as PanelDrop, h as PanelKind, i as PanelPlace, j as PanelStop, k as PanelStopsOptions, l as PanelTarget, m as PanelTargetInput, n as PanelsLayout, o as PanelsNote, p as PanelsNoteCode, q as PanelsOptions, r as PanelsStart, s as PlacedColumn, t as PlacedPanel, u as PlacedRail, R as RAIL_EDGE, v as SIDES, V as View, W as Where, w as close, x as columnWidth, y as createPanels, z as defOf, A as dock, B as float, E as floatSize, H as focus, J as giveWayOrder, K as homePlace, L as keep, M as layoutPanels, N as liftPanel, O as open, Q as ownWidth, T as panelDrop, U as panelStops, X as panelTargets, Y as pin, Z as placeRank, _ as resizeColumn, $ as resizeFloat, a0 as samePlaces, a1 as tick, a2 as toPage, a3 as toView, a4 as toggleFold, a5 as whereIs } from './targets-DqhZf3XZ.js';
1
+ import { b as PanelsState, S as Side, C as Clock, a as PanelDef } from './targets-DwOTs4UC.js';
2
+ export { g as COLUMN_REACH, h as Column, D as DEFAULT_PANELS_OPTIONS, i as DockOptions, F as FLOAT_HEIGHT, j as FLOAT_MIN, k as FloatAt, G as GiveWay, I as IDENTITY_VIEW, e as PanelDrop, m as PanelKind, n as PanelPlace, o as PanelStop, q as PanelStopsOptions, d as PanelTarget, c as PanelTargetInput, f as PanelsLayout, r as PanelsNote, s as PanelsNoteCode, P as PanelsOptions, t as PanelsStart, u as PlacedColumn, v as PlacedPanel, w as PlacedRail, R as RAIL_EDGE, x as SIDES, V as View, W as Where, y as activate, z as close, A as columnWidth, B as createPanels, E as defOf, H as dock, J as float, K as floatSize, L as focus, M as giveWayOrder, N as homePlace, O as keep, l as layoutPanels, Q as liftPanel, T as open, U as ownWidth, p as panelDrop, X as panelStops, Y as panelTargets, Z as pin, _ as placeRank, $ as resizeColumn, a0 as resizeFloat, a1 as samePlaces, a2 as showTabs, a3 as tick, a4 as toPage, a5 as toView, a6 as toggleFold, a7 as whereIs } from './targets-DwOTs4UC.js';
3
3
  import { R as Rect } from './geometry-mL-GTRti.js';
4
4
 
5
5
  /**
@@ -12,14 +12,18 @@ import { R as Rect } from './geometry-mL-GTRti.js';
12
12
  * Version 1 only gains optional fields. A field this reader doesn't know (a newer writer's, say) is no error either:
13
13
  * it is skipped and reported in `dropped` (`"<field>"` at the top, `"sides.<key>"`, `"column.<field>"`,
14
14
  * `"float.<field>"`; a clock entry for a panel that isn't placed as `"clock.<id>"`), so a consumer can tell that
15
- * something was left out.
15
+ * something was left out. A column's `show` ("tabs") and `active` are such optional fields: an unknown `show` is
16
+ * dropped as `"column.show"`, an `active` that isn't one of the column's panels as `"column.active:<id>"`.
16
17
  */
17
18
 
18
19
  interface StoredPanels {
19
20
  readonly v: 1;
21
+ /** A column's `show` and `active` only when it is tabbed / has one (optional fields of v1). */
20
22
  readonly sides: Record<Side, {
21
23
  panels: string[];
22
24
  width: number;
25
+ show?: "tabs";
26
+ active?: string;
23
27
  }[]>;
24
28
  readonly floats: {
25
29
  id: string;
package/dist/panels.js CHANGED
@@ -1,3 +1,7 @@
1
+ import {
2
+ readPanels,
3
+ storePanels
4
+ } from "./chunk-XUV6MJ2P.js";
1
5
  import {
2
6
  COLUMN_REACH,
3
7
  DEFAULT_PANELS_OPTIONS,
@@ -6,6 +10,7 @@ import {
6
10
  IDENTITY_VIEW,
7
11
  RAIL_EDGE,
8
12
  SIDES,
13
+ activate,
9
14
  close,
10
15
  columnWidth,
11
16
  createPanels,
@@ -29,130 +34,14 @@ import {
29
34
  resizeColumn,
30
35
  resizeFloat,
31
36
  samePlaces,
37
+ showTabs,
32
38
  tick,
33
39
  toPage,
34
40
  toView,
35
41
  toggleFold,
36
42
  whereIs
37
- } from "./chunk-QR7MGDX6.js";
43
+ } from "./chunk-PWQWD2CS.js";
38
44
  import "./chunk-QMTNB2C3.js";
39
-
40
- // src/panels/store.ts
41
- function storePanels(state) {
42
- const sides = Object.fromEntries(SIDES.map((s) => [s, state.sides[s].map((c) => ({ panels: [...c.panels], width: c.width }))]));
43
- return {
44
- v: 1,
45
- sides,
46
- floats: state.floats.map((f) => ({ id: f.id, rect: { x: f.rect.x, y: f.rect.y, width: f.rect.width, height: f.rect.height }, pinned: !!f.pinned })),
47
- folded: [...state.folded],
48
- kept: [...state.kept],
49
- closed: [...state.closed],
50
- clock: Object.fromEntries(Object.entries(state.clock).map(([k, c]) => [k, { opened: c.opened, used: c.used }]))
51
- };
52
- }
53
- var isObject = (x) => typeof x === "object" && x !== null && !Array.isArray(x);
54
- var finite = (x) => typeof x === "number" && Number.isFinite(x);
55
- function readPanels(data, defs) {
56
- try {
57
- return read(data, defs);
58
- } catch (e) {
59
- return { ok: false, error: `unreadable: ${e instanceof Error ? e.message : typeof e}` };
60
- }
61
- }
62
- function read(data, defs) {
63
- if (!isObject(data)) return { ok: false, error: "not an object" };
64
- if (data.v !== 1) return { ok: false, error: `unknown version ${typeof data.v === "number" || typeof data.v === "string" ? String(data.v) : typeof data.v} (this reads version 1)` };
65
- if (!isObject(data.sides)) return { ok: false, error: "sides is missing" };
66
- const dropped = [];
67
- const drop = (what) => {
68
- if (!dropped.includes(what)) dropped.push(what);
69
- };
70
- const seen = /* @__PURE__ */ new Set();
71
- const take = (x) => {
72
- if (typeof x !== "string") {
73
- drop(`a ${typeof x} where an id goes`);
74
- return null;
75
- }
76
- if (defs && !defOf(defs, x) || seen.has(x)) {
77
- drop(x);
78
- return null;
79
- }
80
- seen.add(x);
81
- return x;
82
- };
83
- const extra = (o, known, prefix) => {
84
- for (const k of Object.keys(o)) if (!known.includes(k)) drop(`${prefix}${k}`);
85
- };
86
- extra(data, ["v", "sides", "floats", "folded", "kept", "closed", "clock"], "");
87
- extra(data.sides, SIDES, "sides.");
88
- const sides = { left: [], right: [] };
89
- for (const side of SIDES) {
90
- const cols = data.sides[side];
91
- if (cols === void 0) continue;
92
- if (!Array.isArray(cols)) {
93
- drop(`sides.${side}`);
94
- continue;
95
- }
96
- for (const c of cols) {
97
- if (!isObject(c) || !Array.isArray(c.panels)) {
98
- drop(`a column on the ${side}`);
99
- continue;
100
- }
101
- extra(c, ["panels", "width"], "column.");
102
- const panels = c.panels.map(take).filter((x) => x !== null);
103
- if (panels.length === 0) continue;
104
- const ds = defs ? panels.map((id) => defOf(defs, id)) : [];
105
- const lo = Math.max(0, ...ds.map((d) => d.width.min));
106
- const hi = Math.max(lo, Math.min(...ds.map((d) => d.width.max)));
107
- const natural = ds.length ? Math.max(...ds.map((d) => d.width.natural)) : 0;
108
- const width = finite(c.width) ? c.width : natural;
109
- sides[side].push({ panels, width: defs ? Math.min(Math.max(width, lo), hi) : Math.max(0, width) });
110
- }
111
- }
112
- const floats = [];
113
- for (const f of Array.isArray(data.floats) ? data.floats : []) {
114
- const r = isObject(f) ? f.rect : void 0;
115
- if (!isObject(f) || !isObject(r) || !finite(r.x) || !finite(r.y) || !finite(r.width) || !finite(r.height)) {
116
- drop(isObject(f) && typeof f.id === "string" ? f.id : "a float");
117
- continue;
118
- }
119
- extra(f, ["id", "rect", "pinned"], "float.");
120
- const id = take(f.id);
121
- if (id === null) continue;
122
- const min = defs ? floatSize(defOf(defs, id)).min : { width: 0, height: 0 };
123
- floats.push({ id, rect: { x: r.x, y: r.y, width: Math.max(min.width, r.width), height: Math.max(min.height, r.height) }, ...f.pinned === true ? { pinned: true } : {} });
124
- }
125
- if (data.floats !== void 0 && !Array.isArray(data.floats)) drop("floats");
126
- const placed = (key) => {
127
- const x = data[key];
128
- if (x === void 0) return [];
129
- if (!Array.isArray(x)) {
130
- drop(key);
131
- return [];
132
- }
133
- const out = [];
134
- for (const id of x) {
135
- if (typeof id === "string" && seen.has(id)) {
136
- if (!out.includes(id)) out.push(id);
137
- } else drop(typeof id === "string" ? id : `a ${typeof id} in ${key}`);
138
- }
139
- return out;
140
- };
141
- const floating = new Set(floats.map((f) => f.id));
142
- const kept = placed("kept").filter((id) => {
143
- if (floating.has(id)) drop(id);
144
- return !floating.has(id);
145
- });
146
- const clock = {};
147
- if (isObject(data.clock)) {
148
- for (const id of Object.keys(data.clock)) if (!seen.has(id)) drop(`clock.${id}`);
149
- for (const id of seen) {
150
- const c = data.clock[id];
151
- clock[id] = isObject(c) && finite(c.opened) && finite(c.used) ? { opened: c.opened, used: c.used } : { opened: 0, used: 0 };
152
- }
153
- }
154
- return { ok: true, state: { sides, floats, folded: placed("folded"), kept, closed: placed("closed"), clock }, dropped };
155
- }
156
45
  export {
157
46
  COLUMN_REACH,
158
47
  DEFAULT_PANELS_OPTIONS,
@@ -161,6 +50,7 @@ export {
161
50
  IDENTITY_VIEW,
162
51
  RAIL_EDGE,
163
52
  SIDES,
53
+ activate,
164
54
  close,
165
55
  columnWidth,
166
56
  createPanels,
@@ -185,6 +75,7 @@ export {
185
75
  resizeColumn,
186
76
  resizeFloat,
187
77
  samePlaces,
78
+ showTabs,
188
79
  storePanels,
189
80
  tick,
190
81
  toPage,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/panels/store.ts"],"sourcesContent":["/**\n * The panels' stored form: `storePanels(state)` gives plain JSON-safe data (`{ v: 1, … }`); `readPanels(data, defs?)`\n * reads parsed data back and never throws. As with the toolbar's `readArrangement`: anything but an object of\n * version 1 is `{ ok: false, error }`. Inside one, it is lenient: an unknown id (with `defs`), a repeated one or a\n * malformed entry is dropped and listed in `dropped`; widths and float sizes are clamped to the defs. A panel the\n * consumer has but the stored state lacks is no error: the consumer places it (`open` with a place, say).\n *\n * Version 1 only gains optional fields. A field this reader doesn't know (a newer writer's, say) is no error either:\n * it is skipped and reported in `dropped` (`\"<field>\"` at the top, `\"sides.<key>\"`, `\"column.<field>\"`,\n * `\"float.<field>\"`; a clock entry for a panel that isn't placed as `\"clock.<id>\"`), so a consumer can tell that\n * something was left out.\n */\nimport type { Rect } from \"../geometry\";\nimport { SIDES, defOf, floatSize, type Clock, type Column, type FloatAt, type PanelDef, type PanelsState, type Side } from \"./model\";\n\nexport interface StoredPanels {\n readonly v: 1;\n readonly sides: Record<Side, { panels: string[]; width: number }[]>;\n readonly floats: { id: string; rect: Rect; pinned: boolean }[];\n readonly folded: string[];\n readonly kept: string[];\n readonly closed: string[];\n readonly clock: Record<string, Clock>;\n}\n\nexport type PanelsRead = { readonly ok: true; readonly state: PanelsState; readonly dropped: readonly string[] } | { readonly ok: false; readonly error: string };\n\nexport function storePanels(state: PanelsState): StoredPanels {\n const sides = Object.fromEntries(SIDES.map((s) => [s, state.sides[s].map((c) => ({ panels: [...c.panels], width: c.width }))])) as StoredPanels[\"sides\"];\n return {\n v: 1,\n sides,\n floats: state.floats.map((f) => ({ id: f.id, rect: { x: f.rect.x, y: f.rect.y, width: f.rect.width, height: f.rect.height }, pinned: !!f.pinned })),\n folded: [...state.folded],\n kept: [...state.kept],\n closed: [...state.closed],\n clock: Object.fromEntries(Object.entries(state.clock).map(([k, c]) => [k, { opened: c.opened, used: c.used }])),\n };\n}\n\nconst isObject = (x: unknown): x is Record<string, unknown> => typeof x === \"object\" && x !== null && !Array.isArray(x);\nconst finite = (x: unknown): x is number => typeof x === \"number\" && Number.isFinite(x);\n\nexport function readPanels(data: unknown, defs?: readonly PanelDef[]): PanelsRead {\n try {\n return read(data, defs);\n } catch (e) {\n // A getter that throws, a proxy: still no throw.\n return { ok: false, error: `unreadable: ${e instanceof Error ? e.message : typeof e}` };\n }\n}\n\nfunction read(data: unknown, defs?: readonly PanelDef[]): PanelsRead {\n if (!isObject(data)) return { ok: false, error: \"not an object\" };\n // Named without serialising it: a BigInt or a circular value must not throw.\n if (data.v !== 1) return { ok: false, error: `unknown version ${typeof data.v === \"number\" || typeof data.v === \"string\" ? String(data.v) : typeof data.v} (this reads version 1)` };\n if (!isObject(data.sides)) return { ok: false, error: \"sides is missing\" };\n const dropped: string[] = [];\n const drop = (what: string): void => {\n if (!dropped.includes(what)) dropped.push(what);\n };\n const seen = new Set<string>();\n // An id the consumer has, not placed yet.\n const take = (x: unknown): string | null => {\n if (typeof x !== \"string\") {\n drop(`a ${typeof x} where an id goes`);\n return null;\n }\n if ((defs && !defOf(defs, x)) || seen.has(x)) {\n drop(x);\n return null;\n }\n seen.add(x);\n return x;\n };\n // Fields this version doesn't know: skipped, and reported.\n const extra = (o: Record<string, unknown>, known: readonly string[], prefix: string): void => {\n for (const k of Object.keys(o)) if (!known.includes(k)) drop(`${prefix}${k}`);\n };\n extra(data, [\"v\", \"sides\", \"floats\", \"folded\", \"kept\", \"closed\", \"clock\"], \"\");\n extra(data.sides, SIDES, \"sides.\");\n const sides = { left: [] as Column[], right: [] as Column[] };\n for (const side of SIDES) {\n const cols = data.sides[side];\n if (cols === undefined) continue;\n if (!Array.isArray(cols)) {\n drop(`sides.${side}`);\n continue;\n }\n for (const c of cols as unknown[]) {\n if (!isObject(c) || !Array.isArray(c.panels)) {\n drop(`a column on the ${side}`);\n continue;\n }\n extra(c, [\"panels\", \"width\"], \"column.\");\n const panels = (c.panels as unknown[]).map(take).filter((x): x is string => x !== null);\n if (panels.length === 0) continue;\n const ds = defs ? panels.map((id) => defOf(defs, id)!) : [];\n const lo = Math.max(0, ...ds.map((d) => d.width.min));\n const hi = Math.max(lo, Math.min(...ds.map((d) => d.width.max)));\n const natural = ds.length ? Math.max(...ds.map((d) => d.width.natural)) : 0;\n const width = finite(c.width) ? c.width : natural;\n sides[side].push({ panels, width: defs ? Math.min(Math.max(width, lo), hi) : Math.max(0, width) });\n }\n }\n const floats: FloatAt[] = [];\n for (const f of Array.isArray(data.floats) ? (data.floats as unknown[]) : []) {\n const r = isObject(f) ? f.rect : undefined;\n if (!isObject(f) || !isObject(r) || !finite(r.x) || !finite(r.y) || !finite(r.width) || !finite(r.height)) {\n drop(isObject(f) && typeof f.id === \"string\" ? f.id : \"a float\");\n continue;\n }\n extra(f, [\"id\", \"rect\", \"pinned\"], \"float.\");\n const id = take(f.id);\n if (id === null) continue;\n const min = defs ? floatSize(defOf(defs, id)).min : { width: 0, height: 0 };\n floats.push({ id, rect: { x: r.x, y: r.y, width: Math.max(min.width, r.width), height: Math.max(min.height, r.height) }, ...(f.pinned === true ? { pinned: true } : {}) });\n }\n if (data.floats !== undefined && !Array.isArray(data.floats)) drop(\"floats\");\n // The lists keep only ids that are placed (a closed panel keeps its place).\n const placed = (key: \"folded\" | \"kept\" | \"closed\"): string[] => {\n const x = data[key];\n if (x === undefined) return [];\n if (!Array.isArray(x)) {\n drop(key);\n return [];\n }\n const out: string[] = [];\n for (const id of x as unknown[]) {\n if (typeof id === \"string\" && seen.has(id)) {\n if (!out.includes(id)) out.push(id);\n } else drop(typeof id === \"string\" ? id : `a ${typeof id} in ${key}`);\n }\n return out;\n };\n const floating = new Set(floats.map((f) => f.id));\n // Only a docked panel is kept open.\n const kept = placed(\"kept\").filter((id) => {\n if (floating.has(id)) drop(id);\n return !floating.has(id);\n });\n const clock: Record<string, Clock> = {};\n if (isObject(data.clock)) {\n for (const id of Object.keys(data.clock)) if (!seen.has(id)) drop(`clock.${id}`);\n for (const id of seen) {\n const c = data.clock[id];\n clock[id] = isObject(c) && finite(c.opened) && finite(c.used) ? { opened: c.opened, used: c.used } : { opened: 0, used: 0 };\n }\n }\n return { ok: true, state: { sides, floats, folded: placed(\"folded\"), kept, closed: placed(\"closed\"), clock }, dropped };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BO,SAAS,YAAY,OAAkC;AAC5D,QAAM,QAAQ,OAAO,YAAY,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;AAC9H,SAAO;AAAA,IACL,GAAG;AAAA,IACH;AAAA,IACA,QAAQ,MAAM,OAAO,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,MAAM,EAAE,GAAG,EAAE,KAAK,GAAG,GAAG,EAAE,KAAK,GAAG,OAAO,EAAE,KAAK,OAAO,QAAQ,EAAE,KAAK,OAAO,GAAG,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE;AAAA,IAClJ,QAAQ,CAAC,GAAG,MAAM,MAAM;AAAA,IACxB,MAAM,CAAC,GAAG,MAAM,IAAI;AAAA,IACpB,QAAQ,CAAC,GAAG,MAAM,MAAM;AAAA,IACxB,OAAO,OAAO,YAAY,OAAO,QAAQ,MAAM,KAAK,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;AAAA,EAChH;AACF;AAEA,IAAM,WAAW,CAAC,MAA6C,OAAO,MAAM,YAAY,MAAM,QAAQ,CAAC,MAAM,QAAQ,CAAC;AACtH,IAAM,SAAS,CAAC,MAA4B,OAAO,MAAM,YAAY,OAAO,SAAS,CAAC;AAE/E,SAAS,WAAW,MAAe,MAAwC;AAChF,MAAI;AACF,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,SAAS,GAAG;AAEV,WAAO,EAAE,IAAI,OAAO,OAAO,eAAe,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,GAAG;AAAA,EACxF;AACF;AAEA,SAAS,KAAK,MAAe,MAAwC;AACnE,MAAI,CAAC,SAAS,IAAI,EAAG,QAAO,EAAE,IAAI,OAAO,OAAO,gBAAgB;AAEhE,MAAI,KAAK,MAAM,EAAG,QAAO,EAAE,IAAI,OAAO,OAAO,mBAAmB,OAAO,KAAK,MAAM,YAAY,OAAO,KAAK,MAAM,WAAW,OAAO,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,0BAA0B;AACnL,MAAI,CAAC,SAAS,KAAK,KAAK,EAAG,QAAO,EAAE,IAAI,OAAO,OAAO,mBAAmB;AACzE,QAAM,UAAoB,CAAC;AAC3B,QAAM,OAAO,CAAC,SAAuB;AACnC,QAAI,CAAC,QAAQ,SAAS,IAAI,EAAG,SAAQ,KAAK,IAAI;AAAA,EAChD;AACA,QAAM,OAAO,oBAAI,IAAY;AAE7B,QAAM,OAAO,CAAC,MAA8B;AAC1C,QAAI,OAAO,MAAM,UAAU;AACzB,WAAK,KAAK,OAAO,CAAC,mBAAmB;AACrC,aAAO;AAAA,IACT;AACA,QAAK,QAAQ,CAAC,MAAM,MAAM,CAAC,KAAM,KAAK,IAAI,CAAC,GAAG;AAC5C,WAAK,CAAC;AACN,aAAO;AAAA,IACT;AACA,SAAK,IAAI,CAAC;AACV,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,CAAC,GAA4B,OAA0B,WAAyB;AAC5F,eAAW,KAAK,OAAO,KAAK,CAAC,EAAG,KAAI,CAAC,MAAM,SAAS,CAAC,EAAG,MAAK,GAAG,MAAM,GAAG,CAAC,EAAE;AAAA,EAC9E;AACA,QAAM,MAAM,CAAC,KAAK,SAAS,UAAU,UAAU,QAAQ,UAAU,OAAO,GAAG,EAAE;AAC7E,QAAM,KAAK,OAAO,OAAO,QAAQ;AACjC,QAAM,QAAQ,EAAE,MAAM,CAAC,GAAe,OAAO,CAAC,EAAc;AAC5D,aAAW,QAAQ,OAAO;AACxB,UAAM,OAAO,KAAK,MAAM,IAAI;AAC5B,QAAI,SAAS,OAAW;AACxB,QAAI,CAAC,MAAM,QAAQ,IAAI,GAAG;AACxB,WAAK,SAAS,IAAI,EAAE;AACpB;AAAA,IACF;AACA,eAAW,KAAK,MAAmB;AACjC,UAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,QAAQ,EAAE,MAAM,GAAG;AAC5C,aAAK,mBAAmB,IAAI,EAAE;AAC9B;AAAA,MACF;AACA,YAAM,GAAG,CAAC,UAAU,OAAO,GAAG,SAAS;AACvC,YAAM,SAAU,EAAE,OAAqB,IAAI,IAAI,EAAE,OAAO,CAAC,MAAmB,MAAM,IAAI;AACtF,UAAI,OAAO,WAAW,EAAG;AACzB,YAAM,KAAK,OAAO,OAAO,IAAI,CAAC,OAAO,MAAM,MAAM,EAAE,CAAE,IAAI,CAAC;AAC1D,YAAM,KAAK,KAAK,IAAI,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC;AACpD,YAAM,KAAK,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC;AAC/D,YAAM,UAAU,GAAG,SAAS,KAAK,IAAI,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI;AAC1E,YAAM,QAAQ,OAAO,EAAE,KAAK,IAAI,EAAE,QAAQ;AAC1C,YAAM,IAAI,EAAE,KAAK,EAAE,QAAQ,OAAO,OAAO,KAAK,IAAI,KAAK,IAAI,OAAO,EAAE,GAAG,EAAE,IAAI,KAAK,IAAI,GAAG,KAAK,EAAE,CAAC;AAAA,IACnG;AAAA,EACF;AACA,QAAM,SAAoB,CAAC;AAC3B,aAAW,KAAK,MAAM,QAAQ,KAAK,MAAM,IAAK,KAAK,SAAuB,CAAC,GAAG;AAC5E,UAAM,IAAI,SAAS,CAAC,IAAI,EAAE,OAAO;AACjC,QAAI,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG;AACzG,WAAK,SAAS,CAAC,KAAK,OAAO,EAAE,OAAO,WAAW,EAAE,KAAK,SAAS;AAC/D;AAAA,IACF;AACA,UAAM,GAAG,CAAC,MAAM,QAAQ,QAAQ,GAAG,QAAQ;AAC3C,UAAM,KAAK,KAAK,EAAE,EAAE;AACpB,QAAI,OAAO,KAAM;AACjB,UAAM,MAAM,OAAO,UAAU,MAAM,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,GAAG,QAAQ,EAAE;AAC1E,WAAO,KAAK,EAAE,IAAI,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,GAAG,OAAO,KAAK,IAAI,IAAI,OAAO,EAAE,KAAK,GAAG,QAAQ,KAAK,IAAI,IAAI,QAAQ,EAAE,MAAM,EAAE,GAAG,GAAI,EAAE,WAAW,OAAO,EAAE,QAAQ,KAAK,IAAI,CAAC,EAAG,CAAC;AAAA,EAC3K;AACA,MAAI,KAAK,WAAW,UAAa,CAAC,MAAM,QAAQ,KAAK,MAAM,EAAG,MAAK,QAAQ;AAE3E,QAAM,SAAS,CAAC,QAAgD;AAC9D,UAAM,IAAI,KAAK,GAAG;AAClB,QAAI,MAAM,OAAW,QAAO,CAAC;AAC7B,QAAI,CAAC,MAAM,QAAQ,CAAC,GAAG;AACrB,WAAK,GAAG;AACR,aAAO,CAAC;AAAA,IACV;AACA,UAAM,MAAgB,CAAC;AACvB,eAAW,MAAM,GAAgB;AAC/B,UAAI,OAAO,OAAO,YAAY,KAAK,IAAI,EAAE,GAAG;AAC1C,YAAI,CAAC,IAAI,SAAS,EAAE,EAAG,KAAI,KAAK,EAAE;AAAA,MACpC,MAAO,MAAK,OAAO,OAAO,WAAW,KAAK,KAAK,OAAO,EAAE,OAAO,GAAG,EAAE;AAAA,IACtE;AACA,WAAO;AAAA,EACT;AACA,QAAM,WAAW,IAAI,IAAI,OAAO,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAEhD,QAAM,OAAO,OAAO,MAAM,EAAE,OAAO,CAAC,OAAO;AACzC,QAAI,SAAS,IAAI,EAAE,EAAG,MAAK,EAAE;AAC7B,WAAO,CAAC,SAAS,IAAI,EAAE;AAAA,EACzB,CAAC;AACD,QAAM,QAA+B,CAAC;AACtC,MAAI,SAAS,KAAK,KAAK,GAAG;AACxB,eAAW,MAAM,OAAO,KAAK,KAAK,KAAK,EAAG,KAAI,CAAC,KAAK,IAAI,EAAE,EAAG,MAAK,SAAS,EAAE,EAAE;AAC/E,eAAW,MAAM,MAAM;AACrB,YAAM,IAAI,KAAK,MAAM,EAAE;AACvB,YAAM,EAAE,IAAI,SAAS,CAAC,KAAK,OAAO,EAAE,MAAM,KAAK,OAAO,EAAE,IAAI,IAAI,EAAE,QAAQ,EAAE,QAAQ,MAAM,EAAE,KAAK,IAAI,EAAE,QAAQ,GAAG,MAAM,EAAE;AAAA,IAC5H;AAAA,EACF;AACA,SAAO,EAAE,IAAI,MAAM,OAAO,EAAE,OAAO,QAAQ,QAAQ,OAAO,QAAQ,GAAG,MAAM,QAAQ,OAAO,QAAQ,GAAG,MAAM,GAAG,QAAQ;AACxH;","names":[]}
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}