@knowvah/dot-engine 2.6.10 → 2.6.12
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/async/render-async.d.ts.map +1 -1
- package/dist/common/agerr.d.ts +37 -0
- package/dist/common/agerr.d.ts.map +1 -0
- package/dist/common/arrows-shapes-poly.d.ts.map +1 -1
- package/dist/common/color.d.ts.map +1 -1
- package/dist/common/crand.d.ts +0 -20
- package/dist/common/crand.d.ts.map +1 -1
- package/dist/common/emit-once.d.ts +6 -0
- package/dist/common/emit-once.d.ts.map +1 -0
- package/dist/common/graph-init.d.ts.map +1 -1
- package/dist/common/html-entities.d.ts +13 -5
- package/dist/common/html-entities.d.ts.map +1 -1
- package/dist/common/htmltable-attr-warn.d.ts.map +1 -1
- package/dist/common/htmltable-emit-fill.d.ts +9 -0
- package/dist/common/htmltable-emit-fill.d.ts.map +1 -1
- package/dist/common/htmltable-emit-rules.d.ts.map +1 -1
- package/dist/common/htmltable-lex-chardata.d.ts +9 -0
- package/dist/common/htmltable-lex-chardata.d.ts.map +1 -1
- package/dist/common/htmltable-lex-expat.d.ts +1 -6
- package/dist/common/htmltable-lex-expat.d.ts.map +1 -1
- package/dist/common/htmltable.d.ts +1 -7
- package/dist/common/htmltable.d.ts.map +1 -1
- package/dist/common/poly-gencode.d.ts.map +1 -1
- package/dist/common/poly-init.d.ts.map +1 -1
- package/dist/common/postproc.d.ts.map +1 -1
- package/dist/common/random.d.ts.map +1 -1
- package/dist/common/render-state.d.ts +8 -0
- package/dist/common/render-state.d.ts.map +1 -0
- package/dist/common/splines-geom.d.ts +8 -0
- package/dist/common/splines-geom.d.ts.map +1 -1
- package/dist/common/splines-routespl.d.ts.map +1 -1
- package/dist/common/textmeasure-lookup.d.ts.map +1 -1
- package/dist/common/textmeasure.d.ts.map +1 -1
- package/dist/gvc/anchor.d.ts.map +1 -1
- package/dist/gvc/device-cluster.d.ts.map +1 -1
- package/dist/gvc/device-labels.d.ts +14 -0
- package/dist/gvc/device-labels.d.ts.map +1 -1
- package/dist/gvc/device.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +821 -471
- package/dist/index.js.map +4 -4
- package/dist/layout/dot/cluster.d.ts.map +1 -1
- package/dist/layout/dot/conc.d.ts.map +1 -1
- package/dist/layout/dot/decomp.d.ts.map +1 -1
- package/dist/layout/dot/edge-route-clip.d.ts +18 -10
- package/dist/layout/dot/edge-route-clip.d.ts.map +1 -1
- package/dist/layout/dot/mincross-build.d.ts.map +1 -1
- package/dist/layout/dot/mincross-cross.d.ts.map +1 -1
- package/dist/layout/dot/rank.d.ts.map +1 -1
- package/dist/layout/dot/splines.d.ts.map +1 -1
- package/dist/layout/fdp/index.d.ts.map +1 -1
- package/dist/layout/fdp/tlayout-parms.d.ts.map +1 -1
- package/dist/layout/fdp/xlayout.d.ts.map +1 -1
- package/dist/layout/neato/edge-len.d.ts.map +1 -1
- package/dist/layout/neato/fdp-adjust.d.ts.map +1 -1
- package/dist/layout/neato/init.d.ts +4 -10
- package/dist/layout/neato/init.d.ts.map +1 -1
- package/dist/layout/neato/kk.d.ts.map +1 -1
- package/dist/layout/neato/multispline-router.d.ts.map +1 -1
- package/dist/layout/neato/multispline.d.ts.map +1 -1
- package/dist/layout/neato/poly.d.ts.map +1 -1
- package/dist/layout/neato/sgd.d.ts.map +1 -1
- package/dist/layout/neato/start.d.ts.map +1 -1
- package/dist/ortho/index.d.ts.map +1 -1
- package/dist/parser/index.d.ts.map +1 -1
- package/dist/render/color-resolve.d.ts +49 -1
- package/dist/render/color-resolve.d.ts.map +1 -1
- package/dist/render/public.d.ts.map +1 -1
- package/dist/render/svg-edge-split.d.ts +2 -0
- package/dist/render/svg-edge-split.d.ts.map +1 -1
- package/dist/render/xdot-public.d.ts.map +1 -1
- package/dist/render.js +569 -220
- package/dist/render.js.map +4 -4
- package/package.json +1 -1
- package/src/async/render-async.ts +6 -0
- package/src/common/agerr.ts +96 -0
- package/src/common/arrows-shapes-poly.ts +19 -5
- package/src/common/color.ts +38 -10
- package/src/common/crand.ts +8 -2
- package/src/common/emit-once.ts +27 -0
- package/src/common/graph-init.ts +2 -1
- package/src/common/html-entities.ts +77 -25
- package/src/common/htmltable-attr-warn.ts +3 -4
- package/src/common/htmltable-emit-fill.ts +48 -0
- package/src/common/htmltable-emit-rules.ts +2 -0
- package/src/common/htmltable-lex-chardata.ts +42 -8
- package/src/common/htmltable-lex-expat.ts +78 -23
- package/src/common/htmltable.ts +15 -16
- package/src/common/poly-gencode.ts +14 -2
- package/src/common/poly-init.ts +2 -1
- package/src/common/postproc.ts +4 -1
- package/src/common/random.ts +11 -1
- package/src/common/render-state.ts +36 -0
- package/src/common/splines-geom.ts +8 -4
- package/src/common/splines-routespl.ts +2 -1
- package/src/common/textmeasure-lookup.ts +10 -3
- package/src/common/textmeasure.ts +45 -2
- package/src/gvc/anchor.ts +1 -12
- package/src/gvc/device-cluster.ts +37 -9
- package/src/gvc/device-labels.ts +27 -0
- package/src/gvc/device.ts +18 -6
- package/src/index.ts +3 -0
- package/src/layout/dot/cluster.ts +2 -1
- package/src/layout/dot/conc.ts +6 -5
- package/src/layout/dot/decomp.ts +3 -0
- package/src/layout/dot/edge-route-clip.ts +27 -21
- package/src/layout/dot/mincross-build.ts +2 -0
- package/src/layout/dot/mincross-cross.ts +2 -0
- package/src/layout/dot/rank.ts +2 -0
- package/src/layout/dot/splines.ts +2 -1
- package/src/layout/fdp/index.ts +2 -1
- package/src/layout/fdp/tlayout-parms.ts +9 -2
- package/src/layout/fdp/xlayout.ts +10 -2
- package/src/layout/neato/cdt-surface.ts +6 -6
- package/src/layout/neato/edge-len.ts +2 -1
- package/src/layout/neato/fdp-adjust.ts +3 -2
- package/src/layout/neato/init.ts +11 -11
- package/src/layout/neato/kk.ts +2 -1
- package/src/layout/neato/multispline-router.ts +3 -3
- package/src/layout/neato/multispline.ts +3 -2
- package/src/layout/neato/poly.ts +3 -2
- package/src/layout/neato/sgd.ts +5 -2
- package/src/layout/neato/start.ts +14 -10
- package/src/ortho/index.ts +3 -1
- package/src/parser/dot.js +4 -1
- package/src/parser/dot.pegjs +5 -1
- package/src/parser/index.ts +4 -3
- package/src/render/color-resolve.ts +193 -4
- package/src/render/public.ts +2 -0
- package/src/render/svg-edge-split.ts +4 -2
- package/src/render/xdot-public.ts +2 -0
package/dist/index.js
CHANGED
|
@@ -1,3 +1,54 @@
|
|
|
1
|
+
// src/common/render-state.ts
|
|
2
|
+
var resets = [];
|
|
3
|
+
function registerRenderState(reset2) {
|
|
4
|
+
resets.push(reset2);
|
|
5
|
+
}
|
|
6
|
+
function resetRenderState() {
|
|
7
|
+
for (const reset2 of resets) reset2();
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// src/common/agerr.ts
|
|
11
|
+
var PREFIX_ERROR = "Error";
|
|
12
|
+
var PREFIX_WARNING = "Warning";
|
|
13
|
+
var PREFIX_SEP = ": ";
|
|
14
|
+
var DEL = 127;
|
|
15
|
+
var LAST_CNTRL = 31;
|
|
16
|
+
var WHITESPACE = /* @__PURE__ */ new Set([9, 10, 11, 12, 13]);
|
|
17
|
+
var OCTAL_WIDTH = 3;
|
|
18
|
+
var OCTAL_RADIX = 8;
|
|
19
|
+
var lastLevel = "warning";
|
|
20
|
+
registerRenderState(() => {
|
|
21
|
+
lastLevel = "warning";
|
|
22
|
+
});
|
|
23
|
+
function escapeControl(message) {
|
|
24
|
+
let out = "";
|
|
25
|
+
for (const ch of message) {
|
|
26
|
+
const c = ch.codePointAt(0);
|
|
27
|
+
if ((c <= LAST_CNTRL || c === DEL) && !WHITESPACE.has(c)) {
|
|
28
|
+
out += `\\${c.toString(OCTAL_RADIX).padStart(OCTAL_WIDTH, "0")}`;
|
|
29
|
+
} else out += ch;
|
|
30
|
+
}
|
|
31
|
+
return out;
|
|
32
|
+
}
|
|
33
|
+
function agerrLineOn(channel, line) {
|
|
34
|
+
if (channel === "warn") console.warn(escapeControl(line));
|
|
35
|
+
else console.error(escapeControl(line));
|
|
36
|
+
}
|
|
37
|
+
function agerr(level, msg, channel) {
|
|
38
|
+
if (level === "prev") {
|
|
39
|
+
agerrLineOn(channel ?? (lastLevel === "warning" ? "warn" : "error"), msg);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
lastLevel = level;
|
|
43
|
+
const prefix = level === "error" ? PREFIX_ERROR : PREFIX_WARNING;
|
|
44
|
+
agerrLineOn(channel ?? (level === "warning" ? "warn" : "error"), `${prefix}${PREFIX_SEP}${msg}`);
|
|
45
|
+
}
|
|
46
|
+
var agerrorf = (msg, channel) => agerr("error", msg, channel);
|
|
47
|
+
var agwarningf = (msg, channel) => agerr("warning", msg, channel);
|
|
48
|
+
function agerrFinished(line, channel) {
|
|
49
|
+
agerrLineOn(channel ?? (line.startsWith(PREFIX_WARNING) ? "warn" : "error"), line);
|
|
50
|
+
}
|
|
51
|
+
|
|
1
52
|
// src/parser/dot.js
|
|
2
53
|
var peg$SyntaxError = class extends SyntaxError {
|
|
3
54
|
constructor(message, expected, found, location) {
|
|
@@ -248,7 +299,7 @@ function peg$parse(input, options) {
|
|
|
248
299
|
return s;
|
|
249
300
|
}
|
|
250
301
|
function peg$f13(t, m, attrs) {
|
|
251
|
-
if (m)
|
|
302
|
+
if (m) agwarningf("attribute macros not implemented", "error");
|
|
252
303
|
return { type: "attr", target: t, attrs };
|
|
253
304
|
}
|
|
254
305
|
function peg$f14(a) {
|
|
@@ -4221,8 +4272,8 @@ var StmtProcessor = class _StmtProcessor {
|
|
|
4221
4272
|
resolveEndpoint(item, root, scope, directed) {
|
|
4222
4273
|
if ("type" in item && item.type === "subgraph") {
|
|
4223
4274
|
this.processSubgraph(item, scope, root, directed);
|
|
4224
|
-
const
|
|
4225
|
-
const nodes = NameCollector.fromStmts(item.stmts).map((n) => this.registry.ensure(n, root, scope)).filter((nd) =>
|
|
4275
|
+
const seen2 = /* @__PURE__ */ new Set();
|
|
4276
|
+
const nodes = NameCollector.fromStmts(item.stmts).map((n) => this.registry.ensure(n, root, scope)).filter((nd) => seen2.has(nd.id) ? false : (seen2.add(nd.id), true));
|
|
4226
4277
|
return nodes.sort((a, b) => a.id - b.id);
|
|
4227
4278
|
}
|
|
4228
4279
|
return [this.registry.ensure(item.id, root, scope)];
|
|
@@ -4466,22 +4517,22 @@ function countNewlines(s, from, to) {
|
|
|
4466
4517
|
return n;
|
|
4467
4518
|
}
|
|
4468
4519
|
var HEADER_KEYWORDS = ["strict", "graph", "digraph"];
|
|
4469
|
-
function isTruncatedHeaderKeyword(src, step, offset,
|
|
4470
|
-
if (offset !== src.length || step.end !== offset ||
|
|
4471
|
-
if (
|
|
4520
|
+
function isTruncatedHeaderKeyword(src, step, offset, seen2) {
|
|
4521
|
+
if (offset !== src.length || step.end !== offset || seen2.length > 1) return false;
|
|
4522
|
+
if (seen2.length === 1 && seen2[0].toLowerCase() !== "strict") return false;
|
|
4472
4523
|
const word = step.text.toLowerCase();
|
|
4473
4524
|
return HEADER_KEYWORDS.some((k) => k.length > word.length && k.startsWith(word));
|
|
4474
4525
|
}
|
|
4475
|
-
function reachesOffset(src, step, offset,
|
|
4526
|
+
function reachesOffset(src, step, offset, seen2) {
|
|
4476
4527
|
if (step.end > offset) return true;
|
|
4477
|
-
if (isTruncatedHeaderKeyword(src, step, offset,
|
|
4528
|
+
if (isTruncatedHeaderKeyword(src, step, offset, seen2)) return true;
|
|
4478
4529
|
if (step.text !== "-" && step.text !== ".") return false;
|
|
4479
4530
|
return offset <= step.end + (step.text === "-" && src[step.end] === "." ? 1 : 0);
|
|
4480
4531
|
}
|
|
4481
4532
|
function scanAtError(src, offset) {
|
|
4482
4533
|
let line = 1;
|
|
4483
4534
|
let i = 0;
|
|
4484
|
-
const
|
|
4535
|
+
const seen2 = [];
|
|
4485
4536
|
while (i < src.length) {
|
|
4486
4537
|
const step = lexStep(src, i);
|
|
4487
4538
|
if (step.kind === "open") {
|
|
@@ -4490,10 +4541,10 @@ function scanAtError(src, offset) {
|
|
|
4490
4541
|
}
|
|
4491
4542
|
if (step.kind === "skip" && step.line !== void 0) line = step.line;
|
|
4492
4543
|
line += countNewlines(src, i, step.end);
|
|
4493
|
-
if (step.kind === "token" && reachesOffset(src, step, offset,
|
|
4544
|
+
if (step.kind === "token" && reachesOffset(src, step, offset, seen2)) {
|
|
4494
4545
|
return { state: "INITIAL", text: step.text, line, buffer: "" };
|
|
4495
4546
|
}
|
|
4496
|
-
if (step.kind === "token")
|
|
4547
|
+
if (step.kind === "token") seen2.push(step.text);
|
|
4497
4548
|
i = step.end;
|
|
4498
4549
|
}
|
|
4499
4550
|
return { state: "INITIAL", text: "", line, buffer: "" };
|
|
@@ -4803,7 +4854,7 @@ function isPeggyError(err) {
|
|
|
4803
4854
|
function warnNumberAmbiguities(src, upTo) {
|
|
4804
4855
|
for (const a of scanNumberAmbiguities(src, Stripper.strip(src))) {
|
|
4805
4856
|
if (a.offset > upTo) break;
|
|
4806
|
-
|
|
4857
|
+
agerrFinished(numberAmbiguityMessage(a), "error");
|
|
4807
4858
|
}
|
|
4808
4859
|
}
|
|
4809
4860
|
function parse(src) {
|
|
@@ -4817,7 +4868,7 @@ function parse(src) {
|
|
|
4817
4868
|
if (isPeggyError(err)) {
|
|
4818
4869
|
const start = err.location.start;
|
|
4819
4870
|
warnNumberAmbiguities(src, start.offset);
|
|
4820
|
-
|
|
4871
|
+
agerrFinished(syntaxErrorMessage(src, start.offset));
|
|
4821
4872
|
const code = err.found === null ? "SYNTAX_UNEXPECTED_EOF" : "SYNTAX_ERROR";
|
|
4822
4873
|
throw new ParseError(
|
|
4823
4874
|
err instanceof Error ? err.message : String(err),
|
|
@@ -4842,7 +4893,7 @@ function parse(src) {
|
|
|
4842
4893
|
const offset = err instanceof ParseError ? err.location.offset : void 0;
|
|
4843
4894
|
if (offset !== void 0) {
|
|
4844
4895
|
warnNumberAmbiguities(src, offset);
|
|
4845
|
-
|
|
4896
|
+
agerrFinished(syntaxErrorMessage(src, offset));
|
|
4846
4897
|
}
|
|
4847
4898
|
throw err;
|
|
4848
4899
|
}
|
|
@@ -8542,6 +8593,9 @@ var COLOR_LIB = [
|
|
|
8542
8593
|
|
|
8543
8594
|
// src/common/color.ts
|
|
8544
8595
|
var colorScheme = "";
|
|
8596
|
+
registerRenderState(() => {
|
|
8597
|
+
colorScheme = "";
|
|
8598
|
+
});
|
|
8545
8599
|
function setColorScheme(scheme) {
|
|
8546
8600
|
colorScheme = scheme;
|
|
8547
8601
|
}
|
|
@@ -8671,18 +8725,28 @@ function setBlackOpaque(color, targetType) {
|
|
|
8671
8725
|
if (targetType === "rgba") setRgba(color, 0, 0, 0, 255);
|
|
8672
8726
|
else if (targetType === "hsva") setHsvaDirect(color, 0, 0, 0, 1);
|
|
8673
8727
|
}
|
|
8728
|
+
var SSCANF_SPACE = /* @__PURE__ */ new Set([" ", " ", "\n", "\v", "\f", "\r"]);
|
|
8729
|
+
function scanHexGroups(p, width2, max) {
|
|
8730
|
+
const out = [];
|
|
8731
|
+
if (p.charAt(0) !== "#") return out;
|
|
8732
|
+
let i = 1;
|
|
8733
|
+
while (out.length < max) {
|
|
8734
|
+
while (SSCANF_SPACE.has(p.charAt(i))) i++;
|
|
8735
|
+
let j = i;
|
|
8736
|
+
while (j < p.length && j - i < width2 && /[0-9a-fA-F]/.test(p.charAt(j))) j++;
|
|
8737
|
+
if (j === i) break;
|
|
8738
|
+
out.push(parseInt(p.slice(i, j), 16));
|
|
8739
|
+
i = j;
|
|
8740
|
+
}
|
|
8741
|
+
return out;
|
|
8742
|
+
}
|
|
8674
8743
|
function parseHexColor(p) {
|
|
8675
|
-
|
|
8676
|
-
|
|
8677
|
-
|
|
8678
|
-
|
|
8679
|
-
|
|
8680
|
-
|
|
8681
|
-
if (!m3) return null;
|
|
8682
|
-
const r = parseInt(m3[1], 16);
|
|
8683
|
-
const g = parseInt(m3[2], 16);
|
|
8684
|
-
const b = parseInt(m3[3], 16);
|
|
8685
|
-
return { r: r | r << 4, g: g | g << 4, b: b | b << 4, a: 255 };
|
|
8744
|
+
const g = scanHexGroups(p, 2, 4);
|
|
8745
|
+
if (g.length >= 3) return { r: g[0], g: g[1], b: g[2], a: g[3] ?? 255 };
|
|
8746
|
+
const short = p.length === 4 ? scanHexGroups(p, 1, 3) : [];
|
|
8747
|
+
if (short.length !== 3) return null;
|
|
8748
|
+
const [r, gg, b] = short;
|
|
8749
|
+
return { r: r | r << 4, g: gg | gg << 4, b: b | b << 4, a: 255 };
|
|
8686
8750
|
}
|
|
8687
8751
|
function clamp01(x) {
|
|
8688
8752
|
return Math.max(0, Math.min(1, x));
|
|
@@ -8728,6 +8792,263 @@ function colorxlate(str, color, targetType) {
|
|
|
8728
8792
|
return 1 /* ColorUnknown */;
|
|
8729
8793
|
}
|
|
8730
8794
|
|
|
8795
|
+
// src/common/multicolor.ts
|
|
8796
|
+
var EPS = 1e-5;
|
|
8797
|
+
function aeq0(x) {
|
|
8798
|
+
return x < EPS && x > -EPS;
|
|
8799
|
+
}
|
|
8800
|
+
function getSegLen(token) {
|
|
8801
|
+
const semi = token.indexOf(";");
|
|
8802
|
+
if (semi === -1) return { color: token, v: 0 };
|
|
8803
|
+
const color = token.slice(0, semi);
|
|
8804
|
+
const rest = token.slice(semi + 1);
|
|
8805
|
+
if (rest.length === 0) return { color, v: -1 };
|
|
8806
|
+
const parsed = parseFloat(rest);
|
|
8807
|
+
return !isNaN(parsed) && parsed >= 0 ? { color, v: parsed } : { color, v: -1 };
|
|
8808
|
+
}
|
|
8809
|
+
function appendSeg(token, left2, segs, warnedExceeded) {
|
|
8810
|
+
const { color, v } = getSegLen(token);
|
|
8811
|
+
if (v < 0) return null;
|
|
8812
|
+
let t = v;
|
|
8813
|
+
let rval = 0;
|
|
8814
|
+
const del = t - left2;
|
|
8815
|
+
if (del > 0) {
|
|
8816
|
+
if (!aeq0(del) && !warnedExceeded.v) {
|
|
8817
|
+
warnedExceeded.v = true;
|
|
8818
|
+
rval = 3;
|
|
8819
|
+
}
|
|
8820
|
+
t = left2;
|
|
8821
|
+
}
|
|
8822
|
+
left2 -= t;
|
|
8823
|
+
segs.push({ color: color.length > 0 ? color : null, t, hasFraction: t > 0 && v > 0 });
|
|
8824
|
+
return { left: left2, rval };
|
|
8825
|
+
}
|
|
8826
|
+
function distributeLeft(segs, left2) {
|
|
8827
|
+
if (left2 <= 0) return;
|
|
8828
|
+
const zeroCount = segs.filter((s) => s.t <= 0).length;
|
|
8829
|
+
if (zeroCount > 0) {
|
|
8830
|
+
const delta2 = left2 / zeroCount;
|
|
8831
|
+
for (const s of segs) {
|
|
8832
|
+
if (s.t <= 0) s.t = delta2;
|
|
8833
|
+
}
|
|
8834
|
+
} else if (segs.length > 0) {
|
|
8835
|
+
segs[segs.length - 1].t += left2;
|
|
8836
|
+
}
|
|
8837
|
+
}
|
|
8838
|
+
function trimTrailing(segs) {
|
|
8839
|
+
while (segs.length > 0 && (segs[segs.length - 1]?.t ?? 0) <= 0) {
|
|
8840
|
+
segs.pop();
|
|
8841
|
+
}
|
|
8842
|
+
}
|
|
8843
|
+
function parseSegs(colorlist) {
|
|
8844
|
+
const segs = [];
|
|
8845
|
+
let left2 = 1;
|
|
8846
|
+
let rval = 0;
|
|
8847
|
+
let badFloatCount = 0;
|
|
8848
|
+
const warnedExceeded = { v: false };
|
|
8849
|
+
for (const token of colorlist.split(":")) {
|
|
8850
|
+
const result = appendSeg(token, left2, segs, warnedExceeded);
|
|
8851
|
+
if (result === null) {
|
|
8852
|
+
const errCode = badFloatCount === 0 ? 2 : 1;
|
|
8853
|
+
badFloatCount++;
|
|
8854
|
+
return { segs: [], error: errCode };
|
|
8855
|
+
}
|
|
8856
|
+
if (result.rval === 3) rval = 3;
|
|
8857
|
+
left2 = result.left;
|
|
8858
|
+
if (aeq0(left2)) {
|
|
8859
|
+
left2 = 0;
|
|
8860
|
+
break;
|
|
8861
|
+
}
|
|
8862
|
+
}
|
|
8863
|
+
distributeLeft(segs, left2);
|
|
8864
|
+
trimTrailing(segs);
|
|
8865
|
+
return { segs, error: rval };
|
|
8866
|
+
}
|
|
8867
|
+
|
|
8868
|
+
// src/common/style-resolve.ts
|
|
8869
|
+
var DEFAULT_COLOR = "black";
|
|
8870
|
+
var DEFAULT_FILL = "lightgrey";
|
|
8871
|
+
var PENWIDTH_BOLD = 2;
|
|
8872
|
+
var TOKEN_FLAG = {
|
|
8873
|
+
filled: "filled",
|
|
8874
|
+
dashed: "dashed",
|
|
8875
|
+
dotted: "dotted",
|
|
8876
|
+
bold: "bold",
|
|
8877
|
+
invis: "invis",
|
|
8878
|
+
diagonals: "diagonals",
|
|
8879
|
+
rounded: "rounded",
|
|
8880
|
+
striped: "striped",
|
|
8881
|
+
wedged: "wedged",
|
|
8882
|
+
underline: "underline"
|
|
8883
|
+
};
|
|
8884
|
+
function zeroFlags() {
|
|
8885
|
+
return {
|
|
8886
|
+
filled: false,
|
|
8887
|
+
dashed: false,
|
|
8888
|
+
dotted: false,
|
|
8889
|
+
bold: false,
|
|
8890
|
+
invis: false,
|
|
8891
|
+
diagonals: false,
|
|
8892
|
+
rounded: false,
|
|
8893
|
+
radial: false,
|
|
8894
|
+
striped: false,
|
|
8895
|
+
wedged: false,
|
|
8896
|
+
underline: false,
|
|
8897
|
+
setLineWidth: null
|
|
8898
|
+
};
|
|
8899
|
+
}
|
|
8900
|
+
var FUNLIMIT = 64;
|
|
8901
|
+
function styleTokens(style2) {
|
|
8902
|
+
if (!style2) return [];
|
|
8903
|
+
const out = [];
|
|
8904
|
+
let fun = 0;
|
|
8905
|
+
for (const raw of style2.split(",")) {
|
|
8906
|
+
const token = raw.trim();
|
|
8907
|
+
if (token.length === 0) continue;
|
|
8908
|
+
if (fun === FUNLIMIT - 1) return [];
|
|
8909
|
+
fun++;
|
|
8910
|
+
out.push(token);
|
|
8911
|
+
}
|
|
8912
|
+
return out;
|
|
8913
|
+
}
|
|
8914
|
+
function parseSetLineWidth(token) {
|
|
8915
|
+
const m = /^setlinewidth\s*\(\s*([^)]*)\)\s*$/.exec(token);
|
|
8916
|
+
if (m === null) return null;
|
|
8917
|
+
const v = parseFloat(m[1]);
|
|
8918
|
+
return Number.isNaN(v) ? 0 : v;
|
|
8919
|
+
}
|
|
8920
|
+
function applyToken(flags, token) {
|
|
8921
|
+
if (token === "radial") {
|
|
8922
|
+
flags.radial = true;
|
|
8923
|
+
flags.filled = true;
|
|
8924
|
+
return;
|
|
8925
|
+
}
|
|
8926
|
+
const key = TOKEN_FLAG[token];
|
|
8927
|
+
if (key !== void 0) flags[key] = true;
|
|
8928
|
+
}
|
|
8929
|
+
function nonEmpty(s) {
|
|
8930
|
+
return s !== void 0 && s.length > 0;
|
|
8931
|
+
}
|
|
8932
|
+
function orElse(s, fallback) {
|
|
8933
|
+
return nonEmpty(s) ? s : fallback;
|
|
8934
|
+
}
|
|
8935
|
+
function firstSolidColor(raw) {
|
|
8936
|
+
const grad = parseGradientSpec(raw);
|
|
8937
|
+
return grad !== null ? grad[0] : raw;
|
|
8938
|
+
}
|
|
8939
|
+
function parseStyleFlags(style2) {
|
|
8940
|
+
const flags = zeroFlags();
|
|
8941
|
+
if (!style2) return flags;
|
|
8942
|
+
let fun = 0;
|
|
8943
|
+
for (const raw of style2.split(",")) {
|
|
8944
|
+
const token = raw.trim();
|
|
8945
|
+
if (token.length === 0) continue;
|
|
8946
|
+
if (fun === FUNLIMIT - 1) return zeroFlags();
|
|
8947
|
+
fun++;
|
|
8948
|
+
const lw = parseSetLineWidth(token);
|
|
8949
|
+
if (lw !== null) {
|
|
8950
|
+
flags.setLineWidth = lw;
|
|
8951
|
+
continue;
|
|
8952
|
+
}
|
|
8953
|
+
if (!token.includes("(")) applyToken(flags, token);
|
|
8954
|
+
}
|
|
8955
|
+
return flags;
|
|
8956
|
+
}
|
|
8957
|
+
function styleHasInvisibleAlias(style2) {
|
|
8958
|
+
if (!style2) return false;
|
|
8959
|
+
let fun = 0;
|
|
8960
|
+
for (const raw of style2.split(",")) {
|
|
8961
|
+
const token = raw.trim();
|
|
8962
|
+
if (token.length === 0) continue;
|
|
8963
|
+
if (fun === FUNLIMIT - 1) return false;
|
|
8964
|
+
fun++;
|
|
8965
|
+
if (token === "invisible") return true;
|
|
8966
|
+
}
|
|
8967
|
+
return false;
|
|
8968
|
+
}
|
|
8969
|
+
function resolvePenType(flags) {
|
|
8970
|
+
if (flags.invis) return 0 /* None */;
|
|
8971
|
+
if (flags.dashed) return 1 /* Dashed */;
|
|
8972
|
+
if (flags.dotted) return 2 /* Dotted */;
|
|
8973
|
+
return 3 /* Solid */;
|
|
8974
|
+
}
|
|
8975
|
+
function resolvePenWidth(flags, penwidthAttr) {
|
|
8976
|
+
if (penwidthAttr && penwidthAttr.length > 0) {
|
|
8977
|
+
const v = parseFloat(penwidthAttr);
|
|
8978
|
+
if (isFinite(v)) return v;
|
|
8979
|
+
}
|
|
8980
|
+
if (flags.setLineWidth !== null) return flags.setLineWidth;
|
|
8981
|
+
if (flags.bold) return PENWIDTH_BOLD;
|
|
8982
|
+
return 1;
|
|
8983
|
+
}
|
|
8984
|
+
function resolvePenColor(colorAttr) {
|
|
8985
|
+
if (!colorAttr || colorAttr.length === 0) return DEFAULT_COLOR;
|
|
8986
|
+
return firstSolidColor(colorAttr);
|
|
8987
|
+
}
|
|
8988
|
+
function clusterColorAttrs(attrs) {
|
|
8989
|
+
const base = nonEmpty(attrs.color) ? attrs.color : void 0;
|
|
8990
|
+
const pencolor = orElse(attrs.pencolor, base ?? "");
|
|
8991
|
+
const fillcolor = orElse(attrs.fillcolor, base ?? "");
|
|
8992
|
+
return {
|
|
8993
|
+
fillcolor: nonEmpty(fillcolor) ? fillcolor : void 0,
|
|
8994
|
+
pencolor: nonEmpty(pencolor) ? pencolor : void 0
|
|
8995
|
+
};
|
|
8996
|
+
}
|
|
8997
|
+
function applyBgcolor(attrs, filled, fillcolor) {
|
|
8998
|
+
if ((!filled || !fillcolor) && nonEmpty(attrs.bgcolor)) {
|
|
8999
|
+
return { filled: true, fillcolor: attrs.bgcolor };
|
|
9000
|
+
}
|
|
9001
|
+
return { filled, fillcolor };
|
|
9002
|
+
}
|
|
9003
|
+
function findStopColor(colorlist) {
|
|
9004
|
+
const { segs, error } = parseSegs(colorlist);
|
|
9005
|
+
if (error === 1 || error === 2) return null;
|
|
9006
|
+
if (segs.length < 2) return null;
|
|
9007
|
+
const seg0 = segs[0];
|
|
9008
|
+
const seg1 = segs[1];
|
|
9009
|
+
if (seg0.color === null) return null;
|
|
9010
|
+
const fillColor = seg0.color;
|
|
9011
|
+
const stopColor = seg1.color ?? DEFAULT_COLOR;
|
|
9012
|
+
const frac = seg0.hasFraction ? seg0.t : seg1.hasFraction ? 1 - seg1.t : 0;
|
|
9013
|
+
return { fillColor, stopColor, frac };
|
|
9014
|
+
}
|
|
9015
|
+
function parseAngle(gradientangle2) {
|
|
9016
|
+
if (!gradientangle2 || gradientangle2.length === 0) return 0;
|
|
9017
|
+
const v = parseInt(gradientangle2, 10);
|
|
9018
|
+
return isFinite(v) ? v : 0;
|
|
9019
|
+
}
|
|
9020
|
+
function buildResolvedFill(rawColor, flags, angle) {
|
|
9021
|
+
const stop = findStopColor(rawColor);
|
|
9022
|
+
if (stop === null) return { kind: "solid", color: rawColor };
|
|
9023
|
+
const kind = flags.radial ? "radial" : "linear";
|
|
9024
|
+
return { kind, fillColor: stop.fillColor, stopColor: stop.stopColor, frac: stop.frac, angle };
|
|
9025
|
+
}
|
|
9026
|
+
function resolveNodeFillEx(attrs) {
|
|
9027
|
+
const flags = parseStyleFlags(attrs.style);
|
|
9028
|
+
if (!flags.filled) return { kind: "none" };
|
|
9029
|
+
const raw = nonEmpty(attrs.fillcolor) ? attrs.fillcolor : nonEmpty(attrs.color) ? attrs.color : DEFAULT_FILL;
|
|
9030
|
+
return buildResolvedFill(raw, flags, parseAngle(attrs.gradientangle));
|
|
9031
|
+
}
|
|
9032
|
+
function resolveClusterFillEx(attrs) {
|
|
9033
|
+
const flags = parseStyleFlags(attrs.style);
|
|
9034
|
+
const colors = clusterColorAttrs(attrs);
|
|
9035
|
+
const bg = applyBgcolor(attrs, flags.filled, colors.fillcolor);
|
|
9036
|
+
if (!bg.filled) return { kind: "none" };
|
|
9037
|
+
const raw = bg.fillcolor ?? DEFAULT_FILL;
|
|
9038
|
+
return buildResolvedFill(raw, flags, parseAngle(attrs.gradientangle));
|
|
9039
|
+
}
|
|
9040
|
+
|
|
9041
|
+
// src/common/emit-once.ts
|
|
9042
|
+
var seen = /* @__PURE__ */ new Set();
|
|
9043
|
+
registerRenderState(() => {
|
|
9044
|
+
seen.clear();
|
|
9045
|
+
});
|
|
9046
|
+
function emitOnce(str) {
|
|
9047
|
+
if (seen.has(str)) return false;
|
|
9048
|
+
seen.add(str);
|
|
9049
|
+
return true;
|
|
9050
|
+
}
|
|
9051
|
+
|
|
8731
9052
|
// src/render/color-resolve.ts
|
|
8732
9053
|
var SVG_KNOWN_COLORS = [
|
|
8733
9054
|
"aliceblue",
|
|
@@ -8880,12 +9201,33 @@ var SVG_KNOWN_COLORS = [
|
|
|
8880
9201
|
"yellowgreen"
|
|
8881
9202
|
];
|
|
8882
9203
|
var KNOWN_COLORS = new Set(SVG_KNOWN_COLORS);
|
|
8883
|
-
|
|
9204
|
+
var rendererColors = { hasKnownList: true };
|
|
9205
|
+
registerRenderState(() => {
|
|
9206
|
+
rendererColors.hasKnownList = true;
|
|
9207
|
+
});
|
|
9208
|
+
function setRendererKnownColors(hasList) {
|
|
9209
|
+
rendererColors.hasKnownList = hasList;
|
|
9210
|
+
}
|
|
9211
|
+
function firstColor(name) {
|
|
9212
|
+
const i = name.indexOf(":");
|
|
9213
|
+
return i < 0 ? name : name.slice(0, i);
|
|
9214
|
+
}
|
|
9215
|
+
function resolveRenderColor(raw, report = true) {
|
|
8884
9216
|
if (raw === "" || raw === "none") return { type: "none" };
|
|
8885
|
-
|
|
9217
|
+
const known = KNOWN_COLORS.has(raw.toLowerCase());
|
|
9218
|
+
if (known && (rendererColors.hasKnownList || !report)) return { type: "string", s: raw };
|
|
8886
9219
|
const color = { type: "rgba", r: 0, g: 0, b: 0, a: 0 };
|
|
8887
|
-
colorxlate(raw, color, "rgba");
|
|
8888
|
-
|
|
9220
|
+
const rc = colorxlate(raw, color, "rgba");
|
|
9221
|
+
if (report) reportColorxlate(raw, rc);
|
|
9222
|
+
return known ? { type: "string", s: raw } : color;
|
|
9223
|
+
}
|
|
9224
|
+
function reportColorxlate(name, rc) {
|
|
9225
|
+
if (rc === 0 /* ColorOk */) return;
|
|
9226
|
+
if (rc === 1 /* ColorUnknown */) {
|
|
9227
|
+
if (emitOnce(`color ${name}`)) agwarningf(`${name} is not a known color.`);
|
|
9228
|
+
} else {
|
|
9229
|
+
agerrorf("error in colorxlate()");
|
|
9230
|
+
}
|
|
8889
9231
|
}
|
|
8890
9232
|
function withColorScheme(scheme, fn) {
|
|
8891
9233
|
const prev = getColorScheme();
|
|
@@ -8932,6 +9274,72 @@ function textFillAttrs(fontColor) {
|
|
|
8932
9274
|
if (byte < 255) out += ' fill-opacity="' + (byte / 255).toFixed(6) + '"';
|
|
8933
9275
|
return out;
|
|
8934
9276
|
}
|
|
9277
|
+
var DEFAULT_COLOR2 = "black";
|
|
9278
|
+
var SEG_EPS = 1e-5;
|
|
9279
|
+
function reportColorNames(names) {
|
|
9280
|
+
for (const name of names) resolveRenderColor(firstColor(name));
|
|
9281
|
+
}
|
|
9282
|
+
function countChar(s, ch) {
|
|
9283
|
+
return s.split(ch).length - 1;
|
|
9284
|
+
}
|
|
9285
|
+
function multicolorNames(color, arrows) {
|
|
9286
|
+
const { segs, error } = parseSegs(color);
|
|
9287
|
+
if (error === 1 || error === 2) return null;
|
|
9288
|
+
const out = [];
|
|
9289
|
+
const front = segs[0]?.color ?? null;
|
|
9290
|
+
for (const bz of arrows) {
|
|
9291
|
+
let endcolor = null;
|
|
9292
|
+
for (const seg2 of segs) {
|
|
9293
|
+
if (seg2.color === null) break;
|
|
9294
|
+
if (Math.abs(seg2.t) < SEG_EPS) continue;
|
|
9295
|
+
out.push(seg2.color);
|
|
9296
|
+
endcolor = seg2.color;
|
|
9297
|
+
}
|
|
9298
|
+
if (bz.sflag && front !== null) out.push(front);
|
|
9299
|
+
if (bz.eflag && endcolor !== null) out.push(endcolor);
|
|
9300
|
+
}
|
|
9301
|
+
return out;
|
|
9302
|
+
}
|
|
9303
|
+
function taperedNames(color, fillcolor, hasFill) {
|
|
9304
|
+
const pen = color === "" ? DEFAULT_COLOR2 : color;
|
|
9305
|
+
return hasFill ? [pen, fillcolor === "" ? DEFAULT_COLOR2 : fillcolor] : [pen];
|
|
9306
|
+
}
|
|
9307
|
+
function edgeGraphicsColors(spec) {
|
|
9308
|
+
const numc = countChar(spec.color, ":");
|
|
9309
|
+
let color = spec.color;
|
|
9310
|
+
if (countChar(color, ";") > 0 && numc > 0) {
|
|
9311
|
+
const multi = multicolorNames(color, spec.arrows);
|
|
9312
|
+
if (multi !== null) return multi;
|
|
9313
|
+
color = DEFAULT_COLOR2;
|
|
9314
|
+
}
|
|
9315
|
+
const hasFill = spec.fillcolor !== "";
|
|
9316
|
+
const early = hasFill ? [spec.fillcolor] : [];
|
|
9317
|
+
if (spec.tapered) return [...early, ...taperedNames(color, spec.fillcolor, hasFill)];
|
|
9318
|
+
if (numc > 0) return [...early, ...color.split(":").filter((c) => c !== "")];
|
|
9319
|
+
const fill = hasFill ? spec.fillcolor : color;
|
|
9320
|
+
if (color !== "") return [...early, color, fill];
|
|
9321
|
+
return [...early, DEFAULT_COLOR2, fill !== "" ? fill : DEFAULT_COLOR2];
|
|
9322
|
+
}
|
|
9323
|
+
function reportEdgeColors(e) {
|
|
9324
|
+
const spl = e.info.spl;
|
|
9325
|
+
if (!spl) return;
|
|
9326
|
+
const color = e.attrs.get("color") ?? "";
|
|
9327
|
+
reportColorNames(edgeGraphicsColors({
|
|
9328
|
+
color,
|
|
9329
|
+
fillcolor: e.attrs.get("fillcolor") ?? "",
|
|
9330
|
+
tapered: styleTokens(e.attrs.get("style")).includes("tapered"),
|
|
9331
|
+
arrows: spl.list.map((bz) => ({ sflag: bz.sflag !== 0, eflag: bz.eflag !== 0 }))
|
|
9332
|
+
}));
|
|
9333
|
+
}
|
|
9334
|
+
function backgroundColors(bgcolor, truecolor) {
|
|
9335
|
+
let str = bgcolor !== void 0 && bgcolor !== "" ? bgcolor : "white";
|
|
9336
|
+
if (str === "transparent") {
|
|
9337
|
+
if (truecolor) return [];
|
|
9338
|
+
str = "white";
|
|
9339
|
+
}
|
|
9340
|
+
const stop = findStopColor(str);
|
|
9341
|
+
return stop === null ? [str, "transparent"] : [stop.fillColor, "transparent", stop.stopColor];
|
|
9342
|
+
}
|
|
8935
9343
|
|
|
8936
9344
|
// src/common/poly-shapes-util.ts
|
|
8937
9345
|
var RBCONST = 12;
|
|
@@ -9543,6 +9951,7 @@ function htmlFillPenWidth() {
|
|
|
9543
9951
|
function resetHtmlFillPenWidth() {
|
|
9544
9952
|
htmlFillPen = 1;
|
|
9545
9953
|
}
|
|
9954
|
+
registerRenderState(resetHtmlFillPenWidth);
|
|
9546
9955
|
function penTypeOf(style2) {
|
|
9547
9956
|
const st = htmlStyle(style2);
|
|
9548
9957
|
if (st.dashed) return 1 /* Dashed */;
|
|
@@ -9671,6 +10080,31 @@ function emitSidedPolylines(sides2, corners, renderer, job) {
|
|
|
9671
10080
|
renderer.polyline(seq2.map((i) => corners[i]), job);
|
|
9672
10081
|
}
|
|
9673
10082
|
}
|
|
10083
|
+
var HTML_DEFAULT_COLOR = "black";
|
|
10084
|
+
function bgNames(bgcolor) {
|
|
10085
|
+
const spec = parseGradientSpec(bgcolor);
|
|
10086
|
+
return spec === null ? [bgcolor] : [spec[0], spec[1]];
|
|
10087
|
+
}
|
|
10088
|
+
function cellNames(cell2) {
|
|
10089
|
+
if (htmlStyle(cell2.style).invisible) return [];
|
|
10090
|
+
const out = cell2.bgcolor !== void 0 ? bgNames(cell2.bgcolor) : [];
|
|
10091
|
+
if (cell2.border > 0) out.push(cell2.color ?? HTML_DEFAULT_COLOR);
|
|
10092
|
+
if (cell2.nested !== void 0) out.push(...tableNames(cell2.nested));
|
|
10093
|
+
else for (const line of cell2.lines) if (line.fontColor !== null) out.push(line.fontColor);
|
|
10094
|
+
return out;
|
|
10095
|
+
}
|
|
10096
|
+
function tableNames(tbl) {
|
|
10097
|
+
if (htmlStyle(tbl.style).invisible) return [];
|
|
10098
|
+
const out = tbl.bgcolor !== void 0 ? bgNames(tbl.bgcolor) : [];
|
|
10099
|
+
const color = tbl.color ?? HTML_DEFAULT_COLOR;
|
|
10100
|
+
if (tbl.cells.some((c) => c.vruled === true || c.hruled === true)) out.push(color);
|
|
10101
|
+
if (tbl.border > 0) out.push(color);
|
|
10102
|
+
for (const cell2 of tbl.cells) out.push(...cellNames(cell2));
|
|
10103
|
+
return out;
|
|
10104
|
+
}
|
|
10105
|
+
function htmlLabelColors(label) {
|
|
10106
|
+
return [label.color ?? HTML_DEFAULT_COLOR, ...tableNames(label)];
|
|
10107
|
+
}
|
|
9674
10108
|
|
|
9675
10109
|
// src/common/htmltable-emit-rules.ts
|
|
9676
10110
|
function emitHtmlRules(ctx) {
|
|
@@ -9757,6 +10191,7 @@ function resetHtmlAnchorIds() {
|
|
|
9757
10191
|
anchorEnv.objLabel = null;
|
|
9758
10192
|
anchorEnv.imgscale = "false";
|
|
9759
10193
|
}
|
|
10194
|
+
registerRenderState(resetHtmlAnchorIds);
|
|
9760
10195
|
function initHtmlAnchor(data, box, renderer, job) {
|
|
9761
10196
|
if (data.href === void 0 && data.title === void 0 && data.target === void 0) {
|
|
9762
10197
|
return false;
|
|
@@ -10011,7 +10446,7 @@ var sides = (v) => {
|
|
|
10011
10446
|
};
|
|
10012
10447
|
var STYLE_WORDS = ["rounded", "radial", "solid", "invisible", "invis", "dotted", "dashed"];
|
|
10013
10448
|
var STYLE_DELIM = " ,";
|
|
10014
|
-
function
|
|
10449
|
+
function styleTokens2(v) {
|
|
10015
10450
|
const out = [];
|
|
10016
10451
|
const span = (from, member) => {
|
|
10017
10452
|
let i = from;
|
|
@@ -10030,7 +10465,7 @@ function styleTokens(v) {
|
|
|
10030
10465
|
var style = (v) => {
|
|
10031
10466
|
const legal = [];
|
|
10032
10467
|
const text = [];
|
|
10033
|
-
for (const tk of
|
|
10468
|
+
for (const tk of styleTokens2(v)) {
|
|
10034
10469
|
if (STYLE_WORDS.includes(lower(tk))) legal.push(tk);
|
|
10035
10470
|
else text.push(warning(`Illegal value ${tk} for STYLE - ignored
|
|
10036
10471
|
`));
|
|
@@ -10149,10 +10584,7 @@ var StderrLines = class {
|
|
|
10149
10584
|
this.pending = "";
|
|
10150
10585
|
}
|
|
10151
10586
|
};
|
|
10152
|
-
var consoleLine = (line) =>
|
|
10153
|
-
if (line.startsWith("Warning")) console.warn(line);
|
|
10154
|
-
else console.error(line);
|
|
10155
|
-
};
|
|
10587
|
+
var consoleLine = (line) => agerrFinished(line);
|
|
10156
10588
|
var labelStderr = () => new StderrLines(consoleLine);
|
|
10157
10589
|
var agerrLine = (out, msg) => {
|
|
10158
10590
|
if (out === void 0) consoleLine(msg);
|
|
@@ -10439,28 +10871,46 @@ var HTML_ENTITIES = {
|
|
|
10439
10871
|
"zwj": 8205,
|
|
10440
10872
|
"zwnj": 8204
|
|
10441
10873
|
};
|
|
10442
|
-
var
|
|
10443
|
-
|
|
10444
|
-
|
|
10445
|
-
|
|
10446
|
-
|
|
10447
|
-
|
|
10448
|
-
|
|
10449
|
-
|
|
10450
|
-
|
|
10451
|
-
|
|
10452
|
-
|
|
10874
|
+
var ENTITY_NAME_LENGTH_MAX = 8;
|
|
10875
|
+
function numericEntity(s, at) {
|
|
10876
|
+
const hex = s[at + 1] === "x" || s[at + 1] === "X";
|
|
10877
|
+
const digit = hex ? /^[0-9A-Fa-f]$/ : /^[0-9]$/;
|
|
10878
|
+
let n = 0;
|
|
10879
|
+
let i = hex ? 2 : 1;
|
|
10880
|
+
for (; i < 8; i++) {
|
|
10881
|
+
const c = s[at + i] ?? "";
|
|
10882
|
+
if (!digit.test(c)) break;
|
|
10883
|
+
n = n * (hex ? 16 : 10) + parseInt(c, 16);
|
|
10884
|
+
}
|
|
10885
|
+
if (i < 8 && s[at + i] === ";") return { value: n, next: at + i + 1 };
|
|
10886
|
+
return { value: 0, next: at };
|
|
10887
|
+
}
|
|
10888
|
+
function namedEntity(s, at) {
|
|
10889
|
+
for (let i = 0; i < ENTITY_NAME_LENGTH_MAX; i++) {
|
|
10890
|
+
const c = s[at + i];
|
|
10891
|
+
if (c === void 0 || c === "\0") break;
|
|
10892
|
+
if (c === ";") {
|
|
10893
|
+
const key = s.slice(at, at + i);
|
|
10894
|
+
if (Object.hasOwn(HTML_ENTITIES, key)) return { value: HTML_ENTITIES[key], next: at + i + 1 };
|
|
10895
|
+
break;
|
|
10896
|
+
}
|
|
10897
|
+
}
|
|
10898
|
+
return { value: 0, next: at };
|
|
10453
10899
|
}
|
|
10454
|
-
function
|
|
10455
|
-
|
|
10456
|
-
return BASIC_ENTITIES[body] ?? HTML_ENTITIES[body] ?? null;
|
|
10900
|
+
function htmlEntity(s, at) {
|
|
10901
|
+
return s[at] === "#" ? numericEntity(s, at) : namedEntity(s, at);
|
|
10457
10902
|
}
|
|
10458
10903
|
function htmlEntityUTF8(s) {
|
|
10459
|
-
|
|
10460
|
-
|
|
10461
|
-
|
|
10462
|
-
|
|
10463
|
-
|
|
10904
|
+
let amp = s.indexOf("&");
|
|
10905
|
+
if (amp < 0) return s;
|
|
10906
|
+
let out = "";
|
|
10907
|
+
let from = 0;
|
|
10908
|
+
for (; amp >= 0; amp = s.indexOf("&", from)) {
|
|
10909
|
+
const e = htmlEntity(s, amp + 1);
|
|
10910
|
+
out += s.slice(from, amp) + (e.value ? String.fromCodePoint(e.value) : "&");
|
|
10911
|
+
from = e.next;
|
|
10912
|
+
}
|
|
10913
|
+
return out + s.slice(from);
|
|
10464
10914
|
}
|
|
10465
10915
|
|
|
10466
10916
|
// src/common/htmltable-lex-attvalue.ts
|
|
@@ -10594,14 +11044,14 @@ function tagEdge(text, i) {
|
|
|
10594
11044
|
if (i + 1 >= text.length) return PARTIAL;
|
|
10595
11045
|
return text[i + 1] === ">" ? COMPLETE_END(i + 2) : void 0;
|
|
10596
11046
|
}
|
|
10597
|
-
function storeAttError(text, p, at, pair,
|
|
10598
|
-
if (
|
|
10599
|
-
|
|
11047
|
+
function storeAttError(text, p, at, pair, seen2) {
|
|
11048
|
+
if (seen2.has(pair.name)) return { message: XML_ERROR_DUPLICATE_ATTRIBUTE, offset: at };
|
|
11049
|
+
seen2.add(pair.name);
|
|
10600
11050
|
const err = attValueError(text.slice(pair.value.start, pair.value.end), pair.value.start);
|
|
10601
11051
|
return err === void 0 ? void 0 : { message: err.message, offset: err.offset ?? p };
|
|
10602
11052
|
}
|
|
10603
11053
|
function scanAttributes(text, p, from) {
|
|
10604
|
-
const
|
|
11054
|
+
const seen2 = /* @__PURE__ */ new Set();
|
|
10605
11055
|
let attError;
|
|
10606
11056
|
let i = skipSpace(text, from);
|
|
10607
11057
|
for (; ; ) {
|
|
@@ -10610,7 +11060,7 @@ function scanAttributes(text, p, from) {
|
|
|
10610
11060
|
if (edge !== void 0) return edge;
|
|
10611
11061
|
const pair = scanPair(text, i);
|
|
10612
11062
|
if ("kind" in pair) return pair;
|
|
10613
|
-
attError ??= storeAttError(text, p, i, pair,
|
|
11063
|
+
attError ??= storeAttError(text, p, i, pair, seen2);
|
|
10614
11064
|
i = pair.next;
|
|
10615
11065
|
}
|
|
10616
11066
|
}
|
|
@@ -10678,9 +11128,11 @@ function scanCdata(text, p, base, dataOf, tokens) {
|
|
|
10678
11128
|
}
|
|
10679
11129
|
function scanText(text, p, base, tokens) {
|
|
10680
11130
|
const e = text.indexOf("<", p);
|
|
10681
|
-
const
|
|
10682
|
-
|
|
10683
|
-
|
|
11131
|
+
const slice = text.slice(p, e < 0 ? text.length : e);
|
|
11132
|
+
const from = e < 0 ? heldRefStart(slice) : void 0;
|
|
11133
|
+
const end = from === void 0 ? p + slice.length : p + from;
|
|
11134
|
+
if (end > p) tokens.push({ kind: "text", start: base + p, end: base + end });
|
|
11135
|
+
return { at: end, held: from !== void 0 };
|
|
10684
11136
|
}
|
|
10685
11137
|
function scanContent(text, base, inCdata, dataOf) {
|
|
10686
11138
|
const tokens = [];
|
|
@@ -10695,7 +11147,9 @@ function scanContent(text, base, inCdata, dataOf) {
|
|
|
10695
11147
|
continue;
|
|
10696
11148
|
}
|
|
10697
11149
|
if (text[p] !== "<") {
|
|
10698
|
-
|
|
11150
|
+
const scanned = scanText(text, p, base, tokens);
|
|
11151
|
+
if (scanned.held) return { tokens, consumed: scanned.at, inCdata: false };
|
|
11152
|
+
p = scanned.at;
|
|
10699
11153
|
continue;
|
|
10700
11154
|
}
|
|
10701
11155
|
const { scan, kind } = scanMarkup(text, p);
|
|
@@ -10795,24 +11249,44 @@ var ExpatFeed = class {
|
|
|
10795
11249
|
}
|
|
10796
11250
|
};
|
|
10797
11251
|
var XML_PREDEFINED_ENTITIES = /* @__PURE__ */ new Set(["lt", "gt", "amp", "quot", "apos"]);
|
|
10798
|
-
var
|
|
10799
|
-
|
|
10800
|
-
|
|
10801
|
-
|
|
10802
|
-
|
|
10803
|
-
|
|
10804
|
-
|
|
10805
|
-
|
|
11252
|
+
var SCANNED_ENTITY = /^&([^;&<]*);/;
|
|
11253
|
+
function contentRef(text, t) {
|
|
11254
|
+
const semi = text.indexOf(";", t);
|
|
11255
|
+
const ref = text.slice(t, semi < 0 ? text.length : semi + 1);
|
|
11256
|
+
const scan = scanAttValue(`"${ref}"`, 0);
|
|
11257
|
+
if ("close" in scan) return { end: t + scan.close - 1 };
|
|
11258
|
+
return { invalid: "invalid" in scan ? t + scan.invalid - 1 : text.length };
|
|
11259
|
+
}
|
|
11260
|
+
function firstRefProblem(text) {
|
|
11261
|
+
let t = text.indexOf("&");
|
|
11262
|
+
while (t >= 0) {
|
|
11263
|
+
if (text[t + 1] !== "#") {
|
|
11264
|
+
const name = SCANNED_ENTITY.exec(text.slice(t))?.[1];
|
|
11265
|
+
if (name !== void 0 && name.length >= 2 && Object.hasOwn(HTML_ENTITIES, name)) {
|
|
11266
|
+
t = text.indexOf("&", t + name.length + 2);
|
|
11267
|
+
continue;
|
|
11268
|
+
}
|
|
10806
11269
|
}
|
|
10807
|
-
const
|
|
10808
|
-
if (
|
|
10809
|
-
const key = text.slice(t + 1,
|
|
10810
|
-
if (
|
|
10811
|
-
return { message:
|
|
11270
|
+
const ref = contentRef(text, t);
|
|
11271
|
+
if ("invalid" in ref) return { message: XML_ERROR_INVALID_TOKEN, offset: ref.invalid, from: t };
|
|
11272
|
+
const key = text.slice(t + 1, ref.end - 1);
|
|
11273
|
+
if (text[t + 1] === "#") {
|
|
11274
|
+
if (charRefNumber(`&${key};`) < 0) return { message: XML_ERROR_BAD_CHAR_REF, offset: t, from: t };
|
|
11275
|
+
} else if (!XML_PREDEFINED_ENTITIES.has(key)) {
|
|
11276
|
+
return { message: XML_ERROR_UNDEFINED_ENTITY, offset: t, from: t };
|
|
10812
11277
|
}
|
|
11278
|
+
t = text.indexOf("&", ref.end);
|
|
10813
11279
|
}
|
|
10814
11280
|
return void 0;
|
|
10815
11281
|
}
|
|
11282
|
+
function textRefError(text) {
|
|
11283
|
+
const problem = firstRefProblem(text);
|
|
11284
|
+
return problem === void 0 ? void 0 : { message: problem.message, offset: problem.offset };
|
|
11285
|
+
}
|
|
11286
|
+
function heldRefStart(text) {
|
|
11287
|
+
const problem = firstRefProblem(text);
|
|
11288
|
+
return problem?.message === XML_ERROR_INVALID_TOKEN && problem.offset === text.length ? problem.from : void 0;
|
|
11289
|
+
}
|
|
10816
11290
|
function parseTagChunk(chunk) {
|
|
10817
11291
|
if (!chunk.endsWith(">")) return void 0;
|
|
10818
11292
|
const body = chunk.slice(1, -1);
|
|
@@ -10854,8 +11328,26 @@ function releaseXb(st, first) {
|
|
|
10854
11328
|
function cleanText(decoded) {
|
|
10855
11329
|
return decoded.replace(/[\x00-\x1f]/g, "");
|
|
10856
11330
|
}
|
|
11331
|
+
var XML_PREDEFINED = { lt: "<", gt: ">", amp: "&", quot: '"', apos: "'" };
|
|
11332
|
+
var SCAN_ENTITY_MIN = 2;
|
|
11333
|
+
var SCAN_ENTITY_MAX = 8;
|
|
11334
|
+
var TEXT_REF = /&(#x[0-9A-Fa-f]+|#[0-9]+|[^&;]+);/g;
|
|
11335
|
+
function textRefValue(ref, body) {
|
|
11336
|
+
if (body[0] === "#") {
|
|
11337
|
+
const v = charRefNumber(ref);
|
|
11338
|
+
return v < 0 ? ref : String.fromCodePoint(v);
|
|
11339
|
+
}
|
|
11340
|
+
const n = body.length;
|
|
11341
|
+
if (n >= SCAN_ENTITY_MIN && n <= SCAN_ENTITY_MAX && Object.hasOwn(HTML_ENTITIES, body)) {
|
|
11342
|
+
return String.fromCodePoint(HTML_ENTITIES[body]);
|
|
11343
|
+
}
|
|
11344
|
+
return Object.hasOwn(XML_PREDEFINED, body) ? XML_PREDEFINED[body] : ref;
|
|
11345
|
+
}
|
|
11346
|
+
function decodeTextRefs(raw) {
|
|
11347
|
+
return raw.indexOf("&") < 0 ? raw : raw.replace(TEXT_REF, textRefValue);
|
|
11348
|
+
}
|
|
10857
11349
|
function textTokens(raw) {
|
|
10858
|
-
return charDataTokens(
|
|
11350
|
+
return charDataTokens(decodeTextRefs(raw));
|
|
10859
11351
|
}
|
|
10860
11352
|
function charDataTokens(decoded) {
|
|
10861
11353
|
const clean = cleanText(decoded);
|
|
@@ -11827,30 +12319,23 @@ var splitSizedLines = (texts, measurer, env) => {
|
|
|
11827
12319
|
return lines;
|
|
11828
12320
|
};
|
|
11829
12321
|
var itemHasFlags = (i) => i.bold === true || i.italic === true || i.underline === true || i.strikethrough === true || i.overline === true || i.subscript === true || i.superscript === true;
|
|
11830
|
-
var htmlTextIsSimple = (
|
|
12322
|
+
var htmlTextIsSimple = (lines, env) => {
|
|
11831
12323
|
let prevFs = -1;
|
|
11832
12324
|
let prevFace = null;
|
|
11833
|
-
|
|
11834
|
-
|
|
11835
|
-
|
|
11836
|
-
|
|
11837
|
-
|
|
11838
|
-
|
|
11839
|
-
|
|
11840
|
-
|
|
11841
|
-
if (++count > 1 || itemHasFlags(item)) return false;
|
|
11842
|
-
const { fs, face } = itemFont(item, env);
|
|
11843
|
-
if (prevFs < 0) prevFs = fs;
|
|
11844
|
-
else if (fs !== prevFs) return false;
|
|
11845
|
-
if (prevFace === null) prevFace = face;
|
|
11846
|
-
else if (face !== prevFace) return false;
|
|
11847
|
-
}
|
|
12325
|
+
for (const ln of lines) {
|
|
12326
|
+
const item = ln.items[0];
|
|
12327
|
+
if (ln.items.length > 1 || itemHasFlags(item)) return false;
|
|
12328
|
+
const { fs, face } = itemFont(item, env);
|
|
12329
|
+
if (prevFs < 0) prevFs = fs;
|
|
12330
|
+
else if (fs !== prevFs) return false;
|
|
12331
|
+
if (prevFace === null) prevFace = face;
|
|
12332
|
+
else if (face !== prevFace) return false;
|
|
11848
12333
|
}
|
|
11849
12334
|
return true;
|
|
11850
12335
|
};
|
|
11851
12336
|
var sizeTextContent = (texts, measurer, env = defaultSizeEnv()) => {
|
|
11852
12337
|
const lines = splitSizedLines(texts, measurer, env);
|
|
11853
|
-
const simple = htmlTextIsSimple(
|
|
12338
|
+
const simple = htmlTextIsSimple(lines, env);
|
|
11854
12339
|
let w = 0;
|
|
11855
12340
|
let h = 0;
|
|
11856
12341
|
for (const ln of lines) {
|
|
@@ -16922,6 +17407,7 @@ function normalizeFontName(name) {
|
|
|
16922
17407
|
return result;
|
|
16923
17408
|
}
|
|
16924
17409
|
var warnedFontNames = /* @__PURE__ */ new Set();
|
|
17410
|
+
registerRenderState(() => warnedFontNames.clear());
|
|
16925
17411
|
function getFamilyMetrics(fontName) {
|
|
16926
17412
|
const key = normalizeFontName(fontName);
|
|
16927
17413
|
for (const family of ALL_FONT_METRICS) {
|
|
@@ -16929,8 +17415,8 @@ function getFamilyMetrics(fontName) {
|
|
|
16929
17415
|
}
|
|
16930
17416
|
if (!warnedFontNames.has(fontName)) {
|
|
16931
17417
|
warnedFontNames.add(fontName);
|
|
16932
|
-
|
|
16933
|
-
`
|
|
17418
|
+
agwarningf(
|
|
17419
|
+
`no hard-coded metrics for '${fontName}'. Falling back to 'Times' metrics`
|
|
16934
17420
|
);
|
|
16935
17421
|
}
|
|
16936
17422
|
return TIMES_FALLBACK;
|
|
@@ -17089,10 +17575,37 @@ function getVariantWidths(family, bold, italic) {
|
|
|
17089
17575
|
return family.regular;
|
|
17090
17576
|
}
|
|
17091
17577
|
var SPACE_CHAR_CODE = 32;
|
|
17578
|
+
var FIRST_NON_ASCII = 128;
|
|
17579
|
+
var warned = /* @__PURE__ */ new Set();
|
|
17580
|
+
var NON_ASCII_FLAG = "non-ascii";
|
|
17581
|
+
var ASCII_FLAG = "ascii";
|
|
17582
|
+
registerRenderState(() => warned.clear());
|
|
17583
|
+
function warnNonAscii(character) {
|
|
17584
|
+
if (warned.has(NON_ASCII_FLAG)) return;
|
|
17585
|
+
warned.add(NON_ASCII_FLAG);
|
|
17586
|
+
agwarningf(
|
|
17587
|
+
`Warning: no value for width of non-ASCII character ${character}. Falling back to width of space character`
|
|
17588
|
+
);
|
|
17589
|
+
}
|
|
17590
|
+
function warnAscii(character) {
|
|
17591
|
+
if (warned.has(ASCII_FLAG)) return;
|
|
17592
|
+
warned.add(ASCII_FLAG);
|
|
17593
|
+
agwarningf(
|
|
17594
|
+
`Warning: no value for width of ASCII character ${character}. Falling back to 0`
|
|
17595
|
+
);
|
|
17596
|
+
}
|
|
17092
17597
|
function charWidthUnits(widths, charCode) {
|
|
17093
|
-
|
|
17598
|
+
let code = charCode;
|
|
17599
|
+
if (code >= FIRST_NON_ASCII) {
|
|
17600
|
+
warnNonAscii(code);
|
|
17601
|
+
code = SPACE_CHAR_CODE;
|
|
17602
|
+
}
|
|
17094
17603
|
const w = widths[code] ?? -1;
|
|
17095
|
-
|
|
17604
|
+
if (w < 0) {
|
|
17605
|
+
warnAscii(code);
|
|
17606
|
+
return 0;
|
|
17607
|
+
}
|
|
17608
|
+
return w;
|
|
17096
17609
|
}
|
|
17097
17610
|
var utf8Encoder = new TextEncoder();
|
|
17098
17611
|
function utf8Bytes(text) {
|
|
@@ -17775,7 +18288,7 @@ function preprocessTooltip(s) {
|
|
|
17775
18288
|
// src/common/make-label.ts
|
|
17776
18289
|
var DEFAULT_FONTSIZE2 = 14;
|
|
17777
18290
|
var DEFAULT_FONTNAME = "Times-Roman";
|
|
17778
|
-
var
|
|
18291
|
+
var DEFAULT_COLOR3 = "black";
|
|
17779
18292
|
function getPenColor(obj) {
|
|
17780
18293
|
if (obj === void 0) return void 0;
|
|
17781
18294
|
const pc = obj.attrs.get("pencolor");
|
|
@@ -18397,252 +18910,6 @@ function assembleResult(p, dimen, grown, fixedshape) {
|
|
|
18397
18910
|
};
|
|
18398
18911
|
}
|
|
18399
18912
|
|
|
18400
|
-
// src/common/multicolor.ts
|
|
18401
|
-
var EPS = 1e-5;
|
|
18402
|
-
function aeq0(x) {
|
|
18403
|
-
return x < EPS && x > -EPS;
|
|
18404
|
-
}
|
|
18405
|
-
function getSegLen(token) {
|
|
18406
|
-
const semi = token.indexOf(";");
|
|
18407
|
-
if (semi === -1) return { color: token, v: 0 };
|
|
18408
|
-
const color = token.slice(0, semi);
|
|
18409
|
-
const rest = token.slice(semi + 1);
|
|
18410
|
-
if (rest.length === 0) return { color, v: -1 };
|
|
18411
|
-
const parsed = parseFloat(rest);
|
|
18412
|
-
return !isNaN(parsed) && parsed >= 0 ? { color, v: parsed } : { color, v: -1 };
|
|
18413
|
-
}
|
|
18414
|
-
function appendSeg(token, left2, segs, warnedExceeded) {
|
|
18415
|
-
const { color, v } = getSegLen(token);
|
|
18416
|
-
if (v < 0) return null;
|
|
18417
|
-
let t = v;
|
|
18418
|
-
let rval = 0;
|
|
18419
|
-
const del = t - left2;
|
|
18420
|
-
if (del > 0) {
|
|
18421
|
-
if (!aeq0(del) && !warnedExceeded.v) {
|
|
18422
|
-
warnedExceeded.v = true;
|
|
18423
|
-
rval = 3;
|
|
18424
|
-
}
|
|
18425
|
-
t = left2;
|
|
18426
|
-
}
|
|
18427
|
-
left2 -= t;
|
|
18428
|
-
segs.push({ color: color.length > 0 ? color : null, t, hasFraction: t > 0 && v > 0 });
|
|
18429
|
-
return { left: left2, rval };
|
|
18430
|
-
}
|
|
18431
|
-
function distributeLeft(segs, left2) {
|
|
18432
|
-
if (left2 <= 0) return;
|
|
18433
|
-
const zeroCount = segs.filter((s) => s.t <= 0).length;
|
|
18434
|
-
if (zeroCount > 0) {
|
|
18435
|
-
const delta2 = left2 / zeroCount;
|
|
18436
|
-
for (const s of segs) {
|
|
18437
|
-
if (s.t <= 0) s.t = delta2;
|
|
18438
|
-
}
|
|
18439
|
-
} else if (segs.length > 0) {
|
|
18440
|
-
segs[segs.length - 1].t += left2;
|
|
18441
|
-
}
|
|
18442
|
-
}
|
|
18443
|
-
function trimTrailing(segs) {
|
|
18444
|
-
while (segs.length > 0 && (segs[segs.length - 1]?.t ?? 0) <= 0) {
|
|
18445
|
-
segs.pop();
|
|
18446
|
-
}
|
|
18447
|
-
}
|
|
18448
|
-
function parseSegs(colorlist) {
|
|
18449
|
-
const segs = [];
|
|
18450
|
-
let left2 = 1;
|
|
18451
|
-
let rval = 0;
|
|
18452
|
-
let badFloatCount = 0;
|
|
18453
|
-
const warnedExceeded = { v: false };
|
|
18454
|
-
for (const token of colorlist.split(":")) {
|
|
18455
|
-
const result = appendSeg(token, left2, segs, warnedExceeded);
|
|
18456
|
-
if (result === null) {
|
|
18457
|
-
const errCode = badFloatCount === 0 ? 2 : 1;
|
|
18458
|
-
badFloatCount++;
|
|
18459
|
-
return { segs: [], error: errCode };
|
|
18460
|
-
}
|
|
18461
|
-
if (result.rval === 3) rval = 3;
|
|
18462
|
-
left2 = result.left;
|
|
18463
|
-
if (aeq0(left2)) {
|
|
18464
|
-
left2 = 0;
|
|
18465
|
-
break;
|
|
18466
|
-
}
|
|
18467
|
-
}
|
|
18468
|
-
distributeLeft(segs, left2);
|
|
18469
|
-
trimTrailing(segs);
|
|
18470
|
-
return { segs, error: rval };
|
|
18471
|
-
}
|
|
18472
|
-
|
|
18473
|
-
// src/common/style-resolve.ts
|
|
18474
|
-
var DEFAULT_COLOR2 = "black";
|
|
18475
|
-
var DEFAULT_FILL = "lightgrey";
|
|
18476
|
-
var PENWIDTH_BOLD = 2;
|
|
18477
|
-
var TOKEN_FLAG = {
|
|
18478
|
-
filled: "filled",
|
|
18479
|
-
dashed: "dashed",
|
|
18480
|
-
dotted: "dotted",
|
|
18481
|
-
bold: "bold",
|
|
18482
|
-
invis: "invis",
|
|
18483
|
-
diagonals: "diagonals",
|
|
18484
|
-
rounded: "rounded",
|
|
18485
|
-
striped: "striped",
|
|
18486
|
-
wedged: "wedged",
|
|
18487
|
-
underline: "underline"
|
|
18488
|
-
};
|
|
18489
|
-
function zeroFlags() {
|
|
18490
|
-
return {
|
|
18491
|
-
filled: false,
|
|
18492
|
-
dashed: false,
|
|
18493
|
-
dotted: false,
|
|
18494
|
-
bold: false,
|
|
18495
|
-
invis: false,
|
|
18496
|
-
diagonals: false,
|
|
18497
|
-
rounded: false,
|
|
18498
|
-
radial: false,
|
|
18499
|
-
striped: false,
|
|
18500
|
-
wedged: false,
|
|
18501
|
-
underline: false,
|
|
18502
|
-
setLineWidth: null
|
|
18503
|
-
};
|
|
18504
|
-
}
|
|
18505
|
-
var FUNLIMIT = 64;
|
|
18506
|
-
function styleTokens2(style2) {
|
|
18507
|
-
if (!style2) return [];
|
|
18508
|
-
const out = [];
|
|
18509
|
-
let fun = 0;
|
|
18510
|
-
for (const raw of style2.split(",")) {
|
|
18511
|
-
const token = raw.trim();
|
|
18512
|
-
if (token.length === 0) continue;
|
|
18513
|
-
if (fun === FUNLIMIT - 1) return [];
|
|
18514
|
-
fun++;
|
|
18515
|
-
out.push(token);
|
|
18516
|
-
}
|
|
18517
|
-
return out;
|
|
18518
|
-
}
|
|
18519
|
-
function parseSetLineWidth(token) {
|
|
18520
|
-
const m = /^setlinewidth\s*\(\s*([^)]*)\)\s*$/.exec(token);
|
|
18521
|
-
if (m === null) return null;
|
|
18522
|
-
const v = parseFloat(m[1]);
|
|
18523
|
-
return Number.isNaN(v) ? 0 : v;
|
|
18524
|
-
}
|
|
18525
|
-
function applyToken(flags, token) {
|
|
18526
|
-
if (token === "radial") {
|
|
18527
|
-
flags.radial = true;
|
|
18528
|
-
flags.filled = true;
|
|
18529
|
-
return;
|
|
18530
|
-
}
|
|
18531
|
-
const key = TOKEN_FLAG[token];
|
|
18532
|
-
if (key !== void 0) flags[key] = true;
|
|
18533
|
-
}
|
|
18534
|
-
function nonEmpty(s) {
|
|
18535
|
-
return s !== void 0 && s.length > 0;
|
|
18536
|
-
}
|
|
18537
|
-
function orElse(s, fallback) {
|
|
18538
|
-
return nonEmpty(s) ? s : fallback;
|
|
18539
|
-
}
|
|
18540
|
-
function firstSolidColor(raw) {
|
|
18541
|
-
const grad = parseGradientSpec(raw);
|
|
18542
|
-
return grad !== null ? grad[0] : raw;
|
|
18543
|
-
}
|
|
18544
|
-
function parseStyleFlags(style2) {
|
|
18545
|
-
const flags = zeroFlags();
|
|
18546
|
-
if (!style2) return flags;
|
|
18547
|
-
let fun = 0;
|
|
18548
|
-
for (const raw of style2.split(",")) {
|
|
18549
|
-
const token = raw.trim();
|
|
18550
|
-
if (token.length === 0) continue;
|
|
18551
|
-
if (fun === FUNLIMIT - 1) return zeroFlags();
|
|
18552
|
-
fun++;
|
|
18553
|
-
const lw = parseSetLineWidth(token);
|
|
18554
|
-
if (lw !== null) {
|
|
18555
|
-
flags.setLineWidth = lw;
|
|
18556
|
-
continue;
|
|
18557
|
-
}
|
|
18558
|
-
if (!token.includes("(")) applyToken(flags, token);
|
|
18559
|
-
}
|
|
18560
|
-
return flags;
|
|
18561
|
-
}
|
|
18562
|
-
function styleHasInvisibleAlias(style2) {
|
|
18563
|
-
if (!style2) return false;
|
|
18564
|
-
let fun = 0;
|
|
18565
|
-
for (const raw of style2.split(",")) {
|
|
18566
|
-
const token = raw.trim();
|
|
18567
|
-
if (token.length === 0) continue;
|
|
18568
|
-
if (fun === FUNLIMIT - 1) return false;
|
|
18569
|
-
fun++;
|
|
18570
|
-
if (token === "invisible") return true;
|
|
18571
|
-
}
|
|
18572
|
-
return false;
|
|
18573
|
-
}
|
|
18574
|
-
function resolvePenType(flags) {
|
|
18575
|
-
if (flags.invis) return 0 /* None */;
|
|
18576
|
-
if (flags.dashed) return 1 /* Dashed */;
|
|
18577
|
-
if (flags.dotted) return 2 /* Dotted */;
|
|
18578
|
-
return 3 /* Solid */;
|
|
18579
|
-
}
|
|
18580
|
-
function resolvePenWidth(flags, penwidthAttr) {
|
|
18581
|
-
if (penwidthAttr && penwidthAttr.length > 0) {
|
|
18582
|
-
const v = parseFloat(penwidthAttr);
|
|
18583
|
-
if (isFinite(v)) return v;
|
|
18584
|
-
}
|
|
18585
|
-
if (flags.setLineWidth !== null) return flags.setLineWidth;
|
|
18586
|
-
if (flags.bold) return PENWIDTH_BOLD;
|
|
18587
|
-
return 1;
|
|
18588
|
-
}
|
|
18589
|
-
function resolvePenColor(colorAttr) {
|
|
18590
|
-
if (!colorAttr || colorAttr.length === 0) return DEFAULT_COLOR2;
|
|
18591
|
-
return firstSolidColor(colorAttr);
|
|
18592
|
-
}
|
|
18593
|
-
function clusterColorAttrs(attrs) {
|
|
18594
|
-
const base = nonEmpty(attrs.color) ? attrs.color : void 0;
|
|
18595
|
-
const pencolor = orElse(attrs.pencolor, base ?? "");
|
|
18596
|
-
const fillcolor = orElse(attrs.fillcolor, base ?? "");
|
|
18597
|
-
return {
|
|
18598
|
-
fillcolor: nonEmpty(fillcolor) ? fillcolor : void 0,
|
|
18599
|
-
pencolor: nonEmpty(pencolor) ? pencolor : void 0
|
|
18600
|
-
};
|
|
18601
|
-
}
|
|
18602
|
-
function applyBgcolor(attrs, filled, fillcolor) {
|
|
18603
|
-
if ((!filled || !fillcolor) && nonEmpty(attrs.bgcolor)) {
|
|
18604
|
-
return { filled: true, fillcolor: attrs.bgcolor };
|
|
18605
|
-
}
|
|
18606
|
-
return { filled, fillcolor };
|
|
18607
|
-
}
|
|
18608
|
-
function findStopColor(colorlist) {
|
|
18609
|
-
const { segs, error } = parseSegs(colorlist);
|
|
18610
|
-
if (error === 1 || error === 2) return null;
|
|
18611
|
-
if (segs.length < 2) return null;
|
|
18612
|
-
const seg0 = segs[0];
|
|
18613
|
-
const seg1 = segs[1];
|
|
18614
|
-
if (seg0.color === null) return null;
|
|
18615
|
-
const fillColor = seg0.color;
|
|
18616
|
-
const stopColor = seg1.color ?? DEFAULT_COLOR2;
|
|
18617
|
-
const frac = seg0.hasFraction ? seg0.t : seg1.hasFraction ? 1 - seg1.t : 0;
|
|
18618
|
-
return { fillColor, stopColor, frac };
|
|
18619
|
-
}
|
|
18620
|
-
function parseAngle(gradientangle2) {
|
|
18621
|
-
if (!gradientangle2 || gradientangle2.length === 0) return 0;
|
|
18622
|
-
const v = parseInt(gradientangle2, 10);
|
|
18623
|
-
return isFinite(v) ? v : 0;
|
|
18624
|
-
}
|
|
18625
|
-
function buildResolvedFill(rawColor, flags, angle) {
|
|
18626
|
-
const stop = findStopColor(rawColor);
|
|
18627
|
-
if (stop === null) return { kind: "solid", color: rawColor };
|
|
18628
|
-
const kind = flags.radial ? "radial" : "linear";
|
|
18629
|
-
return { kind, fillColor: stop.fillColor, stopColor: stop.stopColor, frac: stop.frac, angle };
|
|
18630
|
-
}
|
|
18631
|
-
function resolveNodeFillEx(attrs) {
|
|
18632
|
-
const flags = parseStyleFlags(attrs.style);
|
|
18633
|
-
if (!flags.filled) return { kind: "none" };
|
|
18634
|
-
const raw = nonEmpty(attrs.fillcolor) ? attrs.fillcolor : nonEmpty(attrs.color) ? attrs.color : DEFAULT_FILL;
|
|
18635
|
-
return buildResolvedFill(raw, flags, parseAngle(attrs.gradientangle));
|
|
18636
|
-
}
|
|
18637
|
-
function resolveClusterFillEx(attrs) {
|
|
18638
|
-
const flags = parseStyleFlags(attrs.style);
|
|
18639
|
-
const colors = clusterColorAttrs(attrs);
|
|
18640
|
-
const bg = applyBgcolor(attrs, flags.filled, colors.fillcolor);
|
|
18641
|
-
if (!bg.filled) return { kind: "none" };
|
|
18642
|
-
const raw = bg.fillcolor ?? DEFAULT_FILL;
|
|
18643
|
-
return buildResolvedFill(raw, flags, parseAngle(attrs.gradientangle));
|
|
18644
|
-
}
|
|
18645
|
-
|
|
18646
18913
|
// src/layout/dot/fastgr.ts
|
|
18647
18914
|
var VIRTUAL = 1;
|
|
18648
18915
|
var NORMAL = 0;
|
|
@@ -18859,10 +19126,10 @@ var SMALL2 = 1e-10;
|
|
|
18859
19126
|
function ptToLine2(a, b, p) {
|
|
18860
19127
|
const dx = b.x - a.x;
|
|
18861
19128
|
const dy = b.y - a.y;
|
|
18862
|
-
let a2 = (p.y - a.y
|
|
19129
|
+
let a2 = fma(p.y - a.y, dx, -(dy * (p.x - a.x)));
|
|
18863
19130
|
a2 *= a2;
|
|
18864
19131
|
if (a2 < SMALL2) return 0;
|
|
18865
|
-
return a2 / (dx
|
|
19132
|
+
return a2 / fma(dx, dx, dy * dy);
|
|
18866
19133
|
}
|
|
18867
19134
|
function checkControlPoints(cp) {
|
|
18868
19135
|
const dis1 = ptToLine2(cp[0], cp[3], cp[1]);
|
|
@@ -19319,10 +19586,14 @@ function cubicHalf(c, rightHalf) {
|
|
|
19319
19586
|
function curveControlPoints(p, v, w, flag) {
|
|
19320
19587
|
const AF0 = { x: p.x + v.x + w.x, y: p.y + v.y + w.y };
|
|
19321
19588
|
const AF3 = { x: p.x - v.x + w.x, y: p.y - v.y + w.y };
|
|
19322
|
-
const
|
|
19323
|
-
const
|
|
19324
|
-
const
|
|
19325
|
-
|
|
19589
|
+
const bulgeX = w.x * 4 / 3;
|
|
19590
|
+
const bulgeY = w.y * 4 / 3;
|
|
19591
|
+
const x1 = fma(v.x, 0.95, p.x) + w.x;
|
|
19592
|
+
const x2 = fma(v.x, -0.95, p.x) + w.x;
|
|
19593
|
+
if (flag & ARR_MOD_INV) {
|
|
19594
|
+
return [AF0, { x: x1 + bulgeX, y: AF0.y + bulgeY }, { x: x2 + bulgeX, y: AF3.y + bulgeY }, AF3];
|
|
19595
|
+
}
|
|
19596
|
+
return [AF0, { x: x1 - bulgeX, y: AF0.y - bulgeY }, { x: x2 - bulgeX, y: AF3.y - bulgeY }, AF3];
|
|
19326
19597
|
}
|
|
19327
19598
|
function genCurve(p0, u, _arrowsize, penwidth, flag, rankdir = 0) {
|
|
19328
19599
|
if (rankdir !== 0) {
|
|
@@ -19625,13 +19896,14 @@ function bezierClipNode(sp, cx, cy, insideFn, leftInside) {
|
|
|
19625
19896
|
y: p.y + cy
|
|
19626
19897
|
}));
|
|
19627
19898
|
}
|
|
19899
|
+
function distFused(p, q) {
|
|
19900
|
+
const dx = p.x - q.x;
|
|
19901
|
+
const dy = p.y - q.y;
|
|
19902
|
+
return Math.sqrt(fma(dx, dx, dy * dy));
|
|
19903
|
+
}
|
|
19628
19904
|
function arrowEndClip(path4, arrowTip, elen) {
|
|
19629
|
-
if (elen <= 0) return path4;
|
|
19630
19905
|
const sp = [arrowTip, path4[2], path4[1], path4[0]];
|
|
19631
|
-
const
|
|
19632
|
-
const spRel = sp.map((p) => ({ x: p.x - arrowTip.x, y: p.y - arrowTip.y }));
|
|
19633
|
-
const clippedRel = bezierClipLocal(spRel, insideSphere, true);
|
|
19634
|
-
const clipped = clippedRel.map((p) => ({ x: p.x + arrowTip.x, y: p.y + arrowTip.y }));
|
|
19906
|
+
const clipped = elen > 0 ? bezierClipNode(sp, 0, 0, (x, y) => distFused({ x, y }, arrowTip) <= elen, true) : sp;
|
|
19635
19907
|
return [clipped[3], clipped[2], clipped[1], clipped[0]];
|
|
19636
19908
|
}
|
|
19637
19909
|
function arrowClipLength(arrowName, arrowsize, penwidth) {
|
|
@@ -20752,7 +21024,7 @@ function readFontParams(sg) {
|
|
|
20752
21024
|
return {
|
|
20753
21025
|
fontsize: parseFloat(graphAttrInherited(sg, "fontsize") ?? "") || DEFAULT_FONTSIZE2,
|
|
20754
21026
|
fontname: graphAttrInherited(sg, "fontname") ?? DEFAULT_FONTNAME,
|
|
20755
|
-
fontcolor: graphAttrInherited(sg, "fontcolor") ??
|
|
21027
|
+
fontcolor: graphAttrInherited(sg, "fontcolor") ?? DEFAULT_COLOR3
|
|
20756
21028
|
};
|
|
20757
21029
|
}
|
|
20758
21030
|
function applyLabelBorder(sg, dimen) {
|
|
@@ -20856,6 +21128,9 @@ function decompSearch(g, start, cmark) {
|
|
|
20856
21128
|
}
|
|
20857
21129
|
}
|
|
20858
21130
|
var _dc = { cmark: 0 };
|
|
21131
|
+
registerRenderState(() => {
|
|
21132
|
+
_dc.cmark = 0;
|
|
21133
|
+
});
|
|
20859
21134
|
function resolveNode(n, pass) {
|
|
20860
21135
|
if (pass > 0) {
|
|
20861
21136
|
const subg = n.info.clust;
|
|
@@ -22630,6 +22905,9 @@ function makeInterclustChain(from, to, orig) {
|
|
|
22630
22905
|
|
|
22631
22906
|
// src/layout/dot/mincross-cross.ts
|
|
22632
22907
|
var reMincross = false;
|
|
22908
|
+
registerRenderState(() => {
|
|
22909
|
+
reMincross = false;
|
|
22910
|
+
});
|
|
22633
22911
|
function setReMincross(b) {
|
|
22634
22912
|
reMincross = b;
|
|
22635
22913
|
}
|
|
@@ -23080,6 +23358,9 @@ function allocateRanks(g) {
|
|
|
23080
23358
|
g.info.rank = rt;
|
|
23081
23359
|
}
|
|
23082
23360
|
var fillSeq = 0;
|
|
23361
|
+
registerRenderState(() => {
|
|
23362
|
+
fillSeq = 0;
|
|
23363
|
+
});
|
|
23083
23364
|
function makeFillNode(sg, rank3, seq2) {
|
|
23084
23365
|
const n = agnode(sg, `__fill_${rank3}_${seq2}`, true);
|
|
23085
23366
|
agsubnode(sg, n, true);
|
|
@@ -23437,7 +23718,7 @@ function pruneForeignClusterNodes(par, clust) {
|
|
|
23437
23718
|
}
|
|
23438
23719
|
function markClusterNode(clust, n, g) {
|
|
23439
23720
|
if ((n.info.ranktype ?? 0) !== 0) {
|
|
23440
|
-
|
|
23721
|
+
agwarningf(`${n.name} was already in a rankset, deleted from cluster ${g.name}`, "error");
|
|
23441
23722
|
agDeleteFromCluster(clust, n);
|
|
23442
23723
|
return;
|
|
23443
23724
|
}
|
|
@@ -23902,6 +24183,9 @@ var clType = LOCAL;
|
|
|
23902
24183
|
function setClType(t) {
|
|
23903
24184
|
clType = t;
|
|
23904
24185
|
}
|
|
24186
|
+
registerRenderState(() => {
|
|
24187
|
+
clType = LOCAL;
|
|
24188
|
+
});
|
|
23905
24189
|
function mapbool2(s) {
|
|
23906
24190
|
if (!s || s === "") return false;
|
|
23907
24191
|
const l = s.toLowerCase();
|
|
@@ -24669,7 +24953,7 @@ function readFontAttrs(n, g) {
|
|
|
24669
24953
|
return {
|
|
24670
24954
|
fontname: nodeAttr(n, g, "fontname") ?? DEFAULT_FONTNAME,
|
|
24671
24955
|
fontsize: parseFloat(nodeAttr(n, g, "fontsize") ?? String(DEFAULT_FONTSIZE2)),
|
|
24672
|
-
fontcolor: nodeAttr(n, g, "fontcolor") ??
|
|
24956
|
+
fontcolor: nodeAttr(n, g, "fontcolor") ?? DEFAULT_COLOR3
|
|
24673
24957
|
};
|
|
24674
24958
|
}
|
|
24675
24959
|
function assignShapeInfo(n, polyDesc) {
|
|
@@ -24694,7 +24978,7 @@ function polyInit(n, g, measurer) {
|
|
|
24694
24978
|
const shapefile = nodeAttr(n, g, "shapefile");
|
|
24695
24979
|
n.info.shape = bindShape(shapeName2, shapefile);
|
|
24696
24980
|
if (shapefile !== void 0 && shapefile !== "" && shapeName2 !== "epsf") {
|
|
24697
|
-
|
|
24981
|
+
agwarningf(`No or improper shapefile="${shapefile}" for node "${n.name}"`, "error");
|
|
24698
24982
|
}
|
|
24699
24983
|
if (n.info.shape.kind === 2 /* SH_RECORD */) {
|
|
24700
24984
|
if (n.info.shape_info === void 0) recordNodeInit(n, g, measurer);
|
|
@@ -25065,20 +25349,36 @@ function applyClusterObjState(sg, job) {
|
|
|
25065
25349
|
if (job.obj === null) return false;
|
|
25066
25350
|
const obj = job.obj;
|
|
25067
25351
|
return withColorScheme(clusterAttr(sg, "colorscheme"), () => {
|
|
25352
|
+
const filled = applyClusterFill(obj, fillRes);
|
|
25068
25353
|
applyClusterPenState(obj, sg);
|
|
25069
|
-
|
|
25070
|
-
|
|
25071
|
-
return false;
|
|
25072
|
-
}
|
|
25073
|
-
if (fillRes.kind === "solid") {
|
|
25074
|
-
obj.fill = 1 /* Solid */;
|
|
25075
|
-
obj.fillColor = resolveRenderColor(fillRes.color);
|
|
25076
|
-
return true;
|
|
25077
|
-
}
|
|
25078
|
-
applyClusterGradient(obj, fillRes);
|
|
25079
|
-
return true;
|
|
25354
|
+
reportColorNames(stripedClusterColors(sg));
|
|
25355
|
+
return filled;
|
|
25080
25356
|
});
|
|
25081
25357
|
}
|
|
25358
|
+
function stripedClusterColors(sg) {
|
|
25359
|
+
const flags = parseStyleFlags(clusterStyle(sg));
|
|
25360
|
+
if (!flags.striped || flags.rounded) return [];
|
|
25361
|
+
const color = clusterAttr(sg, "color") ?? "";
|
|
25362
|
+
let fill = clusterAttr(sg, "fillcolor") || color;
|
|
25363
|
+
const bg = clusterAttr(sg, "bgcolor") ?? "";
|
|
25364
|
+
if ((!flags.filled || fill === "") && bg !== "") fill = bg;
|
|
25365
|
+
const { segs, error } = parseSegs(fill === "" ? "lightgrey" : fill);
|
|
25366
|
+
if (error === 1 || error === 2) return [];
|
|
25367
|
+
return segs.flatMap((seg2) => seg2.color !== null && seg2.t > 0 ? [seg2.color] : []);
|
|
25368
|
+
}
|
|
25369
|
+
function applyClusterFill(obj, fillRes) {
|
|
25370
|
+
if (fillRes.kind === "none") {
|
|
25371
|
+
obj.fill = 0 /* None */;
|
|
25372
|
+
return false;
|
|
25373
|
+
}
|
|
25374
|
+
if (fillRes.kind === "solid") {
|
|
25375
|
+
obj.fill = 1 /* Solid */;
|
|
25376
|
+
obj.fillColor = resolveRenderColor(fillRes.color);
|
|
25377
|
+
return true;
|
|
25378
|
+
}
|
|
25379
|
+
applyClusterGradient(obj, fillRes);
|
|
25380
|
+
return true;
|
|
25381
|
+
}
|
|
25082
25382
|
|
|
25083
25383
|
// src/render/svg-id.ts
|
|
25084
25384
|
function svgClass(kind, classAttr) {
|
|
@@ -25166,6 +25466,7 @@ function renderPeripheries(poly, coord, filled, ctx) {
|
|
|
25166
25466
|
}
|
|
25167
25467
|
function renderLabel(label, coord, renderer, job) {
|
|
25168
25468
|
if (label.u.kind !== "txt" || label.u.nspans < 1) return;
|
|
25469
|
+
reportColorNames([label.fontcolor]);
|
|
25169
25470
|
label.pos = coord;
|
|
25170
25471
|
label.set = true;
|
|
25171
25472
|
const VALIGN_TOP2 = "t".charCodeAt(0);
|
|
@@ -25185,6 +25486,7 @@ function renderNodeLabel(n, coord, renderer, job) {
|
|
|
25185
25486
|
label.pos = coord;
|
|
25186
25487
|
label.set = true;
|
|
25187
25488
|
const html = label.u.html;
|
|
25489
|
+
reportColorNames(htmlLabelColors(html));
|
|
25188
25490
|
withLabelEmitState(job, () => emitHtmlLabel(html, coord, renderer, job));
|
|
25189
25491
|
} else {
|
|
25190
25492
|
renderLabel(label, coord, renderer, job);
|
|
@@ -25259,13 +25561,18 @@ function applyPenState(obj, styleAttr, colorAttr, penwidthAttr) {
|
|
|
25259
25561
|
obj.penColor = resolveRenderColor(resolvePenColor(colorAttr));
|
|
25260
25562
|
obj.pen = resolvePenType(flags);
|
|
25261
25563
|
obj.penWidth = resolvePenWidth(flags, penwidthAttr);
|
|
25262
|
-
obj.rawStyle =
|
|
25564
|
+
obj.rawStyle = styleTokens(styleAttr);
|
|
25263
25565
|
}
|
|
25264
25566
|
function applyNodeStyle(obj, n, job) {
|
|
25265
25567
|
const styleAttr = nodeAttr(n, n.root, "style");
|
|
25266
25568
|
const colorAttr = nodeAttr(n, n.root, "color");
|
|
25569
|
+
const penwidth = nodeAttr(n, n.root, "penwidth");
|
|
25570
|
+
if (n.info.shape?.kind === 2 /* SH_RECORD */) {
|
|
25571
|
+
applyPenState(obj, styleAttr, colorAttr, penwidth);
|
|
25572
|
+
return applyFillState(obj, n, job);
|
|
25573
|
+
}
|
|
25267
25574
|
const filled = applyFillState(obj, n, job);
|
|
25268
|
-
applyPenState(obj, styleAttr, colorAttr,
|
|
25575
|
+
applyPenState(obj, styleAttr, colorAttr, penwidth);
|
|
25269
25576
|
return filled;
|
|
25270
25577
|
}
|
|
25271
25578
|
function prepareDrawPoly(poly, filled, obj) {
|
|
@@ -25482,7 +25789,7 @@ function initFontEdgeAttr(e) {
|
|
|
25482
25789
|
return {
|
|
25483
25790
|
fontsize: lateDouble(e.attrs.get("fontsize"), DEFAULT_FONTSIZE2, MIN_FONTSIZE),
|
|
25484
25791
|
fontname: e.attrs.get("fontname") || DEFAULT_FONTNAME,
|
|
25485
|
-
fontcolor: e.attrs.get("fontcolor") ||
|
|
25792
|
+
fontcolor: e.attrs.get("fontcolor") || DEFAULT_COLOR3
|
|
25486
25793
|
};
|
|
25487
25794
|
}
|
|
25488
25795
|
function initFontLabelEdgeAttr(e, fi) {
|
|
@@ -25608,7 +25915,7 @@ function findCharset(g) {
|
|
|
25608
25915
|
}
|
|
25609
25916
|
if (p === "big-5" || p === "big5") return CHAR_BIG5;
|
|
25610
25917
|
if (p === "utf-8" || p === "utf8") return CHAR_UTF8;
|
|
25611
|
-
|
|
25918
|
+
agwarningf(`Unsupported charset "${raw}" - assuming utf-8`, "error");
|
|
25612
25919
|
return CHAR_UTF8;
|
|
25613
25920
|
}
|
|
25614
25921
|
function maptoken(p, names, vals) {
|
|
@@ -27257,7 +27564,7 @@ function advanceTmpList(tmplist, offlist) {
|
|
|
27257
27564
|
// src/render/svg-parallel-edge.ts
|
|
27258
27565
|
var PENWIDTH_NORMAL2 = 1;
|
|
27259
27566
|
var PENWIDTH_THRESHOLD2 = 5e-3;
|
|
27260
|
-
var
|
|
27567
|
+
var DEFAULT_COLOR4 = "black";
|
|
27261
27568
|
function emitOffsetBezier(tmplist, job, color) {
|
|
27262
27569
|
const obj = job.obj;
|
|
27263
27570
|
const resolved = resolveRenderColor(color);
|
|
@@ -27299,11 +27606,11 @@ function emitParallelEdgePaths(e, job, colorList) {
|
|
|
27299
27606
|
const spl = e.info.spl;
|
|
27300
27607
|
const numc = (colorList.match(/:/g) ?? []).length;
|
|
27301
27608
|
const segData = buildSegData(spl?.list ?? [], (2 + numc) / 2);
|
|
27302
|
-
const colors = parseSegs(colorList).segs.map((s) => s.color ??
|
|
27609
|
+
const colors = parseSegs(colorList).segs.map((s) => s.color ?? DEFAULT_COLOR4);
|
|
27303
27610
|
emitColorPasses(segData, colors, job);
|
|
27304
27611
|
return {
|
|
27305
|
-
headColor: colors[0] ??
|
|
27306
|
-
tailColor: colors[1] ?? colors[0] ??
|
|
27612
|
+
headColor: colors[0] ?? DEFAULT_COLOR4,
|
|
27613
|
+
tailColor: colors[1] ?? colors[0] ?? DEFAULT_COLOR4
|
|
27307
27614
|
};
|
|
27308
27615
|
}
|
|
27309
27616
|
|
|
@@ -27815,7 +28122,6 @@ function beginAnchorIf(renderer, job) {
|
|
|
27815
28122
|
}
|
|
27816
28123
|
var DFLT_SAMPLE = 20;
|
|
27817
28124
|
var MAP_HW = 2;
|
|
27818
|
-
var MAP_SMALL = 1e-10;
|
|
27819
28125
|
function mapTransform(p, ctx) {
|
|
27820
28126
|
return {
|
|
27821
28127
|
x: (p.x + ctx.pad.x - ctx.bb.ll.x) * ctx.scale + ctx.marginOff.x,
|
|
@@ -27932,16 +28238,8 @@ function computeLabelRectMap(lab, obj, ctx) {
|
|
|
27932
28238
|
mapTransform({ x: lab.pos.x + dx, y: lab.pos.y + dy }, ctx)
|
|
27933
28239
|
];
|
|
27934
28240
|
}
|
|
27935
|
-
function ptToLine22(a, b, p) {
|
|
27936
|
-
const dx = b.x - a.x;
|
|
27937
|
-
const dy = b.y - a.y;
|
|
27938
|
-
let a2 = (p.y - a.y) * dx - (p.x - a.x) * dy;
|
|
27939
|
-
a2 *= a2;
|
|
27940
|
-
if (a2 < MAP_SMALL) return 0;
|
|
27941
|
-
return a2 / (dx * dx + dy * dy);
|
|
27942
|
-
}
|
|
27943
28241
|
function checkControlPoints2(cp) {
|
|
27944
|
-
return
|
|
28242
|
+
return ptToLine2(cp[0], cp[3], cp[1]) < MAP_HW * MAP_HW && ptToLine2(cp[0], cp[3], cp[2]) < MAP_HW * MAP_HW;
|
|
27945
28243
|
}
|
|
27946
28244
|
function bezierHalf(v) {
|
|
27947
28245
|
const left2 = [];
|
|
@@ -28176,9 +28474,20 @@ function labelSpanX(lp, just) {
|
|
|
28176
28474
|
if (just === "r") return lp.pos.x + lp.space.x / 2;
|
|
28177
28475
|
return lp.pos.x;
|
|
28178
28476
|
}
|
|
28477
|
+
function labelColorNames(lp) {
|
|
28478
|
+
if (lp.html) return lp.u.kind === "html" ? htmlLabelColors(lp.u.html) : [];
|
|
28479
|
+
return lp.u.kind === "txt" && lp.u.nspans >= 1 ? [lp.fontcolor] : [];
|
|
28480
|
+
}
|
|
28481
|
+
function reportEdgeLabelColors(e) {
|
|
28482
|
+
const labels = [e.info.label, e.info.xlabel, e.info.head_label, e.info.tail_label];
|
|
28483
|
+
for (const lp of labels) {
|
|
28484
|
+
if (lp?.set) reportColorNames(labelColorNames(lp));
|
|
28485
|
+
}
|
|
28486
|
+
}
|
|
28179
28487
|
function renderOneLabel(lp, renderer, job, requireSet = true) {
|
|
28180
28488
|
if (!lp) return;
|
|
28181
28489
|
if (requireSet && !lp.set) return;
|
|
28490
|
+
reportColorNames(labelColorNames(lp));
|
|
28182
28491
|
if (lp.html) {
|
|
28183
28492
|
if (lp.u.kind === "html") {
|
|
28184
28493
|
const html = lp.u.html;
|
|
@@ -28287,11 +28596,11 @@ function setEdgePen(e, job) {
|
|
|
28287
28596
|
const flags = parseStyleFlags(e.attrs.get("style"));
|
|
28288
28597
|
obj.penColor = withColorScheme(
|
|
28289
28598
|
e.attrs.get("colorscheme"),
|
|
28290
|
-
() => resolveRenderColor(resolvePenColor(e.attrs.get("color")))
|
|
28599
|
+
() => resolveRenderColor(resolvePenColor(e.attrs.get("color")), false)
|
|
28291
28600
|
);
|
|
28292
28601
|
obj.pen = resolvePenType(flags);
|
|
28293
28602
|
obj.penWidth = resolvePenWidth(flags, e.attrs.get("penwidth"));
|
|
28294
|
-
obj.rawStyle =
|
|
28603
|
+
obj.rawStyle = styleTokens(e.attrs.get("style"));
|
|
28295
28604
|
}
|
|
28296
28605
|
function renderEdge(e, renderer, job) {
|
|
28297
28606
|
emitEdgeComments(e, renderer, job);
|
|
@@ -28306,6 +28615,8 @@ function renderEdge(e, renderer, job) {
|
|
|
28306
28615
|
resolveEdgeAnchor(e, svgEdgeId(e, job), obj);
|
|
28307
28616
|
withColorScheme(e.attrs.get("colorscheme"), () => {
|
|
28308
28617
|
renderer.beginEdge(e, job);
|
|
28618
|
+
reportEdgeColors(e);
|
|
28619
|
+
reportEdgeLabelColors(e);
|
|
28309
28620
|
renderer.endEdge(e, job);
|
|
28310
28621
|
});
|
|
28311
28622
|
} finally {
|
|
@@ -28389,8 +28700,11 @@ function renderPage(g, renderer, job, info) {
|
|
|
28389
28700
|
resolveObjAnchor(g, labelTextOf2(g.info.label), svgGraphId(g, job), job.obj);
|
|
28390
28701
|
}
|
|
28391
28702
|
const anchored = beginAnchorIf(renderer, job);
|
|
28392
|
-
|
|
28393
|
-
|
|
28703
|
+
withColorScheme(g.attrs.get("colorscheme"), () => {
|
|
28704
|
+
reportColorNames(backgroundColors(g.attrs.get("bgcolor"), renderer.type === "svg"));
|
|
28705
|
+
renderer.pageBackground?.(g, job);
|
|
28706
|
+
renderGraphLabel(g, renderer, job);
|
|
28707
|
+
});
|
|
28394
28708
|
if (anchored) renderer.endAnchor?.(job);
|
|
28395
28709
|
const clustersLast = (job.flags & EMIT_CLUSTERS_LAST) !== 0;
|
|
28396
28710
|
if (!clustersLast) renderClusters(g, renderer, job);
|
|
@@ -28422,6 +28736,7 @@ function render(ctx, g, format, inlineImages = false) {
|
|
|
28422
28736
|
job.scale = { x: z * dpiScale, y: z * dpiScale };
|
|
28423
28737
|
job.rotation = parseLandscape(g) ? 90 : 0;
|
|
28424
28738
|
job.renderer = renderer;
|
|
28739
|
+
setRendererKnownColors(renderer.type === "svg");
|
|
28425
28740
|
resetHtmlAnchorIds();
|
|
28426
28741
|
for (const n of g.nodes.values()) polyInit(n, g, job.measurer);
|
|
28427
28742
|
return renderGraph(g, job, renderer);
|
|
@@ -29693,20 +30008,20 @@ function fillRankVlist(g, r, root) {
|
|
|
29693
30008
|
const rankArr = g.info.rank;
|
|
29694
30009
|
const lead = g.info.rankleader[r];
|
|
29695
30010
|
if (lead === void 0 || lead === null) {
|
|
29696
|
-
|
|
30011
|
+
agerrorf(`rebuild_vlists: lead is null for rank ${r}`);
|
|
29697
30012
|
return -1;
|
|
29698
30013
|
}
|
|
29699
30014
|
const rootRank = root.info.rank[r];
|
|
29700
30015
|
if (rootRank.v[lead.info.order ?? 0] !== lead) {
|
|
29701
|
-
|
|
29702
|
-
`
|
|
30016
|
+
agerrorf(
|
|
30017
|
+
`rebuild_vlists: rank lead ${lead.name} not in order ${lead.info.order ?? 0} of rank ${r}`
|
|
29703
30018
|
);
|
|
29704
30019
|
return -1;
|
|
29705
30020
|
}
|
|
29706
30021
|
rankArr[r].v = rootRank.v;
|
|
29707
30022
|
rankArr[r].vStart = lead.info.order ?? 0;
|
|
29708
30023
|
const maxi = computeMaxi(g, r);
|
|
29709
|
-
if (maxi === -1)
|
|
30024
|
+
if (maxi === -1) agwarningf(`degenerate concentrated rank ${g.name},${r}`, "error");
|
|
29710
30025
|
rankArr[r].n = maxi + 1;
|
|
29711
30026
|
return 0;
|
|
29712
30027
|
}
|
|
@@ -29795,7 +30110,7 @@ function dotConcentrate(g) {
|
|
|
29795
30110
|
const clust = g.info.clust ?? [];
|
|
29796
30111
|
for (let c = 0; c < nCluster; c++) {
|
|
29797
30112
|
if (rebuildVlists(clust[c]) !== 0) {
|
|
29798
|
-
|
|
30113
|
+
agerr("prev", "concentrate=true may not work correctly.");
|
|
29799
30114
|
return -1;
|
|
29800
30115
|
}
|
|
29801
30116
|
}
|
|
@@ -32525,7 +32840,7 @@ function routeSplinesInternal(pp, polyline) {
|
|
|
32525
32840
|
];
|
|
32526
32841
|
const pl = shortestPath(poly, eps);
|
|
32527
32842
|
if (pl === null) {
|
|
32528
|
-
|
|
32843
|
+
agerrLineOn("warn", "in routesplines, Pshortestpath failed");
|
|
32529
32844
|
return null;
|
|
32530
32845
|
}
|
|
32531
32846
|
emitDump("S3_POLY", dumpNames, () => ({
|
|
@@ -34844,6 +35159,10 @@ function addXLabels(gp) {
|
|
|
34844
35159
|
var IGNORED_EDGE = 6;
|
|
34845
35160
|
var Rankdir = 0;
|
|
34846
35161
|
var Offset = { x: 0, y: 0 };
|
|
35162
|
+
registerRenderState(() => {
|
|
35163
|
+
Rankdir = 0;
|
|
35164
|
+
Offset = { x: 0, y: 0 };
|
|
35165
|
+
});
|
|
34847
35166
|
function mapPoint(p) {
|
|
34848
35167
|
const r = ccwrotatepf(p, Rankdir * 90);
|
|
34849
35168
|
return { x: r.x - Offset.x, y: r.y - Offset.y };
|
|
@@ -34931,7 +35250,7 @@ function translateDrawing(g) {
|
|
|
34931
35250
|
if (e.tail !== v) continue;
|
|
34932
35251
|
if (e.info.spl === void 0) {
|
|
34933
35252
|
if (!(g.info.concentrate ?? false) && (e.info.edge_type ?? 0) !== IGNORED_EDGE) {
|
|
34934
|
-
|
|
35253
|
+
agerrLineOn("warn", `lost ${e.tail.name} ${e.head.name} edge`);
|
|
34935
35254
|
}
|
|
34936
35255
|
continue;
|
|
34937
35256
|
}
|
|
@@ -36044,7 +36363,11 @@ var A = BigInt("0x5deece66d");
|
|
|
36044
36363
|
var C = BigInt("0xb");
|
|
36045
36364
|
var MASK48 = (1n << 48n) - 1n;
|
|
36046
36365
|
var TWO48 = 2 ** 48;
|
|
36047
|
-
var
|
|
36366
|
+
var UNSEEDED_STATE = 0x1234abcd330en;
|
|
36367
|
+
var state = UNSEEDED_STATE;
|
|
36368
|
+
registerRenderState(() => {
|
|
36369
|
+
state = UNSEEDED_STATE;
|
|
36370
|
+
});
|
|
36048
36371
|
function srand48(seed) {
|
|
36049
36372
|
const s = BigInt(Math.trunc(seed)) & 0xffffffffn;
|
|
36050
36373
|
state = (s << 16n | 0x330en) & MASK48;
|
|
@@ -38231,7 +38554,8 @@ function ensureDummyNodes(sg, gstart) {
|
|
|
38231
38554
|
}
|
|
38232
38555
|
function orthoEdges(g, useLbls, clipAndInstall2) {
|
|
38233
38556
|
if (useLbls) {
|
|
38234
|
-
|
|
38557
|
+
agerrLineOn(
|
|
38558
|
+
"warn",
|
|
38235
38559
|
"Orthogonal edges do not currently handle edge labels. Try using xlabels.\n"
|
|
38236
38560
|
);
|
|
38237
38561
|
useLbls = false;
|
|
@@ -38591,12 +38915,12 @@ function origSeq(e) {
|
|
|
38591
38915
|
return resolveOrigEdge(e).seq;
|
|
38592
38916
|
}
|
|
38593
38917
|
function dedupByOrig(group) {
|
|
38594
|
-
const
|
|
38918
|
+
const seen2 = /* @__PURE__ */ new Set();
|
|
38595
38919
|
const out = [];
|
|
38596
38920
|
for (const e of group) {
|
|
38597
38921
|
const o = resolveOrigEdge(e);
|
|
38598
|
-
if (
|
|
38599
|
-
|
|
38922
|
+
if (seen2.has(o)) continue;
|
|
38923
|
+
seen2.add(o);
|
|
38600
38924
|
out.push(o);
|
|
38601
38925
|
}
|
|
38602
38926
|
return out;
|
|
@@ -38913,7 +39237,7 @@ function orthoDispatch(g) {
|
|
|
38913
39237
|
function curvedTop(g) {
|
|
38914
39238
|
resetRW(g);
|
|
38915
39239
|
if (((g.root.info.has_labels ?? 0) & EDGE_LABEL) !== 0) {
|
|
38916
|
-
|
|
39240
|
+
agerrLineOn("warn", "edge labels with splines=curved not supported in dot - use xlabels\n");
|
|
38917
39241
|
}
|
|
38918
39242
|
}
|
|
38919
39243
|
function finalizeSplines(g, et, normalize) {
|
|
@@ -40561,7 +40885,7 @@ function lenattr(ep, g) {
|
|
|
40561
40885
|
const val2 = /^\s*[+-]?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?/.exec(s);
|
|
40562
40886
|
const len = val2 === null ? Number.NaN : parseFloat(val2[0]);
|
|
40563
40887
|
if (Number.isNaN(len) || len < 0 || len === 0) {
|
|
40564
|
-
|
|
40888
|
+
agerrLineOn("warn", `bad edge len "${s}" in ${g.name} - setting to ${DEFAULT_EDGE_LEN.toFixed(2)}`);
|
|
40565
40889
|
return DEFAULT_EDGE_LEN;
|
|
40566
40890
|
}
|
|
40567
40891
|
return len;
|
|
@@ -40658,7 +40982,10 @@ var START_KEYWORDS = [
|
|
|
40658
40982
|
];
|
|
40659
40983
|
var WARN_POS_IGNORED = "node positions are ignored unless start=random";
|
|
40660
40984
|
var WARN_SELF_IGNORED = "start=0 not supported with mode=self - ignored";
|
|
40661
|
-
var
|
|
40985
|
+
var selfOnce = { warned: false };
|
|
40986
|
+
registerRenderState(() => {
|
|
40987
|
+
selfOnce.warned = false;
|
|
40988
|
+
});
|
|
40662
40989
|
var circuitWarned = /* @__PURE__ */ new WeakSet();
|
|
40663
40990
|
function parseStart(p, dflt) {
|
|
40664
40991
|
let init = dflt;
|
|
@@ -40689,7 +41016,7 @@ function initRegular(g, nG) {
|
|
|
40689
41016
|
function checkStart(g, nG = g.nodes.size, dflt = INIT_RANDOM) {
|
|
40690
41017
|
const { init, seed } = parseStart(g.root.attrs.get("start"), dflt);
|
|
40691
41018
|
if (init !== INIT_RANDOM && [...g.nodes.values()].some((n) => n.attrs.has("pos"))) {
|
|
40692
|
-
|
|
41019
|
+
agerrLineOn("warn", WARN_POS_IGNORED);
|
|
40693
41020
|
}
|
|
40694
41021
|
if (init === INIT_REGULAR) initRegular(g, nG);
|
|
40695
41022
|
srand48(seed);
|
|
@@ -40722,7 +41049,7 @@ function neatoMode(g) {
|
|
|
40722
41049
|
if (str === void 0 || str === "") return MODE_MAJOR;
|
|
40723
41050
|
const mode = modeByName().get(str);
|
|
40724
41051
|
if (mode !== void 0) return mode;
|
|
40725
|
-
|
|
41052
|
+
agerrLineOn("warn", `Illegal value ${str} for attribute "mode" in graph ${g.root.name} - ignored`);
|
|
40726
41053
|
return MODE_MAJOR;
|
|
40727
41054
|
}
|
|
40728
41055
|
function checkMode(g, mode) {
|
|
@@ -40736,9 +41063,9 @@ function checkStartAttr(g, mode) {
|
|
|
40736
41063
|
const value = g.root.attrs.get("start");
|
|
40737
41064
|
if (parseStart(value, INIT_RANDOM).init !== INIT_SELF) return;
|
|
40738
41065
|
if (mode === MODE_MAJOR || mode === MODE_IPSEP) unsupported("start", value ?? "", "smart initialisation");
|
|
40739
|
-
if ((mode === MODE_KK || mode === MODE_SGD) && !
|
|
40740
|
-
|
|
40741
|
-
|
|
41066
|
+
if ((mode === MODE_KK || mode === MODE_SGD) && !selfOnce.warned) {
|
|
41067
|
+
selfOnce.warned = true;
|
|
41068
|
+
agerrLineOn("warn", WARN_SELF_IGNORED);
|
|
40742
41069
|
}
|
|
40743
41070
|
}
|
|
40744
41071
|
function isConnected(g) {
|
|
@@ -40749,15 +41076,15 @@ function isConnected(g) {
|
|
|
40749
41076
|
adj.get(e.tail)?.push(e.head);
|
|
40750
41077
|
adj.get(e.head)?.push(e.tail);
|
|
40751
41078
|
}
|
|
40752
|
-
const
|
|
41079
|
+
const seen2 = /* @__PURE__ */ new Set([nodes[0]]);
|
|
40753
41080
|
const stack = [nodes[0]];
|
|
40754
41081
|
for (let n = stack.pop(); n !== void 0; n = stack.pop()) {
|
|
40755
|
-
for (const m of adj.get(n) ?? []) if (!
|
|
40756
|
-
|
|
41082
|
+
for (const m of adj.get(n) ?? []) if (!seen2.has(m)) {
|
|
41083
|
+
seen2.add(m);
|
|
40757
41084
|
stack.push(m);
|
|
40758
41085
|
}
|
|
40759
41086
|
}
|
|
40760
|
-
return
|
|
41087
|
+
return seen2.size === nodes.length;
|
|
40761
41088
|
}
|
|
40762
41089
|
function kkCircuitFallsBack(g) {
|
|
40763
41090
|
const packed = getPack(g.root, -1, 0) >= 0 || (g.root.attrs.get("packmode") ?? "") !== "";
|
|
@@ -40766,7 +41093,8 @@ function kkCircuitFallsBack(g) {
|
|
|
40766
41093
|
function warnCircuitDisconnected(g) {
|
|
40767
41094
|
if (circuitWarned.has(g.root)) return;
|
|
40768
41095
|
circuitWarned.add(g.root);
|
|
40769
|
-
|
|
41096
|
+
agerrLineOn(
|
|
41097
|
+
"warn",
|
|
40770
41098
|
`graph ${g.root.name} is disconnected. Hence, the circuit model
|
|
40771
41099
|
is undefined. Reverting to the shortest path model.
|
|
40772
41100
|
Alternatively, consider running neato using -Gpack=true or decomposing
|
|
@@ -40985,13 +41313,15 @@ function buildUnfixed(g, n) {
|
|
|
40985
41313
|
}
|
|
40986
41314
|
function resolveModel(model) {
|
|
40987
41315
|
if (model === MODEL_CIRCUIT2) {
|
|
40988
|
-
|
|
41316
|
+
agerrLineOn(
|
|
41317
|
+
"warn",
|
|
40989
41318
|
"circuit model not yet supported in Gmode=sgd, reverting to shortpath model"
|
|
40990
41319
|
);
|
|
40991
41320
|
return MODEL_SHORTPATH;
|
|
40992
41321
|
}
|
|
40993
41322
|
if (model === MODEL_MDS) {
|
|
40994
|
-
|
|
41323
|
+
agerrLineOn(
|
|
41324
|
+
"warn",
|
|
40995
41325
|
"mds model not yet supported in Gmode=sgd, reverting to shortpath model"
|
|
40996
41326
|
);
|
|
40997
41327
|
return MODEL_SHORTPATH;
|
|
@@ -41376,7 +41706,7 @@ function moveNode(st, m) {
|
|
|
41376
41706
|
function solveModel(g, st) {
|
|
41377
41707
|
for (let m = chooseNode(st); m >= 0; m = chooseNode(st)) moveNode(st, m);
|
|
41378
41708
|
if (st.move === st.maxIter) {
|
|
41379
|
-
|
|
41709
|
+
agerrLineOn("warn", `Max. iterations (${st.maxIter}) reached on graph ${g.name}`);
|
|
41380
41710
|
}
|
|
41381
41711
|
}
|
|
41382
41712
|
function mdsEdges(g, nodes, lens) {
|
|
@@ -41835,6 +42165,7 @@ var MODE_MAJOR = 1;
|
|
|
41835
42165
|
var MODE_HIER = 2;
|
|
41836
42166
|
var MODE_IPSEP = 3;
|
|
41837
42167
|
var MODE_SGD = 4;
|
|
42168
|
+
var SGD_ITERATIONS = 30;
|
|
41838
42169
|
var MODEL_SHORTPATH2 = 0;
|
|
41839
42170
|
var MODEL_CIRCUIT = 1;
|
|
41840
42171
|
var MODEL_SUBSET = 2;
|
|
@@ -41874,6 +42205,11 @@ function assignNodeIds2(g) {
|
|
|
41874
42205
|
}
|
|
41875
42206
|
return nodeList;
|
|
41876
42207
|
}
|
|
42208
|
+
function neatoMaxIter(maxiter, mode, n) {
|
|
42209
|
+
if (maxiter !== void 0) return parseInt(maxiter, 10) || 0;
|
|
42210
|
+
if (mode === MODE_MAJOR) return DFLT_ITERATIONS;
|
|
42211
|
+
return mode === MODE_SGD ? SGD_ITERATIONS : 100 * n;
|
|
42212
|
+
}
|
|
41877
42213
|
function runMajorization(g, mode, model) {
|
|
41878
42214
|
void model;
|
|
41879
42215
|
const nodeList = assignNodeIds2(g);
|
|
@@ -41881,7 +42217,7 @@ function runMajorization(g, mode, model) {
|
|
|
41881
42217
|
const haveLen = graphHasLen(g);
|
|
41882
42218
|
const vtx = makeGraphDataC(g, nodeList, haveLen, mode === MODE_HIER || mode === MODE_IPSEP);
|
|
41883
42219
|
checkStart(g);
|
|
41884
|
-
const maxi =
|
|
42220
|
+
const maxi = neatoMaxIter(g.attrs.get("maxiter"), mode, n);
|
|
41885
42221
|
const epsilon = lateDouble(g.attrs.get("epsilon"), 1e-4, 0);
|
|
41886
42222
|
const weighted = haveLen && mode !== MODE_IPSEP;
|
|
41887
42223
|
const Dij = weighted ? computeWeightedApspPacked2(vtx, n) : computeApspPacked2(vtx, n);
|
|
@@ -41911,18 +42247,18 @@ function makeGraphDataC(g, nodeList, haveLen, haveDir) {
|
|
|
41911
42247
|
for (const np of nodeList) {
|
|
41912
42248
|
const i = np.info.id;
|
|
41913
42249
|
const entry = vtx[i];
|
|
41914
|
-
const
|
|
42250
|
+
const seen2 = /* @__PURE__ */ new Map();
|
|
41915
42251
|
for (const ep of [...np.outEdges(g), ...np.inEdges(g)]) {
|
|
41916
42252
|
if (ep.head === ep.tail) continue;
|
|
41917
42253
|
const vp = ep.tail === np ? ep.head : ep.tail;
|
|
41918
42254
|
const vid = vp.info.id;
|
|
41919
42255
|
const dist4 = haveLen ? lateDouble(ep.attrs.get("len"), 1, 0) : 1;
|
|
41920
|
-
const idx =
|
|
42256
|
+
const idx = seen2.get(vid);
|
|
41921
42257
|
if (idx !== void 0) {
|
|
41922
42258
|
if (haveLen) entry.ewgts[idx] = Math.max(entry.ewgts[idx], dist4);
|
|
41923
42259
|
continue;
|
|
41924
42260
|
}
|
|
41925
|
-
|
|
42261
|
+
seen2.set(vid, entry.nedges);
|
|
41926
42262
|
entry.edges.push(vid);
|
|
41927
42263
|
if (haveLen || haveDir) entry.ewgts.push(dist4);
|
|
41928
42264
|
entry.nedges++;
|
|
@@ -42269,15 +42605,15 @@ function delaunayTri(xv, yv, n) {
|
|
|
42269
42605
|
for (let i = 1; i < n; i++) edges2.push(vs[i - 1], vs[i]);
|
|
42270
42606
|
return edges2;
|
|
42271
42607
|
}
|
|
42272
|
-
const
|
|
42608
|
+
const seen2 = /* @__PURE__ */ new Set();
|
|
42273
42609
|
const pairs = [];
|
|
42274
42610
|
for (const t of tris) {
|
|
42275
42611
|
for (const [u, v] of [[t.a, t.b], [t.b, t.c], [t.c, t.a]]) {
|
|
42276
42612
|
const i = Math.min(u, v);
|
|
42277
42613
|
const j = Math.max(u, v);
|
|
42278
42614
|
const key = i * 1048576 + j;
|
|
42279
|
-
if (!
|
|
42280
|
-
|
|
42615
|
+
if (!seen2.has(key)) {
|
|
42616
|
+
seen2.add(key);
|
|
42281
42617
|
pairs.push([i, j]);
|
|
42282
42618
|
}
|
|
42283
42619
|
}
|
|
@@ -42562,8 +42898,8 @@ var Cdt = class {
|
|
|
42562
42898
|
const en = this.edgeOrNew(v3, v4);
|
|
42563
42899
|
this.removeFace(f1);
|
|
42564
42900
|
this.removeFace(f2);
|
|
42565
|
-
const f3 = this.addFace([v4, v2,
|
|
42566
|
-
const f4 = this.addFace([
|
|
42901
|
+
const f3 = this.addFace([v3, v4, v2], [en, e5, e2]);
|
|
42902
|
+
const f4 = this.addFace([v4, v3, v1], [en, e3, e4]);
|
|
42567
42903
|
this.swapIfInCircle(f3, v4, v2, v3, e5, e2, en);
|
|
42568
42904
|
this.swapIfInCircle(f4, v1, v4, v3, e4, en, e3);
|
|
42569
42905
|
}
|
|
@@ -42865,10 +43201,7 @@ function sharedEdge(faces, p3, q3) {
|
|
|
42865
43201
|
return { i: p1, j: p2 };
|
|
42866
43202
|
}
|
|
42867
43203
|
function addTriEdge(g, t, h, seg2) {
|
|
42868
|
-
const dist4 = Math.
|
|
42869
|
-
g.nodes[t].ctr.x - g.nodes[h].ctr.x,
|
|
42870
|
-
g.nodes[t].ctr.y - g.nodes[h].ctr.y
|
|
42871
|
-
);
|
|
43204
|
+
const dist4 = Math.sqrt(dist2(g.nodes[t].ctr, g.nodes[h].ctr));
|
|
42872
43205
|
const idx = g.edges.length;
|
|
42873
43206
|
g.edges.push({ t, h, seg: seg2, dist: dist4 });
|
|
42874
43207
|
g.nodes[t].edges.push(idx);
|
|
@@ -43195,7 +43528,7 @@ var SEP = 15;
|
|
|
43195
43528
|
function bisectorTarget(v, cosTheta, sinTheta) {
|
|
43196
43529
|
return { x: fma(cosTheta, 100, v.x), y: fma(sinTheta, 100, v.y) };
|
|
43197
43530
|
}
|
|
43198
|
-
function
|
|
43531
|
+
function distFused2(p, q) {
|
|
43199
43532
|
const dx = p.x - q.x;
|
|
43200
43533
|
const dy = p.y - q.y;
|
|
43201
43534
|
return Math.sqrt(fma(dx, dx, dy * dy));
|
|
@@ -43220,7 +43553,7 @@ function mkCtrlPts(s, mult, prev, v, nxt, trip) {
|
|
|
43220
43553
|
}
|
|
43221
43554
|
const q = triPoint(trip, idx, v, w);
|
|
43222
43555
|
if (q === null) return null;
|
|
43223
|
-
const d =
|
|
43556
|
+
const d = distFused2(q, v);
|
|
43224
43557
|
const sep = d >= mult * SEP ? SEP : d / mult;
|
|
43225
43558
|
const ps = new Array(mult);
|
|
43226
43559
|
if (idx < s) {
|
|
@@ -43349,8 +43682,8 @@ function chainOf(e) {
|
|
|
43349
43682
|
return list;
|
|
43350
43683
|
}
|
|
43351
43684
|
function warnNoControlPoints(e) {
|
|
43352
|
-
|
|
43353
|
-
`
|
|
43685
|
+
agwarningf(
|
|
43686
|
+
`Could not create control points for multiple spline for edge (${e.tail.name},${e.head.name})`
|
|
43354
43687
|
);
|
|
43355
43688
|
return 1;
|
|
43356
43689
|
}
|
|
@@ -46013,7 +46346,11 @@ function armPow(x, y) {
|
|
|
46013
46346
|
|
|
46014
46347
|
// src/common/crand.ts
|
|
46015
46348
|
var C_RAND_MAX = 2147483647;
|
|
46016
|
-
var
|
|
46349
|
+
var UNSEEDED_STATE2 = 1;
|
|
46350
|
+
var state2 = UNSEEDED_STATE2;
|
|
46351
|
+
registerRenderState(() => {
|
|
46352
|
+
state2 = UNSEEDED_STATE2;
|
|
46353
|
+
});
|
|
46017
46354
|
function csrand(seed) {
|
|
46018
46355
|
state2 = seed;
|
|
46019
46356
|
}
|
|
@@ -47953,7 +48290,7 @@ function makeAddPoly(n, xmargin, ymargin) {
|
|
|
47953
48290
|
case 3 /* SH_POINT */:
|
|
47954
48291
|
return finishPoly(genRound(n, xmargin, ymargin), POLY_CIRCLE);
|
|
47955
48292
|
default:
|
|
47956
|
-
|
|
48293
|
+
agerrorf(`makeAddPoly: unknown shape type ${shapeName(n)}
|
|
47957
48294
|
`);
|
|
47958
48295
|
return null;
|
|
47959
48296
|
}
|
|
@@ -47986,7 +48323,7 @@ function baseShape(n) {
|
|
|
47986
48323
|
case 3 /* SH_POINT */:
|
|
47987
48324
|
return { verts: genRound(n, 0, 0), kind: POLY_CIRCLE };
|
|
47988
48325
|
default:
|
|
47989
|
-
|
|
48326
|
+
agerrorf(`makePoly: unknown shape type ${shapeName(n)}
|
|
47990
48327
|
`);
|
|
47991
48328
|
return null;
|
|
47992
48329
|
}
|
|
@@ -49368,7 +49705,7 @@ function warnUnrecognizedOverlap(flag) {
|
|
|
49368
49705
|
const s = flag.toLowerCase();
|
|
49369
49706
|
if (s.startsWith("prism") || NAMED_MODES.has(s)) return;
|
|
49370
49707
|
if (mapBoolDflt(flag, false) === mapBoolDflt(flag, true)) return;
|
|
49371
|
-
|
|
49708
|
+
agerrLineOn("warn", `Unrecognized overlap value "${flag}" - using false`);
|
|
49372
49709
|
}
|
|
49373
49710
|
function getAdjustMode(flag) {
|
|
49374
49711
|
warnUnrecognizedOverlap(flag);
|
|
@@ -49401,7 +49738,7 @@ function adjustLate(g, am) {
|
|
|
49401
49738
|
case AM_VPSC:
|
|
49402
49739
|
return vpscAdjust(g);
|
|
49403
49740
|
default:
|
|
49404
|
-
|
|
49741
|
+
agerrLineOn("warn", `Unhandled adjust option ${am.print}`);
|
|
49405
49742
|
return 0;
|
|
49406
49743
|
}
|
|
49407
49744
|
}
|
|
@@ -49620,20 +49957,20 @@ function setSubtreeSize(g) {
|
|
|
49620
49957
|
walkAncestorChain(n);
|
|
49621
49958
|
}
|
|
49622
49959
|
}
|
|
49623
|
-
function applySpanToChild(g, n, next, ratio,
|
|
49960
|
+
function applySpanToChild(g, n, next, ratio, seen2) {
|
|
49624
49961
|
const nd2 = rdata(next);
|
|
49625
|
-
if (nd2.parent !== n || nd2.span !== 0 ||
|
|
49626
|
-
|
|
49962
|
+
if (nd2.parent !== n || nd2.span !== 0 || seen2.has(next)) return;
|
|
49963
|
+
seen2.add(next);
|
|
49627
49964
|
nd2.span = ratio * nd2.subtreeSize;
|
|
49628
49965
|
if (nd2.nChildren > 0) setChildSubtreeSpans(g, next);
|
|
49629
49966
|
}
|
|
49630
49967
|
function setChildSubtreeSpans(g, n) {
|
|
49631
49968
|
const nd = rdata(n);
|
|
49632
49969
|
const ratio = nd.span / nd.subtreeSize;
|
|
49633
|
-
const
|
|
49970
|
+
const seen2 = /* @__PURE__ */ new Set();
|
|
49634
49971
|
for (const ep of incidentEdges2(g, n)) {
|
|
49635
49972
|
const next = neighborOf(ep, n);
|
|
49636
|
-
if (next !== null) applySpanToChild(g, n, next, ratio,
|
|
49973
|
+
if (next !== null) applySpanToChild(g, n, next, ratio, seen2);
|
|
49637
49974
|
}
|
|
49638
49975
|
}
|
|
49639
49976
|
function setSubtreeSpans(sg, center) {
|
|
@@ -49902,7 +50239,7 @@ var fdpParms = {
|
|
|
49902
50239
|
* equivalent). @see lib/fdpgen/fdp.h:fdpParms_s.Mlimit */
|
|
49903
50240
|
Mlimit: Infinity
|
|
49904
50241
|
};
|
|
49905
|
-
var
|
|
50242
|
+
var PARMS_INIT = {
|
|
49906
50243
|
useGrid: 0,
|
|
49907
50244
|
useNew: 0,
|
|
49908
50245
|
seed: 0,
|
|
@@ -49920,6 +50257,10 @@ var parms = {
|
|
|
49920
50257
|
pass1: 0,
|
|
49921
50258
|
loopcnt: 0
|
|
49922
50259
|
};
|
|
50260
|
+
var parms = { ...PARMS_INIT };
|
|
50261
|
+
registerRenderState(() => {
|
|
50262
|
+
Object.assign(parms, PARMS_INIT);
|
|
50263
|
+
});
|
|
49923
50264
|
function cool(t) {
|
|
49924
50265
|
return parms.T0 * (parms.maxIters - t) / parms.maxIters;
|
|
49925
50266
|
}
|
|
@@ -50564,14 +50905,19 @@ function fdpTLayout(g, xpms) {
|
|
|
50564
50905
|
// src/layout/fdp/xlayout.ts
|
|
50565
50906
|
var DFLT_OVERLAP = "9:prism";
|
|
50566
50907
|
var PS2INCH3 = (x) => x / 72;
|
|
50567
|
-
var
|
|
50908
|
+
var XPARAMS_INIT = {
|
|
50568
50909
|
numIters: 60,
|
|
50569
50910
|
T0: 0,
|
|
50570
50911
|
K: 0.3,
|
|
50571
50912
|
C: 1.5,
|
|
50572
50913
|
loopcnt: 0
|
|
50573
50914
|
};
|
|
50915
|
+
var xParams = { ...XPARAMS_INIT };
|
|
50574
50916
|
var xMarg = { x: 0, y: 0, doAdd: false };
|
|
50917
|
+
registerRenderState(() => {
|
|
50918
|
+
Object.assign(xParams, XPARAMS_INIT);
|
|
50919
|
+
xMarg = { x: 0, y: 0, doAdd: false };
|
|
50920
|
+
});
|
|
50575
50921
|
function wd2(n) {
|
|
50576
50922
|
return xMarg.doAdd ? n.info.width / 2 + xMarg.x : n.info.width * xMarg.x / 2;
|
|
50577
50923
|
}
|
|
@@ -51433,7 +51779,7 @@ function fdpSplines(g) {
|
|
|
51433
51779
|
);
|
|
51434
51780
|
}
|
|
51435
51781
|
if (g.info.n_cluster_edges) {
|
|
51436
|
-
|
|
51782
|
+
agerrLineOn("warn", CLUSTER_EDGE_WARNING);
|
|
51437
51783
|
et = EDGETYPE_LINE;
|
|
51438
51784
|
} else {
|
|
51439
51785
|
splineEdges1(g, et);
|
|
@@ -52855,7 +53201,7 @@ function buildDerivedGraph(g) {
|
|
|
52855
53201
|
}
|
|
52856
53202
|
function buildDerivedEdges(g, dg) {
|
|
52857
53203
|
const edges = [];
|
|
52858
|
-
const
|
|
53204
|
+
const seen2 = /* @__PURE__ */ new Set();
|
|
52859
53205
|
for (const n of nodesInSeq(g)) {
|
|
52860
53206
|
for (const e of n.outEdges(g)) {
|
|
52861
53207
|
if (e.tail === e.head) continue;
|
|
@@ -52863,8 +53209,8 @@ function buildDerivedEdges(g, dg) {
|
|
|
52863
53209
|
const head = dg.nodes.get(e.head.name);
|
|
52864
53210
|
if (!tail || !head) continue;
|
|
52865
53211
|
const key = [tail.name, head.name].sort().join("\0");
|
|
52866
|
-
if (
|
|
52867
|
-
|
|
53212
|
+
if (seen2.has(key)) continue;
|
|
53213
|
+
seen2.add(key);
|
|
52868
53214
|
edges.push({ tail, head, order: 0, origEdge: e });
|
|
52869
53215
|
}
|
|
52870
53216
|
}
|
|
@@ -53708,12 +54054,12 @@ function svgEndCluster(job) {
|
|
|
53708
54054
|
}
|
|
53709
54055
|
|
|
53710
54056
|
// src/render/svg-edge-split.ts
|
|
53711
|
-
var
|
|
54057
|
+
var DEFAULT_COLOR5 = "black";
|
|
53712
54058
|
var PENWIDTH_NORMAL4 = 1;
|
|
53713
54059
|
var PENWIDTH_THRESHOLD4 = 5e-3;
|
|
53714
54060
|
var EPS3 = 1e-5;
|
|
53715
54061
|
function dist3(a, b) {
|
|
53716
|
-
return Math.
|
|
54062
|
+
return Math.sqrt(dist2(a, b));
|
|
53717
54063
|
}
|
|
53718
54064
|
function approxLen(list, off) {
|
|
53719
54065
|
return dist3(list[off], list[off + 1]) + dist3(list[off + 1], list[off + 2]) + dist3(list[off + 2], list[off + 3]);
|
|
@@ -53762,7 +54108,7 @@ function emitCurve(list, color, job) {
|
|
|
53762
54108
|
}
|
|
53763
54109
|
function stepSegment(list, s, st, out) {
|
|
53764
54110
|
if (Math.abs(s.t) < EPS3) return;
|
|
53765
|
-
const color = s.color ??
|
|
54111
|
+
const color = s.color ?? DEFAULT_COLOR5;
|
|
53766
54112
|
st.left -= s.t;
|
|
53767
54113
|
st.endColor = color;
|
|
53768
54114
|
if (st.first) {
|
|
@@ -53781,7 +54127,7 @@ function stepSegment(list, s, st, out) {
|
|
|
53781
54127
|
}
|
|
53782
54128
|
}
|
|
53783
54129
|
function splitSplineByColor(list, segs) {
|
|
53784
|
-
const st = { left: 1, first: true, bzR: list, done: false, endColor:
|
|
54130
|
+
const st = { left: 1, first: true, bzR: list, done: false, endColor: DEFAULT_COLOR5 };
|
|
53785
54131
|
const curves = [];
|
|
53786
54132
|
for (const s of segs) {
|
|
53787
54133
|
stepSegment(list, s, st, curves);
|
|
@@ -53796,16 +54142,16 @@ function drawSplitSpline(list, segs, job) {
|
|
|
53796
54142
|
}
|
|
53797
54143
|
function emitSplitEdgePaths(e, job, colorList) {
|
|
53798
54144
|
const segs = parseSegs(colorList).segs;
|
|
53799
|
-
const
|
|
54145
|
+
const firstColor2 = segs[0]?.color ?? DEFAULT_COLOR5;
|
|
53800
54146
|
const spl = e.info.spl;
|
|
53801
|
-
let endColor =
|
|
53802
|
-
if (spl === void 0) return { firstColor, endColor };
|
|
54147
|
+
let endColor = firstColor2;
|
|
54148
|
+
if (spl === void 0) return { firstColor: firstColor2, endColor };
|
|
53803
54149
|
for (let si = 0; si < spl.size; si++) {
|
|
53804
54150
|
const bz = spl.list[si];
|
|
53805
54151
|
if (bz === void 0 || bz.size < 4) continue;
|
|
53806
54152
|
endColor = drawSplitSpline(bz.list, segs, job);
|
|
53807
54153
|
}
|
|
53808
|
-
return { firstColor, endColor };
|
|
54154
|
+
return { firstColor: firstColor2, endColor };
|
|
53809
54155
|
}
|
|
53810
54156
|
|
|
53811
54157
|
// src/common/taper.ts
|
|
@@ -55250,7 +55596,7 @@ var DotWriterBase = class {
|
|
|
55250
55596
|
};
|
|
55251
55597
|
|
|
55252
55598
|
// src/render/dot/edge-draw.ts
|
|
55253
|
-
var
|
|
55599
|
+
var DEFAULT_COLOR6 = "black";
|
|
55254
55600
|
var DEFAULT_LINE_STYLE = ["solid", "setlinewidth(1)"];
|
|
55255
55601
|
function emitArrowOp(buf, op, pen) {
|
|
55256
55602
|
switch (op.kind) {
|
|
@@ -55343,8 +55689,8 @@ var EdgeDrawBase = class extends DotWriterBase {
|
|
|
55343
55689
|
*/
|
|
55344
55690
|
emitSplitSpline(bzList, colorAttr, edraw, job) {
|
|
55345
55691
|
const segs = parseSegs(colorAttr).segs;
|
|
55346
|
-
const
|
|
55347
|
-
let endColor =
|
|
55692
|
+
const firstColor2 = segs[0]?.color ?? DEFAULT_COLOR6;
|
|
55693
|
+
let endColor = firstColor2;
|
|
55348
55694
|
for (const bz of bzList) {
|
|
55349
55695
|
if (bz === void 0 || bz.size < 4) continue;
|
|
55350
55696
|
const split = splitSplineByColor(bz.list.slice(0, bz.size), segs);
|
|
@@ -55353,7 +55699,7 @@ var EdgeDrawBase = class extends DotWriterBase {
|
|
|
55353
55699
|
edraw.push(this.styleOp(job), xdotPenColor(resolveRenderColor(c.color)), xdotPoints("B", c.points));
|
|
55354
55700
|
}
|
|
55355
55701
|
}
|
|
55356
|
-
return { firstColor, endColor };
|
|
55702
|
+
return { firstColor: firstColor2, endColor };
|
|
55357
55703
|
}
|
|
55358
55704
|
/**
|
|
55359
55705
|
* Emit the parallel-multicolor edge spline: one offset Bézier per color,
|
|
@@ -55365,7 +55711,7 @@ var EdgeDrawBase = class extends DotWriterBase {
|
|
|
55365
55711
|
const segData = bzList.map(
|
|
55366
55712
|
(bz) => bz !== void 0 && bz.size >= 4 ? buildOffsetLists(bz.list, (2 + numc) / 2) : { offlist: [], tmplist: [] }
|
|
55367
55713
|
);
|
|
55368
|
-
const colors = parseSegs(colorAttr).segs.map((s) => s.color ??
|
|
55714
|
+
const colors = parseSegs(colorAttr).segs.map((s) => s.color ?? DEFAULT_COLOR6);
|
|
55369
55715
|
for (const color of colors) {
|
|
55370
55716
|
const pen = xdotPenColor(resolveRenderColor(color));
|
|
55371
55717
|
for (const sd of segData) {
|
|
@@ -55375,8 +55721,8 @@ var EdgeDrawBase = class extends DotWriterBase {
|
|
|
55375
55721
|
}
|
|
55376
55722
|
}
|
|
55377
55723
|
return {
|
|
55378
|
-
headColor: colors[0] ??
|
|
55379
|
-
tailColor: colors[1] ?? colors[0] ??
|
|
55724
|
+
headColor: colors[0] ?? DEFAULT_COLOR6,
|
|
55725
|
+
tailColor: colors[1] ?? colors[0] ?? DEFAULT_COLOR6
|
|
55380
55726
|
};
|
|
55381
55727
|
}
|
|
55382
55728
|
/** Emit one arrow's primitive ops into `buf` (pen/fill from the edge color).
|
|
@@ -55893,8 +56239,8 @@ var SvgRenderer = class {
|
|
|
55893
56239
|
const numc = (colorAttr.match(/:/g) ?? []).length;
|
|
55894
56240
|
const numsemi = (colorAttr.match(/;/g) ?? []).length;
|
|
55895
56241
|
if (numsemi > 0 && numc > 0) {
|
|
55896
|
-
const { firstColor, endColor } = emitSplitEdgePaths(e, job, colorAttr);
|
|
55897
|
-
emitMulticolorArrows(e, job, endColor,
|
|
56242
|
+
const { firstColor: firstColor2, endColor } = emitSplitEdgePaths(e, job, colorAttr);
|
|
56243
|
+
emitMulticolorArrows(e, job, endColor, firstColor2);
|
|
55898
56244
|
} else if (edgeIsTapered(e)) {
|
|
55899
56245
|
svgTaperedEdge(e, job);
|
|
55900
56246
|
} else if (numc > 0) {
|
|
@@ -57162,6 +57508,7 @@ function checkRenderArgs(g, format, opts) {
|
|
|
57162
57508
|
}
|
|
57163
57509
|
function render2(g, format, opts) {
|
|
57164
57510
|
checkRenderArgs(g, format, opts);
|
|
57511
|
+
resetRenderState();
|
|
57165
57512
|
const engine = opts?.engine ?? "dot";
|
|
57166
57513
|
const inlineImages = opts?.inlineImages ?? false;
|
|
57167
57514
|
const ctx = createDefaultContext();
|
|
@@ -57358,6 +57705,7 @@ async function renderAsync(g, format, opts) {
|
|
|
57358
57705
|
const engine = opts?.engine ?? "dot";
|
|
57359
57706
|
try {
|
|
57360
57707
|
const { fontIssues, sizes, bytes } = await prefetchAll(g, opts);
|
|
57708
|
+
resetRenderState();
|
|
57361
57709
|
const ctx = createDefaultContext();
|
|
57362
57710
|
if (opts?.imageSizer !== void 0) {
|
|
57363
57711
|
const sizer = (src) => sizes.get(src) ?? null;
|
|
@@ -57434,6 +57782,7 @@ function layoutAndRenderXdot(g, engine) {
|
|
|
57434
57782
|
}
|
|
57435
57783
|
function getDrawOps(g, opts) {
|
|
57436
57784
|
checkDrawOpsArgs(g, opts);
|
|
57785
|
+
resetRenderState();
|
|
57437
57786
|
const engine = opts?.engine ?? DEFAULT_DRAW_ENGINE;
|
|
57438
57787
|
return collectGraphOps(parse(layoutAndRenderXdot(g, engine)));
|
|
57439
57788
|
}
|
|
@@ -57592,6 +57941,7 @@ function classifyError(err) {
|
|
|
57592
57941
|
}
|
|
57593
57942
|
function renderSvg(dotSource, engine) {
|
|
57594
57943
|
checkRenderArgs2(dotSource, engine);
|
|
57944
|
+
resetRenderState();
|
|
57595
57945
|
const ctx = createDefaultContext();
|
|
57596
57946
|
try {
|
|
57597
57947
|
const g = parse(dotSource);
|