@graview/react 0.1.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.
- package/LICENSE +96 -0
- package/README.md +20 -0
- package/dist/activity.d.ts +113 -0
- package/dist/activity.d.ts.map +1 -0
- package/dist/activity.js +207 -0
- package/dist/activity.js.map +1 -0
- package/dist/animation.d.ts +64 -0
- package/dist/animation.d.ts.map +1 -0
- package/dist/animation.js +245 -0
- package/dist/animation.js.map +1 -0
- package/dist/captions.d.ts +43 -0
- package/dist/captions.d.ts.map +1 -0
- package/dist/captions.js +61 -0
- package/dist/captions.js.map +1 -0
- package/dist/channels.d.ts +15 -0
- package/dist/channels.d.ts.map +1 -0
- package/dist/channels.js +114 -0
- package/dist/channels.js.map +1 -0
- package/dist/connectors.d.ts +176 -0
- package/dist/connectors.d.ts.map +1 -0
- package/dist/connectors.js +837 -0
- package/dist/connectors.js.map +1 -0
- package/dist/context.d.ts +348 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +568 -0
- package/dist/context.js.map +1 -0
- package/dist/drawn.d.ts +60 -0
- package/dist/drawn.d.ts.map +1 -0
- package/dist/drawn.js +58 -0
- package/dist/drawn.js.map +1 -0
- package/dist/edge-signs.d.ts +13 -0
- package/dist/edge-signs.d.ts.map +1 -0
- package/dist/edge-signs.js +76 -0
- package/dist/edge-signs.js.map +1 -0
- package/dist/hooks.d.ts +160 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +457 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/keyboard.d.ts +5 -0
- package/dist/keyboard.d.ts.map +1 -0
- package/dist/keyboard.js +178 -0
- package/dist/keyboard.js.map +1 -0
- package/dist/kit.d.ts +10 -0
- package/dist/kit.d.ts.map +1 -0
- package/dist/kit.js +32 -0
- package/dist/kit.js.map +1 -0
- package/dist/local-intelligence.d.ts +31 -0
- package/dist/local-intelligence.d.ts.map +1 -0
- package/dist/local-intelligence.js +66 -0
- package/dist/local-intelligence.js.map +1 -0
- package/dist/motion.d.ts +17 -0
- package/dist/motion.d.ts.map +1 -0
- package/dist/motion.js +26 -0
- package/dist/motion.js.map +1 -0
- package/dist/occupants.d.ts +45 -0
- package/dist/occupants.d.ts.map +1 -0
- package/dist/occupants.js +57 -0
- package/dist/occupants.js.map +1 -0
- package/dist/parallel.d.ts +19 -0
- package/dist/parallel.d.ts.map +1 -0
- package/dist/parallel.js +30 -0
- package/dist/parallel.js.map +1 -0
- package/dist/picking.d.ts +30 -0
- package/dist/picking.d.ts.map +1 -0
- package/dist/picking.js +140 -0
- package/dist/picking.js.map +1 -0
- package/dist/plots.d.ts +106 -0
- package/dist/plots.d.ts.map +1 -0
- package/dist/plots.js +306 -0
- package/dist/plots.js.map +1 -0
- package/dist/pointer.d.ts +27 -0
- package/dist/pointer.d.ts.map +1 -0
- package/dist/pointer.js +39 -0
- package/dist/pointer.js.map +1 -0
- package/dist/presence.d.ts +110 -0
- package/dist/presence.d.ts.map +1 -0
- package/dist/presence.js +280 -0
- package/dist/presence.js.map +1 -0
- package/dist/rails.d.ts +11 -0
- package/dist/rails.d.ts.map +1 -0
- package/dist/rails.js +15 -0
- package/dist/rails.js.map +1 -0
- package/dist/resolved-view.d.ts +78 -0
- package/dist/resolved-view.d.ts.map +1 -0
- package/dist/resolved-view.js +365 -0
- package/dist/resolved-view.js.map +1 -0
- package/dist/robot.d.ts +114 -0
- package/dist/robot.d.ts.map +1 -0
- package/dist/robot.js +93 -0
- package/dist/robot.js.map +1 -0
- package/dist/routes.d.ts +50 -0
- package/dist/routes.d.ts.map +1 -0
- package/dist/routes.js +150 -0
- package/dist/routes.js.map +1 -0
- package/dist/scene-camera.d.ts +25 -0
- package/dist/scene-camera.d.ts.map +1 -0
- package/dist/scene-camera.js +130 -0
- package/dist/scene-camera.js.map +1 -0
- package/dist/scene-hand.d.ts +110 -0
- package/dist/scene-hand.d.ts.map +1 -0
- package/dist/scene-hand.js +317 -0
- package/dist/scene-hand.js.map +1 -0
- package/dist/scene-helpers.d.ts +46 -0
- package/dist/scene-helpers.d.ts.map +1 -0
- package/dist/scene-helpers.js +108 -0
- package/dist/scene-helpers.js.map +1 -0
- package/dist/scene-lines.d.ts +76 -0
- package/dist/scene-lines.d.ts.map +1 -0
- package/dist/scene-lines.js +578 -0
- package/dist/scene-lines.js.map +1 -0
- package/dist/scene-root.d.ts +71 -0
- package/dist/scene-root.d.ts.map +1 -0
- package/dist/scene-root.js +790 -0
- package/dist/scene-root.js.map +1 -0
- package/dist/scene.d.ts +17 -0
- package/dist/scene.d.ts.map +1 -0
- package/dist/scene.js +17 -0
- package/dist/scene.js.map +1 -0
- package/dist/seat-marks.d.ts +35 -0
- package/dist/seat-marks.d.ts.map +1 -0
- package/dist/seat-marks.js +43 -0
- package/dist/seat-marks.js.map +1 -0
- package/dist/settings.d.ts +30 -0
- package/dist/settings.d.ts.map +1 -0
- package/dist/settings.js +73 -0
- package/dist/settings.js.map +1 -0
- package/dist/view-boundary.d.ts +33 -0
- package/dist/view-boundary.d.ts.map +1 -0
- package/dist/view-boundary.js +53 -0
- package/dist/view-boundary.js.map +1 -0
- package/dist/view-host.d.ts +57 -0
- package/dist/view-host.d.ts.map +1 -0
- package/dist/view-host.js +474 -0
- package/dist/view-host.js.map +1 -0
- package/dist/view-registry.d.ts +122 -0
- package/dist/view-registry.d.ts.map +1 -0
- package/dist/view-registry.js +20 -0
- package/dist/view-registry.js.map +1 -0
- package/dist/where-drawn.d.ts +151 -0
- package/dist/where-drawn.d.ts.map +1 -0
- package/dist/where-drawn.js +231 -0
- package/dist/where-drawn.js.map +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { aggregateId, isAggregateId, kindCardId, kindOfCard, withFocus } from "@graview/layout";
|
|
3
|
+
import { PLANE_STYLES } from "@graview/render";
|
|
4
|
+
import { memo, useEffect, useMemo, useRef, useState } from "react";
|
|
5
|
+
import { createPortal } from "react-dom";
|
|
6
|
+
import { useFlagged, useImplicated, useNavigation } from "./hooks.js";
|
|
7
|
+
import { useFound, useGraph, useGraview, ViewModeProvider } from "./context.js";
|
|
8
|
+
import { ViewBoundary } from "./view-boundary.js";
|
|
9
|
+
/**
|
|
10
|
+
* THE DISTRICTS THE ROW COULD NOT HOLD, NAMED — BEHIND ONE PRESS.
|
|
11
|
+
*
|
|
12
|
+
* A district is read rather than glanced at, so the row never squeezes a
|
|
13
|
+
* name below a word: past what it can hold at a legible width it keeps the
|
|
14
|
+
* ones that fit and hands the rest to this. Not a district — it has no
|
|
15
|
+
* members, no figure and no count of its own — a card that says how many
|
|
16
|
+
* are missing and takes you to any of them.
|
|
17
|
+
*
|
|
18
|
+
* It used to list every name inside its own box, which is a district
|
|
19
|
+
* card's height: room for the count and nothing else, the names scrolled
|
|
20
|
+
* away under a fade, and "+6" over one clipped word read as a broken
|
|
21
|
+
* placeholder rather than the only way to five districts. So the card IS
|
|
22
|
+
* the control now — "+6 more" is a button — and pressing it opens a panel
|
|
23
|
+
* above the row that names every district with what it holds, each name
|
|
24
|
+
* a press to that district. The district you are already in, which lands
|
|
25
|
+
* here when the row has room for nothing else, is marked as here rather
|
|
26
|
+
* than offered as somewhere to go.
|
|
27
|
+
*/
|
|
28
|
+
export function BeyondCard({ kinds }) {
|
|
29
|
+
const { store } = useGraview();
|
|
30
|
+
const { view, go } = useNavigation();
|
|
31
|
+
const [open, setOpen] = useState(false);
|
|
32
|
+
const card = useRef(null);
|
|
33
|
+
/*
|
|
34
|
+
* THE PANEL LEAVES THE PLANE. Drawn inside the card it sat on plane two,
|
|
35
|
+
* and the focused card on plane zero painted over it — a menu nobody
|
|
36
|
+
* could press. It is portalled onto the scene's ground, above every
|
|
37
|
+
* plane, and placed by the card's own screen rectangle at the moment it
|
|
38
|
+
* opens; a press anywhere else closes it before the scene can move.
|
|
39
|
+
*/
|
|
40
|
+
const [anchor, setAnchor] = useState(null);
|
|
41
|
+
const place = () => {
|
|
42
|
+
const box = card.current;
|
|
43
|
+
const into = box?.closest(".graview-ground");
|
|
44
|
+
if (!box || !into)
|
|
45
|
+
return null;
|
|
46
|
+
const mine = box.getBoundingClientRect();
|
|
47
|
+
const ground = into.getBoundingClientRect();
|
|
48
|
+
return { into, left: mine.left - ground.left, bottom: ground.bottom - mine.top + 6 };
|
|
49
|
+
};
|
|
50
|
+
const plural = (kind) => store.schema.tryDefinition(kind)?.plural ?? `${kind}s`;
|
|
51
|
+
const count = (kind) => store.graph.allNodes().filter((node) => node.kind === kind).length;
|
|
52
|
+
const here = (kind) => !view.overview && view.focusId === aggregateId(kind);
|
|
53
|
+
/* Escape, or a press anywhere else, closes it; the button keeps focus. */
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
if (!open)
|
|
56
|
+
return;
|
|
57
|
+
const away = (event) => {
|
|
58
|
+
const target = event.target;
|
|
59
|
+
if (target?.closest(".graview-beyond-list, .graview-beyond"))
|
|
60
|
+
return;
|
|
61
|
+
setOpen(false);
|
|
62
|
+
setAnchor(null);
|
|
63
|
+
};
|
|
64
|
+
const key = (event) => {
|
|
65
|
+
if (event.key === "Escape") {
|
|
66
|
+
setOpen(false);
|
|
67
|
+
card.current?.querySelector(".graview-beyond-more")?.focus();
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
document.addEventListener("pointerdown", away, true);
|
|
71
|
+
document.addEventListener("keydown", key);
|
|
72
|
+
return () => {
|
|
73
|
+
document.removeEventListener("pointerdown", away, true);
|
|
74
|
+
document.removeEventListener("keydown", key);
|
|
75
|
+
};
|
|
76
|
+
}, [open]);
|
|
77
|
+
const going = kinds.filter((kind) => !here(kind));
|
|
78
|
+
/*
|
|
79
|
+
* CHOSEN, THE KEYBOARD GOES WITH IT. Choosing a district closes the menu
|
|
80
|
+
* and, often, takes this card away with it, and the keyboard fell to
|
|
81
|
+
* <body> until something noticed: on a slow phone a person pressing Tab
|
|
82
|
+
* in that moment started again at the top of the page (a location took
|
|
83
|
+
* twenty-two presses from the keyboard where it takes fourteen). The
|
|
84
|
+
* keyboard goes to the district chosen as soon as it is drawn, and to
|
|
85
|
+
* this button while it is not.
|
|
86
|
+
*/
|
|
87
|
+
const choose = (kind) => {
|
|
88
|
+
setOpen(false);
|
|
89
|
+
const button = card.current?.querySelector(".graview-beyond-more") ?? null;
|
|
90
|
+
if (!here(kind))
|
|
91
|
+
go(withFocus(view, aggregateId(kind)));
|
|
92
|
+
button?.focus({ preventScroll: true });
|
|
93
|
+
const wanted = `[data-graview-view="${aggregateId(kind)}"][tabindex], [data-graview-view="${kindCardId(kind)}"][tabindex]`;
|
|
94
|
+
let tries = 40;
|
|
95
|
+
const land = () => {
|
|
96
|
+
const drawn = document.querySelector(wanted);
|
|
97
|
+
if (drawn)
|
|
98
|
+
drawn.focus({ preventScroll: true });
|
|
99
|
+
else if (--tries > 0)
|
|
100
|
+
requestAnimationFrame(land);
|
|
101
|
+
};
|
|
102
|
+
requestAnimationFrame(land);
|
|
103
|
+
};
|
|
104
|
+
return (_jsxs("div", { ref: card, className: "graview-beyond", "data-graview-beyond": kinds.length, "data-graview-beyond-open": open ? "" : undefined, children: [_jsxs("button", { type: "button", className: "graview-beyond-more", "data-testid": "beyond-more", "aria-expanded": open, "aria-haspopup": "menu", title: `${going.length} more district${going.length === 1 ? "" : "s"} — press to see them`, onPointerDown: (event) => event.stopPropagation(), onClick: (event) => {
|
|
105
|
+
event.stopPropagation();
|
|
106
|
+
const next = !open;
|
|
107
|
+
setAnchor(next ? place() : null);
|
|
108
|
+
setOpen(next);
|
|
109
|
+
}, children: [_jsxs("span", { className: "graview-beyond-count", children: ["+", going.length] }), _jsx("span", { className: "graview-beyond-word", children: "more" }), _jsx("span", { className: "graview-beyond-chevron", "aria-hidden": "true", children: open ? "▾" : "▴" })] }), open && anchor ? createPortal(_jsx("ul", { className: "graview-beyond-list", role: "menu", "aria-label": "The other districts", "data-testid": "beyond-list", "data-graview-overlay": "", style: { left: anchor.left, bottom: anchor.bottom }, onPointerDown: (event) => event.stopPropagation(), children: kinds.map((kind) => (_jsx("li", { role: "none", children: _jsxs("button", { type: "button", role: "menuitem", "data-graview-pick": kindCardId(kind), "aria-current": here(kind) ? "location" : undefined, title: here(kind) ? `${plural(kind)} — where you are` : `Go to ${plural(kind)}`, onPointerDown: (event) => event.stopPropagation(), onClick: (event) => {
|
|
110
|
+
event.stopPropagation();
|
|
111
|
+
choose(kind);
|
|
112
|
+
}, children: [_jsx("span", { className: "graview-beyond-name", children: plural(kind) }), _jsx("span", { className: "graview-beyond-tally", children: here(kind) ? "here" : count(kind) })] }) }, kind))) }), anchor.into) : open ? (_jsx("ul", { className: "graview-beyond-list", role: "menu", "aria-label": "The other districts", "data-testid": "beyond-list", children: kinds.map((kind) => (_jsx("li", { role: "none", children: _jsx("button", { type: "button", role: "menuitem", "data-graview-pick": kindCardId(kind), onClick: () => choose(kind), children: plural(kind) }) }, kind))) })) : null] }));
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* WHETHER TWO FRAMES ASK FOR THE SAME PICTURE.
|
|
116
|
+
*
|
|
117
|
+
* Every field of the node except where it is. A pan moves the whole world by
|
|
118
|
+
* one offset and changes nothing else, so this is false exactly when the
|
|
119
|
+
* view has something new to draw — which is what lets `SettledView` sit out
|
|
120
|
+
* a drag.
|
|
121
|
+
*/
|
|
122
|
+
function samePicture(before, after) {
|
|
123
|
+
if (before === after)
|
|
124
|
+
return true;
|
|
125
|
+
const keys = Object.keys(before);
|
|
126
|
+
if (keys.length !== Object.keys(after).length)
|
|
127
|
+
return false;
|
|
128
|
+
return keys.every((key) => key === "x" ||
|
|
129
|
+
key === "y" ||
|
|
130
|
+
sameValue(before[key], after[key]));
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* The same value, by what it holds. A pan reuses a node's nested objects;
|
|
134
|
+
* a re-layout — a district moved by hand — builds them again with the same
|
|
135
|
+
* contents, and comparing those by identity redrew every lens in the city on
|
|
136
|
+
* every pointer move of the drag.
|
|
137
|
+
*/
|
|
138
|
+
function sameValue(a, b) {
|
|
139
|
+
if (Object.is(a, b))
|
|
140
|
+
return true;
|
|
141
|
+
if (typeof a !== "object" || typeof b !== "object" || a === null || b === null)
|
|
142
|
+
return false;
|
|
143
|
+
if (Array.isArray(a) !== Array.isArray(b))
|
|
144
|
+
return false;
|
|
145
|
+
if (Object.getPrototypeOf(a) !== Object.getPrototypeOf(b))
|
|
146
|
+
return false;
|
|
147
|
+
const proto = Object.getPrototypeOf(a);
|
|
148
|
+
// Only plain data: anything with a class of its own is compared by identity.
|
|
149
|
+
if (proto !== Object.prototype && proto !== Array.prototype)
|
|
150
|
+
return false;
|
|
151
|
+
const keys = Object.keys(a);
|
|
152
|
+
if (keys.length !== Object.keys(b).length)
|
|
153
|
+
return false;
|
|
154
|
+
return keys.every((key) => sameValue(a[key], b[key]));
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* THE PICTURE DOES NOT REDRAW ITSELF BECAUSE THE WORLD MOVED.
|
|
158
|
+
*
|
|
159
|
+
* `panLayout` hands every node a new object per frame — it has moved, after
|
|
160
|
+
* all — and React took that at face value and re-rendered every lens in the
|
|
161
|
+
* scene on every pointer move of a drag. A profile of one drag across rota's
|
|
162
|
+
* city put a fifth of the main thread inside the calendar, the coverage
|
|
163
|
+
* matrix and the timeline redrawing themselves, none of which had anything
|
|
164
|
+
* new to say: a lens is drawn in its host's own coordinates and does not
|
|
165
|
+
* know where the host is.
|
|
166
|
+
*
|
|
167
|
+
* So a view redraws when its picture changes, not when its position does.
|
|
168
|
+
*/
|
|
169
|
+
export const SettledView = memo(ResolvedView, (before, after) => before.mode === after.mode &&
|
|
170
|
+
before.selected === after.selected &&
|
|
171
|
+
before.fidelity === after.fidelity &&
|
|
172
|
+
samePicture(before.node, after.node));
|
|
173
|
+
/**
|
|
174
|
+
* Picks the view for a cell of the matrix — cardinality by whether this is an
|
|
175
|
+
* aggregate, fidelity by plane depth — and renders it.
|
|
176
|
+
*
|
|
177
|
+
* A kind with no registered view falls back to the primitive the app
|
|
178
|
+
* supplied, which is why a new node kind renders sensibly before anyone
|
|
179
|
+
* writes a view for it.
|
|
180
|
+
*/
|
|
181
|
+
export function ResolvedView({ node, mode, selected, fidelity, }) {
|
|
182
|
+
const { store, views, view } = useGraview();
|
|
183
|
+
/* The graph's own version: a view redraws when the graph it is drawing changes. */
|
|
184
|
+
const graph = useGraph();
|
|
185
|
+
const implicated = useImplicated();
|
|
186
|
+
const flagged = useFlagged();
|
|
187
|
+
const cardinality = node.aggregate || isAggregateId(node.id) || kindOfCard(node.id) !== null ? "many" : "one";
|
|
188
|
+
const cell = {
|
|
189
|
+
cardinality,
|
|
190
|
+
fidelity: fidelity ?? PLANE_STYLES[clampPlane(node.plane)].fidelity,
|
|
191
|
+
};
|
|
192
|
+
/*
|
|
193
|
+
* WHICH PICTURE, when a group has more than one.
|
|
194
|
+
*
|
|
195
|
+
* The week and the month are two questions about the same pile of tasks,
|
|
196
|
+
* and the stop says which one is being asked — `in.view=the-month`. A
|
|
197
|
+
* node that is not the group the address names keeps its own view, so a
|
|
198
|
+
* calendar chosen over the tasks does not try to draw a list.
|
|
199
|
+
*
|
|
200
|
+
* THE GROUP THE ADDRESS NAMES IS THE ONE IT FOCUSES, and that had to be
|
|
201
|
+
* said rather than assumed. The slug was handed to every group in the
|
|
202
|
+
* scene, so pressing "Who may do what" and then looking at something else
|
|
203
|
+
* left `in.view=who-may-do-what` in the stop, where the PEOPLE district —
|
|
204
|
+
* which is not what you are looking at — drew the policy lens instead of
|
|
205
|
+
* itself: no name, no count, no figure, no way in, just the words "Who may
|
|
206
|
+
* do what · 3 roles" floating where a district used to be. The same thing
|
|
207
|
+
* turned the Shifts card into "The week · 10".
|
|
208
|
+
*
|
|
209
|
+
* A place is a picture OF a group. A district card is the group's own
|
|
210
|
+
* mark in the city, and it stays that whatever picture the address names.
|
|
211
|
+
*/
|
|
212
|
+
const asked = cardinality === "many" && node.id === view.focusId ? view.within?.["view"] : undefined;
|
|
213
|
+
const registration = views.resolve(node.kind, cell, asked);
|
|
214
|
+
const Component = registration?.view;
|
|
215
|
+
// Whether this kind has a picture of its own to travel into.
|
|
216
|
+
const own = views.resolve(node.kind, { cardinality: "many", fidelity: "full" })?.view;
|
|
217
|
+
const hasOwnView = own !== undefined && own.generic !== true;
|
|
218
|
+
/*
|
|
219
|
+
* A group's members, looked up once per graph rather than once per frame:
|
|
220
|
+
* a kind's card holds every song, and a tween re-renders it sixty times a
|
|
221
|
+
* second with the same list.
|
|
222
|
+
*/
|
|
223
|
+
const memberIds = node.aggregate?.memberIds;
|
|
224
|
+
const members = useMemo(() => (memberIds ?? []).map((id) => store.graph.getNode(id)).filter((n) => n !== undefined), [memberIds, store, graph]);
|
|
225
|
+
const props = {
|
|
226
|
+
...(node.aggregate
|
|
227
|
+
? {
|
|
228
|
+
nodes: members,
|
|
229
|
+
// A titled registration names the picture; the plural is the fallback.
|
|
230
|
+
label: registration?.title ?? node.aggregate.label,
|
|
231
|
+
}
|
|
232
|
+
: { node: store.graph.getNode(node.id) }),
|
|
233
|
+
fidelity: cell.fidelity,
|
|
234
|
+
cardinality: cell.cardinality,
|
|
235
|
+
mode,
|
|
236
|
+
selected,
|
|
237
|
+
implicated,
|
|
238
|
+
flagged,
|
|
239
|
+
...(node.raised ? { raised: true } : {}),
|
|
240
|
+
...(node.focused ? { focused: true } : {}),
|
|
241
|
+
...(node.opened ? { opened: true } : {}),
|
|
242
|
+
...(node.openedRows !== undefined ? { openedRows: node.openedRows } : {}),
|
|
243
|
+
...(node.plot ? { plot: node.plot } : {}),
|
|
244
|
+
...(node.aggregate?.retired ? { retired: node.aggregate.retired } : {}),
|
|
245
|
+
...(node.rank ? { rank: node.rank } : {}),
|
|
246
|
+
...(node.nestedUnder ? { nestedUnder: node.nestedUnder } : {}),
|
|
247
|
+
...(hasOwnView ? { hasOwnView: true } : {}),
|
|
248
|
+
};
|
|
249
|
+
if (!Component)
|
|
250
|
+
return _jsx(MissingView, { node: node, props: props });
|
|
251
|
+
/*
|
|
252
|
+
* DRAWN AGAIN ONLY WHEN WHAT IT DRAWS CHANGED.
|
|
253
|
+
*
|
|
254
|
+
* A host re-renders on every frame of a flight, a pan and a zoom — the
|
|
255
|
+
* box it is given is changing, which is the point — and the view inside
|
|
256
|
+
* it was re-rendered with it, sixty times a second, for a picture that
|
|
257
|
+
* had not changed at all. On a heavy lens (a matrix with rotated heads,
|
|
258
|
+
* a calendar of a hundred moments) that is the whole frame budget, and
|
|
259
|
+
* it is what made choosing a picture feel slow.
|
|
260
|
+
*
|
|
261
|
+
* What it draws is the node or the members, the cell, and the handful of
|
|
262
|
+
* flags a view reads; the SIZE is not a prop, it is the box around it.
|
|
263
|
+
* A view that watches the store or the selection through a hook still
|
|
264
|
+
* re-renders on its own, because context reaches past a bailout.
|
|
265
|
+
*/
|
|
266
|
+
const signature = [
|
|
267
|
+
node.id,
|
|
268
|
+
registration?.title ?? "",
|
|
269
|
+
cell.fidelity,
|
|
270
|
+
cell.cardinality,
|
|
271
|
+
mode,
|
|
272
|
+
selected,
|
|
273
|
+
node.raised ?? false,
|
|
274
|
+
node.focused ?? false,
|
|
275
|
+
node.opened ?? false,
|
|
276
|
+
node.openedRows ?? "",
|
|
277
|
+
node.rank ?? "",
|
|
278
|
+
node.nestedUnder ?? "",
|
|
279
|
+
node.plot ? `${node.plot.col},${node.plot.row},${node.plot.side}` : "",
|
|
280
|
+
node.aggregate ? idsKey(node.aggregate.memberIds) : "",
|
|
281
|
+
node.aggregate?.retired ?? "",
|
|
282
|
+
(implicated ?? []).join(","),
|
|
283
|
+
(flagged ?? []).join(","),
|
|
284
|
+
hasOwnView,
|
|
285
|
+
].join("|");
|
|
286
|
+
/*
|
|
287
|
+
* The boundary is keyed by what it is drawing, so changing the picture or
|
|
288
|
+
* the node gives the view a fresh start rather than leaving a panel that
|
|
289
|
+
* once threw stuck saying so forever.
|
|
290
|
+
*/
|
|
291
|
+
return (_jsx(ViewModeProvider, { mode: mode, children: _jsx(ViewBoundary, { kind: props.label ?? node.kind, ...(registration?.title ? { view: registration.title } : {}), children: _jsx(Drawn, { signature: signature, graph: graph, draw: () => _jsx(Component, { ...props }) }) }, `${node.id}|${registration?.title ?? ""}`) }));
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* One view, redrawn when its signature changes and not otherwise. The
|
|
295
|
+
* element is built inside a memo, so a parent re-render with the same
|
|
296
|
+
* signature hands React the same element and it skips the subtree.
|
|
297
|
+
*/
|
|
298
|
+
export const Drawn = memo(function Drawn({ draw }) {
|
|
299
|
+
return _jsx(_Fragment, { children: draw() });
|
|
300
|
+
}, (was, now) => was.signature === now.signature && was.graph === now.graph);
|
|
301
|
+
function clampPlane(plane) {
|
|
302
|
+
return Math.max(0, Math.min(2, Math.round(plane)));
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* What a kind with no view looks like. Deliberately readable rather than
|
|
306
|
+
* apologetic: an undecorated node is a legitimate state during development,
|
|
307
|
+
* and it should still say what it is.
|
|
308
|
+
*/
|
|
309
|
+
function MissingView({ node, props, }) {
|
|
310
|
+
return (_jsxs("div", { style: { padding: 8, font: "13px/1.4 system-ui", overflow: "hidden" }, children: [_jsx("strong", { children: props.label ?? node.kind }), props.nodes ? _jsxs("div", { children: [props.nodes.length, " items"] }) : _jsx("div", { children: node.id })] }));
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* A RELATION THE BAND COULD NOT HOLD, drawn as what it is (docs/scale.md):
|
|
314
|
+
* a group in the graph's own words with a true count and the first names
|
|
315
|
+
* in it — the most relevant — or the "+N more" door to the kind's picture.
|
|
316
|
+
* Not the kind's own lens squeezed into a card: a coverage matrix at 180
|
|
317
|
+
* pixels says nothing and costs thousands of elements. Opened by the host's
|
|
318
|
+
* own press (a double-click, or Enter), like every card.
|
|
319
|
+
*/
|
|
320
|
+
export const BandCard = memo(function BandCard({ node }) {
|
|
321
|
+
const { store } = useGraview();
|
|
322
|
+
const found = useFound();
|
|
323
|
+
const aggregate = node.aggregate;
|
|
324
|
+
const opens = aggregate.opens;
|
|
325
|
+
const count = aggregate.memberIds.length;
|
|
326
|
+
const plural = (store.schema.tryDefinition(aggregate.kind)?.plural ?? `${aggregate.kind}s`).toLowerCase();
|
|
327
|
+
const counted = `${count} ${count === 1 ? aggregate.kind.replace(/-/g, " ") : plural}`;
|
|
328
|
+
const names = aggregate.memberIds.slice(0, 3).map((id) => {
|
|
329
|
+
const member = store.graph.getNode(id);
|
|
330
|
+
const definition = member ? store.schema.tryDefinition(member.kind) : undefined;
|
|
331
|
+
return member ? (definition?.label ? definition.label(member) : String(member.label ?? id)) : id;
|
|
332
|
+
});
|
|
333
|
+
const hits = found ? aggregate.memberIds.filter(new Set(found.matched).has, new Set(found.matched)).length : 0;
|
|
334
|
+
const door = opens.in === "picture";
|
|
335
|
+
/*
|
|
336
|
+
* TWO LINES, read at a glance: what the group is and which way it opens,
|
|
337
|
+
* then how many and the first of them. A card stacked four lines deep
|
|
338
|
+
* was cut to its name in a band row, and the count — the one thing a
|
|
339
|
+
* group says that a member cannot — was the line that went.
|
|
340
|
+
*/
|
|
341
|
+
return (_jsxs("div", { className: "graview-band-group", "data-graview-band": opens.in, "data-graview-band-count": count, "data-graview-emphasis": found ? (hits > 0 ? "lit" : "dimmed") : undefined, title: door ? `${aggregate.label} — press twice to see them all, arranged` : `${aggregate.label}: ${counted} — press twice to open`, children: [_jsxs("span", { className: "graview-band-group-head", children: [_jsx("span", { className: "graview-band-group-name", children: aggregate.label }), _jsx("span", { className: "graview-band-group-open", "aria-hidden": "true", children: door ? "↗" : "▾" })] }), _jsxs("span", { className: "graview-band-group-names", children: [door ? null : (_jsxs("span", { className: "graview-band-group-count", children: [counted, hits > 0 ? ` · ${hits} match` : "", " · "] })), names.join(" · "), count > names.length ? " …" : ""] })] }));
|
|
342
|
+
});
|
|
343
|
+
/*
|
|
344
|
+
* A group's members as a short key: their count and a hash of their ids.
|
|
345
|
+
* The signature joined them, and a band group or a district holds hundreds,
|
|
346
|
+
* so every host rebuilt a string of thousands of characters every frame of
|
|
347
|
+
* a transition to learn that nothing had changed (docs/scale.md).
|
|
348
|
+
*/
|
|
349
|
+
const keys = new WeakMap();
|
|
350
|
+
function idsKey(ids) {
|
|
351
|
+
// The same array from frame to frame of a tween: hashed once.
|
|
352
|
+
const known = keys.get(ids);
|
|
353
|
+
if (known !== undefined)
|
|
354
|
+
return known;
|
|
355
|
+
let hash = 0x811c9dc5;
|
|
356
|
+
for (const id of ids) {
|
|
357
|
+
for (let i = 0; i < id.length; i++)
|
|
358
|
+
hash = Math.imul(hash ^ id.charCodeAt(i), 0x01000193);
|
|
359
|
+
hash = Math.imul(hash ^ 0x2c, 0x01000193);
|
|
360
|
+
}
|
|
361
|
+
const key = `${ids.length}:${(hash >>> 0).toString(36)}`;
|
|
362
|
+
keys.set(ids, key);
|
|
363
|
+
return key;
|
|
364
|
+
}
|
|
365
|
+
//# sourceMappingURL=resolved-view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolved-view.js","sourceRoot":"","sources":["../src/resolved-view.tsx"],"names":[],"mappings":"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"}
|
package/dist/robot.d.ts
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import type { Author } from "@graview/core";
|
|
2
|
+
/**
|
|
3
|
+
* THE SEAT IS A ROBOT IN THE CITY, and where it stands is DERIVED.
|
|
4
|
+
*
|
|
5
|
+
* A seat's body is not decoration: it stands where the seat read, where it
|
|
6
|
+
* wrote, at the gate of the plot it may not enter, on the doorstep of the
|
|
7
|
+
* node it is asking about — and at its dock when it has nothing to do.
|
|
8
|
+
* Every one of those is a fact the interface already sees: the runtime's
|
|
9
|
+
* calls, the log's ops, the store's refusals, the seat's own replies. This
|
|
10
|
+
* fold turns them into one state per participant and nothing else decides
|
|
11
|
+
* it. Pure, so it can be tested like `markActivity`.
|
|
12
|
+
*
|
|
13
|
+
* A participant is `kind:id:session` — the same key the op log attributes
|
|
14
|
+
* to — so the body and the log can never disagree about who moved.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* What the seat is doing. `following` retired with the figure that walked
|
|
18
|
+
* the ground: the seat lives on the frame now, and what it is about is the
|
|
19
|
+
* companion's subject, not a body trailing the pointer. `docked` stays as
|
|
20
|
+
* the resting state the rail says "listening" for.
|
|
21
|
+
*/
|
|
22
|
+
export type RobotMode = "docked" | "reading" | "writing" | "refused" | "asking";
|
|
23
|
+
export interface RobotState {
|
|
24
|
+
readonly participant: string;
|
|
25
|
+
/** The seat's own name, for its label. */
|
|
26
|
+
readonly who: string;
|
|
27
|
+
/** What it stands at: a node id, `kind:<kind>` for a whole neighbourhood, or null for its dock. */
|
|
28
|
+
readonly at: string | null;
|
|
29
|
+
readonly mode: RobotMode;
|
|
30
|
+
/** What it is saying, if anything: a reply, a refusal, a question, a stop reason. */
|
|
31
|
+
readonly say?: string;
|
|
32
|
+
/** How sure, when the seat decided rather than talked. */
|
|
33
|
+
readonly confidence?: number;
|
|
34
|
+
/** A run's own name, when the figure is a run rather than the tab's seat. */
|
|
35
|
+
readonly caption?: string;
|
|
36
|
+
/** The pick target under the pointer while following. */
|
|
37
|
+
readonly over?: string | null;
|
|
38
|
+
/** When it last did anything, in ms. */
|
|
39
|
+
readonly since: number;
|
|
40
|
+
/** Where it has been this turn, most recent last — the trail. */
|
|
41
|
+
readonly trail: readonly string[];
|
|
42
|
+
}
|
|
43
|
+
export type RobotEvent = {
|
|
44
|
+
readonly type: "read";
|
|
45
|
+
readonly author: Author;
|
|
46
|
+
readonly ids: readonly string[];
|
|
47
|
+
readonly at: number;
|
|
48
|
+
} | {
|
|
49
|
+
readonly type: "write";
|
|
50
|
+
readonly author: Author;
|
|
51
|
+
readonly ids: readonly string[];
|
|
52
|
+
readonly at: number;
|
|
53
|
+
} | {
|
|
54
|
+
readonly type: "about-to-write";
|
|
55
|
+
readonly author: Author;
|
|
56
|
+
readonly ids: readonly string[];
|
|
57
|
+
readonly at: number;
|
|
58
|
+
} | {
|
|
59
|
+
readonly type: "refused";
|
|
60
|
+
readonly author: Author;
|
|
61
|
+
readonly at: number;
|
|
62
|
+
readonly where: string | null;
|
|
63
|
+
readonly say: string;
|
|
64
|
+
} | {
|
|
65
|
+
readonly type: "asking";
|
|
66
|
+
readonly author: Author;
|
|
67
|
+
readonly at: number;
|
|
68
|
+
readonly where: string | null;
|
|
69
|
+
readonly say: string;
|
|
70
|
+
readonly confidence?: number;
|
|
71
|
+
} | {
|
|
72
|
+
readonly type: "said";
|
|
73
|
+
readonly author: Author;
|
|
74
|
+
readonly at: number;
|
|
75
|
+
readonly say: string;
|
|
76
|
+
readonly confidence?: number;
|
|
77
|
+
readonly caption?: string;
|
|
78
|
+
} | {
|
|
79
|
+
readonly type: "over";
|
|
80
|
+
readonly author: Author;
|
|
81
|
+
readonly at: number;
|
|
82
|
+
readonly over: string | null;
|
|
83
|
+
} | {
|
|
84
|
+
readonly type: "home";
|
|
85
|
+
readonly author: Author;
|
|
86
|
+
readonly at: number;
|
|
87
|
+
} | {
|
|
88
|
+
readonly type: "rest";
|
|
89
|
+
readonly at: number;
|
|
90
|
+
readonly holdMs: number;
|
|
91
|
+
};
|
|
92
|
+
/** An event as a surface tells it: the time is filled in on arrival. Distributive over the union, or TypeScript keeps only the common keys. */
|
|
93
|
+
export type SeatNote = RobotEvent extends infer E ? (E extends RobotEvent ? Omit<E, "at"> & {
|
|
94
|
+
readonly at?: number;
|
|
95
|
+
} : never) : never;
|
|
96
|
+
/** One participant's identity across a window — the op log's own reading of an author. */
|
|
97
|
+
export declare function participantOf(author: Author): string;
|
|
98
|
+
/** How many targets a turn visits one by one before it stands at the kind instead. */
|
|
99
|
+
export declare const VISIT_EACH_UP_TO = 4;
|
|
100
|
+
/**
|
|
101
|
+
* Where a set of ids puts the robot: the one thing, or — past a handful —
|
|
102
|
+
* the neighbourhood, because a figure sprinting between eleven cards says
|
|
103
|
+
* less than one standing where the work is. `kindOf` reads a node's kind so
|
|
104
|
+
* a set of one kind becomes that kind's plot.
|
|
105
|
+
*/
|
|
106
|
+
export declare function standingFor(ids: readonly string[], kindOf: (id: string) => string | undefined): string | null;
|
|
107
|
+
/**
|
|
108
|
+
* Folds one event into the robots. Only agents have bodies: a person is at
|
|
109
|
+
* the keyboard, a rule is the store's own, a system is elsewhere. A
|
|
110
|
+
* following robot stays following through reads and writes — the person
|
|
111
|
+
* asked it to come — until released or a turn is over.
|
|
112
|
+
*/
|
|
113
|
+
export declare function foldRobots(robots: ReadonlyMap<string, RobotState>, event: RobotEvent, kindOf: (id: string) => string | undefined): Map<string, RobotState>;
|
|
114
|
+
//# sourceMappingURL=robot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"robot.d.ts","sourceRoot":"","sources":["../src/robot.ts"],"names":[],"mappings":"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"}
|
package/dist/robot.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/** One participant's identity across a window — the op log's own reading of an author. */
|
|
2
|
+
export function participantOf(author) {
|
|
3
|
+
return `${author.kind}:${author.id ?? ""}:${author.session ?? ""}`;
|
|
4
|
+
}
|
|
5
|
+
const TRAIL = 12;
|
|
6
|
+
/** How many targets a turn visits one by one before it stands at the kind instead. */
|
|
7
|
+
export const VISIT_EACH_UP_TO = 4;
|
|
8
|
+
function stateOf(robots, author, at) {
|
|
9
|
+
const participant = participantOf(author);
|
|
10
|
+
return (robots.get(participant) ?? {
|
|
11
|
+
participant,
|
|
12
|
+
who: author.id ?? author.kind,
|
|
13
|
+
at: null,
|
|
14
|
+
mode: "docked",
|
|
15
|
+
since: at,
|
|
16
|
+
trail: [],
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
const walked = (trail, at) => at === null || trail[trail.length - 1] === at ? trail : [...trail, at].slice(-TRAIL);
|
|
20
|
+
/**
|
|
21
|
+
* Where a set of ids puts the robot: the one thing, or — past a handful —
|
|
22
|
+
* the neighbourhood, because a figure sprinting between eleven cards says
|
|
23
|
+
* less than one standing where the work is. `kindOf` reads a node's kind so
|
|
24
|
+
* a set of one kind becomes that kind's plot.
|
|
25
|
+
*/
|
|
26
|
+
export function standingFor(ids, kindOf) {
|
|
27
|
+
const real = ids.filter((id) => id.length > 0);
|
|
28
|
+
if (real.length === 0)
|
|
29
|
+
return null;
|
|
30
|
+
if (real.length <= VISIT_EACH_UP_TO)
|
|
31
|
+
return real[0];
|
|
32
|
+
const kinds = new Set(real.map((id) => kindOf(id)).filter((kind) => kind !== undefined));
|
|
33
|
+
if (kinds.size === 1)
|
|
34
|
+
return `kind:${[...kinds][0]}`;
|
|
35
|
+
return real[0];
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Folds one event into the robots. Only agents have bodies: a person is at
|
|
39
|
+
* the keyboard, a rule is the store's own, a system is elsewhere. A
|
|
40
|
+
* following robot stays following through reads and writes — the person
|
|
41
|
+
* asked it to come — until released or a turn is over.
|
|
42
|
+
*/
|
|
43
|
+
export function foldRobots(robots, event, kindOf) {
|
|
44
|
+
const next = new Map(robots);
|
|
45
|
+
if (event.type === "rest") {
|
|
46
|
+
for (const [key, robot] of robots) {
|
|
47
|
+
if (robot.mode === "asking")
|
|
48
|
+
continue;
|
|
49
|
+
if (robot.mode !== "docked" && event.at - robot.since >= event.holdMs) {
|
|
50
|
+
next.set(key, { ...robot, mode: "docked", at: null, trail: [], say: undefined, confidence: undefined });
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return next;
|
|
54
|
+
}
|
|
55
|
+
if (event.author.kind !== "agent")
|
|
56
|
+
return next;
|
|
57
|
+
const robot = stateOf(robots, event.author, event.at);
|
|
58
|
+
const put = (patch) => next.set(robot.participant, { ...robot, ...patch, since: event.at });
|
|
59
|
+
switch (event.type) {
|
|
60
|
+
case "read": {
|
|
61
|
+
const at = standingFor(event.ids, kindOf);
|
|
62
|
+
put({ at, mode: "reading", trail: walked(robot.trail, at) });
|
|
63
|
+
return next;
|
|
64
|
+
}
|
|
65
|
+
case "about-to-write":
|
|
66
|
+
case "write": {
|
|
67
|
+
const at = standingFor(event.ids, kindOf);
|
|
68
|
+
put({ at, mode: "writing", trail: walked(robot.trail, at), say: undefined, confidence: undefined });
|
|
69
|
+
return next;
|
|
70
|
+
}
|
|
71
|
+
case "refused":
|
|
72
|
+
put({ at: event.where, mode: "refused", say: event.say, confidence: undefined, trail: walked(robot.trail, event.where) });
|
|
73
|
+
return next;
|
|
74
|
+
case "asking":
|
|
75
|
+
put({ at: event.where ?? robot.at, mode: "asking", say: event.say, ...(event.confidence !== undefined ? { confidence: event.confidence } : { confidence: undefined }), trail: walked(robot.trail, event.where) });
|
|
76
|
+
return next;
|
|
77
|
+
case "said":
|
|
78
|
+
put({ say: event.say, ...(event.confidence !== undefined ? { confidence: event.confidence } : { confidence: undefined }), ...(event.caption ? { caption: event.caption } : {}) });
|
|
79
|
+
return next;
|
|
80
|
+
case "over":
|
|
81
|
+
// What the pointer is on, for a surface that wants it — the companion
|
|
82
|
+
// reads its own subject, but a presence figure still says where a
|
|
83
|
+
// teammate's agent is looking.
|
|
84
|
+
put({ over: event.over });
|
|
85
|
+
return next;
|
|
86
|
+
case "home":
|
|
87
|
+
put({ at: null, mode: "docked", trail: [], say: undefined, confidence: undefined, over: null });
|
|
88
|
+
return next;
|
|
89
|
+
default:
|
|
90
|
+
return next;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=robot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"robot.js","sourceRoot":"","sources":["../src/robot.ts"],"names":[],"mappings":"AA4DA,0FAA0F;AAC1F,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,OAAO,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,MAAM,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;AACrE,CAAC;AAED,MAAM,KAAK,GAAG,EAAE,CAAC;AAEjB,sFAAsF;AACtF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAElC,SAAS,OAAO,CAAC,MAAuC,EAAE,MAAc,EAAE,EAAU;IAClF,MAAM,WAAW,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAC1C,OAAO,CACL,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI;QACzB,WAAW;QACX,GAAG,EAAE,MAAM,CAAC,EAAE,IAAI,MAAM,CAAC,IAAI;QAC7B,EAAE,EAAE,IAAI;QACR,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,EAAE;QACT,KAAK,EAAE,EAAE;KACV,CACF,CAAC;AACJ,CAAC;AAED,MAAM,MAAM,GAAG,CAAC,KAAwB,EAAE,EAAiB,EAAqB,EAAE,CAChF,EAAE,KAAK,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC;AAEvF;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,GAAsB,EAAE,MAA0C;IAC5F,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC/C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,IAAI,IAAI,CAAC,MAAM,IAAI,gBAAgB;QAAE,OAAO,IAAI,CAAC,CAAC,CAAE,CAAC;IACrD,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC;IACzG,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAE,EAAE,CAAC;IACtD,OAAO,IAAI,CAAC,CAAC,CAAE,CAAC;AAClB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CACxB,MAAuC,EACvC,KAAiB,EACjB,MAA0C;IAE1C,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC1B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,EAAE,CAAC;YAClC,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ;gBAAE,SAAS;YACtC,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,EAAE,GAAG,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;gBACtE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC;YAC1G,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC;IAC/C,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;IACtD,MAAM,GAAG,GAAG,CAAC,KAA0B,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;IACjH,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,MAAM,EAAE,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAC1C,GAAG,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;YAC7D,OAAO,IAAI,CAAC;QACd,CAAC;QACD,KAAK,gBAAgB,CAAC;QACtB,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,EAAE,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAC1C,GAAG,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC;YACpG,OAAO,IAAI,CAAC;QACd,CAAC;QACD,KAAK,SAAS;YACZ,GAAG,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC1H,OAAO,IAAI,CAAC;QACd,KAAK,QAAQ;YACX,GAAG,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAClN,OAAO,IAAI,CAAC;QACd,KAAK,MAAM;YACT,GAAG,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YAClL,OAAO,IAAI,CAAC;QACd,KAAK,MAAM;YACT,sEAAsE;YACtE,kEAAkE;YAClE,+BAA+B;YAC/B,GAAG,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YAC1B,OAAO,IAAI,CAAC;QACd,KAAK,MAAM;YACT,GAAG,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAChG,OAAO,IAAI,CAAC;QACd;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC"}
|