@draftably/mermaid 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +64 -2
- package/dist/LICENSE +21 -0
- package/dist/cdn/font-data-DbrpaYkG-vzB__apN.mjs +30 -0
- package/dist/cdn/index-MjBeFYcO.mjs +7738 -0
- package/dist/cdn/mermaid-facade-BoLWBerE.mjs +289 -0
- package/dist/cdn/mermaid-importer-SlRnjUhj.mjs +3753 -0
- package/dist/chunks/mermaid-facade-BoLWBerE.js +289 -0
- package/dist/chunks/mermaid-importer-IVovOQE9.js +3753 -0
- package/dist/mermaid.esm.min.mjs +13 -0
- package/dist/mermaid.js +117 -0
- package/dist/types/packages/mermaid/src/index.d.ts +59 -0
- package/dist/types/src/dsl/cells.d.ts +91 -0
- package/dist/types/src/dsl/channels.d.ts +53 -0
- package/dist/types/src/dsl/compile.d.ts +162 -0
- package/dist/types/src/dsl/frame.d.ts +38 -0
- package/dist/types/src/dsl/lanes.d.ts +23 -0
- package/dist/types/src/dsl/legend-notes.d.ts +3 -0
- package/dist/types/src/dsl/project.d.ts +39 -0
- package/dist/types/src/dsl/syntax.d.ts +317 -0
- package/dist/types/src/import/import-core.d.ts +105 -0
- package/dist/types/src/import/mermaid-facade.d.ts +120 -0
- package/dist/types/src/import/mermaid-importer.d.ts +4 -0
- package/dist/types/src/import/mermaid-sequence.d.ts +8 -0
- package/dist/types/src/model/appearance.d.ts +209 -0
- package/dist/types/src/model/bounds.d.ts +19 -0
- package/dist/types/src/model/document.d.ts +24 -0
- package/dist/types/src/model/font-faces.d.ts +24 -0
- package/dist/types/src/model/fonts.d.ts +47 -0
- package/dist/types/src/model/footnote.d.ts +34 -0
- package/dist/types/src/model/geometry.d.ts +29 -0
- package/dist/types/src/model/graph.d.ts +53 -0
- package/dist/types/src/model/heading.d.ts +38 -0
- package/dist/types/src/model/icons.d.ts +2 -0
- package/dist/types/src/model/labels.d.ts +88 -0
- package/dist/types/src/model/link.d.ts +63 -0
- package/dist/types/src/model/markers.d.ts +47 -0
- package/dist/types/src/model/note.d.ts +75 -0
- package/dist/types/src/model/rich-text.d.ts +24 -0
- package/dist/types/src/model/routes.d.ts +170 -0
- package/dist/types/src/model/status.d.ts +84 -0
- package/dist/types/src/model/styles.d.ts +13 -0
- package/dist/types/src/model/types.d.ts +277 -0
- package/package.json +36 -3
|
@@ -0,0 +1,3753 @@
|
|
|
1
|
+
import { MERMAID_VERSION as Wt } from "./mermaid-facade-BoLWBerE.mjs";
|
|
2
|
+
const co = {
|
|
3
|
+
"sans-500": { unitsPerEm: 1e3, fallback: 1003, advances: { 0: 646, 1: 415, 2: 616, 3: 627, 4: 656, 5: 603, 6: 630, 7: 571, 8: 629, 9: 630, " ": 267, "!": 304, '"': 494, "#": 639, $: 646, "%": 993, "&": 653, "'": 313, "(": 369, ")": 369, "*": 521, "+": 667, ",": 303, "-": 462, ".": 303, "/": 370, ":": 303, ";": 315, "<": 667, "=": 667, ">": 667, "?": 527, "@": 982, A: 709, B: 657, C: 733, D: 722, E: 603, F: 589, G: 748, H: 745, I: 272, J: 575, K: 688, L: 565, M: 913, N: 756, O: 767, P: 642, Q: 769, R: 648, S: 646, T: 653, U: 740, V: 709, W: 1003, X: 701, Y: 696, Z: 641, "[": 369, "\\": 370, "]": 369, "^": 477, _: 463, "`": 337, a: 568, b: 618, c: 577, d: 618, e: 587, f: 379, g: 620, h: 602, i: 252, j: 252, k: 559, l: 252, m: 888, n: 602, o: 604, p: 618, q: 618, r: 387, s: 539, t: 340, u: 602, v: 575, w: 829, x: 557, y: 575, z: 559, "{": 440, "|": 346, "}": 440, "~": 667, " ": 267, "¡": 304, "¢": 577, "£": 620, "¤": 737, "¥": 557, "¦": 293, "§": 568, "¨": 602, "©": 914, ª: 457, "«": 608, "¬": 667, "": 0, "®": 665, "¯": 465, "°": 457, "±": 667, "²": 448, "³": 455, "´": 337, µ: 600, "¶": 601, "·": 303, "¸": 300, "¹": 314, º: 485, "»": 608, "¼": 817, "½": 858, "¾": 895, "¿": 527, À: 709, Á: 709, Â: 709, Ã: 709, Ä: 709, Å: 709, Æ: 1003, Ç: 733, È: 603, É: 603, Ê: 603, Ë: 603, Ì: 272, Í: 272, Î: 272, Ï: 272, Ð: 743, Ñ: 756, Ò: 767, Ó: 767, Ô: 767, Õ: 767, Ö: 767, "×": 667, Ø: 767, Ù: 740, Ú: 740, Û: 740, Ü: 740, Ý: 696, Þ: 647, ß: 630, à: 568, á: 568, â: 568, ã: 568, ä: 568, å: 568, æ: 915, ç: 577, è: 587, é: 587, ê: 587, ë: 587, ì: 252, í: 252, î: 252, ï: 252, ð: 588, ñ: 602, ò: 604, ó: 604, ô: 604, õ: 604, ö: 604, "÷": 667, ø: 604, ù: 602, ú: 602, û: 602, ü: 602, ý: 575, þ: 618, ÿ: 575, "‘": 277, "’": 277, "“": 474, "”": 471, "–": 500, "—": 1e3, "…": 910, "•": 533, "→": 1e3, "←": 1e3, "≤": 549, "≥": 549, "≠": 549, "€": 672 } },
|
|
4
|
+
"sans-600": { unitsPerEm: 1e3, fallback: 1020, advances: { 0: 660, 1: 423, 2: 623, 3: 636, 4: 666, 5: 612, 6: 640, 7: 576, 8: 640, 9: 640, " ": 252, "!": 321, '"': 523, "#": 644, $: 650, "%": 1004, "&": 663, "'": 326, "(": 373, ")": 373, "*": 540, "+": 673, ",": 319, "-": 465, ".": 319, "/": 379, ":": 319, ";": 329, "<": 673, "=": 673, ">": 673, "?": 543, "@": 999, A: 728, B: 659, C: 737, D: 722, E: 605, F: 588, G: 749, H: 746, I: 277, J: 580, K: 703, L: 565, M: 922, N: 759, O: 769, P: 645, Q: 773, R: 652, S: 650, T: 660, U: 736, V: 728, W: 1020, X: 720, Y: 713, Z: 652, "[": 373, "\\": 379, "]": 373, "^": 481, _: 469, "`": 351, a: 574, b: 624, c: 583, d: 624, e: 591, f: 389, g: 625, h: 612, i: 262, j: 262, k: 569, l: 262, m: 900, n: 612, o: 609, p: 624, q: 624, r: 397, s: 549, t: 353, u: 612, v: 587, w: 839, x: 569, y: 588, z: 566, "{": 455, "|": 359, "}": 455, "~": 673, " ": 252, "¡": 321, "¢": 583, "£": 629, "¤": 749, "¥": 563, "¦": 316, "§": 568, "¨": 612, "©": 914, ª: 460, "«": 634, "¬": 673, "": 0, "®": 664, "¯": 452, "°": 458, "±": 673, "²": 454, "³": 463, "´": 351, µ: 614, "¶": 600, "·": 319, "¸": 332, "¹": 324, º: 487, "»": 634, "¼": 831, "½": 870, "¾": 907, "¿": 543, À: 728, Á: 728, Â: 728, Ã: 728, Ä: 728, Å: 728, Æ: 1013, Ç: 737, È: 605, É: 605, Ê: 605, Ë: 605, Ì: 277, Í: 277, Î: 277, Ï: 277, Ð: 751, Ñ: 759, Ò: 769, Ó: 769, Ô: 769, Õ: 769, Ö: 769, "×": 673, Ø: 769, Ù: 736, Ú: 736, Û: 736, Ü: 736, Ý: 713, Þ: 658, ß: 644, à: 574, á: 574, â: 574, ã: 574, ä: 574, å: 574, æ: 913, ç: 583, è: 591, é: 591, ê: 591, ë: 591, ì: 262, í: 262, î: 262, ï: 262, ð: 594, ñ: 612, ò: 609, ó: 609, ô: 609, õ: 609, ö: 609, "÷": 673, ø: 609, ù: 612, ú: 612, û: 612, ü: 612, ý: 588, þ: 624, ÿ: 588, "‘": 294, "’": 294, "“": 507, "”": 501, "–": 500, "—": 1e3, "…": 956, "•": 503, "→": 1e3, "←": 1e3, "≤": 549, "≥": 549, "≠": 549, "€": 679 } },
|
|
5
|
+
"serif-600": { unitsPerEm: 1e3, fallback: 1020, advances: { 0: 547, 1: 547, 2: 547, 3: 547, 4: 547, 5: 547, 6: 547, 7: 547, 8: 547, 9: 547, " ": 228, "!": 314, '"': 423, "#": 544, $: 538, "%": 949, "&": 739, "'": 206, "(": 384, ")": 384, "*": 458, "+": 548, ",": 307, "-": 335, ".": 307, "/": 364, ":": 307, ";": 307, "<": 548, "=": 548, ">": 548, "?": 430, "@": 867, A: 712, B: 668, C: 663, D: 744, E: 634, F: 610, G: 725, H: 809, I: 387, J: 394, K: 726, L: 616, M: 930, N: 757, O: 742, P: 637, Q: 742, R: 707, S: 560, T: 650, U: 757, V: 706, W: 1020, X: 678, Y: 667, Z: 592, "[": 356, "\\": 364, "]": 356, "^": 548, _: 528, "`": 400, a: 554, b: 630, c: 527, d: 623, e: 540, f: 374, g: 573, h: 650, i: 336, j: 313, k: 615, l: 337, m: 961, n: 652, o: 590, p: 632, q: 613, r: 475, s: 475, t: 368, u: 640, v: 581, w: 850, x: 585, y: 592, z: 497, "{": 365, "|": 301, "}": 365, "~": 548, " ": 228, "¡": 314, "¢": 538, "£": 539, "¤": 520, "¥": 538, "¦": 301, "§": 514, "¨": 400, "©": 750, ª: 385, "«": 572, "¬": 548, "": 0, "®": 465, "¯": 400, "°": 344, "±": 548, "²": 390, "³": 390, "´": 400, µ: 626, "¶": 622, "·": 307, "¸": 400, "¹": 390, º: 409, "»": 572, "¼": 918, "½": 949, "¾": 918, "¿": 430, À: 712, Á: 712, Â: 712, Ã: 712, Ä: 712, Å: 712, Æ: 943, Ç: 663, È: 634, É: 634, Ê: 634, Ë: 634, Ì: 387, Í: 387, Î: 387, Ï: 387, Ð: 744, Ñ: 757, Ò: 742, Ó: 742, Ô: 742, Õ: 742, Ö: 742, "×": 548, Ø: 742, Ù: 757, Ú: 757, Û: 757, Ü: 757, Ý: 667, Þ: 638, ß: 656, à: 554, á: 554, â: 554, ã: 554, ä: 554, å: 554, æ: 831, ç: 527, è: 540, é: 540, ê: 540, ë: 540, ì: 336, í: 336, î: 336, ï: 336, ð: 577, ñ: 652, ò: 590, ó: 590, ô: 590, õ: 590, ö: 590, "÷": 548, ø: 590, ù: 640, ú: 640, û: 640, ü: 640, ý: 592, þ: 622, ÿ: 592, "‘": 236, "’": 236, "“": 460, "”": 459, "–": 528, "—": 828, "…": 853, "•": 320, "→": 1e3, "←": 1e3, "≤": 549, "≥": 549, "≠": 549, "€": 538 } },
|
|
6
|
+
"mono-500": { unitsPerEm: 1e3, fallback: 600, advances: { 0: 600, 1: 600, 2: 600, 3: 600, 4: 600, 5: 600, 6: 600, 7: 600, 8: 600, 9: 600, " ": 600, "!": 600, '"': 600, "#": 600, $: 600, "%": 600, "&": 600, "'": 600, "(": 600, ")": 600, "*": 600, "+": 600, ",": 600, "-": 600, ".": 600, "/": 600, ":": 600, ";": 600, "<": 600, "=": 600, ">": 600, "?": 600, "@": 600, A: 600, B: 600, C: 600, D: 600, E: 600, F: 600, G: 600, H: 600, I: 600, J: 600, K: 600, L: 600, M: 600, N: 600, O: 600, P: 600, Q: 600, R: 600, S: 600, T: 600, U: 600, V: 600, W: 600, X: 600, Y: 600, Z: 600, "[": 600, "\\": 600, "]": 600, "^": 600, _: 600, "`": 600, a: 600, b: 600, c: 600, d: 600, e: 600, f: 600, g: 600, h: 600, i: 600, j: 600, k: 600, l: 600, m: 600, n: 600, o: 600, p: 600, q: 600, r: 600, s: 600, t: 600, u: 600, v: 600, w: 600, x: 600, y: 600, z: 600, "{": 600, "|": 600, "}": 600, "~": 600, " ": 600, "¡": 600, "¢": 600, "£": 600, "¤": 600, "¥": 600, "¦": 600, "§": 600, "¨": 600, "©": 600, ª: 600, "«": 600, "¬": 600, "": 0, "®": 600, "¯": 600, "°": 600, "±": 600, "²": 600, "³": 600, "´": 600, µ: 600, "¶": 600, "·": 600, "¸": 600, "¹": 600, º: 600, "»": 600, "¼": 600, "½": 600, "¾": 600, "¿": 600, À: 600, Á: 600, Â: 600, Ã: 600, Ä: 600, Å: 600, Æ: 600, Ç: 600, È: 600, É: 600, Ê: 600, Ë: 600, Ì: 600, Í: 600, Î: 600, Ï: 600, Ð: 600, Ñ: 600, Ò: 600, Ó: 600, Ô: 600, Õ: 600, Ö: 600, "×": 600, Ø: 600, Ù: 600, Ú: 600, Û: 600, Ü: 600, Ý: 600, Þ: 600, ß: 600, à: 600, á: 600, â: 600, ã: 600, ä: 600, å: 600, æ: 600, ç: 600, è: 600, é: 600, ê: 600, ë: 600, ì: 600, í: 600, î: 600, ï: 600, ð: 600, ñ: 600, ò: 600, ó: 600, ô: 600, õ: 600, ö: 600, "÷": 600, ø: 600, ù: 600, ú: 600, û: 600, ü: 600, ý: 600, þ: 600, ÿ: 600, "‘": 600, "’": 600, "“": 600, "”": 600, "–": 600, "—": 600, "…": 600, "•": 600, "→": 602, "←": 602, "≤": 549, "≥": 549, "≠": 549, "€": 600 } }
|
|
7
|
+
}, rt = "269b2d3580f4", Pn = {
|
|
8
|
+
"sans-500": {
|
|
9
|
+
family: `Draft Inter ${rt}`,
|
|
10
|
+
weight: 500,
|
|
11
|
+
file: "inter-latin-500-normal.woff2"
|
|
12
|
+
},
|
|
13
|
+
"sans-600": {
|
|
14
|
+
family: `Draft Inter ${rt}`,
|
|
15
|
+
weight: 600,
|
|
16
|
+
file: "inter-latin-600-normal.woff2"
|
|
17
|
+
},
|
|
18
|
+
"serif-600": {
|
|
19
|
+
family: `Draft Source Serif ${rt}`,
|
|
20
|
+
weight: 600,
|
|
21
|
+
file: "source-serif-4-latin-600-normal.woff2"
|
|
22
|
+
},
|
|
23
|
+
"mono-500": {
|
|
24
|
+
family: `Draft JetBrains Mono ${rt}`,
|
|
25
|
+
weight: 500,
|
|
26
|
+
file: "jetbrains-mono-latin-500-normal.woff2"
|
|
27
|
+
}
|
|
28
|
+
}, fo = ["sans", "serif", "mono"], ho = {
|
|
29
|
+
sans: "Inter, Arial, sans-serif",
|
|
30
|
+
serif: "'Source Serif 4', Georgia, serif",
|
|
31
|
+
mono: "'JetBrains Mono', Menlo, Consolas, monospace"
|
|
32
|
+
}, Fn = (e, t) => e === "serif" ? "serif-600" : e === "mono" ? "mono-500" : t ? "sans-600" : "sans-500", uo = (e) => `'${Pn[Fn(e, !0)].family}', ${ho[e]}`;
|
|
33
|
+
function gt(e, t, i, o) {
|
|
34
|
+
const s = Fn(e, t);
|
|
35
|
+
return { role: e, face: s, family: uo(e), weight: Pn[s].weight, size: i, lineHeight: o };
|
|
36
|
+
}
|
|
37
|
+
const po = co;
|
|
38
|
+
function pe(e, t) {
|
|
39
|
+
const i = po[t.face];
|
|
40
|
+
let o = 0;
|
|
41
|
+
for (const s of e) o += i.advances[s] ?? i.fallback;
|
|
42
|
+
return o * t.size / i.unitsPerEm;
|
|
43
|
+
}
|
|
44
|
+
function Cn(e) {
|
|
45
|
+
const t = [];
|
|
46
|
+
let i = "";
|
|
47
|
+
for (const o of e.split(/(?<=[/._:-])(?=[^/._:-])|(?<=[a-z0-9])(?=[A-Z])/))
|
|
48
|
+
/[\p{L}\p{N}]/u.test(o) ? (t.push(i + o), i = "") : i += o;
|
|
49
|
+
return i && t.length ? t[t.length - 1] += i : i && t.push(i), t.length > 1 && t[t.length - 1].length <= 3 && t.splice(-2, 2, t[t.length - 2] + t[t.length - 1]), t;
|
|
50
|
+
}
|
|
51
|
+
function jn(e, t) {
|
|
52
|
+
return Math.max(
|
|
53
|
+
0,
|
|
54
|
+
...String(e).split(/\s+/).flatMap(Cn).map((i) => pe(i, t))
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
function go(e, t, i) {
|
|
58
|
+
const o = [];
|
|
59
|
+
let s = "";
|
|
60
|
+
for (const r of e.split(/\s+/)) {
|
|
61
|
+
if (!r) continue;
|
|
62
|
+
const l = o[o.length - 1];
|
|
63
|
+
!s && l !== void 0 && /\d$/.test(l) && /^(%|[\p{L}µ]{1,3}[.,;:)]?)$/u.test(r) && pe(l + " " + r, i) <= t ? o[o.length - 1] = l + " " + r : s && pe(s + " " + r, i) <= t ? (o.push(s + " " + r), s = "") : (s && o.push(s), s = "", !/[\p{L}\p{N}]/u.test(r) && r.length <= 2 ? s = r : o.push(r));
|
|
64
|
+
}
|
|
65
|
+
if (s) {
|
|
66
|
+
const r = o[o.length - 1];
|
|
67
|
+
r !== void 0 && pe(r + " " + s, i) <= t ? o[o.length - 1] = r + " " + s : o.push(s);
|
|
68
|
+
}
|
|
69
|
+
return o;
|
|
70
|
+
}
|
|
71
|
+
function mo(e, t, i) {
|
|
72
|
+
const o = (l) => pe(l, i) <= t, s = [];
|
|
73
|
+
let r = "";
|
|
74
|
+
for (const l of e) {
|
|
75
|
+
if (!o(l)) {
|
|
76
|
+
r && s.push(r);
|
|
77
|
+
let h = "";
|
|
78
|
+
for (const c of Cn(l)) {
|
|
79
|
+
if (h && o(h + c)) {
|
|
80
|
+
h += c;
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (h && s.push(h), h = "", o(c)) {
|
|
84
|
+
h = c;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
for (const M of c)
|
|
88
|
+
h && !o(h + M) && (s.push(h), h = ""), h += M;
|
|
89
|
+
}
|
|
90
|
+
r = h;
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
r && !o(r + " " + l) ? (s.push(r), r = l) : r += (r ? " " : "") + l;
|
|
94
|
+
}
|
|
95
|
+
return s.push(r), s;
|
|
96
|
+
}
|
|
97
|
+
function wo(e, t, i, o) {
|
|
98
|
+
const s = e.map((n) => pe(n, o)), r = pe(" ", o);
|
|
99
|
+
if (s.some((n) => n > i)) return;
|
|
100
|
+
const l = [0];
|
|
101
|
+
for (const n of s) l.push(l[l.length - 1] + n);
|
|
102
|
+
const h = (n, a) => l[a] - l[n] + (a - n - 1) * r, c = h(0, s.length) / t, M = (c / 10) ** 2, m = [[0, ...s.map(() => 1 / 0)]], d = [[]];
|
|
103
|
+
for (let n = 1; n <= t; n++) {
|
|
104
|
+
m.push(s.map(() => 1 / 0).concat(1 / 0)), d.push([]);
|
|
105
|
+
for (let a = n; a <= s.length; a++)
|
|
106
|
+
for (let p = a - 1; p >= n - 1 && h(p, a) <= i; p--) {
|
|
107
|
+
const u = m[n - 1][p] + (h(p, a) - c) ** 2;
|
|
108
|
+
u < m[n][a] - M && ([m[n][a], d[n][a]] = [u, p]);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (!Number.isFinite(m[t][s.length])) return;
|
|
112
|
+
const f = [];
|
|
113
|
+
for (let n = t, a = s.length; n > 0; a = d[n][a], n--)
|
|
114
|
+
f.unshift(e.slice(d[n][a], a).join(" "));
|
|
115
|
+
return f;
|
|
116
|
+
}
|
|
117
|
+
function ot(e, t, i, o = !1) {
|
|
118
|
+
const s = [];
|
|
119
|
+
for (const r of String(e).split(`
|
|
120
|
+
`)) {
|
|
121
|
+
const l = o ? go(r, t, i) : r.split(/\s+/).filter(Boolean), h = mo(l, t, i);
|
|
122
|
+
s.push(
|
|
123
|
+
...o && h.length > 1 ? wo(l, h.length, t, i) ?? h : h
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
return s.length ? s : [""];
|
|
127
|
+
}
|
|
128
|
+
const Xt = ["drafting", "fieldnotes", "signal", "ink", "blueprint"], mt = "drafting", Tt = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950], wt = 500, yo = (e) => et[e]?.dark ? 900 : 100, Lt = [
|
|
129
|
+
"primary",
|
|
130
|
+
"secondary",
|
|
131
|
+
"slate",
|
|
132
|
+
"stone",
|
|
133
|
+
"blue",
|
|
134
|
+
"sky",
|
|
135
|
+
"teal",
|
|
136
|
+
"mint",
|
|
137
|
+
"green",
|
|
138
|
+
"amber",
|
|
139
|
+
"orange",
|
|
140
|
+
"red",
|
|
141
|
+
"rose",
|
|
142
|
+
"violet"
|
|
143
|
+
], Rt = (e) => Lt.includes(e), Kt = ["dashed", "solid"], Bn = () => ({
|
|
144
|
+
theme: mt,
|
|
145
|
+
overrides: {},
|
|
146
|
+
colors: []
|
|
147
|
+
}), Qt = {
|
|
148
|
+
paddingX: { min: 4, max: 48 },
|
|
149
|
+
paddingY: { min: 4, max: 48 },
|
|
150
|
+
radius: { min: 0, max: 24 }
|
|
151
|
+
}, Mo = /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i, et = {
|
|
152
|
+
drafting: {
|
|
153
|
+
label: "Drafting",
|
|
154
|
+
description: "Navy ink on cool paper, with drafting blue and marker gold",
|
|
155
|
+
dark: !1,
|
|
156
|
+
canvas: "#F7F7F4",
|
|
157
|
+
text: "#1B2433",
|
|
158
|
+
muted: "#586172",
|
|
159
|
+
connection: "#39414F",
|
|
160
|
+
node: { fill: "#FFFFFF", stroke: "#C3C8CF", ink: "#1B2433" },
|
|
161
|
+
group: { fill: "#EEEFEB", stroke: "#D5D8DC", ink: "#363F4D" },
|
|
162
|
+
paddingX: 12,
|
|
163
|
+
paddingY: 20,
|
|
164
|
+
radius: 4,
|
|
165
|
+
shadow: !1,
|
|
166
|
+
titleFont: "sans",
|
|
167
|
+
annotationFont: "sans",
|
|
168
|
+
titleSize: 13,
|
|
169
|
+
titleLine: 16,
|
|
170
|
+
annotationSize: 11,
|
|
171
|
+
chroma: 0.9,
|
|
172
|
+
primary: ["#2754A6", 700],
|
|
173
|
+
secondary: ["#F0B43C", 400]
|
|
174
|
+
},
|
|
175
|
+
fieldnotes: {
|
|
176
|
+
label: "Fieldnotes",
|
|
177
|
+
description: "Editorial serif titles on warm paper, indigo and terracotta",
|
|
178
|
+
dark: !1,
|
|
179
|
+
canvas: "#F6F1E6",
|
|
180
|
+
text: "#2F2B24",
|
|
181
|
+
muted: "#6B6559",
|
|
182
|
+
connection: "#57503F",
|
|
183
|
+
node: { fill: "#FFFCF5", stroke: "#CFC4AF", ink: "#2F2B24" },
|
|
184
|
+
group: { fill: "#EEE7D8", stroke: "#D8CDB8", ink: "#4A4539" },
|
|
185
|
+
paddingX: 18,
|
|
186
|
+
paddingY: 22,
|
|
187
|
+
radius: 3,
|
|
188
|
+
shadow: !1,
|
|
189
|
+
titleFont: "serif",
|
|
190
|
+
annotationFont: "sans",
|
|
191
|
+
titleSize: 15,
|
|
192
|
+
titleLine: 19,
|
|
193
|
+
annotationSize: 11,
|
|
194
|
+
chroma: 0.72,
|
|
195
|
+
primary: ["#34507F", 700],
|
|
196
|
+
secondary: ["#B5532F", 600],
|
|
197
|
+
hues: { green: [150, 0.1], amber: [80, 0.12], violet: [320, 0.1] }
|
|
198
|
+
},
|
|
199
|
+
signal: {
|
|
200
|
+
label: "Signal",
|
|
201
|
+
description: "Color-blind-safe Okabe–Ito hues on white, with monospace annotations",
|
|
202
|
+
dark: !1,
|
|
203
|
+
canvas: "#FFFFFF",
|
|
204
|
+
text: "#16202B",
|
|
205
|
+
muted: "#4F5B68",
|
|
206
|
+
connection: "#3B4652",
|
|
207
|
+
node: { fill: "#F5F7F9", stroke: "#C3CAD3", ink: "#16202B" },
|
|
208
|
+
group: { fill: "#F6F8FA", stroke: "#D9DEE4", ink: "#2A3644" },
|
|
209
|
+
paddingX: 16,
|
|
210
|
+
paddingY: 20,
|
|
211
|
+
radius: 6,
|
|
212
|
+
shadow: !1,
|
|
213
|
+
titleFont: "sans",
|
|
214
|
+
annotationFont: "mono",
|
|
215
|
+
titleSize: 13,
|
|
216
|
+
titleLine: 16,
|
|
217
|
+
annotationSize: 10.5,
|
|
218
|
+
chroma: 1,
|
|
219
|
+
primary: ["#0067A5", 600],
|
|
220
|
+
secondary: ["#E69F00", 500],
|
|
221
|
+
// After Okabe & Ito's set: blue, sky blue, bluish green, orange, vermilion, reddish purple.
|
|
222
|
+
hues: {
|
|
223
|
+
blue: [248, 0.15],
|
|
224
|
+
sky: [237, 0.11],
|
|
225
|
+
green: [163, 0.13],
|
|
226
|
+
mint: [172, 0.1],
|
|
227
|
+
amber: [72, 0.16],
|
|
228
|
+
orange: [55, 0.16],
|
|
229
|
+
red: [36, 0.18],
|
|
230
|
+
rose: [350, 0.13]
|
|
231
|
+
}
|
|
232
|
+
},
|
|
233
|
+
ink: {
|
|
234
|
+
label: "Ink",
|
|
235
|
+
description: "Sumi ink tones with indigo and a vermilion seal, generous spacing",
|
|
236
|
+
dark: !1,
|
|
237
|
+
canvas: "#F8F6F1",
|
|
238
|
+
text: "#1A1A1A",
|
|
239
|
+
muted: "#625F5A",
|
|
240
|
+
connection: "#3B3A38",
|
|
241
|
+
node: { fill: "#FFFFFF", stroke: "#C8C5BF", ink: "#1A1A1A" },
|
|
242
|
+
group: { fill: "#EFECE5", stroke: "#D9D5CC", ink: "#3F3D39" },
|
|
243
|
+
paddingX: 22,
|
|
244
|
+
paddingY: 26,
|
|
245
|
+
radius: 3,
|
|
246
|
+
shadow: !1,
|
|
247
|
+
titleFont: "sans",
|
|
248
|
+
annotationFont: "sans",
|
|
249
|
+
titleSize: 14,
|
|
250
|
+
titleLine: 19,
|
|
251
|
+
annotationSize: 11.5,
|
|
252
|
+
chroma: 0.6,
|
|
253
|
+
primary: ["#2B3A55", 900],
|
|
254
|
+
secondary: ["#C23B22", 600]
|
|
255
|
+
},
|
|
256
|
+
blueprint: {
|
|
257
|
+
label: "Blueprint",
|
|
258
|
+
description: "White lines on blueprint blue, cyan and yellow, monospace titles",
|
|
259
|
+
dark: !0,
|
|
260
|
+
canvas: "#13233D",
|
|
261
|
+
text: "#EAF1FB",
|
|
262
|
+
muted: "#A6B8D2",
|
|
263
|
+
connection: "#A9C2E6",
|
|
264
|
+
node: { fill: "#1B3154", stroke: "#45679B", ink: "#EAF1FB" },
|
|
265
|
+
group: { fill: "#172A48", stroke: "#2F4C78", ink: "#CFDCEF" },
|
|
266
|
+
paddingX: 16,
|
|
267
|
+
paddingY: 20,
|
|
268
|
+
radius: 3,
|
|
269
|
+
shadow: !1,
|
|
270
|
+
titleFont: "mono",
|
|
271
|
+
annotationFont: "sans",
|
|
272
|
+
titleSize: 12.5,
|
|
273
|
+
titleLine: 17,
|
|
274
|
+
annotationSize: 11,
|
|
275
|
+
chroma: 0.85,
|
|
276
|
+
primary: ["#7FC4F2", 300],
|
|
277
|
+
secondary: ["#F2C14E", 300]
|
|
278
|
+
}
|
|
279
|
+
}, Un = (e) => e <= 0.04045 ? e / 12.92 : ((e + 0.055) / 1.055) ** 2.4, xo = (e) => e <= 31308e-7 ? 12.92 * e : 1.055 * e ** (1 / 2.4) - 0.055;
|
|
280
|
+
function zn(e) {
|
|
281
|
+
const t = e.length === 4 ? e.replace(/[0-9a-f]/gi, (i) => i + i) : e;
|
|
282
|
+
return [1, 3, 5].map((i) => parseInt(t.slice(i, i + 2), 16) / 255);
|
|
283
|
+
}
|
|
284
|
+
function qt(e) {
|
|
285
|
+
const [t, i, o] = zn(e).map(Un), s = Math.cbrt(0.4122214708 * t + 0.5363325363 * i + 0.0514459929 * o), r = Math.cbrt(0.2119034982 * t + 0.6806995451 * i + 0.1073969566 * o), l = Math.cbrt(0.0883024619 * t + 0.2817188376 * i + 0.6299787005 * o), h = 0.2104542553 * s + 0.793617785 * r - 0.0040720468 * l, c = 1.9779984951 * s - 2.428592205 * r + 0.4505937099 * l, M = 0.0259040371 * s + 0.7827717662 * r - 0.808675766 * l;
|
|
286
|
+
return [h, Math.hypot(c, M), (Math.atan2(M, c) * 180 / Math.PI + 360) % 360];
|
|
287
|
+
}
|
|
288
|
+
function Vt([e, t, i]) {
|
|
289
|
+
const o = t * Math.cos(i * Math.PI / 180), s = t * Math.sin(i * Math.PI / 180), r = (e + 0.3963377774 * o + 0.2158037573 * s) ** 3, l = (e - 0.1055613458 * o - 0.0638541728 * s) ** 3, h = (e - 0.0894841775 * o - 1.291485548 * s) ** 3;
|
|
290
|
+
return [
|
|
291
|
+
4.0767416621 * r - 3.3077115913 * l + 0.2309699292 * h,
|
|
292
|
+
-1.2684380046 * r + 2.6097574011 * l - 0.3413193965 * h,
|
|
293
|
+
-0.0041960863 * r - 0.7034186147 * l + 1.707614701 * h
|
|
294
|
+
];
|
|
295
|
+
}
|
|
296
|
+
function Qe([e, t, i]) {
|
|
297
|
+
let o = t, s = Vt([e, o, i]);
|
|
298
|
+
for (; o > 0 && s.some((r) => r < -5e-4 || r > 1.0005); )
|
|
299
|
+
o = Math.max(0, o - 4e-3), s = Vt([e, o, i]);
|
|
300
|
+
return "#" + s.map(
|
|
301
|
+
(r) => Math.round(Math.min(1, Math.max(0, xo(Math.min(1, Math.max(0, r))))) * 255).toString(16).padStart(2, "0")
|
|
302
|
+
).join("").toUpperCase();
|
|
303
|
+
}
|
|
304
|
+
function Ot(e) {
|
|
305
|
+
const [t, i, o] = zn(e).map(Un);
|
|
306
|
+
return 0.2126 * t + 0.7152 * i + 0.0722 * o;
|
|
307
|
+
}
|
|
308
|
+
function yt(e, t) {
|
|
309
|
+
const [i, o] = [Ot(e), Ot(t)].sort((s, r) => r - s);
|
|
310
|
+
return (i + 0.05) / (o + 0.05);
|
|
311
|
+
}
|
|
312
|
+
const Zt = {
|
|
313
|
+
50: 0.975,
|
|
314
|
+
100: 0.945,
|
|
315
|
+
200: 0.9,
|
|
316
|
+
300: 0.84,
|
|
317
|
+
400: 0.62,
|
|
318
|
+
500: 0.56,
|
|
319
|
+
600: 0.5,
|
|
320
|
+
700: 0.44,
|
|
321
|
+
800: 0.38,
|
|
322
|
+
900: 0.32,
|
|
323
|
+
950: 0.26
|
|
324
|
+
}, Gt = (e) => e <= 300, qn = (e) => e >= 45 && e <= 110, $t = { 400: 0.8, 500: 0.74 }, bo = (e, t) => $t[e] === void 0 ? void 0 : $t[e] - (t < 65 ? 0.07 : 0), vo = (e, t) => Gt(e) || qn(t) && e in $t, Re = {
|
|
325
|
+
/** Dark title text on a pale fill. */
|
|
326
|
+
paleInk: 7,
|
|
327
|
+
/** White title text on a dark fill. */
|
|
328
|
+
darkInk: 4.5,
|
|
329
|
+
/** A shape's outline against the canvas when its fill alone does not separate it. */
|
|
330
|
+
outline: 3,
|
|
331
|
+
/** Connection lines and connection label text against the canvas. */
|
|
332
|
+
connection: 4.5,
|
|
333
|
+
/** A group's frame against the canvas. */
|
|
334
|
+
frame: 2
|
|
335
|
+
}, ut = (e) => Math.max(0.18, 1 - ((e - 0.6) / 0.42) ** 2), ko = {
|
|
336
|
+
slate: [255, 0.03],
|
|
337
|
+
stone: [70, 0.02],
|
|
338
|
+
blue: [258, 0.14],
|
|
339
|
+
sky: [232, 0.1],
|
|
340
|
+
teal: [195, 0.085],
|
|
341
|
+
mint: [168, 0.09],
|
|
342
|
+
green: [155, 0.12],
|
|
343
|
+
amber: [78, 0.14],
|
|
344
|
+
orange: [50, 0.15],
|
|
345
|
+
red: [32, 0.17],
|
|
346
|
+
rose: [358, 0.12],
|
|
347
|
+
violet: [305, 0.13]
|
|
348
|
+
}, Eo = (e) => Qe([0.24, 0.035, e]), Ao = "#FFFFFF";
|
|
349
|
+
function Ue(e, t, i) {
|
|
350
|
+
if (yt(e, t) >= i) return e;
|
|
351
|
+
const [o, s, r] = qt(e), l = Ot(t) > 0.18 ? -0.01 : 0.01;
|
|
352
|
+
let h = e;
|
|
353
|
+
for (let c = o; c > 0 && c < 1 && yt(h, t) < i; c += l)
|
|
354
|
+
h = Qe([c, s, r]);
|
|
355
|
+
return h;
|
|
356
|
+
}
|
|
357
|
+
function Jt(e, t, i, o, s, r, l) {
|
|
358
|
+
const h = vo(e, o), c = h ? Eo(o) : Ao, M = Gt(e) ? Re.paleInk : Re.darkInk;
|
|
359
|
+
let m = l ? qt(l)[0] : t, d = l ?? Qe([m, i * ut(m), o]);
|
|
360
|
+
for (; yt(d, c) < M && m > 0.05 && m < 0.995; )
|
|
361
|
+
m += h ? 5e-3 : -0.01, d = Qe([m, i * ut(m), o]);
|
|
362
|
+
const f = h ? m - 0.2 : r ? m + 0.14 : m - 0.08;
|
|
363
|
+
let n = Qe([f, i * ut(f) * 1.1, o]);
|
|
364
|
+
return yt(d, s) < Re.outline && (n = Ue(n, s, Re.outline)), { swatch: { fill: d, stroke: n, ink: c }, L: m };
|
|
365
|
+
}
|
|
366
|
+
const _o = 0.055;
|
|
367
|
+
function Gn(e, t, i, o, s) {
|
|
368
|
+
const r = /* @__PURE__ */ new Map();
|
|
369
|
+
let l = 1;
|
|
370
|
+
for (const h of Tt) {
|
|
371
|
+
const c = qn(e) ? bo(h, e) : void 0, M = Gt(h) ? Zt[h] : Math.min(c ?? Zt[h], l - _o);
|
|
372
|
+
let m = Jt(
|
|
373
|
+
h,
|
|
374
|
+
M,
|
|
375
|
+
t,
|
|
376
|
+
e,
|
|
377
|
+
i,
|
|
378
|
+
o,
|
|
379
|
+
s?.[1] === h ? s[0] : void 0
|
|
380
|
+
);
|
|
381
|
+
m.L >= l - 0.01 && (m = Jt(h, M, t, e, i, o)), l = m.L, r.set(h, m.swatch);
|
|
382
|
+
}
|
|
383
|
+
return r;
|
|
384
|
+
}
|
|
385
|
+
function en([e, t], i, o) {
|
|
386
|
+
const [s, r, l] = qt(e);
|
|
387
|
+
return Gn(l, r / ut(s), i, o, [e.toUpperCase(), t]);
|
|
388
|
+
}
|
|
389
|
+
const tn = /* @__PURE__ */ new Map();
|
|
390
|
+
function So(e, t = et[e].canvas) {
|
|
391
|
+
const i = e + t;
|
|
392
|
+
let o = tn.get(i);
|
|
393
|
+
if (!o) {
|
|
394
|
+
const s = et[e];
|
|
395
|
+
o = /* @__PURE__ */ new Map([
|
|
396
|
+
["primary", en(s.primary, t, s.dark)],
|
|
397
|
+
["secondary", en(s.secondary, t, s.dark)]
|
|
398
|
+
]);
|
|
399
|
+
for (const [r, l] of Object.entries(ko)) {
|
|
400
|
+
const [h, c] = s.hues?.[r] ?? l;
|
|
401
|
+
o.set(r, Gn(h, c * s.chroma, t, s.dark));
|
|
402
|
+
}
|
|
403
|
+
tn.set(i, o);
|
|
404
|
+
}
|
|
405
|
+
return o;
|
|
406
|
+
}
|
|
407
|
+
const Io = (e) => Math.round(e + 32), lt = /* @__PURE__ */ new Map();
|
|
408
|
+
function tt(e) {
|
|
409
|
+
const t = e ?? Bn(), i = JSON.stringify(t), o = lt.get(i);
|
|
410
|
+
if (o) return o;
|
|
411
|
+
const s = et[t.theme] ?? et[mt], r = t.overrides, l = r.titleFont ?? s.titleFont, h = r.annotationFont ?? s.annotationFont, c = r.canvas ?? s.canvas, M = new Map(
|
|
412
|
+
[...So(t.theme, c)].map(([n, a]) => [n, new Map(a)])
|
|
413
|
+
), m = /* @__PURE__ */ new Set();
|
|
414
|
+
for (const n of t.colors) {
|
|
415
|
+
M.has(n.family) || (M.set(n.family, /* @__PURE__ */ new Map()), m.add(n.family));
|
|
416
|
+
const a = M.get(n.family), p = a.get(n.shade);
|
|
417
|
+
(p || n.fill && n.stroke && n.ink) && a.set(n.shade, {
|
|
418
|
+
fill: n.fill ?? p.fill,
|
|
419
|
+
stroke: n.stroke ?? p.stroke,
|
|
420
|
+
ink: n.ink ?? p.ink
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
const d = gt(l, !0, s.titleSize, s.titleLine), f = {
|
|
424
|
+
theme: t.theme,
|
|
425
|
+
dark: s.dark,
|
|
426
|
+
// Preset colors are held to the contrast targets against the actual canvas; colors the file
|
|
427
|
+
// sets explicitly are used exactly as written.
|
|
428
|
+
canvas: c,
|
|
429
|
+
text: r.text ?? Ue(s.text, c, 7),
|
|
430
|
+
muted: Ue(s.muted, c, Re.connection),
|
|
431
|
+
connection: r.connection ?? Ue(s.connection, c, Re.connection),
|
|
432
|
+
node: {
|
|
433
|
+
fill: s.node.fill,
|
|
434
|
+
stroke: Ue(s.node.stroke, c, Re.outline),
|
|
435
|
+
ink: r.text ?? Ue(s.node.ink, s.node.fill, Re.paleInk)
|
|
436
|
+
},
|
|
437
|
+
group: {
|
|
438
|
+
fill: s.group.fill,
|
|
439
|
+
stroke: Ue(s.group.stroke, c, Re.frame),
|
|
440
|
+
ink: Ue(s.group.ink, s.group.fill, Re.paleInk)
|
|
441
|
+
},
|
|
442
|
+
paddingX: r.paddingX ?? s.paddingX,
|
|
443
|
+
paddingY: r.paddingY ?? s.paddingY,
|
|
444
|
+
radius: r.radius ?? s.radius,
|
|
445
|
+
shadow: s.shadow,
|
|
446
|
+
title: d,
|
|
447
|
+
groupTitle: d,
|
|
448
|
+
annotation: gt(
|
|
449
|
+
h,
|
|
450
|
+
!1,
|
|
451
|
+
s.annotationSize,
|
|
452
|
+
Math.round(s.annotationSize * 1.4)
|
|
453
|
+
),
|
|
454
|
+
groupHeader: Io(d.lineHeight),
|
|
455
|
+
families: M,
|
|
456
|
+
custom: m,
|
|
457
|
+
strikeRemoved: !!t.config?.strikeRemoved
|
|
458
|
+
};
|
|
459
|
+
return lt.size > 50 && lt.clear(), lt.set(i, f), f;
|
|
460
|
+
}
|
|
461
|
+
function nn(e, t = 0) {
|
|
462
|
+
if (!e.length) return { x: 70, y: 160, w: 240, h: 160 };
|
|
463
|
+
let i = 1 / 0, o = 1 / 0, s = -1 / 0, r = -1 / 0;
|
|
464
|
+
for (const l of e)
|
|
465
|
+
i = Math.min(i, l.x), o = Math.min(o, l.y), s = Math.max(s, l.x + l.w), r = Math.max(r, l.y + l.h);
|
|
466
|
+
return { x: i - t, y: o - t, w: s - i + t * 2, h: r - o + t * 2 };
|
|
467
|
+
}
|
|
468
|
+
const be = 24, To = 48, Dt = 97, Ve = 10, Mt = 18, Hn = (e, t = To) => ({
|
|
469
|
+
x: e.x + be,
|
|
470
|
+
y: e.y + t
|
|
471
|
+
}), Lo = 48;
|
|
472
|
+
function Yn(e) {
|
|
473
|
+
return e === "circle" || e === "icon" ? { w: 80, h: 80 } : e === "diamond" ? { w: 112, h: 112 } : e === "text" ? { w: 164, h: 38 } : { w: 164, h: 56 };
|
|
474
|
+
}
|
|
475
|
+
function xt(e, t, i, o, s = !1) {
|
|
476
|
+
if (e === "diamond") return { width: Math.max(40, t * 0.55), maxHeight: i * 0.45 };
|
|
477
|
+
if (e === "circle") return { width: Math.max(40, t * 0.7), maxHeight: i * 0.7 };
|
|
478
|
+
const r = e === "text" ? Math.min(o.paddingY, 11) : o.paddingY;
|
|
479
|
+
return {
|
|
480
|
+
width: Math.max(40, t - 2 * o.paddingX - (s ? 30 : 0) - (e === "pill" ? 8 : 0)),
|
|
481
|
+
maxHeight: i - 2 * r
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
function Ro(e, t, i, o) {
|
|
485
|
+
const s = t * o.title.lineHeight;
|
|
486
|
+
return e === "circle" ? Math.max(i, Math.ceil(s / 0.7)) : e === "text" ? s + 2 * Math.min(o.paddingY, 11) : s + 2 * o.paddingY;
|
|
487
|
+
}
|
|
488
|
+
const nt = (e, t, i) => ot(e, t, i.title, !0), Oo = 6;
|
|
489
|
+
function $o(e, t, i) {
|
|
490
|
+
const o = t - 2 * Oo;
|
|
491
|
+
for (let s = 1; s * i.title.lineHeight < o; s++) {
|
|
492
|
+
const r = o - s * i.title.lineHeight;
|
|
493
|
+
if (r >= 40 && nt(e, r, i).length <= s) return r;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
const on = 3, pt = (e, t = 1) => e.groupHeader + (t - 1) * e.groupTitle.lineHeight, Do = 168, Wn = (e, t = !1) => t ? { ...e.annotation, size: e.annotation.size + 1.5, lineHeight: e.annotation.lineHeight + 2 } : e.annotation, No = 140, Po = (e, t, i = !1) => ot(e, i ? Do : No, Wn(t, i)), ze = { out: 36, down: 22, label: 4 };
|
|
497
|
+
function He(e, t = tt(), i = !1) {
|
|
498
|
+
const o = Wn(t, i), s = Po(e, t, i), r = Math.max(...s.map((l) => pe(l, o))) + 16;
|
|
499
|
+
return {
|
|
500
|
+
w: Math.round(Math.max(36, r)),
|
|
501
|
+
h: Math.round(s.length * o.lineHeight + 6)
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
function sn(e, t) {
|
|
505
|
+
if (!e) return { right: ze.out, above: 0, below: ze.down };
|
|
506
|
+
const { w: i, h: o } = He(e, t, !0);
|
|
507
|
+
return {
|
|
508
|
+
right: ze.out + ze.label + i,
|
|
509
|
+
above: Math.max(0, o / 2 - ze.down / 2),
|
|
510
|
+
below: Math.max(ze.down, ze.down / 2 + o / 2)
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
const Et = 8, an = 16, Nt = 10, Fo = 64, Co = 240, Pt = (e) => Math.round(e + 14);
|
|
514
|
+
function jo(e, t) {
|
|
515
|
+
if (e.size?.height !== void 0) return { w: e.size.width, h: e.size.height };
|
|
516
|
+
if (e.size) {
|
|
517
|
+
const r = nt(e.label, e.size.width - 2 * t.paddingX, t).length;
|
|
518
|
+
return {
|
|
519
|
+
w: e.size.width,
|
|
520
|
+
h: r * t.title.lineHeight + 2 * Math.min(t.paddingY, Nt)
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
const i = 2 * t.paddingX, o = Math.min(Co, Math.max(Fo, Math.ceil(pe(e.label, t.title)) + i)), s = nt(e.label, o - i, t).length;
|
|
524
|
+
return { w: o, h: s * t.title.lineHeight + 2 * Math.min(t.paddingY, Nt) };
|
|
525
|
+
}
|
|
526
|
+
function Bo(e, t, i, o = 0) {
|
|
527
|
+
const s = e.filter((R) => !R.marker), r = new Map(s.map((R) => [R.id, jo(R, i)])), l = Math.max(
|
|
528
|
+
1,
|
|
529
|
+
t.columns ?? (t.direction === "down" ? 1 : s.reduce((R, L) => R + (L.span ?? 1), 0))
|
|
530
|
+
), h = /* @__PURE__ */ new Map();
|
|
531
|
+
let c = 0, M = 0;
|
|
532
|
+
for (const R of s) {
|
|
533
|
+
const L = Math.min(R.span ?? 1, l);
|
|
534
|
+
M + L > l && (c++, M = 0), h.set(R.id, { row: c, col: M, span: L }), M += L;
|
|
535
|
+
}
|
|
536
|
+
const m = Array(l).fill(0), d = Array(s.length ? c + 1 : 0).fill(0);
|
|
537
|
+
for (const R of s) {
|
|
538
|
+
const { row: L, col: H, span: I } = h.get(R.id);
|
|
539
|
+
I === 1 && (m[H] = Math.max(m[H], r.get(R.id).w)), d[L] = Math.max(d[L], r.get(R.id).h);
|
|
540
|
+
}
|
|
541
|
+
for (const R of s) {
|
|
542
|
+
const { col: L, span: H } = h.get(R.id), I = r.get(R.id).w - m.slice(L, L + H).reduce((P, O) => P + O, 0);
|
|
543
|
+
I > 0 && (m[L + H - 1] += I);
|
|
544
|
+
}
|
|
545
|
+
const f = o - m.reduce((R, L) => R + L, 0);
|
|
546
|
+
f > 0 && (m[l - 1] += f);
|
|
547
|
+
const n = [0], a = [0];
|
|
548
|
+
for (const R of m) n.push(n.at(-1) + R);
|
|
549
|
+
for (const R of d) a.push(a.at(-1) + R);
|
|
550
|
+
const p = n.at(-1), u = a.at(-1), g = /* @__PURE__ */ new Map();
|
|
551
|
+
for (const R of s) {
|
|
552
|
+
const { row: L, col: H, span: I } = h.get(R.id);
|
|
553
|
+
g.set(R.id, { x: n[H], y: a[L], w: n[H + I] - n[H], h: d[L] });
|
|
554
|
+
}
|
|
555
|
+
const x = Pt(i.groupTitle.lineHeight), E = l > 1 || t.direction === "right";
|
|
556
|
+
return e.forEach((R, L) => {
|
|
557
|
+
if (!R.marker) return;
|
|
558
|
+
const H = e.slice(L + 1).find((O) => !O.marker), I = H ? g.get(H.id) : void 0, P = Et / 2;
|
|
559
|
+
g.set(
|
|
560
|
+
R.id,
|
|
561
|
+
E ? { x: (I?.x ?? p) - P, y: -x, w: Et, h: u + x + an } : { x: 0, y: (I?.y ?? u) - P, w: p + an, h: Et }
|
|
562
|
+
);
|
|
563
|
+
}), { boxes: g, w: p, h: u };
|
|
564
|
+
}
|
|
565
|
+
const Uo = { bit: 24, byte: 48 }, zo = { bit: 32, byte: 16 };
|
|
566
|
+
function qo(e, t, i) {
|
|
567
|
+
const o = t.columns ?? zo[t.unit], s = t.unitWidth ?? Uo[t.unit], r = 2 * Math.min(i.paddingX, 6), l = /* @__PURE__ */ new Map();
|
|
568
|
+
let h = 0, c = 0;
|
|
569
|
+
for (const u of e) {
|
|
570
|
+
const g = [];
|
|
571
|
+
if (u.open)
|
|
572
|
+
g.push({ row: h, col: c, span: o - c }), h++, c = 0;
|
|
573
|
+
else
|
|
574
|
+
for (let x = u.span ?? 1; x > 0; ) {
|
|
575
|
+
const E = Math.min(x, o - c);
|
|
576
|
+
g.push({ row: h, col: c, span: E }), x -= E, c += E, c === o && (h++, c = 0);
|
|
577
|
+
}
|
|
578
|
+
l.set(u.id, g);
|
|
579
|
+
}
|
|
580
|
+
const M = c ? h + 1 : h, m = (u) => l.get(u).reduce((g, x) => x.span > g.span ? x : g), d = Math.max(
|
|
581
|
+
0,
|
|
582
|
+
...e.map((u) => nt(u.label, Math.max(8, m(u.id).span * s - r), i).length * i.title.lineHeight + 2 * Math.min(i.paddingY, Nt))
|
|
583
|
+
), f = (u) => ({
|
|
584
|
+
x: u.col * s,
|
|
585
|
+
y: u.row * d,
|
|
586
|
+
w: u.span * s,
|
|
587
|
+
h: d
|
|
588
|
+
}), n = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Map();
|
|
589
|
+
for (const u of e) {
|
|
590
|
+
const g = m(u.id), x = l.get(u.id).filter((E) => E !== g);
|
|
591
|
+
n.set(u.id, f(g)), x.length && a.set(u.id, x.map(f));
|
|
592
|
+
}
|
|
593
|
+
const p = t.ruler ? Math.round(i.annotation.lineHeight + 6) : 0;
|
|
594
|
+
return {
|
|
595
|
+
boxes: n,
|
|
596
|
+
pieces: a,
|
|
597
|
+
open: e.filter((u) => u.open).map((u) => u.id),
|
|
598
|
+
...t.ruler ? {
|
|
599
|
+
ruler: {
|
|
600
|
+
h: p,
|
|
601
|
+
ticks: Array.from({ length: o }, (u, g) => ({
|
|
602
|
+
x: g * s + s / 2,
|
|
603
|
+
label: String(g)
|
|
604
|
+
}))
|
|
605
|
+
}
|
|
606
|
+
} : {},
|
|
607
|
+
w: o * s,
|
|
608
|
+
h: M * d
|
|
609
|
+
};
|
|
610
|
+
}
|
|
611
|
+
const Go = /\[([^\]\n]+)\]\(([^)\s]+)\)/g;
|
|
612
|
+
function Ho(e, t, i) {
|
|
613
|
+
let o = "";
|
|
614
|
+
const s = [];
|
|
615
|
+
let r = 0;
|
|
616
|
+
for (const c of e.matchAll(Go)) {
|
|
617
|
+
const M = e.slice(r, c.index);
|
|
618
|
+
o += M + c[1], s.push(
|
|
619
|
+
...Array(M.length).fill(void 0),
|
|
620
|
+
...Array(c[1].length).fill(c[2])
|
|
621
|
+
), r = c.index + c[0].length;
|
|
622
|
+
}
|
|
623
|
+
o += e.slice(r), s.push(...Array(e.length - r).fill(void 0));
|
|
624
|
+
let l = 0;
|
|
625
|
+
const h = (c) => /\s/.test(o[c] ?? "");
|
|
626
|
+
return ot(o, t, i).map((c) => {
|
|
627
|
+
for (; l < o.length && h(l); ) l++;
|
|
628
|
+
const M = [];
|
|
629
|
+
for (const f of c)
|
|
630
|
+
if (f === " " && h(l)) {
|
|
631
|
+
const n = s[l - 1];
|
|
632
|
+
for (; l < o.length && h(l); ) l++;
|
|
633
|
+
M.push(n && n === s[l] ? n : void 0);
|
|
634
|
+
} else M.push(s[l++]);
|
|
635
|
+
const m = [];
|
|
636
|
+
M.forEach((f, n) => {
|
|
637
|
+
const a = m.at(-1);
|
|
638
|
+
a && a.href === f ? a.text += c[n] : m.push({ text: c[n], href: f, x: 0, w: 0 });
|
|
639
|
+
});
|
|
640
|
+
let d = 0;
|
|
641
|
+
for (const f of m)
|
|
642
|
+
f.x = d, f.w = pe(f.text, i), d += f.w;
|
|
643
|
+
return m.length ? m : [{ text: "", x: 0, w: 0 }];
|
|
644
|
+
});
|
|
645
|
+
}
|
|
646
|
+
const Yo = ["below", "above", "left", "right"], Xn = 280, Kn = { x: 12, y: 8 }, rn = Kn.x, Wo = Kn.y, Xo = 8;
|
|
647
|
+
function Ko(e, t) {
|
|
648
|
+
const i = e.annotation, o = Ho(t.text, (t.width ?? Xn) - rn * 2, i), s = Math.ceil(Math.max(...o.map((r) => r.reduce((l, h) => l + h.w, 0)))) + rn * 2;
|
|
649
|
+
return { note: t, lines: o, rect: { x: 0, y: 0, w: s, h: o.length * i.lineHeight + Wo * 2 } };
|
|
650
|
+
}
|
|
651
|
+
function Qo(e, t, i, { left: o, right: s, top: r }) {
|
|
652
|
+
const l = t.map(() => null);
|
|
653
|
+
for (const h of ["left", "right"]) {
|
|
654
|
+
let c = r;
|
|
655
|
+
t.map((M, m) => ({ note: M, i: m, row: i.get(M.near ?? "") })).filter((M) => M.row !== void 0 && (M.note.side ?? "right") === h).sort((M, m) => M.row - m.row).forEach(({ note: M, i: m, row: d }) => {
|
|
656
|
+
const { w: f, h: n } = Ko(e, M).rect, a = Math.max(c, Math.round(d - n / 2));
|
|
657
|
+
l[m] = { x: h === "right" ? s : o - f, y: a, w: f, h: n }, c = a + n + Xo;
|
|
658
|
+
});
|
|
659
|
+
}
|
|
660
|
+
return l;
|
|
661
|
+
}
|
|
662
|
+
const Vo = 1.1;
|
|
663
|
+
function Zo(e, t, i) {
|
|
664
|
+
const o = new Map(e), s = [...o].flatMap(
|
|
665
|
+
([r, l]) => Object.keys(l.lines).filter((h) => l.lines[h]).map((h) => ({ id: r, side: h, n: l.lines[h] }))
|
|
666
|
+
);
|
|
667
|
+
s.sort((r, l) => r.n - l.n || (r.id < l.id ? 1 : -1));
|
|
668
|
+
for (const { id: r, side: l } of s) {
|
|
669
|
+
if (!o.size || i(o) <= t * Vo) break;
|
|
670
|
+
const h = { ...o.get(r), lines: { ...o.get(r).lines, [l]: 0 } };
|
|
671
|
+
h[l] = l === "top" ? 0 : be, Object.values(h.lines).some(Boolean) ? o.set(r, h) : o.delete(r);
|
|
672
|
+
}
|
|
673
|
+
return o;
|
|
674
|
+
}
|
|
675
|
+
const Jo = 20, ln = 16, ct = 10;
|
|
676
|
+
function es(e, t, i = {}) {
|
|
677
|
+
const o = new Map(e.map((a) => [a.id, a])), s = (a) => {
|
|
678
|
+
const p = [];
|
|
679
|
+
for (let u = o.get(a); u && u.parent !== "root"; u = o.get(u.parent))
|
|
680
|
+
p.push(u.parent);
|
|
681
|
+
return p;
|
|
682
|
+
}, r = (a, p) => a === p || s(a).includes(p), l = /* @__PURE__ */ new Map(), h = (a, p) => {
|
|
683
|
+
const u = l.get(a) ?? { left: 0, right: 0, top: 0, bottom: 0 };
|
|
684
|
+
u[p]++, l.set(a, u);
|
|
685
|
+
}, c = (a) => ({ x: a.x + a.w / 2, y: a.y + a.h / 2 }), M = (a, p, u, g) => e.some((x) => x.id === a.id || x.id === g || !r(x.id, p.id) || x.id === p.id || r(a.id, x.id) || r(g, x.id) || !(u === "left" || u === "right" ? x.y < a.y + a.h + ct && x.y + x.h > a.y - ct : x.x < a.x + a.w + ct && x.x + x.w > a.x - ct) ? !1 : u === "right" ? x.x >= a.x + a.w : u === "left" ? x.x + x.w <= a.x : u === "bottom" ? x.y >= a.y + a.h : x.y + x.h <= a.y), m = (a, p) => [
|
|
686
|
+
...p.x > a.x + a.w ? ["right"] : [],
|
|
687
|
+
...p.x < a.x ? ["left"] : [],
|
|
688
|
+
...p.y > a.y + a.h ? ["bottom"] : [],
|
|
689
|
+
// A line leaves through the top only past the title band, which it may not cross.
|
|
690
|
+
...p.y < a.y ? ["top"] : []
|
|
691
|
+
];
|
|
692
|
+
for (const a of t) {
|
|
693
|
+
const p = o.get(a.source), u = o.get(a.target);
|
|
694
|
+
if (!p || !u || p === u || a.from !== "auto" || a.to !== "auto") continue;
|
|
695
|
+
const g = [p.id, ...s(p.id)], x = [u.id, ...s(u.id)].find((I) => g.includes(I) && I !== p.id && I !== u.id), E = x && o.get(x)?.type === "group" ? o.get(x) : void 0, R = (I) => {
|
|
696
|
+
let P = I;
|
|
697
|
+
for (; P.parent !== (E?.id ?? "root"); ) P = o.get(P.parent);
|
|
698
|
+
return P;
|
|
699
|
+
}, [L, H] = [R(p), R(u)];
|
|
700
|
+
if (E && L !== H) {
|
|
701
|
+
const I = (N, Q, z) => N === Q || m(Q, c(z)).some((Y) => !M(N, Q, Y, ""));
|
|
702
|
+
if (!e.some(
|
|
703
|
+
(N) => N.parent === E.id && N !== L && N !== H && ts(L, H, N)
|
|
704
|
+
) && I(p, L, u) && I(u, H, p)) continue;
|
|
705
|
+
const O = Math.abs(c(L).y - c(H).y) > Math.abs(c(L).x - c(H).x), y = (N, Q, z) => (c(N)[z] - c(Q)[z]) / Math.max(1, z === "x" ? Q.w : Q.h), D = O ? "x" : "y", w = y(p, L, D) + y(u, H, D), b = c(H)[O ? "y" : "x"] > c(L)[O ? "y" : "x"], _ = Math.abs(w) > 0.1 ? w > 0 : b;
|
|
706
|
+
h(E.id, O ? _ ? "right" : "left" : _ ? "bottom" : "top");
|
|
707
|
+
continue;
|
|
708
|
+
}
|
|
709
|
+
for (const [I, P] of [
|
|
710
|
+
[p, u],
|
|
711
|
+
[u, p]
|
|
712
|
+
]) {
|
|
713
|
+
const O = I.parent === "root" ? void 0 : o.get(I.parent);
|
|
714
|
+
if (!O || E && O.id === E.id || r(P.id, O.id)) continue;
|
|
715
|
+
const y = m(O, c(P));
|
|
716
|
+
!y.length || y.some((D) => !M(I, O, D, P.id)) || (y.some((D) => D === "left" || D === "right") ? h(O.id, c(I).y < c(O).y + 24 ? "top" : "bottom") : h(O.id, c(P).x < c(I).x ? "left" : "right"));
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
const d = i.standoff ?? Jo, f = Math.max(i.edgeGap ?? ln, i.portGap ?? ln), n = (a) => a ? 2 * d + (a - 1) * f : be;
|
|
720
|
+
return new Map(
|
|
721
|
+
[...l].map(([a, p]) => [
|
|
722
|
+
a,
|
|
723
|
+
{
|
|
724
|
+
left: n(p.left),
|
|
725
|
+
right: n(p.right),
|
|
726
|
+
top: p.top ? d + (p.top - 1) * f : 0,
|
|
727
|
+
bottom: n(p.bottom),
|
|
728
|
+
lines: p
|
|
729
|
+
}
|
|
730
|
+
])
|
|
731
|
+
);
|
|
732
|
+
}
|
|
733
|
+
function ts(e, t, i) {
|
|
734
|
+
const o = Math.min(e.x + e.w, t.x + t.w), s = Math.max(e.x, t.x), r = Math.min(e.y + e.h, t.y + t.h), l = Math.max(e.y, t.y), h = { x: Math.min(o, s), y: Math.min(r, l) }, c = { x: Math.max(o, s), y: Math.max(r, l) };
|
|
735
|
+
return i.x < c.x && i.x + i.w > h.x && i.y < c.y && i.y + i.h > h.y;
|
|
736
|
+
}
|
|
737
|
+
const cn = 20, dt = 20, ns = 12, os = 16;
|
|
738
|
+
function ss(e, t, i, o, s = (r) => He(r)) {
|
|
739
|
+
const r = /* @__PURE__ */ new Map();
|
|
740
|
+
for (const l of e.filter((h) => h.scope === "root")) {
|
|
741
|
+
const h = l.axis === "right", c = (u) => h ? u.x : u.y, M = (u) => h ? u.x + u.w : u.y + u.h, m = (u) => h ? u.y : u.x, d = (u) => h ? u.y + u.h : u.x + u.w, f = (u) => (c(u) + M(u)) / 2, n = (u) => (m(u) + d(u)) / 2, a = [...i.values()].filter((u) => u.parent === l.scope);
|
|
742
|
+
(l.bands?.map((u) => u.map((g) => i.get(g))) ?? [a]).forEach((u) => {
|
|
743
|
+
const g = Math.min(...u.map(m)), x = Math.max(...u.map(d)), E = Math.min(...u.map(c)), R = Math.max(...u.map(M)), L = new Set(u.map((O) => O.id)), H = (O) => [...i.values()].some(
|
|
744
|
+
(y) => y.parent === l.scope && !L.has(y.id) && c(y) < R && M(y) > E && (O ? d(y) <= g : m(y) >= x)
|
|
745
|
+
), I = { before: !H(!0), after: !H(!1) }, P = [];
|
|
746
|
+
for (const O of t) {
|
|
747
|
+
if (o.has(O.id) || O.from !== "auto" || O.to !== "auto") continue;
|
|
748
|
+
const y = i.get(O.source), D = i.get(O.target);
|
|
749
|
+
if (!y || !D || y === D || !L.has(y.id) || !L.has(D.id) || y.type === "group" || D.type === "group") continue;
|
|
750
|
+
const w = f(D) < f(y), [b, _] = w ? [D, y] : [y, D], N = Math.min(n(y), n(D)) - 8, Q = Math.max(n(y), n(D)) + 8, z = u.filter(
|
|
751
|
+
(A) => A !== y && A !== D && c(A) >= M(b) - 1 && M(A) <= c(_) + 1
|
|
752
|
+
);
|
|
753
|
+
if (!z.some((A) => m(A) < Q && d(A) > N) && !(w && z.length)) continue;
|
|
754
|
+
const $ = (A, F) => !u.some(
|
|
755
|
+
(Z) => Z !== A && c(Z) < M(A) && M(Z) > c(A) && (F ? d(Z) <= m(A) : m(Z) >= d(A))
|
|
756
|
+
), k = (A) => !I[A ? "before" : "after"] || !$(y, A) || !$(D, A) ? 1 / 0 : A ? m(y) - g + (m(D) - g) : x - d(y) + (x - d(D)), [T, j] = [k(!0), k(!1)];
|
|
757
|
+
if (!Number.isFinite(T) && !Number.isFinite(j)) continue;
|
|
758
|
+
const v = T === j ? !w : T < j;
|
|
759
|
+
P.push({ id: O.id, before: v, from: f(b), to: f(_), back: w });
|
|
760
|
+
}
|
|
761
|
+
for (const O of [!0, !1]) {
|
|
762
|
+
const y = P.filter((b) => b.before === O).sort((b, _) => b.to - b.from - (_.to - _.from) || b.from - _.from), D = [], w = /* @__PURE__ */ new Set();
|
|
763
|
+
for (const b of y) {
|
|
764
|
+
const _ = t.find((A) => A.id === b.id);
|
|
765
|
+
if (w.has(_.source) || w.has(_.target)) continue;
|
|
766
|
+
w.add(_.source).add(_.target);
|
|
767
|
+
let N = 0;
|
|
768
|
+
for (; D[N]?.some(([A, F]) => b.from < F + dt && b.to > A - dt); ) N++;
|
|
769
|
+
(D[N] ??= []).push([b.from, b.to]);
|
|
770
|
+
const Q = t.find((A) => A.id === b.id), z = i.get(Q.target), Y = O ? g - cn - N * dt : x + cn + N * dt, $ = is(z, u, !b.back, c, M), k = Math.min(os, (d(z) - m(z)) / 2 - ns), T = as(z, u, !b.back, Q.id, t, i, c, M, m, d), j = z.shape === "diamond" && T.length > 0 || T.some((A) => {
|
|
771
|
+
if (!A.label) return !1;
|
|
772
|
+
const { w: F, h: Z } = s(A.label);
|
|
773
|
+
return (h ? Z : F) / 2 + 2 > k;
|
|
774
|
+
}), v = j ? f(z) : b.back ? M(z) + $ / 2 : c(z) - $ / 2;
|
|
775
|
+
r.set(b.id, {
|
|
776
|
+
...h ? { y: Math.round(Y) } : { x: Math.round(Y) },
|
|
777
|
+
enter: Math.round(v),
|
|
778
|
+
out: !0,
|
|
779
|
+
...j ? { face: !0 } : {}
|
|
780
|
+
});
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
});
|
|
784
|
+
}
|
|
785
|
+
return r;
|
|
786
|
+
}
|
|
787
|
+
function is(e, t, i, o, s) {
|
|
788
|
+
const r = t.filter((l) => l !== e && (i ? s(l) <= o(e) : o(l) >= s(e))).map((l) => i ? o(e) - s(l) : o(l) - s(e));
|
|
789
|
+
return Math.min(48, ...r);
|
|
790
|
+
}
|
|
791
|
+
function as(e, t, i, o, s, r, l, h, c, M) {
|
|
792
|
+
const m = new Set(
|
|
793
|
+
t.filter(
|
|
794
|
+
(f) => f !== e && (i ? h(f) <= l(e) : l(f) >= h(e)) && c(f) < M(e) && M(f) > c(e)
|
|
795
|
+
).map((f) => f.id)
|
|
796
|
+
), d = (f) => {
|
|
797
|
+
for (let n = r.get(f); n; n = r.get(n.parent)) if (m.has(n.id)) return !0;
|
|
798
|
+
return !1;
|
|
799
|
+
};
|
|
800
|
+
return s.filter(
|
|
801
|
+
(f) => f.id !== o && (f.source === e.id && d(f.target) || f.target === e.id && d(f.source))
|
|
802
|
+
);
|
|
803
|
+
}
|
|
804
|
+
const rs = ["vscode", "vscode-insiders", "cursor", "windsurf", "zed"], dn = [
|
|
805
|
+
"arrow",
|
|
806
|
+
"none",
|
|
807
|
+
"triangle",
|
|
808
|
+
"open-triangle",
|
|
809
|
+
"diamond",
|
|
810
|
+
"open-diamond",
|
|
811
|
+
"circle",
|
|
812
|
+
"cross"
|
|
813
|
+
];
|
|
814
|
+
function Qn(e) {
|
|
815
|
+
return {
|
|
816
|
+
title: gt(e.title.role, !0, 20, 26),
|
|
817
|
+
subtitle: gt(e.annotation.role, !1, 13, 18)
|
|
818
|
+
};
|
|
819
|
+
}
|
|
820
|
+
const fn = 360, ls = 70;
|
|
821
|
+
function cs(e, t) {
|
|
822
|
+
const i = Qn(e).subtitle, o = pe("abcdefghijklmnopqrstuvwxyz ", i) / 27 * ls;
|
|
823
|
+
return Math.round(Math.min(Math.max(t, fn), Math.max(o, fn)));
|
|
824
|
+
}
|
|
825
|
+
const ds = Qn;
|
|
826
|
+
function fs(e) {
|
|
827
|
+
return [...us(e), ...ps(e), ...gs(e)];
|
|
828
|
+
}
|
|
829
|
+
const hs = /* @__PURE__ */ new Set(["slate", "stone"]);
|
|
830
|
+
function us(e) {
|
|
831
|
+
if (e.objects.some((r) => r.status) || e.edges.some((r) => r.status)) return [];
|
|
832
|
+
const t = e.appearance.legend ?? [], i = [];
|
|
833
|
+
if (t.length) {
|
|
834
|
+
const r = new Set(t.map((c) => c.family)), l = e.objects.filter(
|
|
835
|
+
(c) => c.color !== "auto" && !hs.has(c.color) && !r.has(c.color)
|
|
836
|
+
), h = [...new Set(l.map((c) => c.color))];
|
|
837
|
+
h.length && i.push({
|
|
838
|
+
level: "warning",
|
|
839
|
+
code: "legend-missing",
|
|
840
|
+
message: `The legend has no row for ${h.join(", ")}. Add a \`legend <color> "meaning"\` line for each color the drawing uses, or draw those objects in slate.`,
|
|
841
|
+
line: e.legendLines[0],
|
|
842
|
+
ids: l.map((c) => c.id)
|
|
843
|
+
});
|
|
844
|
+
}
|
|
845
|
+
const o = e.layouts.some((r) => r.algorithm === "sequence"), s = e.edges.filter((r) => r.dashed);
|
|
846
|
+
return !o && s.length && s.length < e.edges.length && !t.some((r) => r.line) && i.push({
|
|
847
|
+
level: "info",
|
|
848
|
+
code: "legend-lines",
|
|
849
|
+
message: 'Some lines are dashed (kind=async) and some solid. Say what each style means with `legend line dashed "meaning"` and `legend line solid "meaning"`.',
|
|
850
|
+
line: s[0].line,
|
|
851
|
+
ids: s.map((r) => r.id)
|
|
852
|
+
}), i;
|
|
853
|
+
}
|
|
854
|
+
function ps(e) {
|
|
855
|
+
return (e.appearance.legend ?? []).flatMap((t, i) => {
|
|
856
|
+
if (!t.family) return [];
|
|
857
|
+
const o = e.objects.filter((l) => l.type === "node" && l.color === t.family), s = t.shade ?? wt, r = [...new Set(o.map((l) => l.shade ?? wt))].sort((l, h) => l - h);
|
|
858
|
+
return !o.length || r.includes(s) ? [] : [
|
|
859
|
+
{
|
|
860
|
+
level: "warning",
|
|
861
|
+
code: "legend-shade",
|
|
862
|
+
message: `legend ${t.family} is shade ${s}; ${t.family} nodes use ${r.join(", ")}. Add \`shade=${r[0]}\`${r.length > 1 ? " or another of them" : ""}.`,
|
|
863
|
+
line: e.legendLines[i],
|
|
864
|
+
ids: o.map((l) => l.id)
|
|
865
|
+
}
|
|
866
|
+
];
|
|
867
|
+
});
|
|
868
|
+
}
|
|
869
|
+
function gs(e) {
|
|
870
|
+
const t = [], i = e.appearance.heading?.subtitle;
|
|
871
|
+
if (i) {
|
|
872
|
+
const o = tt(e.appearance), s = ot(i, cs(o, 1 / 0), ds(o).subtitle);
|
|
873
|
+
s.length > 1 && t.push({
|
|
874
|
+
level: "warning",
|
|
875
|
+
code: "heading-prose",
|
|
876
|
+
message: `The subtitle takes ${s.length} lines. Cut it to one short takeaway, about 10 words; let the drawing say the rest.`,
|
|
877
|
+
ids: []
|
|
878
|
+
});
|
|
879
|
+
}
|
|
880
|
+
return (e.appearance.notes ?? []).forEach((o, s) => {
|
|
881
|
+
o.near || t.push({
|
|
882
|
+
level: "warning",
|
|
883
|
+
code: "heading-prose",
|
|
884
|
+
message: "This note has no near=, so it sits under the heading as prose. Anchor it with near=<id> to the object it explains, or make it a footnote under the drawing.",
|
|
885
|
+
line: e.noteLines[s],
|
|
886
|
+
ids: []
|
|
887
|
+
});
|
|
888
|
+
}), [...t, ...ms(e)];
|
|
889
|
+
}
|
|
890
|
+
function ms(e) {
|
|
891
|
+
const t = new Set((e.appearance.footnotes ?? []).flatMap((o) => o.mark ? [o.mark] : []));
|
|
892
|
+
return t.size ? [
|
|
893
|
+
...e.objects.map((o) => ({ id: o.id, text: o.label, line: o.line })),
|
|
894
|
+
...e.edges.map((o) => ({ id: o.id, text: o.label, line: o.line }))
|
|
895
|
+
].flatMap(
|
|
896
|
+
(o) => [...o.text.matchAll(/\[([A-Za-z0-9*]{1,3})\]/g)].filter((s) => !t.has(s[1])).map((s) => ({
|
|
897
|
+
level: "warning",
|
|
898
|
+
code: "footnote-missing",
|
|
899
|
+
message: `${o.id} points at [${s[1]}], but no footnote has that marker. Add footnote ${s[1]} "…" or fix the label.`,
|
|
900
|
+
line: o.line,
|
|
901
|
+
ids: [o.id]
|
|
902
|
+
}))
|
|
903
|
+
) : [];
|
|
904
|
+
}
|
|
905
|
+
class _e extends Error {
|
|
906
|
+
constructor(t, i = 0, o = 0) {
|
|
907
|
+
super((i ? `Line ${i}${o ? `, column ${o}` : ""}: ` : "") + t), this.line = i, this.column = o, this.name = "DslError";
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
const Vn = { "+": "added", "-": "removed", "~": "changed", ".": "context" }, ws = (e) => ({ value: String(e), quoted: !1 }), ys = (e) => ({ value: e, quoted: !0 }), Ms = 'A quote inside a quoted string needs a backslash: write \\" for each inner quote.';
|
|
911
|
+
function xs(e, t = 0) {
|
|
912
|
+
const i = [], o = [];
|
|
913
|
+
let s = "", r = 0, l = 0, h = !1, c = !1;
|
|
914
|
+
const M = () => {
|
|
915
|
+
s && (i.push(s), o.push(r + 1)), s = "";
|
|
916
|
+
};
|
|
917
|
+
for (let m = 0; m < e.length; m++) {
|
|
918
|
+
const d = e[m];
|
|
919
|
+
if (s || (r = m), c) {
|
|
920
|
+
s += d, c = !1;
|
|
921
|
+
continue;
|
|
922
|
+
}
|
|
923
|
+
if (h && d === "\\") {
|
|
924
|
+
s += d, c = !0;
|
|
925
|
+
continue;
|
|
926
|
+
}
|
|
927
|
+
if (d === '"') {
|
|
928
|
+
if (h && m + 1 < e.length && !/[\s#]/.test(e[m + 1]) && !e.startsWith("//", m + 1))
|
|
929
|
+
throw new _e(Ms, t, m + 1);
|
|
930
|
+
h || (l = m), h = !h, s += d;
|
|
931
|
+
continue;
|
|
932
|
+
}
|
|
933
|
+
const f = d === "/" && e[m + 1] === "/" && !/[^\s"]/.test(e[m - 1] ?? " ");
|
|
934
|
+
if (!h && (d === "#" || f))
|
|
935
|
+
return M(), { tokens: i, columns: o, comment: e.slice(m).trim() };
|
|
936
|
+
!h && /\s/.test(d) ? M() : s += d;
|
|
937
|
+
}
|
|
938
|
+
if (h) throw new _e("Unclosed quoted string.", t, l + 1);
|
|
939
|
+
return M(), { tokens: i, columns: o };
|
|
940
|
+
}
|
|
941
|
+
function hn(e, t, i) {
|
|
942
|
+
if (!e.startsWith('"')) return ws(e);
|
|
943
|
+
try {
|
|
944
|
+
return ys(JSON.parse(e));
|
|
945
|
+
} catch {
|
|
946
|
+
throw new _e(
|
|
947
|
+
'Invalid escape in a quoted string. Use \\" for a quote, \\\\ for a backslash and \\n for a line break.',
|
|
948
|
+
t,
|
|
949
|
+
i
|
|
950
|
+
);
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
function bs(e) {
|
|
954
|
+
if (typeof e != "string") throw new _e("Source must be text.");
|
|
955
|
+
if (e.length > 3e5) throw new _e("Limit: 300,000 source characters.");
|
|
956
|
+
return { lines: e.split(/\r?\n/).map((i, o) => {
|
|
957
|
+
const s = o + 1, { tokens: r, columns: l, comment: h } = xs(i, s);
|
|
958
|
+
if (!r.length) return h ? { kind: "comment", text: h } : { kind: "blank" };
|
|
959
|
+
const [c, ...M] = r, m = Vn[c[0]] && c.length > 1 ? c[0] : void 0, d = m ? c.slice(1) : c, f = [], n = [];
|
|
960
|
+
return M.forEach((a, p) => {
|
|
961
|
+
const u = a.indexOf("="), g = l[p + 1];
|
|
962
|
+
if (u > 0 && !a.startsWith('"')) {
|
|
963
|
+
const x = a.slice(0, u);
|
|
964
|
+
if (n.some(([E]) => E === x)) throw new _e(`Duplicate attribute ${x}.`, s);
|
|
965
|
+
n.push([x, hn(a.slice(u + 1), s, g + u + 1)]);
|
|
966
|
+
} else f.push(hn(a, s, g));
|
|
967
|
+
}), { kind: "statement", command: d, ...m ? { mark: m } : {}, args: f, attrs: n, comment: h, line: s };
|
|
968
|
+
}) };
|
|
969
|
+
}
|
|
970
|
+
const vs = { wide: 2, slide: 1.78, square: 1, page: 0.77, tall: 0.6 };
|
|
971
|
+
function Ft(e, t, i) {
|
|
972
|
+
const o = Xe(e, t);
|
|
973
|
+
for (let s = i; s && s !== "root"; s = Xe(e, s))
|
|
974
|
+
if (Xe(e, s) === o) return s === t ? void 0 : s;
|
|
975
|
+
}
|
|
976
|
+
const ks = ["near", "nudge", "stay", "pin"], un = {
|
|
977
|
+
"link-base": "linkBase",
|
|
978
|
+
editor: "editor",
|
|
979
|
+
"strike-removed": "strikeRemoved"
|
|
980
|
+
}, pn = {
|
|
981
|
+
"padding-x": "paddingX",
|
|
982
|
+
"padding-y": "paddingY",
|
|
983
|
+
radius: "radius",
|
|
984
|
+
"title-font": "titleFont",
|
|
985
|
+
"annotation-font": "annotationFont",
|
|
986
|
+
canvas: "canvas",
|
|
987
|
+
text: "text",
|
|
988
|
+
connection: "connection"
|
|
989
|
+
}, gn = [
|
|
990
|
+
"compound-flow",
|
|
991
|
+
"boundary-align",
|
|
992
|
+
"compound-spring",
|
|
993
|
+
"tidy",
|
|
994
|
+
"stress",
|
|
995
|
+
"force",
|
|
996
|
+
"flow",
|
|
997
|
+
"layered",
|
|
998
|
+
"tree",
|
|
999
|
+
"grid"
|
|
1000
|
+
], Ct = {
|
|
1001
|
+
"rank-gap": { key: "rankGap", min: 12, max: 220 },
|
|
1002
|
+
"group-gap": { key: "groupGap", min: 12, max: 180 },
|
|
1003
|
+
"node-gap": { key: "nodeGap", min: 4, max: 160 },
|
|
1004
|
+
"boundary-pull": { key: "boundaryPull", min: 0, max: 100 },
|
|
1005
|
+
"hierarchy-sweeps": { key: "hierarchySweeps", min: 1, max: 4 },
|
|
1006
|
+
"edge-length": { key: "edgeLength", min: 20, max: 260 },
|
|
1007
|
+
repulsion: { key: "repulsion", min: 0, max: 100 },
|
|
1008
|
+
"flow-strength": { key: "flowStrength", min: 0, max: 100 },
|
|
1009
|
+
alignment: { key: "alignment", min: 0, max: 100 },
|
|
1010
|
+
compactness: { key: "compactness", min: 0, max: 100 },
|
|
1011
|
+
"grid-strength": { key: "gridStrength", min: 0, max: 100 },
|
|
1012
|
+
ordering: { key: "ordering", choices: ["stable", "crossings"] },
|
|
1013
|
+
fold: { key: "fold", choices: ["auto", "never"] },
|
|
1014
|
+
aspect: { key: "aspect", choices: ["1", "1.333", "1.6", "2", "0.75"] },
|
|
1015
|
+
root: { key: "rootId", choices: [] }
|
|
1016
|
+
}, mn = {
|
|
1017
|
+
clearance: { key: "clearance", min: 4, max: 30 },
|
|
1018
|
+
"port-gap": { key: "portGap", min: 6, max: 28 },
|
|
1019
|
+
"edge-gap": { key: "edgeGap", min: 4, max: 48 },
|
|
1020
|
+
"bend-penalty": { key: "bendPenalty", min: 0, max: 100 },
|
|
1021
|
+
"crossing-penalty": { key: "crossingPenalty", min: 0, max: 1200 },
|
|
1022
|
+
"shared-penalty": { key: "sharedPenalty", min: 0, max: 20 },
|
|
1023
|
+
"parallel-penalty": { key: "parallelPenalty", min: 0, max: 60 },
|
|
1024
|
+
"port-stability": { key: "portStability", min: 0, max: 150 },
|
|
1025
|
+
"fanout-penalty": { key: "fanoutPenalty", min: 0, max: 160 },
|
|
1026
|
+
passes: { key: "passes", min: 1, max: 5 },
|
|
1027
|
+
"corner-radius": { key: "cornerRadius", min: 0, max: 16 },
|
|
1028
|
+
standoff: { key: "standoff", min: 0, max: 40 }
|
|
1029
|
+
};
|
|
1030
|
+
function Es(e, t) {
|
|
1031
|
+
return t && e === "gap" ? "Engine lines space boxes with node-gap= and rank-gap=." : !t && e in Ct ? `${e}= needs an engine: add engine=layered or another engine.` : e === "fit" ? "fit= goes on the layout root line." : "draftably skill print lists the layout settings.";
|
|
1032
|
+
}
|
|
1033
|
+
const As = /^[A-Za-z_][A-Za-z0-9_.-]*$/, At = /^[A-Za-z_][A-Za-z0-9_-]*$/, Zn = ["box", "pill", "circle", "diamond", "text", "marker"], _s = Zn.filter((e) => e !== "marker"), wn = ["box", "soft", "none"], Ss = /^[A-Za-z]{1,8}$/, yn = ["auto", "left", "right", "top", "bottom"];
|
|
1034
|
+
function Is(e) {
|
|
1035
|
+
const t = typeof e == "string" ? bs(e) : e, i = {
|
|
1036
|
+
title: "Untitled diagram",
|
|
1037
|
+
objects: [],
|
|
1038
|
+
edges: [],
|
|
1039
|
+
layouts: [],
|
|
1040
|
+
hints: [],
|
|
1041
|
+
routing: {},
|
|
1042
|
+
appearance: Bn(),
|
|
1043
|
+
themeLine: 0,
|
|
1044
|
+
colorLines: /* @__PURE__ */ new Map(),
|
|
1045
|
+
legendLines: [],
|
|
1046
|
+
noteLines: [],
|
|
1047
|
+
footnoteLines: [],
|
|
1048
|
+
stateLines: /* @__PURE__ */ new Map(),
|
|
1049
|
+
phases: [],
|
|
1050
|
+
warnings: []
|
|
1051
|
+
}, o = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Set(), r = /* @__PURE__ */ new Set(), l = /* @__PURE__ */ new Set();
|
|
1052
|
+
let h = 0;
|
|
1053
|
+
for (const c of t.lines) {
|
|
1054
|
+
if (c.kind !== "statement") continue;
|
|
1055
|
+
const M = c.line, { command: m, args: d } = c, f = new Map(c.attrs), n = (w) => {
|
|
1056
|
+
throw new _e(w, M);
|
|
1057
|
+
}, a = (w, b) => {
|
|
1058
|
+
w || n(b);
|
|
1059
|
+
}, p = (w) => {
|
|
1060
|
+
for (const b of f.keys())
|
|
1061
|
+
a(w.includes(b), `Unknown ${m} attribute: ${b}.`);
|
|
1062
|
+
}, u = (w, b = w) => a(d.length >= w && d.length <= b, `Wrong number of arguments for ${m}.`), g = (w) => (a(
|
|
1063
|
+
w && !w.quoted && As.test(w.value),
|
|
1064
|
+
"Expected a stable identifier (letters, digits, _, . or -)."
|
|
1065
|
+
), w.value), x = (w) => w?.value ?? "", E = (w, b, _ = -1e5, N = 1e5) => {
|
|
1066
|
+
const Q = f.get(w);
|
|
1067
|
+
if (Q === void 0) return b;
|
|
1068
|
+
const z = Number(Q.value);
|
|
1069
|
+
return a(
|
|
1070
|
+
!Q.quoted && Number.isFinite(z) && z >= _ && z <= N,
|
|
1071
|
+
`Expected ${w} from ${_} to ${N}; got ${Q.value}.`
|
|
1072
|
+
), z;
|
|
1073
|
+
}, R = (w, b) => {
|
|
1074
|
+
const _ = f.get(w);
|
|
1075
|
+
return !_.quoted && Ss.test(_.value) ? _.value : E(w, b, b, 1e6);
|
|
1076
|
+
}, L = (w, b, _) => {
|
|
1077
|
+
const N = f.get(w)?.value ?? b;
|
|
1078
|
+
return a(_.includes(N), `Expected ${w}=${_.join("|")}; got ${N}.`), N;
|
|
1079
|
+
}, H = (w) => {
|
|
1080
|
+
const b = Number(w.value);
|
|
1081
|
+
return a(
|
|
1082
|
+
!w.quoted && Tt.includes(b),
|
|
1083
|
+
`Expected shade=${Tt.join("|")}; got ${w.value}.`
|
|
1084
|
+
), b;
|
|
1085
|
+
}, I = (w) => {
|
|
1086
|
+
const b = f.get(w);
|
|
1087
|
+
return a(
|
|
1088
|
+
b.quoted && Mo.test(b.value),
|
|
1089
|
+
`Expected ${w}="#rrggbb" in double quotes; got ${b.value || "nothing"}.`
|
|
1090
|
+
), b.value.toUpperCase();
|
|
1091
|
+
}, P = (w) => {
|
|
1092
|
+
a(!l.has(w), `Duplicate declaration: ${w}. Edit the existing line instead.`), l.add(w);
|
|
1093
|
+
}, O = c.mark && Vn[c.mark];
|
|
1094
|
+
a(
|
|
1095
|
+
!c.mark || ["node", "group", "edge"].includes(m),
|
|
1096
|
+
`Only node, group and edge lines take a ${c.mark} mark.`
|
|
1097
|
+
);
|
|
1098
|
+
const y = () => {
|
|
1099
|
+
for (const w of ["was", "was-shape", "was-count"])
|
|
1100
|
+
a(!f.has(w) || c.mark === "~", `${w}= belongs on a changed (~) line.`);
|
|
1101
|
+
return {
|
|
1102
|
+
...f.has("was") ? { was: f.get("was").value } : {},
|
|
1103
|
+
...f.has("was-shape") ? { wasShape: L("was-shape", "box", _s) } : {},
|
|
1104
|
+
...f.has("was-count") ? { wasCount: R("was-count", 1) } : {}
|
|
1105
|
+
};
|
|
1106
|
+
}, D = (w) => {
|
|
1107
|
+
const b = {};
|
|
1108
|
+
for (const [_, N] of Object.entries(w))
|
|
1109
|
+
f.has(_) && ("min" in N ? b[N.key] = E(_, 0, N.min, N.max) : N.choices.length ? b[N.key] = L(_, N.choices[0], N.choices) : b[N.key] = g(f.get(_)));
|
|
1110
|
+
return b;
|
|
1111
|
+
};
|
|
1112
|
+
switch (m) {
|
|
1113
|
+
case "diagram":
|
|
1114
|
+
u(1), p(["version", "width"]), a(!h, "Only one diagram declaration is allowed."), h = M, i.title = x(d[0]), E("version", 1, 1, 1), i.title && ((i.appearance.heading ??= {}).title = i.title), f.has("width") && ((i.appearance.heading ??= {}).width = E("width", 0, 160, 8e3));
|
|
1115
|
+
break;
|
|
1116
|
+
case "compare": {
|
|
1117
|
+
u(0, 2), p(["direction", "aspect"]), P("compare");
|
|
1118
|
+
const w = L("direction", "auto", ["auto", "right", "down"]);
|
|
1119
|
+
i.appearance.compare = {
|
|
1120
|
+
before: x(d[0]) || "Before",
|
|
1121
|
+
after: x(d[1]) || "After",
|
|
1122
|
+
...w !== "auto" ? { direction: w } : {},
|
|
1123
|
+
...f.has("aspect") ? { aspect: E("aspect", 1.6, 0.25, 8) } : {}
|
|
1124
|
+
};
|
|
1125
|
+
break;
|
|
1126
|
+
}
|
|
1127
|
+
case "config": {
|
|
1128
|
+
u(0), p(Object.keys(un)), a(f.size, `config needs a setting: ${Object.keys(un).join(", ")}.`);
|
|
1129
|
+
const w = i.appearance.config ??= {};
|
|
1130
|
+
for (const [b, _] of f) {
|
|
1131
|
+
const N = o.get(b);
|
|
1132
|
+
N && i.warnings.push({
|
|
1133
|
+
code: "config-repeated",
|
|
1134
|
+
message: `config ${b} is also set on line ${N}; this line wins.`,
|
|
1135
|
+
line: M
|
|
1136
|
+
}), o.set(b, M), b === "editor" ? w.editor = L("editor", "vscode", rs) : b === "strike-removed" ? w.strikeRemoved = L(b, "off", ["on", "off"]) === "on" : (a(_.quoted, `Expected ${b}="path" in double quotes.`), w.linkBase = _.value);
|
|
1137
|
+
}
|
|
1138
|
+
break;
|
|
1139
|
+
}
|
|
1140
|
+
case "state": {
|
|
1141
|
+
a(d.length >= 1, 'A state needs an ID: state write "Write path" api orders.'), p(["rest"]);
|
|
1142
|
+
const w = g(d[0]), b = d[1]?.quoted ? d[1].value : void 0, _ = d.slice(b === void 0 ? 1 : 2).map((z) => g(z)), N = i.appearance.states ??= [];
|
|
1143
|
+
let Q = N.find((z) => z.id === w);
|
|
1144
|
+
Q || (Q = { id: w, label: b ?? w, ids: [], rest: "dim" }, N.push(Q)), f.has("rest") && (Q.rest = L("rest", "dim", ["dim", "plain"]));
|
|
1145
|
+
for (const z of _)
|
|
1146
|
+
a(!Q.ids.includes(z), `${z} is already in state ${w}.`), Q.ids.push(z), i.stateLines.set(`${w}:${z}`, M);
|
|
1147
|
+
break;
|
|
1148
|
+
}
|
|
1149
|
+
case "phase": {
|
|
1150
|
+
a(
|
|
1151
|
+
d.length >= 3 && d[1]?.quoted,
|
|
1152
|
+
'A phase needs an ID, a label and its messages: phase preview "Preview" m1 m2.'
|
|
1153
|
+
), p([]);
|
|
1154
|
+
const w = g(d[0]);
|
|
1155
|
+
a(!i.phases.some((b) => b.id === w), `Duplicate phase ${w}.`), i.phases.push({ id: w, label: d[1].value, ids: d.slice(2).map((b) => g(b)), line: M });
|
|
1156
|
+
break;
|
|
1157
|
+
}
|
|
1158
|
+
case "was-order":
|
|
1159
|
+
a(d.length, "was-order lists the older message order: was-order m2 m1."), p([]), P("was-order"), i.wasOrder = { ids: d.map((w) => g(w)), line: M };
|
|
1160
|
+
break;
|
|
1161
|
+
case "subtitle":
|
|
1162
|
+
u(1), p([]), P("subtitle"), a(x(d[0]).trim(), "A subtitle needs its text in quotes."), (i.appearance.heading ??= {}).subtitle = x(d[0]);
|
|
1163
|
+
break;
|
|
1164
|
+
case "node":
|
|
1165
|
+
case "group": {
|
|
1166
|
+
u(2), p(
|
|
1167
|
+
m === "node" ? [
|
|
1168
|
+
"in",
|
|
1169
|
+
"color",
|
|
1170
|
+
"shade",
|
|
1171
|
+
"shape",
|
|
1172
|
+
"was",
|
|
1173
|
+
"was-shape",
|
|
1174
|
+
"was-count",
|
|
1175
|
+
"href",
|
|
1176
|
+
"count",
|
|
1177
|
+
"span"
|
|
1178
|
+
] : ["in", "color", "shade", "was", "href", "frame", "fold"]
|
|
1179
|
+
);
|
|
1180
|
+
const w = g(d[0]);
|
|
1181
|
+
a(w !== "root", "root is reserved for the outer layout scope."), a(!s.has(w), `Duplicate node/group id ${w}.`), s.add(w);
|
|
1182
|
+
const b = f.get("color")?.value ?? "auto";
|
|
1183
|
+
a(
|
|
1184
|
+
!f.get("color")?.quoted && At.test(b),
|
|
1185
|
+
`Expected color=auto, a built-in color (${Lt.join(", ")}) or a theme-color name; got ${b}.`
|
|
1186
|
+
);
|
|
1187
|
+
const _ = f.has("shade") ? H(f.get("shade")) : void 0;
|
|
1188
|
+
i.objects.push({
|
|
1189
|
+
id: w,
|
|
1190
|
+
type: m,
|
|
1191
|
+
label: x(d[1]),
|
|
1192
|
+
parent: f.has("in") ? g(f.get("in")) : "root",
|
|
1193
|
+
color: b,
|
|
1194
|
+
..._ !== void 0 ? { shade: _ } : {},
|
|
1195
|
+
shape: m === "node" ? L("shape", "box", Zn) : "box",
|
|
1196
|
+
...c.mark ? { status: O } : {},
|
|
1197
|
+
...y(),
|
|
1198
|
+
...f.has("href") ? { href: x(f.get("href")) } : {},
|
|
1199
|
+
...f.has("count") ? { count: R("count", 2) } : {},
|
|
1200
|
+
...m === "group" && L("fold", "auto", ["auto", "never"]) === "never" ? { fold: "never" } : {},
|
|
1201
|
+
...m === "group" && L("frame", "box", wn) !== "box" ? { frame: L("frame", "box", wn) } : {},
|
|
1202
|
+
...f.has("span") ? {
|
|
1203
|
+
span: f.get("span").value === "var" ? "var" : E("span", 1, 1, 4096)
|
|
1204
|
+
} : {},
|
|
1205
|
+
line: M
|
|
1206
|
+
});
|
|
1207
|
+
break;
|
|
1208
|
+
}
|
|
1209
|
+
case "edge": {
|
|
1210
|
+
u(4, 5), p(["kind", "from", "to", "was", "constraint", "directed", "head", "tail"]), a(
|
|
1211
|
+
d[2]?.value === "->" && !d[2].quoted,
|
|
1212
|
+
'Edges use: edge id source -> target "label".'
|
|
1213
|
+
);
|
|
1214
|
+
const w = g(d[0]);
|
|
1215
|
+
a(!r.has(w), `Duplicate edge id ${w}.`), r.add(w);
|
|
1216
|
+
const b = L("directed", "true", ["true", "false"]) === "false", _ = L("head", "arrow", dn), N = L("tail", "none", dn);
|
|
1217
|
+
a(
|
|
1218
|
+
!b || !(f.has("head") || f.has("tail")),
|
|
1219
|
+
`Edge ${w} has directed=false, so it has no ends to mark. Remove head= and tail=, or remove directed=false.`
|
|
1220
|
+
), i.edges.push({
|
|
1221
|
+
id: w,
|
|
1222
|
+
source: g(d[1]),
|
|
1223
|
+
target: g(d[3]),
|
|
1224
|
+
label: x(d[4]),
|
|
1225
|
+
dashed: L("kind", "sync", ["sync", "async"]) === "async",
|
|
1226
|
+
from: L("from", "auto", yn),
|
|
1227
|
+
to: L("to", "auto", yn),
|
|
1228
|
+
...b ? { directed: !1 } : {},
|
|
1229
|
+
..._ !== "arrow" ? { head: _ } : {},
|
|
1230
|
+
...N !== "none" ? { tail: N } : {},
|
|
1231
|
+
...L("constraint", "true", ["true", "false"]) === "false" ? { constraint: !1 } : {},
|
|
1232
|
+
...c.mark ? { status: O } : {},
|
|
1233
|
+
...y(),
|
|
1234
|
+
line: M
|
|
1235
|
+
});
|
|
1236
|
+
break;
|
|
1237
|
+
}
|
|
1238
|
+
case "layout": {
|
|
1239
|
+
const w = g(d[0]), b = f.get("engine")?.value, _ = i.layouts.findIndex(($) => $.scope === w);
|
|
1240
|
+
_ >= 0 && (i.warnings.push({
|
|
1241
|
+
code: "layout-repeated",
|
|
1242
|
+
message: `layout ${w} is also set on line ${i.layouts[_].line}; this line wins.`,
|
|
1243
|
+
line: M
|
|
1244
|
+
}), i.layouts.splice(_, 1));
|
|
1245
|
+
const N = ($) => {
|
|
1246
|
+
for (const k of [...f.keys()])
|
|
1247
|
+
$.includes(k) || (i.warnings.push({
|
|
1248
|
+
code: "layout-attribute",
|
|
1249
|
+
message: `This layout line does not take ${k}=, so it is ignored. ${Es(k, b !== void 0)}`,
|
|
1250
|
+
line: M
|
|
1251
|
+
}), f.delete(k));
|
|
1252
|
+
}, Q = [
|
|
1253
|
+
"direction",
|
|
1254
|
+
"min-width",
|
|
1255
|
+
"min-height",
|
|
1256
|
+
...w === "root" ? ["fit"] : []
|
|
1257
|
+
];
|
|
1258
|
+
let z;
|
|
1259
|
+
if (b !== void 0)
|
|
1260
|
+
u(1), a(
|
|
1261
|
+
gn.includes(b),
|
|
1262
|
+
`Unknown layout engine ${b}; use ${gn.join(", ")}.`
|
|
1263
|
+
), N(["engine", ...Q, ...Object.keys(Ct)]), z = { algorithm: b, params: D(Ct) };
|
|
1264
|
+
else {
|
|
1265
|
+
u(2);
|
|
1266
|
+
const $ = d[1]?.value;
|
|
1267
|
+
N(
|
|
1268
|
+
$ === "cells" ? ["columns", "unit", "unit-width", "ruler", ...Q] : ["gap", ...$ === "flow" ? ["fold"] : [], ...Q]
|
|
1269
|
+
);
|
|
1270
|
+
}
|
|
1271
|
+
const Y = b ? "flow" : d[1]?.value;
|
|
1272
|
+
a(
|
|
1273
|
+
["flow", "row", "column", "lanes", "sequence", "cells"].includes(Y),
|
|
1274
|
+
`The ${Y} recipe is not supported; use flow, row, column, lanes, sequence or cells, or engine=.`
|
|
1275
|
+
), a(
|
|
1276
|
+
!["lanes", "sequence"].includes(Y) || w === "root",
|
|
1277
|
+
`${Y} arranges the whole diagram: write layout root ${Y}.`
|
|
1278
|
+
), a(
|
|
1279
|
+
Y !== "cells" || w !== "root",
|
|
1280
|
+
"Cells lay out a group; give the cells a group and use layout <group> cells."
|
|
1281
|
+
), i.layouts.push({
|
|
1282
|
+
scope: w,
|
|
1283
|
+
algorithm: Y,
|
|
1284
|
+
...z ? { engine: z } : {},
|
|
1285
|
+
direction: L("direction", "auto", ["auto", "right", "down"]),
|
|
1286
|
+
fold: b ? "auto" : L("fold", "auto", ["auto", "never"]),
|
|
1287
|
+
...f.has("fit") ? { fit: L("fit", "slide", Object.keys(vs)) } : {},
|
|
1288
|
+
...f.has("columns") ? { columns: E("columns", 1, 1, 512) } : {},
|
|
1289
|
+
...f.has("unit") ? {
|
|
1290
|
+
unit: L("unit", "byte", ["bit", "byte"]),
|
|
1291
|
+
ruler: L("ruler", "on", ["on", "off"]) === "on",
|
|
1292
|
+
...f.has("unit-width") ? { unitWidth: E("unit-width", 24, 8, 200) } : {}
|
|
1293
|
+
} : {},
|
|
1294
|
+
gap: E("gap", 28, 8, 300),
|
|
1295
|
+
minWidth: E("min-width", 0, 0, 1e4),
|
|
1296
|
+
minHeight: E("min-height", 0, 0, 1e4),
|
|
1297
|
+
line: M
|
|
1298
|
+
});
|
|
1299
|
+
break;
|
|
1300
|
+
}
|
|
1301
|
+
case "theme": {
|
|
1302
|
+
u(1), p(Object.keys(pn)), P("theme");
|
|
1303
|
+
const w = d[0].value;
|
|
1304
|
+
a(Xt.includes(w), `Unknown theme ${w}; use ${Xt.join(", ")}.`), i.appearance.theme = w, i.themeLine = M;
|
|
1305
|
+
const b = i.appearance.overrides;
|
|
1306
|
+
for (const [_, N] of Object.entries(pn))
|
|
1307
|
+
f.has(_) && (N === "paddingX" || N === "paddingY" || N === "radius" ? b[N] = E(_, 0, Qt[N].min, Qt[N].max) : N === "titleFont" || N === "annotationFont" ? b[N] = L(_, "sans", fo) : b[N] = I(_));
|
|
1308
|
+
break;
|
|
1309
|
+
}
|
|
1310
|
+
case "theme-color": {
|
|
1311
|
+
u(1), p(["shade", "fill", "stroke", "ink"]);
|
|
1312
|
+
const w = d[0].value;
|
|
1313
|
+
a(
|
|
1314
|
+
!d[0].quoted && At.test(w) && w !== "auto",
|
|
1315
|
+
"Expected a color family name (letters, digits, _ or -)."
|
|
1316
|
+
);
|
|
1317
|
+
const b = f.has("shade") ? H(f.get("shade")) : 500;
|
|
1318
|
+
P(`theme-color:${w}:${b}`);
|
|
1319
|
+
const _ = { family: w, shade: b };
|
|
1320
|
+
for (const N of ["fill", "stroke", "ink"])
|
|
1321
|
+
f.has(N) && (_[N] = I(N));
|
|
1322
|
+
a(
|
|
1323
|
+
Rt(w) || _.fill && _.stroke && _.ink,
|
|
1324
|
+
`${w} is not a built-in color, so shade ${b} needs fill, stroke and ink.`
|
|
1325
|
+
), a(_.fill || _.stroke || _.ink, "Set at least one of fill, stroke and ink."), i.appearance.colors.push(_), i.colorLines.set(`${w}:${b}`, M);
|
|
1326
|
+
break;
|
|
1327
|
+
}
|
|
1328
|
+
case "legend": {
|
|
1329
|
+
if (d[0]?.value === "line" && !d[0].quoted) {
|
|
1330
|
+
u(3), p([]);
|
|
1331
|
+
const _ = d[1].value;
|
|
1332
|
+
a(
|
|
1333
|
+
!d[1].quoted && Kt.includes(_),
|
|
1334
|
+
`Expected legend line ${Kt.join("|")} "meaning".`
|
|
1335
|
+
), P(`legend:line:${_}`), a(x(d[2]).trim(), "A legend entry needs its meaning in quotes."), (i.appearance.legend ??= []).push({ line: _, label: x(d[2]) }), i.legendLines.push(M);
|
|
1336
|
+
break;
|
|
1337
|
+
}
|
|
1338
|
+
u(2), p(["shade"]);
|
|
1339
|
+
const w = d[0].value;
|
|
1340
|
+
a(
|
|
1341
|
+
!d[0].quoted && At.test(w) && w !== "auto",
|
|
1342
|
+
`Expected legend family "meaning", with a built-in color (${Lt.join(", ")}) or a theme-color name.`
|
|
1343
|
+
), P(`legend:${w}:${f.get("shade")?.value ?? ""}`);
|
|
1344
|
+
const b = f.has("shade") ? H(f.get("shade")) : void 0;
|
|
1345
|
+
a(x(d[1]).trim(), "A legend entry needs its meaning in quotes."), (i.appearance.legend ??= []).push({
|
|
1346
|
+
family: w,
|
|
1347
|
+
label: x(d[1]),
|
|
1348
|
+
...b !== void 0 ? { shade: b } : {}
|
|
1349
|
+
}), i.legendLines.push(M);
|
|
1350
|
+
break;
|
|
1351
|
+
}
|
|
1352
|
+
case "note": {
|
|
1353
|
+
u(1), p(["near", "side", "width"]), a(d[0].quoted && d[0].value.trim(), "A note needs its text in quotes."), a(f.has("near") || !f.has("side"), "side= places a note beside near=<id>."), (i.appearance.notes ??= []).push({
|
|
1354
|
+
text: d[0].value,
|
|
1355
|
+
...f.has("near") ? { near: g(f.get("near")) } : {},
|
|
1356
|
+
...f.has("side") ? { side: L("side", "below", Yo) } : {},
|
|
1357
|
+
...f.has("width") ? { width: E("width", Xn, 80, 1200) } : {}
|
|
1358
|
+
}), i.noteLines.push(M);
|
|
1359
|
+
break;
|
|
1360
|
+
}
|
|
1361
|
+
case "footnote": {
|
|
1362
|
+
u(1, 2), p([]);
|
|
1363
|
+
const w = d[d.length - 1], b = d.length === 2 ? d[0] : void 0;
|
|
1364
|
+
a(w.quoted && w.value.trim(), "A footnote needs its text in quotes."), a(
|
|
1365
|
+
!b || !b.quoted && /^[A-Za-z0-9*]{1,3}$/.test(b.value),
|
|
1366
|
+
'A footnote marker is a short word: footnote 1 "text".'
|
|
1367
|
+
), b && P(`footnote:${b.value}`), (i.appearance.footnotes ??= []).push({
|
|
1368
|
+
text: w.value,
|
|
1369
|
+
...b ? { mark: b.value } : {}
|
|
1370
|
+
}), i.footnoteLines.push(M);
|
|
1371
|
+
break;
|
|
1372
|
+
}
|
|
1373
|
+
case "routing":
|
|
1374
|
+
u(0), p(Object.keys(mn)), P("routing"), i.routing = D(mn);
|
|
1375
|
+
break;
|
|
1376
|
+
case "order":
|
|
1377
|
+
u(2, 300), p([]), i.hints.push({ type: "order", scope: g(d[0]), ids: d.slice(1).map(g), line: M }), P("order:" + d[0].value);
|
|
1378
|
+
break;
|
|
1379
|
+
case "align": {
|
|
1380
|
+
u(3, 300), p(["strength"]);
|
|
1381
|
+
const w = d[0]?.value;
|
|
1382
|
+
a(w === "x" || w === "y", "Expected align x or align y.");
|
|
1383
|
+
const b = d.slice(1).map(g);
|
|
1384
|
+
P(`align:${w}:${b.join(",")}`), i.hints.push({
|
|
1385
|
+
type: "align",
|
|
1386
|
+
axis: w,
|
|
1387
|
+
ids: b,
|
|
1388
|
+
strength: L("strength", "prefer", ["prefer", "required"]),
|
|
1389
|
+
line: M
|
|
1390
|
+
});
|
|
1391
|
+
break;
|
|
1392
|
+
}
|
|
1393
|
+
case "near":
|
|
1394
|
+
case "nudge":
|
|
1395
|
+
case "stay":
|
|
1396
|
+
case "pin":
|
|
1397
|
+
case "size": {
|
|
1398
|
+
u(m === "near" ? 2 : 1);
|
|
1399
|
+
const w = g(d[0]);
|
|
1400
|
+
if (P(`${m}:${w}`), m === "near") {
|
|
1401
|
+
p(["side", "gap", "offset", "strength"]);
|
|
1402
|
+
const b = g(d[1]);
|
|
1403
|
+
a(b !== w, "An object cannot be placed relative to itself."), i.hints.push({
|
|
1404
|
+
type: "near",
|
|
1405
|
+
id: w,
|
|
1406
|
+
ref: b,
|
|
1407
|
+
side: L("side", "right", ["right", "left", "above", "below"]),
|
|
1408
|
+
gap: E("gap", 28, 0, 2e3),
|
|
1409
|
+
offset: E("offset", 0),
|
|
1410
|
+
strength: L("strength", "prefer", ["prefer", "required"]),
|
|
1411
|
+
line: M
|
|
1412
|
+
});
|
|
1413
|
+
} else m === "nudge" ? (p(["dx", "dy"]), i.hints.push({ type: "nudge", id: w, dx: E("dx", 0), dy: E("dy", 0), line: M })) : m === "stay" ? (p(["x", "y", "weight"]), i.hints.push({
|
|
1414
|
+
type: "stay",
|
|
1415
|
+
id: w,
|
|
1416
|
+
// The root has no frame, so an arrangement can place objects left of or above 0,0.
|
|
1417
|
+
x: E("x", 0),
|
|
1418
|
+
y: E("y", 0),
|
|
1419
|
+
weight: E("weight", 8, 1, 100),
|
|
1420
|
+
line: M
|
|
1421
|
+
})) : m === "pin" ? (p(["x", "y"]), i.hints.push({ type: "pin", id: w, x: E("x", 0, 0), y: E("y", 0, 0), line: M })) : (p(["width", "height"]), i.hints.push({
|
|
1422
|
+
type: "size",
|
|
1423
|
+
id: w,
|
|
1424
|
+
width: E("width", 164, 40, 1200),
|
|
1425
|
+
...f.get("height")?.value === "auto" ? {} : { height: E("height", 56, 24, 1200) },
|
|
1426
|
+
line: M
|
|
1427
|
+
}));
|
|
1428
|
+
break;
|
|
1429
|
+
}
|
|
1430
|
+
case "view":
|
|
1431
|
+
case "snapshot":
|
|
1432
|
+
case "box":
|
|
1433
|
+
n(`${m} statements are not supported yet. Remove them to open this file.`);
|
|
1434
|
+
break;
|
|
1435
|
+
default:
|
|
1436
|
+
n(`Unknown statement ${m}.`);
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
if (i.objects.length > 500) throw new _e("Limit: 500 nodes and groups.");
|
|
1440
|
+
if (i.edges.length > 1200) throw new _e("Limit: 1,200 edges.");
|
|
1441
|
+
return Ts(i), i;
|
|
1442
|
+
}
|
|
1443
|
+
function Xe(e, t) {
|
|
1444
|
+
let i = e.get(t)?.parent ?? "root";
|
|
1445
|
+
for (; i !== "root" && e.get(i)?.frame; ) i = e.get(i).parent;
|
|
1446
|
+
return i;
|
|
1447
|
+
}
|
|
1448
|
+
function Ts(e) {
|
|
1449
|
+
const t = new Map(e.objects.map((n) => [n.id, n])), i = (n, a, p) => s(
|
|
1450
|
+
!t.get(n)?.frame,
|
|
1451
|
+
`${n} is a ${t.get(n)?.frame} group, so it has no ${p} of its own. Use frame=box, or ${p === "layout" ? "set the layout of the container around it" : "place its members"}.`,
|
|
1452
|
+
a
|
|
1453
|
+
), o = (n) => Xe(t, n), s = (n, a, p) => {
|
|
1454
|
+
if (!n) throw new _e(a, p);
|
|
1455
|
+
}, r = (n, a) => s(t.has(n), `Unknown node/group ${n}.`, a), l = (n, a) => s(n === "root" || t.get(n)?.type === "group", `Unknown container ${n}.`, a), h = /* @__PURE__ */ new Map();
|
|
1456
|
+
for (const n of e.appearance.colors)
|
|
1457
|
+
h.has(n.family) || h.set(n.family, /* @__PURE__ */ new Set()), h.get(n.family).add(n.shade);
|
|
1458
|
+
(e.appearance.legend ?? []).forEach((n, a) => {
|
|
1459
|
+
if (!n.family || Rt(n.family)) return;
|
|
1460
|
+
const p = h.get(n.family), u = n.shade ?? wt;
|
|
1461
|
+
s(
|
|
1462
|
+
p?.has(u),
|
|
1463
|
+
p ? `${n.family} has no shade ${u}; it defines ${[...p].sort((g, x) => g - x).join(", ")}.` : `Unknown color ${n.family}. Define it with theme-color ${n.family} shade=… fill= stroke= ink=.`,
|
|
1464
|
+
e.legendLines[a]
|
|
1465
|
+
);
|
|
1466
|
+
});
|
|
1467
|
+
for (const n of e.objects) {
|
|
1468
|
+
if (n.color !== "auto" && !Rt(n.color)) {
|
|
1469
|
+
const p = h.get(n.color), u = n.shade ?? (n.type === "group" ? yo(e.appearance.theme) : wt);
|
|
1470
|
+
s(
|
|
1471
|
+
p,
|
|
1472
|
+
`Unknown color ${n.color}. Define it with theme-color ${n.color} shade=… fill= stroke= ink=.`,
|
|
1473
|
+
n.line
|
|
1474
|
+
), s(
|
|
1475
|
+
p.has(u),
|
|
1476
|
+
`${n.color} has no shade ${u}${n.shade === void 0 ? " (the default)" : ""}; it defines ${[...p].sort((g, x) => g - x).join(", ")}.`,
|
|
1477
|
+
n.line
|
|
1478
|
+
);
|
|
1479
|
+
}
|
|
1480
|
+
l(n.parent, n.line);
|
|
1481
|
+
const a = /* @__PURE__ */ new Set();
|
|
1482
|
+
for (let p = n; p; p = t.get(p.parent))
|
|
1483
|
+
s(!a.has(p.id), `Containment cycle at ${p.id}.`, n.line), a.add(p.id), s(a.size <= 12, "Limit: 12 nesting levels.", n.line);
|
|
1484
|
+
}
|
|
1485
|
+
if (e.layouts.some((n) => n.scope === "root" && n.algorithm === "lanes"))
|
|
1486
|
+
for (const n of e.objects)
|
|
1487
|
+
n.parent === "root" && (s(
|
|
1488
|
+
n.type === "group",
|
|
1489
|
+
`In a lanes diagram every node sits in a lane; put ${n.id} in= one of the top-level groups.`,
|
|
1490
|
+
n.line
|
|
1491
|
+
), s(!n.frame, `${n.id} is a lane, so it needs its frame; remove frame=.`, n.line));
|
|
1492
|
+
const c = e.layouts.some((n) => n.scope === "root" && n.algorithm === "sequence");
|
|
1493
|
+
if (c)
|
|
1494
|
+
for (const n of e.objects)
|
|
1495
|
+
s(
|
|
1496
|
+
n.type === "node" ? t.get(n.parent)?.type !== "node" : n.parent === "root" && !n.frame,
|
|
1497
|
+
`In a sequence diagram a group is a band of participants: put ${n.id} at the top level and its participants in=${n.id}.`,
|
|
1498
|
+
n.line
|
|
1499
|
+
), s(
|
|
1500
|
+
n.type === "node" || e.objects.some((a) => a.parent === n.id),
|
|
1501
|
+
`Group ${n.id} has no participants, so it has no band to draw. Put a participant in=${n.id} or remove the group.`,
|
|
1502
|
+
n.line
|
|
1503
|
+
);
|
|
1504
|
+
const M = new Set(e.edges.map((n) => n.id)), m = /* @__PURE__ */ new Set();
|
|
1505
|
+
for (const n of e.phases) {
|
|
1506
|
+
s(
|
|
1507
|
+
c,
|
|
1508
|
+
"A phase groups messages in a sequence diagram; use layout root sequence.",
|
|
1509
|
+
n.line
|
|
1510
|
+
);
|
|
1511
|
+
for (const u of n.ids)
|
|
1512
|
+
s(
|
|
1513
|
+
M.has(u),
|
|
1514
|
+
`Unknown message ${u} in phase ${n.id}; a phase lists edge IDs.`,
|
|
1515
|
+
n.line
|
|
1516
|
+
), s(!m.has(u), `${u} is already in another phase.`, n.line), m.add(u);
|
|
1517
|
+
const a = e.edges.flatMap((u, g) => n.ids.includes(u.id) ? [g] : []), p = e.edges.slice(a[0], a[a.length - 1] + 1).filter((u) => !n.ids.includes(u.id) && u.status !== "removed").map((u) => u.id);
|
|
1518
|
+
s(
|
|
1519
|
+
!p.length,
|
|
1520
|
+
`Phase ${n.id} skips ${p.join(", ")}: a phase is a run of consecutive messages. Include it or split the phase.`,
|
|
1521
|
+
n.line
|
|
1522
|
+
);
|
|
1523
|
+
}
|
|
1524
|
+
if (e.wasOrder) {
|
|
1525
|
+
const { ids: n, line: a } = e.wasOrder, p = (g) => e.edges.find((x) => x.id === g), u = (g) => e.warnings.push({ code: "was-order", message: g, line: a });
|
|
1526
|
+
s(
|
|
1527
|
+
e.layouts.some((g) => g.scope === "root" && g.algorithm === "sequence"),
|
|
1528
|
+
"was-order gives the older order of a sequence diagram; use layout root sequence.",
|
|
1529
|
+
a
|
|
1530
|
+
), s(new Set(n).size === n.length, "was-order lists a message twice.", a);
|
|
1531
|
+
for (const g of n)
|
|
1532
|
+
s(p(g)?.status !== "added", `${g} is added, so was-order can't list it.`, a), p(g) || u(`was-order lists ${g}, which is not a message. The panels skip it.`);
|
|
1533
|
+
for (const g of e.edges)
|
|
1534
|
+
g.status !== "added" && !n.includes(g.id) && u(`was-order leaves out ${g.id}, so the older panel keeps it on its new row.`);
|
|
1535
|
+
}
|
|
1536
|
+
for (const n of e.edges)
|
|
1537
|
+
for (const a of [n.source, n.target]) {
|
|
1538
|
+
r(a, n.line);
|
|
1539
|
+
const p = t.get(a), u = a === n.source ? n.target : n.source;
|
|
1540
|
+
s(
|
|
1541
|
+
!c || p.type === "node",
|
|
1542
|
+
`A message joins participants, and ${a} is a group. End ${n.id} on one of its participants.`,
|
|
1543
|
+
n.line
|
|
1544
|
+
), s(
|
|
1545
|
+
p.type === "node" || !p.frame,
|
|
1546
|
+
`${a} is a ${p.frame} group, which has no frame for a line to end on. Connect to one of its members, or use frame=box.`,
|
|
1547
|
+
n.line
|
|
1548
|
+
);
|
|
1549
|
+
let g = !1;
|
|
1550
|
+
for (let x = t.get(u)?.parent; x && x !== "root"; x = t.get(x)?.parent)
|
|
1551
|
+
x === a && (g = !0);
|
|
1552
|
+
s(
|
|
1553
|
+
!g,
|
|
1554
|
+
`${u} is inside ${a}, so a line between them has nowhere to go.`,
|
|
1555
|
+
n.line
|
|
1556
|
+
);
|
|
1557
|
+
}
|
|
1558
|
+
(e.appearance.notes ?? []).forEach((n, a) => {
|
|
1559
|
+
if (!(!n.near || t.has(n.near))) {
|
|
1560
|
+
if (!M.has(n.near)) return r(n.near, e.noteLines[a]);
|
|
1561
|
+
s(
|
|
1562
|
+
c,
|
|
1563
|
+
`near=${n.near} names a connection. Only a sequence diagram anchors a note to a message; use a node or group here.`,
|
|
1564
|
+
e.noteLines[a]
|
|
1565
|
+
);
|
|
1566
|
+
}
|
|
1567
|
+
});
|
|
1568
|
+
const d = new Set(e.edges.map((n) => n.id));
|
|
1569
|
+
for (const n of e.appearance.states ?? [])
|
|
1570
|
+
for (const a of n.ids) {
|
|
1571
|
+
const p = e.stateLines.get(`${n.id}:${a}`);
|
|
1572
|
+
s(
|
|
1573
|
+
t.has(a) || d.has(a),
|
|
1574
|
+
`Unknown node, group or edge ${a} in state ${n.id}.`,
|
|
1575
|
+
p
|
|
1576
|
+
);
|
|
1577
|
+
}
|
|
1578
|
+
const f = new Map(e.layouts.filter((n) => n.algorithm === "cells").map((n) => [n.scope, n]));
|
|
1579
|
+
for (const n of e.objects) {
|
|
1580
|
+
const a = f.get(n.parent);
|
|
1581
|
+
a ? (s(
|
|
1582
|
+
n.type === "node",
|
|
1583
|
+
`Cells are nodes; ${n.id} is a group inside cells ${n.parent}.`,
|
|
1584
|
+
n.line
|
|
1585
|
+
), s(
|
|
1586
|
+
n.shape !== "marker" || (a.columns ?? 0) <= 1 && !a.unit,
|
|
1587
|
+
a.unit ? `A marker cuts a sequence of cells; ${n.parent} is a ${a.unit} layout.` : `A marker cuts one row or column of cells; ${n.parent} has ${a.columns} columns.`,
|
|
1588
|
+
n.line
|
|
1589
|
+
), s(
|
|
1590
|
+
n.span !== "var" || !!a.unit,
|
|
1591
|
+
`span=var is for a byte or bit layout; give ${n.parent} unit=byte or unit=bit.`,
|
|
1592
|
+
n.line
|
|
1593
|
+
)) : (s(
|
|
1594
|
+
n.shape !== "marker",
|
|
1595
|
+
`A marker sits between cells; put ${n.id} in a group with layout cells.`,
|
|
1596
|
+
n.line
|
|
1597
|
+
), s(n.span === void 0, `span= is for cells; ${n.parent} has no layout cells.`, n.line));
|
|
1598
|
+
}
|
|
1599
|
+
for (const n of e.layouts) {
|
|
1600
|
+
l(n.scope, n.line), i(n.scope, n.line, "layout");
|
|
1601
|
+
const a = n.engine?.params.rootId;
|
|
1602
|
+
a && (r(a, n.line), s(t.get(a).type === "node", `The tree root ${a} must be a node.`, n.line));
|
|
1603
|
+
}
|
|
1604
|
+
for (const n of e.hints)
|
|
1605
|
+
if (n.type === "order") {
|
|
1606
|
+
l(n.scope, n.line), i(n.scope, n.line, "layout");
|
|
1607
|
+
for (const a of n.ids)
|
|
1608
|
+
r(a, n.line), i(a, n.line, "position"), s(o(a) === n.scope, `${a} is not a direct child of ${n.scope}.`, n.line);
|
|
1609
|
+
} else if (n.type === "align") {
|
|
1610
|
+
n.ids.forEach((p) => r(p, n.line)), n.ids.forEach((p) => i(p, n.line, "position")), s(new Set(n.ids).size === n.ids.length, "Duplicate member in align.", n.line);
|
|
1611
|
+
const a = o(n.ids[0]);
|
|
1612
|
+
s(
|
|
1613
|
+
n.ids.every((p) => o(p) === a),
|
|
1614
|
+
"Members of align must be direct siblings.",
|
|
1615
|
+
n.line
|
|
1616
|
+
);
|
|
1617
|
+
} else
|
|
1618
|
+
r(n.id, n.line), i(n.id, n.line, "position"), n.type === "near" && (r(n.ref, n.line), i(n.ref, n.line, "position"), s(
|
|
1619
|
+
Ft(t, n.id, n.ref) !== void 0,
|
|
1620
|
+
`Relative placement is between siblings, or with something inside a sibling group. ${n.id} is inside ${o(n.id)}; place ${o(n.id)} relative to ${n.ref} instead.`,
|
|
1621
|
+
n.line
|
|
1622
|
+
)), n.type === "size" && s(
|
|
1623
|
+
t.get(n.id).type === "node",
|
|
1624
|
+
"Use layout min-width/min-height to reserve room in a group.",
|
|
1625
|
+
n.line
|
|
1626
|
+
);
|
|
1627
|
+
}
|
|
1628
|
+
const bt = { width: 1100, height: 720 }, Ze = 12, Ls = 56, Mn = 24, xn = 0, Rs = 56, bn = { w: 260, h: 110 }, vn = (e, t) => Math.max(t.x - e.x - e.w, e.x - t.x - t.w, t.y - e.y - e.h, e.y - t.y - t.h), le = (e) => Math.round(e);
|
|
1629
|
+
function Os(e) {
|
|
1630
|
+
if (!e.appearance.compare || !e.edges.some((o) => o.was)) return e;
|
|
1631
|
+
const t = tt(e.appearance), i = (o) => o ? He(o, t).w : 0;
|
|
1632
|
+
return {
|
|
1633
|
+
...e,
|
|
1634
|
+
edges: e.edges.map((o) => o.was && i(o.was) > i(o.label) ? { ...o, label: o.was } : o)
|
|
1635
|
+
};
|
|
1636
|
+
}
|
|
1637
|
+
function $s(e, t) {
|
|
1638
|
+
if (e.model.edges === t.edges) return e;
|
|
1639
|
+
const i = new Map(t.edges.map((o) => [o.id, o.label]));
|
|
1640
|
+
return {
|
|
1641
|
+
...e,
|
|
1642
|
+
model: { ...e.model, edges: t.edges },
|
|
1643
|
+
edges: e.edges.map((o) => ({ ...o, label: i.get(o.id) }))
|
|
1644
|
+
};
|
|
1645
|
+
}
|
|
1646
|
+
function Ds(e) {
|
|
1647
|
+
const t = Is(e), i = zs(t);
|
|
1648
|
+
return Us(
|
|
1649
|
+
Jn(Ys($s(Ut(Os(i)), i), t))
|
|
1650
|
+
);
|
|
1651
|
+
}
|
|
1652
|
+
const Ns = 24, Ps = 0, kn = 36, Fs = 40, Cs = 16, En = 8, Te = 16, Ye = 20, An = 8, js = 104;
|
|
1653
|
+
function Bs(e, t) {
|
|
1654
|
+
const i = Math.ceil(pe(e.label, t.title));
|
|
1655
|
+
if (e.label.includes(`
|
|
1656
|
+
`) || xt(e.shape, e.w, e.h, t).width < i) return e.w;
|
|
1657
|
+
let o = js;
|
|
1658
|
+
for (; o < e.w && xt(e.shape, o, e.h, t).width < i; ) o += 4;
|
|
1659
|
+
return Math.min(o, e.w);
|
|
1660
|
+
}
|
|
1661
|
+
function Jn(e) {
|
|
1662
|
+
if (!e.model.layouts.some((v) => v.scope === "root" && v.algorithm === "sequence"))
|
|
1663
|
+
return e;
|
|
1664
|
+
const t = e.look, i = new Set(e.model.hints.flatMap((v) => v.type === "size" ? [v.id] : [])), o = e.objects.filter((v) => v.type === "node"), s = e.objects.filter((v) => v.type === "group");
|
|
1665
|
+
if (!o.length) return e;
|
|
1666
|
+
const r = (v, A) => {
|
|
1667
|
+
const F = e.model.hints.find((se) => se.type === "order" && se.scope === v), Z = F?.type === "order" ? F.ids : [];
|
|
1668
|
+
return [...Z, ...A.filter((se) => !Z.includes(se))];
|
|
1669
|
+
}, l = [...new Set(o.map((v) => v.parent === "root" ? v.id : v.parent))], c = r("root", l).flatMap(
|
|
1670
|
+
(v) => e.byId.get(v).type === "node" ? [v] : r(
|
|
1671
|
+
v,
|
|
1672
|
+
o.filter((A) => A.parent === v).map((A) => A.id)
|
|
1673
|
+
)
|
|
1674
|
+
).map((v) => e.byId.get(v)).map((v) => i.has(v.id) ? v : { ...v, w: Bs(v, t) }), M = new Map(c.map((v, A) => [v.id, A])), m = e.model.phases.length ? Math.max(...e.model.phases.map((v) => pe(v.label, t.annotation))) + 2 * Te : 0, d = s.length ? t.groupHeader : 0, f = (v) => c[v - 1].parent !== c[v].parent, n = !!e.model.appearance.compare, a = (v) => [v.label, n ? v.was : ""].filter((A) => !!A), p = (v) => {
|
|
1675
|
+
const A = a(v).map((F) => He(F, t, !0));
|
|
1676
|
+
return { w: Math.max(0, ...A.map((F) => F.w)), h: Math.max(0, ...A.map((F) => F.h)) };
|
|
1677
|
+
}, u = (v) => {
|
|
1678
|
+
const A = a(v).map((F) => sn(F, t));
|
|
1679
|
+
return A.length ? {
|
|
1680
|
+
right: Math.max(...A.map((F) => F.right)),
|
|
1681
|
+
above: Math.max(...A.map((F) => F.above)),
|
|
1682
|
+
below: Math.max(...A.map((F) => F.below))
|
|
1683
|
+
} : sn(void 0, t);
|
|
1684
|
+
}, g = /* @__PURE__ */ new Map(), x = c.map(() => []);
|
|
1685
|
+
for (const v of e.edges) {
|
|
1686
|
+
const [A, F] = [M.get(v.source), M.get(v.target)].sort((se, ae) => se - ae);
|
|
1687
|
+
if (A < F) {
|
|
1688
|
+
const { w: se } = p(v);
|
|
1689
|
+
se && x[F].push({ from: A, room: se + Cs });
|
|
1690
|
+
continue;
|
|
1691
|
+
}
|
|
1692
|
+
const { right: Z } = u(v);
|
|
1693
|
+
g.set(v.source, Math.max(g.get(v.source) ?? 0, Z)), A + 1 < c.length && x[A + 1].push({
|
|
1694
|
+
from: A,
|
|
1695
|
+
room: Z + En + (f(A + 1) ? 2 * Te + c[A + 1].w / 2 : 0)
|
|
1696
|
+
});
|
|
1697
|
+
}
|
|
1698
|
+
const E = [];
|
|
1699
|
+
c.forEach((v, A) => {
|
|
1700
|
+
if (!A) return void E.push(m + Te + v.w / 2);
|
|
1701
|
+
const F = c[A - 1].w / 2 + Fs + (f(A) ? 2 * Te : 0) + v.w / 2;
|
|
1702
|
+
E.push(Math.max(E[A - 1] + F, ...x[A].map((Z) => E[Z.from] + Z.room)));
|
|
1703
|
+
});
|
|
1704
|
+
let R = d + Math.max(0, ...c.map((v) => v.h)) - Ps, L = 0;
|
|
1705
|
+
const H = /* @__PURE__ */ new Map(), I = /* @__PURE__ */ new Map();
|
|
1706
|
+
for (const v of e.edges) {
|
|
1707
|
+
const A = p(v).h, F = v.source === v.target ? u(v) : void 0, Z = F ? F.above : A && A + 1;
|
|
1708
|
+
R = Math.ceil(
|
|
1709
|
+
Math.max(R + Math.max(kn, A ? A + 8 : 0), L + En + Z)
|
|
1710
|
+
), H.set(v.id, R), L = F ? R + F.below : 0, I.set(v.id, { from: R - Math.max(A, kn / 2) - 4, to: Math.max(R, L) + 8 }), F && (R += ze.down);
|
|
1711
|
+
}
|
|
1712
|
+
const P = Math.max(R, L) + Ns, O = new Map(
|
|
1713
|
+
c.map((v) => {
|
|
1714
|
+
const A = le(E[M.get(v.id)] - v.w / 2);
|
|
1715
|
+
return [v.id, { x: A, w: v.w }];
|
|
1716
|
+
})
|
|
1717
|
+
), y = (v) => Math.max(O.get(v.id).x + v.w, E[M.get(v.id)] + (g.get(v.id) ?? 0)), D = e.objects.map((v) => {
|
|
1718
|
+
if (v.type === "group") {
|
|
1719
|
+
const Z = c.filter((S) => S.parent === v.id), se = le(Math.min(...Z.map((S) => O.get(S.id).x)) - Te), ae = le(Math.max(...Z.map((S) => y(S))) + Te - se);
|
|
1720
|
+
return {
|
|
1721
|
+
...v,
|
|
1722
|
+
shade: v.shade ?? 50,
|
|
1723
|
+
x: se,
|
|
1724
|
+
y: 0,
|
|
1725
|
+
w: ae,
|
|
1726
|
+
h: P + Te,
|
|
1727
|
+
localX: se,
|
|
1728
|
+
localY: 0,
|
|
1729
|
+
baseX: se,
|
|
1730
|
+
baseY: 0
|
|
1731
|
+
};
|
|
1732
|
+
}
|
|
1733
|
+
const { x: A, w: F } = O.get(v.id);
|
|
1734
|
+
return {
|
|
1735
|
+
...v,
|
|
1736
|
+
w: F,
|
|
1737
|
+
x: A,
|
|
1738
|
+
y: d,
|
|
1739
|
+
localX: A,
|
|
1740
|
+
localY: d,
|
|
1741
|
+
baseX: A,
|
|
1742
|
+
baseY: d,
|
|
1743
|
+
lifeline: P - d - v.h
|
|
1744
|
+
};
|
|
1745
|
+
}), w = Math.min(0, ...D.map((v) => v.x)) - (m ? 0 : Te), b = Math.max(
|
|
1746
|
+
...D.map((v) => v.x + v.w + Te),
|
|
1747
|
+
...c.map((v) => E[M.get(v.id)] + (g.get(v.id) ?? 0))
|
|
1748
|
+
), _ = {
|
|
1749
|
+
x: w - Ye,
|
|
1750
|
+
y: -Ye,
|
|
1751
|
+
w: b - w + 2 * Ye,
|
|
1752
|
+
h: P + Te + 2 * Ye
|
|
1753
|
+
}, N = e.model.appearance.notes ?? [], Q = new Map([...H].filter(([v]) => !e.byId.has(v))), z = Qo(t, N, Q, {
|
|
1754
|
+
left: w - (m ? Ye : An),
|
|
1755
|
+
right: b + An,
|
|
1756
|
+
top: 0
|
|
1757
|
+
}), Y = z.filter((v) => v !== null), $ = Y.length ? nn([_, nn(Y, Ye)]) : _, k = $.x < _.x ? _.x : void 0, T = e.model.phases.map((v) => {
|
|
1758
|
+
const A = v.ids.map((F) => I.get(F));
|
|
1759
|
+
return {
|
|
1760
|
+
id: v.id,
|
|
1761
|
+
label: v.label,
|
|
1762
|
+
from: le(Math.min(...A.map((F) => F.from))),
|
|
1763
|
+
to: le(Math.max(...A.map((F) => F.to)))
|
|
1764
|
+
};
|
|
1765
|
+
}).sort((v, A) => v.from - A.from), j = T.map(({ id: v, label: A, from: F, to: Z }, se) => ({
|
|
1766
|
+
id: v,
|
|
1767
|
+
label: A,
|
|
1768
|
+
y: F,
|
|
1769
|
+
h: Math.min(Z, T[se + 1]?.from ?? Z) - F
|
|
1770
|
+
}));
|
|
1771
|
+
return {
|
|
1772
|
+
...e,
|
|
1773
|
+
objects: D,
|
|
1774
|
+
byId: new Map(D.map((v) => [v.id, v])),
|
|
1775
|
+
edges: e.edges.map((v) => ({ ...v, lane: void 0, row: H.get(v.id) })),
|
|
1776
|
+
sequence: {
|
|
1777
|
+
panel: $,
|
|
1778
|
+
phases: j,
|
|
1779
|
+
...k !== void 0 ? { phaseX: k } : {},
|
|
1780
|
+
...Y.length ? { notes: z, inner: _ } : {}
|
|
1781
|
+
}
|
|
1782
|
+
};
|
|
1783
|
+
}
|
|
1784
|
+
function Us(e) {
|
|
1785
|
+
const t = e.model.wasOrder?.ids.flatMap((r) => e.edges.filter((l) => l.id === r));
|
|
1786
|
+
if (!t || !e.sequence) return e;
|
|
1787
|
+
const i = [...t], o = Jn({
|
|
1788
|
+
...e,
|
|
1789
|
+
edges: e.edges.map((r) => t.includes(r) ? i.shift() : r)
|
|
1790
|
+
}), s = (r) => r.objects.find((l) => l.type === "node")?.lifeline ?? 0;
|
|
1791
|
+
return {
|
|
1792
|
+
...e,
|
|
1793
|
+
sequence: {
|
|
1794
|
+
...e.sequence,
|
|
1795
|
+
before: {
|
|
1796
|
+
rows: Object.fromEntries(o.edges.map((r) => [r.id, r.row])),
|
|
1797
|
+
phases: o.sequence.phases,
|
|
1798
|
+
grow: Math.max(0, s(o) - s(e))
|
|
1799
|
+
}
|
|
1800
|
+
}
|
|
1801
|
+
};
|
|
1802
|
+
}
|
|
1803
|
+
function zs(e) {
|
|
1804
|
+
if (!e.objects.some((o) => o.frame)) return e;
|
|
1805
|
+
const t = new Map(e.objects.map((o) => [o.id, o])), i = (o) => {
|
|
1806
|
+
const s = [];
|
|
1807
|
+
for (let r = t.get(o).parent; r !== "root" && t.get(r).frame; r = t.get(r).parent)
|
|
1808
|
+
s.unshift(r);
|
|
1809
|
+
return s;
|
|
1810
|
+
};
|
|
1811
|
+
return {
|
|
1812
|
+
...e,
|
|
1813
|
+
objects: e.objects.filter((o) => !o.frame).map((o) => ({ ...o, parent: Xe(t, o.id), soft: i(o.id) }))
|
|
1814
|
+
};
|
|
1815
|
+
}
|
|
1816
|
+
function Ht(e, t, i = 0) {
|
|
1817
|
+
if (!e.some((s) => t(s)?.[i])) return e;
|
|
1818
|
+
const o = /* @__PURE__ */ new Map();
|
|
1819
|
+
return e.forEach((s, r) => {
|
|
1820
|
+
const l = t(s)?.[i] ?? `\0${s}`, h = o.get(l) ?? { at: 0, ids: [] };
|
|
1821
|
+
h.at += r, h.ids.push(s), o.set(l, h);
|
|
1822
|
+
}), [...o].sort(([, s], [, r]) => s.at / s.ids.length - r.at / r.ids.length).flatMap(([s, r]) => s.startsWith("\0") ? r.ids : Ht(r.ids, t, i + 1));
|
|
1823
|
+
}
|
|
1824
|
+
const qs = 8;
|
|
1825
|
+
function vt(e = [], t = [], i) {
|
|
1826
|
+
const o = e.filter((r) => !t.includes(r)).length, s = t.filter((r) => !e.includes(r)).length;
|
|
1827
|
+
return !o && !s ? 0 : (o + s) * Ve + (i && s ? Mt : 0) + qs;
|
|
1828
|
+
}
|
|
1829
|
+
function eo(e, t, i, o) {
|
|
1830
|
+
const s = new Set(e.flatMap((c) => i(c) ?? [])), r = (c, M) => (i(c) ?? []).filter((m) => !M.has(m)), l = new Set(t.flatMap((c) => i(c) ?? []));
|
|
1831
|
+
let h = 0;
|
|
1832
|
+
for (const c of e)
|
|
1833
|
+
for (const M of t) h = Math.max(h, vt(r(c, l), r(M, s), o));
|
|
1834
|
+
return h;
|
|
1835
|
+
}
|
|
1836
|
+
const ft = (e, t) => e.x < t.x + t.w && e.x + e.w > t.x && e.y < t.y + t.h && e.y + e.h > t.y, Gs = (e, t) => ({
|
|
1837
|
+
x: e.x - t,
|
|
1838
|
+
y: e.y - t,
|
|
1839
|
+
w: e.w + 2 * t,
|
|
1840
|
+
h: e.h + 2 * t
|
|
1841
|
+
});
|
|
1842
|
+
function Hs(e, t) {
|
|
1843
|
+
const i = Math.max(e.x, t.x), o = Math.min(e.x + e.w, t.x + t.w), s = Math.max(e.y, t.y), r = Math.min(e.y + e.h, t.y + t.h);
|
|
1844
|
+
if (o > i) {
|
|
1845
|
+
const c = Math.min(e.y + e.h, t.y + t.h);
|
|
1846
|
+
return { x: i, y: c, w: o - i, h: Math.max(e.y, t.y) - c };
|
|
1847
|
+
}
|
|
1848
|
+
if (r > s) {
|
|
1849
|
+
const c = Math.min(e.x + e.w, t.x + t.w);
|
|
1850
|
+
return { x: c, y: s, w: Math.max(e.x, t.x) - c, h: r - s };
|
|
1851
|
+
}
|
|
1852
|
+
const l = Math.min(e.x, t.x), h = Math.min(e.y, t.y);
|
|
1853
|
+
return { x: l, y: h, w: Math.max(e.x + e.w, t.x + t.w) - l, h: Math.max(e.y + e.h, t.y + t.h) - h };
|
|
1854
|
+
}
|
|
1855
|
+
function Ys(e, t) {
|
|
1856
|
+
const i = t.objects.filter((d) => d.frame);
|
|
1857
|
+
if (!i.length) return e;
|
|
1858
|
+
const o = new Map(t.objects.map((d) => [d.id, d])), s = new Map(
|
|
1859
|
+
e.objects.map((d) => [d.id, { ...d, parent: o.get(d.id).parent, soft: void 0 }])
|
|
1860
|
+
), r = [...e.diagnostics], l = (d, f) => {
|
|
1861
|
+
for (let n = o.get(d)?.parent; n && n !== "root"; n = o.get(n)?.parent)
|
|
1862
|
+
if (n === f) return !0;
|
|
1863
|
+
return !1;
|
|
1864
|
+
}, h = (d) => {
|
|
1865
|
+
let f = 0;
|
|
1866
|
+
for (let n = o.get(d).parent; n !== "root"; n = o.get(n).parent) f++;
|
|
1867
|
+
return f;
|
|
1868
|
+
}, c = (d) => d.frame === "soft" ? (d.hull ?? []).map((f) => ({ ...f, x: f.x + d.x, y: f.y + d.y })) : d.frame ? [] : [d];
|
|
1869
|
+
for (const d of [...i].sort((f, n) => h(n.id) - h(f.id))) {
|
|
1870
|
+
const f = [...s.values()].filter((O) => l(O.id, d.id)), n = s.get(Xe(o, d.id)), a = n ? Hn(n, pt(e.look, n.titleLines)) : { x: 0, y: 0 }, p = [...s.values()].filter(
|
|
1871
|
+
(O) => !O.frame && !l(O.id, d.id) && !l(d.id, O.id)
|
|
1872
|
+
), u = f.flatMap((O) => c(O).map((y) => Gs(y, Ve)));
|
|
1873
|
+
let g = [], x = 0;
|
|
1874
|
+
if (u.length) {
|
|
1875
|
+
const O = u.reduce((z, Y) => Y.y < z.y || Y.y === z.y && Y.x < z.x ? Y : z);
|
|
1876
|
+
O.y -= Mt, O.h += Mt, g = [O, ...u.filter((z) => z !== O)];
|
|
1877
|
+
const y = Math.min(...g.map((z) => z.x)), D = Math.min(...g.map((z) => z.y)), w = {
|
|
1878
|
+
x: y,
|
|
1879
|
+
y: D,
|
|
1880
|
+
w: Math.max(...g.map((z) => z.x + z.w)) - y,
|
|
1881
|
+
h: Math.max(...g.map((z) => z.y + z.h)) - D
|
|
1882
|
+
};
|
|
1883
|
+
p.some((z) => ft(z, w)) || (g = [w]);
|
|
1884
|
+
const b = (z, Y) => Math.max(Y.x - (z.x + z.w), z.x - (Y.x + Y.w), Y.y - (z.y + z.h), z.y - (Y.y + Y.h), 0), _ = [g[0]], N = g.slice(1), Q = [];
|
|
1885
|
+
for (; N.length; ) {
|
|
1886
|
+
let z = { gap: 1 / 0, a: g[0], i: 0 };
|
|
1887
|
+
for (const k of _)
|
|
1888
|
+
N.forEach((T, j) => {
|
|
1889
|
+
const v = b(k, T);
|
|
1890
|
+
v < z.gap && (z = { gap: v, a: k, i: j });
|
|
1891
|
+
});
|
|
1892
|
+
const [Y] = N.splice(z.i, 1);
|
|
1893
|
+
if (_.push(Y), ft(z.a, Y)) continue;
|
|
1894
|
+
const $ = Hs(z.a, Y);
|
|
1895
|
+
p.some((k) => ft(k, $)) ? x++ : Q.push($);
|
|
1896
|
+
}
|
|
1897
|
+
g.push(...Q);
|
|
1898
|
+
}
|
|
1899
|
+
const E = g.length ? Math.min(...g.map((O) => O.x)) : a.x, R = g.length ? Math.min(...g.map((O) => O.y)) : a.y, L = g.length ? Math.max(...g.map((O) => O.x + O.w)) : a.x, H = g.length ? Math.max(...g.map((O) => O.y + O.h)) : a.y, I = { x: E - a.x, y: R - a.y };
|
|
1900
|
+
if (s.set(d.id, {
|
|
1901
|
+
...d,
|
|
1902
|
+
x: E,
|
|
1903
|
+
y: R,
|
|
1904
|
+
w: L - E,
|
|
1905
|
+
h: H - R,
|
|
1906
|
+
localX: I.x,
|
|
1907
|
+
localY: I.y,
|
|
1908
|
+
baseX: I.x,
|
|
1909
|
+
baseY: I.y,
|
|
1910
|
+
depth: h(d.id),
|
|
1911
|
+
hull: g.map((O) => ({ x: O.x - E, y: O.y - R, w: O.w, h: O.h }))
|
|
1912
|
+
}), d.frame !== "soft") continue;
|
|
1913
|
+
const P = p.filter((O) => g.some((y) => ft(O, y)));
|
|
1914
|
+
P.length && r.push({
|
|
1915
|
+
level: "warning",
|
|
1916
|
+
code: "soft-overlap",
|
|
1917
|
+
message: `${d.id}'s tint covers ${P.map((O) => O.id).join(", ")}, which ${P.length > 1 ? "are" : "is"} not in it. Place its members together, or use frame=box.`,
|
|
1918
|
+
line: d.line,
|
|
1919
|
+
ids: [d.id, ...P.map((O) => O.id)]
|
|
1920
|
+
}), x && r.push({
|
|
1921
|
+
level: "info",
|
|
1922
|
+
code: "soft-split",
|
|
1923
|
+
message: `${d.id}'s members are apart, so its tint is drawn in ${x + 1} pieces. Place its members together, or use frame=box.`,
|
|
1924
|
+
line: d.line,
|
|
1925
|
+
ids: [d.id]
|
|
1926
|
+
});
|
|
1927
|
+
}
|
|
1928
|
+
const M = new Map(t.objects.map((d, f) => [d.id, f])), m = [...s.values()].sort((d, f) => M.get(d.id) - M.get(f.id));
|
|
1929
|
+
return { ...e, model: t, objects: m, byId: new Map(m.map((d) => [d.id, d])), diagnostics: r };
|
|
1930
|
+
}
|
|
1931
|
+
const _n = 4, Ws = /* @__PURE__ */ new Set(["slate", "stone"]);
|
|
1932
|
+
function Xs(e) {
|
|
1933
|
+
const t = [], i = e.objects.filter((l) => l.color !== "auto"), o = [...new Set(i.map((l) => l.color))].filter((l) => !Ws.has(l));
|
|
1934
|
+
o.length > _n && t.push({
|
|
1935
|
+
level: "info",
|
|
1936
|
+
code: "many-colors",
|
|
1937
|
+
message: `${o.length} accent colors (${o.join(", ")}). Use two to four, each for one role, with slate or stone for the rest, and say what each one means with legend lines.`,
|
|
1938
|
+
line: i.find((l) => l.color === o[_n])?.line,
|
|
1939
|
+
ids: i.filter((l) => o.includes(l.color)).map((l) => l.id)
|
|
1940
|
+
});
|
|
1941
|
+
const s = new Map(e.objects.map((l) => [l.id, l])), r = i.filter((l) => s.get(l.parent)?.color === l.color);
|
|
1942
|
+
return r.length && t.push({
|
|
1943
|
+
level: "info",
|
|
1944
|
+
code: "color-matches-container",
|
|
1945
|
+
message: `${r.map((l) => l.id).join(", ")} ${r.length > 1 ? "repeat their containers’ colors" : "repeats its container’s color"}. Drop the color to inherit it, or give the member a family of its own.`,
|
|
1946
|
+
line: r[0].line,
|
|
1947
|
+
ids: r.map((l) => l.id)
|
|
1948
|
+
}), t;
|
|
1949
|
+
}
|
|
1950
|
+
function We(e) {
|
|
1951
|
+
return e.direction !== "auto" ? e.direction : "right";
|
|
1952
|
+
}
|
|
1953
|
+
function Ks(e, t) {
|
|
1954
|
+
const i = new Map(e.objects.map((o) => [o.id, o.parent]));
|
|
1955
|
+
for (let o = t; o; o = o === "root" ? void 0 : i.get(o)) {
|
|
1956
|
+
const s = e.layouts.find((r) => r.scope === o);
|
|
1957
|
+
if (s) return o === t || s.engine ? s : void 0;
|
|
1958
|
+
}
|
|
1959
|
+
}
|
|
1960
|
+
const Qs = 240;
|
|
1961
|
+
function Vs(e, t, i) {
|
|
1962
|
+
const o = Math.ceil(pe(e, i.groupTitle)) + Dt;
|
|
1963
|
+
let s = Math.max(t, Qs);
|
|
1964
|
+
if (o <= s) return { w: o, lines: 1 };
|
|
1965
|
+
const r = () => ot(e, s - Dt, i.groupTitle, !0).length;
|
|
1966
|
+
for (; r() > on && s < o; ) s += 8;
|
|
1967
|
+
return { w: Math.min(s, o), lines: Math.min(r(), on) };
|
|
1968
|
+
}
|
|
1969
|
+
const Sn = 16, Zs = 1.5, Oe = 14;
|
|
1970
|
+
function _t(e, t, i, o) {
|
|
1971
|
+
const s = He(i, o);
|
|
1972
|
+
return { a: e, b: t, w: s.w + 2 * Oe, h: s.h + 2 * Oe };
|
|
1973
|
+
}
|
|
1974
|
+
function jt(e, t, i, o, s) {
|
|
1975
|
+
let r = o;
|
|
1976
|
+
for (const l of e)
|
|
1977
|
+
(l.a === t && l.b === i || l.a === i && l.b === t) && (r = Math.max(r, s ? l.w : l.h));
|
|
1978
|
+
return r;
|
|
1979
|
+
}
|
|
1980
|
+
function St(e, t) {
|
|
1981
|
+
return e.layouts.find((i) => i.scope === t) ?? {
|
|
1982
|
+
scope: t,
|
|
1983
|
+
algorithm: t === "root" ? "flow" : "column",
|
|
1984
|
+
direction: "auto",
|
|
1985
|
+
fold: "auto",
|
|
1986
|
+
gap: t === "root" ? 48 : 24,
|
|
1987
|
+
minWidth: 0,
|
|
1988
|
+
minHeight: 0,
|
|
1989
|
+
line: 0
|
|
1990
|
+
};
|
|
1991
|
+
}
|
|
1992
|
+
const In = 2;
|
|
1993
|
+
function Js(e, t, i) {
|
|
1994
|
+
const o = e.label.includes(`
|
|
1995
|
+
`) && e.shape !== "circle" ? e.label.split(`
|
|
1996
|
+
`) : [], s = Math.max(jn(e.label, i.title), ...o.map((l) => pe(l, i.title)));
|
|
1997
|
+
let r = t.w;
|
|
1998
|
+
for (; xt(e.shape, r, t.h, i).width < s && r < t.w * In; ) r += 4;
|
|
1999
|
+
return Math.min(r, t.w * In);
|
|
2000
|
+
}
|
|
2001
|
+
function Tn(e, t, i) {
|
|
2002
|
+
const o = Yn(e.shape);
|
|
2003
|
+
if (e.shape === "diamond") return ei(e, t, o, i);
|
|
2004
|
+
const s = t?.width ?? Js(e, o, i), r = xt(e.shape, s, t?.height ?? o.h, i), l = nt(e.label, r.width, i).length;
|
|
2005
|
+
return t?.height !== void 0 ? { w: s, h: t.height, overflow: l * i.title.lineHeight > r.maxHeight + 0.5 } : {
|
|
2006
|
+
w: s,
|
|
2007
|
+
h: Ro(e.shape, l, e.shape === "circle" ? o.h : 0, i),
|
|
2008
|
+
overflow: !1
|
|
2009
|
+
};
|
|
2010
|
+
}
|
|
2011
|
+
function ei(e, t, i, o) {
|
|
2012
|
+
const s = jn(e.label, o.title), r = (h) => ($o(e.label, h, o) ?? 0) >= s;
|
|
2013
|
+
if (t) {
|
|
2014
|
+
const h = Math.max(t.width, t.height ?? 0);
|
|
2015
|
+
return { w: h, h, overflow: !r(h) };
|
|
2016
|
+
}
|
|
2017
|
+
let l = i.w;
|
|
2018
|
+
for (; !r(l); ) l += 4;
|
|
2019
|
+
return { w: l, h: l, overflow: !1 };
|
|
2020
|
+
}
|
|
2021
|
+
const ti = 1.4;
|
|
2022
|
+
function Je(e, t) {
|
|
2023
|
+
const i = new Map(e.map((f) => [f, []]));
|
|
2024
|
+
for (const [f, n] of t)
|
|
2025
|
+
f !== n && i.has(f) && i.has(n) && !i.get(f).includes(n) && i.get(f).push(n);
|
|
2026
|
+
const o = new Set([...i.values()].flat()), s = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Set(), l = (f) => {
|
|
2027
|
+
s.set(f, "open");
|
|
2028
|
+
for (const n of i.get(f))
|
|
2029
|
+
s.get(n) === "open" ? r.add(f + "\0" + n) : s.has(n) || l(n);
|
|
2030
|
+
s.set(f, "done");
|
|
2031
|
+
};
|
|
2032
|
+
for (const f of [...e.filter((n) => !o.has(n)), ...e]) s.has(f) || l(f);
|
|
2033
|
+
const h = new Map(e.map((f) => [f, 0])), c = new Map(e.map((f) => [f, 0])), M = (f) => i.get(f).filter((n) => !r.has(f + "\0" + n));
|
|
2034
|
+
for (const f of e) for (const n of M(f)) h.set(n, h.get(n) + 1);
|
|
2035
|
+
const m = e.filter((f) => !h.get(f));
|
|
2036
|
+
for (; m.length; ) {
|
|
2037
|
+
const f = m.shift();
|
|
2038
|
+
for (const n of M(f))
|
|
2039
|
+
c.set(n, Math.max(c.get(n), c.get(f) + 1)), h.set(n, h.get(n) - 1), h.get(n) || m.push(n);
|
|
2040
|
+
}
|
|
2041
|
+
const d = [];
|
|
2042
|
+
for (const f of e) (d[c.get(f)] ||= []).push(f);
|
|
2043
|
+
return d.filter(Boolean);
|
|
2044
|
+
}
|
|
2045
|
+
const to = 3, Ln = 5, Rn = 1.25, Ge = 20, ni = 3, oi = 2, si = 1;
|
|
2046
|
+
function ii(e, t) {
|
|
2047
|
+
const i = new Map(e.map((h) => [h, []]));
|
|
2048
|
+
for (const [h, c] of t) i.get(h)?.push(c);
|
|
2049
|
+
const o = (h) => {
|
|
2050
|
+
const c = /* @__PURE__ */ new Set([h]), M = [h];
|
|
2051
|
+
for (; M.length; )
|
|
2052
|
+
for (const m of i.get(M.shift()) ?? [])
|
|
2053
|
+
c.has(m) || (c.add(m), M.push(m));
|
|
2054
|
+
return c;
|
|
2055
|
+
}, s = new Map(e.map((h) => [h, o(h)])), r = [], l = /* @__PURE__ */ new Set();
|
|
2056
|
+
for (const h of e) {
|
|
2057
|
+
if (l.has(h)) continue;
|
|
2058
|
+
const c = e.filter((M) => s.get(h).has(M) && s.get(M).has(h));
|
|
2059
|
+
c.forEach((M) => l.add(M)), c.length > 1 && r.push(c);
|
|
2060
|
+
}
|
|
2061
|
+
return r;
|
|
2062
|
+
}
|
|
2063
|
+
function It(e, t, i, o, s, r = [], l = /* @__PURE__ */ new Set(), h = t, {
|
|
2064
|
+
aspect: c = to,
|
|
2065
|
+
fewest: M = 4,
|
|
2066
|
+
room: m = i === "right" ? bt.width : bt.height
|
|
2067
|
+
} = {}) {
|
|
2068
|
+
const d = new Map(e.map(($) => [$.id, $])), f = i === "right" ? "x" : "y", n = i === "right" ? "y" : "x", a = ($, k) => k === "x" ? $.w : $.h, p = ($) => {
|
|
2069
|
+
const k = [...e].sort((j, v) => $.get(j.id)[f] - $.get(v.id)[f]), T = [];
|
|
2070
|
+
for (const j of k) {
|
|
2071
|
+
const v = $.get(j.id)[f], A = v + a(j, f), F = T[T.length - 1];
|
|
2072
|
+
F && v < F.end ? (F.end = Math.max(F.end, A), F.ids.push(j.id)) : T.push({ start: v, end: A, ids: [j.id] });
|
|
2073
|
+
}
|
|
2074
|
+
return T;
|
|
2075
|
+
}, u = p(t);
|
|
2076
|
+
let g = p(h);
|
|
2077
|
+
const x = ($) => $.map((k) => [...k.ids].sort().join(",")).join("|");
|
|
2078
|
+
x(g) !== x(u) && (h = t, g = u);
|
|
2079
|
+
const E = ($, k) => {
|
|
2080
|
+
const T = Math.min(...e.map((v) => $.get(v.id)[k]));
|
|
2081
|
+
return Math.max(...e.map((v) => $.get(v.id)[k] + a(v, k))) - T;
|
|
2082
|
+
}, R = ($, k, T = 1) => $ <= m * T || $ <= c * k * T, L = ($) => R(E($, f), E($, n)), H = ($) => L($) || E($, f) <= m * Rn;
|
|
2083
|
+
if (e.length < M || L(h) && H(t)) return { positions: t };
|
|
2084
|
+
const I = new Map(u.flatMap(($, k) => $.ids.map((T) => [T, k]))), P = ($, k, T) => {
|
|
2085
|
+
const [j, v] = [I.get(k), I.get(T)];
|
|
2086
|
+
return j !== void 0 && v !== void 0 && Math.min(j, v) < $ && Math.max(j, v) >= $;
|
|
2087
|
+
}, O = ($) => s.filter(([k, T]) => P($, k, T)).length, y = ii(
|
|
2088
|
+
e.map(($) => $.id),
|
|
2089
|
+
s
|
|
2090
|
+
), D = ($) => ni * [...l].filter((k) => s.some((T) => T[0] === k && P($, ...T))).length + oi * y.filter((k) => k.some((T) => P($, k[0], T))).length, w = ($, k) => {
|
|
2091
|
+
const T = (k ? r : []).filter((j) => P($, j.a, j.b)).map((j) => (i === "right" ? j.h : j.w) - 2 * Oe);
|
|
2092
|
+
return Math.max(
|
|
2093
|
+
o + 40,
|
|
2094
|
+
84,
|
|
2095
|
+
T.length ? Math.max(...T) + 2 * Oe : 0,
|
|
2096
|
+
(O($) + 1) * Ge + T.reduce((j, v) => j + v, 0)
|
|
2097
|
+
);
|
|
2098
|
+
}, b = ($, k) => {
|
|
2099
|
+
const T = k[k.length - 1].end - k[0].start, j = [], v = new Map(k.flatMap((A) => A.ids.map((F) => [F, A.start])));
|
|
2100
|
+
for (let A = 1; A < $; A++) {
|
|
2101
|
+
const F = (W) => s.filter((X) => P(W, ...X)).reduce((X, [C, K]) => {
|
|
2102
|
+
const [te, ce] = I.get(C) < I.get(K) ? [C, K] : [K, C];
|
|
2103
|
+
return X + Math.abs(v.get(te) - ae - (v.get(ce) - k[W].start));
|
|
2104
|
+
}, 0) / (T / $), Z = k[0].start + T * A / $, se = (W) => O(W) + D(W) + F(W) * si + Math.abs(k[W].start - Z) / (T / $) * 2, ae = k[j.at(-1) ?? 0].start, S = T / $, q = (W, X, C) => k[W - 1].end - ae >= S * C && k[W - 1].end - ae <= S * (1 + X) && k[k.length - 1].end - k[W].start <= S * ($ - A) * (1 + X), G = (W) => !D(W) && q(W, 0.25, 0.5) ? 0 : !D(W) && q(W, 0.5, 0) ? 1 : q(W, 0.25, 0.5) ? 2 : 3;
|
|
2105
|
+
let U = 0;
|
|
2106
|
+
for (let W = (j.at(-1) ?? 0) + 1; W < k.length; W++)
|
|
2107
|
+
(!U || G(W) < G(U) || G(W) === G(U) && se(W) < se(U)) && (U = W);
|
|
2108
|
+
U && j.push(U);
|
|
2109
|
+
}
|
|
2110
|
+
return j;
|
|
2111
|
+
}, _ = new Set(
|
|
2112
|
+
u.flatMap(
|
|
2113
|
+
($) => $.ids.length > 1 ? $.ids.filter((k) => !s.some(([T, j]) => T === k && j !== k)) : []
|
|
2114
|
+
)
|
|
2115
|
+
), N = ($, k) => {
|
|
2116
|
+
const T = [];
|
|
2117
|
+
return k.forEach((j, v) => v === 0 || $.includes(v) ? T.push([j]) : T.at(-1).push(j)), T;
|
|
2118
|
+
}, Q = ($, k) => {
|
|
2119
|
+
const T = N($, k), j = new Map(T.flatMap((F, Z) => F.flatMap((se) => se.ids.map((ae) => [ae, Z])))), v = new Map(k.flatMap((F) => F.ids.map((Z) => [Z, F.start]))), A = /* @__PURE__ */ new Map();
|
|
2120
|
+
for (const [F, Z] of T.entries()) {
|
|
2121
|
+
if (!F) continue;
|
|
2122
|
+
const se = [];
|
|
2123
|
+
for (const ae of Z[0].ids) {
|
|
2124
|
+
if (l.has(ae)) continue;
|
|
2125
|
+
const S = s.filter(([C, K]) => K === ae && C !== ae).map(([C]) => C), q = s.filter(([C, K]) => C === ae && K !== ae).map(([, C]) => C);
|
|
2126
|
+
if (!S.length || S.some((C) => j.get(C) !== F - 1)) continue;
|
|
2127
|
+
const G = (C, K) => v.get(C) - T[K][0].start, U = (C) => S.reduce((K, te) => K + Math.abs(G(te, F - 1) - G(ae, C)), 0) + q.reduce((K, te) => K + Math.abs(G(ae, C) - G(te, j.get(te))), 0), W = (C) => (C === F - 1 ? 0 : S.length) + q.filter((K) => j.get(K) !== C).length;
|
|
2128
|
+
if (W(F - 1) > W(F) || U(F - 1) >= U(F)) continue;
|
|
2129
|
+
const X = S.reduce((C, K) => v.get(K) > v.get(C) ? K : C);
|
|
2130
|
+
se.push({ id: ae, source: X, saves: U(F) - U(F - 1) });
|
|
2131
|
+
}
|
|
2132
|
+
se.sort((ae, S) => S.saves - ae.saves);
|
|
2133
|
+
for (const ae of se.slice(0, Z[0].ids.length - 1)) A.set(ae.id, ae.source);
|
|
2134
|
+
}
|
|
2135
|
+
return A;
|
|
2136
|
+
}, z = ($, k, T, j, v = /* @__PURE__ */ new Map()) => {
|
|
2137
|
+
const A = N($, k);
|
|
2138
|
+
if (v.size) {
|
|
2139
|
+
T = new Map(T);
|
|
2140
|
+
const q = [];
|
|
2141
|
+
for (const [G, U] of v) {
|
|
2142
|
+
const W = d.get(G);
|
|
2143
|
+
let C = T.get(U)[n] + (a(d.get(U), n) - a(W, n)) / 2;
|
|
2144
|
+
for (const K of q) C < K.hi + o && C + a(W, n) > K.lo && (C = K.hi + o);
|
|
2145
|
+
q.push({ lo: C, hi: C + a(W, n) }), T.set(G, { ...T.get(G), [n]: C });
|
|
2146
|
+
}
|
|
2147
|
+
}
|
|
2148
|
+
const F = /* @__PURE__ */ new Map(), Z = [];
|
|
2149
|
+
let se = 0, ae = 0, S = 0;
|
|
2150
|
+
for (const [q, G] of A.entries()) {
|
|
2151
|
+
const U = A[q + 1]?.[0].ids ?? [], W = [
|
|
2152
|
+
...G.flatMap((oe) => oe.ids).filter((oe) => !v.has(oe)),
|
|
2153
|
+
...U.filter((oe) => v.has(oe))
|
|
2154
|
+
], X = Math.min(...W.map((oe) => T.get(oe)[f])), C = Math.min(...W.map((oe) => T.get(oe)[n])), K = Math.max(...W.map((oe) => T.get(oe)[n] + a(d.get(oe), n)));
|
|
2155
|
+
for (const oe of W) {
|
|
2156
|
+
const ke = T.get(oe), Se = ke[f] - X, Me = ke[n] - C + se;
|
|
2157
|
+
F.set(oe, i === "right" ? { x: Se, y: Me } : { x: Me, y: Se });
|
|
2158
|
+
}
|
|
2159
|
+
const te = q < $.length ? w($[q], j) : 0, ce = W.filter((oe) => !_.has(oe)), ue = ce.length ? ce : W;
|
|
2160
|
+
se += K - C + te, S += Math.max(...ue.map((oe) => T.get(oe)[n] + a(d.get(oe), n))) - Math.min(...ue.map((oe) => T.get(oe)[n])) + te, ae = Math.max(
|
|
2161
|
+
ae,
|
|
2162
|
+
Math.max(...W.map((oe) => T.get(oe)[f] + a(d.get(oe), f))) - X
|
|
2163
|
+
), Z.push(W);
|
|
2164
|
+
}
|
|
2165
|
+
return {
|
|
2166
|
+
out: F,
|
|
2167
|
+
length: ae,
|
|
2168
|
+
// The depth that decides the count leaves side leaves out.
|
|
2169
|
+
depth: S,
|
|
2170
|
+
count: A.length,
|
|
2171
|
+
bands: Z
|
|
2172
|
+
};
|
|
2173
|
+
};
|
|
2174
|
+
let Y = 0;
|
|
2175
|
+
if (!L(h))
|
|
2176
|
+
for (let $ = 2; $ <= u.length && !Y; $++) {
|
|
2177
|
+
const k = z(b($, g), g, h, !1);
|
|
2178
|
+
k.count === $ && R(k.length, k.depth) && (Y = $);
|
|
2179
|
+
}
|
|
2180
|
+
for (let $ = Math.max(2, Y); $ <= u.length; $++) {
|
|
2181
|
+
const k = b($, g), T = z(k, u, t, !0), j = $ === Y ? Rn : 1;
|
|
2182
|
+
if (T.count !== $ || !R(T.length, T.depth, j)) continue;
|
|
2183
|
+
const v = Q(k, g), A = v.size ? z(k, u, t, !0, v) : void 0, F = A && R(A.length, A.depth, j) ? A : T;
|
|
2184
|
+
return { positions: F.out, fold: { bands: F.bands, axis: i } };
|
|
2185
|
+
}
|
|
2186
|
+
return { positions: t };
|
|
2187
|
+
}
|
|
2188
|
+
function ai(e, t, i, o, s) {
|
|
2189
|
+
const r = /* @__PURE__ */ new Map();
|
|
2190
|
+
for (const { scope: l, fold: h } of e) {
|
|
2191
|
+
const c = h.axis === "right", M = (E) => c ? E.y : E.x, m = (E) => c ? E.y + E.h : E.x + E.w, d = (E) => c ? E.x : E.y, f = (E) => c ? E.x + E.w : E.y + E.h, n = (E) => (d(E) + f(E)) / 2, a = (E) => (M(E) + m(E)) / 2, p = (E, R) => d(E) < f(R) && f(E) > d(R), u = new Map(h.bands.flatMap((E, R) => E.map((L) => [L, R]))), g = (E) => u.get(o(E.id, l) ?? ""), x = (E) => [...i.values()].filter((R) => R.type !== "group" && g(R) === E);
|
|
2192
|
+
for (let E = 0; E + 1 < h.bands.length; E++) {
|
|
2193
|
+
const R = h.bands[E].map((Y) => i.get(Y)), L = h.bands[E + 1].map((Y) => i.get(Y)), H = Math.max(...R.map(m)), I = Math.min(...L.map(M)), P = Math.max(...R.map(f)) + Ge, O = Math.min(...L.map(d)) - Ge, [y, D] = [x(E), x(E + 1)], w = t.flatMap((Y) => {
|
|
2194
|
+
const $ = i.get(Y.source), k = i.get(Y.target);
|
|
2195
|
+
if (g($) !== E || g(k) !== E + 1) return [];
|
|
2196
|
+
if (Y.from !== "auto" || Y.to !== "auto") return [];
|
|
2197
|
+
const T = y.some((A) => M(A) > M($) && p(A, $)), j = o(Y.target, l) !== Y.target || D.some((A) => M(A) < M(k) && p(A, k)), v = (A, F) => M(A) < m(F) && m(A) > M(F);
|
|
2198
|
+
return T && y.some((A) => v(A, $) && d(A) >= f($)) ? [] : j && D.some((A) => v(A, k) && f(A) <= d(k)) ? [] : [{ id: Y.id, source: $, target: k, leave: T, enter: j }];
|
|
2199
|
+
}), b = /* @__PURE__ */ new Map(), _ = /* @__PURE__ */ new Map();
|
|
2200
|
+
for (const Y of w)
|
|
2201
|
+
Y.leave || _.set(Y.source.id, [..._.get(Y.source.id) ?? [], Y]);
|
|
2202
|
+
for (const Y of _.values()) {
|
|
2203
|
+
const $ = (k) => Math.abs(n(k.target) - n(k.source)) + Math.abs(a(k.target) - a(k.source));
|
|
2204
|
+
Y.sort((k, T) => $(k) - $(T) || (k.id < T.id ? -1 : 1)), Y.forEach((k, T) => {
|
|
2205
|
+
const j = n(k.target) < n(k.source) ? -1 : 1, v = Math.ceil(T / 2) * s * (T % 2 ? j : -j);
|
|
2206
|
+
b.set(k.id, n(k.source) + v);
|
|
2207
|
+
});
|
|
2208
|
+
}
|
|
2209
|
+
if (!w.length || I - H < (w.length + 1) * Ge) continue;
|
|
2210
|
+
const N = (Y) => {
|
|
2211
|
+
const $ = Y.filter((T) => T.leave), k = Y.filter((T) => T.enter);
|
|
2212
|
+
return Y.map((T, j) => ({
|
|
2213
|
+
w: T,
|
|
2214
|
+
at: le(H + (I - H) * (j + 1) / (Y.length + 1)),
|
|
2215
|
+
leave: T.leave ? le(P + Ge * $.indexOf(T)) : void 0,
|
|
2216
|
+
enter: T.enter ? le(O - Ge * (k.length - 1 - k.indexOf(T))) : void 0
|
|
2217
|
+
}));
|
|
2218
|
+
}, Q = (Y) => N(Y).map(({ w: $, at: k, leave: T, enter: j }) => [
|
|
2219
|
+
...T !== void 0 ? [
|
|
2220
|
+
{ u: f($.source), v: a($.source) },
|
|
2221
|
+
{ u: T, v: a($.source) },
|
|
2222
|
+
{ u: T, v: k }
|
|
2223
|
+
] : [
|
|
2224
|
+
{ u: b.get($.id), v: H },
|
|
2225
|
+
{ u: b.get($.id), v: k }
|
|
2226
|
+
],
|
|
2227
|
+
...j !== void 0 ? [
|
|
2228
|
+
{ u: j, v: k },
|
|
2229
|
+
{ u: j, v: a($.target) },
|
|
2230
|
+
{ u: d($.target), v: a($.target) }
|
|
2231
|
+
] : [
|
|
2232
|
+
{ u: n($.target), v: k },
|
|
2233
|
+
{ u: n($.target), v: I }
|
|
2234
|
+
]
|
|
2235
|
+
]), z = li(
|
|
2236
|
+
[...w].sort((Y, $) => n($.source) - n(Y.source)),
|
|
2237
|
+
(Y) => ri(Q(Y))
|
|
2238
|
+
);
|
|
2239
|
+
for (const { w: Y, at: $, leave: k, enter: T } of N(z))
|
|
2240
|
+
r.set(Y.id, {
|
|
2241
|
+
...c ? { y: $ } : { x: $ },
|
|
2242
|
+
...k !== void 0 ? { leave: k } : {},
|
|
2243
|
+
...T !== void 0 ? { enter: T } : {}
|
|
2244
|
+
});
|
|
2245
|
+
}
|
|
2246
|
+
}
|
|
2247
|
+
return r;
|
|
2248
|
+
}
|
|
2249
|
+
function ri(e) {
|
|
2250
|
+
const t = e.map((o) => o.slice(1).map((s, r) => [o[r], s]));
|
|
2251
|
+
let i = 0;
|
|
2252
|
+
for (let o = 0; o < t.length; o++)
|
|
2253
|
+
for (let s = o + 1; s < t.length; s++)
|
|
2254
|
+
for (const [r, l] of t[o])
|
|
2255
|
+
for (const [h, c] of t[s]) {
|
|
2256
|
+
const [M, m] = r.v === l.v && h.u === c.u ? [
|
|
2257
|
+
[r, l],
|
|
2258
|
+
[h, c]
|
|
2259
|
+
] : h.v === c.v && r.u === l.u ? [
|
|
2260
|
+
[h, c],
|
|
2261
|
+
[r, l]
|
|
2262
|
+
] : [];
|
|
2263
|
+
if (!M || !m) continue;
|
|
2264
|
+
const d = m[0].u, f = M[0].v;
|
|
2265
|
+
d > Math.min(M[0].u, M[1].u) && d < Math.max(M[0].u, M[1].u) && f > Math.min(m[0].v, m[1].v) && f < Math.max(m[0].v, m[1].v) && i++;
|
|
2266
|
+
}
|
|
2267
|
+
return i;
|
|
2268
|
+
}
|
|
2269
|
+
function li(e, t) {
|
|
2270
|
+
if (e.length > 6) return e;
|
|
2271
|
+
let i = e, o = t(e);
|
|
2272
|
+
const s = (r, l) => {
|
|
2273
|
+
if (o) {
|
|
2274
|
+
if (!l.length) {
|
|
2275
|
+
const h = t(r);
|
|
2276
|
+
h < o && ([i, o] = [r, h]);
|
|
2277
|
+
return;
|
|
2278
|
+
}
|
|
2279
|
+
l.forEach((h, c) => s([...r, h], [...l.slice(0, c), ...l.slice(c + 1)]));
|
|
2280
|
+
}
|
|
2281
|
+
};
|
|
2282
|
+
return s([], e), i;
|
|
2283
|
+
}
|
|
2284
|
+
const je = 4;
|
|
2285
|
+
function ci(e, t, i) {
|
|
2286
|
+
const o = t === "right" ? "x" : "y", s = t === "right" ? "y" : "x", r = (c, M) => M === "x" ? c.w : c.h, l = [], h = /* @__PURE__ */ new Set();
|
|
2287
|
+
for (const c of i) {
|
|
2288
|
+
let [M, m] = [e.get(c.a), e.get(c.b)];
|
|
2289
|
+
if (!M || !m) continue;
|
|
2290
|
+
m[o] < M[o] && ([M, m] = [m, M]);
|
|
2291
|
+
const d = M[o] + r(M, o), f = m[o];
|
|
2292
|
+
if (f <= d) continue;
|
|
2293
|
+
const n = (t === "right" ? c.w : c.h) - 2 * Oe, a = (t === "right" ? c.h : c.w) - 2 * Oe, p = d - n / 2 - je, u = f + n / 2 + je, g = M[s] + r(M, s) / 2, x = m[s] + r(m, s) / 2, E = Math.min(g, x) + je, R = Math.max(g, x) - je;
|
|
2294
|
+
if (R - E < a) continue;
|
|
2295
|
+
const L = [
|
|
2296
|
+
...[...e.values()].filter((O) => O[o] < u && O[o] + r(O, o) > p).map((O) => ({
|
|
2297
|
+
lo: O[s] - je,
|
|
2298
|
+
hi: O[s] + r(O, s) + je
|
|
2299
|
+
})),
|
|
2300
|
+
...l.filter((O) => O.from < u && O.to > p)
|
|
2301
|
+
], H = (O) => L.every((y) => O + a <= y.lo || O >= y.hi), I = (E + R - a) / 2, P = [E, I, ...L.map((O) => O.hi)].filter((O) => O >= E && O + a <= R && H(O)).sort((O, y) => Math.abs(O - I) - Math.abs(y - I))[0];
|
|
2302
|
+
P !== void 0 && (h.add(c), l.push({ lo: P - je, hi: P + a + je, from: p, to: u }));
|
|
2303
|
+
}
|
|
2304
|
+
return h;
|
|
2305
|
+
}
|
|
2306
|
+
const di = 96, fi = 1.25;
|
|
2307
|
+
function hi(e, t, i, o, s) {
|
|
2308
|
+
const r = new Map(e.flatMap((m, d) => m.map((f) => [f, d]))), l = (m) => !t.some(([d, f]) => d === m && f !== m), h = (m) => [
|
|
2309
|
+
...new Set(t.filter(([d, f]) => f === m && d !== m).map((d) => d[0]))
|
|
2310
|
+
], c = /* @__PURE__ */ new Set(), M = Math.max(...e.map(s));
|
|
2311
|
+
for (const [m, d] of e.entries())
|
|
2312
|
+
if (m)
|
|
2313
|
+
for (const f of d) {
|
|
2314
|
+
const n = h(f);
|
|
2315
|
+
if (!i(f) || !l(f) || !n.length || n.some((g) => r.get(g) !== m - 1)) continue;
|
|
2316
|
+
const a = [...new Set(t.filter(([g]) => n.includes(g)).map((g) => g[1]))].filter(
|
|
2317
|
+
(g) => g !== f && r.get(g) === m
|
|
2318
|
+
), p = [f, ...a].filter(l).sort((g, x) => o(x) - o(g))[0], u = [...e[m - 1], ...d.filter((g) => c.has(g)), f];
|
|
2319
|
+
s(u) > fi * M || (a.some((g) => !l(g)) || p !== f) && c.add(f);
|
|
2320
|
+
}
|
|
2321
|
+
return c.size ? e.map((m, d) => [
|
|
2322
|
+
...m.filter((f) => !c.has(f)),
|
|
2323
|
+
...(e[d + 1] ?? []).filter((f) => c.has(f))
|
|
2324
|
+
]).filter((m) => m.length) : e;
|
|
2325
|
+
}
|
|
2326
|
+
function ui(e, t, i, o, s, r, l = !1, h = [], c = /* @__PURE__ */ new Map(), M = /* @__PURE__ */ new Map(), m = () => {
|
|
2327
|
+
}) {
|
|
2328
|
+
const d = new Map(e.map((k) => [k.id, k])), f = e.map((k) => k.id), n = i === "right", a = (k) => n ? d.get(k).w : d.get(k).h, p = (k) => n ? d.get(k).h : d.get(k).w, u = (k) => d.get(k).type === "group", g = (k) => n ? k.y + k.h / 2 : k.x + k.w / 2, x = new Set(o.flat()), E = (k) => {
|
|
2329
|
+
const T = !x.size || x.has(k) ? [] : (c.get(k) ?? []).flatMap((v) => t.get(v) ?? []);
|
|
2330
|
+
if (T.length) return T.reduce((v, A) => v + g(A), 0) / T.length;
|
|
2331
|
+
const j = t.get(k);
|
|
2332
|
+
return n ? j.y + d.get(k).h / 2 : j.x + d.get(k).w / 2;
|
|
2333
|
+
}, R = (k, T) => Math.max(
|
|
2334
|
+
jt(s, k, T, u(k) || u(T) ? r.group : r.node, !n),
|
|
2335
|
+
vt(d.get(k).soft, d.get(T).soft, n)
|
|
2336
|
+
), L = (k) => k.reduce((T, j, v) => T + p(j) + (v ? R(k[v - 1], j) : 0), 0), H = hi(
|
|
2337
|
+
Je(f, o),
|
|
2338
|
+
o,
|
|
2339
|
+
l ? u : () => !1,
|
|
2340
|
+
a,
|
|
2341
|
+
L
|
|
2342
|
+
).map(
|
|
2343
|
+
(k) => Ht(
|
|
2344
|
+
[...k].sort((T, j) => E(T) - E(j) || f.indexOf(T) - f.indexOf(j)),
|
|
2345
|
+
(T) => d.get(T).soft
|
|
2346
|
+
)
|
|
2347
|
+
), I = new Map(H.flatMap((k, T) => k.map((j) => [j, T]))), P = H.map(L), O = Math.max(...P), y = new Map(f.map((k) => [k, /* @__PURE__ */ new Set()])), D = new Map(f.map((k) => [k, /* @__PURE__ */ new Set()]));
|
|
2348
|
+
for (const [k, T] of o)
|
|
2349
|
+
I.get(T) > I.get(k) && (y.get(k).add(T), D.get(T).add(k));
|
|
2350
|
+
const w = /* @__PURE__ */ new Map(), b = /* @__PURE__ */ new Map();
|
|
2351
|
+
for (const [k, T] of H.entries()) {
|
|
2352
|
+
let j = (O - P[k]) / 2, v = -1 / 0;
|
|
2353
|
+
for (const [A, F] of T.entries()) {
|
|
2354
|
+
const [Z] = D.get(F), se = D.get(F).size === 1 && y.get(Z).size === 1, ae = se ? m(Z, F) : void 0, S = ae !== void 0 ? w.get(Z) + ae : se ? b.get(Z) - p(F) / 2 : j, q = A ? Math.max(S, v + R(T[A - 1], F)) : S;
|
|
2355
|
+
w.set(F, q), b.set(F, q + p(F) / 2), v = q + p(F), j = Math.max(j + p(F), v) + (T[A + 1] ? R(F, T[A + 1]) : 0);
|
|
2356
|
+
}
|
|
2357
|
+
}
|
|
2358
|
+
const _ = H.length === 1 && N(H[0]);
|
|
2359
|
+
function N(k) {
|
|
2360
|
+
const T = k.map((F) => M.get(F));
|
|
2361
|
+
if (k.length < 2 || T.some((F, Z) => F === void 0 || Z && F < T[Z - 1]))
|
|
2362
|
+
return !1;
|
|
2363
|
+
const j = [];
|
|
2364
|
+
let v = -1 / 0;
|
|
2365
|
+
for (const [F, Z] of k.entries()) {
|
|
2366
|
+
const se = T[F] - T[0] + p(k[0]) / 2 - p(Z) / 2;
|
|
2367
|
+
j.push(F ? Math.max(se, v + R(k[F - 1], Z)) : se), v = j[F] + p(Z);
|
|
2368
|
+
}
|
|
2369
|
+
const A = T.at(-1) - T[0] + (p(k[0]) + p(k.at(-1))) / 2;
|
|
2370
|
+
return v - j[0] > Math.max(P[0] * 1.25, A + 1) ? !1 : (k.forEach((F, Z) => w.set(F, j[Z])), !0);
|
|
2371
|
+
}
|
|
2372
|
+
const Q = Math.min(...w.values()), z = Bt(H, h, s, i), Y = /* @__PURE__ */ new Map();
|
|
2373
|
+
let $ = 0;
|
|
2374
|
+
for (const [k, T] of H.entries()) {
|
|
2375
|
+
for (const A of T) {
|
|
2376
|
+
const F = le(w.get(A) - Q);
|
|
2377
|
+
Y.set(A, n ? { x: $, y: F } : { x: F, y: $ });
|
|
2378
|
+
}
|
|
2379
|
+
const j = H[k + 1];
|
|
2380
|
+
if (!j) break;
|
|
2381
|
+
let v = Math.max(
|
|
2382
|
+
T.some(u) || j.some(u) ? r.group : r.rank,
|
|
2383
|
+
z[k],
|
|
2384
|
+
eo(T, j, (A) => d.get(A).soft, !n)
|
|
2385
|
+
);
|
|
2386
|
+
for (const A of s)
|
|
2387
|
+
Math.min(I.get(A.a), I.get(A.b)) === k && Math.abs(I.get(A.a) - I.get(A.b)) === 1 && (v = Math.max(v, n ? A.w : A.h));
|
|
2388
|
+
$ += Math.max(...T.map(a)) + v;
|
|
2389
|
+
}
|
|
2390
|
+
return { positions: Y, axis: i, followed: _ };
|
|
2391
|
+
}
|
|
2392
|
+
const pi = 20;
|
|
2393
|
+
function Bt(e, t, i, o) {
|
|
2394
|
+
const s = new Map(e.flatMap((h, c) => h.map((M) => [M, c]))), r = (h) => o === "right" ? 2 * Oe : h.h, l = 2 * Oe;
|
|
2395
|
+
return e.slice(0, -1).map((h, c) => {
|
|
2396
|
+
let M = 0, m = 0;
|
|
2397
|
+
const d = [...i], f = [], n = [];
|
|
2398
|
+
for (const p of t) {
|
|
2399
|
+
const u = p.a !== void 0 ? s.get(p.a) : void 0, g = p.b !== void 0 ? s.get(p.b) : void 0;
|
|
2400
|
+
let x;
|
|
2401
|
+
if (u !== void 0 && g !== void 0) {
|
|
2402
|
+
const E = Math.min(u, g), R = Math.max(u, g);
|
|
2403
|
+
if (x = E <= c && R > c && (E === c || R === c + 1), !x) continue;
|
|
2404
|
+
const L = d.findIndex(
|
|
2405
|
+
(H) => H.a === p.a && H.b === p.b || H.a === p.b && H.b === p.a
|
|
2406
|
+
);
|
|
2407
|
+
L >= 0 && (m += r(d.splice(L, 1)[0]) - l, E === c && R === c + 1 && n.push(p));
|
|
2408
|
+
} else {
|
|
2409
|
+
if (x = u !== void 0 ? u === c : g === c + 1, !x) continue;
|
|
2410
|
+
p.label && i.length && (m += r(p.label) - (o === "right" ? l : 0));
|
|
2411
|
+
}
|
|
2412
|
+
M++, f.push(p);
|
|
2413
|
+
}
|
|
2414
|
+
return n.some(
|
|
2415
|
+
(p) => f.some((u) => !(u.a && u.b) && [u.a, u.b].some((g) => g && (g === p.a || g === p.b)))
|
|
2416
|
+
) ? 2 * pi + (M - 1) * Ge + m : 0;
|
|
2417
|
+
});
|
|
2418
|
+
}
|
|
2419
|
+
function gi(e, t, i, o = [], s = []) {
|
|
2420
|
+
const r = /* @__PURE__ */ new Map(), l = t.gap, h = We(t), c = new Map(e.map((M) => [M.id, M]));
|
|
2421
|
+
if (t.algorithm === "row" || t.algorithm === "column") {
|
|
2422
|
+
const M = t.algorithm === "row", m = Bt(
|
|
2423
|
+
e.map((f) => [f.id]),
|
|
2424
|
+
s,
|
|
2425
|
+
o,
|
|
2426
|
+
M ? "right" : "down"
|
|
2427
|
+
);
|
|
2428
|
+
let d = 0;
|
|
2429
|
+
for (const [f, n] of e.entries()) {
|
|
2430
|
+
const a = e[f + 1]?.id ?? "";
|
|
2431
|
+
r.set(n.id, M ? { x: d, y: 0 } : { x: 0, y: d }), d += (M ? n.w : n.h) + Math.max(
|
|
2432
|
+
jt(o, n.id, a, l, M),
|
|
2433
|
+
m[f] ?? 0,
|
|
2434
|
+
vt(n.soft, e[f + 1]?.soft, !M)
|
|
2435
|
+
);
|
|
2436
|
+
}
|
|
2437
|
+
} else {
|
|
2438
|
+
const M = e.map((g) => g.id), m = (g) => c.get(g).soft, d = i.length ? no(Je(M, i), i, (g) => Ht(g, m)) : M.map((g) => [g]), f = (g) => h === "right" ? c.get(g).w : c.get(g).h, n = (g) => h === "right" ? c.get(g).h : c.get(g).w, a = new Map(d.flatMap((g, x) => g.map((E) => [E, x]))), p = Bt(d, s, o, h);
|
|
2439
|
+
let u = 0;
|
|
2440
|
+
for (const [g, x] of d.entries()) {
|
|
2441
|
+
let E = 0, R = Math.max(l, p[g] ?? 0);
|
|
2442
|
+
for (const [L, H] of x.entries())
|
|
2443
|
+
r.set(H, h === "right" ? { x: u, y: E } : { x: E, y: u }), E += n(H) + Math.max(
|
|
2444
|
+
jt(o, H, x[L + 1] ?? "", l, h !== "right"),
|
|
2445
|
+
x[L + 1] ? vt(m(H), m(x[L + 1]), h === "right") : 0
|
|
2446
|
+
);
|
|
2447
|
+
d[g + 1] && (R = Math.max(R, eo(x, d[g + 1], m, h === "down")));
|
|
2448
|
+
for (const L of o)
|
|
2449
|
+
Math.min(a.get(L.a), a.get(L.b)) === g && Math.abs(a.get(L.a) - a.get(L.b)) === 1 && (R = Math.max(R, h === "right" ? L.w : L.h));
|
|
2450
|
+
u += Math.max(...x.map(f)) + R;
|
|
2451
|
+
}
|
|
2452
|
+
}
|
|
2453
|
+
return { positions: r, axis: h };
|
|
2454
|
+
}
|
|
2455
|
+
function no(e, t, i = (o) => o) {
|
|
2456
|
+
const o = [i(e[0])];
|
|
2457
|
+
for (let s = 1; s < e.length; s++) {
|
|
2458
|
+
const r = new Map(o[s - 1].map((d, f) => [d, f])), h = e[s].map((d, f) => {
|
|
2459
|
+
const n = t.flatMap(([a, p]) => a === d ? [p] : p === d ? [a] : []).filter((a) => r.has(a)).map((a) => r.get(a));
|
|
2460
|
+
return {
|
|
2461
|
+
id: d,
|
|
2462
|
+
key: n.length ? n.reduce((a, p) => a + p, 0) / n.length : null,
|
|
2463
|
+
k: f
|
|
2464
|
+
};
|
|
2465
|
+
}).filter((d) => d.key !== null), c = [...h].sort((d, f) => d.key - f.key || d.k - f.k), M = h.map((d) => d.k), m = [...e[s]];
|
|
2466
|
+
c.forEach((d, f) => m[M[f]] = d.id), o.push(i(m));
|
|
2467
|
+
}
|
|
2468
|
+
return o;
|
|
2469
|
+
}
|
|
2470
|
+
class On {
|
|
2471
|
+
parent;
|
|
2472
|
+
constructor(t) {
|
|
2473
|
+
this.parent = new Map(t.map((i) => [i, i]));
|
|
2474
|
+
}
|
|
2475
|
+
find(t) {
|
|
2476
|
+
let i = t;
|
|
2477
|
+
for (; this.parent.get(i) !== i; ) i = this.parent.get(i);
|
|
2478
|
+
return i;
|
|
2479
|
+
}
|
|
2480
|
+
join(t, i) {
|
|
2481
|
+
t = this.find(t), i = this.find(i), t !== i && this.parent.set(i, t);
|
|
2482
|
+
}
|
|
2483
|
+
}
|
|
2484
|
+
function mi(e, t, i, o) {
|
|
2485
|
+
const s = i.filter((d) => d.type === "stay");
|
|
2486
|
+
if (!s.length) return [];
|
|
2487
|
+
const r = new Map(s.map((d) => [d.id, { x: d.x, y: d.y }])), l = /* @__PURE__ */ new Set(), h = o === "right" ? "x" : "y", c = o === "right" ? "y" : "x", M = (d, f) => f === "x" ? d.w : d.h, m = (d, f, n, a, p) => Math.min(f[p] + M(d, p), a[p] + M(n, p)) - Math.max(f[p], a[p]);
|
|
2488
|
+
for (let d = 0; d < e.length; d++)
|
|
2489
|
+
for (let f = d + 1; f < e.length; f++) {
|
|
2490
|
+
const n = e[d], a = e[f], p = r.get(n.id), u = r.get(a.id), g = t.get(n.id), x = t.get(a.id);
|
|
2491
|
+
!p || !u || !g || !x || m(n, g, a, x, h) > 0 || m(n, p, a, u, c) > 0 && m(n, p, a, u, h) >= Math.min(M(n, h), M(a, h)) / 2 && (l.add(n.id), l.add(a.id));
|
|
2492
|
+
}
|
|
2493
|
+
return s.filter((d) => l.has(d.id));
|
|
2494
|
+
}
|
|
2495
|
+
function wi(e, t, i, o, s, r) {
|
|
2496
|
+
const l = e.map((y) => y.id), h = new Map(e.map((y) => [y.id, y])), c = new Map(e.map((y) => [y.id, { ...t.get(y.id) }])), M = new Map(l.map((y) => [y, 1])), m = i.filter(
|
|
2497
|
+
(y) => "ids" in y ? y.type === "align" && y.ids.every((D) => h.has(D)) : "id" in y && h.has(y.id)
|
|
2498
|
+
), d = /* @__PURE__ */ new Map(), f = mi(e, t, m, r);
|
|
2499
|
+
f.length && s.push({
|
|
2500
|
+
level: "info",
|
|
2501
|
+
code: "stale-stay",
|
|
2502
|
+
message: `The stays on ${f.map((y) => y.id).join(", ")} no longer fit ${o}'s arrangement, so they were ignored. Drag again to anchor the new layout.`,
|
|
2503
|
+
line: f[0].line,
|
|
2504
|
+
ids: f.map((y) => y.id)
|
|
2505
|
+
});
|
|
2506
|
+
for (const y of m)
|
|
2507
|
+
y.type === "stay" && !f.includes(y) && (c.set(y.id, { x: y.x, y: y.y }), M.set(y.id, y.weight), d.set(y.id, { pos: { x: y.x, y: y.y }, hint: y }));
|
|
2508
|
+
for (const y of m)
|
|
2509
|
+
if (y.type === "nudge") {
|
|
2510
|
+
const D = t.get(y.id), w = { x: D.x + y.dx, y: D.y + y.dy };
|
|
2511
|
+
c.set(y.id, w), M.set(y.id, 4), d.set(y.id, { pos: w, hint: y });
|
|
2512
|
+
}
|
|
2513
|
+
const n = new Map(
|
|
2514
|
+
m.flatMap((y) => y.type === "near" && h.has(y.ref) ? [[y.id, y]] : [])
|
|
2515
|
+
), a = /* @__PURE__ */ new Set(), p = /* @__PURE__ */ new Set(), u = (y) => {
|
|
2516
|
+
const D = n.get(y);
|
|
2517
|
+
if (a.has(y) || !D) return;
|
|
2518
|
+
if (p.has(y))
|
|
2519
|
+
throw new _e(
|
|
2520
|
+
`Relative placement cycle in ${o}. Replace one near with nudge.`,
|
|
2521
|
+
D.line
|
|
2522
|
+
);
|
|
2523
|
+
p.add(y), u(D.ref);
|
|
2524
|
+
const w = h.get(y), b = h.get(D.ref), _ = c.get(D.ref);
|
|
2525
|
+
let N = _.x + (b.w - w.w) / 2, Q = _.y + (b.h - w.h) / 2;
|
|
2526
|
+
D.side === "right" || D.side === "left" ? (N = D.side === "right" ? _.x + b.w + D.gap : _.x - w.w - D.gap, Q += D.offset) : (Q = D.side === "below" ? _.y + b.h + D.gap : _.y - w.h - D.gap, N += D.offset), c.set(y, { x: N, y: Q }), M.set(y, 5), d.set(y, { pos: { x: N, y: Q }, hint: D }), p.delete(y), a.add(y);
|
|
2527
|
+
};
|
|
2528
|
+
l.forEach(u);
|
|
2529
|
+
for (const y of m)
|
|
2530
|
+
if (y.type === "align" && y.strength === "prefer") {
|
|
2531
|
+
const D = h.get(y.ids[0]), w = c.get(D.id), b = (N) => y.axis === "x" ? N.w : N.h, _ = w[y.axis] + b(D) / 2;
|
|
2532
|
+
for (const N of y.ids.slice(1)) c.get(N)[y.axis] = _ - b(h.get(N)) / 2;
|
|
2533
|
+
}
|
|
2534
|
+
const g = new Map(m.flatMap((y) => y.type === "pin" ? [[y.id, y]] : []));
|
|
2535
|
+
for (const [y, D] of g) c.set(y, { x: D.x, y: D.y });
|
|
2536
|
+
const x = (y, D) => (y === "x" ? h.get(D).w : h.get(D).h) / 2, E = { x: new On(l), y: new On(l) };
|
|
2537
|
+
for (const y of m)
|
|
2538
|
+
if (y.type === "align" && y.strength === "required")
|
|
2539
|
+
for (const D of y.ids.slice(1)) {
|
|
2540
|
+
const w = /* @__PURE__ */ new Set([E[y.axis].find(y.ids[0]), E[y.axis].find(D)]), b = l.filter((_) => g.has(_) && w.has(E[y.axis].find(_))).map((_) => c.get(_)[y.axis] + x(y.axis, _));
|
|
2541
|
+
b.length > 1 && Math.max(...b) - Math.min(...b) > 0.01 ? s.push({
|
|
2542
|
+
level: "error",
|
|
2543
|
+
code: "pin-align-conflict",
|
|
2544
|
+
message: `Pins conflict with required ${y.axis} alignment in ${o}. The pins were kept.`,
|
|
2545
|
+
line: y.line,
|
|
2546
|
+
ids: y.ids
|
|
2547
|
+
}) : E[y.axis].join(y.ids[0], D);
|
|
2548
|
+
}
|
|
2549
|
+
const R = { x: /* @__PURE__ */ new Map(), y: /* @__PURE__ */ new Map() };
|
|
2550
|
+
for (const y of ["x", "y"])
|
|
2551
|
+
for (const D of l) {
|
|
2552
|
+
const w = E[y].find(D), b = c.get(D)[y] + x(y, D);
|
|
2553
|
+
R[y].has(w) || R[y].set(w, { sum: 0, weight: 0, value: 0, fixed: null, members: [] });
|
|
2554
|
+
const _ = R[y].get(w);
|
|
2555
|
+
_.sum += b * M.get(D), _.weight += M.get(D), _.members.push(D), g.has(D) && (_.fixed = b);
|
|
2556
|
+
}
|
|
2557
|
+
for (const y of ["x", "y"])
|
|
2558
|
+
for (const D of R[y].values()) D.value = D.fixed ?? D.sum / D.weight;
|
|
2559
|
+
const L = (y, D) => R[y].get(E[y].find(D)), H = (y, D) => L(y, D).value, I = (y, D, w, b) => {
|
|
2560
|
+
const _ = L(y, D), N = L(y, w), Q = b - (_.value - N.value);
|
|
2561
|
+
if (Q <= 5e-3 || _ === N || _.fixed !== null && N.fixed !== null) return 0;
|
|
2562
|
+
if (_.fixed !== null) N.value -= Q;
|
|
2563
|
+
else if (N.fixed !== null) _.value += Q;
|
|
2564
|
+
else {
|
|
2565
|
+
const z = _.weight + N.weight;
|
|
2566
|
+
_.value += Q * N.weight / z, N.value -= Q * _.weight / z;
|
|
2567
|
+
}
|
|
2568
|
+
return Q;
|
|
2569
|
+
}, P = m.flatMap(
|
|
2570
|
+
(y) => y.type === "near" && y.strength === "required" && h.has(y.ref) ? [y] : []
|
|
2571
|
+
), O = r === "right" ? "x" : "y";
|
|
2572
|
+
for (let y = 0; y < 48; y++) {
|
|
2573
|
+
let D = 0;
|
|
2574
|
+
for (const w of P) {
|
|
2575
|
+
const b = w.side === "right" || w.side === "left" ? "x" : "y", _ = w.side === "right" || w.side === "below";
|
|
2576
|
+
D += I(
|
|
2577
|
+
b,
|
|
2578
|
+
_ ? w.id : w.ref,
|
|
2579
|
+
_ ? w.ref : w.id,
|
|
2580
|
+
x(b, w.id) + x(b, w.ref) + w.gap
|
|
2581
|
+
);
|
|
2582
|
+
}
|
|
2583
|
+
for (let w = 0; w < e.length; w++)
|
|
2584
|
+
for (let b = w + 1; b < e.length; b++) {
|
|
2585
|
+
const _ = e[w], N = e[b], Q = H("x", N.id) - H("x", _.id), z = H("y", N.id) - H("y", _.id), Y = (_.w + N.w) / 2 + Ze - Math.abs(Q), $ = (_.h + N.h) / 2 + Ze - Math.abs(z);
|
|
2586
|
+
if (Y <= 5e-3 || $ <= 5e-3) continue;
|
|
2587
|
+
const k = ["x", "y"].filter(
|
|
2588
|
+
(A) => L(A, _.id) !== L(A, N.id) && !(L(A, _.id).fixed !== null && L(A, N.id).fixed !== null)
|
|
2589
|
+
);
|
|
2590
|
+
if (!k.length) continue;
|
|
2591
|
+
const T = (A) => (A === "x" ? Y : $) + (A === O ? 0 : 3), j = [...k].sort((A, F) => T(A) - T(F))[0], v = j === "x" ? Q : z;
|
|
2592
|
+
D += I(
|
|
2593
|
+
j,
|
|
2594
|
+
v >= 0 ? N.id : _.id,
|
|
2595
|
+
v >= 0 ? _.id : N.id,
|
|
2596
|
+
(j === "x" ? _.w + N.w : _.h + N.h) / 2 + Ze
|
|
2597
|
+
);
|
|
2598
|
+
}
|
|
2599
|
+
if (o !== "root")
|
|
2600
|
+
for (const w of ["x", "y"])
|
|
2601
|
+
for (const b of R[w].values()) {
|
|
2602
|
+
const _ = Math.max(...b.members.map((N) => x(w, N)));
|
|
2603
|
+
b.value < _ && b.fixed === null && (D += _ - b.value, b.value = _);
|
|
2604
|
+
}
|
|
2605
|
+
if (D < 0.01) break;
|
|
2606
|
+
}
|
|
2607
|
+
for (const y of e)
|
|
2608
|
+
c.set(y.id, {
|
|
2609
|
+
x: le(H("x", y.id) - y.w / 2),
|
|
2610
|
+
y: le(H("y", y.id) - y.h / 2)
|
|
2611
|
+
});
|
|
2612
|
+
for (let y = 0; y < e.length; y++)
|
|
2613
|
+
for (let D = y + 1; D < e.length; D++) {
|
|
2614
|
+
const w = e[y], b = e[D], _ = c.get(w.id), N = c.get(b.id);
|
|
2615
|
+
_.x + w.w > N.x + 0.1 && N.x + b.w > _.x + 0.1 && _.y + w.h > N.y + 0.1 && N.y + b.h > _.y + 0.1 && s.push({
|
|
2616
|
+
level: "error",
|
|
2617
|
+
code: "overlap",
|
|
2618
|
+
message: `${w.id} overlaps ${b.id}. Release a pin or give ${o} more room.`,
|
|
2619
|
+
ids: [w.id, b.id]
|
|
2620
|
+
});
|
|
2621
|
+
}
|
|
2622
|
+
for (const y of P) {
|
|
2623
|
+
const D = h.get(y.id), w = h.get(y.ref), b = c.get(D.id), _ = c.get(w.id);
|
|
2624
|
+
(y.side === "right" ? b.x - _.x - w.w : y.side === "left" ? _.x - b.x - D.w : y.side === "below" ? b.y - _.y - w.h : _.y - b.y - D.h) < y.gap - 0.5 && s.push({
|
|
2625
|
+
level: "error",
|
|
2626
|
+
code: "unsatisfied-near",
|
|
2627
|
+
message: `Required: ${y.id} ${y.side} of ${y.ref} is not satisfied.`,
|
|
2628
|
+
line: y.line,
|
|
2629
|
+
ids: [y.id, y.ref]
|
|
2630
|
+
});
|
|
2631
|
+
}
|
|
2632
|
+
for (const [y, { pos: D, hint: w }] of d) {
|
|
2633
|
+
if (g.has(y) || w.type === "near" && w.strength === "required") continue;
|
|
2634
|
+
const b = c.get(y), _ = Math.round(Math.hypot(b.x - D.x, b.y - D.y));
|
|
2635
|
+
_ >= 2 && s.push({
|
|
2636
|
+
level: _ >= Sn ? "warning" : "info",
|
|
2637
|
+
code: "relaxed",
|
|
2638
|
+
message: `${w.type} ${y} gave way by ${_} px to keep ${o} clear.${_ >= Sn ? ` Remove line ${w.line}, or run format --drop-stale.` : ""}`,
|
|
2639
|
+
line: w.line,
|
|
2640
|
+
ids: [y]
|
|
2641
|
+
});
|
|
2642
|
+
}
|
|
2643
|
+
return c;
|
|
2644
|
+
}
|
|
2645
|
+
const yi = 0.5, Mi = 16, $n = (e) => Math.min(e * yi, Math.max(0, e - Mi));
|
|
2646
|
+
function Ut(e, t, i = !1) {
|
|
2647
|
+
if (i) return ht(e, t, !0);
|
|
2648
|
+
const o = new Map(e.objects.map((d) => [d.id, d])), s = e.hints.filter(
|
|
2649
|
+
(d) => d.type === "near" && Ft(o, d.id, d.ref) !== d.ref
|
|
2650
|
+
);
|
|
2651
|
+
if (s.length) {
|
|
2652
|
+
const d = Ut(
|
|
2653
|
+
{ ...e, hints: e.hints.filter((a) => !s.includes(a)) },
|
|
2654
|
+
t
|
|
2655
|
+
), f = (a, p) => {
|
|
2656
|
+
const u = d.byId.get(a);
|
|
2657
|
+
return p === "x" ? u.x + u.w / 2 : u.y + u.h / 2;
|
|
2658
|
+
}, n = e.hints.map((a) => {
|
|
2659
|
+
if (!s.includes(a) || a.type !== "near") return a;
|
|
2660
|
+
const p = Ft(o, a.id, a.ref), u = a.side === "left" || a.side === "right" ? "y" : "x";
|
|
2661
|
+
return { ...a, ref: p, offset: a.offset + f(a.ref, u) - f(p, u) };
|
|
2662
|
+
});
|
|
2663
|
+
return Ut({ ...e, hints: n }, t);
|
|
2664
|
+
}
|
|
2665
|
+
const r = { ...e, hints: e.hints.filter((d) => d.type === "size" || d.type === "order") }, l = ht(r, t), h = l, c = oo.get(h), M = (d) => (Math.max(...d.map((f) => f.x + f.w)) - Math.min(...d.map((f) => f.x))) * (Math.max(...d.map((f) => f.y + f.h)) - Math.min(...d.map((f) => f.y))), m = Zo(
|
|
2666
|
+
es(h.objects, e.edges, e.routing),
|
|
2667
|
+
M(h.objects),
|
|
2668
|
+
(d) => M(ht(r, t, !1, d, c).objects)
|
|
2669
|
+
);
|
|
2670
|
+
return ht(e, t, !1, m.size ? m : void 0, c);
|
|
2671
|
+
}
|
|
2672
|
+
const oo = /* @__PURE__ */ new WeakMap();
|
|
2673
|
+
function ht(e, t, i = !1, o, s) {
|
|
2674
|
+
const r = e.edges.filter((S) => S.constraint !== !1 && S.directed !== !1), l = [], h = /* @__PURE__ */ new Map([["root", []]]);
|
|
2675
|
+
for (const S of e.objects)
|
|
2676
|
+
h.has(S.parent) || h.set(S.parent, []), h.get(S.parent).push(S);
|
|
2677
|
+
const c = tt(e.appearance), M = c.groupHeader, m = /* @__PURE__ */ new Map(), d = c.theme === mt ? c : tt({ ...e.appearance, theme: mt }), f = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Map(), p = /* @__PURE__ */ new Map(), u = /* @__PURE__ */ new Map(), g = /* @__PURE__ */ new Map(), x = new Map(e.objects.map((S) => [S.id, S])), E = /* @__PURE__ */ new Map(), R = (S, q) => {
|
|
2678
|
+
let G = x.get(S);
|
|
2679
|
+
for (; G && G.parent !== q; ) G = x.get(G.parent);
|
|
2680
|
+
return G?.id;
|
|
2681
|
+
}, L = [], H = [], I = new Set(s?.groups);
|
|
2682
|
+
let P = s?.wrap ?? !1;
|
|
2683
|
+
const O = (S) => {
|
|
2684
|
+
const q = /* @__PURE__ */ new Map();
|
|
2685
|
+
for (const G of r) {
|
|
2686
|
+
const U = R(G.source, S);
|
|
2687
|
+
U && R(G.target, S) !== U && q.set(U, [...q.get(U) ?? [], G]);
|
|
2688
|
+
}
|
|
2689
|
+
return new Set(
|
|
2690
|
+
[...q].filter(
|
|
2691
|
+
([G, U]) => U.length > 1 && (x.get(G).shape === "diamond" || U.filter((W) => W.label).length > 1)
|
|
2692
|
+
).map(([G]) => G)
|
|
2693
|
+
);
|
|
2694
|
+
}, y = (S) => r.map((q) => [R(q.source, S), R(q.target, S)]).filter((q) => !!q[0] && !!q[1] && q[0] !== q[1]), D = (S, q, G) => {
|
|
2695
|
+
const U = (te) => R(te, S) !== void 0, W = e.objects.filter((te) => U(te.id)).map((te) => te.id), X = new Map(
|
|
2696
|
+
Je(
|
|
2697
|
+
W,
|
|
2698
|
+
r.filter((te) => U(te.source) && U(te.target)).map((te) => [te.source, te.target])
|
|
2699
|
+
).flatMap((te, ce) => te.map((ue) => [ue, ce]))
|
|
2700
|
+
), C = new Map(q.map((te) => [te, 1 / 0]));
|
|
2701
|
+
for (const te of W) {
|
|
2702
|
+
const ce = R(te, S);
|
|
2703
|
+
C.set(ce, Math.min(C.get(ce), X.get(te)));
|
|
2704
|
+
}
|
|
2705
|
+
const K = (te, ce) => {
|
|
2706
|
+
const ue = /* @__PURE__ */ new Set([te]), oe = [te];
|
|
2707
|
+
for (; oe.length; ) {
|
|
2708
|
+
const ke = oe.pop();
|
|
2709
|
+
if (ke === ce) return !0;
|
|
2710
|
+
for (const [Se, Me] of G)
|
|
2711
|
+
Se === ke && !ue.has(Me) && (ue.add(Me), oe.push(Me));
|
|
2712
|
+
}
|
|
2713
|
+
return !1;
|
|
2714
|
+
};
|
|
2715
|
+
return G.filter(([te, ce]) => !(C.get(ce) < C.get(te) && K(ce, te)));
|
|
2716
|
+
}, w = (S) => {
|
|
2717
|
+
h.get(S);
|
|
2718
|
+
};
|
|
2719
|
+
let b = 0, _ = 0;
|
|
2720
|
+
for (const S of h.keys()) {
|
|
2721
|
+
const q = w(S);
|
|
2722
|
+
if (!q) continue;
|
|
2723
|
+
b = Math.max(b, q.groupGap);
|
|
2724
|
+
const G = y(S), U = new Map(
|
|
2725
|
+
Je(
|
|
2726
|
+
(h.get(S) ?? []).map((X) => X.id),
|
|
2727
|
+
G
|
|
2728
|
+
).flatMap((X, C) => X.map((K) => [K, C]))
|
|
2729
|
+
), W = Math.max(0, ...U.values());
|
|
2730
|
+
for (let X = 0; X < W; X++)
|
|
2731
|
+
_ = Math.max(
|
|
2732
|
+
_,
|
|
2733
|
+
G.filter(
|
|
2734
|
+
([C, K]) => Math.min(U.get(C), U.get(K)) <= X && Math.max(U.get(C), U.get(K)) > X
|
|
2735
|
+
).length
|
|
2736
|
+
);
|
|
2737
|
+
}
|
|
2738
|
+
b = Math.min(di, Math.max(b, (_ + 1) * (e.routing.edgeGap ?? 16)));
|
|
2739
|
+
function N(S) {
|
|
2740
|
+
const q = St(e, S);
|
|
2741
|
+
return q.algorithm === "row" ? "right" : q.algorithm === "column" ? "down" : We(q);
|
|
2742
|
+
}
|
|
2743
|
+
function Q(S, q) {
|
|
2744
|
+
const G = We(q) === "right", U = Math.max(q.gap, Ls), W = /* @__PURE__ */ new Map();
|
|
2745
|
+
for (const ee of S) for (const he of h.get(ee.id) ?? []) W.set(he.id, ee.id);
|
|
2746
|
+
const X = [...W.keys()], C = (ee) => f.get(ee) ?? p.get(ee), K = (ee) => G ? C(ee).w : C(ee).h, te = (ee) => G ? C(ee).h : C(ee).w, ce = (ee) => {
|
|
2747
|
+
let he = x.get(ee);
|
|
2748
|
+
for (; he && !W.has(he.id); ) he = x.get(he.parent);
|
|
2749
|
+
return he?.id;
|
|
2750
|
+
}, ue = r.map((ee) => [ce(ee.source), ce(ee.target)]).filter((ee) => !!ee[0] && !!ee[1] && ee[0] !== ee[1]), oe = X.length ? no(Je(X, ue), ue) : [], ke = new Map(oe.flatMap((ee, he) => ee.map((we) => [we, he]))), Se = oe.map((ee) => Math.max(...ee.map(K))), Me = [];
|
|
2751
|
+
let Pe = 0;
|
|
2752
|
+
for (const [ee, he] of oe.entries()) {
|
|
2753
|
+
Me.push(Pe);
|
|
2754
|
+
let we = U;
|
|
2755
|
+
for (const Ie of e.edges) {
|
|
2756
|
+
const ye = ke.get(ce(Ie.source) ?? ""), xe = ke.get(ce(Ie.target) ?? "");
|
|
2757
|
+
if (Ie.label && ye !== void 0 && xe !== void 0 && Math.min(ye, xe) === ee && ye !== xe) {
|
|
2758
|
+
const ve = _t("", "", Ie.label, c);
|
|
2759
|
+
we = Math.max(we, G ? ve.w : ve.h);
|
|
2760
|
+
}
|
|
2761
|
+
}
|
|
2762
|
+
Pe += Se[ee] + (he === oe.at(-1) ? 0 : we);
|
|
2763
|
+
}
|
|
2764
|
+
const Ee = Pe, st = /* @__PURE__ */ new Map();
|
|
2765
|
+
for (const ee of S) {
|
|
2766
|
+
const he = oe.map((ye) => ye.filter((xe) => W.get(xe) === ee.id)), we = (ye) => ye.reduce((xe, ve, Ce) => xe + te(ve) + (Ce ? Mn : 0), 0), Ie = Math.max(Rs, ...he.map(we));
|
|
2767
|
+
st.set(ee.id, Ie), he.forEach((ye, xe) => {
|
|
2768
|
+
let ve = (Ie - we(ye)) / 2;
|
|
2769
|
+
for (const Ce of ye) {
|
|
2770
|
+
const ge = Me[xe] + (Se[xe] - K(Ce)) / 2, De = G ? { x: ge, y: ve } : { x: ve, y: ge };
|
|
2771
|
+
u.set(Ce, { x: le(De.x), y: le(De.y) }), g.set(Ce, De), ve += te(Ce) + Mn;
|
|
2772
|
+
}
|
|
2773
|
+
});
|
|
2774
|
+
}
|
|
2775
|
+
const it = (ee) => Math.ceil(pe(ee.label, c.groupTitle)) + Dt, $e = Math.max(Ee + 2 * be, ...S.map(it));
|
|
2776
|
+
let qe = 0;
|
|
2777
|
+
for (const ee of S) {
|
|
2778
|
+
const he = st.get(ee.id);
|
|
2779
|
+
ee.w = G ? $e : Math.max(he + 2 * be, it(ee)), ee.h = M + (G ? he : Ee) + be;
|
|
2780
|
+
const we = G ? { x: 0, y: qe } : { x: qe, y: 0 };
|
|
2781
|
+
u.set(ee.id, we), g.set(ee.id, we), qe += (G ? ee.h : ee.w) + xn;
|
|
2782
|
+
}
|
|
2783
|
+
const Fe = Math.max(0, qe - xn);
|
|
2784
|
+
return G ? { w: S.length ? $e : 0, h: Fe } : { w: Fe, h: S.length ? M + Ee + be : 0 };
|
|
2785
|
+
}
|
|
2786
|
+
function z(S) {
|
|
2787
|
+
const q = St(e, S), G = e.hints.find((B) => B.type === "order" && B.scope === S);
|
|
2788
|
+
let U = h.get(S) ?? [];
|
|
2789
|
+
if (G?.type === "order" && (U = [...G.ids.flatMap((J) => U.filter((V) => V.id === J)), ...U.filter((J) => !G.ids.includes(J.id))]), q.algorithm === "cells") return Y(S, U, q);
|
|
2790
|
+
const W = /* @__PURE__ */ new Map(), X = U.map((B) => {
|
|
2791
|
+
let J;
|
|
2792
|
+
if (B.type === "group") {
|
|
2793
|
+
const ie = z(B.id), ne = St(e, B.id), fe = !h.get(B.id)?.length, de = n.get(B.id);
|
|
2794
|
+
J = de !== void 0 ? {
|
|
2795
|
+
w: Math.max(ie.w, ne.minWidth),
|
|
2796
|
+
h: Math.max(ie.h + de, ne.minHeight)
|
|
2797
|
+
} : (() => {
|
|
2798
|
+
const me = Math.max(
|
|
2799
|
+
fe ? bn.w : 0,
|
|
2800
|
+
ie.w + be + (o?.get(B.id)?.right ?? be),
|
|
2801
|
+
ne.minWidth
|
|
2802
|
+
), Ne = Vs(B.label, me, c);
|
|
2803
|
+
return Ne.lines > 1 && m.set(B.id, Ne.lines), {
|
|
2804
|
+
w: Math.max(me, Ne.w),
|
|
2805
|
+
h: Math.max(
|
|
2806
|
+
fe ? bn.h : 0,
|
|
2807
|
+
ie.h + pt(c, Ne.lines) + (o?.get(B.id)?.bottom ?? be),
|
|
2808
|
+
ne.minHeight
|
|
2809
|
+
)
|
|
2810
|
+
};
|
|
2811
|
+
})();
|
|
2812
|
+
} else {
|
|
2813
|
+
const ie = e.hints.find((fe) => fe.type === "size" && fe.id === B.id), ne = Tn(B, ie?.type === "size" ? ie : void 0, c);
|
|
2814
|
+
if (J = ne, d !== c) {
|
|
2815
|
+
const fe = Tn(B, ie?.type === "size" ? ie : void 0, d);
|
|
2816
|
+
W.set(B.id, {
|
|
2817
|
+
look: { w: le(ne.w), h: le(ne.h) },
|
|
2818
|
+
ref: { w: le(fe.w), h: le(fe.h) }
|
|
2819
|
+
});
|
|
2820
|
+
}
|
|
2821
|
+
B.shape === "diamond" && !ie && ne.w > Yn("diamond").w * ti && l.push({
|
|
2822
|
+
level: "info",
|
|
2823
|
+
code: "big-diamond",
|
|
2824
|
+
message: `${B.id}'s question makes its diamond ${le(ne.w)}px square, much larger than the shapes around it. Shorten the question, or move the detail onto its edges' labels.`,
|
|
2825
|
+
line: B.line,
|
|
2826
|
+
ids: [B.id]
|
|
2827
|
+
}), ne.overflow && l.push({
|
|
2828
|
+
level: "warning",
|
|
2829
|
+
code: "text-overflow",
|
|
2830
|
+
message: `${B.id}'s title does not fit in its requested size. Make it larger or remove the size line.`,
|
|
2831
|
+
line: ie?.line,
|
|
2832
|
+
ids: [B.id]
|
|
2833
|
+
});
|
|
2834
|
+
}
|
|
2835
|
+
const V = { ...B, w: le(J.w), h: le(J.h) };
|
|
2836
|
+
return p.set(B.id, V), V;
|
|
2837
|
+
});
|
|
2838
|
+
if (S === "root" && q.algorithm === "lanes") return Q(X, q);
|
|
2839
|
+
const C = y(S), K = x.get(S)?.parent, te = K !== void 0 && N(K) === N(S), ce = (S === "root" ? [] : e.edges).flatMap((B) => {
|
|
2840
|
+
const J = R(B.source, S), V = R(B.target, S);
|
|
2841
|
+
return !J && !V || J === V || !(J && V) && !te ? [] : [{ a: J, b: V, label: B.label && !(J && V) ? He(B.label, c) : void 0 }];
|
|
2842
|
+
}), ue = /* @__PURE__ */ new Map();
|
|
2843
|
+
for (const B of r) {
|
|
2844
|
+
const J = R(B.source, S), V = R(B.target, S);
|
|
2845
|
+
J && !V && ue.set(J, [...ue.get(J) ?? [], B.target]), V && !J && ue.set(V, [...ue.get(V) ?? [], B.source]);
|
|
2846
|
+
}
|
|
2847
|
+
const oe = (B, J) => {
|
|
2848
|
+
const V = u.get(B), ie = f.get(B) ?? p.get(B);
|
|
2849
|
+
return J ? V.y + ie.h / 2 : V.x + ie.w / 2;
|
|
2850
|
+
}, ke = /* @__PURE__ */ new Map(), Se = x.get(S)?.parent, Me = Se !== void 0 && h.get(Se) || [], Pe = X.map((B) => ue.get(B.id) ?? []), Ee = Pe[0]?.length === 1 ? x.get(Pe[0][0])?.parent : void 0, st = Me.findIndex((B) => B.id === Ee) < Me.findIndex((B) => B.id === S);
|
|
2851
|
+
if (Ee !== void 0 && Ee !== S && Me.some((B) => B.id === Ee) && st && Pe.every((B) => B.length === 1 && x.get(B[0])?.parent === Ee && u.has(B[0])))
|
|
2852
|
+
for (const [B, J] of X.entries())
|
|
2853
|
+
ke.set(J.id, oe(Pe[B][0], N(Ee) === "right"));
|
|
2854
|
+
const it = (B, J) => {
|
|
2855
|
+
if (E.get(J) !== B) return;
|
|
2856
|
+
const V = N(S) === "right", ie = (de) => V ? pt(c, m.get(de)) : be, fe = e.edges.filter(
|
|
2857
|
+
(de) => x.get(de.source)?.parent === B && x.get(de.target)?.parent === J
|
|
2858
|
+
).sort((de, me) => oe(de.target, V) - oe(me.target, V))[0];
|
|
2859
|
+
return fe ? ie(B) + oe(fe.source, V) - ie(J) - oe(fe.target, V) : void 0;
|
|
2860
|
+
}, $e = e.edges.flatMap((B) => {
|
|
2861
|
+
const J = R(B.source, S), V = R(B.target, S);
|
|
2862
|
+
if (!B.label || !J || !V || J === V) return [];
|
|
2863
|
+
const ie = _t(J, V, B.label, c);
|
|
2864
|
+
if (d === c) return [ie];
|
|
2865
|
+
const ne = _t(J, V, B.label, d);
|
|
2866
|
+
return [{ a: J, b: V, w: Math.max(ne.w, ie.w - Oe), h: Math.max(ne.h, ie.h - Oe) }];
|
|
2867
|
+
}), qe = t, Fe = w(S), ee = Fe ? { node: Fe.nodeGap, rank: Fe.rankGap, group: b } : void 0, he = Fe ? D(
|
|
2868
|
+
S,
|
|
2869
|
+
X.map((B) => B.id),
|
|
2870
|
+
C
|
|
2871
|
+
) : void 0, we = (B, J) => {
|
|
2872
|
+
const V = q.algorithm === "row" ? "right" : q.algorithm === "column" ? "down" : B, ie = {
|
|
2873
|
+
x: V === "right",
|
|
2874
|
+
y: V === "down"
|
|
2875
|
+
}, ne = (de) => i ? de : W.get(de.id)?.look ?? de, fe = /* @__PURE__ */ new Map();
|
|
2876
|
+
return new Map(
|
|
2877
|
+
X.map((de) => {
|
|
2878
|
+
const me = ne(de);
|
|
2879
|
+
return [
|
|
2880
|
+
de.id,
|
|
2881
|
+
{
|
|
2882
|
+
x: ie.x ? (de.w - me.w) / 2 : 0,
|
|
2883
|
+
y: fe.get(de.id) ?? (ie.y ? (de.h - me.h) / 2 : 0),
|
|
2884
|
+
w: me.w,
|
|
2885
|
+
h: me.h
|
|
2886
|
+
}
|
|
2887
|
+
];
|
|
2888
|
+
})
|
|
2889
|
+
);
|
|
2890
|
+
}, Ie = (B) => {
|
|
2891
|
+
for (const re of X) {
|
|
2892
|
+
const Ae = W.get(re.id);
|
|
2893
|
+
Ae && (re.w = Math.max(Ae.ref.w, Ae.look.w - B.w), re.h = Math.max(Ae.ref.h, Ae.look.h - B.h));
|
|
2894
|
+
}
|
|
2895
|
+
const J = (re) => ee ? ui(
|
|
2896
|
+
X,
|
|
2897
|
+
t,
|
|
2898
|
+
We(qe),
|
|
2899
|
+
he,
|
|
2900
|
+
re,
|
|
2901
|
+
ee,
|
|
2902
|
+
S === "root",
|
|
2903
|
+
ce,
|
|
2904
|
+
ue,
|
|
2905
|
+
ke,
|
|
2906
|
+
it
|
|
2907
|
+
) : gi(X, q, C, re, ce), V = $e.length ? J([]) : void 0, ie = V ? ci(
|
|
2908
|
+
new Map(
|
|
2909
|
+
X.map((re) => {
|
|
2910
|
+
const Ae = V.positions.get(re.id), at = we(V.axis, V.positions).get(re.id);
|
|
2911
|
+
return [re.id, { x: Ae.x + at.x, y: Ae.y + at.y, w: at.w, h: at.h }];
|
|
2912
|
+
})
|
|
2913
|
+
),
|
|
2914
|
+
V.axis,
|
|
2915
|
+
$e
|
|
2916
|
+
) : /* @__PURE__ */ new Set(), ne = J($e.filter((re) => !ie.has(re)));
|
|
2917
|
+
let fe;
|
|
2918
|
+
if (q.algorithm === "flow" && q.fold === "auto") {
|
|
2919
|
+
const re = It(
|
|
2920
|
+
X,
|
|
2921
|
+
ne.positions,
|
|
2922
|
+
ne.axis,
|
|
2923
|
+
q.gap,
|
|
2924
|
+
C,
|
|
2925
|
+
$e,
|
|
2926
|
+
O(S),
|
|
2927
|
+
(V ?? ne).positions
|
|
2928
|
+
);
|
|
2929
|
+
ne.positions = re.positions, fe = re.fold;
|
|
2930
|
+
}
|
|
2931
|
+
const de = !fe && Fe && qe?.engine?.params.fold !== "never";
|
|
2932
|
+
if (de && I.has(S)) {
|
|
2933
|
+
const re = It(
|
|
2934
|
+
X,
|
|
2935
|
+
ne.positions,
|
|
2936
|
+
ne.axis,
|
|
2937
|
+
ee.rank,
|
|
2938
|
+
C,
|
|
2939
|
+
$e,
|
|
2940
|
+
O(S),
|
|
2941
|
+
(V ?? ne).positions,
|
|
2942
|
+
{ fewest: 2, room: 0 }
|
|
2943
|
+
);
|
|
2944
|
+
ne.positions = re.positions, fe = re.fold;
|
|
2945
|
+
}
|
|
2946
|
+
if (de && S === "root" && P) {
|
|
2947
|
+
const re = It(
|
|
2948
|
+
X,
|
|
2949
|
+
ne.positions,
|
|
2950
|
+
ne.axis,
|
|
2951
|
+
ee.rank,
|
|
2952
|
+
C,
|
|
2953
|
+
$e,
|
|
2954
|
+
O(S),
|
|
2955
|
+
(V ?? ne).positions,
|
|
2956
|
+
{ aspect: Ln, fewest: 2 }
|
|
2957
|
+
);
|
|
2958
|
+
ne.positions = re.positions, fe = re.fold;
|
|
2959
|
+
}
|
|
2960
|
+
const me = o?.get(S);
|
|
2961
|
+
if (me && (me.left > be || me.top))
|
|
2962
|
+
for (const [re, Ae] of ne.positions)
|
|
2963
|
+
ne.positions.set(re, { x: Ae.x + me.left - be, y: Ae.y + me.top });
|
|
2964
|
+
const Ne = we(ne.axis, ne.positions), ro = W.size ? e.hints.map(
|
|
2965
|
+
(re) => (re.type === "stay" || re.type === "pin") && Ne.has(re.id) ? { ...re, x: re.x - Ne.get(re.id).x, y: re.y - Ne.get(re.id).y } : re
|
|
2966
|
+
) : e.hints, lo = wi(X, ne.positions, ro, S, l, ne.axis);
|
|
2967
|
+
return "followed" in ne && ne.followed ? E.set(S, Ee) : E.delete(S), { base: ne, fold: fe, pos: lo, off: Ne };
|
|
2968
|
+
}, ye = (B, J) => {
|
|
2969
|
+
const V = J.pos.get(B.id), ie = J.off.get(B.id);
|
|
2970
|
+
return { x: V.x + ie.x, y: V.y + ie.y, w: ie.w, h: ie.h };
|
|
2971
|
+
}, xe = (B, J) => ({
|
|
2972
|
+
...J.pos.get(B.id),
|
|
2973
|
+
w: B.w,
|
|
2974
|
+
h: B.h
|
|
2975
|
+
}), ve = W.size ? { w: $n(q.gap), h: $n(q.gap) } : { w: 0, h: 0 }, Ce = l.length;
|
|
2976
|
+
let ge = Ie(ve);
|
|
2977
|
+
!i && (ve.w || ve.h) && X.some(
|
|
2978
|
+
(B, J) => X.slice(J + 1).some(
|
|
2979
|
+
(V) => vn(xe(B, ge), xe(V, ge)) >= Ze - 0.5 && vn(ye(B, ge), ye(V, ge)) < Ze - 0.5
|
|
2980
|
+
)
|
|
2981
|
+
) && (l.length = Ce, ge = Ie({ w: 0, h: 0 })), ge.fold && L.push({ scope: S, fold: ge.fold }), q.algorithm === "flow" && H.push({ scope: S, axis: ge.base.axis });
|
|
2982
|
+
const De = X.map((B) => ye(B, ge)), kt = S === "root" ? 0 : Math.max(0, ...X.map((B) => B.soft?.length ?? 0)), Ke = S === "root" || !X.length ? { x: 0, y: 0 } : {
|
|
2983
|
+
x: Math.max(0, -Math.min(...De.map((B) => B.x))) + kt * Ve,
|
|
2984
|
+
y: Math.max(0, -Math.min(...De.map((B) => B.y))) + kt * (Ve + Mt)
|
|
2985
|
+
};
|
|
2986
|
+
for (const [B, J] of X.entries()) {
|
|
2987
|
+
const V = De[B], ie = ge.off.get(J.id), ne = ge.base.positions.get(J.id);
|
|
2988
|
+
u.set(J.id, { x: le(V.x + Ke.x), y: le(V.y + Ke.y) }), g.set(J.id, { x: ne.x + ie.x + Ke.x, y: ne.y + ie.y + Ke.y }), W.has(J.id) && f.set(J.id, { w: le(V.w), h: le(V.h) });
|
|
2989
|
+
}
|
|
2990
|
+
const Yt = (B, J) => X.length ? Math.max(
|
|
2991
|
+
...X.map(
|
|
2992
|
+
(V, ie) => Math.max(ge.pos.get(V.id)[B] + V[J], De[ie][B] + De[ie][J])
|
|
2993
|
+
)
|
|
2994
|
+
) + Ke[B] + kt * Ve : 0;
|
|
2995
|
+
return { w: Yt("x", "w"), h: Yt("y", "h") };
|
|
2996
|
+
}
|
|
2997
|
+
function Y(S, q, G) {
|
|
2998
|
+
if (G.unit) return $(S, q, G);
|
|
2999
|
+
const U = Math.ceil(pe(x.get(S).label, c.groupTitle)) + Lo, W = (C) => e.hints.find((K) => K.type === "size" && K.id === C), X = Bo(
|
|
3000
|
+
q.map((C) => {
|
|
3001
|
+
const K = W(C.id);
|
|
3002
|
+
return {
|
|
3003
|
+
id: C.id,
|
|
3004
|
+
label: C.label,
|
|
3005
|
+
marker: C.shape === "marker",
|
|
3006
|
+
...typeof C.span == "number" ? { span: C.span } : {},
|
|
3007
|
+
...K?.type === "size" ? { size: { width: K.width, height: K.height } } : {}
|
|
3008
|
+
};
|
|
3009
|
+
}),
|
|
3010
|
+
{
|
|
3011
|
+
direction: G.direction === "down" ? "down" : "right",
|
|
3012
|
+
...G.columns ? { columns: G.columns } : {}
|
|
3013
|
+
},
|
|
3014
|
+
c,
|
|
3015
|
+
U
|
|
3016
|
+
);
|
|
3017
|
+
return k(S, q, X.boxes), n.set(S, Pt(c.groupTitle.lineHeight)), { w: Math.max(X.w, U), h: X.h };
|
|
3018
|
+
}
|
|
3019
|
+
function $(S, q, G) {
|
|
3020
|
+
const U = qo(
|
|
3021
|
+
q.map((C) => ({
|
|
3022
|
+
id: C.id,
|
|
3023
|
+
label: C.label,
|
|
3024
|
+
marker: !1,
|
|
3025
|
+
...typeof C.span == "number" ? { span: C.span } : {},
|
|
3026
|
+
open: C.span === "var"
|
|
3027
|
+
})),
|
|
3028
|
+
{
|
|
3029
|
+
unit: G.unit,
|
|
3030
|
+
ruler: G.ruler !== !1,
|
|
3031
|
+
...G.columns ? { columns: G.columns } : {},
|
|
3032
|
+
...G.unitWidth ? { unitWidth: G.unitWidth } : {}
|
|
3033
|
+
},
|
|
3034
|
+
c
|
|
3035
|
+
), W = Pt(c.groupTitle.lineHeight), X = W + (U.ruler?.h ?? 0);
|
|
3036
|
+
return k(S, q, U.boxes), n.set(S, X), a.set(S, {
|
|
3037
|
+
...U.ruler ? { ruler: { y: W, ...U.ruler } } : {},
|
|
3038
|
+
...U.pieces.size ? {
|
|
3039
|
+
pieces: Object.fromEntries(
|
|
3040
|
+
[...U.pieces].map(([C, K]) => [C, K.map((te) => ({ ...te, y: te.y + X }))])
|
|
3041
|
+
)
|
|
3042
|
+
} : {},
|
|
3043
|
+
...U.open.length ? { open: U.open } : {}
|
|
3044
|
+
}), { w: U.w, h: U.h };
|
|
3045
|
+
}
|
|
3046
|
+
function k(S, q, G) {
|
|
3047
|
+
for (const U of q) {
|
|
3048
|
+
const W = G.get(U.id);
|
|
3049
|
+
p.set(U.id, { ...U, w: le(W.w), h: le(W.h) }), u.set(U.id, { x: le(W.x), y: le(W.y) }), g.set(U.id, { x: W.x, y: W.y });
|
|
3050
|
+
const X = e.hints.find(
|
|
3051
|
+
(C) => ks.includes(C.type) && "id" in C && C.id === U.id
|
|
3052
|
+
);
|
|
3053
|
+
X && l.push({
|
|
3054
|
+
level: "warning",
|
|
3055
|
+
code: "cell-position",
|
|
3056
|
+
message: `${U.id} is a cell of ${S}, so it stays in its place. Move ${S} instead, or reorder its cells with order.`,
|
|
3057
|
+
line: X.line,
|
|
3058
|
+
ids: [U.id]
|
|
3059
|
+
});
|
|
3060
|
+
}
|
|
3061
|
+
}
|
|
3062
|
+
const T = l.length, j = w("root") && Ks(e, "root");
|
|
3063
|
+
let v = z("root");
|
|
3064
|
+
if (!s && j && j.engine?.params.fold !== "never") {
|
|
3065
|
+
let S = function(C) {
|
|
3066
|
+
return G(C) > to * U(C);
|
|
3067
|
+
};
|
|
3068
|
+
const q = We(j) === "right", G = (C) => q ? C.w : C.h, U = (C) => q ? C.h : C.w, W = q ? bt.width : bt.height, X = (C) => G(C) > W && G(C) > Ln * U(C);
|
|
3069
|
+
for (; X(v) && !P; ) {
|
|
3070
|
+
const C = [...p.values()].filter(
|
|
3071
|
+
(K) => K.type === "group" && !I.has(K.id) && w(K.id) && S(K)
|
|
3072
|
+
).sort((K, te) => G(te) - G(K))[0];
|
|
3073
|
+
C ? I.add(C.id) : P = !0, l.length = T, L.length = H.length = 0, f.clear(), v = z("root");
|
|
3074
|
+
}
|
|
3075
|
+
}
|
|
3076
|
+
if (!s && j && We(j) === "down" && j.engine?.params.fold !== "never") {
|
|
3077
|
+
const S = (G) => G.h, q = (G) => G.w * G.h;
|
|
3078
|
+
for (; ; ) {
|
|
3079
|
+
const G = (h.get("root") ?? []).map((C) => p.get(C.id)).filter(Boolean).sort((C, K) => S(K) - S(C)), [U, W] = G;
|
|
3080
|
+
if (!U || !W || U.type !== "group" || U.fold === "never" || I.has(U.id) || !w(U.id) || S(U) < Zs * S(W))
|
|
3081
|
+
break;
|
|
3082
|
+
const X = v;
|
|
3083
|
+
if (I.add(U.id), l.length = T, L.length = H.length = 0, f.clear(), v = z("root"), !(q(v) < q(X))) {
|
|
3084
|
+
I.delete(U.id), l.length = T, L.length = H.length = 0, f.clear(), z("root");
|
|
3085
|
+
break;
|
|
3086
|
+
}
|
|
3087
|
+
}
|
|
3088
|
+
}
|
|
3089
|
+
const A = [], F = (S, q, G) => {
|
|
3090
|
+
for (const U of h.get(S) ?? []) {
|
|
3091
|
+
const W = f.get(U.id) ?? p.get(U.id), X = u.get(U.id), C = g.get(U.id), K = {
|
|
3092
|
+
...U,
|
|
3093
|
+
x: q.x + X.x,
|
|
3094
|
+
y: q.y + X.y,
|
|
3095
|
+
w: W.w,
|
|
3096
|
+
h: W.h,
|
|
3097
|
+
localX: X.x,
|
|
3098
|
+
localY: X.y,
|
|
3099
|
+
baseX: le(C.x),
|
|
3100
|
+
baseY: le(C.y),
|
|
3101
|
+
depth: G,
|
|
3102
|
+
...m.has(U.id) ? { titleLines: m.get(U.id) } : {}
|
|
3103
|
+
};
|
|
3104
|
+
A.push(K), U.type === "group" && F(
|
|
3105
|
+
U.id,
|
|
3106
|
+
n.has(U.id) ? { x: K.x, y: K.y + n.get(U.id) } : Hn(K, pt(c, K.titleLines)),
|
|
3107
|
+
G + 1
|
|
3108
|
+
);
|
|
3109
|
+
}
|
|
3110
|
+
};
|
|
3111
|
+
F("root", { x: 0, y: 0 }, 0);
|
|
3112
|
+
const Z = ai(
|
|
3113
|
+
L,
|
|
3114
|
+
e.edges,
|
|
3115
|
+
new Map(A.map((S) => [S.id, S])),
|
|
3116
|
+
R,
|
|
3117
|
+
Math.max(e.routing.portGap ?? 16, e.routing.edgeGap ?? 16)
|
|
3118
|
+
);
|
|
3119
|
+
for (const [S, q] of ss(
|
|
3120
|
+
H.map((G) => ({ ...G, bands: L.find((U) => U.scope === G.scope)?.fold.bands })),
|
|
3121
|
+
e.edges,
|
|
3122
|
+
new Map(A.map((G) => [G.id, G])),
|
|
3123
|
+
new Set(Z.keys()),
|
|
3124
|
+
(G) => He(G, c)
|
|
3125
|
+
))
|
|
3126
|
+
Z.set(S, q);
|
|
3127
|
+
for (const S of e.layouts) {
|
|
3128
|
+
const q = A.find((G) => G.id === S.scope);
|
|
3129
|
+
!q || !S.minWidth && !S.minHeight || (S.minWidth && q.w > S.minWidth + 0.5 || S.minHeight && q.h > S.minHeight + 0.5) && l.push({
|
|
3130
|
+
level: "info",
|
|
3131
|
+
code: "group-grew",
|
|
3132
|
+
message: `${q.id} needs at least ${q.w}×${q.h} for its contents.`,
|
|
3133
|
+
line: S.line,
|
|
3134
|
+
ids: [q.id]
|
|
3135
|
+
});
|
|
3136
|
+
}
|
|
3137
|
+
l.push(...Xs(e), ...fs(e));
|
|
3138
|
+
for (const S of e.warnings) l.push({ level: "warning", ...S, ids: [] });
|
|
3139
|
+
const se = new Map(e.objects.map((S, q) => [S.id, q]));
|
|
3140
|
+
A.sort((S, q) => se.get(S.id) - se.get(q.id));
|
|
3141
|
+
const ae = {
|
|
3142
|
+
model: e,
|
|
3143
|
+
title: e.title,
|
|
3144
|
+
objects: A,
|
|
3145
|
+
byId: new Map(A.map((S) => [S.id, S])),
|
|
3146
|
+
edges: e.edges.map((S) => Z.has(S.id) ? { ...S, lane: Z.get(S.id) } : S),
|
|
3147
|
+
diagnostics: l,
|
|
3148
|
+
look: c,
|
|
3149
|
+
cells: a
|
|
3150
|
+
};
|
|
3151
|
+
return oo.set(ae, { groups: I, wrap: P }), ae;
|
|
3152
|
+
}
|
|
3153
|
+
const Le = Object.freeze({
|
|
3154
|
+
sourceBytes: 256 * 1024,
|
|
3155
|
+
objects: 500,
|
|
3156
|
+
edges: 1200,
|
|
3157
|
+
depth: 12,
|
|
3158
|
+
labelChars: 16 * 1024,
|
|
3159
|
+
totalLabelBytes: 1024 * 1024,
|
|
3160
|
+
outputBytes: 1024 * 1024,
|
|
3161
|
+
nativeSourceChars: 3e5
|
|
3162
|
+
}), zt = /* @__PURE__ */ new Set(["root", "__proto__", "constructor", "prototype"]);
|
|
3163
|
+
class so {
|
|
3164
|
+
entries = [];
|
|
3165
|
+
byForeign = /* @__PURE__ */ new Map();
|
|
3166
|
+
taken = new Set(zt);
|
|
3167
|
+
get(t, i, o = i) {
|
|
3168
|
+
const s = JSON.stringify([t, i]), r = this.byForeign.get(s);
|
|
3169
|
+
if (r) return r;
|
|
3170
|
+
let l = [...o].map((c) => /[A-Za-z0-9_.-]/.test(c) ? c : "_u" + c.codePointAt(0).toString(16) + "_").join("");
|
|
3171
|
+
/^[A-Za-z_]/.test(l) || (l = t + "_" + l), (!l || zt.has(l)) && (l = t + "_" + (l || "item"));
|
|
3172
|
+
let h = l;
|
|
3173
|
+
for (let c = 2; this.taken.has(h); c++) h = l + "__" + c;
|
|
3174
|
+
return this.byForeign.set(s, h), this.taken.add(h), this.entries.push({ kind: t, foreign: i, native: h }), h;
|
|
3175
|
+
}
|
|
3176
|
+
}
|
|
3177
|
+
const Be = (e) => JSON.stringify(e), io = (e) => ({
|
|
3178
|
+
title: e,
|
|
3179
|
+
objects: [],
|
|
3180
|
+
edges: [],
|
|
3181
|
+
layouts: [],
|
|
3182
|
+
colors: []
|
|
3183
|
+
});
|
|
3184
|
+
function ao(e, t, i, o, s) {
|
|
3185
|
+
const r = (a, p, u = "semantics") => o.push({ code: a, severity: "error", impact: u, message: p });
|
|
3186
|
+
(i.objects.length > Le.objects || i.edges.length > Le.edges) && r(
|
|
3187
|
+
"IMPORT_GRAPH_LIMIT",
|
|
3188
|
+
"Native source allows at most 500 nodes plus groups, and 1,200 edges.",
|
|
3189
|
+
"limit"
|
|
3190
|
+
);
|
|
3191
|
+
const l = new TextEncoder();
|
|
3192
|
+
[i.title, ...i.objects.map((a) => a.label), ...i.edges.map((a) => a.label)].reduce((a, p) => a + l.encode(p).length, 0) > Le.totalLabelBytes && r(
|
|
3193
|
+
"IMPORT_TOTAL_LABEL_LIMIT",
|
|
3194
|
+
"Expanded native labels exceed a combined 1 MiB of UTF-8 text.",
|
|
3195
|
+
"limit"
|
|
3196
|
+
), i.title.length > Le.labelChars && r("IMPORT_LABEL_LIMIT", "Diagram title exceeds 16,384 characters.", "limit");
|
|
3197
|
+
const c = new Map(i.objects.map((a) => [a.id, a])), M = [...i.objects.map((a) => a.id), ...i.edges.map((a) => a.id)];
|
|
3198
|
+
(new Set(M).size !== M.length || M.some((a) => zt.has(a) || !/^[A-Za-z_][A-Za-z0-9_.-]*$/.test(a))) && r("IMPORT_ID_INVARIANT", "Generated IDs must be safe, globally unique native identifiers.");
|
|
3199
|
+
const m = (a) => {
|
|
3200
|
+
const p = [];
|
|
3201
|
+
let u = c.get(a)?.parent;
|
|
3202
|
+
for (; u; ) {
|
|
3203
|
+
if (p.includes(u) || p.length >= Le.depth) {
|
|
3204
|
+
r("IMPORT_HIERARCHY", "Containment cycle or excessive nesting.");
|
|
3205
|
+
break;
|
|
3206
|
+
}
|
|
3207
|
+
if (p.push(u), c.get(u)?.kind !== "group") {
|
|
3208
|
+
r("IMPORT_PARENT", "Missing or non-group parent: " + u);
|
|
3209
|
+
break;
|
|
3210
|
+
}
|
|
3211
|
+
u = c.get(u)?.parent;
|
|
3212
|
+
}
|
|
3213
|
+
return p;
|
|
3214
|
+
};
|
|
3215
|
+
for (const a of i.objects)
|
|
3216
|
+
m(a.id).length + 1 > Le.depth && r("IMPORT_DEPTH", "Native source permits 12 nesting levels.", "limit"), a.label.length > Le.labelChars && r("IMPORT_LABEL_LIMIT", "Label exceeds 16,384 characters.", "limit");
|
|
3217
|
+
for (const a of i.edges)
|
|
3218
|
+
(!c.has(a.from) || !c.has(a.to)) && r("IMPORT_ENDPOINT", "Missing endpoint for " + a.id), (m(a.from).includes(a.to) || m(a.to).includes(a.from)) && r(
|
|
3219
|
+
"IMPORT_ANCESTOR_EDGE",
|
|
3220
|
+
"Native source cannot connect a group to one of its descendants."
|
|
3221
|
+
), a.label.length > Le.labelChars && r("IMPORT_LABEL_LIMIT", "Edge label exceeds 16,384 characters.", "limit");
|
|
3222
|
+
const d = i.edges.some((a) => !a.directed) ? ["IMP-02-native-undirected"] : [];
|
|
3223
|
+
if (o.some((a) => a.severity === "error"))
|
|
3224
|
+
return { status: "failed", format: e, family: t, diagnostics: o, ids: s.entries, requires: d };
|
|
3225
|
+
const f = ["diagram " + Be(i.title) + " version=1"];
|
|
3226
|
+
for (const a of i.colors)
|
|
3227
|
+
f.push(
|
|
3228
|
+
"theme-color " + a.name + " shade=500 fill=" + Be(a.fill) + " stroke=" + Be(a.stroke) + " ink=" + Be(a.ink)
|
|
3229
|
+
);
|
|
3230
|
+
for (const a of i.objects) {
|
|
3231
|
+
let p = a.kind + " " + a.id + " " + Be(a.label);
|
|
3232
|
+
a.parent && (p += " in=" + a.parent), a.shape && a.shape !== "box" && a.kind === "node" && (p += " shape=" + a.shape), a.color && (p += " color=" + a.color + " shade=" + (a.shade ?? 500)), f.push(p);
|
|
3233
|
+
}
|
|
3234
|
+
for (const a of i.edges) {
|
|
3235
|
+
let p = "edge " + a.id + " " + a.from + " -> " + a.to + " " + Be(a.label);
|
|
3236
|
+
a.directed || (p += " directed=false"), a.head && a.head !== "arrow" && (p += " head=" + a.head), a.tail && a.tail !== "none" && (p += " tail=" + a.tail), a.dashed && (p += " kind=async"), a.constraint === !1 && (p += " constraint=false"), a.fromSide && (p += " from=" + a.fromSide), a.toSide && (p += " to=" + a.toSide), f.push(p);
|
|
3237
|
+
}
|
|
3238
|
+
for (const a of i.layouts)
|
|
3239
|
+
f.push(
|
|
3240
|
+
"layout " + a.scope + " " + a.kind + (a.direction ? " direction=" + a.direction : "")
|
|
3241
|
+
);
|
|
3242
|
+
for (const a of i.phases ?? [])
|
|
3243
|
+
f.push(["phase", a.id, Be(a.label), ...a.members].join(" "));
|
|
3244
|
+
for (const a of i.notes ?? []) {
|
|
3245
|
+
let p = "note " + Be(a.text);
|
|
3246
|
+
a.near && (p += " near=" + a.near), a.side && (p += " side=" + a.side), f.push(p);
|
|
3247
|
+
}
|
|
3248
|
+
const n = f.join(`
|
|
3249
|
+
`) + `
|
|
3250
|
+
`;
|
|
3251
|
+
return n.length > Le.nativeSourceChars && r(
|
|
3252
|
+
"IMPORT_NATIVE_SOURCE_LIMIT",
|
|
3253
|
+
"Generated source exceeds the native parser limit of 300,000 source characters.",
|
|
3254
|
+
"limit"
|
|
3255
|
+
), l.encode(n).length > Le.outputBytes && r("IMPORT_OUTPUT_LIMIT", "Generated native source exceeds 1 MiB of UTF-8 text.", "limit"), o.some((a) => a.severity === "error") ? { status: "failed", format: e, family: t, diagnostics: o, ids: s.entries, requires: d } : {
|
|
3256
|
+
status: o.some((a) => a.severity === "warning") ? "needs-review" : "ready",
|
|
3257
|
+
format: e,
|
|
3258
|
+
family: t,
|
|
3259
|
+
diagnostics: o,
|
|
3260
|
+
ids: s.entries,
|
|
3261
|
+
requires: d,
|
|
3262
|
+
nativeSource: n,
|
|
3263
|
+
facts: i
|
|
3264
|
+
};
|
|
3265
|
+
}
|
|
3266
|
+
function xi(e) {
|
|
3267
|
+
if (e) {
|
|
3268
|
+
if (/^#[a-f0-9]{6}$/i.test(e)) return e.toLowerCase();
|
|
3269
|
+
if (/^#[a-f0-9]{3}$/i.test(e))
|
|
3270
|
+
return "#" + [...e.slice(1)].map((t) => t + t).join("").toLowerCase();
|
|
3271
|
+
}
|
|
3272
|
+
}
|
|
3273
|
+
function bi(e, t, i, o, s) {
|
|
3274
|
+
if (!i && !o && !s) return;
|
|
3275
|
+
const r = { fill: i ?? "#ffffff", stroke: o ?? "#64748b", ink: s ?? "#172033" };
|
|
3276
|
+
let l = e.colors.find((h) => h.fill === r.fill && h.stroke === r.stroke && h.ink === r.ink);
|
|
3277
|
+
l || (l = { name: "import_" + (e.colors.length + 1), ...r }, e.colors.push(l)), t.color = l.name, t.shade = 500;
|
|
3278
|
+
}
|
|
3279
|
+
const vi = {
|
|
3280
|
+
SOLID: {},
|
|
3281
|
+
DOTTED: { dashed: !0 },
|
|
3282
|
+
SOLID_OPEN: { head: "none" },
|
|
3283
|
+
DOTTED_OPEN: { head: "none", dashed: !0 },
|
|
3284
|
+
SOLID_CROSS: { head: "cross" },
|
|
3285
|
+
DOTTED_CROSS: { head: "cross", dashed: !0 },
|
|
3286
|
+
SOLID_POINT: {},
|
|
3287
|
+
DOTTED_POINT: { dashed: !0 },
|
|
3288
|
+
BIDIRECTIONAL_SOLID: { tail: "arrow" },
|
|
3289
|
+
BIDIRECTIONAL_DOTTED: { tail: "arrow", dashed: !0 }
|
|
3290
|
+
}, Dn = {
|
|
3291
|
+
LOOP_START: "loop",
|
|
3292
|
+
ALT_START: "alt",
|
|
3293
|
+
OPT_START: "opt",
|
|
3294
|
+
PAR_START: "par",
|
|
3295
|
+
PAR_OVER_START: "par",
|
|
3296
|
+
CRITICAL_START: "critical",
|
|
3297
|
+
BREAK_START: "break"
|
|
3298
|
+
}, Nn = {
|
|
3299
|
+
ALT_ELSE: "else",
|
|
3300
|
+
PAR_AND: "and",
|
|
3301
|
+
CRITICAL_OPTION: "option"
|
|
3302
|
+
}, ki = ["LOOP_END", "ALT_END", "OPT_END", "PAR_END", "CRITICAL_END", "BREAK_END"];
|
|
3303
|
+
function Ei(e, t, i, o) {
|
|
3304
|
+
const s = io(e.title ? t(e.title) : i), r = new so(), l = /* @__PURE__ */ new Set(), h = (g, x, E = "semantics") => {
|
|
3305
|
+
l.has(g) || (l.add(g), o.push({ code: g, severity: "warning", impact: E, message: x }));
|
|
3306
|
+
}, c = e.boxes.map((g, x) => {
|
|
3307
|
+
const E = r.get("group", "box_" + (x + 1));
|
|
3308
|
+
return s.objects.push({ id: E, kind: "group", label: t(g.name ?? "") }), g.fill && g.fill !== "transparent" && h("MERMAID_SEQUENCE_BOX_COLOR", "Box colors are omitted.", "appearance"), E;
|
|
3309
|
+
}), M = /* @__PURE__ */ new Map();
|
|
3310
|
+
for (const g of e.actors) {
|
|
3311
|
+
const x = r.get("node", g.id);
|
|
3312
|
+
M.set(g.id, x), s.objects.push({
|
|
3313
|
+
id: x,
|
|
3314
|
+
kind: "node",
|
|
3315
|
+
// `participant p as "Name"` keeps its quotes in the DB.
|
|
3316
|
+
label: t(g.name).replace(/^"(.*)"$/s, "$1"),
|
|
3317
|
+
...g.box != null && g.box >= 0 ? { parent: c[g.box] } : {}
|
|
3318
|
+
}), g.type !== "participant" && h(
|
|
3319
|
+
"MERMAID_SEQUENCE_ACTOR_TYPE",
|
|
3320
|
+
"Participant symbols such as actor or database become ordinary boxes.",
|
|
3321
|
+
"appearance"
|
|
3322
|
+
), g.links.length && h(
|
|
3323
|
+
"MERMAID_LINK_OMITTED",
|
|
3324
|
+
"Participant link menus are omitted; native participants have no menu.",
|
|
3325
|
+
"security"
|
|
3326
|
+
);
|
|
3327
|
+
}
|
|
3328
|
+
(e.created.length || e.destroyed.length) && h(
|
|
3329
|
+
"MERMAID_SEQUENCE_LIFELINE",
|
|
3330
|
+
"create and destroy are omitted: native participants span the whole diagram."
|
|
3331
|
+
), s.layouts.push({ scope: "root", kind: "sequence" });
|
|
3332
|
+
const m = [], d = [];
|
|
3333
|
+
let f = 0, n, a;
|
|
3334
|
+
const p = (g, x) => {
|
|
3335
|
+
const E = t(x).trim();
|
|
3336
|
+
n = {
|
|
3337
|
+
id: r.get("phase", String(m.length + 1), "phase_" + (m.length + 1)),
|
|
3338
|
+
label: E ? `${g}: ${E}` : g,
|
|
3339
|
+
members: []
|
|
3340
|
+
}, m.push(n);
|
|
3341
|
+
}, u = (g) => {
|
|
3342
|
+
const x = [g.from, g.to].filter((L) => L != null), E = a && x.every((L) => a.ends.includes(L)), R = g.placement === "left" ? "left" : g.placement === "right" ? "right" : void 0;
|
|
3343
|
+
d.push({
|
|
3344
|
+
text: t(g.text),
|
|
3345
|
+
near: E ? a.id : M.get(x[0]),
|
|
3346
|
+
side: R ?? (E ? "right" : "below")
|
|
3347
|
+
});
|
|
3348
|
+
};
|
|
3349
|
+
for (const [g, x] of e.events.entries())
|
|
3350
|
+
if (Dn[x.kind])
|
|
3351
|
+
f++, f === 1 ? p(Dn[x.kind], x.text) : h(
|
|
3352
|
+
"MERMAID_SEQUENCE_NESTED_BLOCK",
|
|
3353
|
+
"A nested block has no band of its own; its messages stay in the outer band."
|
|
3354
|
+
), h(
|
|
3355
|
+
"MERMAID_SEQUENCE_BLOCK",
|
|
3356
|
+
"Native sequences have no fragments. Each block branch becomes a phase band, so the branch logic is only in its label."
|
|
3357
|
+
);
|
|
3358
|
+
else if (Nn[x.kind])
|
|
3359
|
+
f === 1 && p(Nn[x.kind], x.text);
|
|
3360
|
+
else if (ki.includes(x.kind))
|
|
3361
|
+
f--, f || (n = void 0);
|
|
3362
|
+
else if (x.kind === "NOTE") u(x);
|
|
3363
|
+
else if (x.kind === "ACTIVE_START" || x.kind === "ACTIVE_END")
|
|
3364
|
+
h("MERMAID_SEQUENCE_ACTIVATION", "Activation bars are omitted.", "appearance");
|
|
3365
|
+
else if (x.kind === "AUTONUMBER")
|
|
3366
|
+
h("MERMAID_SEQUENCE_AUTONUMBER", "Message numbers are omitted.", "appearance");
|
|
3367
|
+
else if (x.kind === "RECT_START" || x.kind === "RECT_END")
|
|
3368
|
+
h("MERMAID_SEQUENCE_RECT", "Background rectangles are omitted.", "appearance");
|
|
3369
|
+
else {
|
|
3370
|
+
const E = vi[x.kind], R = M.get(x.from ?? ""), L = M.get(x.to ?? "");
|
|
3371
|
+
if (!E || !R || !L || x.central) {
|
|
3372
|
+
o.push({
|
|
3373
|
+
code: "MERMAID_SEQUENCE_ARROW_UNSUPPORTED",
|
|
3374
|
+
severity: "error",
|
|
3375
|
+
impact: "semantics",
|
|
3376
|
+
message: "Message line type is unsupported: " + (x.central ? "central connection" : x.kind) + ". The import is blocked rather than replacing it with an ordinary arrow."
|
|
3377
|
+
});
|
|
3378
|
+
continue;
|
|
3379
|
+
}
|
|
3380
|
+
x.kind === "SOLID_POINT" && h(
|
|
3381
|
+
"MERMAID_SEQUENCE_ASYNC_ARROW",
|
|
3382
|
+
"The open async arrow `-)` becomes an ordinary solid message, because native async draws dashed."
|
|
3383
|
+
);
|
|
3384
|
+
const H = r.get("edge-occurrence", String(g + 1), "m" + (s.edges.length + 1));
|
|
3385
|
+
s.edges.push({ id: H, from: R, to: L, label: t(x.text), directed: !0, ...E }), n?.members.push(H), a = { id: H, ends: [x.from, x.to] };
|
|
3386
|
+
}
|
|
3387
|
+
return s.phases = m.filter((g) => g.members.length), s.notes = d, ao("mermaid", "sequence", s, o, r);
|
|
3388
|
+
}
|
|
3389
|
+
const Ai = {
|
|
3390
|
+
arrow_point: {},
|
|
3391
|
+
arrow_open: {},
|
|
3392
|
+
arrow_circle: { head: "circle" },
|
|
3393
|
+
arrow_cross: { head: "cross" },
|
|
3394
|
+
double_arrow_point: { tail: "arrow" },
|
|
3395
|
+
double_arrow_circle: { head: "circle", tail: "circle" },
|
|
3396
|
+
double_arrow_cross: { head: "cross", tail: "cross" }
|
|
3397
|
+
};
|
|
3398
|
+
function _i(e, t, i = "Imported Mermaid") {
|
|
3399
|
+
const o = io(i), s = new so(), r = e.diagnostics.map((u) => ({
|
|
3400
|
+
code: u.code,
|
|
3401
|
+
severity: u.severity,
|
|
3402
|
+
impact: u.code.includes("LIMIT") || u.code.includes("TIMEOUT") ? "limit" : u.code.includes("CONFIGURATION") || u.code.includes("INTERACTION") ? "security" : "syntax",
|
|
3403
|
+
message: u.message + (u.locationKind === "parser-relative" && u.line != null ? ` (Parser-relative line ${u.line}, column ${u.column ?? 1}; original-source mapping is unavailable.)` : ""),
|
|
3404
|
+
...u.locationKind === "source" && u.line != null ? { line: u.line, column: u.column } : {}
|
|
3405
|
+
})), l = (u, g, x = "appearance", E = "warning", R) => r.push({ code: u, message: g, impact: x, severity: E, ...R ? { foreignIds: R } : {} }), h = () => ao("mermaid", "flowchart", o, r, s);
|
|
3406
|
+
if (!e.ok) return h();
|
|
3407
|
+
const c = e.snapshot;
|
|
3408
|
+
if (c.parserVersion !== Wt)
|
|
3409
|
+
return l(
|
|
3410
|
+
"MERMAID_VERSION_MISMATCH",
|
|
3411
|
+
"This adapter is verified only against Mermaid " + Wt + ".",
|
|
3412
|
+
"syntax",
|
|
3413
|
+
"error"
|
|
3414
|
+
), h();
|
|
3415
|
+
if (c.family === "sequence")
|
|
3416
|
+
return Ei(c, t, i, r);
|
|
3417
|
+
const M = (u, g, x) => (/<\/?[a-z][\s\S]*?>/i.test(u) && l(
|
|
3418
|
+
"MERMAID_HTML_LABEL",
|
|
3419
|
+
"HTML label formatting was reduced to plain text; line breaks are retained and no HTML is inserted into the diagram.",
|
|
3420
|
+
"appearance",
|
|
3421
|
+
"warning",
|
|
3422
|
+
[x]
|
|
3423
|
+
), g === "markdown" && l(
|
|
3424
|
+
"MERMAID_MARKDOWN_LABEL",
|
|
3425
|
+
"Markdown label markers remain literal text in this profile.",
|
|
3426
|
+
"appearance",
|
|
3427
|
+
"warning",
|
|
3428
|
+
[x]
|
|
3429
|
+
), t(u)), m = (u, g) => {
|
|
3430
|
+
if (u) {
|
|
3431
|
+
if (u === "LR") return "right";
|
|
3432
|
+
if (u === "TB" || u === "TD") return "down";
|
|
3433
|
+
if (u === "RL" || u === "BT")
|
|
3434
|
+
return l(
|
|
3435
|
+
"MERMAID_REVERSED_LAYOUT",
|
|
3436
|
+
`${u} layout is normalized to ${u === "RL" ? "right" : "down"}; edge endpoints keep their semantic order.`,
|
|
3437
|
+
"layout",
|
|
3438
|
+
"warning",
|
|
3439
|
+
[g]
|
|
3440
|
+
), u === "RL" ? "right" : "down";
|
|
3441
|
+
l("MERMAID_DIRECTION", "Unsupported Mermaid layout direction: " + u, "layout", "error", [
|
|
3442
|
+
g
|
|
3443
|
+
]);
|
|
3444
|
+
}
|
|
3445
|
+
}, d = new Map(c.classes.map((u) => [u.id, u])), f = (u, g, x, E) => {
|
|
3446
|
+
const R = [];
|
|
3447
|
+
for (const L of [...x ? ["default", "node"] : [], ...u]) {
|
|
3448
|
+
const H = d.get(L);
|
|
3449
|
+
H ? R.push(H) : ["default", "node", "clickable"].includes(L) || l(
|
|
3450
|
+
"MERMAID_CLASS_UNRESOLVED",
|
|
3451
|
+
"CSS class has no in-diagram definition and was not imported: " + L,
|
|
3452
|
+
"appearance",
|
|
3453
|
+
"warning",
|
|
3454
|
+
[E]
|
|
3455
|
+
);
|
|
3456
|
+
}
|
|
3457
|
+
return [...R.flatMap((L) => [...L.styles, ...L.textStyles]), ...g];
|
|
3458
|
+
}, n = (u, g, x) => {
|
|
3459
|
+
const E = /* @__PURE__ */ new Map();
|
|
3460
|
+
for (const R of g.flatMap((L) => L.split(";"))) {
|
|
3461
|
+
if (!R.trim()) continue;
|
|
3462
|
+
const L = /^\s*([a-z-]+)\s*:\s*(.*?)\s*$/i.exec(R), H = L?.[1]?.toLowerCase(), I = L?.[2];
|
|
3463
|
+
if (!H || !["fill", "stroke", "color"].includes(H)) {
|
|
3464
|
+
l(
|
|
3465
|
+
"MERMAID_STYLE_PROPERTY",
|
|
3466
|
+
"Unsupported style declaration was omitted: " + R,
|
|
3467
|
+
/url\s*\(|javascript:|expression\s*\(/i.test(R) ? "security" : "appearance",
|
|
3468
|
+
"warning",
|
|
3469
|
+
[x]
|
|
3470
|
+
);
|
|
3471
|
+
continue;
|
|
3472
|
+
}
|
|
3473
|
+
const P = xi(I);
|
|
3474
|
+
if (!P) {
|
|
3475
|
+
l(
|
|
3476
|
+
"MERMAID_COLOR_VALUE",
|
|
3477
|
+
"Only #RGB or #RRGGBB colors are imported: " + R,
|
|
3478
|
+
"appearance",
|
|
3479
|
+
"warning",
|
|
3480
|
+
[x]
|
|
3481
|
+
);
|
|
3482
|
+
continue;
|
|
3483
|
+
}
|
|
3484
|
+
E.set(H, P);
|
|
3485
|
+
}
|
|
3486
|
+
bi(o, u, E.get("fill"), E.get("stroke"), E.get("color"));
|
|
3487
|
+
}, a = {
|
|
3488
|
+
square: "box",
|
|
3489
|
+
rect: "box",
|
|
3490
|
+
rectangle: "box",
|
|
3491
|
+
box: "box",
|
|
3492
|
+
stadium: "pill",
|
|
3493
|
+
circle: "circle",
|
|
3494
|
+
diamond: "diamond",
|
|
3495
|
+
text: "text"
|
|
3496
|
+
}, p = (u, g) => {
|
|
3497
|
+
if (!u) return "box";
|
|
3498
|
+
if (Object.hasOwn(a, u)) return a[u];
|
|
3499
|
+
const x = u === "doublecircle" || u === "ellipse" ? "circle" : u === "round" ? "pill" : "box";
|
|
3500
|
+
return l(
|
|
3501
|
+
"MERMAID_SHAPE_APPROXIMATION",
|
|
3502
|
+
`Mermaid shape ${u} becomes native ${x}; the shape-specific visual meaning is not fully preserved.`,
|
|
3503
|
+
"semantics",
|
|
3504
|
+
"warning",
|
|
3505
|
+
[g]
|
|
3506
|
+
), x;
|
|
3507
|
+
};
|
|
3508
|
+
try {
|
|
3509
|
+
const u = new Map(c.groups.map((I) => [I.id, I])), g = new Map(c.vertices.map((I) => [I.id, I]));
|
|
3510
|
+
if (u.size !== c.groups.length || g.size !== c.vertices.length)
|
|
3511
|
+
return l(
|
|
3512
|
+
"MERMAID_DUPLICATE_DB_ID",
|
|
3513
|
+
"The parser snapshot contains duplicate group or node identities.",
|
|
3514
|
+
"semantics",
|
|
3515
|
+
"error"
|
|
3516
|
+
), h();
|
|
3517
|
+
const x = /* @__PURE__ */ new Map();
|
|
3518
|
+
for (const I of c.groups)
|
|
3519
|
+
x.set(I.id, {
|
|
3520
|
+
id: s.get("group", I.id),
|
|
3521
|
+
kind: "group",
|
|
3522
|
+
label: M(I.title, I.labelType, I.id)
|
|
3523
|
+
});
|
|
3524
|
+
for (const I of c.vertices)
|
|
3525
|
+
u.has(I.id) || x.set(I.id, {
|
|
3526
|
+
id: s.get("node", I.id),
|
|
3527
|
+
kind: "node",
|
|
3528
|
+
label: M(I.text, I.labelType, I.id),
|
|
3529
|
+
shape: p(I.type, I.id)
|
|
3530
|
+
});
|
|
3531
|
+
const E = /* @__PURE__ */ new Map();
|
|
3532
|
+
for (const I of c.groups)
|
|
3533
|
+
for (const P of I.nodes) {
|
|
3534
|
+
if (!x.has(P)) {
|
|
3535
|
+
l(
|
|
3536
|
+
"MERMAID_UNKNOWN_MEMBER",
|
|
3537
|
+
"Subgraph references an absent member: " + P,
|
|
3538
|
+
"semantics",
|
|
3539
|
+
"error",
|
|
3540
|
+
[I.id, P]
|
|
3541
|
+
);
|
|
3542
|
+
continue;
|
|
3543
|
+
}
|
|
3544
|
+
const O = E.get(P);
|
|
3545
|
+
if (O && O !== I.id) {
|
|
3546
|
+
l(
|
|
3547
|
+
"MERMAID_MULTIPLE_PARENTS",
|
|
3548
|
+
"A member belongs to multiple native parents; containment was not guessed.",
|
|
3549
|
+
"semantics",
|
|
3550
|
+
"error",
|
|
3551
|
+
[P, O, I.id]
|
|
3552
|
+
);
|
|
3553
|
+
continue;
|
|
3554
|
+
}
|
|
3555
|
+
E.set(P, I.id), x.get(P).parent = x.get(I.id).id;
|
|
3556
|
+
}
|
|
3557
|
+
const R = m(c.direction, "root");
|
|
3558
|
+
R && o.layouts.push({ scope: "root", kind: "flow", direction: R });
|
|
3559
|
+
const L = /* @__PURE__ */ new Map();
|
|
3560
|
+
for (const I of c.groups) {
|
|
3561
|
+
const P = m(I.dir, I.id);
|
|
3562
|
+
P && L.set(I.id, P);
|
|
3563
|
+
}
|
|
3564
|
+
const H = (I) => {
|
|
3565
|
+
const P = /* @__PURE__ */ new Set();
|
|
3566
|
+
let O = I;
|
|
3567
|
+
for (; O && !P.has(O); ) {
|
|
3568
|
+
P.add(O);
|
|
3569
|
+
const y = L.get(O);
|
|
3570
|
+
if (y) return y;
|
|
3571
|
+
O = E.get(O);
|
|
3572
|
+
}
|
|
3573
|
+
return R ?? "down";
|
|
3574
|
+
};
|
|
3575
|
+
for (const I of c.groups) {
|
|
3576
|
+
const P = x.get(I.id), O = g.get(I.id);
|
|
3577
|
+
n(
|
|
3578
|
+
P,
|
|
3579
|
+
f([...I.classes, ...O?.classes ?? []], O?.styles ?? [], !1, I.id),
|
|
3580
|
+
I.id
|
|
3581
|
+
), o.layouts.push({
|
|
3582
|
+
scope: P.id,
|
|
3583
|
+
kind: "flow",
|
|
3584
|
+
direction: H(I.id)
|
|
3585
|
+
}), I.dir ? l(
|
|
3586
|
+
"MERMAID_SUBGRAPH_LAYOUT",
|
|
3587
|
+
"The native group retains its declared direction. Mermaid can ignore a subgraph direction when its members connect outside, so the resulting layout may differ.",
|
|
3588
|
+
"layout",
|
|
3589
|
+
"warning",
|
|
3590
|
+
[I.id]
|
|
3591
|
+
) : l(
|
|
3592
|
+
"MERMAID_INHERITED_LAYOUT",
|
|
3593
|
+
"This group has no declared direction. Native flow layout uses the nearest declared ancestor/root direction; Mermaid can use another direction depending on its layout engine and external connections.",
|
|
3594
|
+
"layout",
|
|
3595
|
+
"warning",
|
|
3596
|
+
[I.id]
|
|
3597
|
+
), I.metadata && Object.keys(I.metadata).length && l(
|
|
3598
|
+
"MERMAID_GROUP_METADATA",
|
|
3599
|
+
"Group metadata (including collapsed view and engine hints) is omitted: " + Object.keys(I.metadata).join(", "),
|
|
3600
|
+
"layout",
|
|
3601
|
+
"warning",
|
|
3602
|
+
[I.id]
|
|
3603
|
+
);
|
|
3604
|
+
}
|
|
3605
|
+
for (const I of c.vertices) {
|
|
3606
|
+
const P = x.get(I.id);
|
|
3607
|
+
u.has(I.id) || n(P, f(I.classes, I.styles, !0, I.id), I.id), I.link && l(
|
|
3608
|
+
"MERMAID_LINK_OMITTED",
|
|
3609
|
+
"External link was omitted; the native object has no active link.",
|
|
3610
|
+
"security",
|
|
3611
|
+
"warning",
|
|
3612
|
+
[I.id]
|
|
3613
|
+
), (I.img || I.icon) && l(
|
|
3614
|
+
"MERMAID_ASSET_OMITTED",
|
|
3615
|
+
"Image/icon references are not fetched or embedded; the object remains a labeled native shape.",
|
|
3616
|
+
"security",
|
|
3617
|
+
"warning",
|
|
3618
|
+
[I.id]
|
|
3619
|
+
), I.props && Object.keys(I.props).length && l(
|
|
3620
|
+
"MERMAID_NODE_METADATA",
|
|
3621
|
+
"Node properties are omitted: " + Object.keys(I.props).join(", "),
|
|
3622
|
+
"semantics",
|
|
3623
|
+
"warning",
|
|
3624
|
+
[I.id]
|
|
3625
|
+
);
|
|
3626
|
+
}
|
|
3627
|
+
o.objects.push(...x.values());
|
|
3628
|
+
for (const [I, P] of c.edges.entries()) {
|
|
3629
|
+
const O = Ai[String(P.type)];
|
|
3630
|
+
if (!O) {
|
|
3631
|
+
l(
|
|
3632
|
+
"MERMAID_ARROW_UNSUPPORTED",
|
|
3633
|
+
"Edge terminal semantics are unsupported: " + String(P.type) + ". The import is blocked rather than replacing them with ordinary arrows.",
|
|
3634
|
+
"semantics",
|
|
3635
|
+
"error",
|
|
3636
|
+
[P.id ?? String(I + 1)]
|
|
3637
|
+
);
|
|
3638
|
+
continue;
|
|
3639
|
+
}
|
|
3640
|
+
if (P.stroke === "invisible") {
|
|
3641
|
+
l(
|
|
3642
|
+
"MERMAID_INVISIBLE_EDGE",
|
|
3643
|
+
"Invisible links express layout constraints, not visible relationships; this profile cannot preserve them.",
|
|
3644
|
+
"layout",
|
|
3645
|
+
"error",
|
|
3646
|
+
[P.id ?? String(I + 1)]
|
|
3647
|
+
);
|
|
3648
|
+
continue;
|
|
3649
|
+
}
|
|
3650
|
+
if (!["normal", "thick", "dotted"].includes(P.stroke ?? "normal")) {
|
|
3651
|
+
l(
|
|
3652
|
+
"MERMAID_EDGE_STROKE",
|
|
3653
|
+
"Unsupported edge stroke: " + String(P.stroke),
|
|
3654
|
+
"appearance",
|
|
3655
|
+
"error",
|
|
3656
|
+
[P.id ?? String(I + 1)]
|
|
3657
|
+
);
|
|
3658
|
+
continue;
|
|
3659
|
+
}
|
|
3660
|
+
const y = x.get(P.start), D = x.get(P.end);
|
|
3661
|
+
if (!y || !D) {
|
|
3662
|
+
l("MERMAID_ENDPOINT", "A parsed edge has a missing endpoint.", "semantics", "error", [
|
|
3663
|
+
P.start,
|
|
3664
|
+
P.end
|
|
3665
|
+
]);
|
|
3666
|
+
continue;
|
|
3667
|
+
}
|
|
3668
|
+
const w = P.isUserDefinedId && P.id ? s.get("edge-id", P.id, P.id) : s.get("edge-occurrence", String(I + 1), "edge_" + (I + 1)), b = P.id ?? String(I + 1);
|
|
3669
|
+
o.edges.push({
|
|
3670
|
+
id: w,
|
|
3671
|
+
from: y.id,
|
|
3672
|
+
to: D.id,
|
|
3673
|
+
label: M(P.text, P.labelType, b),
|
|
3674
|
+
directed: P.type !== "arrow_open",
|
|
3675
|
+
...O,
|
|
3676
|
+
...P.stroke === "dotted" ? { dashed: !0 } : {}
|
|
3677
|
+
}), P.stroke === "dotted" && l(
|
|
3678
|
+
"MERMAID_DASH_STYLE",
|
|
3679
|
+
"Dotted Mermaid stroke uses native kind=async only for its dashed visual treatment; no asynchronous execution semantics are inferred.",
|
|
3680
|
+
"appearance",
|
|
3681
|
+
"info",
|
|
3682
|
+
[b]
|
|
3683
|
+
), P.stroke === "thick" && l(
|
|
3684
|
+
"MERMAID_THICK_EDGE",
|
|
3685
|
+
"Thick edge emphasis is omitted by this native-source profile.",
|
|
3686
|
+
"appearance",
|
|
3687
|
+
"warning",
|
|
3688
|
+
[b]
|
|
3689
|
+
), (P.length ?? 1) > 1 && l(
|
|
3690
|
+
"MERMAID_MIN_RANK_LENGTH",
|
|
3691
|
+
"Minimum rank-length hint is omitted; native layout chooses spacing.",
|
|
3692
|
+
"layout",
|
|
3693
|
+
"warning",
|
|
3694
|
+
[b]
|
|
3695
|
+
), (P.animate || P.animation) && l("MERMAID_EDGE_ANIMATION", "Edge animation is omitted.", "appearance", "warning", [
|
|
3696
|
+
b
|
|
3697
|
+
]), (P.interpolate || c.defaultEdgeInterpolate) && l(
|
|
3698
|
+
"MERMAID_EDGE_CURVE",
|
|
3699
|
+
"Mermaid curve hints are omitted; native routing is used.",
|
|
3700
|
+
"layout",
|
|
3701
|
+
"warning",
|
|
3702
|
+
[b]
|
|
3703
|
+
);
|
|
3704
|
+
const _ = f(
|
|
3705
|
+
P.classes,
|
|
3706
|
+
[...c.defaultEdgeStyle, ...P.style],
|
|
3707
|
+
!1,
|
|
3708
|
+
b
|
|
3709
|
+
);
|
|
3710
|
+
_.length && l(
|
|
3711
|
+
"MERMAID_EDGE_STYLE",
|
|
3712
|
+
"Per-edge CSS is omitted because native edge appearance is not a general CSS style map: " + _.join("; "),
|
|
3713
|
+
"appearance",
|
|
3714
|
+
"warning",
|
|
3715
|
+
[b]
|
|
3716
|
+
);
|
|
3717
|
+
}
|
|
3718
|
+
return h();
|
|
3719
|
+
} catch (u) {
|
|
3720
|
+
return l(
|
|
3721
|
+
"MERMAID_MAPPING_ERROR",
|
|
3722
|
+
"Could not map the parser snapshot: " + (u instanceof Error ? u.message : String(u)),
|
|
3723
|
+
"semantics",
|
|
3724
|
+
"error"
|
|
3725
|
+
), h();
|
|
3726
|
+
}
|
|
3727
|
+
}
|
|
3728
|
+
function Ii(e, t, i) {
|
|
3729
|
+
const o = _i(e, t, i);
|
|
3730
|
+
if (!o.nativeSource) return o;
|
|
3731
|
+
try {
|
|
3732
|
+
return Ds(o.nativeSource), o;
|
|
3733
|
+
} catch (s) {
|
|
3734
|
+
return {
|
|
3735
|
+
...o,
|
|
3736
|
+
status: "failed",
|
|
3737
|
+
nativeSource: void 0,
|
|
3738
|
+
facts: void 0,
|
|
3739
|
+
diagnostics: [
|
|
3740
|
+
...o.diagnostics,
|
|
3741
|
+
{
|
|
3742
|
+
code: "IMPORT_NATIVE_INVALID",
|
|
3743
|
+
severity: "error",
|
|
3744
|
+
impact: "semantics",
|
|
3745
|
+
message: "The converted diagram cannot be represented in native source: " + (s instanceof Error ? s.message : String(s))
|
|
3746
|
+
}
|
|
3747
|
+
]
|
|
3748
|
+
};
|
|
3749
|
+
}
|
|
3750
|
+
}
|
|
3751
|
+
export {
|
|
3752
|
+
Ii as importMermaidFlow
|
|
3753
|
+
};
|