@knowvah/dot-engine 2.6.4 → 2.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/dist/common/arrows-shapes-poly.d.ts.map +1 -1
  2. package/dist/common/bezier.d.ts +12 -0
  3. package/dist/common/bezier.d.ts.map +1 -0
  4. package/dist/common/htmltable-attr-warn.d.ts +41 -0
  5. package/dist/common/htmltable-attr-warn.d.ts.map +1 -0
  6. package/dist/common/htmltable-fontinfo.d.ts +42 -0
  7. package/dist/common/htmltable-fontinfo.d.ts.map +1 -0
  8. package/dist/common/htmltable-lex-expat.d.ts +63 -0
  9. package/dist/common/htmltable-lex-expat.d.ts.map +1 -0
  10. package/dist/common/htmltable-lex-units.d.ts +32 -0
  11. package/dist/common/htmltable-lex-units.d.ts.map +1 -0
  12. package/dist/common/htmltable-lex.d.ts +10 -2
  13. package/dist/common/htmltable-lex.d.ts.map +1 -1
  14. package/dist/common/htmltable-parse-attrs.d.ts +7 -5
  15. package/dist/common/htmltable-parse-attrs.d.ts.map +1 -1
  16. package/dist/common/htmltable-parse-font.d.ts +33 -0
  17. package/dist/common/htmltable-parse-font.d.ts.map +1 -0
  18. package/dist/common/htmltable-parse-state.d.ts +39 -0
  19. package/dist/common/htmltable-parse-state.d.ts.map +1 -0
  20. package/dist/common/htmltable-parse.d.ts +18 -23
  21. package/dist/common/htmltable-parse.d.ts.map +1 -1
  22. package/dist/common/htmltable-pos.d.ts.map +1 -1
  23. package/dist/common/htmltable-types.d.ts +33 -3
  24. package/dist/common/htmltable-types.d.ts.map +1 -1
  25. package/dist/common/htmltable.d.ts +3 -2
  26. package/dist/common/htmltable.d.ts.map +1 -1
  27. package/dist/common/spline-midpoint.d.ts.map +1 -1
  28. package/dist/common/splines-geom.d.ts +5 -6
  29. package/dist/common/splines-geom.d.ts.map +1 -1
  30. package/dist/common/splines-routespl.d.ts.map +1 -1
  31. package/dist/common/taper.d.ts.map +1 -1
  32. package/dist/gvc/anchor.d.ts.map +1 -1
  33. package/dist/index.js +1362 -647
  34. package/dist/index.js.map +4 -4
  35. package/dist/layout/dot/compound-clip.d.ts +5 -5
  36. package/dist/layout/dot/compound-clip.d.ts.map +1 -1
  37. package/dist/layout/dot/compound-geom.d.ts +2 -7
  38. package/dist/layout/dot/compound-geom.d.ts.map +1 -1
  39. package/dist/layout/dot/compound.d.ts +1 -1
  40. package/dist/layout/dot/compound.d.ts.map +1 -1
  41. package/dist/layout/dot/edge-route-clip.d.ts +1 -1
  42. package/dist/layout/dot/edge-route-clip.d.ts.map +1 -1
  43. package/dist/layout/dot/ortho-adapter.d.ts +13 -4
  44. package/dist/layout/dot/ortho-adapter.d.ts.map +1 -1
  45. package/dist/layout/dot/splines-label.d.ts.map +1 -1
  46. package/dist/layout/neato/bfs.d.ts +10 -3
  47. package/dist/layout/neato/bfs.d.ts.map +1 -1
  48. package/dist/layout/neato/init.d.ts +6 -11
  49. package/dist/layout/neato/init.d.ts.map +1 -1
  50. package/dist/layout/neato/splines.d.ts.map +1 -1
  51. package/dist/parser/index.d.ts.map +1 -1
  52. package/dist/parser/scan-token.d.ts +40 -0
  53. package/dist/parser/scan-token.d.ts.map +1 -0
  54. package/dist/render/svg-edge-split.d.ts.map +1 -1
  55. package/dist/render.js +1384 -669
  56. package/dist/render.js.map +4 -4
  57. package/package.json +1 -1
  58. package/src/common/arrows-shapes-poly.ts +9 -10
  59. package/src/common/bezier.ts +33 -0
  60. package/src/common/htmltable-attr-warn.ts +270 -0
  61. package/src/common/htmltable-fontinfo.ts +83 -0
  62. package/src/common/htmltable-lex-expat.ts +357 -0
  63. package/src/common/htmltable-lex-units.ts +75 -0
  64. package/src/common/htmltable-lex.ts +221 -160
  65. package/src/common/htmltable-parse-attrs.ts +10 -14
  66. package/src/common/htmltable-parse-font.ts +92 -0
  67. package/src/common/htmltable-parse-state.ts +64 -0
  68. package/src/common/htmltable-parse.ts +138 -98
  69. package/src/common/htmltable-pos.ts +9 -8
  70. package/src/common/htmltable-types.ts +35 -3
  71. package/src/common/htmltable.ts +14 -7
  72. package/src/common/spline-midpoint.ts +2 -22
  73. package/src/common/splines-geom.ts +5 -25
  74. package/src/common/splines-routespl.ts +21 -13
  75. package/src/common/taper.ts +2 -14
  76. package/src/gvc/anchor.ts +5 -14
  77. package/src/layout/dot/compound-clip.ts +9 -19
  78. package/src/layout/dot/compound-geom.ts +6 -23
  79. package/src/layout/dot/compound.ts +1 -1
  80. package/src/layout/dot/edge-route-clip.ts +6 -29
  81. package/src/layout/dot/ortho-adapter.ts +5 -5
  82. package/src/layout/dot/splines-label.ts +3 -29
  83. package/src/layout/neato/bfs.ts +13 -4
  84. package/src/layout/neato/init.ts +15 -15
  85. package/src/layout/neato/splines.ts +4 -8
  86. package/src/parser/index.ts +13 -1
  87. package/src/parser/scan-token.ts +289 -0
  88. package/src/render/svg-edge-split.ts +5 -13
package/dist/index.js CHANGED
@@ -4317,6 +4317,179 @@ function numberAmbiguityMessage(a) {
4317
4317
  return `Warning: syntax ambiguity - badly delimited number '${a.text}' in line ${a.line} of input splits into two tokens`;
4318
4318
  }
4319
4319
 
4320
+ // src/parser/scan-token.ts
4321
+ var YY_BUF_SIZE = 16384;
4322
+ var STRING_STARTING_BYTES = 80;
4323
+ var ASCII_DEL2 = 127;
4324
+ function isLetter2(c) {
4325
+ if (c === void 0) return false;
4326
+ return c >= "A" && c <= "Z" || c >= "a" && c <= "z" || c === "_" || c.charCodeAt(0) > ASCII_DEL2;
4327
+ }
4328
+ function isDigit2(c) {
4329
+ return c !== void 0 && c >= "0" && c <= "9";
4330
+ }
4331
+ function startsNumber2(s, i) {
4332
+ const c = s[i];
4333
+ if (isDigit2(c)) return true;
4334
+ if (c === ".") return isDigit2(s[i + 1]);
4335
+ if (c !== "-") return false;
4336
+ return isDigit2(s[i + 1]) || s[i + 1] === "." && isDigit2(s[i + 2]);
4337
+ }
4338
+ function matchNumber2(s, i) {
4339
+ let j = s[i] === "-" ? i + 1 : i;
4340
+ if (s[j] === ".") {
4341
+ j++;
4342
+ while (isDigit2(s[j])) j++;
4343
+ } else {
4344
+ while (isDigit2(s[j])) j++;
4345
+ if (s[j] === ".") {
4346
+ j++;
4347
+ while (isDigit2(s[j])) j++;
4348
+ }
4349
+ }
4350
+ if (s[j] === "." || isLetter2(s[j])) j++;
4351
+ return j;
4352
+ }
4353
+ function badlyDelimited(text) {
4354
+ const c = text[text.length - 1];
4355
+ const dot = text.indexOf(".");
4356
+ return !isDigit2(c) && c !== "." || c === "." && dot !== text.length - 1;
4357
+ }
4358
+ function lineEnd(s, i) {
4359
+ const nl = s.indexOf("\n", i);
4360
+ return nl === -1 ? s.length : nl;
4361
+ }
4362
+ function directiveLine(text) {
4363
+ const rest = text.slice(1).replace(/^line/, "");
4364
+ const m = /^\s*([+-]?\d+)/.exec(rest);
4365
+ if (m === null) return void 0;
4366
+ const lineno = Number.parseInt(m[1], 10);
4367
+ return lineno <= 0 ? void 0 : lineno - 1;
4368
+ }
4369
+ function qstringBuffer(body) {
4370
+ return body.replace(/\\\\|\\"|\\\n/g, (m) => m === '\\"' ? '"' : m === "\\\n" ? "" : m);
4371
+ }
4372
+ function lexQuoted(s, i) {
4373
+ for (let j = i + 1; j < s.length; j++) {
4374
+ if (s[j] === "\\" && j + 1 < s.length) j++;
4375
+ else if (s[j] === '"') return { kind: "token", end: j + 1, text: '"' };
4376
+ }
4377
+ return { kind: "open", state: "qstring", buffer: qstringBuffer(s.slice(i + 1)) };
4378
+ }
4379
+ function lexHtml(s, i) {
4380
+ let nest = 1;
4381
+ for (let j = i + 1; j < s.length; j++) {
4382
+ if (s[j] === "<") nest++;
4383
+ else if (s[j] === ">" && --nest === 0) return { kind: "token", end: j + 1, text: ">" };
4384
+ }
4385
+ return { kind: "open", state: "hstring", buffer: s.slice(i + 1) };
4386
+ }
4387
+ function lexComment(s, i) {
4388
+ const close = s.indexOf("*/", i + 2);
4389
+ if (close === -1) return { kind: "open", state: "comment", buffer: "" };
4390
+ return { kind: "skip", end: close + 2 };
4391
+ }
4392
+ function lexHash(s, i) {
4393
+ const end = lineEnd(s, i);
4394
+ const atLineStart = i === 0 || s[i - 1] === "\n";
4395
+ const line = atLineStart ? directiveLine(s.slice(i, end)) : void 0;
4396
+ return line === void 0 ? { kind: "skip", end } : { kind: "skip", end, line };
4397
+ }
4398
+ function lexAtom(s, i) {
4399
+ if (isLetter2(s[i])) {
4400
+ let j2 = i + 1;
4401
+ while (isLetter2(s[j2]) || isDigit2(s[j2])) j2++;
4402
+ const text = s.slice(i, j2);
4403
+ return text === "\uFEFF" ? { kind: "skip", end: j2 } : { kind: "token", end: j2, text };
4404
+ }
4405
+ if (s[i] === "-" && (s[i + 1] === "-" || s[i + 1] === ">")) {
4406
+ return { kind: "token", end: i + 2, text: s.slice(i, i + 2) };
4407
+ }
4408
+ if (!startsNumber2(s, i)) return { kind: "token", end: i + 1, text: s[i] };
4409
+ const j = matchNumber2(s, i);
4410
+ const end = badlyDelimited(s.slice(i, j)) ? j - 1 : j;
4411
+ return { kind: "token", end, text: s.slice(i, end) };
4412
+ }
4413
+ function lexTrivia(s, i) {
4414
+ const c = s[i];
4415
+ if (c === "\n" || c === " " || c === " " || c === "\r") return { kind: "skip", end: i + 1 };
4416
+ if (c === "#") return lexHash(s, i);
4417
+ if (c !== "/") return void 0;
4418
+ if (s[i + 1] === "*") return lexComment(s, i);
4419
+ if (s[i + 1] === "/") return { kind: "skip", end: lineEnd(s, i) };
4420
+ return void 0;
4421
+ }
4422
+ function lexStep(s, i) {
4423
+ const trivia = lexTrivia(s, i);
4424
+ if (trivia !== void 0) return trivia;
4425
+ if (s[i] === '"') return lexQuoted(s, i);
4426
+ if (s[i] === "<") return lexHtml(s, i);
4427
+ return lexAtom(s, i);
4428
+ }
4429
+ function countNewlines(s, from, to) {
4430
+ let n = 0;
4431
+ for (let i = s.indexOf("\n", from); i !== -1 && i < to; i = s.indexOf("\n", i + 1)) n++;
4432
+ return n;
4433
+ }
4434
+ var HEADER_KEYWORDS = ["strict", "graph", "digraph"];
4435
+ function isTruncatedHeaderKeyword(src, step, offset, seen) {
4436
+ if (offset !== src.length || step.end !== offset || seen.length > 1) return false;
4437
+ if (seen.length === 1 && seen[0].toLowerCase() !== "strict") return false;
4438
+ const word = step.text.toLowerCase();
4439
+ return HEADER_KEYWORDS.some((k) => k.length > word.length && k.startsWith(word));
4440
+ }
4441
+ function reachesOffset(src, step, offset, seen) {
4442
+ if (step.end > offset) return true;
4443
+ if (isTruncatedHeaderKeyword(src, step, offset, seen)) return true;
4444
+ if (step.text !== "-" && step.text !== ".") return false;
4445
+ return offset <= step.end + (step.text === "-" && src[step.end] === "." ? 1 : 0);
4446
+ }
4447
+ function scanAtError(src, offset) {
4448
+ let line = 1;
4449
+ let i = 0;
4450
+ const seen = [];
4451
+ while (i < src.length) {
4452
+ const step = lexStep(src, i);
4453
+ if (step.kind === "open") {
4454
+ line += countNewlines(src, i, src.length);
4455
+ return { state: step.state, text: "", line, buffer: step.buffer };
4456
+ }
4457
+ if (step.kind === "skip" && step.line !== void 0) line = step.line;
4458
+ line += countNewlines(src, i, step.end);
4459
+ if (step.kind === "token" && reachesOffset(src, step, offset, seen)) {
4460
+ return { state: "INITIAL", text: step.text, line, buffer: "" };
4461
+ }
4462
+ if (step.kind === "token") seen.push(step.text);
4463
+ i = step.end;
4464
+ }
4465
+ return { state: "INITIAL", text: "", line, buffer: "" };
4466
+ }
4467
+ function firstBytes(s) {
4468
+ const bytes = new TextEncoder().encode(s);
4469
+ if (bytes.length <= STRING_STARTING_BYTES) return s;
4470
+ return new TextDecoder().decode(bytes.subarray(0, STRING_STARTING_BYTES));
4471
+ }
4472
+ function stateNote(at) {
4473
+ const start = at.buffer.length > 0 ? firstBytes(at.buffer) : "";
4474
+ switch (at.state) {
4475
+ case "qstring":
4476
+ return ` scanning a quoted string (missing endquote? longer than ${YY_BUF_SIZE}?)` + (start === "" ? "" : `
4477
+ String starting:"${start}`);
4478
+ case "hstring":
4479
+ return ` scanning a HTML string (missing '>'? bad nesting? longer than ${YY_BUF_SIZE}?)` + (start === "" ? "" : `
4480
+ String starting:<${start}`);
4481
+ case "comment":
4482
+ return ` scanning a /*...*/ comment (missing '*/? longer than ${YY_BUF_SIZE}?)`;
4483
+ case "INITIAL":
4484
+ return "";
4485
+ }
4486
+ }
4487
+ function syntaxErrorMessage(src, offset) {
4488
+ const at = scanAtError(src, offset);
4489
+ const where = `Error: syntax error in line ${at.line}`;
4490
+ return at.text === "" ? where + stateNote(at) : `${where} near '${at.text}'`;
4491
+ }
4492
+
4320
4493
  // src/errors.ts
4321
4494
  var FRIENDLY_MESSAGES = {
4322
4495
  SYNTAX_ERROR: "There is a syntax error in the DOT source.",
@@ -4497,9 +4670,9 @@ var Stripper = class _Stripper {
4497
4670
  */
4498
4671
  static blankLine(src, i, out) {
4499
4672
  const n = src.length;
4500
- const width = src[i] === "#" ? 1 : 2;
4501
- out.push(" ".repeat(width));
4502
- i += width;
4673
+ const width2 = src[i] === "#" ? 1 : 2;
4674
+ out.push(" ".repeat(width2));
4675
+ i += width2;
4503
4676
  while (i < n && src[i] !== "\n") {
4504
4677
  out.push(" ");
4505
4678
  i++;
@@ -4610,6 +4783,7 @@ function parse(src) {
4610
4783
  if (isPeggyError(err)) {
4611
4784
  const start = err.location.start;
4612
4785
  warnNumberAmbiguities(src, start.offset);
4786
+ console.error(syntaxErrorMessage(src, start.offset));
4613
4787
  const code = err.found === null ? "SYNTAX_UNEXPECTED_EOF" : "SYNTAX_ERROR";
4614
4788
  throw new ParseError(
4615
4789
  err instanceof Error ? err.message : String(err),
@@ -4627,8 +4801,17 @@ function parse(src) {
4627
4801
  }
4628
4802
  throw err;
4629
4803
  }
4804
+ try {
4805
+ validateEdgeOperators(src, ast.directed);
4806
+ } catch (err) {
4807
+ const offset = err instanceof ParseError ? err.location.offset : void 0;
4808
+ if (offset !== void 0) {
4809
+ warnNumberAmbiguities(src, offset);
4810
+ console.error(syntaxErrorMessage(src, offset));
4811
+ }
4812
+ throw err;
4813
+ }
4630
4814
  warnNumberAmbiguities(src, src.length);
4631
- validateEdgeOperators(src, ast.directed);
4632
4815
  return buildFromAst(ast);
4633
4816
  }
4634
4817
 
@@ -8745,20 +8928,20 @@ function rect(x, y, w, h) {
8745
8928
  function dnaY(af) {
8746
8929
  return af[2].y + (af[0].y - af[3].y) / 2;
8747
8930
  }
8748
- function nextV(af, seg2, sides) {
8749
- return seg2 + 1 < sides ? af[seg2 + 1] : af[0];
8931
+ function nextV(af, seg2, sides2) {
8932
+ return seg2 + 1 < sides2 ? af[seg2 + 1] : af[0];
8750
8933
  }
8751
- function interpolationPoints(af, sides, shape, rounded = false) {
8934
+ function interpolationPoints(af, sides2, shape, rounded = false) {
8752
8935
  let rbconst = RBCONST;
8753
- for (let seg2 = 0; seg2 < sides; seg2++) {
8936
+ for (let seg2 = 0; seg2 < sides2; seg2++) {
8754
8937
  const p0 = af[seg2];
8755
- const p1 = nextV(af, seg2, sides);
8938
+ const p1 = nextV(af, seg2, sides2);
8756
8939
  rbconst = Math.min(rbconst, Math.hypot(p1.x - p0.x, p1.y - p0.y) / 3);
8757
8940
  }
8758
8941
  const b = [];
8759
- for (let seg2 = 0; seg2 < sides; seg2++) {
8942
+ for (let seg2 = 0; seg2 < sides2; seg2++) {
8760
8943
  const p0 = af[seg2];
8761
- const p1 = nextV(af, seg2, sides);
8944
+ const p1 = nextV(af, seg2, sides2);
8762
8945
  let t = rbconst / Math.hypot(p1.x - p0.x, p1.y - p0.y);
8763
8946
  if (shape === BOX3D || shape === COMPONENT) t /= 3;
8764
8947
  else if (shape === DOGEAR) t /= 2;
@@ -8795,28 +8978,28 @@ function drawCds(af, b, coord, filled, ctx) {
8795
8978
  renderShapePolygon(D, coord, ctx, filled);
8796
8979
  }
8797
8980
  function drawDogear(af, b, coord, filled, ctx) {
8798
- const sides = af.length;
8799
- const D = new Array(sides + 1);
8800
- for (let seg2 = 1; seg2 < sides; seg2++) D[seg2] = af[seg2];
8801
- D[0] = b[3 * (sides - 1) + 4];
8802
- D[sides] = b[3 * (sides - 1) + 2];
8981
+ const sides2 = af.length;
8982
+ const D = new Array(sides2 + 1);
8983
+ for (let seg2 = 1; seg2 < sides2; seg2++) D[seg2] = af[seg2];
8984
+ D[0] = b[3 * (sides2 - 1) + 4];
8985
+ D[sides2] = b[3 * (sides2 - 1) + 2];
8803
8986
  renderShapePolygon(D, coord, ctx, filled);
8804
- const s = sides - 1;
8987
+ const s = sides2 - 1;
8805
8988
  const c0 = b[3 * s + 2];
8806
8989
  const c2 = vadd(b[3 * s + 4], vsub(c0, b[3 * s + 3]));
8807
8990
  renderShapePolyline([b[3 * s + 4], c2], coord, ctx);
8808
8991
  renderShapePolyline([c0, c2], coord, ctx);
8809
8992
  }
8810
8993
  function drawTab(af, b, coord, filled, ctx) {
8811
- const sides = af.length;
8994
+ const sides2 = af.length;
8812
8995
  const w = { x: (b[3].x - b[4].x) / 3, y: (b[3].y - b[4].y) / 3 };
8813
8996
  const D = [af[0], b[2], vadd(b[2], w), vadd(b[3], w)];
8814
- for (let seg2 = 4; seg2 < sides + 2; seg2++) D.push(af[seg2 - 2]);
8997
+ for (let seg2 = 4; seg2 < sides2 + 2; seg2++) D.push(af[seg2 - 2]);
8815
8998
  renderShapePolygon(D, coord, ctx, filled);
8816
8999
  renderShapePolyline([b[3], b[2]], coord, ctx);
8817
9000
  }
8818
9001
  function drawFolder(af, b, coord, filled, ctx) {
8819
- const sides = af.length;
9002
+ const sides2 = af.length;
8820
9003
  const dx = af[0].x - b[1].x;
8821
9004
  const wy = (b[3].y - b[4].y) / 3;
8822
9005
  const D = [
@@ -8825,7 +9008,7 @@ function drawFolder(af, b, coord, filled, ctx) {
8825
9008
  { x: af[0].x - 2 * dx, y: af[0].y + wy },
8826
9009
  { x: af[0].x - 2.25 * dx, y: b[3].y }
8827
9010
  ];
8828
- for (let seg2 = 4; seg2 < sides + 3; seg2++) D.push(af[seg2 - 3]);
9011
+ for (let seg2 = 4; seg2 < sides2 + 3; seg2++) D.push(af[seg2 - 3]);
8829
9012
  renderShapePolygon(D, coord, ctx, filled);
8830
9013
  }
8831
9014
  function drawBox3d(af, b, coord, filled, ctx) {
@@ -9175,10 +9358,10 @@ function drawRoundCorners(ring, coord, filled, ctx) {
9175
9358
  else if (ctx.rounded) roundedDraw(ring, coord, filled, ctx);
9176
9359
  }
9177
9360
  function diagonalsDraw(ring, coord, filled, ctx) {
9178
- const sides = ring.length;
9179
- const b = interpolationPoints(ring, sides, 0);
9361
+ const sides2 = ring.length;
9362
+ const b = interpolationPoints(ring, sides2, 0);
9180
9363
  renderShapePolygon(ring, coord, ctx, filled);
9181
- for (let seg2 = 0; seg2 < sides; seg2++) {
9364
+ for (let seg2 = 0; seg2 < sides2; seg2++) {
9182
9365
  renderShapePolyline([b[3 * seg2 + 2], b[3 * seg2 + 4]], coord, ctx);
9183
9366
  }
9184
9367
  }
@@ -9186,10 +9369,10 @@ function roundedDraw(ring, coord, filled, ctx) {
9186
9369
  emitRoundedBezier(ring, coord, filled, ctx);
9187
9370
  }
9188
9371
  function emitRoundedBezier(ring, coord, filled, ctx) {
9189
- const sides = ring.length;
9190
- const b = interpolationPoints(ring, sides, 0, true);
9372
+ const sides2 = ring.length;
9373
+ const b = interpolationPoints(ring, sides2, 0, true);
9191
9374
  const pts = [];
9192
- for (let seg2 = 0; seg2 < sides; seg2++) {
9375
+ for (let seg2 = 0; seg2 < sides2; seg2++) {
9193
9376
  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]);
9194
9377
  }
9195
9378
  pts.push(pts[0], pts[1]);
@@ -9319,11 +9502,11 @@ function zeroFlags() {
9319
9502
  };
9320
9503
  }
9321
9504
  var FUNLIMIT = 64;
9322
- function styleTokens(style) {
9323
- if (!style) return [];
9505
+ function styleTokens(style2) {
9506
+ if (!style2) return [];
9324
9507
  const out = [];
9325
9508
  let fun = 0;
9326
- for (const raw of style.split(",")) {
9509
+ for (const raw of style2.split(",")) {
9327
9510
  const token = raw.trim();
9328
9511
  if (token.length === 0) continue;
9329
9512
  if (fun === FUNLIMIT - 1) return [];
@@ -9357,11 +9540,11 @@ function firstSolidColor(raw) {
9357
9540
  const grad = parseGradientSpec(raw);
9358
9541
  return grad !== null ? grad[0] : raw;
9359
9542
  }
9360
- function parseStyleFlags(style) {
9543
+ function parseStyleFlags(style2) {
9361
9544
  const flags = zeroFlags();
9362
- if (!style) return flags;
9545
+ if (!style2) return flags;
9363
9546
  let fun = 0;
9364
- for (const raw of style.split(",")) {
9547
+ for (const raw of style2.split(",")) {
9365
9548
  const token = raw.trim();
9366
9549
  if (token.length === 0) continue;
9367
9550
  if (fun === FUNLIMIT - 1) return zeroFlags();
@@ -9375,10 +9558,10 @@ function parseStyleFlags(style) {
9375
9558
  }
9376
9559
  return flags;
9377
9560
  }
9378
- function styleHasInvisibleAlias(style) {
9379
- if (!style) return false;
9561
+ function styleHasInvisibleAlias(style2) {
9562
+ if (!style2) return false;
9380
9563
  let fun = 0;
9381
- for (const raw of style.split(",")) {
9564
+ for (const raw of style2.split(",")) {
9382
9565
  const token = raw.trim();
9383
9566
  if (token.length === 0) continue;
9384
9567
  if (fun === FUNLIMIT - 1) return false;
@@ -9433,9 +9616,9 @@ function findStopColor(colorlist) {
9433
9616
  const frac = seg0.hasFraction ? seg0.t : seg1.hasFraction ? 1 - seg1.t : 0;
9434
9617
  return { fillColor, stopColor, frac };
9435
9618
  }
9436
- function parseAngle(gradientangle) {
9437
- if (!gradientangle || gradientangle.length === 0) return 0;
9438
- const v = parseInt(gradientangle, 10);
9619
+ function parseAngle(gradientangle2) {
9620
+ if (!gradientangle2 || gradientangle2.length === 0) return 0;
9621
+ const v = parseInt(gradientangle2, 10);
9439
9622
  return isFinite(v) ? v : 0;
9440
9623
  }
9441
9624
  function buildResolvedFill(rawColor, flags, angle) {
@@ -9540,9 +9723,9 @@ function htmlFillPenWidth() {
9540
9723
  function resetHtmlFillPenWidth() {
9541
9724
  htmlFillPen = 1;
9542
9725
  }
9543
- function penTypeOf(style) {
9544
- if (style !== void 0 && style.includes("dashed")) return 1 /* Dashed */;
9545
- if (style !== void 0 && style.includes("dotted")) return 2 /* Dotted */;
9726
+ function penTypeOf(style2) {
9727
+ if (style2 !== void 0 && style2.includes("dashed")) return 1 /* Dashed */;
9728
+ if (style2 !== void 0 && style2.includes("dotted")) return 2 /* Dotted */;
9546
9729
  return 3 /* Solid */;
9547
9730
  }
9548
9731
  function withHtmlPaint(paint, job, drawFn) {
@@ -9573,13 +9756,13 @@ function applyHtmlFill(paint) {
9573
9756
  paintObj.gradientAngle = 0;
9574
9757
  paintObj.gradientFrac = 0;
9575
9758
  }
9576
- function mkPts(b, border, pos) {
9759
+ function mkPts(b, border2, pos) {
9577
9760
  let llx = b.ll.x + pos.x;
9578
9761
  let lly = b.ll.y + pos.y;
9579
9762
  let urx = b.ur.x + pos.x;
9580
9763
  let ury = b.ur.y + pos.y;
9581
- if (border > 1) {
9582
- const delta2 = border / 2;
9764
+ if (border2 > 1) {
9765
+ const delta2 = border2 / 2;
9583
9766
  llx += delta2;
9584
9767
  lly += delta2;
9585
9768
  urx -= delta2;
@@ -9606,26 +9789,26 @@ function doSide(p, wd, ht, renderer, job) {
9606
9789
  renderer.polygon(pts, true, job);
9607
9790
  }
9608
9791
  function doBorder(spec, renderer, job) {
9609
- const { box, pos, border, color, sides, style } = spec;
9610
- htmlFillPen = border;
9611
- withHtmlPaint({ pen: color, penWidth: border, penStyle: style }, job, () => {
9612
- if (parseStyleFlags(style).rounded) {
9613
- emitRoundedBezier(mkPts(box, border, pos), { x: 0, y: 0 }, false, { renderer, job });
9792
+ const { box, pos, border: border2, color, sides: sides2, style: style2 } = spec;
9793
+ htmlFillPen = border2;
9794
+ withHtmlPaint({ pen: color, penWidth: border2, penStyle: style2 }, job, () => {
9795
+ if (parseStyleFlags(style2).rounded) {
9796
+ emitRoundedBezier(mkPts(box, border2, pos), { x: 0, y: 0 }, false, { renderer, job });
9614
9797
  return;
9615
9798
  }
9616
- const effSides = sides !== void 0 ? sides & BORDER_MASK : 0;
9799
+ const effSides = sides2 !== void 0 ? sides2 & BORDER_MASK : 0;
9617
9800
  if (effSides !== 0) {
9618
- const corners = mkPts(box, border, pos).map((p) => transformPoint(p, job));
9801
+ const corners = mkPts(box, border2, pos).map((p) => transformPoint(p, job));
9619
9802
  emitSidedPolylines(effSides, corners, renderer, job);
9620
9803
  } else {
9621
- emitFullBoxBorder(box, pos, border, renderer, job);
9804
+ emitFullBoxBorder(box, pos, border2, renderer, job);
9622
9805
  }
9623
9806
  });
9624
9807
  }
9625
- function emitFullBoxBorder(box, pos, border, renderer, job) {
9626
- const b2 = border > 1 ? {
9627
- ll: { x: box.ll.x + border / 2, y: box.ll.y + border / 2 },
9628
- ur: { x: box.ur.x - border / 2, y: box.ur.y - border / 2 }
9808
+ function emitFullBoxBorder(box, pos, border2, renderer, job) {
9809
+ const b2 = border2 > 1 ? {
9810
+ ll: { x: box.ll.x + border2 / 2, y: box.ll.y + border2 / 2 },
9811
+ ur: { x: box.ur.x - border2 / 2, y: box.ur.y - border2 / 2 }
9629
9812
  } : box;
9630
9813
  const pts = [
9631
9814
  { x: b2.ll.x + pos.x, y: b2.ll.y + pos.y },
@@ -9660,8 +9843,8 @@ var SIDES_TABLE = /* @__PURE__ */ new Map([
9660
9843
  [T, [[NE, NW]]],
9661
9844
  [L, [[NW, SW]]]
9662
9845
  ]);
9663
- function emitSidedPolylines(sides, corners, renderer, job) {
9664
- const seqs = SIDES_TABLE.get(sides & BORDER_MASK);
9846
+ function emitSidedPolylines(sides2, corners, renderer, job) {
9847
+ const seqs = SIDES_TABLE.get(sides2 & BORDER_MASK);
9665
9848
  if (seqs === void 0) return;
9666
9849
  for (const seq2 of seqs) {
9667
9850
  renderer.polyline(seq2.map((i) => corners[i]), job);
@@ -9819,10 +10002,10 @@ function bgFillPaint(ctx) {
9819
10002
  };
9820
10003
  }
9821
10004
  function emitBgFill(ctx) {
9822
- const { box, pos, border, renderer, job } = ctx;
10005
+ const { box, pos, border: border2, renderer, job } = ctx;
9823
10006
  withHtmlPaint(bgFillPaint(ctx), job, () => {
9824
10007
  if (parseStyleFlags(ctx.style).rounded) {
9825
- emitRoundedBezier(mkPts(box, border, pos), { x: 0, y: 0 }, true, { renderer, job });
10008
+ emitRoundedBezier(mkPts(box, border2, pos), { x: 0, y: 0 }, true, { renderer, job });
9826
10009
  return;
9827
10010
  }
9828
10011
  const pts = [
@@ -9887,9 +10070,9 @@ function emitHtmlImg(img, pos, renderer, job) {
9887
10070
  }
9888
10071
  renderer.usershape?.(img.src, b, job);
9889
10072
  }
9890
- function htmlStyleInvisible(style) {
9891
- if (style === void 0) return false;
9892
- return style.split(/[ ,]+/).some((tok) => {
10073
+ function htmlStyleInvisible(style2) {
10074
+ if (style2 === void 0) return false;
10075
+ return style2.split(/[ ,]+/).some((tok) => {
9893
10076
  const t = tok.toUpperCase();
9894
10077
  return t === "INVIS" || t === "INVISIBLE";
9895
10078
  });
@@ -9963,6 +10146,218 @@ function emitHtmlLabel(placed, pos, renderer, job) {
9963
10146
  }
9964
10147
  }
9965
10148
 
10149
+ // src/common/htmltable-attr-warn.ts
10150
+ var accepted = (v) => ({ keep: v, text: [], warn: false });
10151
+ var ignored = (text) => ({ keep: void 0, text: [text], warn: true });
10152
+ var warning = (msg) => `Warning: ${msg}`;
10153
+ var lower = (s) => s.replace(/[A-Z]/g, (c) => c.toLowerCase());
10154
+ var accept = accepted;
10155
+ var STRTOL = /^[ \t\n\v\f\r]*([+-]?\d+)/;
10156
+ function doInt(v, s, min, max) {
10157
+ const m = STRTOL.exec(v);
10158
+ if (m === null) return ignored(warning(`Improper ${s} value ${v} - ignored`));
10159
+ const b = Number(m[1]);
10160
+ if (b > max) return ignored(warning(`${s} value ${v} > ${max} - too large - ignored`));
10161
+ if (b < min) return ignored(warning(`${s} value ${v} < ${min} - too small - ignored`));
10162
+ return accepted(v);
10163
+ }
10164
+ var intHandler = (s, min, max) => (v) => doInt(v, s, min, max);
10165
+ var UCHAR_MAX = 255;
10166
+ var SCHAR_MIN = -128;
10167
+ var SCHAR_MAX = 127;
10168
+ var INT8_MAX = 127;
10169
+ var USHRT_MAX = 65535;
10170
+ var GRADIENT_MAX = 360;
10171
+ var spanHandler = (s) => (v) => {
10172
+ const r = doInt(v, s, 0, USHRT_MAX);
10173
+ if (r.keep === void 0 || Number(STRTOL.exec(v)?.[1]) !== 0) return r;
10174
+ return ignored(warning(`${s} value cannot be 0 - ignored
10175
+ `));
10176
+ };
10177
+ var wordsHandler = (words, what) => (v) => words.includes(lower(v)) ? accepted(v) : ignored(warning(`Illegal value ${v} for ${what} - ignored
10178
+ `));
10179
+ var starHandler = (what) => (v) => v.startsWith("*") ? accepted(v) : ignored(warning(`Unknown value ${v} for ${what} - ignored
10180
+ `));
10181
+ var valign = wordsHandler(["bottom", "top", "middle"], "VALIGN");
10182
+ var fixedsize = wordsHandler(["true", "false"], "FIXEDSIZE");
10183
+ var tableAlign = wordsHandler(["left", "right", "center"], "ALIGN");
10184
+ var brAlign = tableAlign;
10185
+ var cellAlign = wordsHandler(["left", "right", "text", "center"], "ALIGN in TD");
10186
+ var balign = wordsHandler(["left", "right", "center"], "BALIGN in TD");
10187
+ var SIDES_LETTERS = "ltrb";
10188
+ var sides = (v) => {
10189
+ const text = [];
10190
+ for (const b of new TextEncoder().encode(v)) {
10191
+ if (SIDES_LETTERS.includes(lower(String.fromCharCode(b)))) continue;
10192
+ const code = b > SCHAR_MAX ? b - 256 : b;
10193
+ text.push(warning(`Unrecognized character '${String.fromCharCode(b)}' (${code}) in sides attribute
10194
+ `));
10195
+ }
10196
+ return { keep: v, text, warn: false };
10197
+ };
10198
+ var STYLE_WORDS = ["rounded", "radial", "solid", "invisible", "invis", "dotted", "dashed"];
10199
+ var STYLE_DELIM = " ,";
10200
+ function styleTokens2(v) {
10201
+ const out = [];
10202
+ const span = (from, member) => {
10203
+ let i = from;
10204
+ while (i < v.length && STYLE_DELIM.includes(v[i]) === member) i++;
10205
+ return i;
10206
+ };
10207
+ let end = span(0, false);
10208
+ out.push(v.slice(0, end));
10209
+ while (end < v.length) {
10210
+ const start = span(end, true);
10211
+ end = span(start, false);
10212
+ out.push(v.slice(start, end));
10213
+ }
10214
+ return out;
10215
+ }
10216
+ var style = (v) => {
10217
+ const legal = [];
10218
+ const text = [];
10219
+ for (const tk of styleTokens2(v)) {
10220
+ if (STYLE_WORDS.includes(lower(tk))) legal.push(tk);
10221
+ else text.push(warning(`Illegal value ${tk} for STYLE - ignored
10222
+ `));
10223
+ }
10224
+ return { keep: legal.length > 0 ? legal.join(" ") : void 0, text, warn: text.length > 0 };
10225
+ };
10226
+ var border = intHandler("BORDER", 0, UCHAR_MAX);
10227
+ var cellpadding = intHandler("CELLPADDING", 0, UCHAR_MAX);
10228
+ var cellspacing = intHandler("CELLSPACING", SCHAR_MIN, SCHAR_MAX);
10229
+ var gradientangle = intHandler("GRADIENTANGLE", 0, GRADIENT_MAX);
10230
+ var height = intHandler("HEIGHT", 0, USHRT_MAX);
10231
+ var width = intHandler("WIDTH", 0, USHRT_MAX);
10232
+ var TBL_ITEMS = /* @__PURE__ */ new Map([
10233
+ ["align", tableAlign],
10234
+ ["bgcolor", accept],
10235
+ ["border", border],
10236
+ ["cellborder", intHandler("CELLBORDER", 0, INT8_MAX)],
10237
+ ["cellpadding", cellpadding],
10238
+ ["cellspacing", cellspacing],
10239
+ ["color", accept],
10240
+ ["columns", starHandler("COLUMNS")],
10241
+ ["fixedsize", fixedsize],
10242
+ ["gradientangle", gradientangle],
10243
+ ["height", height],
10244
+ ["href", accept],
10245
+ ["id", accept],
10246
+ ["port", accept],
10247
+ ["rows", starHandler("ROWS")],
10248
+ ["sides", sides],
10249
+ ["style", style],
10250
+ ["target", accept],
10251
+ ["title", accept],
10252
+ ["tooltip", accept],
10253
+ ["valign", valign],
10254
+ ["width", width]
10255
+ ]);
10256
+ var CELL_ITEMS = /* @__PURE__ */ new Map([
10257
+ ["align", cellAlign],
10258
+ ["balign", balign],
10259
+ ["bgcolor", accept],
10260
+ ["border", border],
10261
+ ["cellpadding", cellpadding],
10262
+ ["cellspacing", cellspacing],
10263
+ ["color", accept],
10264
+ ["colspan", spanHandler("COLSPAN")],
10265
+ ["fixedsize", fixedsize],
10266
+ ["gradientangle", gradientangle],
10267
+ ["height", height],
10268
+ ["href", accept],
10269
+ ["id", accept],
10270
+ ["port", accept],
10271
+ ["rowspan", spanHandler("ROWSPAN")],
10272
+ ["sides", sides],
10273
+ ["style", style],
10274
+ ["target", accept],
10275
+ ["title", accept],
10276
+ ["tooltip", accept],
10277
+ ["valign", valign],
10278
+ ["width", width]
10279
+ ]);
10280
+ var FONT_ITEMS = /* @__PURE__ */ new Map([
10281
+ ["color", accept],
10282
+ ["face", accept],
10283
+ ["point-size", intHandler("POINT-SIZE", 0, UCHAR_MAX)]
10284
+ ]);
10285
+ var IMG_ITEMS = /* @__PURE__ */ new Map([["scale", accept], ["src", accept]]);
10286
+ var BR_ITEMS = /* @__PURE__ */ new Map([["align", brAlign]]);
10287
+ var ELEMENTS = /* @__PURE__ */ new Map([
10288
+ ["TABLE", { items: TBL_ITEMS, name: "<TABLE>" }],
10289
+ ["TD", { items: CELL_ITEMS, name: "<TD>" }],
10290
+ ["FONT", { items: FONT_ITEMS, name: "<FONT>" }],
10291
+ ["IMG", { items: IMG_ITEMS, name: "<IMG>" }],
10292
+ ["BR", { items: BR_ITEMS, name: "<BR>" }]
10293
+ ]);
10294
+ function checkAttrs(tag, pairs) {
10295
+ const el = ELEMENTS.get(tag);
10296
+ const attrs = {};
10297
+ const warnings = [];
10298
+ let warn = false;
10299
+ for (const [name, value] of pairs) {
10300
+ const key = lower(name);
10301
+ if (el === void 0) {
10302
+ attrs[key] = value;
10303
+ continue;
10304
+ }
10305
+ const handler = el.items.get(key);
10306
+ if (handler === void 0) {
10307
+ warnings.push(warning(`Illegal attribute ${name} in ${el.name} - ignored
10308
+ `));
10309
+ warn = true;
10310
+ continue;
10311
+ }
10312
+ const r = handler(value);
10313
+ warnings.push(...r.text);
10314
+ warn ||= r.warn;
10315
+ if (r.keep !== void 0) attrs[key] = r.keep;
10316
+ }
10317
+ return { attrs, warnings, warn };
10318
+ }
10319
+ var StderrLines = class {
10320
+ constructor(writeLine) {
10321
+ this.writeLine = writeLine;
10322
+ }
10323
+ writeLine;
10324
+ pending = "";
10325
+ write(text) {
10326
+ const parts = (this.pending + text).split("\n");
10327
+ this.pending = parts.pop() ?? "";
10328
+ for (const line of parts) this.writeLine(line);
10329
+ }
10330
+ flush() {
10331
+ if (this.pending === "") return;
10332
+ this.writeLine(this.pending);
10333
+ this.pending = "";
10334
+ }
10335
+ };
10336
+
10337
+ // src/common/htmltable-parse-state.ts
10338
+ var peek = (s) => s.tokens[s.pos];
10339
+ var emitWarnings = (s, tok) => {
10340
+ if (s.stderr === void 0 || s.emitted?.has(tok) === true) return;
10341
+ s.emitted?.add(tok);
10342
+ emitOutput(s, tok);
10343
+ };
10344
+ var emitOutput = (s, out) => {
10345
+ for (const text of out.warnings ?? []) s.stderr?.write(text);
10346
+ if (out.warn === true) s.warn = true;
10347
+ };
10348
+ var emitEof = (s) => {
10349
+ if (s.stderr === void 0 || s.eof === void 0) return;
10350
+ const out = s.eof;
10351
+ delete s.eof;
10352
+ emitOutput(s, out);
10353
+ };
10354
+ var consume = (s) => {
10355
+ const t = s.tokens[s.pos];
10356
+ s.pos++;
10357
+ if (t !== void 0) emitWarnings(s, t);
10358
+ return t;
10359
+ };
10360
+
9966
10361
  // src/common/html-entities.ts
9967
10362
  var HTML_ENTITIES = {
9968
10363
  "AElig": 198,
@@ -10242,6 +10637,286 @@ function htmlEntityUTF8(s) {
10242
10637
  });
10243
10638
  }
10244
10639
 
10640
+ // src/common/htmltable-lex-expat.ts
10641
+ var XML_ERROR_INVALID_TOKEN = "not well-formed (invalid token)";
10642
+ var XML_CONTEXT_BYTES = 1024;
10643
+ var INIT_BUFFER_SIZE = 1024;
10644
+ var COMPLETE_END = (end, dup) => dup === void 0 ? { kind: "complete", end } : { kind: "complete", end, dup };
10645
+ var PARTIAL = { kind: "partial" };
10646
+ var INVALID = (offset) => ({ kind: "invalid", offset });
10647
+ var XML_NAME = /^[A-Za-z_:\u0080-\uFFFF][\w.:\u0080-\uFFFF-]*/;
10648
+ var isSpace = (c) => c !== void 0 && /\s/.test(c);
10649
+ function skipSpace(text, i) {
10650
+ let j = i;
10651
+ while (isSpace(text[j])) j++;
10652
+ return j;
10653
+ }
10654
+ var byteLength = (s) => new TextEncoder().encode(s).length;
10655
+ function fedBytes(unit, isText) {
10656
+ if (!isText) return byteLength(unit);
10657
+ let text = unit.replace(/&([^;&<]*);/g, (m, name) => {
10658
+ return name.length >= 2 && Object.hasOwn(HTML_ENTITIES, name) ? `&#${HTML_ENTITIES[name]};` : m;
10659
+ });
10660
+ if (text.endsWith("]")) text = `${text.slice(0, -1)}&#93;`;
10661
+ return byteLength(text);
10662
+ }
10663
+ function scanValue(text, j) {
10664
+ const q = text[j];
10665
+ if (q !== '"' && q !== "'") return INVALID(j);
10666
+ const close = text.indexOf(q, j + 1);
10667
+ if (close < 0) {
10668
+ const lt = text.indexOf("<", j + 1);
10669
+ return lt >= 0 ? INVALID(lt) : PARTIAL;
10670
+ }
10671
+ const next = skipSpace(text, close + 1);
10672
+ if (next === close + 1 && !">/".includes(text[next] ?? ">")) return INVALID(next);
10673
+ return next;
10674
+ }
10675
+ function scanPair(text, i) {
10676
+ const name = XML_NAME.exec(text.slice(i))?.[0];
10677
+ if (name === void 0) return INVALID(i);
10678
+ const eq = skipSpace(text, i + name.length);
10679
+ if (eq >= text.length) return PARTIAL;
10680
+ if (text[eq] !== "=") return INVALID(eq);
10681
+ const j = skipSpace(text, eq + 1);
10682
+ if (j >= text.length) return PARTIAL;
10683
+ const next = scanValue(text, j);
10684
+ return typeof next === "number" ? { name, next } : next;
10685
+ }
10686
+ function tagEdge(text, i) {
10687
+ const c = text[i];
10688
+ if (c === void 0) return PARTIAL;
10689
+ if (c === ">") return COMPLETE_END(i + 1);
10690
+ if (c !== "/") return void 0;
10691
+ if (i + 1 >= text.length) return PARTIAL;
10692
+ return text[i + 1] === ">" ? COMPLETE_END(i + 2) : void 0;
10693
+ }
10694
+ function scanAttributes(text, from) {
10695
+ const seen = /* @__PURE__ */ new Set();
10696
+ let dup;
10697
+ let i = skipSpace(text, from);
10698
+ for (; ; ) {
10699
+ const edge = tagEdge(text, i);
10700
+ if (edge?.kind === "complete") return COMPLETE_END(edge.end, dup);
10701
+ if (edge !== void 0) return edge;
10702
+ const pair = scanPair(text, i);
10703
+ if ("kind" in pair) return pair;
10704
+ if (seen.has(pair.name)) dup ??= i;
10705
+ seen.add(pair.name);
10706
+ i = pair.next;
10707
+ }
10708
+ }
10709
+ function scanName(text, at) {
10710
+ const name = XML_NAME.exec(text.slice(at))?.[0];
10711
+ if (name === void 0) return at >= text.length ? PARTIAL : INVALID(at);
10712
+ return { next: at + name.length };
10713
+ }
10714
+ function scanStartTag(text, p) {
10715
+ const name = scanName(text, p + 1);
10716
+ if ("kind" in name) return name;
10717
+ const c = text[name.next];
10718
+ if (c === void 0) return PARTIAL;
10719
+ if (!isSpace(c) && c !== ">" && c !== "/") return INVALID(name.next);
10720
+ return scanAttributes(text, name.next);
10721
+ }
10722
+ function scanEndTag(text, p) {
10723
+ const name = scanName(text, p + 2);
10724
+ if ("kind" in name) return name;
10725
+ const i = skipSpace(text, name.next);
10726
+ if (i >= text.length) return PARTIAL;
10727
+ return text[i] === ">" ? COMPLETE_END(i + 1) : INVALID(i);
10728
+ }
10729
+ function scanPi(text, p) {
10730
+ const e = text.indexOf("?>", p + 2);
10731
+ return e < 0 ? PARTIAL : COMPLETE_END(e + 2);
10732
+ }
10733
+ function scanDeclaration(text, p) {
10734
+ const cdata = "<![CDATA[".startsWith(text.slice(p, p + 9));
10735
+ if (!cdata && text.length - p >= 3) return INVALID(p + 2);
10736
+ for (let i = p + 1; i < text.length; i++) {
10737
+ if (text[i] === ">") return COMPLETE_END(i + 1);
10738
+ if (text[i] === "<") return INVALID(i);
10739
+ }
10740
+ return PARTIAL;
10741
+ }
10742
+ function scanComment(text, p) {
10743
+ for (let i = p + 4; i < text.length; i++) {
10744
+ if (text[i] !== "-") continue;
10745
+ if (i + 1 >= text.length) return PARTIAL;
10746
+ if (text[i + 1] !== "-") continue;
10747
+ if (i + 2 >= text.length) return PARTIAL;
10748
+ return text[i + 2] === ">" ? COMPLETE_END(i + 3) : INVALID(i + 2);
10749
+ }
10750
+ return PARTIAL;
10751
+ }
10752
+ function scanMarkup(text, p) {
10753
+ const rest = text.slice(p, p + 4);
10754
+ if (rest === "<!--") return { scan: scanComment(text, p), kind: "comment" };
10755
+ if (text.length - p < 4 && "<!--".startsWith(rest)) return { scan: PARTIAL, kind: "comment" };
10756
+ if (rest.startsWith("<!-")) return { scan: INVALID(p + 3), kind: "comment" };
10757
+ const c = text[p + 1];
10758
+ if (c === "/") return { scan: scanEndTag(text, p), kind: "tag" };
10759
+ if (c === "?") return { scan: scanPi(text, p), kind: "pi" };
10760
+ if (c === "!") return { scan: scanDeclaration(text, p), kind: "tag" };
10761
+ return { scan: scanStartTag(text, p), kind: "tag" };
10762
+ }
10763
+ function scanContent(text, base) {
10764
+ const tokens = [];
10765
+ let p = 0;
10766
+ while (p < text.length) {
10767
+ if (text[p] !== "<") {
10768
+ const e = text.indexOf("<", p);
10769
+ const end = e < 0 ? text.length : e;
10770
+ tokens.push({ kind: "text", start: base + p, end: base + end });
10771
+ p = end;
10772
+ continue;
10773
+ }
10774
+ const { scan, kind } = scanMarkup(text, p);
10775
+ if (scan.kind === "invalid") return { tokens, consumed: p, invalid: base + scan.offset };
10776
+ if (scan.kind === "partial") return { tokens, consumed: p };
10777
+ const tok = { kind, start: base + p, end: base + scan.end };
10778
+ if (scan.dup !== void 0) tok.dup = base + scan.dup;
10779
+ tokens.push(tok);
10780
+ p = scan.end;
10781
+ }
10782
+ return { tokens, consumed: p };
10783
+ }
10784
+ var InputBuffer = class {
10785
+ size = 0;
10786
+ ptr = 0;
10787
+ end = 0;
10788
+ lastRequest = 0;
10789
+ /** Bytes the last attempt could not consume; 0 once something was. */
10790
+ hadBefore = 0;
10791
+ /** `XML_GetBuffer(len)` then the append of `len` bytes. */
10792
+ append(len) {
10793
+ this.lastRequest = len;
10794
+ if (len > this.size - this.end) {
10795
+ const keep = Math.min(this.ptr, XML_CONTEXT_BYTES);
10796
+ const needed = len + (this.end - this.ptr) + keep;
10797
+ if (needed > this.size) {
10798
+ let grown = this.size;
10799
+ if (grown === 0) grown = INIT_BUFFER_SIZE;
10800
+ do
10801
+ grown *= 2;
10802
+ while (grown < needed);
10803
+ this.size = grown;
10804
+ }
10805
+ this.end = this.end - this.ptr + keep;
10806
+ this.ptr = keep;
10807
+ }
10808
+ this.end += len;
10809
+ }
10810
+ /** Bytes between the read pointer and the end of the data. */
10811
+ get have() {
10812
+ return this.end - this.ptr;
10813
+ }
10814
+ /** `callProcessor`: is it worth re-reading the partial token now? */
10815
+ get enough() {
10816
+ const available = this.ptr - Math.min(this.ptr, XML_CONTEXT_BYTES) + (this.size - this.end);
10817
+ return this.have >= 2 * this.hadBefore || this.lastRequest > available;
10818
+ }
10819
+ /** After an attempt that left `remaining` bytes unconsumed. */
10820
+ consumedTo(remaining, madeProgress) {
10821
+ this.hadBefore = madeProgress ? 0 : this.have;
10822
+ this.ptr = this.end - remaining;
10823
+ }
10824
+ };
10825
+ var ExpatFeed = class {
10826
+ constructor(src) {
10827
+ this.src = src;
10828
+ }
10829
+ src;
10830
+ buffer = new InputBuffer();
10831
+ heldStart = 0;
10832
+ fedEnd = 0;
10833
+ /** Start of the token expat still holds, or undefined when it holds nothing. */
10834
+ get held() {
10835
+ return this.heldStart < this.fedEnd ? this.heldStart : void 0;
10836
+ }
10837
+ /** One `XML_Parse(parser, src[start, end), nbytes, 0)`. */
10838
+ feed(start, end, nbytes) {
10839
+ this.buffer.append(nbytes);
10840
+ this.fedEnd = end;
10841
+ if (!this.buffer.enough) return { tokens: [] };
10842
+ const text = this.src.slice(this.heldStart, end);
10843
+ const scan = scanContent(text, this.heldStart);
10844
+ if (scan.invalid !== void 0) {
10845
+ return { tokens: scan.tokens, invalid: { message: XML_ERROR_INVALID_TOKEN, offset: scan.invalid } };
10846
+ }
10847
+ this.heldStart += scan.consumed;
10848
+ this.buffer.consumedTo(byteLength(this.src.slice(this.heldStart, end)), scan.consumed > 0);
10849
+ return { tokens: scan.tokens };
10850
+ }
10851
+ };
10852
+ var XML_PREDEFINED_ENTITIES = /* @__PURE__ */ new Set(["lt", "gt", "amp", "quot", "apos"]);
10853
+ var ENTITY_NAME = /^[A-Za-z_:][\w.:-]*$/;
10854
+ function findUndefinedEntity(text) {
10855
+ for (let t = text.indexOf("&"); t >= 0; t = text.indexOf("&", t + 1)) {
10856
+ if (text[t + 1] === "#") continue;
10857
+ const semi = text.indexOf(";", t + 1);
10858
+ if (semi < 0) continue;
10859
+ const key = text.slice(t + 1, semi);
10860
+ if (ENTITY_NAME.test(key) && !Object.hasOwn(HTML_ENTITIES, key) && !XML_PREDEFINED_ENTITIES.has(key)) {
10861
+ return t;
10862
+ }
10863
+ }
10864
+ return -1;
10865
+ }
10866
+ function parseTagChunk(chunk) {
10867
+ if (!chunk.endsWith(">")) return void 0;
10868
+ const body = chunk.slice(1, -1);
10869
+ if (body.startsWith("!")) return void 0;
10870
+ const close = body.startsWith("/");
10871
+ const name = /^[^\s/>]*/.exec(close ? body.slice(1) : body)?.[0] ?? "";
10872
+ return { close, selfClose: !close && body.endsWith("/"), name };
10873
+ }
10874
+
10875
+ // src/common/htmltable-lex-units.ts
10876
+ var UNCLOSED_COMMENT = "Warning: Unclosed comment\n";
10877
+ var LABEL_CLOSED = "Warning: Label closed before end of HTML element\n";
10878
+ function eatComment(label, p) {
10879
+ let depth = 1;
10880
+ let s = p;
10881
+ while (depth > 0 && s < label.length) {
10882
+ const c = label[s++];
10883
+ if (c === "<") depth++;
10884
+ else if (c === ">") depth--;
10885
+ }
10886
+ if (depth === 0) s--;
10887
+ const warnings = [];
10888
+ if (s < label.length) {
10889
+ const t = s - 2;
10890
+ if (t < p || !label.startsWith("--", t)) warnings.push(UNCLOSED_COMMENT);
10891
+ }
10892
+ return { at: s, warnings };
10893
+ }
10894
+ function findNext(label, s) {
10895
+ let t = s + 1;
10896
+ const warnings = [];
10897
+ let warn = false;
10898
+ if (label[s] === "<") {
10899
+ if (label.startsWith("!--", t)) {
10900
+ const eaten = eatComment(label, t + 3);
10901
+ t = eaten.at;
10902
+ warnings.push(...eaten.warnings);
10903
+ warn = eaten.warnings.length > 0;
10904
+ } else {
10905
+ while (t < label.length && label[t] !== ">") t++;
10906
+ }
10907
+ if (label[t] !== ">") {
10908
+ warnings.push(LABEL_CLOSED);
10909
+ warn = true;
10910
+ } else {
10911
+ t++;
10912
+ }
10913
+ } else {
10914
+ t = s;
10915
+ while (t < label.length && label[t] !== "<") t++;
10916
+ }
10917
+ return { end: t, warnings, warn };
10918
+ }
10919
+
10245
10920
  // src/common/htmltable-lex.ts
10246
10921
  var KNOWN_TAGS = /* @__PURE__ */ new Set([
10247
10922
  "TABLE",
@@ -10268,15 +10943,15 @@ function checkTag(tag) {
10268
10943
  }
10269
10944
  }
10270
10945
  var isWs = (c) => c === " " || c === " " || c === "\n" || c === "\r";
10271
- function parseAttrs(raw) {
10272
- const out = {};
10946
+ function parseAttrPairs(raw) {
10947
+ const out = [];
10273
10948
  let i = 0;
10274
10949
  while (i < raw.length) {
10275
10950
  while (isWs(raw[i])) i++;
10276
10951
  if (i >= raw.length) break;
10277
10952
  const m = /^[\w-]+/.exec(raw.slice(i));
10278
10953
  if (m === null) throw new HtmlParseError(raw.slice(i, i + 10));
10279
- const name = m[0].toLowerCase();
10954
+ const name = m[0];
10280
10955
  i += m[0].length;
10281
10956
  while (isWs(raw[i])) i++;
10282
10957
  if (raw[i] !== "=") throw new HtmlParseError(name);
@@ -10286,7 +10961,7 @@ function parseAttrs(raw) {
10286
10961
  if (q !== '"' && q !== "'") throw new HtmlParseError(name);
10287
10962
  const end = raw.indexOf(q, i + 1);
10288
10963
  if (end < 0) throw new HtmlParseError(name);
10289
- out[name] = raw.slice(i + 1, end);
10964
+ out.push([name, raw.slice(i + 1, end)]);
10290
10965
  i = end + 1;
10291
10966
  }
10292
10967
  return out;
@@ -10305,48 +10980,36 @@ function cleanText(raw) {
10305
10980
  const isKeep = (c) => c === " " || c === " " || c === "\n" || c === "\r";
10306
10981
  return raw.replace(/[\x00-\x1f\x7f]/g, (c) => isKeep(c) ? c : "");
10307
10982
  }
10308
- function scanText(src, start, tokens) {
10309
- let j = start;
10310
- while (j < src.length && src[j] !== "<") j++;
10311
- const clean = htmlEntityUTF8(cleanText(src.slice(start, j)));
10312
- if (clean.length > 0) tokens.push({ type: "text", value: clean });
10313
- return j;
10983
+ function textTokens(raw) {
10984
+ const clean = htmlEntityUTF8(cleanText(raw));
10985
+ return clean.length > 0 ? [{ type: "text", value: clean }] : [];
10314
10986
  }
10315
- function scanTag(src, start, tokens) {
10316
- let j = start + 1;
10317
- while (j < src.length && src[j] !== ">") j++;
10318
- const inner = src.slice(start + 1, j).trim();
10319
- const next = j + 1;
10320
- if (inner.startsWith("!--")) return next;
10321
- if (inner.startsWith("/")) {
10322
- tokens.push(parseCloseToken(inner));
10323
- return next;
10324
- }
10987
+ function tagTokens(text) {
10988
+ const inner = text.slice(1, -1).trim();
10989
+ if (inner.startsWith("/")) return [parseCloseToken(inner)];
10325
10990
  if (inner.endsWith("/")) {
10326
10991
  const open = parseOpenToken(inner.slice(0, -1).trim());
10327
- tokens.push(open, { type: "close", tag: open.tag });
10328
- return next;
10992
+ return [open, { type: "close", tag: open.tag }];
10329
10993
  }
10330
- tokens.push(parseOpenToken(inner));
10331
- return next;
10994
+ return [parseOpenToken(inner)];
10995
+ }
10996
+ function openToken(tag, raw) {
10997
+ const { attrs, warnings, warn } = checkAttrs(tag, parseAttrPairs(raw));
10998
+ const tok = { type: "open", tag, attrs };
10999
+ if (warnings.length > 0) tok.warnings = warnings;
11000
+ if (warn) tok.warn = true;
11001
+ return tok;
10332
11002
  }
10333
11003
  function parseOpenToken(inner) {
10334
11004
  const sp = inner.search(/\s/);
10335
- if (sp === -1) {
10336
- const tag2 = inner.toUpperCase();
10337
- checkTag(tag2);
10338
- return { type: "open", tag: normalizeTag(tag2), attrs: parseAttrs("") };
10339
- }
10340
- const tag = inner.slice(0, sp).toUpperCase();
11005
+ const tag = (sp === -1 ? inner : inner.slice(0, sp)).toUpperCase();
10341
11006
  checkTag(tag);
10342
- return { type: "open", tag: normalizeTag(tag), attrs: parseAttrs(inner.slice(sp + 1)) };
11007
+ return openToken(normalizeTag(tag), sp === -1 ? "" : inner.slice(sp + 1));
10343
11008
  }
10344
11009
  var XML_ERROR_UNDEFINED_ENTITY = "undefined entity";
10345
11010
  var XML_ERROR_TAG_MISMATCH = "mismatched tag";
10346
- var XML_ERROR_INVALID_TOKEN = "not well-formed (invalid token)";
10347
11011
  var XML_ERROR_DUPLICATE_ATTRIBUTE = "duplicate attribute";
10348
- var XML_PREDEFINED_ENTITIES = /* @__PURE__ */ new Set(["lt", "gt", "amp", "quot", "apos"]);
10349
- var XML_NAME = /^[A-Za-z_:][\w.:-]*$/;
11012
+ var SYNTAX_ERROR = "syntax error";
10350
11013
  var HtmlLexError = class extends HtmlParseError {
10351
11014
  diagnostics;
10352
11015
  constructor(tag, message, diagnostics) {
@@ -10378,112 +11041,131 @@ function htmlErrorAtToken(message, tok) {
10378
11041
  if (info === void 0) return void 0;
10379
11042
  return htmlErrorInLine(message, chunkLine(info), info.context);
10380
11043
  }
10381
- function chunkEnd(src, i) {
10382
- const j = src[i] === "<" ? src.indexOf(">", i + 1) : src.indexOf("<", i);
10383
- if (j < 0) return src.length;
10384
- return src[i] === "<" ? j + 1 : j;
10385
- }
10386
- function findUndefinedEntity(text) {
10387
- for (let t = text.indexOf("&"); t >= 0; t = text.indexOf("&", t + 1)) {
10388
- if (text[t + 1] === "#") continue;
10389
- const semi = text.indexOf(";", t + 1);
10390
- if (semi < 0) continue;
10391
- const key = text.slice(t + 1, semi);
10392
- if (XML_NAME.test(key) && !Object.hasOwn(HTML_ENTITIES, key) && !XML_PREDEFINED_ENTITIES.has(key)) {
10393
- return t;
10394
- }
10395
- }
10396
- return -1;
10397
- }
10398
- function parseTagChunk(chunk) {
10399
- if (!chunk.endsWith(">")) return void 0;
10400
- const body = chunk.slice(1, -1);
10401
- if (body.startsWith("!")) return void 0;
10402
- const close = body.startsWith("/");
10403
- const name = /^[^\s/>]*/.exec(close ? body.slice(1) : body)?.[0] ?? "";
10404
- return { close, selfClose: !close && body.endsWith("/"), name };
10405
- }
10406
- var ATTR_NAME = /^[A-Za-z_:][\w.:-]*/;
10407
- var isSpace = (c) => c !== void 0 && /\s/.test(c);
10408
- var invalidToken = (offset) => ({ message: XML_ERROR_INVALID_TOKEN, offset });
10409
- function skipSpace(chunk, i) {
10410
- let j = i;
10411
- while (isSpace(chunk[j])) j++;
10412
- return j;
10413
- }
10414
- function readAttrPair(chunk, i) {
10415
- const name = ATTR_NAME.exec(chunk.slice(i))?.[0];
10416
- if (name === void 0) return invalidToken(i);
10417
- let j = skipSpace(chunk, i + name.length);
10418
- if (chunk[j] !== "=") return invalidToken(j);
10419
- j = skipSpace(chunk, j + 1);
10420
- const q = chunk[j];
10421
- if (q !== '"' && q !== "'") return invalidToken(j);
10422
- const end = chunk.indexOf(q, j + 1);
10423
- return end < 0 ? void 0 : { name, next: end + 1 };
10424
- }
10425
- function findAttrError(chunk, from) {
10426
- const seen = /* @__PURE__ */ new Set();
10427
- let dup;
10428
- let i = skipSpace(chunk, from);
10429
- while (chunk[i] !== ">" && !(chunk[i] === "/" && chunk[i + 1] === ">")) {
10430
- const pair = readAttrPair(chunk, i);
10431
- if (pair === void 0) return void 0;
10432
- if ("message" in pair) return pair;
10433
- if (seen.has(pair.name) && dup === void 0) dup = { message: XML_ERROR_DUPLICATE_ATTRIBUTE, offset: i };
10434
- seen.add(pair.name);
10435
- i = skipSpace(chunk, pair.next);
10436
- }
10437
- return dup;
10438
- }
10439
- function checkTagChunk(src, start, st) {
10440
- const tag = parseTagChunk(st.curr);
11044
+ function checkTagToken(site) {
11045
+ const { src, tok, st } = site;
11046
+ const tag = parseTagChunk(src.slice(tok.start, tok.end));
10441
11047
  if (tag === void 0) return;
11048
+ const context = st.prev + st.curr;
10442
11049
  if (tag.close) {
10443
11050
  if (st.stack.length > 0 && st.stack.pop() !== tag.name) {
10444
- throw htmlErrorInLine(XML_ERROR_TAG_MISMATCH, lineAt(src, start), st.prev + st.curr);
11051
+ throw htmlErrorInLine(XML_ERROR_TAG_MISMATCH, lineAt(src, tok.start), context);
10445
11052
  }
10446
11053
  } else {
10447
- const bad = findAttrError(st.curr, 1 + tag.name.length);
10448
- if (bad !== void 0) {
10449
- throw htmlErrorInLine(bad.message, lineAt(src, start + bad.offset), st.prev + st.curr);
10450
- }
11054
+ if (tok.dup !== void 0) throw htmlErrorInLine(XML_ERROR_DUPLICATE_ATTRIBUTE, lineAt(src, tok.dup), context);
10451
11055
  if (!tag.selfClose) st.stack.push(tag.name);
10452
11056
  }
10453
11057
  if (KNOWN_TAGS.has(tag.name.toUpperCase())) return;
10454
- const text = `Unknown HTML element <${tag.name}> on line ${lineAt(src, start)} `;
11058
+ const text = `Unknown HTML element <${tag.name}> on line ${lineAt(src, tok.start)} `;
10455
11059
  throw new HtmlLexError(tag.name.toUpperCase(), text, [`Error: ${text}`]);
10456
11060
  }
10457
- function checkChunk(src, start, st) {
10458
- if (st.curr.startsWith("<")) {
10459
- checkTagChunk(src, start, st);
10460
- return;
11061
+ function eventTokens(site) {
11062
+ const { src, tok, st } = site;
11063
+ const text = src.slice(tok.start, tok.end);
11064
+ if (tok.kind === "comment" || tok.kind === "pi") return [];
11065
+ if (tok.kind === "tag") {
11066
+ checkTagToken(site);
11067
+ return tagTokens(text);
10461
11068
  }
10462
- const off = findUndefinedEntity(st.curr);
11069
+ const off = findUndefinedEntity(text);
10463
11070
  if (off >= 0) {
10464
- throw htmlErrorInLine(XML_ERROR_UNDEFINED_ENTITY, lineAt(src, start + off), st.prev + st.curr);
11071
+ throw htmlErrorInLine(XML_ERROR_UNDEFINED_ENTITY, lineAt(src, tok.start + off), st.prev + st.curr);
11072
+ }
11073
+ return textTokens(text);
11074
+ }
11075
+ function attachCarry(carry, first) {
11076
+ if (carry.warnings.length > 0) first.warnings = [...carry.warnings, ...first.warnings ?? []];
11077
+ if (carry.warn) first.warn = true;
11078
+ carry.warnings = [];
11079
+ carry.warn = false;
11080
+ }
11081
+ function absorb(carry, lost) {
11082
+ for (const t of lost) {
11083
+ carry.warnings.push(...t.warnings ?? []);
11084
+ if (t.warn === true) carry.warn = true;
11085
+ }
11086
+ }
11087
+ function eventGroups(run, res) {
11088
+ const groups = [];
11089
+ for (const tok of res.tokens) {
11090
+ const tokens = eventTokens({ src: run.src, tok, st: run.st });
11091
+ if (tokens.length > 0) groups.push({ tokens, tok });
11092
+ }
11093
+ if (res.invalid !== void 0) {
11094
+ const { message, offset } = res.invalid;
11095
+ throw htmlErrorInLine(message, lineAt(run.src, offset), run.st.prev + run.st.curr);
11096
+ }
11097
+ return groups;
11098
+ }
11099
+ function deliver(run, last) {
11100
+ const first = last.tokens[0];
11101
+ attachCarry(run.carry, first);
11102
+ const info = { src: run.src, pos: last.tok.start, end: last.tok.end, context: run.st.prev + run.st.curr };
11103
+ const prev = run.tokens.at(-1);
11104
+ if (prev?.type === "text" && first.type === "text") {
11105
+ appendString(prev, first);
11106
+ chunkInfo.set(prev, { ...info, pos: chunkInfo.get(prev)?.pos ?? info.pos });
11107
+ return;
10465
11108
  }
11109
+ for (const t of last.tokens) chunkInfo.set(t, info);
11110
+ run.tokens.push(...last.tokens);
10466
11111
  }
10467
- function tokenizeDeferred(src) {
10468
- const tokens = [];
10469
- const st = { stack: [], prev: "", curr: "" };
10470
- let i = 0;
11112
+ function runEvents(run, res) {
11113
+ const groups = eventGroups(run, res);
11114
+ const last = groups.pop();
11115
+ for (const g of groups) absorb(run.carry, g.tokens);
11116
+ if (last !== void 0) deliver(run, last);
11117
+ }
11118
+ function appendString(into, more) {
11119
+ into.value += more.value;
11120
+ if (more.warnings !== void 0) into.warnings = [...into.warnings ?? [], ...more.warnings];
11121
+ if (more.warn === true) into.warn = true;
11122
+ }
11123
+ function* lexUnits(src, label) {
11124
+ if (label.start > 0) yield { start: 0, end: label.start, warnings: [], warn: false };
11125
+ const text = src.slice(label.start, label.end);
11126
+ for (let at = 0; at < text.length; ) {
11127
+ const u = findNext(text, at);
11128
+ yield { start: label.start + at, end: label.start + u.end, warnings: u.warnings, warn: u.warn };
11129
+ at = u.end;
11130
+ }
11131
+ if (label.end < src.length) yield { start: label.end, end: src.length, warnings: [], warn: false };
11132
+ }
11133
+ function unfinishedError(run, held) {
11134
+ return htmlErrorInLine(SYNTAX_ERROR, lineAt(run.src, held), run.st.prev + run.st.curr);
11135
+ }
11136
+ var eofOutput = (carry) => {
11137
+ if (carry.warnings.length === 0 && !carry.warn) return void 0;
11138
+ return carry.warn ? { warnings: carry.warnings, warn: true } : { warnings: carry.warnings };
11139
+ };
11140
+ function tokenizeDeferred(src, label = { start: 0, end: src.length }) {
11141
+ const run = {
11142
+ src,
11143
+ tokens: [],
11144
+ st: { stack: [], prev: "", curr: "" },
11145
+ expat: new ExpatFeed(src),
11146
+ carry: { warnings: [], warn: false }
11147
+ };
11148
+ let error;
10471
11149
  try {
10472
- while (i < src.length) {
10473
- const first = tokens.length;
10474
- const start = i;
10475
- st.prev = st.curr;
10476
- st.curr = src.slice(i, chunkEnd(src, i));
10477
- checkChunk(src, i, st);
10478
- i = src[i] === "<" ? scanTag(src, i, tokens) : scanText(src, i, tokens);
10479
- const info = { src, pos: start, end: i, context: st.prev + st.curr };
10480
- for (let k = first; k < tokens.length; k++) chunkInfo.set(tokens[k], info);
10481
- }
11150
+ for (const u of lexUnits(src, label)) {
11151
+ run.st.prev = run.st.curr;
11152
+ run.st.curr = src.slice(u.start, u.end);
11153
+ run.carry.warnings.push(...u.warnings);
11154
+ if (u.warn) run.carry.warn = true;
11155
+ const nbytes = fedBytes(run.st.curr, !run.st.curr.startsWith("<"));
11156
+ runEvents(run, run.expat.feed(u.start, u.end, nbytes));
11157
+ }
11158
+ const held = run.expat.held;
11159
+ if (held !== void 0) error = unfinishedError(run, held);
10482
11160
  } catch (e) {
10483
- if (e instanceof HtmlParseError) return { tokens, error: e };
10484
- throw e;
11161
+ if (!(e instanceof HtmlParseError)) throw e;
11162
+ error = e;
10485
11163
  }
10486
- return { tokens };
11164
+ const result = { tokens: run.tokens };
11165
+ if (error !== void 0) result.error = error;
11166
+ const eof = eofOutput(run.carry);
11167
+ if (eof !== void 0) result.eof = eof;
11168
+ return result;
10487
11169
  }
10488
11170
 
10489
11171
  // src/common/htmltable-parse-attrs.ts
@@ -10523,15 +11205,9 @@ var parseSides = (v) => {
10523
11205
  if (flags === 0 || flags === BORDER_MASK) return void 0;
10524
11206
  return flags;
10525
11207
  };
10526
- var parseGradientAngle = (v) => {
10527
- if (v === void 0) return void 0;
10528
- const n = parseInt(v, 10);
10529
- if (isNaN(n) || String(n) !== v.trim()) return void 0;
10530
- if (n < 0 || n > 360) return void 0;
10531
- return n;
10532
- };
10533
- var parseColumns = (v) => v === "*" ? true : void 0;
10534
- var parseRows = (v) => v === "*" ? true : void 0;
11208
+ var parseGradientAngle = (v) => num(v);
11209
+ var parseColumns = (v) => v?.startsWith("*") === true ? true : void 0;
11210
+ var parseRows = (v) => v?.startsWith("*") === true ? true : void 0;
10535
11211
  var buildCell = (content, a) => ({
10536
11212
  kind: "cell",
10537
11213
  content,
@@ -10583,7 +11259,7 @@ var buildTable = (rows, a) => ({
10583
11259
  hrule: parseRows(a["rows"])
10584
11260
  });
10585
11261
 
10586
- // src/common/htmltable-parse.ts
11262
+ // src/common/htmltable-parse-font.ts
10587
11263
  var definedOf = (s) => Object.fromEntries(
10588
11264
  Object.entries(s).filter(([, v]) => v !== void 0)
10589
11265
  );
@@ -10607,17 +11283,6 @@ var fontItemProps = (f) => {
10607
11283
  if (f.fontSize !== void 0) out.fontSize = f.fontSize;
10608
11284
  return out;
10609
11285
  };
10610
- var MSG_SYNTAX_ERROR = "syntax error";
10611
- var MSG_TEXT_BEFORE_TABLE = "Syntax error: non-space string used before <TABLE>";
10612
- var MSG_TEXT_AFTER_TABLE = "Syntax error: non-space string used after </TABLE>";
10613
- var nonSpace = (text) => /[^ \t\n\r]/.test(text);
10614
- var parseError = (s, tok, message) => (tok === void 0 ? s.pending : htmlErrorAtToken(message, tok)) ?? new HtmlParseError(message);
10615
- var peek = (s) => s.tokens[s.pos];
10616
- var consume = (s) => {
10617
- const t = s.tokens[s.pos];
10618
- s.pos++;
10619
- return t;
10620
- };
10621
11286
  var isInlineTag = (tag) => ["B", "I", "U", "O", "S", "SUB", "SUP"].includes(tag);
10622
11287
  var inlineFontState = (tag, _attrs) => {
10623
11288
  const fs = {};
@@ -10630,6 +11295,35 @@ var inlineFontState = (tag, _attrs) => {
10630
11295
  if (tag === "SUP") fs.superscript = true;
10631
11296
  return fs;
10632
11297
  };
11298
+ var wrapperFont = (t, fontStack) => {
11299
+ const font = fontStack[fontStack.length - 1] ?? {};
11300
+ if (t.tag !== "FONT") return mergeFontState(font, inlineFontState(t.tag, t.attrs));
11301
+ return mergeFontState(font, {
11302
+ fontColor: t.attrs["color"],
11303
+ fontFace: t.attrs["face"],
11304
+ fontSize: num(t.attrs["point-size"])
11305
+ });
11306
+ };
11307
+ var tableFont = (fontStack) => {
11308
+ if (fontStack.length < 2) return void 0;
11309
+ const { fontColor, fontFace, fontSize } = fontStack[fontStack.length - 1];
11310
+ const font = {};
11311
+ if (fontColor !== void 0) font.fontColor = fontColor;
11312
+ if (fontFace !== void 0) font.fontFace = fontFace;
11313
+ if (fontSize !== void 0) font.fontSize = fontSize;
11314
+ return font;
11315
+ };
11316
+
11317
+ // src/common/htmltable-parse.ts
11318
+ var MSG_SYNTAX_ERROR = "syntax error";
11319
+ var MSG_TEXT_BEFORE_TABLE = "Syntax error: non-space string used before <TABLE>";
11320
+ var MSG_TEXT_AFTER_TABLE = "Syntax error: non-space string used after </TABLE>";
11321
+ var nonSpace = (text) => /[^ \t\n\r]/.test(text);
11322
+ var parseError = (s, tok, message) => {
11323
+ if (tok !== void 0) emitWarnings(s, tok);
11324
+ else emitEof(s);
11325
+ return (tok === void 0 ? s.pending : htmlErrorAtToken(message, tok)) ?? new HtmlParseError(message);
11326
+ };
10633
11327
  var consumeClose = (s, tag) => {
10634
11328
  const nxt = peek(s);
10635
11329
  if (nxt === void 0) return;
@@ -10700,6 +11394,45 @@ var parseText = (s, fontStack) => {
10700
11394
  }
10701
11395
  return { kind: "text", items };
10702
11396
  };
11397
+ var FONTTABLE_TAGS = ["FONT", "B", "I", "U", "O"];
11398
+ var fontTableWrapper = (s) => {
11399
+ const open = peek(s);
11400
+ if (open?.type !== "open" || !FONTTABLE_TAGS.includes(open.tag)) return void 0;
11401
+ let i = s.pos + 1;
11402
+ while (s.tokens[i]?.type === "text") i++;
11403
+ const next = s.tokens[i];
11404
+ return next?.type === "open" && next.tag === "TABLE" ? open : void 0;
11405
+ };
11406
+ var skipStrings = (s) => {
11407
+ let found = false;
11408
+ for (let t = peek(s); t?.type === "text"; t = peek(s)) {
11409
+ consume(s);
11410
+ if (nonSpace(t.value)) found = true;
11411
+ }
11412
+ return found;
11413
+ };
11414
+ var parseFontTable = (s, open, fontStack) => {
11415
+ consume(s);
11416
+ fontStack.push(wrapperFont(open, fontStack));
11417
+ const textBefore = skipStrings(s);
11418
+ const tblTok = peek(s);
11419
+ if (textBefore && tblTok !== void 0) throw parseError(s, tblTok, MSG_TEXT_BEFORE_TABLE);
11420
+ const table = parseTable(s, fontStack);
11421
+ const textAfter = skipStrings(s);
11422
+ const close = peek(s);
11423
+ if (close !== void 0 && textAfter) throw parseError(s, close, MSG_TEXT_AFTER_TABLE);
11424
+ if (close?.type !== "close" || close.tag !== open.tag) throw parseError(s, close, MSG_SYNTAX_ERROR);
11425
+ consume(s);
11426
+ fontStack.pop();
11427
+ return table;
11428
+ };
11429
+ var rejectTableAfterTag = (s, start) => {
11430
+ const nxt = peek(s);
11431
+ if (nxt?.type !== "open" || nxt.tag !== "TABLE") return;
11432
+ if (s.tokens.slice(start, s.pos).some((t) => t.type !== "text")) {
11433
+ throw parseError(s, nxt, MSG_SYNTAX_ERROR);
11434
+ }
11435
+ };
10703
11436
  var parseImgContent = (s, t, cellAttrs) => {
10704
11437
  consume(s);
10705
11438
  const img = {
@@ -10721,6 +11454,7 @@ var scanCellText = (s, t, fontStack, st) => {
10721
11454
  const start = s.pos;
10722
11455
  const txt = parseText(s, fontStack);
10723
11456
  if (s.pos === start) throw parseError(s, t, MSG_SYNTAX_ERROR);
11457
+ rejectTableAfterTag(s, start);
10724
11458
  if (txt.items.some((i) => i.text !== void 0 && nonSpace(i.text))) st.textNonSpace = true;
10725
11459
  st.kind = "text";
10726
11460
  return txt.items.length > 0 ? [txt] : [];
@@ -10737,7 +11471,13 @@ var scanCellImage = (s, t, cellAttrs, st) => {
10737
11471
  return [parseImgContent(s, t, cellAttrs)];
10738
11472
  };
10739
11473
  var scanCellItem = (s, t, cellAttrs, fontStack, st) => {
11474
+ if (st.kind === "fonttable") throw parseError(s, t, MSG_SYNTAX_ERROR);
10740
11475
  if (st.kind === "table") return scanAfterTable(s, t, st);
11476
+ const wrapper = st.kind === "none" ? fontTableWrapper(s) : void 0;
11477
+ if (wrapper !== void 0) {
11478
+ st.kind = "fonttable";
11479
+ return [parseFontTable(s, wrapper, fontStack)];
11480
+ }
10741
11481
  if (t.type === "open" && t.tag === "TABLE") return scanCellTable(s, t, fontStack, st);
10742
11482
  if (t.type === "open" && t.tag === "IMG") return scanCellImage(s, t, cellAttrs, st);
10743
11483
  if (st.kind === "image") throw parseError(s, t, MSG_SYNTAX_ERROR);
@@ -10840,7 +11580,10 @@ var parseTable = (s, fontStack) => {
10840
11580
  for (let t = peek(s); t !== void 0; t = peek(s)) {
10841
11581
  if (scanTableToken(s, t, fontStack, ts)) break;
10842
11582
  }
10843
- return buildTable(ts.rows, open.attrs);
11583
+ const table = buildTable(ts.rows, open.attrs);
11584
+ const font = tableFont(fontStack);
11585
+ if (font !== void 0) table.font = font;
11586
+ return table;
10844
11587
  };
10845
11588
  var parseTableRow = (s, fontStack, opts) => {
10846
11589
  const row = parseRow(s, fontStack);
@@ -10880,6 +11623,14 @@ var finishTableLabel = (s) => {
10880
11623
  if (nxt.type !== "close" || nxt.tag !== "HTML") throw parseError(s, nxt, MSG_SYNTAX_ERROR);
10881
11624
  consume(s);
10882
11625
  };
11626
+ var parseFontTableLabel = (s, open, fontStack) => {
11627
+ const table = parseFontTable(s, open, fontStack);
11628
+ const nxt = peek(s);
11629
+ if (nxt === void 0) return { kind: "table", table };
11630
+ if (nxt.type !== "close" || nxt.tag !== "HTML") throw parseError(s, nxt, MSG_SYNTAX_ERROR);
11631
+ consume(s);
11632
+ return { kind: "table", table };
11633
+ };
10883
11634
  var parseTableLabel = (s, fontStack) => {
10884
11635
  skipLeadingWs(s);
10885
11636
  const table = parseTable(s, fontStack);
@@ -10888,17 +11639,16 @@ var parseTableLabel = (s, fontStack) => {
10888
11639
  };
10889
11640
  var parseTextLabel = (s, fontStack) => {
10890
11641
  const texts = [];
11642
+ const start = s.pos;
10891
11643
  const txt = parseText(s, fontStack);
10892
11644
  if (txt.items.length > 0) texts.push(txt);
10893
11645
  const nxt = peek(s);
10894
11646
  if (nxt === void 0) return { kind: "text", texts };
10895
11647
  if (nxt.type === "open" && nxt.tag === "TABLE") {
10896
- if (txt.items.some((i) => i.text !== void 0 && nonSpace(i.text))) {
10897
- throw parseError(s, nxt, MSG_TEXT_BEFORE_TABLE);
10898
- }
10899
- throw new HtmlParseError("TABLE");
11648
+ rejectTableAfterTag(s, start);
11649
+ throw parseError(s, nxt, MSG_TEXT_BEFORE_TABLE);
10900
11650
  }
10901
- if (nxt.type !== "close" || nxt.tag !== "HTML") throw parseError(s, nxt, MSG_SYNTAX_ERROR);
11651
+ if (nxt.type !== "close" || nxt.tag !== "HTML" || s.pos === start) throw parseError(s, nxt, MSG_SYNTAX_ERROR);
10902
11652
  consume(s);
10903
11653
  return { kind: "text", texts };
10904
11654
  };
@@ -10906,23 +11656,38 @@ var parseTokens = (s) => {
10906
11656
  const fontStack = [{}];
10907
11657
  const htmlOpen = consume(s);
10908
11658
  if (htmlOpen.type !== "open" || htmlOpen.tag !== "HTML") throw new HtmlParseError("HTML");
11659
+ const wrapper = fontTableWrapper(s);
11660
+ if (wrapper !== void 0) return parseFontTableLabel(s, wrapper, fontStack);
10909
11661
  const firstReal = findFirstRealToken(s.tokens, s.pos);
10910
11662
  if (firstReal?.type === "open" && firstReal.tag === "TABLE") return parseTableLabel(s, fontStack);
10911
11663
  return parseTextLabel(s, fontStack);
10912
11664
  };
10913
- var parseHtmlLabel = (src) => {
10914
- const { tokens, error } = tokenizeDeferred(`<HTML>${src}</HTML>`);
10915
- const s = { tokens, pos: 0, pending: error };
10916
- let label;
11665
+ var parseHtmlLabelRv = (src, writeLine = (line) => console.warn(line)) => {
11666
+ const { tokens, error, eof } = tokenizeDeferred(`<HTML>${src}</HTML>`, { start: 6, end: 6 + src.length });
11667
+ const s = {
11668
+ tokens,
11669
+ pos: 0,
11670
+ pending: error,
11671
+ stderr: new StderrLines(writeLine),
11672
+ emitted: /* @__PURE__ */ new WeakSet(),
11673
+ warn: false,
11674
+ eof
11675
+ };
10917
11676
  try {
10918
- label = parseTokens(s);
11677
+ const label = parseTokens(s);
11678
+ if (error !== void 0) throw error;
11679
+ return { label, warn: s.warn === true };
10919
11680
  } catch (e) {
10920
- if (error !== void 0 && s.pos >= tokens.length) throw error;
11681
+ if (error !== void 0 && s.pos >= tokens.length) {
11682
+ emitEof(s);
11683
+ throw error;
11684
+ }
10921
11685
  throw e;
11686
+ } finally {
11687
+ s.stderr?.flush();
10922
11688
  }
10923
- if (error !== void 0) throw error;
10924
- return label;
10925
11689
  };
11690
+ var parseHtmlLabel = (src) => parseHtmlLabelRv(src, () => void 0).label;
10926
11691
 
10927
11692
  // src/gvc/usershape.ts
10928
11693
  var activeSizer = null;
@@ -10987,6 +11752,41 @@ var PointSet = class {
10987
11752
  }
10988
11753
  };
10989
11754
 
11755
+ // src/common/htmltable-fontinfo.ts
11756
+ var SIZE_SAVEF = { fontsize: 0 };
11757
+ var EMIT_SAVEF = { fontsize: 0 };
11758
+ var pushFontInfo = (env, fp, savp) => {
11759
+ if (fp.fontFace !== void 0) {
11760
+ savp.fontname = env.fontname;
11761
+ env.fontname = fp.fontFace;
11762
+ } else savp.fontname = void 0;
11763
+ if (env.fontcolor !== void 0) {
11764
+ if (fp.fontColor !== void 0) {
11765
+ savp.fontcolor = env.fontcolor;
11766
+ env.fontcolor = fp.fontColor;
11767
+ } else savp.fontcolor = void 0;
11768
+ }
11769
+ if (env.fontsize >= 0) {
11770
+ if (fp.fontSize !== void 0 && fp.fontSize >= 0) {
11771
+ savp.fontsize = env.fontsize;
11772
+ env.fontsize = fp.fontSize;
11773
+ } else savp.fontsize = -1;
11774
+ }
11775
+ };
11776
+ var popFontInfo = (env, savp) => {
11777
+ if (savp.fontname !== void 0) env.fontname = savp.fontname;
11778
+ if (savp.fontcolor !== void 0) env.fontcolor = savp.fontcolor;
11779
+ if (savp.fontsize >= 0) env.fontsize = savp.fontsize;
11780
+ };
11781
+ var withTableFont = (env, font, slot, fn) => {
11782
+ if (font === void 0) return fn();
11783
+ const savp = slot === "size" ? SIZE_SAVEF : EMIT_SAVEF;
11784
+ pushFontInfo(env, font, savp);
11785
+ const r = fn();
11786
+ popFontInfo(env, savp);
11787
+ return r;
11788
+ };
11789
+
10990
11790
  // src/common/htmltable.ts
10991
11791
  var DEFAULT_BORDER = 1;
10992
11792
  var DEFAULT_CELLPADDING = 2;
@@ -11012,7 +11812,7 @@ var findCol = (ps, row, startCol, colspan, rowspan) => {
11012
11812
  }
11013
11813
  return col;
11014
11814
  };
11015
- var DEFAULT_SIZE_ENV = { fontsize: DEFAULT_FONTSIZE, fontname: "" };
11815
+ var defaultSizeEnv = () => ({ fontsize: DEFAULT_FONTSIZE, fontname: "" });
11016
11816
  var itemFont = (item, env) => ({
11017
11817
  fs: item.fontSize !== void 0 ? item.fontSize : env.fontsize,
11018
11818
  face: item.fontFace !== void 0 ? item.fontFace : env.fontname
@@ -11075,7 +11875,7 @@ var htmlTextIsSimple = (texts, env) => {
11075
11875
  }
11076
11876
  return true;
11077
11877
  };
11078
- var sizeTextContent = (texts, measurer, env = DEFAULT_SIZE_ENV) => {
11878
+ var sizeTextContent = (texts, measurer, env = defaultSizeEnv()) => {
11079
11879
  const lines = splitSizedLines(texts, measurer, env);
11080
11880
  const simple = htmlTextIsSimple(texts, env);
11081
11881
  let w = 0;
@@ -11244,18 +12044,18 @@ var sumTableDims = (a) => {
11244
12044
  for (let i = 0; i < a.nrows; i++) ht += a.heights[i];
11245
12045
  return { wd, ht };
11246
12046
  };
11247
- var layoutHtmlTable = (tbl, measurer, env = DEFAULT_SIZE_ENV) => {
12047
+ var layoutHtmlTable = (tbl, measurer, env = defaultSizeEnv()) => {
11248
12048
  const spacing = getSpacing(tbl);
11249
- const border = getBorder(tbl);
12049
+ const border2 = getBorder(tbl);
11250
12050
  const { entries, rv } = buildLayouts(tbl, measurer, env);
11251
12051
  if (entries.length === 0) {
11252
- return { entries, widths: [], heights: [], spacing, border, rv };
12052
+ return { entries, widths: [], heights: [], spacing, border: border2, rv };
11253
12053
  }
11254
12054
  const ncols = Math.max(...entries.map((e) => e.col + e.colspan));
11255
12055
  const nrows = Math.max(...entries.map((e) => e.row + e.rowspan));
11256
12056
  const widths = setColWidths(entries, ncols, spacing);
11257
12057
  const heights = setRowHeights(entries, nrows, spacing);
11258
- return { entries, widths, heights, spacing, border, rv };
12058
+ return { entries, widths, heights, spacing, border: border2, rv };
11259
12059
  };
11260
12060
  var warnFixedTable = (tbl, dims) => {
11261
12061
  const warn = !sizeWarned.has(tbl);
@@ -11269,17 +12069,17 @@ var warnFixedTable = (tbl, dims) => {
11269
12069
  if (warn) console.warn(WARN_TABLE_UNSPECIFIED);
11270
12070
  return 1;
11271
12071
  };
11272
- var sizeTableInner = (tbl, measurer, env) => {
11273
- const { entries, widths, heights, spacing, border, rv } = layoutHtmlTable(tbl, measurer, env);
12072
+ var sizeTableBody = (tbl, measurer, env) => {
12073
+ const { entries, widths, heights, spacing, border: border2, rv } = layoutHtmlTable(tbl, measurer, env);
11274
12074
  if (entries.length === 0) {
11275
- const fixed2 = warnFixedTable(tbl, sumTableDims({ widths, heights, ncols: 0, nrows: 0, spacing, border }));
12075
+ const fixed2 = warnFixedTable(tbl, sumTableDims({ widths, heights, ncols: 0, nrows: 0, spacing, border: border2 }));
11276
12076
  tbl.dimen = { w: 0, h: 0 };
11277
12077
  return rv | fixed2;
11278
12078
  }
11279
12079
  const ncols = Math.max(...entries.map((e) => e.col + e.colspan));
11280
12080
  const nrows = Math.max(...entries.map((e) => e.row + e.rowspan));
11281
12081
  for (const e of entries) e.cell.dimen = { w: e.w, h: e.h };
11282
- const { wd, ht } = sumTableDims({ widths, heights, ncols, nrows, spacing, border });
12082
+ const { wd, ht } = sumTableDims({ widths, heights, ncols, nrows, spacing, border: border2 });
11283
12083
  const baseWd = tbl.width !== void 0 ? tbl.width : 0;
11284
12084
  const baseHt = tbl.height !== void 0 ? tbl.height : 0;
11285
12085
  const fixed = warnFixedTable(tbl, { wd, ht });
@@ -11290,7 +12090,8 @@ var sizeTableInner = (tbl, measurer, env) => {
11290
12090
  };
11291
12091
  return rv | fixed;
11292
12092
  };
11293
- var sizeHtmlLabel = (label, measurer, env = DEFAULT_SIZE_ENV) => {
12093
+ var sizeTableInner = (tbl, measurer, env) => withTableFont(env, tbl.font, "size", () => sizeTableBody(tbl, measurer, env));
12094
+ var sizeHtmlLabel = (label, measurer, env = defaultSizeEnv()) => {
11294
12095
  if (label.kind === "table") {
11295
12096
  const rv = sizeTableInner(label.table, measurer, env);
11296
12097
  label.dimen = label.table.dimen;
@@ -16142,8 +16943,8 @@ function normalizeFontName(name) {
16142
16943
  for (let i = 0; i < name.length; i++) {
16143
16944
  const ch = name[i];
16144
16945
  const code = ch.charCodeAt(0);
16145
- const isLetter2 = code >= 65 && code <= 90 || code >= 97 && code <= 122;
16146
- if (isLetter2) result += ch.toLowerCase();
16946
+ const isLetter3 = code >= 65 && code <= 90 || code >= 97 && code <= 122;
16947
+ if (isLetter3) result += ch.toLowerCase();
16147
16948
  }
16148
16949
  return result;
16149
16950
  }
@@ -16223,30 +17024,30 @@ function fontFamilyAttrs(fontName, mode = FontnameKind.NativeFonts) {
16223
17024
  if (a === null) return null;
16224
17025
  let family;
16225
17026
  let weight;
16226
- let style;
17027
+ let style2;
16227
17028
  switch (mode) {
16228
17029
  case FontnameKind.PsFonts:
16229
17030
  family = a.name;
16230
17031
  weight = a.weight;
16231
- style = a.style;
17032
+ style2 = a.style;
16232
17033
  break;
16233
17034
  case FontnameKind.SvgFonts:
16234
17035
  family = a.svgFontFamily;
16235
17036
  weight = a.svgFontWeight;
16236
- style = a.svgFontStyle;
17037
+ style2 = a.svgFontStyle;
16237
17038
  break;
16238
17039
  default:
16239
17040
  family = a.family;
16240
17041
  weight = a.weight;
16241
- style = a.style;
17042
+ style2 = a.style;
16242
17043
  break;
16243
17044
  }
16244
17045
  const fam = a.svgFontFamily !== family ? family + "," + a.svgFontFamily : family;
16245
17046
  let attrs = ' font-family="' + fam + '"';
16246
17047
  if (weight !== null) attrs += ' font-weight="' + weight + '"';
16247
17048
  if (a.stretch !== null) attrs += ' font-stretch="' + a.stretch + '"';
16248
- if (style !== null) attrs += ' font-style="' + style + '"';
16249
- return { attrs, weight: weight !== null, style: style !== null };
17049
+ if (style2 !== null) attrs += ' font-style="' + style2 + '"';
17050
+ return { attrs, weight: weight !== null, style: style2 !== null };
16250
17051
  }
16251
17052
 
16252
17053
  // src/common/css-font.ts
@@ -16635,8 +17436,8 @@ function alignContentBox(box, cell2, w, h) {
16635
17436
  var HTML_ALL_SIDES = TOP | BOTTOM | LEFT | RIGHT;
16636
17437
  function placeCellRuns(ctx) {
16637
17438
  const { cell: cell2, tbl, box, finfo, measurer } = ctx;
16638
- const border = cellBorder(cell2, tbl);
16639
- const inset = border + cellPad(cell2, tbl);
17439
+ const border2 = cellBorder(cell2, tbl);
17440
+ const inset = border2 + cellPad(cell2, tbl);
16640
17441
  const cbox = {
16641
17442
  ll: { x: box.ll.x + inset, y: box.ll.y + inset },
16642
17443
  ur: { x: box.ur.x - inset, y: box.ur.y - inset }
@@ -16685,17 +17486,17 @@ function placeCellNested(ctx) {
16685
17486
  ll: { x: box.ll.x + inset, y: box.ll.y + inset },
16686
17487
  ur: { x: box.ur.x - inset, y: box.ur.y - inset }
16687
17488
  };
16688
- return posHtmlTable(nested2, finfo, measurer, cbox, sidesMask);
17489
+ return withTableFont(finfo, nested2.font, "emit", () => posHtmlTable(nested2, finfo, measurer, cbox, sidesMask));
16689
17490
  }
16690
17491
  function placeCell(ctx) {
16691
17492
  const { cell: cell2, tbl, box, col, row, colspan, rowspan } = ctx;
16692
- const border = cellBorder(cell2, tbl);
17493
+ const border2 = cellBorder(cell2, tbl);
16693
17494
  const vruled = cell2.vruled;
16694
17495
  const nested2 = placeCellNested(ctx);
16695
17496
  const image = nested2 === void 0 ? placeCellImage(cell2, tbl, box) : void 0;
16696
17497
  return {
16697
17498
  box,
16698
- border,
17499
+ border: border2,
16699
17500
  lines: nested2 === void 0 ? placeCellRuns(ctx) : [],
16700
17501
  image,
16701
17502
  nested: nested2,
@@ -16725,18 +17526,18 @@ function distributeExtra(sizes, del, count) {
16725
17526
  const plus = r >= 0 ? Math.floor(r + 0.5) : Math.ceil(r - 0.5);
16726
17527
  return sizes.map((w, i) => w + extra + (i < plus ? 1 : 0));
16727
17528
  }
16728
- function buildColX(pos, border, spacing, widths) {
17529
+ function buildColX(pos, border2, spacing, widths) {
16729
17530
  const colX = [];
16730
- let x = pos.ll.x + border + spacing;
17531
+ let x = pos.ll.x + border2 + spacing;
16731
17532
  for (let i = 0; i < widths.length; i++) {
16732
17533
  colX[i] = x;
16733
17534
  x += widths[i] + spacing;
16734
17535
  }
16735
17536
  return colX;
16736
17537
  }
16737
- function buildRowY(pos, border, spacing, heights) {
17538
+ function buildRowY(pos, border2, spacing, heights) {
16738
17539
  const rowY = [];
16739
- let y = pos.ur.y - border - spacing;
17540
+ let y = pos.ur.y - border2 - spacing;
16740
17541
  for (let i = 0; i < heights.length; i++) {
16741
17542
  rowY[i] = y;
16742
17543
  y -= heights[i] + spacing;
@@ -16756,14 +17557,14 @@ function tblDecoration(tbl) {
16756
17557
  gradientangle: tbl.gradientangle
16757
17558
  };
16758
17559
  }
16759
- function cellSidesMask(e, ncols, nrows, sides) {
16760
- if (sides === 0) return 0;
17560
+ function cellSidesMask(e, ncols, nrows, sides2) {
17561
+ if (sides2 === 0) return 0;
16761
17562
  let mask = 0;
16762
17563
  if (e.col === 0) mask |= LEFT;
16763
17564
  if (e.row === 0) mask |= TOP;
16764
17565
  if (e.col + e.colspan === ncols) mask |= RIGHT;
16765
17566
  if (e.row + e.rowspan === nrows) mask |= BOTTOM;
16766
- return sides & mask;
17567
+ return sides2 & mask;
16767
17568
  }
16768
17569
  function ruledBoundaries(tbl) {
16769
17570
  const bits = /* @__PURE__ */ new Set();
@@ -16773,7 +17574,7 @@ function ruledBoundaries(tbl) {
16773
17574
  return bits;
16774
17575
  }
16775
17576
  function placeCells(ctx) {
16776
- const { tbl, entries, colX, rowY, spacing, ncols, nrows, sides, finfo, measurer } = ctx;
17577
+ const { tbl, entries, colX, rowY, spacing, ncols, nrows, sides: sides2, finfo, measurer } = ctx;
16777
17578
  const boundaries = ruledBoundaries(tbl);
16778
17579
  return entries.map((e) => {
16779
17580
  const box = {
@@ -16790,19 +17591,19 @@ function placeCells(ctx) {
16790
17591
  row: e.row,
16791
17592
  colspan: e.colspan,
16792
17593
  rowspan: e.rowspan,
16793
- sidesMask: cellSidesMask(e, ncols, nrows, sides)
17594
+ sidesMask: cellSidesMask(e, ncols, nrows, sides2)
16794
17595
  });
16795
17596
  if (boundaries.has(e.row + e.rowspan)) placed.hruled = true;
16796
17597
  return placed;
16797
17598
  });
16798
17599
  }
16799
- function posHtmlTable(tbl, finfo, measurer, pos, sides = HTML_ALL_SIDES) {
17600
+ function posHtmlTable(tbl, finfo, measurer, pos, sides2 = HTML_ALL_SIDES) {
16800
17601
  const dim = tbl.dimen ?? { w: 0, h: 0 };
16801
17602
  const box = pos !== void 0 ? { ll: { ...pos.ll }, ur: { ...pos.ur } } : {
16802
17603
  ll: { x: -dim.w / 2, y: -dim.h / 2 },
16803
17604
  ur: { x: dim.w / 2, y: dim.h / 2 }
16804
17605
  };
16805
- const { entries, widths, heights, spacing, border } = layoutHtmlTable(tbl, measurer, {
17606
+ const { entries, widths, heights, spacing, border: border2 } = layoutHtmlTable(tbl, measurer, {
16806
17607
  fontsize: finfo.fontsize,
16807
17608
  fontname: finfo.fontname
16808
17609
  });
@@ -16834,10 +17635,10 @@ function posHtmlTable(tbl, finfo, measurer, pos, sides = HTML_ALL_SIDES) {
16834
17635
  dely = 0;
16835
17636
  }
16836
17637
  }
16837
- const colX = buildColX(box, border, spacing, distributeExtra(widths, delx, ncols));
16838
- const rowY = buildRowY(box, border, spacing, distributeExtra(heights, dely, nrows));
16839
- const cells = placeCells({ tbl, entries, colX, rowY, spacing, ncols, nrows, sides, finfo, measurer });
16840
- return { box, border, cells, spacing, columnCount: ncols, rowCount: nrows, port: tbl.port, boundarySides: sides, ...tblDecoration(tbl) };
17638
+ const colX = buildColX(box, border2, spacing, distributeExtra(widths, delx, ncols));
17639
+ const rowY = buildRowY(box, border2, spacing, distributeExtra(heights, dely, nrows));
17640
+ const cells = placeCells({ tbl, entries, colX, rowY, spacing, ncols, nrows, sides: sides2, finfo, measurer });
17641
+ return { box, border: border2, cells, spacing, columnCount: ncols, rowCount: nrows, port: tbl.port, boundarySides: sides2, ...tblDecoration(tbl) };
16841
17642
  }
16842
17643
  function posTextLabel(label, finfo, measurer) {
16843
17644
  const dim = label.dimen ?? { w: 0, h: 0 };
@@ -16864,21 +17665,22 @@ function posTextLabel(label, finfo, measurer) {
16864
17665
  };
16865
17666
  }
16866
17667
  function posHtmlLabel(label, finfo, measurer) {
16867
- if (label.kind === "table") return posHtmlTable(label.table, finfo, measurer);
17668
+ const env = { ...finfo };
17669
+ if (label.kind === "table") return withTableFont(env, label.table.font, "emit", () => posHtmlTable(label.table, env, measurer));
16868
17670
  return posTextLabel(label, finfo, measurer);
16869
17671
  }
16870
17672
  var HTML_PARSE_FATAL = 3;
16871
17673
  function makeHtmlLabelRv(content, finfo, measurer) {
16872
17674
  const { fontname, fontsize, fontcolor, imageSizer, pencolor } = finfo;
16873
- let lbl;
17675
+ let lbl, lexWarn;
16874
17676
  try {
16875
- lbl = parseHtmlLabel(content);
17677
+ ({ label: lbl, warn: lexWarn } = parseHtmlLabelRv(content));
16876
17678
  } catch (e) {
16877
17679
  if (e instanceof HtmlLexError) for (const line of e.diagnostics) console.error(line);
16878
17680
  return { label: makeLabel("", fontname, fontsize, fontcolor, measurer), rv: HTML_PARSE_FATAL };
16879
17681
  }
16880
17682
  if (lbl.kind === "table") inheritTablePenColor(lbl.table, pencolor);
16881
- const rv = sizeHtmlLabel(lbl, measurer, {
17683
+ const rv = Number(lexWarn) | sizeHtmlLabel(lbl, measurer, {
16882
17684
  fontsize,
16883
17685
  fontname,
16884
17686
  imageSizer
@@ -17228,7 +18030,7 @@ function starRings(box, peripheries) {
17228
18030
  return rings.flat();
17229
18031
  }
17230
18032
  function computeVertices(poly, w, h, base) {
17231
- const sides = poly.sides;
18033
+ const sides2 = poly.sides;
17232
18034
  if (poly.option.fixedshape && base !== void 0) {
17233
18035
  w = base.w;
17234
18036
  h = base.h;
@@ -17236,10 +18038,10 @@ function computeVertices(poly, w, h, base) {
17236
18038
  if (poly.option.shape === CYLINDER) return cylinderVertices(w, h);
17237
18039
  const peripheries = Math.max(poly.peripheries, 1);
17238
18040
  if (poly.option.shape === STAR) return starRings({ w, h, base }, peripheries);
17239
- if (sides <= 2) {
18041
+ if (sides2 <= 2) {
17240
18042
  return ellipseRings(w, h, peripheries, poly.option.fixedshape ? base : void 0);
17241
18043
  }
17242
- if (sides === 4 && Math.abs(poly.orientation % 90) < 0.5 && poly.distortion === 0 && poly.skew === 0) {
18044
+ if (sides2 === 4 && Math.abs(poly.orientation % 90) < 0.5 && poly.distortion === 0 && poly.skew === 0) {
17243
18045
  return boxRings(w, h, peripheries, poly.orientation, base);
17244
18046
  }
17245
18047
  return generalPolyRings(poly, { w, h, base }, peripheries);
@@ -17364,17 +18166,17 @@ function starSize(bb) {
17364
18166
  function cylinderSize(bb) {
17365
18167
  return { x: bb.x, y: bb.y * 1.375 };
17366
18168
  }
17367
- function expandForShape(bb, sides, heightPts, valign) {
18169
+ function expandForShape(bb, sides2, heightPts, valign2) {
17368
18170
  const b = { x: bb.x, y: bb.y };
17369
18171
  const temp = b.y * SQRT2;
17370
- if (heightPts > temp && valign === "c") {
18172
+ if (heightPts > temp && valign2 === "c") {
17371
18173
  b.x *= Math.sqrt(1 / (1 - (b.y / heightPts) ** 2));
17372
18174
  } else {
17373
18175
  b.x *= SQRT2;
17374
18176
  b.y = temp;
17375
18177
  }
17376
- if (sides > 2) {
17377
- const c = Math.cos(Math.PI / sides);
18178
+ if (sides2 > 2) {
18179
+ const c = Math.cos(Math.PI / sides2);
17378
18180
  b.x /= c;
17379
18181
  b.y /= c;
17380
18182
  }
@@ -17429,21 +18231,21 @@ function vertexExtents(verts) {
17429
18231
  }
17430
18232
  return { xmax, ymax };
17431
18233
  }
17432
- function initBisector(verts, sides) {
18234
+ function initBisector(verts, sides2) {
17433
18235
  const R2 = verts[0];
17434
18236
  let Q = R2;
17435
- for (let j = 1; j < sides; j++) {
17436
- Q = verts[(sides - j) % sides];
18237
+ for (let j = 1; j < sides2; j++) {
18238
+ Q = verts[(sides2 - j) % sides2];
17437
18239
  if (Q.x !== R2.x || Q.y !== R2.y) break;
17438
18240
  }
17439
18241
  return { beta: Math.atan2(R2.y - Q.y, R2.x - Q.x), Qprev: Q, sinx: 0, cosx: 0 };
17440
18242
  }
17441
- function bisectorOffset(verts, sides, i, st) {
18243
+ function bisectorOffset(verts, sides2, i, st) {
17442
18244
  const V = verts[i];
17443
18245
  if (V.x !== st.Qprev.x || V.y !== st.Qprev.y) {
17444
18246
  let R2 = V;
17445
- for (let j = 1; j < sides; j++) {
17446
- R2 = verts[(i + j) % sides];
18247
+ for (let j = 1; j < sides2; j++) {
18248
+ R2 = verts[(i + j) % sides2];
17447
18249
  if (R2.x !== V.x || R2.y !== V.y) break;
17448
18250
  }
17449
18251
  const alpha = st.beta;
@@ -17455,32 +18257,32 @@ function bisectorOffset(verts, sides, i, st) {
17455
18257
  }
17456
18258
  st.Qprev = V;
17457
18259
  }
17458
- function polygonRingOffsets(verts, sides) {
17459
- const st = initBisector(verts, sides);
18260
+ function polygonRingOffsets(verts, sides2) {
18261
+ const st = initBisector(verts, sides2);
17460
18262
  const out = [];
17461
- for (let i = 0; i < sides; i++) {
17462
- bisectorOffset(verts, sides, i, st);
18263
+ for (let i = 0; i < sides2; i++) {
18264
+ bisectorOffset(verts, sides2, i, st);
17463
18265
  out.push({ x: st.cosx, y: st.sinx });
17464
18266
  }
17465
18267
  return out;
17466
18268
  }
17467
- function polygonOutlineRing(verts, sides, penwidth) {
17468
- const st = initBisector(verts, sides);
18269
+ function polygonOutlineRing(verts, sides2, penwidth) {
18270
+ const st = initBisector(verts, sides2);
17469
18271
  const out = [];
17470
18272
  const k = penwidth / 2 / GAP;
17471
- for (let i = 0; i < sides; i++) {
17472
- bisectorOffset(verts, sides, i, st);
18273
+ for (let i = 0; i < sides2; i++) {
18274
+ bisectorOffset(verts, sides2, i, st);
17473
18275
  const V = verts[i];
17474
18276
  out.push({ x: V.x + k * st.cosx, y: V.y + k * st.sinx });
17475
18277
  }
17476
18278
  return out;
17477
18279
  }
17478
- function polygonPeripheryBB(verts, sides, p, bb) {
17479
- const st = initBisector(verts, sides);
18280
+ function polygonPeripheryBB(verts, sides2, p, bb) {
18281
+ const st = initBisector(verts, sides2);
17480
18282
  const out = { x: bb.x, y: bb.y };
17481
18283
  const outl = { x: bb.x, y: bb.y };
17482
- for (let i = 0; i < sides; i++) {
17483
- bisectorOffset(verts, sides, i, st);
18284
+ for (let i = 0; i < sides2; i++) {
18285
+ bisectorOffset(verts, sides2, i, st);
17484
18286
  const off = p.peripheries - 1;
17485
18287
  const V = verts[i];
17486
18288
  const P = { x: V.x + off * st.cosx, y: V.y + off * st.sinx };
@@ -17504,9 +18306,9 @@ function starVertexGen(bb) {
17504
18306
  }
17505
18307
  return { verts: starVertices(bb.x, bb.y), xmax: sz.x / 2, ymax: sz.y / 2 };
17506
18308
  }
17507
- function polygonBB(bb, minSize, p, sides, isBox3) {
18309
+ function polygonBB(bb, minSize, p, sides2, isBox3) {
17508
18310
  const geom = {
17509
- sides,
18311
+ sides: sides2,
17510
18312
  orientation: p.orientation,
17511
18313
  distortion: p.distortion,
17512
18314
  skew: p.skew
@@ -17523,7 +18325,7 @@ function polygonBB(bb, minSize, p, sides, isBox3) {
17523
18325
  v.x *= scalex;
17524
18326
  v.y *= scaley;
17525
18327
  }
17526
- return { ...polygonPeripheryBB(verts, isBox3 ? 4 : sides, p, nbb), base: nbb };
18328
+ return { ...polygonPeripheryBB(verts, isBox3 ? 4 : sides2, p, nbb), base: nbb };
17527
18329
  }
17528
18330
  function gvNodesize(widthPts, heightPts, flip) {
17529
18331
  if (flip) return { lw: heightPts / 2, rw: heightPts / 2, ht: widthPts };
@@ -17548,7 +18350,7 @@ function applySizeConstraints(p, bb0, width0, height0) {
17548
18350
  function polySize(p) {
17549
18351
  const init = initialSizePts(p);
17550
18352
  const dimen = quantize(padLabelDimen(p.labelDimen, p.margin, p.isPlain), p.quantumIn);
17551
- const { sides, isBox: isBox3 } = effectiveShape(p);
18353
+ const { sides: sides2, isBox: isBox3 } = effectiveShape(p);
17552
18354
  let bb = { x: dimen.x, y: dimen.y };
17553
18355
  if (isBox3) {
17554
18356
  } else if (p.optionShape === STAR) {
@@ -17556,13 +18358,13 @@ function polySize(p) {
17556
18358
  } else if (p.optionShape === CYLINDER) {
17557
18359
  bb = cylinderSize(bb);
17558
18360
  } else {
17559
- bb = expandForShape(bb, sides, init.height, labelValign(p));
18361
+ bb = expandForShape(bb, sides2, init.height, labelValign(p));
17560
18362
  }
17561
18363
  const minBb = bb;
17562
18364
  const c = applySizeConstraints(p, bb, init.width, init.height);
17563
18365
  const penwidth = p.penwidth ?? 1;
17564
18366
  const hasOutline = penwidth > 0 || p.peripheries < 1;
17565
- const grown = sides < 3 ? { ...ellipsePeripheryBB(c.bb, p.peripheries, penwidth, hasOutline), base: c.bb } : polygonBB(c.bb, { x: c.width, y: c.height }, { ...p, penwidth, hasOutline }, sides, isBox3);
18367
+ 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);
17566
18368
  const result = assembleResult(p, dimen, grown, c.fixedshape);
17567
18369
  return { ...result, ...labelSpace(p, dimen, c.bb, minBb, isBox3, c.fixedshape) };
17568
18370
  }
@@ -17582,10 +18384,10 @@ function labelSpace(p, dimen, bb, minBb, isBox3, fixedshape) {
17582
18384
  return { space: { x: spaceX, y: spaceY }, valign: labelValign(p) };
17583
18385
  }
17584
18386
  function effectiveShape(p) {
17585
- let sides = p.sides;
17586
- if (sides <= 2 && (p.distortion !== 0 || p.skew !== 0)) sides = 120;
17587
- const isBox3 = sides === 4 && Math.abs(p.orientation % 90) < 0.5 && p.distortion === 0 && p.skew === 0;
17588
- return { sides, isBox: isBox3 };
18387
+ let sides2 = p.sides;
18388
+ if (sides2 <= 2 && (p.distortion !== 0 || p.skew !== 0)) sides2 = 120;
18389
+ const isBox3 = sides2 === 4 && Math.abs(p.orientation % 90) < 0.5 && p.distortion === 0 && p.skew === 0;
18390
+ return { sides: sides2, isBox: isBox3 };
17589
18391
  }
17590
18392
  function labelValign(p) {
17591
18393
  const ll = p.labelloc?.[0];
@@ -17796,33 +18598,33 @@ function otherEdge(e) {
17796
18598
  elistAppend(e.tail.info.other, e);
17797
18599
  }
17798
18600
 
18601
+ // src/common/bezier.ts
18602
+ function bezier(v, t, left2, right2) {
18603
+ const degree = 3;
18604
+ const u = 1 - t;
18605
+ const tri = [[v[0], v[1], v[2], v[3]]];
18606
+ for (let i = 1; i <= degree; i++) {
18607
+ const prev = tri[i - 1];
18608
+ const row = [];
18609
+ for (let j = 0; j <= degree - i; j++) {
18610
+ row.push({
18611
+ x: fma(prev[j].x, u, t * prev[j + 1].x),
18612
+ y: fma(prev[j].y, u, t * prev[j + 1].y)
18613
+ });
18614
+ }
18615
+ tri.push(row);
18616
+ }
18617
+ if (left2 !== null) for (let j = 0; j <= degree; j++) left2[j] = tri[j][0];
18618
+ if (right2 !== null) for (let j = 0; j <= degree; j++) right2[j] = tri[degree - j][j];
18619
+ return tri[degree][0];
18620
+ }
18621
+
17799
18622
  // src/common/splines-geom.ts
17800
18623
  function approxEqPt(p, q, tol) {
17801
18624
  const dx = p.x - q.x;
17802
18625
  const dy = p.y - q.y;
17803
18626
  return dx * dx + dy * dy < tol * tol;
17804
18627
  }
17805
- function evalBezier(sp, t, left2, right2) {
17806
- const ab = { x: sp[0].x + t * (sp[1].x - sp[0].x), y: sp[0].y + t * (sp[1].y - sp[0].y) };
17807
- const bc = { x: sp[1].x + t * (sp[2].x - sp[1].x), y: sp[1].y + t * (sp[2].y - sp[1].y) };
17808
- const cd = { x: sp[2].x + t * (sp[3].x - sp[2].x), y: sp[2].y + t * (sp[3].y - sp[2].y) };
17809
- const abbc = { x: ab.x + t * (bc.x - ab.x), y: ab.y + t * (bc.y - ab.y) };
17810
- const bccd = { x: bc.x + t * (cd.x - bc.x), y: bc.y + t * (cd.y - bc.y) };
17811
- const pt = { x: abbc.x + t * (bccd.x - abbc.x), y: abbc.y + t * (bccd.y - abbc.y) };
17812
- if (left2 !== null) {
17813
- left2[0] = sp[0];
17814
- left2[1] = ab;
17815
- left2[2] = abbc;
17816
- left2[3] = pt;
17817
- }
17818
- if (right2 !== null) {
17819
- right2[0] = pt;
17820
- right2[1] = bccd;
17821
- right2[2] = cd;
17822
- right2[3] = sp[3];
17823
- }
17824
- return pt;
17825
- }
17826
18628
  var HW = 2;
17827
18629
  var SMALL2 = 1e-10;
17828
18630
  function ptToLine2(a, b, p) {
@@ -17857,7 +18659,7 @@ function updateBbBz(bb, cp) {
17857
18659
  }
17858
18660
  const left2 = [];
17859
18661
  const right2 = [];
17860
- evalBezier(cp, 0.5, left2, right2);
18662
+ bezier(cp, 0.5, left2, right2);
17861
18663
  updateBbBz(bb, left2);
17862
18664
  updateBbBz(bb, right2);
17863
18665
  }
@@ -17883,7 +18685,7 @@ function bezierClip(insideCtx, insideFn, sp, leftInside) {
17883
18685
  do {
17884
18686
  const opt = pt;
17885
18687
  const t = (high + low) / 2;
17886
- pt = evalBezier(sp, t, left2, right2);
18688
+ pt = bezier(sp, t, left2, right2);
17887
18689
  if (insideFn(insideCtx, pt)) {
17888
18690
  if (leftInside) {
17889
18691
  low = t;
@@ -18280,15 +19082,10 @@ function arrowLengthTee(lenfact, arrowsize, penwidth) {
18280
19082
  if (extendStart > 0) length += extendEnd;
18281
19083
  return length;
18282
19084
  }
18283
- var lerp = (a, b) => ({ x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 });
18284
19085
  function cubicHalf(c, rightHalf) {
18285
- const A3 = lerp(c[0], c[1]);
18286
- const B2 = lerp(c[1], c[2]);
18287
- const C6 = lerp(c[2], c[3]);
18288
- const D = lerp(A3, B2);
18289
- const E = lerp(B2, C6);
18290
- const M2 = lerp(D, E);
18291
- return rightHalf ? [M2, E, C6, c[3]] : [c[0], A3, D, M2];
19086
+ const half = [];
19087
+ bezier(c, 0.5, rightHalf ? null : half, rightHalf ? half : null);
19088
+ return half;
18292
19089
  }
18293
19090
  function curveControlPoints(p, v, w, flag) {
18294
19091
  const AF0 = { x: p.x + v.x + w.x, y: p.y + v.y + w.y };
@@ -18561,29 +19358,11 @@ function arrowDrawOps(comps, tip2, dir, arrowsize, penwidth, rankdir = 0) {
18561
19358
  }
18562
19359
 
18563
19360
  // src/layout/dot/edge-route-clip.ts
18564
- function deCasteljauTriangle(sp, t) {
18565
- const u = 1 - t;
18566
- const v = [
18567
- [sp[0], sp[1], sp[2], sp[3]],
18568
- [{ x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }],
18569
- [{ x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }],
18570
- [{ x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }]
18571
- ];
18572
- for (let i = 1; i <= 3; i++) {
18573
- for (let j = 0; j <= 3 - i; j++) {
18574
- v[i][j] = {
18575
- x: u * v[i - 1][j].x + t * v[i - 1][j + 1].x,
18576
- y: u * v[i - 1][j].y + t * v[i - 1][j + 1].y
18577
- };
18578
- }
18579
- }
18580
- return v;
18581
- }
18582
19361
  function bezierSubdivide(sp, t) {
18583
- const v = deCasteljauTriangle(sp, t);
18584
- const left2 = [v[0][0], v[1][0], v[2][0], v[3][0]];
18585
- const right2 = [v[3][0], v[2][1], v[1][2], v[0][3]];
18586
- return [left2, right2, v[3][0]];
19362
+ const left2 = [];
19363
+ const right2 = [];
19364
+ const mid = bezier(sp, t, left2, right2);
19365
+ return [left2, right2, mid];
18587
19366
  }
18588
19367
  function bisectStep(c, insideFn, leftInside, s) {
18589
19368
  const t = (s.high + s.low) / 2;
@@ -19214,10 +19993,10 @@ var SelfEdgeImpl = class _SelfEdgeImpl {
19214
19993
  const lbl = e.info.label;
19215
19994
  if (!lbl?.dimen) return 0;
19216
19995
  const flip = e.tail.root.info.flip === true;
19217
- const height = flip ? lbl.dimen.x : lbl.dimen.y;
19218
- lbl.pos = { x: a.x, y: a.y + a.sign * height / 2 };
19996
+ const height2 = flip ? lbl.dimen.x : lbl.dimen.y;
19997
+ lbl.pos = { x: a.x, y: a.y + a.sign * height2 / 2 };
19219
19998
  lbl.set = true;
19220
- return height;
19999
+ return height2;
19221
20000
  }
19222
20001
  /** Place a left/right self-loop label; return the label width that governs
19223
20002
  * the loop's widen. Under flip the label is rotated, so dimen.y is the
@@ -19226,10 +20005,10 @@ var SelfEdgeImpl = class _SelfEdgeImpl {
19226
20005
  const lbl = e.info.label;
19227
20006
  if (!lbl?.dimen) return 0;
19228
20007
  const flip = e.tail.root.info.flip === true;
19229
- const width = flip ? lbl.dimen.y : lbl.dimen.x;
19230
- lbl.pos = { x: a.x + a.sign * width / 2, y: a.y };
20008
+ const width2 = flip ? lbl.dimen.y : lbl.dimen.x;
20009
+ lbl.pos = { x: a.x + a.sign * width2 / 2, y: a.y };
19231
20010
  lbl.set = true;
19232
- return width;
20011
+ return width2;
19233
20012
  }
19234
20013
  static bottomPts(a) {
19235
20014
  const { tp, hp, np, dx, dy, ty, hy } = a;
@@ -19559,11 +20338,11 @@ function processFlatEdge(g, u, e) {
19559
20338
  const isOrdered = nodeOrder(u) < nodeOrder(e.head);
19560
20339
  const t0 = isOrdered ? e.tail : e.head;
19561
20340
  const h0 = isOrdered ? e.head : e.tail;
19562
- const width = nodeRw(t0) + nodeLw(h0);
19563
- let m0 = Math.trunc(edgeMinlen(e) * nodesep + width);
20341
+ const width2 = nodeRw(t0) + nodeLw(h0);
20342
+ let m0 = Math.trunc(edgeMinlen(e) * nodesep + width2);
19564
20343
  const ex = findFastEdge(t0, h0);
19565
20344
  if (ex !== void 0) {
19566
- m0 = Math.trunc(Math.max(m0, width + nodesep + cround(edgeDist(e))));
20345
+ m0 = Math.trunc(Math.max(m0, width2 + nodesep + cround(edgeDist(e))));
19567
20346
  ex.info.minlen = Math.max(ex.info.minlen ?? 1, m0);
19568
20347
  ex.info.weight = Math.max(ex.info.weight ?? 0, edgeWeight(e));
19569
20348
  } else if (!e.info.label) {
@@ -19618,9 +20397,9 @@ function selfWidth(u) {
19618
20397
  }
19619
20398
  function lrRankPair(g, r, u, v, last) {
19620
20399
  const nodesep = lrSep(g, r);
19621
- const width = nodeRw(u) + nodeLw(v) + nodesep;
19622
- makeAuxEdge(u, v, width, 0);
19623
- const next = Math.trunc(last + width);
20400
+ const width2 = nodeRw(u) + nodeLw(v) + nodesep;
20401
+ makeAuxEdge(u, v, width2, 0);
20402
+ const next = Math.trunc(last + width2);
19624
20403
  v.info.rank = next;
19625
20404
  return next;
19626
20405
  }
@@ -22647,9 +23426,9 @@ function labelVnode(g, orig) {
22647
23426
  return v;
22648
23427
  }
22649
23428
  function incrWidth(g, v) {
22650
- const width = Math.floor((g.info.nodesep ?? 0) / 2);
22651
- v.info.lw = (v.info.lw ?? 0) + width;
22652
- v.info.rw = (v.info.rw ?? 0) + width;
23429
+ const width2 = Math.floor((g.info.nodesep ?? 0) / 2);
23430
+ v.info.lw = (v.info.lw ?? 0) + width2;
23431
+ v.info.rw = (v.info.rw ?? 0) + width2;
22653
23432
  }
22654
23433
  function plainVnode(g) {
22655
23434
  const v = virtualNode(g);
@@ -23525,8 +24304,8 @@ function recSideMask(f, i, last) {
23525
24304
  if (i === 0) return i === last ? TOP2 | BOTTOM2 | RIGHT2 | LEFT2 : TOP2 | RIGHT2 | LEFT2;
23526
24305
  return i === last ? LEFT2 | BOTTOM2 | RIGHT2 : LEFT2 | RIGHT2;
23527
24306
  }
23528
- function posReclbl(f, ul, sides) {
23529
- f.sides = sides;
24307
+ function posReclbl(f, ul, sides2) {
24308
+ f.sides = sides2;
23530
24309
  f.b = {
23531
24310
  ll: { x: ul.x, y: ul.y - f.size.y },
23532
24311
  ur: { x: ul.x + f.size.x, y: ul.y }
@@ -23534,8 +24313,8 @@ function posReclbl(f, ul, sides) {
23534
24313
  const last = f.n_flds - 1;
23535
24314
  const pos = { x: ul.x, y: ul.y };
23536
24315
  for (let i = 0; i <= last; i++) {
23537
- const mask = sides ? recSideMask(f, i, last) : 0;
23538
- posReclbl(f.fld[i], { x: pos.x, y: pos.y }, sides & mask);
24316
+ const mask = sides2 ? recSideMask(f, i, last) : 0;
24317
+ posReclbl(f.fld[i], { x: pos.x, y: pos.y }, sides2 & mask);
23539
24318
  if (f.LR) pos.x += f.fld[i].size.x;
23540
24319
  else pos.y -= f.fld[i].size.y;
23541
24320
  }
@@ -24033,11 +24812,11 @@ function renderPolyRing(ring, coord, filled, j, ctx) {
24033
24812
  } else renderPolygon(ring, coord, ctx.renderer, ctx.job, filled);
24034
24813
  }
24035
24814
  function renderPeripheries(poly, coord, filled, ctx) {
24036
- const sides = poly.sides <= 2 ? 2 : poly.sides;
24815
+ const sides2 = poly.sides <= 2 ? 2 : poly.sides;
24037
24816
  const verts = poly.vertices;
24038
24817
  for (let j = 0; j < poly.peripheries; j++) {
24039
- const ring = verts.slice(j * sides, (j + 1) * sides);
24040
- if (ring.length < sides) break;
24818
+ const ring = verts.slice(j * sides2, (j + 1) * sides2);
24819
+ if (ring.length < sides2) break;
24041
24820
  const ringFilled = j === 0 ? filled : false;
24042
24821
  if (poly.sides <= 2) {
24043
24822
  renderEllipseRing(ring, coord, ringFilled, j, ctx);
@@ -24186,12 +24965,12 @@ function resolveNodeDrawCtx(job, n) {
24186
24965
  };
24187
24966
  return { poly: drawPoly, coord, filled, ringCtx };
24188
24967
  }
24189
- function specialCornerFlags(opt, style) {
24968
+ function specialCornerFlags(opt, style2) {
24190
24969
  return {
24191
24970
  shape: opt.shape,
24192
- diagonals: opt.diagonals || style.diagonals,
24193
- rounded: opt.rounded || style.rounded,
24194
- underline: opt.underline || style.underline
24971
+ diagonals: opt.diagonals || style2.diagonals,
24972
+ rounded: opt.rounded || style2.rounded,
24973
+ underline: opt.underline || style2.underline
24195
24974
  };
24196
24975
  }
24197
24976
  function polyGencode(rawJob, rawNode) {
@@ -24264,22 +25043,22 @@ function insideScale(n, poly) {
24264
25043
  boxURy: oh / 2
24265
25044
  };
24266
25045
  }
24267
- function polygonWalk(P, vertex, sides) {
25046
+ function polygonWalk(P, vertex, sides2) {
24268
25047
  const O = { x: 0, y: 0 };
24269
25048
  let i = 0;
24270
- let i1 = 1 % sides;
25049
+ let i1 = 1 % sides2;
24271
25050
  const Q = vertex[i];
24272
25051
  const R2 = vertex[i1];
24273
25052
  if (!sameSide(P, O, Q, R2)) return false;
24274
25053
  const s = sameSide(P, Q, R2, O);
24275
25054
  if (s && sameSide(P, R2, O, Q)) return true;
24276
- for (let j = 1; j < sides; j++) {
25055
+ for (let j = 1; j < sides2; j++) {
24277
25056
  if (s) {
24278
25057
  i = i1;
24279
- i1 = (i + 1) % sides;
25058
+ i1 = (i + 1) % sides2;
24280
25059
  } else {
24281
25060
  i1 = i;
24282
- i = (i + sides - 1) % sides;
25061
+ i = (i + sides2 - 1) % sides2;
24283
25062
  }
24284
25063
  if (!sameSide(P, O, vertex[i], vertex[i1])) return false;
24285
25064
  }
@@ -24321,15 +25100,15 @@ function starInside(ctx, p) {
24321
25100
  }
24322
25101
  const poly = n.info.shape_info;
24323
25102
  if (poly === void 0 || poly.vertices === null) return false;
24324
- const sides = poly.sides;
24325
- const outerStart = (Math.max(poly.peripheries, 1) - 1) * sides;
24326
- const outer = poly.vertices.slice(outerStart, outerStart + sides);
24327
- const ring = polygonOutlineRing(outer, sides, poly.penwidth ?? 1);
25103
+ const sides2 = poly.sides;
25104
+ const outerStart = (Math.max(poly.peripheries, 1) - 1) * sides2;
25105
+ const outer = poly.vertices.slice(outerStart, outerStart + sides2);
25106
+ const ring = polygonOutlineRing(outer, sides2, poly.penwidth ?? 1);
24328
25107
  const O = { x: 0, y: 0 };
24329
25108
  let outcnt = 0;
24330
- for (let i = 0; i < sides; i += 2) {
25109
+ for (let i = 0; i < sides2; i += 2) {
24331
25110
  const Q = ring[i];
24332
- const R2 = ring[(i + 4) % sides];
25111
+ const R2 = ring[(i + 4) % sides2];
24333
25112
  if (!sameSide(P, O, Q, R2)) outcnt++;
24334
25113
  if (outcnt === 2) return false;
24335
25114
  }
@@ -24475,7 +25254,7 @@ var DEFAULT_NODESEP = 0.25;
24475
25254
  var MIN_NODESEP = 0.02;
24476
25255
  var DEFAULT_RANKSEP = 0.5;
24477
25256
  var MIN_RANKSEP = 0.02;
24478
- var UCHAR_MAX = 255;
25257
+ var UCHAR_MAX2 = 255;
24479
25258
  var CHAR_UTF8 = 0;
24480
25259
  var CHAR_LATIN1 = 1;
24481
25260
  var CHAR_BIG5 = 2;
@@ -24572,7 +25351,7 @@ function graphInit(g, useRankdir) {
24572
25351
  g.info.flip = false;
24573
25352
  }
24574
25353
  parseSepAttrs(g);
24575
- g.info.showboxes = Math.min(lateInt(g.attrs.get("showboxes"), 0, 0), UCHAR_MAX);
25354
+ g.info.showboxes = Math.min(lateInt(g.attrs.get("showboxes"), 0, 0), UCHAR_MAX2);
24576
25355
  const fn = maptoken(g.attrs.get("fontnames"), FONTNAME_NAMES, fontnameCodes());
24577
25356
  if (fn !== -1) g.info.fontnames = fn;
24578
25357
  parseRatioDrawing(g);
@@ -24800,54 +25579,54 @@ function dirDefault(p) {
24800
25579
  function dirUnrecognized(p) {
24801
25580
  return { p, theta: 0, side: 0, constrain: false, clip: true, dyna: false, defined: false, rv: 1 };
24802
25581
  }
24803
- function dirN(rest, b, ctr, sides) {
25582
+ function dirN(rest, b, ctr, sides2) {
24804
25583
  const base = { constrain: true, clip: false, dyna: false };
24805
25584
  switch (rest) {
24806
25585
  case "":
24807
- return { ...base, p: { x: ctr.x, y: b.ur.y }, theta: Math.PI * 0.5, side: sides & TOP, defined: true, rv: 0 };
25586
+ return { ...base, p: { x: ctr.x, y: b.ur.y }, theta: Math.PI * 0.5, side: sides2 & TOP, defined: true, rv: 0 };
24808
25587
  case "e":
24809
- return { ...base, p: { x: b.ur.x, y: b.ur.y }, theta: Math.PI * 0.25, side: sides & (TOP | RIGHT), defined: true, rv: 0 };
25588
+ return { ...base, p: { x: b.ur.x, y: b.ur.y }, theta: Math.PI * 0.25, side: sides2 & (TOP | RIGHT), defined: true, rv: 0 };
24810
25589
  case "w":
24811
- return { ...base, p: { x: b.ll.x, y: b.ur.y }, theta: Math.PI * 0.75, side: sides & (TOP | LEFT), defined: true, rv: 0 };
25590
+ return { ...base, p: { x: b.ll.x, y: b.ur.y }, theta: Math.PI * 0.75, side: sides2 & (TOP | LEFT), defined: true, rv: 0 };
24812
25591
  default:
24813
25592
  return dirUnrecognized({ x: ctr.x, y: ctr.y });
24814
25593
  }
24815
25594
  }
24816
- function dirS(rest, b, ctr, sides) {
25595
+ function dirS(rest, b, ctr, sides2) {
24817
25596
  const base = { constrain: true, clip: false, dyna: false };
24818
25597
  switch (rest) {
24819
25598
  case "":
24820
- return { ...base, p: { x: ctr.x, y: b.ll.y }, theta: -Math.PI * 0.5, side: sides & BOTTOM, defined: true, rv: 0 };
25599
+ return { ...base, p: { x: ctr.x, y: b.ll.y }, theta: -Math.PI * 0.5, side: sides2 & BOTTOM, defined: true, rv: 0 };
24821
25600
  case "e":
24822
- return { ...base, p: { x: b.ur.x, y: b.ll.y }, theta: -Math.PI * 0.25, side: sides & (BOTTOM | RIGHT), defined: true, rv: 0 };
25601
+ return { ...base, p: { x: b.ur.x, y: b.ll.y }, theta: -Math.PI * 0.25, side: sides2 & (BOTTOM | RIGHT), defined: true, rv: 0 };
24823
25602
  case "w":
24824
- return { ...base, p: { x: b.ll.x, y: b.ll.y }, theta: -Math.PI * 0.75, side: sides & (BOTTOM | LEFT), defined: true, rv: 0 };
25603
+ return { ...base, p: { x: b.ll.x, y: b.ll.y }, theta: -Math.PI * 0.75, side: sides2 & (BOTTOM | LEFT), defined: true, rv: 0 };
24825
25604
  default:
24826
25605
  return dirUnrecognized({ x: ctr.x, y: ctr.y });
24827
25606
  }
24828
25607
  }
24829
- function dirE(rest, b, ctr, sides) {
25608
+ function dirE(rest, b, ctr, sides2) {
24830
25609
  if (rest.length > 0) return dirUnrecognized(ctr);
24831
- return { p: { x: b.ur.x, y: ctr.y }, theta: 0, side: sides & RIGHT, constrain: true, clip: false, dyna: false, defined: true, rv: 0 };
25610
+ return { p: { x: b.ur.x, y: ctr.y }, theta: 0, side: sides2 & RIGHT, constrain: true, clip: false, dyna: false, defined: true, rv: 0 };
24832
25611
  }
24833
- function dirW(rest, b, ctr, sides) {
25612
+ function dirW(rest, b, ctr, sides2) {
24834
25613
  if (rest.length > 0) return dirUnrecognized(ctr);
24835
- return { p: { x: b.ll.x, y: ctr.y }, theta: Math.PI, side: sides & LEFT, constrain: true, clip: false, dyna: false, defined: true, rv: 0 };
25614
+ 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 };
24836
25615
  }
24837
- function compassDirection(compass, b, ctr, sides) {
25616
+ function compassDirection(compass, b, ctr, sides2) {
24838
25617
  if (compass.length === 0) return dirDefault(ctr);
24839
25618
  const rest = compass.slice(1);
24840
25619
  switch (compass[0]) {
24841
25620
  case "n":
24842
- return dirN(rest, b, ctr, sides);
25621
+ return dirN(rest, b, ctr, sides2);
24843
25622
  case "s":
24844
- return dirS(rest, b, ctr, sides);
25623
+ return dirS(rest, b, ctr, sides2);
24845
25624
  case "e":
24846
- return dirE(rest, b, ctr, sides);
25625
+ return dirE(rest, b, ctr, sides2);
24847
25626
  case "w":
24848
- return dirW(rest, b, ctr, sides);
25627
+ return dirW(rest, b, ctr, sides2);
24849
25628
  case "_":
24850
- return { p: { ...ctr }, theta: 0, side: sides, constrain: false, clip: true, dyna: true, defined: false, rv: 0 };
25629
+ return { p: { ...ctr }, theta: 0, side: sides2, constrain: false, clip: true, dyna: true, defined: false, rv: 0 };
24851
25630
  case "c":
24852
25631
  return dirDefault(ctr);
24853
25632
  default:
@@ -24896,31 +25675,31 @@ function applyIctxt(n, dir, b, ctr) {
24896
25675
  dir.p = compassPoint(n, insideFn, yArg, xArg, gdRankdir(n));
24897
25676
  }
24898
25677
  function compassPort(n, args, pp) {
24899
- const { bp, compass, sides } = args;
25678
+ const { bp, compass, sides: sides2 } = args;
24900
25679
  const { b, p, defined: defBp } = compassBbox(n, bp);
24901
- const dir = compassDirection(compass, b, p, sides);
25680
+ const dir = compassDirection(compass, b, p, sides2);
24902
25681
  if (bp === null && !isBox(n)) applyIctxt(n, dir, b, p);
24903
25682
  const defFinal = dir.rv === 1 ? defBp : dir.defined || defBp;
24904
25683
  applyDir(pp, bp, dir, gdRankdir(n), defFinal);
24905
25684
  return dir.rv;
24906
25685
  }
24907
- function htmlPort(n, portname, sides) {
25686
+ function htmlPort(n, portname, sides2) {
24908
25687
  const label = n.info.label;
24909
25688
  const placed = label?.u?.kind === "html" ? label.u.html : void 0;
24910
25689
  if (placed === void 0) return null;
24911
25690
  const hit = portToTbl(placed, portname);
24912
25691
  if (hit === null) return null;
24913
- sides.value = hit.sides;
25692
+ sides2.value = hit.sides;
24914
25693
  return hit.box;
24915
25694
  }
24916
25695
  function polyPort(n, portname, compass) {
24917
25696
  if (portname.length === 0) return makePort();
24918
25697
  const compassStr = compass.length === 0 ? "_" : compass;
24919
- const sides = BOTTOM | RIGHT | TOP | LEFT;
25698
+ const sides2 = BOTTOM | RIGHT | TOP | LEFT;
24920
25699
  const rv = makePort();
24921
25700
  const label = n.info.label;
24922
25701
  if (label?.html === true) {
24923
- const sidesRef = { value: sides };
25702
+ const sidesRef = { value: sides2 };
24924
25703
  const bp = htmlPort(n, portname, sidesRef);
24925
25704
  if (bp !== null) {
24926
25705
  compassPort(n, { bp, compass: compassStr, sides: sidesRef.value }, rv);
@@ -24928,7 +25707,7 @@ function polyPort(n, portname, compass) {
24928
25707
  return rv;
24929
25708
  }
24930
25709
  }
24931
- compassPort(n, { bp: null, compass: portname, sides }, rv);
25710
+ compassPort(n, { bp: null, compass: portname, sides: sides2 }, rv);
24932
25711
  rv.name = null;
24933
25712
  return rv;
24934
25713
  }
@@ -25289,8 +26068,8 @@ function initNodeFromLabel(n, g, measurer) {
25289
26068
  return true;
25290
26069
  }
25291
26070
  function effectivePolygon(poly, p, fixedshape) {
25292
- let sides = p.sides;
25293
- if (sides <= 2 && (p.distortion !== 0 || p.skew !== 0)) sides = 120;
26071
+ let sides2 = p.sides;
26072
+ if (sides2 <= 2 && (p.distortion !== 0 || p.skew !== 0)) sides2 = 120;
25294
26073
  return {
25295
26074
  ...poly,
25296
26075
  // C: poly->option.fixedshape = true inside the fixedsize="shape" branch;
@@ -25298,7 +26077,7 @@ function effectivePolygon(poly, p, fixedshape) {
25298
26077
  option: { ...poly.option, fixedshape },
25299
26078
  regular: p.regular,
25300
26079
  peripheries: p.peripheries,
25301
- sides,
26080
+ sides: sides2,
25302
26081
  orientation: p.orientation,
25303
26082
  distortion: p.distortion,
25304
26083
  skew: p.skew,
@@ -26440,8 +27219,8 @@ function orthoRoundedRadius(e, job) {
26440
27219
  if (e.head.root.attrs.get("splines") !== "ortho") return null;
26441
27220
  let wantRounded = false;
26442
27221
  let radius = 0;
26443
- const style = e.attrs.get("style");
26444
- if (style !== void 0 && style.split(",").map((s) => s.trim()).includes("rounded")) {
27222
+ const style2 = e.attrs.get("style");
27223
+ if (style2 !== void 0 && style2.split(",").map((s) => s.trim()).includes("rounded")) {
26445
27224
  wantRounded = true;
26446
27225
  }
26447
27226
  const radiusAttr = e.attrs.get("radius");
@@ -26826,20 +27605,10 @@ function checkControlPoints2(cp) {
26826
27605
  return ptToLine22(cp[0], cp[3], cp[1]) < MAP_HW * MAP_HW && ptToLine22(cp[0], cp[3], cp[2]) < MAP_HW * MAP_HW;
26827
27606
  }
26828
27607
  function bezierHalf(v) {
26829
- const t = 0.5;
26830
- const vt = [v.slice(0, 4)];
26831
- for (let i = 1; i <= 3; i++) {
26832
- vt[i] = [];
26833
- for (let j = 0; j <= 3 - i; j++) {
26834
- const a = vt[i - 1][j];
26835
- const b = vt[i - 1][j + 1];
26836
- vt[i][j] = { x: (1 - t) * a.x + t * b.x, y: (1 - t) * a.y + t * b.y };
26837
- }
26838
- }
26839
- return {
26840
- left: [vt[0][0], vt[1][0], vt[2][0], vt[3][0]],
26841
- right: [vt[3][0], vt[2][1], vt[1][2], vt[0][3]]
26842
- };
27608
+ const left2 = [];
27609
+ const right2 = [];
27610
+ bezier(v, 0.5, left2, right2);
27611
+ return { left: left2, right: right2 };
26843
27612
  }
26844
27613
  function approxBezier(cp, out) {
26845
27614
  if (checkControlPoints2(cp)) {
@@ -28397,9 +29166,9 @@ function setAspect2(g) {
28397
29166
  function placeLabelNonFlip(g) {
28398
29167
  const bb = g.info.bb;
28399
29168
  const labelPos2 = g.info.label_pos ?? 1;
28400
- const border = g.info.border;
29169
+ const border2 = g.info.border;
28401
29170
  const zero = { x: 0, y: 0 };
28402
- const d = labelPos2 & 1 ? border?.[TOP_IX] ?? zero : border?.[BOTTOM_IX] ?? zero;
29171
+ const d = labelPos2 & 1 ? border2?.[TOP_IX] ?? zero : border2?.[BOTTOM_IX] ?? zero;
28403
29172
  const py = labelPos2 & 1 ? bb.ur.y - d.y / 2 : bb.ll.y + d.y / 2;
28404
29173
  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;
28405
29174
  return { x: px, y: py };
@@ -28407,9 +29176,9 @@ function placeLabelNonFlip(g) {
28407
29176
  function placeLabelFlip(g) {
28408
29177
  const bb = g.info.bb;
28409
29178
  const labelPos2 = g.info.label_pos ?? 1;
28410
- const border = g.info.border;
29179
+ const border2 = g.info.border;
28411
29180
  const zero = { x: 0, y: 0 };
28412
- const d = labelPos2 & 1 ? border?.[RIGHT_IX] ?? zero : border?.[LEFT_IX] ?? zero;
29181
+ const d = labelPos2 & 1 ? border2?.[RIGHT_IX] ?? zero : border2?.[LEFT_IX] ?? zero;
28413
29182
  const px = labelPos2 & 1 ? bb.ur.x - d.x / 2 : bb.ll.x + d.x / 2;
28414
29183
  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;
28415
29184
  return { x: px, y: py };
@@ -29387,18 +30156,6 @@ function dist2(p, q) {
29387
30156
  function distPt(p, q) {
29388
30157
  return Math.sqrt(dist2(p, q));
29389
30158
  }
29390
- function bezier(v, t) {
29391
- const u = 1 - t;
29392
- const x = [v[0].x, v[1].x, v[2].x, v[3].x];
29393
- const y = [v[0].y, v[1].y, v[2].y, v[3].y];
29394
- for (let i = 1; i <= 3; i++) {
29395
- for (let j = 0; j <= 3 - i; j++) {
29396
- x[j] = fma(x[j], u, t * x[j + 1]);
29397
- y[j] = fma(y[j], u, t * y[j + 1]);
29398
- }
29399
- }
29400
- return { x: x[0], y: y[0] };
29401
- }
29402
30159
  function dotneatoClosest(spl, pt) {
29403
30160
  let besti = 0;
29404
30161
  let bestj = -1;
@@ -29427,7 +30184,7 @@ function dotneatoClosest(spl, pt) {
29427
30184
  let pt2;
29428
30185
  for (; ; ) {
29429
30186
  const t = (lo + hi) / 2;
29430
- pt2 = bezier(c, t);
30187
+ pt2 = bezier(c, t, null, null);
29431
30188
  if (Math.abs(dlo2 - dhi2) < 1 || Math.abs(hi - lo) < 1e-5) break;
29432
30189
  if (dlo2 < dhi2) {
29433
30190
  hi = t;
@@ -29518,8 +30275,8 @@ function faceMidpoint(b, ix) {
29518
30275
  return { x: b.ll.x, y: cy };
29519
30276
  }
29520
30277
  function closestSide(n, other, port) {
29521
- const sides = port.side;
29522
- if (sides === 0 || sides === ALL_SIDES2) return null;
30278
+ const sides2 = port.side;
30279
+ if (sides2 === 0 || sides2 === ALL_SIDES2) return null;
29523
30280
  const rkd = (n.root.info.rankdir ?? 0) & 3;
29524
30281
  const pt = cvtPt(n.info.coord, rkd);
29525
30282
  const opt = cvtPt(other.info.coord, rkd);
@@ -29527,7 +30284,7 @@ function closestSide(n, other, port) {
29527
30284
  let rv = null;
29528
30285
  let mind = 0;
29529
30286
  for (let i = 0; i < 4; i++) {
29530
- if ((sides & 1 << i) === 0) continue;
30287
+ if ((sides2 & 1 << i) === 0) continue;
29531
30288
  const m = faceMidpoint(b, i);
29532
30289
  const d = dist2({ x: m.x + pt.x, y: m.y + pt.y }, opt);
29533
30290
  if (rv === null || d < mind) {
@@ -31244,17 +32001,20 @@ function checkPath(boxn, boxes, pp) {
31244
32001
  return false;
31245
32002
  }
31246
32003
  function deCasteljauPoint(p0, p1, p2, p3, t) {
31247
- const ax = p0.x + t * (p1.x - p0.x);
31248
- const ay = p0.y + t * (p1.y - p0.y);
31249
- const bx = p1.x + t * (p2.x - p1.x);
31250
- const by = p1.y + t * (p2.y - p1.y);
31251
- const cx = p2.x + t * (p3.x - p2.x);
31252
- const cy = p2.y + t * (p3.y - p2.y);
31253
- const dx = ax + t * (bx - ax);
31254
- const dy = ay + t * (by - ay);
31255
- const ex = bx + t * (cx - bx);
31256
- const ey = by + t * (cy - by);
31257
- return { x: dx + t * (ex - dx), y: dy + t * (ey - dy) };
32004
+ let s0x = p0.x, s0y = p0.y, s1x = p1.x, s1y = p1.y, s2x = p2.x, s2y = p2.y;
32005
+ s0x = fma(t, s1x - s0x, s0x);
32006
+ s0y = fma(t, s1y - s0y, s0y);
32007
+ s1x = fma(t, s2x - s1x, s1x);
32008
+ s1y = fma(t, s2y - s1y, s1y);
32009
+ s2x = fma(t, p3.x - s2x, s2x);
32010
+ s2y = fma(t, p3.y - s2y, s2y);
32011
+ s0x = fma(t, s1x - s0x, s0x);
32012
+ s0y = fma(t, s1y - s0y, s0y);
32013
+ s1x = fma(t, s2x - s1x, s1x);
32014
+ s1y = fma(t, s2y - s1y, s1y);
32015
+ s0x = fma(t, s1x - s0x, s0x);
32016
+ s0y = fma(t, s1y - s0y, s0y);
32017
+ return { x: s0x, y: s0y };
31258
32018
  }
31259
32019
  function updateBoxExtents(boxes, boxn, sp) {
31260
32020
  for (let bi = 0; bi < boxn; bi++) {
@@ -31275,7 +32035,7 @@ function sampleBezierSegment(boxes, boxn, pps, splinepi, numDiv) {
31275
32035
  }
31276
32036
  }
31277
32037
  function limitBoxes(boxes, boxn, pps, pn, delta2) {
31278
- const numDiv = Math.round(delta2 * boxn);
32038
+ const numDiv = delta2 * boxn;
31279
32039
  for (let splinepi = 0; splinepi + 3 < pn; splinepi += 3) {
31280
32040
  sampleBezierSegment(boxes, boxn, pps, splinepi, numDiv);
31281
32041
  }
@@ -31941,15 +32701,15 @@ function leftOf(p1, p2, p3) {
31941
32701
  }
31942
32702
  function lineLabelPoints(g, startp, endp, label) {
31943
32703
  const flip = g.info.flip === true;
31944
- const width = flip ? label.dimen.y : label.dimen.x;
31945
- const height = flip ? label.dimen.x : label.dimen.y;
32704
+ const width2 = flip ? label.dimen.y : label.dimen.x;
32705
+ const height2 = flip ? label.dimen.x : label.dimen.y;
31946
32706
  const lp = { x: label.pos.x, y: label.pos.y };
31947
32707
  if (leftOf(endp, startp, lp)) {
31948
- lp.x += width / 2;
31949
- lp.y -= height / 2;
32708
+ lp.x += width2 / 2;
32709
+ lp.y -= height2 / 2;
31950
32710
  } else {
31951
- lp.x -= width / 2;
31952
- lp.y += height / 2;
32711
+ lp.x -= width2 / 2;
32712
+ lp.y += height2 / 2;
31953
32713
  }
31954
32714
  return [startp, startp, lp, lp, lp, endp, endp];
31955
32715
  }
@@ -33336,8 +34096,8 @@ function findNormalOutEdge(first) {
33336
34096
  }
33337
34097
  function labelXPos(n, l) {
33338
34098
  const flip = !!n.root?.info.flip;
33339
- const width = flip ? l.dimen.y : l.dimen.x;
33340
- return n.info.coord.x + width / 2;
34099
+ const width2 = flip ? l.dimen.y : l.dimen.x;
34100
+ return n.info.coord.x + width2 / 2;
33341
34101
  }
33342
34102
  function placeVnlabel(n) {
33343
34103
  if ((n.info.in?.size ?? 0) === 0) return;
@@ -33375,22 +34135,12 @@ function setEdgeLabelPos(g) {
33375
34135
  }
33376
34136
  var PORT_LABEL_DISTANCE = 10;
33377
34137
  var PORT_LABEL_ANGLE = -25;
33378
- function cubicBezierAt(pts, t) {
33379
- const p0 = pts[0], p1 = pts[1], p2 = pts[2], p3 = pts[3];
33380
- const mt = 1 - t;
33381
- const q0 = { x: mt * p0.x + t * p1.x, y: mt * p0.y + t * p1.y };
33382
- const q1 = { x: mt * p1.x + t * p2.x, y: mt * p1.y + t * p2.y };
33383
- const q2 = { x: mt * p2.x + t * p3.x, y: mt * p2.y + t * p3.y };
33384
- const r0 = { x: mt * q0.x + t * q1.x, y: mt * q0.y + t * q1.y };
33385
- const r1 = { x: mt * q1.x + t * q2.x, y: mt * q1.y + t * q2.y };
33386
- return { x: mt * r0.x + t * r1.x, y: mt * r0.y + t * r1.y };
33387
- }
33388
34138
  function tailEndpoints(bez) {
33389
34139
  if (bez.sflag) {
33390
34140
  return { pe: bez.sp, pf: bez.list[0] };
33391
34141
  }
33392
34142
  const pe = bez.list[0];
33393
- const pf = cubicBezierAt(bez.list, 0.1);
34143
+ const pf = bezier(bez.list, 0.1, null, null);
33394
34144
  return { pe, pf };
33395
34145
  }
33396
34146
  function headEndpoints(bez) {
@@ -33399,7 +34149,7 @@ function headEndpoints(bez) {
33399
34149
  }
33400
34150
  const pe = bez.list[bez.size - 1];
33401
34151
  const last4 = bez.list.slice(bez.size - 4, bez.size);
33402
- const pf = cubicBezierAt(last4, 0.9);
34152
+ const pf = bezier(last4, 0.9, null, null);
33403
34153
  return { pe, pf };
33404
34154
  }
33405
34155
  function placePortlabel(e, headP) {
@@ -36574,22 +37324,22 @@ function gcellWalk(pd, sx, sy, boundIsX, bound) {
36574
37324
  }
36575
37325
  return out;
36576
37326
  }
36577
- function appendSide(sides, found, cp, cellIdx) {
37327
+ function appendSide(sides2, found, cp, cellIdx) {
36578
37328
  for (const np of found) {
36579
- sides.push(np);
37329
+ sides2.push(np);
36580
37330
  np.cells[cellIdx] = cp;
36581
37331
  }
36582
37332
  }
36583
37333
  function attachGcellSides(mp, hdict, vdict) {
36584
37334
  let maxdeg = 0;
36585
37335
  for (const cp of mp.gcells) {
36586
- const sides = [];
36587
- appendSide(sides, gcellWalk(hdict, cp.bb.LL.x, cp.bb.LL.y, true, cp.bb.UR.x), cp, 1);
36588
- appendSide(sides, gcellWalk(vdict, cp.bb.LL.x, cp.bb.LL.y, false, cp.bb.UR.y), cp, 1);
36589
- appendSide(sides, gcellWalk(hdict, cp.bb.LL.x, cp.bb.UR.y, true, cp.bb.UR.x), cp, 0);
36590
- appendSide(sides, gcellWalk(vdict, cp.bb.UR.x, cp.bb.LL.y, false, cp.bb.UR.y), cp, 0);
36591
- cp.sides = sides;
36592
- cp.nsides = sides.length;
37336
+ const sides2 = [];
37337
+ appendSide(sides2, gcellWalk(hdict, cp.bb.LL.x, cp.bb.LL.y, true, cp.bb.UR.x), cp, 1);
37338
+ appendSide(sides2, gcellWalk(vdict, cp.bb.LL.x, cp.bb.LL.y, false, cp.bb.UR.y), cp, 1);
37339
+ appendSide(sides2, gcellWalk(hdict, cp.bb.LL.x, cp.bb.UR.y, true, cp.bb.UR.x), cp, 0);
37340
+ appendSide(sides2, gcellWalk(vdict, cp.bb.UR.x, cp.bb.LL.y, false, cp.bb.UR.y), cp, 0);
37341
+ cp.sides = sides2;
37342
+ cp.nsides = sides2.length;
36593
37343
  if (cp.nsides > maxdeg) maxdeg = cp.nsides;
36594
37344
  }
36595
37345
  return maxdeg;
@@ -37871,21 +38621,10 @@ function inBoxf(p, bb) {
37871
38621
  function midPointf2(a, b) {
37872
38622
  return { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };
37873
38623
  }
37874
- function casteljauStep(prev, t) {
37875
- const u = 1 - t;
37876
- return [
37877
- { x: u * prev[0].x + t * prev[1].x, y: u * prev[0].y + t * prev[1].y },
37878
- { x: u * prev[1].x + t * prev[2].x, y: u * prev[1].y + t * prev[2].y },
37879
- { x: u * prev[2].x + t * prev[3].x, y: u * prev[2].y + t * prev[3].y },
37880
- { x: 0, y: 0 }
37881
- ];
37882
- }
37883
38624
  function subdivideBezier(v, t, side) {
37884
- const r0 = [{ ...v[0] }, { ...v[1] }, { ...v[2] }, { ...v[3] }];
37885
- const r1 = casteljauStep(r0, t);
37886
- const r2 = casteljauStep(r1, t);
37887
- const r3 = casteljauStep(r2, t);
37888
- return side === "left" ? [r0[0], r1[0], r2[0], r3[0]] : [r3[0], r2[1], r1[2], r0[3]];
38625
+ const half = [];
38626
+ bezier([...v], t, side === "left" ? half : null, side === "right" ? half : null);
38627
+ return half;
37889
38628
  }
37890
38629
  function countVertCross(pts, xcoord) {
37891
38630
  let sign2 = fcmp(pts[0].x, xcoord);
@@ -39369,10 +40108,11 @@ function bfsFixDisconnected(n, dist4, closestDist) {
39369
40108
  function bfsVisitNeighbors(vertex, graph, dist4, queue) {
39370
40109
  const vd = graph[vertex];
39371
40110
  const d = dist4[vertex];
40111
+ const unit = graph[0].ewgts.length === 0;
39372
40112
  for (let i = 1; i < vd.nedges; i++) {
39373
40113
  const nb = vd.edges[i];
39374
40114
  if (dist4[nb] < 0) {
39375
- dist4[nb] = d + 1;
40115
+ dist4[nb] = d + (unit ? 1 : Math.trunc(Math.fround(vd.ewgts[i])));
39376
40116
  queue.push(nb);
39377
40117
  }
39378
40118
  }
@@ -40800,11 +41540,12 @@ function runMajorization(g, mode, model) {
40800
41540
  const nodeList = assignNodeIds2(g);
40801
41541
  const n = nodeList.length;
40802
41542
  const haveLen = graphHasLen(g);
40803
- const vtx = makeGraphDataC(g, nodeList, haveLen);
41543
+ const vtx = makeGraphDataC(g, nodeList, haveLen, mode === MODE_HIER || mode === MODE_IPSEP);
40804
41544
  checkStart(g);
40805
41545
  const maxi = lateDouble(g.attrs.get("maxiter"), DFLT_ITERATIONS, 0);
40806
41546
  const epsilon = lateDouble(g.attrs.get("epsilon"), 1e-4, 0);
40807
- const Dij = haveLen ? computeWeightedApspPacked2(vtx, n) : computeApspPacked2(vtx, n);
41547
+ const weighted = haveLen && mode !== MODE_IPSEP;
41548
+ const Dij = weighted ? computeWeightedApspPacked2(vtx, n) : computeApspPacked2(vtx, n);
40808
41549
  const dCoords = [new Float64Array(n), new Float64Array(n)];
40809
41550
  stressMajorizationKDMkernel(Dij, n, dCoords, nodeList, {
40810
41551
  dim: DFLT_DIM,
@@ -40822,11 +41563,11 @@ function graphHasLen(g) {
40822
41563
  }
40823
41564
  return false;
40824
41565
  }
40825
- function makeGraphDataC(g, nodeList, haveLen) {
41566
+ function makeGraphDataC(g, nodeList, haveLen, haveDir) {
40826
41567
  const vtx = nodeList.map((_, i) => ({
40827
41568
  nedges: 1,
40828
41569
  edges: [i],
40829
- ewgts: haveLen ? [0] : []
41570
+ ewgts: haveLen || haveDir ? [0] : []
40830
41571
  }));
40831
41572
  for (const np of nodeList) {
40832
41573
  const i = np.info.id;
@@ -40844,7 +41585,7 @@ function makeGraphDataC(g, nodeList, haveLen) {
40844
41585
  }
40845
41586
  seen.set(vid, entry.nedges);
40846
41587
  entry.edges.push(vid);
40847
- if (haveLen) entry.ewgts.push(dist4);
41588
+ if (haveLen || haveDir) entry.ewgts.push(dist4);
40848
41589
  entry.nedges++;
40849
41590
  }
40850
41591
  }
@@ -41905,7 +42646,7 @@ var RIGHT3 = 1 << 1;
41905
42646
  var TOP3 = 1 << 2;
41906
42647
  var LEFT3 = 1 << 3;
41907
42648
  var add = (p, q) => ({ x: p.x + q.x, y: p.y + q.y });
41908
- function sideCone(p, sides) {
42649
+ function sideCone(p, sides2) {
41909
42650
  const north = { x: 0, y: 1 };
41910
42651
  const northeast = { x: 1, y: 1 };
41911
42652
  const east = { x: 1, y: 0 };
@@ -41914,7 +42655,7 @@ function sideCone(p, sides) {
41914
42655
  const southwest = { x: -1, y: -1 };
41915
42656
  const west = { x: -1, y: 0 };
41916
42657
  const northwest = { x: -1, y: 1 };
41917
- switch (sides) {
42658
+ switch (sides2) {
41918
42659
  case TOP3:
41919
42660
  return [add(p, north), add(p, northwest), add(p, northeast)];
41920
42661
  case TOP3 | RIGHT3:
@@ -41935,17 +42676,17 @@ function sideCone(p, sides) {
41935
42676
  return [p, p, p];
41936
42677
  }
41937
42678
  }
41938
- function addEndpoint(rtr, p, obsId, vId, sides) {
42679
+ function addEndpoint(rtr, p, obsId, vId, sides2) {
41939
42680
  const starti = rtr.obs[obsId];
41940
42681
  const endi = rtr.obs[obsId + 1];
41941
42682
  const pts = rtr.ps;
41942
- const [vr, v0, v1] = sideCone(p, sides);
42683
+ const [vr, v0, v1] = sideCone(p, sides2);
41943
42684
  rtr.tg.nodes[vId].edges.length = 0;
41944
42685
  rtr.tg.nodes[vId].ctr = p;
41945
42686
  for (let i = starti; i < endi; i++) {
41946
42687
  const seg2 = { i, j: i < endi - 1 ? i + 1 : starti };
41947
42688
  const t = findMap(rtr.trimap, seg2.i, seg2.j);
41948
- if (sides !== 0 && !inCone(v0, p, v1, pts[seg2.i]) && !inCone(v0, p, v1, pts[seg2.j]) && !raySeg(p, vr, pts[seg2.i], pts[seg2.j])) {
42689
+ 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])) {
41949
42690
  continue;
41950
42691
  }
41951
42692
  addTriEdge(rtr.tg, vId, t, seg2);
@@ -42609,7 +43350,7 @@ function boxCornerMargin(j, m) {
42609
43350
  return { x: m.x, y: -m.y };
42610
43351
  }
42611
43352
  function polyObstacle(n, poly, pmargin) {
42612
- const sides = poly.sides;
43353
+ const sides2 = poly.sides;
42613
43354
  const stored = poly.vertices;
42614
43355
  if (stored == null) return null;
42615
43356
  const penwidth = poly.penwidth ?? 1;
@@ -42619,19 +43360,19 @@ function polyObstacle(n, poly, pmargin) {
42619
43360
  const storedRings = Math.max(poly.peripheries, 1);
42620
43361
  let verts;
42621
43362
  if (ringIdx < storedRings) {
42622
- verts = stored.slice(ringIdx * sides, (ringIdx + 1) * sides);
43363
+ verts = stored.slice(ringIdx * sides2, (ringIdx + 1) * sides2);
42623
43364
  } else {
42624
- const outer = stored.slice((storedRings - 1) * sides, storedRings * sides);
42625
- verts = polygonOutlineRing(outer, sides, penwidth);
43365
+ const outer = stored.slice((storedRings - 1) * sides2, storedRings * sides2);
43366
+ verts = polygonOutlineRing(outer, sides2, penwidth);
42626
43367
  }
42627
- if (verts.length < sides) return null;
42628
- const ps = new Array(sides);
42629
- for (let j = 0; j < sides; j++) {
43368
+ if (verts.length < sides2) return null;
43369
+ const ps = new Array(sides2);
43370
+ for (let j = 0; j < sides2; j++) {
42630
43371
  const v = verts[j];
42631
43372
  if (v === void 0) return null;
42632
43373
  let polyp;
42633
43374
  if (pmargin.doAdd) {
42634
- if (sides === 4) {
43375
+ if (sides2 === 4) {
42635
43376
  const m = boxCornerMargin(j, { x: pmargin.x, y: pmargin.y });
42636
43377
  polyp = { x: v.x + m.x, y: v.y + m.y };
42637
43378
  } else {
@@ -42641,22 +43382,22 @@ function polyObstacle(n, poly, pmargin) {
42641
43382
  } else {
42642
43383
  polyp = { x: v.x * pmargin.x, y: v.y * pmargin.y };
42643
43384
  }
42644
- ps[sides - j - 1] = { x: polyp.x + n.info.coord.x, y: polyp.y + n.info.coord.y };
43385
+ ps[sides2 - j - 1] = { x: polyp.x + n.info.coord.x, y: polyp.y + n.info.coord.y };
42645
43386
  }
42646
43387
  return { ps };
42647
43388
  }
42648
43389
  function ellipseObstacle(n, pmargin) {
42649
- const sides = 8;
42650
- const width = (n.info.outline_width ?? 0) > 0 ? n.info.outline_width * 72 : n.info.lw + n.info.rw;
42651
- const height = (n.info.outline_height ?? 0) > 0 ? n.info.outline_height * 72 : n.info.ht;
43390
+ const sides2 = 8;
43391
+ const width2 = (n.info.outline_width ?? 0) > 0 ? n.info.outline_width * 72 : n.info.lw + n.info.rw;
43392
+ const height2 = (n.info.outline_height ?? 0) > 0 ? n.info.outline_height * 72 : n.info.ht;
42652
43393
  const mx = pmargin.doAdd ? pmargin.x : 0;
42653
43394
  const my = pmargin.doAdd ? pmargin.y : 0;
42654
- const a = (width + mx) / 2;
42655
- const b = (height + my) / 2;
42656
- const ps = new Array(sides);
42657
- for (let j = 0; j < sides; j++) {
42658
- const polyp = circumscribedCorner(a, b, j, sides);
42659
- ps[sides - j - 1] = { x: polyp.x + n.info.coord.x, y: polyp.y + n.info.coord.y };
43395
+ const a = (width2 + mx) / 2;
43396
+ const b = (height2 + my) / 2;
43397
+ const ps = new Array(sides2);
43398
+ for (let j = 0; j < sides2; j++) {
43399
+ const polyp = circumscribedCorner(a, b, j, sides2);
43400
+ ps[sides2 - j - 1] = { x: polyp.x + n.info.coord.x, y: polyp.y + n.info.coord.y };
42660
43401
  }
42661
43402
  return { ps };
42662
43403
  }
@@ -42733,10 +43474,10 @@ function makeOrthoObstacle(n, sep) {
42733
43474
  cy += (bb.ur.y + bb.ll.y) / 2;
42734
43475
  cx += 0;
42735
43476
  } else {
42736
- const width = info.lw + info.rw;
42737
- const outlineW = (info.outline_width ?? 0) > 0 ? info.outline_width * 72 : width;
43477
+ const width2 = info.lw + info.rw;
43478
+ const outlineW = (info.outline_width ?? 0) > 0 ? info.outline_width * 72 : width2;
42738
43479
  const outlineH = (info.outline_height ?? 0) > 0 ? info.outline_height * 72 : info.ht;
42739
- const outlineLw = width > 0 ? info.lw * outlineW / width : outlineW / 2;
43480
+ const outlineLw = width2 > 0 ? info.lw * outlineW / width2 : outlineW / 2;
42740
43481
  lw = outlineLw;
42741
43482
  rw = outlineLw;
42742
43483
  hh = outlineH / 2;
@@ -42914,17 +43655,11 @@ var OrthoHelper = class _OrthoHelper {
42914
43655
  }
42915
43656
  static buildEdges(g, nodeArr, orthoNodes) {
42916
43657
  const concentrate = g.root.info.concentrate ?? false;
42917
- const seen = /* @__PURE__ */ new Set();
43658
+ const ps = concentrate ? new PointSet() : null;
42918
43659
  const edges = [];
42919
43660
  for (const n of nodesInSeq(g)) {
42920
43661
  for (const e of n.outEdges(g)) {
42921
- if (concentrate) {
42922
- const ti = e.tail.id;
42923
- const hi = e.head.id;
42924
- const key = ti <= hi ? `${ti}|${hi}` : `${hi}|${ti}`;
42925
- if (seen.has(key)) continue;
42926
- seen.add(key);
42927
- }
43662
+ if (ps && isConcentrateDup(ps, e)) continue;
42928
43663
  const tc = e.tail.info.coord;
42929
43664
  const hc = e.head.info.coord;
42930
43665
  const tp = e.info.tail_port.p;
@@ -44980,13 +45715,13 @@ function pointDistance(p1, o1, p2, o2, dim) {
44980
45715
  }
44981
45716
  return Math.sqrt(dist4);
44982
45717
  }
44983
- function quadTreeNew(dim, center, width, maxLevel) {
45718
+ function quadTreeNew(dim, center, width2, maxLevel) {
44984
45719
  return {
44985
45720
  n: 0,
44986
45721
  totalWeight: 0,
44987
45722
  dim,
44988
45723
  center: center.slice(0, dim),
44989
- width,
45724
+ width: width2,
44990
45725
  average: null,
44991
45726
  qts: null,
44992
45727
  l: null,
@@ -45004,15 +45739,15 @@ function getQuadrant(dim, center, coord, off) {
45004
45739
  }
45005
45740
  return d;
45006
45741
  }
45007
- function newInQuadrant(dim, parentCenter, width, maxLevel, i) {
45008
- const qt = quadTreeNew(dim, parentCenter, width, maxLevel);
45742
+ function newInQuadrant(dim, parentCenter, width2, maxLevel, i) {
45743
+ const qt = quadTreeNew(dim, parentCenter, width2, maxLevel);
45009
45744
  const center = qt.center;
45010
45745
  let ii = i;
45011
45746
  for (let k = 0; k < dim; k++) {
45012
45747
  if (ii % 2 === 0) {
45013
- center[k] -= width;
45748
+ center[k] -= width2;
45014
45749
  } else {
45015
- center[k] += width;
45750
+ center[k] += width2;
45016
45751
  }
45017
45752
  ii = (ii - ii % 2) / 2;
45018
45753
  }
@@ -45083,14 +45818,14 @@ function quadTreeNewFromPointList(dim, n, maxLevel, coord) {
45083
45818
  xmax[k] = Math.max(xmax[k], coord[i * dim + k]);
45084
45819
  }
45085
45820
  }
45086
- let width = xmax[0] - xmin[0];
45821
+ let width2 = xmax[0] - xmin[0];
45087
45822
  for (let i = 0; i < dim; i++) {
45088
45823
  center[i] = (xmin[i] + xmax[i]) * 0.5;
45089
- width = Math.max(width, xmax[i] - xmin[i]);
45824
+ width2 = Math.max(width2, xmax[i] - xmin[i]);
45090
45825
  }
45091
- width = Math.max(width, 1e-5);
45092
- width *= 0.52;
45093
- const qt = quadTreeNew(dim, center, width, maxLevel);
45826
+ width2 = Math.max(width2, 1e-5);
45827
+ width2 *= 0.52;
45828
+ const qt = quadTreeNew(dim, center, width2, maxLevel);
45094
45829
  for (let i = 0; i < n; i++) {
45095
45830
  quadTreeAdd(qt, coord, i * dim, 1, i);
45096
45831
  }
@@ -45910,18 +46645,18 @@ function compScanPoints(p, q) {
45910
46645
  if (pp.node < qq.node) return -1;
45911
46646
  return 0;
45912
46647
  }
45913
- function getOverlapGraph(dim, n, x, width, checkOverlapOnly) {
46648
+ function getOverlapGraph(dim, n, x, width2, checkOverlapOnly) {
45914
46649
  let A3 = smNew(n, n, MATRIX_TYPE_REAL, FORMAT_COORD);
45915
46650
  const scanpointsx = new Array(2 * n);
45916
46651
  for (let i = 0; i < n; i++) {
45917
- scanpointsx[2 * i] = { node: i, x: x[i * dim] - width[i * dim], status: INTV_OPEN };
45918
- scanpointsx[2 * i + 1] = { node: i + n, x: x[i * dim] + width[i * dim], status: INTV_CLOSE };
46652
+ scanpointsx[2 * i] = { node: i, x: x[i * dim] - width2[i * dim], status: INTV_OPEN };
46653
+ scanpointsx[2 * i + 1] = { node: i + n, x: x[i * dim] + width2[i * dim], status: INTV_CLOSE };
45919
46654
  }
45920
46655
  scanpointsx.sort(compScanPoints);
45921
46656
  const scanpointsy = new Array(2 * n);
45922
46657
  for (let i = 0; i < n; i++) {
45923
- scanpointsy[i] = { node: i, x: x[i * dim + 1] - width[i * dim + 1], status: INTV_OPEN };
45924
- scanpointsy[i + n] = { node: i, x: x[i * dim + 1] + width[i * dim + 1], status: INTV_CLOSE };
46658
+ scanpointsy[i] = { node: i, x: x[i * dim + 1] - width2[i * dim + 1], status: INTV_OPEN };
46659
+ scanpointsy[i + n] = { node: i, x: x[i * dim + 1] + width2[i * dim + 1], status: INTV_CLOSE };
45925
46660
  }
45926
46661
  const treey = rbTreeCreate(compScanPoints, () => void 0);
45927
46662
  outer:
@@ -45954,7 +46689,7 @@ function getOverlapGraph(dim, n, x, width, checkOverlapOnly) {
45954
46689
  A3 = smSymmetrize(B2, false);
45955
46690
  return A3;
45956
46691
  }
45957
- function idealDistanceAvoidOverlap(dim, A3, x, width, idealDistance) {
46692
+ function idealDistanceAvoidOverlap(dim, A3, x, width2, idealDistance) {
45958
46693
  const ia = A3.ia;
45959
46694
  const ja = A3.ja;
45960
46695
  const expandmax = 1.5;
@@ -45968,8 +46703,8 @@ function idealDistanceAvoidOverlap(dim, A3, x, width, idealDistance) {
45968
46703
  const dist4 = distance(x, dim, i, jj);
45969
46704
  const dx = Math.abs(x[i * dim] - x[jj * dim]);
45970
46705
  const dy = Math.abs(x[i * dim + 1] - x[jj * dim + 1]);
45971
- const wx = width[i * dim] + width[jj * dim];
45972
- const wy = width[i * dim + 1] + width[jj * dim + 1];
46706
+ const wx = width2[i * dim] + width2[jj * dim];
46707
+ const wy = width2[i * dim + 1] + width2[jj * dim + 1];
45973
46708
  if (dx < MACHINEACC * wx && dy < MACHINEACC * wy) {
45974
46709
  idealDistance[j] = Math.hypot(wx, wy);
45975
46710
  tmax = 2;
@@ -46000,7 +46735,7 @@ function idealDistanceAvoidOverlap(dim, A3, x, width, idealDistance) {
46000
46735
  function scaleCoord(dim, m, x, scale) {
46001
46736
  for (let i = 0; i < dim * m; i++) x[i] *= scale;
46002
46737
  }
46003
- function overlapScaling(dim, m, x, width, scaleStaIn, scaleStoIn, epsilon, maxiter) {
46738
+ function overlapScaling(dim, m, x, width2, scaleStaIn, scaleStoIn, epsilon, maxiter) {
46004
46739
  let scaleSta = scaleStaIn;
46005
46740
  let scaleSto = scaleStoIn;
46006
46741
  let iter = 0;
@@ -46008,7 +46743,7 @@ function overlapScaling(dim, m, x, width, scaleStaIn, scaleStoIn, epsilon, maxit
46008
46743
  scaleSta = 0;
46009
46744
  } else {
46010
46745
  scaleCoord(dim, m, x, scaleSta);
46011
- const C6 = getOverlapGraph(dim, m, x, width, true);
46746
+ const C6 = getOverlapGraph(dim, m, x, width2, true);
46012
46747
  if (C6.nz === 0) return;
46013
46748
  scaleCoord(dim, m, x, 1 / scaleSta);
46014
46749
  }
@@ -46023,7 +46758,7 @@ function overlapScaling(dim, m, x, width, scaleStaIn, scaleStoIn, epsilon, maxit
46023
46758
  do {
46024
46759
  scaleSto *= 2;
46025
46760
  scaleCoord(dim, m, x, 2);
46026
- const C6 = getOverlapGraph(dim, m, x, width, true);
46761
+ const C6 = getOverlapGraph(dim, m, x, width2, true);
46027
46762
  overlap5 = C6.nz > 0;
46028
46763
  } while (overlap5);
46029
46764
  scaleCoord(dim, m, x, 1 / scaleSto);
@@ -46032,7 +46767,7 @@ function overlapScaling(dim, m, x, width, scaleStaIn, scaleStoIn, epsilon, maxit
46032
46767
  while (iter++ < maxiter && scaleSto - scaleSta > epsilon) {
46033
46768
  const scale = 0.5 * (scaleSta + scaleSto);
46034
46769
  scaleCoord(dim, m, x, scale);
46035
- const C6 = getOverlapGraph(dim, m, x, width, true);
46770
+ const C6 = getOverlapGraph(dim, m, x, width2, true);
46036
46771
  scaleCoord(dim, m, x, 1 / scale);
46037
46772
  const overlap5 = C6.nz > 0;
46038
46773
  if (overlap5) {
@@ -46043,7 +46778,7 @@ function overlapScaling(dim, m, x, width, scaleStaIn, scaleStoIn, epsilon, maxit
46043
46778
  }
46044
46779
  scaleCoord(dim, m, x, scaleBest);
46045
46780
  }
46046
- function overlapSmootherNew(m, dim, x, width, neighborhoodOnly, shrink) {
46781
+ function overlapSmootherNew(m, dim, x, width2, neighborhoodOnly, shrink) {
46047
46782
  const sm = {
46048
46783
  Lw: null,
46049
46784
  Lwd: null,
@@ -46053,16 +46788,16 @@ function overlapSmootherNew(m, dim, x, width, neighborhoodOnly, shrink) {
46053
46788
  };
46054
46789
  let B2 = callTri(m, x);
46055
46790
  if (!neighborhoodOnly) {
46056
- const C6 = getOverlapGraph(dim, m, x, width, false);
46791
+ const C6 = getOverlapGraph(dim, m, x, width2, false);
46057
46792
  B2 = smAdd(B2, C6);
46058
46793
  }
46059
46794
  sm.Lw = B2;
46060
46795
  sm.Lwd = smCopy(sm.Lw);
46061
- const { tmax, tmin } = idealDistanceAvoidOverlap(dim, sm.Lwd, x, width, sm.Lwd.a);
46796
+ const { tmax, tmin } = idealDistanceAvoidOverlap(dim, sm.Lwd, x, width2, sm.Lwd.a);
46062
46797
  if (tmax < 1 && shrink) {
46063
46798
  const scaleSta = Math.min(1, tmax * 1.0001);
46064
46799
  const scaleSto = 1;
46065
- overlapScaling(dim, m, x, width, scaleSta, scaleSto, 1e-4, 15);
46800
+ overlapScaling(dim, m, x, width2, scaleSta, scaleSto, 1e-4, 15);
46066
46801
  return { sm, maxOverlap: 1, minOverlap: tmin };
46067
46802
  }
46068
46803
  const iw = sm.Lw.ia;
@@ -46336,7 +47071,7 @@ function scAdjust(g, equal) {
46336
47071
  // src/layout/neato/simple-scale.ts
46337
47072
  var ISZERO = (d) => Math.abs(d) < 1e-9;
46338
47073
  var LF = /^\s*([+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?)/;
46339
- function scanPair(p) {
47074
+ function scanPair2(p) {
46340
47075
  const m1 = LF.exec(p);
46341
47076
  if (m1 === null) return [];
46342
47077
  const rest = p.slice(m1[0].length);
@@ -46347,7 +47082,7 @@ function scanPair(p) {
46347
47082
  function simpleScale(g) {
46348
47083
  const p = aggetGraph(g, "scale");
46349
47084
  if (p === void 0) return 0;
46350
- const sc = scanPair(p);
47085
+ const sc = scanPair2(p);
46351
47086
  if (sc.length === 0) return 0;
46352
47087
  const x = sc[0];
46353
47088
  if (ISZERO(x)) return 0;
@@ -46671,16 +47406,16 @@ function overlaps(p) {
46671
47406
  function initItem(n, margin) {
46672
47407
  const x = cround(SCALE * (n.info.pos?.[0] ?? 0) * POINTS_PER_INCH6);
46673
47408
  const y = cround(SCALE * (n.info.pos?.[1] ?? 0) * POINTS_PER_INCH6);
46674
- const width = n.info.width ?? 0;
46675
- const height = n.info.height ?? 0;
47409
+ const width2 = n.info.width ?? 0;
47410
+ const height2 = n.info.height ?? 0;
46676
47411
  let w2;
46677
47412
  let h2;
46678
47413
  if (margin.doAdd) {
46679
- w2 = d2i(SCALE * (cround(width / 2 * POINTS_PER_INCH6) + margin.x));
46680
- h2 = d2i(SCALE * (cround(height / 2 * POINTS_PER_INCH6) + margin.y));
47414
+ w2 = d2i(SCALE * (cround(width2 / 2 * POINTS_PER_INCH6) + margin.x));
47415
+ h2 = d2i(SCALE * (cround(height2 / 2 * POINTS_PER_INCH6) + margin.y));
46681
47416
  } else {
46682
- w2 = cround(margin.x * SCALE2 * width * POINTS_PER_INCH6);
46683
- h2 = cround(margin.y * SCALE2 * height * POINTS_PER_INCH6);
47417
+ w2 = cround(margin.x * SCALE2 * width2 * POINTS_PER_INCH6);
47418
+ h2 = cround(margin.y * SCALE2 * height2 * POINTS_PER_INCH6);
46684
47419
  }
46685
47420
  return {
46686
47421
  val: 0,
@@ -46782,12 +47517,12 @@ function atoi2(s) {
46782
47517
  }
46783
47518
  function genRound(n, xm, ym) {
46784
47519
  const isides = atoi2(n.attrs.get("samplepoints"));
46785
- const sides = isides < MIN_SAMPLES ? DFLT_SAMPLE2 : isides;
47520
+ const sides2 = isides < MIN_SAMPLES ? DFLT_SAMPLE2 : isides;
46786
47521
  const verts = [];
46787
- for (let i = 0; i < sides; i++) {
47522
+ for (let i = 0; i < sides2; i++) {
46788
47523
  verts.push({
46789
- x: (n.info.width / 2 + xm) * Math.cos(i / sides * Math.PI * 2),
46790
- y: (n.info.height / 2 + ym) * Math.sin(i / sides * Math.PI * 2)
47524
+ x: (n.info.width / 2 + xm) * Math.cos(i / sides2 * Math.PI * 2),
47525
+ y: (n.info.height / 2 + ym) * Math.sin(i / sides2 * Math.PI * 2)
46791
47526
  });
46792
47527
  }
46793
47528
  return verts;
@@ -49205,30 +49940,30 @@ function boundaryFromBB(bb) {
49205
49940
  x: (bb.llx + bb.urx) / 2,
49206
49941
  y: (bb.lly + bb.ury) / 2
49207
49942
  };
49208
- const width = EXPFACTOR * (bb.urx - bb.llx);
49209
- const height = EXPFACTOR * (bb.ury - bb.lly);
49210
- sizeBoundary(width, height);
49943
+ const width2 = EXPFACTOR * (bb.urx - bb.llx);
49944
+ const height2 = EXPFACTOR * (bb.ury - bb.lly);
49945
+ sizeBoundary(width2, height2);
49211
49946
  const alpha = Math.atan2(parms.Ht, parms.Wd);
49212
49947
  parms.Wd = parms.Wd / Math.cos(alpha);
49213
49948
  parms.Ht = parms.Ht / Math.sin(alpha);
49214
49949
  return ctr;
49215
49950
  }
49216
- function sizeBoundary(width, height) {
49951
+ function sizeBoundary(width2, height2) {
49217
49952
  const area = 4 * parms.Wd * parms.Ht;
49218
- let quot = width * height / area;
49953
+ let quot = width2 * height2 / area;
49219
49954
  if (quot >= 1) {
49220
- parms.Wd = width / 2;
49221
- parms.Ht = height / 2;
49955
+ parms.Wd = width2 / 2;
49956
+ parms.Ht = height2 / 2;
49222
49957
  } else if (quot > 0) {
49223
49958
  quot = 2 * Math.sqrt(quot);
49224
- parms.Wd = width / quot;
49225
- parms.Ht = height / quot;
49226
- } else if (width > 0) {
49227
- parms.Wd = width / 2;
49228
- parms.Ht = area / width / 2;
49229
- } else if (height > 0) {
49230
- parms.Wd = area / height / 2;
49231
- parms.Ht = height / 2;
49959
+ parms.Wd = width2 / quot;
49960
+ parms.Ht = height2 / quot;
49961
+ } else if (width2 > 0) {
49962
+ parms.Wd = width2 / 2;
49963
+ parms.Ht = area / width2 / 2;
49964
+ } else if (height2 > 0) {
49965
+ parms.Wd = area / height2 / 2;
49966
+ parms.Ht = height2 / 2;
49232
49967
  }
49233
49968
  }
49234
49969
  function placeWithPorts(g, pp, ctr) {
@@ -50151,7 +50886,7 @@ function finalCC(g, cc, pts, rg, infop) {
50151
50886
  };
50152
50887
  }
50153
50888
  function applyMarginAndBorder(rg, bb, margin) {
50154
- const border = rg.info.border ?? [
50889
+ const border2 = rg.info.border ?? [
50155
50890
  { x: 0, y: 0 },
50156
50891
  { x: 0, y: 0 },
50157
50892
  { x: 0, y: 0 },
@@ -50159,12 +50894,12 @@ function applyMarginAndBorder(rg, bb, margin) {
50159
50894
  ];
50160
50895
  const pt = {
50161
50896
  x: -bb.ll.x + margin,
50162
- y: -bb.ll.y + margin + border[BOTTOM_IX].y
50897
+ y: -bb.ll.y + margin + border2[BOTTOM_IX].y
50163
50898
  };
50164
50899
  bb.ll.x = 0;
50165
50900
  bb.ll.y = 0;
50166
50901
  bb.ur.x += pt.x + margin;
50167
- bb.ur.y += pt.y + margin + border[TOP_IX].y;
50902
+ bb.ur.y += pt.y + margin + border2[TOP_IX].y;
50168
50903
  return pt;
50169
50904
  }
50170
50905
  function evalPositions(g, rootg) {
@@ -52072,9 +52807,9 @@ function applyLabelExpansion(g, total, rbb) {
52072
52807
  }
52073
52808
  function addMarginAndBorder(g, margin, rbb) {
52074
52809
  let { llx, lly, urx, ury } = rbb;
52075
- const border = g.info.border;
52076
- const bottomY = border ? border[BOTTOM_IX].y : 0;
52077
- const topY = border ? border[TOP_IX].y : 0;
52810
+ const border2 = g.info.border;
52811
+ const bottomY = border2 ? border2[BOTTOM_IX].y : 0;
52812
+ const topY = border2 ? border2[TOP_IX].y : 0;
52078
52813
  llx -= margin;
52079
52814
  urx += margin;
52080
52815
  lly -= margin + bottomY;
@@ -52645,18 +53380,9 @@ function approxLen(list, off) {
52645
53380
  return dist3(list[off], list[off + 1]) + dist3(list[off + 1], list[off + 2]) + dist3(list[off + 2], list[off + 3]);
52646
53381
  }
52647
53382
  function splitCubic(v, t) {
52648
- const u = 1 - t;
52649
- const row = [v[0], v[1], v[2], v[3]];
52650
- const left2 = [row[0]];
52651
- const right2 = new Array(4);
52652
- right2[3] = row[3];
52653
- for (let i = 1; i <= 3; i++) {
52654
- for (let j = 0; j <= 3 - i; j++) {
52655
- row[j] = { x: u * row[j].x + t * row[j + 1].x, y: u * row[j].y + t * row[j + 1].y };
52656
- }
52657
- left2.push(row[0]);
52658
- right2[3 - i] = row[3 - i];
52659
- }
53383
+ const left2 = [];
53384
+ const right2 = [];
53385
+ bezier(v, t, left2, right2);
52660
53386
  return { left: left2, right: right2 };
52661
53387
  }
52662
53388
  function splitBSpline(list, t) {
@@ -52776,17 +53502,6 @@ function mymod(original, modulus) {
52776
53502
  function l2dist(p0, p1) {
52777
53503
  return Math.hypot(p0.x - p1.x, p0.y - p1.y);
52778
53504
  }
52779
- function bezierPoint(v, t) {
52780
- const vx = [v[0].x, v[1].x, v[2].x, v[3].x];
52781
- const vy = [v[0].y, v[1].y, v[2].y, v[3].y];
52782
- for (let i = 1; i <= 3; i++) {
52783
- for (let j = 0; j <= 3 - i; j++) {
52784
- vx[j] = (1 - t) * vx[j] + t * vx[j + 1];
52785
- vy[j] = (1 - t) * vy[j] + t * vy[j + 1];
52786
- }
52787
- }
52788
- return { x: vx[0], y: vy[0] };
52789
- }
52790
53505
  function pathtolines(bez) {
52791
53506
  const arr = [];
52792
53507
  const A3 = bez.list;
@@ -52802,7 +53517,7 @@ function pathtolines(bez) {
52802
53517
  for (let j = 1; j <= 3; j++) V[j] = A3[i + j];
52803
53518
  let p0 = V[0];
52804
53519
  for (let step = 1; step <= BEZIER_SUBDIVISION; step++) {
52805
- const p1 = bezierPoint(V, step / BEZIER_SUBDIVISION);
53520
+ const p1 = bezier(V, step / BEZIER_SUBDIVISION, null, null);
52806
53521
  linelen += l2dist(p0, p1);
52807
53522
  push(p1, linelen);
52808
53523
  p0 = p1;
@@ -53027,9 +53742,9 @@ function agstrcanonText(arg) {
53027
53742
  if (needsQuotes || cnt === 1 && (first === 46 || first === 45)) {
53028
53743
  return new TextDecoder().decode(new Uint8Array(out));
53029
53744
  }
53030
- const lower = arg.toLowerCase();
53745
+ const lower2 = arg.toLowerCase();
53031
53746
  for (const tok of CANON_KEYWORDS) {
53032
- if (tok === lower) return new TextDecoder().decode(new Uint8Array(out));
53747
+ if (tok === lower2) return new TextDecoder().decode(new Uint8Array(out));
53033
53748
  }
53034
53749
  return arg;
53035
53750
  }
@@ -53113,9 +53828,9 @@ function writePlainEdge(e, extend, out) {
53113
53828
  if (lbl !== void 0) {
53114
53829
  out.push(" " + agstrcanonText(lbl.text) + " " + plainCoord(lbl.pos.x) + " " + plainCoord(lbl.pos.y));
53115
53830
  }
53116
- const style = lateNN(e.attrs.get("style"), "solid");
53831
+ const style2 = lateNN(e.attrs.get("style"), "solid");
53117
53832
  const color = lateNN(e.attrs.get("color"), "black");
53118
- out.push(" " + style + " " + color + "\n");
53833
+ out.push(" " + style2 + " " + color + "\n");
53119
53834
  }
53120
53835
  function writePlain(g, job, extend) {
53121
53836
  const w = plainCoord(g.info.bb.ur.x);
@@ -54682,9 +55397,9 @@ function createXdotRenderer() {
54682
55397
 
54683
55398
  // src/render/svg-tapered-edge.ts
54684
55399
  function edgeIsTapered(e) {
54685
- const style = e.attrs.get("style");
54686
- if (style === void 0 || style === "") return false;
54687
- return style.split(",").some((t) => t.trim() === "tapered");
55400
+ const style2 = e.attrs.get("style");
55401
+ if (style2 === void 0 || style2 === "") return false;
55402
+ return style2.split(",").some((t) => t.trim() === "tapered");
54688
55403
  }
54689
55404
  function svgTaperedEdge(e, job) {
54690
55405
  const spl = e.info.spl;
@@ -54905,16 +55620,16 @@ var SvgRenderer = class {
54905
55620
  */
54906
55621
  usershape(src, b, job) {
54907
55622
  const g = (n) => String(parseFloat(n.toPrecision(6)));
54908
- const width = b.ur.x - b.ll.x;
54909
- const height = b.ur.y - b.ll.y;
54910
- const originx = (b.ur.x + b.ll.x - width) / 2;
54911
- const originy = (b.ur.y + b.ll.y + height) / 2;
55623
+ const width2 = b.ur.x - b.ll.x;
55624
+ const height2 = b.ur.y - b.ll.y;
55625
+ const originx = (b.ur.x + b.ll.x - width2) / 2;
55626
+ const originy = (b.ur.y + b.ll.y + height2) / 2;
54912
55627
  let href = src;
54913
55628
  if (job.inlineImages === true) {
54914
55629
  const found = findImageBytes(src, job.imageResolver);
54915
55630
  if (found !== null) href = toDataUri(found.bytes, found.mime);
54916
55631
  }
54917
- job.write('<image xlink:href="' + escapeXml(href) + '" width="' + g(width) + 'px" height="' + g(height) + 'px" preserveAspectRatio="xMinYMin meet" x="' + g(originx) + '" y="' + g(-originy) + '"/>\n');
55632
+ 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');
54918
55633
  }
54919
55634
  comment(text, job) {
54920
55635
  svgComment(text, job);