@knowvah/dot-engine 2.6.2 → 2.6.4
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/common/htmltable-lex.d.ts +38 -0
- package/dist/common/htmltable-lex.d.ts.map +1 -1
- package/dist/common/htmltable-parse-attrs.d.ts +41 -0
- package/dist/common/htmltable-parse-attrs.d.ts.map +1 -0
- package/dist/common/htmltable-parse.d.ts +3 -0
- package/dist/common/htmltable-parse.d.ts.map +1 -1
- package/dist/common/htmltable-pos.d.ts +17 -0
- package/dist/common/htmltable-pos.d.ts.map +1 -1
- package/dist/common/htmltable.d.ts +13 -1
- package/dist/common/htmltable.d.ts.map +1 -1
- package/dist/common/make-label.d.ts.map +1 -1
- package/dist/common/spline-midpoint.d.ts +8 -0
- package/dist/common/spline-midpoint.d.ts.map +1 -1
- package/dist/index.js +621 -323
- package/dist/index.js.map +4 -4
- package/dist/label/node.d.ts +7 -1
- package/dist/label/node.d.ts.map +1 -1
- package/dist/layout/circo/position-helpers.d.ts +15 -3
- package/dist/layout/circo/position-helpers.d.ts.map +1 -1
- package/dist/layout/circo/position.d.ts +17 -1
- package/dist/layout/circo/position.d.ts.map +1 -1
- package/dist/layout/dot/ortho-adapter.d.ts.map +1 -1
- package/dist/layout/dot/splines-flat-labeled.d.ts.map +1 -1
- package/dist/layout/neato/multispline.d.ts.map +1 -1
- package/dist/layout/pack/poly-pack.d.ts +2 -18
- package/dist/layout/pack/poly-pack.d.ts.map +1 -1
- package/dist/pathplan/shortest.d.ts.map +1 -1
- package/dist/render.js +774 -476
- package/dist/render.js.map +4 -4
- package/package.json +1 -1
- package/src/common/htmltable-lex.ts +265 -5
- package/src/common/htmltable-parse-attrs.ts +166 -0
- package/src/common/htmltable-parse.ts +262 -242
- package/src/common/htmltable-pos.ts +37 -38
- package/src/common/htmltable.ts +139 -45
- package/src/common/make-label.ts +19 -3
- package/src/common/spline-midpoint.ts +30 -9
- package/src/label/node.ts +8 -2
- package/src/layout/circo/position-helpers.ts +28 -17
- package/src/layout/circo/position.ts +28 -7
- package/src/layout/dot/__fixtures__/2796-flat-labeled-lost.dot +161 -0
- package/src/layout/dot/ortho-adapter.ts +20 -9
- package/src/layout/dot/splines-flat-labeled.ts +3 -1
- package/src/layout/neato/multispline.ts +17 -5
- package/src/layout/pack/poly-pack.ts +5 -31
- package/src/pathplan/shortest.ts +15 -2
package/dist/index.js
CHANGED
|
@@ -4302,11 +4302,11 @@ function lexToken(s, i) {
|
|
|
4302
4302
|
function scanNumberAmbiguities(src, stripped) {
|
|
4303
4303
|
const out = [];
|
|
4304
4304
|
let line = 1;
|
|
4305
|
-
let
|
|
4305
|
+
let lineAt2 = 0;
|
|
4306
4306
|
for (let i = 0; i < stripped.length; ) {
|
|
4307
4307
|
const { next, bad } = lexToken(stripped, i);
|
|
4308
4308
|
if (bad !== null) {
|
|
4309
|
-
for (;
|
|
4309
|
+
for (; lineAt2 < i; lineAt2++) if (src[lineAt2] === "\n") line++;
|
|
4310
4310
|
out.push({ text: bad, line, offset: i });
|
|
4311
4311
|
}
|
|
4312
4312
|
i = next;
|
|
@@ -10341,16 +10341,152 @@ function parseOpenToken(inner) {
|
|
|
10341
10341
|
checkTag(tag);
|
|
10342
10342
|
return { type: "open", tag: normalizeTag(tag), attrs: parseAttrs(inner.slice(sp + 1)) };
|
|
10343
10343
|
}
|
|
10344
|
-
|
|
10344
|
+
var XML_ERROR_UNDEFINED_ENTITY = "undefined entity";
|
|
10345
|
+
var XML_ERROR_TAG_MISMATCH = "mismatched tag";
|
|
10346
|
+
var XML_ERROR_INVALID_TOKEN = "not well-formed (invalid token)";
|
|
10347
|
+
var XML_ERROR_DUPLICATE_ATTRIBUTE = "duplicate attribute";
|
|
10348
|
+
var XML_PREDEFINED_ENTITIES = /* @__PURE__ */ new Set(["lt", "gt", "amp", "quot", "apos"]);
|
|
10349
|
+
var XML_NAME = /^[A-Za-z_:][\w.:-]*$/;
|
|
10350
|
+
var HtmlLexError = class extends HtmlParseError {
|
|
10351
|
+
diagnostics;
|
|
10352
|
+
constructor(tag, message, diagnostics) {
|
|
10353
|
+
super(tag);
|
|
10354
|
+
this.message = message;
|
|
10355
|
+
this.diagnostics = diagnostics;
|
|
10356
|
+
}
|
|
10357
|
+
};
|
|
10358
|
+
function htmlErrorInLine(message, line, context) {
|
|
10359
|
+
const text = `${message} in line ${line} `;
|
|
10360
|
+
return new HtmlLexError(message, text, [`Error: ${text}`, `... ${context} ...`]);
|
|
10361
|
+
}
|
|
10362
|
+
var chunkInfo = /* @__PURE__ */ new WeakMap();
|
|
10363
|
+
function lineAt(src, pos) {
|
|
10364
|
+
let line = 1;
|
|
10365
|
+
for (let k = 0; k < pos; k++) {
|
|
10366
|
+
if (src[k] === "\n" || src[k] === "\r" && src[k + 1] !== "\n") line++;
|
|
10367
|
+
}
|
|
10368
|
+
return line;
|
|
10369
|
+
}
|
|
10370
|
+
function chunkLine(info) {
|
|
10371
|
+
if (info.src[info.pos] === "<") return lineAt(info.src, info.pos);
|
|
10372
|
+
const last = info.src.lastIndexOf("\n", info.end - 1);
|
|
10373
|
+
if (last < info.pos) return lineAt(info.src, info.pos);
|
|
10374
|
+
return lineAt(info.src, last === info.end - 1 ? last : last + 1);
|
|
10375
|
+
}
|
|
10376
|
+
function htmlErrorAtToken(message, tok) {
|
|
10377
|
+
const info = tok === void 0 ? void 0 : chunkInfo.get(tok);
|
|
10378
|
+
if (info === void 0) return void 0;
|
|
10379
|
+
return htmlErrorInLine(message, chunkLine(info), info.context);
|
|
10380
|
+
}
|
|
10381
|
+
function chunkEnd(src, i) {
|
|
10382
|
+
const j = src[i] === "<" ? src.indexOf(">", i + 1) : src.indexOf("<", i);
|
|
10383
|
+
if (j < 0) return src.length;
|
|
10384
|
+
return src[i] === "<" ? j + 1 : j;
|
|
10385
|
+
}
|
|
10386
|
+
function findUndefinedEntity(text) {
|
|
10387
|
+
for (let t = text.indexOf("&"); t >= 0; t = text.indexOf("&", t + 1)) {
|
|
10388
|
+
if (text[t + 1] === "#") continue;
|
|
10389
|
+
const semi = text.indexOf(";", t + 1);
|
|
10390
|
+
if (semi < 0) continue;
|
|
10391
|
+
const key = text.slice(t + 1, semi);
|
|
10392
|
+
if (XML_NAME.test(key) && !Object.hasOwn(HTML_ENTITIES, key) && !XML_PREDEFINED_ENTITIES.has(key)) {
|
|
10393
|
+
return t;
|
|
10394
|
+
}
|
|
10395
|
+
}
|
|
10396
|
+
return -1;
|
|
10397
|
+
}
|
|
10398
|
+
function parseTagChunk(chunk) {
|
|
10399
|
+
if (!chunk.endsWith(">")) return void 0;
|
|
10400
|
+
const body = chunk.slice(1, -1);
|
|
10401
|
+
if (body.startsWith("!")) return void 0;
|
|
10402
|
+
const close = body.startsWith("/");
|
|
10403
|
+
const name = /^[^\s/>]*/.exec(close ? body.slice(1) : body)?.[0] ?? "";
|
|
10404
|
+
return { close, selfClose: !close && body.endsWith("/"), name };
|
|
10405
|
+
}
|
|
10406
|
+
var ATTR_NAME = /^[A-Za-z_:][\w.:-]*/;
|
|
10407
|
+
var isSpace = (c) => c !== void 0 && /\s/.test(c);
|
|
10408
|
+
var invalidToken = (offset) => ({ message: XML_ERROR_INVALID_TOKEN, offset });
|
|
10409
|
+
function skipSpace(chunk, i) {
|
|
10410
|
+
let j = i;
|
|
10411
|
+
while (isSpace(chunk[j])) j++;
|
|
10412
|
+
return j;
|
|
10413
|
+
}
|
|
10414
|
+
function readAttrPair(chunk, i) {
|
|
10415
|
+
const name = ATTR_NAME.exec(chunk.slice(i))?.[0];
|
|
10416
|
+
if (name === void 0) return invalidToken(i);
|
|
10417
|
+
let j = skipSpace(chunk, i + name.length);
|
|
10418
|
+
if (chunk[j] !== "=") return invalidToken(j);
|
|
10419
|
+
j = skipSpace(chunk, j + 1);
|
|
10420
|
+
const q = chunk[j];
|
|
10421
|
+
if (q !== '"' && q !== "'") return invalidToken(j);
|
|
10422
|
+
const end = chunk.indexOf(q, j + 1);
|
|
10423
|
+
return end < 0 ? void 0 : { name, next: end + 1 };
|
|
10424
|
+
}
|
|
10425
|
+
function findAttrError(chunk, from) {
|
|
10426
|
+
const seen = /* @__PURE__ */ new Set();
|
|
10427
|
+
let dup;
|
|
10428
|
+
let i = skipSpace(chunk, from);
|
|
10429
|
+
while (chunk[i] !== ">" && !(chunk[i] === "/" && chunk[i + 1] === ">")) {
|
|
10430
|
+
const pair = readAttrPair(chunk, i);
|
|
10431
|
+
if (pair === void 0) return void 0;
|
|
10432
|
+
if ("message" in pair) return pair;
|
|
10433
|
+
if (seen.has(pair.name) && dup === void 0) dup = { message: XML_ERROR_DUPLICATE_ATTRIBUTE, offset: i };
|
|
10434
|
+
seen.add(pair.name);
|
|
10435
|
+
i = skipSpace(chunk, pair.next);
|
|
10436
|
+
}
|
|
10437
|
+
return dup;
|
|
10438
|
+
}
|
|
10439
|
+
function checkTagChunk(src, start, st) {
|
|
10440
|
+
const tag = parseTagChunk(st.curr);
|
|
10441
|
+
if (tag === void 0) return;
|
|
10442
|
+
if (tag.close) {
|
|
10443
|
+
if (st.stack.length > 0 && st.stack.pop() !== tag.name) {
|
|
10444
|
+
throw htmlErrorInLine(XML_ERROR_TAG_MISMATCH, lineAt(src, start), st.prev + st.curr);
|
|
10445
|
+
}
|
|
10446
|
+
} else {
|
|
10447
|
+
const bad = findAttrError(st.curr, 1 + tag.name.length);
|
|
10448
|
+
if (bad !== void 0) {
|
|
10449
|
+
throw htmlErrorInLine(bad.message, lineAt(src, start + bad.offset), st.prev + st.curr);
|
|
10450
|
+
}
|
|
10451
|
+
if (!tag.selfClose) st.stack.push(tag.name);
|
|
10452
|
+
}
|
|
10453
|
+
if (KNOWN_TAGS.has(tag.name.toUpperCase())) return;
|
|
10454
|
+
const text = `Unknown HTML element <${tag.name}> on line ${lineAt(src, start)} `;
|
|
10455
|
+
throw new HtmlLexError(tag.name.toUpperCase(), text, [`Error: ${text}`]);
|
|
10456
|
+
}
|
|
10457
|
+
function checkChunk(src, start, st) {
|
|
10458
|
+
if (st.curr.startsWith("<")) {
|
|
10459
|
+
checkTagChunk(src, start, st);
|
|
10460
|
+
return;
|
|
10461
|
+
}
|
|
10462
|
+
const off = findUndefinedEntity(st.curr);
|
|
10463
|
+
if (off >= 0) {
|
|
10464
|
+
throw htmlErrorInLine(XML_ERROR_UNDEFINED_ENTITY, lineAt(src, start + off), st.prev + st.curr);
|
|
10465
|
+
}
|
|
10466
|
+
}
|
|
10467
|
+
function tokenizeDeferred(src) {
|
|
10345
10468
|
const tokens = [];
|
|
10469
|
+
const st = { stack: [], prev: "", curr: "" };
|
|
10346
10470
|
let i = 0;
|
|
10347
|
-
|
|
10348
|
-
|
|
10471
|
+
try {
|
|
10472
|
+
while (i < src.length) {
|
|
10473
|
+
const first = tokens.length;
|
|
10474
|
+
const start = i;
|
|
10475
|
+
st.prev = st.curr;
|
|
10476
|
+
st.curr = src.slice(i, chunkEnd(src, i));
|
|
10477
|
+
checkChunk(src, i, st);
|
|
10478
|
+
i = src[i] === "<" ? scanTag(src, i, tokens) : scanText(src, i, tokens);
|
|
10479
|
+
const info = { src, pos: start, end: i, context: st.prev + st.curr };
|
|
10480
|
+
for (let k = first; k < tokens.length; k++) chunkInfo.set(tokens[k], info);
|
|
10481
|
+
}
|
|
10482
|
+
} catch (e) {
|
|
10483
|
+
if (e instanceof HtmlParseError) return { tokens, error: e };
|
|
10484
|
+
throw e;
|
|
10349
10485
|
}
|
|
10350
|
-
return tokens;
|
|
10486
|
+
return { tokens };
|
|
10351
10487
|
}
|
|
10352
10488
|
|
|
10353
|
-
// src/common/htmltable-parse.ts
|
|
10489
|
+
// src/common/htmltable-parse-attrs.ts
|
|
10354
10490
|
function anchorAttr(v) {
|
|
10355
10491
|
return v === void 0 ? void 0 : htmlEntityUTF8(v);
|
|
10356
10492
|
}
|
|
@@ -10373,6 +10509,81 @@ var num = (s) => {
|
|
|
10373
10509
|
const n = parseInt(s, 10);
|
|
10374
10510
|
return isNaN(n) ? void 0 : n;
|
|
10375
10511
|
};
|
|
10512
|
+
var parseFixedSize = (a) => a["fixedsize"]?.toUpperCase() === "TRUE" ? true : void 0;
|
|
10513
|
+
var parseTitle = (a) => a["title"] !== void 0 ? a["title"] : a["tooltip"];
|
|
10514
|
+
var parseSides = (v) => {
|
|
10515
|
+
if (v === void 0) return void 0;
|
|
10516
|
+
let flags = 0;
|
|
10517
|
+
for (const c of v.toLowerCase()) {
|
|
10518
|
+
if (c === "l") flags |= BORDER_LEFT;
|
|
10519
|
+
else if (c === "t") flags |= BORDER_TOP;
|
|
10520
|
+
else if (c === "r") flags |= BORDER_RIGHT;
|
|
10521
|
+
else if (c === "b") flags |= BORDER_BOTTOM;
|
|
10522
|
+
}
|
|
10523
|
+
if (flags === 0 || flags === BORDER_MASK) return void 0;
|
|
10524
|
+
return flags;
|
|
10525
|
+
};
|
|
10526
|
+
var parseGradientAngle = (v) => {
|
|
10527
|
+
if (v === void 0) return void 0;
|
|
10528
|
+
const n = parseInt(v, 10);
|
|
10529
|
+
if (isNaN(n) || String(n) !== v.trim()) return void 0;
|
|
10530
|
+
if (n < 0 || n > 360) return void 0;
|
|
10531
|
+
return n;
|
|
10532
|
+
};
|
|
10533
|
+
var parseColumns = (v) => v === "*" ? true : void 0;
|
|
10534
|
+
var parseRows = (v) => v === "*" ? true : void 0;
|
|
10535
|
+
var buildCell = (content, a) => ({
|
|
10536
|
+
kind: "cell",
|
|
10537
|
+
content,
|
|
10538
|
+
port: a["port"],
|
|
10539
|
+
align: parseAlign(a["align"] !== void 0 ? a["align"] : ""),
|
|
10540
|
+
valign: parseVAlign(a["valign"] !== void 0 ? a["valign"] : ""),
|
|
10541
|
+
balign: parseAlign(a["balign"] !== void 0 ? a["balign"] : ""),
|
|
10542
|
+
bgcolor: a["bgcolor"],
|
|
10543
|
+
color: a["color"],
|
|
10544
|
+
border: num(a["border"]),
|
|
10545
|
+
cellpadding: num(a["cellpadding"]),
|
|
10546
|
+
cellspacing: num(a["cellspacing"]),
|
|
10547
|
+
sides: parseSides(a["sides"]),
|
|
10548
|
+
gradientangle: parseGradientAngle(a["gradientangle"]),
|
|
10549
|
+
style: a["style"],
|
|
10550
|
+
width: num(a["width"]),
|
|
10551
|
+
height: num(a["height"]),
|
|
10552
|
+
fixedsize: parseFixedSize(a),
|
|
10553
|
+
colspan: num(a["colspan"]),
|
|
10554
|
+
rowspan: num(a["rowspan"]),
|
|
10555
|
+
href: anchorAttr(a["href"]),
|
|
10556
|
+
title: parseTitle(a),
|
|
10557
|
+
target: anchorAttr(a["target"]),
|
|
10558
|
+
id: a["id"]
|
|
10559
|
+
});
|
|
10560
|
+
var buildTable = (rows, a) => ({
|
|
10561
|
+
kind: "table",
|
|
10562
|
+
rows,
|
|
10563
|
+
border: num(a["border"]),
|
|
10564
|
+
cellborder: num(a["cellborder"]),
|
|
10565
|
+
cellspacing: num(a["cellspacing"]),
|
|
10566
|
+
cellpadding: num(a["cellpadding"]),
|
|
10567
|
+
bgcolor: a["bgcolor"],
|
|
10568
|
+
color: a["color"],
|
|
10569
|
+
style: a["style"],
|
|
10570
|
+
align: parseAlign(a["align"] !== void 0 ? a["align"] : ""),
|
|
10571
|
+
valign: parseVAlign(a["valign"] !== void 0 ? a["valign"] : ""),
|
|
10572
|
+
fixedsize: parseFixedSize(a),
|
|
10573
|
+
width: num(a["width"]),
|
|
10574
|
+
height: num(a["height"]),
|
|
10575
|
+
href: anchorAttr(a["href"]),
|
|
10576
|
+
title: parseTitle(a),
|
|
10577
|
+
target: anchorAttr(a["target"]),
|
|
10578
|
+
id: a["id"],
|
|
10579
|
+
port: a["port"],
|
|
10580
|
+
sides: parseSides(a["sides"]),
|
|
10581
|
+
gradientangle: parseGradientAngle(a["gradientangle"]),
|
|
10582
|
+
vrule: parseColumns(a["columns"]),
|
|
10583
|
+
hrule: parseRows(a["rows"])
|
|
10584
|
+
});
|
|
10585
|
+
|
|
10586
|
+
// src/common/htmltable-parse.ts
|
|
10376
10587
|
var definedOf = (s) => Object.fromEntries(
|
|
10377
10588
|
Object.entries(s).filter(([, v]) => v !== void 0)
|
|
10378
10589
|
);
|
|
@@ -10396,6 +10607,11 @@ var fontItemProps = (f) => {
|
|
|
10396
10607
|
if (f.fontSize !== void 0) out.fontSize = f.fontSize;
|
|
10397
10608
|
return out;
|
|
10398
10609
|
};
|
|
10610
|
+
var MSG_SYNTAX_ERROR = "syntax error";
|
|
10611
|
+
var MSG_TEXT_BEFORE_TABLE = "Syntax error: non-space string used before <TABLE>";
|
|
10612
|
+
var MSG_TEXT_AFTER_TABLE = "Syntax error: non-space string used after </TABLE>";
|
|
10613
|
+
var nonSpace = (text) => /[^ \t\n\r]/.test(text);
|
|
10614
|
+
var parseError = (s, tok, message) => (tok === void 0 ? s.pending : htmlErrorAtToken(message, tok)) ?? new HtmlParseError(message);
|
|
10399
10615
|
var peek = (s) => s.tokens[s.pos];
|
|
10400
10616
|
var consume = (s) => {
|
|
10401
10617
|
const t = s.tokens[s.pos];
|
|
@@ -10414,12 +10630,20 @@ var inlineFontState = (tag, _attrs) => {
|
|
|
10414
10630
|
if (tag === "SUP") fs.superscript = true;
|
|
10415
10631
|
return fs;
|
|
10416
10632
|
};
|
|
10633
|
+
var consumeClose = (s, tag) => {
|
|
10634
|
+
const nxt = peek(s);
|
|
10635
|
+
if (nxt === void 0) return;
|
|
10636
|
+
if (nxt.type === "close" && nxt.tag === tag) {
|
|
10637
|
+
consume(s);
|
|
10638
|
+
return;
|
|
10639
|
+
}
|
|
10640
|
+
throw parseError(s, nxt, MSG_SYNTAX_ERROR);
|
|
10641
|
+
};
|
|
10417
10642
|
var applyBrTag = (s, t, fontStack, items) => {
|
|
10418
10643
|
consume(s);
|
|
10419
10644
|
const font = fontStack[fontStack.length - 1] ?? {};
|
|
10420
10645
|
items.push({ br: true, brAlign: parseAlign(t.attrs["align"] ?? ""), ...fontItemProps(font) });
|
|
10421
|
-
|
|
10422
|
-
if (nxt?.type === "close" && nxt.tag === "BR") consume(s);
|
|
10646
|
+
consumeClose(s, "BR");
|
|
10423
10647
|
};
|
|
10424
10648
|
var applyFontTag = (s, t, fontStack, items) => {
|
|
10425
10649
|
consume(s);
|
|
@@ -10476,12 +10700,6 @@ var parseText = (s, fontStack) => {
|
|
|
10476
10700
|
}
|
|
10477
10701
|
return { kind: "text", items };
|
|
10478
10702
|
};
|
|
10479
|
-
var parseHrContent = (s) => {
|
|
10480
|
-
consume(s);
|
|
10481
|
-
const nxt = peek(s);
|
|
10482
|
-
if (nxt?.type === "close" && nxt.tag === "HR") consume(s);
|
|
10483
|
-
return { kind: "hr" };
|
|
10484
|
-
};
|
|
10485
10703
|
var parseImgContent = (s, t, cellAttrs) => {
|
|
10486
10704
|
consume(s);
|
|
10487
10705
|
const img = {
|
|
@@ -10489,24 +10707,54 @@ var parseImgContent = (s, t, cellAttrs) => {
|
|
|
10489
10707
|
src: cellAttrs["src"] ?? t.attrs["src"] ?? "",
|
|
10490
10708
|
scale: t.attrs["scale"]
|
|
10491
10709
|
};
|
|
10492
|
-
|
|
10493
|
-
if (nxt?.type === "close" && nxt.tag === "IMG") consume(s);
|
|
10710
|
+
consumeClose(s, "IMG");
|
|
10494
10711
|
return img;
|
|
10495
10712
|
};
|
|
10496
|
-
var
|
|
10497
|
-
if (
|
|
10498
|
-
if (
|
|
10499
|
-
|
|
10713
|
+
var scanCellTable = (s, t, fontStack, st) => {
|
|
10714
|
+
if (st.kind === "image" || st.kind === "table") throw parseError(s, t, MSG_SYNTAX_ERROR);
|
|
10715
|
+
if (st.textNonSpace) throw parseError(s, t, MSG_TEXT_BEFORE_TABLE);
|
|
10716
|
+
const tbl = parseTable(s, fontStack);
|
|
10717
|
+
st.kind = "table";
|
|
10718
|
+
return [tbl];
|
|
10719
|
+
};
|
|
10720
|
+
var scanCellText = (s, t, fontStack, st) => {
|
|
10721
|
+
const start = s.pos;
|
|
10500
10722
|
const txt = parseText(s, fontStack);
|
|
10723
|
+
if (s.pos === start) throw parseError(s, t, MSG_SYNTAX_ERROR);
|
|
10724
|
+
if (txt.items.some((i) => i.text !== void 0 && nonSpace(i.text))) st.textNonSpace = true;
|
|
10725
|
+
st.kind = "text";
|
|
10501
10726
|
return txt.items.length > 0 ? [txt] : [];
|
|
10502
10727
|
};
|
|
10728
|
+
var scanAfterTable = (s, t, st) => {
|
|
10729
|
+
if (t.type !== "text") throw parseError(s, t, st.afterNonSpace ? MSG_TEXT_AFTER_TABLE : MSG_SYNTAX_ERROR);
|
|
10730
|
+
consume(s);
|
|
10731
|
+
if (nonSpace(t.value)) st.afterNonSpace = true;
|
|
10732
|
+
return [];
|
|
10733
|
+
};
|
|
10734
|
+
var scanCellImage = (s, t, cellAttrs, st) => {
|
|
10735
|
+
if (st.kind !== "none") throw parseError(s, t, MSG_SYNTAX_ERROR);
|
|
10736
|
+
st.kind = "image";
|
|
10737
|
+
return [parseImgContent(s, t, cellAttrs)];
|
|
10738
|
+
};
|
|
10739
|
+
var scanCellItem = (s, t, cellAttrs, fontStack, st) => {
|
|
10740
|
+
if (st.kind === "table") return scanAfterTable(s, t, st);
|
|
10741
|
+
if (t.type === "open" && t.tag === "TABLE") return scanCellTable(s, t, fontStack, st);
|
|
10742
|
+
if (t.type === "open" && t.tag === "IMG") return scanCellImage(s, t, cellAttrs, st);
|
|
10743
|
+
if (st.kind === "image") throw parseError(s, t, MSG_SYNTAX_ERROR);
|
|
10744
|
+
return scanCellText(s, t, fontStack, st);
|
|
10745
|
+
};
|
|
10746
|
+
var endsCell = (s, t, st) => {
|
|
10747
|
+
if (t.type !== "close") return false;
|
|
10748
|
+
const afterText = st.kind === "table" && st.afterNonSpace;
|
|
10749
|
+
if (t.tag === "TD" && !afterText) return true;
|
|
10750
|
+
throw parseError(s, t, afterText ? MSG_TEXT_AFTER_TABLE : MSG_SYNTAX_ERROR);
|
|
10751
|
+
};
|
|
10503
10752
|
var parseCellContent = (s, cellAttrs, fontStack) => {
|
|
10504
10753
|
const content = [];
|
|
10505
|
-
|
|
10506
|
-
|
|
10507
|
-
if (
|
|
10508
|
-
|
|
10509
|
-
content.push(...parseCellItem(s, t, cellAttrs, fontStack));
|
|
10754
|
+
const st = { kind: "none", textNonSpace: false, afterNonSpace: false };
|
|
10755
|
+
for (let t = peek(s); t !== void 0; t = peek(s)) {
|
|
10756
|
+
if (endsCell(s, t, st)) break;
|
|
10757
|
+
content.push(...scanCellItem(s, t, cellAttrs, fontStack, st));
|
|
10510
10758
|
}
|
|
10511
10759
|
const nxt = peek(s);
|
|
10512
10760
|
if (nxt?.type === "close" && nxt.tag === "TD") consume(s);
|
|
@@ -10514,134 +10762,85 @@ var parseCellContent = (s, cellAttrs, fontStack) => {
|
|
|
10514
10762
|
if (tbl !== void 0) return [tbl];
|
|
10515
10763
|
return content;
|
|
10516
10764
|
};
|
|
10517
|
-
var parseFixedSize = (a) => a["fixedsize"]?.toUpperCase() === "TRUE" ? true : void 0;
|
|
10518
|
-
var parseTitle = (a) => a["title"] !== void 0 ? a["title"] : a["tooltip"];
|
|
10519
|
-
var parseSides = (v) => {
|
|
10520
|
-
if (v === void 0) return void 0;
|
|
10521
|
-
let flags = 0;
|
|
10522
|
-
for (const c of v.toLowerCase()) {
|
|
10523
|
-
if (c === "l") flags |= BORDER_LEFT;
|
|
10524
|
-
else if (c === "t") flags |= BORDER_TOP;
|
|
10525
|
-
else if (c === "r") flags |= BORDER_RIGHT;
|
|
10526
|
-
else if (c === "b") flags |= BORDER_BOTTOM;
|
|
10527
|
-
}
|
|
10528
|
-
if (flags === 0 || flags === BORDER_MASK) return void 0;
|
|
10529
|
-
return flags;
|
|
10530
|
-
};
|
|
10531
|
-
var parseGradientAngle = (v) => {
|
|
10532
|
-
if (v === void 0) return void 0;
|
|
10533
|
-
const n = parseInt(v, 10);
|
|
10534
|
-
if (isNaN(n) || String(n) !== v.trim()) return void 0;
|
|
10535
|
-
if (n < 0 || n > 360) return void 0;
|
|
10536
|
-
return n;
|
|
10537
|
-
};
|
|
10538
|
-
var parseColumns = (v) => v === "*" ? true : void 0;
|
|
10539
|
-
var parseRows = (v) => v === "*" ? true : void 0;
|
|
10540
|
-
var buildCell = (content, a) => ({
|
|
10541
|
-
kind: "cell",
|
|
10542
|
-
content,
|
|
10543
|
-
port: a["port"],
|
|
10544
|
-
align: parseAlign(a["align"] !== void 0 ? a["align"] : ""),
|
|
10545
|
-
valign: parseVAlign(a["valign"] !== void 0 ? a["valign"] : ""),
|
|
10546
|
-
balign: parseAlign(a["balign"] !== void 0 ? a["balign"] : ""),
|
|
10547
|
-
bgcolor: a["bgcolor"],
|
|
10548
|
-
color: a["color"],
|
|
10549
|
-
border: num(a["border"]),
|
|
10550
|
-
cellpadding: num(a["cellpadding"]),
|
|
10551
|
-
cellspacing: num(a["cellspacing"]),
|
|
10552
|
-
sides: parseSides(a["sides"]),
|
|
10553
|
-
gradientangle: parseGradientAngle(a["gradientangle"]),
|
|
10554
|
-
style: a["style"],
|
|
10555
|
-
width: num(a["width"]),
|
|
10556
|
-
height: num(a["height"]),
|
|
10557
|
-
fixedsize: parseFixedSize(a),
|
|
10558
|
-
colspan: num(a["colspan"]),
|
|
10559
|
-
rowspan: num(a["rowspan"]),
|
|
10560
|
-
href: anchorAttr(a["href"]),
|
|
10561
|
-
title: parseTitle(a),
|
|
10562
|
-
target: anchorAttr(a["target"]),
|
|
10563
|
-
id: a["id"]
|
|
10564
|
-
});
|
|
10565
10765
|
var parseCell = (s, attrs, fontStack) => buildCell(parseCellContent(s, attrs, fontStack), attrs);
|
|
10566
|
-
var
|
|
10766
|
+
var parseRowVr = (s, t, cells) => {
|
|
10767
|
+
const prev = cells[cells.length - 1];
|
|
10768
|
+
if (prev === void 0) throw parseError(s, t, MSG_SYNTAX_ERROR);
|
|
10769
|
+
consume(s);
|
|
10770
|
+
consumeClose(s, "VR");
|
|
10771
|
+
prev.vruled = true;
|
|
10772
|
+
};
|
|
10773
|
+
var scanRowCell = (s, t, fontStack, rs) => {
|
|
10567
10774
|
if (t.type === "open" && t.tag === "TD") {
|
|
10568
10775
|
consume(s);
|
|
10569
|
-
cells.push(parseCell(s, t.attrs, fontStack));
|
|
10570
|
-
|
|
10776
|
+
rs.cells.push(parseCell(s, t.attrs, fontStack));
|
|
10777
|
+
rs.needCell = false;
|
|
10778
|
+
} else if (t.type === "open" && t.tag === "VR" && !rs.needCell) {
|
|
10779
|
+
parseRowVr(s, t, rs.cells);
|
|
10780
|
+
rs.needCell = true;
|
|
10781
|
+
} else {
|
|
10782
|
+
throw parseError(s, t, MSG_SYNTAX_ERROR);
|
|
10571
10783
|
}
|
|
10572
|
-
|
|
10784
|
+
};
|
|
10785
|
+
var scanRowToken = (s, t, fontStack, rs) => {
|
|
10786
|
+
if (t.type === "text") {
|
|
10573
10787
|
consume(s);
|
|
10574
|
-
|
|
10575
|
-
if (nxt?.type === "close" && nxt.tag === "VR") consume(s);
|
|
10576
|
-
const prev = cells[cells.length - 1];
|
|
10577
|
-
if (prev === void 0) throw new HtmlParseError("VR");
|
|
10578
|
-
prev.vruled = true;
|
|
10579
|
-
return;
|
|
10788
|
+
return false;
|
|
10580
10789
|
}
|
|
10581
|
-
|
|
10790
|
+
if (t.type !== "close" || t.tag !== "TR") {
|
|
10791
|
+
scanRowCell(s, t, fontStack, rs);
|
|
10792
|
+
return false;
|
|
10793
|
+
}
|
|
10794
|
+
if (rs.cells.length === 0 || rs.needCell) throw parseError(s, t, MSG_SYNTAX_ERROR);
|
|
10795
|
+
return true;
|
|
10582
10796
|
};
|
|
10583
10797
|
var parseRow = (s, fontStack) => {
|
|
10584
|
-
const
|
|
10585
|
-
|
|
10586
|
-
|
|
10587
|
-
if (!t) break;
|
|
10588
|
-
if (t.type === "close" && t.tag === "TR") break;
|
|
10589
|
-
processRowToken(s, t, cells, fontStack);
|
|
10798
|
+
const rs = { cells: [], needCell: false };
|
|
10799
|
+
for (let t = peek(s); t !== void 0; t = peek(s)) {
|
|
10800
|
+
if (scanRowToken(s, t, fontStack, rs)) break;
|
|
10590
10801
|
}
|
|
10591
10802
|
const nxt = peek(s);
|
|
10592
10803
|
if (nxt?.type === "close" && nxt.tag === "TR") consume(s);
|
|
10593
|
-
return { cells };
|
|
10804
|
+
return { cells: rs.cells };
|
|
10805
|
+
};
|
|
10806
|
+
var scanTableRow = (s, t, fontStack, ts) => {
|
|
10807
|
+
if (t.type === "open" && t.tag === "TR") {
|
|
10808
|
+
consume(s);
|
|
10809
|
+
ts.rows.push(parseTableRow(s, fontStack, ts));
|
|
10810
|
+
ts.needRow = false;
|
|
10811
|
+
} else if (t.type === "open" && t.tag === "HR" && ts.rows.length > 0 && !ts.needRow) {
|
|
10812
|
+
consumeRowHr(s, ts.rows);
|
|
10813
|
+
ts.needRow = true;
|
|
10814
|
+
} else {
|
|
10815
|
+
throw parseError(s, t, MSG_SYNTAX_ERROR);
|
|
10816
|
+
}
|
|
10817
|
+
};
|
|
10818
|
+
var scanTableToken = (s, t, fontStack, ts) => {
|
|
10819
|
+
if (t.type === "text") {
|
|
10820
|
+
consume(s);
|
|
10821
|
+
return false;
|
|
10822
|
+
}
|
|
10823
|
+
if (t.type !== "close" || t.tag !== "TABLE") {
|
|
10824
|
+
scanTableRow(s, t, fontStack, ts);
|
|
10825
|
+
return false;
|
|
10826
|
+
}
|
|
10827
|
+
if (ts.rows.length === 0 || ts.needRow) throw parseError(s, t, MSG_SYNTAX_ERROR);
|
|
10828
|
+
consume(s);
|
|
10829
|
+
return true;
|
|
10594
10830
|
};
|
|
10595
|
-
var buildTable = (rows, a) => ({
|
|
10596
|
-
kind: "table",
|
|
10597
|
-
rows,
|
|
10598
|
-
border: num(a["border"]),
|
|
10599
|
-
cellborder: num(a["cellborder"]),
|
|
10600
|
-
cellspacing: num(a["cellspacing"]),
|
|
10601
|
-
cellpadding: num(a["cellpadding"]),
|
|
10602
|
-
bgcolor: a["bgcolor"],
|
|
10603
|
-
color: a["color"],
|
|
10604
|
-
style: a["style"],
|
|
10605
|
-
align: parseAlign(a["align"] !== void 0 ? a["align"] : ""),
|
|
10606
|
-
valign: parseVAlign(a["valign"] !== void 0 ? a["valign"] : ""),
|
|
10607
|
-
fixedsize: parseFixedSize(a),
|
|
10608
|
-
width: num(a["width"]),
|
|
10609
|
-
height: num(a["height"]),
|
|
10610
|
-
href: anchorAttr(a["href"]),
|
|
10611
|
-
title: parseTitle(a),
|
|
10612
|
-
target: anchorAttr(a["target"]),
|
|
10613
|
-
id: a["id"],
|
|
10614
|
-
port: a["port"],
|
|
10615
|
-
sides: parseSides(a["sides"]),
|
|
10616
|
-
gradientangle: parseGradientAngle(a["gradientangle"]),
|
|
10617
|
-
vrule: parseColumns(a["columns"]),
|
|
10618
|
-
hrule: parseRows(a["rows"])
|
|
10619
|
-
});
|
|
10620
10831
|
var parseTable = (s, fontStack) => {
|
|
10621
10832
|
const open = consume(s);
|
|
10622
10833
|
if (open.type !== "open" || open.tag !== "TABLE") throw new HtmlParseError("TABLE");
|
|
10623
|
-
const
|
|
10624
|
-
|
|
10625
|
-
|
|
10626
|
-
|
|
10627
|
-
|
|
10628
|
-
|
|
10629
|
-
|
|
10630
|
-
|
|
10631
|
-
break;
|
|
10632
|
-
}
|
|
10633
|
-
if (t.type === "open" && t.tag === "TR") {
|
|
10634
|
-
consume(s);
|
|
10635
|
-
rows.push(parseTableRow(s, fontStack, { hrule, vrule }));
|
|
10636
|
-
continue;
|
|
10637
|
-
}
|
|
10638
|
-
if (t.type === "open" && t.tag === "HR") {
|
|
10639
|
-
consumeRowHr(s, rows);
|
|
10640
|
-
continue;
|
|
10641
|
-
}
|
|
10642
|
-
consume(s);
|
|
10834
|
+
const ts = {
|
|
10835
|
+
rows: [],
|
|
10836
|
+
needRow: false,
|
|
10837
|
+
hrule: parseRows(open.attrs["rows"]) === true,
|
|
10838
|
+
vrule: parseColumns(open.attrs["columns"]) === true
|
|
10839
|
+
};
|
|
10840
|
+
for (let t = peek(s); t !== void 0; t = peek(s)) {
|
|
10841
|
+
if (scanTableToken(s, t, fontStack, ts)) break;
|
|
10643
10842
|
}
|
|
10644
|
-
return buildTable(rows, open.attrs);
|
|
10843
|
+
return buildTable(ts.rows, open.attrs);
|
|
10645
10844
|
};
|
|
10646
10845
|
var parseTableRow = (s, fontStack, opts) => {
|
|
10647
10846
|
const row = parseRow(s, fontStack);
|
|
@@ -10651,11 +10850,9 @@ var parseTableRow = (s, fontStack, opts) => {
|
|
|
10651
10850
|
};
|
|
10652
10851
|
var consumeRowHr = (s, rows) => {
|
|
10653
10852
|
consume(s);
|
|
10654
|
-
|
|
10655
|
-
if (nxt?.type === "close" && nxt.tag === "HR") consume(s);
|
|
10853
|
+
consumeClose(s, "HR");
|
|
10656
10854
|
const prev = rows[rows.length - 1];
|
|
10657
|
-
if (prev
|
|
10658
|
-
prev.ruled = true;
|
|
10855
|
+
if (prev !== void 0) prev.ruled = true;
|
|
10659
10856
|
};
|
|
10660
10857
|
var findFirstRealToken = (tokens, start) => {
|
|
10661
10858
|
for (let i = start; i < tokens.length; i++) {
|
|
@@ -10671,34 +10868,61 @@ var skipLeadingWs = (s) => {
|
|
|
10671
10868
|
consume(s);
|
|
10672
10869
|
}
|
|
10673
10870
|
};
|
|
10871
|
+
var finishTableLabel = (s) => {
|
|
10872
|
+
let afterNonSpace = false;
|
|
10873
|
+
for (let t = peek(s); t?.type === "text"; t = peek(s)) {
|
|
10874
|
+
consume(s);
|
|
10875
|
+
if (nonSpace(t.value)) afterNonSpace = true;
|
|
10876
|
+
}
|
|
10877
|
+
const nxt = peek(s);
|
|
10878
|
+
if (nxt === void 0) return;
|
|
10879
|
+
if (afterNonSpace) throw parseError(s, nxt, MSG_TEXT_AFTER_TABLE);
|
|
10880
|
+
if (nxt.type !== "close" || nxt.tag !== "HTML") throw parseError(s, nxt, MSG_SYNTAX_ERROR);
|
|
10881
|
+
consume(s);
|
|
10882
|
+
};
|
|
10674
10883
|
var parseTableLabel = (s, fontStack) => {
|
|
10675
10884
|
skipLeadingWs(s);
|
|
10676
10885
|
const table = parseTable(s, fontStack);
|
|
10677
|
-
|
|
10678
|
-
if (nxt?.type === "close" && nxt.tag === "HTML") consume(s);
|
|
10886
|
+
finishTableLabel(s);
|
|
10679
10887
|
return { kind: "table", table };
|
|
10680
10888
|
};
|
|
10681
|
-
var
|
|
10682
|
-
const wrapped = `<HTML>${src}</HTML>`;
|
|
10683
|
-
const tokens = tokenize(wrapped);
|
|
10684
|
-
const s = { tokens, pos: 0 };
|
|
10685
|
-
const fontStack = [{}];
|
|
10686
|
-
const htmlOpen = consume(s);
|
|
10687
|
-
if (htmlOpen.type !== "open" || htmlOpen.tag !== "HTML") throw new HtmlParseError("HTML");
|
|
10688
|
-
const firstReal = findFirstRealToken(tokens, s.pos);
|
|
10689
|
-
if (firstReal?.type === "open" && firstReal.tag === "TABLE") {
|
|
10690
|
-
return parseTableLabel(s, fontStack);
|
|
10691
|
-
}
|
|
10889
|
+
var parseTextLabel = (s, fontStack) => {
|
|
10692
10890
|
const texts = [];
|
|
10693
10891
|
const txt = parseText(s, fontStack);
|
|
10694
10892
|
if (txt.items.length > 0) texts.push(txt);
|
|
10695
10893
|
const nxt = peek(s);
|
|
10696
|
-
if (nxt
|
|
10697
|
-
|
|
10894
|
+
if (nxt === void 0) return { kind: "text", texts };
|
|
10895
|
+
if (nxt.type === "open" && nxt.tag === "TABLE") {
|
|
10896
|
+
if (txt.items.some((i) => i.text !== void 0 && nonSpace(i.text))) {
|
|
10897
|
+
throw parseError(s, nxt, MSG_TEXT_BEFORE_TABLE);
|
|
10898
|
+
}
|
|
10899
|
+
throw new HtmlParseError("TABLE");
|
|
10698
10900
|
}
|
|
10699
|
-
if (nxt
|
|
10901
|
+
if (nxt.type !== "close" || nxt.tag !== "HTML") throw parseError(s, nxt, MSG_SYNTAX_ERROR);
|
|
10902
|
+
consume(s);
|
|
10700
10903
|
return { kind: "text", texts };
|
|
10701
10904
|
};
|
|
10905
|
+
var parseTokens = (s) => {
|
|
10906
|
+
const fontStack = [{}];
|
|
10907
|
+
const htmlOpen = consume(s);
|
|
10908
|
+
if (htmlOpen.type !== "open" || htmlOpen.tag !== "HTML") throw new HtmlParseError("HTML");
|
|
10909
|
+
const firstReal = findFirstRealToken(s.tokens, s.pos);
|
|
10910
|
+
if (firstReal?.type === "open" && firstReal.tag === "TABLE") return parseTableLabel(s, fontStack);
|
|
10911
|
+
return parseTextLabel(s, fontStack);
|
|
10912
|
+
};
|
|
10913
|
+
var parseHtmlLabel = (src) => {
|
|
10914
|
+
const { tokens, error } = tokenizeDeferred(`<HTML>${src}</HTML>`);
|
|
10915
|
+
const s = { tokens, pos: 0, pending: error };
|
|
10916
|
+
let label;
|
|
10917
|
+
try {
|
|
10918
|
+
label = parseTokens(s);
|
|
10919
|
+
} catch (e) {
|
|
10920
|
+
if (error !== void 0 && s.pos >= tokens.length) throw error;
|
|
10921
|
+
throw e;
|
|
10922
|
+
}
|
|
10923
|
+
if (error !== void 0) throw error;
|
|
10924
|
+
return label;
|
|
10925
|
+
};
|
|
10702
10926
|
|
|
10703
10927
|
// src/gvc/usershape.ts
|
|
10704
10928
|
var activeSizer = null;
|
|
@@ -10712,28 +10936,80 @@ function findImageSize(src) {
|
|
|
10712
10936
|
return activeSizer !== null ? activeSizer(src) : null;
|
|
10713
10937
|
}
|
|
10714
10938
|
|
|
10939
|
+
// src/common/pointset.ts
|
|
10940
|
+
function cmpPair(a, b) {
|
|
10941
|
+
if (a.x > b.x) return 1;
|
|
10942
|
+
if (a.x < b.x) return -1;
|
|
10943
|
+
if (a.y > b.y) return 1;
|
|
10944
|
+
if (a.y < b.y) return -1;
|
|
10945
|
+
return 0;
|
|
10946
|
+
}
|
|
10947
|
+
var PointSet = class {
|
|
10948
|
+
byX = /* @__PURE__ */ new Map();
|
|
10949
|
+
n = 0;
|
|
10950
|
+
/**
|
|
10951
|
+
* Insert (x, y). A duplicate keeps the point inserted first, as `dtinsert`
|
|
10952
|
+
* returns the existing object and the new one is freed.
|
|
10953
|
+
* @see lib/common/pointset.c:addPS
|
|
10954
|
+
*/
|
|
10955
|
+
addPS(x, y) {
|
|
10956
|
+
let col = this.byX.get(x);
|
|
10957
|
+
if (col === void 0) {
|
|
10958
|
+
col = /* @__PURE__ */ new Map();
|
|
10959
|
+
this.byX.set(x, col);
|
|
10960
|
+
}
|
|
10961
|
+
if (col.has(y)) return;
|
|
10962
|
+
col.set(y, { x, y });
|
|
10963
|
+
this.n++;
|
|
10964
|
+
}
|
|
10965
|
+
/** @see lib/common/pointset.c:inPS */
|
|
10966
|
+
inPS(pt) {
|
|
10967
|
+
return this.byX.get(pt.x)?.has(pt.y) ?? false;
|
|
10968
|
+
}
|
|
10969
|
+
/** @see lib/common/pointset.c:isInPS */
|
|
10970
|
+
isInPS(x, y) {
|
|
10971
|
+
return this.byX.get(x)?.has(y) ?? false;
|
|
10972
|
+
}
|
|
10973
|
+
/** @see lib/common/pointset.c:sizeOf */
|
|
10974
|
+
sizeOf() {
|
|
10975
|
+
return this.n;
|
|
10976
|
+
}
|
|
10977
|
+
/**
|
|
10978
|
+
* The points in dictionary order (`dtflatten` walks the ordered set).
|
|
10979
|
+
* @see lib/common/pointset.c:pointsOf
|
|
10980
|
+
*/
|
|
10981
|
+
pointsOf() {
|
|
10982
|
+
const pts = [];
|
|
10983
|
+
for (const col of this.byX.values()) {
|
|
10984
|
+
for (const p of col.values()) pts.push({ x: p.x, y: p.y });
|
|
10985
|
+
}
|
|
10986
|
+
return pts.sort(cmpPair);
|
|
10987
|
+
}
|
|
10988
|
+
};
|
|
10989
|
+
|
|
10715
10990
|
// src/common/htmltable.ts
|
|
10716
10991
|
var DEFAULT_BORDER = 1;
|
|
10717
10992
|
var DEFAULT_CELLPADDING = 2;
|
|
10718
10993
|
var DEFAULT_CELLSPACING = 2;
|
|
10719
10994
|
var DEFAULT_FONTSIZE = 14;
|
|
10720
|
-
var findCol = (
|
|
10995
|
+
var findCol = (ps, row, startCol, colspan, rowspan) => {
|
|
10721
10996
|
let col = startCol;
|
|
10722
|
-
|
|
10723
|
-
|
|
10724
|
-
|
|
10725
|
-
|
|
10726
|
-
|
|
10727
|
-
|
|
10728
|
-
|
|
10729
|
-
|
|
10730
|
-
|
|
10997
|
+
let notFound = true;
|
|
10998
|
+
const end = colspan - 1;
|
|
10999
|
+
while (notFound) {
|
|
11000
|
+
const lastc = col + end;
|
|
11001
|
+
let c;
|
|
11002
|
+
for (c = lastc; c >= col; c--) {
|
|
11003
|
+
if (ps.isInPS(c, row)) break;
|
|
11004
|
+
}
|
|
11005
|
+
if (c >= col) col = c + 1;
|
|
11006
|
+
else notFound = false;
|
|
11007
|
+
}
|
|
11008
|
+
for (let j = col; j < col + colspan; j++) {
|
|
11009
|
+
for (let i = row; i < row + rowspan; i++) {
|
|
11010
|
+
ps.addPS(j, i);
|
|
10731
11011
|
}
|
|
10732
|
-
if (!conflict) break;
|
|
10733
11012
|
}
|
|
10734
|
-
for (let c = col; c < col + colspan; c++)
|
|
10735
|
-
for (let r = row; r < row + rowspan; r++)
|
|
10736
|
-
used.add(`${c},${r}`);
|
|
10737
11013
|
return col;
|
|
10738
11014
|
};
|
|
10739
11015
|
var DEFAULT_SIZE_ENV = { fontsize: DEFAULT_FONTSIZE, fontname: "" };
|
|
@@ -10812,29 +11088,32 @@ var sizeTextContent = (texts, measurer, env = DEFAULT_SIZE_ENV) => {
|
|
|
10812
11088
|
if (lines.length === 1) h = lines[0].items.length > 0 ? lines[0].mxysize : DEFAULT_FONTSIZE;
|
|
10813
11089
|
return { w, h };
|
|
10814
11090
|
};
|
|
11091
|
+
var missingImages = /* @__PURE__ */ new WeakSet();
|
|
10815
11092
|
var sizeHtmlImg = (img, imageSizer) => {
|
|
10816
|
-
if (img.width !== void 0 && img.height !== void 0) return;
|
|
11093
|
+
if (img.width !== void 0 && img.height !== void 0) return missingImages.has(img) ? 1 : 0;
|
|
10817
11094
|
const sz = imageSizer !== void 0 ? imageSizer(img.src) : findImageSize(img.src);
|
|
10818
11095
|
if (sz !== null) {
|
|
10819
11096
|
img.width = sz.w;
|
|
10820
11097
|
img.height = sz.h;
|
|
10821
|
-
return;
|
|
11098
|
+
return 0;
|
|
10822
11099
|
}
|
|
10823
11100
|
console.error(`Error: No or improper image file="${img.src}"`);
|
|
10824
11101
|
img.width = 0;
|
|
10825
11102
|
img.height = 0;
|
|
11103
|
+
missingImages.add(img);
|
|
11104
|
+
return 1;
|
|
10826
11105
|
};
|
|
10827
11106
|
var sizeContentItem = (item, measurer, env) => {
|
|
10828
|
-
if (item.kind === "text") return sizeTextContent([item], measurer, env);
|
|
11107
|
+
if (item.kind === "text") return { ...sizeTextContent([item], measurer, env), rv: 0 };
|
|
10829
11108
|
if (item.kind === "table") {
|
|
10830
|
-
sizeTableInner(item, measurer, env);
|
|
10831
|
-
return item.dimen !== void 0 ? item.dimen : { w: 0, h: 0 };
|
|
11109
|
+
const rv = sizeTableInner(item, measurer, env);
|
|
11110
|
+
return { ...item.dimen !== void 0 ? item.dimen : { w: 0, h: 0 }, rv };
|
|
10832
11111
|
}
|
|
10833
11112
|
if (item.kind === "image") {
|
|
10834
|
-
sizeHtmlImg(item, env.imageSizer);
|
|
10835
|
-
return { w: item.width ?? 0, h: item.height ?? 0 };
|
|
11113
|
+
const rv = sizeHtmlImg(item, env.imageSizer);
|
|
11114
|
+
return { w: item.width ?? 0, h: item.height ?? 0, rv };
|
|
10836
11115
|
}
|
|
10837
|
-
return { w: 0, h: 0 };
|
|
11116
|
+
return { w: 0, h: 0, rv: 0 };
|
|
10838
11117
|
};
|
|
10839
11118
|
var cellPad = (cell2, tbl) => cell2.cellpadding !== void 0 ? cell2.cellpadding : tbl.cellpadding !== void 0 ? tbl.cellpadding : DEFAULT_CELLPADDING;
|
|
10840
11119
|
var cellBorder = (cell2, tbl) => {
|
|
@@ -10844,27 +11123,60 @@ var cellBorder = (cell2, tbl) => {
|
|
|
10844
11123
|
if (tbl.border !== void 0) return tbl.border;
|
|
10845
11124
|
return DEFAULT_BORDER;
|
|
10846
11125
|
};
|
|
11126
|
+
function inheritTablePenColor(tbl, parentColor) {
|
|
11127
|
+
if (tbl.color === void 0) tbl.color = parentColor;
|
|
11128
|
+
const tblColor = tbl.color;
|
|
11129
|
+
for (const row of tbl.rows) {
|
|
11130
|
+
for (const cell2 of row.cells) {
|
|
11131
|
+
if (cell2.color === void 0) cell2.color = tblColor;
|
|
11132
|
+
for (const item of cell2.content) {
|
|
11133
|
+
if (item.kind === "table") inheritTablePenColor(item, cell2.color);
|
|
11134
|
+
}
|
|
11135
|
+
}
|
|
11136
|
+
}
|
|
11137
|
+
}
|
|
11138
|
+
var WARN_CELL_TOO_SMALL = "Warning: cell size too small for content";
|
|
11139
|
+
var WARN_CELL_UNSPECIFIED = "Warning: fixed cell size with unspecified width or height";
|
|
11140
|
+
var WARN_TABLE_TOO_SMALL = "Warning: table size too small for content";
|
|
11141
|
+
var WARN_TABLE_UNSPECIFIED = "Warning: fixed table size with unspecified width or height";
|
|
11142
|
+
var sizeWarned = /* @__PURE__ */ new WeakSet();
|
|
11143
|
+
var fixedCellCheck = (cell2, sz, warn) => {
|
|
11144
|
+
if (!cell2.fixedsize) return { rv: 0, zero: false };
|
|
11145
|
+
if (cell2.width && cell2.height) {
|
|
11146
|
+
const small = (cell2.width < sz.w || cell2.height < sz.h) && cell2.content[0]?.kind !== "image";
|
|
11147
|
+
if (small && warn) console.warn(WARN_CELL_TOO_SMALL);
|
|
11148
|
+
return { rv: small ? 1 : 0, zero: true };
|
|
11149
|
+
}
|
|
11150
|
+
if (warn) console.warn(WARN_CELL_UNSPECIFIED);
|
|
11151
|
+
return { rv: 1, zero: false };
|
|
11152
|
+
};
|
|
10847
11153
|
var getCellSize = (cell2, tbl, measurer, env) => {
|
|
10848
11154
|
const margin = 2 * (cellPad(cell2, tbl) + cellBorder(cell2, tbl));
|
|
10849
|
-
let cw = 0, ch = 0;
|
|
11155
|
+
let cw = 0, ch = 0, rv = 0;
|
|
10850
11156
|
for (const item of cell2.content) {
|
|
10851
11157
|
const s = sizeContentItem(item, measurer, env);
|
|
10852
11158
|
cw = Math.max(cw, s.w);
|
|
10853
11159
|
ch += s.h;
|
|
11160
|
+
rv |= s.rv;
|
|
10854
11161
|
}
|
|
10855
11162
|
let szx = cw + margin;
|
|
10856
11163
|
let szy = ch + margin;
|
|
10857
|
-
|
|
11164
|
+
const warn = !sizeWarned.has(cell2);
|
|
11165
|
+
sizeWarned.add(cell2);
|
|
11166
|
+
const fixed = fixedCellCheck(cell2, { w: szx, h: szy }, warn);
|
|
11167
|
+
rv |= fixed.rv;
|
|
11168
|
+
if (fixed.zero) {
|
|
10858
11169
|
szx = 0;
|
|
10859
11170
|
szy = 0;
|
|
10860
11171
|
}
|
|
10861
11172
|
const bw = cell2.width !== void 0 ? cell2.width : 0;
|
|
10862
11173
|
const bh = cell2.height !== void 0 ? cell2.height : 0;
|
|
10863
|
-
return { w: Math.max(szx, bw), h: Math.max(szy, bh) };
|
|
11174
|
+
return { w: Math.max(szx, bw), h: Math.max(szy, bh), rv };
|
|
10864
11175
|
};
|
|
10865
11176
|
var buildLayouts = (tbl, measurer, env) => {
|
|
10866
11177
|
const entries = [];
|
|
10867
|
-
|
|
11178
|
+
let rv = 0;
|
|
11179
|
+
const ps = new PointSet();
|
|
10868
11180
|
let rowIdx = 0;
|
|
10869
11181
|
for (const row of tbl.rows) {
|
|
10870
11182
|
let col = 0;
|
|
@@ -10874,14 +11186,15 @@ var buildLayouts = (tbl, measurer, env) => {
|
|
|
10874
11186
|
}
|
|
10875
11187
|
const colspan = c.colspan !== void 0 ? c.colspan : 1;
|
|
10876
11188
|
const rowspan = c.rowspan !== void 0 ? c.rowspan : 1;
|
|
10877
|
-
const { w, h } = getCellSize(c, tbl, measurer, env);
|
|
10878
|
-
|
|
11189
|
+
const { w, h, rv: cellRv } = getCellSize(c, tbl, measurer, env);
|
|
11190
|
+
rv |= cellRv;
|
|
11191
|
+
col = findCol(ps, rowIdx, col, colspan, rowspan);
|
|
10879
11192
|
entries.push({ cell: c, row: rowIdx, col, colspan, rowspan, w, h });
|
|
10880
11193
|
col += colspan;
|
|
10881
11194
|
}
|
|
10882
11195
|
rowIdx++;
|
|
10883
11196
|
}
|
|
10884
|
-
return entries;
|
|
11197
|
+
return { entries, rv };
|
|
10885
11198
|
};
|
|
10886
11199
|
var setColWidths = (entries, ncols, spacing) => {
|
|
10887
11200
|
const widths = new Array(ncols + 1).fill(0);
|
|
@@ -10934,21 +11247,34 @@ var sumTableDims = (a) => {
|
|
|
10934
11247
|
var layoutHtmlTable = (tbl, measurer, env = DEFAULT_SIZE_ENV) => {
|
|
10935
11248
|
const spacing = getSpacing(tbl);
|
|
10936
11249
|
const border = getBorder(tbl);
|
|
10937
|
-
const entries = buildLayouts(tbl, measurer, env);
|
|
11250
|
+
const { entries, rv } = buildLayouts(tbl, measurer, env);
|
|
10938
11251
|
if (entries.length === 0) {
|
|
10939
|
-
return { entries, widths: [], heights: [], spacing, border };
|
|
11252
|
+
return { entries, widths: [], heights: [], spacing, border, rv };
|
|
10940
11253
|
}
|
|
10941
11254
|
const ncols = Math.max(...entries.map((e) => e.col + e.colspan));
|
|
10942
11255
|
const nrows = Math.max(...entries.map((e) => e.row + e.rowspan));
|
|
10943
11256
|
const widths = setColWidths(entries, ncols, spacing);
|
|
10944
11257
|
const heights = setRowHeights(entries, nrows, spacing);
|
|
10945
|
-
return { entries, widths, heights, spacing, border };
|
|
11258
|
+
return { entries, widths, heights, spacing, border, rv };
|
|
11259
|
+
};
|
|
11260
|
+
var warnFixedTable = (tbl, dims) => {
|
|
11261
|
+
const warn = !sizeWarned.has(tbl);
|
|
11262
|
+
sizeWarned.add(tbl);
|
|
11263
|
+
if (tbl.fixedsize !== true) return 0;
|
|
11264
|
+
if (tbl.width && tbl.height) {
|
|
11265
|
+
if (tbl.width >= dims.wd && tbl.height >= dims.ht) return 0;
|
|
11266
|
+
if (warn) console.warn(WARN_TABLE_TOO_SMALL);
|
|
11267
|
+
return 1;
|
|
11268
|
+
}
|
|
11269
|
+
if (warn) console.warn(WARN_TABLE_UNSPECIFIED);
|
|
11270
|
+
return 1;
|
|
10946
11271
|
};
|
|
10947
11272
|
var sizeTableInner = (tbl, measurer, env) => {
|
|
10948
|
-
const { entries, widths, heights, spacing, border } = layoutHtmlTable(tbl, measurer, env);
|
|
11273
|
+
const { entries, widths, heights, spacing, border, rv } = layoutHtmlTable(tbl, measurer, env);
|
|
10949
11274
|
if (entries.length === 0) {
|
|
11275
|
+
const fixed2 = warnFixedTable(tbl, sumTableDims({ widths, heights, ncols: 0, nrows: 0, spacing, border }));
|
|
10950
11276
|
tbl.dimen = { w: 0, h: 0 };
|
|
10951
|
-
return;
|
|
11277
|
+
return rv | fixed2;
|
|
10952
11278
|
}
|
|
10953
11279
|
const ncols = Math.max(...entries.map((e) => e.col + e.colspan));
|
|
10954
11280
|
const nrows = Math.max(...entries.map((e) => e.row + e.rowspan));
|
|
@@ -10956,19 +11282,22 @@ var sizeTableInner = (tbl, measurer, env) => {
|
|
|
10956
11282
|
const { wd, ht } = sumTableDims({ widths, heights, ncols, nrows, spacing, border });
|
|
10957
11283
|
const baseWd = tbl.width !== void 0 ? tbl.width : 0;
|
|
10958
11284
|
const baseHt = tbl.height !== void 0 ? tbl.height : 0;
|
|
11285
|
+
const fixed = warnFixedTable(tbl, { wd, ht });
|
|
10959
11286
|
const zeroContent = isTblFixed(tbl) && baseWd !== 0 && baseHt !== 0;
|
|
10960
11287
|
tbl.dimen = {
|
|
10961
11288
|
w: Math.max(zeroContent ? 0 : wd, baseWd),
|
|
10962
11289
|
h: Math.max(zeroContent ? 0 : ht, baseHt)
|
|
10963
11290
|
};
|
|
11291
|
+
return rv | fixed;
|
|
10964
11292
|
};
|
|
10965
11293
|
var sizeHtmlLabel = (label, measurer, env = DEFAULT_SIZE_ENV) => {
|
|
10966
11294
|
if (label.kind === "table") {
|
|
10967
|
-
sizeTableInner(label.table, measurer, env);
|
|
11295
|
+
const rv = sizeTableInner(label.table, measurer, env);
|
|
10968
11296
|
label.dimen = label.table.dimen;
|
|
10969
|
-
|
|
10970
|
-
label.dimen = sizeTextContent(label.texts, measurer, env);
|
|
11297
|
+
return rv;
|
|
10971
11298
|
}
|
|
11299
|
+
label.dimen = sizeTextContent(label.texts, measurer, env);
|
|
11300
|
+
return 0;
|
|
10972
11301
|
};
|
|
10973
11302
|
|
|
10974
11303
|
// src/common/splines-constants.ts
|
|
@@ -16538,28 +16867,18 @@ function posHtmlLabel(label, finfo, measurer) {
|
|
|
16538
16867
|
if (label.kind === "table") return posHtmlTable(label.table, finfo, measurer);
|
|
16539
16868
|
return posTextLabel(label, finfo, measurer);
|
|
16540
16869
|
}
|
|
16541
|
-
|
|
16542
|
-
|
|
16543
|
-
const tblColor = tbl.color;
|
|
16544
|
-
for (const row of tbl.rows) {
|
|
16545
|
-
for (const cell2 of row.cells) {
|
|
16546
|
-
if (cell2.color === void 0) cell2.color = tblColor;
|
|
16547
|
-
for (const item of cell2.content) {
|
|
16548
|
-
if (item.kind === "table") inheritTablePenColor(item, cell2.color);
|
|
16549
|
-
}
|
|
16550
|
-
}
|
|
16551
|
-
}
|
|
16552
|
-
}
|
|
16553
|
-
function makeHtmlLabel(content, finfo, measurer) {
|
|
16870
|
+
var HTML_PARSE_FATAL = 3;
|
|
16871
|
+
function makeHtmlLabelRv(content, finfo, measurer) {
|
|
16554
16872
|
const { fontname, fontsize, fontcolor, imageSizer, pencolor } = finfo;
|
|
16555
16873
|
let lbl;
|
|
16556
16874
|
try {
|
|
16557
16875
|
lbl = parseHtmlLabel(content);
|
|
16558
|
-
} catch {
|
|
16559
|
-
|
|
16876
|
+
} catch (e) {
|
|
16877
|
+
if (e instanceof HtmlLexError) for (const line of e.diagnostics) console.error(line);
|
|
16878
|
+
return { label: makeLabel("", fontname, fontsize, fontcolor, measurer), rv: HTML_PARSE_FATAL };
|
|
16560
16879
|
}
|
|
16561
16880
|
if (lbl.kind === "table") inheritTablePenColor(lbl.table, pencolor);
|
|
16562
|
-
sizeHtmlLabel(lbl, measurer, {
|
|
16881
|
+
const rv = sizeHtmlLabel(lbl, measurer, {
|
|
16563
16882
|
fontsize,
|
|
16564
16883
|
fontname,
|
|
16565
16884
|
imageSizer
|
|
@@ -16567,7 +16886,7 @@ function makeHtmlLabel(content, finfo, measurer) {
|
|
|
16567
16886
|
const placed = posHtmlLabel(lbl, { fontname, fontsize, fontcolor }, measurer);
|
|
16568
16887
|
const dim = lbl.dimen ?? { w: 0, h: 0 };
|
|
16569
16888
|
const text = lbl.kind === "table" ? "<TABLE>" : content;
|
|
16570
|
-
return htmlTextLabel(text, { fontname, fontsize, fontcolor }, placed, dim);
|
|
16889
|
+
return { label: htmlTextLabel(text, { fontname, fontsize, fontcolor }, placed, dim), rv };
|
|
16571
16890
|
}
|
|
16572
16891
|
function htmlTextLabel(text, finfo, placed, dim) {
|
|
16573
16892
|
return {
|
|
@@ -16686,6 +17005,14 @@ function getPenColor(obj) {
|
|
|
16686
17005
|
function rootOf(obj) {
|
|
16687
17006
|
return obj instanceof Edge ? obj.tail.root : obj.root;
|
|
16688
17007
|
}
|
|
17008
|
+
function inLabelOf(obj) {
|
|
17009
|
+
if (obj instanceof Edge) {
|
|
17010
|
+
const sep = obj.head.root.kind.endsWith("undirected") ? "--" : "->";
|
|
17011
|
+
return `in label of edge ${obj.tail.name} ${sep} ${obj.head.name}`;
|
|
17012
|
+
}
|
|
17013
|
+
if (obj instanceof Graph) return `in label of graph ${obj.name}`;
|
|
17014
|
+
return `in label of node ${obj.name}`;
|
|
17015
|
+
}
|
|
16689
17016
|
function buildSpan(text, font, measured) {
|
|
16690
17017
|
return {
|
|
16691
17018
|
str: text,
|
|
@@ -16753,7 +17080,9 @@ function makeLabel(text, fontname, fontsize, fontcolor, measurer) {
|
|
|
16753
17080
|
function makeAnyLabel(content, isHtml, font, measurer, obj) {
|
|
16754
17081
|
if (isHtml && content !== "") {
|
|
16755
17082
|
const imageSizer = obj !== void 0 ? rootOf(obj).info.gvc?.imageSizer : void 0;
|
|
16756
|
-
|
|
17083
|
+
const { label, rv } = makeHtmlLabelRv(content, { ...font, pencolor: getPenColor(obj), imageSizer }, measurer);
|
|
17084
|
+
if (rv !== 0 && obj !== void 0) console.error(inLabelOf(obj));
|
|
17085
|
+
return label;
|
|
16757
17086
|
}
|
|
16758
17087
|
const subst2 = obj !== void 0 ? substObj(content, obj, false) : content;
|
|
16759
17088
|
const text = htmlEntityUTF8(subst2);
|
|
@@ -29053,18 +29382,22 @@ function dotSameports(g) {
|
|
|
29053
29382
|
function dist2(p, q) {
|
|
29054
29383
|
const dx = p.x - q.x;
|
|
29055
29384
|
const dy = p.y - q.y;
|
|
29056
|
-
return dx
|
|
29385
|
+
return fma(dx, dx, dy * dy);
|
|
29057
29386
|
}
|
|
29058
29387
|
function distPt(p, q) {
|
|
29059
29388
|
return Math.sqrt(dist2(p, q));
|
|
29060
29389
|
}
|
|
29061
|
-
function
|
|
29390
|
+
function bezier(v, t) {
|
|
29062
29391
|
const u = 1 - t;
|
|
29063
|
-
const [
|
|
29064
|
-
|
|
29065
|
-
|
|
29066
|
-
|
|
29067
|
-
|
|
29392
|
+
const x = [v[0].x, v[1].x, v[2].x, v[3].x];
|
|
29393
|
+
const y = [v[0].y, v[1].y, v[2].y, v[3].y];
|
|
29394
|
+
for (let i = 1; i <= 3; i++) {
|
|
29395
|
+
for (let j = 0; j <= 3 - i; j++) {
|
|
29396
|
+
x[j] = fma(x[j], u, t * x[j + 1]);
|
|
29397
|
+
y[j] = fma(y[j], u, t * y[j + 1]);
|
|
29398
|
+
}
|
|
29399
|
+
}
|
|
29400
|
+
return { x: x[0], y: y[0] };
|
|
29068
29401
|
}
|
|
29069
29402
|
function dotneatoClosest(spl, pt) {
|
|
29070
29403
|
let besti = 0;
|
|
@@ -29094,7 +29427,7 @@ function dotneatoClosest(spl, pt) {
|
|
|
29094
29427
|
let pt2;
|
|
29095
29428
|
for (; ; ) {
|
|
29096
29429
|
const t = (lo + hi) / 2;
|
|
29097
|
-
pt2 =
|
|
29430
|
+
pt2 = bezier(c, t);
|
|
29098
29431
|
if (Math.abs(dlo2 - dhi2) < 1 || Math.abs(hi - lo) < 1e-5) break;
|
|
29099
29432
|
if (dlo2 < dhi2) {
|
|
29100
29433
|
hi = t;
|
|
@@ -30006,9 +30339,19 @@ var ShortestHelper = class _ShortestHelper {
|
|
|
30006
30339
|
_ShortestHelper.connectAll(tris);
|
|
30007
30340
|
const ftrii = _ShortestHelper.findTri(tris, eps[0]);
|
|
30008
30341
|
const ltrii = _ShortestHelper.findTri(tris, eps[1]);
|
|
30009
|
-
if (ftrii === NO_TRI
|
|
30342
|
+
if (ftrii === NO_TRI) {
|
|
30343
|
+
console.warn("source point not in any triangle");
|
|
30344
|
+
return null;
|
|
30345
|
+
}
|
|
30346
|
+
if (ltrii === NO_TRI) {
|
|
30347
|
+
console.warn("destination point not in any triangle");
|
|
30348
|
+
return null;
|
|
30349
|
+
}
|
|
30010
30350
|
if (ftrii === ltrii) return [eps[0], eps[1]];
|
|
30011
|
-
if (!_ShortestHelper.markPath(tris, ftrii, ltrii))
|
|
30351
|
+
if (!_ShortestHelper.markPath(tris, ftrii, ltrii)) {
|
|
30352
|
+
console.warn("cannot find triangle path");
|
|
30353
|
+
return [eps[0], eps[1]];
|
|
30354
|
+
}
|
|
30012
30355
|
const epnls = [{ pp: eps[0], link: null }, { pp: eps[1], link: null }];
|
|
30013
30356
|
const dq = _ShortestHelper.initDeque(pnlps.length);
|
|
30014
30357
|
_ShortestHelper.add2dq(dq, DQ_FRONT, epnls[0]);
|
|
@@ -31990,7 +32333,7 @@ function nodeCover(n) {
|
|
|
31990
32333
|
for (let i = 0; i < NODECARD; i++) {
|
|
31991
32334
|
if (n.branch[i].child !== null) {
|
|
31992
32335
|
if (flag) {
|
|
31993
|
-
r = n.branch[i].rect;
|
|
32336
|
+
r = { boundary: [...n.branch[i].rect.boundary] };
|
|
31994
32337
|
flag = false;
|
|
31995
32338
|
} else {
|
|
31996
32339
|
r = combineRect(r, n.branch[i].rect);
|
|
@@ -33943,7 +34286,10 @@ function makeFlatLabeledEdge(g, e) {
|
|
|
33943
34286
|
info: { ...e.info, tail_port: e.info.head_port, head_port: e.info.tail_port }
|
|
33944
34287
|
};
|
|
33945
34288
|
const ps = routeFlatLabeledChannel(g, sample, ln, et);
|
|
33946
|
-
if (ps === null || ps.length === 0)
|
|
34289
|
+
if (ps === null || ps.length === 0) {
|
|
34290
|
+
e.info.lost = true;
|
|
34291
|
+
return true;
|
|
34292
|
+
}
|
|
33947
34293
|
if (!tailIsLeft) ps.reverse();
|
|
33948
34294
|
clipAndInstall(e, e.head, ps, ps.length, { ...buildDotSinfo(), ignoreSwap: true });
|
|
33949
34295
|
return true;
|
|
@@ -34256,8 +34602,8 @@ function nodeInsideFn2(box) {
|
|
|
34256
34602
|
const pw = box.penwidth ?? DEFAULT_NODEPENWIDTH;
|
|
34257
34603
|
return box.isEllipse ? makeEllipseInsideFn(halfW, halfH, pw) : makeBoxInsideFn(halfW, halfH, pw);
|
|
34258
34604
|
}
|
|
34259
|
-
function clipToNodes(
|
|
34260
|
-
const step1 = clip.tail ? bezierClipNode(
|
|
34605
|
+
function clipToNodes(bezier2, tailBox, headBox, penwidth = DEFAULT_NODEPENWIDTH, clip = CLIP_BOTH) {
|
|
34606
|
+
const step1 = clip.tail ? bezierClipNode(bezier2, tailBox.center.x, tailBox.center.y, nodeInsideFn2(tailBox), true) : bezier2;
|
|
34261
34607
|
const step2 = clip.head ? bezierClipNode(step1, headBox.center.x, headBox.center.y, nodeInsideFn2(headBox), false) : step1;
|
|
34262
34608
|
const arrowTip = step2[3];
|
|
34263
34609
|
const elen = normalArrowLen(penwidth);
|
|
@@ -34271,9 +34617,9 @@ function clipToNodes(bezier, tailBox, headBox, penwidth = DEFAULT_NODEPENWIDTH,
|
|
|
34271
34617
|
function routeWithRank(tailBox, headBox, rank3, penwidth = DEFAULT_NODEPENWIDTH, port) {
|
|
34272
34618
|
const corridor = port ? { tailP: port.tailP, headP: port.headP } : void 0;
|
|
34273
34619
|
const { startPt, endPt, boxes } = buildRankCorridor(tailBox, headBox, rank3, corridor);
|
|
34274
|
-
const
|
|
34620
|
+
const bezier2 = computeSpline(boxes, startPt, endPt);
|
|
34275
34621
|
const clip = port ? { tail: port.clipTail, head: port.clipHead } : CLIP_BOTH;
|
|
34276
|
-
const { clipped, arrowTip, arrowDir } = clipToNodes(
|
|
34622
|
+
const { clipped, arrowTip, arrowDir } = clipToNodes(bezier2, tailBox, headBox, penwidth, clip);
|
|
34277
34623
|
return { bezierPts: clipped, arrowTip, arrowDir };
|
|
34278
34624
|
}
|
|
34279
34625
|
function routeSimple(tailBox, headBox, routeBezierFn) {
|
|
@@ -36866,24 +37212,27 @@ function buildNodes(nodeArr) {
|
|
|
36866
37212
|
ysize: n.info.ht
|
|
36867
37213
|
}));
|
|
36868
37214
|
}
|
|
37215
|
+
function isConcentrateDup(ps, e) {
|
|
37216
|
+
const ti = e.tail.id;
|
|
37217
|
+
const hi = e.head.id;
|
|
37218
|
+
const lo = ti <= hi ? ti : hi;
|
|
37219
|
+
const up = ti <= hi ? hi : ti;
|
|
37220
|
+
if (ps.isInPS(lo, up)) return true;
|
|
37221
|
+
ps.addPS(lo, up);
|
|
37222
|
+
return false;
|
|
37223
|
+
}
|
|
36869
37224
|
function buildEdges(g, nodeArr, orthoNodes) {
|
|
36870
37225
|
const concentrate = dotRoot(g).info.concentrate ?? false;
|
|
36871
37226
|
const nodeIndex = /* @__PURE__ */ new Map();
|
|
36872
37227
|
nodeArr.forEach((n, i) => nodeIndex.set(n, i));
|
|
36873
37228
|
const outIndex = buildOutEdgeIndex(g);
|
|
36874
|
-
const
|
|
37229
|
+
const ps = concentrate ? new PointSet() : null;
|
|
36875
37230
|
const result = [];
|
|
36876
37231
|
for (const n of nodeArr) {
|
|
36877
37232
|
const oes = outIndex.get(n);
|
|
36878
37233
|
if (oes === void 0) continue;
|
|
36879
37234
|
for (const e of oes) {
|
|
36880
|
-
if (
|
|
36881
|
-
const ti = e.tail.id;
|
|
36882
|
-
const hi = e.head.id;
|
|
36883
|
-
const key = ti <= hi ? `${ti},${hi}` : `${hi},${ti}`;
|
|
36884
|
-
if (seen.has(key)) continue;
|
|
36885
|
-
seen.add(key);
|
|
36886
|
-
}
|
|
37235
|
+
if (ps !== null && isConcentrateDup(ps, e)) continue;
|
|
36887
37236
|
result.push({
|
|
36888
37237
|
tail: orthoNodes[nodeIndex.get(e.tail)],
|
|
36889
37238
|
head: orthoNodes[nodeIndex.get(e.head)],
|
|
@@ -37971,15 +38320,6 @@ function spiralSearch(info, ctx, wide) {
|
|
|
37971
38320
|
|
|
37972
38321
|
// src/layout/pack/poly-pack.ts
|
|
37973
38322
|
var C2 = 100;
|
|
37974
|
-
function psKey(x, y) {
|
|
37975
|
-
return `${cround(x)},${cround(y)}`;
|
|
37976
|
-
}
|
|
37977
|
-
function inPS(ps, p) {
|
|
37978
|
-
return ps.has(psKey(p.x, p.y));
|
|
37979
|
-
}
|
|
37980
|
-
function insertPS(ps, p) {
|
|
37981
|
-
ps.add(psKey(p.x, p.y));
|
|
37982
|
-
}
|
|
37983
38323
|
function computeStep(ng, bbs, margin) {
|
|
37984
38324
|
let b = 0;
|
|
37985
38325
|
let c = 0;
|
|
@@ -38026,14 +38366,14 @@ function genBox2(p) {
|
|
|
38026
38366
|
function hasCollision(cells, dx, dy, ps) {
|
|
38027
38367
|
for (let i = 0; i < cells.length; i++) {
|
|
38028
38368
|
const cell2 = cells[i];
|
|
38029
|
-
if (cell2 !== void 0 && inPS(
|
|
38369
|
+
if (cell2 !== void 0 && ps.inPS({ x: cell2.x + dx, y: cell2.y + dy })) return true;
|
|
38030
38370
|
}
|
|
38031
38371
|
return false;
|
|
38032
38372
|
}
|
|
38033
38373
|
function markCells(cells, dx, dy, ps) {
|
|
38034
38374
|
for (let i = 0; i < cells.length; i++) {
|
|
38035
38375
|
const cell2 = cells[i];
|
|
38036
|
-
if (cell2 !== void 0)
|
|
38376
|
+
if (cell2 !== void 0) ps.addPS(cell2.x + dx, cell2.y + dy);
|
|
38037
38377
|
}
|
|
38038
38378
|
}
|
|
38039
38379
|
function fits(x, y, info, ctx) {
|
|
@@ -38078,7 +38418,7 @@ function polyRects(ng, bbs, pinfo) {
|
|
|
38078
38418
|
infos.push(genBox2({ bb, ssize: step, margin: pinfo.margin, idx: i }));
|
|
38079
38419
|
}
|
|
38080
38420
|
const sorted = gvQsort([...infos], cmpByGPerimeter);
|
|
38081
|
-
const ctx = { ps:
|
|
38421
|
+
const ctx = { ps: new PointSet(), step, bbs };
|
|
38082
38422
|
const places = new Array(ng).fill({ x: 0, y: 0 });
|
|
38083
38423
|
for (let i = 0; i < sorted.length; i++) {
|
|
38084
38424
|
const info = sorted[i];
|
|
@@ -38088,57 +38428,6 @@ function polyRects(ng, bbs, pinfo) {
|
|
|
38088
38428
|
return places;
|
|
38089
38429
|
}
|
|
38090
38430
|
|
|
38091
|
-
// src/common/pointset.ts
|
|
38092
|
-
function cmpPair(a, b) {
|
|
38093
|
-
if (a.x > b.x) return 1;
|
|
38094
|
-
if (a.x < b.x) return -1;
|
|
38095
|
-
if (a.y > b.y) return 1;
|
|
38096
|
-
if (a.y < b.y) return -1;
|
|
38097
|
-
return 0;
|
|
38098
|
-
}
|
|
38099
|
-
var PointSet = class {
|
|
38100
|
-
byX = /* @__PURE__ */ new Map();
|
|
38101
|
-
n = 0;
|
|
38102
|
-
/**
|
|
38103
|
-
* Insert (x, y). A duplicate keeps the point inserted first, as `dtinsert`
|
|
38104
|
-
* returns the existing object and the new one is freed.
|
|
38105
|
-
* @see lib/common/pointset.c:addPS
|
|
38106
|
-
*/
|
|
38107
|
-
addPS(x, y) {
|
|
38108
|
-
let col = this.byX.get(x);
|
|
38109
|
-
if (col === void 0) {
|
|
38110
|
-
col = /* @__PURE__ */ new Map();
|
|
38111
|
-
this.byX.set(x, col);
|
|
38112
|
-
}
|
|
38113
|
-
if (col.has(y)) return;
|
|
38114
|
-
col.set(y, { x, y });
|
|
38115
|
-
this.n++;
|
|
38116
|
-
}
|
|
38117
|
-
/** @see lib/common/pointset.c:inPS */
|
|
38118
|
-
inPS(pt) {
|
|
38119
|
-
return this.byX.get(pt.x)?.has(pt.y) ?? false;
|
|
38120
|
-
}
|
|
38121
|
-
/** @see lib/common/pointset.c:isInPS */
|
|
38122
|
-
isInPS(x, y) {
|
|
38123
|
-
return this.byX.get(x)?.has(y) ?? false;
|
|
38124
|
-
}
|
|
38125
|
-
/** @see lib/common/pointset.c:sizeOf */
|
|
38126
|
-
sizeOf() {
|
|
38127
|
-
return this.n;
|
|
38128
|
-
}
|
|
38129
|
-
/**
|
|
38130
|
-
* The points in dictionary order (`dtflatten` walks the ordered set).
|
|
38131
|
-
* @see lib/common/pointset.c:pointsOf
|
|
38132
|
-
*/
|
|
38133
|
-
pointsOf() {
|
|
38134
|
-
const pts = [];
|
|
38135
|
-
for (const col of this.byX.values()) {
|
|
38136
|
-
for (const p of col.values()) pts.push({ x: p.x, y: p.y });
|
|
38137
|
-
}
|
|
38138
|
-
return pts.sort(cmpPair);
|
|
38139
|
-
}
|
|
38140
|
-
};
|
|
38141
|
-
|
|
38142
38431
|
// src/layout/pack/poly-place.ts
|
|
38143
38432
|
var C_AVG = 100;
|
|
38144
38433
|
function grid(x, s) {
|
|
@@ -41979,6 +42268,12 @@ function chainOf(e) {
|
|
|
41979
42268
|
}
|
|
41980
42269
|
return list;
|
|
41981
42270
|
}
|
|
42271
|
+
function warnNoControlPoints(e) {
|
|
42272
|
+
console.warn(
|
|
42273
|
+
`Warning: Could not create control points for multiple spline for edge (${e.tail.name},${e.head.name})`
|
|
42274
|
+
);
|
|
42275
|
+
return 1;
|
|
42276
|
+
}
|
|
41982
42277
|
function genroute(g, trip, t, e, doPolyline) {
|
|
41983
42278
|
const eps = [
|
|
41984
42279
|
{ x: trip.ps[0].x, y: trip.ps[0].y },
|
|
@@ -41988,7 +42283,7 @@ function genroute(g, trip, t, e, doPolyline) {
|
|
|
41988
42283
|
const mult = e.info.count ?? 1;
|
|
41989
42284
|
const head = e.head;
|
|
41990
42285
|
const pl = shortestPath({ ps: trip.ps }, eps);
|
|
41991
|
-
if (pl === null) return
|
|
42286
|
+
if (pl === null) return warnNoControlPoints(e);
|
|
41992
42287
|
if (pl.length === 2) {
|
|
41993
42288
|
const chain = chainOf(e);
|
|
41994
42289
|
makeStraightEdges(g, chain, chain.length, doPolyline ? 1 : 0, MSINFO);
|
|
@@ -41996,7 +42291,7 @@ function genroute(g, trip, t, e, doPolyline) {
|
|
|
41996
42291
|
}
|
|
41997
42292
|
if (mult === 1 || concentrate) {
|
|
41998
42293
|
const spl = routeMember(trip.ps, t, pl, doPolyline);
|
|
41999
|
-
if (spl === null) return
|
|
42294
|
+
if (spl === null) return warnNoControlPoints(e);
|
|
42000
42295
|
finishEdge(e, spl, e.head !== head);
|
|
42001
42296
|
return 0;
|
|
42002
42297
|
}
|
|
@@ -42004,7 +42299,7 @@ function genroute(g, trip, t, e, doPolyline) {
|
|
|
42004
42299
|
const cpts = [];
|
|
42005
42300
|
for (let i = 0; i + 2 < pl.length; i++) {
|
|
42006
42301
|
const cp = mkCtrlPts(t, mult + 1, pl[i], pl[i + 1], pl[i + 2], trip);
|
|
42007
|
-
if (cp === null) return
|
|
42302
|
+
if (cp === null) return warnNoControlPoints(e);
|
|
42008
42303
|
cpts.push(cp);
|
|
42009
42304
|
}
|
|
42010
42305
|
let cur = e;
|
|
@@ -42019,9 +42314,9 @@ function genroute(g, trip, t, e, doPolyline) {
|
|
|
42019
42314
|
poly[pn - j] = cpts[j - 1][i + 1];
|
|
42020
42315
|
}
|
|
42021
42316
|
const mmpl = shortestPath({ ps: poly }, eps);
|
|
42022
|
-
if (mmpl === null) return
|
|
42317
|
+
if (mmpl === null) return warnNoControlPoints(cur);
|
|
42023
42318
|
const spl = routeMember(poly, pl.length - 1, mmpl, doPolyline);
|
|
42024
|
-
if (spl === null) return
|
|
42319
|
+
if (spl === null) return warnNoControlPoints(cur);
|
|
42025
42320
|
finishEdge(cur, spl, cur.head !== head);
|
|
42026
42321
|
cur = cur.info.to_virt;
|
|
42027
42322
|
}
|
|
@@ -51245,22 +51540,22 @@ function freeBlocktree(bp) {
|
|
|
51245
51540
|
|
|
51246
51541
|
// src/layout/circo/position-helpers.ts
|
|
51247
51542
|
function rotatePoint(x, y, cosR, sinR) {
|
|
51248
|
-
return [x
|
|
51543
|
+
return [fma(x, cosR, -sinR * y), fma(x, sinR, cosR * y)];
|
|
51249
51544
|
}
|
|
51250
51545
|
function nodePsi(n) {
|
|
51251
51546
|
return n.info.alg?.psi ?? 0;
|
|
51252
51547
|
}
|
|
51253
51548
|
function rotFromParentPos(sn, theta) {
|
|
51254
|
-
let r = theta + Math.PI - sn.parentPos;
|
|
51549
|
+
let r = theta + (Math.PI - sn.parentPos);
|
|
51255
51550
|
if (r < 0) r += 2 * Math.PI;
|
|
51256
51551
|
return r;
|
|
51257
51552
|
}
|
|
51258
51553
|
function closestNode(sn, x, y, skip) {
|
|
51259
51554
|
let best = skip;
|
|
51260
|
-
let bestDist =
|
|
51555
|
+
let bestDist = libmHypot(skip.info.pos[0] + x, skip.info.pos[1] + y);
|
|
51261
51556
|
for (const dn of sn.subGraph.nodes) {
|
|
51262
51557
|
if (dn.orig === skip) continue;
|
|
51263
|
-
const d =
|
|
51558
|
+
const d = libmHypot(dn.orig.info.pos[0] + x, dn.orig.info.pos[1] + y);
|
|
51264
51559
|
if (d < bestDist) {
|
|
51265
51560
|
bestDist = d;
|
|
51266
51561
|
best = dn.orig;
|
|
@@ -51273,22 +51568,19 @@ function rotCoalesced(sn, x, y, nbr, theta) {
|
|
|
51273
51568
|
const r = sn.radius - rho;
|
|
51274
51569
|
const nx = nbr.info.pos[0];
|
|
51275
51570
|
const ny = nbr.info.pos[1];
|
|
51276
|
-
|
|
51277
|
-
const phi2 = Math.atan2(ny, nx);
|
|
51278
|
-
return theta + Math.PI - phi2 - nodePsi(nbr);
|
|
51279
|
-
}
|
|
51280
|
-
const R2 = Math.hypot(x, y);
|
|
51571
|
+
const R2 = libmHypot(x, y);
|
|
51281
51572
|
const phi = Math.atan2(ny, nx + r);
|
|
51282
51573
|
const l = r - rho / Math.cos(phi);
|
|
51283
|
-
return theta + Math.PI / 2 - phi - Math.asin(l / R2 * Math.cos(phi));
|
|
51574
|
+
return theta + (Math.PI / 2 - phi - Math.asin(l / R2 * Math.cos(phi)));
|
|
51284
51575
|
}
|
|
51285
51576
|
function rotGeneral(sn, x, y, nbr, theta) {
|
|
51286
51577
|
if (closestNode(sn, x, y, nbr) === nbr) return 0;
|
|
51287
|
-
|
|
51578
|
+
const r = sn.radius - sn.rad0;
|
|
51579
|
+
if (isCoalesced(sn) && -r < nbr.info.pos[0]) return rotCoalesced(sn, x, y, nbr, theta);
|
|
51288
51580
|
const phi = Math.atan2(nbr.info.pos[1], nbr.info.pos[0]);
|
|
51289
|
-
let
|
|
51290
|
-
if (
|
|
51291
|
-
return
|
|
51581
|
+
let t = theta + (Math.PI - phi - nodePsi(nbr));
|
|
51582
|
+
if (t > 2 * Math.PI) t -= 2 * Math.PI;
|
|
51583
|
+
return t;
|
|
51292
51584
|
}
|
|
51293
51585
|
function applyDelta(sn, x, y, rotate) {
|
|
51294
51586
|
const cosR = Math.cos(rotate);
|
|
@@ -51331,7 +51623,7 @@ function getInfo(pi, stp, minDist) {
|
|
|
51331
51623
|
}
|
|
51332
51624
|
function setInfo(p0, p1, delta2) {
|
|
51333
51625
|
const t = Math.max(
|
|
51334
|
-
(p0.diameter
|
|
51626
|
+
fma(p0.diameter, p1.minRadius, p1.diameter * p0.minRadius) / (2 * delta2 * p0.minRadius * p1.minRadius),
|
|
51335
51627
|
1
|
|
51336
51628
|
);
|
|
51337
51629
|
p0.scale = Math.max(p0.scale, t);
|
|
@@ -51341,7 +51633,13 @@ function placeChild(child, ca, ctx) {
|
|
|
51341
51633
|
const dx = ctx.childRadius * Math.cos(ca);
|
|
51342
51634
|
const dy = ctx.childRadius * Math.sin(ca);
|
|
51343
51635
|
applyDelta(child, dx, dy, getRotation(child, dx, dy, ca));
|
|
51344
|
-
return
|
|
51636
|
+
return nextChildAngle(ca, ctx.incAngle, ctx.mindistAngle, ctx.length);
|
|
51637
|
+
}
|
|
51638
|
+
function nextChildAngle(ca, inc2, mda, length) {
|
|
51639
|
+
return length === 1 ? ca + (inc2 + mda) : ca + (inc2 + mda / 2);
|
|
51640
|
+
}
|
|
51641
|
+
function leftoverArc(childRadius, diameter) {
|
|
51642
|
+
return fma(2 * Math.PI, childRadius, -diameter);
|
|
51345
51643
|
}
|
|
51346
51644
|
function advanceAngleL1(ca, inc2, total, cnt, stp) {
|
|
51347
51645
|
const next = cnt === 0 ? 0 : total === 2 ? Math.PI : ca + inc2;
|
|
@@ -51351,7 +51649,7 @@ function advanceAngleL1(ca, inc2, total, cnt, stp) {
|
|
|
51351
51649
|
}
|
|
51352
51650
|
function advanceAngleLN(ca, inc2, mda, total, theta) {
|
|
51353
51651
|
if (total === 1) return theta;
|
|
51354
|
-
return ca + inc2 + mda / 2;
|
|
51652
|
+
return ca + (inc2 + mda / 2);
|
|
51355
51653
|
}
|
|
51356
51654
|
function maybeWritePsi(n, stp, ca, isMid) {
|
|
51357
51655
|
if (isMid && n === stp.neighbor) {
|
|
@@ -51366,7 +51664,7 @@ function positionChildren(pi, stp, length, minDist) {
|
|
|
51366
51664
|
let md = minDist;
|
|
51367
51665
|
if (length === 1) {
|
|
51368
51666
|
cr = Math.max(cr, pi.diameter / (2 * Math.PI));
|
|
51369
|
-
const d =
|
|
51667
|
+
const d = leftoverArc(cr, pi.diameter);
|
|
51370
51668
|
if (d > 0) md += d / pi.childCount;
|
|
51371
51669
|
}
|
|
51372
51670
|
stp.subtreeR = Math.max(stp.subtreeR, cr + pi.maxRadius);
|