@knowvah/dot-engine 2.6.4 → 2.6.5
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/arrows-shapes-poly.d.ts.map +1 -1
- package/dist/common/bezier.d.ts +12 -0
- package/dist/common/bezier.d.ts.map +1 -0
- package/dist/common/htmltable-attr-warn.d.ts +41 -0
- package/dist/common/htmltable-attr-warn.d.ts.map +1 -0
- package/dist/common/htmltable-fontinfo.d.ts +42 -0
- package/dist/common/htmltable-fontinfo.d.ts.map +1 -0
- package/dist/common/htmltable-lex-expat.d.ts +63 -0
- package/dist/common/htmltable-lex-expat.d.ts.map +1 -0
- package/dist/common/htmltable-lex-units.d.ts +32 -0
- package/dist/common/htmltable-lex-units.d.ts.map +1 -0
- package/dist/common/htmltable-lex.d.ts +10 -2
- package/dist/common/htmltable-lex.d.ts.map +1 -1
- package/dist/common/htmltable-parse-attrs.d.ts +7 -5
- package/dist/common/htmltable-parse-attrs.d.ts.map +1 -1
- package/dist/common/htmltable-parse-font.d.ts +33 -0
- package/dist/common/htmltable-parse-font.d.ts.map +1 -0
- package/dist/common/htmltable-parse-state.d.ts +39 -0
- package/dist/common/htmltable-parse-state.d.ts.map +1 -0
- package/dist/common/htmltable-parse.d.ts +18 -23
- package/dist/common/htmltable-parse.d.ts.map +1 -1
- package/dist/common/htmltable-pos.d.ts.map +1 -1
- package/dist/common/htmltable-types.d.ts +33 -3
- package/dist/common/htmltable-types.d.ts.map +1 -1
- package/dist/common/htmltable.d.ts +3 -2
- package/dist/common/htmltable.d.ts.map +1 -1
- package/dist/common/spline-midpoint.d.ts.map +1 -1
- package/dist/common/splines-geom.d.ts +5 -6
- package/dist/common/splines-geom.d.ts.map +1 -1
- package/dist/common/splines-routespl.d.ts.map +1 -1
- package/dist/common/taper.d.ts.map +1 -1
- package/dist/gvc/anchor.d.ts.map +1 -1
- package/dist/index.js +1362 -647
- package/dist/index.js.map +4 -4
- package/dist/layout/dot/compound-clip.d.ts +5 -5
- package/dist/layout/dot/compound-clip.d.ts.map +1 -1
- package/dist/layout/dot/compound-geom.d.ts +2 -7
- package/dist/layout/dot/compound-geom.d.ts.map +1 -1
- package/dist/layout/dot/compound.d.ts +1 -1
- package/dist/layout/dot/compound.d.ts.map +1 -1
- package/dist/layout/dot/edge-route-clip.d.ts +1 -1
- package/dist/layout/dot/edge-route-clip.d.ts.map +1 -1
- package/dist/layout/dot/ortho-adapter.d.ts +13 -4
- package/dist/layout/dot/ortho-adapter.d.ts.map +1 -1
- package/dist/layout/dot/splines-label.d.ts.map +1 -1
- package/dist/layout/neato/bfs.d.ts +10 -3
- package/dist/layout/neato/bfs.d.ts.map +1 -1
- package/dist/layout/neato/init.d.ts +6 -11
- package/dist/layout/neato/init.d.ts.map +1 -1
- package/dist/layout/neato/splines.d.ts.map +1 -1
- package/dist/parser/index.d.ts.map +1 -1
- package/dist/parser/scan-token.d.ts +40 -0
- package/dist/parser/scan-token.d.ts.map +1 -0
- package/dist/render/svg-edge-split.d.ts.map +1 -1
- package/dist/render.js +1384 -669
- package/dist/render.js.map +4 -4
- package/package.json +1 -1
- package/src/common/arrows-shapes-poly.ts +9 -10
- package/src/common/bezier.ts +33 -0
- package/src/common/htmltable-attr-warn.ts +270 -0
- package/src/common/htmltable-fontinfo.ts +83 -0
- package/src/common/htmltable-lex-expat.ts +357 -0
- package/src/common/htmltable-lex-units.ts +75 -0
- package/src/common/htmltable-lex.ts +221 -160
- package/src/common/htmltable-parse-attrs.ts +10 -14
- package/src/common/htmltable-parse-font.ts +92 -0
- package/src/common/htmltable-parse-state.ts +64 -0
- package/src/common/htmltable-parse.ts +138 -98
- package/src/common/htmltable-pos.ts +9 -8
- package/src/common/htmltable-types.ts +35 -3
- package/src/common/htmltable.ts +14 -7
- package/src/common/spline-midpoint.ts +2 -22
- package/src/common/splines-geom.ts +5 -25
- package/src/common/splines-routespl.ts +21 -13
- package/src/common/taper.ts +2 -14
- package/src/gvc/anchor.ts +5 -14
- package/src/layout/dot/compound-clip.ts +9 -19
- package/src/layout/dot/compound-geom.ts +6 -23
- package/src/layout/dot/compound.ts +1 -1
- package/src/layout/dot/edge-route-clip.ts +6 -29
- package/src/layout/dot/ortho-adapter.ts +5 -5
- package/src/layout/dot/splines-label.ts +3 -29
- package/src/layout/neato/bfs.ts +13 -4
- package/src/layout/neato/init.ts +15 -15
- package/src/layout/neato/splines.ts +4 -8
- package/src/parser/index.ts +13 -1
- package/src/parser/scan-token.ts +289 -0
- package/src/render/svg-edge-split.ts +5 -13
package/dist/render.js
CHANGED
|
@@ -5086,8 +5086,8 @@ function normalizeFontName(name) {
|
|
|
5086
5086
|
for (let i = 0; i < name.length; i++) {
|
|
5087
5087
|
const ch = name[i];
|
|
5088
5088
|
const code = ch.charCodeAt(0);
|
|
5089
|
-
const
|
|
5090
|
-
if (
|
|
5089
|
+
const isLetter3 = code >= 65 && code <= 90 || code >= 97 && code <= 122;
|
|
5090
|
+
if (isLetter3) result += ch.toLowerCase();
|
|
5091
5091
|
}
|
|
5092
5092
|
return result;
|
|
5093
5093
|
}
|
|
@@ -5193,30 +5193,30 @@ function fontFamilyAttrs(fontName, mode = FontnameKind.NativeFonts) {
|
|
|
5193
5193
|
if (a === null) return null;
|
|
5194
5194
|
let family;
|
|
5195
5195
|
let weight;
|
|
5196
|
-
let
|
|
5196
|
+
let style2;
|
|
5197
5197
|
switch (mode) {
|
|
5198
5198
|
case FontnameKind.PsFonts:
|
|
5199
5199
|
family = a.name;
|
|
5200
5200
|
weight = a.weight;
|
|
5201
|
-
|
|
5201
|
+
style2 = a.style;
|
|
5202
5202
|
break;
|
|
5203
5203
|
case FontnameKind.SvgFonts:
|
|
5204
5204
|
family = a.svgFontFamily;
|
|
5205
5205
|
weight = a.svgFontWeight;
|
|
5206
|
-
|
|
5206
|
+
style2 = a.svgFontStyle;
|
|
5207
5207
|
break;
|
|
5208
5208
|
default:
|
|
5209
5209
|
family = a.family;
|
|
5210
5210
|
weight = a.weight;
|
|
5211
|
-
|
|
5211
|
+
style2 = a.style;
|
|
5212
5212
|
break;
|
|
5213
5213
|
}
|
|
5214
5214
|
const fam = a.svgFontFamily !== family ? family + "," + a.svgFontFamily : family;
|
|
5215
5215
|
let attrs = ' font-family="' + fam + '"';
|
|
5216
5216
|
if (weight !== null) attrs += ' font-weight="' + weight + '"';
|
|
5217
5217
|
if (a.stretch !== null) attrs += ' font-stretch="' + a.stretch + '"';
|
|
5218
|
-
if (
|
|
5219
|
-
return { attrs, weight: weight !== null, style:
|
|
5218
|
+
if (style2 !== null) attrs += ' font-style="' + style2 + '"';
|
|
5219
|
+
return { attrs, weight: weight !== null, style: style2 !== null };
|
|
5220
5220
|
}
|
|
5221
5221
|
|
|
5222
5222
|
// src/common/css-font.ts
|
|
@@ -5476,6 +5476,218 @@ var BORDER_RIGHT = 1 << 12;
|
|
|
5476
5476
|
var BORDER_BOTTOM = 1 << 13;
|
|
5477
5477
|
var BORDER_MASK = BORDER_LEFT | BORDER_TOP | BORDER_RIGHT | BORDER_BOTTOM;
|
|
5478
5478
|
|
|
5479
|
+
// src/common/htmltable-attr-warn.ts
|
|
5480
|
+
var accepted = (v) => ({ keep: v, text: [], warn: false });
|
|
5481
|
+
var ignored = (text) => ({ keep: void 0, text: [text], warn: true });
|
|
5482
|
+
var warning = (msg) => `Warning: ${msg}`;
|
|
5483
|
+
var lower = (s) => s.replace(/[A-Z]/g, (c) => c.toLowerCase());
|
|
5484
|
+
var accept = accepted;
|
|
5485
|
+
var STRTOL = /^[ \t\n\v\f\r]*([+-]?\d+)/;
|
|
5486
|
+
function doInt(v, s, min, max) {
|
|
5487
|
+
const m = STRTOL.exec(v);
|
|
5488
|
+
if (m === null) return ignored(warning(`Improper ${s} value ${v} - ignored`));
|
|
5489
|
+
const b = Number(m[1]);
|
|
5490
|
+
if (b > max) return ignored(warning(`${s} value ${v} > ${max} - too large - ignored`));
|
|
5491
|
+
if (b < min) return ignored(warning(`${s} value ${v} < ${min} - too small - ignored`));
|
|
5492
|
+
return accepted(v);
|
|
5493
|
+
}
|
|
5494
|
+
var intHandler = (s, min, max) => (v) => doInt(v, s, min, max);
|
|
5495
|
+
var UCHAR_MAX = 255;
|
|
5496
|
+
var SCHAR_MIN = -128;
|
|
5497
|
+
var SCHAR_MAX = 127;
|
|
5498
|
+
var INT8_MAX = 127;
|
|
5499
|
+
var USHRT_MAX = 65535;
|
|
5500
|
+
var GRADIENT_MAX = 360;
|
|
5501
|
+
var spanHandler = (s) => (v) => {
|
|
5502
|
+
const r = doInt(v, s, 0, USHRT_MAX);
|
|
5503
|
+
if (r.keep === void 0 || Number(STRTOL.exec(v)?.[1]) !== 0) return r;
|
|
5504
|
+
return ignored(warning(`${s} value cannot be 0 - ignored
|
|
5505
|
+
`));
|
|
5506
|
+
};
|
|
5507
|
+
var wordsHandler = (words, what) => (v) => words.includes(lower(v)) ? accepted(v) : ignored(warning(`Illegal value ${v} for ${what} - ignored
|
|
5508
|
+
`));
|
|
5509
|
+
var starHandler = (what) => (v) => v.startsWith("*") ? accepted(v) : ignored(warning(`Unknown value ${v} for ${what} - ignored
|
|
5510
|
+
`));
|
|
5511
|
+
var valign = wordsHandler(["bottom", "top", "middle"], "VALIGN");
|
|
5512
|
+
var fixedsize = wordsHandler(["true", "false"], "FIXEDSIZE");
|
|
5513
|
+
var tableAlign = wordsHandler(["left", "right", "center"], "ALIGN");
|
|
5514
|
+
var brAlign = tableAlign;
|
|
5515
|
+
var cellAlign = wordsHandler(["left", "right", "text", "center"], "ALIGN in TD");
|
|
5516
|
+
var balign = wordsHandler(["left", "right", "center"], "BALIGN in TD");
|
|
5517
|
+
var SIDES_LETTERS = "ltrb";
|
|
5518
|
+
var sides = (v) => {
|
|
5519
|
+
const text = [];
|
|
5520
|
+
for (const b of new TextEncoder().encode(v)) {
|
|
5521
|
+
if (SIDES_LETTERS.includes(lower(String.fromCharCode(b)))) continue;
|
|
5522
|
+
const code = b > SCHAR_MAX ? b - 256 : b;
|
|
5523
|
+
text.push(warning(`Unrecognized character '${String.fromCharCode(b)}' (${code}) in sides attribute
|
|
5524
|
+
`));
|
|
5525
|
+
}
|
|
5526
|
+
return { keep: v, text, warn: false };
|
|
5527
|
+
};
|
|
5528
|
+
var STYLE_WORDS = ["rounded", "radial", "solid", "invisible", "invis", "dotted", "dashed"];
|
|
5529
|
+
var STYLE_DELIM = " ,";
|
|
5530
|
+
function styleTokens(v) {
|
|
5531
|
+
const out = [];
|
|
5532
|
+
const span = (from, member) => {
|
|
5533
|
+
let i = from;
|
|
5534
|
+
while (i < v.length && STYLE_DELIM.includes(v[i]) === member) i++;
|
|
5535
|
+
return i;
|
|
5536
|
+
};
|
|
5537
|
+
let end = span(0, false);
|
|
5538
|
+
out.push(v.slice(0, end));
|
|
5539
|
+
while (end < v.length) {
|
|
5540
|
+
const start = span(end, true);
|
|
5541
|
+
end = span(start, false);
|
|
5542
|
+
out.push(v.slice(start, end));
|
|
5543
|
+
}
|
|
5544
|
+
return out;
|
|
5545
|
+
}
|
|
5546
|
+
var style = (v) => {
|
|
5547
|
+
const legal = [];
|
|
5548
|
+
const text = [];
|
|
5549
|
+
for (const tk of styleTokens(v)) {
|
|
5550
|
+
if (STYLE_WORDS.includes(lower(tk))) legal.push(tk);
|
|
5551
|
+
else text.push(warning(`Illegal value ${tk} for STYLE - ignored
|
|
5552
|
+
`));
|
|
5553
|
+
}
|
|
5554
|
+
return { keep: legal.length > 0 ? legal.join(" ") : void 0, text, warn: text.length > 0 };
|
|
5555
|
+
};
|
|
5556
|
+
var border = intHandler("BORDER", 0, UCHAR_MAX);
|
|
5557
|
+
var cellpadding = intHandler("CELLPADDING", 0, UCHAR_MAX);
|
|
5558
|
+
var cellspacing = intHandler("CELLSPACING", SCHAR_MIN, SCHAR_MAX);
|
|
5559
|
+
var gradientangle = intHandler("GRADIENTANGLE", 0, GRADIENT_MAX);
|
|
5560
|
+
var height = intHandler("HEIGHT", 0, USHRT_MAX);
|
|
5561
|
+
var width = intHandler("WIDTH", 0, USHRT_MAX);
|
|
5562
|
+
var TBL_ITEMS = /* @__PURE__ */ new Map([
|
|
5563
|
+
["align", tableAlign],
|
|
5564
|
+
["bgcolor", accept],
|
|
5565
|
+
["border", border],
|
|
5566
|
+
["cellborder", intHandler("CELLBORDER", 0, INT8_MAX)],
|
|
5567
|
+
["cellpadding", cellpadding],
|
|
5568
|
+
["cellspacing", cellspacing],
|
|
5569
|
+
["color", accept],
|
|
5570
|
+
["columns", starHandler("COLUMNS")],
|
|
5571
|
+
["fixedsize", fixedsize],
|
|
5572
|
+
["gradientangle", gradientangle],
|
|
5573
|
+
["height", height],
|
|
5574
|
+
["href", accept],
|
|
5575
|
+
["id", accept],
|
|
5576
|
+
["port", accept],
|
|
5577
|
+
["rows", starHandler("ROWS")],
|
|
5578
|
+
["sides", sides],
|
|
5579
|
+
["style", style],
|
|
5580
|
+
["target", accept],
|
|
5581
|
+
["title", accept],
|
|
5582
|
+
["tooltip", accept],
|
|
5583
|
+
["valign", valign],
|
|
5584
|
+
["width", width]
|
|
5585
|
+
]);
|
|
5586
|
+
var CELL_ITEMS = /* @__PURE__ */ new Map([
|
|
5587
|
+
["align", cellAlign],
|
|
5588
|
+
["balign", balign],
|
|
5589
|
+
["bgcolor", accept],
|
|
5590
|
+
["border", border],
|
|
5591
|
+
["cellpadding", cellpadding],
|
|
5592
|
+
["cellspacing", cellspacing],
|
|
5593
|
+
["color", accept],
|
|
5594
|
+
["colspan", spanHandler("COLSPAN")],
|
|
5595
|
+
["fixedsize", fixedsize],
|
|
5596
|
+
["gradientangle", gradientangle],
|
|
5597
|
+
["height", height],
|
|
5598
|
+
["href", accept],
|
|
5599
|
+
["id", accept],
|
|
5600
|
+
["port", accept],
|
|
5601
|
+
["rowspan", spanHandler("ROWSPAN")],
|
|
5602
|
+
["sides", sides],
|
|
5603
|
+
["style", style],
|
|
5604
|
+
["target", accept],
|
|
5605
|
+
["title", accept],
|
|
5606
|
+
["tooltip", accept],
|
|
5607
|
+
["valign", valign],
|
|
5608
|
+
["width", width]
|
|
5609
|
+
]);
|
|
5610
|
+
var FONT_ITEMS = /* @__PURE__ */ new Map([
|
|
5611
|
+
["color", accept],
|
|
5612
|
+
["face", accept],
|
|
5613
|
+
["point-size", intHandler("POINT-SIZE", 0, UCHAR_MAX)]
|
|
5614
|
+
]);
|
|
5615
|
+
var IMG_ITEMS = /* @__PURE__ */ new Map([["scale", accept], ["src", accept]]);
|
|
5616
|
+
var BR_ITEMS = /* @__PURE__ */ new Map([["align", brAlign]]);
|
|
5617
|
+
var ELEMENTS = /* @__PURE__ */ new Map([
|
|
5618
|
+
["TABLE", { items: TBL_ITEMS, name: "<TABLE>" }],
|
|
5619
|
+
["TD", { items: CELL_ITEMS, name: "<TD>" }],
|
|
5620
|
+
["FONT", { items: FONT_ITEMS, name: "<FONT>" }],
|
|
5621
|
+
["IMG", { items: IMG_ITEMS, name: "<IMG>" }],
|
|
5622
|
+
["BR", { items: BR_ITEMS, name: "<BR>" }]
|
|
5623
|
+
]);
|
|
5624
|
+
function checkAttrs(tag, pairs) {
|
|
5625
|
+
const el = ELEMENTS.get(tag);
|
|
5626
|
+
const attrs = {};
|
|
5627
|
+
const warnings = [];
|
|
5628
|
+
let warn = false;
|
|
5629
|
+
for (const [name, value] of pairs) {
|
|
5630
|
+
const key = lower(name);
|
|
5631
|
+
if (el === void 0) {
|
|
5632
|
+
attrs[key] = value;
|
|
5633
|
+
continue;
|
|
5634
|
+
}
|
|
5635
|
+
const handler = el.items.get(key);
|
|
5636
|
+
if (handler === void 0) {
|
|
5637
|
+
warnings.push(warning(`Illegal attribute ${name} in ${el.name} - ignored
|
|
5638
|
+
`));
|
|
5639
|
+
warn = true;
|
|
5640
|
+
continue;
|
|
5641
|
+
}
|
|
5642
|
+
const r = handler(value);
|
|
5643
|
+
warnings.push(...r.text);
|
|
5644
|
+
warn ||= r.warn;
|
|
5645
|
+
if (r.keep !== void 0) attrs[key] = r.keep;
|
|
5646
|
+
}
|
|
5647
|
+
return { attrs, warnings, warn };
|
|
5648
|
+
}
|
|
5649
|
+
var StderrLines = class {
|
|
5650
|
+
constructor(writeLine) {
|
|
5651
|
+
this.writeLine = writeLine;
|
|
5652
|
+
}
|
|
5653
|
+
writeLine;
|
|
5654
|
+
pending = "";
|
|
5655
|
+
write(text) {
|
|
5656
|
+
const parts = (this.pending + text).split("\n");
|
|
5657
|
+
this.pending = parts.pop() ?? "";
|
|
5658
|
+
for (const line of parts) this.writeLine(line);
|
|
5659
|
+
}
|
|
5660
|
+
flush() {
|
|
5661
|
+
if (this.pending === "") return;
|
|
5662
|
+
this.writeLine(this.pending);
|
|
5663
|
+
this.pending = "";
|
|
5664
|
+
}
|
|
5665
|
+
};
|
|
5666
|
+
|
|
5667
|
+
// src/common/htmltable-parse-state.ts
|
|
5668
|
+
var peek = (s) => s.tokens[s.pos];
|
|
5669
|
+
var emitWarnings = (s, tok) => {
|
|
5670
|
+
if (s.stderr === void 0 || s.emitted?.has(tok) === true) return;
|
|
5671
|
+
s.emitted?.add(tok);
|
|
5672
|
+
emitOutput(s, tok);
|
|
5673
|
+
};
|
|
5674
|
+
var emitOutput = (s, out) => {
|
|
5675
|
+
for (const text of out.warnings ?? []) s.stderr?.write(text);
|
|
5676
|
+
if (out.warn === true) s.warn = true;
|
|
5677
|
+
};
|
|
5678
|
+
var emitEof = (s) => {
|
|
5679
|
+
if (s.stderr === void 0 || s.eof === void 0) return;
|
|
5680
|
+
const out = s.eof;
|
|
5681
|
+
delete s.eof;
|
|
5682
|
+
emitOutput(s, out);
|
|
5683
|
+
};
|
|
5684
|
+
var consume = (s) => {
|
|
5685
|
+
const t = s.tokens[s.pos];
|
|
5686
|
+
s.pos++;
|
|
5687
|
+
if (t !== void 0) emitWarnings(s, t);
|
|
5688
|
+
return t;
|
|
5689
|
+
};
|
|
5690
|
+
|
|
5479
5691
|
// src/common/html-entities.ts
|
|
5480
5692
|
var HTML_ENTITIES = {
|
|
5481
5693
|
"AElig": 198,
|
|
@@ -5755,6 +5967,286 @@ function htmlEntityUTF8(s) {
|
|
|
5755
5967
|
});
|
|
5756
5968
|
}
|
|
5757
5969
|
|
|
5970
|
+
// src/common/htmltable-lex-expat.ts
|
|
5971
|
+
var XML_ERROR_INVALID_TOKEN = "not well-formed (invalid token)";
|
|
5972
|
+
var XML_CONTEXT_BYTES = 1024;
|
|
5973
|
+
var INIT_BUFFER_SIZE = 1024;
|
|
5974
|
+
var COMPLETE_END = (end, dup) => dup === void 0 ? { kind: "complete", end } : { kind: "complete", end, dup };
|
|
5975
|
+
var PARTIAL = { kind: "partial" };
|
|
5976
|
+
var INVALID = (offset) => ({ kind: "invalid", offset });
|
|
5977
|
+
var XML_NAME = /^[A-Za-z_:\u0080-\uFFFF][\w.:\u0080-\uFFFF-]*/;
|
|
5978
|
+
var isSpace = (c) => c !== void 0 && /\s/.test(c);
|
|
5979
|
+
function skipSpace(text, i) {
|
|
5980
|
+
let j = i;
|
|
5981
|
+
while (isSpace(text[j])) j++;
|
|
5982
|
+
return j;
|
|
5983
|
+
}
|
|
5984
|
+
var byteLength = (s) => new TextEncoder().encode(s).length;
|
|
5985
|
+
function fedBytes(unit, isText) {
|
|
5986
|
+
if (!isText) return byteLength(unit);
|
|
5987
|
+
let text = unit.replace(/&([^;&<]*);/g, (m, name) => {
|
|
5988
|
+
return name.length >= 2 && Object.hasOwn(HTML_ENTITIES, name) ? `&#${HTML_ENTITIES[name]};` : m;
|
|
5989
|
+
});
|
|
5990
|
+
if (text.endsWith("]")) text = `${text.slice(0, -1)}]`;
|
|
5991
|
+
return byteLength(text);
|
|
5992
|
+
}
|
|
5993
|
+
function scanValue(text, j) {
|
|
5994
|
+
const q = text[j];
|
|
5995
|
+
if (q !== '"' && q !== "'") return INVALID(j);
|
|
5996
|
+
const close = text.indexOf(q, j + 1);
|
|
5997
|
+
if (close < 0) {
|
|
5998
|
+
const lt = text.indexOf("<", j + 1);
|
|
5999
|
+
return lt >= 0 ? INVALID(lt) : PARTIAL;
|
|
6000
|
+
}
|
|
6001
|
+
const next = skipSpace(text, close + 1);
|
|
6002
|
+
if (next === close + 1 && !">/".includes(text[next] ?? ">")) return INVALID(next);
|
|
6003
|
+
return next;
|
|
6004
|
+
}
|
|
6005
|
+
function scanPair(text, i) {
|
|
6006
|
+
const name = XML_NAME.exec(text.slice(i))?.[0];
|
|
6007
|
+
if (name === void 0) return INVALID(i);
|
|
6008
|
+
const eq = skipSpace(text, i + name.length);
|
|
6009
|
+
if (eq >= text.length) return PARTIAL;
|
|
6010
|
+
if (text[eq] !== "=") return INVALID(eq);
|
|
6011
|
+
const j = skipSpace(text, eq + 1);
|
|
6012
|
+
if (j >= text.length) return PARTIAL;
|
|
6013
|
+
const next = scanValue(text, j);
|
|
6014
|
+
return typeof next === "number" ? { name, next } : next;
|
|
6015
|
+
}
|
|
6016
|
+
function tagEdge(text, i) {
|
|
6017
|
+
const c = text[i];
|
|
6018
|
+
if (c === void 0) return PARTIAL;
|
|
6019
|
+
if (c === ">") return COMPLETE_END(i + 1);
|
|
6020
|
+
if (c !== "/") return void 0;
|
|
6021
|
+
if (i + 1 >= text.length) return PARTIAL;
|
|
6022
|
+
return text[i + 1] === ">" ? COMPLETE_END(i + 2) : void 0;
|
|
6023
|
+
}
|
|
6024
|
+
function scanAttributes(text, from) {
|
|
6025
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6026
|
+
let dup;
|
|
6027
|
+
let i = skipSpace(text, from);
|
|
6028
|
+
for (; ; ) {
|
|
6029
|
+
const edge = tagEdge(text, i);
|
|
6030
|
+
if (edge?.kind === "complete") return COMPLETE_END(edge.end, dup);
|
|
6031
|
+
if (edge !== void 0) return edge;
|
|
6032
|
+
const pair = scanPair(text, i);
|
|
6033
|
+
if ("kind" in pair) return pair;
|
|
6034
|
+
if (seen.has(pair.name)) dup ??= i;
|
|
6035
|
+
seen.add(pair.name);
|
|
6036
|
+
i = pair.next;
|
|
6037
|
+
}
|
|
6038
|
+
}
|
|
6039
|
+
function scanName(text, at) {
|
|
6040
|
+
const name = XML_NAME.exec(text.slice(at))?.[0];
|
|
6041
|
+
if (name === void 0) return at >= text.length ? PARTIAL : INVALID(at);
|
|
6042
|
+
return { next: at + name.length };
|
|
6043
|
+
}
|
|
6044
|
+
function scanStartTag(text, p) {
|
|
6045
|
+
const name = scanName(text, p + 1);
|
|
6046
|
+
if ("kind" in name) return name;
|
|
6047
|
+
const c = text[name.next];
|
|
6048
|
+
if (c === void 0) return PARTIAL;
|
|
6049
|
+
if (!isSpace(c) && c !== ">" && c !== "/") return INVALID(name.next);
|
|
6050
|
+
return scanAttributes(text, name.next);
|
|
6051
|
+
}
|
|
6052
|
+
function scanEndTag(text, p) {
|
|
6053
|
+
const name = scanName(text, p + 2);
|
|
6054
|
+
if ("kind" in name) return name;
|
|
6055
|
+
const i = skipSpace(text, name.next);
|
|
6056
|
+
if (i >= text.length) return PARTIAL;
|
|
6057
|
+
return text[i] === ">" ? COMPLETE_END(i + 1) : INVALID(i);
|
|
6058
|
+
}
|
|
6059
|
+
function scanPi(text, p) {
|
|
6060
|
+
const e = text.indexOf("?>", p + 2);
|
|
6061
|
+
return e < 0 ? PARTIAL : COMPLETE_END(e + 2);
|
|
6062
|
+
}
|
|
6063
|
+
function scanDeclaration(text, p) {
|
|
6064
|
+
const cdata = "<![CDATA[".startsWith(text.slice(p, p + 9));
|
|
6065
|
+
if (!cdata && text.length - p >= 3) return INVALID(p + 2);
|
|
6066
|
+
for (let i = p + 1; i < text.length; i++) {
|
|
6067
|
+
if (text[i] === ">") return COMPLETE_END(i + 1);
|
|
6068
|
+
if (text[i] === "<") return INVALID(i);
|
|
6069
|
+
}
|
|
6070
|
+
return PARTIAL;
|
|
6071
|
+
}
|
|
6072
|
+
function scanComment(text, p) {
|
|
6073
|
+
for (let i = p + 4; i < text.length; i++) {
|
|
6074
|
+
if (text[i] !== "-") continue;
|
|
6075
|
+
if (i + 1 >= text.length) return PARTIAL;
|
|
6076
|
+
if (text[i + 1] !== "-") continue;
|
|
6077
|
+
if (i + 2 >= text.length) return PARTIAL;
|
|
6078
|
+
return text[i + 2] === ">" ? COMPLETE_END(i + 3) : INVALID(i + 2);
|
|
6079
|
+
}
|
|
6080
|
+
return PARTIAL;
|
|
6081
|
+
}
|
|
6082
|
+
function scanMarkup(text, p) {
|
|
6083
|
+
const rest = text.slice(p, p + 4);
|
|
6084
|
+
if (rest === "<!--") return { scan: scanComment(text, p), kind: "comment" };
|
|
6085
|
+
if (text.length - p < 4 && "<!--".startsWith(rest)) return { scan: PARTIAL, kind: "comment" };
|
|
6086
|
+
if (rest.startsWith("<!-")) return { scan: INVALID(p + 3), kind: "comment" };
|
|
6087
|
+
const c = text[p + 1];
|
|
6088
|
+
if (c === "/") return { scan: scanEndTag(text, p), kind: "tag" };
|
|
6089
|
+
if (c === "?") return { scan: scanPi(text, p), kind: "pi" };
|
|
6090
|
+
if (c === "!") return { scan: scanDeclaration(text, p), kind: "tag" };
|
|
6091
|
+
return { scan: scanStartTag(text, p), kind: "tag" };
|
|
6092
|
+
}
|
|
6093
|
+
function scanContent(text, base) {
|
|
6094
|
+
const tokens = [];
|
|
6095
|
+
let p = 0;
|
|
6096
|
+
while (p < text.length) {
|
|
6097
|
+
if (text[p] !== "<") {
|
|
6098
|
+
const e = text.indexOf("<", p);
|
|
6099
|
+
const end = e < 0 ? text.length : e;
|
|
6100
|
+
tokens.push({ kind: "text", start: base + p, end: base + end });
|
|
6101
|
+
p = end;
|
|
6102
|
+
continue;
|
|
6103
|
+
}
|
|
6104
|
+
const { scan, kind } = scanMarkup(text, p);
|
|
6105
|
+
if (scan.kind === "invalid") return { tokens, consumed: p, invalid: base + scan.offset };
|
|
6106
|
+
if (scan.kind === "partial") return { tokens, consumed: p };
|
|
6107
|
+
const tok = { kind, start: base + p, end: base + scan.end };
|
|
6108
|
+
if (scan.dup !== void 0) tok.dup = base + scan.dup;
|
|
6109
|
+
tokens.push(tok);
|
|
6110
|
+
p = scan.end;
|
|
6111
|
+
}
|
|
6112
|
+
return { tokens, consumed: p };
|
|
6113
|
+
}
|
|
6114
|
+
var InputBuffer = class {
|
|
6115
|
+
size = 0;
|
|
6116
|
+
ptr = 0;
|
|
6117
|
+
end = 0;
|
|
6118
|
+
lastRequest = 0;
|
|
6119
|
+
/** Bytes the last attempt could not consume; 0 once something was. */
|
|
6120
|
+
hadBefore = 0;
|
|
6121
|
+
/** `XML_GetBuffer(len)` then the append of `len` bytes. */
|
|
6122
|
+
append(len) {
|
|
6123
|
+
this.lastRequest = len;
|
|
6124
|
+
if (len > this.size - this.end) {
|
|
6125
|
+
const keep = Math.min(this.ptr, XML_CONTEXT_BYTES);
|
|
6126
|
+
const needed = len + (this.end - this.ptr) + keep;
|
|
6127
|
+
if (needed > this.size) {
|
|
6128
|
+
let grown = this.size;
|
|
6129
|
+
if (grown === 0) grown = INIT_BUFFER_SIZE;
|
|
6130
|
+
do
|
|
6131
|
+
grown *= 2;
|
|
6132
|
+
while (grown < needed);
|
|
6133
|
+
this.size = grown;
|
|
6134
|
+
}
|
|
6135
|
+
this.end = this.end - this.ptr + keep;
|
|
6136
|
+
this.ptr = keep;
|
|
6137
|
+
}
|
|
6138
|
+
this.end += len;
|
|
6139
|
+
}
|
|
6140
|
+
/** Bytes between the read pointer and the end of the data. */
|
|
6141
|
+
get have() {
|
|
6142
|
+
return this.end - this.ptr;
|
|
6143
|
+
}
|
|
6144
|
+
/** `callProcessor`: is it worth re-reading the partial token now? */
|
|
6145
|
+
get enough() {
|
|
6146
|
+
const available = this.ptr - Math.min(this.ptr, XML_CONTEXT_BYTES) + (this.size - this.end);
|
|
6147
|
+
return this.have >= 2 * this.hadBefore || this.lastRequest > available;
|
|
6148
|
+
}
|
|
6149
|
+
/** After an attempt that left `remaining` bytes unconsumed. */
|
|
6150
|
+
consumedTo(remaining, madeProgress) {
|
|
6151
|
+
this.hadBefore = madeProgress ? 0 : this.have;
|
|
6152
|
+
this.ptr = this.end - remaining;
|
|
6153
|
+
}
|
|
6154
|
+
};
|
|
6155
|
+
var ExpatFeed = class {
|
|
6156
|
+
constructor(src) {
|
|
6157
|
+
this.src = src;
|
|
6158
|
+
}
|
|
6159
|
+
src;
|
|
6160
|
+
buffer = new InputBuffer();
|
|
6161
|
+
heldStart = 0;
|
|
6162
|
+
fedEnd = 0;
|
|
6163
|
+
/** Start of the token expat still holds, or undefined when it holds nothing. */
|
|
6164
|
+
get held() {
|
|
6165
|
+
return this.heldStart < this.fedEnd ? this.heldStart : void 0;
|
|
6166
|
+
}
|
|
6167
|
+
/** One `XML_Parse(parser, src[start, end), nbytes, 0)`. */
|
|
6168
|
+
feed(start, end, nbytes) {
|
|
6169
|
+
this.buffer.append(nbytes);
|
|
6170
|
+
this.fedEnd = end;
|
|
6171
|
+
if (!this.buffer.enough) return { tokens: [] };
|
|
6172
|
+
const text = this.src.slice(this.heldStart, end);
|
|
6173
|
+
const scan = scanContent(text, this.heldStart);
|
|
6174
|
+
if (scan.invalid !== void 0) {
|
|
6175
|
+
return { tokens: scan.tokens, invalid: { message: XML_ERROR_INVALID_TOKEN, offset: scan.invalid } };
|
|
6176
|
+
}
|
|
6177
|
+
this.heldStart += scan.consumed;
|
|
6178
|
+
this.buffer.consumedTo(byteLength(this.src.slice(this.heldStart, end)), scan.consumed > 0);
|
|
6179
|
+
return { tokens: scan.tokens };
|
|
6180
|
+
}
|
|
6181
|
+
};
|
|
6182
|
+
var XML_PREDEFINED_ENTITIES = /* @__PURE__ */ new Set(["lt", "gt", "amp", "quot", "apos"]);
|
|
6183
|
+
var ENTITY_NAME = /^[A-Za-z_:][\w.:-]*$/;
|
|
6184
|
+
function findUndefinedEntity(text) {
|
|
6185
|
+
for (let t = text.indexOf("&"); t >= 0; t = text.indexOf("&", t + 1)) {
|
|
6186
|
+
if (text[t + 1] === "#") continue;
|
|
6187
|
+
const semi = text.indexOf(";", t + 1);
|
|
6188
|
+
if (semi < 0) continue;
|
|
6189
|
+
const key = text.slice(t + 1, semi);
|
|
6190
|
+
if (ENTITY_NAME.test(key) && !Object.hasOwn(HTML_ENTITIES, key) && !XML_PREDEFINED_ENTITIES.has(key)) {
|
|
6191
|
+
return t;
|
|
6192
|
+
}
|
|
6193
|
+
}
|
|
6194
|
+
return -1;
|
|
6195
|
+
}
|
|
6196
|
+
function parseTagChunk(chunk) {
|
|
6197
|
+
if (!chunk.endsWith(">")) return void 0;
|
|
6198
|
+
const body = chunk.slice(1, -1);
|
|
6199
|
+
if (body.startsWith("!")) return void 0;
|
|
6200
|
+
const close = body.startsWith("/");
|
|
6201
|
+
const name = /^[^\s/>]*/.exec(close ? body.slice(1) : body)?.[0] ?? "";
|
|
6202
|
+
return { close, selfClose: !close && body.endsWith("/"), name };
|
|
6203
|
+
}
|
|
6204
|
+
|
|
6205
|
+
// src/common/htmltable-lex-units.ts
|
|
6206
|
+
var UNCLOSED_COMMENT = "Warning: Unclosed comment\n";
|
|
6207
|
+
var LABEL_CLOSED = "Warning: Label closed before end of HTML element\n";
|
|
6208
|
+
function eatComment(label, p) {
|
|
6209
|
+
let depth = 1;
|
|
6210
|
+
let s = p;
|
|
6211
|
+
while (depth > 0 && s < label.length) {
|
|
6212
|
+
const c = label[s++];
|
|
6213
|
+
if (c === "<") depth++;
|
|
6214
|
+
else if (c === ">") depth--;
|
|
6215
|
+
}
|
|
6216
|
+
if (depth === 0) s--;
|
|
6217
|
+
const warnings = [];
|
|
6218
|
+
if (s < label.length) {
|
|
6219
|
+
const t = s - 2;
|
|
6220
|
+
if (t < p || !label.startsWith("--", t)) warnings.push(UNCLOSED_COMMENT);
|
|
6221
|
+
}
|
|
6222
|
+
return { at: s, warnings };
|
|
6223
|
+
}
|
|
6224
|
+
function findNext(label, s) {
|
|
6225
|
+
let t = s + 1;
|
|
6226
|
+
const warnings = [];
|
|
6227
|
+
let warn = false;
|
|
6228
|
+
if (label[s] === "<") {
|
|
6229
|
+
if (label.startsWith("!--", t)) {
|
|
6230
|
+
const eaten = eatComment(label, t + 3);
|
|
6231
|
+
t = eaten.at;
|
|
6232
|
+
warnings.push(...eaten.warnings);
|
|
6233
|
+
warn = eaten.warnings.length > 0;
|
|
6234
|
+
} else {
|
|
6235
|
+
while (t < label.length && label[t] !== ">") t++;
|
|
6236
|
+
}
|
|
6237
|
+
if (label[t] !== ">") {
|
|
6238
|
+
warnings.push(LABEL_CLOSED);
|
|
6239
|
+
warn = true;
|
|
6240
|
+
} else {
|
|
6241
|
+
t++;
|
|
6242
|
+
}
|
|
6243
|
+
} else {
|
|
6244
|
+
t = s;
|
|
6245
|
+
while (t < label.length && label[t] !== "<") t++;
|
|
6246
|
+
}
|
|
6247
|
+
return { end: t, warnings, warn };
|
|
6248
|
+
}
|
|
6249
|
+
|
|
5758
6250
|
// src/common/htmltable-lex.ts
|
|
5759
6251
|
var KNOWN_TAGS = /* @__PURE__ */ new Set([
|
|
5760
6252
|
"TABLE",
|
|
@@ -5781,15 +6273,15 @@ function checkTag(tag) {
|
|
|
5781
6273
|
}
|
|
5782
6274
|
}
|
|
5783
6275
|
var isWs = (c) => c === " " || c === " " || c === "\n" || c === "\r";
|
|
5784
|
-
function
|
|
5785
|
-
const out =
|
|
6276
|
+
function parseAttrPairs(raw) {
|
|
6277
|
+
const out = [];
|
|
5786
6278
|
let i = 0;
|
|
5787
6279
|
while (i < raw.length) {
|
|
5788
6280
|
while (isWs(raw[i])) i++;
|
|
5789
6281
|
if (i >= raw.length) break;
|
|
5790
6282
|
const m = /^[\w-]+/.exec(raw.slice(i));
|
|
5791
6283
|
if (m === null) throw new HtmlParseError(raw.slice(i, i + 10));
|
|
5792
|
-
const name = m[0]
|
|
6284
|
+
const name = m[0];
|
|
5793
6285
|
i += m[0].length;
|
|
5794
6286
|
while (isWs(raw[i])) i++;
|
|
5795
6287
|
if (raw[i] !== "=") throw new HtmlParseError(name);
|
|
@@ -5799,7 +6291,7 @@ function parseAttrs(raw) {
|
|
|
5799
6291
|
if (q !== '"' && q !== "'") throw new HtmlParseError(name);
|
|
5800
6292
|
const end = raw.indexOf(q, i + 1);
|
|
5801
6293
|
if (end < 0) throw new HtmlParseError(name);
|
|
5802
|
-
out[name
|
|
6294
|
+
out.push([name, raw.slice(i + 1, end)]);
|
|
5803
6295
|
i = end + 1;
|
|
5804
6296
|
}
|
|
5805
6297
|
return out;
|
|
@@ -5818,48 +6310,36 @@ function cleanText(raw) {
|
|
|
5818
6310
|
const isKeep = (c) => c === " " || c === " " || c === "\n" || c === "\r";
|
|
5819
6311
|
return raw.replace(/[\x00-\x1f\x7f]/g, (c) => isKeep(c) ? c : "");
|
|
5820
6312
|
}
|
|
5821
|
-
function
|
|
5822
|
-
|
|
5823
|
-
|
|
5824
|
-
const clean = htmlEntityUTF8(cleanText(src.slice(start, j)));
|
|
5825
|
-
if (clean.length > 0) tokens.push({ type: "text", value: clean });
|
|
5826
|
-
return j;
|
|
6313
|
+
function textTokens(raw) {
|
|
6314
|
+
const clean = htmlEntityUTF8(cleanText(raw));
|
|
6315
|
+
return clean.length > 0 ? [{ type: "text", value: clean }] : [];
|
|
5827
6316
|
}
|
|
5828
|
-
function
|
|
5829
|
-
|
|
5830
|
-
|
|
5831
|
-
const inner = src.slice(start + 1, j).trim();
|
|
5832
|
-
const next = j + 1;
|
|
5833
|
-
if (inner.startsWith("!--")) return next;
|
|
5834
|
-
if (inner.startsWith("/")) {
|
|
5835
|
-
tokens.push(parseCloseToken(inner));
|
|
5836
|
-
return next;
|
|
5837
|
-
}
|
|
6317
|
+
function tagTokens(text) {
|
|
6318
|
+
const inner = text.slice(1, -1).trim();
|
|
6319
|
+
if (inner.startsWith("/")) return [parseCloseToken(inner)];
|
|
5838
6320
|
if (inner.endsWith("/")) {
|
|
5839
6321
|
const open = parseOpenToken(inner.slice(0, -1).trim());
|
|
5840
|
-
|
|
5841
|
-
return next;
|
|
6322
|
+
return [open, { type: "close", tag: open.tag }];
|
|
5842
6323
|
}
|
|
5843
|
-
|
|
5844
|
-
|
|
6324
|
+
return [parseOpenToken(inner)];
|
|
6325
|
+
}
|
|
6326
|
+
function openToken(tag, raw) {
|
|
6327
|
+
const { attrs, warnings, warn } = checkAttrs(tag, parseAttrPairs(raw));
|
|
6328
|
+
const tok = { type: "open", tag, attrs };
|
|
6329
|
+
if (warnings.length > 0) tok.warnings = warnings;
|
|
6330
|
+
if (warn) tok.warn = true;
|
|
6331
|
+
return tok;
|
|
5845
6332
|
}
|
|
5846
6333
|
function parseOpenToken(inner) {
|
|
5847
6334
|
const sp = inner.search(/\s/);
|
|
5848
|
-
|
|
5849
|
-
const tag2 = inner.toUpperCase();
|
|
5850
|
-
checkTag(tag2);
|
|
5851
|
-
return { type: "open", tag: normalizeTag(tag2), attrs: parseAttrs("") };
|
|
5852
|
-
}
|
|
5853
|
-
const tag = inner.slice(0, sp).toUpperCase();
|
|
6335
|
+
const tag = (sp === -1 ? inner : inner.slice(0, sp)).toUpperCase();
|
|
5854
6336
|
checkTag(tag);
|
|
5855
|
-
return
|
|
6337
|
+
return openToken(normalizeTag(tag), sp === -1 ? "" : inner.slice(sp + 1));
|
|
5856
6338
|
}
|
|
5857
6339
|
var XML_ERROR_UNDEFINED_ENTITY = "undefined entity";
|
|
5858
6340
|
var XML_ERROR_TAG_MISMATCH = "mismatched tag";
|
|
5859
|
-
var XML_ERROR_INVALID_TOKEN = "not well-formed (invalid token)";
|
|
5860
6341
|
var XML_ERROR_DUPLICATE_ATTRIBUTE = "duplicate attribute";
|
|
5861
|
-
var
|
|
5862
|
-
var XML_NAME = /^[A-Za-z_:][\w.:-]*$/;
|
|
6342
|
+
var SYNTAX_ERROR = "syntax error";
|
|
5863
6343
|
var HtmlLexError = class extends HtmlParseError {
|
|
5864
6344
|
diagnostics;
|
|
5865
6345
|
constructor(tag, message, diagnostics) {
|
|
@@ -5891,112 +6371,131 @@ function htmlErrorAtToken(message, tok) {
|
|
|
5891
6371
|
if (info === void 0) return void 0;
|
|
5892
6372
|
return htmlErrorInLine(message, chunkLine(info), info.context);
|
|
5893
6373
|
}
|
|
5894
|
-
function
|
|
5895
|
-
const
|
|
5896
|
-
|
|
5897
|
-
return src[i] === "<" ? j + 1 : j;
|
|
5898
|
-
}
|
|
5899
|
-
function findUndefinedEntity(text) {
|
|
5900
|
-
for (let t = text.indexOf("&"); t >= 0; t = text.indexOf("&", t + 1)) {
|
|
5901
|
-
if (text[t + 1] === "#") continue;
|
|
5902
|
-
const semi = text.indexOf(";", t + 1);
|
|
5903
|
-
if (semi < 0) continue;
|
|
5904
|
-
const key = text.slice(t + 1, semi);
|
|
5905
|
-
if (XML_NAME.test(key) && !Object.hasOwn(HTML_ENTITIES, key) && !XML_PREDEFINED_ENTITIES.has(key)) {
|
|
5906
|
-
return t;
|
|
5907
|
-
}
|
|
5908
|
-
}
|
|
5909
|
-
return -1;
|
|
5910
|
-
}
|
|
5911
|
-
function parseTagChunk(chunk) {
|
|
5912
|
-
if (!chunk.endsWith(">")) return void 0;
|
|
5913
|
-
const body = chunk.slice(1, -1);
|
|
5914
|
-
if (body.startsWith("!")) return void 0;
|
|
5915
|
-
const close = body.startsWith("/");
|
|
5916
|
-
const name = /^[^\s/>]*/.exec(close ? body.slice(1) : body)?.[0] ?? "";
|
|
5917
|
-
return { close, selfClose: !close && body.endsWith("/"), name };
|
|
5918
|
-
}
|
|
5919
|
-
var ATTR_NAME = /^[A-Za-z_:][\w.:-]*/;
|
|
5920
|
-
var isSpace = (c) => c !== void 0 && /\s/.test(c);
|
|
5921
|
-
var invalidToken = (offset) => ({ message: XML_ERROR_INVALID_TOKEN, offset });
|
|
5922
|
-
function skipSpace(chunk, i) {
|
|
5923
|
-
let j = i;
|
|
5924
|
-
while (isSpace(chunk[j])) j++;
|
|
5925
|
-
return j;
|
|
5926
|
-
}
|
|
5927
|
-
function readAttrPair(chunk, i) {
|
|
5928
|
-
const name = ATTR_NAME.exec(chunk.slice(i))?.[0];
|
|
5929
|
-
if (name === void 0) return invalidToken(i);
|
|
5930
|
-
let j = skipSpace(chunk, i + name.length);
|
|
5931
|
-
if (chunk[j] !== "=") return invalidToken(j);
|
|
5932
|
-
j = skipSpace(chunk, j + 1);
|
|
5933
|
-
const q = chunk[j];
|
|
5934
|
-
if (q !== '"' && q !== "'") return invalidToken(j);
|
|
5935
|
-
const end = chunk.indexOf(q, j + 1);
|
|
5936
|
-
return end < 0 ? void 0 : { name, next: end + 1 };
|
|
5937
|
-
}
|
|
5938
|
-
function findAttrError(chunk, from) {
|
|
5939
|
-
const seen = /* @__PURE__ */ new Set();
|
|
5940
|
-
let dup;
|
|
5941
|
-
let i = skipSpace(chunk, from);
|
|
5942
|
-
while (chunk[i] !== ">" && !(chunk[i] === "/" && chunk[i + 1] === ">")) {
|
|
5943
|
-
const pair = readAttrPair(chunk, i);
|
|
5944
|
-
if (pair === void 0) return void 0;
|
|
5945
|
-
if ("message" in pair) return pair;
|
|
5946
|
-
if (seen.has(pair.name) && dup === void 0) dup = { message: XML_ERROR_DUPLICATE_ATTRIBUTE, offset: i };
|
|
5947
|
-
seen.add(pair.name);
|
|
5948
|
-
i = skipSpace(chunk, pair.next);
|
|
5949
|
-
}
|
|
5950
|
-
return dup;
|
|
5951
|
-
}
|
|
5952
|
-
function checkTagChunk(src, start, st) {
|
|
5953
|
-
const tag = parseTagChunk(st.curr);
|
|
6374
|
+
function checkTagToken(site) {
|
|
6375
|
+
const { src, tok, st } = site;
|
|
6376
|
+
const tag = parseTagChunk(src.slice(tok.start, tok.end));
|
|
5954
6377
|
if (tag === void 0) return;
|
|
6378
|
+
const context = st.prev + st.curr;
|
|
5955
6379
|
if (tag.close) {
|
|
5956
6380
|
if (st.stack.length > 0 && st.stack.pop() !== tag.name) {
|
|
5957
|
-
throw htmlErrorInLine(XML_ERROR_TAG_MISMATCH, lineAt(src, start),
|
|
6381
|
+
throw htmlErrorInLine(XML_ERROR_TAG_MISMATCH, lineAt(src, tok.start), context);
|
|
5958
6382
|
}
|
|
5959
6383
|
} else {
|
|
5960
|
-
|
|
5961
|
-
if (bad !== void 0) {
|
|
5962
|
-
throw htmlErrorInLine(bad.message, lineAt(src, start + bad.offset), st.prev + st.curr);
|
|
5963
|
-
}
|
|
6384
|
+
if (tok.dup !== void 0) throw htmlErrorInLine(XML_ERROR_DUPLICATE_ATTRIBUTE, lineAt(src, tok.dup), context);
|
|
5964
6385
|
if (!tag.selfClose) st.stack.push(tag.name);
|
|
5965
6386
|
}
|
|
5966
6387
|
if (KNOWN_TAGS.has(tag.name.toUpperCase())) return;
|
|
5967
|
-
const text = `Unknown HTML element <${tag.name}> on line ${lineAt(src, start)} `;
|
|
6388
|
+
const text = `Unknown HTML element <${tag.name}> on line ${lineAt(src, tok.start)} `;
|
|
5968
6389
|
throw new HtmlLexError(tag.name.toUpperCase(), text, [`Error: ${text}`]);
|
|
5969
6390
|
}
|
|
5970
|
-
function
|
|
5971
|
-
|
|
5972
|
-
|
|
5973
|
-
|
|
6391
|
+
function eventTokens(site) {
|
|
6392
|
+
const { src, tok, st } = site;
|
|
6393
|
+
const text = src.slice(tok.start, tok.end);
|
|
6394
|
+
if (tok.kind === "comment" || tok.kind === "pi") return [];
|
|
6395
|
+
if (tok.kind === "tag") {
|
|
6396
|
+
checkTagToken(site);
|
|
6397
|
+
return tagTokens(text);
|
|
5974
6398
|
}
|
|
5975
|
-
const off = findUndefinedEntity(
|
|
6399
|
+
const off = findUndefinedEntity(text);
|
|
5976
6400
|
if (off >= 0) {
|
|
5977
|
-
throw htmlErrorInLine(XML_ERROR_UNDEFINED_ENTITY, lineAt(src, start + off), st.prev + st.curr);
|
|
6401
|
+
throw htmlErrorInLine(XML_ERROR_UNDEFINED_ENTITY, lineAt(src, tok.start + off), st.prev + st.curr);
|
|
6402
|
+
}
|
|
6403
|
+
return textTokens(text);
|
|
6404
|
+
}
|
|
6405
|
+
function attachCarry(carry, first) {
|
|
6406
|
+
if (carry.warnings.length > 0) first.warnings = [...carry.warnings, ...first.warnings ?? []];
|
|
6407
|
+
if (carry.warn) first.warn = true;
|
|
6408
|
+
carry.warnings = [];
|
|
6409
|
+
carry.warn = false;
|
|
6410
|
+
}
|
|
6411
|
+
function absorb(carry, lost) {
|
|
6412
|
+
for (const t of lost) {
|
|
6413
|
+
carry.warnings.push(...t.warnings ?? []);
|
|
6414
|
+
if (t.warn === true) carry.warn = true;
|
|
6415
|
+
}
|
|
6416
|
+
}
|
|
6417
|
+
function eventGroups(run, res) {
|
|
6418
|
+
const groups = [];
|
|
6419
|
+
for (const tok of res.tokens) {
|
|
6420
|
+
const tokens = eventTokens({ src: run.src, tok, st: run.st });
|
|
6421
|
+
if (tokens.length > 0) groups.push({ tokens, tok });
|
|
6422
|
+
}
|
|
6423
|
+
if (res.invalid !== void 0) {
|
|
6424
|
+
const { message, offset } = res.invalid;
|
|
6425
|
+
throw htmlErrorInLine(message, lineAt(run.src, offset), run.st.prev + run.st.curr);
|
|
6426
|
+
}
|
|
6427
|
+
return groups;
|
|
6428
|
+
}
|
|
6429
|
+
function deliver(run, last) {
|
|
6430
|
+
const first = last.tokens[0];
|
|
6431
|
+
attachCarry(run.carry, first);
|
|
6432
|
+
const info = { src: run.src, pos: last.tok.start, end: last.tok.end, context: run.st.prev + run.st.curr };
|
|
6433
|
+
const prev = run.tokens.at(-1);
|
|
6434
|
+
if (prev?.type === "text" && first.type === "text") {
|
|
6435
|
+
appendString(prev, first);
|
|
6436
|
+
chunkInfo.set(prev, { ...info, pos: chunkInfo.get(prev)?.pos ?? info.pos });
|
|
6437
|
+
return;
|
|
5978
6438
|
}
|
|
6439
|
+
for (const t of last.tokens) chunkInfo.set(t, info);
|
|
6440
|
+
run.tokens.push(...last.tokens);
|
|
5979
6441
|
}
|
|
5980
|
-
function
|
|
5981
|
-
const
|
|
5982
|
-
const
|
|
5983
|
-
|
|
6442
|
+
function runEvents(run, res) {
|
|
6443
|
+
const groups = eventGroups(run, res);
|
|
6444
|
+
const last = groups.pop();
|
|
6445
|
+
for (const g of groups) absorb(run.carry, g.tokens);
|
|
6446
|
+
if (last !== void 0) deliver(run, last);
|
|
6447
|
+
}
|
|
6448
|
+
function appendString(into, more) {
|
|
6449
|
+
into.value += more.value;
|
|
6450
|
+
if (more.warnings !== void 0) into.warnings = [...into.warnings ?? [], ...more.warnings];
|
|
6451
|
+
if (more.warn === true) into.warn = true;
|
|
6452
|
+
}
|
|
6453
|
+
function* lexUnits(src, label) {
|
|
6454
|
+
if (label.start > 0) yield { start: 0, end: label.start, warnings: [], warn: false };
|
|
6455
|
+
const text = src.slice(label.start, label.end);
|
|
6456
|
+
for (let at = 0; at < text.length; ) {
|
|
6457
|
+
const u = findNext(text, at);
|
|
6458
|
+
yield { start: label.start + at, end: label.start + u.end, warnings: u.warnings, warn: u.warn };
|
|
6459
|
+
at = u.end;
|
|
6460
|
+
}
|
|
6461
|
+
if (label.end < src.length) yield { start: label.end, end: src.length, warnings: [], warn: false };
|
|
6462
|
+
}
|
|
6463
|
+
function unfinishedError(run, held) {
|
|
6464
|
+
return htmlErrorInLine(SYNTAX_ERROR, lineAt(run.src, held), run.st.prev + run.st.curr);
|
|
6465
|
+
}
|
|
6466
|
+
var eofOutput = (carry) => {
|
|
6467
|
+
if (carry.warnings.length === 0 && !carry.warn) return void 0;
|
|
6468
|
+
return carry.warn ? { warnings: carry.warnings, warn: true } : { warnings: carry.warnings };
|
|
6469
|
+
};
|
|
6470
|
+
function tokenizeDeferred(src, label = { start: 0, end: src.length }) {
|
|
6471
|
+
const run = {
|
|
6472
|
+
src,
|
|
6473
|
+
tokens: [],
|
|
6474
|
+
st: { stack: [], prev: "", curr: "" },
|
|
6475
|
+
expat: new ExpatFeed(src),
|
|
6476
|
+
carry: { warnings: [], warn: false }
|
|
6477
|
+
};
|
|
6478
|
+
let error;
|
|
5984
6479
|
try {
|
|
5985
|
-
|
|
5986
|
-
|
|
5987
|
-
|
|
5988
|
-
|
|
5989
|
-
|
|
5990
|
-
|
|
5991
|
-
|
|
5992
|
-
|
|
5993
|
-
|
|
5994
|
-
|
|
6480
|
+
for (const u of lexUnits(src, label)) {
|
|
6481
|
+
run.st.prev = run.st.curr;
|
|
6482
|
+
run.st.curr = src.slice(u.start, u.end);
|
|
6483
|
+
run.carry.warnings.push(...u.warnings);
|
|
6484
|
+
if (u.warn) run.carry.warn = true;
|
|
6485
|
+
const nbytes = fedBytes(run.st.curr, !run.st.curr.startsWith("<"));
|
|
6486
|
+
runEvents(run, run.expat.feed(u.start, u.end, nbytes));
|
|
6487
|
+
}
|
|
6488
|
+
const held = run.expat.held;
|
|
6489
|
+
if (held !== void 0) error = unfinishedError(run, held);
|
|
5995
6490
|
} catch (e) {
|
|
5996
|
-
if (e instanceof HtmlParseError)
|
|
5997
|
-
|
|
6491
|
+
if (!(e instanceof HtmlParseError)) throw e;
|
|
6492
|
+
error = e;
|
|
5998
6493
|
}
|
|
5999
|
-
|
|
6494
|
+
const result = { tokens: run.tokens };
|
|
6495
|
+
if (error !== void 0) result.error = error;
|
|
6496
|
+
const eof = eofOutput(run.carry);
|
|
6497
|
+
if (eof !== void 0) result.eof = eof;
|
|
6498
|
+
return result;
|
|
6000
6499
|
}
|
|
6001
6500
|
|
|
6002
6501
|
// src/common/htmltable-parse-attrs.ts
|
|
@@ -6036,15 +6535,9 @@ var parseSides = (v) => {
|
|
|
6036
6535
|
if (flags === 0 || flags === BORDER_MASK) return void 0;
|
|
6037
6536
|
return flags;
|
|
6038
6537
|
};
|
|
6039
|
-
var parseGradientAngle = (v) =>
|
|
6040
|
-
|
|
6041
|
-
|
|
6042
|
-
if (isNaN(n) || String(n) !== v.trim()) return void 0;
|
|
6043
|
-
if (n < 0 || n > 360) return void 0;
|
|
6044
|
-
return n;
|
|
6045
|
-
};
|
|
6046
|
-
var parseColumns = (v) => v === "*" ? true : void 0;
|
|
6047
|
-
var parseRows = (v) => v === "*" ? true : void 0;
|
|
6538
|
+
var parseGradientAngle = (v) => num(v);
|
|
6539
|
+
var parseColumns = (v) => v?.startsWith("*") === true ? true : void 0;
|
|
6540
|
+
var parseRows = (v) => v?.startsWith("*") === true ? true : void 0;
|
|
6048
6541
|
var buildCell = (content, a) => ({
|
|
6049
6542
|
kind: "cell",
|
|
6050
6543
|
content,
|
|
@@ -6096,7 +6589,7 @@ var buildTable = (rows, a) => ({
|
|
|
6096
6589
|
hrule: parseRows(a["rows"])
|
|
6097
6590
|
});
|
|
6098
6591
|
|
|
6099
|
-
// src/common/htmltable-parse.ts
|
|
6592
|
+
// src/common/htmltable-parse-font.ts
|
|
6100
6593
|
var definedOf = (s) => Object.fromEntries(
|
|
6101
6594
|
Object.entries(s).filter(([, v]) => v !== void 0)
|
|
6102
6595
|
);
|
|
@@ -6120,17 +6613,6 @@ var fontItemProps = (f) => {
|
|
|
6120
6613
|
if (f.fontSize !== void 0) out.fontSize = f.fontSize;
|
|
6121
6614
|
return out;
|
|
6122
6615
|
};
|
|
6123
|
-
var MSG_SYNTAX_ERROR = "syntax error";
|
|
6124
|
-
var MSG_TEXT_BEFORE_TABLE = "Syntax error: non-space string used before <TABLE>";
|
|
6125
|
-
var MSG_TEXT_AFTER_TABLE = "Syntax error: non-space string used after </TABLE>";
|
|
6126
|
-
var nonSpace = (text) => /[^ \t\n\r]/.test(text);
|
|
6127
|
-
var parseError = (s, tok, message) => (tok === void 0 ? s.pending : htmlErrorAtToken(message, tok)) ?? new HtmlParseError(message);
|
|
6128
|
-
var peek = (s) => s.tokens[s.pos];
|
|
6129
|
-
var consume = (s) => {
|
|
6130
|
-
const t = s.tokens[s.pos];
|
|
6131
|
-
s.pos++;
|
|
6132
|
-
return t;
|
|
6133
|
-
};
|
|
6134
6616
|
var isInlineTag = (tag) => ["B", "I", "U", "O", "S", "SUB", "SUP"].includes(tag);
|
|
6135
6617
|
var inlineFontState = (tag, _attrs) => {
|
|
6136
6618
|
const fs = {};
|
|
@@ -6143,6 +6625,35 @@ var inlineFontState = (tag, _attrs) => {
|
|
|
6143
6625
|
if (tag === "SUP") fs.superscript = true;
|
|
6144
6626
|
return fs;
|
|
6145
6627
|
};
|
|
6628
|
+
var wrapperFont = (t, fontStack) => {
|
|
6629
|
+
const font = fontStack[fontStack.length - 1] ?? {};
|
|
6630
|
+
if (t.tag !== "FONT") return mergeFontState(font, inlineFontState(t.tag, t.attrs));
|
|
6631
|
+
return mergeFontState(font, {
|
|
6632
|
+
fontColor: t.attrs["color"],
|
|
6633
|
+
fontFace: t.attrs["face"],
|
|
6634
|
+
fontSize: num(t.attrs["point-size"])
|
|
6635
|
+
});
|
|
6636
|
+
};
|
|
6637
|
+
var tableFont = (fontStack) => {
|
|
6638
|
+
if (fontStack.length < 2) return void 0;
|
|
6639
|
+
const { fontColor, fontFace, fontSize } = fontStack[fontStack.length - 1];
|
|
6640
|
+
const font = {};
|
|
6641
|
+
if (fontColor !== void 0) font.fontColor = fontColor;
|
|
6642
|
+
if (fontFace !== void 0) font.fontFace = fontFace;
|
|
6643
|
+
if (fontSize !== void 0) font.fontSize = fontSize;
|
|
6644
|
+
return font;
|
|
6645
|
+
};
|
|
6646
|
+
|
|
6647
|
+
// src/common/htmltable-parse.ts
|
|
6648
|
+
var MSG_SYNTAX_ERROR = "syntax error";
|
|
6649
|
+
var MSG_TEXT_BEFORE_TABLE = "Syntax error: non-space string used before <TABLE>";
|
|
6650
|
+
var MSG_TEXT_AFTER_TABLE = "Syntax error: non-space string used after </TABLE>";
|
|
6651
|
+
var nonSpace = (text) => /[^ \t\n\r]/.test(text);
|
|
6652
|
+
var parseError = (s, tok, message) => {
|
|
6653
|
+
if (tok !== void 0) emitWarnings(s, tok);
|
|
6654
|
+
else emitEof(s);
|
|
6655
|
+
return (tok === void 0 ? s.pending : htmlErrorAtToken(message, tok)) ?? new HtmlParseError(message);
|
|
6656
|
+
};
|
|
6146
6657
|
var consumeClose = (s, tag) => {
|
|
6147
6658
|
const nxt = peek(s);
|
|
6148
6659
|
if (nxt === void 0) return;
|
|
@@ -6213,6 +6724,45 @@ var parseText = (s, fontStack) => {
|
|
|
6213
6724
|
}
|
|
6214
6725
|
return { kind: "text", items };
|
|
6215
6726
|
};
|
|
6727
|
+
var FONTTABLE_TAGS = ["FONT", "B", "I", "U", "O"];
|
|
6728
|
+
var fontTableWrapper = (s) => {
|
|
6729
|
+
const open = peek(s);
|
|
6730
|
+
if (open?.type !== "open" || !FONTTABLE_TAGS.includes(open.tag)) return void 0;
|
|
6731
|
+
let i = s.pos + 1;
|
|
6732
|
+
while (s.tokens[i]?.type === "text") i++;
|
|
6733
|
+
const next = s.tokens[i];
|
|
6734
|
+
return next?.type === "open" && next.tag === "TABLE" ? open : void 0;
|
|
6735
|
+
};
|
|
6736
|
+
var skipStrings = (s) => {
|
|
6737
|
+
let found = false;
|
|
6738
|
+
for (let t = peek(s); t?.type === "text"; t = peek(s)) {
|
|
6739
|
+
consume(s);
|
|
6740
|
+
if (nonSpace(t.value)) found = true;
|
|
6741
|
+
}
|
|
6742
|
+
return found;
|
|
6743
|
+
};
|
|
6744
|
+
var parseFontTable = (s, open, fontStack) => {
|
|
6745
|
+
consume(s);
|
|
6746
|
+
fontStack.push(wrapperFont(open, fontStack));
|
|
6747
|
+
const textBefore = skipStrings(s);
|
|
6748
|
+
const tblTok = peek(s);
|
|
6749
|
+
if (textBefore && tblTok !== void 0) throw parseError(s, tblTok, MSG_TEXT_BEFORE_TABLE);
|
|
6750
|
+
const table = parseTable(s, fontStack);
|
|
6751
|
+
const textAfter = skipStrings(s);
|
|
6752
|
+
const close = peek(s);
|
|
6753
|
+
if (close !== void 0 && textAfter) throw parseError(s, close, MSG_TEXT_AFTER_TABLE);
|
|
6754
|
+
if (close?.type !== "close" || close.tag !== open.tag) throw parseError(s, close, MSG_SYNTAX_ERROR);
|
|
6755
|
+
consume(s);
|
|
6756
|
+
fontStack.pop();
|
|
6757
|
+
return table;
|
|
6758
|
+
};
|
|
6759
|
+
var rejectTableAfterTag = (s, start) => {
|
|
6760
|
+
const nxt = peek(s);
|
|
6761
|
+
if (nxt?.type !== "open" || nxt.tag !== "TABLE") return;
|
|
6762
|
+
if (s.tokens.slice(start, s.pos).some((t) => t.type !== "text")) {
|
|
6763
|
+
throw parseError(s, nxt, MSG_SYNTAX_ERROR);
|
|
6764
|
+
}
|
|
6765
|
+
};
|
|
6216
6766
|
var parseImgContent = (s, t, cellAttrs) => {
|
|
6217
6767
|
consume(s);
|
|
6218
6768
|
const img = {
|
|
@@ -6234,6 +6784,7 @@ var scanCellText = (s, t, fontStack, st) => {
|
|
|
6234
6784
|
const start = s.pos;
|
|
6235
6785
|
const txt = parseText(s, fontStack);
|
|
6236
6786
|
if (s.pos === start) throw parseError(s, t, MSG_SYNTAX_ERROR);
|
|
6787
|
+
rejectTableAfterTag(s, start);
|
|
6237
6788
|
if (txt.items.some((i) => i.text !== void 0 && nonSpace(i.text))) st.textNonSpace = true;
|
|
6238
6789
|
st.kind = "text";
|
|
6239
6790
|
return txt.items.length > 0 ? [txt] : [];
|
|
@@ -6250,7 +6801,13 @@ var scanCellImage = (s, t, cellAttrs, st) => {
|
|
|
6250
6801
|
return [parseImgContent(s, t, cellAttrs)];
|
|
6251
6802
|
};
|
|
6252
6803
|
var scanCellItem = (s, t, cellAttrs, fontStack, st) => {
|
|
6804
|
+
if (st.kind === "fonttable") throw parseError(s, t, MSG_SYNTAX_ERROR);
|
|
6253
6805
|
if (st.kind === "table") return scanAfterTable(s, t, st);
|
|
6806
|
+
const wrapper = st.kind === "none" ? fontTableWrapper(s) : void 0;
|
|
6807
|
+
if (wrapper !== void 0) {
|
|
6808
|
+
st.kind = "fonttable";
|
|
6809
|
+
return [parseFontTable(s, wrapper, fontStack)];
|
|
6810
|
+
}
|
|
6254
6811
|
if (t.type === "open" && t.tag === "TABLE") return scanCellTable(s, t, fontStack, st);
|
|
6255
6812
|
if (t.type === "open" && t.tag === "IMG") return scanCellImage(s, t, cellAttrs, st);
|
|
6256
6813
|
if (st.kind === "image") throw parseError(s, t, MSG_SYNTAX_ERROR);
|
|
@@ -6353,7 +6910,10 @@ var parseTable = (s, fontStack) => {
|
|
|
6353
6910
|
for (let t = peek(s); t !== void 0; t = peek(s)) {
|
|
6354
6911
|
if (scanTableToken(s, t, fontStack, ts)) break;
|
|
6355
6912
|
}
|
|
6356
|
-
|
|
6913
|
+
const table = buildTable(ts.rows, open.attrs);
|
|
6914
|
+
const font = tableFont(fontStack);
|
|
6915
|
+
if (font !== void 0) table.font = font;
|
|
6916
|
+
return table;
|
|
6357
6917
|
};
|
|
6358
6918
|
var parseTableRow = (s, fontStack, opts) => {
|
|
6359
6919
|
const row = parseRow(s, fontStack);
|
|
@@ -6393,6 +6953,14 @@ var finishTableLabel = (s) => {
|
|
|
6393
6953
|
if (nxt.type !== "close" || nxt.tag !== "HTML") throw parseError(s, nxt, MSG_SYNTAX_ERROR);
|
|
6394
6954
|
consume(s);
|
|
6395
6955
|
};
|
|
6956
|
+
var parseFontTableLabel = (s, open, fontStack) => {
|
|
6957
|
+
const table = parseFontTable(s, open, fontStack);
|
|
6958
|
+
const nxt = peek(s);
|
|
6959
|
+
if (nxt === void 0) return { kind: "table", table };
|
|
6960
|
+
if (nxt.type !== "close" || nxt.tag !== "HTML") throw parseError(s, nxt, MSG_SYNTAX_ERROR);
|
|
6961
|
+
consume(s);
|
|
6962
|
+
return { kind: "table", table };
|
|
6963
|
+
};
|
|
6396
6964
|
var parseTableLabel = (s, fontStack) => {
|
|
6397
6965
|
skipLeadingWs(s);
|
|
6398
6966
|
const table = parseTable(s, fontStack);
|
|
@@ -6401,17 +6969,16 @@ var parseTableLabel = (s, fontStack) => {
|
|
|
6401
6969
|
};
|
|
6402
6970
|
var parseTextLabel = (s, fontStack) => {
|
|
6403
6971
|
const texts = [];
|
|
6972
|
+
const start = s.pos;
|
|
6404
6973
|
const txt = parseText(s, fontStack);
|
|
6405
6974
|
if (txt.items.length > 0) texts.push(txt);
|
|
6406
6975
|
const nxt = peek(s);
|
|
6407
6976
|
if (nxt === void 0) return { kind: "text", texts };
|
|
6408
6977
|
if (nxt.type === "open" && nxt.tag === "TABLE") {
|
|
6409
|
-
|
|
6410
|
-
|
|
6411
|
-
}
|
|
6412
|
-
throw new HtmlParseError("TABLE");
|
|
6978
|
+
rejectTableAfterTag(s, start);
|
|
6979
|
+
throw parseError(s, nxt, MSG_TEXT_BEFORE_TABLE);
|
|
6413
6980
|
}
|
|
6414
|
-
if (nxt.type !== "close" || nxt.tag !== "HTML") throw parseError(s, nxt, MSG_SYNTAX_ERROR);
|
|
6981
|
+
if (nxt.type !== "close" || nxt.tag !== "HTML" || s.pos === start) throw parseError(s, nxt, MSG_SYNTAX_ERROR);
|
|
6415
6982
|
consume(s);
|
|
6416
6983
|
return { kind: "text", texts };
|
|
6417
6984
|
};
|
|
@@ -6419,23 +6986,38 @@ var parseTokens = (s) => {
|
|
|
6419
6986
|
const fontStack = [{}];
|
|
6420
6987
|
const htmlOpen = consume(s);
|
|
6421
6988
|
if (htmlOpen.type !== "open" || htmlOpen.tag !== "HTML") throw new HtmlParseError("HTML");
|
|
6989
|
+
const wrapper = fontTableWrapper(s);
|
|
6990
|
+
if (wrapper !== void 0) return parseFontTableLabel(s, wrapper, fontStack);
|
|
6422
6991
|
const firstReal = findFirstRealToken(s.tokens, s.pos);
|
|
6423
6992
|
if (firstReal?.type === "open" && firstReal.tag === "TABLE") return parseTableLabel(s, fontStack);
|
|
6424
6993
|
return parseTextLabel(s, fontStack);
|
|
6425
6994
|
};
|
|
6426
|
-
var
|
|
6427
|
-
const { tokens, error } = tokenizeDeferred(`<HTML>${src}</HTML
|
|
6428
|
-
const s = {
|
|
6429
|
-
|
|
6995
|
+
var parseHtmlLabelRv = (src, writeLine = (line) => console.warn(line)) => {
|
|
6996
|
+
const { tokens, error, eof } = tokenizeDeferred(`<HTML>${src}</HTML>`, { start: 6, end: 6 + src.length });
|
|
6997
|
+
const s = {
|
|
6998
|
+
tokens,
|
|
6999
|
+
pos: 0,
|
|
7000
|
+
pending: error,
|
|
7001
|
+
stderr: new StderrLines(writeLine),
|
|
7002
|
+
emitted: /* @__PURE__ */ new WeakSet(),
|
|
7003
|
+
warn: false,
|
|
7004
|
+
eof
|
|
7005
|
+
};
|
|
6430
7006
|
try {
|
|
6431
|
-
label = parseTokens(s);
|
|
7007
|
+
const label = parseTokens(s);
|
|
7008
|
+
if (error !== void 0) throw error;
|
|
7009
|
+
return { label, warn: s.warn === true };
|
|
6432
7010
|
} catch (e) {
|
|
6433
|
-
if (error !== void 0 && s.pos >= tokens.length)
|
|
7011
|
+
if (error !== void 0 && s.pos >= tokens.length) {
|
|
7012
|
+
emitEof(s);
|
|
7013
|
+
throw error;
|
|
7014
|
+
}
|
|
6434
7015
|
throw e;
|
|
7016
|
+
} finally {
|
|
7017
|
+
s.stderr?.flush();
|
|
6435
7018
|
}
|
|
6436
|
-
if (error !== void 0) throw error;
|
|
6437
|
-
return label;
|
|
6438
7019
|
};
|
|
7020
|
+
var parseHtmlLabel = (src) => parseHtmlLabelRv(src, () => void 0).label;
|
|
6439
7021
|
|
|
6440
7022
|
// src/gvc/usershape.ts
|
|
6441
7023
|
var activeSizer = null;
|
|
@@ -6494,6 +7076,41 @@ var PointSet = class {
|
|
|
6494
7076
|
}
|
|
6495
7077
|
};
|
|
6496
7078
|
|
|
7079
|
+
// src/common/htmltable-fontinfo.ts
|
|
7080
|
+
var SIZE_SAVEF = { fontsize: 0 };
|
|
7081
|
+
var EMIT_SAVEF = { fontsize: 0 };
|
|
7082
|
+
var pushFontInfo = (env, fp, savp) => {
|
|
7083
|
+
if (fp.fontFace !== void 0) {
|
|
7084
|
+
savp.fontname = env.fontname;
|
|
7085
|
+
env.fontname = fp.fontFace;
|
|
7086
|
+
} else savp.fontname = void 0;
|
|
7087
|
+
if (env.fontcolor !== void 0) {
|
|
7088
|
+
if (fp.fontColor !== void 0) {
|
|
7089
|
+
savp.fontcolor = env.fontcolor;
|
|
7090
|
+
env.fontcolor = fp.fontColor;
|
|
7091
|
+
} else savp.fontcolor = void 0;
|
|
7092
|
+
}
|
|
7093
|
+
if (env.fontsize >= 0) {
|
|
7094
|
+
if (fp.fontSize !== void 0 && fp.fontSize >= 0) {
|
|
7095
|
+
savp.fontsize = env.fontsize;
|
|
7096
|
+
env.fontsize = fp.fontSize;
|
|
7097
|
+
} else savp.fontsize = -1;
|
|
7098
|
+
}
|
|
7099
|
+
};
|
|
7100
|
+
var popFontInfo = (env, savp) => {
|
|
7101
|
+
if (savp.fontname !== void 0) env.fontname = savp.fontname;
|
|
7102
|
+
if (savp.fontcolor !== void 0) env.fontcolor = savp.fontcolor;
|
|
7103
|
+
if (savp.fontsize >= 0) env.fontsize = savp.fontsize;
|
|
7104
|
+
};
|
|
7105
|
+
var withTableFont = (env, font, slot, fn) => {
|
|
7106
|
+
if (font === void 0) return fn();
|
|
7107
|
+
const savp = slot === "size" ? SIZE_SAVEF : EMIT_SAVEF;
|
|
7108
|
+
pushFontInfo(env, font, savp);
|
|
7109
|
+
const r = fn();
|
|
7110
|
+
popFontInfo(env, savp);
|
|
7111
|
+
return r;
|
|
7112
|
+
};
|
|
7113
|
+
|
|
6497
7114
|
// src/common/htmltable.ts
|
|
6498
7115
|
var DEFAULT_BORDER = 1;
|
|
6499
7116
|
var DEFAULT_CELLPADDING = 2;
|
|
@@ -6519,7 +7136,7 @@ var findCol = (ps, row, startCol, colspan, rowspan) => {
|
|
|
6519
7136
|
}
|
|
6520
7137
|
return col;
|
|
6521
7138
|
};
|
|
6522
|
-
var
|
|
7139
|
+
var defaultSizeEnv = () => ({ fontsize: DEFAULT_FONTSIZE, fontname: "" });
|
|
6523
7140
|
var itemFont = (item, env) => ({
|
|
6524
7141
|
fs: item.fontSize !== void 0 ? item.fontSize : env.fontsize,
|
|
6525
7142
|
face: item.fontFace !== void 0 ? item.fontFace : env.fontname
|
|
@@ -6582,7 +7199,7 @@ var htmlTextIsSimple = (texts, env) => {
|
|
|
6582
7199
|
}
|
|
6583
7200
|
return true;
|
|
6584
7201
|
};
|
|
6585
|
-
var sizeTextContent = (texts, measurer, env =
|
|
7202
|
+
var sizeTextContent = (texts, measurer, env = defaultSizeEnv()) => {
|
|
6586
7203
|
const lines = splitSizedLines(texts, measurer, env);
|
|
6587
7204
|
const simple = htmlTextIsSimple(texts, env);
|
|
6588
7205
|
let w = 0;
|
|
@@ -6751,18 +7368,18 @@ var sumTableDims = (a) => {
|
|
|
6751
7368
|
for (let i = 0; i < a.nrows; i++) ht += a.heights[i];
|
|
6752
7369
|
return { wd, ht };
|
|
6753
7370
|
};
|
|
6754
|
-
var layoutHtmlTable = (tbl, measurer, env =
|
|
7371
|
+
var layoutHtmlTable = (tbl, measurer, env = defaultSizeEnv()) => {
|
|
6755
7372
|
const spacing = getSpacing(tbl);
|
|
6756
|
-
const
|
|
7373
|
+
const border2 = getBorder(tbl);
|
|
6757
7374
|
const { entries, rv } = buildLayouts(tbl, measurer, env);
|
|
6758
7375
|
if (entries.length === 0) {
|
|
6759
|
-
return { entries, widths: [], heights: [], spacing, border, rv };
|
|
7376
|
+
return { entries, widths: [], heights: [], spacing, border: border2, rv };
|
|
6760
7377
|
}
|
|
6761
7378
|
const ncols = Math.max(...entries.map((e) => e.col + e.colspan));
|
|
6762
7379
|
const nrows = Math.max(...entries.map((e) => e.row + e.rowspan));
|
|
6763
7380
|
const widths = setColWidths(entries, ncols, spacing);
|
|
6764
7381
|
const heights = setRowHeights(entries, nrows, spacing);
|
|
6765
|
-
return { entries, widths, heights, spacing, border, rv };
|
|
7382
|
+
return { entries, widths, heights, spacing, border: border2, rv };
|
|
6766
7383
|
};
|
|
6767
7384
|
var warnFixedTable = (tbl, dims) => {
|
|
6768
7385
|
const warn = !sizeWarned.has(tbl);
|
|
@@ -6776,17 +7393,17 @@ var warnFixedTable = (tbl, dims) => {
|
|
|
6776
7393
|
if (warn) console.warn(WARN_TABLE_UNSPECIFIED);
|
|
6777
7394
|
return 1;
|
|
6778
7395
|
};
|
|
6779
|
-
var
|
|
6780
|
-
const { entries, widths, heights, spacing, border, rv } = layoutHtmlTable(tbl, measurer, env);
|
|
7396
|
+
var sizeTableBody = (tbl, measurer, env) => {
|
|
7397
|
+
const { entries, widths, heights, spacing, border: border2, rv } = layoutHtmlTable(tbl, measurer, env);
|
|
6781
7398
|
if (entries.length === 0) {
|
|
6782
|
-
const fixed2 = warnFixedTable(tbl, sumTableDims({ widths, heights, ncols: 0, nrows: 0, spacing, border }));
|
|
7399
|
+
const fixed2 = warnFixedTable(tbl, sumTableDims({ widths, heights, ncols: 0, nrows: 0, spacing, border: border2 }));
|
|
6783
7400
|
tbl.dimen = { w: 0, h: 0 };
|
|
6784
7401
|
return rv | fixed2;
|
|
6785
7402
|
}
|
|
6786
7403
|
const ncols = Math.max(...entries.map((e) => e.col + e.colspan));
|
|
6787
7404
|
const nrows = Math.max(...entries.map((e) => e.row + e.rowspan));
|
|
6788
7405
|
for (const e of entries) e.cell.dimen = { w: e.w, h: e.h };
|
|
6789
|
-
const { wd, ht } = sumTableDims({ widths, heights, ncols, nrows, spacing, border });
|
|
7406
|
+
const { wd, ht } = sumTableDims({ widths, heights, ncols, nrows, spacing, border: border2 });
|
|
6790
7407
|
const baseWd = tbl.width !== void 0 ? tbl.width : 0;
|
|
6791
7408
|
const baseHt = tbl.height !== void 0 ? tbl.height : 0;
|
|
6792
7409
|
const fixed = warnFixedTable(tbl, { wd, ht });
|
|
@@ -6797,7 +7414,8 @@ var sizeTableInner = (tbl, measurer, env) => {
|
|
|
6797
7414
|
};
|
|
6798
7415
|
return rv | fixed;
|
|
6799
7416
|
};
|
|
6800
|
-
var
|
|
7417
|
+
var sizeTableInner = (tbl, measurer, env) => withTableFont(env, tbl.font, "size", () => sizeTableBody(tbl, measurer, env));
|
|
7418
|
+
var sizeHtmlLabel = (label, measurer, env = defaultSizeEnv()) => {
|
|
6801
7419
|
if (label.kind === "table") {
|
|
6802
7420
|
const rv = sizeTableInner(label.table, measurer, env);
|
|
6803
7421
|
label.dimen = label.table.dimen;
|
|
@@ -7015,8 +7633,8 @@ function alignContentBox(box, cell2, w, h) {
|
|
|
7015
7633
|
var HTML_ALL_SIDES = TOP | BOTTOM | LEFT | RIGHT;
|
|
7016
7634
|
function placeCellRuns(ctx) {
|
|
7017
7635
|
const { cell: cell2, tbl, box, finfo, measurer } = ctx;
|
|
7018
|
-
const
|
|
7019
|
-
const inset =
|
|
7636
|
+
const border2 = cellBorder(cell2, tbl);
|
|
7637
|
+
const inset = border2 + cellPad(cell2, tbl);
|
|
7020
7638
|
const cbox = {
|
|
7021
7639
|
ll: { x: box.ll.x + inset, y: box.ll.y + inset },
|
|
7022
7640
|
ur: { x: box.ur.x - inset, y: box.ur.y - inset }
|
|
@@ -7065,17 +7683,17 @@ function placeCellNested(ctx) {
|
|
|
7065
7683
|
ll: { x: box.ll.x + inset, y: box.ll.y + inset },
|
|
7066
7684
|
ur: { x: box.ur.x - inset, y: box.ur.y - inset }
|
|
7067
7685
|
};
|
|
7068
|
-
return posHtmlTable(nested2, finfo, measurer, cbox, sidesMask);
|
|
7686
|
+
return withTableFont(finfo, nested2.font, "emit", () => posHtmlTable(nested2, finfo, measurer, cbox, sidesMask));
|
|
7069
7687
|
}
|
|
7070
7688
|
function placeCell(ctx) {
|
|
7071
7689
|
const { cell: cell2, tbl, box, col, row, colspan, rowspan } = ctx;
|
|
7072
|
-
const
|
|
7690
|
+
const border2 = cellBorder(cell2, tbl);
|
|
7073
7691
|
const vruled = cell2.vruled;
|
|
7074
7692
|
const nested2 = placeCellNested(ctx);
|
|
7075
7693
|
const image = nested2 === void 0 ? placeCellImage(cell2, tbl, box) : void 0;
|
|
7076
7694
|
return {
|
|
7077
7695
|
box,
|
|
7078
|
-
border,
|
|
7696
|
+
border: border2,
|
|
7079
7697
|
lines: nested2 === void 0 ? placeCellRuns(ctx) : [],
|
|
7080
7698
|
image,
|
|
7081
7699
|
nested: nested2,
|
|
@@ -7105,18 +7723,18 @@ function distributeExtra(sizes, del, count) {
|
|
|
7105
7723
|
const plus = r >= 0 ? Math.floor(r + 0.5) : Math.ceil(r - 0.5);
|
|
7106
7724
|
return sizes.map((w, i) => w + extra + (i < plus ? 1 : 0));
|
|
7107
7725
|
}
|
|
7108
|
-
function buildColX(pos,
|
|
7726
|
+
function buildColX(pos, border2, spacing, widths) {
|
|
7109
7727
|
const colX = [];
|
|
7110
|
-
let x = pos.ll.x +
|
|
7728
|
+
let x = pos.ll.x + border2 + spacing;
|
|
7111
7729
|
for (let i = 0; i < widths.length; i++) {
|
|
7112
7730
|
colX[i] = x;
|
|
7113
7731
|
x += widths[i] + spacing;
|
|
7114
7732
|
}
|
|
7115
7733
|
return colX;
|
|
7116
7734
|
}
|
|
7117
|
-
function buildRowY(pos,
|
|
7735
|
+
function buildRowY(pos, border2, spacing, heights) {
|
|
7118
7736
|
const rowY = [];
|
|
7119
|
-
let y = pos.ur.y -
|
|
7737
|
+
let y = pos.ur.y - border2 - spacing;
|
|
7120
7738
|
for (let i = 0; i < heights.length; i++) {
|
|
7121
7739
|
rowY[i] = y;
|
|
7122
7740
|
y -= heights[i] + spacing;
|
|
@@ -7136,14 +7754,14 @@ function tblDecoration(tbl) {
|
|
|
7136
7754
|
gradientangle: tbl.gradientangle
|
|
7137
7755
|
};
|
|
7138
7756
|
}
|
|
7139
|
-
function cellSidesMask(e, ncols, nrows,
|
|
7140
|
-
if (
|
|
7757
|
+
function cellSidesMask(e, ncols, nrows, sides2) {
|
|
7758
|
+
if (sides2 === 0) return 0;
|
|
7141
7759
|
let mask = 0;
|
|
7142
7760
|
if (e.col === 0) mask |= LEFT;
|
|
7143
7761
|
if (e.row === 0) mask |= TOP;
|
|
7144
7762
|
if (e.col + e.colspan === ncols) mask |= RIGHT;
|
|
7145
7763
|
if (e.row + e.rowspan === nrows) mask |= BOTTOM;
|
|
7146
|
-
return
|
|
7764
|
+
return sides2 & mask;
|
|
7147
7765
|
}
|
|
7148
7766
|
function ruledBoundaries(tbl) {
|
|
7149
7767
|
const bits = /* @__PURE__ */ new Set();
|
|
@@ -7153,7 +7771,7 @@ function ruledBoundaries(tbl) {
|
|
|
7153
7771
|
return bits;
|
|
7154
7772
|
}
|
|
7155
7773
|
function placeCells(ctx) {
|
|
7156
|
-
const { tbl, entries, colX, rowY, spacing, ncols, nrows, sides, finfo, measurer } = ctx;
|
|
7774
|
+
const { tbl, entries, colX, rowY, spacing, ncols, nrows, sides: sides2, finfo, measurer } = ctx;
|
|
7157
7775
|
const boundaries = ruledBoundaries(tbl);
|
|
7158
7776
|
return entries.map((e) => {
|
|
7159
7777
|
const box = {
|
|
@@ -7170,19 +7788,19 @@ function placeCells(ctx) {
|
|
|
7170
7788
|
row: e.row,
|
|
7171
7789
|
colspan: e.colspan,
|
|
7172
7790
|
rowspan: e.rowspan,
|
|
7173
|
-
sidesMask: cellSidesMask(e, ncols, nrows,
|
|
7791
|
+
sidesMask: cellSidesMask(e, ncols, nrows, sides2)
|
|
7174
7792
|
});
|
|
7175
7793
|
if (boundaries.has(e.row + e.rowspan)) placed.hruled = true;
|
|
7176
7794
|
return placed;
|
|
7177
7795
|
});
|
|
7178
7796
|
}
|
|
7179
|
-
function posHtmlTable(tbl, finfo, measurer, pos,
|
|
7797
|
+
function posHtmlTable(tbl, finfo, measurer, pos, sides2 = HTML_ALL_SIDES) {
|
|
7180
7798
|
const dim = tbl.dimen ?? { w: 0, h: 0 };
|
|
7181
7799
|
const box = pos !== void 0 ? { ll: { ...pos.ll }, ur: { ...pos.ur } } : {
|
|
7182
7800
|
ll: { x: -dim.w / 2, y: -dim.h / 2 },
|
|
7183
7801
|
ur: { x: dim.w / 2, y: dim.h / 2 }
|
|
7184
7802
|
};
|
|
7185
|
-
const { entries, widths, heights, spacing, border } = layoutHtmlTable(tbl, measurer, {
|
|
7803
|
+
const { entries, widths, heights, spacing, border: border2 } = layoutHtmlTable(tbl, measurer, {
|
|
7186
7804
|
fontsize: finfo.fontsize,
|
|
7187
7805
|
fontname: finfo.fontname
|
|
7188
7806
|
});
|
|
@@ -7214,10 +7832,10 @@ function posHtmlTable(tbl, finfo, measurer, pos, sides = HTML_ALL_SIDES) {
|
|
|
7214
7832
|
dely = 0;
|
|
7215
7833
|
}
|
|
7216
7834
|
}
|
|
7217
|
-
const colX = buildColX(box,
|
|
7218
|
-
const rowY = buildRowY(box,
|
|
7219
|
-
const cells = placeCells({ tbl, entries, colX, rowY, spacing, ncols, nrows, sides, finfo, measurer });
|
|
7220
|
-
return { box, border, cells, spacing, columnCount: ncols, rowCount: nrows, port: tbl.port, boundarySides:
|
|
7835
|
+
const colX = buildColX(box, border2, spacing, distributeExtra(widths, delx, ncols));
|
|
7836
|
+
const rowY = buildRowY(box, border2, spacing, distributeExtra(heights, dely, nrows));
|
|
7837
|
+
const cells = placeCells({ tbl, entries, colX, rowY, spacing, ncols, nrows, sides: sides2, finfo, measurer });
|
|
7838
|
+
return { box, border: border2, cells, spacing, columnCount: ncols, rowCount: nrows, port: tbl.port, boundarySides: sides2, ...tblDecoration(tbl) };
|
|
7221
7839
|
}
|
|
7222
7840
|
function posTextLabel(label, finfo, measurer) {
|
|
7223
7841
|
const dim = label.dimen ?? { w: 0, h: 0 };
|
|
@@ -7244,21 +7862,22 @@ function posTextLabel(label, finfo, measurer) {
|
|
|
7244
7862
|
};
|
|
7245
7863
|
}
|
|
7246
7864
|
function posHtmlLabel(label, finfo, measurer) {
|
|
7247
|
-
|
|
7865
|
+
const env = { ...finfo };
|
|
7866
|
+
if (label.kind === "table") return withTableFont(env, label.table.font, "emit", () => posHtmlTable(label.table, env, measurer));
|
|
7248
7867
|
return posTextLabel(label, finfo, measurer);
|
|
7249
7868
|
}
|
|
7250
7869
|
var HTML_PARSE_FATAL = 3;
|
|
7251
7870
|
function makeHtmlLabelRv(content, finfo, measurer) {
|
|
7252
7871
|
const { fontname, fontsize, fontcolor, imageSizer, pencolor } = finfo;
|
|
7253
|
-
let lbl;
|
|
7872
|
+
let lbl, lexWarn;
|
|
7254
7873
|
try {
|
|
7255
|
-
lbl =
|
|
7874
|
+
({ label: lbl, warn: lexWarn } = parseHtmlLabelRv(content));
|
|
7256
7875
|
} catch (e) {
|
|
7257
7876
|
if (e instanceof HtmlLexError) for (const line of e.diagnostics) console.error(line);
|
|
7258
7877
|
return { label: makeLabel("", fontname, fontsize, fontcolor, measurer), rv: HTML_PARSE_FATAL };
|
|
7259
7878
|
}
|
|
7260
7879
|
if (lbl.kind === "table") inheritTablePenColor(lbl.table, pencolor);
|
|
7261
|
-
const rv = sizeHtmlLabel(lbl, measurer, {
|
|
7880
|
+
const rv = Number(lexWarn) | sizeHtmlLabel(lbl, measurer, {
|
|
7262
7881
|
fontsize,
|
|
7263
7882
|
fontname,
|
|
7264
7883
|
imageSizer
|
|
@@ -8100,33 +8719,53 @@ function otherEdge(e) {
|
|
|
8100
8719
|
elistAppend(e.tail.info.other, e);
|
|
8101
8720
|
}
|
|
8102
8721
|
|
|
8722
|
+
// src/common/fma.ts
|
|
8723
|
+
var SPLIT = 134217729;
|
|
8724
|
+
function fma(a, b, c) {
|
|
8725
|
+
const p = a * b;
|
|
8726
|
+
const at = SPLIT * a;
|
|
8727
|
+
const ahi = at - (at - a);
|
|
8728
|
+
const alo = a - ahi;
|
|
8729
|
+
const bt = SPLIT * b;
|
|
8730
|
+
const bhi = bt - (bt - b);
|
|
8731
|
+
const blo = b - bhi;
|
|
8732
|
+
const e = ahi * bhi - p + ahi * blo + alo * bhi + alo * blo;
|
|
8733
|
+
const s = p + c;
|
|
8734
|
+
const bv = s - p;
|
|
8735
|
+
const err = p - (s - bv) + (c - bv);
|
|
8736
|
+
return s + (err + e);
|
|
8737
|
+
}
|
|
8738
|
+
function fms(a, b, c) {
|
|
8739
|
+
return fma(-a, b, c);
|
|
8740
|
+
}
|
|
8741
|
+
|
|
8742
|
+
// src/common/bezier.ts
|
|
8743
|
+
function bezier(v, t, left2, right2) {
|
|
8744
|
+
const degree = 3;
|
|
8745
|
+
const u = 1 - t;
|
|
8746
|
+
const tri = [[v[0], v[1], v[2], v[3]]];
|
|
8747
|
+
for (let i = 1; i <= degree; i++) {
|
|
8748
|
+
const prev = tri[i - 1];
|
|
8749
|
+
const row = [];
|
|
8750
|
+
for (let j = 0; j <= degree - i; j++) {
|
|
8751
|
+
row.push({
|
|
8752
|
+
x: fma(prev[j].x, u, t * prev[j + 1].x),
|
|
8753
|
+
y: fma(prev[j].y, u, t * prev[j + 1].y)
|
|
8754
|
+
});
|
|
8755
|
+
}
|
|
8756
|
+
tri.push(row);
|
|
8757
|
+
}
|
|
8758
|
+
if (left2 !== null) for (let j = 0; j <= degree; j++) left2[j] = tri[j][0];
|
|
8759
|
+
if (right2 !== null) for (let j = 0; j <= degree; j++) right2[j] = tri[degree - j][j];
|
|
8760
|
+
return tri[degree][0];
|
|
8761
|
+
}
|
|
8762
|
+
|
|
8103
8763
|
// src/common/splines-geom.ts
|
|
8104
8764
|
function approxEqPt(p, q, tol) {
|
|
8105
8765
|
const dx = p.x - q.x;
|
|
8106
8766
|
const dy = p.y - q.y;
|
|
8107
8767
|
return dx * dx + dy * dy < tol * tol;
|
|
8108
8768
|
}
|
|
8109
|
-
function evalBezier(sp, t, left2, right2) {
|
|
8110
|
-
const ab = { x: sp[0].x + t * (sp[1].x - sp[0].x), y: sp[0].y + t * (sp[1].y - sp[0].y) };
|
|
8111
|
-
const bc = { x: sp[1].x + t * (sp[2].x - sp[1].x), y: sp[1].y + t * (sp[2].y - sp[1].y) };
|
|
8112
|
-
const cd = { x: sp[2].x + t * (sp[3].x - sp[2].x), y: sp[2].y + t * (sp[3].y - sp[2].y) };
|
|
8113
|
-
const abbc = { x: ab.x + t * (bc.x - ab.x), y: ab.y + t * (bc.y - ab.y) };
|
|
8114
|
-
const bccd = { x: bc.x + t * (cd.x - bc.x), y: bc.y + t * (cd.y - bc.y) };
|
|
8115
|
-
const pt = { x: abbc.x + t * (bccd.x - abbc.x), y: abbc.y + t * (bccd.y - abbc.y) };
|
|
8116
|
-
if (left2 !== null) {
|
|
8117
|
-
left2[0] = sp[0];
|
|
8118
|
-
left2[1] = ab;
|
|
8119
|
-
left2[2] = abbc;
|
|
8120
|
-
left2[3] = pt;
|
|
8121
|
-
}
|
|
8122
|
-
if (right2 !== null) {
|
|
8123
|
-
right2[0] = pt;
|
|
8124
|
-
right2[1] = bccd;
|
|
8125
|
-
right2[2] = cd;
|
|
8126
|
-
right2[3] = sp[3];
|
|
8127
|
-
}
|
|
8128
|
-
return pt;
|
|
8129
|
-
}
|
|
8130
8769
|
var HW = 2;
|
|
8131
8770
|
var SMALL = 1e-10;
|
|
8132
8771
|
function ptToLine2(a, b, p) {
|
|
@@ -8161,7 +8800,7 @@ function updateBbBz(bb, cp) {
|
|
|
8161
8800
|
}
|
|
8162
8801
|
const left2 = [];
|
|
8163
8802
|
const right2 = [];
|
|
8164
|
-
|
|
8803
|
+
bezier(cp, 0.5, left2, right2);
|
|
8165
8804
|
updateBbBz(bb, left2);
|
|
8166
8805
|
updateBbBz(bb, right2);
|
|
8167
8806
|
}
|
|
@@ -8187,7 +8826,7 @@ function bezierClip(insideCtx, insideFn, sp, leftInside) {
|
|
|
8187
8826
|
do {
|
|
8188
8827
|
const opt = pt;
|
|
8189
8828
|
const t = (high + low) / 2;
|
|
8190
|
-
pt =
|
|
8829
|
+
pt = bezier(sp, t, left2, right2);
|
|
8191
8830
|
if (insideFn(insideCtx, pt)) {
|
|
8192
8831
|
if (leftInside) {
|
|
8193
8832
|
low = t;
|
|
@@ -8618,15 +9257,10 @@ function arrowLengthTee(lenfact, arrowsize, penwidth) {
|
|
|
8618
9257
|
if (extendStart > 0) length += extendEnd;
|
|
8619
9258
|
return length;
|
|
8620
9259
|
}
|
|
8621
|
-
var lerp = (a, b) => ({ x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 });
|
|
8622
9260
|
function cubicHalf(c, rightHalf) {
|
|
8623
|
-
const
|
|
8624
|
-
|
|
8625
|
-
|
|
8626
|
-
const D = lerp(A3, B2);
|
|
8627
|
-
const E = lerp(B2, C6);
|
|
8628
|
-
const M2 = lerp(D, E);
|
|
8629
|
-
return rightHalf ? [M2, E, C6, c[3]] : [c[0], A3, D, M2];
|
|
9261
|
+
const half = [];
|
|
9262
|
+
bezier(c, 0.5, rightHalf ? null : half, rightHalf ? half : null);
|
|
9263
|
+
return half;
|
|
8630
9264
|
}
|
|
8631
9265
|
function curveControlPoints(p, v, w, flag) {
|
|
8632
9266
|
const AF0 = { x: p.x + v.x + w.x, y: p.y + v.y + w.y };
|
|
@@ -8899,29 +9533,11 @@ function arrowDrawOps(comps, tip2, dir, arrowsize, penwidth, rankdir = 0) {
|
|
|
8899
9533
|
}
|
|
8900
9534
|
|
|
8901
9535
|
// src/layout/dot/edge-route-clip.ts
|
|
8902
|
-
function deCasteljauTriangle(sp, t) {
|
|
8903
|
-
const u = 1 - t;
|
|
8904
|
-
const v = [
|
|
8905
|
-
[sp[0], sp[1], sp[2], sp[3]],
|
|
8906
|
-
[{ x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }],
|
|
8907
|
-
[{ x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }],
|
|
8908
|
-
[{ x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }]
|
|
8909
|
-
];
|
|
8910
|
-
for (let i = 1; i <= 3; i++) {
|
|
8911
|
-
for (let j = 0; j <= 3 - i; j++) {
|
|
8912
|
-
v[i][j] = {
|
|
8913
|
-
x: u * v[i - 1][j].x + t * v[i - 1][j + 1].x,
|
|
8914
|
-
y: u * v[i - 1][j].y + t * v[i - 1][j + 1].y
|
|
8915
|
-
};
|
|
8916
|
-
}
|
|
8917
|
-
}
|
|
8918
|
-
return v;
|
|
8919
|
-
}
|
|
8920
9536
|
function bezierSubdivide(sp, t) {
|
|
8921
|
-
const
|
|
8922
|
-
const
|
|
8923
|
-
const
|
|
8924
|
-
return [left2, right2,
|
|
9537
|
+
const left2 = [];
|
|
9538
|
+
const right2 = [];
|
|
9539
|
+
const mid = bezier(sp, t, left2, right2);
|
|
9540
|
+
return [left2, right2, mid];
|
|
8925
9541
|
}
|
|
8926
9542
|
function bisectStep(c, insideFn, leftInside, s) {
|
|
8927
9543
|
const t = (s.high + s.low) / 2;
|
|
@@ -10039,20 +10655,20 @@ function rect(x, y, w, h) {
|
|
|
10039
10655
|
function dnaY(af) {
|
|
10040
10656
|
return af[2].y + (af[0].y - af[3].y) / 2;
|
|
10041
10657
|
}
|
|
10042
|
-
function nextV(af, seg2,
|
|
10043
|
-
return seg2 + 1 <
|
|
10658
|
+
function nextV(af, seg2, sides2) {
|
|
10659
|
+
return seg2 + 1 < sides2 ? af[seg2 + 1] : af[0];
|
|
10044
10660
|
}
|
|
10045
|
-
function interpolationPoints(af,
|
|
10661
|
+
function interpolationPoints(af, sides2, shape, rounded = false) {
|
|
10046
10662
|
let rbconst = RBCONST;
|
|
10047
|
-
for (let seg2 = 0; seg2 <
|
|
10663
|
+
for (let seg2 = 0; seg2 < sides2; seg2++) {
|
|
10048
10664
|
const p0 = af[seg2];
|
|
10049
|
-
const p1 = nextV(af, seg2,
|
|
10665
|
+
const p1 = nextV(af, seg2, sides2);
|
|
10050
10666
|
rbconst = Math.min(rbconst, Math.hypot(p1.x - p0.x, p1.y - p0.y) / 3);
|
|
10051
10667
|
}
|
|
10052
10668
|
const b = [];
|
|
10053
|
-
for (let seg2 = 0; seg2 <
|
|
10669
|
+
for (let seg2 = 0; seg2 < sides2; seg2++) {
|
|
10054
10670
|
const p0 = af[seg2];
|
|
10055
|
-
const p1 = nextV(af, seg2,
|
|
10671
|
+
const p1 = nextV(af, seg2, sides2);
|
|
10056
10672
|
let t = rbconst / Math.hypot(p1.x - p0.x, p1.y - p0.y);
|
|
10057
10673
|
if (shape === BOX3D || shape === COMPONENT) t /= 3;
|
|
10058
10674
|
else if (shape === DOGEAR) t /= 2;
|
|
@@ -10089,28 +10705,28 @@ function drawCds(af, b, coord, filled, ctx) {
|
|
|
10089
10705
|
renderShapePolygon(D, coord, ctx, filled);
|
|
10090
10706
|
}
|
|
10091
10707
|
function drawDogear(af, b, coord, filled, ctx) {
|
|
10092
|
-
const
|
|
10093
|
-
const D = new Array(
|
|
10094
|
-
for (let seg2 = 1; seg2 <
|
|
10095
|
-
D[0] = b[3 * (
|
|
10096
|
-
D[
|
|
10708
|
+
const sides2 = af.length;
|
|
10709
|
+
const D = new Array(sides2 + 1);
|
|
10710
|
+
for (let seg2 = 1; seg2 < sides2; seg2++) D[seg2] = af[seg2];
|
|
10711
|
+
D[0] = b[3 * (sides2 - 1) + 4];
|
|
10712
|
+
D[sides2] = b[3 * (sides2 - 1) + 2];
|
|
10097
10713
|
renderShapePolygon(D, coord, ctx, filled);
|
|
10098
|
-
const s =
|
|
10714
|
+
const s = sides2 - 1;
|
|
10099
10715
|
const c0 = b[3 * s + 2];
|
|
10100
10716
|
const c2 = vadd2(b[3 * s + 4], vsub2(c0, b[3 * s + 3]));
|
|
10101
10717
|
renderShapePolyline([b[3 * s + 4], c2], coord, ctx);
|
|
10102
10718
|
renderShapePolyline([c0, c2], coord, ctx);
|
|
10103
10719
|
}
|
|
10104
10720
|
function drawTab(af, b, coord, filled, ctx) {
|
|
10105
|
-
const
|
|
10721
|
+
const sides2 = af.length;
|
|
10106
10722
|
const w = { x: (b[3].x - b[4].x) / 3, y: (b[3].y - b[4].y) / 3 };
|
|
10107
10723
|
const D = [af[0], b[2], vadd2(b[2], w), vadd2(b[3], w)];
|
|
10108
|
-
for (let seg2 = 4; seg2 <
|
|
10724
|
+
for (let seg2 = 4; seg2 < sides2 + 2; seg2++) D.push(af[seg2 - 2]);
|
|
10109
10725
|
renderShapePolygon(D, coord, ctx, filled);
|
|
10110
10726
|
renderShapePolyline([b[3], b[2]], coord, ctx);
|
|
10111
10727
|
}
|
|
10112
10728
|
function drawFolder(af, b, coord, filled, ctx) {
|
|
10113
|
-
const
|
|
10729
|
+
const sides2 = af.length;
|
|
10114
10730
|
const dx = af[0].x - b[1].x;
|
|
10115
10731
|
const wy = (b[3].y - b[4].y) / 3;
|
|
10116
10732
|
const D = [
|
|
@@ -10119,7 +10735,7 @@ function drawFolder(af, b, coord, filled, ctx) {
|
|
|
10119
10735
|
{ x: af[0].x - 2 * dx, y: af[0].y + wy },
|
|
10120
10736
|
{ x: af[0].x - 2.25 * dx, y: b[3].y }
|
|
10121
10737
|
];
|
|
10122
|
-
for (let seg2 = 4; seg2 <
|
|
10738
|
+
for (let seg2 = 4; seg2 < sides2 + 3; seg2++) D.push(af[seg2 - 3]);
|
|
10123
10739
|
renderShapePolygon(D, coord, ctx, filled);
|
|
10124
10740
|
}
|
|
10125
10741
|
function drawBox3d(af, b, coord, filled, ctx) {
|
|
@@ -10469,10 +11085,10 @@ function drawRoundCorners(ring, coord, filled, ctx) {
|
|
|
10469
11085
|
else if (ctx.rounded) roundedDraw(ring, coord, filled, ctx);
|
|
10470
11086
|
}
|
|
10471
11087
|
function diagonalsDraw(ring, coord, filled, ctx) {
|
|
10472
|
-
const
|
|
10473
|
-
const b = interpolationPoints(ring,
|
|
11088
|
+
const sides2 = ring.length;
|
|
11089
|
+
const b = interpolationPoints(ring, sides2, 0);
|
|
10474
11090
|
renderShapePolygon(ring, coord, ctx, filled);
|
|
10475
|
-
for (let seg2 = 0; seg2 <
|
|
11091
|
+
for (let seg2 = 0; seg2 < sides2; seg2++) {
|
|
10476
11092
|
renderShapePolyline([b[3 * seg2 + 2], b[3 * seg2 + 4]], coord, ctx);
|
|
10477
11093
|
}
|
|
10478
11094
|
}
|
|
@@ -10480,10 +11096,10 @@ function roundedDraw(ring, coord, filled, ctx) {
|
|
|
10480
11096
|
emitRoundedBezier(ring, coord, filled, ctx);
|
|
10481
11097
|
}
|
|
10482
11098
|
function emitRoundedBezier(ring, coord, filled, ctx) {
|
|
10483
|
-
const
|
|
10484
|
-
const b = interpolationPoints(ring,
|
|
11099
|
+
const sides2 = ring.length;
|
|
11100
|
+
const b = interpolationPoints(ring, sides2, 0, true);
|
|
10485
11101
|
const pts = [];
|
|
10486
|
-
for (let seg2 = 0; seg2 <
|
|
11102
|
+
for (let seg2 = 0; seg2 < sides2; seg2++) {
|
|
10487
11103
|
pts.push(b[4 * seg2], b[4 * seg2 + 1], b[4 * seg2 + 1], b[4 * seg2 + 2], b[4 * seg2 + 2], b[4 * seg2 + 3]);
|
|
10488
11104
|
}
|
|
10489
11105
|
pts.push(pts[0], pts[1]);
|
|
@@ -10658,10 +11274,10 @@ function bgFillPaint(ctx) {
|
|
|
10658
11274
|
};
|
|
10659
11275
|
}
|
|
10660
11276
|
function emitBgFill(ctx) {
|
|
10661
|
-
const { box, pos, border, renderer, job } = ctx;
|
|
11277
|
+
const { box, pos, border: border2, renderer, job } = ctx;
|
|
10662
11278
|
withHtmlPaint(bgFillPaint(ctx), job, () => {
|
|
10663
11279
|
if (parseStyleFlags(ctx.style).rounded) {
|
|
10664
|
-
emitRoundedBezier(mkPts(box,
|
|
11280
|
+
emitRoundedBezier(mkPts(box, border2, pos), { x: 0, y: 0 }, true, { renderer, job });
|
|
10665
11281
|
return;
|
|
10666
11282
|
}
|
|
10667
11283
|
const pts = [
|
|
@@ -10726,9 +11342,9 @@ function emitHtmlImg(img, pos, renderer, job) {
|
|
|
10726
11342
|
}
|
|
10727
11343
|
renderer.usershape?.(img.src, b, job);
|
|
10728
11344
|
}
|
|
10729
|
-
function htmlStyleInvisible(
|
|
10730
|
-
if (
|
|
10731
|
-
return
|
|
11345
|
+
function htmlStyleInvisible(style2) {
|
|
11346
|
+
if (style2 === void 0) return false;
|
|
11347
|
+
return style2.split(/[ ,]+/).some((tok) => {
|
|
10732
11348
|
const t = tok.toUpperCase();
|
|
10733
11349
|
return t === "INVIS" || t === "INVISIBLE";
|
|
10734
11350
|
});
|
|
@@ -10941,7 +11557,7 @@ function starRings(box, peripheries) {
|
|
|
10941
11557
|
return rings.flat();
|
|
10942
11558
|
}
|
|
10943
11559
|
function computeVertices(poly, w, h, base) {
|
|
10944
|
-
const
|
|
11560
|
+
const sides2 = poly.sides;
|
|
10945
11561
|
if (poly.option.fixedshape && base !== void 0) {
|
|
10946
11562
|
w = base.w;
|
|
10947
11563
|
h = base.h;
|
|
@@ -10949,35 +11565,15 @@ function computeVertices(poly, w, h, base) {
|
|
|
10949
11565
|
if (poly.option.shape === CYLINDER) return cylinderVertices(w, h);
|
|
10950
11566
|
const peripheries = Math.max(poly.peripheries, 1);
|
|
10951
11567
|
if (poly.option.shape === STAR) return starRings({ w, h, base }, peripheries);
|
|
10952
|
-
if (
|
|
11568
|
+
if (sides2 <= 2) {
|
|
10953
11569
|
return ellipseRings(w, h, peripheries, poly.option.fixedshape ? base : void 0);
|
|
10954
11570
|
}
|
|
10955
|
-
if (
|
|
11571
|
+
if (sides2 === 4 && Math.abs(poly.orientation % 90) < 0.5 && poly.distortion === 0 && poly.skew === 0) {
|
|
10956
11572
|
return boxRings(w, h, peripheries, poly.orientation, base);
|
|
10957
11573
|
}
|
|
10958
11574
|
return generalPolyRings(poly, { w, h, base }, peripheries);
|
|
10959
11575
|
}
|
|
10960
11576
|
|
|
10961
|
-
// src/common/fma.ts
|
|
10962
|
-
var SPLIT = 134217729;
|
|
10963
|
-
function fma(a, b, c) {
|
|
10964
|
-
const p = a * b;
|
|
10965
|
-
const at = SPLIT * a;
|
|
10966
|
-
const ahi = at - (at - a);
|
|
10967
|
-
const alo = a - ahi;
|
|
10968
|
-
const bt = SPLIT * b;
|
|
10969
|
-
const bhi = bt - (bt - b);
|
|
10970
|
-
const blo = b - bhi;
|
|
10971
|
-
const e = ahi * bhi - p + ahi * blo + alo * bhi + alo * blo;
|
|
10972
|
-
const s = p + c;
|
|
10973
|
-
const bv = s - p;
|
|
10974
|
-
const err = p - (s - bv) + (c - bv);
|
|
10975
|
-
return s + (err + e);
|
|
10976
|
-
}
|
|
10977
|
-
function fms(a, b, c) {
|
|
10978
|
-
return fma(-a, b, c);
|
|
10979
|
-
}
|
|
10980
|
-
|
|
10981
11577
|
// src/common/arith.ts
|
|
10982
11578
|
function cround(v) {
|
|
10983
11579
|
return v >= 0 ? Math.floor(v + 0.5) : Math.ceil(v - 0.5);
|
|
@@ -11077,17 +11673,17 @@ function starSize(bb) {
|
|
|
11077
11673
|
function cylinderSize(bb) {
|
|
11078
11674
|
return { x: bb.x, y: bb.y * 1.375 };
|
|
11079
11675
|
}
|
|
11080
|
-
function expandForShape(bb,
|
|
11676
|
+
function expandForShape(bb, sides2, heightPts, valign2) {
|
|
11081
11677
|
const b = { x: bb.x, y: bb.y };
|
|
11082
11678
|
const temp = b.y * SQRT2;
|
|
11083
|
-
if (heightPts > temp &&
|
|
11679
|
+
if (heightPts > temp && valign2 === "c") {
|
|
11084
11680
|
b.x *= Math.sqrt(1 / (1 - (b.y / heightPts) ** 2));
|
|
11085
11681
|
} else {
|
|
11086
11682
|
b.x *= SQRT2;
|
|
11087
11683
|
b.y = temp;
|
|
11088
11684
|
}
|
|
11089
|
-
if (
|
|
11090
|
-
const c = Math.cos(Math.PI /
|
|
11685
|
+
if (sides2 > 2) {
|
|
11686
|
+
const c = Math.cos(Math.PI / sides2);
|
|
11091
11687
|
b.x /= c;
|
|
11092
11688
|
b.y /= c;
|
|
11093
11689
|
}
|
|
@@ -11142,21 +11738,21 @@ function vertexExtents(verts) {
|
|
|
11142
11738
|
}
|
|
11143
11739
|
return { xmax, ymax };
|
|
11144
11740
|
}
|
|
11145
|
-
function initBisector(verts,
|
|
11741
|
+
function initBisector(verts, sides2) {
|
|
11146
11742
|
const R2 = verts[0];
|
|
11147
11743
|
let Q = R2;
|
|
11148
|
-
for (let j = 1; j <
|
|
11149
|
-
Q = verts[(
|
|
11744
|
+
for (let j = 1; j < sides2; j++) {
|
|
11745
|
+
Q = verts[(sides2 - j) % sides2];
|
|
11150
11746
|
if (Q.x !== R2.x || Q.y !== R2.y) break;
|
|
11151
11747
|
}
|
|
11152
11748
|
return { beta: Math.atan2(R2.y - Q.y, R2.x - Q.x), Qprev: Q, sinx: 0, cosx: 0 };
|
|
11153
11749
|
}
|
|
11154
|
-
function bisectorOffset(verts,
|
|
11750
|
+
function bisectorOffset(verts, sides2, i, st) {
|
|
11155
11751
|
const V = verts[i];
|
|
11156
11752
|
if (V.x !== st.Qprev.x || V.y !== st.Qprev.y) {
|
|
11157
11753
|
let R2 = V;
|
|
11158
|
-
for (let j = 1; j <
|
|
11159
|
-
R2 = verts[(i + j) %
|
|
11754
|
+
for (let j = 1; j < sides2; j++) {
|
|
11755
|
+
R2 = verts[(i + j) % sides2];
|
|
11160
11756
|
if (R2.x !== V.x || R2.y !== V.y) break;
|
|
11161
11757
|
}
|
|
11162
11758
|
const alpha = st.beta;
|
|
@@ -11168,32 +11764,32 @@ function bisectorOffset(verts, sides, i, st) {
|
|
|
11168
11764
|
}
|
|
11169
11765
|
st.Qprev = V;
|
|
11170
11766
|
}
|
|
11171
|
-
function polygonRingOffsets(verts,
|
|
11172
|
-
const st = initBisector(verts,
|
|
11767
|
+
function polygonRingOffsets(verts, sides2) {
|
|
11768
|
+
const st = initBisector(verts, sides2);
|
|
11173
11769
|
const out = [];
|
|
11174
|
-
for (let i = 0; i <
|
|
11175
|
-
bisectorOffset(verts,
|
|
11770
|
+
for (let i = 0; i < sides2; i++) {
|
|
11771
|
+
bisectorOffset(verts, sides2, i, st);
|
|
11176
11772
|
out.push({ x: st.cosx, y: st.sinx });
|
|
11177
11773
|
}
|
|
11178
11774
|
return out;
|
|
11179
11775
|
}
|
|
11180
|
-
function polygonOutlineRing(verts,
|
|
11181
|
-
const st = initBisector(verts,
|
|
11776
|
+
function polygonOutlineRing(verts, sides2, penwidth) {
|
|
11777
|
+
const st = initBisector(verts, sides2);
|
|
11182
11778
|
const out = [];
|
|
11183
11779
|
const k = penwidth / 2 / GAP;
|
|
11184
|
-
for (let i = 0; i <
|
|
11185
|
-
bisectorOffset(verts,
|
|
11780
|
+
for (let i = 0; i < sides2; i++) {
|
|
11781
|
+
bisectorOffset(verts, sides2, i, st);
|
|
11186
11782
|
const V = verts[i];
|
|
11187
11783
|
out.push({ x: V.x + k * st.cosx, y: V.y + k * st.sinx });
|
|
11188
11784
|
}
|
|
11189
11785
|
return out;
|
|
11190
11786
|
}
|
|
11191
|
-
function polygonPeripheryBB(verts,
|
|
11192
|
-
const st = initBisector(verts,
|
|
11787
|
+
function polygonPeripheryBB(verts, sides2, p, bb) {
|
|
11788
|
+
const st = initBisector(verts, sides2);
|
|
11193
11789
|
const out = { x: bb.x, y: bb.y };
|
|
11194
11790
|
const outl = { x: bb.x, y: bb.y };
|
|
11195
|
-
for (let i = 0; i <
|
|
11196
|
-
bisectorOffset(verts,
|
|
11791
|
+
for (let i = 0; i < sides2; i++) {
|
|
11792
|
+
bisectorOffset(verts, sides2, i, st);
|
|
11197
11793
|
const off = p.peripheries - 1;
|
|
11198
11794
|
const V = verts[i];
|
|
11199
11795
|
const P = { x: V.x + off * st.cosx, y: V.y + off * st.sinx };
|
|
@@ -11217,9 +11813,9 @@ function starVertexGen(bb) {
|
|
|
11217
11813
|
}
|
|
11218
11814
|
return { verts: starVertices(bb.x, bb.y), xmax: sz.x / 2, ymax: sz.y / 2 };
|
|
11219
11815
|
}
|
|
11220
|
-
function polygonBB(bb, minSize, p,
|
|
11816
|
+
function polygonBB(bb, minSize, p, sides2, isBox3) {
|
|
11221
11817
|
const geom = {
|
|
11222
|
-
sides,
|
|
11818
|
+
sides: sides2,
|
|
11223
11819
|
orientation: p.orientation,
|
|
11224
11820
|
distortion: p.distortion,
|
|
11225
11821
|
skew: p.skew
|
|
@@ -11236,7 +11832,7 @@ function polygonBB(bb, minSize, p, sides, isBox3) {
|
|
|
11236
11832
|
v.x *= scalex;
|
|
11237
11833
|
v.y *= scaley;
|
|
11238
11834
|
}
|
|
11239
|
-
return { ...polygonPeripheryBB(verts, isBox3 ? 4 :
|
|
11835
|
+
return { ...polygonPeripheryBB(verts, isBox3 ? 4 : sides2, p, nbb), base: nbb };
|
|
11240
11836
|
}
|
|
11241
11837
|
function gvNodesize(widthPts, heightPts, flip) {
|
|
11242
11838
|
if (flip) return { lw: heightPts / 2, rw: heightPts / 2, ht: widthPts };
|
|
@@ -11261,7 +11857,7 @@ function applySizeConstraints(p, bb0, width0, height0) {
|
|
|
11261
11857
|
function polySize(p) {
|
|
11262
11858
|
const init = initialSizePts(p);
|
|
11263
11859
|
const dimen = quantize(padLabelDimen(p.labelDimen, p.margin, p.isPlain), p.quantumIn);
|
|
11264
|
-
const { sides, isBox: isBox3 } = effectiveShape(p);
|
|
11860
|
+
const { sides: sides2, isBox: isBox3 } = effectiveShape(p);
|
|
11265
11861
|
let bb = { x: dimen.x, y: dimen.y };
|
|
11266
11862
|
if (isBox3) {
|
|
11267
11863
|
} else if (p.optionShape === STAR) {
|
|
@@ -11269,13 +11865,13 @@ function polySize(p) {
|
|
|
11269
11865
|
} else if (p.optionShape === CYLINDER) {
|
|
11270
11866
|
bb = cylinderSize(bb);
|
|
11271
11867
|
} else {
|
|
11272
|
-
bb = expandForShape(bb,
|
|
11868
|
+
bb = expandForShape(bb, sides2, init.height, labelValign(p));
|
|
11273
11869
|
}
|
|
11274
11870
|
const minBb = bb;
|
|
11275
11871
|
const c = applySizeConstraints(p, bb, init.width, init.height);
|
|
11276
11872
|
const penwidth = p.penwidth ?? 1;
|
|
11277
11873
|
const hasOutline = penwidth > 0 || p.peripheries < 1;
|
|
11278
|
-
const grown =
|
|
11874
|
+
const grown = sides2 < 3 ? { ...ellipsePeripheryBB(c.bb, p.peripheries, penwidth, hasOutline), base: c.bb } : polygonBB(c.bb, { x: c.width, y: c.height }, { ...p, penwidth, hasOutline }, sides2, isBox3);
|
|
11279
11875
|
const result = assembleResult(p, dimen, grown, c.fixedshape);
|
|
11280
11876
|
return { ...result, ...labelSpace(p, dimen, c.bb, minBb, isBox3, c.fixedshape) };
|
|
11281
11877
|
}
|
|
@@ -11295,10 +11891,10 @@ function labelSpace(p, dimen, bb, minBb, isBox3, fixedshape) {
|
|
|
11295
11891
|
return { space: { x: spaceX, y: spaceY }, valign: labelValign(p) };
|
|
11296
11892
|
}
|
|
11297
11893
|
function effectiveShape(p) {
|
|
11298
|
-
let
|
|
11299
|
-
if (
|
|
11300
|
-
const isBox3 =
|
|
11301
|
-
return { sides, isBox: isBox3 };
|
|
11894
|
+
let sides2 = p.sides;
|
|
11895
|
+
if (sides2 <= 2 && (p.distortion !== 0 || p.skew !== 0)) sides2 = 120;
|
|
11896
|
+
const isBox3 = sides2 === 4 && Math.abs(p.orientation % 90) < 0.5 && p.distortion === 0 && p.skew === 0;
|
|
11897
|
+
return { sides: sides2, isBox: isBox3 };
|
|
11302
11898
|
}
|
|
11303
11899
|
function labelValign(p) {
|
|
11304
11900
|
const ll = p.labelloc?.[0];
|
|
@@ -11584,8 +12180,8 @@ function recSideMask(f, i, last) {
|
|
|
11584
12180
|
if (i === 0) return i === last ? TOP2 | BOTTOM2 | RIGHT2 | LEFT2 : TOP2 | RIGHT2 | LEFT2;
|
|
11585
12181
|
return i === last ? LEFT2 | BOTTOM2 | RIGHT2 : LEFT2 | RIGHT2;
|
|
11586
12182
|
}
|
|
11587
|
-
function posReclbl(f, ul,
|
|
11588
|
-
f.sides =
|
|
12183
|
+
function posReclbl(f, ul, sides2) {
|
|
12184
|
+
f.sides = sides2;
|
|
11589
12185
|
f.b = {
|
|
11590
12186
|
ll: { x: ul.x, y: ul.y - f.size.y },
|
|
11591
12187
|
ur: { x: ul.x + f.size.x, y: ul.y }
|
|
@@ -11593,8 +12189,8 @@ function posReclbl(f, ul, sides) {
|
|
|
11593
12189
|
const last = f.n_flds - 1;
|
|
11594
12190
|
const pos = { x: ul.x, y: ul.y };
|
|
11595
12191
|
for (let i = 0; i <= last; i++) {
|
|
11596
|
-
const mask =
|
|
11597
|
-
posReclbl(f.fld[i], { x: pos.x, y: pos.y },
|
|
12192
|
+
const mask = sides2 ? recSideMask(f, i, last) : 0;
|
|
12193
|
+
posReclbl(f.fld[i], { x: pos.x, y: pos.y }, sides2 & mask);
|
|
11598
12194
|
if (f.LR) pos.x += f.fld[i].size.x;
|
|
11599
12195
|
else pos.y -= f.fld[i].size.y;
|
|
11600
12196
|
}
|
|
@@ -15097,11 +15693,11 @@ function renderPolyRing(ring, coord, filled, j, ctx) {
|
|
|
15097
15693
|
} else renderPolygon(ring, coord, ctx.renderer, ctx.job, filled);
|
|
15098
15694
|
}
|
|
15099
15695
|
function renderPeripheries(poly, coord, filled, ctx) {
|
|
15100
|
-
const
|
|
15696
|
+
const sides2 = poly.sides <= 2 ? 2 : poly.sides;
|
|
15101
15697
|
const verts = poly.vertices;
|
|
15102
15698
|
for (let j = 0; j < poly.peripheries; j++) {
|
|
15103
|
-
const ring = verts.slice(j *
|
|
15104
|
-
if (ring.length <
|
|
15699
|
+
const ring = verts.slice(j * sides2, (j + 1) * sides2);
|
|
15700
|
+
if (ring.length < sides2) break;
|
|
15105
15701
|
const ringFilled = j === 0 ? filled : false;
|
|
15106
15702
|
if (poly.sides <= 2) {
|
|
15107
15703
|
renderEllipseRing(ring, coord, ringFilled, j, ctx);
|
|
@@ -15205,7 +15801,7 @@ function applyPenState(obj, styleAttr, colorAttr, penwidthAttr) {
|
|
|
15205
15801
|
obj.penColor = resolveRenderColor(resolvePenColor(colorAttr));
|
|
15206
15802
|
obj.pen = resolvePenType(flags);
|
|
15207
15803
|
obj.penWidth = resolvePenWidth(flags, penwidthAttr);
|
|
15208
|
-
obj.rawStyle =
|
|
15804
|
+
obj.rawStyle = styleTokens2(styleAttr);
|
|
15209
15805
|
}
|
|
15210
15806
|
function applyNodeStyle(obj, n, job) {
|
|
15211
15807
|
const styleAttr = nodeAttr(n, n.root, "style");
|
|
@@ -15250,12 +15846,12 @@ function resolveNodeDrawCtx(job, n) {
|
|
|
15250
15846
|
};
|
|
15251
15847
|
return { poly: drawPoly, coord, filled, ringCtx };
|
|
15252
15848
|
}
|
|
15253
|
-
function specialCornerFlags(opt,
|
|
15849
|
+
function specialCornerFlags(opt, style2) {
|
|
15254
15850
|
return {
|
|
15255
15851
|
shape: opt.shape,
|
|
15256
|
-
diagonals: opt.diagonals ||
|
|
15257
|
-
rounded: opt.rounded ||
|
|
15258
|
-
underline: opt.underline ||
|
|
15852
|
+
diagonals: opt.diagonals || style2.diagonals,
|
|
15853
|
+
rounded: opt.rounded || style2.rounded,
|
|
15854
|
+
underline: opt.underline || style2.underline
|
|
15259
15855
|
};
|
|
15260
15856
|
}
|
|
15261
15857
|
function polyGencode(rawJob, rawNode) {
|
|
@@ -15328,22 +15924,22 @@ function insideScale(n, poly) {
|
|
|
15328
15924
|
boxURy: oh / 2
|
|
15329
15925
|
};
|
|
15330
15926
|
}
|
|
15331
|
-
function polygonWalk(P, vertex,
|
|
15927
|
+
function polygonWalk(P, vertex, sides2) {
|
|
15332
15928
|
const O = { x: 0, y: 0 };
|
|
15333
15929
|
let i = 0;
|
|
15334
|
-
let i1 = 1 %
|
|
15930
|
+
let i1 = 1 % sides2;
|
|
15335
15931
|
const Q = vertex[i];
|
|
15336
15932
|
const R2 = vertex[i1];
|
|
15337
15933
|
if (!sameSide(P, O, Q, R2)) return false;
|
|
15338
15934
|
const s = sameSide(P, Q, R2, O);
|
|
15339
15935
|
if (s && sameSide(P, R2, O, Q)) return true;
|
|
15340
|
-
for (let j = 1; j <
|
|
15936
|
+
for (let j = 1; j < sides2; j++) {
|
|
15341
15937
|
if (s) {
|
|
15342
15938
|
i = i1;
|
|
15343
|
-
i1 = (i + 1) %
|
|
15939
|
+
i1 = (i + 1) % sides2;
|
|
15344
15940
|
} else {
|
|
15345
15941
|
i1 = i;
|
|
15346
|
-
i = (i +
|
|
15942
|
+
i = (i + sides2 - 1) % sides2;
|
|
15347
15943
|
}
|
|
15348
15944
|
if (!sameSide(P, O, vertex[i], vertex[i1])) return false;
|
|
15349
15945
|
}
|
|
@@ -15385,15 +15981,15 @@ function starInside(ctx, p) {
|
|
|
15385
15981
|
}
|
|
15386
15982
|
const poly = n.info.shape_info;
|
|
15387
15983
|
if (poly === void 0 || poly.vertices === null) return false;
|
|
15388
|
-
const
|
|
15389
|
-
const outerStart = (Math.max(poly.peripheries, 1) - 1) *
|
|
15390
|
-
const outer = poly.vertices.slice(outerStart, outerStart +
|
|
15391
|
-
const ring = polygonOutlineRing(outer,
|
|
15984
|
+
const sides2 = poly.sides;
|
|
15985
|
+
const outerStart = (Math.max(poly.peripheries, 1) - 1) * sides2;
|
|
15986
|
+
const outer = poly.vertices.slice(outerStart, outerStart + sides2);
|
|
15987
|
+
const ring = polygonOutlineRing(outer, sides2, poly.penwidth ?? 1);
|
|
15392
15988
|
const O = { x: 0, y: 0 };
|
|
15393
15989
|
let outcnt = 0;
|
|
15394
|
-
for (let i = 0; i <
|
|
15990
|
+
for (let i = 0; i < sides2; i += 2) {
|
|
15395
15991
|
const Q = ring[i];
|
|
15396
|
-
const R2 = ring[(i + 4) %
|
|
15992
|
+
const R2 = ring[(i + 4) % sides2];
|
|
15397
15993
|
if (!sameSide(P, O, Q, R2)) outcnt++;
|
|
15398
15994
|
if (outcnt === 2) return false;
|
|
15399
15995
|
}
|
|
@@ -16814,9 +17410,9 @@ function labelVnode(g, orig) {
|
|
|
16814
17410
|
return v;
|
|
16815
17411
|
}
|
|
16816
17412
|
function incrWidth(g, v) {
|
|
16817
|
-
const
|
|
16818
|
-
v.info.lw = (v.info.lw ?? 0) +
|
|
16819
|
-
v.info.rw = (v.info.rw ?? 0) +
|
|
17413
|
+
const width2 = Math.floor((g.info.nodesep ?? 0) / 2);
|
|
17414
|
+
v.info.lw = (v.info.lw ?? 0) + width2;
|
|
17415
|
+
v.info.rw = (v.info.rw ?? 0) + width2;
|
|
16820
17416
|
}
|
|
16821
17417
|
function plainVnode(g) {
|
|
16822
17418
|
const v = virtualNode(g);
|
|
@@ -17160,7 +17756,7 @@ var DEFAULT_NODESEP = 0.25;
|
|
|
17160
17756
|
var MIN_NODESEP = 0.02;
|
|
17161
17757
|
var DEFAULT_RANKSEP = 0.5;
|
|
17162
17758
|
var MIN_RANKSEP = 0.02;
|
|
17163
|
-
var
|
|
17759
|
+
var UCHAR_MAX2 = 255;
|
|
17164
17760
|
var CHAR_UTF8 = 0;
|
|
17165
17761
|
var CHAR_LATIN1 = 1;
|
|
17166
17762
|
var CHAR_BIG5 = 2;
|
|
@@ -17257,7 +17853,7 @@ function graphInit(g, useRankdir) {
|
|
|
17257
17853
|
g.info.flip = false;
|
|
17258
17854
|
}
|
|
17259
17855
|
parseSepAttrs(g);
|
|
17260
|
-
g.info.showboxes = Math.min(lateInt(g.attrs.get("showboxes"), 0, 0),
|
|
17856
|
+
g.info.showboxes = Math.min(lateInt(g.attrs.get("showboxes"), 0, 0), UCHAR_MAX2);
|
|
17261
17857
|
const fn = maptoken(g.attrs.get("fontnames"), FONTNAME_NAMES, fontnameCodes());
|
|
17262
17858
|
if (fn !== -1) g.info.fontnames = fn;
|
|
17263
17859
|
parseRatioDrawing(g);
|
|
@@ -17485,54 +18081,54 @@ function dirDefault(p) {
|
|
|
17485
18081
|
function dirUnrecognized(p) {
|
|
17486
18082
|
return { p, theta: 0, side: 0, constrain: false, clip: true, dyna: false, defined: false, rv: 1 };
|
|
17487
18083
|
}
|
|
17488
|
-
function dirN(rest, b, ctr,
|
|
18084
|
+
function dirN(rest, b, ctr, sides2) {
|
|
17489
18085
|
const base = { constrain: true, clip: false, dyna: false };
|
|
17490
18086
|
switch (rest) {
|
|
17491
18087
|
case "":
|
|
17492
|
-
return { ...base, p: { x: ctr.x, y: b.ur.y }, theta: Math.PI * 0.5, side:
|
|
18088
|
+
return { ...base, p: { x: ctr.x, y: b.ur.y }, theta: Math.PI * 0.5, side: sides2 & TOP, defined: true, rv: 0 };
|
|
17493
18089
|
case "e":
|
|
17494
|
-
return { ...base, p: { x: b.ur.x, y: b.ur.y }, theta: Math.PI * 0.25, side:
|
|
18090
|
+
return { ...base, p: { x: b.ur.x, y: b.ur.y }, theta: Math.PI * 0.25, side: sides2 & (TOP | RIGHT), defined: true, rv: 0 };
|
|
17495
18091
|
case "w":
|
|
17496
|
-
return { ...base, p: { x: b.ll.x, y: b.ur.y }, theta: Math.PI * 0.75, side:
|
|
18092
|
+
return { ...base, p: { x: b.ll.x, y: b.ur.y }, theta: Math.PI * 0.75, side: sides2 & (TOP | LEFT), defined: true, rv: 0 };
|
|
17497
18093
|
default:
|
|
17498
18094
|
return dirUnrecognized({ x: ctr.x, y: ctr.y });
|
|
17499
18095
|
}
|
|
17500
18096
|
}
|
|
17501
|
-
function dirS(rest, b, ctr,
|
|
18097
|
+
function dirS(rest, b, ctr, sides2) {
|
|
17502
18098
|
const base = { constrain: true, clip: false, dyna: false };
|
|
17503
18099
|
switch (rest) {
|
|
17504
18100
|
case "":
|
|
17505
|
-
return { ...base, p: { x: ctr.x, y: b.ll.y }, theta: -Math.PI * 0.5, side:
|
|
18101
|
+
return { ...base, p: { x: ctr.x, y: b.ll.y }, theta: -Math.PI * 0.5, side: sides2 & BOTTOM, defined: true, rv: 0 };
|
|
17506
18102
|
case "e":
|
|
17507
|
-
return { ...base, p: { x: b.ur.x, y: b.ll.y }, theta: -Math.PI * 0.25, side:
|
|
18103
|
+
return { ...base, p: { x: b.ur.x, y: b.ll.y }, theta: -Math.PI * 0.25, side: sides2 & (BOTTOM | RIGHT), defined: true, rv: 0 };
|
|
17508
18104
|
case "w":
|
|
17509
|
-
return { ...base, p: { x: b.ll.x, y: b.ll.y }, theta: -Math.PI * 0.75, side:
|
|
18105
|
+
return { ...base, p: { x: b.ll.x, y: b.ll.y }, theta: -Math.PI * 0.75, side: sides2 & (BOTTOM | LEFT), defined: true, rv: 0 };
|
|
17510
18106
|
default:
|
|
17511
18107
|
return dirUnrecognized({ x: ctr.x, y: ctr.y });
|
|
17512
18108
|
}
|
|
17513
18109
|
}
|
|
17514
|
-
function dirE(rest, b, ctr,
|
|
18110
|
+
function dirE(rest, b, ctr, sides2) {
|
|
17515
18111
|
if (rest.length > 0) return dirUnrecognized(ctr);
|
|
17516
|
-
return { p: { x: b.ur.x, y: ctr.y }, theta: 0, side:
|
|
18112
|
+
return { p: { x: b.ur.x, y: ctr.y }, theta: 0, side: sides2 & RIGHT, constrain: true, clip: false, dyna: false, defined: true, rv: 0 };
|
|
17517
18113
|
}
|
|
17518
|
-
function dirW(rest, b, ctr,
|
|
18114
|
+
function dirW(rest, b, ctr, sides2) {
|
|
17519
18115
|
if (rest.length > 0) return dirUnrecognized(ctr);
|
|
17520
|
-
return { p: { x: b.ll.x, y: ctr.y }, theta: Math.PI, side:
|
|
18116
|
+
return { p: { x: b.ll.x, y: ctr.y }, theta: Math.PI, side: sides2 & LEFT, constrain: true, clip: false, dyna: false, defined: true, rv: 0 };
|
|
17521
18117
|
}
|
|
17522
|
-
function compassDirection(compass, b, ctr,
|
|
18118
|
+
function compassDirection(compass, b, ctr, sides2) {
|
|
17523
18119
|
if (compass.length === 0) return dirDefault(ctr);
|
|
17524
18120
|
const rest = compass.slice(1);
|
|
17525
18121
|
switch (compass[0]) {
|
|
17526
18122
|
case "n":
|
|
17527
|
-
return dirN(rest, b, ctr,
|
|
18123
|
+
return dirN(rest, b, ctr, sides2);
|
|
17528
18124
|
case "s":
|
|
17529
|
-
return dirS(rest, b, ctr,
|
|
18125
|
+
return dirS(rest, b, ctr, sides2);
|
|
17530
18126
|
case "e":
|
|
17531
|
-
return dirE(rest, b, ctr,
|
|
18127
|
+
return dirE(rest, b, ctr, sides2);
|
|
17532
18128
|
case "w":
|
|
17533
|
-
return dirW(rest, b, ctr,
|
|
18129
|
+
return dirW(rest, b, ctr, sides2);
|
|
17534
18130
|
case "_":
|
|
17535
|
-
return { p: { ...ctr }, theta: 0, side:
|
|
18131
|
+
return { p: { ...ctr }, theta: 0, side: sides2, constrain: false, clip: true, dyna: true, defined: false, rv: 0 };
|
|
17536
18132
|
case "c":
|
|
17537
18133
|
return dirDefault(ctr);
|
|
17538
18134
|
default:
|
|
@@ -17581,31 +18177,31 @@ function applyIctxt(n, dir, b, ctr) {
|
|
|
17581
18177
|
dir.p = compassPoint(n, insideFn, yArg, xArg, gdRankdir(n));
|
|
17582
18178
|
}
|
|
17583
18179
|
function compassPort(n, args, pp) {
|
|
17584
|
-
const { bp, compass, sides } = args;
|
|
18180
|
+
const { bp, compass, sides: sides2 } = args;
|
|
17585
18181
|
const { b, p, defined: defBp } = compassBbox(n, bp);
|
|
17586
|
-
const dir = compassDirection(compass, b, p,
|
|
18182
|
+
const dir = compassDirection(compass, b, p, sides2);
|
|
17587
18183
|
if (bp === null && !isBox(n)) applyIctxt(n, dir, b, p);
|
|
17588
18184
|
const defFinal = dir.rv === 1 ? defBp : dir.defined || defBp;
|
|
17589
18185
|
applyDir(pp, bp, dir, gdRankdir(n), defFinal);
|
|
17590
18186
|
return dir.rv;
|
|
17591
18187
|
}
|
|
17592
|
-
function htmlPort(n, portname,
|
|
18188
|
+
function htmlPort(n, portname, sides2) {
|
|
17593
18189
|
const label = n.info.label;
|
|
17594
18190
|
const placed = label?.u?.kind === "html" ? label.u.html : void 0;
|
|
17595
18191
|
if (placed === void 0) return null;
|
|
17596
18192
|
const hit = portToTbl(placed, portname);
|
|
17597
18193
|
if (hit === null) return null;
|
|
17598
|
-
|
|
18194
|
+
sides2.value = hit.sides;
|
|
17599
18195
|
return hit.box;
|
|
17600
18196
|
}
|
|
17601
18197
|
function polyPort(n, portname, compass) {
|
|
17602
18198
|
if (portname.length === 0) return makePort();
|
|
17603
18199
|
const compassStr = compass.length === 0 ? "_" : compass;
|
|
17604
|
-
const
|
|
18200
|
+
const sides2 = BOTTOM | RIGHT | TOP | LEFT;
|
|
17605
18201
|
const rv = makePort();
|
|
17606
18202
|
const label = n.info.label;
|
|
17607
18203
|
if (label?.html === true) {
|
|
17608
|
-
const sidesRef = { value:
|
|
18204
|
+
const sidesRef = { value: sides2 };
|
|
17609
18205
|
const bp = htmlPort(n, portname, sidesRef);
|
|
17610
18206
|
if (bp !== null) {
|
|
17611
18207
|
compassPort(n, { bp, compass: compassStr, sides: sidesRef.value }, rv);
|
|
@@ -17613,7 +18209,7 @@ function polyPort(n, portname, compass) {
|
|
|
17613
18209
|
return rv;
|
|
17614
18210
|
}
|
|
17615
18211
|
}
|
|
17616
|
-
compassPort(n, { bp: null, compass: portname, sides }, rv);
|
|
18212
|
+
compassPort(n, { bp: null, compass: portname, sides: sides2 }, rv);
|
|
17617
18213
|
rv.name = null;
|
|
17618
18214
|
return rv;
|
|
17619
18215
|
}
|
|
@@ -17974,8 +18570,8 @@ function initNodeFromLabel(n, g, measurer) {
|
|
|
17974
18570
|
return true;
|
|
17975
18571
|
}
|
|
17976
18572
|
function effectivePolygon(poly, p, fixedshape) {
|
|
17977
|
-
let
|
|
17978
|
-
if (
|
|
18573
|
+
let sides2 = p.sides;
|
|
18574
|
+
if (sides2 <= 2 && (p.distortion !== 0 || p.skew !== 0)) sides2 = 120;
|
|
17979
18575
|
return {
|
|
17980
18576
|
...poly,
|
|
17981
18577
|
// C: poly->option.fixedshape = true inside the fixedsize="shape" branch;
|
|
@@ -17983,7 +18579,7 @@ function effectivePolygon(poly, p, fixedshape) {
|
|
|
17983
18579
|
option: { ...poly.option, fixedshape },
|
|
17984
18580
|
regular: p.regular,
|
|
17985
18581
|
peripheries: p.peripheries,
|
|
17986
|
-
sides,
|
|
18582
|
+
sides: sides2,
|
|
17987
18583
|
orientation: p.orientation,
|
|
17988
18584
|
distortion: p.distortion,
|
|
17989
18585
|
skew: p.skew,
|
|
@@ -19125,8 +19721,8 @@ function orthoRoundedRadius(e, job) {
|
|
|
19125
19721
|
if (e.head.root.attrs.get("splines") !== "ortho") return null;
|
|
19126
19722
|
let wantRounded = false;
|
|
19127
19723
|
let radius = 0;
|
|
19128
|
-
const
|
|
19129
|
-
if (
|
|
19724
|
+
const style2 = e.attrs.get("style");
|
|
19725
|
+
if (style2 !== void 0 && style2.split(",").map((s) => s.trim()).includes("rounded")) {
|
|
19130
19726
|
wantRounded = true;
|
|
19131
19727
|
}
|
|
19132
19728
|
const radiusAttr = e.attrs.get("radius");
|
|
@@ -19511,20 +20107,10 @@ function checkControlPoints2(cp) {
|
|
|
19511
20107
|
return ptToLine22(cp[0], cp[3], cp[1]) < MAP_HW * MAP_HW && ptToLine22(cp[0], cp[3], cp[2]) < MAP_HW * MAP_HW;
|
|
19512
20108
|
}
|
|
19513
20109
|
function bezierHalf(v) {
|
|
19514
|
-
const
|
|
19515
|
-
const
|
|
19516
|
-
|
|
19517
|
-
|
|
19518
|
-
for (let j = 0; j <= 3 - i; j++) {
|
|
19519
|
-
const a = vt[i - 1][j];
|
|
19520
|
-
const b = vt[i - 1][j + 1];
|
|
19521
|
-
vt[i][j] = { x: (1 - t) * a.x + t * b.x, y: (1 - t) * a.y + t * b.y };
|
|
19522
|
-
}
|
|
19523
|
-
}
|
|
19524
|
-
return {
|
|
19525
|
-
left: [vt[0][0], vt[1][0], vt[2][0], vt[3][0]],
|
|
19526
|
-
right: [vt[3][0], vt[2][1], vt[1][2], vt[0][3]]
|
|
19527
|
-
};
|
|
20110
|
+
const left2 = [];
|
|
20111
|
+
const right2 = [];
|
|
20112
|
+
bezier(v, 0.5, left2, right2);
|
|
20113
|
+
return { left: left2, right: right2 };
|
|
19528
20114
|
}
|
|
19529
20115
|
function approxBezier(cp, out) {
|
|
19530
20116
|
if (checkControlPoints2(cp)) {
|
|
@@ -19868,7 +20454,7 @@ function setEdgePen(e, job) {
|
|
|
19868
20454
|
);
|
|
19869
20455
|
obj.pen = resolvePenType(flags);
|
|
19870
20456
|
obj.penWidth = resolvePenWidth(flags, e.attrs.get("penwidth"));
|
|
19871
|
-
obj.rawStyle =
|
|
20457
|
+
obj.rawStyle = styleTokens2(e.attrs.get("style"));
|
|
19872
20458
|
}
|
|
19873
20459
|
function renderEdge(e, renderer, job) {
|
|
19874
20460
|
emitEdgeComments(e, renderer, job);
|
|
@@ -20067,9 +20653,9 @@ function htmlFillPenWidth() {
|
|
|
20067
20653
|
function resetHtmlFillPenWidth() {
|
|
20068
20654
|
htmlFillPen = 1;
|
|
20069
20655
|
}
|
|
20070
|
-
function penTypeOf(
|
|
20071
|
-
if (
|
|
20072
|
-
if (
|
|
20656
|
+
function penTypeOf(style2) {
|
|
20657
|
+
if (style2 !== void 0 && style2.includes("dashed")) return 1 /* Dashed */;
|
|
20658
|
+
if (style2 !== void 0 && style2.includes("dotted")) return 2 /* Dotted */;
|
|
20073
20659
|
return 3 /* Solid */;
|
|
20074
20660
|
}
|
|
20075
20661
|
function withHtmlPaint(paint, job, drawFn) {
|
|
@@ -20100,13 +20686,13 @@ function applyHtmlFill(paint) {
|
|
|
20100
20686
|
paintObj.gradientAngle = 0;
|
|
20101
20687
|
paintObj.gradientFrac = 0;
|
|
20102
20688
|
}
|
|
20103
|
-
function mkPts(b,
|
|
20689
|
+
function mkPts(b, border2, pos) {
|
|
20104
20690
|
let llx = b.ll.x + pos.x;
|
|
20105
20691
|
let lly = b.ll.y + pos.y;
|
|
20106
20692
|
let urx = b.ur.x + pos.x;
|
|
20107
20693
|
let ury = b.ur.y + pos.y;
|
|
20108
|
-
if (
|
|
20109
|
-
const delta2 =
|
|
20694
|
+
if (border2 > 1) {
|
|
20695
|
+
const delta2 = border2 / 2;
|
|
20110
20696
|
llx += delta2;
|
|
20111
20697
|
lly += delta2;
|
|
20112
20698
|
urx -= delta2;
|
|
@@ -20133,26 +20719,26 @@ function doSide(p, wd, ht, renderer, job) {
|
|
|
20133
20719
|
renderer.polygon(pts, true, job);
|
|
20134
20720
|
}
|
|
20135
20721
|
function doBorder(spec, renderer, job) {
|
|
20136
|
-
const { box, pos, border, color, sides, style } = spec;
|
|
20137
|
-
htmlFillPen =
|
|
20138
|
-
withHtmlPaint({ pen: color, penWidth:
|
|
20139
|
-
if (parseStyleFlags(
|
|
20140
|
-
emitRoundedBezier(mkPts(box,
|
|
20722
|
+
const { box, pos, border: border2, color, sides: sides2, style: style2 } = spec;
|
|
20723
|
+
htmlFillPen = border2;
|
|
20724
|
+
withHtmlPaint({ pen: color, penWidth: border2, penStyle: style2 }, job, () => {
|
|
20725
|
+
if (parseStyleFlags(style2).rounded) {
|
|
20726
|
+
emitRoundedBezier(mkPts(box, border2, pos), { x: 0, y: 0 }, false, { renderer, job });
|
|
20141
20727
|
return;
|
|
20142
20728
|
}
|
|
20143
|
-
const effSides =
|
|
20729
|
+
const effSides = sides2 !== void 0 ? sides2 & BORDER_MASK : 0;
|
|
20144
20730
|
if (effSides !== 0) {
|
|
20145
|
-
const corners = mkPts(box,
|
|
20731
|
+
const corners = mkPts(box, border2, pos).map((p) => transformPoint(p, job));
|
|
20146
20732
|
emitSidedPolylines(effSides, corners, renderer, job);
|
|
20147
20733
|
} else {
|
|
20148
|
-
emitFullBoxBorder(box, pos,
|
|
20734
|
+
emitFullBoxBorder(box, pos, border2, renderer, job);
|
|
20149
20735
|
}
|
|
20150
20736
|
});
|
|
20151
20737
|
}
|
|
20152
|
-
function emitFullBoxBorder(box, pos,
|
|
20153
|
-
const b2 =
|
|
20154
|
-
ll: { x: box.ll.x +
|
|
20155
|
-
ur: { x: box.ur.x -
|
|
20738
|
+
function emitFullBoxBorder(box, pos, border2, renderer, job) {
|
|
20739
|
+
const b2 = border2 > 1 ? {
|
|
20740
|
+
ll: { x: box.ll.x + border2 / 2, y: box.ll.y + border2 / 2 },
|
|
20741
|
+
ur: { x: box.ur.x - border2 / 2, y: box.ur.y - border2 / 2 }
|
|
20156
20742
|
} : box;
|
|
20157
20743
|
const pts = [
|
|
20158
20744
|
{ x: b2.ll.x + pos.x, y: b2.ll.y + pos.y },
|
|
@@ -20187,8 +20773,8 @@ var SIDES_TABLE = /* @__PURE__ */ new Map([
|
|
|
20187
20773
|
[T, [[NE, NW]]],
|
|
20188
20774
|
[L, [[NW, SW]]]
|
|
20189
20775
|
]);
|
|
20190
|
-
function emitSidedPolylines(
|
|
20191
|
-
const seqs = SIDES_TABLE.get(
|
|
20776
|
+
function emitSidedPolylines(sides2, corners, renderer, job) {
|
|
20777
|
+
const seqs = SIDES_TABLE.get(sides2 & BORDER_MASK);
|
|
20192
20778
|
if (seqs === void 0) return;
|
|
20193
20779
|
for (const seq2 of seqs) {
|
|
20194
20780
|
renderer.polyline(seq2.map((i) => corners[i]), job);
|
|
@@ -20228,11 +20814,11 @@ function zeroFlags() {
|
|
|
20228
20814
|
};
|
|
20229
20815
|
}
|
|
20230
20816
|
var FUNLIMIT = 64;
|
|
20231
|
-
function
|
|
20232
|
-
if (!
|
|
20817
|
+
function styleTokens2(style2) {
|
|
20818
|
+
if (!style2) return [];
|
|
20233
20819
|
const out = [];
|
|
20234
20820
|
let fun = 0;
|
|
20235
|
-
for (const raw of
|
|
20821
|
+
for (const raw of style2.split(",")) {
|
|
20236
20822
|
const token = raw.trim();
|
|
20237
20823
|
if (token.length === 0) continue;
|
|
20238
20824
|
if (fun === FUNLIMIT - 1) return [];
|
|
@@ -20266,11 +20852,11 @@ function firstSolidColor(raw) {
|
|
|
20266
20852
|
const grad = parseGradientSpec(raw);
|
|
20267
20853
|
return grad !== null ? grad[0] : raw;
|
|
20268
20854
|
}
|
|
20269
|
-
function parseStyleFlags(
|
|
20855
|
+
function parseStyleFlags(style2) {
|
|
20270
20856
|
const flags = zeroFlags();
|
|
20271
|
-
if (!
|
|
20857
|
+
if (!style2) return flags;
|
|
20272
20858
|
let fun = 0;
|
|
20273
|
-
for (const raw of
|
|
20859
|
+
for (const raw of style2.split(",")) {
|
|
20274
20860
|
const token = raw.trim();
|
|
20275
20861
|
if (token.length === 0) continue;
|
|
20276
20862
|
if (fun === FUNLIMIT - 1) return zeroFlags();
|
|
@@ -20284,10 +20870,10 @@ function parseStyleFlags(style) {
|
|
|
20284
20870
|
}
|
|
20285
20871
|
return flags;
|
|
20286
20872
|
}
|
|
20287
|
-
function styleHasInvisibleAlias(
|
|
20288
|
-
if (!
|
|
20873
|
+
function styleHasInvisibleAlias(style2) {
|
|
20874
|
+
if (!style2) return false;
|
|
20289
20875
|
let fun = 0;
|
|
20290
|
-
for (const raw of
|
|
20876
|
+
for (const raw of style2.split(",")) {
|
|
20291
20877
|
const token = raw.trim();
|
|
20292
20878
|
if (token.length === 0) continue;
|
|
20293
20879
|
if (fun === FUNLIMIT - 1) return false;
|
|
@@ -20342,9 +20928,9 @@ function findStopColor(colorlist) {
|
|
|
20342
20928
|
const frac = seg0.hasFraction ? seg0.t : seg1.hasFraction ? 1 - seg1.t : 0;
|
|
20343
20929
|
return { fillColor, stopColor, frac };
|
|
20344
20930
|
}
|
|
20345
|
-
function parseAngle(
|
|
20346
|
-
if (!
|
|
20347
|
-
const v = parseInt(
|
|
20931
|
+
function parseAngle(gradientangle2) {
|
|
20932
|
+
if (!gradientangle2 || gradientangle2.length === 0) return 0;
|
|
20933
|
+
const v = parseInt(gradientangle2, 10);
|
|
20348
20934
|
return isFinite(v) ? v : 0;
|
|
20349
20935
|
}
|
|
20350
20936
|
function buildResolvedFill(rawColor, flags, angle) {
|
|
@@ -20881,10 +21467,10 @@ var SelfEdgeImpl = class _SelfEdgeImpl {
|
|
|
20881
21467
|
const lbl = e.info.label;
|
|
20882
21468
|
if (!lbl?.dimen) return 0;
|
|
20883
21469
|
const flip = e.tail.root.info.flip === true;
|
|
20884
|
-
const
|
|
20885
|
-
lbl.pos = { x: a.x, y: a.y + a.sign *
|
|
21470
|
+
const height2 = flip ? lbl.dimen.x : lbl.dimen.y;
|
|
21471
|
+
lbl.pos = { x: a.x, y: a.y + a.sign * height2 / 2 };
|
|
20886
21472
|
lbl.set = true;
|
|
20887
|
-
return
|
|
21473
|
+
return height2;
|
|
20888
21474
|
}
|
|
20889
21475
|
/** Place a left/right self-loop label; return the label width that governs
|
|
20890
21476
|
* the loop's widen. Under flip the label is rotated, so dimen.y is the
|
|
@@ -20893,10 +21479,10 @@ var SelfEdgeImpl = class _SelfEdgeImpl {
|
|
|
20893
21479
|
const lbl = e.info.label;
|
|
20894
21480
|
if (!lbl?.dimen) return 0;
|
|
20895
21481
|
const flip = e.tail.root.info.flip === true;
|
|
20896
|
-
const
|
|
20897
|
-
lbl.pos = { x: a.x + a.sign *
|
|
21482
|
+
const width2 = flip ? lbl.dimen.y : lbl.dimen.x;
|
|
21483
|
+
lbl.pos = { x: a.x + a.sign * width2 / 2, y: a.y };
|
|
20898
21484
|
lbl.set = true;
|
|
20899
|
-
return
|
|
21485
|
+
return width2;
|
|
20900
21486
|
}
|
|
20901
21487
|
static bottomPts(a) {
|
|
20902
21488
|
const { tp, hp, np, dx, dy, ty, hy } = a;
|
|
@@ -21226,11 +21812,11 @@ function processFlatEdge(g, u, e) {
|
|
|
21226
21812
|
const isOrdered = nodeOrder(u) < nodeOrder(e.head);
|
|
21227
21813
|
const t0 = isOrdered ? e.tail : e.head;
|
|
21228
21814
|
const h0 = isOrdered ? e.head : e.tail;
|
|
21229
|
-
const
|
|
21230
|
-
let m0 = Math.trunc(edgeMinlen(e) * nodesep +
|
|
21815
|
+
const width2 = nodeRw(t0) + nodeLw(h0);
|
|
21816
|
+
let m0 = Math.trunc(edgeMinlen(e) * nodesep + width2);
|
|
21231
21817
|
const ex = findFastEdge(t0, h0);
|
|
21232
21818
|
if (ex !== void 0) {
|
|
21233
|
-
m0 = Math.trunc(Math.max(m0,
|
|
21819
|
+
m0 = Math.trunc(Math.max(m0, width2 + nodesep + cround(edgeDist(e))));
|
|
21234
21820
|
ex.info.minlen = Math.max(ex.info.minlen ?? 1, m0);
|
|
21235
21821
|
ex.info.weight = Math.max(ex.info.weight ?? 0, edgeWeight2(e));
|
|
21236
21822
|
} else if (!e.info.label) {
|
|
@@ -21285,9 +21871,9 @@ function selfWidth(u) {
|
|
|
21285
21871
|
}
|
|
21286
21872
|
function lrRankPair(g, r, u, v, last) {
|
|
21287
21873
|
const nodesep = lrSep(g, r);
|
|
21288
|
-
const
|
|
21289
|
-
makeAuxEdge(u, v,
|
|
21290
|
-
const next = Math.trunc(last +
|
|
21874
|
+
const width2 = nodeRw(u) + nodeLw(v) + nodesep;
|
|
21875
|
+
makeAuxEdge(u, v, width2, 0);
|
|
21876
|
+
const next = Math.trunc(last + width2);
|
|
21291
21877
|
v.info.rank = next;
|
|
21292
21878
|
return next;
|
|
21293
21879
|
}
|
|
@@ -24401,9 +24987,9 @@ function setAspect2(g) {
|
|
|
24401
24987
|
function placeLabelNonFlip(g) {
|
|
24402
24988
|
const bb = g.info.bb;
|
|
24403
24989
|
const labelPos2 = g.info.label_pos ?? 1;
|
|
24404
|
-
const
|
|
24990
|
+
const border2 = g.info.border;
|
|
24405
24991
|
const zero = { x: 0, y: 0 };
|
|
24406
|
-
const d = labelPos2 & 1 ?
|
|
24992
|
+
const d = labelPos2 & 1 ? border2?.[TOP_IX] ?? zero : border2?.[BOTTOM_IX] ?? zero;
|
|
24407
24993
|
const py = labelPos2 & 1 ? bb.ur.y - d.y / 2 : bb.ll.y + d.y / 2;
|
|
24408
24994
|
const px = labelPos2 & 4 ? bb.ur.x - d.x / 2 : labelPos2 & 2 ? bb.ll.x + d.x / 2 : (bb.ll.x + bb.ur.x) / 2;
|
|
24409
24995
|
return { x: px, y: py };
|
|
@@ -24411,9 +24997,9 @@ function placeLabelNonFlip(g) {
|
|
|
24411
24997
|
function placeLabelFlip(g) {
|
|
24412
24998
|
const bb = g.info.bb;
|
|
24413
24999
|
const labelPos2 = g.info.label_pos ?? 1;
|
|
24414
|
-
const
|
|
25000
|
+
const border2 = g.info.border;
|
|
24415
25001
|
const zero = { x: 0, y: 0 };
|
|
24416
|
-
const d = labelPos2 & 1 ?
|
|
25002
|
+
const d = labelPos2 & 1 ? border2?.[RIGHT_IX] ?? zero : border2?.[LEFT_IX] ?? zero;
|
|
24417
25003
|
const px = labelPos2 & 1 ? bb.ur.x - d.x / 2 : bb.ll.x + d.x / 2;
|
|
24418
25004
|
const py = labelPos2 & 4 ? bb.ll.y + d.y / 2 : labelPos2 & 2 ? bb.ur.y - d.y / 2 : (bb.ll.y + bb.ur.y) / 2;
|
|
24419
25005
|
return { x: px, y: py };
|
|
@@ -25391,18 +25977,6 @@ function dist2(p, q) {
|
|
|
25391
25977
|
function distPt(p, q) {
|
|
25392
25978
|
return Math.sqrt(dist2(p, q));
|
|
25393
25979
|
}
|
|
25394
|
-
function bezier(v, t) {
|
|
25395
|
-
const u = 1 - t;
|
|
25396
|
-
const x = [v[0].x, v[1].x, v[2].x, v[3].x];
|
|
25397
|
-
const y = [v[0].y, v[1].y, v[2].y, v[3].y];
|
|
25398
|
-
for (let i = 1; i <= 3; i++) {
|
|
25399
|
-
for (let j = 0; j <= 3 - i; j++) {
|
|
25400
|
-
x[j] = fma(x[j], u, t * x[j + 1]);
|
|
25401
|
-
y[j] = fma(y[j], u, t * y[j + 1]);
|
|
25402
|
-
}
|
|
25403
|
-
}
|
|
25404
|
-
return { x: x[0], y: y[0] };
|
|
25405
|
-
}
|
|
25406
25980
|
function dotneatoClosest(spl, pt) {
|
|
25407
25981
|
let besti = 0;
|
|
25408
25982
|
let bestj = -1;
|
|
@@ -25431,7 +26005,7 @@ function dotneatoClosest(spl, pt) {
|
|
|
25431
26005
|
let pt2;
|
|
25432
26006
|
for (; ; ) {
|
|
25433
26007
|
const t = (lo + hi) / 2;
|
|
25434
|
-
pt2 = bezier(c, t);
|
|
26008
|
+
pt2 = bezier(c, t, null, null);
|
|
25435
26009
|
if (Math.abs(dlo2 - dhi2) < 1 || Math.abs(hi - lo) < 1e-5) break;
|
|
25436
26010
|
if (dlo2 < dhi2) {
|
|
25437
26011
|
hi = t;
|
|
@@ -25522,8 +26096,8 @@ function faceMidpoint(b, ix) {
|
|
|
25522
26096
|
return { x: b.ll.x, y: cy };
|
|
25523
26097
|
}
|
|
25524
26098
|
function closestSide(n, other, port) {
|
|
25525
|
-
const
|
|
25526
|
-
if (
|
|
26099
|
+
const sides2 = port.side;
|
|
26100
|
+
if (sides2 === 0 || sides2 === ALL_SIDES2) return null;
|
|
25527
26101
|
const rkd = (n.root.info.rankdir ?? 0) & 3;
|
|
25528
26102
|
const pt = cvtPt(n.info.coord, rkd);
|
|
25529
26103
|
const opt = cvtPt(other.info.coord, rkd);
|
|
@@ -25531,7 +26105,7 @@ function closestSide(n, other, port) {
|
|
|
25531
26105
|
let rv = null;
|
|
25532
26106
|
let mind = 0;
|
|
25533
26107
|
for (let i = 0; i < 4; i++) {
|
|
25534
|
-
if ((
|
|
26108
|
+
if ((sides2 & 1 << i) === 0) continue;
|
|
25535
26109
|
const m = faceMidpoint(b, i);
|
|
25536
26110
|
const d = dist2({ x: m.x + pt.x, y: m.y + pt.y }, opt);
|
|
25537
26111
|
if (rv === null || d < mind) {
|
|
@@ -27248,17 +27822,20 @@ function checkPath(boxn, boxes, pp) {
|
|
|
27248
27822
|
return false;
|
|
27249
27823
|
}
|
|
27250
27824
|
function deCasteljauPoint(p0, p1, p2, p3, t) {
|
|
27251
|
-
|
|
27252
|
-
|
|
27253
|
-
|
|
27254
|
-
|
|
27255
|
-
|
|
27256
|
-
|
|
27257
|
-
|
|
27258
|
-
|
|
27259
|
-
|
|
27260
|
-
|
|
27261
|
-
|
|
27825
|
+
let s0x = p0.x, s0y = p0.y, s1x = p1.x, s1y = p1.y, s2x = p2.x, s2y = p2.y;
|
|
27826
|
+
s0x = fma(t, s1x - s0x, s0x);
|
|
27827
|
+
s0y = fma(t, s1y - s0y, s0y);
|
|
27828
|
+
s1x = fma(t, s2x - s1x, s1x);
|
|
27829
|
+
s1y = fma(t, s2y - s1y, s1y);
|
|
27830
|
+
s2x = fma(t, p3.x - s2x, s2x);
|
|
27831
|
+
s2y = fma(t, p3.y - s2y, s2y);
|
|
27832
|
+
s0x = fma(t, s1x - s0x, s0x);
|
|
27833
|
+
s0y = fma(t, s1y - s0y, s0y);
|
|
27834
|
+
s1x = fma(t, s2x - s1x, s1x);
|
|
27835
|
+
s1y = fma(t, s2y - s1y, s1y);
|
|
27836
|
+
s0x = fma(t, s1x - s0x, s0x);
|
|
27837
|
+
s0y = fma(t, s1y - s0y, s0y);
|
|
27838
|
+
return { x: s0x, y: s0y };
|
|
27262
27839
|
}
|
|
27263
27840
|
function updateBoxExtents(boxes, boxn, sp) {
|
|
27264
27841
|
for (let bi = 0; bi < boxn; bi++) {
|
|
@@ -27279,7 +27856,7 @@ function sampleBezierSegment(boxes, boxn, pps, splinepi, numDiv) {
|
|
|
27279
27856
|
}
|
|
27280
27857
|
}
|
|
27281
27858
|
function limitBoxes(boxes, boxn, pps, pn, delta2) {
|
|
27282
|
-
const numDiv =
|
|
27859
|
+
const numDiv = delta2 * boxn;
|
|
27283
27860
|
for (let splinepi = 0; splinepi + 3 < pn; splinepi += 3) {
|
|
27284
27861
|
sampleBezierSegment(boxes, boxn, pps, splinepi, numDiv);
|
|
27285
27862
|
}
|
|
@@ -27945,15 +28522,15 @@ function leftOf(p1, p2, p3) {
|
|
|
27945
28522
|
}
|
|
27946
28523
|
function lineLabelPoints(g, startp, endp, label) {
|
|
27947
28524
|
const flip = g.info.flip === true;
|
|
27948
|
-
const
|
|
27949
|
-
const
|
|
28525
|
+
const width2 = flip ? label.dimen.y : label.dimen.x;
|
|
28526
|
+
const height2 = flip ? label.dimen.x : label.dimen.y;
|
|
27950
28527
|
const lp = { x: label.pos.x, y: label.pos.y };
|
|
27951
28528
|
if (leftOf(endp, startp, lp)) {
|
|
27952
|
-
lp.x +=
|
|
27953
|
-
lp.y -=
|
|
28529
|
+
lp.x += width2 / 2;
|
|
28530
|
+
lp.y -= height2 / 2;
|
|
27954
28531
|
} else {
|
|
27955
|
-
lp.x -=
|
|
27956
|
-
lp.y +=
|
|
28532
|
+
lp.x -= width2 / 2;
|
|
28533
|
+
lp.y += height2 / 2;
|
|
27957
28534
|
}
|
|
27958
28535
|
return [startp, startp, lp, lp, lp, endp, endp];
|
|
27959
28536
|
}
|
|
@@ -29340,8 +29917,8 @@ function findNormalOutEdge(first) {
|
|
|
29340
29917
|
}
|
|
29341
29918
|
function labelXPos(n, l) {
|
|
29342
29919
|
const flip = !!n.root?.info.flip;
|
|
29343
|
-
const
|
|
29344
|
-
return n.info.coord.x +
|
|
29920
|
+
const width2 = flip ? l.dimen.y : l.dimen.x;
|
|
29921
|
+
return n.info.coord.x + width2 / 2;
|
|
29345
29922
|
}
|
|
29346
29923
|
function placeVnlabel(n) {
|
|
29347
29924
|
if ((n.info.in?.size ?? 0) === 0) return;
|
|
@@ -29379,22 +29956,12 @@ function setEdgeLabelPos(g) {
|
|
|
29379
29956
|
}
|
|
29380
29957
|
var PORT_LABEL_DISTANCE = 10;
|
|
29381
29958
|
var PORT_LABEL_ANGLE = -25;
|
|
29382
|
-
function cubicBezierAt(pts, t) {
|
|
29383
|
-
const p0 = pts[0], p1 = pts[1], p2 = pts[2], p3 = pts[3];
|
|
29384
|
-
const mt = 1 - t;
|
|
29385
|
-
const q0 = { x: mt * p0.x + t * p1.x, y: mt * p0.y + t * p1.y };
|
|
29386
|
-
const q1 = { x: mt * p1.x + t * p2.x, y: mt * p1.y + t * p2.y };
|
|
29387
|
-
const q2 = { x: mt * p2.x + t * p3.x, y: mt * p2.y + t * p3.y };
|
|
29388
|
-
const r0 = { x: mt * q0.x + t * q1.x, y: mt * q0.y + t * q1.y };
|
|
29389
|
-
const r1 = { x: mt * q1.x + t * q2.x, y: mt * q1.y + t * q2.y };
|
|
29390
|
-
return { x: mt * r0.x + t * r1.x, y: mt * r0.y + t * r1.y };
|
|
29391
|
-
}
|
|
29392
29959
|
function tailEndpoints(bez) {
|
|
29393
29960
|
if (bez.sflag) {
|
|
29394
29961
|
return { pe: bez.sp, pf: bez.list[0] };
|
|
29395
29962
|
}
|
|
29396
29963
|
const pe = bez.list[0];
|
|
29397
|
-
const pf =
|
|
29964
|
+
const pf = bezier(bez.list, 0.1, null, null);
|
|
29398
29965
|
return { pe, pf };
|
|
29399
29966
|
}
|
|
29400
29967
|
function headEndpoints(bez) {
|
|
@@ -29403,7 +29970,7 @@ function headEndpoints(bez) {
|
|
|
29403
29970
|
}
|
|
29404
29971
|
const pe = bez.list[bez.size - 1];
|
|
29405
29972
|
const last4 = bez.list.slice(bez.size - 4, bez.size);
|
|
29406
|
-
const pf =
|
|
29973
|
+
const pf = bezier(last4, 0.9, null, null);
|
|
29407
29974
|
return { pe, pf };
|
|
29408
29975
|
}
|
|
29409
29976
|
function placePortlabel(e, headP) {
|
|
@@ -32578,22 +33145,22 @@ function gcellWalk(pd, sx, sy, boundIsX, bound) {
|
|
|
32578
33145
|
}
|
|
32579
33146
|
return out;
|
|
32580
33147
|
}
|
|
32581
|
-
function appendSide(
|
|
33148
|
+
function appendSide(sides2, found, cp, cellIdx) {
|
|
32582
33149
|
for (const np of found) {
|
|
32583
|
-
|
|
33150
|
+
sides2.push(np);
|
|
32584
33151
|
np.cells[cellIdx] = cp;
|
|
32585
33152
|
}
|
|
32586
33153
|
}
|
|
32587
33154
|
function attachGcellSides(mp, hdict, vdict) {
|
|
32588
33155
|
let maxdeg = 0;
|
|
32589
33156
|
for (const cp of mp.gcells) {
|
|
32590
|
-
const
|
|
32591
|
-
appendSide(
|
|
32592
|
-
appendSide(
|
|
32593
|
-
appendSide(
|
|
32594
|
-
appendSide(
|
|
32595
|
-
cp.sides =
|
|
32596
|
-
cp.nsides =
|
|
33157
|
+
const sides2 = [];
|
|
33158
|
+
appendSide(sides2, gcellWalk(hdict, cp.bb.LL.x, cp.bb.LL.y, true, cp.bb.UR.x), cp, 1);
|
|
33159
|
+
appendSide(sides2, gcellWalk(vdict, cp.bb.LL.x, cp.bb.LL.y, false, cp.bb.UR.y), cp, 1);
|
|
33160
|
+
appendSide(sides2, gcellWalk(hdict, cp.bb.LL.x, cp.bb.UR.y, true, cp.bb.UR.x), cp, 0);
|
|
33161
|
+
appendSide(sides2, gcellWalk(vdict, cp.bb.UR.x, cp.bb.LL.y, false, cp.bb.UR.y), cp, 0);
|
|
33162
|
+
cp.sides = sides2;
|
|
33163
|
+
cp.nsides = sides2.length;
|
|
32597
33164
|
if (cp.nsides > maxdeg) maxdeg = cp.nsides;
|
|
32598
33165
|
}
|
|
32599
33166
|
return maxdeg;
|
|
@@ -33875,21 +34442,10 @@ function inBoxf(p, bb) {
|
|
|
33875
34442
|
function midPointf2(a, b) {
|
|
33876
34443
|
return { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };
|
|
33877
34444
|
}
|
|
33878
|
-
function casteljauStep(prev, t) {
|
|
33879
|
-
const u = 1 - t;
|
|
33880
|
-
return [
|
|
33881
|
-
{ x: u * prev[0].x + t * prev[1].x, y: u * prev[0].y + t * prev[1].y },
|
|
33882
|
-
{ x: u * prev[1].x + t * prev[2].x, y: u * prev[1].y + t * prev[2].y },
|
|
33883
|
-
{ x: u * prev[2].x + t * prev[3].x, y: u * prev[2].y + t * prev[3].y },
|
|
33884
|
-
{ x: 0, y: 0 }
|
|
33885
|
-
];
|
|
33886
|
-
}
|
|
33887
34445
|
function subdivideBezier(v, t, side) {
|
|
33888
|
-
const
|
|
33889
|
-
|
|
33890
|
-
|
|
33891
|
-
const r3 = casteljauStep(r2, t);
|
|
33892
|
-
return side === "left" ? [r0[0], r1[0], r2[0], r3[0]] : [r3[0], r2[1], r1[2], r0[3]];
|
|
34446
|
+
const half = [];
|
|
34447
|
+
bezier([...v], t, side === "left" ? half : null, side === "right" ? half : null);
|
|
34448
|
+
return half;
|
|
33893
34449
|
}
|
|
33894
34450
|
function countVertCross(pts, xcoord) {
|
|
33895
34451
|
let sign2 = fcmp(pts[0].x, xcoord);
|
|
@@ -35373,10 +35929,11 @@ function bfsFixDisconnected(n, dist4, closestDist) {
|
|
|
35373
35929
|
function bfsVisitNeighbors(vertex, graph, dist4, queue) {
|
|
35374
35930
|
const vd = graph[vertex];
|
|
35375
35931
|
const d = dist4[vertex];
|
|
35932
|
+
const unit = graph[0].ewgts.length === 0;
|
|
35376
35933
|
for (let i = 1; i < vd.nedges; i++) {
|
|
35377
35934
|
const nb = vd.edges[i];
|
|
35378
35935
|
if (dist4[nb] < 0) {
|
|
35379
|
-
dist4[nb] = d + 1;
|
|
35936
|
+
dist4[nb] = d + (unit ? 1 : Math.trunc(Math.fround(vd.ewgts[i])));
|
|
35380
35937
|
queue.push(nb);
|
|
35381
35938
|
}
|
|
35382
35939
|
}
|
|
@@ -36804,11 +37361,12 @@ function runMajorization(g, mode, model) {
|
|
|
36804
37361
|
const nodeList = assignNodeIds2(g);
|
|
36805
37362
|
const n = nodeList.length;
|
|
36806
37363
|
const haveLen = graphHasLen(g);
|
|
36807
|
-
const vtx = makeGraphDataC(g, nodeList, haveLen);
|
|
37364
|
+
const vtx = makeGraphDataC(g, nodeList, haveLen, mode === MODE_HIER || mode === MODE_IPSEP);
|
|
36808
37365
|
checkStart(g);
|
|
36809
37366
|
const maxi = lateDouble(g.attrs.get("maxiter"), DFLT_ITERATIONS, 0);
|
|
36810
37367
|
const epsilon = lateDouble(g.attrs.get("epsilon"), 1e-4, 0);
|
|
36811
|
-
const
|
|
37368
|
+
const weighted = haveLen && mode !== MODE_IPSEP;
|
|
37369
|
+
const Dij = weighted ? computeWeightedApspPacked2(vtx, n) : computeApspPacked2(vtx, n);
|
|
36812
37370
|
const dCoords = [new Float64Array(n), new Float64Array(n)];
|
|
36813
37371
|
stressMajorizationKDMkernel(Dij, n, dCoords, nodeList, {
|
|
36814
37372
|
dim: DFLT_DIM,
|
|
@@ -36826,11 +37384,11 @@ function graphHasLen(g) {
|
|
|
36826
37384
|
}
|
|
36827
37385
|
return false;
|
|
36828
37386
|
}
|
|
36829
|
-
function makeGraphDataC(g, nodeList, haveLen) {
|
|
37387
|
+
function makeGraphDataC(g, nodeList, haveLen, haveDir) {
|
|
36830
37388
|
const vtx = nodeList.map((_, i) => ({
|
|
36831
37389
|
nedges: 1,
|
|
36832
37390
|
edges: [i],
|
|
36833
|
-
ewgts: haveLen ? [0] : []
|
|
37391
|
+
ewgts: haveLen || haveDir ? [0] : []
|
|
36834
37392
|
}));
|
|
36835
37393
|
for (const np of nodeList) {
|
|
36836
37394
|
const i = np.info.id;
|
|
@@ -36848,7 +37406,7 @@ function makeGraphDataC(g, nodeList, haveLen) {
|
|
|
36848
37406
|
}
|
|
36849
37407
|
seen.set(vid, entry.nedges);
|
|
36850
37408
|
entry.edges.push(vid);
|
|
36851
|
-
if (haveLen) entry.ewgts.push(dist4);
|
|
37409
|
+
if (haveLen || haveDir) entry.ewgts.push(dist4);
|
|
36852
37410
|
entry.nedges++;
|
|
36853
37411
|
}
|
|
36854
37412
|
}
|
|
@@ -37909,7 +38467,7 @@ var RIGHT3 = 1 << 1;
|
|
|
37909
38467
|
var TOP3 = 1 << 2;
|
|
37910
38468
|
var LEFT3 = 1 << 3;
|
|
37911
38469
|
var add = (p, q) => ({ x: p.x + q.x, y: p.y + q.y });
|
|
37912
|
-
function sideCone(p,
|
|
38470
|
+
function sideCone(p, sides2) {
|
|
37913
38471
|
const north = { x: 0, y: 1 };
|
|
37914
38472
|
const northeast = { x: 1, y: 1 };
|
|
37915
38473
|
const east = { x: 1, y: 0 };
|
|
@@ -37918,7 +38476,7 @@ function sideCone(p, sides) {
|
|
|
37918
38476
|
const southwest = { x: -1, y: -1 };
|
|
37919
38477
|
const west = { x: -1, y: 0 };
|
|
37920
38478
|
const northwest = { x: -1, y: 1 };
|
|
37921
|
-
switch (
|
|
38479
|
+
switch (sides2) {
|
|
37922
38480
|
case TOP3:
|
|
37923
38481
|
return [add(p, north), add(p, northwest), add(p, northeast)];
|
|
37924
38482
|
case TOP3 | RIGHT3:
|
|
@@ -37939,17 +38497,17 @@ function sideCone(p, sides) {
|
|
|
37939
38497
|
return [p, p, p];
|
|
37940
38498
|
}
|
|
37941
38499
|
}
|
|
37942
|
-
function addEndpoint(rtr, p, obsId, vId,
|
|
38500
|
+
function addEndpoint(rtr, p, obsId, vId, sides2) {
|
|
37943
38501
|
const starti = rtr.obs[obsId];
|
|
37944
38502
|
const endi = rtr.obs[obsId + 1];
|
|
37945
38503
|
const pts = rtr.ps;
|
|
37946
|
-
const [vr, v0, v1] = sideCone(p,
|
|
38504
|
+
const [vr, v0, v1] = sideCone(p, sides2);
|
|
37947
38505
|
rtr.tg.nodes[vId].edges.length = 0;
|
|
37948
38506
|
rtr.tg.nodes[vId].ctr = p;
|
|
37949
38507
|
for (let i = starti; i < endi; i++) {
|
|
37950
38508
|
const seg2 = { i, j: i < endi - 1 ? i + 1 : starti };
|
|
37951
38509
|
const t = findMap(rtr.trimap, seg2.i, seg2.j);
|
|
37952
|
-
if (
|
|
38510
|
+
if (sides2 !== 0 && !inCone(v0, p, v1, pts[seg2.i]) && !inCone(v0, p, v1, pts[seg2.j]) && !raySeg(p, vr, pts[seg2.i], pts[seg2.j])) {
|
|
37953
38511
|
continue;
|
|
37954
38512
|
}
|
|
37955
38513
|
addTriEdge(rtr.tg, vId, t, seg2);
|
|
@@ -38613,7 +39171,7 @@ function boxCornerMargin(j, m) {
|
|
|
38613
39171
|
return { x: m.x, y: -m.y };
|
|
38614
39172
|
}
|
|
38615
39173
|
function polyObstacle(n, poly, pmargin) {
|
|
38616
|
-
const
|
|
39174
|
+
const sides2 = poly.sides;
|
|
38617
39175
|
const stored = poly.vertices;
|
|
38618
39176
|
if (stored == null) return null;
|
|
38619
39177
|
const penwidth = poly.penwidth ?? 1;
|
|
@@ -38623,19 +39181,19 @@ function polyObstacle(n, poly, pmargin) {
|
|
|
38623
39181
|
const storedRings = Math.max(poly.peripheries, 1);
|
|
38624
39182
|
let verts;
|
|
38625
39183
|
if (ringIdx < storedRings) {
|
|
38626
|
-
verts = stored.slice(ringIdx *
|
|
39184
|
+
verts = stored.slice(ringIdx * sides2, (ringIdx + 1) * sides2);
|
|
38627
39185
|
} else {
|
|
38628
|
-
const outer = stored.slice((storedRings - 1) *
|
|
38629
|
-
verts = polygonOutlineRing(outer,
|
|
39186
|
+
const outer = stored.slice((storedRings - 1) * sides2, storedRings * sides2);
|
|
39187
|
+
verts = polygonOutlineRing(outer, sides2, penwidth);
|
|
38630
39188
|
}
|
|
38631
|
-
if (verts.length <
|
|
38632
|
-
const ps = new Array(
|
|
38633
|
-
for (let j = 0; j <
|
|
39189
|
+
if (verts.length < sides2) return null;
|
|
39190
|
+
const ps = new Array(sides2);
|
|
39191
|
+
for (let j = 0; j < sides2; j++) {
|
|
38634
39192
|
const v = verts[j];
|
|
38635
39193
|
if (v === void 0) return null;
|
|
38636
39194
|
let polyp;
|
|
38637
39195
|
if (pmargin.doAdd) {
|
|
38638
|
-
if (
|
|
39196
|
+
if (sides2 === 4) {
|
|
38639
39197
|
const m = boxCornerMargin(j, { x: pmargin.x, y: pmargin.y });
|
|
38640
39198
|
polyp = { x: v.x + m.x, y: v.y + m.y };
|
|
38641
39199
|
} else {
|
|
@@ -38645,22 +39203,22 @@ function polyObstacle(n, poly, pmargin) {
|
|
|
38645
39203
|
} else {
|
|
38646
39204
|
polyp = { x: v.x * pmargin.x, y: v.y * pmargin.y };
|
|
38647
39205
|
}
|
|
38648
|
-
ps[
|
|
39206
|
+
ps[sides2 - j - 1] = { x: polyp.x + n.info.coord.x, y: polyp.y + n.info.coord.y };
|
|
38649
39207
|
}
|
|
38650
39208
|
return { ps };
|
|
38651
39209
|
}
|
|
38652
39210
|
function ellipseObstacle(n, pmargin) {
|
|
38653
|
-
const
|
|
38654
|
-
const
|
|
38655
|
-
const
|
|
39211
|
+
const sides2 = 8;
|
|
39212
|
+
const width2 = (n.info.outline_width ?? 0) > 0 ? n.info.outline_width * 72 : n.info.lw + n.info.rw;
|
|
39213
|
+
const height2 = (n.info.outline_height ?? 0) > 0 ? n.info.outline_height * 72 : n.info.ht;
|
|
38656
39214
|
const mx = pmargin.doAdd ? pmargin.x : 0;
|
|
38657
39215
|
const my = pmargin.doAdd ? pmargin.y : 0;
|
|
38658
|
-
const a = (
|
|
38659
|
-
const b = (
|
|
38660
|
-
const ps = new Array(
|
|
38661
|
-
for (let j = 0; j <
|
|
38662
|
-
const polyp = circumscribedCorner(a, b, j,
|
|
38663
|
-
ps[
|
|
39216
|
+
const a = (width2 + mx) / 2;
|
|
39217
|
+
const b = (height2 + my) / 2;
|
|
39218
|
+
const ps = new Array(sides2);
|
|
39219
|
+
for (let j = 0; j < sides2; j++) {
|
|
39220
|
+
const polyp = circumscribedCorner(a, b, j, sides2);
|
|
39221
|
+
ps[sides2 - j - 1] = { x: polyp.x + n.info.coord.x, y: polyp.y + n.info.coord.y };
|
|
38664
39222
|
}
|
|
38665
39223
|
return { ps };
|
|
38666
39224
|
}
|
|
@@ -38737,10 +39295,10 @@ function makeOrthoObstacle(n, sep) {
|
|
|
38737
39295
|
cy += (bb.ur.y + bb.ll.y) / 2;
|
|
38738
39296
|
cx += 0;
|
|
38739
39297
|
} else {
|
|
38740
|
-
const
|
|
38741
|
-
const outlineW = (info.outline_width ?? 0) > 0 ? info.outline_width * 72 :
|
|
39298
|
+
const width2 = info.lw + info.rw;
|
|
39299
|
+
const outlineW = (info.outline_width ?? 0) > 0 ? info.outline_width * 72 : width2;
|
|
38742
39300
|
const outlineH = (info.outline_height ?? 0) > 0 ? info.outline_height * 72 : info.ht;
|
|
38743
|
-
const outlineLw =
|
|
39301
|
+
const outlineLw = width2 > 0 ? info.lw * outlineW / width2 : outlineW / 2;
|
|
38744
39302
|
lw = outlineLw;
|
|
38745
39303
|
rw = outlineLw;
|
|
38746
39304
|
hh = outlineH / 2;
|
|
@@ -38918,17 +39476,11 @@ var OrthoHelper = class _OrthoHelper {
|
|
|
38918
39476
|
}
|
|
38919
39477
|
static buildEdges(g, nodeArr, orthoNodes) {
|
|
38920
39478
|
const concentrate = g.root.info.concentrate ?? false;
|
|
38921
|
-
const
|
|
39479
|
+
const ps = concentrate ? new PointSet() : null;
|
|
38922
39480
|
const edges = [];
|
|
38923
39481
|
for (const n of nodesInSeq(g)) {
|
|
38924
39482
|
for (const e of n.outEdges(g)) {
|
|
38925
|
-
if (
|
|
38926
|
-
const ti = e.tail.id;
|
|
38927
|
-
const hi = e.head.id;
|
|
38928
|
-
const key = ti <= hi ? `${ti}|${hi}` : `${hi}|${ti}`;
|
|
38929
|
-
if (seen.has(key)) continue;
|
|
38930
|
-
seen.add(key);
|
|
38931
|
-
}
|
|
39483
|
+
if (ps && isConcentrateDup(ps, e)) continue;
|
|
38932
39484
|
const tc = e.tail.info.coord;
|
|
38933
39485
|
const hc = e.head.info.coord;
|
|
38934
39486
|
const tp = e.info.tail_port.p;
|
|
@@ -40984,13 +41536,13 @@ function pointDistance(p1, o1, p2, o2, dim) {
|
|
|
40984
41536
|
}
|
|
40985
41537
|
return Math.sqrt(dist4);
|
|
40986
41538
|
}
|
|
40987
|
-
function quadTreeNew(dim, center,
|
|
41539
|
+
function quadTreeNew(dim, center, width2, maxLevel) {
|
|
40988
41540
|
return {
|
|
40989
41541
|
n: 0,
|
|
40990
41542
|
totalWeight: 0,
|
|
40991
41543
|
dim,
|
|
40992
41544
|
center: center.slice(0, dim),
|
|
40993
|
-
width,
|
|
41545
|
+
width: width2,
|
|
40994
41546
|
average: null,
|
|
40995
41547
|
qts: null,
|
|
40996
41548
|
l: null,
|
|
@@ -41008,15 +41560,15 @@ function getQuadrant(dim, center, coord, off) {
|
|
|
41008
41560
|
}
|
|
41009
41561
|
return d;
|
|
41010
41562
|
}
|
|
41011
|
-
function newInQuadrant(dim, parentCenter,
|
|
41012
|
-
const qt = quadTreeNew(dim, parentCenter,
|
|
41563
|
+
function newInQuadrant(dim, parentCenter, width2, maxLevel, i) {
|
|
41564
|
+
const qt = quadTreeNew(dim, parentCenter, width2, maxLevel);
|
|
41013
41565
|
const center = qt.center;
|
|
41014
41566
|
let ii = i;
|
|
41015
41567
|
for (let k = 0; k < dim; k++) {
|
|
41016
41568
|
if (ii % 2 === 0) {
|
|
41017
|
-
center[k] -=
|
|
41569
|
+
center[k] -= width2;
|
|
41018
41570
|
} else {
|
|
41019
|
-
center[k] +=
|
|
41571
|
+
center[k] += width2;
|
|
41020
41572
|
}
|
|
41021
41573
|
ii = (ii - ii % 2) / 2;
|
|
41022
41574
|
}
|
|
@@ -41087,14 +41639,14 @@ function quadTreeNewFromPointList(dim, n, maxLevel, coord) {
|
|
|
41087
41639
|
xmax[k] = Math.max(xmax[k], coord[i * dim + k]);
|
|
41088
41640
|
}
|
|
41089
41641
|
}
|
|
41090
|
-
let
|
|
41642
|
+
let width2 = xmax[0] - xmin[0];
|
|
41091
41643
|
for (let i = 0; i < dim; i++) {
|
|
41092
41644
|
center[i] = (xmin[i] + xmax[i]) * 0.5;
|
|
41093
|
-
|
|
41645
|
+
width2 = Math.max(width2, xmax[i] - xmin[i]);
|
|
41094
41646
|
}
|
|
41095
|
-
|
|
41096
|
-
|
|
41097
|
-
const qt = quadTreeNew(dim, center,
|
|
41647
|
+
width2 = Math.max(width2, 1e-5);
|
|
41648
|
+
width2 *= 0.52;
|
|
41649
|
+
const qt = quadTreeNew(dim, center, width2, maxLevel);
|
|
41098
41650
|
for (let i = 0; i < n; i++) {
|
|
41099
41651
|
quadTreeAdd(qt, coord, i * dim, 1, i);
|
|
41100
41652
|
}
|
|
@@ -41914,18 +42466,18 @@ function compScanPoints(p, q) {
|
|
|
41914
42466
|
if (pp.node < qq.node) return -1;
|
|
41915
42467
|
return 0;
|
|
41916
42468
|
}
|
|
41917
|
-
function getOverlapGraph(dim, n, x,
|
|
42469
|
+
function getOverlapGraph(dim, n, x, width2, checkOverlapOnly) {
|
|
41918
42470
|
let A3 = smNew(n, n, MATRIX_TYPE_REAL, FORMAT_COORD);
|
|
41919
42471
|
const scanpointsx = new Array(2 * n);
|
|
41920
42472
|
for (let i = 0; i < n; i++) {
|
|
41921
|
-
scanpointsx[2 * i] = { node: i, x: x[i * dim] -
|
|
41922
|
-
scanpointsx[2 * i + 1] = { node: i + n, x: x[i * dim] +
|
|
42473
|
+
scanpointsx[2 * i] = { node: i, x: x[i * dim] - width2[i * dim], status: INTV_OPEN };
|
|
42474
|
+
scanpointsx[2 * i + 1] = { node: i + n, x: x[i * dim] + width2[i * dim], status: INTV_CLOSE };
|
|
41923
42475
|
}
|
|
41924
42476
|
scanpointsx.sort(compScanPoints);
|
|
41925
42477
|
const scanpointsy = new Array(2 * n);
|
|
41926
42478
|
for (let i = 0; i < n; i++) {
|
|
41927
|
-
scanpointsy[i] = { node: i, x: x[i * dim + 1] -
|
|
41928
|
-
scanpointsy[i + n] = { node: i, x: x[i * dim + 1] +
|
|
42479
|
+
scanpointsy[i] = { node: i, x: x[i * dim + 1] - width2[i * dim + 1], status: INTV_OPEN };
|
|
42480
|
+
scanpointsy[i + n] = { node: i, x: x[i * dim + 1] + width2[i * dim + 1], status: INTV_CLOSE };
|
|
41929
42481
|
}
|
|
41930
42482
|
const treey = rbTreeCreate(compScanPoints, () => void 0);
|
|
41931
42483
|
outer:
|
|
@@ -41958,7 +42510,7 @@ function getOverlapGraph(dim, n, x, width, checkOverlapOnly) {
|
|
|
41958
42510
|
A3 = smSymmetrize(B2, false);
|
|
41959
42511
|
return A3;
|
|
41960
42512
|
}
|
|
41961
|
-
function idealDistanceAvoidOverlap(dim, A3, x,
|
|
42513
|
+
function idealDistanceAvoidOverlap(dim, A3, x, width2, idealDistance) {
|
|
41962
42514
|
const ia = A3.ia;
|
|
41963
42515
|
const ja = A3.ja;
|
|
41964
42516
|
const expandmax = 1.5;
|
|
@@ -41972,8 +42524,8 @@ function idealDistanceAvoidOverlap(dim, A3, x, width, idealDistance) {
|
|
|
41972
42524
|
const dist4 = distance(x, dim, i, jj);
|
|
41973
42525
|
const dx = Math.abs(x[i * dim] - x[jj * dim]);
|
|
41974
42526
|
const dy = Math.abs(x[i * dim + 1] - x[jj * dim + 1]);
|
|
41975
|
-
const wx =
|
|
41976
|
-
const wy =
|
|
42527
|
+
const wx = width2[i * dim] + width2[jj * dim];
|
|
42528
|
+
const wy = width2[i * dim + 1] + width2[jj * dim + 1];
|
|
41977
42529
|
if (dx < MACHINEACC * wx && dy < MACHINEACC * wy) {
|
|
41978
42530
|
idealDistance[j] = Math.hypot(wx, wy);
|
|
41979
42531
|
tmax = 2;
|
|
@@ -42004,7 +42556,7 @@ function idealDistanceAvoidOverlap(dim, A3, x, width, idealDistance) {
|
|
|
42004
42556
|
function scaleCoord(dim, m, x, scale) {
|
|
42005
42557
|
for (let i = 0; i < dim * m; i++) x[i] *= scale;
|
|
42006
42558
|
}
|
|
42007
|
-
function overlapScaling(dim, m, x,
|
|
42559
|
+
function overlapScaling(dim, m, x, width2, scaleStaIn, scaleStoIn, epsilon, maxiter) {
|
|
42008
42560
|
let scaleSta = scaleStaIn;
|
|
42009
42561
|
let scaleSto = scaleStoIn;
|
|
42010
42562
|
let iter = 0;
|
|
@@ -42012,7 +42564,7 @@ function overlapScaling(dim, m, x, width, scaleStaIn, scaleStoIn, epsilon, maxit
|
|
|
42012
42564
|
scaleSta = 0;
|
|
42013
42565
|
} else {
|
|
42014
42566
|
scaleCoord(dim, m, x, scaleSta);
|
|
42015
|
-
const C6 = getOverlapGraph(dim, m, x,
|
|
42567
|
+
const C6 = getOverlapGraph(dim, m, x, width2, true);
|
|
42016
42568
|
if (C6.nz === 0) return;
|
|
42017
42569
|
scaleCoord(dim, m, x, 1 / scaleSta);
|
|
42018
42570
|
}
|
|
@@ -42027,7 +42579,7 @@ function overlapScaling(dim, m, x, width, scaleStaIn, scaleStoIn, epsilon, maxit
|
|
|
42027
42579
|
do {
|
|
42028
42580
|
scaleSto *= 2;
|
|
42029
42581
|
scaleCoord(dim, m, x, 2);
|
|
42030
|
-
const C6 = getOverlapGraph(dim, m, x,
|
|
42582
|
+
const C6 = getOverlapGraph(dim, m, x, width2, true);
|
|
42031
42583
|
overlap5 = C6.nz > 0;
|
|
42032
42584
|
} while (overlap5);
|
|
42033
42585
|
scaleCoord(dim, m, x, 1 / scaleSto);
|
|
@@ -42036,7 +42588,7 @@ function overlapScaling(dim, m, x, width, scaleStaIn, scaleStoIn, epsilon, maxit
|
|
|
42036
42588
|
while (iter++ < maxiter && scaleSto - scaleSta > epsilon) {
|
|
42037
42589
|
const scale = 0.5 * (scaleSta + scaleSto);
|
|
42038
42590
|
scaleCoord(dim, m, x, scale);
|
|
42039
|
-
const C6 = getOverlapGraph(dim, m, x,
|
|
42591
|
+
const C6 = getOverlapGraph(dim, m, x, width2, true);
|
|
42040
42592
|
scaleCoord(dim, m, x, 1 / scale);
|
|
42041
42593
|
const overlap5 = C6.nz > 0;
|
|
42042
42594
|
if (overlap5) {
|
|
@@ -42047,7 +42599,7 @@ function overlapScaling(dim, m, x, width, scaleStaIn, scaleStoIn, epsilon, maxit
|
|
|
42047
42599
|
}
|
|
42048
42600
|
scaleCoord(dim, m, x, scaleBest);
|
|
42049
42601
|
}
|
|
42050
|
-
function overlapSmootherNew(m, dim, x,
|
|
42602
|
+
function overlapSmootherNew(m, dim, x, width2, neighborhoodOnly, shrink) {
|
|
42051
42603
|
const sm = {
|
|
42052
42604
|
Lw: null,
|
|
42053
42605
|
Lwd: null,
|
|
@@ -42057,16 +42609,16 @@ function overlapSmootherNew(m, dim, x, width, neighborhoodOnly, shrink) {
|
|
|
42057
42609
|
};
|
|
42058
42610
|
let B2 = callTri(m, x);
|
|
42059
42611
|
if (!neighborhoodOnly) {
|
|
42060
|
-
const C6 = getOverlapGraph(dim, m, x,
|
|
42612
|
+
const C6 = getOverlapGraph(dim, m, x, width2, false);
|
|
42061
42613
|
B2 = smAdd(B2, C6);
|
|
42062
42614
|
}
|
|
42063
42615
|
sm.Lw = B2;
|
|
42064
42616
|
sm.Lwd = smCopy(sm.Lw);
|
|
42065
|
-
const { tmax, tmin } = idealDistanceAvoidOverlap(dim, sm.Lwd, x,
|
|
42617
|
+
const { tmax, tmin } = idealDistanceAvoidOverlap(dim, sm.Lwd, x, width2, sm.Lwd.a);
|
|
42066
42618
|
if (tmax < 1 && shrink) {
|
|
42067
42619
|
const scaleSta = Math.min(1, tmax * 1.0001);
|
|
42068
42620
|
const scaleSto = 1;
|
|
42069
|
-
overlapScaling(dim, m, x,
|
|
42621
|
+
overlapScaling(dim, m, x, width2, scaleSta, scaleSto, 1e-4, 15);
|
|
42070
42622
|
return { sm, maxOverlap: 1, minOverlap: tmin };
|
|
42071
42623
|
}
|
|
42072
42624
|
const iw = sm.Lw.ia;
|
|
@@ -42340,7 +42892,7 @@ function scAdjust(g, equal) {
|
|
|
42340
42892
|
// src/layout/neato/simple-scale.ts
|
|
42341
42893
|
var ISZERO = (d) => Math.abs(d) < 1e-9;
|
|
42342
42894
|
var LF = /^\s*([+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?)/;
|
|
42343
|
-
function
|
|
42895
|
+
function scanPair2(p) {
|
|
42344
42896
|
const m1 = LF.exec(p);
|
|
42345
42897
|
if (m1 === null) return [];
|
|
42346
42898
|
const rest = p.slice(m1[0].length);
|
|
@@ -42351,7 +42903,7 @@ function scanPair(p) {
|
|
|
42351
42903
|
function simpleScale(g) {
|
|
42352
42904
|
const p = aggetGraph(g, "scale");
|
|
42353
42905
|
if (p === void 0) return 0;
|
|
42354
|
-
const sc =
|
|
42906
|
+
const sc = scanPair2(p);
|
|
42355
42907
|
if (sc.length === 0) return 0;
|
|
42356
42908
|
const x = sc[0];
|
|
42357
42909
|
if (ISZERO(x)) return 0;
|
|
@@ -42675,16 +43227,16 @@ function overlaps(p) {
|
|
|
42675
43227
|
function initItem(n, margin) {
|
|
42676
43228
|
const x = cround(SCALE * (n.info.pos?.[0] ?? 0) * POINTS_PER_INCH6);
|
|
42677
43229
|
const y = cround(SCALE * (n.info.pos?.[1] ?? 0) * POINTS_PER_INCH6);
|
|
42678
|
-
const
|
|
42679
|
-
const
|
|
43230
|
+
const width2 = n.info.width ?? 0;
|
|
43231
|
+
const height2 = n.info.height ?? 0;
|
|
42680
43232
|
let w2;
|
|
42681
43233
|
let h2;
|
|
42682
43234
|
if (margin.doAdd) {
|
|
42683
|
-
w2 = d2i(SCALE * (cround(
|
|
42684
|
-
h2 = d2i(SCALE * (cround(
|
|
43235
|
+
w2 = d2i(SCALE * (cround(width2 / 2 * POINTS_PER_INCH6) + margin.x));
|
|
43236
|
+
h2 = d2i(SCALE * (cround(height2 / 2 * POINTS_PER_INCH6) + margin.y));
|
|
42685
43237
|
} else {
|
|
42686
|
-
w2 = cround(margin.x * SCALE2 *
|
|
42687
|
-
h2 = cround(margin.y * SCALE2 *
|
|
43238
|
+
w2 = cround(margin.x * SCALE2 * width2 * POINTS_PER_INCH6);
|
|
43239
|
+
h2 = cround(margin.y * SCALE2 * height2 * POINTS_PER_INCH6);
|
|
42688
43240
|
}
|
|
42689
43241
|
return {
|
|
42690
43242
|
val: 0,
|
|
@@ -42786,12 +43338,12 @@ function atoi2(s) {
|
|
|
42786
43338
|
}
|
|
42787
43339
|
function genRound(n, xm, ym) {
|
|
42788
43340
|
const isides = atoi2(n.attrs.get("samplepoints"));
|
|
42789
|
-
const
|
|
43341
|
+
const sides2 = isides < MIN_SAMPLES ? DFLT_SAMPLE2 : isides;
|
|
42790
43342
|
const verts = [];
|
|
42791
|
-
for (let i = 0; i <
|
|
43343
|
+
for (let i = 0; i < sides2; i++) {
|
|
42792
43344
|
verts.push({
|
|
42793
|
-
x: (n.info.width / 2 + xm) * Math.cos(i /
|
|
42794
|
-
y: (n.info.height / 2 + ym) * Math.sin(i /
|
|
43345
|
+
x: (n.info.width / 2 + xm) * Math.cos(i / sides2 * Math.PI * 2),
|
|
43346
|
+
y: (n.info.height / 2 + ym) * Math.sin(i / sides2 * Math.PI * 2)
|
|
42795
43347
|
});
|
|
42796
43348
|
}
|
|
42797
43349
|
return verts;
|
|
@@ -45209,30 +45761,30 @@ function boundaryFromBB(bb) {
|
|
|
45209
45761
|
x: (bb.llx + bb.urx) / 2,
|
|
45210
45762
|
y: (bb.lly + bb.ury) / 2
|
|
45211
45763
|
};
|
|
45212
|
-
const
|
|
45213
|
-
const
|
|
45214
|
-
sizeBoundary(
|
|
45764
|
+
const width2 = EXPFACTOR * (bb.urx - bb.llx);
|
|
45765
|
+
const height2 = EXPFACTOR * (bb.ury - bb.lly);
|
|
45766
|
+
sizeBoundary(width2, height2);
|
|
45215
45767
|
const alpha = Math.atan2(parms.Ht, parms.Wd);
|
|
45216
45768
|
parms.Wd = parms.Wd / Math.cos(alpha);
|
|
45217
45769
|
parms.Ht = parms.Ht / Math.sin(alpha);
|
|
45218
45770
|
return ctr;
|
|
45219
45771
|
}
|
|
45220
|
-
function sizeBoundary(
|
|
45772
|
+
function sizeBoundary(width2, height2) {
|
|
45221
45773
|
const area = 4 * parms.Wd * parms.Ht;
|
|
45222
|
-
let quot =
|
|
45774
|
+
let quot = width2 * height2 / area;
|
|
45223
45775
|
if (quot >= 1) {
|
|
45224
|
-
parms.Wd =
|
|
45225
|
-
parms.Ht =
|
|
45776
|
+
parms.Wd = width2 / 2;
|
|
45777
|
+
parms.Ht = height2 / 2;
|
|
45226
45778
|
} else if (quot > 0) {
|
|
45227
45779
|
quot = 2 * Math.sqrt(quot);
|
|
45228
|
-
parms.Wd =
|
|
45229
|
-
parms.Ht =
|
|
45230
|
-
} else if (
|
|
45231
|
-
parms.Wd =
|
|
45232
|
-
parms.Ht = area /
|
|
45233
|
-
} else if (
|
|
45234
|
-
parms.Wd = area /
|
|
45235
|
-
parms.Ht =
|
|
45780
|
+
parms.Wd = width2 / quot;
|
|
45781
|
+
parms.Ht = height2 / quot;
|
|
45782
|
+
} else if (width2 > 0) {
|
|
45783
|
+
parms.Wd = width2 / 2;
|
|
45784
|
+
parms.Ht = area / width2 / 2;
|
|
45785
|
+
} else if (height2 > 0) {
|
|
45786
|
+
parms.Wd = area / height2 / 2;
|
|
45787
|
+
parms.Ht = height2 / 2;
|
|
45236
45788
|
}
|
|
45237
45789
|
}
|
|
45238
45790
|
function placeWithPorts(g, pp, ctr) {
|
|
@@ -46155,7 +46707,7 @@ function finalCC(g, cc, pts, rg, infop) {
|
|
|
46155
46707
|
};
|
|
46156
46708
|
}
|
|
46157
46709
|
function applyMarginAndBorder(rg, bb, margin) {
|
|
46158
|
-
const
|
|
46710
|
+
const border2 = rg.info.border ?? [
|
|
46159
46711
|
{ x: 0, y: 0 },
|
|
46160
46712
|
{ x: 0, y: 0 },
|
|
46161
46713
|
{ x: 0, y: 0 },
|
|
@@ -46163,12 +46715,12 @@ function applyMarginAndBorder(rg, bb, margin) {
|
|
|
46163
46715
|
];
|
|
46164
46716
|
const pt = {
|
|
46165
46717
|
x: -bb.ll.x + margin,
|
|
46166
|
-
y: -bb.ll.y + margin +
|
|
46718
|
+
y: -bb.ll.y + margin + border2[BOTTOM_IX].y
|
|
46167
46719
|
};
|
|
46168
46720
|
bb.ll.x = 0;
|
|
46169
46721
|
bb.ll.y = 0;
|
|
46170
46722
|
bb.ur.x += pt.x + margin;
|
|
46171
|
-
bb.ur.y += pt.y + margin +
|
|
46723
|
+
bb.ur.y += pt.y + margin + border2[TOP_IX].y;
|
|
46172
46724
|
return pt;
|
|
46173
46725
|
}
|
|
46174
46726
|
function evalPositions(g, rootg) {
|
|
@@ -48076,9 +48628,9 @@ function applyLabelExpansion(g, total, rbb) {
|
|
|
48076
48628
|
}
|
|
48077
48629
|
function addMarginAndBorder(g, margin, rbb) {
|
|
48078
48630
|
let { llx, lly, urx, ury } = rbb;
|
|
48079
|
-
const
|
|
48080
|
-
const bottomY =
|
|
48081
|
-
const topY =
|
|
48631
|
+
const border2 = g.info.border;
|
|
48632
|
+
const bottomY = border2 ? border2[BOTTOM_IX].y : 0;
|
|
48633
|
+
const topY = border2 ? border2[TOP_IX].y : 0;
|
|
48082
48634
|
llx -= margin;
|
|
48083
48635
|
urx += margin;
|
|
48084
48636
|
lly -= margin + bottomY;
|
|
@@ -48649,18 +49201,9 @@ function approxLen(list, off) {
|
|
|
48649
49201
|
return dist3(list[off], list[off + 1]) + dist3(list[off + 1], list[off + 2]) + dist3(list[off + 2], list[off + 3]);
|
|
48650
49202
|
}
|
|
48651
49203
|
function splitCubic(v, t) {
|
|
48652
|
-
const
|
|
48653
|
-
const
|
|
48654
|
-
|
|
48655
|
-
const right2 = new Array(4);
|
|
48656
|
-
right2[3] = row[3];
|
|
48657
|
-
for (let i = 1; i <= 3; i++) {
|
|
48658
|
-
for (let j = 0; j <= 3 - i; j++) {
|
|
48659
|
-
row[j] = { x: u * row[j].x + t * row[j + 1].x, y: u * row[j].y + t * row[j + 1].y };
|
|
48660
|
-
}
|
|
48661
|
-
left2.push(row[0]);
|
|
48662
|
-
right2[3 - i] = row[3 - i];
|
|
48663
|
-
}
|
|
49204
|
+
const left2 = [];
|
|
49205
|
+
const right2 = [];
|
|
49206
|
+
bezier(v, t, left2, right2);
|
|
48664
49207
|
return { left: left2, right: right2 };
|
|
48665
49208
|
}
|
|
48666
49209
|
function splitBSpline(list, t) {
|
|
@@ -48780,17 +49323,6 @@ function mymod(original, modulus) {
|
|
|
48780
49323
|
function l2dist(p0, p1) {
|
|
48781
49324
|
return Math.hypot(p0.x - p1.x, p0.y - p1.y);
|
|
48782
49325
|
}
|
|
48783
|
-
function bezierPoint(v, t) {
|
|
48784
|
-
const vx = [v[0].x, v[1].x, v[2].x, v[3].x];
|
|
48785
|
-
const vy = [v[0].y, v[1].y, v[2].y, v[3].y];
|
|
48786
|
-
for (let i = 1; i <= 3; i++) {
|
|
48787
|
-
for (let j = 0; j <= 3 - i; j++) {
|
|
48788
|
-
vx[j] = (1 - t) * vx[j] + t * vx[j + 1];
|
|
48789
|
-
vy[j] = (1 - t) * vy[j] + t * vy[j + 1];
|
|
48790
|
-
}
|
|
48791
|
-
}
|
|
48792
|
-
return { x: vx[0], y: vy[0] };
|
|
48793
|
-
}
|
|
48794
49326
|
function pathtolines(bez) {
|
|
48795
49327
|
const arr = [];
|
|
48796
49328
|
const A3 = bez.list;
|
|
@@ -48806,7 +49338,7 @@ function pathtolines(bez) {
|
|
|
48806
49338
|
for (let j = 1; j <= 3; j++) V[j] = A3[i + j];
|
|
48807
49339
|
let p0 = V[0];
|
|
48808
49340
|
for (let step = 1; step <= BEZIER_SUBDIVISION; step++) {
|
|
48809
|
-
const p1 =
|
|
49341
|
+
const p1 = bezier(V, step / BEZIER_SUBDIVISION, null, null);
|
|
48810
49342
|
linelen += l2dist(p0, p1);
|
|
48811
49343
|
push(p1, linelen);
|
|
48812
49344
|
p0 = p1;
|
|
@@ -49031,9 +49563,9 @@ function agstrcanonText(arg) {
|
|
|
49031
49563
|
if (needsQuotes || cnt === 1 && (first === 46 || first === 45)) {
|
|
49032
49564
|
return new TextDecoder().decode(new Uint8Array(out));
|
|
49033
49565
|
}
|
|
49034
|
-
const
|
|
49566
|
+
const lower2 = arg.toLowerCase();
|
|
49035
49567
|
for (const tok of CANON_KEYWORDS) {
|
|
49036
|
-
if (tok ===
|
|
49568
|
+
if (tok === lower2) return new TextDecoder().decode(new Uint8Array(out));
|
|
49037
49569
|
}
|
|
49038
49570
|
return arg;
|
|
49039
49571
|
}
|
|
@@ -49117,9 +49649,9 @@ function writePlainEdge(e, extend, out) {
|
|
|
49117
49649
|
if (lbl !== void 0) {
|
|
49118
49650
|
out.push(" " + agstrcanonText(lbl.text) + " " + plainCoord(lbl.pos.x) + " " + plainCoord(lbl.pos.y));
|
|
49119
49651
|
}
|
|
49120
|
-
const
|
|
49652
|
+
const style2 = lateNN(e.attrs.get("style"), "solid");
|
|
49121
49653
|
const color = lateNN(e.attrs.get("color"), "black");
|
|
49122
|
-
out.push(" " +
|
|
49654
|
+
out.push(" " + style2 + " " + color + "\n");
|
|
49123
49655
|
}
|
|
49124
49656
|
function writePlain(g, job, extend) {
|
|
49125
49657
|
const w = plainCoord(g.info.bb.ur.x);
|
|
@@ -50686,9 +51218,9 @@ function createXdotRenderer() {
|
|
|
50686
51218
|
|
|
50687
51219
|
// src/render/svg-tapered-edge.ts
|
|
50688
51220
|
function edgeIsTapered(e) {
|
|
50689
|
-
const
|
|
50690
|
-
if (
|
|
50691
|
-
return
|
|
51221
|
+
const style2 = e.attrs.get("style");
|
|
51222
|
+
if (style2 === void 0 || style2 === "") return false;
|
|
51223
|
+
return style2.split(",").some((t) => t.trim() === "tapered");
|
|
50692
51224
|
}
|
|
50693
51225
|
function svgTaperedEdge(e, job) {
|
|
50694
51226
|
const spl = e.info.spl;
|
|
@@ -50903,16 +51435,16 @@ var SvgRenderer = class {
|
|
|
50903
51435
|
*/
|
|
50904
51436
|
usershape(src, b, job) {
|
|
50905
51437
|
const g = (n) => String(parseFloat(n.toPrecision(6)));
|
|
50906
|
-
const
|
|
50907
|
-
const
|
|
50908
|
-
const originx = (b.ur.x + b.ll.x -
|
|
50909
|
-
const originy = (b.ur.y + b.ll.y +
|
|
51438
|
+
const width2 = b.ur.x - b.ll.x;
|
|
51439
|
+
const height2 = b.ur.y - b.ll.y;
|
|
51440
|
+
const originx = (b.ur.x + b.ll.x - width2) / 2;
|
|
51441
|
+
const originy = (b.ur.y + b.ll.y + height2) / 2;
|
|
50910
51442
|
let href = src;
|
|
50911
51443
|
if (job.inlineImages === true) {
|
|
50912
51444
|
const found = findImageBytes(src, job.imageResolver);
|
|
50913
51445
|
if (found !== null) href = toDataUri(found.bytes, found.mime);
|
|
50914
51446
|
}
|
|
50915
|
-
job.write('<image xlink:href="' + escapeXml(href) + '" width="' + g(
|
|
51447
|
+
job.write('<image xlink:href="' + escapeXml(href) + '" width="' + g(width2) + 'px" height="' + g(height2) + 'px" preserveAspectRatio="xMinYMin meet" x="' + g(originx) + '" y="' + g(-originy) + '"/>\n');
|
|
50916
51448
|
}
|
|
50917
51449
|
comment(text, job) {
|
|
50918
51450
|
svgComment(text, job);
|
|
@@ -54712,6 +55244,179 @@ function numberAmbiguityMessage(a) {
|
|
|
54712
55244
|
return `Warning: syntax ambiguity - badly delimited number '${a.text}' in line ${a.line} of input splits into two tokens`;
|
|
54713
55245
|
}
|
|
54714
55246
|
|
|
55247
|
+
// src/parser/scan-token.ts
|
|
55248
|
+
var YY_BUF_SIZE = 16384;
|
|
55249
|
+
var STRING_STARTING_BYTES = 80;
|
|
55250
|
+
var ASCII_DEL2 = 127;
|
|
55251
|
+
function isLetter2(c) {
|
|
55252
|
+
if (c === void 0) return false;
|
|
55253
|
+
return c >= "A" && c <= "Z" || c >= "a" && c <= "z" || c === "_" || c.charCodeAt(0) > ASCII_DEL2;
|
|
55254
|
+
}
|
|
55255
|
+
function isDigit2(c) {
|
|
55256
|
+
return c !== void 0 && c >= "0" && c <= "9";
|
|
55257
|
+
}
|
|
55258
|
+
function startsNumber2(s, i) {
|
|
55259
|
+
const c = s[i];
|
|
55260
|
+
if (isDigit2(c)) return true;
|
|
55261
|
+
if (c === ".") return isDigit2(s[i + 1]);
|
|
55262
|
+
if (c !== "-") return false;
|
|
55263
|
+
return isDigit2(s[i + 1]) || s[i + 1] === "." && isDigit2(s[i + 2]);
|
|
55264
|
+
}
|
|
55265
|
+
function matchNumber2(s, i) {
|
|
55266
|
+
let j = s[i] === "-" ? i + 1 : i;
|
|
55267
|
+
if (s[j] === ".") {
|
|
55268
|
+
j++;
|
|
55269
|
+
while (isDigit2(s[j])) j++;
|
|
55270
|
+
} else {
|
|
55271
|
+
while (isDigit2(s[j])) j++;
|
|
55272
|
+
if (s[j] === ".") {
|
|
55273
|
+
j++;
|
|
55274
|
+
while (isDigit2(s[j])) j++;
|
|
55275
|
+
}
|
|
55276
|
+
}
|
|
55277
|
+
if (s[j] === "." || isLetter2(s[j])) j++;
|
|
55278
|
+
return j;
|
|
55279
|
+
}
|
|
55280
|
+
function badlyDelimited(text) {
|
|
55281
|
+
const c = text[text.length - 1];
|
|
55282
|
+
const dot = text.indexOf(".");
|
|
55283
|
+
return !isDigit2(c) && c !== "." || c === "." && dot !== text.length - 1;
|
|
55284
|
+
}
|
|
55285
|
+
function lineEnd(s, i) {
|
|
55286
|
+
const nl = s.indexOf("\n", i);
|
|
55287
|
+
return nl === -1 ? s.length : nl;
|
|
55288
|
+
}
|
|
55289
|
+
function directiveLine(text) {
|
|
55290
|
+
const rest = text.slice(1).replace(/^line/, "");
|
|
55291
|
+
const m = /^\s*([+-]?\d+)/.exec(rest);
|
|
55292
|
+
if (m === null) return void 0;
|
|
55293
|
+
const lineno = Number.parseInt(m[1], 10);
|
|
55294
|
+
return lineno <= 0 ? void 0 : lineno - 1;
|
|
55295
|
+
}
|
|
55296
|
+
function qstringBuffer(body) {
|
|
55297
|
+
return body.replace(/\\\\|\\"|\\\n/g, (m) => m === '\\"' ? '"' : m === "\\\n" ? "" : m);
|
|
55298
|
+
}
|
|
55299
|
+
function lexQuoted(s, i) {
|
|
55300
|
+
for (let j = i + 1; j < s.length; j++) {
|
|
55301
|
+
if (s[j] === "\\" && j + 1 < s.length) j++;
|
|
55302
|
+
else if (s[j] === '"') return { kind: "token", end: j + 1, text: '"' };
|
|
55303
|
+
}
|
|
55304
|
+
return { kind: "open", state: "qstring", buffer: qstringBuffer(s.slice(i + 1)) };
|
|
55305
|
+
}
|
|
55306
|
+
function lexHtml(s, i) {
|
|
55307
|
+
let nest = 1;
|
|
55308
|
+
for (let j = i + 1; j < s.length; j++) {
|
|
55309
|
+
if (s[j] === "<") nest++;
|
|
55310
|
+
else if (s[j] === ">" && --nest === 0) return { kind: "token", end: j + 1, text: ">" };
|
|
55311
|
+
}
|
|
55312
|
+
return { kind: "open", state: "hstring", buffer: s.slice(i + 1) };
|
|
55313
|
+
}
|
|
55314
|
+
function lexComment(s, i) {
|
|
55315
|
+
const close = s.indexOf("*/", i + 2);
|
|
55316
|
+
if (close === -1) return { kind: "open", state: "comment", buffer: "" };
|
|
55317
|
+
return { kind: "skip", end: close + 2 };
|
|
55318
|
+
}
|
|
55319
|
+
function lexHash(s, i) {
|
|
55320
|
+
const end = lineEnd(s, i);
|
|
55321
|
+
const atLineStart = i === 0 || s[i - 1] === "\n";
|
|
55322
|
+
const line = atLineStart ? directiveLine(s.slice(i, end)) : void 0;
|
|
55323
|
+
return line === void 0 ? { kind: "skip", end } : { kind: "skip", end, line };
|
|
55324
|
+
}
|
|
55325
|
+
function lexAtom(s, i) {
|
|
55326
|
+
if (isLetter2(s[i])) {
|
|
55327
|
+
let j2 = i + 1;
|
|
55328
|
+
while (isLetter2(s[j2]) || isDigit2(s[j2])) j2++;
|
|
55329
|
+
const text = s.slice(i, j2);
|
|
55330
|
+
return text === "\uFEFF" ? { kind: "skip", end: j2 } : { kind: "token", end: j2, text };
|
|
55331
|
+
}
|
|
55332
|
+
if (s[i] === "-" && (s[i + 1] === "-" || s[i + 1] === ">")) {
|
|
55333
|
+
return { kind: "token", end: i + 2, text: s.slice(i, i + 2) };
|
|
55334
|
+
}
|
|
55335
|
+
if (!startsNumber2(s, i)) return { kind: "token", end: i + 1, text: s[i] };
|
|
55336
|
+
const j = matchNumber2(s, i);
|
|
55337
|
+
const end = badlyDelimited(s.slice(i, j)) ? j - 1 : j;
|
|
55338
|
+
return { kind: "token", end, text: s.slice(i, end) };
|
|
55339
|
+
}
|
|
55340
|
+
function lexTrivia(s, i) {
|
|
55341
|
+
const c = s[i];
|
|
55342
|
+
if (c === "\n" || c === " " || c === " " || c === "\r") return { kind: "skip", end: i + 1 };
|
|
55343
|
+
if (c === "#") return lexHash(s, i);
|
|
55344
|
+
if (c !== "/") return void 0;
|
|
55345
|
+
if (s[i + 1] === "*") return lexComment(s, i);
|
|
55346
|
+
if (s[i + 1] === "/") return { kind: "skip", end: lineEnd(s, i) };
|
|
55347
|
+
return void 0;
|
|
55348
|
+
}
|
|
55349
|
+
function lexStep(s, i) {
|
|
55350
|
+
const trivia = lexTrivia(s, i);
|
|
55351
|
+
if (trivia !== void 0) return trivia;
|
|
55352
|
+
if (s[i] === '"') return lexQuoted(s, i);
|
|
55353
|
+
if (s[i] === "<") return lexHtml(s, i);
|
|
55354
|
+
return lexAtom(s, i);
|
|
55355
|
+
}
|
|
55356
|
+
function countNewlines(s, from, to) {
|
|
55357
|
+
let n = 0;
|
|
55358
|
+
for (let i = s.indexOf("\n", from); i !== -1 && i < to; i = s.indexOf("\n", i + 1)) n++;
|
|
55359
|
+
return n;
|
|
55360
|
+
}
|
|
55361
|
+
var HEADER_KEYWORDS = ["strict", "graph", "digraph"];
|
|
55362
|
+
function isTruncatedHeaderKeyword(src, step, offset, seen) {
|
|
55363
|
+
if (offset !== src.length || step.end !== offset || seen.length > 1) return false;
|
|
55364
|
+
if (seen.length === 1 && seen[0].toLowerCase() !== "strict") return false;
|
|
55365
|
+
const word = step.text.toLowerCase();
|
|
55366
|
+
return HEADER_KEYWORDS.some((k) => k.length > word.length && k.startsWith(word));
|
|
55367
|
+
}
|
|
55368
|
+
function reachesOffset(src, step, offset, seen) {
|
|
55369
|
+
if (step.end > offset) return true;
|
|
55370
|
+
if (isTruncatedHeaderKeyword(src, step, offset, seen)) return true;
|
|
55371
|
+
if (step.text !== "-" && step.text !== ".") return false;
|
|
55372
|
+
return offset <= step.end + (step.text === "-" && src[step.end] === "." ? 1 : 0);
|
|
55373
|
+
}
|
|
55374
|
+
function scanAtError(src, offset) {
|
|
55375
|
+
let line = 1;
|
|
55376
|
+
let i = 0;
|
|
55377
|
+
const seen = [];
|
|
55378
|
+
while (i < src.length) {
|
|
55379
|
+
const step = lexStep(src, i);
|
|
55380
|
+
if (step.kind === "open") {
|
|
55381
|
+
line += countNewlines(src, i, src.length);
|
|
55382
|
+
return { state: step.state, text: "", line, buffer: step.buffer };
|
|
55383
|
+
}
|
|
55384
|
+
if (step.kind === "skip" && step.line !== void 0) line = step.line;
|
|
55385
|
+
line += countNewlines(src, i, step.end);
|
|
55386
|
+
if (step.kind === "token" && reachesOffset(src, step, offset, seen)) {
|
|
55387
|
+
return { state: "INITIAL", text: step.text, line, buffer: "" };
|
|
55388
|
+
}
|
|
55389
|
+
if (step.kind === "token") seen.push(step.text);
|
|
55390
|
+
i = step.end;
|
|
55391
|
+
}
|
|
55392
|
+
return { state: "INITIAL", text: "", line, buffer: "" };
|
|
55393
|
+
}
|
|
55394
|
+
function firstBytes(s) {
|
|
55395
|
+
const bytes = new TextEncoder().encode(s);
|
|
55396
|
+
if (bytes.length <= STRING_STARTING_BYTES) return s;
|
|
55397
|
+
return new TextDecoder().decode(bytes.subarray(0, STRING_STARTING_BYTES));
|
|
55398
|
+
}
|
|
55399
|
+
function stateNote(at) {
|
|
55400
|
+
const start = at.buffer.length > 0 ? firstBytes(at.buffer) : "";
|
|
55401
|
+
switch (at.state) {
|
|
55402
|
+
case "qstring":
|
|
55403
|
+
return ` scanning a quoted string (missing endquote? longer than ${YY_BUF_SIZE}?)` + (start === "" ? "" : `
|
|
55404
|
+
String starting:"${start}`);
|
|
55405
|
+
case "hstring":
|
|
55406
|
+
return ` scanning a HTML string (missing '>'? bad nesting? longer than ${YY_BUF_SIZE}?)` + (start === "" ? "" : `
|
|
55407
|
+
String starting:<${start}`);
|
|
55408
|
+
case "comment":
|
|
55409
|
+
return ` scanning a /*...*/ comment (missing '*/? longer than ${YY_BUF_SIZE}?)`;
|
|
55410
|
+
case "INITIAL":
|
|
55411
|
+
return "";
|
|
55412
|
+
}
|
|
55413
|
+
}
|
|
55414
|
+
function syntaxErrorMessage(src, offset) {
|
|
55415
|
+
const at = scanAtError(src, offset);
|
|
55416
|
+
const where = `Error: syntax error in line ${at.line}`;
|
|
55417
|
+
return at.text === "" ? where + stateNote(at) : `${where} near '${at.text}'`;
|
|
55418
|
+
}
|
|
55419
|
+
|
|
54715
55420
|
// src/parser/index.ts
|
|
54716
55421
|
var ParseError = class extends DotEngineError {
|
|
54717
55422
|
type = "syntax";
|
|
@@ -54775,9 +55480,9 @@ var Stripper = class _Stripper {
|
|
|
54775
55480
|
*/
|
|
54776
55481
|
static blankLine(src, i, out) {
|
|
54777
55482
|
const n = src.length;
|
|
54778
|
-
const
|
|
54779
|
-
out.push(" ".repeat(
|
|
54780
|
-
i +=
|
|
55483
|
+
const width2 = src[i] === "#" ? 1 : 2;
|
|
55484
|
+
out.push(" ".repeat(width2));
|
|
55485
|
+
i += width2;
|
|
54781
55486
|
while (i < n && src[i] !== "\n") {
|
|
54782
55487
|
out.push(" ");
|
|
54783
55488
|
i++;
|
|
@@ -54888,6 +55593,7 @@ function parse(src) {
|
|
|
54888
55593
|
if (isPeggyError(err)) {
|
|
54889
55594
|
const start = err.location.start;
|
|
54890
55595
|
warnNumberAmbiguities(src, start.offset);
|
|
55596
|
+
console.error(syntaxErrorMessage(src, start.offset));
|
|
54891
55597
|
const code = err.found === null ? "SYNTAX_UNEXPECTED_EOF" : "SYNTAX_ERROR";
|
|
54892
55598
|
throw new ParseError(
|
|
54893
55599
|
err instanceof Error ? err.message : String(err),
|
|
@@ -54905,8 +55611,17 @@ function parse(src) {
|
|
|
54905
55611
|
}
|
|
54906
55612
|
throw err;
|
|
54907
55613
|
}
|
|
55614
|
+
try {
|
|
55615
|
+
validateEdgeOperators(src, ast.directed);
|
|
55616
|
+
} catch (err) {
|
|
55617
|
+
const offset = err instanceof ParseError ? err.location.offset : void 0;
|
|
55618
|
+
if (offset !== void 0) {
|
|
55619
|
+
warnNumberAmbiguities(src, offset);
|
|
55620
|
+
console.error(syntaxErrorMessage(src, offset));
|
|
55621
|
+
}
|
|
55622
|
+
throw err;
|
|
55623
|
+
}
|
|
54908
55624
|
warnNumberAmbiguities(src, src.length);
|
|
54909
|
-
validateEdgeOperators(src, ast.directed);
|
|
54910
55625
|
return buildFromAst(ast);
|
|
54911
55626
|
}
|
|
54912
55627
|
|