@knowvah/dot-engine 2.6.9 → 2.6.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/common/html-entities.d.ts +13 -5
- package/dist/common/html-entities.d.ts.map +1 -1
- package/dist/common/htmltable-emit-fill.d.ts +1 -1
- package/dist/common/htmltable-emit-fill.d.ts.map +1 -1
- package/dist/common/htmltable-emit.d.ts +8 -0
- package/dist/common/htmltable-emit.d.ts.map +1 -1
- package/dist/common/htmltable-lex-chardata.d.ts +9 -0
- package/dist/common/htmltable-lex-chardata.d.ts.map +1 -1
- package/dist/common/htmltable-style.d.ts +22 -0
- package/dist/common/htmltable-style.d.ts.map +1 -0
- package/dist/index.js +345 -284
- package/dist/index.js.map +4 -4
- package/dist/render.js +95 -34
- package/dist/render.js.map +4 -4
- package/package.json +1 -1
- package/src/common/html-entities.ts +77 -25
- package/src/common/htmltable-emit-fill.ts +7 -6
- package/src/common/htmltable-emit.ts +5 -22
- package/src/common/htmltable-lex-chardata.ts +42 -8
- package/src/common/htmltable-style.ts +38 -0
package/dist/index.js
CHANGED
|
@@ -9431,250 +9431,35 @@ function underlineDraw(ring, coord, filled, ctx) {
|
|
|
9431
9431
|
renderShapePolyline([ring[2], ring[3]], coord, ctx);
|
|
9432
9432
|
}
|
|
9433
9433
|
|
|
9434
|
-
// src/common/
|
|
9435
|
-
|
|
9436
|
-
|
|
9437
|
-
|
|
9438
|
-
|
|
9439
|
-
|
|
9440
|
-
|
|
9441
|
-
|
|
9442
|
-
|
|
9443
|
-
|
|
9444
|
-
|
|
9445
|
-
|
|
9446
|
-
|
|
9447
|
-
|
|
9448
|
-
|
|
9449
|
-
|
|
9450
|
-
|
|
9451
|
-
|
|
9452
|
-
|
|
9453
|
-
|
|
9454
|
-
|
|
9455
|
-
|
|
9456
|
-
|
|
9457
|
-
|
|
9458
|
-
|
|
9459
|
-
|
|
9460
|
-
}
|
|
9461
|
-
left2 -= t;
|
|
9462
|
-
segs.push({ color: color.length > 0 ? color : null, t, hasFraction: t > 0 && v > 0 });
|
|
9463
|
-
return { left: left2, rval };
|
|
9464
|
-
}
|
|
9465
|
-
function distributeLeft(segs, left2) {
|
|
9466
|
-
if (left2 <= 0) return;
|
|
9467
|
-
const zeroCount = segs.filter((s) => s.t <= 0).length;
|
|
9468
|
-
if (zeroCount > 0) {
|
|
9469
|
-
const delta2 = left2 / zeroCount;
|
|
9470
|
-
for (const s of segs) {
|
|
9471
|
-
if (s.t <= 0) s.t = delta2;
|
|
9472
|
-
}
|
|
9473
|
-
} else if (segs.length > 0) {
|
|
9474
|
-
segs[segs.length - 1].t += left2;
|
|
9475
|
-
}
|
|
9476
|
-
}
|
|
9477
|
-
function trimTrailing(segs) {
|
|
9478
|
-
while (segs.length > 0 && (segs[segs.length - 1]?.t ?? 0) <= 0) {
|
|
9479
|
-
segs.pop();
|
|
9480
|
-
}
|
|
9481
|
-
}
|
|
9482
|
-
function parseSegs(colorlist) {
|
|
9483
|
-
const segs = [];
|
|
9484
|
-
let left2 = 1;
|
|
9485
|
-
let rval = 0;
|
|
9486
|
-
let badFloatCount = 0;
|
|
9487
|
-
const warnedExceeded = { v: false };
|
|
9488
|
-
for (const token of colorlist.split(":")) {
|
|
9489
|
-
const result = appendSeg(token, left2, segs, warnedExceeded);
|
|
9490
|
-
if (result === null) {
|
|
9491
|
-
const errCode = badFloatCount === 0 ? 2 : 1;
|
|
9492
|
-
badFloatCount++;
|
|
9493
|
-
return { segs: [], error: errCode };
|
|
9494
|
-
}
|
|
9495
|
-
if (result.rval === 3) rval = 3;
|
|
9496
|
-
left2 = result.left;
|
|
9497
|
-
if (aeq0(left2)) {
|
|
9498
|
-
left2 = 0;
|
|
9499
|
-
break;
|
|
9500
|
-
}
|
|
9501
|
-
}
|
|
9502
|
-
distributeLeft(segs, left2);
|
|
9503
|
-
trimTrailing(segs);
|
|
9504
|
-
return { segs, error: rval };
|
|
9505
|
-
}
|
|
9506
|
-
|
|
9507
|
-
// src/common/style-resolve.ts
|
|
9508
|
-
var DEFAULT_COLOR = "black";
|
|
9509
|
-
var DEFAULT_FILL = "lightgrey";
|
|
9510
|
-
var PENWIDTH_BOLD = 2;
|
|
9511
|
-
var TOKEN_FLAG = {
|
|
9512
|
-
filled: "filled",
|
|
9513
|
-
dashed: "dashed",
|
|
9514
|
-
dotted: "dotted",
|
|
9515
|
-
bold: "bold",
|
|
9516
|
-
invis: "invis",
|
|
9517
|
-
diagonals: "diagonals",
|
|
9518
|
-
rounded: "rounded",
|
|
9519
|
-
striped: "striped",
|
|
9520
|
-
wedged: "wedged",
|
|
9521
|
-
underline: "underline"
|
|
9522
|
-
};
|
|
9523
|
-
function zeroFlags() {
|
|
9524
|
-
return {
|
|
9525
|
-
filled: false,
|
|
9526
|
-
dashed: false,
|
|
9527
|
-
dotted: false,
|
|
9528
|
-
bold: false,
|
|
9529
|
-
invis: false,
|
|
9530
|
-
diagonals: false,
|
|
9531
|
-
rounded: false,
|
|
9532
|
-
radial: false,
|
|
9533
|
-
striped: false,
|
|
9534
|
-
wedged: false,
|
|
9535
|
-
underline: false,
|
|
9536
|
-
setLineWidth: null
|
|
9537
|
-
};
|
|
9538
|
-
}
|
|
9539
|
-
var FUNLIMIT = 64;
|
|
9540
|
-
function styleTokens(style2) {
|
|
9541
|
-
if (!style2) return [];
|
|
9542
|
-
const out = [];
|
|
9543
|
-
let fun = 0;
|
|
9544
|
-
for (const raw of style2.split(",")) {
|
|
9545
|
-
const token = raw.trim();
|
|
9546
|
-
if (token.length === 0) continue;
|
|
9547
|
-
if (fun === FUNLIMIT - 1) return [];
|
|
9548
|
-
fun++;
|
|
9549
|
-
out.push(token);
|
|
9550
|
-
}
|
|
9551
|
-
return out;
|
|
9552
|
-
}
|
|
9553
|
-
function parseSetLineWidth(token) {
|
|
9554
|
-
const m = /^setlinewidth\s*\(\s*([^)]*)\)\s*$/.exec(token);
|
|
9555
|
-
if (m === null) return null;
|
|
9556
|
-
const v = parseFloat(m[1]);
|
|
9557
|
-
return Number.isNaN(v) ? 0 : v;
|
|
9558
|
-
}
|
|
9559
|
-
function applyToken(flags, token) {
|
|
9560
|
-
if (token === "radial") {
|
|
9561
|
-
flags.radial = true;
|
|
9562
|
-
flags.filled = true;
|
|
9563
|
-
return;
|
|
9564
|
-
}
|
|
9565
|
-
const key = TOKEN_FLAG[token];
|
|
9566
|
-
if (key !== void 0) flags[key] = true;
|
|
9567
|
-
}
|
|
9568
|
-
function nonEmpty(s) {
|
|
9569
|
-
return s !== void 0 && s.length > 0;
|
|
9570
|
-
}
|
|
9571
|
-
function orElse(s, fallback) {
|
|
9572
|
-
return nonEmpty(s) ? s : fallback;
|
|
9573
|
-
}
|
|
9574
|
-
function firstSolidColor(raw) {
|
|
9575
|
-
const grad = parseGradientSpec(raw);
|
|
9576
|
-
return grad !== null ? grad[0] : raw;
|
|
9577
|
-
}
|
|
9578
|
-
function parseStyleFlags(style2) {
|
|
9579
|
-
const flags = zeroFlags();
|
|
9580
|
-
if (!style2) return flags;
|
|
9581
|
-
let fun = 0;
|
|
9582
|
-
for (const raw of style2.split(",")) {
|
|
9583
|
-
const token = raw.trim();
|
|
9584
|
-
if (token.length === 0) continue;
|
|
9585
|
-
if (fun === FUNLIMIT - 1) return zeroFlags();
|
|
9586
|
-
fun++;
|
|
9587
|
-
const lw = parseSetLineWidth(token);
|
|
9588
|
-
if (lw !== null) {
|
|
9589
|
-
flags.setLineWidth = lw;
|
|
9590
|
-
continue;
|
|
9434
|
+
// src/common/htmltable-style.ts
|
|
9435
|
+
function htmlStyle(style2) {
|
|
9436
|
+
const s = { radial: false, rounded: false, invisible: false, dotted: false, dashed: false };
|
|
9437
|
+
if (style2 === void 0) return s;
|
|
9438
|
+
for (const tk of style2.split(/[ ,]+/)) {
|
|
9439
|
+
switch (tk.toUpperCase()) {
|
|
9440
|
+
case "ROUNDED":
|
|
9441
|
+
s.rounded = true;
|
|
9442
|
+
break;
|
|
9443
|
+
case "RADIAL":
|
|
9444
|
+
s.radial = true;
|
|
9445
|
+
break;
|
|
9446
|
+
case "SOLID":
|
|
9447
|
+
s.dotted = false;
|
|
9448
|
+
s.dashed = false;
|
|
9449
|
+
break;
|
|
9450
|
+
case "INVISIBLE":
|
|
9451
|
+
case "INVIS":
|
|
9452
|
+
s.invisible = true;
|
|
9453
|
+
break;
|
|
9454
|
+
case "DOTTED":
|
|
9455
|
+
s.dotted = true;
|
|
9456
|
+
break;
|
|
9457
|
+
case "DASHED":
|
|
9458
|
+
s.dashed = true;
|
|
9459
|
+
break;
|
|
9591
9460
|
}
|
|
9592
|
-
if (!token.includes("(")) applyToken(flags, token);
|
|
9593
|
-
}
|
|
9594
|
-
return flags;
|
|
9595
|
-
}
|
|
9596
|
-
function styleHasInvisibleAlias(style2) {
|
|
9597
|
-
if (!style2) return false;
|
|
9598
|
-
let fun = 0;
|
|
9599
|
-
for (const raw of style2.split(",")) {
|
|
9600
|
-
const token = raw.trim();
|
|
9601
|
-
if (token.length === 0) continue;
|
|
9602
|
-
if (fun === FUNLIMIT - 1) return false;
|
|
9603
|
-
fun++;
|
|
9604
|
-
if (token === "invisible") return true;
|
|
9605
|
-
}
|
|
9606
|
-
return false;
|
|
9607
|
-
}
|
|
9608
|
-
function resolvePenType(flags) {
|
|
9609
|
-
if (flags.invis) return 0 /* None */;
|
|
9610
|
-
if (flags.dashed) return 1 /* Dashed */;
|
|
9611
|
-
if (flags.dotted) return 2 /* Dotted */;
|
|
9612
|
-
return 3 /* Solid */;
|
|
9613
|
-
}
|
|
9614
|
-
function resolvePenWidth(flags, penwidthAttr) {
|
|
9615
|
-
if (penwidthAttr && penwidthAttr.length > 0) {
|
|
9616
|
-
const v = parseFloat(penwidthAttr);
|
|
9617
|
-
if (isFinite(v)) return v;
|
|
9618
|
-
}
|
|
9619
|
-
if (flags.setLineWidth !== null) return flags.setLineWidth;
|
|
9620
|
-
if (flags.bold) return PENWIDTH_BOLD;
|
|
9621
|
-
return 1;
|
|
9622
|
-
}
|
|
9623
|
-
function resolvePenColor(colorAttr) {
|
|
9624
|
-
if (!colorAttr || colorAttr.length === 0) return DEFAULT_COLOR;
|
|
9625
|
-
return firstSolidColor(colorAttr);
|
|
9626
|
-
}
|
|
9627
|
-
function clusterColorAttrs(attrs) {
|
|
9628
|
-
const base = nonEmpty(attrs.color) ? attrs.color : void 0;
|
|
9629
|
-
const pencolor = orElse(attrs.pencolor, base ?? "");
|
|
9630
|
-
const fillcolor = orElse(attrs.fillcolor, base ?? "");
|
|
9631
|
-
return {
|
|
9632
|
-
fillcolor: nonEmpty(fillcolor) ? fillcolor : void 0,
|
|
9633
|
-
pencolor: nonEmpty(pencolor) ? pencolor : void 0
|
|
9634
|
-
};
|
|
9635
|
-
}
|
|
9636
|
-
function applyBgcolor(attrs, filled, fillcolor) {
|
|
9637
|
-
if ((!filled || !fillcolor) && nonEmpty(attrs.bgcolor)) {
|
|
9638
|
-
return { filled: true, fillcolor: attrs.bgcolor };
|
|
9639
9461
|
}
|
|
9640
|
-
return
|
|
9641
|
-
}
|
|
9642
|
-
function findStopColor(colorlist) {
|
|
9643
|
-
const { segs, error } = parseSegs(colorlist);
|
|
9644
|
-
if (error === 1 || error === 2) return null;
|
|
9645
|
-
if (segs.length < 2) return null;
|
|
9646
|
-
const seg0 = segs[0];
|
|
9647
|
-
const seg1 = segs[1];
|
|
9648
|
-
if (seg0.color === null) return null;
|
|
9649
|
-
const fillColor = seg0.color;
|
|
9650
|
-
const stopColor = seg1.color ?? DEFAULT_COLOR;
|
|
9651
|
-
const frac = seg0.hasFraction ? seg0.t : seg1.hasFraction ? 1 - seg1.t : 0;
|
|
9652
|
-
return { fillColor, stopColor, frac };
|
|
9653
|
-
}
|
|
9654
|
-
function parseAngle(gradientangle2) {
|
|
9655
|
-
if (!gradientangle2 || gradientangle2.length === 0) return 0;
|
|
9656
|
-
const v = parseInt(gradientangle2, 10);
|
|
9657
|
-
return isFinite(v) ? v : 0;
|
|
9658
|
-
}
|
|
9659
|
-
function buildResolvedFill(rawColor, flags, angle) {
|
|
9660
|
-
const stop = findStopColor(rawColor);
|
|
9661
|
-
if (stop === null) return { kind: "solid", color: rawColor };
|
|
9662
|
-
const kind = flags.radial ? "radial" : "linear";
|
|
9663
|
-
return { kind, fillColor: stop.fillColor, stopColor: stop.stopColor, frac: stop.frac, angle };
|
|
9664
|
-
}
|
|
9665
|
-
function resolveNodeFillEx(attrs) {
|
|
9666
|
-
const flags = parseStyleFlags(attrs.style);
|
|
9667
|
-
if (!flags.filled) return { kind: "none" };
|
|
9668
|
-
const raw = nonEmpty(attrs.fillcolor) ? attrs.fillcolor : nonEmpty(attrs.color) ? attrs.color : DEFAULT_FILL;
|
|
9669
|
-
return buildResolvedFill(raw, flags, parseAngle(attrs.gradientangle));
|
|
9670
|
-
}
|
|
9671
|
-
function resolveClusterFillEx(attrs) {
|
|
9672
|
-
const flags = parseStyleFlags(attrs.style);
|
|
9673
|
-
const colors = clusterColorAttrs(attrs);
|
|
9674
|
-
const bg = applyBgcolor(attrs, flags.filled, colors.fillcolor);
|
|
9675
|
-
if (!bg.filled) return { kind: "none" };
|
|
9676
|
-
const raw = bg.fillcolor ?? DEFAULT_FILL;
|
|
9677
|
-
return buildResolvedFill(raw, flags, parseAngle(attrs.gradientangle));
|
|
9462
|
+
return s;
|
|
9678
9463
|
}
|
|
9679
9464
|
|
|
9680
9465
|
// src/common/htmltable-types.ts
|
|
@@ -9759,8 +9544,9 @@ function resetHtmlFillPenWidth() {
|
|
|
9759
9544
|
htmlFillPen = 1;
|
|
9760
9545
|
}
|
|
9761
9546
|
function penTypeOf(style2) {
|
|
9762
|
-
|
|
9763
|
-
if (
|
|
9547
|
+
const st = htmlStyle(style2);
|
|
9548
|
+
if (st.dashed) return 1 /* Dashed */;
|
|
9549
|
+
if (st.dotted) return 2 /* Dotted */;
|
|
9764
9550
|
return 3 /* Solid */;
|
|
9765
9551
|
}
|
|
9766
9552
|
function withHtmlPaint(paint, job, drawFn) {
|
|
@@ -9827,7 +9613,7 @@ function doBorder(spec, renderer, job) {
|
|
|
9827
9613
|
const { box, pos, border: border2, color, sides: sides2, style: style2 } = spec;
|
|
9828
9614
|
htmlFillPen = border2;
|
|
9829
9615
|
withHtmlPaint({ pen: color, penWidth: border2, penStyle: style2 }, job, () => {
|
|
9830
|
-
if (
|
|
9616
|
+
if (htmlStyle(style2).rounded) {
|
|
9831
9617
|
emitRoundedBezier(mkPts(box, border2, pos), { x: 0, y: 0 }, false, { renderer, job });
|
|
9832
9618
|
return;
|
|
9833
9619
|
}
|
|
@@ -10032,14 +9818,14 @@ function bgFillPaint(ctx) {
|
|
|
10032
9818
|
fill: spec[0],
|
|
10033
9819
|
stop: spec[1],
|
|
10034
9820
|
gradientAngle: ctx.gradientangle ?? 0,
|
|
10035
|
-
radial: ctx.style
|
|
9821
|
+
radial: htmlStyle(ctx.style).radial,
|
|
10036
9822
|
penWidth
|
|
10037
9823
|
};
|
|
10038
9824
|
}
|
|
10039
9825
|
function emitBgFill(ctx) {
|
|
10040
9826
|
const { box, pos, border: border2, renderer, job } = ctx;
|
|
10041
9827
|
withHtmlPaint(bgFillPaint(ctx), job, () => {
|
|
10042
|
-
if (
|
|
9828
|
+
if (htmlStyle(ctx.style).rounded) {
|
|
10043
9829
|
emitRoundedBezier(mkPts(box, border2, pos), { x: 0, y: 0 }, true, { renderer, job });
|
|
10044
9830
|
return;
|
|
10045
9831
|
}
|
|
@@ -10105,13 +9891,6 @@ function emitHtmlImg(img, pos, renderer, job) {
|
|
|
10105
9891
|
}
|
|
10106
9892
|
renderer.usershape?.(img.src, b, job);
|
|
10107
9893
|
}
|
|
10108
|
-
function htmlStyleInvisible(style2) {
|
|
10109
|
-
if (style2 === void 0) return false;
|
|
10110
|
-
return style2.split(/[ ,]+/).some((tok) => {
|
|
10111
|
-
const t = tok.toUpperCase();
|
|
10112
|
-
return t === "INVIS" || t === "INVISIBLE";
|
|
10113
|
-
});
|
|
10114
|
-
}
|
|
10115
9894
|
function emitHtmlCell(cell2, pos, renderer, job) {
|
|
10116
9895
|
const inAnchor = initHtmlAnchor(
|
|
10117
9896
|
{ href: cell2.href, title: cell2.title, target: cell2.target, id: cell2.id },
|
|
@@ -10119,7 +9898,7 @@ function emitHtmlCell(cell2, pos, renderer, job) {
|
|
|
10119
9898
|
renderer,
|
|
10120
9899
|
job
|
|
10121
9900
|
);
|
|
10122
|
-
if (
|
|
9901
|
+
if (htmlStyle(cell2.style).invisible) {
|
|
10123
9902
|
if (inAnchor) endHtmlAnchor(renderer, job);
|
|
10124
9903
|
return;
|
|
10125
9904
|
}
|
|
@@ -10155,7 +9934,7 @@ function emitHtmlLabel(placed, pos, renderer, job) {
|
|
|
10155
9934
|
const tblBox = absBox(placed.box, pos);
|
|
10156
9935
|
const clustersLast = (job.flags & EMIT_CLUSTERS_LAST) !== 0;
|
|
10157
9936
|
const inAnchor = clustersLast ? false : initHtmlAnchor(anchorData, tblBox, renderer, job);
|
|
10158
|
-
const tblInvisible =
|
|
9937
|
+
const tblInvisible = htmlStyle(placed.style).invisible;
|
|
10159
9938
|
if (!tblInvisible) {
|
|
10160
9939
|
if (placed.bgcolor !== void 0) {
|
|
10161
9940
|
emitBgFill({
|
|
@@ -10232,7 +10011,7 @@ var sides = (v) => {
|
|
|
10232
10011
|
};
|
|
10233
10012
|
var STYLE_WORDS = ["rounded", "radial", "solid", "invisible", "invis", "dotted", "dashed"];
|
|
10234
10013
|
var STYLE_DELIM = " ,";
|
|
10235
|
-
function
|
|
10014
|
+
function styleTokens(v) {
|
|
10236
10015
|
const out = [];
|
|
10237
10016
|
const span = (from, member) => {
|
|
10238
10017
|
let i = from;
|
|
@@ -10251,7 +10030,7 @@ function styleTokens2(v) {
|
|
|
10251
10030
|
var style = (v) => {
|
|
10252
10031
|
const legal = [];
|
|
10253
10032
|
const text = [];
|
|
10254
|
-
for (const tk of
|
|
10033
|
+
for (const tk of styleTokens(v)) {
|
|
10255
10034
|
if (STYLE_WORDS.includes(lower(tk))) legal.push(tk);
|
|
10256
10035
|
else text.push(warning(`Illegal value ${tk} for STYLE - ignored
|
|
10257
10036
|
`));
|
|
@@ -10660,28 +10439,46 @@ var HTML_ENTITIES = {
|
|
|
10660
10439
|
"zwj": 8205,
|
|
10661
10440
|
"zwnj": 8204
|
|
10662
10441
|
};
|
|
10663
|
-
var
|
|
10664
|
-
|
|
10665
|
-
|
|
10666
|
-
|
|
10667
|
-
|
|
10668
|
-
|
|
10669
|
-
|
|
10670
|
-
|
|
10671
|
-
|
|
10672
|
-
|
|
10673
|
-
|
|
10442
|
+
var ENTITY_NAME_LENGTH_MAX = 8;
|
|
10443
|
+
function numericEntity(s, at) {
|
|
10444
|
+
const hex = s[at + 1] === "x" || s[at + 1] === "X";
|
|
10445
|
+
const digit = hex ? /^[0-9A-Fa-f]$/ : /^[0-9]$/;
|
|
10446
|
+
let n = 0;
|
|
10447
|
+
let i = hex ? 2 : 1;
|
|
10448
|
+
for (; i < 8; i++) {
|
|
10449
|
+
const c = s[at + i] ?? "";
|
|
10450
|
+
if (!digit.test(c)) break;
|
|
10451
|
+
n = n * (hex ? 16 : 10) + parseInt(c, 16);
|
|
10452
|
+
}
|
|
10453
|
+
if (i < 8 && s[at + i] === ";") return { value: n, next: at + i + 1 };
|
|
10454
|
+
return { value: 0, next: at };
|
|
10455
|
+
}
|
|
10456
|
+
function namedEntity(s, at) {
|
|
10457
|
+
for (let i = 0; i < ENTITY_NAME_LENGTH_MAX; i++) {
|
|
10458
|
+
const c = s[at + i];
|
|
10459
|
+
if (c === void 0 || c === "\0") break;
|
|
10460
|
+
if (c === ";") {
|
|
10461
|
+
const key = s.slice(at, at + i);
|
|
10462
|
+
if (Object.hasOwn(HTML_ENTITIES, key)) return { value: HTML_ENTITIES[key], next: at + i + 1 };
|
|
10463
|
+
break;
|
|
10464
|
+
}
|
|
10465
|
+
}
|
|
10466
|
+
return { value: 0, next: at };
|
|
10674
10467
|
}
|
|
10675
|
-
function
|
|
10676
|
-
|
|
10677
|
-
return BASIC_ENTITIES[body] ?? HTML_ENTITIES[body] ?? null;
|
|
10468
|
+
function htmlEntity(s, at) {
|
|
10469
|
+
return s[at] === "#" ? numericEntity(s, at) : namedEntity(s, at);
|
|
10678
10470
|
}
|
|
10679
10471
|
function htmlEntityUTF8(s) {
|
|
10680
|
-
|
|
10681
|
-
|
|
10682
|
-
|
|
10683
|
-
|
|
10684
|
-
|
|
10472
|
+
let amp = s.indexOf("&");
|
|
10473
|
+
if (amp < 0) return s;
|
|
10474
|
+
let out = "";
|
|
10475
|
+
let from = 0;
|
|
10476
|
+
for (; amp >= 0; amp = s.indexOf("&", from)) {
|
|
10477
|
+
const e = htmlEntity(s, amp + 1);
|
|
10478
|
+
out += s.slice(from, amp) + (e.value ? String.fromCodePoint(e.value) : "&");
|
|
10479
|
+
from = e.next;
|
|
10480
|
+
}
|
|
10481
|
+
return out + s.slice(from);
|
|
10685
10482
|
}
|
|
10686
10483
|
|
|
10687
10484
|
// src/common/htmltable-lex-attvalue.ts
|
|
@@ -11075,8 +10872,26 @@ function releaseXb(st, first) {
|
|
|
11075
10872
|
function cleanText(decoded) {
|
|
11076
10873
|
return decoded.replace(/[\x00-\x1f]/g, "");
|
|
11077
10874
|
}
|
|
10875
|
+
var XML_PREDEFINED = { lt: "<", gt: ">", amp: "&", quot: '"', apos: "'" };
|
|
10876
|
+
var SCAN_ENTITY_MIN = 2;
|
|
10877
|
+
var SCAN_ENTITY_MAX = 8;
|
|
10878
|
+
var TEXT_REF = /&(#x[0-9A-Fa-f]+|#[0-9]+|[^&;]+);/g;
|
|
10879
|
+
function textRefValue(ref, body) {
|
|
10880
|
+
if (body[0] === "#") {
|
|
10881
|
+
const v = charRefNumber(ref);
|
|
10882
|
+
return v < 0 ? ref : String.fromCodePoint(v);
|
|
10883
|
+
}
|
|
10884
|
+
const n = body.length;
|
|
10885
|
+
if (n >= SCAN_ENTITY_MIN && n <= SCAN_ENTITY_MAX && Object.hasOwn(HTML_ENTITIES, body)) {
|
|
10886
|
+
return String.fromCodePoint(HTML_ENTITIES[body]);
|
|
10887
|
+
}
|
|
10888
|
+
return Object.hasOwn(XML_PREDEFINED, body) ? XML_PREDEFINED[body] : ref;
|
|
10889
|
+
}
|
|
10890
|
+
function decodeTextRefs(raw) {
|
|
10891
|
+
return raw.indexOf("&") < 0 ? raw : raw.replace(TEXT_REF, textRefValue);
|
|
10892
|
+
}
|
|
11078
10893
|
function textTokens(raw) {
|
|
11079
|
-
return charDataTokens(
|
|
10894
|
+
return charDataTokens(decodeTextRefs(raw));
|
|
11080
10895
|
}
|
|
11081
10896
|
function charDataTokens(decoded) {
|
|
11082
10897
|
const clean = cleanText(decoded);
|
|
@@ -17996,7 +17811,7 @@ function preprocessTooltip(s) {
|
|
|
17996
17811
|
// src/common/make-label.ts
|
|
17997
17812
|
var DEFAULT_FONTSIZE2 = 14;
|
|
17998
17813
|
var DEFAULT_FONTNAME = "Times-Roman";
|
|
17999
|
-
var
|
|
17814
|
+
var DEFAULT_COLOR = "black";
|
|
18000
17815
|
function getPenColor(obj) {
|
|
18001
17816
|
if (obj === void 0) return void 0;
|
|
18002
17817
|
const pc = obj.attrs.get("pencolor");
|
|
@@ -18618,6 +18433,252 @@ function assembleResult(p, dimen, grown, fixedshape) {
|
|
|
18618
18433
|
};
|
|
18619
18434
|
}
|
|
18620
18435
|
|
|
18436
|
+
// src/common/multicolor.ts
|
|
18437
|
+
var EPS = 1e-5;
|
|
18438
|
+
function aeq0(x) {
|
|
18439
|
+
return x < EPS && x > -EPS;
|
|
18440
|
+
}
|
|
18441
|
+
function getSegLen(token) {
|
|
18442
|
+
const semi = token.indexOf(";");
|
|
18443
|
+
if (semi === -1) return { color: token, v: 0 };
|
|
18444
|
+
const color = token.slice(0, semi);
|
|
18445
|
+
const rest = token.slice(semi + 1);
|
|
18446
|
+
if (rest.length === 0) return { color, v: -1 };
|
|
18447
|
+
const parsed = parseFloat(rest);
|
|
18448
|
+
return !isNaN(parsed) && parsed >= 0 ? { color, v: parsed } : { color, v: -1 };
|
|
18449
|
+
}
|
|
18450
|
+
function appendSeg(token, left2, segs, warnedExceeded) {
|
|
18451
|
+
const { color, v } = getSegLen(token);
|
|
18452
|
+
if (v < 0) return null;
|
|
18453
|
+
let t = v;
|
|
18454
|
+
let rval = 0;
|
|
18455
|
+
const del = t - left2;
|
|
18456
|
+
if (del > 0) {
|
|
18457
|
+
if (!aeq0(del) && !warnedExceeded.v) {
|
|
18458
|
+
warnedExceeded.v = true;
|
|
18459
|
+
rval = 3;
|
|
18460
|
+
}
|
|
18461
|
+
t = left2;
|
|
18462
|
+
}
|
|
18463
|
+
left2 -= t;
|
|
18464
|
+
segs.push({ color: color.length > 0 ? color : null, t, hasFraction: t > 0 && v > 0 });
|
|
18465
|
+
return { left: left2, rval };
|
|
18466
|
+
}
|
|
18467
|
+
function distributeLeft(segs, left2) {
|
|
18468
|
+
if (left2 <= 0) return;
|
|
18469
|
+
const zeroCount = segs.filter((s) => s.t <= 0).length;
|
|
18470
|
+
if (zeroCount > 0) {
|
|
18471
|
+
const delta2 = left2 / zeroCount;
|
|
18472
|
+
for (const s of segs) {
|
|
18473
|
+
if (s.t <= 0) s.t = delta2;
|
|
18474
|
+
}
|
|
18475
|
+
} else if (segs.length > 0) {
|
|
18476
|
+
segs[segs.length - 1].t += left2;
|
|
18477
|
+
}
|
|
18478
|
+
}
|
|
18479
|
+
function trimTrailing(segs) {
|
|
18480
|
+
while (segs.length > 0 && (segs[segs.length - 1]?.t ?? 0) <= 0) {
|
|
18481
|
+
segs.pop();
|
|
18482
|
+
}
|
|
18483
|
+
}
|
|
18484
|
+
function parseSegs(colorlist) {
|
|
18485
|
+
const segs = [];
|
|
18486
|
+
let left2 = 1;
|
|
18487
|
+
let rval = 0;
|
|
18488
|
+
let badFloatCount = 0;
|
|
18489
|
+
const warnedExceeded = { v: false };
|
|
18490
|
+
for (const token of colorlist.split(":")) {
|
|
18491
|
+
const result = appendSeg(token, left2, segs, warnedExceeded);
|
|
18492
|
+
if (result === null) {
|
|
18493
|
+
const errCode = badFloatCount === 0 ? 2 : 1;
|
|
18494
|
+
badFloatCount++;
|
|
18495
|
+
return { segs: [], error: errCode };
|
|
18496
|
+
}
|
|
18497
|
+
if (result.rval === 3) rval = 3;
|
|
18498
|
+
left2 = result.left;
|
|
18499
|
+
if (aeq0(left2)) {
|
|
18500
|
+
left2 = 0;
|
|
18501
|
+
break;
|
|
18502
|
+
}
|
|
18503
|
+
}
|
|
18504
|
+
distributeLeft(segs, left2);
|
|
18505
|
+
trimTrailing(segs);
|
|
18506
|
+
return { segs, error: rval };
|
|
18507
|
+
}
|
|
18508
|
+
|
|
18509
|
+
// src/common/style-resolve.ts
|
|
18510
|
+
var DEFAULT_COLOR2 = "black";
|
|
18511
|
+
var DEFAULT_FILL = "lightgrey";
|
|
18512
|
+
var PENWIDTH_BOLD = 2;
|
|
18513
|
+
var TOKEN_FLAG = {
|
|
18514
|
+
filled: "filled",
|
|
18515
|
+
dashed: "dashed",
|
|
18516
|
+
dotted: "dotted",
|
|
18517
|
+
bold: "bold",
|
|
18518
|
+
invis: "invis",
|
|
18519
|
+
diagonals: "diagonals",
|
|
18520
|
+
rounded: "rounded",
|
|
18521
|
+
striped: "striped",
|
|
18522
|
+
wedged: "wedged",
|
|
18523
|
+
underline: "underline"
|
|
18524
|
+
};
|
|
18525
|
+
function zeroFlags() {
|
|
18526
|
+
return {
|
|
18527
|
+
filled: false,
|
|
18528
|
+
dashed: false,
|
|
18529
|
+
dotted: false,
|
|
18530
|
+
bold: false,
|
|
18531
|
+
invis: false,
|
|
18532
|
+
diagonals: false,
|
|
18533
|
+
rounded: false,
|
|
18534
|
+
radial: false,
|
|
18535
|
+
striped: false,
|
|
18536
|
+
wedged: false,
|
|
18537
|
+
underline: false,
|
|
18538
|
+
setLineWidth: null
|
|
18539
|
+
};
|
|
18540
|
+
}
|
|
18541
|
+
var FUNLIMIT = 64;
|
|
18542
|
+
function styleTokens2(style2) {
|
|
18543
|
+
if (!style2) return [];
|
|
18544
|
+
const out = [];
|
|
18545
|
+
let fun = 0;
|
|
18546
|
+
for (const raw of style2.split(",")) {
|
|
18547
|
+
const token = raw.trim();
|
|
18548
|
+
if (token.length === 0) continue;
|
|
18549
|
+
if (fun === FUNLIMIT - 1) return [];
|
|
18550
|
+
fun++;
|
|
18551
|
+
out.push(token);
|
|
18552
|
+
}
|
|
18553
|
+
return out;
|
|
18554
|
+
}
|
|
18555
|
+
function parseSetLineWidth(token) {
|
|
18556
|
+
const m = /^setlinewidth\s*\(\s*([^)]*)\)\s*$/.exec(token);
|
|
18557
|
+
if (m === null) return null;
|
|
18558
|
+
const v = parseFloat(m[1]);
|
|
18559
|
+
return Number.isNaN(v) ? 0 : v;
|
|
18560
|
+
}
|
|
18561
|
+
function applyToken(flags, token) {
|
|
18562
|
+
if (token === "radial") {
|
|
18563
|
+
flags.radial = true;
|
|
18564
|
+
flags.filled = true;
|
|
18565
|
+
return;
|
|
18566
|
+
}
|
|
18567
|
+
const key = TOKEN_FLAG[token];
|
|
18568
|
+
if (key !== void 0) flags[key] = true;
|
|
18569
|
+
}
|
|
18570
|
+
function nonEmpty(s) {
|
|
18571
|
+
return s !== void 0 && s.length > 0;
|
|
18572
|
+
}
|
|
18573
|
+
function orElse(s, fallback) {
|
|
18574
|
+
return nonEmpty(s) ? s : fallback;
|
|
18575
|
+
}
|
|
18576
|
+
function firstSolidColor(raw) {
|
|
18577
|
+
const grad = parseGradientSpec(raw);
|
|
18578
|
+
return grad !== null ? grad[0] : raw;
|
|
18579
|
+
}
|
|
18580
|
+
function parseStyleFlags(style2) {
|
|
18581
|
+
const flags = zeroFlags();
|
|
18582
|
+
if (!style2) return flags;
|
|
18583
|
+
let fun = 0;
|
|
18584
|
+
for (const raw of style2.split(",")) {
|
|
18585
|
+
const token = raw.trim();
|
|
18586
|
+
if (token.length === 0) continue;
|
|
18587
|
+
if (fun === FUNLIMIT - 1) return zeroFlags();
|
|
18588
|
+
fun++;
|
|
18589
|
+
const lw = parseSetLineWidth(token);
|
|
18590
|
+
if (lw !== null) {
|
|
18591
|
+
flags.setLineWidth = lw;
|
|
18592
|
+
continue;
|
|
18593
|
+
}
|
|
18594
|
+
if (!token.includes("(")) applyToken(flags, token);
|
|
18595
|
+
}
|
|
18596
|
+
return flags;
|
|
18597
|
+
}
|
|
18598
|
+
function styleHasInvisibleAlias(style2) {
|
|
18599
|
+
if (!style2) return false;
|
|
18600
|
+
let fun = 0;
|
|
18601
|
+
for (const raw of style2.split(",")) {
|
|
18602
|
+
const token = raw.trim();
|
|
18603
|
+
if (token.length === 0) continue;
|
|
18604
|
+
if (fun === FUNLIMIT - 1) return false;
|
|
18605
|
+
fun++;
|
|
18606
|
+
if (token === "invisible") return true;
|
|
18607
|
+
}
|
|
18608
|
+
return false;
|
|
18609
|
+
}
|
|
18610
|
+
function resolvePenType(flags) {
|
|
18611
|
+
if (flags.invis) return 0 /* None */;
|
|
18612
|
+
if (flags.dashed) return 1 /* Dashed */;
|
|
18613
|
+
if (flags.dotted) return 2 /* Dotted */;
|
|
18614
|
+
return 3 /* Solid */;
|
|
18615
|
+
}
|
|
18616
|
+
function resolvePenWidth(flags, penwidthAttr) {
|
|
18617
|
+
if (penwidthAttr && penwidthAttr.length > 0) {
|
|
18618
|
+
const v = parseFloat(penwidthAttr);
|
|
18619
|
+
if (isFinite(v)) return v;
|
|
18620
|
+
}
|
|
18621
|
+
if (flags.setLineWidth !== null) return flags.setLineWidth;
|
|
18622
|
+
if (flags.bold) return PENWIDTH_BOLD;
|
|
18623
|
+
return 1;
|
|
18624
|
+
}
|
|
18625
|
+
function resolvePenColor(colorAttr) {
|
|
18626
|
+
if (!colorAttr || colorAttr.length === 0) return DEFAULT_COLOR2;
|
|
18627
|
+
return firstSolidColor(colorAttr);
|
|
18628
|
+
}
|
|
18629
|
+
function clusterColorAttrs(attrs) {
|
|
18630
|
+
const base = nonEmpty(attrs.color) ? attrs.color : void 0;
|
|
18631
|
+
const pencolor = orElse(attrs.pencolor, base ?? "");
|
|
18632
|
+
const fillcolor = orElse(attrs.fillcolor, base ?? "");
|
|
18633
|
+
return {
|
|
18634
|
+
fillcolor: nonEmpty(fillcolor) ? fillcolor : void 0,
|
|
18635
|
+
pencolor: nonEmpty(pencolor) ? pencolor : void 0
|
|
18636
|
+
};
|
|
18637
|
+
}
|
|
18638
|
+
function applyBgcolor(attrs, filled, fillcolor) {
|
|
18639
|
+
if ((!filled || !fillcolor) && nonEmpty(attrs.bgcolor)) {
|
|
18640
|
+
return { filled: true, fillcolor: attrs.bgcolor };
|
|
18641
|
+
}
|
|
18642
|
+
return { filled, fillcolor };
|
|
18643
|
+
}
|
|
18644
|
+
function findStopColor(colorlist) {
|
|
18645
|
+
const { segs, error } = parseSegs(colorlist);
|
|
18646
|
+
if (error === 1 || error === 2) return null;
|
|
18647
|
+
if (segs.length < 2) return null;
|
|
18648
|
+
const seg0 = segs[0];
|
|
18649
|
+
const seg1 = segs[1];
|
|
18650
|
+
if (seg0.color === null) return null;
|
|
18651
|
+
const fillColor = seg0.color;
|
|
18652
|
+
const stopColor = seg1.color ?? DEFAULT_COLOR2;
|
|
18653
|
+
const frac = seg0.hasFraction ? seg0.t : seg1.hasFraction ? 1 - seg1.t : 0;
|
|
18654
|
+
return { fillColor, stopColor, frac };
|
|
18655
|
+
}
|
|
18656
|
+
function parseAngle(gradientangle2) {
|
|
18657
|
+
if (!gradientangle2 || gradientangle2.length === 0) return 0;
|
|
18658
|
+
const v = parseInt(gradientangle2, 10);
|
|
18659
|
+
return isFinite(v) ? v : 0;
|
|
18660
|
+
}
|
|
18661
|
+
function buildResolvedFill(rawColor, flags, angle) {
|
|
18662
|
+
const stop = findStopColor(rawColor);
|
|
18663
|
+
if (stop === null) return { kind: "solid", color: rawColor };
|
|
18664
|
+
const kind = flags.radial ? "radial" : "linear";
|
|
18665
|
+
return { kind, fillColor: stop.fillColor, stopColor: stop.stopColor, frac: stop.frac, angle };
|
|
18666
|
+
}
|
|
18667
|
+
function resolveNodeFillEx(attrs) {
|
|
18668
|
+
const flags = parseStyleFlags(attrs.style);
|
|
18669
|
+
if (!flags.filled) return { kind: "none" };
|
|
18670
|
+
const raw = nonEmpty(attrs.fillcolor) ? attrs.fillcolor : nonEmpty(attrs.color) ? attrs.color : DEFAULT_FILL;
|
|
18671
|
+
return buildResolvedFill(raw, flags, parseAngle(attrs.gradientangle));
|
|
18672
|
+
}
|
|
18673
|
+
function resolveClusterFillEx(attrs) {
|
|
18674
|
+
const flags = parseStyleFlags(attrs.style);
|
|
18675
|
+
const colors = clusterColorAttrs(attrs);
|
|
18676
|
+
const bg = applyBgcolor(attrs, flags.filled, colors.fillcolor);
|
|
18677
|
+
if (!bg.filled) return { kind: "none" };
|
|
18678
|
+
const raw = bg.fillcolor ?? DEFAULT_FILL;
|
|
18679
|
+
return buildResolvedFill(raw, flags, parseAngle(attrs.gradientangle));
|
|
18680
|
+
}
|
|
18681
|
+
|
|
18621
18682
|
// src/layout/dot/fastgr.ts
|
|
18622
18683
|
var VIRTUAL = 1;
|
|
18623
18684
|
var NORMAL = 0;
|
|
@@ -20727,7 +20788,7 @@ function readFontParams(sg) {
|
|
|
20727
20788
|
return {
|
|
20728
20789
|
fontsize: parseFloat(graphAttrInherited(sg, "fontsize") ?? "") || DEFAULT_FONTSIZE2,
|
|
20729
20790
|
fontname: graphAttrInherited(sg, "fontname") ?? DEFAULT_FONTNAME,
|
|
20730
|
-
fontcolor: graphAttrInherited(sg, "fontcolor") ??
|
|
20791
|
+
fontcolor: graphAttrInherited(sg, "fontcolor") ?? DEFAULT_COLOR
|
|
20731
20792
|
};
|
|
20732
20793
|
}
|
|
20733
20794
|
function applyLabelBorder(sg, dimen) {
|
|
@@ -24644,7 +24705,7 @@ function readFontAttrs(n, g) {
|
|
|
24644
24705
|
return {
|
|
24645
24706
|
fontname: nodeAttr(n, g, "fontname") ?? DEFAULT_FONTNAME,
|
|
24646
24707
|
fontsize: parseFloat(nodeAttr(n, g, "fontsize") ?? String(DEFAULT_FONTSIZE2)),
|
|
24647
|
-
fontcolor: nodeAttr(n, g, "fontcolor") ??
|
|
24708
|
+
fontcolor: nodeAttr(n, g, "fontcolor") ?? DEFAULT_COLOR
|
|
24648
24709
|
};
|
|
24649
24710
|
}
|
|
24650
24711
|
function assignShapeInfo(n, polyDesc) {
|
|
@@ -25234,7 +25295,7 @@ function applyPenState(obj, styleAttr, colorAttr, penwidthAttr) {
|
|
|
25234
25295
|
obj.penColor = resolveRenderColor(resolvePenColor(colorAttr));
|
|
25235
25296
|
obj.pen = resolvePenType(flags);
|
|
25236
25297
|
obj.penWidth = resolvePenWidth(flags, penwidthAttr);
|
|
25237
|
-
obj.rawStyle =
|
|
25298
|
+
obj.rawStyle = styleTokens2(styleAttr);
|
|
25238
25299
|
}
|
|
25239
25300
|
function applyNodeStyle(obj, n, job) {
|
|
25240
25301
|
const styleAttr = nodeAttr(n, n.root, "style");
|
|
@@ -25457,7 +25518,7 @@ function initFontEdgeAttr(e) {
|
|
|
25457
25518
|
return {
|
|
25458
25519
|
fontsize: lateDouble(e.attrs.get("fontsize"), DEFAULT_FONTSIZE2, MIN_FONTSIZE),
|
|
25459
25520
|
fontname: e.attrs.get("fontname") || DEFAULT_FONTNAME,
|
|
25460
|
-
fontcolor: e.attrs.get("fontcolor") ||
|
|
25521
|
+
fontcolor: e.attrs.get("fontcolor") || DEFAULT_COLOR
|
|
25461
25522
|
};
|
|
25462
25523
|
}
|
|
25463
25524
|
function initFontLabelEdgeAttr(e, fi) {
|
|
@@ -28266,7 +28327,7 @@ function setEdgePen(e, job) {
|
|
|
28266
28327
|
);
|
|
28267
28328
|
obj.pen = resolvePenType(flags);
|
|
28268
28329
|
obj.penWidth = resolvePenWidth(flags, e.attrs.get("penwidth"));
|
|
28269
|
-
obj.rawStyle =
|
|
28330
|
+
obj.rawStyle = styleTokens2(e.attrs.get("style"));
|
|
28270
28331
|
}
|
|
28271
28332
|
function renderEdge(e, renderer, job) {
|
|
28272
28333
|
emitEdgeComments(e, renderer, job);
|