@knowvah/dot-engine 2.6.3 → 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 +1366 -648
- 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-flat-labeled.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 +1388 -670
- 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/__fixtures__/2796-flat-labeled-lost.dot +161 -0
- 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-flat-labeled.ts +3 -1
- 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) {
|
|
@@ -30290,7 +30857,10 @@ function makeFlatLabeledEdge(g, e) {
|
|
|
30290
30857
|
info: { ...e.info, tail_port: e.info.head_port, head_port: e.info.tail_port }
|
|
30291
30858
|
};
|
|
30292
30859
|
const ps = routeFlatLabeledChannel(g, sample, ln, et);
|
|
30293
|
-
if (ps === null || ps.length === 0)
|
|
30860
|
+
if (ps === null || ps.length === 0) {
|
|
30861
|
+
e.info.lost = true;
|
|
30862
|
+
return true;
|
|
30863
|
+
}
|
|
30294
30864
|
if (!tailIsLeft) ps.reverse();
|
|
30295
30865
|
clipAndInstall(e, e.head, ps, ps.length, { ...buildDotSinfo(), ignoreSwap: true });
|
|
30296
30866
|
return true;
|
|
@@ -32575,22 +33145,22 @@ function gcellWalk(pd, sx, sy, boundIsX, bound) {
|
|
|
32575
33145
|
}
|
|
32576
33146
|
return out;
|
|
32577
33147
|
}
|
|
32578
|
-
function appendSide(
|
|
33148
|
+
function appendSide(sides2, found, cp, cellIdx) {
|
|
32579
33149
|
for (const np of found) {
|
|
32580
|
-
|
|
33150
|
+
sides2.push(np);
|
|
32581
33151
|
np.cells[cellIdx] = cp;
|
|
32582
33152
|
}
|
|
32583
33153
|
}
|
|
32584
33154
|
function attachGcellSides(mp, hdict, vdict) {
|
|
32585
33155
|
let maxdeg = 0;
|
|
32586
33156
|
for (const cp of mp.gcells) {
|
|
32587
|
-
const
|
|
32588
|
-
appendSide(
|
|
32589
|
-
appendSide(
|
|
32590
|
-
appendSide(
|
|
32591
|
-
appendSide(
|
|
32592
|
-
cp.sides =
|
|
32593
|
-
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;
|
|
32594
33164
|
if (cp.nsides > maxdeg) maxdeg = cp.nsides;
|
|
32595
33165
|
}
|
|
32596
33166
|
return maxdeg;
|
|
@@ -33872,21 +34442,10 @@ function inBoxf(p, bb) {
|
|
|
33872
34442
|
function midPointf2(a, b) {
|
|
33873
34443
|
return { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };
|
|
33874
34444
|
}
|
|
33875
|
-
function casteljauStep(prev, t) {
|
|
33876
|
-
const u = 1 - t;
|
|
33877
|
-
return [
|
|
33878
|
-
{ x: u * prev[0].x + t * prev[1].x, y: u * prev[0].y + t * prev[1].y },
|
|
33879
|
-
{ x: u * prev[1].x + t * prev[2].x, y: u * prev[1].y + t * prev[2].y },
|
|
33880
|
-
{ x: u * prev[2].x + t * prev[3].x, y: u * prev[2].y + t * prev[3].y },
|
|
33881
|
-
{ x: 0, y: 0 }
|
|
33882
|
-
];
|
|
33883
|
-
}
|
|
33884
34445
|
function subdivideBezier(v, t, side) {
|
|
33885
|
-
const
|
|
33886
|
-
|
|
33887
|
-
|
|
33888
|
-
const r3 = casteljauStep(r2, t);
|
|
33889
|
-
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;
|
|
33890
34449
|
}
|
|
33891
34450
|
function countVertCross(pts, xcoord) {
|
|
33892
34451
|
let sign2 = fcmp(pts[0].x, xcoord);
|
|
@@ -35370,10 +35929,11 @@ function bfsFixDisconnected(n, dist4, closestDist) {
|
|
|
35370
35929
|
function bfsVisitNeighbors(vertex, graph, dist4, queue) {
|
|
35371
35930
|
const vd = graph[vertex];
|
|
35372
35931
|
const d = dist4[vertex];
|
|
35932
|
+
const unit = graph[0].ewgts.length === 0;
|
|
35373
35933
|
for (let i = 1; i < vd.nedges; i++) {
|
|
35374
35934
|
const nb = vd.edges[i];
|
|
35375
35935
|
if (dist4[nb] < 0) {
|
|
35376
|
-
dist4[nb] = d + 1;
|
|
35936
|
+
dist4[nb] = d + (unit ? 1 : Math.trunc(Math.fround(vd.ewgts[i])));
|
|
35377
35937
|
queue.push(nb);
|
|
35378
35938
|
}
|
|
35379
35939
|
}
|
|
@@ -36801,11 +37361,12 @@ function runMajorization(g, mode, model) {
|
|
|
36801
37361
|
const nodeList = assignNodeIds2(g);
|
|
36802
37362
|
const n = nodeList.length;
|
|
36803
37363
|
const haveLen = graphHasLen(g);
|
|
36804
|
-
const vtx = makeGraphDataC(g, nodeList, haveLen);
|
|
37364
|
+
const vtx = makeGraphDataC(g, nodeList, haveLen, mode === MODE_HIER || mode === MODE_IPSEP);
|
|
36805
37365
|
checkStart(g);
|
|
36806
37366
|
const maxi = lateDouble(g.attrs.get("maxiter"), DFLT_ITERATIONS, 0);
|
|
36807
37367
|
const epsilon = lateDouble(g.attrs.get("epsilon"), 1e-4, 0);
|
|
36808
|
-
const
|
|
37368
|
+
const weighted = haveLen && mode !== MODE_IPSEP;
|
|
37369
|
+
const Dij = weighted ? computeWeightedApspPacked2(vtx, n) : computeApspPacked2(vtx, n);
|
|
36809
37370
|
const dCoords = [new Float64Array(n), new Float64Array(n)];
|
|
36810
37371
|
stressMajorizationKDMkernel(Dij, n, dCoords, nodeList, {
|
|
36811
37372
|
dim: DFLT_DIM,
|
|
@@ -36823,11 +37384,11 @@ function graphHasLen(g) {
|
|
|
36823
37384
|
}
|
|
36824
37385
|
return false;
|
|
36825
37386
|
}
|
|
36826
|
-
function makeGraphDataC(g, nodeList, haveLen) {
|
|
37387
|
+
function makeGraphDataC(g, nodeList, haveLen, haveDir) {
|
|
36827
37388
|
const vtx = nodeList.map((_, i) => ({
|
|
36828
37389
|
nedges: 1,
|
|
36829
37390
|
edges: [i],
|
|
36830
|
-
ewgts: haveLen ? [0] : []
|
|
37391
|
+
ewgts: haveLen || haveDir ? [0] : []
|
|
36831
37392
|
}));
|
|
36832
37393
|
for (const np of nodeList) {
|
|
36833
37394
|
const i = np.info.id;
|
|
@@ -36845,7 +37406,7 @@ function makeGraphDataC(g, nodeList, haveLen) {
|
|
|
36845
37406
|
}
|
|
36846
37407
|
seen.set(vid, entry.nedges);
|
|
36847
37408
|
entry.edges.push(vid);
|
|
36848
|
-
if (haveLen) entry.ewgts.push(dist4);
|
|
37409
|
+
if (haveLen || haveDir) entry.ewgts.push(dist4);
|
|
36849
37410
|
entry.nedges++;
|
|
36850
37411
|
}
|
|
36851
37412
|
}
|
|
@@ -37906,7 +38467,7 @@ var RIGHT3 = 1 << 1;
|
|
|
37906
38467
|
var TOP3 = 1 << 2;
|
|
37907
38468
|
var LEFT3 = 1 << 3;
|
|
37908
38469
|
var add = (p, q) => ({ x: p.x + q.x, y: p.y + q.y });
|
|
37909
|
-
function sideCone(p,
|
|
38470
|
+
function sideCone(p, sides2) {
|
|
37910
38471
|
const north = { x: 0, y: 1 };
|
|
37911
38472
|
const northeast = { x: 1, y: 1 };
|
|
37912
38473
|
const east = { x: 1, y: 0 };
|
|
@@ -37915,7 +38476,7 @@ function sideCone(p, sides) {
|
|
|
37915
38476
|
const southwest = { x: -1, y: -1 };
|
|
37916
38477
|
const west = { x: -1, y: 0 };
|
|
37917
38478
|
const northwest = { x: -1, y: 1 };
|
|
37918
|
-
switch (
|
|
38479
|
+
switch (sides2) {
|
|
37919
38480
|
case TOP3:
|
|
37920
38481
|
return [add(p, north), add(p, northwest), add(p, northeast)];
|
|
37921
38482
|
case TOP3 | RIGHT3:
|
|
@@ -37936,17 +38497,17 @@ function sideCone(p, sides) {
|
|
|
37936
38497
|
return [p, p, p];
|
|
37937
38498
|
}
|
|
37938
38499
|
}
|
|
37939
|
-
function addEndpoint(rtr, p, obsId, vId,
|
|
38500
|
+
function addEndpoint(rtr, p, obsId, vId, sides2) {
|
|
37940
38501
|
const starti = rtr.obs[obsId];
|
|
37941
38502
|
const endi = rtr.obs[obsId + 1];
|
|
37942
38503
|
const pts = rtr.ps;
|
|
37943
|
-
const [vr, v0, v1] = sideCone(p,
|
|
38504
|
+
const [vr, v0, v1] = sideCone(p, sides2);
|
|
37944
38505
|
rtr.tg.nodes[vId].edges.length = 0;
|
|
37945
38506
|
rtr.tg.nodes[vId].ctr = p;
|
|
37946
38507
|
for (let i = starti; i < endi; i++) {
|
|
37947
38508
|
const seg2 = { i, j: i < endi - 1 ? i + 1 : starti };
|
|
37948
38509
|
const t = findMap(rtr.trimap, seg2.i, seg2.j);
|
|
37949
|
-
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])) {
|
|
37950
38511
|
continue;
|
|
37951
38512
|
}
|
|
37952
38513
|
addTriEdge(rtr.tg, vId, t, seg2);
|
|
@@ -38610,7 +39171,7 @@ function boxCornerMargin(j, m) {
|
|
|
38610
39171
|
return { x: m.x, y: -m.y };
|
|
38611
39172
|
}
|
|
38612
39173
|
function polyObstacle(n, poly, pmargin) {
|
|
38613
|
-
const
|
|
39174
|
+
const sides2 = poly.sides;
|
|
38614
39175
|
const stored = poly.vertices;
|
|
38615
39176
|
if (stored == null) return null;
|
|
38616
39177
|
const penwidth = poly.penwidth ?? 1;
|
|
@@ -38620,19 +39181,19 @@ function polyObstacle(n, poly, pmargin) {
|
|
|
38620
39181
|
const storedRings = Math.max(poly.peripheries, 1);
|
|
38621
39182
|
let verts;
|
|
38622
39183
|
if (ringIdx < storedRings) {
|
|
38623
|
-
verts = stored.slice(ringIdx *
|
|
39184
|
+
verts = stored.slice(ringIdx * sides2, (ringIdx + 1) * sides2);
|
|
38624
39185
|
} else {
|
|
38625
|
-
const outer = stored.slice((storedRings - 1) *
|
|
38626
|
-
verts = polygonOutlineRing(outer,
|
|
39186
|
+
const outer = stored.slice((storedRings - 1) * sides2, storedRings * sides2);
|
|
39187
|
+
verts = polygonOutlineRing(outer, sides2, penwidth);
|
|
38627
39188
|
}
|
|
38628
|
-
if (verts.length <
|
|
38629
|
-
const ps = new Array(
|
|
38630
|
-
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++) {
|
|
38631
39192
|
const v = verts[j];
|
|
38632
39193
|
if (v === void 0) return null;
|
|
38633
39194
|
let polyp;
|
|
38634
39195
|
if (pmargin.doAdd) {
|
|
38635
|
-
if (
|
|
39196
|
+
if (sides2 === 4) {
|
|
38636
39197
|
const m = boxCornerMargin(j, { x: pmargin.x, y: pmargin.y });
|
|
38637
39198
|
polyp = { x: v.x + m.x, y: v.y + m.y };
|
|
38638
39199
|
} else {
|
|
@@ -38642,22 +39203,22 @@ function polyObstacle(n, poly, pmargin) {
|
|
|
38642
39203
|
} else {
|
|
38643
39204
|
polyp = { x: v.x * pmargin.x, y: v.y * pmargin.y };
|
|
38644
39205
|
}
|
|
38645
|
-
ps[
|
|
39206
|
+
ps[sides2 - j - 1] = { x: polyp.x + n.info.coord.x, y: polyp.y + n.info.coord.y };
|
|
38646
39207
|
}
|
|
38647
39208
|
return { ps };
|
|
38648
39209
|
}
|
|
38649
39210
|
function ellipseObstacle(n, pmargin) {
|
|
38650
|
-
const
|
|
38651
|
-
const
|
|
38652
|
-
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;
|
|
38653
39214
|
const mx = pmargin.doAdd ? pmargin.x : 0;
|
|
38654
39215
|
const my = pmargin.doAdd ? pmargin.y : 0;
|
|
38655
|
-
const a = (
|
|
38656
|
-
const b = (
|
|
38657
|
-
const ps = new Array(
|
|
38658
|
-
for (let j = 0; j <
|
|
38659
|
-
const polyp = circumscribedCorner(a, b, j,
|
|
38660
|
-
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 };
|
|
38661
39222
|
}
|
|
38662
39223
|
return { ps };
|
|
38663
39224
|
}
|
|
@@ -38734,10 +39295,10 @@ function makeOrthoObstacle(n, sep) {
|
|
|
38734
39295
|
cy += (bb.ur.y + bb.ll.y) / 2;
|
|
38735
39296
|
cx += 0;
|
|
38736
39297
|
} else {
|
|
38737
|
-
const
|
|
38738
|
-
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;
|
|
38739
39300
|
const outlineH = (info.outline_height ?? 0) > 0 ? info.outline_height * 72 : info.ht;
|
|
38740
|
-
const outlineLw =
|
|
39301
|
+
const outlineLw = width2 > 0 ? info.lw * outlineW / width2 : outlineW / 2;
|
|
38741
39302
|
lw = outlineLw;
|
|
38742
39303
|
rw = outlineLw;
|
|
38743
39304
|
hh = outlineH / 2;
|
|
@@ -38915,17 +39476,11 @@ var OrthoHelper = class _OrthoHelper {
|
|
|
38915
39476
|
}
|
|
38916
39477
|
static buildEdges(g, nodeArr, orthoNodes) {
|
|
38917
39478
|
const concentrate = g.root.info.concentrate ?? false;
|
|
38918
|
-
const
|
|
39479
|
+
const ps = concentrate ? new PointSet() : null;
|
|
38919
39480
|
const edges = [];
|
|
38920
39481
|
for (const n of nodesInSeq(g)) {
|
|
38921
39482
|
for (const e of n.outEdges(g)) {
|
|
38922
|
-
if (
|
|
38923
|
-
const ti = e.tail.id;
|
|
38924
|
-
const hi = e.head.id;
|
|
38925
|
-
const key = ti <= hi ? `${ti}|${hi}` : `${hi}|${ti}`;
|
|
38926
|
-
if (seen.has(key)) continue;
|
|
38927
|
-
seen.add(key);
|
|
38928
|
-
}
|
|
39483
|
+
if (ps && isConcentrateDup(ps, e)) continue;
|
|
38929
39484
|
const tc = e.tail.info.coord;
|
|
38930
39485
|
const hc = e.head.info.coord;
|
|
38931
39486
|
const tp = e.info.tail_port.p;
|
|
@@ -40981,13 +41536,13 @@ function pointDistance(p1, o1, p2, o2, dim) {
|
|
|
40981
41536
|
}
|
|
40982
41537
|
return Math.sqrt(dist4);
|
|
40983
41538
|
}
|
|
40984
|
-
function quadTreeNew(dim, center,
|
|
41539
|
+
function quadTreeNew(dim, center, width2, maxLevel) {
|
|
40985
41540
|
return {
|
|
40986
41541
|
n: 0,
|
|
40987
41542
|
totalWeight: 0,
|
|
40988
41543
|
dim,
|
|
40989
41544
|
center: center.slice(0, dim),
|
|
40990
|
-
width,
|
|
41545
|
+
width: width2,
|
|
40991
41546
|
average: null,
|
|
40992
41547
|
qts: null,
|
|
40993
41548
|
l: null,
|
|
@@ -41005,15 +41560,15 @@ function getQuadrant(dim, center, coord, off) {
|
|
|
41005
41560
|
}
|
|
41006
41561
|
return d;
|
|
41007
41562
|
}
|
|
41008
|
-
function newInQuadrant(dim, parentCenter,
|
|
41009
|
-
const qt = quadTreeNew(dim, parentCenter,
|
|
41563
|
+
function newInQuadrant(dim, parentCenter, width2, maxLevel, i) {
|
|
41564
|
+
const qt = quadTreeNew(dim, parentCenter, width2, maxLevel);
|
|
41010
41565
|
const center = qt.center;
|
|
41011
41566
|
let ii = i;
|
|
41012
41567
|
for (let k = 0; k < dim; k++) {
|
|
41013
41568
|
if (ii % 2 === 0) {
|
|
41014
|
-
center[k] -=
|
|
41569
|
+
center[k] -= width2;
|
|
41015
41570
|
} else {
|
|
41016
|
-
center[k] +=
|
|
41571
|
+
center[k] += width2;
|
|
41017
41572
|
}
|
|
41018
41573
|
ii = (ii - ii % 2) / 2;
|
|
41019
41574
|
}
|
|
@@ -41084,14 +41639,14 @@ function quadTreeNewFromPointList(dim, n, maxLevel, coord) {
|
|
|
41084
41639
|
xmax[k] = Math.max(xmax[k], coord[i * dim + k]);
|
|
41085
41640
|
}
|
|
41086
41641
|
}
|
|
41087
|
-
let
|
|
41642
|
+
let width2 = xmax[0] - xmin[0];
|
|
41088
41643
|
for (let i = 0; i < dim; i++) {
|
|
41089
41644
|
center[i] = (xmin[i] + xmax[i]) * 0.5;
|
|
41090
|
-
|
|
41645
|
+
width2 = Math.max(width2, xmax[i] - xmin[i]);
|
|
41091
41646
|
}
|
|
41092
|
-
|
|
41093
|
-
|
|
41094
|
-
const qt = quadTreeNew(dim, center,
|
|
41647
|
+
width2 = Math.max(width2, 1e-5);
|
|
41648
|
+
width2 *= 0.52;
|
|
41649
|
+
const qt = quadTreeNew(dim, center, width2, maxLevel);
|
|
41095
41650
|
for (let i = 0; i < n; i++) {
|
|
41096
41651
|
quadTreeAdd(qt, coord, i * dim, 1, i);
|
|
41097
41652
|
}
|
|
@@ -41911,18 +42466,18 @@ function compScanPoints(p, q) {
|
|
|
41911
42466
|
if (pp.node < qq.node) return -1;
|
|
41912
42467
|
return 0;
|
|
41913
42468
|
}
|
|
41914
|
-
function getOverlapGraph(dim, n, x,
|
|
42469
|
+
function getOverlapGraph(dim, n, x, width2, checkOverlapOnly) {
|
|
41915
42470
|
let A3 = smNew(n, n, MATRIX_TYPE_REAL, FORMAT_COORD);
|
|
41916
42471
|
const scanpointsx = new Array(2 * n);
|
|
41917
42472
|
for (let i = 0; i < n; i++) {
|
|
41918
|
-
scanpointsx[2 * i] = { node: i, x: x[i * dim] -
|
|
41919
|
-
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 };
|
|
41920
42475
|
}
|
|
41921
42476
|
scanpointsx.sort(compScanPoints);
|
|
41922
42477
|
const scanpointsy = new Array(2 * n);
|
|
41923
42478
|
for (let i = 0; i < n; i++) {
|
|
41924
|
-
scanpointsy[i] = { node: i, x: x[i * dim + 1] -
|
|
41925
|
-
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 };
|
|
41926
42481
|
}
|
|
41927
42482
|
const treey = rbTreeCreate(compScanPoints, () => void 0);
|
|
41928
42483
|
outer:
|
|
@@ -41955,7 +42510,7 @@ function getOverlapGraph(dim, n, x, width, checkOverlapOnly) {
|
|
|
41955
42510
|
A3 = smSymmetrize(B2, false);
|
|
41956
42511
|
return A3;
|
|
41957
42512
|
}
|
|
41958
|
-
function idealDistanceAvoidOverlap(dim, A3, x,
|
|
42513
|
+
function idealDistanceAvoidOverlap(dim, A3, x, width2, idealDistance) {
|
|
41959
42514
|
const ia = A3.ia;
|
|
41960
42515
|
const ja = A3.ja;
|
|
41961
42516
|
const expandmax = 1.5;
|
|
@@ -41969,8 +42524,8 @@ function idealDistanceAvoidOverlap(dim, A3, x, width, idealDistance) {
|
|
|
41969
42524
|
const dist4 = distance(x, dim, i, jj);
|
|
41970
42525
|
const dx = Math.abs(x[i * dim] - x[jj * dim]);
|
|
41971
42526
|
const dy = Math.abs(x[i * dim + 1] - x[jj * dim + 1]);
|
|
41972
|
-
const wx =
|
|
41973
|
-
const wy =
|
|
42527
|
+
const wx = width2[i * dim] + width2[jj * dim];
|
|
42528
|
+
const wy = width2[i * dim + 1] + width2[jj * dim + 1];
|
|
41974
42529
|
if (dx < MACHINEACC * wx && dy < MACHINEACC * wy) {
|
|
41975
42530
|
idealDistance[j] = Math.hypot(wx, wy);
|
|
41976
42531
|
tmax = 2;
|
|
@@ -42001,7 +42556,7 @@ function idealDistanceAvoidOverlap(dim, A3, x, width, idealDistance) {
|
|
|
42001
42556
|
function scaleCoord(dim, m, x, scale) {
|
|
42002
42557
|
for (let i = 0; i < dim * m; i++) x[i] *= scale;
|
|
42003
42558
|
}
|
|
42004
|
-
function overlapScaling(dim, m, x,
|
|
42559
|
+
function overlapScaling(dim, m, x, width2, scaleStaIn, scaleStoIn, epsilon, maxiter) {
|
|
42005
42560
|
let scaleSta = scaleStaIn;
|
|
42006
42561
|
let scaleSto = scaleStoIn;
|
|
42007
42562
|
let iter = 0;
|
|
@@ -42009,7 +42564,7 @@ function overlapScaling(dim, m, x, width, scaleStaIn, scaleStoIn, epsilon, maxit
|
|
|
42009
42564
|
scaleSta = 0;
|
|
42010
42565
|
} else {
|
|
42011
42566
|
scaleCoord(dim, m, x, scaleSta);
|
|
42012
|
-
const C6 = getOverlapGraph(dim, m, x,
|
|
42567
|
+
const C6 = getOverlapGraph(dim, m, x, width2, true);
|
|
42013
42568
|
if (C6.nz === 0) return;
|
|
42014
42569
|
scaleCoord(dim, m, x, 1 / scaleSta);
|
|
42015
42570
|
}
|
|
@@ -42024,7 +42579,7 @@ function overlapScaling(dim, m, x, width, scaleStaIn, scaleStoIn, epsilon, maxit
|
|
|
42024
42579
|
do {
|
|
42025
42580
|
scaleSto *= 2;
|
|
42026
42581
|
scaleCoord(dim, m, x, 2);
|
|
42027
|
-
const C6 = getOverlapGraph(dim, m, x,
|
|
42582
|
+
const C6 = getOverlapGraph(dim, m, x, width2, true);
|
|
42028
42583
|
overlap5 = C6.nz > 0;
|
|
42029
42584
|
} while (overlap5);
|
|
42030
42585
|
scaleCoord(dim, m, x, 1 / scaleSto);
|
|
@@ -42033,7 +42588,7 @@ function overlapScaling(dim, m, x, width, scaleStaIn, scaleStoIn, epsilon, maxit
|
|
|
42033
42588
|
while (iter++ < maxiter && scaleSto - scaleSta > epsilon) {
|
|
42034
42589
|
const scale = 0.5 * (scaleSta + scaleSto);
|
|
42035
42590
|
scaleCoord(dim, m, x, scale);
|
|
42036
|
-
const C6 = getOverlapGraph(dim, m, x,
|
|
42591
|
+
const C6 = getOverlapGraph(dim, m, x, width2, true);
|
|
42037
42592
|
scaleCoord(dim, m, x, 1 / scale);
|
|
42038
42593
|
const overlap5 = C6.nz > 0;
|
|
42039
42594
|
if (overlap5) {
|
|
@@ -42044,7 +42599,7 @@ function overlapScaling(dim, m, x, width, scaleStaIn, scaleStoIn, epsilon, maxit
|
|
|
42044
42599
|
}
|
|
42045
42600
|
scaleCoord(dim, m, x, scaleBest);
|
|
42046
42601
|
}
|
|
42047
|
-
function overlapSmootherNew(m, dim, x,
|
|
42602
|
+
function overlapSmootherNew(m, dim, x, width2, neighborhoodOnly, shrink) {
|
|
42048
42603
|
const sm = {
|
|
42049
42604
|
Lw: null,
|
|
42050
42605
|
Lwd: null,
|
|
@@ -42054,16 +42609,16 @@ function overlapSmootherNew(m, dim, x, width, neighborhoodOnly, shrink) {
|
|
|
42054
42609
|
};
|
|
42055
42610
|
let B2 = callTri(m, x);
|
|
42056
42611
|
if (!neighborhoodOnly) {
|
|
42057
|
-
const C6 = getOverlapGraph(dim, m, x,
|
|
42612
|
+
const C6 = getOverlapGraph(dim, m, x, width2, false);
|
|
42058
42613
|
B2 = smAdd(B2, C6);
|
|
42059
42614
|
}
|
|
42060
42615
|
sm.Lw = B2;
|
|
42061
42616
|
sm.Lwd = smCopy(sm.Lw);
|
|
42062
|
-
const { tmax, tmin } = idealDistanceAvoidOverlap(dim, sm.Lwd, x,
|
|
42617
|
+
const { tmax, tmin } = idealDistanceAvoidOverlap(dim, sm.Lwd, x, width2, sm.Lwd.a);
|
|
42063
42618
|
if (tmax < 1 && shrink) {
|
|
42064
42619
|
const scaleSta = Math.min(1, tmax * 1.0001);
|
|
42065
42620
|
const scaleSto = 1;
|
|
42066
|
-
overlapScaling(dim, m, x,
|
|
42621
|
+
overlapScaling(dim, m, x, width2, scaleSta, scaleSto, 1e-4, 15);
|
|
42067
42622
|
return { sm, maxOverlap: 1, minOverlap: tmin };
|
|
42068
42623
|
}
|
|
42069
42624
|
const iw = sm.Lw.ia;
|
|
@@ -42337,7 +42892,7 @@ function scAdjust(g, equal) {
|
|
|
42337
42892
|
// src/layout/neato/simple-scale.ts
|
|
42338
42893
|
var ISZERO = (d) => Math.abs(d) < 1e-9;
|
|
42339
42894
|
var LF = /^\s*([+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?)/;
|
|
42340
|
-
function
|
|
42895
|
+
function scanPair2(p) {
|
|
42341
42896
|
const m1 = LF.exec(p);
|
|
42342
42897
|
if (m1 === null) return [];
|
|
42343
42898
|
const rest = p.slice(m1[0].length);
|
|
@@ -42348,7 +42903,7 @@ function scanPair(p) {
|
|
|
42348
42903
|
function simpleScale(g) {
|
|
42349
42904
|
const p = aggetGraph(g, "scale");
|
|
42350
42905
|
if (p === void 0) return 0;
|
|
42351
|
-
const sc =
|
|
42906
|
+
const sc = scanPair2(p);
|
|
42352
42907
|
if (sc.length === 0) return 0;
|
|
42353
42908
|
const x = sc[0];
|
|
42354
42909
|
if (ISZERO(x)) return 0;
|
|
@@ -42672,16 +43227,16 @@ function overlaps(p) {
|
|
|
42672
43227
|
function initItem(n, margin) {
|
|
42673
43228
|
const x = cround(SCALE * (n.info.pos?.[0] ?? 0) * POINTS_PER_INCH6);
|
|
42674
43229
|
const y = cround(SCALE * (n.info.pos?.[1] ?? 0) * POINTS_PER_INCH6);
|
|
42675
|
-
const
|
|
42676
|
-
const
|
|
43230
|
+
const width2 = n.info.width ?? 0;
|
|
43231
|
+
const height2 = n.info.height ?? 0;
|
|
42677
43232
|
let w2;
|
|
42678
43233
|
let h2;
|
|
42679
43234
|
if (margin.doAdd) {
|
|
42680
|
-
w2 = d2i(SCALE * (cround(
|
|
42681
|
-
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));
|
|
42682
43237
|
} else {
|
|
42683
|
-
w2 = cround(margin.x * SCALE2 *
|
|
42684
|
-
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);
|
|
42685
43240
|
}
|
|
42686
43241
|
return {
|
|
42687
43242
|
val: 0,
|
|
@@ -42783,12 +43338,12 @@ function atoi2(s) {
|
|
|
42783
43338
|
}
|
|
42784
43339
|
function genRound(n, xm, ym) {
|
|
42785
43340
|
const isides = atoi2(n.attrs.get("samplepoints"));
|
|
42786
|
-
const
|
|
43341
|
+
const sides2 = isides < MIN_SAMPLES ? DFLT_SAMPLE2 : isides;
|
|
42787
43342
|
const verts = [];
|
|
42788
|
-
for (let i = 0; i <
|
|
43343
|
+
for (let i = 0; i < sides2; i++) {
|
|
42789
43344
|
verts.push({
|
|
42790
|
-
x: (n.info.width / 2 + xm) * Math.cos(i /
|
|
42791
|
-
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)
|
|
42792
43347
|
});
|
|
42793
43348
|
}
|
|
42794
43349
|
return verts;
|
|
@@ -45206,30 +45761,30 @@ function boundaryFromBB(bb) {
|
|
|
45206
45761
|
x: (bb.llx + bb.urx) / 2,
|
|
45207
45762
|
y: (bb.lly + bb.ury) / 2
|
|
45208
45763
|
};
|
|
45209
|
-
const
|
|
45210
|
-
const
|
|
45211
|
-
sizeBoundary(
|
|
45764
|
+
const width2 = EXPFACTOR * (bb.urx - bb.llx);
|
|
45765
|
+
const height2 = EXPFACTOR * (bb.ury - bb.lly);
|
|
45766
|
+
sizeBoundary(width2, height2);
|
|
45212
45767
|
const alpha = Math.atan2(parms.Ht, parms.Wd);
|
|
45213
45768
|
parms.Wd = parms.Wd / Math.cos(alpha);
|
|
45214
45769
|
parms.Ht = parms.Ht / Math.sin(alpha);
|
|
45215
45770
|
return ctr;
|
|
45216
45771
|
}
|
|
45217
|
-
function sizeBoundary(
|
|
45772
|
+
function sizeBoundary(width2, height2) {
|
|
45218
45773
|
const area = 4 * parms.Wd * parms.Ht;
|
|
45219
|
-
let quot =
|
|
45774
|
+
let quot = width2 * height2 / area;
|
|
45220
45775
|
if (quot >= 1) {
|
|
45221
|
-
parms.Wd =
|
|
45222
|
-
parms.Ht =
|
|
45776
|
+
parms.Wd = width2 / 2;
|
|
45777
|
+
parms.Ht = height2 / 2;
|
|
45223
45778
|
} else if (quot > 0) {
|
|
45224
45779
|
quot = 2 * Math.sqrt(quot);
|
|
45225
|
-
parms.Wd =
|
|
45226
|
-
parms.Ht =
|
|
45227
|
-
} else if (
|
|
45228
|
-
parms.Wd =
|
|
45229
|
-
parms.Ht = area /
|
|
45230
|
-
} else if (
|
|
45231
|
-
parms.Wd = area /
|
|
45232
|
-
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;
|
|
45233
45788
|
}
|
|
45234
45789
|
}
|
|
45235
45790
|
function placeWithPorts(g, pp, ctr) {
|
|
@@ -46152,7 +46707,7 @@ function finalCC(g, cc, pts, rg, infop) {
|
|
|
46152
46707
|
};
|
|
46153
46708
|
}
|
|
46154
46709
|
function applyMarginAndBorder(rg, bb, margin) {
|
|
46155
|
-
const
|
|
46710
|
+
const border2 = rg.info.border ?? [
|
|
46156
46711
|
{ x: 0, y: 0 },
|
|
46157
46712
|
{ x: 0, y: 0 },
|
|
46158
46713
|
{ x: 0, y: 0 },
|
|
@@ -46160,12 +46715,12 @@ function applyMarginAndBorder(rg, bb, margin) {
|
|
|
46160
46715
|
];
|
|
46161
46716
|
const pt = {
|
|
46162
46717
|
x: -bb.ll.x + margin,
|
|
46163
|
-
y: -bb.ll.y + margin +
|
|
46718
|
+
y: -bb.ll.y + margin + border2[BOTTOM_IX].y
|
|
46164
46719
|
};
|
|
46165
46720
|
bb.ll.x = 0;
|
|
46166
46721
|
bb.ll.y = 0;
|
|
46167
46722
|
bb.ur.x += pt.x + margin;
|
|
46168
|
-
bb.ur.y += pt.y + margin +
|
|
46723
|
+
bb.ur.y += pt.y + margin + border2[TOP_IX].y;
|
|
46169
46724
|
return pt;
|
|
46170
46725
|
}
|
|
46171
46726
|
function evalPositions(g, rootg) {
|
|
@@ -48073,9 +48628,9 @@ function applyLabelExpansion(g, total, rbb) {
|
|
|
48073
48628
|
}
|
|
48074
48629
|
function addMarginAndBorder(g, margin, rbb) {
|
|
48075
48630
|
let { llx, lly, urx, ury } = rbb;
|
|
48076
|
-
const
|
|
48077
|
-
const bottomY =
|
|
48078
|
-
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;
|
|
48079
48634
|
llx -= margin;
|
|
48080
48635
|
urx += margin;
|
|
48081
48636
|
lly -= margin + bottomY;
|
|
@@ -48646,18 +49201,9 @@ function approxLen(list, off) {
|
|
|
48646
49201
|
return dist3(list[off], list[off + 1]) + dist3(list[off + 1], list[off + 2]) + dist3(list[off + 2], list[off + 3]);
|
|
48647
49202
|
}
|
|
48648
49203
|
function splitCubic(v, t) {
|
|
48649
|
-
const
|
|
48650
|
-
const
|
|
48651
|
-
|
|
48652
|
-
const right2 = new Array(4);
|
|
48653
|
-
right2[3] = row[3];
|
|
48654
|
-
for (let i = 1; i <= 3; i++) {
|
|
48655
|
-
for (let j = 0; j <= 3 - i; j++) {
|
|
48656
|
-
row[j] = { x: u * row[j].x + t * row[j + 1].x, y: u * row[j].y + t * row[j + 1].y };
|
|
48657
|
-
}
|
|
48658
|
-
left2.push(row[0]);
|
|
48659
|
-
right2[3 - i] = row[3 - i];
|
|
48660
|
-
}
|
|
49204
|
+
const left2 = [];
|
|
49205
|
+
const right2 = [];
|
|
49206
|
+
bezier(v, t, left2, right2);
|
|
48661
49207
|
return { left: left2, right: right2 };
|
|
48662
49208
|
}
|
|
48663
49209
|
function splitBSpline(list, t) {
|
|
@@ -48777,17 +49323,6 @@ function mymod(original, modulus) {
|
|
|
48777
49323
|
function l2dist(p0, p1) {
|
|
48778
49324
|
return Math.hypot(p0.x - p1.x, p0.y - p1.y);
|
|
48779
49325
|
}
|
|
48780
|
-
function bezierPoint(v, t) {
|
|
48781
|
-
const vx = [v[0].x, v[1].x, v[2].x, v[3].x];
|
|
48782
|
-
const vy = [v[0].y, v[1].y, v[2].y, v[3].y];
|
|
48783
|
-
for (let i = 1; i <= 3; i++) {
|
|
48784
|
-
for (let j = 0; j <= 3 - i; j++) {
|
|
48785
|
-
vx[j] = (1 - t) * vx[j] + t * vx[j + 1];
|
|
48786
|
-
vy[j] = (1 - t) * vy[j] + t * vy[j + 1];
|
|
48787
|
-
}
|
|
48788
|
-
}
|
|
48789
|
-
return { x: vx[0], y: vy[0] };
|
|
48790
|
-
}
|
|
48791
49326
|
function pathtolines(bez) {
|
|
48792
49327
|
const arr = [];
|
|
48793
49328
|
const A3 = bez.list;
|
|
@@ -48803,7 +49338,7 @@ function pathtolines(bez) {
|
|
|
48803
49338
|
for (let j = 1; j <= 3; j++) V[j] = A3[i + j];
|
|
48804
49339
|
let p0 = V[0];
|
|
48805
49340
|
for (let step = 1; step <= BEZIER_SUBDIVISION; step++) {
|
|
48806
|
-
const p1 =
|
|
49341
|
+
const p1 = bezier(V, step / BEZIER_SUBDIVISION, null, null);
|
|
48807
49342
|
linelen += l2dist(p0, p1);
|
|
48808
49343
|
push(p1, linelen);
|
|
48809
49344
|
p0 = p1;
|
|
@@ -49028,9 +49563,9 @@ function agstrcanonText(arg) {
|
|
|
49028
49563
|
if (needsQuotes || cnt === 1 && (first === 46 || first === 45)) {
|
|
49029
49564
|
return new TextDecoder().decode(new Uint8Array(out));
|
|
49030
49565
|
}
|
|
49031
|
-
const
|
|
49566
|
+
const lower2 = arg.toLowerCase();
|
|
49032
49567
|
for (const tok of CANON_KEYWORDS) {
|
|
49033
|
-
if (tok ===
|
|
49568
|
+
if (tok === lower2) return new TextDecoder().decode(new Uint8Array(out));
|
|
49034
49569
|
}
|
|
49035
49570
|
return arg;
|
|
49036
49571
|
}
|
|
@@ -49114,9 +49649,9 @@ function writePlainEdge(e, extend, out) {
|
|
|
49114
49649
|
if (lbl !== void 0) {
|
|
49115
49650
|
out.push(" " + agstrcanonText(lbl.text) + " " + plainCoord(lbl.pos.x) + " " + plainCoord(lbl.pos.y));
|
|
49116
49651
|
}
|
|
49117
|
-
const
|
|
49652
|
+
const style2 = lateNN(e.attrs.get("style"), "solid");
|
|
49118
49653
|
const color = lateNN(e.attrs.get("color"), "black");
|
|
49119
|
-
out.push(" " +
|
|
49654
|
+
out.push(" " + style2 + " " + color + "\n");
|
|
49120
49655
|
}
|
|
49121
49656
|
function writePlain(g, job, extend) {
|
|
49122
49657
|
const w = plainCoord(g.info.bb.ur.x);
|
|
@@ -50683,9 +51218,9 @@ function createXdotRenderer() {
|
|
|
50683
51218
|
|
|
50684
51219
|
// src/render/svg-tapered-edge.ts
|
|
50685
51220
|
function edgeIsTapered(e) {
|
|
50686
|
-
const
|
|
50687
|
-
if (
|
|
50688
|
-
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");
|
|
50689
51224
|
}
|
|
50690
51225
|
function svgTaperedEdge(e, job) {
|
|
50691
51226
|
const spl = e.info.spl;
|
|
@@ -50900,16 +51435,16 @@ var SvgRenderer = class {
|
|
|
50900
51435
|
*/
|
|
50901
51436
|
usershape(src, b, job) {
|
|
50902
51437
|
const g = (n) => String(parseFloat(n.toPrecision(6)));
|
|
50903
|
-
const
|
|
50904
|
-
const
|
|
50905
|
-
const originx = (b.ur.x + b.ll.x -
|
|
50906
|
-
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;
|
|
50907
51442
|
let href = src;
|
|
50908
51443
|
if (job.inlineImages === true) {
|
|
50909
51444
|
const found = findImageBytes(src, job.imageResolver);
|
|
50910
51445
|
if (found !== null) href = toDataUri(found.bytes, found.mime);
|
|
50911
51446
|
}
|
|
50912
|
-
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');
|
|
50913
51448
|
}
|
|
50914
51449
|
comment(text, job) {
|
|
50915
51450
|
svgComment(text, job);
|
|
@@ -54709,6 +55244,179 @@ function numberAmbiguityMessage(a) {
|
|
|
54709
55244
|
return `Warning: syntax ambiguity - badly delimited number '${a.text}' in line ${a.line} of input splits into two tokens`;
|
|
54710
55245
|
}
|
|
54711
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
|
+
|
|
54712
55420
|
// src/parser/index.ts
|
|
54713
55421
|
var ParseError = class extends DotEngineError {
|
|
54714
55422
|
type = "syntax";
|
|
@@ -54772,9 +55480,9 @@ var Stripper = class _Stripper {
|
|
|
54772
55480
|
*/
|
|
54773
55481
|
static blankLine(src, i, out) {
|
|
54774
55482
|
const n = src.length;
|
|
54775
|
-
const
|
|
54776
|
-
out.push(" ".repeat(
|
|
54777
|
-
i +=
|
|
55483
|
+
const width2 = src[i] === "#" ? 1 : 2;
|
|
55484
|
+
out.push(" ".repeat(width2));
|
|
55485
|
+
i += width2;
|
|
54778
55486
|
while (i < n && src[i] !== "\n") {
|
|
54779
55487
|
out.push(" ");
|
|
54780
55488
|
i++;
|
|
@@ -54885,6 +55593,7 @@ function parse(src) {
|
|
|
54885
55593
|
if (isPeggyError(err)) {
|
|
54886
55594
|
const start = err.location.start;
|
|
54887
55595
|
warnNumberAmbiguities(src, start.offset);
|
|
55596
|
+
console.error(syntaxErrorMessage(src, start.offset));
|
|
54888
55597
|
const code = err.found === null ? "SYNTAX_UNEXPECTED_EOF" : "SYNTAX_ERROR";
|
|
54889
55598
|
throw new ParseError(
|
|
54890
55599
|
err instanceof Error ? err.message : String(err),
|
|
@@ -54902,8 +55611,17 @@ function parse(src) {
|
|
|
54902
55611
|
}
|
|
54903
55612
|
throw err;
|
|
54904
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
|
+
}
|
|
54905
55624
|
warnNumberAmbiguities(src, src.length);
|
|
54906
|
-
validateEdgeOperators(src, ast.directed);
|
|
54907
55625
|
return buildFromAst(ast);
|
|
54908
55626
|
}
|
|
54909
55627
|
|