@kanzo-tech/graph 0.26.0 → 0.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +7 -4
  2. package/dist/core/client.d.ts.map +1 -1
  3. package/dist/core/client.js +16 -16
  4. package/dist/core/client.js.map +1 -1
  5. package/dist/core/error.d.ts +3 -3
  6. package/dist/core/error.d.ts.map +1 -1
  7. package/dist/core/error.js.map +1 -1
  8. package/dist/core/state.d.ts +8 -3
  9. package/dist/core/state.d.ts.map +1 -1
  10. package/dist/core/store.d.ts +1 -1
  11. package/dist/core/store.d.ts.map +1 -1
  12. package/dist/core/store.js +84 -76
  13. package/dist/core/store.js.map +1 -1
  14. package/dist/core/types.d.ts +5 -3
  15. package/dist/core/types.d.ts.map +1 -1
  16. package/dist/index.d.ts +5 -3
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +28 -24
  19. package/dist/index.js.map +1 -1
  20. package/dist/parts/graph-counts.d.ts +9 -11
  21. package/dist/parts/graph-counts.d.ts.map +1 -1
  22. package/dist/parts/graph-counts.js +28 -27
  23. package/dist/parts/graph-counts.js.map +1 -1
  24. package/dist/parts/graph-select.d.ts +27 -0
  25. package/dist/parts/graph-select.d.ts.map +1 -0
  26. package/dist/parts/graph-select.js +53 -0
  27. package/dist/parts/graph-select.js.map +1 -0
  28. package/dist/parts/graph-status.d.ts +13 -0
  29. package/dist/parts/graph-status.d.ts.map +1 -0
  30. package/dist/parts/graph-status.js +28 -0
  31. package/dist/parts/graph-status.js.map +1 -0
  32. package/dist/react/use-graph-prefs.d.ts +1 -1
  33. package/dist/react/use-graph-prefs.js.map +1 -1
  34. package/dist/render/camera.d.ts +12 -1
  35. package/dist/render/camera.d.ts.map +1 -1
  36. package/dist/render/camera.js +33 -21
  37. package/dist/render/camera.js.map +1 -1
  38. package/dist/render/renderer.d.ts.map +1 -1
  39. package/dist/render/renderer.js +85 -84
  40. package/dist/render/renderer.js.map +1 -1
  41. package/package.json +8 -8
@@ -30,10 +30,12 @@ export type Tool = "rect" | "lasso" | null;
30
30
  /** `settled` converged on its own; `paused` is waiting for you. */
31
31
  export type Motion = "running" | "settled" | "paused";
32
32
  /**
33
- * Where a selection came from. Open-ended on purpose: a host with its own panels adds its own
34
- * sources, and the canvas only ever uses this to label the chip in the corner.
33
+ * Where a selection came from: one of the canvas's own gestures, or `"external"` — a selection the
34
+ * host set through `select`, from a panel of its own. An external selection's identity is its
35
+ * `label`, which is how `GraphSelect` knows the live selection is the one it made. The graph names
36
+ * no host's panels here: a source per panel would be a host's vocabulary in the renderer's type.
35
37
  */
36
- export type SelectionSource = "marquee" | "lasso" | "node" | "order" | "ask";
38
+ export type SelectionSource = "marquee" | "lasso" | "node" | "external";
37
39
  /**
38
40
  * The selection — one value, published once.
39
41
  *
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC;AAE9B;;;;;;GAMG;AACH,MAAM,MAAM,IAAI,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AAE3C,mEAAmE;AACnE,MAAM,MAAM,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEtD;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;AAE7E;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,QAAQ,EAAE,CAAC;IACrB,MAAM,EAAE,eAAe,CAAC;IACxB,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,yFAAyF;AACzF,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,GAAG,IAAI,IAAI,CAAC;IACZ,KAAK,IAAI,IAAI,CAAC;IACd,MAAM,IAAI,IAAI,CAAC;IACf,OAAO,IAAI,IAAI,CAAC;IAChB,qGAAqG;IACrG,KAAK,IAAI,IAAI,CAAC;IACd,oCAAoC;IACpC,MAAM,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC/B,wDAAwD;IACxD,cAAc,IAAI,IAAI,CAAC;IACvB,KAAK,IAAI,IAAI,CAAC;CACf"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC;AAE9B;;;;;;GAMG;AACH,MAAM,MAAM,IAAI,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AAE3C,mEAAmE;AACnE,MAAM,MAAM,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEtD;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,UAAU,CAAC;AAExE;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,QAAQ,EAAE,CAAC;IACrB,MAAM,EAAE,eAAe,CAAC;IACxB,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,yFAAyF;AACzF,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,GAAG,IAAI,IAAI,CAAC;IACZ,KAAK,IAAI,IAAI,CAAC;IACd,MAAM,IAAI,IAAI,CAAC;IACf,OAAO,IAAI,IAAI,CAAC;IAChB,qGAAqG;IACrG,KAAK,IAAI,IAAI,CAAC;IACd,oCAAoC;IACpC,MAAM,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC/B,wDAAwD;IACxD,cAAc,IAAI,IAAI,CAAC;IACvB,KAAK,IAAI,IAAI,CAAC;CACf"}
package/dist/index.d.ts CHANGED
@@ -12,8 +12,8 @@
12
12
  * - `react/` — `useGraph`, `GraphRoot`, `GraphRootProvider`, `useGraphContext`: Ark's four; and
13
13
  * `useGraphState`, TanStack Store's selector, because the api is commands and the state moves at
14
14
  * frame rate.
15
- * - `parts/` — `GraphCanvas`, `GraphLegend`, `GraphCounts`, `GraphToolbar`, `GraphInspector`,
16
- * `GraphSearch`: flat parts over the one context; and `GraphLooks`, the picture's preferences,
15
+ * - `parts/` — `GraphCanvas`, `GraphLegend`, `GraphCounts`, `GraphStatus`, `GraphToolbar`,
16
+ * `GraphInspector`, `GraphSearch`, `GraphSelect`: flat parts over the one context; and `GraphLooks`, the picture's preferences,
17
17
  * which needs only the theme provider. They own the vocabulary; the root's callbacks are the host's policy.
18
18
  *
19
19
  * **Why a package and not `@kanzo-tech/ui`.** The first admission rule is *domain-free — nothing
@@ -27,9 +27,11 @@ export { useGraphPrefs } from './react/use-graph-prefs';
27
27
  export { GraphCanvas, type GraphCanvasProps } from './parts/graph-canvas';
28
28
  export { GraphLegend, type GraphLegendProps } from './parts/graph-legend';
29
29
  export { GraphCounts, type GraphCountsProps } from './parts/graph-counts';
30
+ export { GraphStatus, type GraphStatusProps } from './parts/graph-status';
30
31
  export { GraphToolbar, type GraphToolbarProps } from './parts/graph-toolbar';
31
32
  export { GraphInspector, type GraphInspectorProps } from './parts/graph-inspector';
32
33
  export { GraphSearch, type GraphSearchProps } from './parts/graph-search';
34
+ export { GraphSelect, type GraphSelectProps } from './parts/graph-select';
33
35
  export { GraphLooks, type GraphLooksProps } from './parts/graph-looks';
34
36
  export { ShapeGlyph, type ShapeGlyphProps } from './parts/shape-glyph';
35
37
  export { lookFrom, type Look, type LookPatch, type LookPreset, type Shape } from './render/graph-looks';
@@ -37,7 +39,7 @@ export { simFrom, type Sim } from './render/graph-sim';
37
39
  export { scaleOf } from './render/graph-model';
38
40
  export type { Channels } from './core/channels';
39
41
  export type { GraphCommands, Motion, Selection, SelectionSource, Tool, VertexId } from './core/types';
40
- export type { Drawn, GraphState, GraphStatus } from './core/state';
42
+ export type { DataStatus, Drawn, GraphState } from './core/state';
41
43
  export type { VertexDetail } from './core/source';
42
44
  export { GraphError } from './core/error';
43
45
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,eAAe,EACf,KAAK,cAAc,EACnB,KAAK,sBAAsB,GAC5B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,QAAQ,EAAE,KAAK,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnF,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAIvE,OAAO,EAAE,QAAQ,EAAE,KAAK,IAAI,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,KAAK,KAAK,EAAE,MAAM,sBAAsB,CAAC;AACxG,OAAO,EAAE,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,YAAY,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,YAAY,EAAE,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACtG,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACnE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,eAAe,EACf,KAAK,cAAc,EACnB,KAAK,sBAAsB,GAC5B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,QAAQ,EAAE,KAAK,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnF,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAIvE,OAAO,EAAE,QAAQ,EAAE,KAAK,IAAI,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,KAAK,KAAK,EAAE,MAAM,sBAAsB,CAAC;AACxG,OAAO,EAAE,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,YAAY,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,YAAY,EAAE,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACtG,YAAY,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAClE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC"}
package/dist/index.js CHANGED
@@ -2,33 +2,37 @@ import { GraphRoot as p, GraphRootProvider as e, useGraphContext as t } from "./
2
2
  import { useGraph as m } from "./react/use-graph.js";
3
3
  import { useGraphState as h } from "./react/use-graph-state.js";
4
4
  import { useGraphPrefs as G } from "./react/use-graph-prefs.js";
5
- import { GraphCanvas as n } from "./parts/graph-canvas.js";
6
- import { GraphLegend as l } from "./parts/graph-legend.js";
7
- import { GraphCounts as C } from "./parts/graph-counts.js";
8
- import { GraphToolbar as d } from "./parts/graph-toolbar.js";
9
- import { GraphInspector as k } from "./parts/graph-inspector.js";
10
- import { GraphSearch as F } from "./parts/graph-search.js";
11
- import { GraphLooks as P } from "./parts/graph-looks.js";
12
- import { ShapeGlyph as b } from "./parts/shape-glyph.js";
13
- import { lookFrom as y } from "./render/graph-looks.js";
14
- import { simFrom as I } from "./render/graph-sim.js";
15
- import { scaleOf as T } from "./render/graph-model.js";
16
- import { GraphError as q } from "./core/error.js";
5
+ import { GraphCanvas as u } from "./parts/graph-canvas.js";
6
+ import { GraphLegend as n } from "./parts/graph-legend.js";
7
+ import { GraphCounts as c } from "./parts/graph-counts.js";
8
+ import { GraphStatus as d } from "./parts/graph-status.js";
9
+ import { GraphToolbar as k } from "./parts/graph-toolbar.js";
10
+ import { GraphInspector as F } from "./parts/graph-inspector.js";
11
+ import { GraphSearch as P } from "./parts/graph-search.js";
12
+ import { GraphSelect as b } from "./parts/graph-select.js";
13
+ import { GraphLooks as y } from "./parts/graph-looks.js";
14
+ import { ShapeGlyph as I } from "./parts/shape-glyph.js";
15
+ import { lookFrom as T } from "./render/graph-looks.js";
16
+ import { simFrom as q } from "./render/graph-sim.js";
17
+ import { scaleOf as z } from "./render/graph-model.js";
18
+ import { GraphError as B } from "./core/error.js";
17
19
  export {
18
- n as GraphCanvas,
19
- C as GraphCounts,
20
- q as GraphError,
21
- k as GraphInspector,
22
- l as GraphLegend,
23
- P as GraphLooks,
20
+ u as GraphCanvas,
21
+ c as GraphCounts,
22
+ B as GraphError,
23
+ F as GraphInspector,
24
+ n as GraphLegend,
25
+ y as GraphLooks,
24
26
  p as GraphRoot,
25
27
  e as GraphRootProvider,
26
- F as GraphSearch,
27
- d as GraphToolbar,
28
- b as ShapeGlyph,
29
- y as lookFrom,
30
- T as scaleOf,
31
- I as simFrom,
28
+ P as GraphSearch,
29
+ b as GraphSelect,
30
+ d as GraphStatus,
31
+ k as GraphToolbar,
32
+ I as ShapeGlyph,
33
+ T as lookFrom,
34
+ z as scaleOf,
35
+ q as simFrom,
32
36
  m as useGraph,
33
37
  t as useGraphContext,
34
38
  G as useGraphPrefs,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;"}
@@ -1,15 +1,13 @@
1
- export interface GraphCountsProps extends React.ComponentProps<"p"> {
2
- /** Draws a spinner while the corpus opens, the graph loads or a layout runs — for a host with no status of its own beside it. */
3
- spinner?: boolean;
4
- }
1
+ export type GraphCountsProps = React.ComponentProps<"p">;
5
2
  /**
6
- * **What is drawn of the whole, in one sentence** — "1.2K of 5K nodes drawn · 8K edges". `drawn`
7
- * shrinks with the page's filter and `total` is the manifest's, so the sentence is the filter's
8
- * effect; an edge counts when both its ends are drawn. A figure not yet known is "—", and the
9
- * numbers are compact in the nearest `LocaleProvider`'s locale.
3
+ * **The corpus in one sentence** — "5K nodes · 8K edges", and under the page's filter "1.2K of 5K
4
+ * nodes match · 3K edges". Nodes are the corpus's, so a filter's effect is `matching` of `total`; a
5
+ * vertex the filter drops is greyed on the canvas, not hidden, which is why the verb is "match" and
6
+ * not "drawn". Edges are those whose two ends are drawn, so they shrink with the filter. A figure
7
+ * not yet known is "—", and the numbers are compact in the nearest `LocaleProvider`'s locale.
10
8
  *
11
- * `aria-busy` follows `status`, because only a load changes these figures; a running layout moves
12
- * the points and not the counts, so it reaches the spinner alone, named "Laying out".
9
+ * `aria-busy` follows `status`, because only a load changes these figures; whether a layout runs is
10
+ * `GraphStatus`'s word.
13
11
  */
14
- export declare function GraphCounts({ className, slot, spinner, ...rest }: GraphCountsProps): import("react").JSX.Element;
12
+ export declare function GraphCounts({ className, slot, ...rest }: GraphCountsProps): import("react").JSX.Element;
15
13
  //# sourceMappingURL=graph-counts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"graph-counts.d.ts","sourceRoot":"","sources":["../../src/parts/graph-counts.tsx"],"names":[],"mappings":"AAKA,MAAM,WAAW,gBAAiB,SAAQ,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC;IACjE,iIAAiI;IACjI,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAQD;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,OAAe,EAAE,GAAG,IAAI,EAAE,EAAE,gBAAgB,+BAsB1F"}
1
+ {"version":3,"file":"graph-counts.d.ts","sourceRoot":"","sources":["../../src/parts/graph-counts.tsx"],"names":[],"mappings":"AAKA,MAAM,MAAM,gBAAgB,GAAG,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;AAQzD;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,EAAE,gBAAgB,+BAyBzE"}
@@ -1,41 +1,42 @@
1
1
  "use client";
2
- import { jsxs as i, jsx as n } from "react/jsx-runtime";
3
- import { Show as f, Spinner as h, cn as x, FormatNumber as b } from "@kanzo-tech/ui";
4
- import { useGraphState as e } from "../react/use-graph-state.js";
5
- const v = { notation: "compact", maximumFractionDigits: 1 };
2
+ import { jsxs as s, Fragment as i, jsx as n } from "react/jsx-runtime";
3
+ import { cn as h, FormatNumber as p } from "@kanzo-tech/ui";
4
+ import { useGraphState as a } from "../react/use-graph-state.js";
5
+ const f = { notation: "compact", maximumFractionDigits: 1 };
6
6
  function r({ value: o }) {
7
- return o == null ? "—" : /* @__PURE__ */ n(b, { value: o, ...v });
7
+ return o == null ? "—" : /* @__PURE__ */ n(p, { value: o, ...f });
8
8
  }
9
- function N({ className: o, slot: c, spinner: u = !1, ...l }) {
10
- const m = e((t) => {
11
- var a;
12
- return (a = t.drawn) == null ? void 0 : a.vertices;
13
- }), d = e((t) => {
14
- var a;
15
- return (a = t.drawn) == null ? void 0 : a.edges;
16
- }), g = e((t) => t.total), s = e((t) => t.status === "loading"), p = e((t) => t.motion === "running");
17
- return /* @__PURE__ */ i(
9
+ function C({ className: o, slot: m, ...d }) {
10
+ const e = a((t) => t.total), u = a((t) => t.matching), l = a((t) => {
11
+ var c;
12
+ return (c = t.drawn) == null ? void 0 : c.edges;
13
+ }), g = a((t) => t.status === "loading");
14
+ return /* @__PURE__ */ s(
18
15
  "p",
19
16
  {
20
- "aria-busy": s || void 0,
21
- ...l,
22
- className: x("flex items-center gap-1.5 text-muted-foreground text-xs tabular-nums", o),
23
- "data-slot": c ?? "graph-counts",
17
+ "aria-busy": g || void 0,
18
+ ...d,
19
+ className: h("text-muted-foreground text-xs tabular-nums", o),
20
+ "data-slot": m ?? "graph-counts",
24
21
  children: [
25
- /* @__PURE__ */ n(f, { when: u && (s || p), children: /* @__PURE__ */ n(h, { "aria-label": s ? "Loading" : "Laying out", className: "size-3" }) }),
26
- /* @__PURE__ */ i("span", { children: [
27
- /* @__PURE__ */ n(r, { value: m }),
22
+ u === null ? /* @__PURE__ */ s(i, { children: [
23
+ /* @__PURE__ */ n(r, { value: e }),
24
+ " nodes"
25
+ ] }) : /* @__PURE__ */ s(i, { children: [
26
+ /* @__PURE__ */ n(r, { value: u }),
28
27
  " of ",
29
- /* @__PURE__ */ n(r, { value: g }),
30
- " nodes drawn · ",
31
- /* @__PURE__ */ n(r, { value: d }),
32
- " edges"
33
- ] })
28
+ /* @__PURE__ */ n(r, { value: e }),
29
+ " nodes match"
30
+ ] }),
31
+ " ",
32
+ "· ",
33
+ /* @__PURE__ */ n(r, { value: l }),
34
+ " edges"
34
35
  ]
35
36
  }
36
37
  );
37
38
  }
38
39
  export {
39
- N as GraphCounts
40
+ C as GraphCounts
40
41
  };
41
42
  //# sourceMappingURL=graph-counts.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"graph-counts.js","sources":["../../src/parts/graph-counts.tsx"],"sourcesContent":["\"use client\";\n\nimport { cn, FormatNumber, Show, Spinner } from \"@kanzo-tech/ui\";\nimport { useGraphState } from \"../react/use-graph-state\";\n\nexport interface GraphCountsProps extends React.ComponentProps<\"p\"> {\n /** Draws a spinner while the corpus opens, the graph loads or a layout runs — for a host with no status of its own beside it. */\n spinner?: boolean;\n}\n\nconst COMPACT = { notation: \"compact\", maximumFractionDigits: 1 } as const;\n\nfunction Count({ value }: { value: number | null | undefined }) {\n return value === null || value === undefined ? \"—\" : <FormatNumber value={value} {...COMPACT} />;\n}\n\n/**\n * **What is drawn of the whole, in one sentence** — \"1.2K of 5K nodes drawn · 8K edges\". `drawn`\n * shrinks with the page's filter and `total` is the manifest's, so the sentence is the filter's\n * effect; an edge counts when both its ends are drawn. A figure not yet known is \"—\", and the\n * numbers are compact in the nearest `LocaleProvider`'s locale.\n *\n * `aria-busy` follows `status`, because only a load changes these figures; a running layout moves\n * the points and not the counts, so it reaches the spinner alone, named \"Laying out\".\n */\nexport function GraphCounts({ className, slot, spinner = false, ...rest }: GraphCountsProps) {\n const vertices = useGraphState((s) => s.drawn?.vertices);\n const edges = useGraphState((s) => s.drawn?.edges);\n const total = useGraphState((s) => s.total);\n const busy = useGraphState((s) => s.status === \"loading\");\n const laying = useGraphState((s) => s.motion === \"running\");\n\n return (\n <p\n aria-busy={busy || undefined}\n {...rest}\n className={cn(\"flex items-center gap-1.5 text-muted-foreground text-xs tabular-nums\", className)}\n data-slot={slot ?? \"graph-counts\"}\n >\n <Show when={spinner && (busy || laying)}>\n <Spinner aria-label={busy ? \"Loading\" : \"Laying out\"} className=\"size-3\" />\n </Show>\n <span>\n <Count value={vertices} /> of <Count value={total} /> nodes drawn · <Count value={edges} /> edges\n </span>\n </p>\n );\n}\n"],"names":[],"mappings":";;;;AAUA;AAEA;AACE;AACF;AAWO;AACL;;AAAsC;AAAS;;AACZ;AAAS;AAK5C;AACE;AAAC;AAAA;AACoB;AACf;AAC2F;AAC5E;AAEnB;AAEA;AAEE;AAAwB;AAAE;AAAyB;AAAE;AAAoC;AAAE;AAC7F;AAAA;AAAA;AAGN;;;;"}
1
+ {"version":3,"file":"graph-counts.js","sources":["../../src/parts/graph-counts.tsx"],"sourcesContent":["\"use client\";\n\nimport { cn, FormatNumber } from \"@kanzo-tech/ui\";\nimport { useGraphState } from \"../react/use-graph-state\";\n\nexport type GraphCountsProps = React.ComponentProps<\"p\">;\n\nconst COMPACT = { notation: \"compact\", maximumFractionDigits: 1 } as const;\n\nfunction Count({ value }: { value: number | null | undefined }) {\n return value === null || value === undefined ? \"—\" : <FormatNumber value={value} {...COMPACT} />;\n}\n\n/**\n * **The corpus in one sentence** — \"5K nodes · 8K edges\", and under the page's filter \"1.2K of 5K\n * nodes match · 3K edges\". Nodes are the corpus's, so a filter's effect is `matching` of `total`; a\n * vertex the filter drops is greyed on the canvas, not hidden, which is why the verb is \"match\" and\n * not \"drawn\". Edges are those whose two ends are drawn, so they shrink with the filter. A figure\n * not yet known is \"—\", and the numbers are compact in the nearest `LocaleProvider`'s locale.\n *\n * `aria-busy` follows `status`, because only a load changes these figures; whether a layout runs is\n * `GraphStatus`'s word.\n */\nexport function GraphCounts({ className, slot, ...rest }: GraphCountsProps) {\n const total = useGraphState((s) => s.total);\n const matching = useGraphState((s) => s.matching);\n const edges = useGraphState((s) => s.drawn?.edges);\n const busy = useGraphState((s) => s.status === \"loading\");\n\n return (\n <p\n aria-busy={busy || undefined}\n {...rest}\n className={cn(\"text-muted-foreground text-xs tabular-nums\", className)}\n data-slot={slot ?? \"graph-counts\"}\n >\n {matching === null ? (\n <>\n <Count value={total} /> nodes\n </>\n ) : (\n <>\n <Count value={matching} /> of <Count value={total} /> nodes match\n </>\n )}{\" \"}\n · <Count value={edges} /> edges\n </p>\n );\n}\n"],"names":[],"mappings":";;;;AAOA;AAEA;AACE;AACF;AAYO;AACL;;AAEmC;AAAS;AAG5C;AACE;AAAC;AAAA;AACoB;AACf;AACiE;AAClD;AAElB;AAEG;AAAqB;AAAE;AAIvB;AAAwB;AAAE;AAAyB;AAAE;AACvD;AACC;AAAI;AACgB;AAAE;AAAA;AAAA;AAG/B;;;;"}
@@ -0,0 +1,27 @@
1
+ import { VertexId } from '../core/types';
2
+ export interface GraphSelectProps extends Omit<React.ComponentProps<"button">, "onClick" | "type"> {
3
+ /**
4
+ * The vertices this control selects — `dense_id`s, as SQL returns them. Called when the reader
5
+ * presses it and not before, so a panel of fifty findings reads nothing until one is asked for.
6
+ */
7
+ load: () => Promise<readonly VertexId[]>;
8
+ /** What the corner calls the selection, and its identity: keep it distinct among a panel's controls. */
9
+ label: string;
10
+ }
11
+ /**
12
+ * **A selection the host offers, as a toggle** — *these vertices, on the canvas*. Pressing it calls
13
+ * `load` and selects what it answers as an `"external"` selection named `label`; pressing it again
14
+ * clears it. Whatever the host renders inside is the clickable body: a rule and its count, an answer.
15
+ *
16
+ * The pressed state is **derived** from the live selection — `source === "external"` and the same
17
+ * `label` — rather than stored beside it. A stored flag goes stale the moment the reader lassoes
18
+ * something else; a selection cannot disagree with itself. It is disabled while `load` runs.
19
+ *
20
+ * **A rejected `load` reaches the root's `onFailure`, as thrown** — as `GraphSearch`'s failed read
21
+ * does — and the control stays unpressed, ready to be pressed again. It takes no handler of its own:
22
+ * what a failure shows is the host's policy, and the root is where that lives.
23
+ *
24
+ * ARIA: a `button` with `aria-pressed`, the toggle-button pattern; its name is its content.
25
+ */
26
+ export declare function GraphSelect({ children, className, disabled, label, load, slot, ...rest }: GraphSelectProps): import("react").JSX.Element;
27
+ //# sourceMappingURL=graph-select.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-select.d.ts","sourceRoot":"","sources":["../../src/parts/graph-select.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAI9C,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAChG;;;OAGG;IACH,IAAI,EAAE,MAAM,OAAO,CAAC,SAAS,QAAQ,EAAE,CAAC,CAAC;IACzC,wGAAwG;IACxG,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,EAAE,gBAAgB,+BA4C1G"}
@@ -0,0 +1,53 @@
1
+ "use client";
2
+ import { jsx as b } from "react/jsx-runtime";
3
+ import { useState as f } from "react";
4
+ import { cn as y } from "@kanzo-tech/ui";
5
+ import { useGraphContext as g } from "../react/graph-root.js";
6
+ import { useGraphState as h } from "../react/use-graph-state.js";
7
+ function C({ children: n, className: l, disabled: i, label: o, load: c, slot: d, ...p }) {
8
+ const t = g(), r = h((e) => {
9
+ var s;
10
+ return ((s = e.selection) == null ? void 0 : s.source) === "external" && e.selection.label === o;
11
+ }), [u, a] = f(!1), m = async () => {
12
+ if (r) {
13
+ t.select(null);
14
+ return;
15
+ }
16
+ a(!0);
17
+ try {
18
+ t.select(await c(), "external", o);
19
+ } catch (e) {
20
+ t.getState().options.onFailure(e);
21
+ } finally {
22
+ a(!1);
23
+ }
24
+ };
25
+ return /* @__PURE__ */ b(
26
+ "button",
27
+ {
28
+ "aria-pressed": r,
29
+ ...p,
30
+ className: y(
31
+ "w-full rounded-md border p-2 text-start transition-colors",
32
+ "disabled:cursor-default disabled:opacity-60",
33
+ // Normal / hover / pressed is the ramp's own 3→4→5 progression, written with its names.
34
+ // Over the card, `bg-accent/50` and `bg-accent/60` composite to ΔE 1.21 (light) / 0.86
35
+ // (dark) of each other — under the ΔE 2 the ramp makes a hover owe, so the fill was not
36
+ // carrying the pressed state at all; `--secondary` → `--accent` measures 3.96 / 4.61.
37
+ // `border-primary/50` measures 1.73–2.32:1 for a hued seed, the failure `stroke-primary/50`
38
+ // had on the canvas; solid measures 3.07–6.07 (measured 2026-09, in the workspace showcase).
39
+ r ? "border-primary bg-accent" : "hover:bg-secondary disabled:hover:bg-transparent",
40
+ l
41
+ ),
42
+ "data-slot": d ?? "graph-select",
43
+ disabled: i || u,
44
+ onClick: () => void m(),
45
+ type: "button",
46
+ children: n
47
+ }
48
+ );
49
+ }
50
+ export {
51
+ C as GraphSelect
52
+ };
53
+ //# sourceMappingURL=graph-select.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-select.js","sources":["../../src/parts/graph-select.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { cn } from \"@kanzo-tech/ui\";\nimport type { VertexId } from \"../core/types\";\nimport { useGraphContext } from \"../react/graph-root\";\nimport { useGraphState } from \"../react/use-graph-state\";\n\nexport interface GraphSelectProps extends Omit<React.ComponentProps<\"button\">, \"onClick\" | \"type\"> {\n /**\n * The vertices this control selects — `dense_id`s, as SQL returns them. Called when the reader\n * presses it and not before, so a panel of fifty findings reads nothing until one is asked for.\n */\n load: () => Promise<readonly VertexId[]>;\n /** What the corner calls the selection, and its identity: keep it distinct among a panel's controls. */\n label: string;\n}\n\n/**\n * **A selection the host offers, as a toggle** — *these vertices, on the canvas*. Pressing it calls\n * `load` and selects what it answers as an `\"external\"` selection named `label`; pressing it again\n * clears it. Whatever the host renders inside is the clickable body: a rule and its count, an answer.\n *\n * The pressed state is **derived** from the live selection — `source === \"external\"` and the same\n * `label` — rather than stored beside it. A stored flag goes stale the moment the reader lassoes\n * something else; a selection cannot disagree with itself. It is disabled while `load` runs.\n *\n * **A rejected `load` reaches the root's `onFailure`, as thrown** — as `GraphSearch`'s failed read\n * does — and the control stays unpressed, ready to be pressed again. It takes no handler of its own:\n * what a failure shows is the host's policy, and the root is where that lives.\n *\n * ARIA: a `button` with `aria-pressed`, the toggle-button pattern; its name is its content.\n */\nexport function GraphSelect({ children, className, disabled, label, load, slot, ...rest }: GraphSelectProps) {\n const api = useGraphContext();\n const pressed = useGraphState((s) => s.selection?.source === \"external\" && s.selection.label === label);\n const [busy, setBusy] = useState(false);\n\n const toggle = async () => {\n if (pressed) {\n api.select(null);\n return;\n }\n setBusy(true);\n try {\n api.select(await load(), \"external\", label);\n } catch (error) {\n api.getState().options.onFailure(error);\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <button\n aria-pressed={pressed}\n {...rest}\n className={cn(\n \"w-full rounded-md border p-2 text-start transition-colors\",\n \"disabled:cursor-default disabled:opacity-60\",\n // Normal / hover / pressed is the ramp's own 3→4→5 progression, written with its names.\n // Over the card, `bg-accent/50` and `bg-accent/60` composite to ΔE 1.21 (light) / 0.86\n // (dark) of each other — under the ΔE 2 the ramp makes a hover owe, so the fill was not\n // carrying the pressed state at all; `--secondary` → `--accent` measures 3.96 / 4.61.\n // `border-primary/50` measures 1.73–2.32:1 for a hued seed, the failure `stroke-primary/50`\n // had on the canvas; solid measures 3.07–6.07 (measured 2026-09, in the workspace showcase).\n pressed ? \"border-primary bg-accent\" : \"hover:bg-secondary disabled:hover:bg-transparent\",\n className,\n )}\n data-slot={slot ?? \"graph-select\"}\n disabled={disabled || busy}\n onClick={() => void toggle()}\n type=\"button\"\n >\n {children}\n </button>\n );\n}\n"],"names":[],"mappings":";;;;;;AAiCO;AACL;;AACqC;AAA4D;AAI/F;AACE;AACA;AAAA;AAEF;AACA;AACE;AAA0C;AAE1C;AAAsC;AAEtC;AAAa;AACf;AAGF;AACE;AAAC;AAAA;AACe;AACV;AACO;AACT;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOuC;AACvC;AAAA;AAEiB;AACG;AACF;AACf;AAEJ;AAAA;AAGP;;;;"}
@@ -0,0 +1,13 @@
1
+ export type GraphStatusProps = React.ComponentProps<"span">;
2
+ /**
3
+ * **Where the graph is, in one word** — Loading, Laying out 42%, Ready or Failed. It reads both axes
4
+ * of the state: `status` for the data and `motion` with `progress` for the layout, so a running
5
+ * layout over a drawn graph is "Laying out", never the data's `idle`. A load wins over a layout,
6
+ * and a root with no corpus yet reads as Loading: the host is still opening one.
7
+ *
8
+ * ARIA: the word is a polite live region, so a change of word is announced once; the percentage
9
+ * sits outside it, because it moves at frame rate and would be read out on every frame. The badge
10
+ * is `aria-busy` while loading or laying out. The dot is decoration, hidden from the tree.
11
+ */
12
+ export declare function GraphStatus({ className, slot, ...rest }: GraphStatusProps): import("react").JSX.Element;
13
+ //# sourceMappingURL=graph-status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-status.d.ts","sourceRoot":"","sources":["../../src/parts/graph-status.tsx"],"names":[],"mappings":"AAKA,MAAM,MAAM,gBAAgB,GAAG,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;AAM5D;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,EAAE,gBAAgB,+BA0BzE"}
@@ -0,0 +1,28 @@
1
+ "use client";
2
+ import { jsxs as u, jsx as i } from "react/jsx-runtime";
3
+ import { Badge as d, Status as c, Show as l, FormatNumber as m, cn as g } from "@kanzo-tech/ui";
4
+ import { useGraphState as r } from "../react/use-graph-state.js";
5
+ const p = { Loading: "info", "Laying out": "info", Ready: "success", Failed: "destructive" };
6
+ function v({ className: s, slot: n, ...e }) {
7
+ const t = r((a) => a.status === "failed" ? "Failed" : a.status !== "idle" ? "Loading" : a.motion === "running" ? "Laying out" : "Ready"), o = r((a) => Math.round(a.progress * 100) / 100);
8
+ return /* @__PURE__ */ u(
9
+ d,
10
+ {
11
+ "aria-busy": t === "Loading" || t === "Laying out" || void 0,
12
+ size: "xs",
13
+ variant: "outline",
14
+ ...e,
15
+ className: g("gap-1.5 tabular-nums", s),
16
+ slot: n ?? "graph-status",
17
+ children: [
18
+ /* @__PURE__ */ i(c, { className: "ring-0", size: "sm", variant: p[t] }),
19
+ /* @__PURE__ */ i("span", { "aria-live": "polite", children: t }),
20
+ /* @__PURE__ */ i(l, { when: t === "Laying out", children: /* @__PURE__ */ i(m, { maximumFractionDigits: 0, style: "percent", value: o }) })
21
+ ]
22
+ }
23
+ );
24
+ }
25
+ export {
26
+ v as GraphStatus
27
+ };
28
+ //# sourceMappingURL=graph-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-status.js","sources":["../../src/parts/graph-status.tsx"],"sourcesContent":["\"use client\";\n\nimport { Badge, cn, FormatNumber, Show, Status } from \"@kanzo-tech/ui\";\nimport { useGraphState } from \"../react/use-graph-state\";\n\nexport type GraphStatusProps = React.ComponentProps<\"span\">;\n\ntype Word = \"Loading\" | \"Laying out\" | \"Ready\" | \"Failed\";\n\nconst TONE = { Loading: \"info\", \"Laying out\": \"info\", Ready: \"success\", Failed: \"destructive\" } as const;\n\n/**\n * **Where the graph is, in one word** — Loading, Laying out 42%, Ready or Failed. It reads both axes\n * of the state: `status` for the data and `motion` with `progress` for the layout, so a running\n * layout over a drawn graph is \"Laying out\", never the data's `idle`. A load wins over a layout,\n * and a root with no corpus yet reads as Loading: the host is still opening one.\n *\n * ARIA: the word is a polite live region, so a change of word is announced once; the percentage\n * sits outside it, because it moves at frame rate and would be read out on every frame. The badge\n * is `aria-busy` while loading or laying out. The dot is decoration, hidden from the tree.\n */\nexport function GraphStatus({ className, slot, ...rest }: GraphStatusProps) {\n const word = useGraphState((s): Word => {\n if (s.status === \"failed\") return \"Failed\";\n if (s.status !== \"idle\") return \"Loading\";\n return s.motion === \"running\" ? \"Laying out\" : \"Ready\";\n });\n // Rounded in the selector, so the part re-renders once a percent rather than once a frame.\n const progress = useGraphState((s) => Math.round(s.progress * 100) / 100);\n const busy = word === \"Loading\" || word === \"Laying out\";\n\n return (\n <Badge\n aria-busy={busy || undefined}\n size=\"xs\"\n variant=\"outline\"\n {...rest}\n className={cn(\"gap-1.5 tabular-nums\", className)}\n slot={slot ?? \"graph-status\"}\n >\n <Status className=\"ring-0\" size=\"sm\" variant={TONE[word]} />\n <span aria-live=\"polite\">{word}</span>\n <Show when={word === \"Laying out\"}>\n <FormatNumber maximumFractionDigits={0} style=\"percent\" value={progress} />\n </Show>\n </Badge>\n );\n}\n"],"names":[],"mappings":";;;;AASA;AAYO;AACL;AASA;AACE;AAAC;AAAA;AACoB;AACd;AACG;AACJ;AAC2C;AACjC;AAEd;AAA0D;AAC3B;AAG/B;AAAA;AAAA;AAGN;;;;"}
@@ -4,7 +4,7 @@ import { Sim } from '../render/graph-sim';
4
4
  * The graph section's resolved preferences, as the two objects `useGraph` takes.
5
5
  *
6
6
  * The join between the provider's `sectionPrefs` and the two readers of this package's manifest.
7
- * Every host that drew a graph under a preferences panel wrote it — the docs' workspace and keasy's
7
+ * Every host that drew a graph under a preferences panel wrote it — the docs' workspace and a host's
8
8
  * discover page, the same eight lines each — and it knows nothing a host decides: the namespace,
9
9
  * the keys, the defaults and the bounds are all `GRAPH_SECTION`'s, and the resolution chain is the
10
10
  * provider's. What reaches `lookFrom`/`simFrom` is the resolved value, never the stored one.
@@ -1 +1 @@
1
- {"version":3,"file":"use-graph-prefs.js","sources":["../../src/react/use-graph-prefs.ts"],"sourcesContent":["\"use client\";\n\nimport { useMemo } from \"react\";\nimport { useKanzoTheme } from \"@kanzo-tech/ui\";\nimport { lookFrom, presetOf, type Look, type LookPreset } from \"../render/graph-looks\";\nimport { simFrom, type Sim } from \"../render/graph-sim\";\nimport { GRAPH_SECTION } from \"../section\";\n\n/**\n * The graph section's resolved preferences, as the two objects `useGraph` takes.\n *\n * The join between the provider's `sectionPrefs` and the two readers of this package's manifest.\n * Every host that drew a graph under a preferences panel wrote it — the docs' workspace and keasy's\n * discover page, the same eight lines each — and it knows nothing a host decides: the namespace,\n * the keys, the defaults and the bounds are all `GRAPH_SECTION`'s, and the resolution chain is the\n * provider's. What reaches `lookFrom`/`simFrom` is the resolved value, never the stored one.\n *\n * `preset` is the named look the axes are, for a host that pairs channels with it — Ink spends\n * identity on shape — and `null` once a reader has customised past all three.\n *\n * Needs `KanzoThemeProvider` with `GRAPH_SECTION` among its `sections`. Without it the namespace\n * resolves to nothing, both objects are the manifest's defaults and the preset is Atlas.\n */\nexport function useGraphPrefs(): { look: Look; sim: Sim; preset: LookPreset | null } {\n const resolved = useKanzoTheme().sectionPrefs[GRAPH_SECTION.namespace];\n\n return useMemo(() => {\n const values = Object.fromEntries(\n Object.entries(resolved ?? {}).map(([key, pref]) => [key, pref.value]),\n );\n return { look: lookFrom(values), sim: simFrom(values), preset: presetOf(values) };\n }, [resolved]);\n}\n"],"names":[],"mappings":";;;;;;AAuBO;AACL;AAEA;AACE;AAAsB;AACiD;AAEvE;AAA8E;AAElF;;;;"}
1
+ {"version":3,"file":"use-graph-prefs.js","sources":["../../src/react/use-graph-prefs.ts"],"sourcesContent":["\"use client\";\n\nimport { useMemo } from \"react\";\nimport { useKanzoTheme } from \"@kanzo-tech/ui\";\nimport { lookFrom, presetOf, type Look, type LookPreset } from \"../render/graph-looks\";\nimport { simFrom, type Sim } from \"../render/graph-sim\";\nimport { GRAPH_SECTION } from \"../section\";\n\n/**\n * The graph section's resolved preferences, as the two objects `useGraph` takes.\n *\n * The join between the provider's `sectionPrefs` and the two readers of this package's manifest.\n * Every host that drew a graph under a preferences panel wrote it — the docs' workspace and a host's\n * discover page, the same eight lines each — and it knows nothing a host decides: the namespace,\n * the keys, the defaults and the bounds are all `GRAPH_SECTION`'s, and the resolution chain is the\n * provider's. What reaches `lookFrom`/`simFrom` is the resolved value, never the stored one.\n *\n * `preset` is the named look the axes are, for a host that pairs channels with it — Ink spends\n * identity on shape — and `null` once a reader has customised past all three.\n *\n * Needs `KanzoThemeProvider` with `GRAPH_SECTION` among its `sections`. Without it the namespace\n * resolves to nothing, both objects are the manifest's defaults and the preset is Atlas.\n */\nexport function useGraphPrefs(): { look: Look; sim: Sim; preset: LookPreset | null } {\n const resolved = useKanzoTheme().sectionPrefs[GRAPH_SECTION.namespace];\n\n return useMemo(() => {\n const values = Object.fromEntries(\n Object.entries(resolved ?? {}).map(([key, pref]) => [key, pref.value]),\n );\n return { look: lookFrom(values), sim: simFrom(values), preset: presetOf(values) };\n }, [resolved]);\n}\n"],"names":[],"mappings":";;;;;;AAuBO;AACL;AAEA;AACE;AAAsB;AACiD;AAEvE;AAA8E;AAElF;;;;"}
@@ -1,4 +1,5 @@
1
1
  import { Graph } from '@cosmos.gl/graph';
2
+ import { GraphError } from '../core/error';
2
3
  export declare const FIT_DURATION = 420;
3
4
  export interface Camera {
4
5
  /** A corpus was placed: frame these corners now, and again whenever the canvas changes size. */
@@ -7,6 +8,10 @@ export interface Camera {
7
8
  fit(): void;
8
9
  /** A layout started moving the points: the corners are history, and the camera follows. */
9
10
  run(): void;
11
+ /** cosmos.gl's device came up: the frame is taken again, at the canvas's size. */
12
+ ready(): void;
13
+ /** cosmos.gl was handed positions and rendered them: from now on a fit may read them back. */
14
+ drawn(): void;
10
15
  tick(): void;
11
16
  settle(): void;
12
17
  destroy(): void;
@@ -18,8 +23,14 @@ export interface Camera {
18
23
  * zoomed into a corner — and while a layout runs it follows the moving points and frames them when
19
24
  * they settle: Cosmograph's fit-on-settle, kept up. All of it stops the moment the reader zooms or
20
25
  * pans, and comes back with Fit or the next run.
26
+ *
27
+ * **A fit without corners reads the points back from the GPU** (`fitView` → `getPointPositions` →
28
+ * `readPixels` of cosmos.gl's position framebuffer), so it waits until there is one to read: the
29
+ * device is up and a render has uploaded positions. If the read throws anyway, cosmos.gl holds no
30
+ * positions: that is `graph/no-positions`, reported once through `fail`, and the camera reads no more
31
+ * — rather than the same exception on every tick of a layout over a blank canvas.
21
32
  */
22
- export declare function createCamera(graph: Graph, host: HTMLElement): {
33
+ export declare function createCamera(graph: Graph, host: HTMLElement, fail: (error: GraphError) => void): {
23
34
  camera: Camera;
24
35
  taken: (userDriven: boolean) => void;
25
36
  };
@@ -1 +1 @@
1
- {"version":3,"file":"camera.d.ts","sourceRoot":"","sources":["../../src/render/camera.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAE9C,eAAO,MAAM,YAAY,MAAM,CAAC;AAMhC,MAAM,WAAW,MAAM;IACrB,gGAAgG;IAChG,KAAK,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;IACxC,2FAA2F;IAC3F,GAAG,IAAI,IAAI,CAAC;IACZ,2FAA2F;IAC3F,GAAG,IAAI,IAAI,CAAC;IACZ,IAAI,IAAI,IAAI,CAAC;IACb,MAAM,IAAI,IAAI,CAAC;IACf,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,CAAC,UAAU,EAAE,OAAO,KAAK,IAAI,CAAA;CAAE,CA6DtH"}
1
+ {"version":3,"file":"camera.d.ts","sourceRoot":"","sources":["../../src/render/camera.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,eAAO,MAAM,YAAY,MAAM,CAAC;AAMhC,MAAM,WAAW,MAAM;IACrB,gGAAgG;IAChG,KAAK,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;IACxC,2FAA2F;IAC3F,GAAG,IAAI,IAAI,CAAC;IACZ,2FAA2F;IAC3F,GAAG,IAAI,IAAI,CAAC;IACZ,kFAAkF;IAClF,KAAK,IAAI,IAAI,CAAC;IACd,8FAA8F;IAC9F,KAAK,IAAI,IAAI,CAAC;IACd,IAAI,IAAI,IAAI,CAAC;IACb,MAAM,IAAI,IAAI,CAAC;IACf,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,WAAW,EACjB,IAAI,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,GAChC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,CAAC,UAAU,EAAE,OAAO,KAAK,IAAI,CAAA;CAAE,CA6E1D"}
@@ -1,40 +1,52 @@
1
- const O = 420;
2
- function F(o, a) {
3
- let f = null, r = !1, n = !1, l = 0, i = 0;
4
- const c = (e) => {
5
- f ? o.fitViewByPointPositions([...f], e, 0.18) : o.fitView(e, 0.18);
6
- }, s = () => {
7
- i = 0, r && !n && c(0);
8
- }, t = typeof ResizeObserver > "u" ? null : new ResizeObserver(() => {
9
- i || (i = requestAnimationFrame(s));
10
- });
11
- return t == null || t.observe(a), o.ready.then(s, () => {
12
- }), { camera: {
1
+ import { GraphError as A } from "../core/error.js";
2
+ const d = 420, p = 0.18, I = 900, P = 700;
3
+ function D(a, O, y) {
4
+ let r = null, s = !1, t = !1, f = 0, o = 0, c = !1, u = !1, m = !1;
5
+ const i = (e) => {
6
+ if (!(!c || u || !a.isReady))
7
+ try {
8
+ a.fitView(e, p);
9
+ } catch (R) {
10
+ u = !0, t = !1, y(new A("graph/no-positions", "cosmos.gl holds no positions on the GPU to draw or frame.", {}, { cause: R }));
11
+ }
12
+ }, l = (e) => {
13
+ r ? a.fitViewByPointPositions([...r], e, p) : i(e);
14
+ }, F = () => {
15
+ o = 0, s && !t && l(0);
16
+ }, w = () => {
17
+ !o && !m && (o = requestAnimationFrame(F));
18
+ }, n = typeof ResizeObserver > "u" ? null : new ResizeObserver(w);
19
+ return n == null || n.observe(O), { camera: {
13
20
  frame(e) {
14
- f = e, r = !0, c(0);
21
+ r = e, s = !0, l(0);
15
22
  },
16
23
  fit() {
17
- r = !0, c(420);
24
+ s = !0, l(d);
18
25
  },
19
26
  run() {
20
- f = null, n = !0, l = performance.now();
27
+ r = null, t = !0, f = performance.now();
28
+ },
29
+ // A frame later: the commands cosmos.gl queued for its device run in the same turn as this.
30
+ ready: w,
31
+ drawn() {
32
+ c = !0;
21
33
  },
22
34
  tick() {
23
35
  const e = performance.now();
24
- !n || e - l < 900 || (l = e, o.fitView(700, 0.18));
36
+ !t || e - f < I || (f = e, i(P));
25
37
  },
26
38
  settle() {
27
- n && o.fitView(420, 0.18), n = !1;
39
+ t && i(d), t = !1;
28
40
  },
29
41
  destroy() {
30
- t == null || t.disconnect(), i && cancelAnimationFrame(i);
42
+ m = !0, n == null || n.disconnect(), o && cancelAnimationFrame(o);
31
43
  }
32
44
  }, taken: (e) => {
33
- e && (r = !1, n = !1);
45
+ e && (s = !1, t = !1);
34
46
  } };
35
47
  }
36
48
  export {
37
- O as FIT_DURATION,
38
- F as createCamera
49
+ d as FIT_DURATION,
50
+ D as createCamera
39
51
  };
40
52
  //# sourceMappingURL=camera.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"camera.js","sources":["../../src/render/camera.ts"],"sourcesContent":["import type { Graph } from \"@cosmos.gl/graph\";\n\nexport const FIT_DURATION = 420;\nconst FIT_PADDING = 0.18;\n/** How often a running layout re-frames the camera, and how long each re-frame glides. */\nconst FOLLOW_EVERY = 900;\nconst FOLLOW_DURATION = 700;\n\nexport interface Camera {\n /** A corpus was placed: frame these corners now, and again whenever the canvas changes size. */\n frame(corners: readonly number[]): void;\n /** The reader asked for the whole graph: frame it, and keep it framed through a resize. */\n fit(): void;\n /** A layout started moving the points: the corners are history, and the camera follows. */\n run(): void;\n tick(): void;\n settle(): void;\n destroy(): void;\n}\n\n/**\n * **Who holds the camera, and when it gives it back.** The camera frames the corpus once it is\n * placed and keeps it framed — through cosmos.gl's device coming up and every resize of the canvas,\n * since a host's split panel settles its width after mount and a frame taken at the old size opens\n * zoomed into a corner — and while a layout runs it follows the moving points and frames them when\n * they settle: Cosmograph's fit-on-settle, kept up. All of it stops the moment the reader zooms or\n * pans, and comes back with Fit or the next run.\n */\nexport function createCamera(graph: Graph, host: HTMLElement): { camera: Camera; taken: (userDriven: boolean) => void } {\n let corners: readonly number[] | null = null;\n let framing = false;\n let following = false;\n let followed = 0;\n let pending = 0;\n\n const fitNow = (duration: number) => {\n if (corners) graph.fitViewByPointPositions([...corners], duration, FIT_PADDING);\n else graph.fitView(duration, FIT_PADDING);\n };\n const reframe = () => {\n pending = 0;\n if (framing && !following) fitNow(0);\n };\n // After cosmos.gl's own observer has resized the canvas, so the frame is taken at the new size.\n const resizes =\n typeof ResizeObserver === \"undefined\"\n ? null\n : new ResizeObserver(() => {\n if (!pending) pending = requestAnimationFrame(reframe);\n });\n resizes?.observe(host);\n void graph.ready.then(reframe, () => {});\n\n const camera: Camera = {\n frame(next) {\n corners = next;\n framing = true;\n fitNow(0);\n },\n fit() {\n framing = true;\n fitNow(FIT_DURATION);\n },\n run() {\n corners = null;\n following = true;\n followed = performance.now();\n },\n tick() {\n const now = performance.now();\n if (!following || now - followed < FOLLOW_EVERY) return;\n followed = now;\n graph.fitView(FOLLOW_DURATION, FIT_PADDING);\n },\n settle() {\n if (following) graph.fitView(FIT_DURATION, FIT_PADDING);\n following = false;\n },\n destroy() {\n resizes?.disconnect();\n if (pending) cancelAnimationFrame(pending);\n },\n };\n const taken = (userDriven: boolean) => {\n if (!userDriven) return;\n framing = false;\n following = false;\n };\n return { camera, taken };\n}\n"],"names":["FIT_DURATION","createCamera","graph","host","corners","framing","following","followed","pending","fitNow","duration","reframe","resizes","next","now","userDriven"],"mappings":"AAEO,MAAMA,IAAe;AA0BrB,SAASC,EAAaC,GAAcC,GAA6E;AACtH,MAAIC,IAAoC,MACpCC,IAAU,IACVC,IAAY,IACZC,IAAW,GACXC,IAAU;AAEd,QAAMC,IAAS,CAACC,MAAqB;AACnC,IAAIN,MAAe,wBAAwB,CAAC,GAAGA,CAAO,GAAGM,GAAU,IAAW,IACzER,EAAM,QAAQQ,GAAU,IAAW;AAAA,EAC1C,GACMC,IAAU,MAAM;AACpB,IAAAH,IAAU,GACNH,KAAW,CAACC,KAAWG,EAAO,CAAC;AAAA,EACrC,GAEMG,IACJ,OAAO,iBAAmB,MACtB,OACA,IAAI,eAAe,MAAM;AACvB,IAAKJ,MAASA,IAAU,sBAAsBG,CAAO;AAAA,EACvD,CAAC;AACP,SAAAC,KAAA,QAAAA,EAAS,QAAQT,IACZD,EAAM,MAAM,KAAKS,GAAS,MAAM;AAAA,EAAC,CAAC,GAqChC,EAAE,QAnCc;AAAA,IACrB,MAAME,GAAM;AACV,MAAAT,IAAUS,GACVR,IAAU,IACVI,EAAO,CAAC;AAAA,IACV;AAAA,IACA,MAAM;AACJ,MAAAJ,IAAU,IACVI,EAAO,GAAY;AAAA,IACrB;AAAA,IACA,MAAM;AACJ,MAAAL,IAAU,MACVE,IAAY,IACZC,IAAW,YAAY,IAAA;AAAA,IACzB;AAAA,IACA,OAAO;AACL,YAAMO,IAAM,YAAY,IAAA;AACxB,MAAI,CAACR,KAAaQ,IAAMP,IAAW,QACnCA,IAAWO,GACXZ,EAAM,QAAQ,KAAiB,IAAW;AAAA,IAC5C;AAAA,IACA,SAAS;AACP,MAAII,KAAWJ,EAAM,QAAQ,KAAc,IAAW,GACtDI,IAAY;AAAA,IACd;AAAA,IACA,UAAU;AACR,MAAAM,KAAA,QAAAA,EAAS,cACLJ,0BAA8BA,CAAO;AAAA,IAC3C;AAAA,EAAA,GAOe,OALH,CAACO,MAAwB;AACrC,IAAKA,MACLV,IAAU,IACVC,IAAY;AAAA,EACd,EACiB;AACnB;"}
1
+ {"version":3,"file":"camera.js","sources":["../../src/render/camera.ts"],"sourcesContent":["import type { Graph } from \"@cosmos.gl/graph\";\nimport { GraphError } from \"../core/error\";\n\nexport const FIT_DURATION = 420;\nconst FIT_PADDING = 0.18;\n/** How often a running layout re-frames the camera, and how long each re-frame glides. */\nconst FOLLOW_EVERY = 900;\nconst FOLLOW_DURATION = 700;\n\nexport interface Camera {\n /** A corpus was placed: frame these corners now, and again whenever the canvas changes size. */\n frame(corners: readonly number[]): void;\n /** The reader asked for the whole graph: frame it, and keep it framed through a resize. */\n fit(): void;\n /** A layout started moving the points: the corners are history, and the camera follows. */\n run(): void;\n /** cosmos.gl's device came up: the frame is taken again, at the canvas's size. */\n ready(): void;\n /** cosmos.gl was handed positions and rendered them: from now on a fit may read them back. */\n drawn(): void;\n tick(): void;\n settle(): void;\n destroy(): void;\n}\n\n/**\n * **Who holds the camera, and when it gives it back.** The camera frames the corpus once it is\n * placed and keeps it framed — through cosmos.gl's device coming up and every resize of the canvas,\n * since a host's split panel settles its width after mount and a frame taken at the old size opens\n * zoomed into a corner — and while a layout runs it follows the moving points and frames them when\n * they settle: Cosmograph's fit-on-settle, kept up. All of it stops the moment the reader zooms or\n * pans, and comes back with Fit or the next run.\n *\n * **A fit without corners reads the points back from the GPU** (`fitView` → `getPointPositions` →\n * `readPixels` of cosmos.gl's position framebuffer), so it waits until there is one to read: the\n * device is up and a render has uploaded positions. If the read throws anyway, cosmos.gl holds no\n * positions: that is `graph/no-positions`, reported once through `fail`, and the camera reads no more\n * — rather than the same exception on every tick of a layout over a blank canvas.\n */\nexport function createCamera(\n graph: Graph,\n host: HTMLElement,\n fail: (error: GraphError) => void,\n): { camera: Camera; taken: (userDriven: boolean) => void } {\n let corners: readonly number[] | null = null;\n let framing = false;\n let following = false;\n let followed = 0;\n let pending = 0;\n let drawn = false;\n let broken = false;\n let gone = false;\n\n const fitPoints = (duration: number) => {\n if (!drawn || broken || !graph.isReady) return;\n try {\n graph.fitView(duration, FIT_PADDING);\n } catch (error) {\n broken = true;\n following = false;\n fail(new GraphError(\"graph/no-positions\", \"cosmos.gl holds no positions on the GPU to draw or frame.\", {}, { cause: error }));\n }\n };\n const fitNow = (duration: number) => {\n if (corners) graph.fitViewByPointPositions([...corners], duration, FIT_PADDING);\n else fitPoints(duration);\n };\n const reframe = () => {\n pending = 0;\n if (framing && !following) fitNow(0);\n };\n const later = () => {\n if (!pending && !gone) pending = requestAnimationFrame(reframe);\n };\n // After cosmos.gl's own observer has resized the canvas, so the frame is taken at the new size.\n const resizes = typeof ResizeObserver === \"undefined\" ? null : new ResizeObserver(later);\n resizes?.observe(host);\n\n const camera: Camera = {\n frame(next) {\n corners = next;\n framing = true;\n fitNow(0);\n },\n fit() {\n framing = true;\n fitNow(FIT_DURATION);\n },\n run() {\n corners = null;\n following = true;\n followed = performance.now();\n },\n // A frame later: the commands cosmos.gl queued for its device run in the same turn as this.\n ready: later,\n drawn() {\n drawn = true;\n },\n tick() {\n const now = performance.now();\n if (!following || now - followed < FOLLOW_EVERY) return;\n followed = now;\n fitPoints(FOLLOW_DURATION);\n },\n settle() {\n if (following) fitPoints(FIT_DURATION);\n following = false;\n },\n destroy() {\n gone = true;\n resizes?.disconnect();\n if (pending) cancelAnimationFrame(pending);\n },\n };\n const taken = (userDriven: boolean) => {\n if (!userDriven) return;\n framing = false;\n following = false;\n };\n return { camera, taken };\n}\n"],"names":["FIT_DURATION","FIT_PADDING","FOLLOW_EVERY","FOLLOW_DURATION","createCamera","graph","host","fail","corners","framing","following","followed","pending","drawn","broken","gone","fitPoints","duration","error","GraphError","fitNow","reframe","later","resizes","next","now","userDriven"],"mappings":";AAGO,MAAMA,IAAe,KACtBC,IAAc,MAEdC,IAAe,KACfC,IAAkB;AAgCjB,SAASC,EACdC,GACAC,GACAC,GAC0D;AAC1D,MAAIC,IAAoC,MACpCC,IAAU,IACVC,IAAY,IACZC,IAAW,GACXC,IAAU,GACVC,IAAQ,IACRC,IAAS,IACTC,IAAO;AAEX,QAAMC,IAAY,CAACC,MAAqB;AACtC,QAAI,GAACJ,KAASC,KAAU,CAACT,EAAM;AAC/B,UAAI;AACF,QAAAA,EAAM,QAAQY,GAAUhB,CAAW;AAAA,MACrC,SAASiB,GAAO;AACd,QAAAJ,IAAS,IACTJ,IAAY,IACZH,EAAK,IAAIY,EAAW,sBAAsB,6DAA6D,CAAA,GAAI,EAAE,OAAOD,EAAA,CAAO,CAAC;AAAA,MAC9H;AAAA,EACF,GACME,IAAS,CAACH,MAAqB;AACnC,IAAIT,MAAe,wBAAwB,CAAC,GAAGA,CAAO,GAAGS,GAAUhB,CAAW,MAC/DgB,CAAQ;AAAA,EACzB,GACMI,IAAU,MAAM;AACpB,IAAAT,IAAU,GACNH,KAAW,CAACC,KAAWU,EAAO,CAAC;AAAA,EACrC,GACME,IAAQ,MAAM;AAClB,IAAI,CAACV,KAAW,CAACG,MAAMH,IAAU,sBAAsBS,CAAO;AAAA,EAChE,GAEME,IAAU,OAAO,iBAAmB,MAAc,OAAO,IAAI,eAAeD,CAAK;AACvF,SAAAC,KAAA,QAAAA,EAAS,QAAQjB,IA2CV,EAAE,QAzCc;AAAA,IACrB,MAAMkB,GAAM;AACV,MAAAhB,IAAUgB,GACVf,IAAU,IACVW,EAAO,CAAC;AAAA,IACV;AAAA,IACA,MAAM;AACJ,MAAAX,IAAU,IACVW,EAAOpB,CAAY;AAAA,IACrB;AAAA,IACA,MAAM;AACJ,MAAAQ,IAAU,MACVE,IAAY,IACZC,IAAW,YAAY,IAAA;AAAA,IACzB;AAAA;AAAA,IAEA,OAAOW;AAAA,IACP,QAAQ;AACN,MAAAT,IAAQ;AAAA,IACV;AAAA,IACA,OAAO;AACL,YAAMY,IAAM,YAAY,IAAA;AACxB,MAAI,CAACf,KAAae,IAAMd,IAAWT,MACnCS,IAAWc,GACXT,EAAUb,CAAe;AAAA,IAC3B;AAAA,IACA,SAAS;AACP,MAAIO,OAAqBV,CAAY,GACrCU,IAAY;AAAA,IACd;AAAA,IACA,UAAU;AACR,MAAAK,IAAO,IACPQ,KAAA,QAAAA,EAAS,cACLX,0BAA8BA,CAAO;AAAA,IAC3C;AAAA,EAAA,GAOe,OALH,CAACc,MAAwB;AACrC,IAAKA,MACLjB,IAAU,IACVC,IAAY;AAAA,EACd,EACiB;AACnB;"}
@@ -1 +1 @@
1
- {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/render/renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAGzC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,aAAa,EAAoB,MAAM,eAAe,CAAC;AASrE,MAAM,WAAW,cAAc;IAC7B,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,+FAA+F;IAC/F,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC;CACvD;AAED,MAAM,WAAW,QAAS,SAAQ,aAAa;IAC7C,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,kFAAkF;IAClF,OAAO,IAAI,IAAI,CAAC;IAChB,uFAAuF;IACvF,GAAG,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;KAAE,GAAG;QAAE,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAA;KAAE,GAAG,MAAM,EAAE,CAAC;IACvG,OAAO,IAAI,IAAI,CAAC;CACjB;AAcD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,GAAE,cAAmB,GAAG,QAAQ,GAAG,IAAI,CAmVpH"}
1
+ {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/render/renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAGzC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,aAAa,EAAoB,MAAM,eAAe,CAAC;AASrE,MAAM,WAAW,cAAc;IAC7B,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,+FAA+F;IAC/F,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC;CACvD;AAED,MAAM,WAAW,QAAS,SAAQ,aAAa;IAC7C,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,kFAAkF;IAClF,OAAO,IAAI,IAAI,CAAC;IAChB,uFAAuF;IACvF,GAAG,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;KAAE,GAAG;QAAE,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAA;KAAE,GAAG,MAAM,EAAE,CAAC;IACvG,OAAO,IAAI,IAAI,CAAC;CACjB;AAcD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,GAAE,cAAmB,GAAG,QAAQ,GAAG,IAAI,CAoVpH"}