@graphty/graphty-element 2.6.1 → 3.0.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/dist/ai.js +3 -3
- package/dist/catalog.js +53 -54
- package/dist/chunks/{AiManager-4iQpsJW1.js → AiManager-Bhh0rR_p.js} +706 -655
- package/dist/chunks/GraphSession-DPoTaT3b.js +21175 -0
- package/dist/chunks/{GraphtyLogger-B_O67a6c.js → GraphtyLogger-BtcBJQPL.js} +1 -1
- package/dist/chunks/{VoiceInputAdapter-Cc6mHXTI.js → VoiceInputAdapter-CdLsJ_nG.js} +1 -1
- package/dist/chunks/{XRPivotCameraController-BLa89LXn.js → XRPivotCameraController-CiLJ9Gz6.js} +2 -2
- package/dist/chunks/algorithms-qij74zEN.js +6811 -0
- package/dist/chunks/{capability-check-Am2zliFj.js → capability-check-BbgTejS3.js} +1 -1
- package/dist/chunks/definePalette-BYt2Llxs.js +1333 -0
- package/dist/chunks/fields-5uVC1Pll.js +4999 -0
- package/dist/chunks/{format-detection-BHwrAVzW.js → format-detection-FKaDMshR.js} +1 -1
- package/dist/chunks/{index-BkBLbvui.js → index-Cc_6D9hV.js} +6034 -7127
- package/dist/chunks/interpolation-Dk206AhZ.js +105 -0
- package/dist/chunks/paletteRegistry-De3CGdst.js +357 -0
- package/dist/chunks/parse-SVp77JbE.js +669 -0
- package/dist/chunks/{pluginRegistry-Bs8bEkz9.js → pluginRegistry-Ddfl6Mv2.js} +27 -24
- package/dist/chunks/{registry-BdGvyZou.js → registry-CgMqldp4.js} +1 -1
- package/dist/chunks/{DataSource-BL2UzPff.js → sources-BbAJCDIH.js} +279 -108
- package/dist/commands.d.ts +128 -19
- package/dist/commands.js +49 -1
- package/dist/custom-elements.json +1 -1
- package/dist/extend.d.ts +10 -2
- package/dist/extend.js +64 -57
- package/dist/graphty-catalog.json +6 -3
- package/dist/graphty.bundle.js +267177 -240648
- package/dist/graphty.js +84 -78
- package/dist/index.d.ts +4 -0
- package/dist/logging.js +2 -2
- package/dist/schema.js +70 -71
- package/dist/session.d.ts +5 -6
- package/dist/session.js +40 -86
- package/dist/src/Edge.d.ts +31 -67
- package/dist/src/Graph.d.ts +335 -77
- package/dist/src/Node.d.ts +36 -3
- package/dist/src/NodeBehavior.d.ts +28 -0
- package/dist/src/Styles.d.ts +15 -4
- package/dist/src/acceleration/AccelerationController.d.ts +8 -0
- package/dist/src/acceleration/narrow.d.ts +9 -1
- package/dist/src/acceleration/types.d.ts +10 -0
- package/dist/src/ai/AiController.d.ts +12 -0
- package/dist/src/ai/AiManager.d.ts +7 -0
- package/dist/src/ai/commands/AlgorithmCommands.d.ts +1 -1
- package/dist/src/ai/commands/LayoutCommands.d.ts +1 -1
- package/dist/src/ai/commands/StyleCommands.d.ts +1 -1
- package/dist/src/ai/commands/types.d.ts +20 -1
- package/dist/src/algorithms/Algorithm.d.ts +21 -4
- package/dist/src/algorithms/BFSAlgorithm.d.ts +0 -9
- package/dist/src/algorithms/BellmanFordAlgorithm.d.ts +0 -14
- package/dist/src/algorithms/DFSAlgorithm.d.ts +1 -1
- package/dist/src/algorithms/FloydWarshallAlgorithm.d.ts +5 -0
- package/dist/src/algorithms/GirvanNewmanAlgorithm.d.ts +5 -0
- package/dist/src/algorithms/LeidenAlgorithm.d.ts +5 -0
- package/dist/src/algorithms/PageRankAlgorithm.d.ts +1 -1
- package/dist/src/algorithms/StronglyConnectedComponentsAlgorithm.d.ts +1 -1
- package/dist/src/algorithms/metrics/fields.d.ts +23 -1
- package/dist/src/algorithms/utils/graphUtils.d.ts +13 -1
- package/dist/src/catalog/paletteRegistry.d.ts +4 -4
- package/dist/src/catalog/registry.d.ts +3 -2
- package/dist/src/catalog/types.d.ts +18 -1
- package/dist/src/config/GraphStyle.d.ts +1 -1
- package/dist/src/config/StyleTemplate.d.ts +2 -2
- package/dist/src/config/xr-config-schema.d.ts +4 -4
- package/dist/src/data/CSVDataSource.d.ts +77 -22
- package/dist/src/data/ErrorAggregator.d.ts +5 -0
- package/dist/src/data/GEXFDataSource.d.ts +12 -61
- package/dist/src/data/GraphMLDataSource.d.ts +3 -44
- package/dist/src/data/GraphStore.d.ts +322 -15
- package/dist/src/data/JsonDataSource.d.ts +43 -1
- package/dist/src/data/graph-io-import.d.ts +89 -0
- package/dist/src/data/graph-io-records.d.ts +64 -0
- package/dist/src/data/lane.d.ts +23 -0
- package/dist/src/data/positions.d.ts +13 -0
- package/dist/src/data/seedPosition.d.ts +16 -0
- package/dist/src/errors/GraphtyError.d.ts +3 -1
- package/dist/src/errors/codes.d.ts +23 -0
- package/dist/src/events.d.ts +12 -0
- package/dist/src/graphty-element.d.ts +149 -54
- package/dist/src/input/types.d.ts +2 -0
- package/dist/src/layout/D3GraphLayoutEngine.d.ts +17 -3
- package/dist/src/layout/FixedLayoutEngine.d.ts +20 -4
- package/dist/src/layout/KamadaKawaiLayoutEngine.d.ts +6 -0
- package/dist/src/layout/LayoutEngine.d.ts +214 -116
- package/dist/src/layout/NGraphLayoutEngine.d.ts +10 -3
- package/dist/src/layout/SimulationLayoutEngine.d.ts +8 -3
- package/dist/src/managers/AlgorithmManager.d.ts +24 -5
- package/dist/src/managers/DataManager.d.ts +258 -181
- package/dist/src/managers/EventManager.d.ts +5 -2
- package/dist/src/managers/GraphContext.d.ts +7 -0
- package/dist/src/managers/InputManager.d.ts +11 -0
- package/dist/src/managers/LayoutManager.d.ts +129 -50
- package/dist/src/managers/RenderManager.d.ts +14 -1
- package/dist/src/managers/UpdateManager.d.ts +20 -0
- package/dist/src/screenshot/ScreenshotCapture.d.ts +1 -1
- package/dist/src/session/GraphSession.d.ts +83 -6
- package/dist/src/session/commands/algo.d.ts +169 -0
- package/dist/src/session/commands/config.d.ts +45 -0
- package/dist/src/session/commands/data.d.ts +178 -0
- package/dist/src/session/commands/doors.d.ts +93 -0
- package/dist/src/session/commands/index.d.ts +20 -0
- package/dist/src/session/commands/layout.d.ts +104 -0
- package/dist/src/session/commands/positions.d.ts +30 -0
- package/dist/src/session/commands/sets.d.ts +113 -0
- package/dist/src/session/commands/style.d.ts +92 -0
- package/dist/src/session/commands/view.d.ts +57 -0
- package/dist/src/session/commands/visibility.d.ts +41 -0
- package/dist/src/session/data.d.ts +131 -4
- package/dist/src/session/index.d.ts +1 -1
- package/dist/src/session/planning.d.ts +25 -8
- package/dist/src/session/project/Dispatcher.d.ts +905 -0
- package/dist/src/session/project/History.d.ts +382 -0
- package/dist/src/session/project/arrangement.d.ts +247 -0
- package/dist/src/session/project/derive.d.ts +132 -0
- package/dist/src/session/project/digest.d.ts +33 -0
- package/dist/src/session/project/draft.d.ts +194 -0
- package/dist/src/session/project/graphOps.d.ts +304 -0
- package/dist/src/session/project/ingest.d.ts +364 -0
- package/dist/src/session/project/state.d.ts +145 -0
- package/dist/src/session/project/strict.d.ts +68 -0
- package/dist/src/session/results/RunResult.d.ts +48 -0
- package/dist/src/session/results/statistics.d.ts +20 -0
- package/dist/src/session/runs/Run.d.ts +80 -4
- package/dist/src/session/runs/RunsApi.d.ts +23 -6
- package/dist/src/session/runs/types.d.ts +25 -6
- package/dist/src/session/scope/ElementMask.d.ts +14 -0
- package/dist/src/session/scope/ScopeApi.d.ts +3 -22
- package/dist/src/session/scope/spaces.d.ts +29 -0
- package/dist/src/session/sealed.d.ts +22 -0
- package/dist/src/session/selection/SelectionApi.d.ts +14 -4
- package/dist/src/session/sets/SetsApi.d.ts +13 -5
- package/dist/src/session/sets/store.d.ts +54 -53
- package/dist/src/session/sets/types.d.ts +5 -2
- package/dist/src/session/styles/Layer.d.ts +5 -0
- package/dist/src/session/styles/StylesApi.d.ts +68 -17
- package/dist/src/session/styles/autoApply.d.ts +64 -53
- package/dist/src/session/styles/index.d.ts +3 -3
- package/dist/src/session/styles/predicate.d.ts +7 -0
- package/dist/src/session/styles/repaint.d.ts +16 -1
- package/dist/src/session/styles/sources.d.ts +1 -1
- package/dist/src/session/types.d.ts +625 -54
- package/dist/src/session/visibility/VisibilityApi.d.ts +38 -18
- package/dist/src/session/visibility/filter.d.ts +10 -0
- package/dist/src/simple/defineAlgorithm.d.ts +28 -0
- package/dist/src/simple/defineLayout.d.ts +35 -0
- package/dist/src/simple/defineLogDestination.d.ts +31 -0
- package/dist/src/simple/definePalette.d.ts +26 -0
- package/dist/src/simple/definition.d.ts +106 -0
- package/dist/src/simple/options.d.ts +33 -0
- package/dist/src/simple/source.d.ts +49 -0
- package/dist/src/simple/types.d.ts +366 -0
- package/dist/src/simple/view.d.ts +107 -0
- package/dist/webgpu.js +2 -2
- package/package.json +10 -12
- package/dist/chunks/GraphSession-BhuHSXIo.js +0 -12819
- package/dist/chunks/GraphStyle-Cwr55SAE.js +0 -65
- package/dist/chunks/algorithms-BJ6DQMOe.js +0 -3777
- package/dist/chunks/detect-fyuVnlCT.js +0 -88
- package/dist/chunks/interpolation-DY-PNpqX.js +0 -43
- package/dist/chunks/optionsFromZod-CKMYSwTz.js +0 -3636
- package/dist/chunks/paletteRegistry-BCFSwJGK.js +0 -1196
- package/dist/chunks/parse-BMTqt4SS.js +0 -3658
- package/dist/src/data/csv-variant-detection.d.ts +0 -29
- package/dist/src/data/ingest.d.ts +0 -104
|
@@ -0,0 +1,1333 @@
|
|
|
1
|
+
var se = (n) => {
|
|
2
|
+
throw TypeError(n);
|
|
3
|
+
};
|
|
4
|
+
var W = (n, e, t) => e.has(n) || se("Cannot " + t);
|
|
5
|
+
var S = (n, e, t) => (W(n, e, "read from private field"), t ? t.call(n) : e.get(n)), I = (n, e, t) => e.has(n) ? se("Cannot add the same private member more than once") : e instanceof WeakSet ? e.add(n) : e.set(n, t), O = (n, e, t, o) => (W(n, e, "write to private field"), o ? o.call(n, t) : e.set(n, t), t), z = (n, e, t) => (W(n, e, "access private method"), t);
|
|
6
|
+
var R = (n, e, t, o) => ({
|
|
7
|
+
set _(s) {
|
|
8
|
+
O(n, e, s, t);
|
|
9
|
+
},
|
|
10
|
+
get _() {
|
|
11
|
+
return S(n, e, o);
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
import { T as Se, a as Ne, i as Fe, l as ze, p as Re, m as ie, h as Je, o as Ve, j as Ge, Y as Be, b as re, c as Ke } from "./fields-5uVC1Pll.js";
|
|
15
|
+
import { G as P, i as te } from "./pluginRegistry-Ddfl6Mv2.js";
|
|
16
|
+
import { G as L, r as Ue } from "./GraphtyLogger-BtcBJQPL.js";
|
|
17
|
+
import { O as Ye } from "./types-DFchv4Ny.js";
|
|
18
|
+
import { e as Ee, c as qe } from "./sources-BbAJCDIH.js";
|
|
19
|
+
import { n as We, r as He } from "./paletteRegistry-De3CGdst.js";
|
|
20
|
+
const Xe = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
|
|
21
|
+
function v(n) {
|
|
22
|
+
if (n == null)
|
|
23
|
+
return String(n);
|
|
24
|
+
if (Array.isArray(n))
|
|
25
|
+
return "an array";
|
|
26
|
+
switch (typeof n) {
|
|
27
|
+
case "string":
|
|
28
|
+
return `the string ${JSON.stringify(n)}`;
|
|
29
|
+
case "number":
|
|
30
|
+
case "boolean":
|
|
31
|
+
case "bigint":
|
|
32
|
+
return `the ${typeof n} ${String(n)}`;
|
|
33
|
+
case "function":
|
|
34
|
+
return "a function";
|
|
35
|
+
default:
|
|
36
|
+
return "an object";
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function w(n, e, t, o) {
|
|
40
|
+
const s = e === void 0 ? `${n}()` : `${n}(${JSON.stringify(e)})`;
|
|
41
|
+
return new P({
|
|
42
|
+
code: "E_BAD_COMMAND",
|
|
43
|
+
message: `${s}: ${o}`,
|
|
44
|
+
source: "registry",
|
|
45
|
+
details: { field: t, ...e === void 0 ? {} : { extension: e } }
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
function U(n, e) {
|
|
49
|
+
if (typeof e != "object" || e === null || Array.isArray(e))
|
|
50
|
+
throw w(
|
|
51
|
+
n,
|
|
52
|
+
void 0,
|
|
53
|
+
"definition",
|
|
54
|
+
`the definition must be an object such as { id: "acme-example", ... }; got ${v(e)}.`
|
|
55
|
+
);
|
|
56
|
+
const { id: t } = e;
|
|
57
|
+
if (typeof t != "string" || t === "")
|
|
58
|
+
throw w(
|
|
59
|
+
n,
|
|
60
|
+
void 0,
|
|
61
|
+
"id",
|
|
62
|
+
`"id" must be a non-empty string such as "acme-example"; got ${v(t)}.`
|
|
63
|
+
);
|
|
64
|
+
if (!Xe.test(t))
|
|
65
|
+
throw w(
|
|
66
|
+
n,
|
|
67
|
+
t,
|
|
68
|
+
"id",
|
|
69
|
+
`"id" must be lower-case words joined by hyphens, starting with a letter and led by your own prefix, such as "acme-tiers"; got ${JSON.stringify(t)}. The id is saved in documents, so it cannot contain spaces, capitals, dots, colons or slashes.`
|
|
70
|
+
);
|
|
71
|
+
const o = e;
|
|
72
|
+
for (const s of ["name", "description", "version"])
|
|
73
|
+
Qe(n, o, s);
|
|
74
|
+
return o;
|
|
75
|
+
}
|
|
76
|
+
function ne(n, e, t) {
|
|
77
|
+
if (typeof e[t] != "function")
|
|
78
|
+
throw w(
|
|
79
|
+
n,
|
|
80
|
+
e.id,
|
|
81
|
+
t,
|
|
82
|
+
`"${t}" must be a function; got ${v(e[t])}.`
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
function Qe(n, e, t) {
|
|
86
|
+
const o = e[t];
|
|
87
|
+
if (o !== void 0 && typeof o != "string")
|
|
88
|
+
throw w(n, e.id, t, `"${t}" must be a string; got ${v(o)}.`);
|
|
89
|
+
}
|
|
90
|
+
function K(n, e, t, o) {
|
|
91
|
+
const s = e[t];
|
|
92
|
+
if (s !== void 0 && !o.includes(s)) {
|
|
93
|
+
const i = o.map((c) => JSON.stringify(c)).join(", ");
|
|
94
|
+
throw w(
|
|
95
|
+
n,
|
|
96
|
+
e.id,
|
|
97
|
+
t,
|
|
98
|
+
`"${t}" must be one of ${i}; got ${v(s)}.`
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function ke(n) {
|
|
103
|
+
const t = n.replace(/([a-z0-9])([A-Z])/g, "$1 $2").split(/[\s_-]+/).filter((o) => o !== "").map((o) => o.toLowerCase()).join(" ");
|
|
104
|
+
return t.charAt(0).toUpperCase() + t.slice(1);
|
|
105
|
+
}
|
|
106
|
+
function Y(n) {
|
|
107
|
+
return typeof n.name == "string" && n.name !== "" ? n.name : ke(n.id);
|
|
108
|
+
}
|
|
109
|
+
function G(n, e) {
|
|
110
|
+
const t = e instanceof Error ? `${e.name}: ${e.message}` : String(e), o = n.subject === void 0 ? "" : ` for ${n.subject}`;
|
|
111
|
+
return new P({
|
|
112
|
+
code: "E_EXTENSION_FAILED",
|
|
113
|
+
message: `${n.id}: ${n.member}() threw${o} (${t}).`,
|
|
114
|
+
source: n.source,
|
|
115
|
+
details: {
|
|
116
|
+
extension: n.id,
|
|
117
|
+
member: n.member,
|
|
118
|
+
...n.subject === void 0 ? {} : { subject: n.subject }
|
|
119
|
+
},
|
|
120
|
+
cause: e
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
function Ze(n, e) {
|
|
124
|
+
try {
|
|
125
|
+
return e();
|
|
126
|
+
} catch (t) {
|
|
127
|
+
throw te(t) ? t : G(n, t);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
async function et(n, e) {
|
|
131
|
+
try {
|
|
132
|
+
return await e();
|
|
133
|
+
} catch (t) {
|
|
134
|
+
throw te(t) ? t : G(n, t);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function tt(n, e) {
|
|
138
|
+
return Se(n, e);
|
|
139
|
+
}
|
|
140
|
+
const Ae = /* @__PURE__ */ new WeakMap();
|
|
141
|
+
function Oe(n, e) {
|
|
142
|
+
return `${n}\0${e}`;
|
|
143
|
+
}
|
|
144
|
+
function D(n) {
|
|
145
|
+
return typeof n == "number" ? String(n) : JSON.stringify(n);
|
|
146
|
+
}
|
|
147
|
+
function nt(n, e) {
|
|
148
|
+
return new P({
|
|
149
|
+
code: "E_BAD_COMMAND",
|
|
150
|
+
message: `${n.options.id}: ${e}() needs direction: "directed" in the definition. Without it the graph is read as undirected, and which way an edge points is not known.`,
|
|
151
|
+
source: n.options.source ?? "run",
|
|
152
|
+
details: { extension: n.options.id, member: e, field: "direction" }
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
function J(n, e) {
|
|
156
|
+
if (!n.options.directed)
|
|
157
|
+
throw nt(n, e);
|
|
158
|
+
}
|
|
159
|
+
function C(n, e, t) {
|
|
160
|
+
return t.run !== void 0 ? `${n}: ${e} reads ${t.path}, but no completed run is named "${t.run}"; run the algorithm that produces it first, with { as: "${t.run}" }.` : `${n}: ${e} names a ${t.target} attribute no ${t.target} carries; ${xe(t)}.`;
|
|
161
|
+
}
|
|
162
|
+
function xe(n) {
|
|
163
|
+
return n.carriers.length === 0 ? `no ${n.target} carries any attribute` : `${n.target}s carry: ${n.carriers.join(", ")}`;
|
|
164
|
+
}
|
|
165
|
+
function ot(n) {
|
|
166
|
+
const e = /^results\.([^.]+)\./.exec(n);
|
|
167
|
+
return e === null ? void 0 : e[1];
|
|
168
|
+
}
|
|
169
|
+
function _(n, e, t, o) {
|
|
170
|
+
const s = Oe(e, t);
|
|
171
|
+
if (n.checked.has(s))
|
|
172
|
+
return;
|
|
173
|
+
const { source: i } = n, c = e === "node" ? i.snapshot.nodeCount : i.snapshot.edgeCount;
|
|
174
|
+
let r = c === 0;
|
|
175
|
+
for (let a = 0; a < c && !r; a++) {
|
|
176
|
+
const d = e === "node" ? i.nodeValue(a, t) : i.edgeValue(a, t);
|
|
177
|
+
r = d != null;
|
|
178
|
+
}
|
|
179
|
+
if (!r) {
|
|
180
|
+
const a = ot(t), d = {
|
|
181
|
+
target: e,
|
|
182
|
+
path: t,
|
|
183
|
+
carriers: i.attributeNames?.(e) ?? [],
|
|
184
|
+
...a === void 0 ? {} : { run: a }
|
|
185
|
+
};
|
|
186
|
+
throw new P({
|
|
187
|
+
code: "E_OPTION_RANGE",
|
|
188
|
+
message: o(d),
|
|
189
|
+
source: n.options.source ?? "run",
|
|
190
|
+
details: {
|
|
191
|
+
extension: n.options.id,
|
|
192
|
+
target: e,
|
|
193
|
+
path: t,
|
|
194
|
+
carriers: d.carriers,
|
|
195
|
+
...a === void 0 ? {} : { run: a }
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
n.checked.set(s, { target: e, path: t });
|
|
200
|
+
}
|
|
201
|
+
function X(n, e, t, o, s) {
|
|
202
|
+
const i = Oe(e, t);
|
|
203
|
+
let c = n.tallies.get(i);
|
|
204
|
+
if (c === void 0 && (c = { target: e, path: t, missing: /* @__PURE__ */ new Set(), text: /* @__PURE__ */ new Set(), found: /* @__PURE__ */ new Set(), sample: void 0 }, n.tallies.set(i, c)), typeof s == "number" && Number.isFinite(s))
|
|
205
|
+
return c.found.add(o), s;
|
|
206
|
+
c.missing.add(o), typeof s == "string" && (c.text.add(o), c.sample ??= s);
|
|
207
|
+
}
|
|
208
|
+
function M(n) {
|
|
209
|
+
return Object.freeze(n);
|
|
210
|
+
}
|
|
211
|
+
class st {
|
|
212
|
+
#e;
|
|
213
|
+
#t;
|
|
214
|
+
#o = null;
|
|
215
|
+
#s = null;
|
|
216
|
+
#i = null;
|
|
217
|
+
#r = null;
|
|
218
|
+
#a = null;
|
|
219
|
+
#c = null;
|
|
220
|
+
#d = /* @__PURE__ */ new Map();
|
|
221
|
+
/**
|
|
222
|
+
* Build one node.
|
|
223
|
+
* @param state - The view.
|
|
224
|
+
* @param row - Its row in the snapshot.
|
|
225
|
+
* @param id - Its id.
|
|
226
|
+
*/
|
|
227
|
+
constructor(e, t, o) {
|
|
228
|
+
this.#e = e, this.#t = t, this.id = o;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* The node's row in the snapshot, for the view's own bookkeeping.
|
|
232
|
+
* @returns The row.
|
|
233
|
+
*/
|
|
234
|
+
get row() {
|
|
235
|
+
return this.#t;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* The number of edges touching the node.
|
|
239
|
+
* @returns edges().length: a self-loop counts once.
|
|
240
|
+
*/
|
|
241
|
+
get degree() {
|
|
242
|
+
return this.edges().length;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Every edge touching this node.
|
|
246
|
+
* @returns The edges, in the view's order.
|
|
247
|
+
*/
|
|
248
|
+
edges() {
|
|
249
|
+
return this.#o ??= M(this.#e.incident[this.#t].map((e) => this.#e.edges[e])), this.#o;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* The adjacent nodes.
|
|
253
|
+
* @returns Every adjacent node once, never this node.
|
|
254
|
+
*/
|
|
255
|
+
neighbors() {
|
|
256
|
+
return this.#s ??= this.#n(this.edges(), (e) => e.other(this)), this.#s;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* The edges leaving this node; every edge, in undirected data.
|
|
260
|
+
* @returns The edges.
|
|
261
|
+
*/
|
|
262
|
+
outEdges() {
|
|
263
|
+
return J(this.#e, "outEdges"), this.#i ??= this.#e.directedData ? M(this.edges().filter((e) => e.source === this)) : this.edges(), this.#i;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* The edges entering this node; every edge, in undirected data.
|
|
267
|
+
* @returns The edges.
|
|
268
|
+
*/
|
|
269
|
+
inEdges() {
|
|
270
|
+
return J(this.#e, "inEdges"), this.#r ??= this.#e.directedData ? M(this.edges().filter((e) => e.target === this)) : this.edges(), this.#r;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* The nodes this node's edges lead to.
|
|
274
|
+
* @returns The nodes, never this node.
|
|
275
|
+
*/
|
|
276
|
+
outNeighbors() {
|
|
277
|
+
return J(this.#e, "outNeighbors"), this.#a ??= this.#n(this.outEdges(), (e) => e.other(this)), this.#a;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* The nodes whose edges lead here.
|
|
281
|
+
* @returns The nodes, never this node.
|
|
282
|
+
*/
|
|
283
|
+
inNeighbors() {
|
|
284
|
+
return J(this.#e, "inNeighbors"), this.#c ??= this.#n(this.inEdges(), (e) => e.other(this)), this.#c;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* The edges between this node and another.
|
|
288
|
+
* @param other - The other node.
|
|
289
|
+
* @returns The edges, parallel edges included; in a directed view only those from here to there.
|
|
290
|
+
*/
|
|
291
|
+
edgesTo(e) {
|
|
292
|
+
const t = this.#e;
|
|
293
|
+
return t.options.directed && t.directedData ? M(this.outEdges().filter((o) => o.target === e)) : M(this.edges().filter((o) => o.other(this) === e));
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* The summed weight of the edges to another node.
|
|
297
|
+
* @param other - The other node.
|
|
298
|
+
* @param path - The weight path, or undefined to count each edge as 1.
|
|
299
|
+
* @returns The sum, or undefined when no edge between them has a weight.
|
|
300
|
+
*/
|
|
301
|
+
weightTo(e, t) {
|
|
302
|
+
return ae(this.edgesTo(e), t);
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* The weighted degree.
|
|
306
|
+
* @param path - The weight path, or undefined for the degree.
|
|
307
|
+
* @param direction - All edges, or only outgoing or incoming ones.
|
|
308
|
+
* @returns The sum.
|
|
309
|
+
*/
|
|
310
|
+
strength(e, t = "all") {
|
|
311
|
+
t !== "all" && J(this.#e, "strength");
|
|
312
|
+
const o = `${t}\0${e ?? ""}\0${e === void 0 ? "unbound" : "bound"}`;
|
|
313
|
+
let s = this.#d.get(o);
|
|
314
|
+
if (s === void 0) {
|
|
315
|
+
const i = { all: () => this.edges(), out: () => this.outEdges(), in: () => this.inEdges() }[t]();
|
|
316
|
+
s = e === void 0 ? i.length : ae(i, e) ?? 0, this.#d.set(o, s);
|
|
317
|
+
}
|
|
318
|
+
return s;
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* An attribute or a published result.
|
|
322
|
+
* @param path - The path, or undefined for an unbound option.
|
|
323
|
+
* @returns The value.
|
|
324
|
+
*/
|
|
325
|
+
attr(e) {
|
|
326
|
+
if (e === void 0)
|
|
327
|
+
return;
|
|
328
|
+
const t = this.#e;
|
|
329
|
+
return _(
|
|
330
|
+
t,
|
|
331
|
+
"node",
|
|
332
|
+
e,
|
|
333
|
+
(o) => C(t.options.id, `node.attr(${JSON.stringify(e)})`, o)
|
|
334
|
+
), t.source.nodeValue(this.#t, e);
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* attr(path) when it is a finite number.
|
|
338
|
+
* @param path - The path.
|
|
339
|
+
* @returns The number, or undefined.
|
|
340
|
+
*/
|
|
341
|
+
number(e) {
|
|
342
|
+
if (e === void 0)
|
|
343
|
+
return;
|
|
344
|
+
const t = this.#e;
|
|
345
|
+
return _(
|
|
346
|
+
t,
|
|
347
|
+
"node",
|
|
348
|
+
e,
|
|
349
|
+
(o) => C(t.options.id, `node.number(${JSON.stringify(e)})`, o)
|
|
350
|
+
), X(t, "node", e, this.#t, t.source.nodeValue(this.#t, e));
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* The distinct far ends of a list of edges, in the view's order, leaving this node out.
|
|
354
|
+
* @param list - The edges.
|
|
355
|
+
* @param end - Picks the end.
|
|
356
|
+
* @returns The nodes.
|
|
357
|
+
*/
|
|
358
|
+
#n(e, t) {
|
|
359
|
+
const o = /* @__PURE__ */ new Set();
|
|
360
|
+
for (const i of e) {
|
|
361
|
+
const c = t(i);
|
|
362
|
+
c !== this && o.add(c);
|
|
363
|
+
}
|
|
364
|
+
const { nodePosition: s } = this.#e;
|
|
365
|
+
return M([...o].sort((i, c) => s[i.row] - s[c.row]));
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
function ae(n, e) {
|
|
369
|
+
let t = 0, o = !1;
|
|
370
|
+
for (const s of n) {
|
|
371
|
+
const i = s.weight(e);
|
|
372
|
+
i !== void 0 && (t += i, o = !0);
|
|
373
|
+
}
|
|
374
|
+
return o ? t : void 0;
|
|
375
|
+
}
|
|
376
|
+
class it {
|
|
377
|
+
#e;
|
|
378
|
+
#t;
|
|
379
|
+
/**
|
|
380
|
+
* Build one edge.
|
|
381
|
+
* @param state - The view.
|
|
382
|
+
* @param row - Its row in the snapshot.
|
|
383
|
+
* @param id - The element's edge id.
|
|
384
|
+
* @param source - The end the data named first.
|
|
385
|
+
* @param target - The other end.
|
|
386
|
+
*/
|
|
387
|
+
constructor(e, t, o, s, i) {
|
|
388
|
+
this.#e = e, this.#t = t, this.id = o, this.source = s, this.target = i;
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* The end that is not `node`.
|
|
392
|
+
* @param node - One end.
|
|
393
|
+
* @returns The other end; a self-loop returns `node`.
|
|
394
|
+
*/
|
|
395
|
+
other(e) {
|
|
396
|
+
if (e === this.source)
|
|
397
|
+
return this.target;
|
|
398
|
+
if (e === this.target)
|
|
399
|
+
return this.source;
|
|
400
|
+
const { options: t } = this.#e;
|
|
401
|
+
throw new P({
|
|
402
|
+
code: "E_BAD_COMMAND",
|
|
403
|
+
message: `${t.id}: edge.other() was given node ${D(e.id)}, which is not an end of edge "${this.id}" (its ends are ${D(this.source.id)} and ${D(this.target.id)}).`,
|
|
404
|
+
source: t.source ?? "run",
|
|
405
|
+
details: { extension: t.id, member: "other", edge: this.id, node: e.id }
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* The edge's weight at a path.
|
|
410
|
+
* @param path - The path, or undefined to count the edge as 1.
|
|
411
|
+
* @returns The weight, or undefined when there is no number.
|
|
412
|
+
*/
|
|
413
|
+
weight(e) {
|
|
414
|
+
if (e === void 0)
|
|
415
|
+
return 1;
|
|
416
|
+
const t = this.#e;
|
|
417
|
+
return _(
|
|
418
|
+
t,
|
|
419
|
+
"edge",
|
|
420
|
+
e,
|
|
421
|
+
(o) => C(t.options.id, `edge.weight(${JSON.stringify(e)})`, o)
|
|
422
|
+
), t.weightPaths.add(e), X(t, "edge", e, this.#t, t.source.edgeValue(this.#t, e));
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* An attribute or a published result.
|
|
426
|
+
* @param path - The path, or undefined for an unbound option.
|
|
427
|
+
* @returns The value.
|
|
428
|
+
*/
|
|
429
|
+
attr(e) {
|
|
430
|
+
if (e === void 0)
|
|
431
|
+
return;
|
|
432
|
+
const t = this.#e;
|
|
433
|
+
return _(
|
|
434
|
+
t,
|
|
435
|
+
"edge",
|
|
436
|
+
e,
|
|
437
|
+
(o) => C(t.options.id, `edge.attr(${JSON.stringify(e)})`, o)
|
|
438
|
+
), t.source.edgeValue(this.#t, e);
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* attr(path) when it is a finite number.
|
|
442
|
+
* @param path - The path.
|
|
443
|
+
* @returns The number, or undefined.
|
|
444
|
+
*/
|
|
445
|
+
number(e) {
|
|
446
|
+
if (e === void 0)
|
|
447
|
+
return;
|
|
448
|
+
const t = this.#e;
|
|
449
|
+
return _(
|
|
450
|
+
t,
|
|
451
|
+
"edge",
|
|
452
|
+
e,
|
|
453
|
+
(o) => C(t.options.id, `edge.number(${JSON.stringify(e)})`, o)
|
|
454
|
+
), X(t, "edge", e, this.#t, t.source.edgeValue(this.#t, e));
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
const ce = { number: 0, boolean: 1, string: 2 }, rt = new Intl.Collator("en", { numeric: !0 });
|
|
458
|
+
function at(n, e) {
|
|
459
|
+
const t = ce[typeof n], o = ce[typeof e];
|
|
460
|
+
return t !== o ? t - o : typeof n == "string" && typeof e == "string" ? rt.compare(n, e) || Se(n, e) : Number(n) - Number(e);
|
|
461
|
+
}
|
|
462
|
+
function Me(n, e) {
|
|
463
|
+
const { snapshot: t } = n, { nodeCount: o, edgeCount: s } = t, i = [], c = Array.from({ length: o }, () => []), r = {
|
|
464
|
+
options: e,
|
|
465
|
+
source: n,
|
|
466
|
+
checked: /* @__PURE__ */ new Map(),
|
|
467
|
+
tallies: /* @__PURE__ */ new Map(),
|
|
468
|
+
weightPaths: /* @__PURE__ */ new Set(),
|
|
469
|
+
edges: i,
|
|
470
|
+
nodePosition: new Int32Array(o),
|
|
471
|
+
edgePosition: new Int32Array(s),
|
|
472
|
+
incident: c,
|
|
473
|
+
directedData: t.directed
|
|
474
|
+
}, a = [], d = /* @__PURE__ */ new Map();
|
|
475
|
+
for (let u = 0; u < o; u++) {
|
|
476
|
+
const p = new st(r, u, t.ids.idOf(u));
|
|
477
|
+
a.push(p), d.set(p.id, p);
|
|
478
|
+
}
|
|
479
|
+
const l = [...a].sort((u, p) => tt(u.id, p.id));
|
|
480
|
+
l.forEach((u, p) => {
|
|
481
|
+
r.nodePosition[u.row] = p;
|
|
482
|
+
});
|
|
483
|
+
const g = Ee(t), { src: b, dst: N } = s === 0 ? { src: new Uint32Array(0), dst: new Uint32Array(0) } : t.edgeList(), E = /* @__PURE__ */ new Map();
|
|
484
|
+
for (let u = 0; u < s; u++) {
|
|
485
|
+
const p = new it(r, u, g.idOf(u), a[b[u]], a[N[u]]);
|
|
486
|
+
i.push(p), E.set(p.id, p), c[b[u]].push(u), N[u] !== b[u] && c[N[u]].push(u);
|
|
487
|
+
}
|
|
488
|
+
const F = [...i.keys()].sort((u, p) => Number(i[u].id) - Number(i[p].id) || u - p);
|
|
489
|
+
F.forEach((u, p) => {
|
|
490
|
+
r.edgePosition[u] = p;
|
|
491
|
+
});
|
|
492
|
+
for (const u of c)
|
|
493
|
+
u.sort((p, h) => r.edgePosition[p] - r.edgePosition[h]);
|
|
494
|
+
const j = M(l), f = M(F.map((u) => i[u])), k = /* @__PURE__ */ new Map(), $ = {
|
|
495
|
+
directed: e.directed && t.directed,
|
|
496
|
+
nodeCount: o,
|
|
497
|
+
edgeCount: s,
|
|
498
|
+
nodes: () => j,
|
|
499
|
+
edges: () => f,
|
|
500
|
+
node: (u) => d.get(u),
|
|
501
|
+
edge: (u) => E.get(u),
|
|
502
|
+
groupBy(u) {
|
|
503
|
+
if (u === void 0)
|
|
504
|
+
return /* @__PURE__ */ new Map();
|
|
505
|
+
let p = k.get(u);
|
|
506
|
+
if (p === void 0) {
|
|
507
|
+
_(
|
|
508
|
+
r,
|
|
509
|
+
"node",
|
|
510
|
+
u,
|
|
511
|
+
(m) => C(e.id, `graph.groupBy(${JSON.stringify(u)})`, m)
|
|
512
|
+
);
|
|
513
|
+
const h = /* @__PURE__ */ new Map();
|
|
514
|
+
for (const m of j) {
|
|
515
|
+
const y = n.nodeValue(m.row, u);
|
|
516
|
+
if (typeof y == "string" || typeof y == "boolean" || typeof y == "number" && Number.isFinite(y)) {
|
|
517
|
+
const T = h.get(y) ?? [];
|
|
518
|
+
T.push(m), h.set(y, T);
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
p = new Map(
|
|
522
|
+
[...h.entries()].sort(([m], [y]) => at(m, y)).map(([m, y]) => [m, M(y)])
|
|
523
|
+
), k.set(u, p);
|
|
524
|
+
}
|
|
525
|
+
return p;
|
|
526
|
+
}
|
|
527
|
+
};
|
|
528
|
+
return Ae.set($, r), $;
|
|
529
|
+
}
|
|
530
|
+
function q(n) {
|
|
531
|
+
const e = Ae.get(n);
|
|
532
|
+
if (e === void 0)
|
|
533
|
+
throw new P({
|
|
534
|
+
code: "E_INTERNAL",
|
|
535
|
+
message: "a graph view was used that graphty-element did not build",
|
|
536
|
+
source: "run"
|
|
537
|
+
});
|
|
538
|
+
return e;
|
|
539
|
+
}
|
|
540
|
+
function ct(n, e, t, o) {
|
|
541
|
+
_(q(n), e, t, o);
|
|
542
|
+
}
|
|
543
|
+
function dt(n) {
|
|
544
|
+
return [...q(n).checked.values()];
|
|
545
|
+
}
|
|
546
|
+
function ut(n) {
|
|
547
|
+
return [...q(n).weightPaths];
|
|
548
|
+
}
|
|
549
|
+
function Pe(n) {
|
|
550
|
+
const e = q(n), { id: t } = e.options, o = [];
|
|
551
|
+
for (const s of e.tallies.values()) {
|
|
552
|
+
const i = s.missing.size;
|
|
553
|
+
if (i === 0)
|
|
554
|
+
continue;
|
|
555
|
+
const c = `${s.target}s`, r = s.sample === void 0 ? "" : JSON.stringify(s.sample);
|
|
556
|
+
if (s.found.size === 0) {
|
|
557
|
+
o.push(
|
|
558
|
+
s.text.size > 0 ? `${t}: no ${s.target} has a number at "${s.path}": its values are text (e.g. ${r}), so every read of it was left out.` : `${t}: no ${s.target} has a number at "${s.path}", so every read of it was left out.`
|
|
559
|
+
);
|
|
560
|
+
continue;
|
|
561
|
+
}
|
|
562
|
+
const a = s.target === "node" ? e.source.snapshot.nodeCount : e.source.snapshot.edgeCount, d = s.text.size, l = d === 0 ? "" : ` (${d} ${d === 1 ? "holds" : "hold"} text, e.g. ${r})`;
|
|
563
|
+
o.push(
|
|
564
|
+
`${t}: ${i} of ${a} ${c} ${i === 1 ? "has" : "have"} no number at "${s.path}"${l}; they were left out.`
|
|
565
|
+
);
|
|
566
|
+
}
|
|
567
|
+
return o;
|
|
568
|
+
}
|
|
569
|
+
const de = Ye.filter((n) => n !== "unknown"), Te = /* @__PURE__ */ new Set(["attribute", "partition"]);
|
|
570
|
+
function Ie(n, e, t) {
|
|
571
|
+
if (t === void 0)
|
|
572
|
+
return [];
|
|
573
|
+
if (typeof t != "object" || t === null || Array.isArray(t))
|
|
574
|
+
throw w(
|
|
575
|
+
n,
|
|
576
|
+
e,
|
|
577
|
+
"options",
|
|
578
|
+
`"options" must be an object such as { spacing: 2 }; got ${v(t)}.`
|
|
579
|
+
);
|
|
580
|
+
return Object.entries(t).map(([o, s]) => lt(n, e, o, s));
|
|
581
|
+
}
|
|
582
|
+
function lt(n, e, t, o) {
|
|
583
|
+
const s = `options.${t}`, i = ke(t);
|
|
584
|
+
if (typeof o == "number") {
|
|
585
|
+
if (!Number.isFinite(o))
|
|
586
|
+
throw w(n, e, s, `"${s}" must be a finite number; got ${v(o)}.`);
|
|
587
|
+
return { name: t, plainName: i, type: "number", default: o };
|
|
588
|
+
}
|
|
589
|
+
if (typeof o == "string")
|
|
590
|
+
return { name: t, plainName: i, type: "string", default: o };
|
|
591
|
+
if (typeof o == "boolean")
|
|
592
|
+
return { name: t, plainName: i, type: "boolean", default: o };
|
|
593
|
+
if (typeof o != "object" || o === null || Array.isArray(o))
|
|
594
|
+
throw w(
|
|
595
|
+
n,
|
|
596
|
+
e,
|
|
597
|
+
s,
|
|
598
|
+
`"${s}" must be a number, a string, a boolean, or an object with a "type" such as { type: "attribute", default: "weight" }; got ${v(o)}.`
|
|
599
|
+
);
|
|
600
|
+
const { type: c, on: r, ...a } = o;
|
|
601
|
+
if (typeof c != "string" || !de.includes(c))
|
|
602
|
+
throw w(
|
|
603
|
+
n,
|
|
604
|
+
e,
|
|
605
|
+
`${s}.type`,
|
|
606
|
+
`"${s}" needs a "type", one of ${de.map((l) => `"${l}"`).join(", ")}; got ${v(c)}.`
|
|
607
|
+
);
|
|
608
|
+
if (r !== void 0) {
|
|
609
|
+
if (!Te.has(c))
|
|
610
|
+
throw w(
|
|
611
|
+
n,
|
|
612
|
+
e,
|
|
613
|
+
`${s}.on`,
|
|
614
|
+
`"${s}" has "on", which only an "attribute" or "partition" option takes.`
|
|
615
|
+
);
|
|
616
|
+
if (r !== "node" && r !== "edge")
|
|
617
|
+
throw w(
|
|
618
|
+
n,
|
|
619
|
+
e,
|
|
620
|
+
`${s}.on`,
|
|
621
|
+
`"${s}.on" must be "node" or "edge"; got ${v(r)}.`
|
|
622
|
+
);
|
|
623
|
+
}
|
|
624
|
+
if (c === "enum" && !Array.isArray(a.values))
|
|
625
|
+
throw w(
|
|
626
|
+
n,
|
|
627
|
+
e,
|
|
628
|
+
`${s}.values`,
|
|
629
|
+
`"${s}" is an "enum" and needs "values", such as [{ value: "a", label: "A" }].`
|
|
630
|
+
);
|
|
631
|
+
const d = { ...a, name: t, plainName: a.plainName ?? i, type: c };
|
|
632
|
+
return r !== void 0 && (d.on = r), d.default === null && delete d.default, d;
|
|
633
|
+
}
|
|
634
|
+
function De(n, e, t, o, s = "run") {
|
|
635
|
+
for (const i of t) {
|
|
636
|
+
const c = o[i.name];
|
|
637
|
+
if (c != null) {
|
|
638
|
+
if (Te.has(i.type) && typeof c == "string") {
|
|
639
|
+
const r = i.on ?? "node";
|
|
640
|
+
ct(
|
|
641
|
+
n,
|
|
642
|
+
r,
|
|
643
|
+
c,
|
|
644
|
+
(a) => a.run === void 0 ? `${e}: option "${i.name}" names ${r} attribute "${c}", which no ${r} carries; ${xe(a)}.` : `${e}: option "${i.name}" reads ${c}, but no completed run is named "${a.run}"; run the algorithm that produces it first, with { as: "${a.run}" }.`
|
|
645
|
+
);
|
|
646
|
+
}
|
|
647
|
+
if (i.type === "node-id" && ue(n, e, i.name, c, s), i.type === "node-set" && Array.isArray(c))
|
|
648
|
+
for (const r of c)
|
|
649
|
+
ue(n, e, i.name, r, s);
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
function ue(n, e, t, o, s) {
|
|
654
|
+
if (n.node(o) === void 0)
|
|
655
|
+
throw new P({
|
|
656
|
+
code: "E_OPTION_RANGE",
|
|
657
|
+
message: `${e}: option "${t}" names node ${D(o)}, which the graph does not have.`,
|
|
658
|
+
source: s,
|
|
659
|
+
details: { extension: e, option: t, node: o }
|
|
660
|
+
});
|
|
661
|
+
}
|
|
662
|
+
const ft = {
|
|
663
|
+
node: /* @__PURE__ */ new Set(["id"]),
|
|
664
|
+
edge: /* @__PURE__ */ new Set(["id", "source", "target"])
|
|
665
|
+
};
|
|
666
|
+
function Le(n) {
|
|
667
|
+
const e = n.data.snapshot(), t = Ee(e), o = qe({
|
|
668
|
+
snapshot: () => e,
|
|
669
|
+
results: (s) => n.results.get(s),
|
|
670
|
+
records: {
|
|
671
|
+
nodeAttributes: (s, i) => n.data.node(i),
|
|
672
|
+
edgeAttributes: (s) => n.data.edge(t.idOf(s))
|
|
673
|
+
}
|
|
674
|
+
});
|
|
675
|
+
return {
|
|
676
|
+
snapshot: e,
|
|
677
|
+
nodeValue: (s, i) => o.nodeValue(s, i),
|
|
678
|
+
edgeValue: (s, i) => o.edgeValue(s, i),
|
|
679
|
+
attributeNames: (s) => n.data.attributes().filter((i) => i.kind === s && !ft[s].has(i.name)).map((i) => i.name)
|
|
680
|
+
};
|
|
681
|
+
}
|
|
682
|
+
const ht = ["node", "edge", "nodes", "groups"], _e = {
|
|
683
|
+
node: "node-metric",
|
|
684
|
+
edge: "edge-metric",
|
|
685
|
+
nodes: "node-metric",
|
|
686
|
+
groups: "community"
|
|
687
|
+
}, le = /* @__PURE__ */ new WeakMap(), fe = 200, he = /* @__PURE__ */ new Set();
|
|
688
|
+
function gt(n) {
|
|
689
|
+
const e = "defineAlgorithm", t = U(e, n), { id: o } = t, s = ht.filter((g) => t[g] !== void 0);
|
|
690
|
+
if (s.length === 0)
|
|
691
|
+
throw w(
|
|
692
|
+
e,
|
|
693
|
+
o,
|
|
694
|
+
"node",
|
|
695
|
+
'a definition needs one function that computes the result: "node", "edge", "nodes" or "groups"; it has none.'
|
|
696
|
+
);
|
|
697
|
+
if (s.length > 1)
|
|
698
|
+
throw w(
|
|
699
|
+
e,
|
|
700
|
+
o,
|
|
701
|
+
s[1],
|
|
702
|
+
`a definition carries exactly one of "node", "edge", "nodes" and "groups"; it has ${s.map((g) => `"${g}"`).join(" and ")}.`
|
|
703
|
+
);
|
|
704
|
+
const i = s[0];
|
|
705
|
+
ne(e, t, i), K(e, t, "direction", ["undirected", "directed"]);
|
|
706
|
+
const c = Ie(e, o, t.options), r = new Map(c.map((g) => [g.name, g])), { passes: a } = t;
|
|
707
|
+
if (a !== void 0 && (typeof a != "string" || r.get(a)?.type !== "integer")) {
|
|
708
|
+
const g = typeof a == "string" ? r.get(a) : void 0;
|
|
709
|
+
let b = ", which is not declared.";
|
|
710
|
+
throw typeof a != "string" ? b = "." : g !== void 0 && (b = `, a "${g.type}" option.`), w(
|
|
711
|
+
e,
|
|
712
|
+
o,
|
|
713
|
+
"passes",
|
|
714
|
+
`"passes" must name a declared "integer" option; got ${v(a)}${b}`
|
|
715
|
+
);
|
|
716
|
+
}
|
|
717
|
+
const d = t.weights;
|
|
718
|
+
if (d !== void 0) {
|
|
719
|
+
const g = typeof d.option == "string" ? r.get(d.option) : void 0;
|
|
720
|
+
if (g?.type !== "attribute" || g.on !== "edge")
|
|
721
|
+
throw w(
|
|
722
|
+
e,
|
|
723
|
+
o,
|
|
724
|
+
"weights.option",
|
|
725
|
+
`"weights.option" must name a declared "attribute" option with on: "edge"; got ${v(d.option)}.`
|
|
726
|
+
);
|
|
727
|
+
if (d.meaning !== "distance" && d.meaning !== "strength")
|
|
728
|
+
throw w(
|
|
729
|
+
e,
|
|
730
|
+
o,
|
|
731
|
+
"weights.meaning",
|
|
732
|
+
`"weights.meaning" must be "distance" or "strength"; got ${v(d.meaning)}.`
|
|
733
|
+
);
|
|
734
|
+
}
|
|
735
|
+
const l = Y(t);
|
|
736
|
+
return {
|
|
737
|
+
id: o,
|
|
738
|
+
name: l,
|
|
739
|
+
description: typeof t.description == "string" ? t.description : "",
|
|
740
|
+
member: i,
|
|
741
|
+
compute: t[i],
|
|
742
|
+
directed: t.direction === "directed",
|
|
743
|
+
options: c,
|
|
744
|
+
...d === void 0 ? {} : { weights: d },
|
|
745
|
+
...a === void 0 ? {} : { passes: a },
|
|
746
|
+
...typeof t.version == "string" ? { version: t.version } : {}
|
|
747
|
+
};
|
|
748
|
+
}
|
|
749
|
+
function pt(n) {
|
|
750
|
+
const e = { plainName: n.name, technicalName: n.name }, t = _e[n.member], o = n.member === "node" || n.member === "edge";
|
|
751
|
+
return {
|
|
752
|
+
key: n.id,
|
|
753
|
+
...e,
|
|
754
|
+
description: n.description,
|
|
755
|
+
category: "custom",
|
|
756
|
+
shape: t,
|
|
757
|
+
fields: t === "community" ? Fe(e) : (t === "edge-metric" ? ze : Re)(e),
|
|
758
|
+
options: n.options,
|
|
759
|
+
costClass: o ? "instant" : "iterative",
|
|
760
|
+
complexity: "O(n + m)"
|
|
761
|
+
};
|
|
762
|
+
}
|
|
763
|
+
function B(n) {
|
|
764
|
+
return typeof n == "number" && Number.isFinite(n);
|
|
765
|
+
}
|
|
766
|
+
function mt(n, e, t, o) {
|
|
767
|
+
const s = `${n.member}()`;
|
|
768
|
+
if (!(t instanceof Map))
|
|
769
|
+
throw G(
|
|
770
|
+
{ id: n.id, member: n.member, source: "run" },
|
|
771
|
+
new TypeError(`${s} must return a Map from node id to value; got ${v(t)}`)
|
|
772
|
+
);
|
|
773
|
+
const i = [...t.entries()], c = i.filter(([a]) => e.node(a) !== void 0), r = i.filter(([a]) => e.node(a) === void 0).map(([a]) => D(a));
|
|
774
|
+
if (i.length > 0 && c.length === 0) {
|
|
775
|
+
const a = typeof e.nodes()[0]?.id == "number" ? "numbers" : "strings";
|
|
776
|
+
throw G(
|
|
777
|
+
{ id: n.id, member: n.member, source: "run" },
|
|
778
|
+
new TypeError(
|
|
779
|
+
`${s} returned ${String(i.length)} values but no key matches a node id (got ${r[0]}; node ids here are ${a})`
|
|
780
|
+
)
|
|
781
|
+
);
|
|
782
|
+
}
|
|
783
|
+
return r.length > 0 && o.push(
|
|
784
|
+
`${n.id}: ${s} returned values for ${String(r.length)} keys that are not nodes (${r.slice(0, 5).join(", ")}); they were left out.`
|
|
785
|
+
), c;
|
|
786
|
+
}
|
|
787
|
+
async function yt(n, e, t, o) {
|
|
788
|
+
if (e.nodeCount === 0)
|
|
789
|
+
return null;
|
|
790
|
+
const { id: s, member: i, name: c } = n;
|
|
791
|
+
De(e, s, n.options, t);
|
|
792
|
+
const r = [];
|
|
793
|
+
let a = 0, d = performance.now(), l, g = performance.now();
|
|
794
|
+
const b = {
|
|
795
|
+
options: t,
|
|
796
|
+
graph: e,
|
|
797
|
+
signal: o.signal,
|
|
798
|
+
async progress(h) {
|
|
799
|
+
a = Math.max(a, performance.now() - d), o.signal.throwIfAborted(), o.report({ phase: c, completed: Number.isFinite(h) ? h : 0, total: 1 }), performance.now() - g >= Be && (await o.yieldNow(), g = performance.now()), o.signal.throwIfAborted(), d = performance.now();
|
|
800
|
+
},
|
|
801
|
+
note(h) {
|
|
802
|
+
r.push(h);
|
|
803
|
+
},
|
|
804
|
+
converged(h, m) {
|
|
805
|
+
l = { converged: h, iterations: m };
|
|
806
|
+
}
|
|
807
|
+
}, N = [], E = [];
|
|
808
|
+
let F = "integer", j = e.nodeCount;
|
|
809
|
+
const f = (h, m) => {
|
|
810
|
+
const y = { id: s, member: i, subject: h, source: "run" }, A = performance.now(), T = Ze(y, () => n.compute(m, b));
|
|
811
|
+
if (a = Math.max(a, performance.now() - A), T instanceof Promise)
|
|
812
|
+
throw T.catch(() => {
|
|
813
|
+
}), new P({
|
|
814
|
+
code: "E_EXTENSION_FAILED",
|
|
815
|
+
message: `${s}: ${i}() returned a Promise for ${h}; it must return the score itself. Remove "async", or write a "nodes" function for work that has to wait.`,
|
|
816
|
+
source: "run",
|
|
817
|
+
details: { extension: s, member: i, subject: h }
|
|
818
|
+
});
|
|
819
|
+
return T;
|
|
820
|
+
};
|
|
821
|
+
if (i === "node")
|
|
822
|
+
await ie(o, c, e.nodes(), (h) => {
|
|
823
|
+
const m = f(`node ${D(h.id)}`, h);
|
|
824
|
+
B(m) && N.push({ id: h.id, values: { value: m } });
|
|
825
|
+
});
|
|
826
|
+
else if (i === "edge")
|
|
827
|
+
j = e.edgeCount, await ie(o, c, e.edges(), (h) => {
|
|
828
|
+
const m = f(`edge ${JSON.stringify(h.id)}`, h);
|
|
829
|
+
B(m) && E.push({ id: h.id, values: { value: m } });
|
|
830
|
+
});
|
|
831
|
+
else {
|
|
832
|
+
let h;
|
|
833
|
+
try {
|
|
834
|
+
d = performance.now();
|
|
835
|
+
const y = n.compute(e, b);
|
|
836
|
+
a = Math.max(a, performance.now() - d), h = await y;
|
|
837
|
+
} catch (y) {
|
|
838
|
+
throw o.signal.aborted || te(y) ? y : G({ id: s, member: i, source: "run" }, y);
|
|
839
|
+
}
|
|
840
|
+
let m = 0;
|
|
841
|
+
for (const [y, A] of mt(n, e, h, r))
|
|
842
|
+
typeof A == "boolean" && m++, i === "nodes" && B(A) ? N.push({ id: y, values: { value: A } }) : i === "groups" && (typeof A == "string" || B(A)) && ((typeof A == "string" || !Number.isInteger(A)) && (F = "string"), N.push({ id: y, values: { group: A } }));
|
|
843
|
+
if (m > 0) {
|
|
844
|
+
const y = i === "groups" ? "a group is a number or a string" : "a score is a number";
|
|
845
|
+
r.push(
|
|
846
|
+
`${s}: ${i}() returned true or false for ${String(m)} ${m === 1 ? "node" : "nodes"}; ${y}, so they were left out.`
|
|
847
|
+
);
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
const k = i === "edge" ? "edge" : "node";
|
|
851
|
+
if (j > 0 && N.length + E.length === 0 && r.push(`${s}: no ${k} was measured -- did the function return NaN or undefined for every ${k}?`), r.push(...Pe(e)), a > fe) {
|
|
852
|
+
const h = i === "node" || i === "edge" ? "each call should take a moment, with the slow work moved to a whole-graph function." : "await context.progress(i / n) inside its loop.", m = `${s}: ${i}() held the page for over ${String(fe)} ms at a time; ${h}`;
|
|
853
|
+
r.push(m), he.has(s) || (he.add(s), console.warn(m));
|
|
854
|
+
}
|
|
855
|
+
const $ = dt(e);
|
|
856
|
+
$.length > 0 && r.push(`${s} read: ${$.map(({ target: h, path: m }) => `${h} ${JSON.stringify(m)}`).join(", ")}.`);
|
|
857
|
+
const [u] = ut(e), p = i === "groups" ? Je(!1).map((h) => h.name === "group" ? { ...h, type: F } : h) : Ve(k);
|
|
858
|
+
return {
|
|
859
|
+
shape: _e[i],
|
|
860
|
+
fields: p,
|
|
861
|
+
...i === "edge" ? { edges: E } : { nodes: N },
|
|
862
|
+
...i === "groups" ? {} : { graph: { normalization: "none" } },
|
|
863
|
+
caveats: Ge({
|
|
864
|
+
method: c,
|
|
865
|
+
direction: e.directed ? "directed" : "undirected",
|
|
866
|
+
weight: u === void 0 ? null : { attribute: u, meaning: n.weights?.meaning ?? "strength" },
|
|
867
|
+
notes: r,
|
|
868
|
+
...l ?? {},
|
|
869
|
+
// Stopping at a cap the caller set publishes what the run has, marked inexact
|
|
870
|
+
// (algorithm.md section 2.2 item 9).
|
|
871
|
+
...l?.converged === !1 ? { exact: !1, partialReason: "iteration cap reached" } : {}
|
|
872
|
+
})
|
|
873
|
+
};
|
|
874
|
+
}
|
|
875
|
+
function wt(n) {
|
|
876
|
+
const { id: e, passes: t } = n, o = n.member === "node" || n.member === "edge", i = class i extends Ne {
|
|
877
|
+
/**
|
|
878
|
+
* Run the definition over the graph as it stands.
|
|
879
|
+
* @param context - What the element gave the run.
|
|
880
|
+
* @returns The output.
|
|
881
|
+
*/
|
|
882
|
+
compute(r) {
|
|
883
|
+
const a = Me(Le(this.graph.getSession()), {
|
|
884
|
+
id: e,
|
|
885
|
+
directed: n.directed
|
|
886
|
+
});
|
|
887
|
+
return yt(n, a, this.schemaOptions, r);
|
|
888
|
+
}
|
|
889
|
+
};
|
|
890
|
+
i.namespace = e, i.type = e, i.descriptor = pt(n), i.parallelEdges = "none", i.version = n.version, i.costUnits = (r, a, d) => {
|
|
891
|
+
if (o)
|
|
892
|
+
return r + 2 * a;
|
|
893
|
+
const l = t === void 0 ? 1 : Number(d[t]);
|
|
894
|
+
return (r + a) * (Number.isFinite(l) && l > 0 ? l : 1);
|
|
895
|
+
};
|
|
896
|
+
let s = i;
|
|
897
|
+
return Object.defineProperty(s, "name", { value: `SimpleAlgorithm(${e})` }), s;
|
|
898
|
+
}
|
|
899
|
+
function Jt(n, e) {
|
|
900
|
+
const t = gt(n), { compute: o, ...s } = t, i = JSON.stringify(s);
|
|
901
|
+
let c = le.get(o);
|
|
902
|
+
c?.signature !== i && (c = { cls: wt(t), signature: i }, le.set(o, c)), Ne.register(c.cls, e);
|
|
903
|
+
}
|
|
904
|
+
const V = "defineLayout", ge = 200, $t = 1, bt = 5, Q = L.getLogger(["graphty", "layout", "simple"]), pe = /* @__PURE__ */ new Set(), me = /* @__PURE__ */ new Map();
|
|
905
|
+
function Z(n, e, t = {}) {
|
|
906
|
+
Q.warn(e, { layout: n, ...t }), (!L.isEnabled() || !L.getSinks().some((o) => o.name === "console")) && console.warn(`[graphty] ${e}`);
|
|
907
|
+
}
|
|
908
|
+
function vt(n) {
|
|
909
|
+
let e = n >>> 0;
|
|
910
|
+
return () => {
|
|
911
|
+
e = e + 1831565813 >>> 0;
|
|
912
|
+
let t = e;
|
|
913
|
+
return t = Math.imul(t ^ t >>> 15, t | 1), t ^= t + Math.imul(t ^ t >>> 7, t | 61), ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
914
|
+
};
|
|
915
|
+
}
|
|
916
|
+
function St() {
|
|
917
|
+
return new Promise((n) => {
|
|
918
|
+
setTimeout(n, 0);
|
|
919
|
+
});
|
|
920
|
+
}
|
|
921
|
+
function H(n, e) {
|
|
922
|
+
return new P({
|
|
923
|
+
code: "E_EXTENSION_FAILED",
|
|
924
|
+
message: e,
|
|
925
|
+
source: "layout",
|
|
926
|
+
details: { extension: n, member: "place" }
|
|
927
|
+
});
|
|
928
|
+
}
|
|
929
|
+
function ye(n) {
|
|
930
|
+
return typeof n == "string" || typeof n == "number" ? D(n) : v(n);
|
|
931
|
+
}
|
|
932
|
+
function Nt(n) {
|
|
933
|
+
const e = new Set(n.nodes().map((t) => typeof t.id));
|
|
934
|
+
return e.size > 1 ? "strings and numbers" : e.has("number") ? "numbers" : "strings";
|
|
935
|
+
}
|
|
936
|
+
function Et(n, e, t, o) {
|
|
937
|
+
if (!(e instanceof Map))
|
|
938
|
+
throw H(
|
|
939
|
+
n,
|
|
940
|
+
`${n}: place() must return a Map from node id to [x, y] or [x, y, z]; got ${v(e)}.`
|
|
941
|
+
);
|
|
942
|
+
const s = {}, i = [];
|
|
943
|
+
let c = 0;
|
|
944
|
+
for (const [r, a] of e) {
|
|
945
|
+
const d = typeof r == "string" || typeof r == "number" ? t.node(r) : void 0;
|
|
946
|
+
if (d === void 0) {
|
|
947
|
+
i.push(r);
|
|
948
|
+
continue;
|
|
949
|
+
}
|
|
950
|
+
if (c++, a == null)
|
|
951
|
+
continue;
|
|
952
|
+
if (!Array.isArray(a) || a.length !== 2 && a.length !== 3 || !a.every((N) => typeof N == "number")) {
|
|
953
|
+
const N = Array.isArray(a) ? `[${a.map(String).join(", ")}]` : v(a);
|
|
954
|
+
throw H(
|
|
955
|
+
n,
|
|
956
|
+
`${n}: place() returned ${N} for node ${D(d.id)}. A position is two or three numbers; leave the node out to leave it unplaced.`
|
|
957
|
+
);
|
|
958
|
+
}
|
|
959
|
+
const [l, g] = a, b = a.length === 3 && !o ? a[2] : 0;
|
|
960
|
+
Number.isFinite(l) && Number.isFinite(g) && Number.isFinite(b) && (s[String(d.id)] = [l, g, b]);
|
|
961
|
+
}
|
|
962
|
+
if (c === 0 && e.size > 0)
|
|
963
|
+
throw H(
|
|
964
|
+
n,
|
|
965
|
+
`${n}: place() returned ${e.size} positions but no key matches a node id (got ${ye(i[0])}; node ids here are ${Nt(t)}). Key the map by node.id.`
|
|
966
|
+
);
|
|
967
|
+
if (i.length > 0) {
|
|
968
|
+
const r = i.slice(0, bt).map(ye);
|
|
969
|
+
Z(
|
|
970
|
+
n,
|
|
971
|
+
`${n}: place() returned positions for ${String(i.length)} keys that are not nodes (${r.join(", ")}); they were left out.`,
|
|
972
|
+
{ count: i.length, keys: r }
|
|
973
|
+
);
|
|
974
|
+
}
|
|
975
|
+
return s;
|
|
976
|
+
}
|
|
977
|
+
function kt(n, e, t) {
|
|
978
|
+
var s, i, c, r, a, d, l, je, ee, Ce, E;
|
|
979
|
+
const { id: o } = n;
|
|
980
|
+
return E = class extends Ke {
|
|
981
|
+
constructor(f = {}) {
|
|
982
|
+
super(f);
|
|
983
|
+
I(this, l);
|
|
984
|
+
/** The resolved option values `place` receives. */
|
|
985
|
+
I(this, s);
|
|
986
|
+
/** The run in progress, aborted when a newer one starts or the engine is disposed. */
|
|
987
|
+
I(this, i, null);
|
|
988
|
+
/** A finished layout waiting for the next `doLayout` to adopt it, and the change count it saw. */
|
|
989
|
+
I(this, c, null);
|
|
990
|
+
/** Bumped by every node or edge change, so a layout computed over an older graph is redone. */
|
|
991
|
+
I(this, r, 0);
|
|
992
|
+
/** The change count the background run in flight saw, or null when none is. */
|
|
993
|
+
I(this, a, null);
|
|
994
|
+
I(this, d, !1);
|
|
995
|
+
this.scalingFactor = 1;
|
|
996
|
+
const k = f;
|
|
997
|
+
O(this, s, Object.fromEntries(
|
|
998
|
+
n.options.map(($) => [$.name, k[$.name] ?? $.default])
|
|
999
|
+
)), n.random && typeof S(this, s).seed != "number" && (S(this, s).seed = Math.floor(Math.random() * 2 ** 32), Q.info(`${o}: drew a layout seed`, { layout: o, seed: S(this, s).seed })), this.config = { ...S(this, s) };
|
|
1000
|
+
}
|
|
1001
|
+
/**
|
|
1002
|
+
* Compute the first layout before the element starts drawing, so a refusal or a throw from
|
|
1003
|
+
* `place` reaches the `setLayout` call that caused it.
|
|
1004
|
+
*/
|
|
1005
|
+
async init() {
|
|
1006
|
+
const f = S(this, r);
|
|
1007
|
+
O(this, c, { positions: await z(this, l, ee).call(this), seen: f });
|
|
1008
|
+
}
|
|
1009
|
+
/** Adopt a finished layout; when the graph has changed since it started, place again. */
|
|
1010
|
+
doLayout() {
|
|
1011
|
+
this.stale = !1;
|
|
1012
|
+
const f = S(this, c);
|
|
1013
|
+
f !== null && (this.positions = f.positions, O(this, c, null), f.seen === S(this, r)) || S(this, a) !== S(this, r) && z(this, l, je).call(this);
|
|
1014
|
+
}
|
|
1015
|
+
addNode(f) {
|
|
1016
|
+
super.addNode(f), R(this, r)._++;
|
|
1017
|
+
}
|
|
1018
|
+
addEdge(...f) {
|
|
1019
|
+
super.addEdge(...f), R(this, r)._++;
|
|
1020
|
+
}
|
|
1021
|
+
removeNode(f) {
|
|
1022
|
+
super.removeNode(f), R(this, r)._++;
|
|
1023
|
+
}
|
|
1024
|
+
removeEdge(...f) {
|
|
1025
|
+
super.removeEdge(...f), R(this, r)._++;
|
|
1026
|
+
}
|
|
1027
|
+
/**
|
|
1028
|
+
* Undo or redo restored an arrangement: drop any placement still being computed or waiting
|
|
1029
|
+
* to be drawn, so it cannot land over the restored one.
|
|
1030
|
+
*/
|
|
1031
|
+
loadArrangement() {
|
|
1032
|
+
S(this, i)?.abort(), O(this, a, null), O(this, c, null), super.loadArrangement();
|
|
1033
|
+
}
|
|
1034
|
+
dispose() {
|
|
1035
|
+
O(this, d, !0), S(this, i)?.abort(), super.dispose();
|
|
1036
|
+
}
|
|
1037
|
+
}, s = new WeakMap(), i = new WeakMap(), c = new WeakMap(), r = new WeakMap(), a = new WeakMap(), d = new WeakMap(), l = new WeakSet(), /** Place again in the background, off this frame, and draw the result when it arrives. */
|
|
1038
|
+
je = function() {
|
|
1039
|
+
const f = S(this, r);
|
|
1040
|
+
O(this, a, f);
|
|
1041
|
+
const k = () => S(this, a) === f && !S(this, d);
|
|
1042
|
+
z(this, l, ee).call(this).then(
|
|
1043
|
+
($) => {
|
|
1044
|
+
if (!k())
|
|
1045
|
+
return;
|
|
1046
|
+
O(this, a, null), O(this, c, { positions: $, seen: f }), this.stale = !0;
|
|
1047
|
+
const u = this._nodes[0]?.parentGraph;
|
|
1048
|
+
u && (u.getLayoutManager().running = !0);
|
|
1049
|
+
},
|
|
1050
|
+
($) => {
|
|
1051
|
+
if (!k())
|
|
1052
|
+
return;
|
|
1053
|
+
O(this, a, null);
|
|
1054
|
+
const u = $ instanceof Error ? $ : new Error(String($));
|
|
1055
|
+
Q.error(`${o}: the layout could not be recomputed`, u, { layout: o });
|
|
1056
|
+
const p = this._nodes[0]?.parentGraph;
|
|
1057
|
+
p?.getEventManager?.()?.emitGraphError(p, u, "layout", { layoutType: o });
|
|
1058
|
+
}
|
|
1059
|
+
);
|
|
1060
|
+
}, ee = async function() {
|
|
1061
|
+
S(this, i)?.abort();
|
|
1062
|
+
const f = new AbortController();
|
|
1063
|
+
O(this, i, f);
|
|
1064
|
+
const k = this._nodes[0]?.parentGraph, $ = k?.getSession?.();
|
|
1065
|
+
if (k === void 0 || $ === void 0)
|
|
1066
|
+
return {};
|
|
1067
|
+
const u = k.getStyles().config.graph.viewMode === "2d", p = Me(Le($), { id: o, directed: !1, source: "layout" });
|
|
1068
|
+
De(p, o, n.options, S(this, s), "layout");
|
|
1069
|
+
const h = new Map(this._nodes.map((x) => [x.id, x]));
|
|
1070
|
+
let m = 0, y = 0;
|
|
1071
|
+
const A = {
|
|
1072
|
+
options: S(this, s),
|
|
1073
|
+
dimensions: u ? 2 : 3,
|
|
1074
|
+
fixed: (x) => z(this, l, Ce).call(this, h.get(x), u),
|
|
1075
|
+
random: vt(n.random ? S(this, s).seed : $t),
|
|
1076
|
+
signal: f.signal,
|
|
1077
|
+
progress: async () => {
|
|
1078
|
+
y = Math.max(y, performance.now() - m), f.signal.throwIfAborted(), await St(), f.signal.throwIfAborted(), m = performance.now();
|
|
1079
|
+
}
|
|
1080
|
+
};
|
|
1081
|
+
f.signal.throwIfAborted();
|
|
1082
|
+
const T = await et({ id: o, member: "place", source: "layout" }, () => {
|
|
1083
|
+
m = performance.now();
|
|
1084
|
+
const x = n.place(p, A);
|
|
1085
|
+
return y = Math.max(y, performance.now() - m), x;
|
|
1086
|
+
});
|
|
1087
|
+
if (f.signal.throwIfAborted(), y > ge && !pe.has(o)) {
|
|
1088
|
+
pe.add(o);
|
|
1089
|
+
const x = `${o}: place() held the page for over ${ge} ms at a time; await context.progress(i / n) inside its loop.`;
|
|
1090
|
+
Z(o, x);
|
|
1091
|
+
}
|
|
1092
|
+
for (const x of Pe(p))
|
|
1093
|
+
Z(o, x);
|
|
1094
|
+
return Et(o, T, p, u);
|
|
1095
|
+
}, /**
|
|
1096
|
+
* Where a pinned or held node is.
|
|
1097
|
+
* @param node - The node, when the graph has it.
|
|
1098
|
+
* @param twoD - Whether the view is 2D.
|
|
1099
|
+
* @returns Its position, or null for a node the layout may place.
|
|
1100
|
+
*/
|
|
1101
|
+
Ce = function(f, k) {
|
|
1102
|
+
if (f === void 0 || !(f.isPinned() || this.isHeld(f.index)))
|
|
1103
|
+
return null;
|
|
1104
|
+
const $ = { x: 0, y: 0, z: 0 };
|
|
1105
|
+
return this.readNodePosition(f, $) ? k ? [$.x, $.y] : [$.x, $.y, $.z] : null;
|
|
1106
|
+
}, E.type = o, E.maxDimensions = t, E.scoped = !0, E.descriptor = e, E;
|
|
1107
|
+
}
|
|
1108
|
+
function At(n) {
|
|
1109
|
+
const e = new Set(n.map((o) => o.type)), t = [];
|
|
1110
|
+
return (e.has("node-id") || e.has("node-set")) && t.push("node"), e.has("partition") && t.push("partition"), e.has("ordering") && t.push("ordering"), t;
|
|
1111
|
+
}
|
|
1112
|
+
function Vt(n, e) {
|
|
1113
|
+
const t = U(V, n), { id: o } = t;
|
|
1114
|
+
ne(V, t, "place"), K(V, t, "dimensions", [2, 3]), K(V, t, "random", [!0, !1]);
|
|
1115
|
+
const s = Ie(V, o, t.options), i = t.random === !0;
|
|
1116
|
+
i && !s.some((N) => N.name === "seed") && s.push({ name: "seed", plainName: "Seed", type: "seed" });
|
|
1117
|
+
const c = t.dimensions === 2 ? 2 : 3, r = Y(t), a = typeof t.description == "string" ? t.description : "", d = JSON.stringify([r, a, c, i, s]), l = me.get(o);
|
|
1118
|
+
if (l !== void 0 && l.place === t.place && l.signature === d && re.getClass(o) === l.engine)
|
|
1119
|
+
return;
|
|
1120
|
+
const g = {
|
|
1121
|
+
id: o,
|
|
1122
|
+
plainName: r,
|
|
1123
|
+
technicalName: r,
|
|
1124
|
+
description: a,
|
|
1125
|
+
family: "custom",
|
|
1126
|
+
kind: "batch",
|
|
1127
|
+
maxDimensions: c,
|
|
1128
|
+
sizeRating: "any",
|
|
1129
|
+
structuralInputs: At(s),
|
|
1130
|
+
options: s,
|
|
1131
|
+
engine: o
|
|
1132
|
+
}, b = kt(
|
|
1133
|
+
{ id: o, options: s, random: i, place: t.place },
|
|
1134
|
+
g,
|
|
1135
|
+
c
|
|
1136
|
+
);
|
|
1137
|
+
re.register(b, e), me.set(o, { place: t.place, signature: d, engine: b });
|
|
1138
|
+
}
|
|
1139
|
+
const oe = ["error", "warn", "info", "debug", "trace"], Ot = 1e3, we = [1e3, 2e3, 4e3], xt = 5e3, $e = /* @__PURE__ */ new WeakMap();
|
|
1140
|
+
let be = !1;
|
|
1141
|
+
function Mt(n) {
|
|
1142
|
+
const { error: e } = n;
|
|
1143
|
+
return Object.freeze({
|
|
1144
|
+
time: n.timestamp,
|
|
1145
|
+
level: oe[n.level - 1] ?? "error",
|
|
1146
|
+
category: n.category.join("."),
|
|
1147
|
+
message: n.message,
|
|
1148
|
+
...n.data === void 0 ? {} : { data: n.data },
|
|
1149
|
+
...e === void 0 ? {} : {
|
|
1150
|
+
error: Object.freeze({
|
|
1151
|
+
name: e.name,
|
|
1152
|
+
message: e.message,
|
|
1153
|
+
...e.stack === void 0 ? {} : { stack: e.stack }
|
|
1154
|
+
})
|
|
1155
|
+
}
|
|
1156
|
+
});
|
|
1157
|
+
}
|
|
1158
|
+
async function Pt(n) {
|
|
1159
|
+
try {
|
|
1160
|
+
const e = await n;
|
|
1161
|
+
if (typeof e == "object" && e !== null && "ok" in e && "status" in e && e.ok === !1) {
|
|
1162
|
+
const t = Number(e.status);
|
|
1163
|
+
return { ok: !1, retry: !(t >= 400 && t < 500 && t !== 408 && t !== 429), cause: `HTTP ${String(t)}` };
|
|
1164
|
+
}
|
|
1165
|
+
return { ok: !0 };
|
|
1166
|
+
} catch (e) {
|
|
1167
|
+
return { ok: !1, retry: !0, cause: e };
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
function Tt(n, e) {
|
|
1171
|
+
const { write: t } = e, o = [];
|
|
1172
|
+
let s = 0, i = !1, c;
|
|
1173
|
+
const r = async (d, l) => {
|
|
1174
|
+
let g = l ?? Promise.resolve().then(() => t(d));
|
|
1175
|
+
for (let b = 0; ; b++) {
|
|
1176
|
+
const N = await Pt(g);
|
|
1177
|
+
if (N.ok)
|
|
1178
|
+
return;
|
|
1179
|
+
if (!N.retry || b === we.length || i) {
|
|
1180
|
+
console.error(
|
|
1181
|
+
`[GraphtyLogger] Log destination "${n}" could not send a record after ${String(b + 1)} attempt(s):`,
|
|
1182
|
+
N.cause
|
|
1183
|
+
);
|
|
1184
|
+
return;
|
|
1185
|
+
}
|
|
1186
|
+
await new Promise((E) => setTimeout(E, we[b])), g = Promise.resolve().then(() => t(d));
|
|
1187
|
+
}
|
|
1188
|
+
}, a = async (d, l) => {
|
|
1189
|
+
for (await r(d, l); !i && (o.length > 0 || s > 0); ) {
|
|
1190
|
+
if (s > 0) {
|
|
1191
|
+
const b = s;
|
|
1192
|
+
s = 0, await r(
|
|
1193
|
+
Object.freeze({
|
|
1194
|
+
time: /* @__PURE__ */ new Date(),
|
|
1195
|
+
level: "warn",
|
|
1196
|
+
category: "graphty.logging",
|
|
1197
|
+
message: `${String(b)} log records were dropped because "${n}" could not send them as fast as they were made.`
|
|
1198
|
+
})
|
|
1199
|
+
);
|
|
1200
|
+
}
|
|
1201
|
+
const g = o.shift();
|
|
1202
|
+
g !== void 0 && await r(g);
|
|
1203
|
+
}
|
|
1204
|
+
c = void 0;
|
|
1205
|
+
};
|
|
1206
|
+
return {
|
|
1207
|
+
name: n,
|
|
1208
|
+
level: oe.indexOf(e.level ?? "warn") + 1,
|
|
1209
|
+
...e.categories === void 0 ? {} : { categories: [...e.categories] },
|
|
1210
|
+
write(d) {
|
|
1211
|
+
if (i)
|
|
1212
|
+
return;
|
|
1213
|
+
const l = Mt(d);
|
|
1214
|
+
if (c !== void 0) {
|
|
1215
|
+
o.push(l), o.length > Ot && (o.shift(), s += 1);
|
|
1216
|
+
return;
|
|
1217
|
+
}
|
|
1218
|
+
const g = t(l);
|
|
1219
|
+
(g instanceof Promise || typeof g == "object" && g !== null && "then" in g) && (c = a(l, g));
|
|
1220
|
+
},
|
|
1221
|
+
flush: () => c ?? Promise.resolve(),
|
|
1222
|
+
async dispose() {
|
|
1223
|
+
if (c !== void 0) {
|
|
1224
|
+
let d;
|
|
1225
|
+
await Promise.race([c, new Promise((l) => d = setTimeout(l, xt))]), clearTimeout(d);
|
|
1226
|
+
}
|
|
1227
|
+
i = !0, o.length = 0;
|
|
1228
|
+
}
|
|
1229
|
+
};
|
|
1230
|
+
}
|
|
1231
|
+
function It(n) {
|
|
1232
|
+
const e = U("defineLogDestination", n);
|
|
1233
|
+
ne("defineLogDestination", e, "write");
|
|
1234
|
+
const { level: t, categories: o } = e;
|
|
1235
|
+
if (t !== void 0 && !oe.includes(t))
|
|
1236
|
+
throw w(
|
|
1237
|
+
"defineLogDestination",
|
|
1238
|
+
e.id,
|
|
1239
|
+
"level",
|
|
1240
|
+
`"level" must be one of "error", "warn", "info", "debug" or "trace"; got ${v(t)}.`
|
|
1241
|
+
);
|
|
1242
|
+
if (o !== void 0 && !(Array.isArray(o) && o.every((s) => typeof s == "string" && s !== "")))
|
|
1243
|
+
throw w(
|
|
1244
|
+
"defineLogDestination",
|
|
1245
|
+
e.id,
|
|
1246
|
+
"categories",
|
|
1247
|
+
`"categories" must be a list of words such as ["layout"]; got ${v(o)}.`
|
|
1248
|
+
);
|
|
1249
|
+
return K("defineLogDestination", e, "attach", [!0, !1]), e;
|
|
1250
|
+
}
|
|
1251
|
+
function Gt(n, e) {
|
|
1252
|
+
const t = It(n), { id: o } = t, s = $e.get(n) ?? {
|
|
1253
|
+
descriptor: {
|
|
1254
|
+
id: o,
|
|
1255
|
+
plainName: Y(t),
|
|
1256
|
+
description: typeof t.description == "string" ? t.description : "",
|
|
1257
|
+
options: []
|
|
1258
|
+
},
|
|
1259
|
+
create: () => Tt(o, t)
|
|
1260
|
+
};
|
|
1261
|
+
Ue(s, e), $e.set(n, s), !be && typeof window < "u" && (be = !0, window.addEventListener("pagehide", () => {
|
|
1262
|
+
L.flush();
|
|
1263
|
+
}));
|
|
1264
|
+
const i = t.attach === !1 ? void 0 : s.create({});
|
|
1265
|
+
return i !== void 0 && L.addSink(i), () => {
|
|
1266
|
+
i !== void 0 && L.getSinks().includes(i) && L.removeSink(o);
|
|
1267
|
+
};
|
|
1268
|
+
}
|
|
1269
|
+
const Dt = ["sequential", "diverging", "categorical"], ve = 'Read the token first with getComputedStyle(document.documentElement).getPropertyValue("--brand-navy").trim(), after the stylesheet that defines it has loaded, and pass the colour that returns.';
|
|
1270
|
+
function Bt(n, e) {
|
|
1271
|
+
const t = U("definePalette", n), { id: o } = t;
|
|
1272
|
+
if (!Dt.includes(t.kind))
|
|
1273
|
+
throw w(
|
|
1274
|
+
"definePalette",
|
|
1275
|
+
o,
|
|
1276
|
+
"kind",
|
|
1277
|
+
`"kind" must be "categorical", "sequential" or "diverging"; got ${v(t.kind)}.`
|
|
1278
|
+
);
|
|
1279
|
+
const { colors: s } = t;
|
|
1280
|
+
if (!Array.isArray(s) || s.length === 0)
|
|
1281
|
+
throw w(
|
|
1282
|
+
"definePalette",
|
|
1283
|
+
o,
|
|
1284
|
+
"colors",
|
|
1285
|
+
`"colors" must be a non-empty list of colours such as ["#0B1D51", "#1B7F79"]; got ${v(s)}.`
|
|
1286
|
+
);
|
|
1287
|
+
for (const r of s) {
|
|
1288
|
+
if (typeof r == "string" && r.trim() === "")
|
|
1289
|
+
throw w(
|
|
1290
|
+
"definePalette",
|
|
1291
|
+
o,
|
|
1292
|
+
"colors",
|
|
1293
|
+
`a colour is an empty string, which is what a design token reads as before its stylesheet has loaded. ${ve}`
|
|
1294
|
+
);
|
|
1295
|
+
if (typeof r == "string" && /var\s*\(/i.test(r))
|
|
1296
|
+
throw w(
|
|
1297
|
+
"definePalette",
|
|
1298
|
+
o,
|
|
1299
|
+
"colors",
|
|
1300
|
+
`${JSON.stringify(r)} is a CSS variable, which a palette cannot hold. ${ve}`
|
|
1301
|
+
);
|
|
1302
|
+
if (typeof r != "string" || We(r) === null)
|
|
1303
|
+
throw w(
|
|
1304
|
+
"definePalette",
|
|
1305
|
+
o,
|
|
1306
|
+
"colors",
|
|
1307
|
+
`${typeof r == "string" ? JSON.stringify(r) : v(r)} is not a colour. Write any CSS colour: "#0B1D51", "rgb(27, 127, 121)", "oklch(0.7 0.15 30)" or a colour name.`
|
|
1308
|
+
);
|
|
1309
|
+
}
|
|
1310
|
+
const i = t.colorblindSafe ?? [];
|
|
1311
|
+
if (!Array.isArray(i) || i.some((r) => !["deuteranopia", "protanopia", "tritanopia"].includes(r)))
|
|
1312
|
+
throw w(
|
|
1313
|
+
"definePalette",
|
|
1314
|
+
o,
|
|
1315
|
+
"colorblindSafe",
|
|
1316
|
+
`"colorblindSafe" lists "deuteranopia", "protanopia" or "tritanopia"; got ${v(i)}.`
|
|
1317
|
+
);
|
|
1318
|
+
const c = {
|
|
1319
|
+
id: o,
|
|
1320
|
+
plainName: Y(t),
|
|
1321
|
+
kind: t.kind,
|
|
1322
|
+
colors: s,
|
|
1323
|
+
...t.colorblindSafe === void 0 ? {} : { colorblindSafe: t.colorblindSafe }
|
|
1324
|
+
};
|
|
1325
|
+
He(c, e);
|
|
1326
|
+
}
|
|
1327
|
+
export {
|
|
1328
|
+
Vt as a,
|
|
1329
|
+
Gt as b,
|
|
1330
|
+
tt as c,
|
|
1331
|
+
Jt as d,
|
|
1332
|
+
Bt as e
|
|
1333
|
+
};
|