@avodado/render 0.0.2 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +5 -5
- package/dist/index.js +2103 -391
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -6,34 +6,36 @@ html{scroll-behavior:smooth;}
|
|
|
6
6
|
/* Design tokens live on :root so a theme (applied as :root overrides) reaches
|
|
7
7
|
the whole page \u2014 body chrome included, not just .docskin content. */
|
|
8
8
|
:root{
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
--
|
|
12
|
-
--
|
|
13
|
-
--
|
|
14
|
-
--
|
|
9
|
+
/* Default = "textbook": warm cream paper, deep academic navy, terracotta accent,
|
|
10
|
+
classic serif display + body. Bigger headings for a printed-page feel. */
|
|
11
|
+
--navy:#233a5e; --navy-tint:#c4d0e2; --blue:#2f5c8f; --light-blue:#e8eef6;
|
|
12
|
+
--charcoal:#211f1a; --slate:#4a463d; --gray:#8a8475; --light-gray:#f2efe6;
|
|
13
|
+
--rule:#e4dccb; --highlight:#9c4a2f; --highlight-soft:#f3e4dc;
|
|
14
|
+
--positive:#3f7d4e; --positive-soft:#e3efe2; --negative:#a13b2e; --negative-soft:#f4e0db;
|
|
15
|
+
--purple:#5b4a8a; --purple-soft:#ebe6f3; --teal:#2f6f6a; --teal-soft:#e0eeec; --white:#fcfbf7;
|
|
16
|
+
--radius:4px;
|
|
15
17
|
--font-display:"Inter","SF Pro Display",-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif;
|
|
16
18
|
--font-body:"Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif;
|
|
17
|
-
--font-mono:"
|
|
19
|
+
--font-mono:"SF Mono",ui-monospace,Menlo,Consolas,"Courier New",monospace;
|
|
18
20
|
}
|
|
19
|
-
body{background:var(--white);color:var(--charcoal);font-family:var(--font-body);font-size:
|
|
21
|
+
body{background:var(--white);color:var(--charcoal);font-family:var(--font-body);font-size:15px;line-height:1.6;}
|
|
20
22
|
.docskin{
|
|
21
|
-
background:var(--white); color:var(--charcoal); font-family:var(--font-body); font-size:
|
|
23
|
+
background:var(--white); color:var(--charcoal); font-family:var(--font-body); font-size:15px; line-height:1.6;
|
|
22
24
|
max-width:1180px; margin:0 auto; padding:0 56px 128px;
|
|
23
25
|
}
|
|
24
26
|
.docskin .cover-bar{height:8px;background:var(--navy);margin:0 -56px 36px;}
|
|
25
27
|
.docskin .cover-pad{padding:0 0 40px;margin-bottom:56px;border-bottom:1px solid var(--rule);}
|
|
26
28
|
.docskin .cover-meta{display:flex;justify-content:space-between;flex-wrap:wrap;gap:16px;font-size:11px;text-transform:uppercase;letter-spacing:.12em;color:var(--gray);font-weight:600;margin-bottom:32px;}
|
|
27
29
|
.docskin .cover-meta .accent{color:var(--highlight);}
|
|
28
|
-
.docskin .cover-title{font-family:var(--font-display);font-weight:700;font-size:clamp(
|
|
29
|
-
.docskin .cover-sub{font-size:
|
|
30
|
+
.docskin .cover-title{font-family:var(--font-display);font-weight:700;font-size:clamp(40px,5.2vw,62px);line-height:1.08;letter-spacing:-.015em;color:var(--navy);margin:0 0 22px;}
|
|
31
|
+
.docskin .cover-sub{font-size:19px;line-height:1.55;color:var(--slate);max-width:860px;margin:0 0 36px;}
|
|
30
32
|
.docskin .section{padding:0;margin-bottom:64px;}
|
|
31
33
|
.docskin .section > *:last-child{margin-bottom:0;}
|
|
32
34
|
.docskin .section-num{font-size:11px;text-transform:uppercase;letter-spacing:.14em;color:var(--highlight);font-weight:700;margin-bottom:8px;}
|
|
33
35
|
.docskin .section-head{margin-bottom:28px;padding-bottom:16px;border-bottom:2px solid var(--navy);}
|
|
34
36
|
.docskin .section-head .section-title{border-bottom:0;padding-bottom:0;margin-bottom:14px;}
|
|
35
|
-
.docskin .section-title{font-family:var(--font-display);font-weight:700;font-size:clamp(
|
|
36
|
-
.docskin .section-lede{font-size:
|
|
37
|
+
.docskin .section-title{font-family:var(--font-display);font-weight:700;font-size:clamp(28px,3.6vw,40px);line-height:1.15;letter-spacing:-.01em;color:var(--navy);margin:0 0 14px;padding-bottom:12px;border-bottom:2px solid var(--navy);}
|
|
38
|
+
.docskin .section-lede{font-size:15.5px;color:var(--slate);line-height:1.6;max-width:860px;margin:0;}
|
|
37
39
|
.docskin .section-block{margin-bottom:64px;}
|
|
38
40
|
.docskin .section-block:last-child{margin-bottom:0;}
|
|
39
41
|
.docskin .diagram{margin:28px 0 36px;border:1px solid var(--rule);background:var(--white);padding:22px 26px 18px;border-radius:var(--radius);}
|
|
@@ -86,7 +88,7 @@ body{background:var(--white);color:var(--charcoal);font-family:var(--font-body);
|
|
|
86
88
|
.docskin .code-block .kw{color:var(--navy);font-weight:700;} .docskin .code-block .com{color:var(--gray);font-style:italic;}
|
|
87
89
|
.docskin .code-block .str{color:var(--positive);} .docskin .code-block .num{color:var(--purple);} .docskin .code-block .fn{color:var(--blue);} .docskin .code-block .ty{color:var(--teal);}
|
|
88
90
|
/* er */
|
|
89
|
-
.docskin .er-head-text{fill
|
|
91
|
+
.docskin .er-head-text{fill:var(--white);font-family:var(--font-display);font-size:13px;font-weight:700;text-anchor:middle;}
|
|
90
92
|
.docskin .er-col{font-family:var(--font-mono);font-size:10.5px;fill:var(--charcoal);} .docskin .er-col.dim{fill:var(--gray);}
|
|
91
93
|
.docskin .er-key{font-family:var(--font-mono);font-size:9px;font-weight:700;fill:var(--navy);} .docskin .er-key.fk{fill:var(--highlight);}
|
|
92
94
|
.docskin .er-rowline{stroke:var(--light-gray);stroke-width:1;}
|
|
@@ -412,61 +414,1734 @@ function renderCallout(data) {
|
|
|
412
414
|
return `<div class="callout ${tone}"><div class="callout-title">${escapeHtml(title)}</div><div class="callout-body">${escapeHtml(body)}</div></div>`;
|
|
413
415
|
}
|
|
414
416
|
|
|
417
|
+
// ../../node_modules/.pnpm/@dagrejs+dagre@3.0.0/node_modules/@dagrejs/dagre/dist/dagre.esm.js
|
|
418
|
+
var ge = Object.defineProperty;
|
|
419
|
+
var hn = (e, n, t) => n in e ? ge(e, n, { enumerable: true, configurable: true, writable: true, value: t }) : e[n] = t;
|
|
420
|
+
var fn = (e, n) => {
|
|
421
|
+
for (var t in n) ge(e, t, { get: n[t], enumerable: true });
|
|
422
|
+
};
|
|
423
|
+
var pe = (e, n, t) => hn(e, n + "" , t);
|
|
424
|
+
var z = {};
|
|
425
|
+
fn(z, { Graph: () => p, alg: () => R, json: () => ye, version: () => pn });
|
|
426
|
+
var bn = Object.defineProperty;
|
|
427
|
+
var Le = (e, n) => {
|
|
428
|
+
for (var t in n) bn(e, t, { get: n[t], enumerable: true });
|
|
429
|
+
};
|
|
430
|
+
var p = class {
|
|
431
|
+
constructor(e) {
|
|
432
|
+
this._isDirected = true, this._isMultigraph = false, this._isCompound = false, this._nodes = {}, this._in = {}, this._preds = {}, this._out = {}, this._sucs = {}, this._edgeObjs = {}, this._edgeLabels = {}, this._nodeCount = 0, this._edgeCount = 0, this._defaultNodeLabelFn = () => {
|
|
433
|
+
}, this._defaultEdgeLabelFn = () => {
|
|
434
|
+
}, e && (this._isDirected = "directed" in e ? e.directed : true, this._isMultigraph = "multigraph" in e ? e.multigraph : false, this._isCompound = "compound" in e ? e.compound : false), this._isCompound && (this._parent = {}, this._children = {}, this._children["\0"] = {});
|
|
435
|
+
}
|
|
436
|
+
isDirected() {
|
|
437
|
+
return this._isDirected;
|
|
438
|
+
}
|
|
439
|
+
isMultigraph() {
|
|
440
|
+
return this._isMultigraph;
|
|
441
|
+
}
|
|
442
|
+
isCompound() {
|
|
443
|
+
return this._isCompound;
|
|
444
|
+
}
|
|
445
|
+
setGraph(e) {
|
|
446
|
+
return this._label = e, this;
|
|
447
|
+
}
|
|
448
|
+
graph() {
|
|
449
|
+
return this._label;
|
|
450
|
+
}
|
|
451
|
+
setDefaultNodeLabel(e) {
|
|
452
|
+
return typeof e != "function" ? this._defaultNodeLabelFn = () => e : this._defaultNodeLabelFn = e, this;
|
|
453
|
+
}
|
|
454
|
+
nodeCount() {
|
|
455
|
+
return this._nodeCount;
|
|
456
|
+
}
|
|
457
|
+
nodes() {
|
|
458
|
+
return Object.keys(this._nodes);
|
|
459
|
+
}
|
|
460
|
+
sources() {
|
|
461
|
+
return this.nodes().filter((e) => Object.keys(this._in[e]).length === 0);
|
|
462
|
+
}
|
|
463
|
+
sinks() {
|
|
464
|
+
return this.nodes().filter((e) => Object.keys(this._out[e]).length === 0);
|
|
465
|
+
}
|
|
466
|
+
setNodes(e, n) {
|
|
467
|
+
return e.forEach((t) => {
|
|
468
|
+
n !== void 0 ? this.setNode(t, n) : this.setNode(t);
|
|
469
|
+
}), this;
|
|
470
|
+
}
|
|
471
|
+
setNode(e, n) {
|
|
472
|
+
return e in this._nodes ? (arguments.length > 1 && (this._nodes[e] = n), this) : (this._nodes[e] = arguments.length > 1 ? n : this._defaultNodeLabelFn(e), this._isCompound && (this._parent[e] = "\0", this._children[e] = {}, this._children["\0"][e] = true), this._in[e] = {}, this._preds[e] = {}, this._out[e] = {}, this._sucs[e] = {}, ++this._nodeCount, this);
|
|
473
|
+
}
|
|
474
|
+
node(e) {
|
|
475
|
+
return this._nodes[e];
|
|
476
|
+
}
|
|
477
|
+
hasNode(e) {
|
|
478
|
+
return e in this._nodes;
|
|
479
|
+
}
|
|
480
|
+
removeNode(e) {
|
|
481
|
+
if (e in this._nodes) {
|
|
482
|
+
let n = (t) => this.removeEdge(this._edgeObjs[t]);
|
|
483
|
+
delete this._nodes[e], this._isCompound && (this._removeFromParentsChildList(e), delete this._parent[e], this.children(e).forEach((t) => {
|
|
484
|
+
this.setParent(t);
|
|
485
|
+
}), delete this._children[e]), Object.keys(this._in[e]).forEach(n), delete this._in[e], delete this._preds[e], Object.keys(this._out[e]).forEach(n), delete this._out[e], delete this._sucs[e], --this._nodeCount;
|
|
486
|
+
}
|
|
487
|
+
return this;
|
|
488
|
+
}
|
|
489
|
+
setParent(e, n) {
|
|
490
|
+
if (!this._isCompound) throw new Error("Cannot set parent in a non-compound graph");
|
|
491
|
+
if (n === void 0) n = "\0";
|
|
492
|
+
else {
|
|
493
|
+
n += "";
|
|
494
|
+
for (let t = n; t !== void 0; t = this.parent(t)) if (t === e) throw new Error("Setting " + n + " as parent of " + e + " would create a cycle");
|
|
495
|
+
this.setNode(n);
|
|
496
|
+
}
|
|
497
|
+
return this.setNode(e), this._removeFromParentsChildList(e), this._parent[e] = n, this._children[n][e] = true, this;
|
|
498
|
+
}
|
|
499
|
+
parent(e) {
|
|
500
|
+
if (this._isCompound) {
|
|
501
|
+
let n = this._parent[e];
|
|
502
|
+
if (n !== "\0") return n;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
children(e = "\0") {
|
|
506
|
+
if (this._isCompound) {
|
|
507
|
+
let n = this._children[e];
|
|
508
|
+
if (n) return Object.keys(n);
|
|
509
|
+
} else {
|
|
510
|
+
if (e === "\0") return this.nodes();
|
|
511
|
+
if (this.hasNode(e)) return [];
|
|
512
|
+
}
|
|
513
|
+
return [];
|
|
514
|
+
}
|
|
515
|
+
predecessors(e) {
|
|
516
|
+
let n = this._preds[e];
|
|
517
|
+
if (n) return Object.keys(n);
|
|
518
|
+
}
|
|
519
|
+
successors(e) {
|
|
520
|
+
let n = this._sucs[e];
|
|
521
|
+
if (n) return Object.keys(n);
|
|
522
|
+
}
|
|
523
|
+
neighbors(e) {
|
|
524
|
+
let n = this.predecessors(e);
|
|
525
|
+
if (n) {
|
|
526
|
+
let t = new Set(n);
|
|
527
|
+
for (let r of this.successors(e)) t.add(r);
|
|
528
|
+
return Array.from(t.values());
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
isLeaf(e) {
|
|
532
|
+
let n;
|
|
533
|
+
return this.isDirected() ? n = this.successors(e) : n = this.neighbors(e), n.length === 0;
|
|
534
|
+
}
|
|
535
|
+
filterNodes(e) {
|
|
536
|
+
let n = new this.constructor({ directed: this._isDirected, multigraph: this._isMultigraph, compound: this._isCompound });
|
|
537
|
+
n.setGraph(this.graph()), Object.entries(this._nodes).forEach(([o, i]) => {
|
|
538
|
+
e(o) && n.setNode(o, i);
|
|
539
|
+
}), Object.values(this._edgeObjs).forEach((o) => {
|
|
540
|
+
n.hasNode(o.v) && n.hasNode(o.w) && n.setEdge(o, this.edge(o));
|
|
541
|
+
});
|
|
542
|
+
let t = {}, r = (o) => {
|
|
543
|
+
let i = this.parent(o);
|
|
544
|
+
return !i || n.hasNode(i) ? (t[o] = i != null ? i : void 0, i != null ? i : void 0) : i in t ? t[i] : r(i);
|
|
545
|
+
};
|
|
546
|
+
return this._isCompound && n.nodes().forEach((o) => n.setParent(o, r(o))), n;
|
|
547
|
+
}
|
|
548
|
+
setDefaultEdgeLabel(e) {
|
|
549
|
+
return typeof e != "function" ? this._defaultEdgeLabelFn = () => e : this._defaultEdgeLabelFn = e, this;
|
|
550
|
+
}
|
|
551
|
+
edgeCount() {
|
|
552
|
+
return this._edgeCount;
|
|
553
|
+
}
|
|
554
|
+
edges() {
|
|
555
|
+
return Object.values(this._edgeObjs);
|
|
556
|
+
}
|
|
557
|
+
setPath(e, n) {
|
|
558
|
+
return e.reduce((t, r) => (n !== void 0 ? this.setEdge(t, r, n) : this.setEdge(t, r), r)), this;
|
|
559
|
+
}
|
|
560
|
+
setEdge(e, n, t, r) {
|
|
561
|
+
let o, i, s, a, d = false;
|
|
562
|
+
typeof e == "object" && e !== null && "v" in e ? (o = e.v, i = e.w, s = e.name, arguments.length === 2 && (a = n, d = true)) : (o = e, i = n, s = r, arguments.length > 2 && (a = t, d = true)), o = "" + o, i = "" + i, s !== void 0 && (s = "" + s);
|
|
563
|
+
let l = C(this._isDirected, o, i, s);
|
|
564
|
+
if (l in this._edgeLabels) return d && (this._edgeLabels[l] = a), this;
|
|
565
|
+
if (s !== void 0 && !this._isMultigraph) throw new Error("Cannot set a named edge when isMultigraph = false");
|
|
566
|
+
this.setNode(o), this.setNode(i), this._edgeLabels[l] = d ? a : this._defaultEdgeLabelFn(o, i, s);
|
|
567
|
+
let u = gn(this._isDirected, o, i, s);
|
|
568
|
+
return o = u.v, i = u.w, Object.freeze(u), this._edgeObjs[l] = u, me(this._preds[i], o), me(this._sucs[o], i), this._in[i][l] = u, this._out[o][l] = u, this._edgeCount++, this;
|
|
569
|
+
}
|
|
570
|
+
edge(e, n, t) {
|
|
571
|
+
let r = arguments.length === 1 ? Y(this._isDirected, e) : C(this._isDirected, e, n, t);
|
|
572
|
+
return this._edgeLabels[r];
|
|
573
|
+
}
|
|
574
|
+
edgeAsObj(e, n, t) {
|
|
575
|
+
let r = arguments.length === 1 ? this.edge(e) : this.edge(e, n, t);
|
|
576
|
+
return typeof r != "object" ? { label: r } : r;
|
|
577
|
+
}
|
|
578
|
+
hasEdge(e, n, t) {
|
|
579
|
+
return (arguments.length === 1 ? Y(this._isDirected, e) : C(this._isDirected, e, n, t)) in this._edgeLabels;
|
|
580
|
+
}
|
|
581
|
+
removeEdge(e, n, t) {
|
|
582
|
+
let r = arguments.length === 1 ? Y(this._isDirected, e) : C(this._isDirected, e, n, t), o = this._edgeObjs[r];
|
|
583
|
+
if (o) {
|
|
584
|
+
let i = o.v, s = o.w;
|
|
585
|
+
delete this._edgeLabels[r], delete this._edgeObjs[r], Ee(this._preds[s], i), Ee(this._sucs[i], s), delete this._in[s][r], delete this._out[i][r], this._edgeCount--;
|
|
586
|
+
}
|
|
587
|
+
return this;
|
|
588
|
+
}
|
|
589
|
+
inEdges(e, n) {
|
|
590
|
+
return this.isDirected() ? this.filterEdges(this._in[e], e, n) : this.nodeEdges(e, n);
|
|
591
|
+
}
|
|
592
|
+
outEdges(e, n) {
|
|
593
|
+
return this.isDirected() ? this.filterEdges(this._out[e], e, n) : this.nodeEdges(e, n);
|
|
594
|
+
}
|
|
595
|
+
nodeEdges(e, n) {
|
|
596
|
+
if (e in this._nodes) return this.filterEdges({ ...this._in[e], ...this._out[e] }, e, n);
|
|
597
|
+
}
|
|
598
|
+
_removeFromParentsChildList(e) {
|
|
599
|
+
delete this._children[this._parent[e]][e];
|
|
600
|
+
}
|
|
601
|
+
filterEdges(e, n, t) {
|
|
602
|
+
if (!e) return;
|
|
603
|
+
let r = Object.values(e);
|
|
604
|
+
return t ? r.filter((o) => o.v === n && o.w === t || o.v === t && o.w === n) : r;
|
|
605
|
+
}
|
|
606
|
+
};
|
|
607
|
+
function me(e, n) {
|
|
608
|
+
e[n] ? e[n]++ : e[n] = 1;
|
|
609
|
+
}
|
|
610
|
+
function Ee(e, n) {
|
|
611
|
+
e[n] !== void 0 && !--e[n] && delete e[n];
|
|
612
|
+
}
|
|
613
|
+
function C(e, n, t, r) {
|
|
614
|
+
let o = "" + n, i = "" + t;
|
|
615
|
+
if (!e && o > i) {
|
|
616
|
+
let s = o;
|
|
617
|
+
o = i, i = s;
|
|
618
|
+
}
|
|
619
|
+
return o + "" + i + "" + (r === void 0 ? "\0" : r);
|
|
620
|
+
}
|
|
621
|
+
function gn(e, n, t, r) {
|
|
622
|
+
let o = "" + n, i = "" + t;
|
|
623
|
+
if (!e && o > i) {
|
|
624
|
+
let a = o;
|
|
625
|
+
o = i, i = a;
|
|
626
|
+
}
|
|
627
|
+
let s = { v: o, w: i };
|
|
628
|
+
return r && (s.name = r), s;
|
|
629
|
+
}
|
|
630
|
+
function Y(e, n) {
|
|
631
|
+
return C(e, n.v, n.w, n.name);
|
|
632
|
+
}
|
|
633
|
+
var pn = "4.0.1";
|
|
634
|
+
var ye = {};
|
|
635
|
+
Le(ye, { read: () => yn, write: () => mn });
|
|
636
|
+
function mn(e) {
|
|
637
|
+
let n = { options: { directed: e.isDirected(), multigraph: e.isMultigraph(), compound: e.isCompound() }, nodes: En(e), edges: Ln(e) }, t = e.graph();
|
|
638
|
+
return t !== void 0 && (n.value = structuredClone(t)), n;
|
|
639
|
+
}
|
|
640
|
+
function En(e) {
|
|
641
|
+
return e.nodes().map((n) => {
|
|
642
|
+
let t = e.node(n), r = e.parent(n), o = { v: n };
|
|
643
|
+
return t !== void 0 && (o.value = t), r !== void 0 && (o.parent = r), o;
|
|
644
|
+
});
|
|
645
|
+
}
|
|
646
|
+
function Ln(e) {
|
|
647
|
+
return e.edges().map((n) => {
|
|
648
|
+
let t = e.edge(n), r = { v: n.v, w: n.w };
|
|
649
|
+
return n.name !== void 0 && (r.name = n.name), t !== void 0 && (r.value = t), r;
|
|
650
|
+
});
|
|
651
|
+
}
|
|
652
|
+
function yn(e) {
|
|
653
|
+
let n = new p(e.options);
|
|
654
|
+
return e.value !== void 0 && n.setGraph(e.value), e.nodes.forEach((t) => {
|
|
655
|
+
n.setNode(t.v, t.value), t.parent && n.setParent(t.v, t.parent);
|
|
656
|
+
}), e.edges.forEach((t) => {
|
|
657
|
+
n.setEdge({ v: t.v, w: t.w, name: t.name }, t.value);
|
|
658
|
+
}), n;
|
|
659
|
+
}
|
|
660
|
+
var R = {};
|
|
661
|
+
Le(R, { CycleException: () => D, bellmanFord: () => we, components: () => Gn, dijkstra: () => F, dijkstraAll: () => _n, findCycles: () => xn, floydWarshall: () => On, isAcyclic: () => Cn, postorder: () => Pn, preorder: () => Mn, prim: () => jn, shortestPaths: () => Sn, tarjan: () => Ge, topsort: () => ke });
|
|
662
|
+
var wn = () => 1;
|
|
663
|
+
function we(e, n, t, r) {
|
|
664
|
+
return Nn(e, String(n), t || wn, r || function(o) {
|
|
665
|
+
return e.outEdges(o);
|
|
666
|
+
});
|
|
667
|
+
}
|
|
668
|
+
function Nn(e, n, t, r) {
|
|
669
|
+
let o = {}, i, s = 0, a = e.nodes(), d = function(c) {
|
|
670
|
+
let h = t(c);
|
|
671
|
+
o[c.v].distance + h < o[c.w].distance && (o[c.w] = { distance: o[c.v].distance + h, predecessor: c.v }, i = true);
|
|
672
|
+
}, l = function() {
|
|
673
|
+
a.forEach(function(c) {
|
|
674
|
+
r(c).forEach(function(h) {
|
|
675
|
+
let f = h.v === c ? h.v : h.w, g = f === h.v ? h.w : h.v;
|
|
676
|
+
d({ v: f, w: g });
|
|
677
|
+
});
|
|
678
|
+
});
|
|
679
|
+
};
|
|
680
|
+
a.forEach(function(c) {
|
|
681
|
+
let h = c === n ? 0 : Number.POSITIVE_INFINITY;
|
|
682
|
+
o[c] = { distance: h, predecessor: "" };
|
|
683
|
+
});
|
|
684
|
+
let u = a.length;
|
|
685
|
+
for (let c = 1; c < u && (i = false, s++, l(), !!i); c++) ;
|
|
686
|
+
if (s === u - 1 && (i = false, l(), i)) throw new Error("The graph contains a negative weight cycle");
|
|
687
|
+
return o;
|
|
688
|
+
}
|
|
689
|
+
function Gn(e) {
|
|
690
|
+
let n = {}, t = [], r;
|
|
691
|
+
function o(i) {
|
|
692
|
+
i in n || (n[i] = true, r.push(i), e.successors(i).forEach(o), e.predecessors(i).forEach(o));
|
|
693
|
+
}
|
|
694
|
+
return e.nodes().forEach(function(i) {
|
|
695
|
+
r = [], o(i), r.length && t.push(r);
|
|
696
|
+
}), t;
|
|
697
|
+
}
|
|
698
|
+
var Ne = class {
|
|
699
|
+
constructor() {
|
|
700
|
+
this._arr = [], this._keyIndices = {};
|
|
701
|
+
}
|
|
702
|
+
size() {
|
|
703
|
+
return this._arr.length;
|
|
704
|
+
}
|
|
705
|
+
keys() {
|
|
706
|
+
return this._arr.map((e) => e.key);
|
|
707
|
+
}
|
|
708
|
+
has(e) {
|
|
709
|
+
return e in this._keyIndices;
|
|
710
|
+
}
|
|
711
|
+
priority(e) {
|
|
712
|
+
let n = this._keyIndices[e];
|
|
713
|
+
if (n !== void 0) return this._arr[n].priority;
|
|
714
|
+
}
|
|
715
|
+
min() {
|
|
716
|
+
if (this.size() === 0) throw new Error("Queue underflow");
|
|
717
|
+
return this._arr[0].key;
|
|
718
|
+
}
|
|
719
|
+
add(e, n) {
|
|
720
|
+
let t = this._keyIndices, r = String(e);
|
|
721
|
+
if (!(r in t)) {
|
|
722
|
+
let o = this._arr, i = o.length;
|
|
723
|
+
return t[r] = i, o.push({ key: r, priority: n }), this._decrease(i), true;
|
|
724
|
+
}
|
|
725
|
+
return false;
|
|
726
|
+
}
|
|
727
|
+
removeMin() {
|
|
728
|
+
this._swap(0, this._arr.length - 1);
|
|
729
|
+
let e = this._arr.pop();
|
|
730
|
+
return delete this._keyIndices[e.key], this._heapify(0), e.key;
|
|
731
|
+
}
|
|
732
|
+
decrease(e, n) {
|
|
733
|
+
let t = this._keyIndices[e];
|
|
734
|
+
if (t === void 0) throw new Error(`Key not found: ${e}`);
|
|
735
|
+
let r = this._arr[t].priority;
|
|
736
|
+
if (n > r) throw new Error(`New priority is greater than current priority. Key: ${e} Old: ${r} New: ${n}`);
|
|
737
|
+
this._arr[t].priority = n, this._decrease(t);
|
|
738
|
+
}
|
|
739
|
+
_heapify(e) {
|
|
740
|
+
let n = this._arr, t = 2 * e, r = t + 1, o = e;
|
|
741
|
+
t < n.length && (o = n[t].priority < n[o].priority ? t : o, r < n.length && (o = n[r].priority < n[o].priority ? r : o), o !== e && (this._swap(e, o), this._heapify(o)));
|
|
742
|
+
}
|
|
743
|
+
_decrease(e) {
|
|
744
|
+
let n = this._arr, t = n[e].priority, r;
|
|
745
|
+
for (; e !== 0 && (r = e >> 1, !(n[r].priority < t)); ) this._swap(e, r), e = r;
|
|
746
|
+
}
|
|
747
|
+
_swap(e, n) {
|
|
748
|
+
let t = this._arr, r = this._keyIndices, o = t[e], i = t[n];
|
|
749
|
+
t[e] = i, t[n] = o, r[i.key] = e, r[o.key] = n;
|
|
750
|
+
}
|
|
751
|
+
};
|
|
752
|
+
var kn = () => 1;
|
|
753
|
+
function F(e, n, t, r) {
|
|
754
|
+
let o = function(i) {
|
|
755
|
+
return e.outEdges(i);
|
|
756
|
+
};
|
|
757
|
+
return vn(e, String(n), t || kn, r || o);
|
|
758
|
+
}
|
|
759
|
+
function vn(e, n, t, r) {
|
|
760
|
+
let o = {}, i = new Ne(), s, a, d = function(l) {
|
|
761
|
+
let u = l.v !== s ? l.v : l.w, c = o[u], h = t(l), f = a.distance + h;
|
|
762
|
+
if (h < 0) throw new Error("dijkstra does not allow negative edge weights. Bad edge: " + l + " Weight: " + h);
|
|
763
|
+
f < c.distance && (c.distance = f, c.predecessor = s, i.decrease(u, f));
|
|
764
|
+
};
|
|
765
|
+
for (e.nodes().forEach(function(l) {
|
|
766
|
+
let u = l === n ? 0 : Number.POSITIVE_INFINITY;
|
|
767
|
+
o[l] = { distance: u, predecessor: "" }, i.add(l, u);
|
|
768
|
+
}); i.size() > 0 && (s = i.removeMin(), a = o[s], a.distance !== Number.POSITIVE_INFINITY); ) r(s).forEach(d);
|
|
769
|
+
return o;
|
|
770
|
+
}
|
|
771
|
+
function _n(e, n, t) {
|
|
772
|
+
return e.nodes().reduce(function(r, o) {
|
|
773
|
+
return r[o] = F(e, o, n, t), r;
|
|
774
|
+
}, {});
|
|
775
|
+
}
|
|
776
|
+
function Ge(e) {
|
|
777
|
+
let n = 0, t = [], r = {}, o = [];
|
|
778
|
+
function i(s) {
|
|
779
|
+
let a = r[s] = { onStack: true, lowlink: n, index: n++ };
|
|
780
|
+
if (t.push(s), e.successors(s).forEach(function(d) {
|
|
781
|
+
d in r ? r[d].onStack && (a.lowlink = Math.min(a.lowlink, r[d].index)) : (i(d), a.lowlink = Math.min(a.lowlink, r[d].lowlink));
|
|
782
|
+
}), a.lowlink === a.index) {
|
|
783
|
+
let d = [], l;
|
|
784
|
+
do
|
|
785
|
+
l = t.pop(), r[l].onStack = false, d.push(l);
|
|
786
|
+
while (s !== l);
|
|
787
|
+
o.push(d);
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
return e.nodes().forEach(function(s) {
|
|
791
|
+
s in r || i(s);
|
|
792
|
+
}), o;
|
|
793
|
+
}
|
|
794
|
+
function xn(e) {
|
|
795
|
+
return Ge(e).filter(function(n) {
|
|
796
|
+
return n.length > 1 || n.length === 1 && e.hasEdge(n[0], n[0]);
|
|
797
|
+
});
|
|
798
|
+
}
|
|
799
|
+
var Tn = () => 1;
|
|
800
|
+
function On(e, n, t) {
|
|
801
|
+
return In(e, n || Tn, t || function(r) {
|
|
802
|
+
return e.outEdges(r);
|
|
803
|
+
});
|
|
804
|
+
}
|
|
805
|
+
function In(e, n, t) {
|
|
806
|
+
let r = {}, o = e.nodes();
|
|
807
|
+
return o.forEach(function(i) {
|
|
808
|
+
r[i] = {}, r[i][i] = { distance: 0, predecessor: "" }, o.forEach(function(s) {
|
|
809
|
+
i !== s && (r[i][s] = { distance: Number.POSITIVE_INFINITY, predecessor: "" });
|
|
810
|
+
}), t(i).forEach(function(s) {
|
|
811
|
+
let a = s.v === i ? s.w : s.v, d = n(s);
|
|
812
|
+
r[i][a] = { distance: d, predecessor: i };
|
|
813
|
+
});
|
|
814
|
+
}), o.forEach(function(i) {
|
|
815
|
+
let s = r[i];
|
|
816
|
+
o.forEach(function(a) {
|
|
817
|
+
let d = r[a];
|
|
818
|
+
o.forEach(function(l) {
|
|
819
|
+
let u = d[i], c = s[l], h = d[l], f = u.distance + c.distance;
|
|
820
|
+
f < h.distance && (h.distance = f, h.predecessor = c.predecessor);
|
|
821
|
+
});
|
|
822
|
+
});
|
|
823
|
+
}), r;
|
|
824
|
+
}
|
|
825
|
+
var D = class extends Error {
|
|
826
|
+
constructor(...e) {
|
|
827
|
+
super(...e);
|
|
828
|
+
}
|
|
829
|
+
};
|
|
830
|
+
function ke(e) {
|
|
831
|
+
let n = {}, t = {}, r = [];
|
|
832
|
+
function o(i) {
|
|
833
|
+
if (i in t) throw new D();
|
|
834
|
+
i in n || (t[i] = true, n[i] = true, e.predecessors(i).forEach(o), delete t[i], r.push(i));
|
|
835
|
+
}
|
|
836
|
+
if (e.sinks().forEach(o), Object.keys(n).length !== e.nodeCount()) throw new D();
|
|
837
|
+
return r;
|
|
838
|
+
}
|
|
839
|
+
function Cn(e) {
|
|
840
|
+
try {
|
|
841
|
+
ke(e);
|
|
842
|
+
} catch (n) {
|
|
843
|
+
if (n instanceof D) return false;
|
|
844
|
+
throw n;
|
|
845
|
+
}
|
|
846
|
+
return true;
|
|
847
|
+
}
|
|
848
|
+
function Rn(e, n, t, r, o) {
|
|
849
|
+
Array.isArray(n) || (n = [n]);
|
|
850
|
+
let i = ((a) => {
|
|
851
|
+
var d;
|
|
852
|
+
return (d = e.isDirected() ? e.successors(a) : e.neighbors(a)) != null ? d : [];
|
|
853
|
+
}), s = {};
|
|
854
|
+
return n.forEach(function(a) {
|
|
855
|
+
if (!e.hasNode(a)) throw new Error("Graph does not have node: " + a);
|
|
856
|
+
o = ve(e, a, t === "post", s, i, r, o);
|
|
857
|
+
}), o;
|
|
858
|
+
}
|
|
859
|
+
function ve(e, n, t, r, o, i, s) {
|
|
860
|
+
return n in r || (r[n] = true, t || (s = i(s, n)), o(n).forEach(function(a) {
|
|
861
|
+
s = ve(e, a, t, r, o, i, s);
|
|
862
|
+
}), t && (s = i(s, n))), s;
|
|
863
|
+
}
|
|
864
|
+
function _e(e, n, t) {
|
|
865
|
+
return Rn(e, n, t, function(r, o) {
|
|
866
|
+
return r.push(o), r;
|
|
867
|
+
}, []);
|
|
868
|
+
}
|
|
869
|
+
function Pn(e, n) {
|
|
870
|
+
return _e(e, n, "post");
|
|
871
|
+
}
|
|
872
|
+
function Mn(e, n) {
|
|
873
|
+
return _e(e, n, "pre");
|
|
874
|
+
}
|
|
875
|
+
function jn(e, n) {
|
|
876
|
+
let t = new p(), r = {}, o = new Ne(), i;
|
|
877
|
+
function s(d) {
|
|
878
|
+
let l = d.v === i ? d.w : d.v, u = o.priority(l);
|
|
879
|
+
if (u !== void 0) {
|
|
880
|
+
let c = n(d);
|
|
881
|
+
c < u && (r[l] = i, o.decrease(l, c));
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
if (e.nodeCount() === 0) return t;
|
|
885
|
+
e.nodes().forEach(function(d) {
|
|
886
|
+
o.add(d, Number.POSITIVE_INFINITY), t.setNode(d);
|
|
887
|
+
}), o.decrease(e.nodes()[0], 0);
|
|
888
|
+
let a = false;
|
|
889
|
+
for (; o.size() > 0; ) {
|
|
890
|
+
if (i = o.removeMin(), i in r) t.setEdge(i, r[i]);
|
|
891
|
+
else {
|
|
892
|
+
if (a) throw new Error("Input graph is not connected: " + e);
|
|
893
|
+
a = true;
|
|
894
|
+
}
|
|
895
|
+
e.nodeEdges(i).forEach(s);
|
|
896
|
+
}
|
|
897
|
+
return t;
|
|
898
|
+
}
|
|
899
|
+
function Sn(e, n, t, r) {
|
|
900
|
+
return Fn(e, n, t, r != null ? r : ((o) => {
|
|
901
|
+
let i = e.outEdges(o);
|
|
902
|
+
return i != null ? i : [];
|
|
903
|
+
}));
|
|
904
|
+
}
|
|
905
|
+
function Fn(e, n, t, r) {
|
|
906
|
+
if (t === void 0) return F(e, n, t, r);
|
|
907
|
+
let o = false, i = e.nodes();
|
|
908
|
+
for (let s = 0; s < i.length; s++) {
|
|
909
|
+
let a = r(i[s]);
|
|
910
|
+
for (let d = 0; d < a.length; d++) {
|
|
911
|
+
let l = a[d], u = l.v === i[s] ? l.v : l.w, c = u === l.v ? l.w : l.v;
|
|
912
|
+
t({ v: u, w: c }) < 0 && (o = true);
|
|
913
|
+
}
|
|
914
|
+
if (o) return we(e, n, t, r);
|
|
915
|
+
}
|
|
916
|
+
return F(e, n, t, r);
|
|
917
|
+
}
|
|
918
|
+
function w(e, n, t, r) {
|
|
919
|
+
let o = r;
|
|
920
|
+
for (; e.hasNode(o); ) o = j(r);
|
|
921
|
+
return t.dummy = n, e.setNode(o, t), o;
|
|
922
|
+
}
|
|
923
|
+
function xe(e) {
|
|
924
|
+
let n = new p().setGraph(e.graph());
|
|
925
|
+
return e.nodes().forEach((t) => n.setNode(t, e.node(t))), e.edges().forEach((t) => {
|
|
926
|
+
let r = n.edge(t.v, t.w) || { weight: 0, minlen: 1 }, o = e.edge(t);
|
|
927
|
+
n.setEdge(t.v, t.w, { weight: r.weight + o.weight, minlen: Math.max(r.minlen, o.minlen) });
|
|
928
|
+
}), n;
|
|
929
|
+
}
|
|
930
|
+
function A(e) {
|
|
931
|
+
let n = new p({ multigraph: e.isMultigraph() }).setGraph(e.graph());
|
|
932
|
+
return e.nodes().forEach((t) => {
|
|
933
|
+
e.children(t).length || n.setNode(t, e.node(t));
|
|
934
|
+
}), e.edges().forEach((t) => {
|
|
935
|
+
n.setEdge(t, e.edge(t));
|
|
936
|
+
}), n;
|
|
937
|
+
}
|
|
938
|
+
function H(e, n) {
|
|
939
|
+
let t = e.x, r = e.y, o = n.x - t, i = n.y - r, s = e.width / 2, a = e.height / 2;
|
|
940
|
+
if (!o && !i) throw new Error("Not possible to find intersection inside of the rectangle");
|
|
941
|
+
let d, l;
|
|
942
|
+
return Math.abs(i) * s > Math.abs(o) * a ? (i < 0 && (a = -a), d = a * o / i, l = a) : (o < 0 && (s = -s), d = s, l = s * i / o), { x: t + d, y: r + l };
|
|
943
|
+
}
|
|
944
|
+
function N(e) {
|
|
945
|
+
let n = k(X(e) + 1).map(() => []);
|
|
946
|
+
return e.nodes().forEach((t) => {
|
|
947
|
+
let r = e.node(t), o = r.rank;
|
|
948
|
+
o !== void 0 && (n[o] || (n[o] = []), n[o][r.order] = t);
|
|
949
|
+
}), n;
|
|
950
|
+
}
|
|
951
|
+
function Te(e) {
|
|
952
|
+
let n = e.nodes().map((r) => {
|
|
953
|
+
let o = e.node(r).rank;
|
|
954
|
+
return o === void 0 ? Number.MAX_VALUE : o;
|
|
955
|
+
}), t = L(Math.min, n);
|
|
956
|
+
e.nodes().forEach((r) => {
|
|
957
|
+
let o = e.node(r);
|
|
958
|
+
Object.hasOwn(o, "rank") && (o.rank -= t);
|
|
959
|
+
});
|
|
960
|
+
}
|
|
961
|
+
function Oe(e) {
|
|
962
|
+
let n = e.nodes().map((s) => e.node(s).rank).filter((s) => s !== void 0), t = L(Math.min, n), r = [];
|
|
963
|
+
e.nodes().forEach((s) => {
|
|
964
|
+
let a = e.node(s).rank - t;
|
|
965
|
+
r[a] || (r[a] = []), r[a].push(s);
|
|
966
|
+
});
|
|
967
|
+
let o = 0, i = e.graph().nodeRankFactor;
|
|
968
|
+
Array.from(r).forEach((s, a) => {
|
|
969
|
+
s === void 0 && a % i !== 0 ? --o : s !== void 0 && o && s.forEach((d) => e.node(d).rank += o);
|
|
970
|
+
});
|
|
971
|
+
}
|
|
972
|
+
function q(e, n, t, r) {
|
|
973
|
+
let o = { width: 0, height: 0 };
|
|
974
|
+
return arguments.length >= 4 && (o.rank = t, o.order = r), w(e, "border", o, n);
|
|
975
|
+
}
|
|
976
|
+
function Dn(e, n = Ie) {
|
|
977
|
+
let t = [];
|
|
978
|
+
for (let r = 0; r < e.length; r += n) {
|
|
979
|
+
let o = e.slice(r, r + n);
|
|
980
|
+
t.push(o);
|
|
981
|
+
}
|
|
982
|
+
return t;
|
|
983
|
+
}
|
|
984
|
+
var Ie = 65535;
|
|
985
|
+
function L(e, n) {
|
|
986
|
+
if (n.length > Ie) {
|
|
987
|
+
let t = Dn(n);
|
|
988
|
+
return e(...t.map((r) => e(...r)));
|
|
989
|
+
} else return e(...n);
|
|
990
|
+
}
|
|
991
|
+
function X(e) {
|
|
992
|
+
let t = e.nodes().map((r) => {
|
|
993
|
+
let o = e.node(r).rank;
|
|
994
|
+
return o === void 0 ? Number.MIN_VALUE : o;
|
|
995
|
+
});
|
|
996
|
+
return L(Math.max, t);
|
|
997
|
+
}
|
|
998
|
+
function Ce(e, n) {
|
|
999
|
+
let t = { lhs: [], rhs: [] };
|
|
1000
|
+
return e.forEach((r) => {
|
|
1001
|
+
n(r) ? t.lhs.push(r) : t.rhs.push(r);
|
|
1002
|
+
}), t;
|
|
1003
|
+
}
|
|
1004
|
+
function P(e, n) {
|
|
1005
|
+
let t = Date.now();
|
|
1006
|
+
try {
|
|
1007
|
+
return n();
|
|
1008
|
+
} finally {
|
|
1009
|
+
console.log(e + " time: " + (Date.now() - t) + "ms");
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
function M(e, n) {
|
|
1013
|
+
return n();
|
|
1014
|
+
}
|
|
1015
|
+
var An = 0;
|
|
1016
|
+
function j(e) {
|
|
1017
|
+
let n = ++An;
|
|
1018
|
+
return e + ("" + n);
|
|
1019
|
+
}
|
|
1020
|
+
function k(e, n, t = 1) {
|
|
1021
|
+
n == null && (n = e, e = 0);
|
|
1022
|
+
let r = (i) => i < n;
|
|
1023
|
+
t < 0 && (r = (i) => n < i);
|
|
1024
|
+
let o = [];
|
|
1025
|
+
for (let i = e; r(i); i += t) o.push(i);
|
|
1026
|
+
return o;
|
|
1027
|
+
}
|
|
1028
|
+
function T(e, n) {
|
|
1029
|
+
let t = {};
|
|
1030
|
+
for (let r of n) e[r] !== void 0 && (t[r] = e[r]);
|
|
1031
|
+
return t;
|
|
1032
|
+
}
|
|
1033
|
+
function O(e, n) {
|
|
1034
|
+
let t;
|
|
1035
|
+
return typeof n == "string" ? t = (r) => r[n] : t = n, Object.entries(e).reduce((r, [o, i]) => (r[o] = t(i, o), r), {});
|
|
1036
|
+
}
|
|
1037
|
+
function Re(e, n) {
|
|
1038
|
+
return e.reduce((t, r, o) => (t[r] = n[o], t), {});
|
|
1039
|
+
}
|
|
1040
|
+
var _ = "\0";
|
|
1041
|
+
var U = "3.0.0";
|
|
1042
|
+
var K = class {
|
|
1043
|
+
constructor() {
|
|
1044
|
+
pe(this, "_sentinel");
|
|
1045
|
+
let n = {};
|
|
1046
|
+
n._next = n._prev = n, this._sentinel = n;
|
|
1047
|
+
}
|
|
1048
|
+
dequeue() {
|
|
1049
|
+
let n = this._sentinel, t = n._prev;
|
|
1050
|
+
if (t !== n) return Pe(t), t;
|
|
1051
|
+
}
|
|
1052
|
+
enqueue(n) {
|
|
1053
|
+
let t = this._sentinel;
|
|
1054
|
+
n._prev && n._next && Pe(n), n._next = t._next, t._next._prev = n, t._next = n, n._prev = t;
|
|
1055
|
+
}
|
|
1056
|
+
toString() {
|
|
1057
|
+
let n = [], t = this._sentinel, r = t._prev;
|
|
1058
|
+
for (; r !== t; ) n.push(JSON.stringify(r, Vn)), r = r._prev;
|
|
1059
|
+
return "[" + n.join(", ") + "]";
|
|
1060
|
+
}
|
|
1061
|
+
};
|
|
1062
|
+
function Pe(e) {
|
|
1063
|
+
e._prev._next = e._next, e._next._prev = e._prev, delete e._next, delete e._prev;
|
|
1064
|
+
}
|
|
1065
|
+
function Vn(e, n) {
|
|
1066
|
+
if (e !== "_next" && e !== "_prev") return n;
|
|
1067
|
+
}
|
|
1068
|
+
var Me = K;
|
|
1069
|
+
var Wn = () => 1;
|
|
1070
|
+
function Q(e, n) {
|
|
1071
|
+
if (e.nodeCount() <= 1) return [];
|
|
1072
|
+
let t = Yn(e, n || Wn);
|
|
1073
|
+
return Bn(t.graph, t.buckets, t.zeroIdx).flatMap((o) => e.outEdges(o.v, o.w) || []);
|
|
1074
|
+
}
|
|
1075
|
+
function Bn(e, n, t) {
|
|
1076
|
+
var a;
|
|
1077
|
+
let r = [], o = n[n.length - 1], i = n[0], s;
|
|
1078
|
+
for (; e.nodeCount(); ) {
|
|
1079
|
+
for (; s = i.dequeue(); ) $(e, n, t, s);
|
|
1080
|
+
for (; s = o.dequeue(); ) $(e, n, t, s);
|
|
1081
|
+
if (e.nodeCount()) {
|
|
1082
|
+
for (let d = n.length - 2; d > 0; --d) if (s = (a = n[d]) == null ? void 0 : a.dequeue(), s) {
|
|
1083
|
+
r = r.concat($(e, n, t, s, true) || []);
|
|
1084
|
+
break;
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
return r;
|
|
1089
|
+
}
|
|
1090
|
+
function $(e, n, t, r, o) {
|
|
1091
|
+
let i = [], s = o ? i : void 0;
|
|
1092
|
+
return (e.inEdges(r.v) || []).forEach((a) => {
|
|
1093
|
+
let d = e.edge(a), l = e.node(a.v);
|
|
1094
|
+
o && i.push({ v: a.v, w: a.w }), l.out -= d, J(n, t, l);
|
|
1095
|
+
}), (e.outEdges(r.v) || []).forEach((a) => {
|
|
1096
|
+
let d = e.edge(a), l = a.w, u = e.node(l);
|
|
1097
|
+
u.in -= d, J(n, t, u);
|
|
1098
|
+
}), e.removeNode(r.v), s;
|
|
1099
|
+
}
|
|
1100
|
+
function Yn(e, n) {
|
|
1101
|
+
let t = new p(), r = 0, o = 0;
|
|
1102
|
+
e.nodes().forEach((a) => {
|
|
1103
|
+
t.setNode(a, { v: a, in: 0, out: 0 });
|
|
1104
|
+
}), e.edges().forEach((a) => {
|
|
1105
|
+
let d = t.edge(a.v, a.w) || 0, l = n(a), u = d + l;
|
|
1106
|
+
t.setEdge(a.v, a.w, u);
|
|
1107
|
+
let c = t.node(a.v), h = t.node(a.w);
|
|
1108
|
+
o = Math.max(o, c.out += l), r = Math.max(r, h.in += l);
|
|
1109
|
+
});
|
|
1110
|
+
let i = zn(o + r + 3).map(() => new Me()), s = r + 1;
|
|
1111
|
+
return t.nodes().forEach((a) => {
|
|
1112
|
+
J(i, s, t.node(a));
|
|
1113
|
+
}), { graph: t, buckets: i, zeroIdx: s };
|
|
1114
|
+
}
|
|
1115
|
+
function J(e, n, t) {
|
|
1116
|
+
var r, o, i;
|
|
1117
|
+
t.out ? t.in ? (i = e[t.out - t.in + n]) == null || i.enqueue(t) : (o = e[e.length - 1]) == null || o.enqueue(t) : (r = e[0]) == null || r.enqueue(t);
|
|
1118
|
+
}
|
|
1119
|
+
function zn(e) {
|
|
1120
|
+
let n = [];
|
|
1121
|
+
for (let t = 0; t < e; t++) n.push(t);
|
|
1122
|
+
return n;
|
|
1123
|
+
}
|
|
1124
|
+
function je(e) {
|
|
1125
|
+
(e.graph().acyclicer === "greedy" ? Q(e, t(e)) : Hn(e)).forEach((r) => {
|
|
1126
|
+
let o = e.edge(r);
|
|
1127
|
+
e.removeEdge(r), o.forwardName = r.name, o.reversed = true, e.setEdge(r.w, r.v, o, j("rev"));
|
|
1128
|
+
});
|
|
1129
|
+
function t(r) {
|
|
1130
|
+
return (o) => r.edge(o).weight;
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
function Hn(e) {
|
|
1134
|
+
let n = [], t = {}, r = {};
|
|
1135
|
+
function o(i) {
|
|
1136
|
+
Object.hasOwn(r, i) || (r[i] = true, t[i] = true, e.outEdges(i).forEach((s) => {
|
|
1137
|
+
Object.hasOwn(t, s.w) ? n.push(s) : o(s.w);
|
|
1138
|
+
}), delete t[i]);
|
|
1139
|
+
}
|
|
1140
|
+
return e.nodes().forEach(o), n;
|
|
1141
|
+
}
|
|
1142
|
+
function Se(e) {
|
|
1143
|
+
e.edges().forEach((n) => {
|
|
1144
|
+
let t = e.edge(n);
|
|
1145
|
+
if (t.reversed) {
|
|
1146
|
+
e.removeEdge(n);
|
|
1147
|
+
let r = t.forwardName;
|
|
1148
|
+
delete t.reversed, delete t.forwardName, e.setEdge(n.w, n.v, t, r);
|
|
1149
|
+
}
|
|
1150
|
+
});
|
|
1151
|
+
}
|
|
1152
|
+
function Fe(e) {
|
|
1153
|
+
e.graph().dummyChains = [], e.edges().forEach((n) => Xn(e, n));
|
|
1154
|
+
}
|
|
1155
|
+
function Xn(e, n) {
|
|
1156
|
+
let t = n.v, r = e.node(t).rank, o = n.w, i = e.node(o).rank, s = n.name, a = e.edge(n), d = a.labelRank;
|
|
1157
|
+
if (i === r + 1) return;
|
|
1158
|
+
e.removeEdge(n);
|
|
1159
|
+
let l, u, c;
|
|
1160
|
+
for (c = 0, ++r; r < i; ++c, ++r) a.points = [], u = { width: 0, height: 0, edgeLabel: a, edgeObj: n, rank: r }, l = w(e, "edge", u, "_d"), r === d && (u.width = a.width, u.height = a.height, u.dummy = "edge-label", u.labelpos = a.labelpos), e.setEdge(t, l, { weight: a.weight }, s), c === 0 && e.graph().dummyChains.push(l), t = l;
|
|
1161
|
+
e.setEdge(t, o, { weight: a.weight }, s);
|
|
1162
|
+
}
|
|
1163
|
+
function De(e) {
|
|
1164
|
+
e.graph().dummyChains.forEach((n) => {
|
|
1165
|
+
let t = e.node(n), r = t.edgeLabel, o;
|
|
1166
|
+
for (e.setEdge(t.edgeObj, r); t.dummy; ) o = e.successors(n)[0], e.removeNode(n), r.points.push({ x: t.x, y: t.y }), t.dummy === "edge-label" && (r.x = t.x, r.y = t.y, r.width = t.width, r.height = t.height), n = o, t = e.node(n);
|
|
1167
|
+
});
|
|
1168
|
+
}
|
|
1169
|
+
function S(e) {
|
|
1170
|
+
let n = {};
|
|
1171
|
+
function t(r) {
|
|
1172
|
+
let o = e.node(r);
|
|
1173
|
+
if (Object.hasOwn(n, r)) return o.rank;
|
|
1174
|
+
n[r] = true;
|
|
1175
|
+
let i = e.outEdges(r), s = i ? i.map((d) => d == null ? Number.POSITIVE_INFINITY : t(d.w) - e.edge(d).minlen) : [], a = L(Math.min, s);
|
|
1176
|
+
return a === Number.POSITIVE_INFINITY && (a = 0), o.rank = a;
|
|
1177
|
+
}
|
|
1178
|
+
e.sources().forEach(t);
|
|
1179
|
+
}
|
|
1180
|
+
function v(e, n) {
|
|
1181
|
+
return e.node(n.w).rank - e.node(n.v).rank - e.edge(n).minlen;
|
|
1182
|
+
}
|
|
1183
|
+
var V = Kn;
|
|
1184
|
+
function Kn(e) {
|
|
1185
|
+
let n = new p({ directed: false }), t = e.nodes();
|
|
1186
|
+
if (t.length === 0) throw new Error("Graph must have at least one node");
|
|
1187
|
+
let r = t[0], o = e.nodeCount();
|
|
1188
|
+
n.setNode(r, {});
|
|
1189
|
+
let i, s;
|
|
1190
|
+
for (; $n(n, e) < o && (i = Jn(n, e), !!i); ) s = n.hasNode(i.v) ? v(e, i) : -v(e, i), Qn(n, e, s);
|
|
1191
|
+
return n;
|
|
1192
|
+
}
|
|
1193
|
+
function $n(e, n) {
|
|
1194
|
+
function t(r) {
|
|
1195
|
+
let o = n.nodeEdges(r);
|
|
1196
|
+
o && o.forEach((i) => {
|
|
1197
|
+
let s = i.v, a = r === s ? i.w : s;
|
|
1198
|
+
!e.hasNode(a) && !v(n, i) && (e.setNode(a, {}), e.setEdge(r, a, {}), t(a));
|
|
1199
|
+
});
|
|
1200
|
+
}
|
|
1201
|
+
return e.nodes().forEach(t), e.nodeCount();
|
|
1202
|
+
}
|
|
1203
|
+
function Jn(e, n) {
|
|
1204
|
+
return n.edges().reduce((r, o) => {
|
|
1205
|
+
let i = Number.POSITIVE_INFINITY;
|
|
1206
|
+
return e.hasNode(o.v) !== e.hasNode(o.w) && (i = v(n, o)), i < r[0] ? [i, o] : r;
|
|
1207
|
+
}, [Number.POSITIVE_INFINITY, null])[1];
|
|
1208
|
+
}
|
|
1209
|
+
function Qn(e, n, t) {
|
|
1210
|
+
e.nodes().forEach((r) => n.node(r).rank += t);
|
|
1211
|
+
}
|
|
1212
|
+
var { preorder: Zn, postorder: et } = R;
|
|
1213
|
+
var Ve = x;
|
|
1214
|
+
x.initLowLimValues = ee;
|
|
1215
|
+
x.initCutValues = Z;
|
|
1216
|
+
x.calcCutValue = We;
|
|
1217
|
+
x.leaveEdge = Ye;
|
|
1218
|
+
x.enterEdge = ze;
|
|
1219
|
+
x.exchangeEdges = He;
|
|
1220
|
+
function x(e) {
|
|
1221
|
+
e = xe(e), S(e);
|
|
1222
|
+
let n = V(e);
|
|
1223
|
+
ee(n), Z(n, e);
|
|
1224
|
+
let t, r;
|
|
1225
|
+
for (; t = Ye(n); ) r = ze(n, e, t), He(n, e, t, r);
|
|
1226
|
+
}
|
|
1227
|
+
function Z(e, n) {
|
|
1228
|
+
let t = et(e, e.nodes());
|
|
1229
|
+
t = t.slice(0, t.length - 1), t.forEach((r) => nt(e, n, r));
|
|
1230
|
+
}
|
|
1231
|
+
function nt(e, n, t) {
|
|
1232
|
+
let o = e.node(t).parent, i = e.edge(t, o);
|
|
1233
|
+
i.cutvalue = We(e, n, t);
|
|
1234
|
+
}
|
|
1235
|
+
function We(e, n, t) {
|
|
1236
|
+
let o = e.node(t).parent, i = true, s = n.edge(t, o), a = 0;
|
|
1237
|
+
s || (i = false, s = n.edge(o, t)), a = s.weight;
|
|
1238
|
+
let d = n.nodeEdges(t);
|
|
1239
|
+
return d && d.forEach((l) => {
|
|
1240
|
+
let u = l.v === t, c = u ? l.w : l.v;
|
|
1241
|
+
if (c !== o) {
|
|
1242
|
+
let h = u === i, f = n.edge(l).weight;
|
|
1243
|
+
if (a += h ? f : -f, rt(e, t, c)) {
|
|
1244
|
+
let b = e.edge(t, c).cutvalue;
|
|
1245
|
+
a += h ? -b : b;
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
}), a;
|
|
1249
|
+
}
|
|
1250
|
+
function ee(e, n) {
|
|
1251
|
+
arguments.length < 2 && (n = e.nodes()[0]), Be(e, {}, 1, n);
|
|
1252
|
+
}
|
|
1253
|
+
function Be(e, n, t, r, o) {
|
|
1254
|
+
let i = t, s = e.node(r);
|
|
1255
|
+
n[r] = true;
|
|
1256
|
+
let a = e.neighbors(r);
|
|
1257
|
+
return a && a.forEach((d) => {
|
|
1258
|
+
Object.hasOwn(n, d) || (t = Be(e, n, t, d, r));
|
|
1259
|
+
}), s.low = i, s.lim = t++, o ? s.parent = o : delete s.parent, t;
|
|
1260
|
+
}
|
|
1261
|
+
function Ye(e) {
|
|
1262
|
+
return e.edges().find((n) => e.edge(n).cutvalue < 0);
|
|
1263
|
+
}
|
|
1264
|
+
function ze(e, n, t) {
|
|
1265
|
+
let r = t.v, o = t.w;
|
|
1266
|
+
n.hasEdge(r, o) || (r = t.w, o = t.v);
|
|
1267
|
+
let i = e.node(r), s = e.node(o), a = i, d = false;
|
|
1268
|
+
return i.lim > s.lim && (a = s, d = true), n.edges().filter((u) => d === Ae(e, e.node(u.v), a) && d !== Ae(e, e.node(u.w), a)).reduce((u, c) => v(n, c) < v(n, u) ? c : u);
|
|
1269
|
+
}
|
|
1270
|
+
function He(e, n, t, r) {
|
|
1271
|
+
let o = t.v, i = t.w;
|
|
1272
|
+
e.removeEdge(o, i), e.setEdge(r.v, r.w, {}), ee(e), Z(e, n), tt(e, n);
|
|
1273
|
+
}
|
|
1274
|
+
function tt(e, n) {
|
|
1275
|
+
let t = e.nodes().find((o) => !e.node(o).parent);
|
|
1276
|
+
if (!t) return;
|
|
1277
|
+
let r = Zn(e, [t]);
|
|
1278
|
+
r = r.slice(1), r.forEach((o) => {
|
|
1279
|
+
let s = e.node(o).parent, a = n.edge(o, s), d = false;
|
|
1280
|
+
a || (a = n.edge(s, o), d = true), n.node(o).rank = n.node(s).rank + (d ? a.minlen : -a.minlen);
|
|
1281
|
+
});
|
|
1282
|
+
}
|
|
1283
|
+
function rt(e, n, t) {
|
|
1284
|
+
return e.hasEdge(n, t);
|
|
1285
|
+
}
|
|
1286
|
+
function Ae(e, n, t) {
|
|
1287
|
+
return t.low <= n.lim && n.lim <= t.lim;
|
|
1288
|
+
}
|
|
1289
|
+
var Xe = ot;
|
|
1290
|
+
function ot(e) {
|
|
1291
|
+
let n = e.graph().ranker;
|
|
1292
|
+
if (typeof n == "function") return n(e);
|
|
1293
|
+
switch (n) {
|
|
1294
|
+
case "network-simplex":
|
|
1295
|
+
qe(e);
|
|
1296
|
+
break;
|
|
1297
|
+
case "tight-tree":
|
|
1298
|
+
st(e);
|
|
1299
|
+
break;
|
|
1300
|
+
case "longest-path":
|
|
1301
|
+
it(e);
|
|
1302
|
+
break;
|
|
1303
|
+
case "none":
|
|
1304
|
+
break;
|
|
1305
|
+
default:
|
|
1306
|
+
qe(e);
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
var it = S;
|
|
1310
|
+
function st(e) {
|
|
1311
|
+
S(e), V(e);
|
|
1312
|
+
}
|
|
1313
|
+
function qe(e) {
|
|
1314
|
+
Ve(e);
|
|
1315
|
+
}
|
|
1316
|
+
var Ue = at;
|
|
1317
|
+
function at(e) {
|
|
1318
|
+
let n = lt(e);
|
|
1319
|
+
e.graph().dummyChains.forEach((t) => {
|
|
1320
|
+
let r = e.node(t), o = r.edgeObj, i = dt(e, n, o.v, o.w), s = i.path, a = i.lca, d = 0, l = s[d], u = true;
|
|
1321
|
+
for (; t !== o.w; ) {
|
|
1322
|
+
if (r = e.node(t), u) {
|
|
1323
|
+
for (; (l = s[d]) !== a && e.node(l).maxRank < r.rank; ) d++;
|
|
1324
|
+
l === a && (u = false);
|
|
1325
|
+
}
|
|
1326
|
+
if (!u) {
|
|
1327
|
+
for (; d < s.length - 1 && e.node(s[d + 1]).minRank <= r.rank; ) d++;
|
|
1328
|
+
l = s[d];
|
|
1329
|
+
}
|
|
1330
|
+
l !== void 0 && e.setParent(t, l), t = e.successors(t)[0];
|
|
1331
|
+
}
|
|
1332
|
+
});
|
|
1333
|
+
}
|
|
1334
|
+
function dt(e, n, t, r) {
|
|
1335
|
+
let o = [], i = [], s = Math.min(n[t].low, n[r].low), a = Math.max(n[t].lim, n[r].lim), d;
|
|
1336
|
+
d = t;
|
|
1337
|
+
do
|
|
1338
|
+
d = e.parent(d), o.push(d);
|
|
1339
|
+
while (d && (n[d].low > s || a > n[d].lim));
|
|
1340
|
+
let l = d, u = r;
|
|
1341
|
+
for (; (u = e.parent(u)) !== l; ) i.push(u);
|
|
1342
|
+
return { path: o.concat(i.reverse()), lca: l };
|
|
1343
|
+
}
|
|
1344
|
+
function lt(e) {
|
|
1345
|
+
let n = {}, t = 0;
|
|
1346
|
+
function r(o) {
|
|
1347
|
+
let i = t;
|
|
1348
|
+
e.children(o).forEach(r), n[o] = { low: i, lim: t++ };
|
|
1349
|
+
}
|
|
1350
|
+
return e.children(_).forEach(r), n;
|
|
1351
|
+
}
|
|
1352
|
+
function Ke(e) {
|
|
1353
|
+
let n = w(e, "root", {}, "_root"), t = ut(e), r = Object.values(t), o = L(Math.max, r) - 1, i = 2 * o + 1;
|
|
1354
|
+
e.graph().nestingRoot = n, e.edges().forEach((a) => e.edge(a).minlen *= i);
|
|
1355
|
+
let s = ct(e) + 1;
|
|
1356
|
+
e.children(_).forEach((a) => $e(e, n, i, s, o, t, a)), e.graph().nodeRankFactor = i;
|
|
1357
|
+
}
|
|
1358
|
+
function $e(e, n, t, r, o, i, s) {
|
|
1359
|
+
var c;
|
|
1360
|
+
let a = e.children(s);
|
|
1361
|
+
if (!a.length) {
|
|
1362
|
+
s !== n && e.setEdge(n, s, { weight: 0, minlen: t });
|
|
1363
|
+
return;
|
|
1364
|
+
}
|
|
1365
|
+
let d = q(e, "_bt"), l = q(e, "_bb"), u = e.node(s);
|
|
1366
|
+
e.setParent(d, s), u.borderTop = d, e.setParent(l, s), u.borderBottom = l, a.forEach((h) => {
|
|
1367
|
+
var y;
|
|
1368
|
+
$e(e, n, t, r, o, i, h);
|
|
1369
|
+
let f = e.node(h), g = f.borderTop ? f.borderTop : h, b = f.borderBottom ? f.borderBottom : h, m = f.borderTop ? r : 2 * r, E = g !== b ? 1 : o - ((y = i[s]) != null ? y : 0) + 1;
|
|
1370
|
+
e.setEdge(d, g, { weight: m, minlen: E, nestingEdge: true }), e.setEdge(b, l, { weight: m, minlen: E, nestingEdge: true });
|
|
1371
|
+
}), e.parent(s) || e.setEdge(n, d, { weight: 0, minlen: o + ((c = i[s]) != null ? c : 0) });
|
|
1372
|
+
}
|
|
1373
|
+
function ut(e) {
|
|
1374
|
+
let n = {};
|
|
1375
|
+
function t(r, o) {
|
|
1376
|
+
let i = e.children(r);
|
|
1377
|
+
i && i.length && i.forEach((s) => t(s, o + 1)), n[r] = o;
|
|
1378
|
+
}
|
|
1379
|
+
return e.children(_).forEach((r) => t(r, 1)), n;
|
|
1380
|
+
}
|
|
1381
|
+
function ct(e) {
|
|
1382
|
+
return e.edges().reduce((n, t) => n + e.edge(t).weight, 0);
|
|
1383
|
+
}
|
|
1384
|
+
function Je(e) {
|
|
1385
|
+
let n = e.graph();
|
|
1386
|
+
e.removeNode(n.nestingRoot), delete n.nestingRoot, e.edges().forEach((t) => {
|
|
1387
|
+
e.edge(t).nestingEdge && e.removeEdge(t);
|
|
1388
|
+
});
|
|
1389
|
+
}
|
|
1390
|
+
var Ze = ft;
|
|
1391
|
+
function ft(e) {
|
|
1392
|
+
function n(t) {
|
|
1393
|
+
let r = e.children(t), o = e.node(t);
|
|
1394
|
+
if (r.length && r.forEach(n), Object.hasOwn(o, "minRank")) {
|
|
1395
|
+
o.borderLeft = [], o.borderRight = [];
|
|
1396
|
+
for (let i = o.minRank, s = o.maxRank + 1; i < s; ++i) Qe(e, "borderLeft", "_bl", t, o, i), Qe(e, "borderRight", "_br", t, o, i);
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
e.children(_).forEach(n);
|
|
1400
|
+
}
|
|
1401
|
+
function Qe(e, n, t, r, o, i) {
|
|
1402
|
+
let s = { width: 0, height: 0, rank: i, borderType: n }, a = o[n][i - 1], d = w(e, "border", s, t);
|
|
1403
|
+
o[n][i] = d, e.setParent(d, r), a && e.setEdge(a, d, { weight: 1 });
|
|
1404
|
+
}
|
|
1405
|
+
function nn(e) {
|
|
1406
|
+
var t;
|
|
1407
|
+
let n = (t = e.graph().rankdir) == null ? void 0 : t.toLowerCase();
|
|
1408
|
+
(n === "lr" || n === "rl") && rn(e);
|
|
1409
|
+
}
|
|
1410
|
+
function tn(e) {
|
|
1411
|
+
var t;
|
|
1412
|
+
let n = (t = e.graph().rankdir) == null ? void 0 : t.toLowerCase();
|
|
1413
|
+
(n === "bt" || n === "rl") && bt(e), (n === "lr" || n === "rl") && (gt(e), rn(e));
|
|
1414
|
+
}
|
|
1415
|
+
function rn(e) {
|
|
1416
|
+
e.nodes().forEach((n) => en(e.node(n))), e.edges().forEach((n) => en(e.edge(n)));
|
|
1417
|
+
}
|
|
1418
|
+
function en(e) {
|
|
1419
|
+
let n = e.width;
|
|
1420
|
+
e.width = e.height, e.height = n;
|
|
1421
|
+
}
|
|
1422
|
+
function bt(e) {
|
|
1423
|
+
e.nodes().forEach((n) => ne(e.node(n))), e.edges().forEach((n) => {
|
|
1424
|
+
var r;
|
|
1425
|
+
let t = e.edge(n);
|
|
1426
|
+
(r = t.points) == null || r.forEach(ne), Object.hasOwn(t, "y") && ne(t);
|
|
1427
|
+
});
|
|
1428
|
+
}
|
|
1429
|
+
function ne(e) {
|
|
1430
|
+
e.y = -e.y;
|
|
1431
|
+
}
|
|
1432
|
+
function gt(e) {
|
|
1433
|
+
e.nodes().forEach((n) => te(e.node(n))), e.edges().forEach((n) => {
|
|
1434
|
+
var r;
|
|
1435
|
+
let t = e.edge(n);
|
|
1436
|
+
(r = t.points) == null || r.forEach(te), Object.hasOwn(t, "x") && te(t);
|
|
1437
|
+
});
|
|
1438
|
+
}
|
|
1439
|
+
function te(e) {
|
|
1440
|
+
let n = e.x;
|
|
1441
|
+
e.x = e.y, e.y = n;
|
|
1442
|
+
}
|
|
1443
|
+
function re(e) {
|
|
1444
|
+
let n = {}, t = e.nodes().filter((d) => !e.children(d).length), r = t.map((d) => e.node(d).rank), o = L(Math.max, r), i = k(o + 1).map(() => []);
|
|
1445
|
+
function s(d) {
|
|
1446
|
+
if (n[d]) return;
|
|
1447
|
+
n[d] = true;
|
|
1448
|
+
let l = e.node(d);
|
|
1449
|
+
i[l.rank].push(d);
|
|
1450
|
+
let u = e.successors(d);
|
|
1451
|
+
u && u.forEach(s);
|
|
1452
|
+
}
|
|
1453
|
+
return t.sort((d, l) => e.node(d).rank - e.node(l).rank).forEach(s), i;
|
|
1454
|
+
}
|
|
1455
|
+
function oe(e, n) {
|
|
1456
|
+
let t = 0;
|
|
1457
|
+
for (let r = 1; r < n.length; ++r) t += mt(e, n[r - 1], n[r]);
|
|
1458
|
+
return t;
|
|
1459
|
+
}
|
|
1460
|
+
function mt(e, n, t) {
|
|
1461
|
+
let r = Re(t, t.map((l, u) => u)), o = n.flatMap((l) => {
|
|
1462
|
+
let u = e.outEdges(l);
|
|
1463
|
+
return u ? u.map((c) => ({ pos: r[c.w], weight: e.edge(c).weight })).sort((c, h) => c.pos - h.pos) : [];
|
|
1464
|
+
}), i = 1;
|
|
1465
|
+
for (; i < t.length; ) i <<= 1;
|
|
1466
|
+
let s = 2 * i - 1;
|
|
1467
|
+
i -= 1;
|
|
1468
|
+
let a = new Array(s).fill(0), d = 0;
|
|
1469
|
+
return o.forEach((l) => {
|
|
1470
|
+
let u = l.pos + i;
|
|
1471
|
+
a[u] += l.weight;
|
|
1472
|
+
let c = 0;
|
|
1473
|
+
for (; u > 0; ) u % 2 && (c += a[u + 1]), u = u - 1 >> 1, a[u] += l.weight;
|
|
1474
|
+
d += l.weight * c;
|
|
1475
|
+
}), d;
|
|
1476
|
+
}
|
|
1477
|
+
function ie(e, n = []) {
|
|
1478
|
+
return n.map((t) => {
|
|
1479
|
+
let r = e.inEdges(t);
|
|
1480
|
+
if (!r || !r.length) return { v: t };
|
|
1481
|
+
{
|
|
1482
|
+
let o = r.reduce((i, s) => {
|
|
1483
|
+
let a = e.edge(s), d = e.node(s.v);
|
|
1484
|
+
return { sum: i.sum + a.weight * d.order, weight: i.weight + a.weight };
|
|
1485
|
+
}, { sum: 0, weight: 0 });
|
|
1486
|
+
return { v: t, barycenter: o.sum / o.weight, weight: o.weight };
|
|
1487
|
+
}
|
|
1488
|
+
});
|
|
1489
|
+
}
|
|
1490
|
+
function se(e, n) {
|
|
1491
|
+
let t = {};
|
|
1492
|
+
e.forEach((o, i) => {
|
|
1493
|
+
let s = { indegree: 0, in: [], out: [], vs: [o.v], i };
|
|
1494
|
+
o.barycenter !== void 0 && (s.barycenter = o.barycenter, s.weight = o.weight), t[o.v] = s;
|
|
1495
|
+
}), n.edges().forEach((o) => {
|
|
1496
|
+
let i = t[o.v], s = t[o.w];
|
|
1497
|
+
i !== void 0 && s !== void 0 && (s.indegree++, i.out.push(s));
|
|
1498
|
+
});
|
|
1499
|
+
let r = Object.values(t).filter((o) => !o.indegree);
|
|
1500
|
+
return Et(r);
|
|
1501
|
+
}
|
|
1502
|
+
function Et(e) {
|
|
1503
|
+
let n = [];
|
|
1504
|
+
function t(o) {
|
|
1505
|
+
return (i) => {
|
|
1506
|
+
i.merged || (i.barycenter === void 0 || o.barycenter === void 0 || i.barycenter >= o.barycenter) && Lt(o, i);
|
|
1507
|
+
};
|
|
1508
|
+
}
|
|
1509
|
+
function r(o) {
|
|
1510
|
+
return (i) => {
|
|
1511
|
+
i.in.push(o), --i.indegree === 0 && e.push(i);
|
|
1512
|
+
};
|
|
1513
|
+
}
|
|
1514
|
+
for (; e.length; ) {
|
|
1515
|
+
let o = e.pop();
|
|
1516
|
+
n.push(o), o.in.reverse().forEach(t(o)), o.out.forEach(r(o));
|
|
1517
|
+
}
|
|
1518
|
+
return n.filter((o) => !o.merged).map((o) => T(o, ["vs", "i", "barycenter", "weight"]));
|
|
1519
|
+
}
|
|
1520
|
+
function Lt(e, n) {
|
|
1521
|
+
let t = 0, r = 0;
|
|
1522
|
+
e.weight && (t += e.barycenter * e.weight, r += e.weight), n.weight && (t += n.barycenter * n.weight, r += n.weight), e.vs = n.vs.concat(e.vs), e.barycenter = t / r, e.weight = r, e.i = Math.min(n.i, e.i), n.merged = true;
|
|
1523
|
+
}
|
|
1524
|
+
function ae(e, n) {
|
|
1525
|
+
let t = Ce(e, (u) => Object.hasOwn(u, "barycenter")), r = t.lhs, o = t.rhs.sort((u, c) => c.i - u.i), i = [], s = 0, a = 0, d = 0;
|
|
1526
|
+
r.sort(yt(!!n)), d = on(i, o, d), r.forEach((u) => {
|
|
1527
|
+
d += u.vs.length, i.push(u.vs), s += u.barycenter * u.weight, a += u.weight, d = on(i, o, d);
|
|
1528
|
+
});
|
|
1529
|
+
let l = { vs: i.flat(1) };
|
|
1530
|
+
return a && (l.barycenter = s / a, l.weight = a), l;
|
|
1531
|
+
}
|
|
1532
|
+
function on(e, n, t) {
|
|
1533
|
+
let r;
|
|
1534
|
+
for (; n.length && (r = n[n.length - 1]).i <= t; ) n.pop(), e.push(r.vs), t++;
|
|
1535
|
+
return t;
|
|
1536
|
+
}
|
|
1537
|
+
function yt(e) {
|
|
1538
|
+
return (n, t) => n.barycenter < t.barycenter ? -1 : n.barycenter > t.barycenter ? 1 : e ? t.i - n.i : n.i - t.i;
|
|
1539
|
+
}
|
|
1540
|
+
function W(e, n, t, r) {
|
|
1541
|
+
let o = e.children(n), i = e.node(n), s = i ? i.borderLeft : void 0, a = i ? i.borderRight : void 0, d = {};
|
|
1542
|
+
s && (o = o.filter((h) => h !== s && h !== a));
|
|
1543
|
+
let l = ie(e, o);
|
|
1544
|
+
l.forEach((h) => {
|
|
1545
|
+
if (e.children(h.v).length) {
|
|
1546
|
+
let f = W(e, h.v, t, r);
|
|
1547
|
+
d[h.v] = f, Object.hasOwn(f, "barycenter") && Nt(h, f);
|
|
1548
|
+
}
|
|
1549
|
+
});
|
|
1550
|
+
let u = se(l, t);
|
|
1551
|
+
wt(u, d);
|
|
1552
|
+
let c = ae(u, r);
|
|
1553
|
+
if (s && a) {
|
|
1554
|
+
c.vs = [s, c.vs, a].flat(1);
|
|
1555
|
+
let h = e.predecessors(s);
|
|
1556
|
+
if (h && h.length) {
|
|
1557
|
+
let f = e.node(h[0]), g = e.predecessors(a), b = e.node(g[0]);
|
|
1558
|
+
Object.hasOwn(c, "barycenter") || (c.barycenter = 0, c.weight = 0), c.barycenter = (c.barycenter * c.weight + f.order + b.order) / (c.weight + 2), c.weight += 2;
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
return c;
|
|
1562
|
+
}
|
|
1563
|
+
function wt(e, n) {
|
|
1564
|
+
e.forEach((t) => {
|
|
1565
|
+
t.vs = t.vs.flatMap((r) => n[r] ? n[r].vs : r);
|
|
1566
|
+
});
|
|
1567
|
+
}
|
|
1568
|
+
function Nt(e, n) {
|
|
1569
|
+
e.barycenter !== void 0 ? (e.barycenter = (e.barycenter * e.weight + n.barycenter * n.weight) / (e.weight + n.weight), e.weight += n.weight) : (e.barycenter = n.barycenter, e.weight = n.weight);
|
|
1570
|
+
}
|
|
1571
|
+
function de(e, n, t, r) {
|
|
1572
|
+
r || (r = e.nodes());
|
|
1573
|
+
let o = Gt(e), i = new p({ compound: true }).setGraph({ root: o }).setDefaultNodeLabel((s) => e.node(s));
|
|
1574
|
+
return r.forEach((s) => {
|
|
1575
|
+
let a = e.node(s), d = e.parent(s);
|
|
1576
|
+
if (a.rank === n || a.minRank <= n && n <= a.maxRank) {
|
|
1577
|
+
i.setNode(s), i.setParent(s, d || o);
|
|
1578
|
+
let l = e[t](s);
|
|
1579
|
+
l && l.forEach((u) => {
|
|
1580
|
+
let c = u.v === s ? u.w : u.v, h = i.edge(c, s), f = h !== void 0 ? h.weight : 0;
|
|
1581
|
+
i.setEdge(c, s, { weight: e.edge(u).weight + f });
|
|
1582
|
+
}), Object.hasOwn(a, "minRank") && i.setNode(s, { borderLeft: a.borderLeft[n], borderRight: a.borderRight[n] });
|
|
1583
|
+
}
|
|
1584
|
+
}), i;
|
|
1585
|
+
}
|
|
1586
|
+
function Gt(e) {
|
|
1587
|
+
let n;
|
|
1588
|
+
for (; e.hasNode(n = j("_root")); ) ;
|
|
1589
|
+
return n;
|
|
1590
|
+
}
|
|
1591
|
+
function le(e, n, t) {
|
|
1592
|
+
let r = {}, o;
|
|
1593
|
+
t.forEach((i) => {
|
|
1594
|
+
let s = e.parent(i), a, d;
|
|
1595
|
+
for (; s; ) {
|
|
1596
|
+
if (a = e.parent(s), a ? (d = r[a], r[a] = s) : (d = o, o = s), d && d !== s) {
|
|
1597
|
+
n.setEdge(d, s);
|
|
1598
|
+
return;
|
|
1599
|
+
}
|
|
1600
|
+
s = a;
|
|
1601
|
+
}
|
|
1602
|
+
});
|
|
1603
|
+
}
|
|
1604
|
+
function B(e, n = {}) {
|
|
1605
|
+
if (typeof n.customOrder == "function") {
|
|
1606
|
+
n.customOrder(e, B);
|
|
1607
|
+
return;
|
|
1608
|
+
}
|
|
1609
|
+
let t = X(e), r = sn(e, k(1, t + 1), "inEdges"), o = sn(e, k(t - 1, -1, -1), "outEdges"), i = re(e);
|
|
1610
|
+
if (an(e, i), n.disableOptimalOrderHeuristic) return;
|
|
1611
|
+
let s = Number.POSITIVE_INFINITY, a, d = n.constraints || [];
|
|
1612
|
+
for (let l = 0, u = 0; u < 4; ++l, ++u) {
|
|
1613
|
+
kt(l % 2 ? r : o, l % 4 >= 2, d), i = N(e);
|
|
1614
|
+
let c = oe(e, i);
|
|
1615
|
+
c < s ? (u = 0, a = Object.assign({}, i), s = c) : c === s && (a = structuredClone(i));
|
|
1616
|
+
}
|
|
1617
|
+
an(e, a);
|
|
1618
|
+
}
|
|
1619
|
+
function sn(e, n, t) {
|
|
1620
|
+
let r = /* @__PURE__ */ new Map(), o = (i, s) => {
|
|
1621
|
+
r.has(i) || r.set(i, []), r.get(i).push(s);
|
|
1622
|
+
};
|
|
1623
|
+
for (let i of e.nodes()) {
|
|
1624
|
+
let s = e.node(i);
|
|
1625
|
+
if (typeof s.rank == "number" && o(s.rank, i), typeof s.minRank == "number" && typeof s.maxRank == "number") for (let a = s.minRank; a <= s.maxRank; a++) a !== s.rank && o(a, i);
|
|
1626
|
+
}
|
|
1627
|
+
return n.map(function(i) {
|
|
1628
|
+
return de(e, i, t, r.get(i) || []);
|
|
1629
|
+
});
|
|
1630
|
+
}
|
|
1631
|
+
function kt(e, n, t) {
|
|
1632
|
+
let r = new p();
|
|
1633
|
+
e.forEach(function(o) {
|
|
1634
|
+
t.forEach((a) => r.setEdge(a.left, a.right));
|
|
1635
|
+
let i = o.graph().root, s = W(o, i, r, n);
|
|
1636
|
+
s.vs.forEach((a, d) => o.node(a).order = d), le(o, r, s.vs);
|
|
1637
|
+
});
|
|
1638
|
+
}
|
|
1639
|
+
function an(e, n) {
|
|
1640
|
+
Object.values(n).forEach((t) => t.forEach((r, o) => e.node(r).order = o));
|
|
1641
|
+
}
|
|
1642
|
+
function vt(e, n) {
|
|
1643
|
+
let t = {};
|
|
1644
|
+
function r(o, i) {
|
|
1645
|
+
let s = 0, a = 0, d = o.length, l = i[i.length - 1];
|
|
1646
|
+
return i.forEach((u, c) => {
|
|
1647
|
+
let h = xt(e, u), f = h ? e.node(h).order : d;
|
|
1648
|
+
(h || u === l) && (i.slice(a, c + 1).forEach((g) => {
|
|
1649
|
+
let b = e.predecessors(g);
|
|
1650
|
+
b && b.forEach((m) => {
|
|
1651
|
+
let E = e.node(m), y = E.order;
|
|
1652
|
+
(y < s || f < y) && !(E.dummy && e.node(g).dummy) && dn(t, m, g);
|
|
1653
|
+
});
|
|
1654
|
+
}), a = c + 1, s = f);
|
|
1655
|
+
}), i;
|
|
1656
|
+
}
|
|
1657
|
+
return n.length && n.reduce(r), t;
|
|
1658
|
+
}
|
|
1659
|
+
function _t(e, n) {
|
|
1660
|
+
let t = {};
|
|
1661
|
+
function r(i, s, a, d, l) {
|
|
1662
|
+
k(s, a).forEach((u) => {
|
|
1663
|
+
let c = i[u];
|
|
1664
|
+
if (c !== void 0 && e.node(c).dummy) {
|
|
1665
|
+
let h = e.predecessors(c);
|
|
1666
|
+
h && h.forEach((f) => {
|
|
1667
|
+
if (f === void 0) return;
|
|
1668
|
+
let g = e.node(f);
|
|
1669
|
+
g.dummy && (g.order < d || g.order > l) && dn(t, f, c);
|
|
1670
|
+
});
|
|
1671
|
+
}
|
|
1672
|
+
});
|
|
1673
|
+
}
|
|
1674
|
+
function o(i, s) {
|
|
1675
|
+
let a = -1, d = -1, l = 0;
|
|
1676
|
+
return s.forEach((u, c) => {
|
|
1677
|
+
if (e.node(u).dummy === "border") {
|
|
1678
|
+
let h = e.predecessors(u);
|
|
1679
|
+
if (h && h.length) {
|
|
1680
|
+
let f = h[0];
|
|
1681
|
+
if (f === void 0) return;
|
|
1682
|
+
d = e.node(f).order, r(s, l, c, a, d), l = c, a = d;
|
|
1683
|
+
}
|
|
1684
|
+
}
|
|
1685
|
+
r(s, l, s.length, d, i.length);
|
|
1686
|
+
}), s;
|
|
1687
|
+
}
|
|
1688
|
+
return n.length && n.reduce(o), t;
|
|
1689
|
+
}
|
|
1690
|
+
function xt(e, n) {
|
|
1691
|
+
if (e.node(n).dummy) {
|
|
1692
|
+
let t = e.predecessors(n);
|
|
1693
|
+
if (t) return t.find((r) => e.node(r).dummy);
|
|
1694
|
+
}
|
|
1695
|
+
}
|
|
1696
|
+
function dn(e, n, t) {
|
|
1697
|
+
if (n > t) {
|
|
1698
|
+
let o = n;
|
|
1699
|
+
n = t, t = o;
|
|
1700
|
+
}
|
|
1701
|
+
let r = e[n];
|
|
1702
|
+
r || (e[n] = r = {}), r[t] = true;
|
|
1703
|
+
}
|
|
1704
|
+
function Tt(e, n, t) {
|
|
1705
|
+
if (n > t) {
|
|
1706
|
+
let o = n;
|
|
1707
|
+
n = t, t = o;
|
|
1708
|
+
}
|
|
1709
|
+
let r = e[n];
|
|
1710
|
+
return r !== void 0 && Object.hasOwn(r, t);
|
|
1711
|
+
}
|
|
1712
|
+
function Ot(e, n, t, r) {
|
|
1713
|
+
let o = {}, i = {}, s = {};
|
|
1714
|
+
return n.forEach((a) => {
|
|
1715
|
+
a.forEach((d, l) => {
|
|
1716
|
+
o[d] = d, i[d] = d, s[d] = l;
|
|
1717
|
+
});
|
|
1718
|
+
}), n.forEach((a) => {
|
|
1719
|
+
let d = -1;
|
|
1720
|
+
a.forEach((l) => {
|
|
1721
|
+
let u = r(l);
|
|
1722
|
+
if (u && u.length) {
|
|
1723
|
+
let c = u.sort((f, g) => {
|
|
1724
|
+
let b = s[f], m = s[g];
|
|
1725
|
+
return (b !== void 0 ? b : 0) - (m !== void 0 ? m : 0);
|
|
1726
|
+
}), h = (c.length - 1) / 2;
|
|
1727
|
+
for (let f = Math.floor(h), g = Math.ceil(h); f <= g; ++f) {
|
|
1728
|
+
let b = c[f];
|
|
1729
|
+
if (b === void 0) continue;
|
|
1730
|
+
let m = s[b];
|
|
1731
|
+
if (m !== void 0 && i[l] === l && d < m && !Tt(t, l, b)) {
|
|
1732
|
+
let E = o[b];
|
|
1733
|
+
E !== void 0 && (i[b] = l, i[l] = o[l] = E, d = m);
|
|
1734
|
+
}
|
|
1735
|
+
}
|
|
1736
|
+
}
|
|
1737
|
+
});
|
|
1738
|
+
}), { root: o, align: i };
|
|
1739
|
+
}
|
|
1740
|
+
function It(e, n, t, r, o = false) {
|
|
1741
|
+
let i = {}, s = Ct(e, n, t, o), a = o ? "borderLeft" : "borderRight";
|
|
1742
|
+
function d(f, g) {
|
|
1743
|
+
let b = s.nodes().slice(), m = {}, E = b.pop();
|
|
1744
|
+
for (; E; ) {
|
|
1745
|
+
if (m[E]) f(E);
|
|
1746
|
+
else {
|
|
1747
|
+
m[E] = true, b.push(E);
|
|
1748
|
+
for (let y of g(E)) b.push(y);
|
|
1749
|
+
}
|
|
1750
|
+
E = b.pop();
|
|
1751
|
+
}
|
|
1752
|
+
}
|
|
1753
|
+
function l(f) {
|
|
1754
|
+
let g = s.inEdges(f);
|
|
1755
|
+
g ? i[f] = g.reduce((b, m) => {
|
|
1756
|
+
var I;
|
|
1757
|
+
let E = (I = i[m.v]) != null ? I : 0, y = s.edge(m);
|
|
1758
|
+
return Math.max(b, E + (y !== void 0 ? y : 0));
|
|
1759
|
+
}, 0) : i[f] = 0;
|
|
1760
|
+
}
|
|
1761
|
+
function u(f) {
|
|
1762
|
+
let g = s.outEdges(f), b = Number.POSITIVE_INFINITY;
|
|
1763
|
+
g && (b = g.reduce((E, y) => {
|
|
1764
|
+
let I = i[y.w], be = s.edge(y);
|
|
1765
|
+
return Math.min(E, (I !== void 0 ? I : 0) - (be !== void 0 ? be : 0));
|
|
1766
|
+
}, Number.POSITIVE_INFINITY));
|
|
1767
|
+
let m = e.node(f);
|
|
1768
|
+
b !== Number.POSITIVE_INFINITY && m.borderType !== a && (i[f] = Math.max(i[f] !== void 0 ? i[f] : 0, b));
|
|
1769
|
+
}
|
|
1770
|
+
function c(f) {
|
|
1771
|
+
return s.predecessors(f) || [];
|
|
1772
|
+
}
|
|
1773
|
+
function h(f) {
|
|
1774
|
+
return s.successors(f) || [];
|
|
1775
|
+
}
|
|
1776
|
+
return d(l, c), d(u, h), Object.keys(r).forEach((f) => {
|
|
1777
|
+
var b;
|
|
1778
|
+
let g = t[f];
|
|
1779
|
+
g !== void 0 && (i[f] = (b = i[g]) != null ? b : 0);
|
|
1780
|
+
}), i;
|
|
1781
|
+
}
|
|
1782
|
+
function Ct(e, n, t, r) {
|
|
1783
|
+
let o = new p(), i = e.graph(), s = jt(i.nodesep, i.edgesep, r);
|
|
1784
|
+
return n.forEach((a) => {
|
|
1785
|
+
let d;
|
|
1786
|
+
a.forEach((l) => {
|
|
1787
|
+
let u = t[l];
|
|
1788
|
+
if (u !== void 0) {
|
|
1789
|
+
if (o.setNode(u), d !== void 0) {
|
|
1790
|
+
let c = t[d];
|
|
1791
|
+
if (c !== void 0) {
|
|
1792
|
+
let h = o.edge(c, u);
|
|
1793
|
+
o.setEdge(c, u, Math.max(s(e, l, d), h || 0));
|
|
1794
|
+
}
|
|
1795
|
+
}
|
|
1796
|
+
d = l;
|
|
1797
|
+
}
|
|
1798
|
+
});
|
|
1799
|
+
}), o;
|
|
1800
|
+
}
|
|
1801
|
+
function Rt(e, n) {
|
|
1802
|
+
return Object.values(n).reduce((t, r) => {
|
|
1803
|
+
let o = Number.NEGATIVE_INFINITY, i = Number.POSITIVE_INFINITY;
|
|
1804
|
+
Object.entries(r).forEach(([a, d]) => {
|
|
1805
|
+
let l = St(e, a) / 2;
|
|
1806
|
+
o = Math.max(d + l, o), i = Math.min(d - l, i);
|
|
1807
|
+
});
|
|
1808
|
+
let s = o - i;
|
|
1809
|
+
return s < t[0] && (t = [s, r]), t;
|
|
1810
|
+
}, [Number.POSITIVE_INFINITY, null])[1];
|
|
1811
|
+
}
|
|
1812
|
+
function Pt(e, n) {
|
|
1813
|
+
let t = Object.values(n), r = L(Math.min, t), o = L(Math.max, t);
|
|
1814
|
+
["u", "d"].forEach((i) => {
|
|
1815
|
+
["l", "r"].forEach((s) => {
|
|
1816
|
+
let a = i + s, d = e[a];
|
|
1817
|
+
if (!d || d === n) return;
|
|
1818
|
+
let l = Object.values(d), u = r - L(Math.min, l);
|
|
1819
|
+
s !== "l" && (u = o - L(Math.max, l)), u && (e[a] = O(d, (c) => c + u));
|
|
1820
|
+
});
|
|
1821
|
+
});
|
|
1822
|
+
}
|
|
1823
|
+
function Mt(e, n = void 0) {
|
|
1824
|
+
let t = e.ul;
|
|
1825
|
+
return t ? O(t, (r, o) => {
|
|
1826
|
+
var s, a;
|
|
1827
|
+
if (n) {
|
|
1828
|
+
let d = n.toLowerCase(), l = e[d];
|
|
1829
|
+
if (l && l[o] !== void 0) return l[o];
|
|
1830
|
+
}
|
|
1831
|
+
let i = Object.values(e).map((d) => {
|
|
1832
|
+
let l = d[o];
|
|
1833
|
+
return l !== void 0 ? l : 0;
|
|
1834
|
+
}).sort((d, l) => d - l);
|
|
1835
|
+
return (((s = i[1]) != null ? s : 0) + ((a = i[2]) != null ? a : 0)) / 2;
|
|
1836
|
+
}) : {};
|
|
1837
|
+
}
|
|
1838
|
+
function ln(e) {
|
|
1839
|
+
let n = N(e), t = Object.assign(vt(e, n), _t(e, n)), r = {}, o;
|
|
1840
|
+
["u", "d"].forEach((s) => {
|
|
1841
|
+
o = s === "u" ? n : Object.values(n).reverse(), ["l", "r"].forEach((a) => {
|
|
1842
|
+
a === "r" && (o = o.map((c) => Object.values(c).reverse()));
|
|
1843
|
+
let l = Ot(e, o, t, (c) => (s === "u" ? e.predecessors(c) : e.successors(c)) || []), u = It(e, o, l.root, l.align, a === "r");
|
|
1844
|
+
a === "r" && (u = O(u, (c) => -c)), r[s + a] = u;
|
|
1845
|
+
});
|
|
1846
|
+
});
|
|
1847
|
+
let i = Rt(e, r);
|
|
1848
|
+
return Pt(r, i), Mt(r, e.graph().align);
|
|
1849
|
+
}
|
|
1850
|
+
function jt(e, n, t) {
|
|
1851
|
+
return (r, o, i) => {
|
|
1852
|
+
let s = r.node(o), a = r.node(i), d = 0, l;
|
|
1853
|
+
if (d += s.width / 2, Object.hasOwn(s, "labelpos")) switch (s.labelpos.toLowerCase()) {
|
|
1854
|
+
case "l":
|
|
1855
|
+
l = -s.width / 2;
|
|
1856
|
+
break;
|
|
1857
|
+
case "r":
|
|
1858
|
+
l = s.width / 2;
|
|
1859
|
+
break;
|
|
1860
|
+
}
|
|
1861
|
+
if (l && (d += t ? l : -l), l = void 0, d += (s.dummy ? n : e) / 2, d += (a.dummy ? n : e) / 2, d += a.width / 2, Object.hasOwn(a, "labelpos")) switch (a.labelpos.toLowerCase()) {
|
|
1862
|
+
case "l":
|
|
1863
|
+
l = a.width / 2;
|
|
1864
|
+
break;
|
|
1865
|
+
case "r":
|
|
1866
|
+
l = -a.width / 2;
|
|
1867
|
+
break;
|
|
1868
|
+
}
|
|
1869
|
+
return l && (d += t ? l : -l), d;
|
|
1870
|
+
};
|
|
1871
|
+
}
|
|
1872
|
+
function St(e, n) {
|
|
1873
|
+
return e.node(n).width;
|
|
1874
|
+
}
|
|
1875
|
+
function un(e) {
|
|
1876
|
+
e = A(e), Ft(e), Object.entries(ln(e)).forEach(([n, t]) => e.node(n).x = t);
|
|
1877
|
+
}
|
|
1878
|
+
function Ft(e) {
|
|
1879
|
+
let n = N(e), t = e.graph(), r = t.ranksep, o = t.rankalign, i = 0;
|
|
1880
|
+
n.forEach((s) => {
|
|
1881
|
+
let a = s.reduce((d, l) => {
|
|
1882
|
+
var c;
|
|
1883
|
+
let u = (c = e.node(l).height) != null ? c : 0;
|
|
1884
|
+
return d > u ? d : u;
|
|
1885
|
+
}, 0);
|
|
1886
|
+
s.forEach((d) => {
|
|
1887
|
+
let l = e.node(d);
|
|
1888
|
+
o === "top" ? l.y = i + l.height / 2 : o === "bottom" ? l.y = i + a - l.height / 2 : l.y = i + a / 2;
|
|
1889
|
+
}), i += a + r;
|
|
1890
|
+
});
|
|
1891
|
+
}
|
|
1892
|
+
function he(e, n = {}) {
|
|
1893
|
+
let t = n.debugTiming ? P : M;
|
|
1894
|
+
return t("layout", () => {
|
|
1895
|
+
let r = t(" buildLayoutGraph", () => Xt(e));
|
|
1896
|
+
return t(" runLayout", () => Dt(r, t, n)), t(" updateInputGraph", () => At(e, r)), r;
|
|
1897
|
+
});
|
|
1898
|
+
}
|
|
1899
|
+
function Dt(e, n, t) {
|
|
1900
|
+
n(" makeSpaceForEdgeLabels", () => Ut(e)), n(" removeSelfEdges", () => rr(e)), n(" acyclic", () => je(e)), n(" nestingGraph.run", () => Ke(e)), n(" rank", () => Xe(A(e))), n(" injectEdgeLabelProxies", () => Kt(e)), n(" removeEmptyRanks", () => Oe(e)), n(" nestingGraph.cleanup", () => Je(e)), n(" normalizeRanks", () => Te(e)), n(" assignRankMinMax", () => $t(e)), n(" removeEdgeLabelProxies", () => Jt(e)), n(" normalize.run", () => Fe(e)), n(" parentDummyChains", () => Ue(e)), n(" addBorderSegments", () => Ze(e)), n(" order", () => B(e, t)), n(" insertSelfEdges", () => or(e)), n(" adjustCoordinateSystem", () => nn(e)), n(" position", () => un(e)), n(" positionSelfEdges", () => ir(e)), n(" removeBorderNodes", () => tr(e)), n(" normalize.undo", () => De(e)), n(" fixupEdgeLabelCoords", () => er(e)), n(" undoCoordinateSystem", () => tn(e)), n(" translateGraph", () => Qt(e)), n(" assignNodeIntersects", () => Zt(e)), n(" reversePoints", () => nr(e)), n(" acyclic.undo", () => Se(e));
|
|
1901
|
+
}
|
|
1902
|
+
function At(e, n) {
|
|
1903
|
+
e.nodes().forEach((t) => {
|
|
1904
|
+
let r = e.node(t), o = n.node(t);
|
|
1905
|
+
r && (r.x = o.x, r.y = o.y, r.order = o.order, r.rank = o.rank, n.children(t).length && (r.width = o.width, r.height = o.height));
|
|
1906
|
+
}), e.edges().forEach((t) => {
|
|
1907
|
+
let r = e.edge(t), o = n.edge(t);
|
|
1908
|
+
r.points = o.points, Object.hasOwn(o, "x") && (r.x = o.x, r.y = o.y);
|
|
1909
|
+
}), e.graph().width = n.graph().width, e.graph().height = n.graph().height;
|
|
1910
|
+
}
|
|
1911
|
+
var Vt = ["nodesep", "edgesep", "ranksep", "marginx", "marginy"];
|
|
1912
|
+
var Wt = { ranksep: 50, edgesep: 20, nodesep: 50, rankdir: "TB", rankalign: "center" };
|
|
1913
|
+
var Bt = ["acyclicer", "ranker", "rankdir", "align", "rankalign"];
|
|
1914
|
+
var Yt = ["width", "height", "rank"];
|
|
1915
|
+
var cn = { width: 0, height: 0 };
|
|
1916
|
+
var zt = ["minlen", "weight", "width", "height", "labeloffset"];
|
|
1917
|
+
var Ht = { minlen: 1, weight: 1, width: 0, height: 0, labeloffset: 10, labelpos: "r" };
|
|
1918
|
+
var qt = ["labelpos"];
|
|
1919
|
+
function Xt(e) {
|
|
1920
|
+
let n = new p({ multigraph: true, compound: true }), t = ce(e.graph());
|
|
1921
|
+
return n.setGraph(Object.assign({}, Wt, ue(t, Vt), T(t, Bt))), e.nodes().forEach((r) => {
|
|
1922
|
+
let o = ce(e.node(r)), i = ue(o, Yt);
|
|
1923
|
+
Object.keys(cn).forEach((a) => {
|
|
1924
|
+
i[a] === void 0 && (i[a] = cn[a]);
|
|
1925
|
+
}), n.setNode(r, i);
|
|
1926
|
+
let s = e.parent(r);
|
|
1927
|
+
s !== void 0 && n.setParent(r, s);
|
|
1928
|
+
}), e.edges().forEach((r) => {
|
|
1929
|
+
let o = ce(e.edge(r));
|
|
1930
|
+
n.setEdge(r, Object.assign({}, Ht, ue(o, zt), T(o, qt)));
|
|
1931
|
+
}), n;
|
|
1932
|
+
}
|
|
1933
|
+
function Ut(e) {
|
|
1934
|
+
let n = e.graph();
|
|
1935
|
+
n.ranksep /= 2, e.edges().forEach((t) => {
|
|
1936
|
+
let r = e.edge(t);
|
|
1937
|
+
r.minlen *= 2, r.labelpos.toLowerCase() !== "c" && (n.rankdir === "TB" || n.rankdir === "BT" ? r.width += r.labeloffset : r.height += r.labeloffset);
|
|
1938
|
+
});
|
|
1939
|
+
}
|
|
1940
|
+
function Kt(e) {
|
|
1941
|
+
e.edges().forEach((n) => {
|
|
1942
|
+
let t = e.edge(n);
|
|
1943
|
+
if (t.width && t.height) {
|
|
1944
|
+
let r = e.node(n.v), i = { rank: (e.node(n.w).rank - r.rank) / 2 + r.rank, e: n };
|
|
1945
|
+
w(e, "edge-proxy", i, "_ep");
|
|
1946
|
+
}
|
|
1947
|
+
});
|
|
1948
|
+
}
|
|
1949
|
+
function $t(e) {
|
|
1950
|
+
let n = 0;
|
|
1951
|
+
e.nodes().forEach((t) => {
|
|
1952
|
+
let r = e.node(t);
|
|
1953
|
+
r.borderTop && (r.minRank = e.node(r.borderTop).rank, r.maxRank = e.node(r.borderBottom).rank, n = Math.max(n, r.maxRank));
|
|
1954
|
+
}), e.graph().maxRank = n;
|
|
1955
|
+
}
|
|
1956
|
+
function Jt(e) {
|
|
1957
|
+
e.nodes().forEach((n) => {
|
|
1958
|
+
let t = e.node(n);
|
|
1959
|
+
if (t.dummy === "edge-proxy") {
|
|
1960
|
+
let r = t;
|
|
1961
|
+
e.edge(r.e).labelRank = t.rank, e.removeNode(n);
|
|
1962
|
+
}
|
|
1963
|
+
});
|
|
1964
|
+
}
|
|
1965
|
+
function Qt(e) {
|
|
1966
|
+
let n = Number.POSITIVE_INFINITY, t = 0, r = Number.POSITIVE_INFINITY, o = 0, i = e.graph(), s = i.marginx || 0, a = i.marginy || 0;
|
|
1967
|
+
function d(l) {
|
|
1968
|
+
let u = l.x, c = l.y, h = l.width, f = l.height;
|
|
1969
|
+
n = Math.min(n, u - h / 2), t = Math.max(t, u + h / 2), r = Math.min(r, c - f / 2), o = Math.max(o, c + f / 2);
|
|
1970
|
+
}
|
|
1971
|
+
e.nodes().forEach((l) => d(e.node(l))), e.edges().forEach((l) => {
|
|
1972
|
+
let u = e.edge(l);
|
|
1973
|
+
Object.hasOwn(u, "x") && d(u);
|
|
1974
|
+
}), n -= s, r -= a, e.nodes().forEach((l) => {
|
|
1975
|
+
let u = e.node(l);
|
|
1976
|
+
u.x -= n, u.y -= r;
|
|
1977
|
+
}), e.edges().forEach((l) => {
|
|
1978
|
+
let u = e.edge(l);
|
|
1979
|
+
u.points.forEach((c) => {
|
|
1980
|
+
c.x -= n, c.y -= r;
|
|
1981
|
+
}), Object.hasOwn(u, "x") && (u.x -= n), Object.hasOwn(u, "y") && (u.y -= r);
|
|
1982
|
+
}), i.width = t - n + s, i.height = o - r + a;
|
|
1983
|
+
}
|
|
1984
|
+
function Zt(e) {
|
|
1985
|
+
e.edges().forEach((n) => {
|
|
1986
|
+
let t = e.edge(n), r = e.node(n.v), o = e.node(n.w), i, s;
|
|
1987
|
+
t.points ? (i = t.points[0], s = t.points[t.points.length - 1]) : (t.points = [], i = o, s = r), t.points.unshift(H(r, i)), t.points.push(H(o, s));
|
|
1988
|
+
});
|
|
1989
|
+
}
|
|
1990
|
+
function er(e) {
|
|
1991
|
+
e.edges().forEach((n) => {
|
|
1992
|
+
let t = e.edge(n);
|
|
1993
|
+
if (Object.hasOwn(t, "x")) switch ((t.labelpos === "l" || t.labelpos === "r") && (t.width -= t.labeloffset), t.labelpos) {
|
|
1994
|
+
case "l":
|
|
1995
|
+
t.x -= t.width / 2 + t.labeloffset;
|
|
1996
|
+
break;
|
|
1997
|
+
case "r":
|
|
1998
|
+
t.x += t.width / 2 + t.labeloffset;
|
|
1999
|
+
break;
|
|
2000
|
+
}
|
|
2001
|
+
});
|
|
2002
|
+
}
|
|
2003
|
+
function nr(e) {
|
|
2004
|
+
e.edges().forEach((n) => {
|
|
2005
|
+
let t = e.edge(n);
|
|
2006
|
+
t.reversed && t.points.reverse();
|
|
2007
|
+
});
|
|
2008
|
+
}
|
|
2009
|
+
function tr(e) {
|
|
2010
|
+
e.nodes().forEach((n) => {
|
|
2011
|
+
if (e.children(n).length) {
|
|
2012
|
+
let t = e.node(n), r = e.node(t.borderTop), o = e.node(t.borderBottom), i = e.node(t.borderLeft[t.borderLeft.length - 1]), s = e.node(t.borderRight[t.borderRight.length - 1]);
|
|
2013
|
+
t.width = Math.abs(s.x - i.x), t.height = Math.abs(o.y - r.y), t.x = i.x + t.width / 2, t.y = r.y + t.height / 2;
|
|
2014
|
+
}
|
|
2015
|
+
}), e.nodes().forEach((n) => {
|
|
2016
|
+
e.node(n).dummy === "border" && e.removeNode(n);
|
|
2017
|
+
});
|
|
2018
|
+
}
|
|
2019
|
+
function rr(e) {
|
|
2020
|
+
e.edges().forEach((n) => {
|
|
2021
|
+
if (n.v === n.w) {
|
|
2022
|
+
let t = e.node(n.v);
|
|
2023
|
+
t.selfEdges || (t.selfEdges = []), t.selfEdges.push({ e: n, label: e.edge(n) }), e.removeEdge(n);
|
|
2024
|
+
}
|
|
2025
|
+
});
|
|
2026
|
+
}
|
|
2027
|
+
function or(e) {
|
|
2028
|
+
N(e).forEach((t) => {
|
|
2029
|
+
let r = 0;
|
|
2030
|
+
t.forEach((o, i) => {
|
|
2031
|
+
let s = e.node(o);
|
|
2032
|
+
s.order = i + r, (s.selfEdges || []).forEach((a) => {
|
|
2033
|
+
w(e, "selfedge", { width: a.label.width, height: a.label.height, rank: s.rank, order: i + ++r, e: a.e, label: a.label }, "_se");
|
|
2034
|
+
}), delete s.selfEdges;
|
|
2035
|
+
});
|
|
2036
|
+
});
|
|
2037
|
+
}
|
|
2038
|
+
function ir(e) {
|
|
2039
|
+
e.nodes().forEach((n) => {
|
|
2040
|
+
let t = e.node(n);
|
|
2041
|
+
if (t.dummy === "selfedge") {
|
|
2042
|
+
let r = t, o = e.node(r.e.v), i = o.x + o.width / 2, s = o.y, a = t.x - i, d = o.height / 2;
|
|
2043
|
+
e.setEdge(r.e, r.label), e.removeNode(n), r.label.points = [{ x: i + 2 * a / 3, y: s - d }, { x: i + 5 * a / 6, y: s - d }, { x: i + a, y: s }, { x: i + 5 * a / 6, y: s + d }, { x: i + 2 * a / 3, y: s + d }], r.label.x = t.x, r.label.y = t.y;
|
|
2044
|
+
}
|
|
2045
|
+
});
|
|
2046
|
+
}
|
|
2047
|
+
function ue(e, n) {
|
|
2048
|
+
return O(T(e, n), Number);
|
|
2049
|
+
}
|
|
2050
|
+
function ce(e) {
|
|
2051
|
+
let n = {};
|
|
2052
|
+
return e && Object.entries(e).forEach(([t, r]) => {
|
|
2053
|
+
typeof t == "string" && (t = t.toLowerCase()), n[t] = r;
|
|
2054
|
+
}), n;
|
|
2055
|
+
}
|
|
2056
|
+
function fe(e) {
|
|
2057
|
+
let n = N(e), t = new p({ compound: true, multigraph: true }).setGraph({});
|
|
2058
|
+
return e.nodes().forEach((r) => {
|
|
2059
|
+
t.setNode(r, { label: r }), t.setParent(r, "layer" + e.node(r).rank);
|
|
2060
|
+
}), e.edges().forEach((r) => t.setEdge(r.v, r.w, {}, r.name)), n.forEach((r, o) => {
|
|
2061
|
+
let i = "layer" + o;
|
|
2062
|
+
t.setNode(i, { rank: "same" }), r.reduce((s, a) => (t.setEdge(s, a, { style: "invis" }), a));
|
|
2063
|
+
}), t;
|
|
2064
|
+
}
|
|
2065
|
+
var sr = { graphlib: z, version: U, layout: he, debug: fe, util: { time: P, notime: M } };
|
|
2066
|
+
var To = sr;
|
|
2067
|
+
|
|
415
2068
|
// src/blocks/erd.ts
|
|
2069
|
+
var MAX_ROWS = 10;
|
|
2070
|
+
var COL_W = 216;
|
|
2071
|
+
var ROW_H = 24;
|
|
2072
|
+
var HEAD_H = 32;
|
|
2073
|
+
var BOT_PAD = 8;
|
|
416
2074
|
function renderErd(data) {
|
|
417
2075
|
const ents = data.entities ?? [];
|
|
418
2076
|
const rels = data.relations ?? [];
|
|
419
|
-
const colW = 200;
|
|
420
|
-
const rowH = 22;
|
|
421
|
-
const headH = 30;
|
|
422
|
-
const gapX = 80;
|
|
423
|
-
const top = 14;
|
|
424
|
-
const pad = 16;
|
|
425
|
-
let x = pad;
|
|
426
|
-
let maxH = 0;
|
|
427
2077
|
const boxes = ents.map((e) => {
|
|
428
2078
|
const cols = e.columns ?? [];
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
});
|
|
435
|
-
const W = pad * 2 + ents.length * colW + Math.max(0, ents.length - 1) * gapX;
|
|
436
|
-
const H = top + maxH + 24;
|
|
437
|
-
const byName = /* @__PURE__ */ new Map();
|
|
438
|
-
for (const b of boxes) byName.set(b.name, b);
|
|
439
|
-
let s = `<svg viewBox="0 0 ${W} ${H}" role="img"><title>Entity-relationship diagram</title>`;
|
|
440
|
-
for (const r of rels) {
|
|
441
|
-
const a = byName.get(r.from);
|
|
442
|
-
const b = byName.get(r.to);
|
|
443
|
-
if (!a || !b) continue;
|
|
444
|
-
const x1 = a.x + a.w;
|
|
445
|
-
const y1 = a.y + 24;
|
|
446
|
-
const x2 = b.x;
|
|
447
|
-
const y2 = b.y + 24;
|
|
448
|
-
const mx = (x1 + x2) / 2;
|
|
449
|
-
s += `<path d="M${x1},${y1} H${mx} V${y2} H${x2}" fill="none" stroke="#8a96a3"/><path d="M${x2 - 11},${y2 - 7} L${x2},${y2} L${x2 - 11},${y2 + 7}" fill="none" stroke="#8a96a3"/>`;
|
|
450
|
-
if (r.card !== void 0) {
|
|
451
|
-
const w = 28;
|
|
452
|
-
s += `<rect x="${mx - w / 2}" y="${(y1 + y2) / 2 - 9}" width="${w}" height="18" rx="9" fill="#fff" stroke="#d1d5db"/><text x="${mx}" y="${(y1 + y2) / 2 + 3}" class="edge-label">${escapeHtml(r.card)}</text>`;
|
|
2079
|
+
let rows = cols;
|
|
2080
|
+
let hidden = 0;
|
|
2081
|
+
if (cols.length > MAX_ROWS) {
|
|
2082
|
+
rows = cols.slice(0, MAX_ROWS - 1);
|
|
2083
|
+
hidden = cols.length - rows.length;
|
|
453
2084
|
}
|
|
2085
|
+
const bodyRows = rows.length + (hidden > 0 ? 1 : 0);
|
|
2086
|
+
const h = HEAD_H + bodyRows * ROW_H + BOT_PAD;
|
|
2087
|
+
return { name: e.name, rows, hidden, w: COL_W, h };
|
|
2088
|
+
});
|
|
2089
|
+
const byName = new Map(boxes.map((b) => [b.name, b]));
|
|
2090
|
+
const validRels = rels.filter((r) => byName.has(r.from) && byName.has(r.to));
|
|
2091
|
+
const g = new To.graphlib.Graph({ multigraph: true });
|
|
2092
|
+
g.setGraph({ rankdir: "LR", nodesep: 34, ranksep: 86, marginx: 18, marginy: 18 });
|
|
2093
|
+
g.setDefaultEdgeLabel(() => ({}));
|
|
2094
|
+
for (const b of boxes) g.setNode(b.name, { width: b.w, height: b.h });
|
|
2095
|
+
validRels.forEach((r, i) => g.setEdge(r.from, r.to, {}, `e${i}`));
|
|
2096
|
+
To.layout(g);
|
|
2097
|
+
const graph = g.graph();
|
|
2098
|
+
const W2 = Math.ceil(graph.width ?? 0);
|
|
2099
|
+
const H2 = Math.ceil(graph.height ?? 0);
|
|
2100
|
+
const topLeft = /* @__PURE__ */ new Map();
|
|
2101
|
+
for (const b of boxes) {
|
|
2102
|
+
const n = g.node(b.name);
|
|
2103
|
+
topLeft.set(b.name, { x: n.x - b.w / 2, y: n.y - b.h / 2 });
|
|
454
2104
|
}
|
|
2105
|
+
let s = `<svg viewBox="0 0 ${W2} ${H2}" role="img"><title>Entity-relationship diagram</title>`;
|
|
2106
|
+
validRels.forEach((r, i) => {
|
|
2107
|
+
const e = g.edge(r.from, r.to, `e${i}`);
|
|
2108
|
+
const pts = e?.points;
|
|
2109
|
+
if (!pts || pts.length < 2) return;
|
|
2110
|
+
const first = pts[0];
|
|
2111
|
+
const last = pts[pts.length - 1];
|
|
2112
|
+
const prev = pts[pts.length - 2];
|
|
2113
|
+
if (first === void 0 || last === void 0 || prev === void 0) return;
|
|
2114
|
+
const line = pts.map((p2) => `${round(p2.x)},${round(p2.y)}`).join(" ");
|
|
2115
|
+
s += `<polyline points="${line}" fill="none" stroke="var(--gray)" stroke-width="1.5"/><circle cx="${round(first.x)}" cy="${round(first.y)}" r="2.6" fill="var(--gray)"/>` + arrowHead(prev, last);
|
|
2116
|
+
const mid = r.card !== void 0 ? pts[Math.floor(pts.length / 2)] : void 0;
|
|
2117
|
+
if (r.card !== void 0 && mid !== void 0) {
|
|
2118
|
+
const w2 = 30;
|
|
2119
|
+
s += `<rect x="${round(mid.x - w2 / 2)}" y="${round(mid.y - 9)}" width="${w2}" height="18" rx="9" fill="var(--white)" stroke="var(--rule)"/><text x="${round(mid.x)}" y="${round(mid.y + 3)}" class="edge-label">${escapeHtml(r.card)}</text>`;
|
|
2120
|
+
}
|
|
2121
|
+
});
|
|
455
2122
|
for (const b of boxes) {
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
2123
|
+
const p2 = topLeft.get(b.name);
|
|
2124
|
+
if (!p2) continue;
|
|
2125
|
+
const { x: x2, y } = p2;
|
|
2126
|
+
s += `<rect x="${round(x2)}" y="${round(y)}" width="${b.w}" height="${b.h}" rx="5" fill="var(--white)" stroke="var(--navy)"/><path d="M${round(x2)},${round(y + HEAD_H)} v${ -27} a5,5 0 0 1 5,-5 h${b.w - 10} a5,5 0 0 1 5,5 v${HEAD_H - 5} z" fill="var(--navy)"/><text x="${round(x2 + b.w / 2)}" y="${round(y + 21)}" class="er-head-text">${escapeHtml(b.name)}</text>`;
|
|
2127
|
+
b.rows.forEach((f, j2) => {
|
|
2128
|
+
const rowTop = y + HEAD_H + j2 * ROW_H;
|
|
2129
|
+
const ty = rowTop + 16;
|
|
2130
|
+
if (j2 > 0) {
|
|
2131
|
+
s += `<line x1="${round(x2)}" y1="${round(rowTop)}" x2="${round(x2 + b.w)}" y2="${round(rowTop)}" class="er-rowline"/>`;
|
|
462
2132
|
}
|
|
2133
|
+
const nameX = f.pk === true || f.fk === true ? x2 + 40 : x2 + 13;
|
|
463
2134
|
if (f.pk === true) {
|
|
464
|
-
s += `<text x="${
|
|
2135
|
+
s += `<text x="${round(x2 + 13)}" y="${round(ty)}" class="er-key">PK</text>`;
|
|
465
2136
|
} else if (f.fk === true) {
|
|
466
|
-
s += `<text x="${
|
|
2137
|
+
s += `<text x="${round(x2 + 13)}" y="${round(ty)}" class="er-key fk">FK</text>`;
|
|
467
2138
|
}
|
|
468
|
-
s += `<text x="${nameX}" y="${
|
|
2139
|
+
s += `<text x="${round(nameX)}" y="${round(ty)}" class="er-col">${escapeHtml(f.name)}</text><text x="${round(x2 + b.w - 13)}" y="${round(ty)}" class="er-col dim" text-anchor="end">${escapeHtml(f.type ?? "")}</text>`;
|
|
469
2140
|
});
|
|
2141
|
+
if (b.hidden > 0) {
|
|
2142
|
+
const rowTop = y + HEAD_H + b.rows.length * ROW_H;
|
|
2143
|
+
s += `<line x1="${round(x2)}" y1="${round(rowTop)}" x2="${round(x2 + b.w)}" y2="${round(rowTop)}" class="er-rowline"/><text x="${round(x2 + b.w / 2)}" y="${round(rowTop + 16)}" class="er-col dim" text-anchor="middle">\u2026 +${b.hidden} more</text>`;
|
|
2144
|
+
}
|
|
470
2145
|
}
|
|
471
2146
|
s += `</svg>`;
|
|
472
2147
|
const opts = {
|
|
@@ -477,6 +2152,17 @@ function renderErd(data) {
|
|
|
477
2152
|
};
|
|
478
2153
|
return diagramFrame(opts, s);
|
|
479
2154
|
}
|
|
2155
|
+
function arrowHead(from, to) {
|
|
2156
|
+
const ang = Math.atan2(to.y - from.y, to.x - from.x);
|
|
2157
|
+
const len = 10;
|
|
2158
|
+
const spread = 0.42;
|
|
2159
|
+
const b1x = to.x - len * Math.cos(ang - spread);
|
|
2160
|
+
const b1y = to.y - len * Math.sin(ang - spread);
|
|
2161
|
+
const b2x = to.x - len * Math.cos(ang + spread);
|
|
2162
|
+
const b2y = to.y - len * Math.sin(ang + spread);
|
|
2163
|
+
return `<path d="M${round(b1x)},${round(b1y)} L${round(to.x)},${round(to.y)} L${round(b2x)},${round(b2y)}" fill="none" stroke="var(--navy)" stroke-width="1.6" stroke-linejoin="round" stroke-linecap="round"/>`;
|
|
2164
|
+
}
|
|
2165
|
+
var round = (n) => Math.round(n * 10) / 10;
|
|
480
2166
|
|
|
481
2167
|
// src/blocks/kanban.ts
|
|
482
2168
|
function renderKanban(data) {
|
|
@@ -524,21 +2210,21 @@ function renderFoot(foot) {
|
|
|
524
2210
|
function renderSequence(data) {
|
|
525
2211
|
const actors = data.actors ?? [];
|
|
526
2212
|
const messages = data.messages ?? [];
|
|
527
|
-
const
|
|
2213
|
+
const N2 = Math.max(actors.length, 1);
|
|
528
2214
|
const leftPad = 24;
|
|
529
2215
|
const laneW = 168;
|
|
530
2216
|
const gap = 58;
|
|
531
2217
|
const headY = 16;
|
|
532
2218
|
const headH = 42;
|
|
533
2219
|
const cx = (i) => leftPad + laneW / 2 + i * (laneW + gap);
|
|
534
|
-
const width = leftPad * 2 +
|
|
2220
|
+
const width = leftPad * 2 + N2 * laneW + (N2 - 1) * gap;
|
|
535
2221
|
const idx = (id) => actors.findIndex((a) => a.id === id);
|
|
536
2222
|
const msgStartY = 92;
|
|
537
2223
|
const step = 42;
|
|
538
|
-
const rows = messages.map((m,
|
|
2224
|
+
const rows = messages.map((m, k2) => {
|
|
539
2225
|
const base = {
|
|
540
|
-
n:
|
|
541
|
-
y: msgStartY +
|
|
2226
|
+
n: k2 + 1,
|
|
2227
|
+
y: msgStartY + k2 * step,
|
|
542
2228
|
fromI: idx(m.from),
|
|
543
2229
|
toI: idx(m.to),
|
|
544
2230
|
kind: m.kind ?? "sync",
|
|
@@ -562,8 +2248,8 @@ function renderSequence(data) {
|
|
|
562
2248
|
});
|
|
563
2249
|
let s = `<svg viewBox="0 0 ${width} ${height}" role="img"><title>Sequence diagram</title><defs><marker id="sqArrow" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 z" fill="#1a1a2e"/></marker><marker id="sqOpen" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10" fill="none" stroke="#1a1a2e" stroke-width="1.2"/></marker><marker id="sqErr" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 z" fill="#991b1b"/></marker></defs>`;
|
|
564
2250
|
for (let i = 0; i < actors.length; i++) {
|
|
565
|
-
const
|
|
566
|
-
s += `<line x1="${
|
|
2251
|
+
const x2 = cx(i);
|
|
2252
|
+
s += `<line x1="${x2}" y1="${headY + headH}" x2="${x2}" y2="${bottom}" class="lifeline"/>`;
|
|
567
2253
|
}
|
|
568
2254
|
for (const ac of activations) {
|
|
569
2255
|
if (!ac) continue;
|
|
@@ -575,17 +2261,17 @@ function renderSequence(data) {
|
|
|
575
2261
|
s += `<g><rect x="${cx(i) - laneW / 2}" y="${headY}" width="${laneW}" height="${headH}" class="lane-head${extCls}"/><text x="${cx(i)}" y="${headY + 22}" class="lane-head-text">${escapeHtml(a.name)}</text>` + sub + `</g>`;
|
|
576
2262
|
});
|
|
577
2263
|
for (const r of rows) {
|
|
578
|
-
const
|
|
2264
|
+
const k2 = KIND[r.kind];
|
|
579
2265
|
if (r.kind === "note" || r.toI < 0) {
|
|
580
2266
|
if (r.fromI < 0) continue;
|
|
581
|
-
const
|
|
582
|
-
s += `<g><circle cx="${
|
|
2267
|
+
const x3 = cx(r.fromI);
|
|
2268
|
+
s += `<g><circle cx="${x3 + 18}" cy="${r.y - 10}" r="10" class="step-badge"/><text x="${x3 + 18}" y="${r.y - 6.5}" class="step-badge-text">${r.n}</text><text x="${x3 + 34}" y="${r.y - 6}" class="msg-text note">${escapeHtml(r.label)}</text></g>`;
|
|
583
2269
|
continue;
|
|
584
2270
|
}
|
|
585
2271
|
if (r.fromI === r.toI) {
|
|
586
|
-
const
|
|
2272
|
+
const x3 = cx(r.fromI);
|
|
587
2273
|
const errCls = r.kind === "error" ? " err" : "";
|
|
588
|
-
s += `<g><circle cx="${
|
|
2274
|
+
s += `<g><circle cx="${x3 + 18}" cy="${r.y - 10}" r="10" class="step-badge${errCls}"/><text x="${x3 + 18}" y="${r.y - 6.5}" class="step-badge-text">${r.n}</text><text x="${x3 + 34}" y="${r.y - 6}" class="msg-text note">${escapeHtml(r.label)}</text></g>`;
|
|
589
2275
|
continue;
|
|
590
2276
|
}
|
|
591
2277
|
const x1 = cx(r.fromI);
|
|
@@ -596,8 +2282,8 @@ function renderSequence(data) {
|
|
|
596
2282
|
const badgeX = ltr ? x1 + 18 : x1 - 18;
|
|
597
2283
|
const labelX = ltr ? badgeX + 16 : badgeX - 16;
|
|
598
2284
|
const labelAnchor = ltr ? "start" : "end";
|
|
599
|
-
const markerAttr =
|
|
600
|
-
s += `<line x1="${x1}" y1="${r.y}" x2="${end}" y2="${r.y}" class="${
|
|
2285
|
+
const markerAttr = k2.marker !== null ? ` marker-end="url(#${k2.marker})"` : "";
|
|
2286
|
+
s += `<line x1="${x1}" y1="${r.y}" x2="${end}" y2="${r.y}" class="${k2.cls}"${markerAttr}/><circle cx="${badgeX}" cy="${r.y - 10}" r="10" class="step-badge${errBadge}"/><text x="${badgeX}" y="${r.y - 6.5}" class="step-badge-text">${r.n}</text><text x="${labelX}" y="${r.y - 6}" class="${k2.txt}" text-anchor="${labelAnchor}">${escapeHtml(r.label)}</text>`;
|
|
601
2287
|
}
|
|
602
2288
|
s += `</svg>`;
|
|
603
2289
|
const actorById = /* @__PURE__ */ new Map();
|
|
@@ -670,11 +2356,11 @@ function renderTable(data) {
|
|
|
670
2356
|
function renderTimeline(data) {
|
|
671
2357
|
const items = data.items ?? [];
|
|
672
2358
|
let h = `<div class="tl">`;
|
|
673
|
-
for (const
|
|
674
|
-
const
|
|
675
|
-
const date =
|
|
676
|
-
const desc =
|
|
677
|
-
h += `<div class="tl-item"><span class="tl-dot ${
|
|
2359
|
+
for (const it2 of items) {
|
|
2360
|
+
const st2 = it2.status ?? "future";
|
|
2361
|
+
const date = it2.date !== void 0 ? `<div class="tl-date">${escapeHtml(it2.date)}</div>` : "";
|
|
2362
|
+
const desc = it2.desc !== void 0 ? `<div class="tl-desc">${escapeHtml(it2.desc)}</div>` : "";
|
|
2363
|
+
h += `<div class="tl-item"><span class="tl-dot ${st2}"></span>` + date + `<div class="tl-label">${escapeHtml(it2.label)}</div>` + desc + `</div>`;
|
|
678
2364
|
}
|
|
679
2365
|
return h + `</div>`;
|
|
680
2366
|
}
|
|
@@ -688,18 +2374,18 @@ function renderTracker(data) {
|
|
|
688
2374
|
if (hasOwner) headCells.push("<th>Owner</th>");
|
|
689
2375
|
if (hasDue) headCells.push("<th>Due</th>");
|
|
690
2376
|
let h = `<table class="trk"><thead><tr>${headCells.join("")}</tr></thead><tbody>`;
|
|
691
|
-
for (const
|
|
692
|
-
const
|
|
693
|
-
const pr =
|
|
2377
|
+
for (const it2 of items) {
|
|
2378
|
+
const st2 = it2.status ?? "todo";
|
|
2379
|
+
const pr = it2.priority;
|
|
694
2380
|
const prCell = pr !== void 0 ? `<span class="pri ${pr}">${escapeHtml(pr)}</span>` : "";
|
|
695
|
-
const rowCls =
|
|
2381
|
+
const rowCls = st2 === "done" ? ' class="done"' : "";
|
|
696
2382
|
const cells = [
|
|
697
|
-
`<td class="trk-task">${escapeHtml(
|
|
698
|
-
`<td><span class="st ${
|
|
2383
|
+
`<td class="trk-task">${escapeHtml(it2.task)}</td>`,
|
|
2384
|
+
`<td><span class="st ${st2}">${escapeHtml(st2)}</span></td>`,
|
|
699
2385
|
`<td>${prCell}</td>`
|
|
700
2386
|
];
|
|
701
|
-
if (hasOwner) cells.push(`<td>${escapeHtml(
|
|
702
|
-
if (hasDue) cells.push(`<td>${escapeHtml(
|
|
2387
|
+
if (hasOwner) cells.push(`<td>${escapeHtml(it2.owner ?? "")}</td>`);
|
|
2388
|
+
if (hasDue) cells.push(`<td>${escapeHtml(it2.due ?? "")}</td>`);
|
|
703
2389
|
h += `<tr${rowCls}>${cells.join("")}</tr>`;
|
|
704
2390
|
}
|
|
705
2391
|
return h + `</tbody></table>`;
|
|
@@ -747,11 +2433,11 @@ function renderProseBlock(data) {
|
|
|
747
2433
|
if (t === "h") return `<h3>${escapeHtml(text)}</h3>`;
|
|
748
2434
|
if (t === "quote") return `<blockquote>${escapeHtml(text)}</blockquote>`;
|
|
749
2435
|
if (t === "ul") {
|
|
750
|
-
const items = (b.items ?? []).map((
|
|
2436
|
+
const items = (b.items ?? []).map((x2) => `<li>${escapeHtml(x2)}</li>`).join("");
|
|
751
2437
|
return `<ul>${items}</ul>`;
|
|
752
2438
|
}
|
|
753
2439
|
if (t === "ol") {
|
|
754
|
-
const items = (b.items ?? []).map((
|
|
2440
|
+
const items = (b.items ?? []).map((x2) => `<li>${escapeHtml(x2)}</li>`).join("");
|
|
755
2441
|
return `<ol>${items}</ol>`;
|
|
756
2442
|
}
|
|
757
2443
|
return `<p>${escapeHtml(text)}</p>`;
|
|
@@ -772,7 +2458,7 @@ function renderGlossary(data) {
|
|
|
772
2458
|
function renderProsCons(data) {
|
|
773
2459
|
const prosLabel = data.prosLabel ?? "Pros";
|
|
774
2460
|
const consLabel = data.consLabel ?? "Cons";
|
|
775
|
-
const pros = (data.pros ?? []).map((
|
|
2461
|
+
const pros = (data.pros ?? []).map((p2) => `<div class="pc-item">${escapeHtml(p2)}</div>`).join("");
|
|
776
2462
|
const cons = (data.cons ?? []).map((c) => `<div class="pc-item">${escapeHtml(c)}</div>`).join("");
|
|
777
2463
|
return `<div class="pc"><div class="pc-col pro"><div class="pc-head">${escapeHtml(prosLabel)}</div>` + pros + `</div><div class="pc-col con"><div class="pc-head">${escapeHtml(consLabel)}</div>` + cons + `</div></div>`;
|
|
778
2464
|
}
|
|
@@ -781,8 +2467,8 @@ function renderProsCons(data) {
|
|
|
781
2467
|
function renderCvt(data) {
|
|
782
2468
|
const cur = data.current ?? {};
|
|
783
2469
|
const tgt = data.target ?? {};
|
|
784
|
-
const curItems = (cur.items ?? []).map((
|
|
785
|
-
const tgtItems = (tgt.items ?? []).map((
|
|
2470
|
+
const curItems = (cur.items ?? []).map((x2) => `<div class="ct-item">${escapeHtml(x2)}</div>`).join("");
|
|
2471
|
+
const tgtItems = (tgt.items ?? []).map((x2) => `<div class="ct-item">${escapeHtml(x2)}</div>`).join("");
|
|
786
2472
|
const curLabel = cur.label ?? "Current";
|
|
787
2473
|
const tgtLabel = tgt.label ?? "Target";
|
|
788
2474
|
const note = data.note !== void 0 ? `<div class="tbl-note">${escapeHtml(data.note)}</div>` : "";
|
|
@@ -826,9 +2512,9 @@ function highlightCode(code) {
|
|
|
826
2512
|
} else if (m[3] !== void 0) {
|
|
827
2513
|
out += `<span class="num">${escapeHtml(t)}</span>`;
|
|
828
2514
|
} else {
|
|
829
|
-
const
|
|
830
|
-
if (KW.has(
|
|
831
|
-
else if (TY.has(
|
|
2515
|
+
const lt2 = t.toLowerCase();
|
|
2516
|
+
if (KW.has(lt2)) out += `<span class="kw">${escapeHtml(t)}</span>`;
|
|
2517
|
+
else if (TY.has(lt2)) out += `<span class="ty">${escapeHtml(t)}</span>`;
|
|
832
2518
|
else if (src[TOKEN_RE.lastIndex] === "(")
|
|
833
2519
|
out += `<span class="fn">${escapeHtml(t)}</span>`;
|
|
834
2520
|
else out += escapeHtml(t);
|
|
@@ -850,12 +2536,12 @@ function renderCode(data) {
|
|
|
850
2536
|
// src/blocks/agenda.ts
|
|
851
2537
|
function renderAgenda(data) {
|
|
852
2538
|
const items = data.items ?? [];
|
|
853
|
-
const rows = items.map((
|
|
854
|
-
const dur =
|
|
855
|
-
const owner =
|
|
856
|
-
const desc =
|
|
857
|
-
const time =
|
|
858
|
-
return `<div class="agenda-row"><div>${time}${dur}</div><div><div class="agenda-title">${escapeHtml(
|
|
2539
|
+
const rows = items.map((it2) => {
|
|
2540
|
+
const dur = it2.duration !== void 0 ? `<div class="agenda-dur">${escapeHtml(it2.duration)}</div>` : "";
|
|
2541
|
+
const owner = it2.owner !== void 0 ? `<span class="agenda-owner">${escapeHtml(it2.owner)}</span>` : "";
|
|
2542
|
+
const desc = it2.desc !== void 0 ? `<div class="agenda-desc">${escapeHtml(it2.desc)}</div>` : "";
|
|
2543
|
+
const time = it2.time !== void 0 ? `<div class="agenda-time">${escapeHtml(it2.time)}</div>` : "";
|
|
2544
|
+
return `<div class="agenda-row"><div>${time}${dur}</div><div><div class="agenda-title">${escapeHtml(it2.title)}${owner}</div>` + desc + `</div></div>`;
|
|
859
2545
|
}).join("");
|
|
860
2546
|
return `<div class="agenda">${rows}</div>`;
|
|
861
2547
|
}
|
|
@@ -903,78 +2589,78 @@ var CHART_COLORS = ["#0e54a1", "#1a6dbe", "#0f766e", "#1f9747", "#6b21a8", "#f79
|
|
|
903
2589
|
function renderPyramid(data) {
|
|
904
2590
|
const levels = data.levels ?? [];
|
|
905
2591
|
const n = Math.max(levels.length, 1);
|
|
906
|
-
const
|
|
2592
|
+
const W2 = 520;
|
|
907
2593
|
const top = 16;
|
|
908
2594
|
const rowH = Math.min(72, Math.floor(280 / n));
|
|
909
2595
|
const gap = 4;
|
|
910
|
-
const apex =
|
|
2596
|
+
const apex = W2 / 2;
|
|
911
2597
|
const pad = 16;
|
|
912
2598
|
const maxW = 430;
|
|
913
|
-
const
|
|
914
|
-
const polygons = levels.map((
|
|
2599
|
+
const H2 = top + n * (rowH + gap) + pad;
|
|
2600
|
+
const polygons = levels.map((L2, i) => {
|
|
915
2601
|
const y = top + i * (rowH + gap);
|
|
916
2602
|
const wTop = maxW * (i / n);
|
|
917
2603
|
const wBot = maxW * ((i + 1) / n);
|
|
918
2604
|
const fill = CHART_COLORS[i % CHART_COLORS.length] ?? "#0e54a1";
|
|
919
|
-
const desc =
|
|
920
|
-
return `<g><polygon points="${apex - wTop / 2},${y} ${apex + wTop / 2},${y} ${apex + wBot / 2},${y + rowH} ${apex - wBot / 2},${y + rowH}" fill="${fill}"/><text x="${apex}" y="${y + rowH / 2 - 1}" class="pyr-label">${escapeHtml(
|
|
2605
|
+
const desc = L2.desc !== void 0 ? `<text x="${apex}" y="${y + rowH / 2 + 14}" class="pyr-desc">${escapeHtml(L2.desc)}</text>` : "";
|
|
2606
|
+
return `<g><polygon points="${apex - wTop / 2},${y} ${apex + wTop / 2},${y} ${apex + wBot / 2},${y + rowH} ${apex - wBot / 2},${y + rowH}" fill="${fill}"/><text x="${apex}" y="${y + rowH / 2 - 1}" class="pyr-label">${escapeHtml(L2.label)}</text>` + desc + `</g>`;
|
|
921
2607
|
}).join("");
|
|
922
|
-
return `<svg viewBox="0 0 ${
|
|
2608
|
+
return `<svg viewBox="0 0 ${W2} ${H2}" role="img"><title>Pyramid</title>${polygons}</svg>`;
|
|
923
2609
|
}
|
|
924
2610
|
|
|
925
2611
|
// src/blocks/funnel.ts
|
|
926
2612
|
var CHART_COLORS2 = ["#0e54a1", "#1a6dbe", "#0f766e", "#1f9747", "#6b21a8", "#f7952c"];
|
|
927
|
-
function toNum(
|
|
928
|
-
if (typeof
|
|
929
|
-
const n = parseFloat(
|
|
2613
|
+
function toNum(v2) {
|
|
2614
|
+
if (typeof v2 === "number") return v2;
|
|
2615
|
+
const n = parseFloat(v2.replace(/[, _]/g, ""));
|
|
930
2616
|
return Number.isFinite(n) ? n : 0;
|
|
931
2617
|
}
|
|
932
|
-
function fmt(
|
|
933
|
-
return typeof
|
|
2618
|
+
function fmt(v2) {
|
|
2619
|
+
return typeof v2 === "number" ? v2.toLocaleString() : v2;
|
|
934
2620
|
}
|
|
935
2621
|
function renderFunnel(data) {
|
|
936
2622
|
const stages = (data.stages ?? []).filter(Boolean);
|
|
937
|
-
const
|
|
2623
|
+
const W2 = 560;
|
|
938
2624
|
const top = 14;
|
|
939
2625
|
const rowH = 62;
|
|
940
2626
|
const maxW = 420;
|
|
941
2627
|
const pad = 14;
|
|
942
|
-
const cx =
|
|
943
|
-
const
|
|
2628
|
+
const cx = W2 / 2;
|
|
2629
|
+
const H2 = top + stages.length * rowH + pad;
|
|
944
2630
|
const vals = stages.map((s) => toNum(s.value));
|
|
945
2631
|
const first = vals[0] ?? 0;
|
|
946
2632
|
const max = Math.max(1, ...vals);
|
|
947
|
-
const wOf = (
|
|
2633
|
+
const wOf = (v2) => Math.max(78, maxW * (v2 / max));
|
|
948
2634
|
const groups = stages.map((s, i) => {
|
|
949
|
-
const
|
|
950
|
-
const vNext = i < stages.length - 1 ? vals[i + 1] ?? 0 :
|
|
951
|
-
const wTop = wOf(
|
|
2635
|
+
const v2 = vals[i] ?? 0;
|
|
2636
|
+
const vNext = i < stages.length - 1 ? vals[i + 1] ?? 0 : v2 * 0.82;
|
|
2637
|
+
const wTop = wOf(v2);
|
|
952
2638
|
const wBot = wOf(vNext);
|
|
953
2639
|
const y = top + i * rowH;
|
|
954
2640
|
const fill = CHART_COLORS2[i % CHART_COLORS2.length] ?? "#0e54a1";
|
|
955
|
-
const pct = first > 0 ? Math.round(
|
|
2641
|
+
const pct = first > 0 ? Math.round(v2 / first * 100) : 0;
|
|
956
2642
|
const sub = i > 0 && first > 0 ? ` \xB7 ${pct}%` : "";
|
|
957
2643
|
return `<g><polygon points="${cx - wTop / 2},${y} ${cx + wTop / 2},${y} ${cx + wBot / 2},${y + rowH} ${cx - wBot / 2},${y + rowH}" fill="${fill}" stroke="#fff" stroke-width="2"/><text x="${cx}" y="${y + rowH / 2 - 3}" class="funnel-label">${escapeHtml(s.label)}</text><text x="${cx}" y="${y + rowH / 2 + 15}" class="funnel-val">${escapeHtml(fmt(s.value))}${sub}</text></g>`;
|
|
958
2644
|
}).join("");
|
|
959
|
-
return `<svg viewBox="0 0 ${
|
|
2645
|
+
return `<svg viewBox="0 0 ${W2} ${H2}" role="img"><title>Funnel</title>${groups}</svg>`;
|
|
960
2646
|
}
|
|
961
2647
|
|
|
962
2648
|
// src/svg/ortho.ts
|
|
963
|
-
function ortho(
|
|
964
|
-
const a = { x:
|
|
965
|
-
const b = { x:
|
|
2649
|
+
function ortho(A2, B2) {
|
|
2650
|
+
const a = { x: A2.x + A2.w / 2, y: A2.y + A2.h / 2 };
|
|
2651
|
+
const b = { x: B2.x + B2.w / 2, y: B2.y + B2.h / 2 };
|
|
966
2652
|
const dx = b.x - a.x;
|
|
967
2653
|
const dy = b.y - a.y;
|
|
968
2654
|
if (Math.abs(dx) >= Math.abs(dy)) {
|
|
969
|
-
const sx2 = dx >= 0 ?
|
|
970
|
-
const ex2 = dx >= 0 ?
|
|
2655
|
+
const sx2 = dx >= 0 ? A2.x + A2.w : A2.x;
|
|
2656
|
+
const ex2 = dx >= 0 ? B2.x : B2.x + B2.w;
|
|
971
2657
|
const sy2 = a.y;
|
|
972
2658
|
const ey2 = b.y;
|
|
973
2659
|
const mx = (sx2 + ex2) / 2;
|
|
974
2660
|
return { d: `M ${sx2} ${sy2} H ${mx} V ${ey2} H ${ex2}`, lx: mx, ly: (sy2 + ey2) / 2 };
|
|
975
2661
|
}
|
|
976
|
-
const sy = dy >= 0 ?
|
|
977
|
-
const ey = dy >= 0 ?
|
|
2662
|
+
const sy = dy >= 0 ? A2.y + A2.h : A2.y;
|
|
2663
|
+
const ey = dy >= 0 ? B2.y : B2.y + B2.h;
|
|
978
2664
|
const sx = a.x;
|
|
979
2665
|
const ex = b.x;
|
|
980
2666
|
const my = (sy + ey) / 2;
|
|
@@ -987,16 +2673,16 @@ function wrapText(text, max, maxLines) {
|
|
|
987
2673
|
const words = String(text).split(/\s+/);
|
|
988
2674
|
const lines = [];
|
|
989
2675
|
let cur = "";
|
|
990
|
-
for (const
|
|
2676
|
+
for (const w2 of words) {
|
|
991
2677
|
if (!cur) {
|
|
992
|
-
cur =
|
|
2678
|
+
cur = w2;
|
|
993
2679
|
continue;
|
|
994
2680
|
}
|
|
995
|
-
if ((cur + " " +
|
|
996
|
-
cur += " " +
|
|
2681
|
+
if ((cur + " " + w2).length <= max) {
|
|
2682
|
+
cur += " " + w2;
|
|
997
2683
|
} else {
|
|
998
2684
|
lines.push(cur);
|
|
999
|
-
cur =
|
|
2685
|
+
cur = w2;
|
|
1000
2686
|
if (lines.length === maxLines) break;
|
|
1001
2687
|
}
|
|
1002
2688
|
}
|
|
@@ -1005,11 +2691,11 @@ function wrapText(text, max, maxLines) {
|
|
|
1005
2691
|
}
|
|
1006
2692
|
|
|
1007
2693
|
// src/svg/edgePill.ts
|
|
1008
|
-
function edgePill(
|
|
2694
|
+
function edgePill(p2, label, err = false) {
|
|
1009
2695
|
if (label === void 0 || label === "") return "";
|
|
1010
|
-
const
|
|
2696
|
+
const w2 = Math.max(26, label.length * 5.4);
|
|
1011
2697
|
const errClass = err ? " err" : "";
|
|
1012
|
-
return `<g><rect x="${
|
|
2698
|
+
return `<g><rect x="${p2.lx - w2 / 2}" y="${p2.ly - 9}" width="${w2}" height="18" rx="9" fill="#fff" stroke="#d1d5db"/><text x="${p2.lx}" y="${p2.ly + 3}" class="edge-label${errClass}">${escapeHtml(label)}</text></g>`;
|
|
1013
2699
|
}
|
|
1014
2700
|
|
|
1015
2701
|
// src/blocks/flow.ts
|
|
@@ -1051,32 +2737,32 @@ function renderFlowSvg(data) {
|
|
|
1051
2737
|
const height = padTop + rows * cellH + (rows - 1) * gapY + padBot;
|
|
1052
2738
|
let s = `<svg viewBox="0 0 ${width} ${height}" role="img"><title>Flowchart</title>`;
|
|
1053
2739
|
for (const e of edges) {
|
|
1054
|
-
const
|
|
1055
|
-
const
|
|
1056
|
-
if (!
|
|
1057
|
-
const
|
|
2740
|
+
const A2 = byId.get(e.from);
|
|
2741
|
+
const B2 = byId.get(e.to);
|
|
2742
|
+
if (!A2 || !B2) continue;
|
|
2743
|
+
const p2 = ortho(rectFor2(A2), rectFor2(B2));
|
|
1058
2744
|
const isErr = e.kind === "error" || ERR_LABEL_RE.test(e.label ?? "");
|
|
1059
2745
|
const stroke = isErr ? "#991b1b" : "#1a1a2e";
|
|
1060
2746
|
const marker = isErr ? "gErr" : "gArrow";
|
|
1061
2747
|
const sw = isErr ? 1.6 : 1.4;
|
|
1062
|
-
s += `<g><path d="${
|
|
2748
|
+
s += `<g><path d="${p2.d}" fill="none" stroke="${stroke}" stroke-width="${sw}" marker-end="url(#${marker})"/>` + edgePill(p2, e.label, isErr) + `</g>`;
|
|
1063
2749
|
}
|
|
1064
2750
|
for (const n of nodes) {
|
|
1065
2751
|
const r = rectFor2(n);
|
|
1066
|
-
const
|
|
2752
|
+
const st2 = flowStyle(n.kind);
|
|
1067
2753
|
const cx = r.x + r.w / 2;
|
|
1068
2754
|
const cy = r.y + r.h / 2;
|
|
1069
2755
|
let shape;
|
|
1070
|
-
if (
|
|
1071
|
-
shape = `<polygon points="${cx},${r.y} ${r.x + r.w},${cy} ${cx},${r.y + r.h} ${r.x},${cy}" fill="${
|
|
1072
|
-
} else if (
|
|
1073
|
-
shape = `<rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" rx="${r.h / 2}" fill="${
|
|
2756
|
+
if (st2.shape === "diamond") {
|
|
2757
|
+
shape = `<polygon points="${cx},${r.y} ${r.x + r.w},${cy} ${cx},${r.y + r.h} ${r.x},${cy}" fill="${st2.fill}" stroke="${st2.stroke}" stroke-width="1.5"/>`;
|
|
2758
|
+
} else if (st2.shape === "stadium") {
|
|
2759
|
+
shape = `<rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" rx="${r.h / 2}" fill="${st2.fill}" stroke="${st2.stroke}" stroke-width="1.5"/>`;
|
|
1074
2760
|
} else {
|
|
1075
|
-
shape = `<rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" rx="7" fill="${
|
|
2761
|
+
shape = `<rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" rx="7" fill="${st2.fill}" stroke="${st2.stroke}" stroke-width="1.4"/>`;
|
|
1076
2762
|
}
|
|
1077
2763
|
const lines = wrapText(n.label, 22, 2);
|
|
1078
2764
|
const texts = lines.map(
|
|
1079
|
-
(
|
|
2765
|
+
(ln2, j2) => `<text x="${cx}" y="${cy + 4 - (lines.length - 1) * 7 + j2 * 14}" class="fc-label" fill="${st2.text}">${escapeHtml(ln2)}</text>`
|
|
1080
2766
|
).join("");
|
|
1081
2767
|
s += `<g filter="url(#gshadow)">${shape}${texts}</g>`;
|
|
1082
2768
|
}
|
|
@@ -1135,31 +2821,31 @@ function renderState(data) {
|
|
|
1135
2821
|
const byId = new Map(states.map((s2) => [s2.id, s2]));
|
|
1136
2822
|
let s = `<svg viewBox="0 0 ${width} ${height}" role="img"><title>State machine</title>`;
|
|
1137
2823
|
for (const t of trans) {
|
|
1138
|
-
const
|
|
1139
|
-
const
|
|
1140
|
-
if (!
|
|
2824
|
+
const A2 = byId.get(t.from);
|
|
2825
|
+
const B2 = byId.get(t.to);
|
|
2826
|
+
if (!A2 || !B2) continue;
|
|
1141
2827
|
const label = t.event + (t.guard !== void 0 ? ` ${t.guard}` : "");
|
|
1142
2828
|
if (t.from === t.to) {
|
|
1143
|
-
const r = rectFor(
|
|
2829
|
+
const r = rectFor(A2, cellW, cellH, gapX, gapY, padX, padTop);
|
|
1144
2830
|
s += `<g><path d="M ${r.cx - 12} ${r.y} C ${r.cx - 30} ${r.y - 32}, ${r.cx + 30} ${r.y - 32}, ${r.cx + 12} ${r.y}" fill="none" stroke="#1a1a2e" stroke-width="1.3" marker-end="url(#gArrow)"/>` + edgePill({ lx: r.cx, ly: r.y - 28 }, label) + `</g>`;
|
|
1145
2831
|
continue;
|
|
1146
2832
|
}
|
|
1147
|
-
const
|
|
1148
|
-
rectFor(
|
|
1149
|
-
rectFor(
|
|
2833
|
+
const p2 = ortho(
|
|
2834
|
+
rectFor(A2, cellW, cellH, gapX, gapY, padX, padTop),
|
|
2835
|
+
rectFor(B2, cellW, cellH, gapX, gapY, padX, padTop)
|
|
1150
2836
|
);
|
|
1151
|
-
s += `<g><path d="${
|
|
2837
|
+
s += `<g><path d="${p2.d}" fill="none" stroke="#1a1a2e" stroke-width="1.3" marker-end="url(#gArrow)"/>` + edgePill(p2, label) + `</g>`;
|
|
1152
2838
|
}
|
|
1153
|
-
for (const
|
|
1154
|
-
const r = rectFor(
|
|
1155
|
-
if (
|
|
2839
|
+
for (const st2 of states) {
|
|
2840
|
+
const r = rectFor(st2, cellW, cellH, gapX, gapY, padX, padTop);
|
|
2841
|
+
if (st2.kind === "start") {
|
|
1156
2842
|
s += `<circle cx="${r.cx}" cy="${r.cy}" r="10" fill="#1a1a2e"/>`;
|
|
1157
|
-
} else if (
|
|
2843
|
+
} else if (st2.kind === "terminal") {
|
|
1158
2844
|
s += `<g><circle cx="${r.cx}" cy="${r.cy}" r="12" fill="#fff" stroke="#1a1a2e" stroke-width="1.5"/><circle cx="${r.cx}" cy="${r.cy}" r="6" fill="#1a1a2e"/></g>`;
|
|
1159
2845
|
} else {
|
|
1160
|
-
const fill =
|
|
1161
|
-
const stroke =
|
|
1162
|
-
s += `<g filter="url(#gshadow)"><rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" rx="23" fill="${fill}" stroke="${stroke}" stroke-width="1.5"/><text x="${r.cx}" y="${r.cy + 4.5}" class="sm-name" fill="#1a1a2e">${escapeHtml(
|
|
2846
|
+
const fill = st2.kind === "wait" ? "#fde7cd" : "#dcf1e2";
|
|
2847
|
+
const stroke = st2.kind === "wait" ? "#f7952c" : "#1f9747";
|
|
2848
|
+
s += `<g filter="url(#gshadow)"><rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" rx="23" fill="${fill}" stroke="${stroke}" stroke-width="1.5"/><text x="${r.cx}" y="${r.cy + 4.5}" class="sm-name" fill="#1a1a2e">${escapeHtml(st2.name ?? "")}</text></g>`;
|
|
1163
2849
|
}
|
|
1164
2850
|
}
|
|
1165
2851
|
s += `</svg>`;
|
|
@@ -1211,26 +2897,26 @@ function renderDfd(data) {
|
|
|
1211
2897
|
const height = padTop + rows * cellH + (rows - 1) * gapY + padBot;
|
|
1212
2898
|
let s = `<svg viewBox="0 0 ${width} ${height}" role="img"><title>Data-flow diagram</title>`;
|
|
1213
2899
|
for (const e of edges) {
|
|
1214
|
-
const
|
|
1215
|
-
const
|
|
1216
|
-
if (!
|
|
1217
|
-
const
|
|
1218
|
-
s += `<g><path d="${
|
|
2900
|
+
const A2 = byId.get(e.from);
|
|
2901
|
+
const B2 = byId.get(e.to);
|
|
2902
|
+
if (!A2 || !B2) continue;
|
|
2903
|
+
const p2 = ortho(rectFor2(A2), rectFor2(B2));
|
|
2904
|
+
s += `<g><path d="${p2.d}" fill="none" stroke="#1a1a2e" stroke-width="1.4" marker-end="url(#gArrow)"/>` + edgePill(p2, e.label) + `</g>`;
|
|
1219
2905
|
}
|
|
1220
2906
|
for (const n of nodes) {
|
|
1221
2907
|
const r = rectFor2(n);
|
|
1222
|
-
const
|
|
1223
|
-
const
|
|
2908
|
+
const st2 = dfdStyle(n.kind);
|
|
2909
|
+
const k2 = (n.kind ?? "process").toLowerCase();
|
|
1224
2910
|
let shape;
|
|
1225
|
-
if (
|
|
1226
|
-
shape = `<rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" rx="16" fill="${
|
|
1227
|
-
} else if (
|
|
1228
|
-
shape = `<rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" fill="${
|
|
2911
|
+
if (k2 === "process") {
|
|
2912
|
+
shape = `<rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" rx="16" fill="${st2.fill}" stroke="${st2.stroke}" stroke-width="1.4"/>`;
|
|
2913
|
+
} else if (k2 === "store" || k2 === "datastore") {
|
|
2914
|
+
shape = `<rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" fill="${st2.fill}" stroke="none"/><line x1="${r.x}" y1="${r.y}" x2="${r.x + r.w}" y2="${r.y}" stroke="${st2.stroke}" stroke-width="1.6"/><line x1="${r.x}" y1="${r.y + r.h}" x2="${r.x + r.w}" y2="${r.y + r.h}" stroke="${st2.stroke}" stroke-width="1.6"/><line x1="${r.x}" y1="${r.y}" x2="${r.x}" y2="${r.y + r.h}" stroke="${st2.stroke}" stroke-width="1.6"/>`;
|
|
1229
2915
|
} else {
|
|
1230
|
-
shape = `<rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" fill="${
|
|
2916
|
+
shape = `<rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" fill="${st2.fill}" stroke="${st2.stroke}" stroke-width="1.4"/>`;
|
|
1231
2917
|
}
|
|
1232
|
-
const num = n.num !== void 0 &&
|
|
1233
|
-
s += `<g filter="url(#gshadow)">${shape}${num}<text x="${r.x + r.w / 2}" y="${r.y + r.h / 2 + 4}" class="dfd-name" fill="${
|
|
2918
|
+
const num = n.num !== void 0 && k2 === "process" ? `<text x="${r.x + 12}" y="${r.y + 18}" class="dfd-num" fill="${st2.text}">${escapeHtml(n.num)}</text>` : "";
|
|
2919
|
+
s += `<g filter="url(#gshadow)">${shape}${num}<text x="${r.x + r.w / 2}" y="${r.y + r.h / 2 + 4}" class="dfd-name" fill="${st2.text}">${escapeHtml(n.name)}</text></g>`;
|
|
1234
2920
|
}
|
|
1235
2921
|
s += `</svg>`;
|
|
1236
2922
|
return diagramFrame(
|
|
@@ -1245,34 +2931,34 @@ function renderDfd(data) {
|
|
|
1245
2931
|
}
|
|
1246
2932
|
|
|
1247
2933
|
// src/blocks/journey.ts
|
|
1248
|
-
function clamp01(
|
|
1249
|
-
if (
|
|
1250
|
-
if (
|
|
1251
|
-
return
|
|
2934
|
+
function clamp01(v2) {
|
|
2935
|
+
if (v2 < 0) return 0;
|
|
2936
|
+
if (v2 > 1) return 1;
|
|
2937
|
+
return v2;
|
|
1252
2938
|
}
|
|
1253
2939
|
function renderJourney(data) {
|
|
1254
2940
|
const stages = data.stages ?? [];
|
|
1255
2941
|
const rows = data.rows ?? [];
|
|
1256
2942
|
const emotion = data.emotion ?? [];
|
|
1257
2943
|
const n = Math.max(stages.length, 1);
|
|
1258
|
-
const
|
|
1259
|
-
const
|
|
2944
|
+
const W2 = Math.max(380, n * 150);
|
|
2945
|
+
const H2 = 92;
|
|
1260
2946
|
const pad = 20;
|
|
1261
|
-
const colW = (
|
|
2947
|
+
const colW = (W2 - pad * 2) / n;
|
|
1262
2948
|
const ex = (i) => pad + colW * (i + 0.5);
|
|
1263
|
-
const ey = (
|
|
2949
|
+
const ey = (v2) => H2 - 14 - (H2 - 30) * clamp01(v2);
|
|
1264
2950
|
const head = `<tr><th></th>` + stages.map((s) => `<th class="c">${escapeHtml(s.label)}</th>`).join("") + `</tr>`;
|
|
1265
2951
|
const body = rows.map(
|
|
1266
2952
|
(r) => `<tr><td class="lead">${escapeHtml(r.label)}</td>` + (r.cells ?? []).map((c) => `<td class="c">${escapeHtml(c)}</td>`).join("") + `</tr>`
|
|
1267
2953
|
).join("");
|
|
1268
2954
|
let svg = "";
|
|
1269
2955
|
if (emotion.length > 0) {
|
|
1270
|
-
const points = emotion.map((
|
|
1271
|
-
const dots = emotion.map((
|
|
1272
|
-
const fill =
|
|
1273
|
-
return `<circle cx="${ex(i)}" cy="${ey(
|
|
2956
|
+
const points = emotion.map((v2, i) => `${ex(i)},${ey(v2)}`).join(" ");
|
|
2957
|
+
const dots = emotion.map((v2, i) => {
|
|
2958
|
+
const fill = v2 >= 0.6 ? "#1f9747" : v2 <= 0.35 ? "#991b1b" : "#f7952c";
|
|
2959
|
+
return `<circle cx="${ex(i)}" cy="${ey(v2)}" r="5" fill="${fill}" stroke="#fff" stroke-width="1.5"/>`;
|
|
1274
2960
|
}).join("");
|
|
1275
|
-
svg = `<div style="margin-top:10px"><div style="font-size:10px;color:#6b7280;font-weight:700;text-transform:uppercase;letter-spacing:.08em;margin-bottom:4px">Emotion</div><svg viewBox="0 0 ${
|
|
2961
|
+
svg = `<div style="margin-top:10px"><div style="font-size:10px;color:#6b7280;font-weight:700;text-transform:uppercase;letter-spacing:.08em;margin-bottom:4px">Emotion</div><svg viewBox="0 0 ${W2} ${H2}" style="width:100%" role="img"><title>Emotion curve</title><polyline points="${points}" fill="none" stroke="#0e54a1" stroke-width="2"/>` + dots + `</svg></div>`;
|
|
1276
2962
|
}
|
|
1277
2963
|
return `<div><table class="pres-table"><thead>${head}</thead><tbody>${body}</tbody></table>` + svg + `</div>`;
|
|
1278
2964
|
}
|
|
@@ -1294,7 +2980,7 @@ function ganttColor(kind) {
|
|
|
1294
2980
|
function renderGantt(data) {
|
|
1295
2981
|
const periods = data.periods ?? [];
|
|
1296
2982
|
const tasks = data.tasks ?? [];
|
|
1297
|
-
const
|
|
2983
|
+
const P2 = Math.max(periods.length, 1);
|
|
1298
2984
|
const labelW = 156;
|
|
1299
2985
|
const padX = 20;
|
|
1300
2986
|
const padTop = 34;
|
|
@@ -1302,14 +2988,14 @@ function renderGantt(data) {
|
|
|
1302
2988
|
const barH = 18;
|
|
1303
2989
|
const colW = 64;
|
|
1304
2990
|
const padBot = 14;
|
|
1305
|
-
const width = labelW + padX * 2 +
|
|
2991
|
+
const width = labelW + padX * 2 + P2 * colW;
|
|
1306
2992
|
const height = padTop + tasks.length * rowH + padBot;
|
|
1307
2993
|
const xCol = (i) => labelW + padX + i * colW;
|
|
1308
2994
|
let s = `<svg viewBox="0 0 ${width} ${height}" role="img"><title>Schedule</title>`;
|
|
1309
2995
|
for (let i = 0; i < periods.length; i++) {
|
|
1310
2996
|
s += `<g><line x1="${xCol(i)}" y1="${padTop - 6}" x2="${xCol(i)}" y2="${height - padBot}" stroke="#eef0f3" stroke-width="1"/><text x="${xCol(i) + colW / 2}" y="${padTop - 12}" class="gantt-head">${escapeHtml(periods[i] ?? "")}</text></g>`;
|
|
1311
2997
|
}
|
|
1312
|
-
s += `<line x1="${xCol(
|
|
2998
|
+
s += `<line x1="${xCol(P2)}" y1="${padTop - 6}" x2="${xCol(P2)}" y2="${height - padBot}" stroke="#eef0f3" stroke-width="1"/>`;
|
|
1313
2999
|
for (let i = 0; i < tasks.length; i++) {
|
|
1314
3000
|
const t = tasks[i];
|
|
1315
3001
|
if (t === void 0) continue;
|
|
@@ -1342,21 +3028,21 @@ function renderGraph(data) {
|
|
|
1342
3028
|
const rectFor2 = (n) => {
|
|
1343
3029
|
const cx = cxOf(n.col);
|
|
1344
3030
|
const cy = cyOf(n.row);
|
|
1345
|
-
const
|
|
1346
|
-
return { x: cx -
|
|
3031
|
+
const w2 = Math.max(98, n.label.length * 8 + 26);
|
|
3032
|
+
return { x: cx - w2 / 2, y: cy - 20, w: w2, h: 40, cx, cy };
|
|
1347
3033
|
};
|
|
1348
3034
|
const byId = new Map(nodes.map((n) => [n.id, n]));
|
|
1349
3035
|
const width = padX * 2 + cols * cellW + (cols - 1) * gapX;
|
|
1350
3036
|
const height = padTop + rows * cellH + (rows - 1) * gapY + padBot;
|
|
1351
3037
|
let s = `<svg viewBox="0 0 ${width} ${height}" role="img"><title>Graph</title>`;
|
|
1352
3038
|
for (const e of edges) {
|
|
1353
|
-
const
|
|
1354
|
-
const
|
|
1355
|
-
if (!
|
|
1356
|
-
const
|
|
3039
|
+
const A2 = byId.get(e.from);
|
|
3040
|
+
const B2 = byId.get(e.to);
|
|
3041
|
+
if (!A2 || !B2) continue;
|
|
3042
|
+
const p2 = ortho(rectFor2(A2), rectFor2(B2));
|
|
1357
3043
|
const directed = (e.dir ?? "directed") !== "undirected";
|
|
1358
3044
|
const markerAttr = directed ? ` marker-end="url(#gArrow)"` : "";
|
|
1359
|
-
s += `<g><path d="${
|
|
3045
|
+
s += `<g><path d="${p2.d}" fill="none" stroke="#6b7280" stroke-width="1.4"${markerAttr}/>` + edgePill(p2, e.label) + `</g>`;
|
|
1360
3046
|
}
|
|
1361
3047
|
for (const n of nodes) {
|
|
1362
3048
|
const r = rectFor2(n);
|
|
@@ -1376,28 +3062,28 @@ function renderGraph(data) {
|
|
|
1376
3062
|
}
|
|
1377
3063
|
|
|
1378
3064
|
// src/blocks/quadrant.ts
|
|
1379
|
-
function clamp012(
|
|
1380
|
-
if (
|
|
1381
|
-
if (
|
|
1382
|
-
if (
|
|
1383
|
-
return
|
|
3065
|
+
function clamp012(v2) {
|
|
3066
|
+
if (v2 === void 0 || Number.isNaN(v2)) return 0.5;
|
|
3067
|
+
if (v2 < 0) return 0;
|
|
3068
|
+
if (v2 > 1) return 1;
|
|
3069
|
+
return v2;
|
|
1384
3070
|
}
|
|
1385
3071
|
function renderQuadrant(data) {
|
|
1386
|
-
const
|
|
1387
|
-
const
|
|
3072
|
+
const W2 = 580;
|
|
3073
|
+
const H2 = 440;
|
|
1388
3074
|
const pad = 56;
|
|
1389
3075
|
const x0 = pad;
|
|
1390
|
-
const x1 =
|
|
3076
|
+
const x1 = W2 - pad;
|
|
1391
3077
|
const y0 = pad - 16;
|
|
1392
|
-
const y1 =
|
|
3078
|
+
const y1 = H2 - pad;
|
|
1393
3079
|
const mx = (x0 + x1) / 2;
|
|
1394
3080
|
const my = (y0 + y1) / 2;
|
|
1395
|
-
const px = (
|
|
1396
|
-
const py = (
|
|
3081
|
+
const px = (v2) => x0 + (x1 - x0) * clamp012(v2);
|
|
3082
|
+
const py = (v2) => y1 - (y1 - y0) * clamp012(v2);
|
|
1397
3083
|
const items = data.items ?? [];
|
|
1398
3084
|
const xA = data.xAxis ?? {};
|
|
1399
3085
|
const yA = data.yAxis ?? {};
|
|
1400
|
-
let s = `<svg viewBox="0 0 ${
|
|
3086
|
+
let s = `<svg viewBox="0 0 ${W2} ${H2}" role="img"><title>Quadrant</title>`;
|
|
1401
3087
|
s += `<rect x="${x0}" y="${y0}" width="${x1 - x0}" height="${y1 - y0}" fill="#fafbfc" stroke="#e5e7eb"/>`;
|
|
1402
3088
|
s += `<rect x="${mx}" y="${y0}" width="${x1 - mx}" height="${my - y0}" fill="#0e54a1" fill-opacity="0.04"/>`;
|
|
1403
3089
|
s += `<line x1="${x0}" y1="${my}" x2="${x1}" y2="${my}" class="quad-axis" marker-end="url(#gArrow)"/>`;
|
|
@@ -1414,13 +3100,13 @@ function renderQuadrant(data) {
|
|
|
1414
3100
|
s += `<text x="${x0 - 10}" y="${y0 + 6}" class="quad-end" text-anchor="end">${escapeHtml(yA.high)}</text>`;
|
|
1415
3101
|
if (yA.low !== void 0)
|
|
1416
3102
|
s += `<text x="${x0 - 10}" y="${y1}" class="quad-end" text-anchor="end">${escapeHtml(yA.low)}</text>`;
|
|
1417
|
-
for (const
|
|
1418
|
-
const cx = px(
|
|
1419
|
-
const cy = py(
|
|
3103
|
+
for (const it2 of items) {
|
|
3104
|
+
const cx = px(it2.x);
|
|
3105
|
+
const cy = py(it2.y);
|
|
1420
3106
|
const left = cx > mx;
|
|
1421
3107
|
const tx = cx + (left ? -12 : 12);
|
|
1422
3108
|
const anchor = left ? "end" : "start";
|
|
1423
|
-
s += `<g filter="url(#gshadow)"><circle cx="${cx}" cy="${cy}" r="7" fill="#f7952c" stroke="#fff" stroke-width="1.5"/><text x="${tx}" y="${cy + 4}" class="quad-pt-label" text-anchor="${anchor}">${escapeHtml(
|
|
3109
|
+
s += `<g filter="url(#gshadow)"><circle cx="${cx}" cy="${cy}" r="7" fill="#f7952c" stroke="#fff" stroke-width="1.5"/><text x="${tx}" y="${cy + 4}" class="quad-pt-label" text-anchor="${anchor}">${escapeHtml(it2.label)}</text></g>`;
|
|
1424
3110
|
}
|
|
1425
3111
|
s += `</svg>`;
|
|
1426
3112
|
return diagramFrame(
|
|
@@ -1475,23 +3161,23 @@ function renderSwimlane(data) {
|
|
|
1475
3161
|
const height = padTop + lanes.length * laneH + padBot;
|
|
1476
3162
|
let s = `<svg viewBox="0 0 ${width} ${height}" role="img"><title>Swimlane</title>`;
|
|
1477
3163
|
for (let i = 0; i < lanes.length; i++) {
|
|
1478
|
-
const
|
|
1479
|
-
if (
|
|
1480
|
-
s += `<g><rect x="${padX}" y="${yLane(i)}" width="${width - padX * 2}" height="${laneH}" fill="${i % 2 ? "#fafafa" : "#fff"}" stroke="#e5e7eb"/><rect x="${padX}" y="${yLane(i)}" width="${labelW}" height="${laneH}" fill="#0e54a1"/><text x="${padX + 14}" y="${yLane(i) + laneH / 2 + 4}" class="sl-lane-label">${escapeHtml(
|
|
3164
|
+
const L2 = lanes[i];
|
|
3165
|
+
if (L2 === void 0) continue;
|
|
3166
|
+
s += `<g><rect x="${padX}" y="${yLane(i)}" width="${width - padX * 2}" height="${laneH}" fill="${i % 2 ? "#fafafa" : "#fff"}" stroke="#e5e7eb"/><rect x="${padX}" y="${yLane(i)}" width="${labelW}" height="${laneH}" fill="#0e54a1"/><text x="${padX + 14}" y="${yLane(i) + laneH / 2 + 4}" class="sl-lane-label">${escapeHtml(L2.label)}</text></g>`;
|
|
1481
3167
|
}
|
|
1482
3168
|
for (const lk of links) {
|
|
1483
|
-
const
|
|
1484
|
-
const
|
|
1485
|
-
if (!
|
|
1486
|
-
const
|
|
1487
|
-
s += `<g><path d="${
|
|
1488
|
-
}
|
|
1489
|
-
for (const
|
|
1490
|
-
const r = rectFor2(
|
|
1491
|
-
const c = laneColor(
|
|
1492
|
-
const lines = wrapText(
|
|
3169
|
+
const A2 = byId.get(lk.from);
|
|
3170
|
+
const B2 = byId.get(lk.to);
|
|
3171
|
+
if (!A2 || !B2) continue;
|
|
3172
|
+
const p2 = ortho(rectFor2(A2), rectFor2(B2));
|
|
3173
|
+
s += `<g><path d="${p2.d}" fill="none" stroke="#1a1a2e" stroke-width="1.4" marker-end="url(#gArrow)"/>` + edgePill(p2, lk.label) + `</g>`;
|
|
3174
|
+
}
|
|
3175
|
+
for (const st2 of steps) {
|
|
3176
|
+
const r = rectFor2(st2);
|
|
3177
|
+
const c = laneColor(st2.kind);
|
|
3178
|
+
const lines = wrapText(st2.label, 20, 2);
|
|
1493
3179
|
const texts = lines.map(
|
|
1494
|
-
(
|
|
3180
|
+
(ln2, j2) => `<text x="${r.x + r.w / 2}" y="${r.y + r.h / 2 + 4 - (lines.length - 1) * 7 + j2 * 14}" class="sl-step" fill="${c.text}">${escapeHtml(ln2)}</text>`
|
|
1495
3181
|
).join("");
|
|
1496
3182
|
s += `<g filter="url(#gshadow)"><rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" rx="7" fill="${c.fill}" stroke="${c.stroke}" stroke-width="1.3"/>` + texts + `</g>`;
|
|
1497
3183
|
}
|
|
@@ -1555,35 +3241,35 @@ function blockStyle(kind) {
|
|
|
1555
3241
|
return { accent: "#374151", fill: "#fff", text: "#1a1a2e" };
|
|
1556
3242
|
}
|
|
1557
3243
|
}
|
|
1558
|
-
function nodeGlyph(kind,
|
|
1559
|
-
const
|
|
1560
|
-
if (
|
|
1561
|
-
return `<g stroke="${c}" stroke-width="1.3" fill="none"><ellipse cx="${
|
|
3244
|
+
function nodeGlyph(kind, x2, y, c) {
|
|
3245
|
+
const k2 = (kind ?? "").toLowerCase();
|
|
3246
|
+
if (k2 === "store" || k2 === "db" || k2 === "database") {
|
|
3247
|
+
return `<g stroke="${c}" stroke-width="1.3" fill="none"><ellipse cx="${x2 + 8}" cy="${y + 3}" rx="7" ry="3"/><path d="M${x2 + 1} ${y + 3} V ${y + 13}"/><path d="M${x2 + 15} ${y + 3} V ${y + 13}"/><path d="M${x2 + 1} ${y + 13} a 7 3 0 0 0 14 0"/></g>`;
|
|
1562
3248
|
}
|
|
1563
|
-
if (
|
|
1564
|
-
return `<g stroke="${c}" stroke-width="1.3" fill="none"><ellipse cx="${
|
|
3249
|
+
if (k2 === "bucket" || k2 === "blob" || k2 === "object") {
|
|
3250
|
+
return `<g stroke="${c}" stroke-width="1.3" fill="none"><ellipse cx="${x2 + 8}" cy="${y + 3}" rx="7" ry="2.5"/><path d="M${x2 + 1.5} ${y + 3} L ${x2 + 3.5} ${y + 14} L ${x2 + 12.5} ${y + 14} L ${x2 + 14.5} ${y + 3}"/></g>`;
|
|
1565
3251
|
}
|
|
1566
|
-
if (
|
|
1567
|
-
return `<g stroke="${c}" stroke-width="1.6"><path d="M${
|
|
3252
|
+
if (k2 === "queue" || k2 === "topic") {
|
|
3253
|
+
return `<g stroke="${c}" stroke-width="1.6"><path d="M${x2 + 2} ${y + 1} V ${y + 14}"/><path d="M${x2 + 8} ${y + 1} V ${y + 14}"/><path d="M${x2 + 14} ${y + 1} V ${y + 14}"/></g>`;
|
|
1568
3254
|
}
|
|
1569
|
-
if (
|
|
1570
|
-
return `<path d="M${
|
|
3255
|
+
if (k2 === "firewall") {
|
|
3256
|
+
return `<path d="M${x2 + 8} ${y} L ${x2 + 15} ${y + 3} V ${y + 9} Q ${x2 + 15} ${y + 14} ${x2 + 8} ${y + 16} Q ${x2 + 1} ${y + 14} ${x2 + 1} ${y + 9} V ${y + 3} Z" fill="none" stroke="${c}" stroke-width="1.3"/>`;
|
|
1571
3257
|
}
|
|
1572
|
-
if (
|
|
1573
|
-
const slab = (dy) => `<path d="M${
|
|
3258
|
+
if (k2 === "cache") {
|
|
3259
|
+
const slab = (dy) => `<path d="M${x2 + 1} ${y + 5 + dy} L${x2 + 8} ${y + 2 + dy} L${x2 + 15} ${y + 5 + dy} L${x2 + 8} ${y + 8 + dy} Z" fill="none" stroke="${c}" stroke-width="1.2"/>`;
|
|
1574
3260
|
return `<g>${slab(0)}${slab(3.5)}${slab(7)}</g>`;
|
|
1575
3261
|
}
|
|
1576
|
-
if (
|
|
1577
|
-
return `<text x="${
|
|
3262
|
+
if (k2 === "function" || k2 === "lambda") {
|
|
3263
|
+
return `<text x="${x2 + 7}" y="${y + 14}" font-family="Georgia, serif" font-size="17" font-style="italic" font-weight="700" fill="${c}" text-anchor="middle">\u0192</text>`;
|
|
1578
3264
|
}
|
|
1579
|
-
if (
|
|
1580
|
-
return `<path d="M${
|
|
3265
|
+
if (k2 === "cdn" || k2 === "external") {
|
|
3266
|
+
return `<path d="M${x2 + 3} ${y + 13} a 4 4 0 0 1 0.5 -8 a 5 5 0 0 1 9.5 1.2 a 3 3 0 0 1 1 6.8 z" fill="none" stroke="${c}" stroke-width="1.3"/>`;
|
|
1581
3267
|
}
|
|
1582
|
-
if (
|
|
1583
|
-
return `<g stroke="${c}" stroke-width="1.5" fill="none"><path d="M${
|
|
3268
|
+
if (k2 === "gateway" || k2 === "lb") {
|
|
3269
|
+
return `<g stroke="${c}" stroke-width="1.5" fill="none"><path d="M${x2 + 2} ${y + 1} L ${x2 + 8} ${y + 7} L ${x2 + 2} ${y + 13}"/><path d="M${x2 + 8} ${y + 1} L ${x2 + 14} ${y + 7} L ${x2 + 8} ${y + 13}"/></g>`;
|
|
1584
3270
|
}
|
|
1585
|
-
if (
|
|
1586
|
-
return `<g stroke="${c}" stroke-width="1.3"><rect x="${
|
|
3271
|
+
if (k2 === "service" || k2 === "microservice" || k2 === "compute" || k2 === "container") {
|
|
3272
|
+
return `<g stroke="${c}" stroke-width="1.3"><rect x="${x2 + 4}" y="${y + 1}" width="11" height="11" rx="1.5" fill="none"/><rect x="${x2 + 1}" y="${y + 4}" width="11" height="11" rx="1.5" fill="#fff"/></g>`;
|
|
1587
3273
|
}
|
|
1588
3274
|
return "";
|
|
1589
3275
|
}
|
|
@@ -1743,42 +3429,42 @@ function renderC4(data) {
|
|
|
1743
3429
|
const minY = Math.min(...internals.map((r) => r.y)) - 26;
|
|
1744
3430
|
const maxX = Math.max(...internals.map((r) => r.x + r.w)) + 16;
|
|
1745
3431
|
const maxY = Math.max(...internals.map((r) => r.y + r.h)) + 16;
|
|
1746
|
-
const
|
|
1747
|
-
boundarySvg = `<g><rect x="${minX}" y="${minY}" width="${maxX - minX}" height="${maxY - minY}" rx="12" class="c4-boundary"/><rect x="${minX + 12}" y="${minY - 8}" width="${
|
|
3432
|
+
const w2 = Math.max(120, data.boundary.label.length * 6.2);
|
|
3433
|
+
boundarySvg = `<g><rect x="${minX}" y="${minY}" width="${maxX - minX}" height="${maxY - minY}" rx="12" class="c4-boundary"/><rect x="${minX + 12}" y="${minY - 8}" width="${w2}" height="16" fill="#fff"/><text x="${minX + 16}" y="${minY + 4}" class="c4-boundary-label">${escapeHtml(data.boundary.label)}</text></g>`;
|
|
1748
3434
|
}
|
|
1749
3435
|
}
|
|
1750
3436
|
let s = `<svg viewBox="0 0 ${width} ${height}" role="img"><title>C4 diagram</title>${boundarySvg}`;
|
|
1751
3437
|
for (const e of edges) {
|
|
1752
|
-
const
|
|
1753
|
-
const
|
|
1754
|
-
if (!
|
|
1755
|
-
const
|
|
1756
|
-
const
|
|
3438
|
+
const A2 = byId.get(e.from);
|
|
3439
|
+
const B2 = byId.get(e.to);
|
|
3440
|
+
if (!A2 || !B2) continue;
|
|
3441
|
+
const p2 = ortho(rectFor2(A2), rectFor2(B2));
|
|
3442
|
+
const st2 = GEDGE[e.kind ?? "solid"] ?? GEDGE["solid"] ?? {
|
|
1757
3443
|
stroke: "#1a1a2e",
|
|
1758
3444
|
sw: 1.4,
|
|
1759
3445
|
dash: "",
|
|
1760
3446
|
marker: "gArrow",
|
|
1761
3447
|
err: false
|
|
1762
3448
|
};
|
|
1763
|
-
s += `<g><path d="${
|
|
3449
|
+
s += `<g><path d="${p2.d}" fill="none" stroke="${st2.stroke}" stroke-width="${st2.sw}" stroke-dasharray="${st2.dash}" marker-end="url(#${st2.marker})"/>` + edgePill(p2, e.label, st2.err) + `</g>`;
|
|
1764
3450
|
}
|
|
1765
3451
|
for (const n of nodes) {
|
|
1766
3452
|
const r = rectFor2(n);
|
|
1767
|
-
const
|
|
3453
|
+
const st2 = c4Style(n);
|
|
1768
3454
|
const px = r.x + 16;
|
|
1769
3455
|
const desc = wrapText(n.desc, 30, 2);
|
|
1770
|
-
const strokeWidth =
|
|
1771
|
-
const strokeAttr =
|
|
1772
|
-
const dashAttr =
|
|
1773
|
-
const stripe =
|
|
1774
|
-
const personGlyph = n.kind === "person" ? `<g fill="${
|
|
3456
|
+
const strokeWidth = st2.solid === true ? 0 : 1.2;
|
|
3457
|
+
const strokeAttr = st2.solid === true ? "none" : st2.accent;
|
|
3458
|
+
const dashAttr = st2.dash !== void 0 ? ` stroke-dasharray="${st2.dash}"` : "";
|
|
3459
|
+
const stripe = st2.solid === true ? "" : `<rect x="${r.x}" y="${r.y}" width="5" height="${r.h}" rx="2" fill="${st2.accent}"/>`;
|
|
3460
|
+
const personGlyph = n.kind === "person" ? `<g fill="${st2.text}"><circle cx="${px + 6}" cy="${r.y + 19}" r="6"/><path d="M ${px} ${r.y + 34} a 6 7 0 0 1 12 0 z"/></g>` : "";
|
|
1775
3461
|
const chipX = n.kind === "person" ? px + 22 : px;
|
|
1776
|
-
const chipFill =
|
|
1777
|
-
const techLine = n.tech !== void 0 ? `<text x="${px}" y="${r.y + 60}" class="c4-tech" fill="${
|
|
3462
|
+
const chipFill = st2.solid === true ? st2.sub : st2.accent;
|
|
3463
|
+
const techLine = n.tech !== void 0 ? `<text x="${px}" y="${r.y + 60}" class="c4-tech" fill="${st2.sub}">${escapeHtml(n.tech)}</text>` : "";
|
|
1778
3464
|
const descLines = desc.map(
|
|
1779
|
-
(
|
|
3465
|
+
(ln2, j2) => `<text x="${px}" y="${r.y + 77 + j2 * 13}" class="c4-desc" fill="${st2.sub}">${escapeHtml(ln2)}</text>`
|
|
1780
3466
|
).join("");
|
|
1781
|
-
s += `<g filter="url(#gshadow)"><rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" rx="10" fill="${
|
|
3467
|
+
s += `<g filter="url(#gshadow)"><rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" rx="10" fill="${st2.fill}" stroke="${strokeAttr}" stroke-width="${strokeWidth}"${dashAttr}/>` + stripe + personGlyph + `<text x="${chipX}" y="${r.y + 22}" class="c4-chip" fill="${chipFill}">${escapeHtml(st2.chip)}</text><text x="${px}" y="${r.y + 44}" class="c4-name" fill="${st2.text}">${escapeHtml(n.name)}</text>` + techLine + descLines + `</g>`;
|
|
1782
3468
|
}
|
|
1783
3469
|
s += `</svg>`;
|
|
1784
3470
|
const legend = `<div class="legend">` + LEGEND.map(
|
|
@@ -1851,14 +3537,14 @@ function renderUml(data) {
|
|
|
1851
3537
|
const height = acc - gapY + padBot;
|
|
1852
3538
|
let s = `<svg viewBox="0 0 ${width} ${height}" role="img"><title>UML class diagram</title><defs><marker id="umlTri" viewBox="0 0 14 14" refX="13" refY="7" markerWidth="15" markerHeight="15" orient="auto-start-reverse"><path d="M1,1 L13,7 L1,13 z" fill="#fff" stroke="#1a1a2e" stroke-width="1.2"/></marker><marker id="umlDiaF" viewBox="0 0 20 12" refX="19" refY="6" markerWidth="20" markerHeight="12" orient="auto-start-reverse"><path d="M1,6 L10,1 L19,6 L10,11 z" fill="#1a1a2e"/></marker><marker id="umlDiaH" viewBox="0 0 20 12" refX="19" refY="6" markerWidth="20" markerHeight="12" orient="auto-start-reverse"><path d="M1,6 L10,1 L19,6 L10,11 z" fill="#fff" stroke="#1a1a2e" stroke-width="1.2"/></marker><marker id="umlOpen" viewBox="0 0 12 12" refX="10" refY="6" markerWidth="12" markerHeight="12" orient="auto-start-reverse"><path d="M1,1 L11,6 L1,11" fill="none" stroke="#1a1a2e" stroke-width="1.3"/></marker></defs>`;
|
|
1853
3539
|
for (const rl of rels) {
|
|
1854
|
-
const
|
|
1855
|
-
const
|
|
1856
|
-
if (!
|
|
1857
|
-
const
|
|
1858
|
-
const
|
|
1859
|
-
const start =
|
|
1860
|
-
const end =
|
|
1861
|
-
s += `<g><path d="${
|
|
3540
|
+
const A2 = byId.get(rl.from);
|
|
3541
|
+
const B2 = byId.get(rl.to);
|
|
3542
|
+
if (!A2 || !B2) continue;
|
|
3543
|
+
const p2 = ortho(rectFor2(A2), rectFor2(B2));
|
|
3544
|
+
const st2 = umlRel(rl.kind);
|
|
3545
|
+
const start = st2.start !== void 0 ? ` marker-start="url(#${st2.start})"` : "";
|
|
3546
|
+
const end = st2.end !== void 0 ? ` marker-end="url(#${st2.end})"` : "";
|
|
3547
|
+
s += `<g><path d="${p2.d}" fill="none" stroke="#1a1a2e" stroke-width="1.3" stroke-dasharray="${st2.dash}"${start}${end}/>` + edgePill(p2, rl.label) + `</g>`;
|
|
1862
3548
|
}
|
|
1863
3549
|
for (const c of classes) {
|
|
1864
3550
|
const r = rectFor2(c);
|
|
@@ -1867,10 +3553,10 @@ function renderUml(data) {
|
|
|
1867
3553
|
const nameY = r.y + (c.stereotype !== void 0 ? 24 : 19);
|
|
1868
3554
|
const stereo = c.stereotype !== void 0 ? `<text x="${r.x + r.w / 2}" y="${r.y + 13}" class="uml-stereo">\xAB${escapeHtml(c.stereotype)}\xBB</text>` : "";
|
|
1869
3555
|
const attrs = (c.attrs ?? []).map(
|
|
1870
|
-
(a,
|
|
3556
|
+
(a, j2) => `<text x="${r.x + 10}" y="${r.y + hh + 14 + j2 * rowH}" class="uml-row">${escapeHtml(a)}</text>`
|
|
1871
3557
|
).join("");
|
|
1872
3558
|
const methods = (c.methods ?? []).map(
|
|
1873
|
-
(m,
|
|
3559
|
+
(m, j2) => `<text x="${r.x + 10}" y="${r.y + hh + aH + 14 + j2 * rowH}" class="uml-row">${escapeHtml(m)}</text>`
|
|
1874
3560
|
).join("");
|
|
1875
3561
|
s += `<g filter="url(#gshadow)"><rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" rx="3" fill="#fff" stroke="#0e54a1" stroke-width="1.3"/>` + stereo + `<text x="${r.x + r.w / 2}" y="${nameY}" class="uml-name">${escapeHtml(c.name)}</text><line x1="${r.x}" y1="${r.y + hh}" x2="${r.x + r.w}" y2="${r.y + hh}" class="uml-sep"/>` + attrs + `<line x1="${r.x}" y1="${r.y + hh + aH}" x2="${r.x + r.w}" y2="${r.y + hh + aH}" class="uml-sep"/>` + methods + `</g>`;
|
|
1876
3562
|
}
|
|
@@ -1951,20 +3637,20 @@ function renderMece(data) {
|
|
|
1951
3637
|
}
|
|
1952
3638
|
for (const n of nodes) {
|
|
1953
3639
|
if (!pos.has(n.id)) continue;
|
|
1954
|
-
const
|
|
3640
|
+
const x2 = xOf(n.id);
|
|
1955
3641
|
const y = yOf(n.id);
|
|
1956
|
-
const
|
|
1957
|
-
const stroke =
|
|
1958
|
-
const stripe =
|
|
1959
|
-
const labelX =
|
|
1960
|
-
const anchor =
|
|
1961
|
-
const lines = wrapText(n.label,
|
|
3642
|
+
const st2 = meceStyle(depth.get(n.id) ?? 0);
|
|
3643
|
+
const stroke = st2.solid === true ? "none" : st2.accent;
|
|
3644
|
+
const stripe = st2.solid === true ? "" : `<rect x="${x2}" y="${y}" width="5" height="${nodeH}" rx="2" fill="${st2.accent}"/>`;
|
|
3645
|
+
const labelX = x2 + (st2.solid === true ? nodeW / 2 : 14);
|
|
3646
|
+
const anchor = st2.solid === true ? "middle" : "start";
|
|
3647
|
+
const lines = wrapText(n.label, st2.solid === true ? 22 : 20, n.note !== void 0 ? 1 : 2);
|
|
1962
3648
|
const startY = lines.length === 2 ? y + 22 : y + (n.note !== void 0 ? 22 : 30);
|
|
1963
3649
|
const labelTexts = lines.map(
|
|
1964
|
-
(
|
|
3650
|
+
(ln2, j2) => `<text x="${labelX}" y="${startY + j2 * 14}" class="blk-name" fill="${st2.text}" text-anchor="${anchor}">${escapeHtml(ln2)}</text>`
|
|
1965
3651
|
).join("");
|
|
1966
|
-
const note = n.note !== void 0 ? `<text x="${labelX}" y="${y + 38}" class="ft-note" fill="${
|
|
1967
|
-
s += `<g filter="url(#gshadow)"><rect x="${
|
|
3652
|
+
const note = n.note !== void 0 ? `<text x="${labelX}" y="${y + 38}" class="ft-note" fill="${st2.solid === true ? "#cfe0f3" : st2.accent}" text-anchor="${anchor}">${escapeHtml(n.note)}</text>` : "";
|
|
3653
|
+
s += `<g filter="url(#gshadow)"><rect x="${x2}" y="${y}" width="${nodeW}" height="${nodeH}" rx="6" fill="${st2.fill}" stroke="${stroke}" stroke-width="1.3"/>` + stripe + labelTexts + note + `</g>`;
|
|
1968
3654
|
}
|
|
1969
3655
|
s += `</svg>`;
|
|
1970
3656
|
return diagramFrame(
|
|
@@ -2062,20 +3748,20 @@ function renderFrontend(data) {
|
|
|
2062
3748
|
}
|
|
2063
3749
|
for (const n of nodes) {
|
|
2064
3750
|
if (!pos.has(n.id)) continue;
|
|
2065
|
-
const
|
|
3751
|
+
const x2 = xOf(n.id);
|
|
2066
3752
|
const y = yOf(n.id);
|
|
2067
|
-
const
|
|
2068
|
-
const stroke =
|
|
2069
|
-
const stripe =
|
|
2070
|
-
const labelX =
|
|
2071
|
-
const anchor =
|
|
2072
|
-
const lines = wrapText(n.name,
|
|
3753
|
+
const st2 = ftStyle(n.kind);
|
|
3754
|
+
const stroke = st2.solid === true ? "none" : st2.accent;
|
|
3755
|
+
const stripe = st2.solid === true ? "" : `<rect x="${x2}" y="${y}" width="5" height="${nodeH}" rx="2" fill="${st2.accent}"/>`;
|
|
3756
|
+
const labelX = x2 + (st2.solid === true ? nodeW / 2 : 14);
|
|
3757
|
+
const anchor = st2.solid === true ? "middle" : "start";
|
|
3758
|
+
const lines = wrapText(n.name, st2.solid === true ? 20 : 18, n.note !== void 0 ? 1 : 2);
|
|
2073
3759
|
const startY = lines.length === 2 ? y + 25 : y + (n.note !== void 0 ? 25 : 33);
|
|
2074
3760
|
const labelTexts = lines.map(
|
|
2075
|
-
(
|
|
3761
|
+
(ln2, j2) => `<text x="${labelX}" y="${startY + j2 * 14}" class="blk-name" fill="${st2.text}" text-anchor="${anchor}">${escapeHtml(ln2)}</text>`
|
|
2076
3762
|
).join("");
|
|
2077
|
-
const note = n.note !== void 0 ? `<text x="${labelX}" y="${y + 41}" class="ft-note" fill="${
|
|
2078
|
-
s += `<g filter="url(#gshadow)"><rect x="${
|
|
3763
|
+
const note = n.note !== void 0 ? `<text x="${labelX}" y="${y + 41}" class="ft-note" fill="${st2.solid === true ? "#cfe0f3" : st2.accent}" text-anchor="${anchor}">${escapeHtml(n.note)}</text>` : "";
|
|
3764
|
+
s += `<g filter="url(#gshadow)"><rect x="${x2}" y="${y}" width="${nodeW}" height="${nodeH}" rx="8" fill="${st2.fill}" stroke="${stroke}" stroke-width="1.2"/>` + stripe + labelTexts + note + `</g>`;
|
|
2079
3765
|
}
|
|
2080
3766
|
s += `</svg>`;
|
|
2081
3767
|
return diagramFrame(
|
|
@@ -2144,36 +3830,36 @@ function renderCluster(data) {
|
|
|
2144
3830
|
s += `<g><rect x="${cb.x}" y="${cb.y}" width="${cb.w}" height="${cb.h}" rx="12" fill="#0e54a1" fill-opacity="0.035" stroke="#0e54a1" stroke-width="1.4" stroke-dasharray="8 5"/><rect x="${cb.x}" y="${cb.y}" width="${cb.w}" height="${cHeader}" rx="12" fill="#0e54a1"/><rect x="${cb.x}" y="${cb.y + cHeader - 12}" width="${cb.w}" height="12" fill="#0e54a1"/><text x="${cb.x + 16}" y="${cb.y + 21}" class="cl-head">${escapeHtml(cb.c.label)}</text>` + kindLabel + `</g>`;
|
|
2145
3831
|
}
|
|
2146
3832
|
for (const e of edges) {
|
|
2147
|
-
const
|
|
2148
|
-
const
|
|
2149
|
-
if (!
|
|
2150
|
-
const
|
|
2151
|
-
const
|
|
3833
|
+
const A2 = rects.get(e.from);
|
|
3834
|
+
const B2 = rects.get(e.to);
|
|
3835
|
+
if (!A2 || !B2) continue;
|
|
3836
|
+
const p2 = ortho(A2, B2);
|
|
3837
|
+
const st2 = GEDGE[e.kind ?? "solid"] ?? GEDGE["solid"] ?? {
|
|
2152
3838
|
stroke: "#1a1a2e",
|
|
2153
3839
|
sw: 1.4,
|
|
2154
3840
|
dash: "",
|
|
2155
3841
|
marker: "gArrow",
|
|
2156
3842
|
err: false
|
|
2157
3843
|
};
|
|
2158
|
-
s += `<g><path d="${
|
|
3844
|
+
s += `<g><path d="${p2.d}" fill="none" stroke="${st2.stroke}" stroke-width="${st2.sw}" stroke-dasharray="${st2.dash}" marker-end="url(#${st2.marker})"/>` + edgePill(p2, e.label, st2.err) + `</g>`;
|
|
2159
3845
|
}
|
|
2160
3846
|
for (const sv of services) {
|
|
2161
3847
|
const r = rects.get(sv.id);
|
|
2162
3848
|
if (r === void 0) continue;
|
|
2163
|
-
const
|
|
2164
|
-
const gl = nodeGlyph(sv.kind, r.x + 14, r.y + 14,
|
|
3849
|
+
const st2 = blockStyle(sv.kind);
|
|
3850
|
+
const gl = nodeGlyph(sv.kind, r.x + 14, r.y + 14, st2.accent);
|
|
2165
3851
|
const nx = gl.length > 0 ? r.x + 38 : r.x + 14;
|
|
2166
3852
|
const reps = sv.replicas ?? 0;
|
|
2167
|
-
const techLine = sv.tech !== void 0 ? `<text x="${nx}" y="${r.y + 42}" class="blk-tech" fill="${
|
|
3853
|
+
const techLine = sv.tech !== void 0 ? `<text x="${nx}" y="${r.y + 42}" class="blk-tech" fill="${st2.accent}">${escapeHtml(sv.tech)}</text>` : "";
|
|
2168
3854
|
const repIndicator = reps > 0 ? (() => {
|
|
2169
3855
|
const shown = Math.min(reps, 5);
|
|
2170
3856
|
let bars = "";
|
|
2171
|
-
for (let
|
|
2172
|
-
bars += `<rect x="${r.x + 12 +
|
|
3857
|
+
for (let j2 = 0; j2 < shown; j2++) {
|
|
3858
|
+
bars += `<rect x="${r.x + 12 + j2 * 8}" y="${r.y + r.h - 14}" width="5" height="8" rx="1" fill="${st2.accent}" opacity="0.7"/>`;
|
|
2173
3859
|
}
|
|
2174
|
-
return `<g>` + bars + `<text x="${r.x + 12 + shown * 8 + 4}" y="${r.y + r.h - 7}" class="blk-tech" fill="${
|
|
3860
|
+
return `<g>` + bars + `<text x="${r.x + 12 + shown * 8 + 4}" y="${r.y + r.h - 7}" class="blk-tech" fill="${st2.accent}">\xD7${reps}</text></g>`;
|
|
2175
3861
|
})() : "";
|
|
2176
|
-
s += `<g filter="url(#gshadow)"><rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" rx="8" fill="${
|
|
3862
|
+
s += `<g filter="url(#gshadow)"><rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" rx="8" fill="${st2.fill}" stroke="${st2.accent}" stroke-width="1.2"/><rect x="${r.x}" y="${r.y}" width="5" height="${r.h}" rx="2" fill="${st2.accent}"/>` + gl + `<text x="${nx}" y="${r.y + (sv.tech !== void 0 ? 26 : 30)}" class="blk-name" fill="${st2.text}" style="font-size:12px">${escapeHtml(sv.label)}</text>` + techLine + repIndicator + `</g>`;
|
|
2177
3863
|
}
|
|
2178
3864
|
s += `</svg>`;
|
|
2179
3865
|
return diagramFrame(
|
|
@@ -2247,21 +3933,21 @@ function renderGrid(data) {
|
|
|
2247
3933
|
s += `<g>${zone}${label}</g>`;
|
|
2248
3934
|
}
|
|
2249
3935
|
for (const e of edges) {
|
|
2250
|
-
const
|
|
2251
|
-
const
|
|
2252
|
-
if (!
|
|
2253
|
-
const
|
|
2254
|
-
const
|
|
2255
|
-
s += `<g><path d="${
|
|
3936
|
+
const A2 = byId.get(e.from);
|
|
3937
|
+
const B2 = byId.get(e.to);
|
|
3938
|
+
if (!A2 || !B2) continue;
|
|
3939
|
+
const p2 = ortho(rectFor2(A2), rectFor2(B2));
|
|
3940
|
+
const st2 = GEDGE[e.kind ?? "solid"] ?? GEDGE["solid"] ?? FALLBACK_EDGE;
|
|
3941
|
+
s += `<g><path d="${p2.d}" fill="none" stroke="${st2.stroke}" stroke-width="${st2.sw}" stroke-dasharray="${st2.dash}" marker-end="url(#${st2.marker})"/>` + edgePill(p2, e.label, st2.err) + `</g>`;
|
|
2256
3942
|
}
|
|
2257
3943
|
for (const n of nodes) {
|
|
2258
3944
|
const r = rectFor2(n);
|
|
2259
|
-
const
|
|
2260
|
-
const gl = nodeGlyph(n.kind, r.x + 16, r.y + 16,
|
|
3945
|
+
const st2 = blockStyle(n.kind);
|
|
3946
|
+
const gl = nodeGlyph(n.kind, r.x + 16, r.y + 16, st2.accent);
|
|
2261
3947
|
const nx = gl.length > 0 ? r.x + 42 : r.x + 16;
|
|
2262
|
-
const chip = gl.length === 0 && n.kind !== void 0 ? `<text x="${r.x + 16}" y="${r.y + 22}" class="blk-chip" fill="${
|
|
2263
|
-
const tech = n.tech !== void 0 ? `<text x="${nx}" y="${r.y + (gl.length > 0 ? 50 : 60)}" class="blk-tech" fill="${
|
|
2264
|
-
s += `<g filter="url(#gshadow)"><rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" rx="9" fill="${
|
|
3948
|
+
const chip = gl.length === 0 && n.kind !== void 0 ? `<text x="${r.x + 16}" y="${r.y + 22}" class="blk-chip" fill="${st2.accent}">${escapeHtml(n.kind)}</text>` : "";
|
|
3949
|
+
const tech = n.tech !== void 0 ? `<text x="${nx}" y="${r.y + (gl.length > 0 ? 50 : 60)}" class="blk-tech" fill="${st2.accent}">${escapeHtml(n.tech)}</text>` : "";
|
|
3950
|
+
s += `<g filter="url(#gshadow)"><rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" rx="9" fill="${st2.fill}" stroke="${st2.accent}" stroke-width="1.2"/><rect x="${r.x}" y="${r.y}" width="5" height="${r.h}" rx="2" fill="${st2.accent}"/>` + gl + chip + `<text x="${nx}" y="${r.y + (gl.length > 0 ? 34 : 44)}" class="blk-name" fill="${st2.text}">${escapeHtml(n.name)}</text>` + tech + `</g>`;
|
|
2265
3951
|
}
|
|
2266
3952
|
s += `</svg>`;
|
|
2267
3953
|
return s;
|
|
@@ -2271,7 +3957,7 @@ function renderLayered(data) {
|
|
|
2271
3957
|
const nodes = data.nodes ?? [];
|
|
2272
3958
|
const edges = data.edges ?? [];
|
|
2273
3959
|
const byLayer = layers.map(
|
|
2274
|
-
(
|
|
3960
|
+
(_2, i) => nodes.filter((n) => (n.layer ?? 0) === i)
|
|
2275
3961
|
);
|
|
2276
3962
|
const outerPad = 28;
|
|
2277
3963
|
const titleH = data.systemLabel !== void 0 ? 32 : 16;
|
|
@@ -2295,9 +3981,9 @@ function renderLayered(data) {
|
|
|
2295
3981
|
const rects = /* @__PURE__ */ new Map();
|
|
2296
3982
|
byLayer.forEach((arr, i) => {
|
|
2297
3983
|
const startX = contentX + (bandInnerW - rowW(arr.length)) / 2;
|
|
2298
|
-
arr.forEach((n,
|
|
3984
|
+
arr.forEach((n, j2) => {
|
|
2299
3985
|
rects.set(n.id, {
|
|
2300
|
-
x: startX +
|
|
3986
|
+
x: startX + j2 * (nodeW + nodeGap),
|
|
2301
3987
|
y: bandY(i) + bandPadY,
|
|
2302
3988
|
w: nodeW,
|
|
2303
3989
|
h: nodeH
|
|
@@ -2309,26 +3995,26 @@ function renderLayered(data) {
|
|
|
2309
3995
|
s += `<text x="${outerPad + 14}" y="${outerPad + 18}" class="grp-label" fill="#0e54a1">${escapeHtml(data.systemLabel)}</text>`;
|
|
2310
3996
|
}
|
|
2311
3997
|
for (let i = 0; i < layers.length; i++) {
|
|
2312
|
-
const
|
|
2313
|
-
if (
|
|
2314
|
-
s += `<g><rect x="${innerX}" y="${bandY(i)}" width="${labelW + bandInnerW}" height="${bandH}" rx="6" fill="#f3f4f6" stroke="#d1d5db"/><rect x="${innerX}" y="${bandY(i)}" width="${labelW}" height="${bandH}" rx="6" fill="#0e54a1"/><rect x="${innerX + labelW - 8}" y="${bandY(i)}" width="8" height="${bandH}" fill="#0e54a1"/><text x="${innerX + 14}" y="${bandY(i) + bandH / 2 + 4}" class="layer-label">${escapeHtml(
|
|
3998
|
+
const L2 = layers[i];
|
|
3999
|
+
if (L2 === void 0) continue;
|
|
4000
|
+
s += `<g><rect x="${innerX}" y="${bandY(i)}" width="${labelW + bandInnerW}" height="${bandH}" rx="6" fill="#f3f4f6" stroke="#d1d5db"/><rect x="${innerX}" y="${bandY(i)}" width="${labelW}" height="${bandH}" rx="6" fill="#0e54a1"/><rect x="${innerX + labelW - 8}" y="${bandY(i)}" width="8" height="${bandH}" fill="#0e54a1"/><text x="${innerX + 14}" y="${bandY(i) + bandH / 2 + 4}" class="layer-label">${escapeHtml(L2.label)}</text></g>`;
|
|
2315
4001
|
}
|
|
2316
4002
|
for (const e of edges) {
|
|
2317
|
-
const
|
|
2318
|
-
const
|
|
2319
|
-
if (!
|
|
2320
|
-
const
|
|
2321
|
-
const
|
|
2322
|
-
s += `<g><path d="${
|
|
4003
|
+
const A2 = rects.get(e.from);
|
|
4004
|
+
const B2 = rects.get(e.to);
|
|
4005
|
+
if (!A2 || !B2) continue;
|
|
4006
|
+
const p2 = ortho(A2, B2);
|
|
4007
|
+
const st2 = GEDGE[e.kind ?? "solid"] ?? GEDGE["solid"] ?? FALLBACK_EDGE;
|
|
4008
|
+
s += `<g><path d="${p2.d}" fill="none" stroke="${st2.stroke}" stroke-width="${st2.sw}" stroke-dasharray="${st2.dash}" marker-end="url(#${st2.marker})"/>` + edgePill(p2, e.label, st2.err) + `</g>`;
|
|
2323
4009
|
}
|
|
2324
4010
|
for (const n of nodes) {
|
|
2325
4011
|
const r = rects.get(n.id);
|
|
2326
4012
|
if (r === void 0) continue;
|
|
2327
|
-
const
|
|
2328
|
-
const gl = nodeGlyph(n.kind, r.x + 12, r.y + 12,
|
|
4013
|
+
const st2 = blockStyle(n.kind);
|
|
4014
|
+
const gl = nodeGlyph(n.kind, r.x + 12, r.y + 12, st2.accent);
|
|
2329
4015
|
const nx = gl.length > 0 ? r.x + 34 : r.x + 14;
|
|
2330
|
-
const tech = n.tech !== void 0 ? `<text x="${nx}" y="${r.y + 42}" class="blk-tech" fill="${
|
|
2331
|
-
s += `<g filter="url(#gshadow)"><rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" rx="8" fill="${
|
|
4016
|
+
const tech = n.tech !== void 0 ? `<text x="${nx}" y="${r.y + 42}" class="blk-tech" fill="${st2.accent}">${escapeHtml(n.tech)}</text>` : "";
|
|
4017
|
+
s += `<g filter="url(#gshadow)"><rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" rx="8" fill="${st2.fill}" stroke="${st2.accent}" stroke-width="1.2"/><rect x="${r.x}" y="${r.y}" width="5" height="${r.h}" rx="2" fill="${st2.accent}"/>` + gl + `<text x="${nx}" y="${r.y + (n.tech !== void 0 ? 26 : 33)}" class="blk-name" fill="${st2.text}">${escapeHtml(n.name)}</text>` + tech + `</g>`;
|
|
2332
4018
|
}
|
|
2333
4019
|
s += `</svg>`;
|
|
2334
4020
|
return s;
|
|
@@ -2508,28 +4194,28 @@ function renderFelogicGraph(data, frame) {
|
|
|
2508
4194
|
s += `<g><rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" rx="10" fill="${col}" fill-opacity="0.05" stroke="${col}" stroke-opacity="0.5" stroke-width="1.2" stroke-dasharray="7 5"/><text x="${r.x + 14}" y="${r.y + 15}" class="grp-label" fill="${col}">${escapeHtml(g.label)}</text></g>`;
|
|
2509
4195
|
}
|
|
2510
4196
|
for (const e of edges) {
|
|
2511
|
-
const
|
|
2512
|
-
const
|
|
2513
|
-
if (!
|
|
2514
|
-
const
|
|
2515
|
-
const
|
|
2516
|
-
s += `<g><path d="${
|
|
4197
|
+
const A2 = byId.get(e.from);
|
|
4198
|
+
const B2 = byId.get(e.to);
|
|
4199
|
+
if (!A2 || !B2) continue;
|
|
4200
|
+
const p2 = ortho(rectFor2(A2), rectFor2(B2));
|
|
4201
|
+
const st2 = feEdge(e.kind);
|
|
4202
|
+
s += `<g><path d="${p2.d}" fill="none" stroke="${st2.stroke}" stroke-width="${st2.sw}" stroke-dasharray="${st2.dash}" marker-end="url(#${st2.marker})"/>` + edgePill(p2, e.label) + `</g>`;
|
|
2517
4203
|
}
|
|
2518
4204
|
for (const n of nodes) {
|
|
2519
4205
|
const r = rectFor2(n);
|
|
2520
|
-
const
|
|
2521
|
-
const
|
|
2522
|
-
const gl = GLYPH_KINDS.has(
|
|
2523
|
-
const nx =
|
|
2524
|
-
const anchor =
|
|
2525
|
-
const nameY = r.y + (
|
|
2526
|
-
const noteY = r.y + (
|
|
2527
|
-
const stroke =
|
|
2528
|
-
const dashAttr =
|
|
2529
|
-
const stripe =
|
|
2530
|
-
const stereo =
|
|
2531
|
-
const note = n.note !== void 0 ? `<text x="${nx}" y="${noteY}" class="blk-tech" fill="${
|
|
2532
|
-
s += `<g filter="url(#gshadow)"><rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" rx="9" fill="${
|
|
4206
|
+
const st2 = feStyle(n.kind);
|
|
4207
|
+
const k2 = (n.kind ?? "").toLowerCase();
|
|
4208
|
+
const gl = GLYPH_KINDS.has(k2) ? nodeGlyph(GLYPH_REMAP[k2] ?? k2, r.x + 16, r.y + 16, st2.accent) : "";
|
|
4209
|
+
const nx = st2.solid === true ? r.x + r.w / 2 : gl.length > 0 ? r.x + 42 : r.x + 16;
|
|
4210
|
+
const anchor = st2.solid === true ? "middle" : "start";
|
|
4211
|
+
const nameY = r.y + (st2.stereo !== void 0 ? 38 : n.note !== void 0 ? 36 : 44);
|
|
4212
|
+
const noteY = r.y + (st2.stereo !== void 0 ? 56 : 52);
|
|
4213
|
+
const stroke = st2.solid === true ? "none" : st2.accent;
|
|
4214
|
+
const dashAttr = st2.dash !== void 0 ? ` stroke-dasharray="${st2.dash}"` : "";
|
|
4215
|
+
const stripe = st2.solid === true ? "" : `<rect x="${r.x}" y="${r.y}" width="5" height="${r.h}" rx="2" fill="${st2.accent}"/>`;
|
|
4216
|
+
const stereo = st2.stereo !== void 0 ? `<text x="${r.x + r.w / 2}" y="${r.y + 20}" class="uml-stereo">\xAB${escapeHtml(st2.stereo)}\xBB</text>` : "";
|
|
4217
|
+
const note = n.note !== void 0 ? `<text x="${nx}" y="${noteY}" class="blk-tech" fill="${st2.solid === true ? "#cfe0f3" : st2.accent}" text-anchor="${anchor}">${escapeHtml(n.note)}</text>` : "";
|
|
4218
|
+
s += `<g filter="url(#gshadow)"><rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" rx="9" fill="${st2.fill}" stroke="${stroke}" stroke-width="1.2"${dashAttr}/>` + stripe + gl + stereo + `<text x="${nx}" y="${nameY}" class="blk-name" fill="${st2.text}" text-anchor="${anchor}">${escapeHtml(n.name)}</text>` + note + `</g>`;
|
|
2533
4219
|
}
|
|
2534
4220
|
s += `</svg>`;
|
|
2535
4221
|
return diagramFrame(
|
|
@@ -2593,11 +4279,11 @@ function elementHeight(el) {
|
|
|
2593
4279
|
}
|
|
2594
4280
|
}
|
|
2595
4281
|
var PH = 'fill="var(--light-gray)" stroke="var(--rule)" stroke-width="1"';
|
|
2596
|
-
function drawElement(el,
|
|
4282
|
+
function drawElement(el, x2, y, w2) {
|
|
2597
4283
|
const rows = Math.max(1, el.rows ?? 1);
|
|
2598
4284
|
const label = el.label ?? "";
|
|
2599
4285
|
const accent = el.tone === "danger" ? "var(--negative)" : el.tone === "muted" ? "var(--gray)" : "var(--navy)";
|
|
2600
|
-
const anchorX = el.align === "c" ?
|
|
4286
|
+
const anchorX = el.align === "c" ? x2 + w2 / 2 : el.align === "r" ? x2 + w2 : x2;
|
|
2601
4287
|
const anchor = el.align === "c" ? "middle" : el.align === "r" ? "end" : "start";
|
|
2602
4288
|
switch (el.type) {
|
|
2603
4289
|
case "header":
|
|
@@ -2607,69 +4293,69 @@ function drawElement(el, x, y, w) {
|
|
|
2607
4293
|
case "text": {
|
|
2608
4294
|
let s = "";
|
|
2609
4295
|
for (let i = 0; i < rows; i++) {
|
|
2610
|
-
const lw = i === rows - 1 ?
|
|
2611
|
-
s += `<rect x="${
|
|
4296
|
+
const lw = i === rows - 1 ? w2 * 0.66 : w2;
|
|
4297
|
+
s += `<rect x="${x2}" y="${y + i * 12}" width="${lw}" height="6" rx="3" fill="var(--rule)"/>`;
|
|
2612
4298
|
}
|
|
2613
4299
|
return s;
|
|
2614
4300
|
}
|
|
2615
4301
|
case "button":
|
|
2616
|
-
return `<rect x="${
|
|
4302
|
+
return `<rect x="${x2}" y="${y}" width="${w2}" height="34" rx="8" fill="${accent}"/><text x="${x2 + w2 / 2}" y="${y + 22}" class="wf-btn" text-anchor="middle">${escapeHtml(label || "Button")}</text>`;
|
|
2617
4303
|
case "input":
|
|
2618
4304
|
case "search": {
|
|
2619
|
-
const icon = el.type === "search" ? `<circle cx="${
|
|
2620
|
-
const tx = el.type === "search" ?
|
|
2621
|
-
return `<rect x="${
|
|
4305
|
+
const icon = el.type === "search" ? `<circle cx="${x2 + 16}" cy="${y + 17}" r="5" fill="none" stroke="var(--gray)" stroke-width="1.4"/><path d="M${x2 + 20} ${y + 21} l4 4" stroke="var(--gray)" stroke-width="1.4"/>` : "";
|
|
4306
|
+
const tx = el.type === "search" ? x2 + 30 : x2 + 12;
|
|
4307
|
+
return `<rect x="${x2}" y="${y}" width="${w2}" height="34" rx="8" fill="var(--white)" stroke="var(--rule)" stroke-width="1.2"/>` + icon + `<text x="${tx}" y="${y + 21}" class="wf-ph-text">${escapeHtml(label || "Type here\u2026")}</text>`;
|
|
2622
4308
|
}
|
|
2623
4309
|
case "image":
|
|
2624
|
-
return `<rect x="${
|
|
4310
|
+
return `<rect x="${x2}" y="${y}" width="${w2}" height="88" rx="8" ${PH}/><path d="M${x2} ${y + 88} L${x2 + w2 * 0.4} ${y + 40} L${x2 + w2 * 0.62} ${y + 66} L${x2 + w2 * 0.78} ${y + 50} L${x2 + w2} ${y + 88}" fill="none" stroke="var(--gray)" stroke-width="1.3"/><circle cx="${x2 + w2 * 0.74} " cy="${y + 26}" r="7" fill="none" stroke="var(--gray)" stroke-width="1.3"/>`;
|
|
2625
4311
|
case "avatar":
|
|
2626
|
-
return `<circle cx="${
|
|
4312
|
+
return `<circle cx="${x2 + 22}" cy="${y + 22}" r="20" ${PH}/><circle cx="${x2 + 22}" cy="${y + 17}" r="7" fill="var(--gray)"/><path d="M${x2 + 9} ${y + 40} a13 11 0 0 1 26 0" fill="var(--gray)"/>` + (label ? `<text x="${x2 + 52}" y="${y + 27}" class="wf-sub" fill="var(--charcoal)">${escapeHtml(label)}</text>` : "");
|
|
2627
4313
|
case "card": {
|
|
2628
4314
|
let s = "";
|
|
2629
4315
|
for (let i = 0; i < rows; i++) {
|
|
2630
4316
|
const cy = y + i * 74;
|
|
2631
|
-
s += `<rect x="${
|
|
4317
|
+
s += `<rect x="${x2}" y="${cy}" width="${w2}" height="64" rx="10" fill="var(--white)" stroke="var(--rule)" stroke-width="1.2"/><rect x="${x2 + 12}" y="${cy + 12}" width="40" height="40" rx="8" ${PH}/><rect x="${x2 + 64}" y="${cy + 16}" width="${w2 - 92}" height="7" rx="3.5" fill="var(--rule)"/><rect x="${x2 + 64}" y="${cy + 34}" width="${(w2 - 92) * 0.6}" height="6" rx="3" fill="var(--rule)"/>`;
|
|
2632
4318
|
}
|
|
2633
|
-
const cap = label ? `<text x="${
|
|
4319
|
+
const cap = label ? `<text x="${x2 + 64}" y="${y + 30}" class="wf-ph-text"></text>` : "";
|
|
2634
4320
|
return s + cap;
|
|
2635
4321
|
}
|
|
2636
4322
|
case "list": {
|
|
2637
4323
|
let s = "";
|
|
2638
4324
|
for (let i = 0; i < rows; i++) {
|
|
2639
4325
|
const ly = y + i * 40;
|
|
2640
|
-
s += `<circle cx="${
|
|
4326
|
+
s += `<circle cx="${x2 + 16}" cy="${ly + 20}" r="12" ${PH}/><rect x="${x2 + 38}" y="${ly + 12}" width="${w2 - 76}" height="6" rx="3" fill="var(--rule)"/><rect x="${x2 + 38}" y="${ly + 24}" width="${(w2 - 76) * 0.55}" height="5" rx="2.5" fill="var(--rule)"/><path d="M${x2 + w2 - 14} ${ly + 15} l5 5 l-5 5" fill="none" stroke="var(--gray)" stroke-width="1.4"/>` + (i < rows - 1 ? `<line x1="${x2 + 38}" y1="${ly + 40}" x2="${x2 + w2}" y2="${ly + 40}" stroke="var(--light-gray)" stroke-width="1"/>` : "");
|
|
2641
4327
|
}
|
|
2642
4328
|
return s;
|
|
2643
4329
|
}
|
|
2644
4330
|
case "nav": {
|
|
2645
4331
|
const items = (label || "Home, Docs, Pricing, About").split(",").map((t) => t.trim());
|
|
2646
4332
|
let s = "";
|
|
2647
|
-
let nx =
|
|
2648
|
-
for (const
|
|
2649
|
-
const pw = 16 +
|
|
2650
|
-
s += `<rect x="${nx}" y="${y + 4}" width="${pw}" height="22" rx="11" fill="var(--light-gray)"/><text x="${nx + pw / 2}" y="${y + 19}" class="wf-ph-text" text-anchor="middle">${escapeHtml(
|
|
4333
|
+
let nx = x2;
|
|
4334
|
+
for (const it2 of items) {
|
|
4335
|
+
const pw = 16 + it2.length * 6.2;
|
|
4336
|
+
s += `<rect x="${nx}" y="${y + 4}" width="${pw}" height="22" rx="11" fill="var(--light-gray)"/><text x="${nx + pw / 2}" y="${y + 19}" class="wf-ph-text" text-anchor="middle">${escapeHtml(it2)}</text>`;
|
|
2651
4337
|
nx += pw + 8;
|
|
2652
4338
|
}
|
|
2653
4339
|
return s;
|
|
2654
4340
|
}
|
|
2655
4341
|
case "tabs": {
|
|
2656
4342
|
const items = (label || "Home, Search, Bell, Profile").split(",").map((t) => t.trim());
|
|
2657
|
-
const seg =
|
|
2658
|
-
let s = `<line x1="${
|
|
2659
|
-
items.forEach((
|
|
2660
|
-
const cx =
|
|
2661
|
-
s += `<circle cx="${cx}" cy="${y + 18}" r="8" fill="none" stroke="${i === 0 ? accent : "var(--gray)"}" stroke-width="1.6"/><text x="${cx}" y="${y + 42}" class="wf-tab" text-anchor="middle" fill="${i === 0 ? accent : "var(--gray)"}">${escapeHtml(
|
|
4343
|
+
const seg = w2 / items.length;
|
|
4344
|
+
let s = `<line x1="${x2}" y1="${y}" x2="${x2 + w2}" y2="${y}" stroke="var(--rule)" stroke-width="1"/>`;
|
|
4345
|
+
items.forEach((it2, i) => {
|
|
4346
|
+
const cx = x2 + seg * i + seg / 2;
|
|
4347
|
+
s += `<circle cx="${cx}" cy="${y + 18}" r="8" fill="none" stroke="${i === 0 ? accent : "var(--gray)"}" stroke-width="1.6"/><text x="${cx}" y="${y + 42}" class="wf-tab" text-anchor="middle" fill="${i === 0 ? accent : "var(--gray)"}">${escapeHtml(it2)}</text>`;
|
|
2662
4348
|
});
|
|
2663
4349
|
return s;
|
|
2664
4350
|
}
|
|
2665
4351
|
case "divider":
|
|
2666
|
-
return `<line x1="${
|
|
4352
|
+
return `<line x1="${x2}" y1="${y + 7}" x2="${x2 + w2}" y2="${y + 7}" stroke="var(--rule)" stroke-width="1"/>`;
|
|
2667
4353
|
case "badge": {
|
|
2668
4354
|
const pw = 22 + label.length * 6.4;
|
|
2669
4355
|
return `<rect x="${anchorX - (anchor === "middle" ? pw / 2 : anchor === "end" ? pw : 0)}" y="${y}" width="${pw}" height="22" rx="11" fill="${accent}"/><text x="${anchorX - (anchor === "middle" ? 0 : anchor === "end" ? pw / 2 : -pw / 2)}" y="${y + 15}" class="wf-btn" text-anchor="middle">${escapeHtml(label || "New")}</text>`;
|
|
2670
4356
|
}
|
|
2671
4357
|
case "toggle":
|
|
2672
|
-
return (label ? `<text x="${
|
|
4358
|
+
return (label ? `<text x="${x2}" y="${y + 19}" class="wf-sub" fill="var(--charcoal)">${escapeHtml(label)}</text>` : "") + `<rect x="${x2 + w2 - 44}" y="${y + 6}" width="44" height="22" rx="11" fill="${accent}"/><circle cx="${x2 + w2 - 16}" cy="${y + 17}" r="8" fill="#fff"/>`;
|
|
2673
4359
|
case "spacer":
|
|
2674
4360
|
return "";
|
|
2675
4361
|
default:
|
|
@@ -2738,18 +4424,18 @@ function renderWireframe(data) {
|
|
|
2738
4424
|
const width = totalW + padX * 2;
|
|
2739
4425
|
const height = maxH + capH + padY * 2;
|
|
2740
4426
|
let s = `<svg viewBox="0 0 ${width} ${height}" role="img"><title>${escapeHtml(data.title ?? "UI mockup")}</title>`;
|
|
2741
|
-
let
|
|
4427
|
+
let x2 = padX;
|
|
2742
4428
|
drawn.forEach((d, i) => {
|
|
2743
4429
|
const screen = screens[i];
|
|
2744
|
-
s += `<g transform="translate(${
|
|
4430
|
+
s += `<g transform="translate(${x2}, ${padY})">${d.svg}</g>`;
|
|
2745
4431
|
const cap = screen?.label;
|
|
2746
4432
|
if (cap !== void 0 && cap.length > 0) {
|
|
2747
4433
|
const lines = wrapText(cap, Math.floor(d.width / 6), 2);
|
|
2748
|
-
lines.forEach((
|
|
2749
|
-
s += `<text x="${
|
|
4434
|
+
lines.forEach((ln2, j2) => {
|
|
4435
|
+
s += `<text x="${x2 + d.width / 2}" y="${padY + maxH + 16 + j2 * 12}" class="wf-caption" text-anchor="middle">${escapeHtml(ln2)}</text>`;
|
|
2750
4436
|
});
|
|
2751
4437
|
}
|
|
2752
|
-
|
|
4438
|
+
x2 += d.width + gap;
|
|
2753
4439
|
});
|
|
2754
4440
|
s += `</svg>`;
|
|
2755
4441
|
return diagramFrame(
|
|
@@ -2814,14 +4500,35 @@ function globalDefsSvg() {
|
|
|
2814
4500
|
}
|
|
2815
4501
|
|
|
2816
4502
|
// src/themes.ts
|
|
2817
|
-
var DEFAULT_THEME = "
|
|
4503
|
+
var DEFAULT_THEME = "textbook";
|
|
2818
4504
|
var themes = {
|
|
2819
|
-
// Default:
|
|
2820
|
-
//
|
|
2821
|
-
|
|
4505
|
+
// Default: warm textbook look (cream paper, deep academic navy, terracotta
|
|
4506
|
+
// accent, serif display + body) — the base :root tokens, no overrides needed.
|
|
4507
|
+
textbook: {
|
|
4508
|
+
label: "Textbook",
|
|
4509
|
+
vars: {}
|
|
4510
|
+
},
|
|
4511
|
+
// Clean, modern, white: near-black ink, a single blue accent (#0070f3),
|
|
4512
|
+
// geometric sans, more rounding. (The former default.)
|
|
2822
4513
|
minimal: {
|
|
2823
4514
|
label: "Minimal",
|
|
2824
|
-
vars: {
|
|
4515
|
+
vars: {
|
|
4516
|
+
"--navy": "#000000",
|
|
4517
|
+
"--navy-tint": "#d4d4d4",
|
|
4518
|
+
"--blue": "#0070f3",
|
|
4519
|
+
"--light-blue": "#e5f0ff",
|
|
4520
|
+
"--charcoal": "#111111",
|
|
4521
|
+
"--slate": "#444444",
|
|
4522
|
+
"--gray": "#888888",
|
|
4523
|
+
"--light-gray": "#fafafa",
|
|
4524
|
+
"--rule": "#eaeaea",
|
|
4525
|
+
"--highlight": "#0070f3",
|
|
4526
|
+
"--highlight-soft": "#e5f0ff",
|
|
4527
|
+
"--white": "#ffffff",
|
|
4528
|
+
"--radius": "8px",
|
|
4529
|
+
"--font-display": '"Inter","SF Pro Display",-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif',
|
|
4530
|
+
"--font-body": '"Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif'
|
|
4531
|
+
}
|
|
2825
4532
|
},
|
|
2826
4533
|
teal: {
|
|
2827
4534
|
label: "Teal",
|
|
@@ -2905,7 +4612,7 @@ var themes = {
|
|
|
2905
4612
|
function themeStyle(name) {
|
|
2906
4613
|
const vars = themes[name].vars;
|
|
2907
4614
|
const parts = [];
|
|
2908
|
-
for (const
|
|
4615
|
+
for (const k2 of Object.keys(vars)) parts.push(`${k2}:${vars[k2]};`);
|
|
2909
4616
|
return parts.join("");
|
|
2910
4617
|
}
|
|
2911
4618
|
|
|
@@ -2928,8 +4635,8 @@ function renderSectionHead(num, kind, title, lede) {
|
|
|
2928
4635
|
return `<div class="section-head"><div class="section-num">SECTION ${pad2(num)} \xB7 ${escapeHtml(label)}</div>` + titleHtml + ledeHtml + `</div>`;
|
|
2929
4636
|
}
|
|
2930
4637
|
function dispatchBlock(kind, data) {
|
|
2931
|
-
const
|
|
2932
|
-
return
|
|
4638
|
+
const fn2 = htmlRenderers[kind];
|
|
4639
|
+
return fn2(data);
|
|
2933
4640
|
}
|
|
2934
4641
|
function renderTypedSegment(seg, ctx) {
|
|
2935
4642
|
if (seg.kind === "meta") return "";
|
|
@@ -2959,7 +4666,7 @@ function renderSegment(seg, ctx) {
|
|
|
2959
4666
|
function buildThemeVars(theme, vars) {
|
|
2960
4667
|
let css = themeStyle(theme);
|
|
2961
4668
|
if (vars !== void 0) {
|
|
2962
|
-
for (const
|
|
4669
|
+
for (const k2 of Object.keys(vars)) css += `${k2}:${vars[k2]};`;
|
|
2963
4670
|
}
|
|
2964
4671
|
return css;
|
|
2965
4672
|
}
|
|
@@ -2992,6 +4699,11 @@ function renderDocument(doc, opts = {}) {
|
|
|
2992
4699
|
</html>
|
|
2993
4700
|
`;
|
|
2994
4701
|
}
|
|
4702
|
+
/*! Bundled license information:
|
|
4703
|
+
|
|
4704
|
+
@dagrejs/dagre/dist/dagre.esm.js:
|
|
4705
|
+
(*! For license information please see dagre.esm.js.LEGAL.txt *)
|
|
4706
|
+
*/
|
|
2995
4707
|
|
|
2996
4708
|
export { DEFAULT_THEME, buildThemeVars, edgePill, escapeHtml, globalDefsSvg, houseCss, htmlRenderers, ortho, renderDocument, renderDocumentParts, renderProse, safeColor, safeUrl, themeStyle, themes, wrapText };
|
|
2997
4709
|
//# sourceMappingURL=index.js.map
|