@draftably/runtime 0.3.0 → 0.5.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 (38) hide show
  1. package/README.md +2 -1
  2. package/dist/assets/render.worker-D11vTqoO.js +8548 -0
  3. package/dist/compile-BAIrdu-8.js +7405 -0
  4. package/dist/element.js +275 -125
  5. package/dist/{font-data-DLXJur0j.js → font-data-DME3E71S.js} +1 -1
  6. package/dist/geometry-DfUVE8b2.js +79 -0
  7. package/dist/graph.js +336 -373
  8. package/dist/host.css +37 -0
  9. package/dist/host.js +24 -0
  10. package/dist/index.js +3 -3
  11. package/dist/render-CsJYFD3o.js +1188 -0
  12. package/dist/types/src/dsl/cells.d.ts +1 -0
  13. package/dist/types/src/dsl/compile.d.ts +2 -1
  14. package/dist/types/src/dsl/legend-notes.d.ts +14 -0
  15. package/dist/types/src/dsl/syntax.d.ts +2 -0
  16. package/dist/types/src/model/appearance.d.ts +27 -1
  17. package/dist/types/src/model/colors.d.ts +10 -2
  18. package/dist/types/src/model/labels.d.ts +22 -6
  19. package/dist/types/src/runtime/anchors.d.ts +46 -0
  20. package/dist/types/src/runtime/camera.d.ts +41 -0
  21. package/dist/types/src/runtime/color-scheme.d.ts +15 -0
  22. package/dist/types/src/runtime/element-base.d.ts +40 -0
  23. package/dist/types/src/runtime/element.d.ts +7 -0
  24. package/dist/types/src/runtime/geometry.d.ts +72 -0
  25. package/dist/types/src/runtime/host.d.ts +78 -0
  26. package/dist/types/src/runtime/index.d.ts +1 -0
  27. package/dist/types/src/runtime/page-shared.d.ts +24 -0
  28. package/dist/types/src/runtime/schemes.d.ts +2 -0
  29. package/dist/types/src/runtime/svg-renderer.d.ts +12 -0
  30. package/dist/types/src/runtime/types.d.ts +13 -0
  31. package/dist/types/src/runtime/viewer.d.ts +41 -7
  32. package/dist/version-CO7i33cq.js +4 -0
  33. package/dist/viewer.css +72 -9
  34. package/dist/viewer.js +713 -346
  35. package/package.json +6 -1
  36. package/dist/assets/render.worker-dvseyGmC.js +0 -8310
  37. package/dist/compile-Csfz4rk4.js +0 -7267
  38. package/dist/render-Dgo42PR4.js +0 -1146
package/dist/viewer.js CHANGED
@@ -1,440 +1,807 @@
1
- import { r as ce } from "./render-Dgo42PR4.js";
2
- import { a as ke } from "./render-Dgo42PR4.js";
3
- import { F as ee } from "./compile-Csfz4rk4.js";
4
- import { h as Ae } from "./compile-Csfz4rk4.js";
5
- const de = "http://www.w3.org/2000/svg", le = new Set(
1
+ import { i as Ne, F as Oe } from "./geometry-DfUVE8b2.js";
2
+ import { f as kt } from "./geometry-DfUVE8b2.js";
3
+ import { r as St } from "./version-CO7i33cq.js";
4
+ const $e = 0.02, ze = 8, He = 32, ye = (n, t = $e, i = ze) => Math.min(Math.max(n, Math.max($e, t)), Math.min(ze, i));
5
+ function Re(n = {}) {
6
+ const t = n.padding ?? He;
7
+ return typeof t == "number" ? { top: t, right: t, bottom: t, left: t } : t;
8
+ }
9
+ function Ge(n) {
10
+ if (!n.length) return;
11
+ const t = Math.min(...n.map((d) => d.x)), i = Math.min(...n.map((d) => d.y)), r = Math.max(...n.map((d) => d.x + d.width)), c = Math.max(...n.map((d) => d.y + d.height));
12
+ return { x: t, y: i, width: r - t, height: c - i };
13
+ }
14
+ function Ie(n, t, i = {}) {
15
+ const r = Re(i), c = Math.max(1, t.width - r.left - r.right), d = Math.max(1, t.height - r.top - r.bottom), m = ye(
16
+ Math.min(c / Math.max(1, n.width), d / Math.max(1, n.height)),
17
+ i.minZoom,
18
+ i.maxZoom ?? 1
19
+ );
20
+ return {
21
+ centerX: n.x + n.width / 2 - (r.left - r.right) / 2 / m,
22
+ centerY: n.y + n.height / 2 - (r.top - r.bottom) / 2 / m,
23
+ zoom: m
24
+ };
25
+ }
26
+ function Ue(n, t, i, r = {}) {
27
+ const c = Re(r), d = { width: i.width - c.left - c.right, height: i.height - c.top - c.bottom };
28
+ let { centerX: m, centerY: s, zoom: f } = n;
29
+ if (t.width * f > d.width || t.height * f > d.height)
30
+ return Ie(t, i, { ...r, maxZoom: f });
31
+ f = ye(f, r.minZoom, r.maxZoom);
32
+ const g = (t.x - m) * f + i.width / 2, x = (t.y - s) * f + i.height / 2;
33
+ return g < c.left ? m -= (c.left - g) / f : g + t.width * f > i.width - c.right && (m += (g + t.width * f - (i.width - c.right)) / f), x < c.top ? s -= (c.top - x) / f : x + t.height * f > i.height - c.bottom && (s += (x + t.height * f - (i.height - c.bottom)) / f), { centerX: m, centerY: s, zoom: f };
34
+ }
35
+ const Ke = (n, t) => Math.abs(n.centerX - t.centerX) < 0.01 && Math.abs(n.centerY - t.centerY) < 0.01 && Math.abs(n.zoom - t.zoom) < 1e-6, Je = 0.4, Qe = (n, t) => n.nodes[t] ? "node" : n.groups[t] ? "group" : n.edges[t] ? "edge" : void 0, Te = (n, t, i) => ({
36
+ code: n,
37
+ severity: "warning",
38
+ message: t,
39
+ itemIds: [i]
40
+ });
41
+ function et(n, t = {}) {
42
+ const i = n.createElement("div"), r = n.createElement("div"), c = n.createElement("div");
43
+ i.className = "draft-anchors", r.className = "draft-anchors__bodies", c.className = "draft-anchors__overlays", i.append(r, c), i.dataset.draftDetail = "full";
44
+ const d = /* @__PURE__ */ new Map();
45
+ let m = [], s = null, f = !1, g = [], x = 1;
46
+ const p = /* @__PURE__ */ new Set(), b = n.defaultView, P = () => {
47
+ let l = !1;
48
+ for (const [h, w] of d) {
49
+ if (!w.body) continue;
50
+ const M = (E.get(w) ?? []).some(
51
+ (_) => _.offsetWidth > w.box.width + 0.5 || _.offsetHeight > w.box.height + 0.5
52
+ );
53
+ M !== p.has(h) && (l = !0, M ? p.add(h) : p.delete(h));
54
+ }
55
+ l && t.onOverflow?.();
56
+ }, L = b?.ResizeObserver ? new b.ResizeObserver(P) : void 0, E = /* @__PURE__ */ new Map(), re = (l) => {
57
+ if (!L || !l.body) return;
58
+ for (const w of E.get(l) ?? []) L.unobserve(w);
59
+ const h = U(l.el);
60
+ E.set(l, h);
61
+ for (const w of h) L.observe(w);
62
+ }, k = (l) => {
63
+ for (const h of E.get(l) ?? []) L?.unobserve(h);
64
+ E.delete(l);
65
+ }, Y = (l) => {
66
+ const h = l.closest?.("[data-draft-anchor]")?.getAttribute("data-draft-anchor");
67
+ return h ? d.get(h) : void 0;
68
+ };
69
+ i.addEventListener("slotchange", (l) => {
70
+ const h = Y(l.target);
71
+ h && re(h);
72
+ });
73
+ const W = b?.MutationObserver ? new b.MutationObserver((l) => {
74
+ const h = /* @__PURE__ */ new Set();
75
+ for (const w of l) {
76
+ const M = w.target.dataset?.draftAnchor ? Y(w.target) : void 0;
77
+ M && !h.has(M) && (h.add(M), re(M));
78
+ }
79
+ }) : void 0;
80
+ W?.observe(r, { childList: !0, subtree: !0 });
81
+ let G = !1;
82
+ const J = () => G = !0, F = () => G = !1;
83
+ i.addEventListener("pointerdown", J, !0), n.addEventListener("pointerup", F, !0), n.addEventListener("pointercancel", F, !0);
84
+ function U(l) {
85
+ const h = l.firstElementChild;
86
+ return h instanceof HTMLSlotElement ? h.assignedElements().filter((w) => w instanceof HTMLElement) : [...l.children].filter((w) => w instanceof HTMLElement);
87
+ }
88
+ function ne() {
89
+ let l = n.activeElement;
90
+ for (; l?.shadowRoot?.activeElement; ) l = l.shadowRoot.activeElement;
91
+ return l;
92
+ }
93
+ function se() {
94
+ let l = !1, h = !1;
95
+ const w = /* @__PURE__ */ new Set();
96
+ g = [];
97
+ let M;
98
+ const _ = (S) => {
99
+ M ??= new Map(
100
+ [s.nodes, s.groups, s.edges].flatMap(Object.keys).map((R, N) => [R, N])
101
+ );
102
+ const z = S.dataset.draftAnchor;
103
+ return M.get(z.slice(z.indexOf(":") + 1)) ?? 1 / 0;
104
+ };
105
+ for (const S of m) {
106
+ const z = S.indexOf(":"), R = S.slice(0, z), N = S.slice(z + 1), B = s ? Qe(s, N) : void 0;
107
+ if (!s || !B || R !== "body" && R !== "overlay" || R === "body" && B !== "node" || w.has(S)) {
108
+ f && !w.has(S) && g.push(S);
109
+ continue;
110
+ }
111
+ w.add(S);
112
+ const D = Ne(s, N);
113
+ let $ = d.get(S);
114
+ if (!$ || $.kind !== B) {
115
+ $ && ($.el.remove(), k($));
116
+ const I = n.createElement("div");
117
+ I.className = `draft-anchor draft-anchor--${R}`, I.dataset.draftAnchor = S, $ = { el: I, id: N, kind: B, body: R === "body", box: D }, d.set(S, $);
118
+ const Q = $.body ? r : c, Z = Q.children, ue = _(I);
119
+ let ee = 0, H = Z.length;
120
+ for (; ee < H; ) {
121
+ const ie = ee + H >> 1;
122
+ _(Z[ie]) > ue ? H = ie : ee = ie + 1;
123
+ }
124
+ Q.insertBefore(I, Z[ee] ?? null), re($), l = !0;
125
+ } else $.body && ($.box.width !== D.width || $.box.height !== D.height) && (h = !0);
126
+ if ($.box = D, $.body) {
127
+ const I = $.el.style;
128
+ I.left = `${D.x}px`, I.top = `${D.y}px`, I.width = `${D.width}px`, I.height = `${D.height}px`;
129
+ }
130
+ }
131
+ for (const [S, z] of d) {
132
+ if (w.has(S)) continue;
133
+ const R = ne(), N = !!R && (z.el.contains(R) || U(z.el).some((B) => B.contains(R)));
134
+ z.el.remove(), k(z), d.delete(S), p.delete(S), l = !0, N && i.dispatchEvent(new CustomEvent("draft-anchor-focus-lost"));
135
+ }
136
+ return h && L && P(), l;
137
+ }
138
+ return {
139
+ el: i,
140
+ setSlots(l) {
141
+ return m = [...new Set(l)], se();
142
+ },
143
+ hasSlots: () => m.length > 0,
144
+ setGeometry(l) {
145
+ return s = l, f = !0, se();
146
+ },
147
+ place(l, h, w) {
148
+ if (!m.length) return;
149
+ (w !== x || !i.style.getPropertyValue("--draft-zoom")) && i.style.setProperty("--draft-zoom", String(w)), x = w, r.style.transform = `translate(${l}px, ${h}px) scale(${w})`;
150
+ for (const _ of d.values()) {
151
+ if (_.body) continue;
152
+ const S = _.el.style;
153
+ S.transform = `translate(${l + _.box.x * w}px, ${h + _.box.y * w}px)`, S.width = `${_.box.width * w}px`, S.height = `${_.box.height * w}px`;
154
+ }
155
+ const M = t.detail !== "full" && w < Je;
156
+ i.dataset.draftDetail === "low" !== M && (i.dataset.draftDetail = M ? "low" : "full", r.inert = M);
157
+ },
158
+ anchors: () => [...d].map(([l, h]) => ({
159
+ slot: l,
160
+ id: h.id,
161
+ kind: h.kind,
162
+ el: h.el
163
+ })),
164
+ // Every anchored body, at any zoom: CSS shows titles again below LOW_DETAIL_ZOOM.
165
+ bodyIds: () => [...d.values()].filter((l) => l.body).map((l) => l.id),
166
+ warnings: () => [
167
+ ...g.map(
168
+ (l) => Te(
169
+ "DRAFT_SLOT_UNKNOWN",
170
+ /^(?:body|overlay):/.test(l) ? s ? `Slot ${l} names no item that can hold it. A body fills a node; an overlay covers a node, group or edge.` : `Slot ${l} shows nothing: this drawing repeats items (compare or states), so slots are off.` : `Slot ${l} shows nothing: a slot name starts with body: or overlay:, such as body:api.`,
171
+ l.slice(l.indexOf(":") + 1)
172
+ )
173
+ ),
174
+ ...[...p].map(
175
+ (l) => Te(
176
+ "DRAFT_SLOT_OVERFLOW",
177
+ `The content of ${l} is larger than its node. Declare the room with size … min-height=.`,
178
+ l.slice(l.indexOf(":") + 1)
179
+ )
180
+ )
181
+ ],
182
+ pressed: () => G,
183
+ idOf(l) {
184
+ for (const h of d.values())
185
+ if (h.el.contains(l) || U(h.el).some((w) => w.contains(l))) return h.id;
186
+ },
187
+ destroy() {
188
+ L?.disconnect(), W?.disconnect(), n.removeEventListener("pointerup", F, !0), n.removeEventListener("pointercancel", F, !0), E.clear(), d.clear(), i.remove();
189
+ }
190
+ };
191
+ }
192
+ const tt = /\bdark\b/, rt = /\blight\b/;
193
+ function nt(n, t) {
194
+ const i = n.ownerDocument, r = i.defaultView, c = r?.matchMedia?.("(prefers-color-scheme: dark)"), d = i.createElement("span");
195
+ d.setAttribute("aria-hidden", "true"), d.setAttribute("data-draft-probe", ""), d.style.cssText = "position:absolute;width:0;height:0;overflow:hidden;pointer-events:none;color:light-dark(rgb(0,0,0),rgb(255,255,255));transition:color 1ms !important", n.append(d);
196
+ let m;
197
+ const s = () => {
198
+ const p = r?.getComputedStyle(d).colorScheme ?? "", b = tt.test(p) && (!rt.test(p) || !!c?.matches);
199
+ b !== m && (m = b, t(b));
200
+ }, f = (p) => {
201
+ p.stopPropagation(), s();
202
+ };
203
+ d.addEventListener("transitionrun", f), c?.addEventListener?.("change", s);
204
+ const g = n.nodeType === 11 ? n.host : n, x = r && "ResizeObserver" in r ? new r.ResizeObserver(s) : void 0;
205
+ return x?.observe(g), s(), {
206
+ check: s,
207
+ stop() {
208
+ x?.disconnect(), c?.removeEventListener?.("change", s), d.removeEventListener("transitionrun", f), d.remove();
209
+ }
210
+ };
211
+ }
212
+ const De = Math.max(
213
+ 1,
214
+ Math.min(4, (globalThis.navigator?.hardwareConcurrency || 2) - 1)
215
+ ), ot = 3e4, Fe = /* @__PURE__ */ new Map();
216
+ let st = 0;
217
+ const _e = "The worker is the module next to @draftably/runtime's viewer. With Vite 5–7, add optimizeDeps: { exclude: ['@draftably/runtime', '@draftably/editor'] } to vite.config.", it = () => new Worker(new URL("./assets/render.worker-D11vTqoO.js", import.meta.url), { type: "module" });
218
+ function le(n, t, i) {
219
+ n.slots.splice(n.slots.indexOf(t), 1), clearTimeout(t.timer), clearTimeout(t.idle), t.worker.terminate();
220
+ const r = t.job;
221
+ t.job = void 0, r && i && r.reject(i);
222
+ }
223
+ function at(n, t) {
224
+ let i;
225
+ try {
226
+ i = (n ?? it)();
227
+ } catch (c) {
228
+ throw new Error(
229
+ `Viewer render worker could not start${c instanceof Error ? `: ${c.message}` : ""}. ${_e}`,
230
+ { cause: c }
231
+ );
232
+ }
233
+ const r = { worker: i };
234
+ return t.slots.push(r), i.addEventListener("message", (c) => {
235
+ const d = r.job;
236
+ !d || c.data?.id !== d.id || (clearTimeout(r.timer), r.job = void 0, d.resolve(c.data.result), r.idle = setTimeout(() => le(t, r), ot), ae(n, t));
237
+ }), i.addEventListener("error", (c) => {
238
+ c.preventDefault(), le(
239
+ t,
240
+ r,
241
+ new Error(`${c.message || "Viewer render worker failed."} ${_e}`)
242
+ ), ae(n, t);
243
+ }), i.addEventListener("messageerror", () => {
244
+ le(t, r, new Error("Viewer render worker returned an unreadable result.")), ae(n, t);
245
+ }), r;
246
+ }
247
+ function ae(n, t) {
248
+ for (; t.queue.length; ) {
249
+ const i = t.queue[0].options.idPrefix;
250
+ let r = t.slots.find((m) => !m.job && m.last === i);
251
+ if (!r && t.slots.length >= De && (r = t.slots.find((m) => !m.job)), !r && t.slots.length < De)
252
+ try {
253
+ r = at(n, t);
254
+ } catch (m) {
255
+ for (const s of t.queue.splice(0)) s.reject(m);
256
+ return;
257
+ }
258
+ if (!r) return;
259
+ const c = t.queue.shift();
260
+ clearTimeout(r.idle), r.job = c, r.last = i;
261
+ const d = r;
262
+ r.timer = setTimeout(() => {
263
+ le(t, d, new Error("Viewer render worker timed out.")), ae(n, t);
264
+ }, c.timeoutMs), r.worker.postMessage({ id: c.id, source: c.source, options: c.options });
265
+ }
266
+ }
267
+ function ct(n, t, {
268
+ create: i,
269
+ timeoutMs: r = 5e3,
270
+ signal: c
271
+ }) {
272
+ return new Promise((d, m) => {
273
+ const s = Fe.get(i) ?? { slots: [], queue: [] };
274
+ Fe.set(i, s);
275
+ let f = !1;
276
+ const g = () => {
277
+ f = !0, c?.removeEventListener("abort", p);
278
+ }, x = {
279
+ id: ++st,
280
+ source: n,
281
+ options: t,
282
+ timeoutMs: r,
283
+ resolve: (b) => f || (g(), d(b)),
284
+ reject: (b) => f || (g(), m(b))
285
+ }, p = () => {
286
+ const b = s.queue.indexOf(x);
287
+ b >= 0 && s.queue.splice(b, 1), x.reject(new Error("Viewer render was aborted."));
288
+ };
289
+ c?.addEventListener("abort", p, { once: !0 }), s.queue.push(x), ae(i, s);
290
+ });
291
+ }
292
+ const fe = /* @__PURE__ */ new WeakMap(), we = (n, t) => fe.get(n)?.get(t)?.face;
293
+ function dt(n, t, i) {
294
+ const r = fe.get(n) ?? /* @__PURE__ */ new Map();
295
+ fe.set(n, r);
296
+ const c = r.get(t);
297
+ if (c) return void c.refs++;
298
+ n.fonts.add(i), r.set(t, { face: i, refs: 1 });
299
+ }
300
+ function pe(n, t) {
301
+ const i = fe.get(n), r = i?.get(t);
302
+ !r || --r.refs > 0 || (n.fonts.delete(r.face), i.delete(t));
303
+ }
304
+ const lt = "http://www.w3.org/2000/svg", ft = new Set(
6
305
  "svg title desc metadata defs style marker g a path rect ellipse circle line polyline polygon text tspan".split(
7
306
  " "
8
307
  )
9
- ), fe = new Set(
308
+ ), ut = new Set(
10
309
  "aria-labelledby role id data-id data-phase data-state data-theme xmlns viewBox width height x y x1 y1 x2 y2 cx cy r rx ry d points transform fill fill-rule fill-opacity stroke stroke-opacity stroke-width stroke-linecap stroke-linejoin stroke-dasharray opacity font-family font-size font-weight text-anchor dominant-baseline dy text-decoration marker-start marker-end markerWidth markerHeight markerUnits refX refY orient class clip-path nonce href target rel".split(
11
310
  " "
12
311
  )
13
312
  );
14
- let me = 0;
15
- function ue(y, c) {
16
- const V = new y.defaultView.DOMParser().parseFromString(c, "image/svg+xml"), s = /* @__PURE__ */ new Map();
17
- for (const v of Array.from(V.querySelectorAll("text[font-family]"))) {
18
- const l = (v.getAttribute("font-family") ?? "").split(",")[0].trim().replace(/^['"]|['"]$/g, ""), b = v.getAttribute("font-weight") ?? "400";
19
- if (!Object.values(ee).some((o) => o.family === l && String(o.weight) === b))
313
+ let mt = 0;
314
+ function ht(n, t) {
315
+ return new n.defaultView.DOMParser().parseFromString(t, "image/svg+xml");
316
+ }
317
+ function gt(n) {
318
+ const t = /* @__PURE__ */ new Map();
319
+ for (const i of Array.from(n.querySelectorAll("text[font-family]"))) {
320
+ const r = (i.getAttribute("font-family") ?? "").split(",")[0].trim().replace(/^['"]|['"]$/g, ""), c = i.getAttribute("font-weight") ?? "400";
321
+ if (!Object.values(Oe).some((d) => d.family === r && String(d.weight) === c))
20
322
  throw new Error("Runtime SVG requested an unknown bundled font face.");
21
- s.set(`${l}:${b}`, { family: l, weight: b });
323
+ t.set(`${r}:${c}`, { family: r, weight: c });
22
324
  }
23
- return [...s.values()];
325
+ return [...t.values()];
24
326
  }
25
- function we(y, c, V) {
26
- const s = new y.defaultView.DOMParser().parseFromString(c, "image/svg+xml"), v = /* @__PURE__ */ new Map();
27
- for (const l of Array.from(s.querySelectorAll("style"))) {
28
- const b = l.textContent ?? "";
29
- for (const [, o] of b.matchAll(/@font-face\s*\{([^{}]{1,200000})\}/g)) {
30
- const f = /font-family\s*:\s*['"]([^'"]+)['"]/i.exec(o)?.[1], w = /font-weight\s*:\s*(\d{1,4})/i.exec(o)?.[1], p = /src\s*:\s*url\((data:font\/woff2;base64,[A-Za-z0-9+/=]+)\)/i.exec(o)?.[1];
31
- !f || !w || !p || Object.values(ee).some((m) => m.family === f && String(m.weight) === w) && v.set(`${f}:${w}`, { family: f, weight: w, data: p });
327
+ function wt(n, t) {
328
+ const i = /* @__PURE__ */ new Map();
329
+ for (const r of Array.from(n.querySelectorAll("style"))) {
330
+ const c = r.textContent ?? "";
331
+ for (const [, d] of c.matchAll(/@font-face\s*\{([^{}]{1,200000})\}/g)) {
332
+ const m = /font-family\s*:\s*['"]([^'"]+)['"]/i.exec(d)?.[1], s = /font-weight\s*:\s*(\d{1,4})/i.exec(d)?.[1], f = /src\s*:\s*url\((data:font\/woff2;base64,[A-Za-z0-9+/=]+)\)/i.exec(d)?.[1];
333
+ !m || !s || !f || Object.values(Oe).some((g) => g.family === m && String(g.weight) === s) && i.set(`${m}:${s}`, { family: m, weight: s, data: f });
32
334
  }
33
335
  }
34
- return V.map((l) => {
35
- const b = v.get(`${l.family}:${l.weight}`);
36
- if (!b) throw new Error(`Embedded font ${l.family} ${l.weight} is missing.`);
37
- return b;
336
+ return t.map((r) => {
337
+ const c = i.get(`${r.family}:${r.weight}`);
338
+ if (!c) throw new Error(`Embedded font ${r.family} ${r.weight} is missing.`);
339
+ return c;
38
340
  });
39
341
  }
40
- function ge(y, c, V, s = 1e5) {
41
- const v = new y.defaultView.DOMParser().parseFromString(c, "image/svg+xml");
42
- if (v.querySelector("parsererror") || v.documentElement.localName !== "svg")
342
+ function pt(n, t, i, r = 1e5) {
343
+ if (t.querySelector("parsererror") || t.documentElement.localName !== "svg")
43
344
  throw new Error("Runtime returned invalid SVG.");
44
- const l = new Set(
45
- Array.from(v.querySelectorAll("[id]"), (f) => f.getAttribute("id") ?? "")
345
+ const c = new Set(
346
+ Array.from(t.querySelectorAll("[id]"), (s) => s.getAttribute("id") ?? "")
46
347
  );
47
- let b = 0;
48
- const o = (f) => {
49
- if (++b > s || !le.has(f.localName))
348
+ let d = 0;
349
+ const m = (s) => {
350
+ if (++d > r || !ft.has(s.localName))
50
351
  throw new Error("Runtime SVG exceeded the allowed drawing vocabulary.");
51
- const w = y.createElementNS(de, f.localName);
52
- for (const { name: p, value: m } of Array.from(f.attributes)) {
53
- if (/^on/i.test(p)) continue;
54
- if (p === "href") {
55
- if (f.localName !== "a") continue;
352
+ const f = n.createElementNS(lt, s.localName);
353
+ for (const { name: g, value: x } of Array.from(s.attributes)) {
354
+ if (/^on/i.test(g)) continue;
355
+ if (g === "href") {
356
+ if (s.localName !== "a") continue;
56
357
  try {
57
- const a = new URL(m, y.baseURI);
58
- (a.protocol === "http:" || a.protocol === "https:") && w.setAttribute("href", a.href);
358
+ const b = new URL(x, n.baseURI);
359
+ (b.protocol === "http:" || b.protocol === "https:") && f.setAttribute("href", b.href);
59
360
  } catch {
60
361
  }
61
362
  continue;
62
363
  }
63
- if (!fe.has(p) && !/^data-[a-z0-9-]+$/.test(p)) continue;
64
- const x = [...m.matchAll(/url\(#([^)]*)\)/g)].map((a) => a[1]);
65
- /url\s*\(/i.test(m) && (x.length === 0 || x.some((a) => !l.has(a))) || p === "aria-labelledby" && m.split(/\s+/).some((a) => !l.has(a)) || w.setAttribute(p, m);
364
+ if (!ut.has(g) && !/^data-[a-z0-9-]+$/.test(g)) continue;
365
+ const p = [...x.matchAll(/url\(#([^)]*)\)/g)].map((b) => b[1]);
366
+ /url\s*\(/i.test(x) && (p.length === 0 || p.some((b) => !c.has(b))) || g === "aria-labelledby" && x.split(/\s+/).some((b) => !c.has(b)) || f.setAttribute(g, x);
66
367
  }
67
- f.localName === "a" && w.getAttribute("target") === "_blank" && w.setAttribute("rel", "noopener noreferrer");
68
- for (const p of Array.from(f.childNodes))
69
- if (p.nodeType === 1) w.append(o(p));
70
- else if (p.nodeType === 3) {
71
- const m = p.nodeValue ?? "";
72
- w.append(
73
- y.createTextNode(
74
- f.localName === "style" && V ? m.replace(/@font-face\s*\{[^{}]*\}/g, "") : m
368
+ s.localName === "a" && f.getAttribute("target") === "_blank" && f.setAttribute("rel", "noopener noreferrer");
369
+ for (const g of Array.from(s.childNodes))
370
+ if (g.nodeType === 1) f.append(m(g));
371
+ else if (g.nodeType === 3) {
372
+ const x = g.nodeValue ?? "";
373
+ f.append(
374
+ n.createTextNode(
375
+ s.localName === "style" && i ? x.replace(/@font-face\s*\{[^{}]*\}/g, "") : x
75
376
  )
76
377
  );
77
378
  }
78
- return w;
379
+ return f;
79
380
  };
80
- return o(v.documentElement);
381
+ return m(t.documentElement);
81
382
  }
82
- function K(y, c, V) {
383
+ function de(n, t, i) {
83
384
  return {
84
385
  ok: !1,
85
- reason: y,
86
- diagnostics: [{ code: c, severity: "error", message: V, itemIds: [] }]
386
+ reason: n,
387
+ diagnostics: [{ code: t, severity: "error", message: i, itemIds: [] }]
87
388
  };
88
389
  }
89
- function be(y, c = {}) {
90
- const V = y?.ownerDocument?.defaultView;
91
- if (!V || !(y instanceof V.HTMLElement))
390
+ function bt(n, t = {}) {
391
+ const i = n?.ownerDocument?.defaultView;
392
+ if (!i || !(n instanceof i.HTMLElement))
92
393
  throw new TypeError("host must be an HTMLElement.");
93
- if (y.childNodes.length) throw new Error("Viewer host must be empty and exclusively owned.");
94
- if ((c.execution ?? { mode: "worker" }).mode === "worker" && c.render?.links?.mode === "safe" && c.render.links.resolve)
394
+ if (n.childNodes.length) throw new Error("Viewer host must be empty and exclusively owned.");
395
+ if ((t.execution ?? { mode: "worker" }).mode === "worker" && t.render?.links?.mode === "safe" && t.render.links.resolve)
95
396
  throw new TypeError('A link resolver requires execution: { mode: "main" }.');
96
- const s = y.ownerDocument, v = V, l = s.createElement("section");
97
- l.className = "draft-viewer", c.outline !== "visible" && l.classList.add("draft-viewer--outline-hidden"), l.setAttribute("aria-label", c.label ?? "Diagram viewer");
98
- const b = s.createElement("div");
99
- b.className = "draft-viewer__toolbar", b.setAttribute("role", "toolbar"), b.setAttribute("aria-label", "Diagram controls");
100
- const o = s.createElement("div");
101
- o.className = "draft-viewer__viewport", o.tabIndex = 0, o.setAttribute("aria-label", c.label ?? "Diagram");
102
- const f = s.createElement("p");
397
+ const r = n.ownerDocument, c = i, d = r.createElement("section");
398
+ d.className = "draft-viewer", t.outline !== "visible" && d.classList.add("draft-viewer--outline-hidden"), d.setAttribute("aria-label", t.label ?? "Diagram viewer");
399
+ const m = r.createElement("div");
400
+ m.className = "draft-viewer__toolbar", m.setAttribute("role", "toolbar"), m.setAttribute("aria-label", "Diagram controls");
401
+ const s = r.createElement("div");
402
+ s.className = "draft-viewer__viewport", s.tabIndex = 0, s.setAttribute("aria-label", t.label ?? "Diagram");
403
+ const f = r.createElement("p");
103
404
  f.className = "draft-viewer__status", f.setAttribute("role", "status"), f.setAttribute("aria-live", "polite");
104
- const w = s.createElement("ol");
105
- w.className = "draft-viewer__outline", w.setAttribute("aria-label", "Diagram outline"), l.append(b, o, f, w), y.append(l);
106
- const p = `draftViewer${(++me).toString(36)}${Math.random().toString(36).slice(2, 9)}`;
107
- let m = 0, x = !1, a = { centerX: 0, centerY: 0, zoom: 1 }, _ = !1, u, C, q, te = 0;
108
- const N = /* @__PURE__ */ new Map(), U = /* @__PURE__ */ new Map(), B = /* @__PURE__ */ new Map(), L = (e, r) => {
109
- for (const t of U.get(e) ?? [])
405
+ const g = r.createElement("ol");
406
+ g.className = "draft-viewer__outline", g.setAttribute("aria-label", "Diagram outline"), d.append(m, s, f, g);
407
+ const x = nt(n, (e) => d.style.colorScheme = e ? "dark" : "light"), p = et(r, {
408
+ detail: t.detail,
409
+ onOverflow: () => h()
410
+ });
411
+ s.append(p.el), n.append(d);
412
+ const b = `draftViewer${(++mt).toString(36)}${Math.random().toString(36).slice(2, 9)}`;
413
+ let P = 0, L = !1, E = { centerX: 0, centerY: 0, zoom: 1 }, re = !1, k, Y = { width: 0, height: 0 };
414
+ const W = /* @__PURE__ */ new Set(), G = /* @__PURE__ */ new Map(), J = /* @__PURE__ */ new Map(), F = (e, a) => {
415
+ for (const o of G.get(e) ?? [])
110
416
  try {
111
- t(r);
417
+ o(a);
112
418
  } catch {
113
419
  }
114
- }, j = (e, r) => {
115
- const t = s.createElement("button");
116
- t.type = "button", t.textContent = e, t.setAttribute("aria-label", e), t.addEventListener("click", r), b.append(t);
117
- }, re = () => {
118
- if (!u) return 1;
119
- const e = o.getBoundingClientRect(), [, , r, t] = u.viewBox;
120
- return Math.min(e.width / r, e.height / t);
121
- }, R = () => {
122
- const e = o.querySelector("svg");
123
- if (!e || !u) return;
124
- const [r, t] = u.viewBox, S = o.getBoundingClientRect(), g = a.zoom, n = S.width / 2 - (a.centerX - r) * g, h = S.height / 2 - (a.centerY - t) * g;
125
- e.style.transformOrigin = "0 0", e.style.transform = `translate(${n}px, ${h}px) scale(${g})`, e.style.width = `${u.width}px`, e.style.height = `${u.height}px`, e.style.maxWidth = "none";
126
- }, Y = (e = "fit") => {
127
- if (!u) return;
128
- const r = o.getBoundingClientRect();
129
- if (!r.width || !r.height) return;
130
- const [t, S, g, n] = u.viewBox;
131
- a = {
132
- centerX: t + g / 2,
133
- centerY: S + n / 2,
134
- zoom: Math.min(1, re() * 0.92)
135
- }, _ = !1, R(), L("camera", { camera: { ...a }, reason: e });
136
- }, P = (e) => {
137
- a.zoom = Math.max(0.02, Math.min(8, a.zoom * e)), _ = !0, R(), L("camera", { camera: { ...a }, reason: "user" });
420
+ }, U = (e, a) => {
421
+ const o = r.createElement("button");
422
+ o.type = "button", o.textContent = e, o.setAttribute("aria-label", e), o.addEventListener("click", a), m.append(o);
138
423
  }, ne = () => {
139
- a.zoom = 1, _ = !0, R(), L("camera", { camera: { ...a }, reason: "user" });
424
+ const e = s.querySelector("svg");
425
+ if (!e || !k) return;
426
+ const [a, o] = k.viewBox, v = Y, A = E.zoom, C = v.width / 2 - (E.centerX - a) * A, u = v.height / 2 - (E.centerY - o) * A;
427
+ e.style.transformOrigin = "0 0", e.style.transform = `translate(${C}px, ${u}px) scale(${A})`, e.style.width = `${k.width}px`, e.style.height = `${k.height}px`, e.style.maxWidth = "none", p.place(C - a * A, u - o * A, A);
428
+ const q = p.el.dataset.draftDetail;
429
+ s.dataset.draftDetail !== q && (s.dataset.draftDetail = q);
430
+ }, se = () => {
431
+ const e = new Set(p.bodyIds());
432
+ for (const a of s.querySelectorAll(":scope > svg [data-id]"))
433
+ a.toggleAttribute("data-draft-body", e.has(a.getAttribute("data-id")));
434
+ F("anchors", { anchors: p.anchors() });
435
+ };
436
+ let l = {
437
+ revision: 0,
438
+ diagnostics: [],
439
+ stale: !1
440
+ };
441
+ const h = () => F("diagnostics", {
442
+ ...l,
443
+ diagnostics: [...l.diagnostics, ...p.warnings()]
444
+ });
445
+ let w = "user", M = 0;
446
+ const _ = (e) => c.requestAnimationFrame ? c.requestAnimationFrame(e) : c.setTimeout(e, 16), S = (e) => {
447
+ w = e, !M && (M = _(() => {
448
+ M = 0, L || F("camera", { camera: { ...E }, reason: w });
449
+ }));
450
+ }, z = (e, a, o) => {
451
+ const v = { ...e, zoom: ye(e.zoom) };
452
+ return re = o, Ke(E, v) ? "unchanged" : (E = v, ne(), S(a), "moved");
453
+ }, R = () => {
454
+ const [e, a, o, v] = k.viewBox;
455
+ return { x: e, y: a, width: o, height: v };
140
456
  };
141
- c.toolbar !== !1 && (j("Zoom in", () => P(1.2)), j("Zoom out", () => P(1 / 1.2)), j("Fit diagram", () => Y()), j("Actual size", ne));
142
- const J = new v.ResizeObserver(() => {
143
- u && !o.getBoundingClientRect().width || (_ ? R() : Y("resize"));
457
+ let N = null;
458
+ const B = (e) => N ? Ne(N, e) : void 0;
459
+ let D;
460
+ const $ = (e) => L ? "unchanged" : !k || !Y.width || !Y.height ? (D = e, "pending") : (D = void 0, e()), I = (e, a, o) => $(() => {
461
+ const v = e ? Ge(e.flatMap((A) => B(A) ?? [])) : R();
462
+ return v ? z(Ie(v, Y, a), o, !!e) : "missing";
463
+ }), Q = (e = "fit") => I(void 0, void 0, e), Z = (e) => z({ ...E, zoom: E.zoom * e }, "user", !0), ue = () => z({ ...E, zoom: 1 }, "user", !0);
464
+ U("Zoom in", () => Z(1.2)), U("Zoom out", () => Z(1 / 1.2)), U("Fit diagram", () => Q()), U("Actual size", ue), m.hidden = t.toolbar === !1;
465
+ const ee = new c.ResizeObserver((e) => {
466
+ const a = e.at(-1)?.contentRect;
467
+ a && (Y = { width: a.width, height: a.height }), !(k && !Y.width) && (D ? $(D) : re ? ne() : Q("resize"));
144
468
  });
145
- J.observe(o);
146
- const X = (e, r) => {
147
- f.textContent = r.map((t) => t.message).join(" "), l.classList.add("draft-viewer--stale"), L("diagnostics", { revision: e, diagnostics: r, stale: !!u });
148
- }, oe = async (e, r) => {
149
- const t = ue(s, e);
150
- if (!t.length) return [];
151
- if (!s.fonts) throw new Error("The host document cannot load diagram fonts.");
152
- if (r === "host") {
153
- for (const n of t) {
154
- const h = `${n.weight} 12px "${n.family}"`;
155
- if (!(await s.fonts.load(h)).some(
156
- (E) => E.family.replace(/^['"]|['"]$/g, "") === n.family && E.weight === n.weight && E.status === "loaded"
157
- ) || !s.fonts.check(h))
158
- throw new Error(`Host font ${n.family} ${n.weight} is unavailable.`);
469
+ ee.observe(s);
470
+ const H = (e, a) => {
471
+ f.textContent = a.map((o) => o.message).join(" "), d.classList.add("draft-viewer--stale"), l = { revision: e, diagnostics: a, stale: !!k }, h();
472
+ }, ie = async (e, a) => {
473
+ const o = gt(e);
474
+ if (!o.length) return [];
475
+ if (!r.fonts) throw new Error("The host document cannot load diagram fonts.");
476
+ if (a === "host") {
477
+ for (const u of o) {
478
+ const q = `${u.weight} 12px "${u.family}"`;
479
+ if (!(await r.fonts.load(q)).some(
480
+ (V) => V.family.replace(/^['"]|['"]$/g, "") === u.family && V.weight === u.weight && V.status === "loaded"
481
+ ) || !r.fonts.check(q))
482
+ throw new Error(`Host font ${u.family} ${u.weight} is unavailable.`);
159
483
  }
160
484
  return [];
161
485
  }
162
- const S = we(s, e, t), g = v.FontFace;
163
- if (!g) throw new Error("The browser cannot load embedded diagram fonts.");
486
+ const v = o.map((u) => `${u.family}:${u.weight}`);
487
+ if (v.every((u) => we(r, u)))
488
+ return v.map((u) => ({ key: u, face: we(r, u) }));
489
+ const A = wt(e, o), C = c.FontFace;
490
+ if (!C) throw new Error("The browser cannot load embedded diagram fonts.");
164
491
  return Promise.all(
165
- S.map(async (n) => {
166
- const h = `${n.family}:${n.weight}`, F = N.get(h);
167
- if (F?.status === "loaded" && Array.from(s.fonts).includes(F))
168
- return { key: h, face: F };
169
- const d = new g(n.family, `url("${n.data}")`, { weight: n.weight });
170
- if (await d.load(), d.status !== "loaded")
171
- throw new Error(`Embedded font ${n.family} ${n.weight} did not load.`);
172
- return { key: h, face: d };
492
+ A.map(async (u) => {
493
+ const q = `${u.family}:${u.weight}`, te = we(r, q);
494
+ if (te) return { key: q, face: te };
495
+ const T = new C(u.family, `url("${u.data}")`, { weight: u.weight });
496
+ if (await T.load(), T.status !== "loaded")
497
+ throw new Error(`Embedded font ${u.family} ${u.weight} did not load.`);
498
+ return { key: q, face: T };
173
499
  })
174
500
  );
175
- }, z = (e) => {
176
- const r = q;
177
- q = void 0, r && (v.clearTimeout(r.timer), r.cleanup(), r.finish(void 0, e ?? new Error("Viewer render was cancelled."))), C?.terminate(), C = void 0;
178
- }, ae = (e, r, t) => (c.execution ?? { mode: "worker" }).mode === "main" ? ce(e, { ...r, signal: t }) : new Promise((S, g) => {
179
- const n = ++te;
180
- let h = !1;
181
- const F = () => {
182
- C && (C.removeEventListener("message", E), C.removeEventListener("error", W), C.removeEventListener("messageerror", G), t?.removeEventListener("abort", H));
183
- }, d = (k, D) => {
184
- if (h) return;
185
- h = !0;
186
- const i = q;
187
- i?.id === n && (q = void 0, v.clearTimeout(i.timer), i.cleanup()), D ? g(D) : S(k);
188
- }, E = (k) => {
189
- k.data?.id === n && d(k.data.result);
190
- }, W = (k) => {
191
- k.preventDefault(), z(new Error(k.message || "Viewer render worker failed."));
192
- }, G = () => z(new Error("Viewer render worker returned an unreadable result.")), H = () => z(new Error("Viewer render was aborted."));
193
- try {
194
- C ??= c.execution?.mode === "worker" && c.execution.createWorker ? c.execution.createWorker() : new Worker(new URL(
195
- /* @vite-ignore */
196
- "" + new URL("assets/render.worker-dvseyGmC.js", import.meta.url).href,
197
- import.meta.url
198
- ), { type: "module" }), C.addEventListener("message", E), C.addEventListener("error", W), C.addEventListener("messageerror", G), t?.addEventListener("abort", H, { once: !0 });
199
- const k = c.execution?.mode === "worker" ? c.execution.timeoutMs ?? 5e3 : 5e3, D = v.setTimeout(
200
- () => z(new Error("Viewer render worker timed out.")),
201
- k
202
- );
203
- q = { id: n, timer: D, finish: d, cleanup: F }, C.postMessage({ id: n, source: e, options: r });
204
- } catch (k) {
205
- z(
206
- k instanceof Error ? k : new Error("Viewer render worker could not start.")
207
- ), g(k);
501
+ }, Ce = async (e, a, o) => {
502
+ const v = t.execution ?? { mode: "worker" };
503
+ if (v.mode === "main") {
504
+ const { renderSvg: A } = await import("./render-CsJYFD3o.js");
505
+ return A(e, { ...a, signal: o });
208
506
  }
209
- });
210
- let A;
211
- const ie = (e) => {
212
- const r = o.querySelector("svg"), t = r?.querySelector(":scope > rect");
213
- return e === o || e === r || e === t;
507
+ return ct(e, a, {
508
+ create: v.createWorker,
509
+ timeoutMs: v.timeoutMs,
510
+ signal: o
511
+ });
214
512
  };
215
- o.addEventListener(
513
+ let O;
514
+ const qe = (e) => {
515
+ const a = s.querySelector("svg"), o = a?.querySelector(":scope > rect");
516
+ return e === s || e === a || e === o;
517
+ }, ve = (e) => !(e.target instanceof c.Node) || !s.contains(e.target) || p.el.contains(e.target), Ve = (e) => e.composedPath().some((a) => a instanceof c.Element && a.hasAttribute("data-draft-input"));
518
+ s.addEventListener(
216
519
  "wheel",
217
520
  (e) => {
218
- e.preventDefault(), P(e.deltaY < 0 ? 1.1 : 1 / 1.1);
521
+ Ve(e) || (e.preventDefault(), Z(e.deltaY < 0 ? 1.1 : 1 / 1.1));
219
522
  },
220
523
  { passive: !1 }
221
- ), o.addEventListener("pointerdown", (e) => {
222
- !ie(e.target) || !u || (A = {
524
+ ), s.addEventListener("pointerdown", (e) => {
525
+ !qe(e.target) || !k || (O = {
223
526
  pointerId: e.pointerId,
224
527
  x: e.clientX,
225
528
  y: e.clientY,
226
- centerX: a.centerX,
227
- centerY: a.centerY,
228
- scale: a.zoom
229
- }, o.setPointerCapture(e.pointerId));
230
- }), o.addEventListener("pointermove", (e) => {
231
- A && (a.centerX = A.centerX - (e.clientX - A.x) / A.scale, a.centerY = A.centerY - (e.clientY - A.y) / A.scale, _ = !0, R());
529
+ centerX: E.centerX,
530
+ centerY: E.centerY,
531
+ scale: E.zoom
532
+ }, s.setPointerCapture(e.pointerId));
533
+ }), s.addEventListener("pointermove", (e) => {
534
+ O && z(
535
+ {
536
+ centerX: O.centerX - (e.clientX - O.x) / O.scale,
537
+ centerY: O.centerY - (e.clientY - O.y) / O.scale,
538
+ zoom: E.zoom
539
+ },
540
+ "user",
541
+ !0
542
+ );
232
543
  });
233
- const Q = () => {
234
- if (A) {
544
+ const be = () => {
545
+ if (O) {
235
546
  try {
236
- o.releasePointerCapture(A.pointerId);
547
+ s.releasePointerCapture(O.pointerId);
237
548
  } catch {
238
549
  }
239
- A = void 0, L("camera", { camera: { ...a }, reason: "user" });
550
+ O = void 0;
240
551
  }
241
552
  };
242
- o.addEventListener("pointerup", Q), o.addEventListener("pointercancel", Q), o.addEventListener("click", (e) => {
243
- const r = e.target instanceof v.Element ? e.target : null, t = r?.closest("a[href]");
244
- if (t && o.contains(t)) {
245
- const n = t.querySelector("[data-id]")?.getAttribute("data-id"), h = t.getAttribute("href");
246
- n && h && L("link", {
247
- itemId: n,
248
- href: h,
249
- target: t.getAttribute("target") === "_blank" ? "_blank" : "_self",
553
+ s.addEventListener("pointerup", be), s.addEventListener("pointercancel", be), s.addEventListener("click", (e) => {
554
+ if (ve(e)) return;
555
+ const a = e.target instanceof c.Element ? e.target : null, o = a?.closest("a[href]");
556
+ if (o && s.contains(o)) {
557
+ const C = o.querySelector("[data-id]")?.getAttribute("data-id"), u = o.getAttribute("href");
558
+ C && u && F("link", {
559
+ itemId: C,
560
+ href: u,
561
+ target: o.getAttribute("target") === "_blank" ? "_blank" : "_self",
250
562
  preventDefault: () => e.preventDefault()
251
563
  });
252
564
  return;
253
565
  }
254
- const S = r?.closest("[data-id]")?.getAttribute("data-id"), g = u?.items.find((n) => n.id === S);
255
- g && L("itemactivate", { id: g.id, kind: g.kind, input: "pointer", revision: m });
256
- }), o.addEventListener("keydown", (e) => {
257
- e.target !== o || e.altKey || e.ctrlKey || e.metaKey || (e.key === "+" || e.key === "=" ? P(1.2) : e.key === "-" ? P(1 / 1.2) : e.key.toLowerCase() === "f" && Y());
566
+ const v = a?.closest("[data-id]")?.getAttribute("data-id"), A = k?.items.find((C) => C.id === v);
567
+ A && F("itemactivate", { id: A.id, kind: A.kind, input: "pointer", revision: P });
568
+ }), s.addEventListener("contextmenu", (e) => {
569
+ if (ve(e)) return;
570
+ const o = (e.target instanceof c.Element ? e.target : null)?.closest("[data-id]")?.getAttribute("data-id") ?? null, v = o ? k?.items.find((A) => A.id === o) : void 0;
571
+ F("contextmenu", {
572
+ id: v?.id ?? null,
573
+ ...v ? { kind: v.kind } : {},
574
+ clientX: e.clientX,
575
+ clientY: e.clientY,
576
+ preventDefault: () => e.preventDefault()
577
+ });
578
+ }), p.el.addEventListener("focusin", (e) => {
579
+ const a = e.target instanceof c.Node ? p.idOf(e.target) : void 0;
580
+ a && !p.pressed() && xe.reveal(a);
581
+ }), p.el.addEventListener("keydown", (e) => {
582
+ e.key === "Escape" && s.focus({ preventScroll: !0 });
583
+ }), p.el.addEventListener(
584
+ "draft-anchor-focus-lost",
585
+ () => s.focus({ preventScroll: !0 })
586
+ ), s.addEventListener("keydown", (e) => {
587
+ e.target !== s || e.altKey || e.ctrlKey || e.metaKey || (e.key === "+" || e.key === "=" ? Z(1.2) : e.key === "-" ? Z(1 / 1.2) : e.key.toLowerCase() === "f" && Q());
258
588
  });
259
- const se = (e, r) => {
260
- for (const [t, S] of B)
261
- t !== e && S.resolve({ status: r, revision: t });
589
+ const je = (e, a) => {
590
+ for (const [o, v] of J)
591
+ o !== e && v.resolve({ status: a, revision: o });
262
592
  };
263
- return {
264
- update: (e, r = {}) => {
265
- const t = ++m;
266
- return x ? Promise.resolve({ status: "destroyed", revision: t }) : (se(t, "superseded"), z(new Error("Viewer update was superseded.")), new Promise((S) => {
267
- let g = !1;
268
- const n = (d) => {
269
- if (g) return;
270
- g = !0, r.signal?.removeEventListener("abort", h), B.delete(t);
271
- const E = x ? { status: "destroyed", revision: t } : t !== m ? { status: "superseded", revision: t } : r.signal?.aborted ? { status: "aborted", revision: t } : d;
272
- S(E);
273
- }, h = () => {
274
- t === m && (c.execution ?? { mode: "worker" }).mode === "worker" && z(new Error("Viewer render was aborted.")), n({ status: "aborted", revision: t });
275
- };
276
- if (B.set(t, { resolve: n }), r.signal?.aborted) {
277
- h();
593
+ let me = () => {
594
+ };
595
+ const Pe = (e, a = {}) => {
596
+ const o = ++P;
597
+ if (L) return Promise.resolve({ status: "destroyed", revision: o });
598
+ je(o, "superseded"), me();
599
+ const v = new AbortController();
600
+ return me = () => v.abort(), new Promise((A) => {
601
+ let C = !1;
602
+ const u = (T) => {
603
+ if (C) return;
604
+ C = !0, a.signal?.removeEventListener("abort", q), J.delete(o);
605
+ const V = L ? { status: "destroyed", revision: o } : o !== P ? { status: "superseded", revision: o } : a.signal?.aborted ? { status: "aborted", revision: o } : T;
606
+ A(V);
607
+ }, q = () => {
608
+ v.abort(), u({ status: "aborted", revision: o });
609
+ };
610
+ if (J.set(o, { resolve: u }), a.signal?.aborted) {
611
+ q();
612
+ return;
613
+ }
614
+ a.signal?.addEventListener("abort", q, { once: !0 });
615
+ const te = {
616
+ ...t.render ?? {},
617
+ target: "inline",
618
+ idPrefix: b,
619
+ fonts: t.render?.fonts ?? "embed",
620
+ colorScheme: "auto",
621
+ ...a.state !== void 0 ? { state: a.state } : {}
622
+ };
623
+ Ce(e, te, v.signal).then(async (T) => {
624
+ if (L || o !== P || a.signal?.aborted) {
625
+ u({ status: "superseded", revision: o });
278
626
  return;
279
627
  }
280
- r.signal?.addEventListener("abort", h, { once: !0 });
281
- const F = {
282
- ...c.render ?? {},
283
- target: "inline",
284
- idPrefix: p,
285
- fonts: c.render?.fonts ?? "embed",
286
- ...r.state !== void 0 ? { state: r.state } : {}
287
- };
288
- ae(e, F, r.signal).then(async (d) => {
289
- if (x || t !== m || r.signal?.aborted) {
290
- n({ status: "superseded", revision: t });
291
- return;
292
- }
293
- if (!d.ok) {
294
- X(t, d.diagnostics), n({ status: "error", revision: t, error: d });
295
- return;
296
- }
297
- let E;
298
- try {
299
- E = await oe(d.value.svg, F.fonts ?? "embed");
300
- } catch (i) {
301
- if (x || t !== m || r.signal?.aborted) {
302
- n({
303
- status: r.signal?.aborted ? "aborted" : "superseded",
304
- revision: t
305
- });
306
- return;
307
- }
308
- const $ = K(
309
- "environment",
310
- "DRAFT_FONT_UNAVAILABLE",
311
- i instanceof Error ? i.message : "Diagram fonts are unavailable."
312
- );
313
- X(t, $.diagnostics), n({ status: "error", revision: t, error: $ });
314
- return;
315
- }
316
- if (x || t !== m || r.signal?.aborted) {
317
- n({ status: "superseded", revision: t });
318
- return;
319
- }
320
- let W;
321
- try {
322
- W = ge(s, d.value.svg, F.fonts !== "host");
323
- } catch (i) {
324
- const $ = i instanceof Error ? i.message : "Could not build safe SVG.", M = K("internal", "DRAFT_VIEWER_DOM", $);
325
- X(t, M.diagnostics), n({ status: "error", revision: t, error: M });
326
- return;
327
- }
328
- const G = [];
329
- try {
330
- for (const i of E)
331
- N.has(i.key) || (s.fonts.add(i.face), N.set(i.key, i.face), G.push(i));
332
- } catch (i) {
333
- for (const { key: M, face: Z } of G)
334
- s.fonts.delete(Z), N.delete(M);
335
- const $ = K(
336
- "environment",
337
- "DRAFT_FONT_UNAVAILABLE",
338
- i instanceof Error ? i.message : "Loaded fonts could not be registered."
339
- );
340
- X(t, $.diagnostics), n({ status: "error", revision: t, error: $ });
341
- return;
342
- }
343
- const H = !!u;
344
- u = d.value, o.replaceChildren(W), w.replaceChildren(
345
- ...u.items.map((i) => {
346
- const $ = s.createElement("li"), M = s.createElement("button");
347
- M.type = "button";
348
- const Z = i.label.trim() || (i.kind === "edge" ? `${i.from ?? "?"} to ${i.to ?? "?"}` : i.id);
349
- return M.textContent = `${i.kind}: ${Z}`, M.dataset.itemId = i.id, M.addEventListener("click", () => {
350
- L("itemactivate", {
351
- id: i.id,
352
- kind: i.kind,
353
- input: "keyboard",
354
- revision: t
355
- });
356
- const O = Array.from(o.querySelectorAll("[data-id]")).find(
357
- (T) => T.getAttribute("data-id") === i.id
358
- );
359
- if (O) {
360
- const T = O.getBoundingClientRect(), I = o.getBoundingClientRect();
361
- (T.width || T.height) && I.width && I.height && (a = {
362
- centerX: a.centerX + (T.left + T.width / 2 - (I.left + I.width / 2)) / a.zoom,
363
- centerY: a.centerY + (T.top + T.height / 2 - (I.top + I.height / 2)) / a.zoom,
364
- zoom: Math.max(1, a.zoom)
365
- }, _ = !0, R(), L("camera", { camera: { ...a }, reason: "user" }));
366
- }
367
- }), $.append(M), $;
368
- })
369
- );
370
- const k = new Set(E.map((i) => i.key));
371
- for (const [i, $] of N)
372
- k.has(i) || (s.fonts.delete($), N.delete(i));
373
- l.classList.remove("draft-viewer--stale"), f.textContent = d.diagnostics.map((i) => i.message).join(" "), !H || r.camera === "fit" ? Y() : R();
374
- const D = {
375
- status: "committed",
376
- revision: t,
377
- value: u,
378
- diagnostics: d.diagnostics
379
- };
380
- n(D), L("render", { revision: t, value: u }), L("diagnostics", { revision: t, diagnostics: d.diagnostics, stale: !1 });
381
- }).catch((d) => {
382
- if (x || t !== m || r.signal?.aborted) {
383
- n({
384
- status: r.signal?.aborted ? "aborted" : "superseded",
385
- revision: t
628
+ if (!T.ok) {
629
+ H(o, T.diagnostics), u({ status: "error", revision: o, error: T });
630
+ return;
631
+ }
632
+ let V, he;
633
+ try {
634
+ he = ht(r, T.value.svg), V = await ie(he, te.fonts ?? "embed");
635
+ } catch (y) {
636
+ if (L || o !== P || a.signal?.aborted) {
637
+ u({
638
+ status: a.signal?.aborted ? "aborted" : "superseded",
639
+ revision: o
386
640
  });
387
641
  return;
388
642
  }
389
- const E = K(
643
+ const j = de(
644
+ "environment",
645
+ "DRAFT_FONT_UNAVAILABLE",
646
+ y instanceof Error ? y.message : "Diagram fonts are unavailable."
647
+ );
648
+ H(o, j.diagnostics), u({ status: "error", revision: o, error: j });
649
+ return;
650
+ }
651
+ if (L || o !== P || a.signal?.aborted) {
652
+ u({ status: "superseded", revision: o });
653
+ return;
654
+ }
655
+ let ge;
656
+ try {
657
+ ge = pt(r, he, te.fonts !== "host");
658
+ } catch (y) {
659
+ const j = y instanceof Error ? y.message : "Could not build safe SVG.", X = de("internal", "DRAFT_VIEWER_DOM", j);
660
+ H(o, X.diagnostics), u({ status: "error", revision: o, error: X });
661
+ return;
662
+ }
663
+ const ke = [];
664
+ try {
665
+ for (const y of V)
666
+ W.has(y.key) || (dt(r, y.key, y.face), W.add(y.key), ke.push(y.key));
667
+ } catch (y) {
668
+ for (const X of ke)
669
+ pe(r, X), W.delete(X);
670
+ const j = de(
390
671
  "environment",
391
- "DRAFT_VIEWER_WORKER",
392
- d instanceof Error ? d.message : "Viewer render failed."
672
+ "DRAFT_FONT_UNAVAILABLE",
673
+ y instanceof Error ? y.message : "Loaded fonts could not be registered."
393
674
  );
394
- X(t, E.diagnostics), n({ status: "error", revision: t, error: E });
395
- });
396
- }));
675
+ H(o, j.diagnostics), u({ status: "error", revision: o, error: j });
676
+ return;
677
+ }
678
+ const Ye = !!k;
679
+ k = T.value, N = k.geometry ? { ...k.geometry, revision: o } : null;
680
+ const Ae = s.querySelector(":scope > svg");
681
+ Ae ? Ae.replaceWith(ge) : s.prepend(ge), p.setGeometry(N);
682
+ const Se = g.getRootNode().activeElement, Le = g.contains(Se) ? Se.dataset.itemId : void 0;
683
+ g.replaceChildren(
684
+ ...k.items.map((y) => {
685
+ const j = r.createElement("li"), X = r.createElement("button");
686
+ X.type = "button";
687
+ const Ze = y.label.trim() || (y.kind === "edge" ? `${y.from ?? "?"} to ${y.to ?? "?"}` : y.id);
688
+ return X.textContent = `${y.kind}: ${Ze}`, X.dataset.itemId = y.id, X.addEventListener("click", () => {
689
+ F("itemactivate", {
690
+ id: y.id,
691
+ kind: y.kind,
692
+ input: "keyboard",
693
+ revision: o
694
+ });
695
+ const Me = Array.from(s.querySelectorAll("[data-id]")).find(
696
+ (K) => K.getAttribute("data-id") === y.id
697
+ );
698
+ if (Me) {
699
+ const K = Me.getBoundingClientRect(), oe = s.getBoundingClientRect();
700
+ (K.width || K.height) && oe.width && oe.height && z(
701
+ {
702
+ centerX: E.centerX + (K.left + K.width / 2 - (oe.left + oe.width / 2)) / E.zoom,
703
+ centerY: E.centerY + (K.top + K.height / 2 - (oe.top + oe.height / 2)) / E.zoom,
704
+ zoom: Math.max(1, E.zoom)
705
+ },
706
+ "user",
707
+ !0
708
+ );
709
+ }
710
+ }), j.append(X), j;
711
+ })
712
+ ), Le !== void 0 && (Array.from(g.querySelectorAll("button")).find(
713
+ (j) => j.dataset.itemId === Le
714
+ ) ?? s).focus({ preventScroll: !0 });
715
+ const We = new Set(V.map((y) => y.key));
716
+ for (const y of W)
717
+ We.has(y) || (pe(r, y), W.delete(y));
718
+ d.classList.remove("draft-viewer--stale"), f.textContent = T.diagnostics.map((y) => y.message).join(" "), D ? $(D) : !Ye || a.camera === "fit" ? Q() : ne();
719
+ const Be = {
720
+ status: "committed",
721
+ revision: o,
722
+ value: k,
723
+ diagnostics: T.diagnostics
724
+ };
725
+ x.check(), F("render", { revision: o, value: k, geometry: N }), l = { revision: o, diagnostics: T.diagnostics, stale: !1 }, h(), se(), u(Be);
726
+ }).catch((T) => {
727
+ if (L || o !== P || a.signal?.aborted) {
728
+ u({
729
+ status: a.signal?.aborted ? "aborted" : "superseded",
730
+ revision: o
731
+ });
732
+ return;
733
+ }
734
+ const V = de(
735
+ "environment",
736
+ "DRAFT_VIEWER_WORKER",
737
+ T instanceof Error ? T.message : "Viewer render failed."
738
+ );
739
+ H(o, V.diagnostics), u({ status: "error", revision: o, error: V });
740
+ });
741
+ });
742
+ };
743
+ let ce, Ee;
744
+ const Xe = new Promise((e) => Ee = e), xe = {
745
+ get ready() {
746
+ return ce ?? Xe;
747
+ },
748
+ update: (e, a) => {
749
+ const o = Pe(e, a), v = o.then(
750
+ (A) => A.status === "superseded" && ce !== v ? ce : A
751
+ );
752
+ return ce = v, v.then(Ee), o;
753
+ },
754
+ geometry: () => N,
755
+ anchor(e) {
756
+ if (L) return;
757
+ const a = p.warnings().length;
758
+ p.setSlots(e), ne(), se(), (p.warnings().length || a) && h();
397
759
  },
398
- on(e, r) {
399
- if (x) return () => {
760
+ on(e, a) {
761
+ if (L) return () => {
400
762
  };
401
- const t = U.get(e) ?? /* @__PURE__ */ new Set();
402
- return t.add(r), U.set(e, t), () => t.delete(r);
763
+ const o = G.get(e) ?? /* @__PURE__ */ new Set();
764
+ return o.add(a), G.set(e, o), () => o.delete(a);
403
765
  },
404
- getCamera: () => ({ ...a }),
766
+ getCamera: () => ({ ...E }),
405
767
  setCamera(e) {
406
- x || !Number.isFinite(e.centerX) || !Number.isFinite(e.centerY) || !Number.isFinite(e.zoom) || e.zoom <= 0 || (a = { ...e }, _ = !0, R(), L("camera", { camera: { ...a }, reason: "api" }));
407
- },
408
- fit: () => {
409
- x || Y();
768
+ L || !Number.isFinite(e.centerX) || !Number.isFinite(e.centerY) || !Number.isFinite(e.zoom) || e.zoom <= 0 || z({ ...e }, "api", !0);
410
769
  },
770
+ fit: (e, a) => I(e, a, "api"),
771
+ reveal: (e, a) => $(() => {
772
+ const o = B(e);
773
+ return o ? z(Ue(E, o, Y, a), "api", !0) : "missing";
774
+ }),
411
775
  focusItem(e) {
412
- if (!u?.items.some((t) => t.id === e)) return !1;
413
- const r = Array.from(w.querySelectorAll("button")).find(
414
- (t) => t.dataset.itemId === e
776
+ if (!k?.items.some((o) => o.id === e)) return !1;
777
+ const a = Array.from(g.querySelectorAll("button")).find(
778
+ (o) => o.dataset.itemId === e
415
779
  );
416
- return r?.focus(), !!r;
780
+ return a?.focus(), !!a;
417
781
  },
418
782
  destroy() {
419
- if (!x) {
420
- if (x = !0, m++, A) {
783
+ if (!L) {
784
+ if (L = !0, x.stop(), P++, D = void 0, M && (c.cancelAnimationFrame ?? c.clearTimeout)(M), O) {
421
785
  try {
422
- o.releasePointerCapture(A.pointerId);
786
+ s.releasePointerCapture(O.pointerId);
423
787
  } catch {
424
788
  }
425
- A = void 0;
789
+ O = void 0;
426
790
  }
427
- for (const [e, r] of B)
428
- r.resolve({ status: "destroyed", revision: e });
429
- B.clear(), z(new Error("Viewer was destroyed."));
430
- for (const e of N.values()) s.fonts.delete(e);
431
- N.clear(), J.disconnect(), U.clear(), y.replaceChildren(), u = void 0;
791
+ for (const [e, a] of J)
792
+ a.resolve({ status: "destroyed", revision: e });
793
+ J.clear(), me();
794
+ for (const e of W) pe(r, e);
795
+ W.clear(), ee.disconnect(), F("anchors", { anchors: [] }), p.destroy(), G.clear(), n.replaceChildren(), k = void 0;
432
796
  }
433
797
  }
434
798
  };
799
+ return xe;
435
800
  }
436
801
  export {
437
- Ae as fontMetricsVersion,
438
- be as mountViewer,
439
- ke as runtimeVersion
802
+ ze as ZOOM_MAX,
803
+ $e as ZOOM_MIN,
804
+ kt as fontMetricsVersion,
805
+ bt as mountViewer,
806
+ St as runtimeVersion
440
807
  };