@knowvah/dot-engine 2.6.11 → 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/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-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 +765 -451
- 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 +513 -200
- 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/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-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/render.js
CHANGED
|
@@ -5079,6 +5079,57 @@ var ALL_FONT_METRICS = [
|
|
|
5079
5079
|
CALIBRI_FAMILY
|
|
5080
5080
|
];
|
|
5081
5081
|
|
|
5082
|
+
// src/common/render-state.ts
|
|
5083
|
+
var resets = [];
|
|
5084
|
+
function registerRenderState(reset2) {
|
|
5085
|
+
resets.push(reset2);
|
|
5086
|
+
}
|
|
5087
|
+
function resetRenderState() {
|
|
5088
|
+
for (const reset2 of resets) reset2();
|
|
5089
|
+
}
|
|
5090
|
+
|
|
5091
|
+
// src/common/agerr.ts
|
|
5092
|
+
var PREFIX_ERROR = "Error";
|
|
5093
|
+
var PREFIX_WARNING = "Warning";
|
|
5094
|
+
var PREFIX_SEP = ": ";
|
|
5095
|
+
var DEL = 127;
|
|
5096
|
+
var LAST_CNTRL = 31;
|
|
5097
|
+
var WHITESPACE = /* @__PURE__ */ new Set([9, 10, 11, 12, 13]);
|
|
5098
|
+
var OCTAL_WIDTH = 3;
|
|
5099
|
+
var OCTAL_RADIX = 8;
|
|
5100
|
+
var lastLevel = "warning";
|
|
5101
|
+
registerRenderState(() => {
|
|
5102
|
+
lastLevel = "warning";
|
|
5103
|
+
});
|
|
5104
|
+
function escapeControl(message) {
|
|
5105
|
+
let out = "";
|
|
5106
|
+
for (const ch of message) {
|
|
5107
|
+
const c = ch.codePointAt(0);
|
|
5108
|
+
if ((c <= LAST_CNTRL || c === DEL) && !WHITESPACE.has(c)) {
|
|
5109
|
+
out += `\\${c.toString(OCTAL_RADIX).padStart(OCTAL_WIDTH, "0")}`;
|
|
5110
|
+
} else out += ch;
|
|
5111
|
+
}
|
|
5112
|
+
return out;
|
|
5113
|
+
}
|
|
5114
|
+
function agerrLineOn(channel, line) {
|
|
5115
|
+
if (channel === "warn") console.warn(escapeControl(line));
|
|
5116
|
+
else console.error(escapeControl(line));
|
|
5117
|
+
}
|
|
5118
|
+
function agerr(level, msg, channel) {
|
|
5119
|
+
if (level === "prev") {
|
|
5120
|
+
agerrLineOn(channel ?? (lastLevel === "warning" ? "warn" : "error"), msg);
|
|
5121
|
+
return;
|
|
5122
|
+
}
|
|
5123
|
+
lastLevel = level;
|
|
5124
|
+
const prefix = level === "error" ? PREFIX_ERROR : PREFIX_WARNING;
|
|
5125
|
+
agerrLineOn(channel ?? (level === "warning" ? "warn" : "error"), `${prefix}${PREFIX_SEP}${msg}`);
|
|
5126
|
+
}
|
|
5127
|
+
var agerrorf = (msg, channel) => agerr("error", msg, channel);
|
|
5128
|
+
var agwarningf = (msg, channel) => agerr("warning", msg, channel);
|
|
5129
|
+
function agerrFinished(line, channel) {
|
|
5130
|
+
agerrLineOn(channel ?? (line.startsWith(PREFIX_WARNING) ? "warn" : "error"), line);
|
|
5131
|
+
}
|
|
5132
|
+
|
|
5082
5133
|
// src/common/textmeasure-lookup.ts
|
|
5083
5134
|
var TIMES_FALLBACK = ALL_FONT_METRICS[0];
|
|
5084
5135
|
function normalizeFontName(name) {
|
|
@@ -5092,6 +5143,7 @@ function normalizeFontName(name) {
|
|
|
5092
5143
|
return result;
|
|
5093
5144
|
}
|
|
5094
5145
|
var warnedFontNames = /* @__PURE__ */ new Set();
|
|
5146
|
+
registerRenderState(() => warnedFontNames.clear());
|
|
5095
5147
|
function getFamilyMetrics(fontName) {
|
|
5096
5148
|
const key = normalizeFontName(fontName);
|
|
5097
5149
|
for (const family of ALL_FONT_METRICS) {
|
|
@@ -5099,8 +5151,8 @@ function getFamilyMetrics(fontName) {
|
|
|
5099
5151
|
}
|
|
5100
5152
|
if (!warnedFontNames.has(fontName)) {
|
|
5101
5153
|
warnedFontNames.add(fontName);
|
|
5102
|
-
|
|
5103
|
-
`
|
|
5154
|
+
agwarningf(
|
|
5155
|
+
`no hard-coded metrics for '${fontName}'. Falling back to 'Times' metrics`
|
|
5104
5156
|
);
|
|
5105
5157
|
}
|
|
5106
5158
|
return TIMES_FALLBACK;
|
|
@@ -5285,10 +5337,37 @@ function getVariantWidths(family, bold, italic) {
|
|
|
5285
5337
|
return family.regular;
|
|
5286
5338
|
}
|
|
5287
5339
|
var SPACE_CHAR_CODE = 32;
|
|
5340
|
+
var FIRST_NON_ASCII = 128;
|
|
5341
|
+
var warned = /* @__PURE__ */ new Set();
|
|
5342
|
+
var NON_ASCII_FLAG = "non-ascii";
|
|
5343
|
+
var ASCII_FLAG = "ascii";
|
|
5344
|
+
registerRenderState(() => warned.clear());
|
|
5345
|
+
function warnNonAscii(character) {
|
|
5346
|
+
if (warned.has(NON_ASCII_FLAG)) return;
|
|
5347
|
+
warned.add(NON_ASCII_FLAG);
|
|
5348
|
+
agwarningf(
|
|
5349
|
+
`Warning: no value for width of non-ASCII character ${character}. Falling back to width of space character`
|
|
5350
|
+
);
|
|
5351
|
+
}
|
|
5352
|
+
function warnAscii(character) {
|
|
5353
|
+
if (warned.has(ASCII_FLAG)) return;
|
|
5354
|
+
warned.add(ASCII_FLAG);
|
|
5355
|
+
agwarningf(
|
|
5356
|
+
`Warning: no value for width of ASCII character ${character}. Falling back to 0`
|
|
5357
|
+
);
|
|
5358
|
+
}
|
|
5288
5359
|
function charWidthUnits(widths, charCode) {
|
|
5289
|
-
|
|
5360
|
+
let code = charCode;
|
|
5361
|
+
if (code >= FIRST_NON_ASCII) {
|
|
5362
|
+
warnNonAscii(code);
|
|
5363
|
+
code = SPACE_CHAR_CODE;
|
|
5364
|
+
}
|
|
5290
5365
|
const w = widths[code] ?? -1;
|
|
5291
|
-
|
|
5366
|
+
if (w < 0) {
|
|
5367
|
+
warnAscii(code);
|
|
5368
|
+
return 0;
|
|
5369
|
+
}
|
|
5370
|
+
return w;
|
|
5292
5371
|
}
|
|
5293
5372
|
var utf8Encoder = new TextEncoder();
|
|
5294
5373
|
function utf8Bytes(text) {
|
|
@@ -5665,10 +5744,7 @@ var StderrLines = class {
|
|
|
5665
5744
|
this.pending = "";
|
|
5666
5745
|
}
|
|
5667
5746
|
};
|
|
5668
|
-
var consoleLine = (line) =>
|
|
5669
|
-
if (line.startsWith("Warning")) console.warn(line);
|
|
5670
|
-
else console.error(line);
|
|
5671
|
-
};
|
|
5747
|
+
var consoleLine = (line) => agerrFinished(line);
|
|
5672
5748
|
var labelStderr = () => new StderrLines(consoleLine);
|
|
5673
5749
|
var agerrLine = (out, msg) => {
|
|
5674
5750
|
if (out === void 0) consoleLine(msg);
|
|
@@ -6128,14 +6204,14 @@ function tagEdge(text, i) {
|
|
|
6128
6204
|
if (i + 1 >= text.length) return PARTIAL;
|
|
6129
6205
|
return text[i + 1] === ">" ? COMPLETE_END(i + 2) : void 0;
|
|
6130
6206
|
}
|
|
6131
|
-
function storeAttError(text, p, at, pair,
|
|
6132
|
-
if (
|
|
6133
|
-
|
|
6207
|
+
function storeAttError(text, p, at, pair, seen2) {
|
|
6208
|
+
if (seen2.has(pair.name)) return { message: XML_ERROR_DUPLICATE_ATTRIBUTE, offset: at };
|
|
6209
|
+
seen2.add(pair.name);
|
|
6134
6210
|
const err = attValueError(text.slice(pair.value.start, pair.value.end), pair.value.start);
|
|
6135
6211
|
return err === void 0 ? void 0 : { message: err.message, offset: err.offset ?? p };
|
|
6136
6212
|
}
|
|
6137
6213
|
function scanAttributes(text, p, from) {
|
|
6138
|
-
const
|
|
6214
|
+
const seen2 = /* @__PURE__ */ new Set();
|
|
6139
6215
|
let attError;
|
|
6140
6216
|
let i = skipSpace(text, from);
|
|
6141
6217
|
for (; ; ) {
|
|
@@ -6144,7 +6220,7 @@ function scanAttributes(text, p, from) {
|
|
|
6144
6220
|
if (edge !== void 0) return edge;
|
|
6145
6221
|
const pair = scanPair(text, i);
|
|
6146
6222
|
if ("kind" in pair) return pair;
|
|
6147
|
-
attError ??= storeAttError(text, p, i, pair,
|
|
6223
|
+
attError ??= storeAttError(text, p, i, pair, seen2);
|
|
6148
6224
|
i = pair.next;
|
|
6149
6225
|
}
|
|
6150
6226
|
}
|
|
@@ -6212,9 +6288,11 @@ function scanCdata(text, p, base, dataOf, tokens) {
|
|
|
6212
6288
|
}
|
|
6213
6289
|
function scanText(text, p, base, tokens) {
|
|
6214
6290
|
const e = text.indexOf("<", p);
|
|
6215
|
-
const
|
|
6216
|
-
|
|
6217
|
-
|
|
6291
|
+
const slice = text.slice(p, e < 0 ? text.length : e);
|
|
6292
|
+
const from = e < 0 ? heldRefStart(slice) : void 0;
|
|
6293
|
+
const end = from === void 0 ? p + slice.length : p + from;
|
|
6294
|
+
if (end > p) tokens.push({ kind: "text", start: base + p, end: base + end });
|
|
6295
|
+
return { at: end, held: from !== void 0 };
|
|
6218
6296
|
}
|
|
6219
6297
|
function scanContent(text, base, inCdata, dataOf) {
|
|
6220
6298
|
const tokens = [];
|
|
@@ -6229,7 +6307,9 @@ function scanContent(text, base, inCdata, dataOf) {
|
|
|
6229
6307
|
continue;
|
|
6230
6308
|
}
|
|
6231
6309
|
if (text[p] !== "<") {
|
|
6232
|
-
|
|
6310
|
+
const scanned = scanText(text, p, base, tokens);
|
|
6311
|
+
if (scanned.held) return { tokens, consumed: scanned.at, inCdata: false };
|
|
6312
|
+
p = scanned.at;
|
|
6233
6313
|
continue;
|
|
6234
6314
|
}
|
|
6235
6315
|
const { scan, kind } = scanMarkup(text, p);
|
|
@@ -6329,24 +6409,44 @@ var ExpatFeed = class {
|
|
|
6329
6409
|
}
|
|
6330
6410
|
};
|
|
6331
6411
|
var XML_PREDEFINED_ENTITIES = /* @__PURE__ */ new Set(["lt", "gt", "amp", "quot", "apos"]);
|
|
6332
|
-
var
|
|
6333
|
-
|
|
6334
|
-
|
|
6335
|
-
|
|
6336
|
-
|
|
6337
|
-
|
|
6338
|
-
|
|
6339
|
-
|
|
6412
|
+
var SCANNED_ENTITY = /^&([^;&<]*);/;
|
|
6413
|
+
function contentRef(text, t) {
|
|
6414
|
+
const semi = text.indexOf(";", t);
|
|
6415
|
+
const ref = text.slice(t, semi < 0 ? text.length : semi + 1);
|
|
6416
|
+
const scan = scanAttValue(`"${ref}"`, 0);
|
|
6417
|
+
if ("close" in scan) return { end: t + scan.close - 1 };
|
|
6418
|
+
return { invalid: "invalid" in scan ? t + scan.invalid - 1 : text.length };
|
|
6419
|
+
}
|
|
6420
|
+
function firstRefProblem(text) {
|
|
6421
|
+
let t = text.indexOf("&");
|
|
6422
|
+
while (t >= 0) {
|
|
6423
|
+
if (text[t + 1] !== "#") {
|
|
6424
|
+
const name = SCANNED_ENTITY.exec(text.slice(t))?.[1];
|
|
6425
|
+
if (name !== void 0 && name.length >= 2 && Object.hasOwn(HTML_ENTITIES, name)) {
|
|
6426
|
+
t = text.indexOf("&", t + name.length + 2);
|
|
6427
|
+
continue;
|
|
6428
|
+
}
|
|
6340
6429
|
}
|
|
6341
|
-
const
|
|
6342
|
-
if (
|
|
6343
|
-
const key = text.slice(t + 1,
|
|
6344
|
-
if (
|
|
6345
|
-
return { message:
|
|
6430
|
+
const ref = contentRef(text, t);
|
|
6431
|
+
if ("invalid" in ref) return { message: XML_ERROR_INVALID_TOKEN, offset: ref.invalid, from: t };
|
|
6432
|
+
const key = text.slice(t + 1, ref.end - 1);
|
|
6433
|
+
if (text[t + 1] === "#") {
|
|
6434
|
+
if (charRefNumber(`&${key};`) < 0) return { message: XML_ERROR_BAD_CHAR_REF, offset: t, from: t };
|
|
6435
|
+
} else if (!XML_PREDEFINED_ENTITIES.has(key)) {
|
|
6436
|
+
return { message: XML_ERROR_UNDEFINED_ENTITY, offset: t, from: t };
|
|
6346
6437
|
}
|
|
6438
|
+
t = text.indexOf("&", ref.end);
|
|
6347
6439
|
}
|
|
6348
6440
|
return void 0;
|
|
6349
6441
|
}
|
|
6442
|
+
function textRefError(text) {
|
|
6443
|
+
const problem = firstRefProblem(text);
|
|
6444
|
+
return problem === void 0 ? void 0 : { message: problem.message, offset: problem.offset };
|
|
6445
|
+
}
|
|
6446
|
+
function heldRefStart(text) {
|
|
6447
|
+
const problem = firstRefProblem(text);
|
|
6448
|
+
return problem?.message === XML_ERROR_INVALID_TOKEN && problem.offset === text.length ? problem.from : void 0;
|
|
6449
|
+
}
|
|
6350
6450
|
function parseTagChunk(chunk) {
|
|
6351
6451
|
if (!chunk.endsWith(">")) return void 0;
|
|
6352
6452
|
const body = chunk.slice(1, -1);
|
|
@@ -7373,30 +7473,23 @@ var splitSizedLines = (texts, measurer, env) => {
|
|
|
7373
7473
|
return lines;
|
|
7374
7474
|
};
|
|
7375
7475
|
var itemHasFlags = (i) => i.bold === true || i.italic === true || i.underline === true || i.strikethrough === true || i.overline === true || i.subscript === true || i.superscript === true;
|
|
7376
|
-
var htmlTextIsSimple = (
|
|
7476
|
+
var htmlTextIsSimple = (lines, env) => {
|
|
7377
7477
|
let prevFs = -1;
|
|
7378
7478
|
let prevFace = null;
|
|
7379
|
-
|
|
7380
|
-
|
|
7381
|
-
|
|
7382
|
-
|
|
7383
|
-
|
|
7384
|
-
|
|
7385
|
-
|
|
7386
|
-
|
|
7387
|
-
if (++count > 1 || itemHasFlags(item)) return false;
|
|
7388
|
-
const { fs, face } = itemFont(item, env);
|
|
7389
|
-
if (prevFs < 0) prevFs = fs;
|
|
7390
|
-
else if (fs !== prevFs) return false;
|
|
7391
|
-
if (prevFace === null) prevFace = face;
|
|
7392
|
-
else if (face !== prevFace) return false;
|
|
7393
|
-
}
|
|
7479
|
+
for (const ln of lines) {
|
|
7480
|
+
const item = ln.items[0];
|
|
7481
|
+
if (ln.items.length > 1 || itemHasFlags(item)) return false;
|
|
7482
|
+
const { fs, face } = itemFont(item, env);
|
|
7483
|
+
if (prevFs < 0) prevFs = fs;
|
|
7484
|
+
else if (fs !== prevFs) return false;
|
|
7485
|
+
if (prevFace === null) prevFace = face;
|
|
7486
|
+
else if (face !== prevFace) return false;
|
|
7394
7487
|
}
|
|
7395
7488
|
return true;
|
|
7396
7489
|
};
|
|
7397
7490
|
var sizeTextContent = (texts, measurer, env = defaultSizeEnv()) => {
|
|
7398
7491
|
const lines = splitSizedLines(texts, measurer, env);
|
|
7399
|
-
const simple = htmlTextIsSimple(
|
|
7492
|
+
const simple = htmlTextIsSimple(lines, env);
|
|
7400
7493
|
let w = 0;
|
|
7401
7494
|
let h = 0;
|
|
7402
7495
|
for (const ln of lines) {
|
|
@@ -8976,10 +9069,10 @@ var SMALL = 1e-10;
|
|
|
8976
9069
|
function ptToLine2(a, b, p) {
|
|
8977
9070
|
const dx = b.x - a.x;
|
|
8978
9071
|
const dy = b.y - a.y;
|
|
8979
|
-
let a2 = (p.y - a.y
|
|
9072
|
+
let a2 = fma(p.y - a.y, dx, -(dy * (p.x - a.x)));
|
|
8980
9073
|
a2 *= a2;
|
|
8981
9074
|
if (a2 < SMALL) return 0;
|
|
8982
|
-
return a2 / (dx
|
|
9075
|
+
return a2 / fma(dx, dx, dy * dy);
|
|
8983
9076
|
}
|
|
8984
9077
|
function checkControlPoints(cp) {
|
|
8985
9078
|
const dis1 = ptToLine2(cp[0], cp[3], cp[1]);
|
|
@@ -9470,10 +9563,14 @@ function cubicHalf(c, rightHalf) {
|
|
|
9470
9563
|
function curveControlPoints(p, v, w, flag) {
|
|
9471
9564
|
const AF0 = { x: p.x + v.x + w.x, y: p.y + v.y + w.y };
|
|
9472
9565
|
const AF3 = { x: p.x - v.x + w.x, y: p.y - v.y + w.y };
|
|
9473
|
-
const
|
|
9474
|
-
const
|
|
9475
|
-
const
|
|
9476
|
-
|
|
9566
|
+
const bulgeX = w.x * 4 / 3;
|
|
9567
|
+
const bulgeY = w.y * 4 / 3;
|
|
9568
|
+
const x1 = fma(v.x, 0.95, p.x) + w.x;
|
|
9569
|
+
const x2 = fma(v.x, -0.95, p.x) + w.x;
|
|
9570
|
+
if (flag & ARR_MOD_INV) {
|
|
9571
|
+
return [AF0, { x: x1 + bulgeX, y: AF0.y + bulgeY }, { x: x2 + bulgeX, y: AF3.y + bulgeY }, AF3];
|
|
9572
|
+
}
|
|
9573
|
+
return [AF0, { x: x1 - bulgeX, y: AF0.y - bulgeY }, { x: x2 - bulgeX, y: AF3.y - bulgeY }, AF3];
|
|
9477
9574
|
}
|
|
9478
9575
|
function genCurve(p0, u, _arrowsize, penwidth, flag, rankdir = 0) {
|
|
9479
9576
|
if (rankdir !== 0) {
|
|
@@ -9776,13 +9873,14 @@ function bezierClipNode(sp, cx, cy, insideFn, leftInside) {
|
|
|
9776
9873
|
y: p.y + cy
|
|
9777
9874
|
}));
|
|
9778
9875
|
}
|
|
9876
|
+
function distFused(p, q) {
|
|
9877
|
+
const dx = p.x - q.x;
|
|
9878
|
+
const dy = p.y - q.y;
|
|
9879
|
+
return Math.sqrt(fma(dx, dx, dy * dy));
|
|
9880
|
+
}
|
|
9779
9881
|
function arrowEndClip(path4, arrowTip, elen) {
|
|
9780
|
-
if (elen <= 0) return path4;
|
|
9781
9882
|
const sp = [arrowTip, path4[2], path4[1], path4[0]];
|
|
9782
|
-
const
|
|
9783
|
-
const spRel = sp.map((p) => ({ x: p.x - arrowTip.x, y: p.y - arrowTip.y }));
|
|
9784
|
-
const clippedRel = bezierClipLocal(spRel, insideSphere, true);
|
|
9785
|
-
const clipped = clippedRel.map((p) => ({ x: p.x + arrowTip.x, y: p.y + arrowTip.y }));
|
|
9883
|
+
const clipped = elen > 0 ? bezierClipNode(sp, 0, 0, (x, y) => distFused({ x, y }, arrowTip) <= elen, true) : sp;
|
|
9786
9884
|
return [clipped[3], clipped[2], clipped[1], clipped[0]];
|
|
9787
9885
|
}
|
|
9788
9886
|
function arrowClipLength(arrowName, arrowsize, penwidth) {
|
|
@@ -11444,6 +11542,7 @@ function resetHtmlAnchorIds() {
|
|
|
11444
11542
|
anchorEnv.objLabel = null;
|
|
11445
11543
|
anchorEnv.imgscale = "false";
|
|
11446
11544
|
}
|
|
11545
|
+
registerRenderState(resetHtmlAnchorIds);
|
|
11447
11546
|
function initHtmlAnchor(data, box, renderer, job) {
|
|
11448
11547
|
if (data.href === void 0 && data.title === void 0 && data.target === void 0) {
|
|
11449
11548
|
return false;
|
|
@@ -12570,7 +12669,7 @@ function polyInit(n, g, measurer) {
|
|
|
12570
12669
|
const shapefile = nodeAttr(n, g, "shapefile");
|
|
12571
12670
|
n.info.shape = bindShape(shapeName2, shapefile);
|
|
12572
12671
|
if (shapefile !== void 0 && shapefile !== "" && shapeName2 !== "epsf") {
|
|
12573
|
-
|
|
12672
|
+
agwarningf(`No or improper shapefile="${shapefile}" for node "${n.name}"`, "error");
|
|
12574
12673
|
}
|
|
12575
12674
|
if (n.info.shape.kind === 2 /* SH_RECORD */) {
|
|
12576
12675
|
if (n.info.shape_info === void 0) recordNodeInit(n, g, measurer);
|
|
@@ -15196,6 +15295,9 @@ var COLOR_LIB = [
|
|
|
15196
15295
|
|
|
15197
15296
|
// src/common/color.ts
|
|
15198
15297
|
var colorScheme = "";
|
|
15298
|
+
registerRenderState(() => {
|
|
15299
|
+
colorScheme = "";
|
|
15300
|
+
});
|
|
15199
15301
|
function setColorScheme(scheme) {
|
|
15200
15302
|
colorScheme = scheme;
|
|
15201
15303
|
}
|
|
@@ -15325,18 +15427,28 @@ function setBlackOpaque(color, targetType) {
|
|
|
15325
15427
|
if (targetType === "rgba") setRgba(color, 0, 0, 0, 255);
|
|
15326
15428
|
else if (targetType === "hsva") setHsvaDirect(color, 0, 0, 0, 1);
|
|
15327
15429
|
}
|
|
15430
|
+
var SSCANF_SPACE = /* @__PURE__ */ new Set([" ", " ", "\n", "\v", "\f", "\r"]);
|
|
15431
|
+
function scanHexGroups(p, width2, max) {
|
|
15432
|
+
const out = [];
|
|
15433
|
+
if (p.charAt(0) !== "#") return out;
|
|
15434
|
+
let i = 1;
|
|
15435
|
+
while (out.length < max) {
|
|
15436
|
+
while (SSCANF_SPACE.has(p.charAt(i))) i++;
|
|
15437
|
+
let j = i;
|
|
15438
|
+
while (j < p.length && j - i < width2 && /[0-9a-fA-F]/.test(p.charAt(j))) j++;
|
|
15439
|
+
if (j === i) break;
|
|
15440
|
+
out.push(parseInt(p.slice(i, j), 16));
|
|
15441
|
+
i = j;
|
|
15442
|
+
}
|
|
15443
|
+
return out;
|
|
15444
|
+
}
|
|
15328
15445
|
function parseHexColor(p) {
|
|
15329
|
-
|
|
15330
|
-
|
|
15331
|
-
|
|
15332
|
-
|
|
15333
|
-
|
|
15334
|
-
|
|
15335
|
-
if (!m3) return null;
|
|
15336
|
-
const r = parseInt(m3[1], 16);
|
|
15337
|
-
const g = parseInt(m3[2], 16);
|
|
15338
|
-
const b = parseInt(m3[3], 16);
|
|
15339
|
-
return { r: r | r << 4, g: g | g << 4, b: b | b << 4, a: 255 };
|
|
15446
|
+
const g = scanHexGroups(p, 2, 4);
|
|
15447
|
+
if (g.length >= 3) return { r: g[0], g: g[1], b: g[2], a: g[3] ?? 255 };
|
|
15448
|
+
const short = p.length === 4 ? scanHexGroups(p, 1, 3) : [];
|
|
15449
|
+
if (short.length !== 3) return null;
|
|
15450
|
+
const [r, gg, b] = short;
|
|
15451
|
+
return { r: r | r << 4, g: gg | gg << 4, b: b | b << 4, a: 255 };
|
|
15340
15452
|
}
|
|
15341
15453
|
function clamp01(x) {
|
|
15342
15454
|
return Math.max(0, Math.min(1, x));
|
|
@@ -15382,6 +15494,17 @@ function colorxlate(str, color, targetType) {
|
|
|
15382
15494
|
return 1 /* ColorUnknown */;
|
|
15383
15495
|
}
|
|
15384
15496
|
|
|
15497
|
+
// src/common/emit-once.ts
|
|
15498
|
+
var seen = /* @__PURE__ */ new Set();
|
|
15499
|
+
registerRenderState(() => {
|
|
15500
|
+
seen.clear();
|
|
15501
|
+
});
|
|
15502
|
+
function emitOnce(str) {
|
|
15503
|
+
if (seen.has(str)) return false;
|
|
15504
|
+
seen.add(str);
|
|
15505
|
+
return true;
|
|
15506
|
+
}
|
|
15507
|
+
|
|
15385
15508
|
// src/render/color-resolve.ts
|
|
15386
15509
|
var SVG_KNOWN_COLORS = [
|
|
15387
15510
|
"aliceblue",
|
|
@@ -15534,12 +15657,33 @@ var SVG_KNOWN_COLORS = [
|
|
|
15534
15657
|
"yellowgreen"
|
|
15535
15658
|
];
|
|
15536
15659
|
var KNOWN_COLORS = new Set(SVG_KNOWN_COLORS);
|
|
15537
|
-
|
|
15660
|
+
var rendererColors = { hasKnownList: true };
|
|
15661
|
+
registerRenderState(() => {
|
|
15662
|
+
rendererColors.hasKnownList = true;
|
|
15663
|
+
});
|
|
15664
|
+
function setRendererKnownColors(hasList) {
|
|
15665
|
+
rendererColors.hasKnownList = hasList;
|
|
15666
|
+
}
|
|
15667
|
+
function firstColor(name) {
|
|
15668
|
+
const i = name.indexOf(":");
|
|
15669
|
+
return i < 0 ? name : name.slice(0, i);
|
|
15670
|
+
}
|
|
15671
|
+
function resolveRenderColor(raw, report = true) {
|
|
15538
15672
|
if (raw === "" || raw === "none") return { type: "none" };
|
|
15539
|
-
|
|
15673
|
+
const known = KNOWN_COLORS.has(raw.toLowerCase());
|
|
15674
|
+
if (known && (rendererColors.hasKnownList || !report)) return { type: "string", s: raw };
|
|
15540
15675
|
const color = { type: "rgba", r: 0, g: 0, b: 0, a: 0 };
|
|
15541
|
-
colorxlate(raw, color, "rgba");
|
|
15542
|
-
|
|
15676
|
+
const rc = colorxlate(raw, color, "rgba");
|
|
15677
|
+
if (report) reportColorxlate(raw, rc);
|
|
15678
|
+
return known ? { type: "string", s: raw } : color;
|
|
15679
|
+
}
|
|
15680
|
+
function reportColorxlate(name, rc) {
|
|
15681
|
+
if (rc === 0 /* ColorOk */) return;
|
|
15682
|
+
if (rc === 1 /* ColorUnknown */) {
|
|
15683
|
+
if (emitOnce(`color ${name}`)) agwarningf(`${name} is not a known color.`);
|
|
15684
|
+
} else {
|
|
15685
|
+
agerrorf("error in colorxlate()");
|
|
15686
|
+
}
|
|
15543
15687
|
}
|
|
15544
15688
|
function withColorScheme(scheme, fn) {
|
|
15545
15689
|
const prev = getColorScheme();
|
|
@@ -15586,6 +15730,72 @@ function textFillAttrs(fontColor) {
|
|
|
15586
15730
|
if (byte < 255) out += ' fill-opacity="' + (byte / 255).toFixed(6) + '"';
|
|
15587
15731
|
return out;
|
|
15588
15732
|
}
|
|
15733
|
+
var DEFAULT_COLOR2 = "black";
|
|
15734
|
+
var SEG_EPS = 1e-5;
|
|
15735
|
+
function reportColorNames(names) {
|
|
15736
|
+
for (const name of names) resolveRenderColor(firstColor(name));
|
|
15737
|
+
}
|
|
15738
|
+
function countChar(s, ch) {
|
|
15739
|
+
return s.split(ch).length - 1;
|
|
15740
|
+
}
|
|
15741
|
+
function multicolorNames(color, arrows) {
|
|
15742
|
+
const { segs, error } = parseSegs(color);
|
|
15743
|
+
if (error === 1 || error === 2) return null;
|
|
15744
|
+
const out = [];
|
|
15745
|
+
const front = segs[0]?.color ?? null;
|
|
15746
|
+
for (const bz of arrows) {
|
|
15747
|
+
let endcolor = null;
|
|
15748
|
+
for (const seg2 of segs) {
|
|
15749
|
+
if (seg2.color === null) break;
|
|
15750
|
+
if (Math.abs(seg2.t) < SEG_EPS) continue;
|
|
15751
|
+
out.push(seg2.color);
|
|
15752
|
+
endcolor = seg2.color;
|
|
15753
|
+
}
|
|
15754
|
+
if (bz.sflag && front !== null) out.push(front);
|
|
15755
|
+
if (bz.eflag && endcolor !== null) out.push(endcolor);
|
|
15756
|
+
}
|
|
15757
|
+
return out;
|
|
15758
|
+
}
|
|
15759
|
+
function taperedNames(color, fillcolor, hasFill) {
|
|
15760
|
+
const pen = color === "" ? DEFAULT_COLOR2 : color;
|
|
15761
|
+
return hasFill ? [pen, fillcolor === "" ? DEFAULT_COLOR2 : fillcolor] : [pen];
|
|
15762
|
+
}
|
|
15763
|
+
function edgeGraphicsColors(spec) {
|
|
15764
|
+
const numc = countChar(spec.color, ":");
|
|
15765
|
+
let color = spec.color;
|
|
15766
|
+
if (countChar(color, ";") > 0 && numc > 0) {
|
|
15767
|
+
const multi = multicolorNames(color, spec.arrows);
|
|
15768
|
+
if (multi !== null) return multi;
|
|
15769
|
+
color = DEFAULT_COLOR2;
|
|
15770
|
+
}
|
|
15771
|
+
const hasFill = spec.fillcolor !== "";
|
|
15772
|
+
const early = hasFill ? [spec.fillcolor] : [];
|
|
15773
|
+
if (spec.tapered) return [...early, ...taperedNames(color, spec.fillcolor, hasFill)];
|
|
15774
|
+
if (numc > 0) return [...early, ...color.split(":").filter((c) => c !== "")];
|
|
15775
|
+
const fill = hasFill ? spec.fillcolor : color;
|
|
15776
|
+
if (color !== "") return [...early, color, fill];
|
|
15777
|
+
return [...early, DEFAULT_COLOR2, fill !== "" ? fill : DEFAULT_COLOR2];
|
|
15778
|
+
}
|
|
15779
|
+
function reportEdgeColors(e) {
|
|
15780
|
+
const spl = e.info.spl;
|
|
15781
|
+
if (!spl) return;
|
|
15782
|
+
const color = e.attrs.get("color") ?? "";
|
|
15783
|
+
reportColorNames(edgeGraphicsColors({
|
|
15784
|
+
color,
|
|
15785
|
+
fillcolor: e.attrs.get("fillcolor") ?? "",
|
|
15786
|
+
tapered: styleTokens2(e.attrs.get("style")).includes("tapered"),
|
|
15787
|
+
arrows: spl.list.map((bz) => ({ sflag: bz.sflag !== 0, eflag: bz.eflag !== 0 }))
|
|
15788
|
+
}));
|
|
15789
|
+
}
|
|
15790
|
+
function backgroundColors(bgcolor, truecolor) {
|
|
15791
|
+
let str = bgcolor !== void 0 && bgcolor !== "" ? bgcolor : "white";
|
|
15792
|
+
if (str === "transparent") {
|
|
15793
|
+
if (truecolor) return [];
|
|
15794
|
+
str = "white";
|
|
15795
|
+
}
|
|
15796
|
+
const stop = findStopColor(str);
|
|
15797
|
+
return stop === null ? [str, "transparent"] : [stop.fillColor, "transparent", stop.stopColor];
|
|
15798
|
+
}
|
|
15589
15799
|
|
|
15590
15800
|
// src/render/svg-multicolor.ts
|
|
15591
15801
|
var THIN_LINE = 0.5;
|
|
@@ -15946,20 +16156,36 @@ function applyClusterObjState(sg, job) {
|
|
|
15946
16156
|
if (job.obj === null) return false;
|
|
15947
16157
|
const obj = job.obj;
|
|
15948
16158
|
return withColorScheme(clusterAttr(sg, "colorscheme"), () => {
|
|
16159
|
+
const filled = applyClusterFill(obj, fillRes);
|
|
15949
16160
|
applyClusterPenState(obj, sg);
|
|
15950
|
-
|
|
15951
|
-
|
|
15952
|
-
return false;
|
|
15953
|
-
}
|
|
15954
|
-
if (fillRes.kind === "solid") {
|
|
15955
|
-
obj.fill = 1 /* Solid */;
|
|
15956
|
-
obj.fillColor = resolveRenderColor(fillRes.color);
|
|
15957
|
-
return true;
|
|
15958
|
-
}
|
|
15959
|
-
applyClusterGradient(obj, fillRes);
|
|
15960
|
-
return true;
|
|
16161
|
+
reportColorNames(stripedClusterColors(sg));
|
|
16162
|
+
return filled;
|
|
15961
16163
|
});
|
|
15962
16164
|
}
|
|
16165
|
+
function stripedClusterColors(sg) {
|
|
16166
|
+
const flags = parseStyleFlags(clusterStyle(sg));
|
|
16167
|
+
if (!flags.striped || flags.rounded) return [];
|
|
16168
|
+
const color = clusterAttr(sg, "color") ?? "";
|
|
16169
|
+
let fill = clusterAttr(sg, "fillcolor") || color;
|
|
16170
|
+
const bg = clusterAttr(sg, "bgcolor") ?? "";
|
|
16171
|
+
if ((!flags.filled || fill === "") && bg !== "") fill = bg;
|
|
16172
|
+
const { segs, error } = parseSegs(fill === "" ? "lightgrey" : fill);
|
|
16173
|
+
if (error === 1 || error === 2) return [];
|
|
16174
|
+
return segs.flatMap((seg2) => seg2.color !== null && seg2.t > 0 ? [seg2.color] : []);
|
|
16175
|
+
}
|
|
16176
|
+
function applyClusterFill(obj, fillRes) {
|
|
16177
|
+
if (fillRes.kind === "none") {
|
|
16178
|
+
obj.fill = 0 /* None */;
|
|
16179
|
+
return false;
|
|
16180
|
+
}
|
|
16181
|
+
if (fillRes.kind === "solid") {
|
|
16182
|
+
obj.fill = 1 /* Solid */;
|
|
16183
|
+
obj.fillColor = resolveRenderColor(fillRes.color);
|
|
16184
|
+
return true;
|
|
16185
|
+
}
|
|
16186
|
+
applyClusterGradient(obj, fillRes);
|
|
16187
|
+
return true;
|
|
16188
|
+
}
|
|
15963
16189
|
|
|
15964
16190
|
// src/render/svg-id.ts
|
|
15965
16191
|
function svgClass(kind, classAttr) {
|
|
@@ -16047,6 +16273,7 @@ function renderPeripheries(poly, coord, filled, ctx) {
|
|
|
16047
16273
|
}
|
|
16048
16274
|
function renderLabel(label, coord, renderer, job) {
|
|
16049
16275
|
if (label.u.kind !== "txt" || label.u.nspans < 1) return;
|
|
16276
|
+
reportColorNames([label.fontcolor]);
|
|
16050
16277
|
label.pos = coord;
|
|
16051
16278
|
label.set = true;
|
|
16052
16279
|
const VALIGN_TOP2 = "t".charCodeAt(0);
|
|
@@ -16066,6 +16293,7 @@ function renderNodeLabel(n, coord, renderer, job) {
|
|
|
16066
16293
|
label.pos = coord;
|
|
16067
16294
|
label.set = true;
|
|
16068
16295
|
const html = label.u.html;
|
|
16296
|
+
reportColorNames(htmlLabelColors(html));
|
|
16069
16297
|
withLabelEmitState(job, () => emitHtmlLabel(html, coord, renderer, job));
|
|
16070
16298
|
} else {
|
|
16071
16299
|
renderLabel(label, coord, renderer, job);
|
|
@@ -16145,8 +16373,13 @@ function applyPenState(obj, styleAttr, colorAttr, penwidthAttr) {
|
|
|
16145
16373
|
function applyNodeStyle(obj, n, job) {
|
|
16146
16374
|
const styleAttr = nodeAttr(n, n.root, "style");
|
|
16147
16375
|
const colorAttr = nodeAttr(n, n.root, "color");
|
|
16376
|
+
const penwidth = nodeAttr(n, n.root, "penwidth");
|
|
16377
|
+
if (n.info.shape?.kind === 2 /* SH_RECORD */) {
|
|
16378
|
+
applyPenState(obj, styleAttr, colorAttr, penwidth);
|
|
16379
|
+
return applyFillState(obj, n, job);
|
|
16380
|
+
}
|
|
16148
16381
|
const filled = applyFillState(obj, n, job);
|
|
16149
|
-
applyPenState(obj, styleAttr, colorAttr,
|
|
16382
|
+
applyPenState(obj, styleAttr, colorAttr, penwidth);
|
|
16150
16383
|
return filled;
|
|
16151
16384
|
}
|
|
16152
16385
|
function prepareDrawPoly(poly, filled, obj) {
|
|
@@ -16426,6 +16659,9 @@ function decompSearch(g, start, cmark) {
|
|
|
16426
16659
|
}
|
|
16427
16660
|
}
|
|
16428
16661
|
var _dc = { cmark: 0 };
|
|
16662
|
+
registerRenderState(() => {
|
|
16663
|
+
_dc.cmark = 0;
|
|
16664
|
+
});
|
|
16429
16665
|
function resolveNode(n, pass) {
|
|
16430
16666
|
if (pass > 0) {
|
|
16431
16667
|
const subg = n.info.clust;
|
|
@@ -16658,6 +16894,9 @@ function makeInterclustChain(from, to, orig) {
|
|
|
16658
16894
|
|
|
16659
16895
|
// src/layout/dot/mincross-cross.ts
|
|
16660
16896
|
var reMincross = false;
|
|
16897
|
+
registerRenderState(() => {
|
|
16898
|
+
reMincross = false;
|
|
16899
|
+
});
|
|
16661
16900
|
function setReMincross(b) {
|
|
16662
16901
|
reMincross = b;
|
|
16663
16902
|
}
|
|
@@ -17174,6 +17413,9 @@ function allocateRanks(g) {
|
|
|
17174
17413
|
g.info.rank = rt;
|
|
17175
17414
|
}
|
|
17176
17415
|
var fillSeq = 0;
|
|
17416
|
+
registerRenderState(() => {
|
|
17417
|
+
fillSeq = 0;
|
|
17418
|
+
});
|
|
17177
17419
|
function makeFillNode(sg, rank3, seq2) {
|
|
17178
17420
|
const n = agnode(sg, `__fill_${rank3}_${seq2}`, true);
|
|
17179
17421
|
agsubnode(sg, n, true);
|
|
@@ -17531,7 +17773,7 @@ function pruneForeignClusterNodes(par, clust) {
|
|
|
17531
17773
|
}
|
|
17532
17774
|
function markClusterNode(clust, n, g) {
|
|
17533
17775
|
if ((n.info.ranktype ?? 0) !== 0) {
|
|
17534
|
-
|
|
17776
|
+
agwarningf(`${n.name} was already in a rankset, deleted from cluster ${g.name}`, "error");
|
|
17535
17777
|
agDeleteFromCluster(clust, n);
|
|
17536
17778
|
return;
|
|
17537
17779
|
}
|
|
@@ -18110,7 +18352,7 @@ function findCharset(g) {
|
|
|
18110
18352
|
}
|
|
18111
18353
|
if (p === "big-5" || p === "big5") return CHAR_BIG5;
|
|
18112
18354
|
if (p === "utf-8" || p === "utf8") return CHAR_UTF8;
|
|
18113
|
-
|
|
18355
|
+
agwarningf(`Unsupported charset "${raw}" - assuming utf-8`, "error");
|
|
18114
18356
|
return CHAR_UTF8;
|
|
18115
18357
|
}
|
|
18116
18358
|
function maptoken(p, names, vals) {
|
|
@@ -19759,7 +20001,7 @@ function advanceTmpList(tmplist, offlist) {
|
|
|
19759
20001
|
// src/render/svg-parallel-edge.ts
|
|
19760
20002
|
var PENWIDTH_NORMAL2 = 1;
|
|
19761
20003
|
var PENWIDTH_THRESHOLD2 = 5e-3;
|
|
19762
|
-
var
|
|
20004
|
+
var DEFAULT_COLOR3 = "black";
|
|
19763
20005
|
function emitOffsetBezier(tmplist, job, color) {
|
|
19764
20006
|
const obj = job.obj;
|
|
19765
20007
|
const resolved = resolveRenderColor(color);
|
|
@@ -19801,11 +20043,11 @@ function emitParallelEdgePaths(e, job, colorList) {
|
|
|
19801
20043
|
const spl = e.info.spl;
|
|
19802
20044
|
const numc = (colorList.match(/:/g) ?? []).length;
|
|
19803
20045
|
const segData = buildSegData(spl?.list ?? [], (2 + numc) / 2);
|
|
19804
|
-
const colors = parseSegs(colorList).segs.map((s) => s.color ??
|
|
20046
|
+
const colors = parseSegs(colorList).segs.map((s) => s.color ?? DEFAULT_COLOR3);
|
|
19805
20047
|
emitColorPasses(segData, colors, job);
|
|
19806
20048
|
return {
|
|
19807
|
-
headColor: colors[0] ??
|
|
19808
|
-
tailColor: colors[1] ?? colors[0] ??
|
|
20049
|
+
headColor: colors[0] ?? DEFAULT_COLOR3,
|
|
20050
|
+
tailColor: colors[1] ?? colors[0] ?? DEFAULT_COLOR3
|
|
19809
20051
|
};
|
|
19810
20052
|
}
|
|
19811
20053
|
|
|
@@ -20317,7 +20559,6 @@ function beginAnchorIf(renderer, job) {
|
|
|
20317
20559
|
}
|
|
20318
20560
|
var DFLT_SAMPLE = 20;
|
|
20319
20561
|
var MAP_HW = 2;
|
|
20320
|
-
var MAP_SMALL = 1e-10;
|
|
20321
20562
|
function mapTransform(p, ctx) {
|
|
20322
20563
|
return {
|
|
20323
20564
|
x: (p.x + ctx.pad.x - ctx.bb.ll.x) * ctx.scale + ctx.marginOff.x,
|
|
@@ -20434,16 +20675,8 @@ function computeLabelRectMap(lab, obj, ctx) {
|
|
|
20434
20675
|
mapTransform({ x: lab.pos.x + dx, y: lab.pos.y + dy }, ctx)
|
|
20435
20676
|
];
|
|
20436
20677
|
}
|
|
20437
|
-
function ptToLine22(a, b, p) {
|
|
20438
|
-
const dx = b.x - a.x;
|
|
20439
|
-
const dy = b.y - a.y;
|
|
20440
|
-
let a2 = (p.y - a.y) * dx - (p.x - a.x) * dy;
|
|
20441
|
-
a2 *= a2;
|
|
20442
|
-
if (a2 < MAP_SMALL) return 0;
|
|
20443
|
-
return a2 / (dx * dx + dy * dy);
|
|
20444
|
-
}
|
|
20445
20678
|
function checkControlPoints2(cp) {
|
|
20446
|
-
return
|
|
20679
|
+
return ptToLine2(cp[0], cp[3], cp[1]) < MAP_HW * MAP_HW && ptToLine2(cp[0], cp[3], cp[2]) < MAP_HW * MAP_HW;
|
|
20447
20680
|
}
|
|
20448
20681
|
function bezierHalf(v) {
|
|
20449
20682
|
const left2 = [];
|
|
@@ -20678,9 +20911,20 @@ function labelSpanX(lp, just) {
|
|
|
20678
20911
|
if (just === "r") return lp.pos.x + lp.space.x / 2;
|
|
20679
20912
|
return lp.pos.x;
|
|
20680
20913
|
}
|
|
20914
|
+
function labelColorNames(lp) {
|
|
20915
|
+
if (lp.html) return lp.u.kind === "html" ? htmlLabelColors(lp.u.html) : [];
|
|
20916
|
+
return lp.u.kind === "txt" && lp.u.nspans >= 1 ? [lp.fontcolor] : [];
|
|
20917
|
+
}
|
|
20918
|
+
function reportEdgeLabelColors(e) {
|
|
20919
|
+
const labels = [e.info.label, e.info.xlabel, e.info.head_label, e.info.tail_label];
|
|
20920
|
+
for (const lp of labels) {
|
|
20921
|
+
if (lp?.set) reportColorNames(labelColorNames(lp));
|
|
20922
|
+
}
|
|
20923
|
+
}
|
|
20681
20924
|
function renderOneLabel(lp, renderer, job, requireSet = true) {
|
|
20682
20925
|
if (!lp) return;
|
|
20683
20926
|
if (requireSet && !lp.set) return;
|
|
20927
|
+
reportColorNames(labelColorNames(lp));
|
|
20684
20928
|
if (lp.html) {
|
|
20685
20929
|
if (lp.u.kind === "html") {
|
|
20686
20930
|
const html = lp.u.html;
|
|
@@ -20789,7 +21033,7 @@ function setEdgePen(e, job) {
|
|
|
20789
21033
|
const flags = parseStyleFlags(e.attrs.get("style"));
|
|
20790
21034
|
obj.penColor = withColorScheme(
|
|
20791
21035
|
e.attrs.get("colorscheme"),
|
|
20792
|
-
() => resolveRenderColor(resolvePenColor(e.attrs.get("color")))
|
|
21036
|
+
() => resolveRenderColor(resolvePenColor(e.attrs.get("color")), false)
|
|
20793
21037
|
);
|
|
20794
21038
|
obj.pen = resolvePenType(flags);
|
|
20795
21039
|
obj.penWidth = resolvePenWidth(flags, e.attrs.get("penwidth"));
|
|
@@ -20808,6 +21052,8 @@ function renderEdge(e, renderer, job) {
|
|
|
20808
21052
|
resolveEdgeAnchor(e, svgEdgeId(e, job), obj);
|
|
20809
21053
|
withColorScheme(e.attrs.get("colorscheme"), () => {
|
|
20810
21054
|
renderer.beginEdge(e, job);
|
|
21055
|
+
reportEdgeColors(e);
|
|
21056
|
+
reportEdgeLabelColors(e);
|
|
20811
21057
|
renderer.endEdge(e, job);
|
|
20812
21058
|
});
|
|
20813
21059
|
} finally {
|
|
@@ -20891,8 +21137,11 @@ function renderPage(g, renderer, job, info) {
|
|
|
20891
21137
|
resolveObjAnchor(g, labelTextOf2(g.info.label), svgGraphId(g, job), job.obj);
|
|
20892
21138
|
}
|
|
20893
21139
|
const anchored = beginAnchorIf(renderer, job);
|
|
20894
|
-
|
|
20895
|
-
|
|
21140
|
+
withColorScheme(g.attrs.get("colorscheme"), () => {
|
|
21141
|
+
reportColorNames(backgroundColors(g.attrs.get("bgcolor"), renderer.type === "svg"));
|
|
21142
|
+
renderer.pageBackground?.(g, job);
|
|
21143
|
+
renderGraphLabel(g, renderer, job);
|
|
21144
|
+
});
|
|
20896
21145
|
if (anchored) renderer.endAnchor?.(job);
|
|
20897
21146
|
const clustersLast = (job.flags & EMIT_CLUSTERS_LAST) !== 0;
|
|
20898
21147
|
if (!clustersLast) renderClusters(g, renderer, job);
|
|
@@ -20924,6 +21173,7 @@ function render(ctx, g, format, inlineImages = false) {
|
|
|
20924
21173
|
job.scale = { x: z * dpiScale, y: z * dpiScale };
|
|
20925
21174
|
job.rotation = parseLandscape(g) ? 90 : 0;
|
|
20926
21175
|
job.renderer = renderer;
|
|
21176
|
+
setRendererKnownColors(renderer.type === "svg");
|
|
20927
21177
|
resetHtmlAnchorIds();
|
|
20928
21178
|
for (const n of g.nodes.values()) polyInit(n, g, job.measurer);
|
|
20929
21179
|
return renderGraph(g, job, renderer);
|
|
@@ -20992,6 +21242,7 @@ function htmlFillPenWidth() {
|
|
|
20992
21242
|
function resetHtmlFillPenWidth() {
|
|
20993
21243
|
htmlFillPen = 1;
|
|
20994
21244
|
}
|
|
21245
|
+
registerRenderState(resetHtmlFillPenWidth);
|
|
20995
21246
|
function penTypeOf(style2) {
|
|
20996
21247
|
const st = htmlStyle(style2);
|
|
20997
21248
|
if (st.dashed) return 1 /* Dashed */;
|
|
@@ -21120,9 +21371,34 @@ function emitSidedPolylines(sides2, corners, renderer, job) {
|
|
|
21120
21371
|
renderer.polyline(seq2.map((i) => corners[i]), job);
|
|
21121
21372
|
}
|
|
21122
21373
|
}
|
|
21374
|
+
var HTML_DEFAULT_COLOR = "black";
|
|
21375
|
+
function bgNames(bgcolor) {
|
|
21376
|
+
const spec = parseGradientSpec(bgcolor);
|
|
21377
|
+
return spec === null ? [bgcolor] : [spec[0], spec[1]];
|
|
21378
|
+
}
|
|
21379
|
+
function cellNames(cell2) {
|
|
21380
|
+
if (htmlStyle(cell2.style).invisible) return [];
|
|
21381
|
+
const out = cell2.bgcolor !== void 0 ? bgNames(cell2.bgcolor) : [];
|
|
21382
|
+
if (cell2.border > 0) out.push(cell2.color ?? HTML_DEFAULT_COLOR);
|
|
21383
|
+
if (cell2.nested !== void 0) out.push(...tableNames(cell2.nested));
|
|
21384
|
+
else for (const line of cell2.lines) if (line.fontColor !== null) out.push(line.fontColor);
|
|
21385
|
+
return out;
|
|
21386
|
+
}
|
|
21387
|
+
function tableNames(tbl) {
|
|
21388
|
+
if (htmlStyle(tbl.style).invisible) return [];
|
|
21389
|
+
const out = tbl.bgcolor !== void 0 ? bgNames(tbl.bgcolor) : [];
|
|
21390
|
+
const color = tbl.color ?? HTML_DEFAULT_COLOR;
|
|
21391
|
+
if (tbl.cells.some((c) => c.vruled === true || c.hruled === true)) out.push(color);
|
|
21392
|
+
if (tbl.border > 0) out.push(color);
|
|
21393
|
+
for (const cell2 of tbl.cells) out.push(...cellNames(cell2));
|
|
21394
|
+
return out;
|
|
21395
|
+
}
|
|
21396
|
+
function htmlLabelColors(label) {
|
|
21397
|
+
return [label.color ?? HTML_DEFAULT_COLOR, ...tableNames(label)];
|
|
21398
|
+
}
|
|
21123
21399
|
|
|
21124
21400
|
// src/common/style-resolve.ts
|
|
21125
|
-
var
|
|
21401
|
+
var DEFAULT_COLOR4 = "black";
|
|
21126
21402
|
var DEFAULT_FILL = "lightgrey";
|
|
21127
21403
|
var PENWIDTH_BOLD2 = 2;
|
|
21128
21404
|
var TOKEN_FLAG = {
|
|
@@ -21238,7 +21514,7 @@ function resolvePenWidth(flags, penwidthAttr) {
|
|
|
21238
21514
|
return 1;
|
|
21239
21515
|
}
|
|
21240
21516
|
function resolvePenColor(colorAttr) {
|
|
21241
|
-
if (!colorAttr || colorAttr.length === 0) return
|
|
21517
|
+
if (!colorAttr || colorAttr.length === 0) return DEFAULT_COLOR4;
|
|
21242
21518
|
return firstSolidColor(colorAttr);
|
|
21243
21519
|
}
|
|
21244
21520
|
function clusterColorAttrs(attrs) {
|
|
@@ -21264,7 +21540,7 @@ function findStopColor(colorlist) {
|
|
|
21264
21540
|
const seg1 = segs[1];
|
|
21265
21541
|
if (seg0.color === null) return null;
|
|
21266
21542
|
const fillColor = seg0.color;
|
|
21267
|
-
const stopColor = seg1.color ??
|
|
21543
|
+
const stopColor = seg1.color ?? DEFAULT_COLOR4;
|
|
21268
21544
|
const frac = seg0.hasFraction ? seg0.t : seg1.hasFraction ? 1 - seg1.t : 0;
|
|
21269
21545
|
return { fillColor, stopColor, frac };
|
|
21270
21546
|
}
|
|
@@ -23932,6 +24208,9 @@ var clType = LOCAL;
|
|
|
23932
24208
|
function setClType(t) {
|
|
23933
24209
|
clType = t;
|
|
23934
24210
|
}
|
|
24211
|
+
registerRenderState(() => {
|
|
24212
|
+
clType = LOCAL;
|
|
24213
|
+
});
|
|
23935
24214
|
function mapbool2(s) {
|
|
23936
24215
|
if (!s || s === "") return false;
|
|
23937
24216
|
const l = s.toLowerCase();
|
|
@@ -25515,20 +25794,20 @@ function fillRankVlist(g, r, root) {
|
|
|
25515
25794
|
const rankArr = g.info.rank;
|
|
25516
25795
|
const lead = g.info.rankleader[r];
|
|
25517
25796
|
if (lead === void 0 || lead === null) {
|
|
25518
|
-
|
|
25797
|
+
agerrorf(`rebuild_vlists: lead is null for rank ${r}`);
|
|
25519
25798
|
return -1;
|
|
25520
25799
|
}
|
|
25521
25800
|
const rootRank = root.info.rank[r];
|
|
25522
25801
|
if (rootRank.v[lead.info.order ?? 0] !== lead) {
|
|
25523
|
-
|
|
25524
|
-
`
|
|
25802
|
+
agerrorf(
|
|
25803
|
+
`rebuild_vlists: rank lead ${lead.name} not in order ${lead.info.order ?? 0} of rank ${r}`
|
|
25525
25804
|
);
|
|
25526
25805
|
return -1;
|
|
25527
25806
|
}
|
|
25528
25807
|
rankArr[r].v = rootRank.v;
|
|
25529
25808
|
rankArr[r].vStart = lead.info.order ?? 0;
|
|
25530
25809
|
const maxi = computeMaxi(g, r);
|
|
25531
|
-
if (maxi === -1)
|
|
25810
|
+
if (maxi === -1) agwarningf(`degenerate concentrated rank ${g.name},${r}`, "error");
|
|
25532
25811
|
rankArr[r].n = maxi + 1;
|
|
25533
25812
|
return 0;
|
|
25534
25813
|
}
|
|
@@ -25617,7 +25896,7 @@ function dotConcentrate(g) {
|
|
|
25617
25896
|
const clust = g.info.clust ?? [];
|
|
25618
25897
|
for (let c = 0; c < nCluster; c++) {
|
|
25619
25898
|
if (rebuildVlists(clust[c]) !== 0) {
|
|
25620
|
-
|
|
25899
|
+
agerr("prev", "concentrate=true may not work correctly.");
|
|
25621
25900
|
return -1;
|
|
25622
25901
|
}
|
|
25623
25902
|
}
|
|
@@ -28347,7 +28626,7 @@ function routeSplinesInternal(pp, polyline) {
|
|
|
28347
28626
|
];
|
|
28348
28627
|
const pl = shortestPath(poly, eps);
|
|
28349
28628
|
if (pl === null) {
|
|
28350
|
-
|
|
28629
|
+
agerrLineOn("warn", "in routesplines, Pshortestpath failed");
|
|
28351
28630
|
return null;
|
|
28352
28631
|
}
|
|
28353
28632
|
emitDump("S3_POLY", dumpNames, () => ({
|
|
@@ -30666,6 +30945,10 @@ function addXLabels(gp) {
|
|
|
30666
30945
|
var IGNORED_EDGE = 6;
|
|
30667
30946
|
var Rankdir = 0;
|
|
30668
30947
|
var Offset = { x: 0, y: 0 };
|
|
30948
|
+
registerRenderState(() => {
|
|
30949
|
+
Rankdir = 0;
|
|
30950
|
+
Offset = { x: 0, y: 0 };
|
|
30951
|
+
});
|
|
30669
30952
|
function mapPoint(p) {
|
|
30670
30953
|
const r = ccwrotatepf(p, Rankdir * 90);
|
|
30671
30954
|
return { x: r.x - Offset.x, y: r.y - Offset.y };
|
|
@@ -30753,7 +31036,7 @@ function translateDrawing(g) {
|
|
|
30753
31036
|
if (e.tail !== v) continue;
|
|
30754
31037
|
if (e.info.spl === void 0) {
|
|
30755
31038
|
if (!(g.info.concentrate ?? false) && (e.info.edge_type ?? 0) !== IGNORED_EDGE) {
|
|
30756
|
-
|
|
31039
|
+
agerrLineOn("warn", `lost ${e.tail.name} ${e.head.name} edge`);
|
|
30757
31040
|
}
|
|
30758
31041
|
continue;
|
|
30759
31042
|
}
|
|
@@ -31866,7 +32149,11 @@ var A = BigInt("0x5deece66d");
|
|
|
31866
32149
|
var C = BigInt("0xb");
|
|
31867
32150
|
var MASK48 = (1n << 48n) - 1n;
|
|
31868
32151
|
var TWO48 = 2 ** 48;
|
|
31869
|
-
var
|
|
32152
|
+
var UNSEEDED_STATE = 0x1234abcd330en;
|
|
32153
|
+
var state = UNSEEDED_STATE;
|
|
32154
|
+
registerRenderState(() => {
|
|
32155
|
+
state = UNSEEDED_STATE;
|
|
32156
|
+
});
|
|
31870
32157
|
function srand48(seed) {
|
|
31871
32158
|
const s = BigInt(Math.trunc(seed)) & 0xffffffffn;
|
|
31872
32159
|
state = (s << 16n | 0x330en) & MASK48;
|
|
@@ -34053,7 +34340,8 @@ function ensureDummyNodes(sg, gstart) {
|
|
|
34053
34340
|
}
|
|
34054
34341
|
function orthoEdges(g, useLbls, clipAndInstall2) {
|
|
34055
34342
|
if (useLbls) {
|
|
34056
|
-
|
|
34343
|
+
agerrLineOn(
|
|
34344
|
+
"warn",
|
|
34057
34345
|
"Orthogonal edges do not currently handle edge labels. Try using xlabels.\n"
|
|
34058
34346
|
);
|
|
34059
34347
|
useLbls = false;
|
|
@@ -34413,12 +34701,12 @@ function origSeq(e) {
|
|
|
34413
34701
|
return resolveOrigEdge(e).seq;
|
|
34414
34702
|
}
|
|
34415
34703
|
function dedupByOrig(group) {
|
|
34416
|
-
const
|
|
34704
|
+
const seen2 = /* @__PURE__ */ new Set();
|
|
34417
34705
|
const out = [];
|
|
34418
34706
|
for (const e of group) {
|
|
34419
34707
|
const o = resolveOrigEdge(e);
|
|
34420
|
-
if (
|
|
34421
|
-
|
|
34708
|
+
if (seen2.has(o)) continue;
|
|
34709
|
+
seen2.add(o);
|
|
34422
34710
|
out.push(o);
|
|
34423
34711
|
}
|
|
34424
34712
|
return out;
|
|
@@ -34735,7 +35023,7 @@ function orthoDispatch(g) {
|
|
|
34735
35023
|
function curvedTop(g) {
|
|
34736
35024
|
resetRW(g);
|
|
34737
35025
|
if (((g.root.info.has_labels ?? 0) & EDGE_LABEL) !== 0) {
|
|
34738
|
-
|
|
35026
|
+
agerrLineOn("warn", "edge labels with splines=curved not supported in dot - use xlabels\n");
|
|
34739
35027
|
}
|
|
34740
35028
|
}
|
|
34741
35029
|
function finalizeSplines(g, et, normalize) {
|
|
@@ -36383,7 +36671,7 @@ function lenattr(ep, g) {
|
|
|
36383
36671
|
const val2 = /^\s*[+-]?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?/.exec(s);
|
|
36384
36672
|
const len = val2 === null ? Number.NaN : parseFloat(val2[0]);
|
|
36385
36673
|
if (Number.isNaN(len) || len < 0 || len === 0) {
|
|
36386
|
-
|
|
36674
|
+
agerrLineOn("warn", `bad edge len "${s}" in ${g.name} - setting to ${DEFAULT_EDGE_LEN.toFixed(2)}`);
|
|
36387
36675
|
return DEFAULT_EDGE_LEN;
|
|
36388
36676
|
}
|
|
36389
36677
|
return len;
|
|
@@ -36480,7 +36768,10 @@ var START_KEYWORDS = [
|
|
|
36480
36768
|
];
|
|
36481
36769
|
var WARN_POS_IGNORED = "node positions are ignored unless start=random";
|
|
36482
36770
|
var WARN_SELF_IGNORED = "start=0 not supported with mode=self - ignored";
|
|
36483
|
-
var
|
|
36771
|
+
var selfOnce = { warned: false };
|
|
36772
|
+
registerRenderState(() => {
|
|
36773
|
+
selfOnce.warned = false;
|
|
36774
|
+
});
|
|
36484
36775
|
var circuitWarned = /* @__PURE__ */ new WeakSet();
|
|
36485
36776
|
function parseStart(p, dflt) {
|
|
36486
36777
|
let init = dflt;
|
|
@@ -36511,7 +36802,7 @@ function initRegular(g, nG) {
|
|
|
36511
36802
|
function checkStart(g, nG = g.nodes.size, dflt = INIT_RANDOM) {
|
|
36512
36803
|
const { init, seed } = parseStart(g.root.attrs.get("start"), dflt);
|
|
36513
36804
|
if (init !== INIT_RANDOM && [...g.nodes.values()].some((n) => n.attrs.has("pos"))) {
|
|
36514
|
-
|
|
36805
|
+
agerrLineOn("warn", WARN_POS_IGNORED);
|
|
36515
36806
|
}
|
|
36516
36807
|
if (init === INIT_REGULAR) initRegular(g, nG);
|
|
36517
36808
|
srand48(seed);
|
|
@@ -36544,7 +36835,7 @@ function neatoMode(g) {
|
|
|
36544
36835
|
if (str === void 0 || str === "") return MODE_MAJOR;
|
|
36545
36836
|
const mode = modeByName().get(str);
|
|
36546
36837
|
if (mode !== void 0) return mode;
|
|
36547
|
-
|
|
36838
|
+
agerrLineOn("warn", `Illegal value ${str} for attribute "mode" in graph ${g.root.name} - ignored`);
|
|
36548
36839
|
return MODE_MAJOR;
|
|
36549
36840
|
}
|
|
36550
36841
|
function checkMode(g, mode) {
|
|
@@ -36558,9 +36849,9 @@ function checkStartAttr(g, mode) {
|
|
|
36558
36849
|
const value = g.root.attrs.get("start");
|
|
36559
36850
|
if (parseStart(value, INIT_RANDOM).init !== INIT_SELF) return;
|
|
36560
36851
|
if (mode === MODE_MAJOR || mode === MODE_IPSEP) unsupported("start", value ?? "", "smart initialisation");
|
|
36561
|
-
if ((mode === MODE_KK || mode === MODE_SGD) && !
|
|
36562
|
-
|
|
36563
|
-
|
|
36852
|
+
if ((mode === MODE_KK || mode === MODE_SGD) && !selfOnce.warned) {
|
|
36853
|
+
selfOnce.warned = true;
|
|
36854
|
+
agerrLineOn("warn", WARN_SELF_IGNORED);
|
|
36564
36855
|
}
|
|
36565
36856
|
}
|
|
36566
36857
|
function isConnected(g) {
|
|
@@ -36571,15 +36862,15 @@ function isConnected(g) {
|
|
|
36571
36862
|
adj.get(e.tail)?.push(e.head);
|
|
36572
36863
|
adj.get(e.head)?.push(e.tail);
|
|
36573
36864
|
}
|
|
36574
|
-
const
|
|
36865
|
+
const seen2 = /* @__PURE__ */ new Set([nodes[0]]);
|
|
36575
36866
|
const stack = [nodes[0]];
|
|
36576
36867
|
for (let n = stack.pop(); n !== void 0; n = stack.pop()) {
|
|
36577
|
-
for (const m of adj.get(n) ?? []) if (!
|
|
36578
|
-
|
|
36868
|
+
for (const m of adj.get(n) ?? []) if (!seen2.has(m)) {
|
|
36869
|
+
seen2.add(m);
|
|
36579
36870
|
stack.push(m);
|
|
36580
36871
|
}
|
|
36581
36872
|
}
|
|
36582
|
-
return
|
|
36873
|
+
return seen2.size === nodes.length;
|
|
36583
36874
|
}
|
|
36584
36875
|
function kkCircuitFallsBack(g) {
|
|
36585
36876
|
const packed = getPack(g.root, -1, 0) >= 0 || (g.root.attrs.get("packmode") ?? "") !== "";
|
|
@@ -36588,7 +36879,8 @@ function kkCircuitFallsBack(g) {
|
|
|
36588
36879
|
function warnCircuitDisconnected(g) {
|
|
36589
36880
|
if (circuitWarned.has(g.root)) return;
|
|
36590
36881
|
circuitWarned.add(g.root);
|
|
36591
|
-
|
|
36882
|
+
agerrLineOn(
|
|
36883
|
+
"warn",
|
|
36592
36884
|
`graph ${g.root.name} is disconnected. Hence, the circuit model
|
|
36593
36885
|
is undefined. Reverting to the shortest path model.
|
|
36594
36886
|
Alternatively, consider running neato using -Gpack=true or decomposing
|
|
@@ -36807,13 +37099,15 @@ function buildUnfixed(g, n) {
|
|
|
36807
37099
|
}
|
|
36808
37100
|
function resolveModel(model) {
|
|
36809
37101
|
if (model === MODEL_CIRCUIT2) {
|
|
36810
|
-
|
|
37102
|
+
agerrLineOn(
|
|
37103
|
+
"warn",
|
|
36811
37104
|
"circuit model not yet supported in Gmode=sgd, reverting to shortpath model"
|
|
36812
37105
|
);
|
|
36813
37106
|
return MODEL_SHORTPATH;
|
|
36814
37107
|
}
|
|
36815
37108
|
if (model === MODEL_MDS) {
|
|
36816
|
-
|
|
37109
|
+
agerrLineOn(
|
|
37110
|
+
"warn",
|
|
36817
37111
|
"mds model not yet supported in Gmode=sgd, reverting to shortpath model"
|
|
36818
37112
|
);
|
|
36819
37113
|
return MODEL_SHORTPATH;
|
|
@@ -37198,7 +37492,7 @@ function moveNode(st, m) {
|
|
|
37198
37492
|
function solveModel(g, st) {
|
|
37199
37493
|
for (let m = chooseNode(st); m >= 0; m = chooseNode(st)) moveNode(st, m);
|
|
37200
37494
|
if (st.move === st.maxIter) {
|
|
37201
|
-
|
|
37495
|
+
agerrLineOn("warn", `Max. iterations (${st.maxIter}) reached on graph ${g.name}`);
|
|
37202
37496
|
}
|
|
37203
37497
|
}
|
|
37204
37498
|
function mdsEdges(g, nodes, lens) {
|
|
@@ -37657,6 +37951,7 @@ var MODE_MAJOR = 1;
|
|
|
37657
37951
|
var MODE_HIER = 2;
|
|
37658
37952
|
var MODE_IPSEP = 3;
|
|
37659
37953
|
var MODE_SGD = 4;
|
|
37954
|
+
var SGD_ITERATIONS = 30;
|
|
37660
37955
|
var MODEL_SHORTPATH2 = 0;
|
|
37661
37956
|
var MODEL_CIRCUIT = 1;
|
|
37662
37957
|
var MODEL_SUBSET = 2;
|
|
@@ -37696,6 +37991,11 @@ function assignNodeIds2(g) {
|
|
|
37696
37991
|
}
|
|
37697
37992
|
return nodeList;
|
|
37698
37993
|
}
|
|
37994
|
+
function neatoMaxIter(maxiter, mode, n) {
|
|
37995
|
+
if (maxiter !== void 0) return parseInt(maxiter, 10) || 0;
|
|
37996
|
+
if (mode === MODE_MAJOR) return DFLT_ITERATIONS;
|
|
37997
|
+
return mode === MODE_SGD ? SGD_ITERATIONS : 100 * n;
|
|
37998
|
+
}
|
|
37699
37999
|
function runMajorization(g, mode, model) {
|
|
37700
38000
|
void model;
|
|
37701
38001
|
const nodeList = assignNodeIds2(g);
|
|
@@ -37703,7 +38003,7 @@ function runMajorization(g, mode, model) {
|
|
|
37703
38003
|
const haveLen = graphHasLen(g);
|
|
37704
38004
|
const vtx = makeGraphDataC(g, nodeList, haveLen, mode === MODE_HIER || mode === MODE_IPSEP);
|
|
37705
38005
|
checkStart(g);
|
|
37706
|
-
const maxi =
|
|
38006
|
+
const maxi = neatoMaxIter(g.attrs.get("maxiter"), mode, n);
|
|
37707
38007
|
const epsilon = lateDouble(g.attrs.get("epsilon"), 1e-4, 0);
|
|
37708
38008
|
const weighted = haveLen && mode !== MODE_IPSEP;
|
|
37709
38009
|
const Dij = weighted ? computeWeightedApspPacked2(vtx, n) : computeApspPacked2(vtx, n);
|
|
@@ -37733,18 +38033,18 @@ function makeGraphDataC(g, nodeList, haveLen, haveDir) {
|
|
|
37733
38033
|
for (const np of nodeList) {
|
|
37734
38034
|
const i = np.info.id;
|
|
37735
38035
|
const entry = vtx[i];
|
|
37736
|
-
const
|
|
38036
|
+
const seen2 = /* @__PURE__ */ new Map();
|
|
37737
38037
|
for (const ep of [...np.outEdges(g), ...np.inEdges(g)]) {
|
|
37738
38038
|
if (ep.head === ep.tail) continue;
|
|
37739
38039
|
const vp = ep.tail === np ? ep.head : ep.tail;
|
|
37740
38040
|
const vid = vp.info.id;
|
|
37741
38041
|
const dist4 = haveLen ? lateDouble(ep.attrs.get("len"), 1, 0) : 1;
|
|
37742
|
-
const idx =
|
|
38042
|
+
const idx = seen2.get(vid);
|
|
37743
38043
|
if (idx !== void 0) {
|
|
37744
38044
|
if (haveLen) entry.ewgts[idx] = Math.max(entry.ewgts[idx], dist4);
|
|
37745
38045
|
continue;
|
|
37746
38046
|
}
|
|
37747
|
-
|
|
38047
|
+
seen2.set(vid, entry.nedges);
|
|
37748
38048
|
entry.edges.push(vid);
|
|
37749
38049
|
if (haveLen || haveDir) entry.ewgts.push(dist4);
|
|
37750
38050
|
entry.nedges++;
|
|
@@ -38091,15 +38391,15 @@ function delaunayTri(xv, yv, n) {
|
|
|
38091
38391
|
for (let i = 1; i < n; i++) edges2.push(vs[i - 1], vs[i]);
|
|
38092
38392
|
return edges2;
|
|
38093
38393
|
}
|
|
38094
|
-
const
|
|
38394
|
+
const seen2 = /* @__PURE__ */ new Set();
|
|
38095
38395
|
const pairs = [];
|
|
38096
38396
|
for (const t of tris) {
|
|
38097
38397
|
for (const [u, v] of [[t.a, t.b], [t.b, t.c], [t.c, t.a]]) {
|
|
38098
38398
|
const i = Math.min(u, v);
|
|
38099
38399
|
const j = Math.max(u, v);
|
|
38100
38400
|
const key = i * 1048576 + j;
|
|
38101
|
-
if (!
|
|
38102
|
-
|
|
38401
|
+
if (!seen2.has(key)) {
|
|
38402
|
+
seen2.add(key);
|
|
38103
38403
|
pairs.push([i, j]);
|
|
38104
38404
|
}
|
|
38105
38405
|
}
|
|
@@ -38384,8 +38684,8 @@ var Cdt = class {
|
|
|
38384
38684
|
const en = this.edgeOrNew(v3, v4);
|
|
38385
38685
|
this.removeFace(f1);
|
|
38386
38686
|
this.removeFace(f2);
|
|
38387
|
-
const f3 = this.addFace([v4, v2,
|
|
38388
|
-
const f4 = this.addFace([
|
|
38687
|
+
const f3 = this.addFace([v3, v4, v2], [en, e5, e2]);
|
|
38688
|
+
const f4 = this.addFace([v4, v3, v1], [en, e3, e4]);
|
|
38389
38689
|
this.swapIfInCircle(f3, v4, v2, v3, e5, e2, en);
|
|
38390
38690
|
this.swapIfInCircle(f4, v1, v4, v3, e4, en, e3);
|
|
38391
38691
|
}
|
|
@@ -38687,10 +38987,7 @@ function sharedEdge(faces, p3, q3) {
|
|
|
38687
38987
|
return { i: p1, j: p2 };
|
|
38688
38988
|
}
|
|
38689
38989
|
function addTriEdge(g, t, h, seg2) {
|
|
38690
|
-
const dist4 = Math.
|
|
38691
|
-
g.nodes[t].ctr.x - g.nodes[h].ctr.x,
|
|
38692
|
-
g.nodes[t].ctr.y - g.nodes[h].ctr.y
|
|
38693
|
-
);
|
|
38990
|
+
const dist4 = Math.sqrt(dist2(g.nodes[t].ctr, g.nodes[h].ctr));
|
|
38694
38991
|
const idx = g.edges.length;
|
|
38695
38992
|
g.edges.push({ t, h, seg: seg2, dist: dist4 });
|
|
38696
38993
|
g.nodes[t].edges.push(idx);
|
|
@@ -39017,7 +39314,7 @@ var SEP = 15;
|
|
|
39017
39314
|
function bisectorTarget(v, cosTheta, sinTheta) {
|
|
39018
39315
|
return { x: fma(cosTheta, 100, v.x), y: fma(sinTheta, 100, v.y) };
|
|
39019
39316
|
}
|
|
39020
|
-
function
|
|
39317
|
+
function distFused2(p, q) {
|
|
39021
39318
|
const dx = p.x - q.x;
|
|
39022
39319
|
const dy = p.y - q.y;
|
|
39023
39320
|
return Math.sqrt(fma(dx, dx, dy * dy));
|
|
@@ -39042,7 +39339,7 @@ function mkCtrlPts(s, mult, prev, v, nxt, trip) {
|
|
|
39042
39339
|
}
|
|
39043
39340
|
const q = triPoint(trip, idx, v, w);
|
|
39044
39341
|
if (q === null) return null;
|
|
39045
|
-
const d =
|
|
39342
|
+
const d = distFused2(q, v);
|
|
39046
39343
|
const sep = d >= mult * SEP ? SEP : d / mult;
|
|
39047
39344
|
const ps = new Array(mult);
|
|
39048
39345
|
if (idx < s) {
|
|
@@ -39171,8 +39468,8 @@ function chainOf(e) {
|
|
|
39171
39468
|
return list;
|
|
39172
39469
|
}
|
|
39173
39470
|
function warnNoControlPoints(e) {
|
|
39174
|
-
|
|
39175
|
-
`
|
|
39471
|
+
agwarningf(
|
|
39472
|
+
`Could not create control points for multiple spline for edge (${e.tail.name},${e.head.name})`
|
|
39176
39473
|
);
|
|
39177
39474
|
return 1;
|
|
39178
39475
|
}
|
|
@@ -41835,7 +42132,11 @@ function armPow(x, y) {
|
|
|
41835
42132
|
|
|
41836
42133
|
// src/common/crand.ts
|
|
41837
42134
|
var C_RAND_MAX = 2147483647;
|
|
41838
|
-
var
|
|
42135
|
+
var UNSEEDED_STATE2 = 1;
|
|
42136
|
+
var state2 = UNSEEDED_STATE2;
|
|
42137
|
+
registerRenderState(() => {
|
|
42138
|
+
state2 = UNSEEDED_STATE2;
|
|
42139
|
+
});
|
|
41839
42140
|
function csrand(seed) {
|
|
41840
42141
|
state2 = seed;
|
|
41841
42142
|
}
|
|
@@ -43775,7 +44076,7 @@ function makeAddPoly(n, xmargin, ymargin) {
|
|
|
43775
44076
|
case 3 /* SH_POINT */:
|
|
43776
44077
|
return finishPoly(genRound(n, xmargin, ymargin), POLY_CIRCLE);
|
|
43777
44078
|
default:
|
|
43778
|
-
|
|
44079
|
+
agerrorf(`makeAddPoly: unknown shape type ${shapeName(n)}
|
|
43779
44080
|
`);
|
|
43780
44081
|
return null;
|
|
43781
44082
|
}
|
|
@@ -43808,7 +44109,7 @@ function baseShape(n) {
|
|
|
43808
44109
|
case 3 /* SH_POINT */:
|
|
43809
44110
|
return { verts: genRound(n, 0, 0), kind: POLY_CIRCLE };
|
|
43810
44111
|
default:
|
|
43811
|
-
|
|
44112
|
+
agerrorf(`makePoly: unknown shape type ${shapeName(n)}
|
|
43812
44113
|
`);
|
|
43813
44114
|
return null;
|
|
43814
44115
|
}
|
|
@@ -45190,7 +45491,7 @@ function warnUnrecognizedOverlap(flag) {
|
|
|
45190
45491
|
const s = flag.toLowerCase();
|
|
45191
45492
|
if (s.startsWith("prism") || NAMED_MODES.has(s)) return;
|
|
45192
45493
|
if (mapBoolDflt(flag, false) === mapBoolDflt(flag, true)) return;
|
|
45193
|
-
|
|
45494
|
+
agerrLineOn("warn", `Unrecognized overlap value "${flag}" - using false`);
|
|
45194
45495
|
}
|
|
45195
45496
|
function getAdjustMode(flag) {
|
|
45196
45497
|
warnUnrecognizedOverlap(flag);
|
|
@@ -45223,7 +45524,7 @@ function adjustLate(g, am) {
|
|
|
45223
45524
|
case AM_VPSC:
|
|
45224
45525
|
return vpscAdjust(g);
|
|
45225
45526
|
default:
|
|
45226
|
-
|
|
45527
|
+
agerrLineOn("warn", `Unhandled adjust option ${am.print}`);
|
|
45227
45528
|
return 0;
|
|
45228
45529
|
}
|
|
45229
45530
|
}
|
|
@@ -45442,20 +45743,20 @@ function setSubtreeSize(g) {
|
|
|
45442
45743
|
walkAncestorChain(n);
|
|
45443
45744
|
}
|
|
45444
45745
|
}
|
|
45445
|
-
function applySpanToChild(g, n, next, ratio,
|
|
45746
|
+
function applySpanToChild(g, n, next, ratio, seen2) {
|
|
45446
45747
|
const nd2 = rdata(next);
|
|
45447
|
-
if (nd2.parent !== n || nd2.span !== 0 ||
|
|
45448
|
-
|
|
45748
|
+
if (nd2.parent !== n || nd2.span !== 0 || seen2.has(next)) return;
|
|
45749
|
+
seen2.add(next);
|
|
45449
45750
|
nd2.span = ratio * nd2.subtreeSize;
|
|
45450
45751
|
if (nd2.nChildren > 0) setChildSubtreeSpans(g, next);
|
|
45451
45752
|
}
|
|
45452
45753
|
function setChildSubtreeSpans(g, n) {
|
|
45453
45754
|
const nd = rdata(n);
|
|
45454
45755
|
const ratio = nd.span / nd.subtreeSize;
|
|
45455
|
-
const
|
|
45756
|
+
const seen2 = /* @__PURE__ */ new Set();
|
|
45456
45757
|
for (const ep of incidentEdges2(g, n)) {
|
|
45457
45758
|
const next = neighborOf(ep, n);
|
|
45458
|
-
if (next !== null) applySpanToChild(g, n, next, ratio,
|
|
45759
|
+
if (next !== null) applySpanToChild(g, n, next, ratio, seen2);
|
|
45459
45760
|
}
|
|
45460
45761
|
}
|
|
45461
45762
|
function setSubtreeSpans(sg, center) {
|
|
@@ -45724,7 +46025,7 @@ var fdpParms = {
|
|
|
45724
46025
|
* equivalent). @see lib/fdpgen/fdp.h:fdpParms_s.Mlimit */
|
|
45725
46026
|
Mlimit: Infinity
|
|
45726
46027
|
};
|
|
45727
|
-
var
|
|
46028
|
+
var PARMS_INIT = {
|
|
45728
46029
|
useGrid: 0,
|
|
45729
46030
|
useNew: 0,
|
|
45730
46031
|
seed: 0,
|
|
@@ -45742,6 +46043,10 @@ var parms = {
|
|
|
45742
46043
|
pass1: 0,
|
|
45743
46044
|
loopcnt: 0
|
|
45744
46045
|
};
|
|
46046
|
+
var parms = { ...PARMS_INIT };
|
|
46047
|
+
registerRenderState(() => {
|
|
46048
|
+
Object.assign(parms, PARMS_INIT);
|
|
46049
|
+
});
|
|
45745
46050
|
function cool(t) {
|
|
45746
46051
|
return parms.T0 * (parms.maxIters - t) / parms.maxIters;
|
|
45747
46052
|
}
|
|
@@ -46386,14 +46691,19 @@ function fdpTLayout(g, xpms) {
|
|
|
46386
46691
|
// src/layout/fdp/xlayout.ts
|
|
46387
46692
|
var DFLT_OVERLAP = "9:prism";
|
|
46388
46693
|
var PS2INCH3 = (x) => x / 72;
|
|
46389
|
-
var
|
|
46694
|
+
var XPARAMS_INIT = {
|
|
46390
46695
|
numIters: 60,
|
|
46391
46696
|
T0: 0,
|
|
46392
46697
|
K: 0.3,
|
|
46393
46698
|
C: 1.5,
|
|
46394
46699
|
loopcnt: 0
|
|
46395
46700
|
};
|
|
46701
|
+
var xParams = { ...XPARAMS_INIT };
|
|
46396
46702
|
var xMarg = { x: 0, y: 0, doAdd: false };
|
|
46703
|
+
registerRenderState(() => {
|
|
46704
|
+
Object.assign(xParams, XPARAMS_INIT);
|
|
46705
|
+
xMarg = { x: 0, y: 0, doAdd: false };
|
|
46706
|
+
});
|
|
46397
46707
|
function wd2(n) {
|
|
46398
46708
|
return xMarg.doAdd ? n.info.width / 2 + xMarg.x : n.info.width * xMarg.x / 2;
|
|
46399
46709
|
}
|
|
@@ -47255,7 +47565,7 @@ function fdpSplines(g) {
|
|
|
47255
47565
|
);
|
|
47256
47566
|
}
|
|
47257
47567
|
if (g.info.n_cluster_edges) {
|
|
47258
|
-
|
|
47568
|
+
agerrLineOn("warn", CLUSTER_EDGE_WARNING);
|
|
47259
47569
|
et = EDGETYPE_LINE;
|
|
47260
47570
|
} else {
|
|
47261
47571
|
splineEdges1(g, et);
|
|
@@ -48677,7 +48987,7 @@ function buildDerivedGraph(g) {
|
|
|
48677
48987
|
}
|
|
48678
48988
|
function buildDerivedEdges(g, dg) {
|
|
48679
48989
|
const edges = [];
|
|
48680
|
-
const
|
|
48990
|
+
const seen2 = /* @__PURE__ */ new Set();
|
|
48681
48991
|
for (const n of nodesInSeq(g)) {
|
|
48682
48992
|
for (const e of n.outEdges(g)) {
|
|
48683
48993
|
if (e.tail === e.head) continue;
|
|
@@ -48685,8 +48995,8 @@ function buildDerivedEdges(g, dg) {
|
|
|
48685
48995
|
const head = dg.nodes.get(e.head.name);
|
|
48686
48996
|
if (!tail || !head) continue;
|
|
48687
48997
|
const key = [tail.name, head.name].sort().join("\0");
|
|
48688
|
-
if (
|
|
48689
|
-
|
|
48998
|
+
if (seen2.has(key)) continue;
|
|
48999
|
+
seen2.add(key);
|
|
48690
49000
|
edges.push({ tail, head, order: 0, origEdge: e });
|
|
48691
49001
|
}
|
|
48692
49002
|
}
|
|
@@ -49530,12 +49840,12 @@ function svgEndCluster(job) {
|
|
|
49530
49840
|
}
|
|
49531
49841
|
|
|
49532
49842
|
// src/render/svg-edge-split.ts
|
|
49533
|
-
var
|
|
49843
|
+
var DEFAULT_COLOR5 = "black";
|
|
49534
49844
|
var PENWIDTH_NORMAL4 = 1;
|
|
49535
49845
|
var PENWIDTH_THRESHOLD4 = 5e-3;
|
|
49536
49846
|
var EPS3 = 1e-5;
|
|
49537
49847
|
function dist3(a, b) {
|
|
49538
|
-
return Math.
|
|
49848
|
+
return Math.sqrt(dist2(a, b));
|
|
49539
49849
|
}
|
|
49540
49850
|
function approxLen(list, off) {
|
|
49541
49851
|
return dist3(list[off], list[off + 1]) + dist3(list[off + 1], list[off + 2]) + dist3(list[off + 2], list[off + 3]);
|
|
@@ -49584,7 +49894,7 @@ function emitCurve(list, color, job) {
|
|
|
49584
49894
|
}
|
|
49585
49895
|
function stepSegment(list, s, st, out) {
|
|
49586
49896
|
if (Math.abs(s.t) < EPS3) return;
|
|
49587
|
-
const color = s.color ??
|
|
49897
|
+
const color = s.color ?? DEFAULT_COLOR5;
|
|
49588
49898
|
st.left -= s.t;
|
|
49589
49899
|
st.endColor = color;
|
|
49590
49900
|
if (st.first) {
|
|
@@ -49603,7 +49913,7 @@ function stepSegment(list, s, st, out) {
|
|
|
49603
49913
|
}
|
|
49604
49914
|
}
|
|
49605
49915
|
function splitSplineByColor(list, segs) {
|
|
49606
|
-
const st = { left: 1, first: true, bzR: list, done: false, endColor:
|
|
49916
|
+
const st = { left: 1, first: true, bzR: list, done: false, endColor: DEFAULT_COLOR5 };
|
|
49607
49917
|
const curves = [];
|
|
49608
49918
|
for (const s of segs) {
|
|
49609
49919
|
stepSegment(list, s, st, curves);
|
|
@@ -49618,16 +49928,16 @@ function drawSplitSpline(list, segs, job) {
|
|
|
49618
49928
|
}
|
|
49619
49929
|
function emitSplitEdgePaths(e, job, colorList) {
|
|
49620
49930
|
const segs = parseSegs(colorList).segs;
|
|
49621
|
-
const
|
|
49931
|
+
const firstColor2 = segs[0]?.color ?? DEFAULT_COLOR5;
|
|
49622
49932
|
const spl = e.info.spl;
|
|
49623
|
-
let endColor =
|
|
49624
|
-
if (spl === void 0) return { firstColor, endColor };
|
|
49933
|
+
let endColor = firstColor2;
|
|
49934
|
+
if (spl === void 0) return { firstColor: firstColor2, endColor };
|
|
49625
49935
|
for (let si = 0; si < spl.size; si++) {
|
|
49626
49936
|
const bz = spl.list[si];
|
|
49627
49937
|
if (bz === void 0 || bz.size < 4) continue;
|
|
49628
49938
|
endColor = drawSplitSpline(bz.list, segs, job);
|
|
49629
49939
|
}
|
|
49630
|
-
return { firstColor, endColor };
|
|
49940
|
+
return { firstColor: firstColor2, endColor };
|
|
49631
49941
|
}
|
|
49632
49942
|
|
|
49633
49943
|
// src/common/taper.ts
|
|
@@ -51072,7 +51382,7 @@ var DotWriterBase = class {
|
|
|
51072
51382
|
};
|
|
51073
51383
|
|
|
51074
51384
|
// src/render/dot/edge-draw.ts
|
|
51075
|
-
var
|
|
51385
|
+
var DEFAULT_COLOR6 = "black";
|
|
51076
51386
|
var DEFAULT_LINE_STYLE = ["solid", "setlinewidth(1)"];
|
|
51077
51387
|
function emitArrowOp(buf, op, pen) {
|
|
51078
51388
|
switch (op.kind) {
|
|
@@ -51165,8 +51475,8 @@ var EdgeDrawBase = class extends DotWriterBase {
|
|
|
51165
51475
|
*/
|
|
51166
51476
|
emitSplitSpline(bzList, colorAttr, edraw, job) {
|
|
51167
51477
|
const segs = parseSegs(colorAttr).segs;
|
|
51168
|
-
const
|
|
51169
|
-
let endColor =
|
|
51478
|
+
const firstColor2 = segs[0]?.color ?? DEFAULT_COLOR6;
|
|
51479
|
+
let endColor = firstColor2;
|
|
51170
51480
|
for (const bz of bzList) {
|
|
51171
51481
|
if (bz === void 0 || bz.size < 4) continue;
|
|
51172
51482
|
const split = splitSplineByColor(bz.list.slice(0, bz.size), segs);
|
|
@@ -51175,7 +51485,7 @@ var EdgeDrawBase = class extends DotWriterBase {
|
|
|
51175
51485
|
edraw.push(this.styleOp(job), xdotPenColor(resolveRenderColor(c.color)), xdotPoints("B", c.points));
|
|
51176
51486
|
}
|
|
51177
51487
|
}
|
|
51178
|
-
return { firstColor, endColor };
|
|
51488
|
+
return { firstColor: firstColor2, endColor };
|
|
51179
51489
|
}
|
|
51180
51490
|
/**
|
|
51181
51491
|
* Emit the parallel-multicolor edge spline: one offset Bézier per color,
|
|
@@ -51187,7 +51497,7 @@ var EdgeDrawBase = class extends DotWriterBase {
|
|
|
51187
51497
|
const segData = bzList.map(
|
|
51188
51498
|
(bz) => bz !== void 0 && bz.size >= 4 ? buildOffsetLists(bz.list, (2 + numc) / 2) : { offlist: [], tmplist: [] }
|
|
51189
51499
|
);
|
|
51190
|
-
const colors = parseSegs(colorAttr).segs.map((s) => s.color ??
|
|
51500
|
+
const colors = parseSegs(colorAttr).segs.map((s) => s.color ?? DEFAULT_COLOR6);
|
|
51191
51501
|
for (const color of colors) {
|
|
51192
51502
|
const pen = xdotPenColor(resolveRenderColor(color));
|
|
51193
51503
|
for (const sd of segData) {
|
|
@@ -51197,8 +51507,8 @@ var EdgeDrawBase = class extends DotWriterBase {
|
|
|
51197
51507
|
}
|
|
51198
51508
|
}
|
|
51199
51509
|
return {
|
|
51200
|
-
headColor: colors[0] ??
|
|
51201
|
-
tailColor: colors[1] ?? colors[0] ??
|
|
51510
|
+
headColor: colors[0] ?? DEFAULT_COLOR6,
|
|
51511
|
+
tailColor: colors[1] ?? colors[0] ?? DEFAULT_COLOR6
|
|
51202
51512
|
};
|
|
51203
51513
|
}
|
|
51204
51514
|
/** Emit one arrow's primitive ops into `buf` (pen/fill from the edge color).
|
|
@@ -51709,8 +52019,8 @@ var SvgRenderer = class {
|
|
|
51709
52019
|
const numc = (colorAttr.match(/:/g) ?? []).length;
|
|
51710
52020
|
const numsemi = (colorAttr.match(/;/g) ?? []).length;
|
|
51711
52021
|
if (numsemi > 0 && numc > 0) {
|
|
51712
|
-
const { firstColor, endColor } = emitSplitEdgePaths(e, job, colorAttr);
|
|
51713
|
-
emitMulticolorArrows(e, job, endColor,
|
|
52022
|
+
const { firstColor: firstColor2, endColor } = emitSplitEdgePaths(e, job, colorAttr);
|
|
52023
|
+
emitMulticolorArrows(e, job, endColor, firstColor2);
|
|
51714
52024
|
} else if (edgeIsTapered(e)) {
|
|
51715
52025
|
svgTaperedEdge(e, job);
|
|
51716
52026
|
} else if (numc > 0) {
|
|
@@ -52054,7 +52364,7 @@ function peg$parse(input, options) {
|
|
|
52054
52364
|
return s;
|
|
52055
52365
|
}
|
|
52056
52366
|
function peg$f13(t, m, attrs) {
|
|
52057
|
-
if (m)
|
|
52367
|
+
if (m) agwarningf("attribute macros not implemented", "error");
|
|
52058
52368
|
return { type: "attr", target: t, attrs };
|
|
52059
52369
|
}
|
|
52060
52370
|
function peg$f14(a) {
|
|
@@ -55488,8 +55798,8 @@ var StmtProcessor = class _StmtProcessor {
|
|
|
55488
55798
|
resolveEndpoint(item, root, scope, directed) {
|
|
55489
55799
|
if ("type" in item && item.type === "subgraph") {
|
|
55490
55800
|
this.processSubgraph(item, scope, root, directed);
|
|
55491
|
-
const
|
|
55492
|
-
const nodes = NameCollector.fromStmts(item.stmts).map((n) => this.registry.ensure(n, root, scope)).filter((nd) =>
|
|
55801
|
+
const seen2 = /* @__PURE__ */ new Set();
|
|
55802
|
+
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));
|
|
55493
55803
|
return nodes.sort((a, b) => a.id - b.id);
|
|
55494
55804
|
}
|
|
55495
55805
|
return [this.registry.ensure(item.id, root, scope)];
|
|
@@ -55733,22 +56043,22 @@ function countNewlines(s, from, to) {
|
|
|
55733
56043
|
return n;
|
|
55734
56044
|
}
|
|
55735
56045
|
var HEADER_KEYWORDS = ["strict", "graph", "digraph"];
|
|
55736
|
-
function isTruncatedHeaderKeyword(src, step, offset,
|
|
55737
|
-
if (offset !== src.length || step.end !== offset ||
|
|
55738
|
-
if (
|
|
56046
|
+
function isTruncatedHeaderKeyword(src, step, offset, seen2) {
|
|
56047
|
+
if (offset !== src.length || step.end !== offset || seen2.length > 1) return false;
|
|
56048
|
+
if (seen2.length === 1 && seen2[0].toLowerCase() !== "strict") return false;
|
|
55739
56049
|
const word = step.text.toLowerCase();
|
|
55740
56050
|
return HEADER_KEYWORDS.some((k) => k.length > word.length && k.startsWith(word));
|
|
55741
56051
|
}
|
|
55742
|
-
function reachesOffset(src, step, offset,
|
|
56052
|
+
function reachesOffset(src, step, offset, seen2) {
|
|
55743
56053
|
if (step.end > offset) return true;
|
|
55744
|
-
if (isTruncatedHeaderKeyword(src, step, offset,
|
|
56054
|
+
if (isTruncatedHeaderKeyword(src, step, offset, seen2)) return true;
|
|
55745
56055
|
if (step.text !== "-" && step.text !== ".") return false;
|
|
55746
56056
|
return offset <= step.end + (step.text === "-" && src[step.end] === "." ? 1 : 0);
|
|
55747
56057
|
}
|
|
55748
56058
|
function scanAtError(src, offset) {
|
|
55749
56059
|
let line = 1;
|
|
55750
56060
|
let i = 0;
|
|
55751
|
-
const
|
|
56061
|
+
const seen2 = [];
|
|
55752
56062
|
while (i < src.length) {
|
|
55753
56063
|
const step = lexStep(src, i);
|
|
55754
56064
|
if (step.kind === "open") {
|
|
@@ -55757,10 +56067,10 @@ function scanAtError(src, offset) {
|
|
|
55757
56067
|
}
|
|
55758
56068
|
if (step.kind === "skip" && step.line !== void 0) line = step.line;
|
|
55759
56069
|
line += countNewlines(src, i, step.end);
|
|
55760
|
-
if (step.kind === "token" && reachesOffset(src, step, offset,
|
|
56070
|
+
if (step.kind === "token" && reachesOffset(src, step, offset, seen2)) {
|
|
55761
56071
|
return { state: "INITIAL", text: step.text, line, buffer: "" };
|
|
55762
56072
|
}
|
|
55763
|
-
if (step.kind === "token")
|
|
56073
|
+
if (step.kind === "token") seen2.push(step.text);
|
|
55764
56074
|
i = step.end;
|
|
55765
56075
|
}
|
|
55766
56076
|
return { state: "INITIAL", text: "", line, buffer: "" };
|
|
@@ -55953,7 +56263,7 @@ function isPeggyError(err) {
|
|
|
55953
56263
|
function warnNumberAmbiguities(src, upTo) {
|
|
55954
56264
|
for (const a of scanNumberAmbiguities(src, Stripper.strip(src))) {
|
|
55955
56265
|
if (a.offset > upTo) break;
|
|
55956
|
-
|
|
56266
|
+
agerrFinished(numberAmbiguityMessage(a), "error");
|
|
55957
56267
|
}
|
|
55958
56268
|
}
|
|
55959
56269
|
function parse(src) {
|
|
@@ -55967,7 +56277,7 @@ function parse(src) {
|
|
|
55967
56277
|
if (isPeggyError(err)) {
|
|
55968
56278
|
const start = err.location.start;
|
|
55969
56279
|
warnNumberAmbiguities(src, start.offset);
|
|
55970
|
-
|
|
56280
|
+
agerrFinished(syntaxErrorMessage(src, start.offset));
|
|
55971
56281
|
const code = err.found === null ? "SYNTAX_UNEXPECTED_EOF" : "SYNTAX_ERROR";
|
|
55972
56282
|
throw new ParseError(
|
|
55973
56283
|
err instanceof Error ? err.message : String(err),
|
|
@@ -55992,7 +56302,7 @@ function parse(src) {
|
|
|
55992
56302
|
const offset = err instanceof ParseError ? err.location.offset : void 0;
|
|
55993
56303
|
if (offset !== void 0) {
|
|
55994
56304
|
warnNumberAmbiguities(src, offset);
|
|
55995
|
-
|
|
56305
|
+
agerrFinished(syntaxErrorMessage(src, offset));
|
|
55996
56306
|
}
|
|
55997
56307
|
throw err;
|
|
55998
56308
|
}
|
|
@@ -56835,6 +57145,7 @@ function checkRenderArgs(g, format, opts) {
|
|
|
56835
57145
|
}
|
|
56836
57146
|
function render2(g, format, opts) {
|
|
56837
57147
|
checkRenderArgs(g, format, opts);
|
|
57148
|
+
resetRenderState();
|
|
56838
57149
|
const engine = opts?.engine ?? "dot";
|
|
56839
57150
|
const inlineImages = opts?.inlineImages ?? false;
|
|
56840
57151
|
const ctx = createDefaultContext();
|
|
@@ -57031,6 +57342,7 @@ async function renderAsync(g, format, opts) {
|
|
|
57031
57342
|
const engine = opts?.engine ?? "dot";
|
|
57032
57343
|
try {
|
|
57033
57344
|
const { fontIssues, sizes, bytes } = await prefetchAll(g, opts);
|
|
57345
|
+
resetRenderState();
|
|
57034
57346
|
const ctx = createDefaultContext();
|
|
57035
57347
|
if (opts?.imageSizer !== void 0) {
|
|
57036
57348
|
const sizer = (src) => sizes.get(src) ?? null;
|
|
@@ -57095,6 +57407,7 @@ function layoutAndRenderXdot(g, engine) {
|
|
|
57095
57407
|
}
|
|
57096
57408
|
function getDrawOps(g, opts) {
|
|
57097
57409
|
checkDrawOpsArgs(g, opts);
|
|
57410
|
+
resetRenderState();
|
|
57098
57411
|
const engine = opts?.engine ?? DEFAULT_DRAW_ENGINE;
|
|
57099
57412
|
return collectGraphOps(parse(layoutAndRenderXdot(g, engine)));
|
|
57100
57413
|
}
|