schematex 0.9.4 → 0.9.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -0
- package/dist/ai/ai-sdk.cjs +8 -8
- package/dist/ai/ai-sdk.d.cts +3 -3
- package/dist/ai/ai-sdk.d.ts +3 -3
- package/dist/ai/ai-sdk.js +3 -3
- package/dist/ai/index.cjs +17 -17
- package/dist/ai/index.d.cts +4 -4
- package/dist/ai/index.d.ts +4 -4
- package/dist/ai/index.js +4 -4
- package/dist/{api-1xoGiseb.d.cts → api-BOJJlNb1.d.ts} +2 -2
- package/dist/{api-CgXRSnCn.d.ts → api-v9t1T1v6.d.cts} +2 -2
- package/dist/browser.cjs +9 -9
- package/dist/browser.d.cts +3 -3
- package/dist/browser.d.ts +3 -3
- package/dist/browser.js +3 -3
- package/dist/{chunk-TX3YWZZX.cjs → chunk-7EWP4OD7.cjs} +186 -6
- package/dist/chunk-7EWP4OD7.cjs.map +1 -0
- package/dist/{chunk-PFZKW3HE.js → chunk-II4GLKGF.js} +2 -2
- package/dist/chunk-II4GLKGF.js.map +1 -0
- package/dist/{chunk-UFXDAIDD.js → chunk-LMNWUZMD.js} +1255 -602
- package/dist/chunk-LMNWUZMD.js.map +1 -0
- package/dist/{chunk-WJXLF42K.cjs → chunk-N3HU635X.cjs} +2 -2
- package/dist/chunk-N3HU635X.cjs.map +1 -0
- package/dist/{chunk-NIYB6CHH.js → chunk-N524SY5D.js} +184 -4
- package/dist/chunk-N524SY5D.js.map +1 -0
- package/dist/{chunk-GTCAJPQR.cjs → chunk-Q7CWX6HA.cjs} +1256 -602
- package/dist/chunk-Q7CWX6HA.cjs.map +1 -0
- package/dist/{diagnostics-CDwnQ65n.d.cts → diagnostics-5bVLlGNj.d.cts} +1 -1
- package/dist/{diagnostics-CDwnQ65n.d.ts → diagnostics-5bVLlGNj.d.ts} +1 -1
- package/dist/diagrams/blockdiagram/index.d.cts +1 -1
- package/dist/diagrams/blockdiagram/index.d.ts +1 -1
- package/dist/diagrams/circuit/index.d.cts +1 -1
- package/dist/diagrams/circuit/index.d.ts +1 -1
- package/dist/diagrams/ecomap/index.d.cts +1 -1
- package/dist/diagrams/ecomap/index.d.ts +1 -1
- package/dist/diagrams/entity/index.d.cts +1 -1
- package/dist/diagrams/entity/index.d.ts +1 -1
- package/dist/diagrams/fishbone/index.d.cts +1 -1
- package/dist/diagrams/fishbone/index.d.ts +1 -1
- package/dist/diagrams/flowchart/index.d.cts +2 -2
- package/dist/diagrams/flowchart/index.d.ts +2 -2
- package/dist/diagrams/genogram/index.d.cts +1 -1
- package/dist/diagrams/genogram/index.d.ts +1 -1
- package/dist/diagrams/ladder/index.d.cts +1 -1
- package/dist/diagrams/ladder/index.d.ts +1 -1
- package/dist/diagrams/logic/index.d.cts +1 -1
- package/dist/diagrams/logic/index.d.ts +1 -1
- package/dist/diagrams/orgchart/index.d.cts +1 -1
- package/dist/diagrams/orgchart/index.d.ts +1 -1
- package/dist/diagrams/pedigree/index.d.cts +1 -1
- package/dist/diagrams/pedigree/index.d.ts +1 -1
- package/dist/diagrams/phylo/index.d.cts +1 -1
- package/dist/diagrams/phylo/index.d.ts +1 -1
- package/dist/diagrams/sld/index.cjs +7 -7
- package/dist/diagrams/sld/index.d.cts +1 -1
- package/dist/diagrams/sld/index.d.ts +1 -1
- package/dist/diagrams/sld/index.js +1 -1
- package/dist/diagrams/sociogram/index.d.cts +1 -1
- package/dist/diagrams/sociogram/index.d.ts +1 -1
- package/dist/diagrams/timing/index.d.cts +1 -1
- package/dist/diagrams/timing/index.d.ts +1 -1
- package/dist/diagrams/venn/index.d.cts +1 -1
- package/dist/diagrams/venn/index.d.ts +1 -1
- package/dist/{index-DNOoLmYX.d.cts → index-Cmf4Rcve.d.cts} +1 -1
- package/dist/{index-CYSH3_ca.d.ts → index-syc0E5Ss.d.ts} +1 -1
- package/dist/index.cjs +41 -37
- package/dist/index.d.cts +7 -5
- package/dist/index.d.ts +7 -5
- package/dist/index.js +4 -4
- package/dist/react.cjs +3 -3
- package/dist/react.d.cts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +2 -2
- package/dist/{tools-CbYmQ3hH.d.cts → tools-B98iarLm.d.cts} +2 -2
- package/dist/{tools-BhTti-oG.d.ts → tools-CCZ1IcIN.d.ts} +2 -2
- package/package.json +1 -1
- package/dist/chunk-GTCAJPQR.cjs.map +0 -1
- package/dist/chunk-NIYB6CHH.js.map +0 -1
- package/dist/chunk-PFZKW3HE.js.map +0 -1
- package/dist/chunk-TX3YWZZX.cjs.map +0 -1
- package/dist/chunk-UFXDAIDD.js.map +0 -1
- package/dist/chunk-WJXLF42K.cjs.map +0 -1
|
@@ -2,7 +2,7 @@ import { orgchart } from './chunk-3J4DZPZC.js';
|
|
|
2
2
|
import { circuit } from './chunk-RDYACU2G.js';
|
|
3
3
|
import { blockdiagram } from './chunk-3PH2MQGN.js';
|
|
4
4
|
import { ladder } from './chunk-B4CMWA6Y.js';
|
|
5
|
-
import { sld } from './chunk-
|
|
5
|
+
import { sld } from './chunk-II4GLKGF.js';
|
|
6
6
|
import { entity } from './chunk-JEMAOC2D.js';
|
|
7
7
|
import { fishbone } from './chunk-GYYYULBL.js';
|
|
8
8
|
import { venn } from './chunk-SXOAAQNY.js';
|
|
@@ -2754,8 +2754,8 @@ function renderEras(layout, theme) {
|
|
|
2754
2754
|
layout.eras.forEach((e, i) => {
|
|
2755
2755
|
const l = leftmostOnRow.get(e.bandRow);
|
|
2756
2756
|
if (l === void 0 || e.x < layout.eras[l].x) leftmostOnRow.set(e.bandRow, i);
|
|
2757
|
-
const
|
|
2758
|
-
if (
|
|
2757
|
+
const r7 = rightmostOnRow.get(e.bandRow);
|
|
2758
|
+
if (r7 === void 0 || e.x + e.width > layout.eras[r7].x + layout.eras[r7].width) rightmostOnRow.set(e.bandRow, i);
|
|
2759
2759
|
});
|
|
2760
2760
|
const plotEnd = layout.plotX + layout.plotW;
|
|
2761
2761
|
const items = layout.eras.map((e, i) => {
|
|
@@ -2881,20 +2881,20 @@ function renderSwimlanePoints(layout, theme) {
|
|
|
2881
2881
|
function renderMarker(ev, color, shape, isMilestone) {
|
|
2882
2882
|
const x = ev.x;
|
|
2883
2883
|
const y = ev.y;
|
|
2884
|
-
const
|
|
2884
|
+
const r7 = isMilestone ? 8 : 5;
|
|
2885
2885
|
const klass = isMilestone ? "st-milestone" : "st-event-dot";
|
|
2886
2886
|
switch (shape) {
|
|
2887
2887
|
case "square":
|
|
2888
|
-
return rect({ x: x -
|
|
2888
|
+
return rect({ x: x - r7, y: y - r7, width: r7 * 2, height: r7 * 2, fill: color, class: klass, "data-event-id": ev.event.id });
|
|
2889
2889
|
case "diamond":
|
|
2890
|
-
return path({ d: `M ${x},${y -
|
|
2890
|
+
return path({ d: `M ${x},${y - r7} L ${x + r7},${y} L ${x},${y + r7} L ${x - r7},${y} Z`, fill: color, class: klass, "data-event-id": ev.event.id });
|
|
2891
2891
|
case "star":
|
|
2892
|
-
return path({ d: starPath(x, y,
|
|
2892
|
+
return path({ d: starPath(x, y, r7 + 2, (r7 + 2) / 2.5, 5), fill: color, class: klass, "data-event-id": ev.event.id });
|
|
2893
2893
|
case "flag":
|
|
2894
|
-
return path({ d: `M ${x -
|
|
2894
|
+
return path({ d: `M ${x - r7},${y + r7} L ${x - r7},${y - r7 - 4} L ${x + r7 + 4},${y - r7 - 1} L ${x - r7},${y + 2}`, fill: color, class: klass, "data-event-id": ev.event.id });
|
|
2895
2895
|
case "circle":
|
|
2896
2896
|
default:
|
|
2897
|
-
return circle({ cx: x, cy: y, r:
|
|
2897
|
+
return circle({ cx: x, cy: y, r: r7, fill: color, class: klass, "data-event-id": ev.event.id });
|
|
2898
2898
|
}
|
|
2899
2899
|
}
|
|
2900
2900
|
function renderLabels(layout) {
|
|
@@ -3150,10 +3150,10 @@ function starPath(cx, cy, rOuter, rInner, points) {
|
|
|
3150
3150
|
const step = Math.PI / points;
|
|
3151
3151
|
let d = "";
|
|
3152
3152
|
for (let i = 0; i < points * 2; i++) {
|
|
3153
|
-
const
|
|
3153
|
+
const r7 = i % 2 === 0 ? rOuter : rInner;
|
|
3154
3154
|
const a = i * step - Math.PI / 2;
|
|
3155
|
-
const x = cx +
|
|
3156
|
-
const y = cy +
|
|
3155
|
+
const x = cx + r7 * Math.cos(a);
|
|
3156
|
+
const y = cy + r7 * Math.sin(a);
|
|
3157
3157
|
d += (i === 0 ? "M" : "L") + x.toFixed(2) + "," + y.toFixed(2) + " ";
|
|
3158
3158
|
}
|
|
3159
3159
|
return d + "Z";
|
|
@@ -3424,7 +3424,7 @@ function parseStateDiagram(src) {
|
|
|
3424
3424
|
}
|
|
3425
3425
|
ctxTop.regionMode = true;
|
|
3426
3426
|
if (!parent.regions) parent.regions = [];
|
|
3427
|
-
const lastIdx = parent.regions.reduce((s,
|
|
3427
|
+
const lastIdx = parent.regions.reduce((s, r7) => s + r7.length, 0);
|
|
3428
3428
|
const slice = parent.children.slice(lastIdx);
|
|
3429
3429
|
parent.regions.push(slice);
|
|
3430
3430
|
i++;
|
|
@@ -3628,7 +3628,7 @@ function parseStateDiagram(src) {
|
|
|
3628
3628
|
}
|
|
3629
3629
|
function finalizeRegions(node) {
|
|
3630
3630
|
if (node.regions) {
|
|
3631
|
-
const consumed = node.regions.reduce((s,
|
|
3631
|
+
const consumed = node.regions.reduce((s, r7) => s + r7.length, 0);
|
|
3632
3632
|
if (node.children.length > consumed) {
|
|
3633
3633
|
node.regions.push(node.children.slice(consumed));
|
|
3634
3634
|
}
|
|
@@ -4073,33 +4073,33 @@ function pointsToPath(pts) {
|
|
|
4073
4073
|
const rest = pts.slice(1).map((p) => `L ${p.x} ${p.y}`).join(" ");
|
|
4074
4074
|
return rest ? `${head} ${rest}` : head;
|
|
4075
4075
|
}
|
|
4076
|
-
function trimPathStart(d, cx, cy,
|
|
4076
|
+
function trimPathStart(d, cx, cy, r7) {
|
|
4077
4077
|
const pts = parsePathPoints(d);
|
|
4078
4078
|
if (!pts || pts.length < 2) return d;
|
|
4079
4079
|
const p0 = pts[0];
|
|
4080
4080
|
const p1 = pts[1];
|
|
4081
|
-
const newP0 = projectOnPerimeter(p0, p1, cx, cy,
|
|
4081
|
+
const newP0 = projectOnPerimeter(p0, p1, cx, cy, r7);
|
|
4082
4082
|
pts[0] = newP0;
|
|
4083
4083
|
return pointsToPath(pts);
|
|
4084
4084
|
}
|
|
4085
|
-
function trimPathEnd(d, cx, cy,
|
|
4085
|
+
function trimPathEnd(d, cx, cy, r7) {
|
|
4086
4086
|
const pts = parsePathPoints(d);
|
|
4087
4087
|
if (!pts || pts.length < 2) return d;
|
|
4088
4088
|
const last = pts[pts.length - 1];
|
|
4089
4089
|
const prev = pts[pts.length - 2];
|
|
4090
|
-
const newLast = projectOnPerimeter(last, prev, cx, cy,
|
|
4090
|
+
const newLast = projectOnPerimeter(last, prev, cx, cy, r7);
|
|
4091
4091
|
pts[pts.length - 1] = newLast;
|
|
4092
4092
|
return pointsToPath(pts);
|
|
4093
4093
|
}
|
|
4094
|
-
function projectOnPerimeter(endpoint, neighbor, cx, cy,
|
|
4094
|
+
function projectOnPerimeter(endpoint, neighbor, cx, cy, r7) {
|
|
4095
4095
|
const dx = endpoint.x - neighbor.x;
|
|
4096
4096
|
const dy = endpoint.y - neighbor.y;
|
|
4097
4097
|
if (Math.abs(dx) > Math.abs(dy)) {
|
|
4098
4098
|
const sign2 = dx >= 0 ? 1 : -1;
|
|
4099
|
-
return { x: cx - sign2 *
|
|
4099
|
+
return { x: cx - sign2 * r7, y: cy };
|
|
4100
4100
|
}
|
|
4101
4101
|
const sign = dy >= 0 ? 1 : -1;
|
|
4102
|
-
return { x: cx, y: cy - sign *
|
|
4102
|
+
return { x: cx, y: cy - sign * r7 };
|
|
4103
4103
|
}
|
|
4104
4104
|
function shiftPathX(d, dx) {
|
|
4105
4105
|
return d.replace(/([MLCQ])\s*((?:-?\d+(?:\.\d+)?\s+){1,5}-?\d+(?:\.\d+)?)/g, (_, cmd, args) => {
|
|
@@ -4277,12 +4277,12 @@ function renderPseudo(node) {
|
|
|
4277
4277
|
]
|
|
4278
4278
|
);
|
|
4279
4279
|
case "choice": {
|
|
4280
|
-
const
|
|
4280
|
+
const r7 = 14;
|
|
4281
4281
|
return group(
|
|
4282
4282
|
{ class: "lt-state lt-pseudo", "data-id": node.id, "data-kind": "choice" },
|
|
4283
4283
|
[
|
|
4284
4284
|
polygon({
|
|
4285
|
-
points: `${cx},${cy -
|
|
4285
|
+
points: `${cx},${cy - r7} ${cx + r7},${cy} ${cx},${cy + r7} ${cx - r7},${cy}`,
|
|
4286
4286
|
class: "lt-ps-choice"
|
|
4287
4287
|
})
|
|
4288
4288
|
]
|
|
@@ -5280,27 +5280,27 @@ function renderEquip(type, label, rawType) {
|
|
|
5280
5280
|
]);
|
|
5281
5281
|
}
|
|
5282
5282
|
case "pump_centrifugal": {
|
|
5283
|
-
const
|
|
5283
|
+
const r7 = 22;
|
|
5284
5284
|
return group({}, [
|
|
5285
|
-
circle({ cx: 0, cy: 0, r:
|
|
5285
|
+
circle({ cx: 0, cy: 0, r: r7, class: "lt-pid-equip" }),
|
|
5286
5286
|
polygon({
|
|
5287
|
-
points: `${
|
|
5287
|
+
points: `${r7 * 0.4},${-r7 * 0.9} ${r7 + 6},${-r7 * 0.9} ${r7 * 0.4},${0}`,
|
|
5288
5288
|
class: "lt-pid-equip"
|
|
5289
5289
|
}),
|
|
5290
5290
|
text(
|
|
5291
|
-
{ x: 0, y:
|
|
5291
|
+
{ x: 0, y: r7 + 14, "text-anchor": "middle", class: "lt-pid-equip-tag" },
|
|
5292
5292
|
label
|
|
5293
5293
|
)
|
|
5294
5294
|
]);
|
|
5295
5295
|
}
|
|
5296
5296
|
case "pump_pd": {
|
|
5297
|
-
const
|
|
5297
|
+
const r7 = 22;
|
|
5298
5298
|
return group({}, [
|
|
5299
|
-
circle({ cx: 0, cy: 0, r:
|
|
5299
|
+
circle({ cx: 0, cy: 0, r: r7, class: "lt-pid-equip" }),
|
|
5300
5300
|
circle({ cx: -8, cy: 0, r: 6, class: "lt-pid-tray-line", fill: "none" }),
|
|
5301
5301
|
circle({ cx: 8, cy: 0, r: 6, class: "lt-pid-tray-line", fill: "none" }),
|
|
5302
5302
|
text(
|
|
5303
|
-
{ x: 0, y:
|
|
5303
|
+
{ x: 0, y: r7 + 14, "text-anchor": "middle", class: "lt-pid-equip-tag" },
|
|
5304
5304
|
label
|
|
5305
5305
|
)
|
|
5306
5306
|
]);
|
|
@@ -5315,14 +5315,14 @@ function renderEquip(type, label, rawType) {
|
|
|
5315
5315
|
]);
|
|
5316
5316
|
}
|
|
5317
5317
|
case "blower": {
|
|
5318
|
-
const
|
|
5318
|
+
const r7 = 22;
|
|
5319
5319
|
return group({}, [
|
|
5320
|
-
circle({ cx: 0, cy: 0, r:
|
|
5320
|
+
circle({ cx: 0, cy: 0, r: r7, class: "lt-pid-equip" }),
|
|
5321
5321
|
path({
|
|
5322
|
-
d: `M 0 0 L ${
|
|
5322
|
+
d: `M 0 0 L ${r7 * 0.8} ${-r7 * 0.5} M 0 0 L ${-r7 * 0.6} ${-r7 * 0.6} M 0 0 L 0 ${r7 * 0.8}`,
|
|
5323
5323
|
class: "lt-pid-tray-line"
|
|
5324
5324
|
}),
|
|
5325
|
-
text({ x: 0, y:
|
|
5325
|
+
text({ x: 0, y: r7 + 14, "text-anchor": "middle", class: "lt-pid-equip-tag" }, label)
|
|
5326
5326
|
]);
|
|
5327
5327
|
}
|
|
5328
5328
|
case "reactor_cstr": {
|
|
@@ -5498,7 +5498,7 @@ function renderEquip(type, label, rawType) {
|
|
|
5498
5498
|
}
|
|
5499
5499
|
}
|
|
5500
5500
|
function renderInstrument(category, letterCode, loopNumber) {
|
|
5501
|
-
const
|
|
5501
|
+
const r7 = 14;
|
|
5502
5502
|
const isComputer = category.endsWith("computer");
|
|
5503
5503
|
const isPlc = category.endsWith("plc");
|
|
5504
5504
|
const isShared = category.endsWith("shared");
|
|
@@ -5506,17 +5506,17 @@ function renderInstrument(category, letterCode, loopNumber) {
|
|
|
5506
5506
|
const isLocal = category.startsWith("local_");
|
|
5507
5507
|
const parts = [];
|
|
5508
5508
|
if (isComputer) {
|
|
5509
|
-
parts.push(circle({ cx: 0, cy: 0, r:
|
|
5509
|
+
parts.push(circle({ cx: 0, cy: 0, r: r7, class: "lt-inst-body" }));
|
|
5510
5510
|
parts.push(
|
|
5511
5511
|
polygon({
|
|
5512
|
-
points: `0,${-
|
|
5512
|
+
points: `0,${-r7 + 1} ${r7 - 1},0 0,${r7 - 1} ${ -13},0`,
|
|
5513
5513
|
class: "lt-inst-body",
|
|
5514
5514
|
fill: "none"
|
|
5515
5515
|
})
|
|
5516
5516
|
);
|
|
5517
5517
|
} else if (isPlc) {
|
|
5518
|
-
parts.push(circle({ cx: 0, cy: 0, r:
|
|
5519
|
-
const side =
|
|
5518
|
+
parts.push(circle({ cx: 0, cy: 0, r: r7, class: "lt-inst-body" }));
|
|
5519
|
+
const side = r7 * Math.SQRT1_2 * 2 - 2;
|
|
5520
5520
|
parts.push(
|
|
5521
5521
|
rect({
|
|
5522
5522
|
x: -side / 2,
|
|
@@ -5528,11 +5528,11 @@ function renderInstrument(category, letterCode, loopNumber) {
|
|
|
5528
5528
|
})
|
|
5529
5529
|
);
|
|
5530
5530
|
} else if (isShared) {
|
|
5531
|
-
parts.push(circle({ cx: 0, cy: 0, r:
|
|
5531
|
+
parts.push(circle({ cx: 0, cy: 0, r: r7, class: "lt-inst-body" }));
|
|
5532
5532
|
const hex = [];
|
|
5533
5533
|
for (let i = 0; i < 6; i++) {
|
|
5534
5534
|
const a = Math.PI / 3 * i - Math.PI / 2;
|
|
5535
|
-
hex.push(`${(
|
|
5535
|
+
hex.push(`${(r7 - 2) * Math.cos(a)},${(r7 - 2) * Math.sin(a)}`);
|
|
5536
5536
|
}
|
|
5537
5537
|
parts.push(
|
|
5538
5538
|
polygon({
|
|
@@ -5542,12 +5542,12 @@ function renderInstrument(category, letterCode, loopNumber) {
|
|
|
5542
5542
|
})
|
|
5543
5543
|
);
|
|
5544
5544
|
} else {
|
|
5545
|
-
parts.push(circle({ cx: 0, cy: 0, r:
|
|
5545
|
+
parts.push(circle({ cx: 0, cy: 0, r: r7, class: "lt-inst-body" }));
|
|
5546
5546
|
}
|
|
5547
5547
|
if (isControlRoom) {
|
|
5548
|
-
parts.push(line({ x1: -
|
|
5548
|
+
parts.push(line({ x1: -r7, y1: 0, x2: r7, y2: 0, class: "lt-inst-cr-line" }));
|
|
5549
5549
|
} else if (isLocal) {
|
|
5550
|
-
parts.push(line({ x1: -
|
|
5550
|
+
parts.push(line({ x1: -r7, y1: 0, x2: r7, y2: 0, class: "lt-inst-local-line" }));
|
|
5551
5551
|
}
|
|
5552
5552
|
parts.push(
|
|
5553
5553
|
text(
|
|
@@ -6299,19 +6299,19 @@ function readScalar(map, key) {
|
|
|
6299
6299
|
return { value, line: entry.header.line };
|
|
6300
6300
|
}
|
|
6301
6301
|
function readInt(map, key) {
|
|
6302
|
-
const
|
|
6303
|
-
if (
|
|
6304
|
-
return parseInt10(
|
|
6302
|
+
const r7 = readScalar(map, key);
|
|
6303
|
+
if (r7 === void 0) return void 0;
|
|
6304
|
+
return parseInt10(r7.value, r7.line);
|
|
6305
6305
|
}
|
|
6306
6306
|
function readSources(map, key) {
|
|
6307
|
-
const
|
|
6308
|
-
if (
|
|
6309
|
-
return parsePairs(
|
|
6307
|
+
const r7 = readScalar(map, key);
|
|
6308
|
+
if (r7 === void 0) return void 0;
|
|
6309
|
+
return parsePairs(r7.value, r7.line);
|
|
6310
6310
|
}
|
|
6311
6311
|
function readReasons(map, key) {
|
|
6312
|
-
const
|
|
6313
|
-
if (
|
|
6314
|
-
return parsePairs(
|
|
6312
|
+
const r7 = readScalar(map, key);
|
|
6313
|
+
if (r7 === void 0) return void 0;
|
|
6314
|
+
return parsePairs(r7.value, r7.line);
|
|
6315
6315
|
}
|
|
6316
6316
|
function readBlock(map, key) {
|
|
6317
6317
|
const entry = map.get(key);
|
|
@@ -6639,7 +6639,7 @@ function runArithmeticValidation(ast) {
|
|
|
6639
6639
|
}
|
|
6640
6640
|
}
|
|
6641
6641
|
if (ast.screening.excluded.reasons && ast.screening.excluded.reasons.length > 0) {
|
|
6642
|
-
const sum = ast.screening.excluded.reasons.reduce((a,
|
|
6642
|
+
const sum = ast.screening.excluded.reasons.reduce((a, r7) => a + r7.count, 0);
|
|
6643
6643
|
if (sum !== screenedExcluded) {
|
|
6644
6644
|
issues.push(
|
|
6645
6645
|
`screening.excluded reasons sum to ${formatN(sum)} but n = ${formatN(screenedExcluded)}`
|
|
@@ -6647,7 +6647,7 @@ function runArithmeticValidation(ast) {
|
|
|
6647
6647
|
}
|
|
6648
6648
|
}
|
|
6649
6649
|
if (ast.eligibility.excluded.reasons && ast.eligibility.excluded.reasons.length > 0) {
|
|
6650
|
-
const sum = ast.eligibility.excluded.reasons.reduce((a,
|
|
6650
|
+
const sum = ast.eligibility.excluded.reasons.reduce((a, r7) => a + r7.count, 0);
|
|
6651
6651
|
if (sum !== eligExcluded) {
|
|
6652
6652
|
issues.push(
|
|
6653
6653
|
`eligibility.excluded reasons sum to ${formatN(sum)} but n = ${formatN(eligExcluded)}`
|
|
@@ -6740,7 +6740,7 @@ function aggregateReasons(reasons) {
|
|
|
6740
6740
|
const sorted = [...reasons].sort((a, b) => b.count - a.count);
|
|
6741
6741
|
const head = sorted.slice(0, PRISMA_CONST.MAX_REASON_LINES - 1);
|
|
6742
6742
|
const tail = sorted.slice(PRISMA_CONST.MAX_REASON_LINES - 1);
|
|
6743
|
-
const otherSum = tail.reduce((a,
|
|
6743
|
+
const otherSum = tail.reduce((a, r7) => a + r7.count, 0);
|
|
6744
6744
|
return {
|
|
6745
6745
|
lines: [...head, { name: `Other (${tail.length} reasons)`, count: otherSum }],
|
|
6746
6746
|
truncated: tail.length
|
|
@@ -6797,8 +6797,8 @@ function buildIdentificationRemovedBox(id, kind) {
|
|
|
6797
6797
|
}
|
|
6798
6798
|
if (removed.length === 0) return null;
|
|
6799
6799
|
const lines = [{ text: v.recordsRemovedLabel, style: "label" }];
|
|
6800
|
-
for (const
|
|
6801
|
-
lines.push({ text:
|
|
6800
|
+
for (const r7 of removed) {
|
|
6801
|
+
lines.push({ text: r7, style: "reason", indent: 1 });
|
|
6802
6802
|
}
|
|
6803
6803
|
return {
|
|
6804
6804
|
role: "id-removed",
|
|
@@ -6854,8 +6854,8 @@ function buildScreeningExcludedBox(n, reasons, kind) {
|
|
|
6854
6854
|
{ text: v.recordsExcluded, style: "label" },
|
|
6855
6855
|
{ text: `n = ${nFmt(n)}`, style: "count" }
|
|
6856
6856
|
];
|
|
6857
|
-
for (const
|
|
6858
|
-
out.push({ text: `${
|
|
6857
|
+
for (const r7 of items) {
|
|
6858
|
+
out.push({ text: `${r7.name} (n = ${nFmt(r7.count)})`, style: "reason", indent: 1 });
|
|
6859
6859
|
}
|
|
6860
6860
|
return {
|
|
6861
6861
|
role: "screening-excluded",
|
|
@@ -6885,8 +6885,8 @@ function buildEligibilityExcludedBox(n, reasons, kind) {
|
|
|
6885
6885
|
{ text: v.reportsExcluded, style: "label" },
|
|
6886
6886
|
{ text: `n = ${nFmt(n)}`, style: "count" }
|
|
6887
6887
|
];
|
|
6888
|
-
for (const
|
|
6889
|
-
out.push({ text: `${
|
|
6888
|
+
for (const r7 of items) {
|
|
6889
|
+
out.push({ text: `${r7.name} (n = ${nFmt(r7.count)})`, style: "reason", indent: 1 });
|
|
6890
6890
|
}
|
|
6891
6891
|
return {
|
|
6892
6892
|
role: "eligibility-excluded",
|
|
@@ -7487,7 +7487,7 @@ function classForEdge(kind) {
|
|
|
7487
7487
|
}
|
|
7488
7488
|
}
|
|
7489
7489
|
function renderBand(band) {
|
|
7490
|
-
const
|
|
7490
|
+
const r7 = rect({
|
|
7491
7491
|
x: band.x,
|
|
7492
7492
|
y: band.y,
|
|
7493
7493
|
width: band.width,
|
|
@@ -7510,10 +7510,10 @@ function renderBand(band) {
|
|
|
7510
7510
|
},
|
|
7511
7511
|
band.label
|
|
7512
7512
|
);
|
|
7513
|
-
return group({ "data-band": band.stage }, [
|
|
7513
|
+
return group({ "data-band": band.stage }, [r7, txt]);
|
|
7514
7514
|
}
|
|
7515
7515
|
function renderHeader(h) {
|
|
7516
|
-
const
|
|
7516
|
+
const r7 = rect({
|
|
7517
7517
|
x: h.x,
|
|
7518
7518
|
y: h.y,
|
|
7519
7519
|
width: h.width,
|
|
@@ -7538,10 +7538,10 @@ function renderHeader(h) {
|
|
|
7538
7538
|
ln
|
|
7539
7539
|
)
|
|
7540
7540
|
);
|
|
7541
|
-
return group({ "data-header": h.column }, [
|
|
7541
|
+
return group({ "data-header": h.column }, [r7, ...lines]);
|
|
7542
7542
|
}
|
|
7543
7543
|
function renderBox(box2) {
|
|
7544
|
-
const
|
|
7544
|
+
const r7 = rect({
|
|
7545
7545
|
x: box2.x,
|
|
7546
7546
|
y: box2.y,
|
|
7547
7547
|
width: box2.width,
|
|
@@ -7599,7 +7599,7 @@ function renderBox(box2) {
|
|
|
7599
7599
|
"data-prisma-variant": box2.variant,
|
|
7600
7600
|
"data-prisma-stage": box2.stage
|
|
7601
7601
|
},
|
|
7602
|
-
[
|
|
7602
|
+
[r7, ...textEls]
|
|
7603
7603
|
);
|
|
7604
7604
|
}
|
|
7605
7605
|
function approxLineWidth(line2) {
|
|
@@ -8308,14 +8308,14 @@ function sizeEllipse(uc) {
|
|
|
8308
8308
|
}
|
|
8309
8309
|
function buildDeepEdges(ast, ucIds) {
|
|
8310
8310
|
const edges = [];
|
|
8311
|
-
for (const
|
|
8312
|
-
if (!ucIds.has(
|
|
8313
|
-
if (
|
|
8314
|
-
edges.push({ from:
|
|
8315
|
-
} else if (
|
|
8316
|
-
edges.push({ from:
|
|
8317
|
-
} else if (
|
|
8318
|
-
edges.push({ from:
|
|
8311
|
+
for (const r7 of ast.relations) {
|
|
8312
|
+
if (!ucIds.has(r7.source) || !ucIds.has(r7.target)) continue;
|
|
8313
|
+
if (r7.kind === "include") {
|
|
8314
|
+
edges.push({ from: r7.source, to: r7.target });
|
|
8315
|
+
} else if (r7.kind === "extend") {
|
|
8316
|
+
edges.push({ from: r7.target, to: r7.source });
|
|
8317
|
+
} else if (r7.kind === "generalization") {
|
|
8318
|
+
edges.push({ from: r7.source, to: r7.target });
|
|
8319
8319
|
}
|
|
8320
8320
|
}
|
|
8321
8321
|
return edges;
|
|
@@ -8343,15 +8343,15 @@ function classifyActorSides(ast) {
|
|
|
8343
8343
|
ast.actors.forEach((a, i) => idx.set(a.id, i));
|
|
8344
8344
|
const parent = /* @__PURE__ */ new Map();
|
|
8345
8345
|
const find = (x) => {
|
|
8346
|
-
let
|
|
8347
|
-
while ((parent.get(
|
|
8346
|
+
let r7 = x;
|
|
8347
|
+
while ((parent.get(r7) ?? r7) !== r7) r7 = parent.get(r7) ?? r7;
|
|
8348
8348
|
let c = x;
|
|
8349
8349
|
while ((parent.get(c) ?? c) !== c) {
|
|
8350
8350
|
const next = parent.get(c) ?? c;
|
|
8351
|
-
parent.set(c,
|
|
8351
|
+
parent.set(c, r7);
|
|
8352
8352
|
c = next;
|
|
8353
8353
|
}
|
|
8354
|
-
return
|
|
8354
|
+
return r7;
|
|
8355
8355
|
};
|
|
8356
8356
|
const union = (a, b) => {
|
|
8357
8357
|
const ra = find(a);
|
|
@@ -8361,9 +8361,9 @@ function classifyActorSides(ast) {
|
|
|
8361
8361
|
else parent.set(ra, rb);
|
|
8362
8362
|
};
|
|
8363
8363
|
for (const a of ast.actors) parent.set(a.id, a.id);
|
|
8364
|
-
for (const
|
|
8365
|
-
if (
|
|
8366
|
-
union(
|
|
8364
|
+
for (const r7 of ast.relations) {
|
|
8365
|
+
if (r7.kind === "generalization" && actorIds.has(r7.source) && actorIds.has(r7.target)) {
|
|
8366
|
+
union(r7.source, r7.target);
|
|
8367
8367
|
}
|
|
8368
8368
|
}
|
|
8369
8369
|
const baseSide = (a, i) => a.side === "left" ? "left" : a.side === "right" ? "right" : i === 0 ? "left" : "right";
|
|
@@ -8398,10 +8398,10 @@ function layoutUsecase(ast) {
|
|
|
8398
8398
|
const sides = classifyActorSides(ast);
|
|
8399
8399
|
const connectedActors = /* @__PURE__ */ new Map();
|
|
8400
8400
|
for (const u of ast.usecases) connectedActors.set(u.id, []);
|
|
8401
|
-
for (const
|
|
8402
|
-
if (
|
|
8403
|
-
const aId = actorById.has(
|
|
8404
|
-
const uId = ucIds.has(
|
|
8401
|
+
for (const r7 of ast.relations) {
|
|
8402
|
+
if (r7.kind !== "association" && r7.kind !== "directed") continue;
|
|
8403
|
+
const aId = actorById.has(r7.source) ? r7.source : actorById.has(r7.target) ? r7.target : null;
|
|
8404
|
+
const uId = ucIds.has(r7.source) ? r7.source : ucIds.has(r7.target) ? r7.target : null;
|
|
8405
8405
|
if (aId && uId) connectedActors.get(uId).push(aId);
|
|
8406
8406
|
}
|
|
8407
8407
|
const columns = [];
|
|
@@ -8440,10 +8440,10 @@ function layoutUsecase(ast) {
|
|
|
8440
8440
|
});
|
|
8441
8441
|
let prev = -Infinity;
|
|
8442
8442
|
for (const u of col) {
|
|
8443
|
-
let
|
|
8444
|
-
if (
|
|
8445
|
-
rowPos.set(u.id,
|
|
8446
|
-
prev =
|
|
8443
|
+
let r7 = rowPos.get(u.id);
|
|
8444
|
+
if (r7 <= prev) r7 = prev + 1;
|
|
8445
|
+
rowPos.set(u.id, r7);
|
|
8446
|
+
prev = r7;
|
|
8447
8447
|
}
|
|
8448
8448
|
}
|
|
8449
8449
|
const colMaxRx = columns.map(
|
|
@@ -8589,10 +8589,10 @@ function layoutUsecase(ast) {
|
|
|
8589
8589
|
const edges = [];
|
|
8590
8590
|
const trees = [];
|
|
8591
8591
|
const genByParent = /* @__PURE__ */ new Map();
|
|
8592
|
-
for (const
|
|
8593
|
-
if (
|
|
8594
|
-
if (!genByParent.has(
|
|
8595
|
-
genByParent.get(
|
|
8592
|
+
for (const r7 of ast.relations) {
|
|
8593
|
+
if (r7.kind !== "generalization") continue;
|
|
8594
|
+
if (!genByParent.has(r7.target)) genByParent.set(r7.target, []);
|
|
8595
|
+
genByParent.get(r7.target).push(r7);
|
|
8596
8596
|
}
|
|
8597
8597
|
const handledGen = /* @__PURE__ */ new Set();
|
|
8598
8598
|
function nodeCenter(id) {
|
|
@@ -8626,11 +8626,11 @@ function layoutUsecase(ast) {
|
|
|
8626
8626
|
}
|
|
8627
8627
|
for (const [parentId, rels] of genByParent) {
|
|
8628
8628
|
const useTree = ast.generalizationTree && rels.length >= C2.GEN_TREE_THRESHOLD;
|
|
8629
|
-
const allActors = actorById2.has(parentId) && rels.every((
|
|
8629
|
+
const allActors = actorById2.has(parentId) && rels.every((r7) => actorById2.has(r7.source));
|
|
8630
8630
|
if (allActors) {
|
|
8631
8631
|
const side = sides.get(parentId) ?? "left";
|
|
8632
8632
|
const pAnchor = actorGenAnchor(parentId, side);
|
|
8633
|
-
const childAnchors = rels.map((
|
|
8633
|
+
const childAnchors = rels.map((r7) => ({ r: r7, p: actorGenAnchor(r7.source, side) }));
|
|
8634
8634
|
const xs = [pAnchor.x, ...childAnchors.map((c) => c.p.x)];
|
|
8635
8635
|
const ys = [pAnchor.y, ...childAnchors.map((c) => c.p.y)];
|
|
8636
8636
|
const busX = side === "left" ? Math.min(...xs) - 20 : Math.max(...xs) + 20;
|
|
@@ -8646,7 +8646,7 @@ function layoutUsecase(ast) {
|
|
|
8646
8646
|
}
|
|
8647
8647
|
trees.push({
|
|
8648
8648
|
parentId,
|
|
8649
|
-
childIds: rels.map((
|
|
8649
|
+
childIds: rels.map((r7) => r7.source),
|
|
8650
8650
|
stemX: busX,
|
|
8651
8651
|
stemTop: minY2,
|
|
8652
8652
|
stemBottom: maxY2,
|
|
@@ -8669,7 +8669,7 @@ function layoutUsecase(ast) {
|
|
|
8669
8669
|
if (!useTree) continue;
|
|
8670
8670
|
const parent = nodeCenter(parentId);
|
|
8671
8671
|
if (!parent) continue;
|
|
8672
|
-
const childCenters = rels.map((
|
|
8672
|
+
const childCenters = rels.map((r7) => nodeCenter(r7.source)).filter((c) => c !== null);
|
|
8673
8673
|
if (childCenters.length === 0) continue;
|
|
8674
8674
|
const avgX = childCenters.reduce((s, c) => s + c.cx, 0) / childCenters.length;
|
|
8675
8675
|
const avgY = childCenters.reduce((s, c) => s + c.cy, 0) / childCenters.length;
|
|
@@ -8680,14 +8680,14 @@ function layoutUsecase(ast) {
|
|
|
8680
8680
|
const jx = pPt.x + dirX / len * C2.GEN_JUNCTION_OFFSET;
|
|
8681
8681
|
const jy = pPt.y + dirY / len * C2.GEN_JUNCTION_OFFSET;
|
|
8682
8682
|
const legPaths = [];
|
|
8683
|
-
for (const
|
|
8684
|
-
const cPt = perimeter(
|
|
8683
|
+
for (const r7 of rels) {
|
|
8684
|
+
const cPt = perimeter(r7.source, jx, jy);
|
|
8685
8685
|
legPaths.push(`M ${round3(cPt.x)} ${round3(cPt.y)} L ${round3(jx)} ${round3(jy)}`);
|
|
8686
|
-
handledGen.add(
|
|
8686
|
+
handledGen.add(r7);
|
|
8687
8687
|
}
|
|
8688
8688
|
trees.push({
|
|
8689
8689
|
parentId,
|
|
8690
|
-
childIds: rels.map((
|
|
8690
|
+
childIds: rels.map((r7) => r7.source),
|
|
8691
8691
|
stemX: jx,
|
|
8692
8692
|
stemTop: jy,
|
|
8693
8693
|
stemBottom: jy,
|
|
@@ -8695,72 +8695,72 @@ function layoutUsecase(ast) {
|
|
|
8695
8695
|
legPaths
|
|
8696
8696
|
});
|
|
8697
8697
|
}
|
|
8698
|
-
for (const
|
|
8699
|
-
if (handledGen.has(
|
|
8700
|
-
const a = nodeCenter(
|
|
8701
|
-
const b = nodeCenter(
|
|
8698
|
+
for (const r7 of ast.relations) {
|
|
8699
|
+
if (handledGen.has(r7)) continue;
|
|
8700
|
+
const a = nodeCenter(r7.source);
|
|
8701
|
+
const b = nodeCenter(r7.target);
|
|
8702
8702
|
if (!a || !b) continue;
|
|
8703
|
-
if (
|
|
8704
|
-
const side = sides.get(
|
|
8705
|
-
const pAnchor = actorGenAnchor(
|
|
8706
|
-
const cAnchor = actorGenAnchor(
|
|
8703
|
+
if (r7.kind === "generalization" && actorById2.has(r7.source) && actorById2.has(r7.target)) {
|
|
8704
|
+
const side = sides.get(r7.target) ?? "left";
|
|
8705
|
+
const pAnchor = actorGenAnchor(r7.target, side);
|
|
8706
|
+
const cAnchor = actorGenAnchor(r7.source, side);
|
|
8707
8707
|
const busX = side === "left" ? Math.min(pAnchor.x, cAnchor.x) - 20 : Math.max(pAnchor.x, cAnchor.x) + 20;
|
|
8708
8708
|
edges.push({
|
|
8709
|
-
relation:
|
|
8709
|
+
relation: r7,
|
|
8710
8710
|
d: `M ${round3(cAnchor.x)} ${round3(cAnchor.y)} L ${round3(busX)} ${round3(cAnchor.y)} L ${round3(busX)} ${round3(pAnchor.y)} L ${round3(pAnchor.x)} ${round3(pAnchor.y)}`,
|
|
8711
8711
|
arrowKind: "hollow",
|
|
8712
8712
|
dashed: false
|
|
8713
8713
|
});
|
|
8714
8714
|
continue;
|
|
8715
8715
|
}
|
|
8716
|
-
const srcActor = actorById2.get(
|
|
8717
|
-
const tgtActor = actorById2.get(
|
|
8716
|
+
const srcActor = actorById2.get(r7.source);
|
|
8717
|
+
const tgtActor = actorById2.get(r7.target);
|
|
8718
8718
|
let pa;
|
|
8719
8719
|
let pb;
|
|
8720
8720
|
if (srcActor && !tgtActor) {
|
|
8721
8721
|
pa = { x: srcActor.anchorX, y: srcActor.anchorY };
|
|
8722
|
-
pb = perimeter(
|
|
8722
|
+
pb = perimeter(r7.target, pa.x, pa.y);
|
|
8723
8723
|
} else if (tgtActor && !srcActor) {
|
|
8724
8724
|
pb = { x: tgtActor.anchorX, y: tgtActor.anchorY };
|
|
8725
|
-
pa = perimeter(
|
|
8725
|
+
pa = perimeter(r7.source, pb.x, pb.y);
|
|
8726
8726
|
} else {
|
|
8727
|
-
pa = perimeter(
|
|
8728
|
-
pb = perimeter(
|
|
8727
|
+
pa = perimeter(r7.source, b.cx, b.cy);
|
|
8728
|
+
pb = perimeter(r7.target, a.cx, a.cy);
|
|
8729
8729
|
}
|
|
8730
|
-
const dashed =
|
|
8730
|
+
const dashed = r7.kind === "include" || r7.kind === "extend";
|
|
8731
8731
|
let arrowKind2 = "none";
|
|
8732
|
-
if (
|
|
8733
|
-
else if (
|
|
8732
|
+
if (r7.kind === "directed" || r7.kind === "include" || r7.kind === "extend") arrowKind2 = "open";
|
|
8733
|
+
else if (r7.kind === "generalization") arrowKind2 = "hollow";
|
|
8734
8734
|
const edge = {
|
|
8735
|
-
relation:
|
|
8735
|
+
relation: r7,
|
|
8736
8736
|
d: `M ${round3(pa.x)} ${round3(pa.y)} L ${round3(pb.x)} ${round3(pb.y)}`,
|
|
8737
8737
|
arrowKind: arrowKind2,
|
|
8738
8738
|
dashed
|
|
8739
8739
|
};
|
|
8740
|
-
if (
|
|
8740
|
+
if (r7.kind === "include" || r7.kind === "extend") {
|
|
8741
8741
|
const rows = [];
|
|
8742
|
-
const keyword =
|
|
8743
|
-
rows.push(`\xAB${
|
|
8744
|
-
if (
|
|
8745
|
-
if (
|
|
8742
|
+
const keyword = r7.kind === "include" ? "include" : "extend";
|
|
8743
|
+
rows.push(`\xAB${r7.stereotype ?? keyword}\xBB`);
|
|
8744
|
+
if (r7.condition) rows.push(`[${r7.condition}]`);
|
|
8745
|
+
if (r7.extensionPointRef) rows.push(`(extension point: ${r7.extensionPointRef})`);
|
|
8746
8746
|
const label = {
|
|
8747
8747
|
rows,
|
|
8748
8748
|
cx: (pa.x + pb.x) / 2,
|
|
8749
8749
|
cy: (pa.y + pb.y) / 2
|
|
8750
8750
|
};
|
|
8751
8751
|
edge.label = label;
|
|
8752
|
-
} else if ((
|
|
8752
|
+
} else if ((r7.kind === "association" || r7.kind === "directed") && r7.stereotype) {
|
|
8753
8753
|
edge.label = {
|
|
8754
|
-
rows: [`\xAB${
|
|
8754
|
+
rows: [`\xAB${r7.stereotype}\xBB`],
|
|
8755
8755
|
cx: (pa.x + pb.x) / 2,
|
|
8756
8756
|
cy: (pa.y + pb.y) / 2
|
|
8757
8757
|
};
|
|
8758
8758
|
}
|
|
8759
|
-
if (
|
|
8760
|
-
edge.multiplicityFrom = placeMultiplicity(pa, pb,
|
|
8759
|
+
if (r7.sourceMultiplicity) {
|
|
8760
|
+
edge.multiplicityFrom = placeMultiplicity(pa, pb, r7.sourceMultiplicity);
|
|
8761
8761
|
}
|
|
8762
|
-
if (
|
|
8763
|
-
edge.multiplicityTo = placeMultiplicity(pb, pa,
|
|
8762
|
+
if (r7.targetMultiplicity) {
|
|
8763
|
+
edge.multiplicityTo = placeMultiplicity(pb, pa, r7.targetMultiplicity);
|
|
8764
8764
|
}
|
|
8765
8765
|
edges.push(edge);
|
|
8766
8766
|
}
|
|
@@ -9015,7 +9015,7 @@ function renderEdgeLabel(e) {
|
|
|
9015
9015
|
const rows = e.label.rows;
|
|
9016
9016
|
const lineH = 12;
|
|
9017
9017
|
const totalH = rows.length * lineH;
|
|
9018
|
-
const widest = rows.reduce((m,
|
|
9018
|
+
const widest = rows.reduce((m, r7) => Math.max(m, r7.length), 0);
|
|
9019
9019
|
const pillW = widest * 6 + 8;
|
|
9020
9020
|
const pillH = totalH + 4;
|
|
9021
9021
|
const startY = e.label.cy - totalH / 2 + 9;
|
|
@@ -9031,7 +9031,7 @@ function renderEdgeLabel(e) {
|
|
|
9031
9031
|
ry: 4
|
|
9032
9032
|
})
|
|
9033
9033
|
];
|
|
9034
|
-
rows.forEach((
|
|
9034
|
+
rows.forEach((r7, i) => {
|
|
9035
9035
|
parts.push(
|
|
9036
9036
|
text(
|
|
9037
9037
|
{
|
|
@@ -9040,7 +9040,7 @@ function renderEdgeLabel(e) {
|
|
|
9040
9040
|
y: startY + i * lineH,
|
|
9041
9041
|
"text-anchor": "middle"
|
|
9042
9042
|
},
|
|
9043
|
-
|
|
9043
|
+
r7
|
|
9044
9044
|
)
|
|
9045
9045
|
);
|
|
9046
9046
|
});
|
|
@@ -9080,8 +9080,8 @@ function renderTree(tr) {
|
|
|
9080
9080
|
function renderUsecaseLayout(layout, config) {
|
|
9081
9081
|
const t = resolveBaseTheme(config?.theme ?? "default");
|
|
9082
9082
|
const children = [];
|
|
9083
|
-
const nInclude = layout.ast.relations.filter((
|
|
9084
|
-
const nExtend = layout.ast.relations.filter((
|
|
9083
|
+
const nInclude = layout.ast.relations.filter((r7) => r7.kind === "include").length;
|
|
9084
|
+
const nExtend = layout.ast.relations.filter((r7) => r7.kind === "extend").length;
|
|
9085
9085
|
children.push(title(`Use Case Diagram${layout.title ? " \u2014 " + layout.title : ""}`));
|
|
9086
9086
|
children.push(
|
|
9087
9087
|
desc(
|
|
@@ -9829,12 +9829,12 @@ function layoutAoa(ast, schedule) {
|
|
|
9829
9829
|
const predEvents = (e) => inAdj[e].map((ai) => arcs[ai].from);
|
|
9830
9830
|
const succEvents = (e) => outAdj[e].map((ai) => arcs[ai].to);
|
|
9831
9831
|
for (let iter = 0; iter < 4; iter++) {
|
|
9832
|
-
for (let
|
|
9833
|
-
layers[
|
|
9832
|
+
for (let r7 = 1; r7 <= maxRank; r7++) {
|
|
9833
|
+
layers[r7] = sortByBary(layers[r7], predEvents, pos);
|
|
9834
9834
|
refresh(layers, pos);
|
|
9835
9835
|
}
|
|
9836
|
-
for (let
|
|
9837
|
-
layers[
|
|
9836
|
+
for (let r7 = maxRank - 1; r7 >= 0; r7--) {
|
|
9837
|
+
layers[r7] = sortByBary(layers[r7], succEvents, pos);
|
|
9838
9838
|
refresh(layers, pos);
|
|
9839
9839
|
}
|
|
9840
9840
|
}
|
|
@@ -9844,12 +9844,12 @@ function layoutAoa(ast, schedule) {
|
|
|
9844
9844
|
const contentH = (maxRows - 1) * AOA.VGAP + 2 * AOA.R;
|
|
9845
9845
|
const cx = new Array(nEvents).fill(0);
|
|
9846
9846
|
const cy = new Array(nEvents).fill(0);
|
|
9847
|
-
for (let
|
|
9848
|
-
const layer = layers[
|
|
9847
|
+
for (let r7 = 0; r7 <= maxRank; r7++) {
|
|
9848
|
+
const layer = layers[r7];
|
|
9849
9849
|
const colH = (layer.length - 1) * AOA.VGAP;
|
|
9850
9850
|
const y0 = topY + AOA.R + (contentH - 2 * AOA.R - colH) / 2;
|
|
9851
9851
|
layer.forEach((e, i) => {
|
|
9852
|
-
cx[e] = AOA.PAD + AOA.R +
|
|
9852
|
+
cx[e] = AOA.PAD + AOA.R + r7 * AOA.COL;
|
|
9853
9853
|
cy[e] = y0 + i * AOA.VGAP;
|
|
9854
9854
|
});
|
|
9855
9855
|
}
|
|
@@ -9911,16 +9911,16 @@ function sortByBary(layer, neighbors, pos) {
|
|
|
9911
9911
|
return { e, i, bary };
|
|
9912
9912
|
}).sort((a, b) => a.bary !== b.bary ? a.bary - b.bary : a.i - b.i).map((x) => x.e);
|
|
9913
9913
|
}
|
|
9914
|
-
function arcGeometry(tx, ty, hx, hy,
|
|
9914
|
+
function arcGeometry(tx, ty, hx, hy, r7) {
|
|
9915
9915
|
const dx = hx - tx;
|
|
9916
9916
|
const dy = hy - ty;
|
|
9917
9917
|
const len = Math.hypot(dx, dy) || 1;
|
|
9918
9918
|
const ux = dx / len;
|
|
9919
9919
|
const uy = dy / len;
|
|
9920
|
-
const sx = tx + ux *
|
|
9921
|
-
const sy = ty + uy *
|
|
9922
|
-
const ex = hx - ux *
|
|
9923
|
-
const ey = hy - uy *
|
|
9920
|
+
const sx = tx + ux * r7;
|
|
9921
|
+
const sy = ty + uy * r7;
|
|
9922
|
+
const ex = hx - ux * r7;
|
|
9923
|
+
const ey = hy - uy * r7;
|
|
9924
9924
|
return { d: `M ${round5(sx)} ${round5(sy)} L ${round5(ex)} ${round5(ey)}`, mx: (sx + ex) / 2, my: (sy + ey) / 2 };
|
|
9925
9925
|
}
|
|
9926
9926
|
function buildAoaSummary(ast, sched) {
|
|
@@ -9993,11 +9993,11 @@ function assignRanks(ast) {
|
|
|
9993
9993
|
if (visiting.has(id)) return 0;
|
|
9994
9994
|
visiting.add(id);
|
|
9995
9995
|
const t = byId.get(id);
|
|
9996
|
-
let
|
|
9997
|
-
for (const dep of t.deps)
|
|
9996
|
+
let r7 = 0;
|
|
9997
|
+
for (const dep of t.deps) r7 = Math.max(r7, compute(dep.pred) + 1);
|
|
9998
9998
|
visiting.delete(id);
|
|
9999
|
-
rank.set(id,
|
|
10000
|
-
return
|
|
9999
|
+
rank.set(id, r7);
|
|
10000
|
+
return r7;
|
|
10001
10001
|
};
|
|
10002
10002
|
let maxRank = 0;
|
|
10003
10003
|
for (const t of ast.tasks) maxRank = Math.max(maxRank, compute(t.id));
|
|
@@ -10043,15 +10043,15 @@ function orderLayers(ast, schedule, rank, maxRank) {
|
|
|
10043
10043
|
return s / neighbors.length;
|
|
10044
10044
|
};
|
|
10045
10045
|
for (let iter = 0; iter < 4; iter++) {
|
|
10046
|
-
for (let
|
|
10047
|
-
layers[
|
|
10046
|
+
for (let r7 = 1; r7 <= maxRank; r7++) {
|
|
10047
|
+
layers[r7] = stableSortByKey(layers[r7], (id) => {
|
|
10048
10048
|
const bc = barycenter(id, pred.get(id));
|
|
10049
10049
|
return crit(id) ? bc - 0.4 : bc;
|
|
10050
10050
|
});
|
|
10051
10051
|
refreshPos();
|
|
10052
10052
|
}
|
|
10053
|
-
for (let
|
|
10054
|
-
layers[
|
|
10053
|
+
for (let r7 = maxRank - 1; r7 >= 0; r7--) {
|
|
10054
|
+
layers[r7] = stableSortByKey(layers[r7], (id) => {
|
|
10055
10055
|
const bc = barycenter(id, succ.get(id));
|
|
10056
10056
|
return crit(id) ? bc - 0.4 : bc;
|
|
10057
10057
|
});
|
|
@@ -10103,9 +10103,9 @@ function layoutNetwork(ast, schedule) {
|
|
|
10103
10103
|
const originCross = dir === "TB" ? C2.PAD : C2.PAD + titleH;
|
|
10104
10104
|
const boxes = [];
|
|
10105
10105
|
const boxById = /* @__PURE__ */ new Map();
|
|
10106
|
-
for (let
|
|
10107
|
-
const layer = layers[
|
|
10108
|
-
const extent = colExtent[
|
|
10106
|
+
for (let r7 = 0; r7 <= maxRank; r7++) {
|
|
10107
|
+
const layer = layers[r7];
|
|
10108
|
+
const extent = colExtent[r7];
|
|
10109
10109
|
const crossStart = originCross + (maxExtent - extent) / 2;
|
|
10110
10110
|
let cursor = crossStart;
|
|
10111
10111
|
for (const id of layer) {
|
|
@@ -10116,12 +10116,12 @@ function layoutNetwork(ast, schedule) {
|
|
|
10116
10116
|
let x;
|
|
10117
10117
|
let y;
|
|
10118
10118
|
if (dir === "TB") {
|
|
10119
|
-
const rankPos = originPrimary +
|
|
10119
|
+
const rankPos = originPrimary + r7 * (C2.BOX_H + C2.H_GAP);
|
|
10120
10120
|
x = cursor + (C2.BOX_W - w) / 2;
|
|
10121
10121
|
y = rankPos;
|
|
10122
10122
|
cursor += C2.BOX_W + C2.H_GAP;
|
|
10123
10123
|
} else {
|
|
10124
|
-
const rankPos = originPrimary +
|
|
10124
|
+
const rankPos = originPrimary + r7 * (C2.BOX_W + C2.H_GAP);
|
|
10125
10125
|
x = rankPos + (C2.BOX_W - w) / 2;
|
|
10126
10126
|
y = cursor;
|
|
10127
10127
|
cursor += C2.BOX_H + C2.V_GAP;
|
|
@@ -10135,7 +10135,7 @@ function layoutNetwork(ast, schedule) {
|
|
|
10135
10135
|
width: w,
|
|
10136
10136
|
height: h,
|
|
10137
10137
|
milestone: t.milestone,
|
|
10138
|
-
rank:
|
|
10138
|
+
rank: r7
|
|
10139
10139
|
};
|
|
10140
10140
|
boxes.push(box2);
|
|
10141
10141
|
boxById.set(id, box2);
|
|
@@ -10295,7 +10295,7 @@ function layoutSwimlane2(ast, schedule) {
|
|
|
10295
10295
|
const crit = (id) => schedule.computed.get(id).critical;
|
|
10296
10296
|
const es = (id) => schedule.computed.get(id).es;
|
|
10297
10297
|
const cell = /* @__PURE__ */ new Map();
|
|
10298
|
-
const key = (lane,
|
|
10298
|
+
const key = (lane, r7) => `${lane}\0${r7}`;
|
|
10299
10299
|
for (const t of ast.tasks) {
|
|
10300
10300
|
const k = key(laneOf.get(t.id), rank.get(t.id));
|
|
10301
10301
|
if (!cell.has(k)) cell.set(k, []);
|
|
@@ -10312,15 +10312,15 @@ function layoutSwimlane2(ast, schedule) {
|
|
|
10312
10312
|
}
|
|
10313
10313
|
const titleH = ast.title ? C2.TITLE_H : 0;
|
|
10314
10314
|
const topY = C2.PAD + titleH;
|
|
10315
|
-
const colX = (
|
|
10315
|
+
const colX = (r7) => C2.LANE_LABEL_W + C2.PAD + r7 * (C2.BOX_W + C2.H_GAP);
|
|
10316
10316
|
const lanes = [];
|
|
10317
10317
|
const laneY = /* @__PURE__ */ new Map();
|
|
10318
10318
|
const laneH = /* @__PURE__ */ new Map();
|
|
10319
10319
|
let cursor = topY;
|
|
10320
10320
|
laneOrder.forEach((lane, i) => {
|
|
10321
10321
|
let stack = 1;
|
|
10322
|
-
for (let
|
|
10323
|
-
const arr = cell.get(key(lane,
|
|
10322
|
+
for (let r7 = 0; r7 <= maxRank; r7++) {
|
|
10323
|
+
const arr = cell.get(key(lane, r7));
|
|
10324
10324
|
if (arr) stack = Math.max(stack, arr.length);
|
|
10325
10325
|
}
|
|
10326
10326
|
const bandH = stack * C2.BOX_H + (stack - 1) * C2.V_GAP + 2 * C2.LANE_PAD;
|
|
@@ -10335,15 +10335,15 @@ function layoutSwimlane2(ast, schedule) {
|
|
|
10335
10335
|
for (const lane of laneOrder) {
|
|
10336
10336
|
const bandTop = laneY.get(lane);
|
|
10337
10337
|
const bandH = laneH.get(lane);
|
|
10338
|
-
for (let
|
|
10339
|
-
const arr = cell.get(key(lane,
|
|
10338
|
+
for (let r7 = 0; r7 <= maxRank; r7++) {
|
|
10339
|
+
const arr = cell.get(key(lane, r7));
|
|
10340
10340
|
if (!arr) continue;
|
|
10341
10341
|
const colInnerH = arr.length * C2.BOX_H + (arr.length - 1) * C2.V_GAP;
|
|
10342
10342
|
const y0 = bandTop + (bandH - colInnerH) / 2;
|
|
10343
10343
|
arr.forEach((id, idx) => {
|
|
10344
10344
|
const t = byId.get(id);
|
|
10345
10345
|
const w = t.milestone ? C2.MS_W : C2.BOX_W;
|
|
10346
|
-
const x = colX(
|
|
10346
|
+
const x = colX(r7) + (C2.BOX_W - w) / 2;
|
|
10347
10347
|
const y = y0 + idx * (C2.BOX_H + C2.V_GAP);
|
|
10348
10348
|
const box2 = {
|
|
10349
10349
|
id,
|
|
@@ -10354,7 +10354,7 @@ function layoutSwimlane2(ast, schedule) {
|
|
|
10354
10354
|
width: w,
|
|
10355
10355
|
height: C2.BOX_H,
|
|
10356
10356
|
milestone: t.milestone,
|
|
10357
|
-
rank:
|
|
10357
|
+
rank: r7
|
|
10358
10358
|
};
|
|
10359
10359
|
boxes.push(box2);
|
|
10360
10360
|
boxById.set(id, box2);
|
|
@@ -12021,18 +12021,18 @@ function renderFragmentTab(f) {
|
|
|
12021
12021
|
});
|
|
12022
12022
|
return group({ class: "sx-seq-fragment-tab-g", "data-op": f.op }, parts);
|
|
12023
12023
|
}
|
|
12024
|
-
function renderRef(
|
|
12024
|
+
function renderRef(r7) {
|
|
12025
12025
|
const tabW = 40;
|
|
12026
12026
|
const tabH = 18;
|
|
12027
12027
|
const fold = 6;
|
|
12028
|
-
const tab = `M ${
|
|
12028
|
+
const tab = `M ${r7.x} ${r7.y} H ${r7.x + tabW} V ${r7.y + tabH - fold} L ${r7.x + tabW - fold} ${r7.y + tabH} H ${r7.x} Z`;
|
|
12029
12029
|
return group({ class: "sx-seq-fragment", "data-op": "ref" }, [
|
|
12030
|
-
rect({ class: "sx-seq-frame", x:
|
|
12030
|
+
rect({ class: "sx-seq-frame", x: r7.x, y: r7.y, width: r7.width, height: r7.height, rx: 2, ry: 2 }),
|
|
12031
12031
|
path({ class: "sx-seq-frame-tab", d: tab }),
|
|
12032
|
-
text({ class: "sx-seq-frame-op", x:
|
|
12032
|
+
text({ class: "sx-seq-frame-op", x: r7.x + 8, y: r7.y + 13 }, "ref"),
|
|
12033
12033
|
text(
|
|
12034
|
-
{ class: "sx-seq-ref-name", x:
|
|
12035
|
-
|
|
12034
|
+
{ class: "sx-seq-ref-name", x: r7.x + r7.width / 2, y: r7.y + r7.height / 2 + 8, "text-anchor": "middle" },
|
|
12035
|
+
r7.text
|
|
12036
12036
|
)
|
|
12037
12037
|
]);
|
|
12038
12038
|
}
|
|
@@ -12069,10 +12069,10 @@ function renderInvariant(iv) {
|
|
|
12069
12069
|
]);
|
|
12070
12070
|
}
|
|
12071
12071
|
function renderDestroy(d) {
|
|
12072
|
-
const
|
|
12072
|
+
const r7 = 7;
|
|
12073
12073
|
return group({ class: "sx-seq-destroy-g" }, [
|
|
12074
|
-
line({ class: "sx-seq-destroy", x1: d.x -
|
|
12075
|
-
line({ class: "sx-seq-destroy", x1: d.x -
|
|
12074
|
+
line({ class: "sx-seq-destroy", x1: d.x - r7, y1: d.y - r7, x2: d.x + r7, y2: d.y + r7 }),
|
|
12075
|
+
line({ class: "sx-seq-destroy", x1: d.x - r7, y1: d.y + r7, x2: d.x + r7, y2: d.y - r7 })
|
|
12076
12076
|
]);
|
|
12077
12077
|
}
|
|
12078
12078
|
function renderSequenceLayout(layout, config) {
|
|
@@ -12915,10 +12915,10 @@ function renderArc2(ag) {
|
|
|
12915
12915
|
const dx = last.x - prev.x;
|
|
12916
12916
|
const dy = last.y - prev.y;
|
|
12917
12917
|
const len = Math.hypot(dx, dy) || 1;
|
|
12918
|
-
const
|
|
12919
|
-
const cx = last.x - dx / len *
|
|
12920
|
-
const cy = last.y - dy / len *
|
|
12921
|
-
parts.push(circle({ class: "sx-petri-inhibitor-dot", cx, cy, r:
|
|
12918
|
+
const r7 = 4;
|
|
12919
|
+
const cx = last.x - dx / len * r7;
|
|
12920
|
+
const cy = last.y - dy / len * r7;
|
|
12921
|
+
parts.push(circle({ class: "sx-petri-inhibitor-dot", cx, cy, r: r7 }));
|
|
12922
12922
|
}
|
|
12923
12923
|
if (ag.weight > 1) {
|
|
12924
12924
|
parts.push(
|
|
@@ -13316,10 +13316,10 @@ function parseNetwork(text2) {
|
|
|
13316
13316
|
if (rest[0]) ast.title = rest[0].value;
|
|
13317
13317
|
break;
|
|
13318
13318
|
case "spines":
|
|
13319
|
-
ast.spines.push(...rest.filter((
|
|
13319
|
+
ast.spines.push(...rest.filter((r7) => !r7.str).map((r7) => r7.value));
|
|
13320
13320
|
break;
|
|
13321
13321
|
case "leaves":
|
|
13322
|
-
ast.leaves.push(...rest.filter((
|
|
13322
|
+
ast.leaves.push(...rest.filter((r7) => !r7.str).map((r7) => r7.value));
|
|
13323
13323
|
break;
|
|
13324
13324
|
case "legend":
|
|
13325
13325
|
break;
|
|
@@ -13889,29 +13889,29 @@ function placeBanded(ast, ranks) {
|
|
|
13889
13889
|
const lr = ast.direction === "lr";
|
|
13890
13890
|
const byRank = /* @__PURE__ */ new Map();
|
|
13891
13891
|
for (const d of ast.devices) {
|
|
13892
|
-
const
|
|
13893
|
-
if (!byRank.has(
|
|
13894
|
-
byRank.get(
|
|
13892
|
+
const r7 = ranks.get(d.id) ?? 0;
|
|
13893
|
+
if (!byRank.has(r7)) byRank.set(r7, []);
|
|
13894
|
+
byRank.get(r7).push(d);
|
|
13895
13895
|
}
|
|
13896
13896
|
const rankValues = [...byRank.keys()].sort((a, b) => a - b);
|
|
13897
13897
|
const pos = /* @__PURE__ */ new Map();
|
|
13898
13898
|
let maxRowSpan = 0;
|
|
13899
13899
|
const rowSpans = /* @__PURE__ */ new Map();
|
|
13900
|
-
for (const
|
|
13901
|
-
const devs = byRank.get(
|
|
13900
|
+
for (const r7 of rankValues) {
|
|
13901
|
+
const devs = byRank.get(r7);
|
|
13902
13902
|
let span = 0;
|
|
13903
13903
|
devs.forEach((d, i) => {
|
|
13904
13904
|
const fp = deviceFootprint(d);
|
|
13905
13905
|
const cross = lr ? fp.h + labelExtra(d) : Math.max(fp.w, labelText(d).length * NET_CONST.CHAR_W + 6);
|
|
13906
13906
|
span += cross + (i > 0 ? NET_CONST.SIBLING_GAP : 0);
|
|
13907
13907
|
});
|
|
13908
|
-
rowSpans.set(
|
|
13908
|
+
rowSpans.set(r7, span);
|
|
13909
13909
|
maxRowSpan = Math.max(maxRowSpan, span);
|
|
13910
13910
|
}
|
|
13911
|
-
rankValues.forEach((
|
|
13912
|
-
const devs = byRank.get(
|
|
13911
|
+
rankValues.forEach((r7, rowIdx) => {
|
|
13912
|
+
const devs = byRank.get(r7);
|
|
13913
13913
|
const along = rowIdx * NET_CONST.TIER_BAND_GAP;
|
|
13914
|
-
let cursor = (maxRowSpan - rowSpans.get(
|
|
13914
|
+
let cursor = (maxRowSpan - rowSpans.get(r7)) / 2;
|
|
13915
13915
|
for (const d of devs) {
|
|
13916
13916
|
const fp = deviceFootprint(d);
|
|
13917
13917
|
const cross = lr ? fp.h + labelExtra(d) : Math.max(fp.w, labelText(d).length * NET_CONST.CHAR_W + 6);
|
|
@@ -13946,8 +13946,8 @@ function tieredRanks(ast, links) {
|
|
|
13946
13946
|
if (rank.has(d.id)) continue;
|
|
13947
13947
|
const known = [];
|
|
13948
13948
|
for (const n of adj.get(d.id) ?? []) {
|
|
13949
|
-
const
|
|
13950
|
-
if (
|
|
13949
|
+
const r7 = rank.get(n);
|
|
13950
|
+
if (r7 !== void 0) known.push(r7);
|
|
13951
13951
|
}
|
|
13952
13952
|
if (known.length === 0) continue;
|
|
13953
13953
|
const next = ENDPOINT_KINDS.has(d.kind) ? Math.max(...known) + 1 : Math.min(...known) + 1;
|
|
@@ -13981,10 +13981,10 @@ function treeRanks(ast, links) {
|
|
|
13981
13981
|
rank.set(root.id, 0);
|
|
13982
13982
|
while (queue.length) {
|
|
13983
13983
|
const id = queue.shift();
|
|
13984
|
-
const
|
|
13984
|
+
const r7 = rank.get(id);
|
|
13985
13985
|
for (const n of adj.get(id) ?? []) {
|
|
13986
13986
|
if (!rank.has(n)) {
|
|
13987
|
-
rank.set(n,
|
|
13987
|
+
rank.set(n, r7 + 1);
|
|
13988
13988
|
queue.push(n);
|
|
13989
13989
|
}
|
|
13990
13990
|
}
|
|
@@ -14168,11 +14168,11 @@ function layoutNetwork2(ast) {
|
|
|
14168
14168
|
};
|
|
14169
14169
|
const groupsByDepth = [...ast.groups].sort((a, b) => depthOf(b.id) - depthOf(a.id));
|
|
14170
14170
|
for (const g of groupsByDepth) {
|
|
14171
|
-
let l = Infinity, t = Infinity,
|
|
14171
|
+
let l = Infinity, t = Infinity, r7 = -Infinity, bm = -Infinity;
|
|
14172
14172
|
const addBox = (e) => {
|
|
14173
14173
|
l = Math.min(l, e.left);
|
|
14174
14174
|
t = Math.min(t, e.top);
|
|
14175
|
-
|
|
14175
|
+
r7 = Math.max(r7, e.right);
|
|
14176
14176
|
bm = Math.max(bm, e.bottom);
|
|
14177
14177
|
};
|
|
14178
14178
|
for (const mid of g.members) {
|
|
@@ -14189,7 +14189,7 @@ function layoutNetwork2(ast) {
|
|
|
14189
14189
|
groupBoxesRaw.set(g.id, {
|
|
14190
14190
|
left: l - pad,
|
|
14191
14191
|
top: t - pad - NET_CONST.GROUP_HEADER,
|
|
14192
|
-
right:
|
|
14192
|
+
right: r7 + pad,
|
|
14193
14193
|
bottom: bm + pad,
|
|
14194
14194
|
depth
|
|
14195
14195
|
});
|
|
@@ -14648,10 +14648,10 @@ function parseUmlClass(text2) {
|
|
|
14648
14648
|
}
|
|
14649
14649
|
const rels = tryParseRelationship(t, i + 1);
|
|
14650
14650
|
if (rels) {
|
|
14651
|
-
for (const
|
|
14652
|
-
ast.relationships.push(
|
|
14653
|
-
ensureClassifier(ast,
|
|
14654
|
-
ensureClassifier(ast,
|
|
14651
|
+
for (const r7 of rels) {
|
|
14652
|
+
ast.relationships.push(r7);
|
|
14653
|
+
ensureClassifier(ast, r7.from);
|
|
14654
|
+
ensureClassifier(ast, r7.to);
|
|
14655
14655
|
}
|
|
14656
14656
|
i++;
|
|
14657
14657
|
continue;
|
|
@@ -15206,11 +15206,11 @@ function findConnector(line2, glyph) {
|
|
|
15206
15206
|
}
|
|
15207
15207
|
function validateGeneralizationAcyclicity(ast) {
|
|
15208
15208
|
const adj = /* @__PURE__ */ new Map();
|
|
15209
|
-
for (const
|
|
15210
|
-
if (
|
|
15211
|
-
const list = adj.get(
|
|
15212
|
-
list.push(
|
|
15213
|
-
adj.set(
|
|
15209
|
+
for (const r7 of ast.relationships) {
|
|
15210
|
+
if (r7.kind === "generalization" || r7.kind === "realization") {
|
|
15211
|
+
const list = adj.get(r7.from) ?? [];
|
|
15212
|
+
list.push(r7.to);
|
|
15213
|
+
adj.set(r7.from, list);
|
|
15214
15214
|
}
|
|
15215
15215
|
}
|
|
15216
15216
|
const WHITE = 0, GREY = 1, BLACK = 2;
|
|
@@ -15243,12 +15243,12 @@ function validateGeneralizationAcyclicity(ast) {
|
|
|
15243
15243
|
}
|
|
15244
15244
|
}
|
|
15245
15245
|
function validateRealizationTargets(ast) {
|
|
15246
|
-
for (const
|
|
15247
|
-
if (
|
|
15248
|
-
const target = ast.classifiers.find((c) => c.id ===
|
|
15246
|
+
for (const r7 of ast.relationships) {
|
|
15247
|
+
if (r7.kind !== "realization") continue;
|
|
15248
|
+
const target = ast.classifiers.find((c) => c.id === r7.to);
|
|
15249
15249
|
if (target && target.kind !== "interface") {
|
|
15250
15250
|
ast.warnings.push(
|
|
15251
|
-
`Realization target "${
|
|
15251
|
+
`Realization target "${r7.to}" is not an \xABinterface\xBB \u2014 consider marking it so.`
|
|
15252
15252
|
);
|
|
15253
15253
|
}
|
|
15254
15254
|
}
|
|
@@ -15726,16 +15726,16 @@ function memberLineText(m) {
|
|
|
15726
15726
|
const props = m.properties && m.properties.length > 0 ? ` {${m.properties.join(", ")}}` : "";
|
|
15727
15727
|
return `${v}${m.name}(${params})${ret}${props}`;
|
|
15728
15728
|
}
|
|
15729
|
-
function rankEnds(
|
|
15730
|
-
switch (
|
|
15729
|
+
function rankEnds(r7) {
|
|
15730
|
+
switch (r7.kind) {
|
|
15731
15731
|
case "generalization":
|
|
15732
15732
|
case "realization":
|
|
15733
|
-
return { parent:
|
|
15733
|
+
return { parent: r7.to, child: r7.from };
|
|
15734
15734
|
case "composition":
|
|
15735
15735
|
case "aggregation":
|
|
15736
15736
|
case "directed":
|
|
15737
15737
|
case "dependency":
|
|
15738
|
-
return { parent:
|
|
15738
|
+
return { parent: r7.from, child: r7.to };
|
|
15739
15739
|
case "association":
|
|
15740
15740
|
return null;
|
|
15741
15741
|
}
|
|
@@ -15743,8 +15743,8 @@ function rankEnds(r6) {
|
|
|
15743
15743
|
function computeRanks(ast, boxes) {
|
|
15744
15744
|
const parentsOf = /* @__PURE__ */ new Map();
|
|
15745
15745
|
for (const b of boxes) parentsOf.set(b.classifier.id, /* @__PURE__ */ new Set());
|
|
15746
|
-
for (const
|
|
15747
|
-
const ends = rankEnds(
|
|
15746
|
+
for (const r7 of ast.relationships) {
|
|
15747
|
+
const ends = rankEnds(r7);
|
|
15748
15748
|
if (ends) parentsOf.get(ends.child)?.add(ends.parent);
|
|
15749
15749
|
}
|
|
15750
15750
|
const rank = /* @__PURE__ */ new Map();
|
|
@@ -15786,19 +15786,19 @@ function buildLayeredGraph(rels, boxes, rankByID) {
|
|
|
15786
15786
|
byID.set(n.id, n);
|
|
15787
15787
|
}
|
|
15788
15788
|
const chains = [];
|
|
15789
|
-
for (const
|
|
15790
|
-
const a = byID.get(
|
|
15791
|
-
const b = byID.get(
|
|
15789
|
+
for (const r7 of rels) {
|
|
15790
|
+
const a = byID.get(r7.from);
|
|
15791
|
+
const b = byID.get(r7.to);
|
|
15792
15792
|
if (!a || !b) continue;
|
|
15793
15793
|
if (a.rank === b.rank) {
|
|
15794
|
-
chains.push({ rel:
|
|
15794
|
+
chains.push({ rel: r7, chain: [a.id, b.id], sameRank: true });
|
|
15795
15795
|
continue;
|
|
15796
15796
|
}
|
|
15797
15797
|
const lo = a.rank < b.rank ? a : b;
|
|
15798
15798
|
const hi = a.rank < b.rank ? b : a;
|
|
15799
15799
|
const diff = hi.rank - lo.rank;
|
|
15800
15800
|
if (diff === 1) {
|
|
15801
|
-
chains.push({ rel:
|
|
15801
|
+
chains.push({ rel: r7, chain: [r7.from, r7.to], sameRank: false });
|
|
15802
15802
|
continue;
|
|
15803
15803
|
}
|
|
15804
15804
|
const innerDummies = [];
|
|
@@ -15819,7 +15819,7 @@ function buildLayeredGraph(rels, boxes, rankByID) {
|
|
|
15819
15819
|
}
|
|
15820
15820
|
const lowToHigh = [lo.id, ...innerDummies, hi.id];
|
|
15821
15821
|
const chain = a.rank < b.rank ? lowToHigh : [...lowToHigh].reverse();
|
|
15822
|
-
chains.push({ rel:
|
|
15822
|
+
chains.push({ rel: r7, chain, sameRank: false });
|
|
15823
15823
|
}
|
|
15824
15824
|
return { nodes, chains };
|
|
15825
15825
|
}
|
|
@@ -15859,12 +15859,12 @@ function orderRanks(ranks, chains) {
|
|
|
15859
15859
|
for (let iter = 0; iter < UMLCLASS_CONST.ORDER_ITERATIONS; iter++) {
|
|
15860
15860
|
const downward = iter % 2 === 0;
|
|
15861
15861
|
if (downward) {
|
|
15862
|
-
for (let
|
|
15863
|
-
applyBarycenter(ranks[
|
|
15862
|
+
for (let r7 = 1; r7 < ranks.length; r7++) {
|
|
15863
|
+
applyBarycenter(ranks[r7], ranks[r7 - 1], up);
|
|
15864
15864
|
}
|
|
15865
15865
|
} else {
|
|
15866
|
-
for (let
|
|
15867
|
-
applyBarycenter(ranks[
|
|
15866
|
+
for (let r7 = ranks.length - 2; r7 >= 0; r7--) {
|
|
15867
|
+
applyBarycenter(ranks[r7], ranks[r7 + 1], down);
|
|
15868
15868
|
}
|
|
15869
15869
|
}
|
|
15870
15870
|
}
|
|
@@ -16003,22 +16003,22 @@ function routeEdges(chains, nodes, boxByID, vertical) {
|
|
|
16003
16003
|
const handled = /* @__PURE__ */ new Set();
|
|
16004
16004
|
const groups = /* @__PURE__ */ new Map();
|
|
16005
16005
|
for (const c of chains) {
|
|
16006
|
-
const
|
|
16007
|
-
if (
|
|
16008
|
-
const k = `${
|
|
16009
|
-
if (!groups.has(k)) groups.set(k, { kind:
|
|
16010
|
-
groups.get(k).rels.push(
|
|
16006
|
+
const r7 = c.rel;
|
|
16007
|
+
if (r7.kind !== "generalization" && r7.kind !== "realization") continue;
|
|
16008
|
+
const k = `${r7.kind}::${r7.to}`;
|
|
16009
|
+
if (!groups.has(k)) groups.set(k, { kind: r7.kind, parentId: r7.to, rels: [] });
|
|
16010
|
+
groups.get(k).rels.push(r7);
|
|
16011
16011
|
}
|
|
16012
16012
|
for (const [, group2] of groups) {
|
|
16013
16013
|
if (group2.rels.length < UMLCLASS_CONST.TREE_MERGE_THRESHOLD) continue;
|
|
16014
16014
|
const parent = boxByID.get(group2.parentId);
|
|
16015
16015
|
if (!parent) continue;
|
|
16016
|
-
const children = group2.rels.map((
|
|
16016
|
+
const children = group2.rels.map((r7) => ({ r: r7, box: boxByID.get(r7.from) })).filter((c) => !!c.box);
|
|
16017
16017
|
if (children.length < UMLCLASS_CONST.TREE_MERGE_THRESHOLD) continue;
|
|
16018
16018
|
const tree = buildTree2(group2.kind, parent, children, vertical);
|
|
16019
16019
|
if (tree) {
|
|
16020
16020
|
trees.push(tree);
|
|
16021
|
-
for (const
|
|
16021
|
+
for (const r7 of group2.rels) handled.add(r7);
|
|
16022
16022
|
}
|
|
16023
16023
|
}
|
|
16024
16024
|
const liftLanes = /* @__PURE__ */ new Map();
|
|
@@ -16471,8 +16471,8 @@ function escapeXmlText(s) {
|
|
|
16471
16471
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
16472
16472
|
}
|
|
16473
16473
|
function renderEdge4(e) {
|
|
16474
|
-
const
|
|
16475
|
-
const dashed =
|
|
16474
|
+
const r7 = e.rel;
|
|
16475
|
+
const dashed = r7.kind === "realization" || r7.kind === "dependency";
|
|
16476
16476
|
const parts = [];
|
|
16477
16477
|
parts.push(
|
|
16478
16478
|
path({
|
|
@@ -16481,15 +16481,15 @@ function renderEdge4(e) {
|
|
|
16481
16481
|
"data-dashed": dashed ? "true" : void 0
|
|
16482
16482
|
})
|
|
16483
16483
|
);
|
|
16484
|
-
parts.push(renderTargetAdornment(
|
|
16485
|
-
if (
|
|
16486
|
-
parts.push(renderSourceDiamond(
|
|
16487
|
-
}
|
|
16488
|
-
if (
|
|
16489
|
-
if (
|
|
16490
|
-
if (
|
|
16491
|
-
if (
|
|
16492
|
-
if (
|
|
16484
|
+
parts.push(renderTargetAdornment(r7.kind, e.targetEnd));
|
|
16485
|
+
if (r7.kind === "composition" || r7.kind === "aggregation") {
|
|
16486
|
+
parts.push(renderSourceDiamond(r7.kind, e.sourceEnd));
|
|
16487
|
+
}
|
|
16488
|
+
if (r7.sourceMult) parts.push(renderEndLabel(e.sourceEnd, r7.sourceMult, false));
|
|
16489
|
+
if (r7.targetMult) parts.push(renderEndLabel(e.targetEnd, r7.targetMult, false));
|
|
16490
|
+
if (r7.sourceRole) parts.push(renderEndLabel(e.sourceEnd, r7.sourceRole, true));
|
|
16491
|
+
if (r7.targetRole) parts.push(renderEndLabel(e.targetEnd, r7.targetRole, true));
|
|
16492
|
+
if (r7.label && e.labelAnchor) {
|
|
16493
16493
|
parts.push(
|
|
16494
16494
|
text(
|
|
16495
16495
|
{
|
|
@@ -16498,7 +16498,7 @@ function renderEdge4(e) {
|
|
|
16498
16498
|
class: "sx-umlclass-edge-name sx-umlclass-edge-name-halo",
|
|
16499
16499
|
"text-anchor": "middle"
|
|
16500
16500
|
},
|
|
16501
|
-
|
|
16501
|
+
r7.label
|
|
16502
16502
|
)
|
|
16503
16503
|
);
|
|
16504
16504
|
parts.push(
|
|
@@ -16509,19 +16509,19 @@ function renderEdge4(e) {
|
|
|
16509
16509
|
class: "sx-umlclass-edge-name",
|
|
16510
16510
|
"text-anchor": "middle"
|
|
16511
16511
|
},
|
|
16512
|
-
|
|
16512
|
+
r7.label
|
|
16513
16513
|
)
|
|
16514
16514
|
);
|
|
16515
16515
|
}
|
|
16516
16516
|
return group(
|
|
16517
16517
|
{
|
|
16518
16518
|
class: "sx-umlclass-rel",
|
|
16519
|
-
"data-from":
|
|
16520
|
-
"data-to":
|
|
16521
|
-
"data-kind":
|
|
16522
|
-
"data-source-mult":
|
|
16523
|
-
"data-target-mult":
|
|
16524
|
-
"data-name":
|
|
16519
|
+
"data-from": r7.from,
|
|
16520
|
+
"data-to": r7.to,
|
|
16521
|
+
"data-kind": r7.kind,
|
|
16522
|
+
"data-source-mult": r7.sourceMult,
|
|
16523
|
+
"data-target-mult": r7.targetMult,
|
|
16524
|
+
"data-name": r7.label
|
|
16525
16525
|
},
|
|
16526
16526
|
parts
|
|
16527
16527
|
);
|
|
@@ -16676,8 +16676,8 @@ function summariseDiagram(ast, treeCount) {
|
|
|
16676
16676
|
byKind[k] = (byKind[k] ?? 0) + 1;
|
|
16677
16677
|
}
|
|
16678
16678
|
const relsByKind = {};
|
|
16679
|
-
for (const
|
|
16680
|
-
relsByKind[
|
|
16679
|
+
for (const r7 of ast.relationships) {
|
|
16680
|
+
relsByKind[r7.kind] = (relsByKind[r7.kind] ?? 0) + 1;
|
|
16681
16681
|
}
|
|
16682
16682
|
const classifierStr = Object.entries(byKind).map(([k, n]) => `${n} ${k}`).join(", ");
|
|
16683
16683
|
const relStr = Object.entries(relsByKind).map(([k, n]) => `${n} ${k}`).join(", ");
|
|
@@ -16909,9 +16909,9 @@ function validate(ast) {
|
|
|
16909
16909
|
if (!e.gate) continue;
|
|
16910
16910
|
const refs = [...e.gate.inputs];
|
|
16911
16911
|
if (e.gate.condition && isId(e.gate.condition)) refs.push(e.gate.condition);
|
|
16912
|
-
for (const
|
|
16913
|
-
if (!byId.has(
|
|
16914
|
-
throw new FaultTreeParseError(`gate ${e.id} references undefined event '${
|
|
16912
|
+
for (const r7 of refs) {
|
|
16913
|
+
if (!byId.has(r7)) {
|
|
16914
|
+
throw new FaultTreeParseError(`gate ${e.id} references undefined event '${r7}'`);
|
|
16915
16915
|
}
|
|
16916
16916
|
}
|
|
16917
16917
|
if (e.gate.kind === "voting") {
|
|
@@ -16983,9 +16983,9 @@ function parseProb(s, lineNo) {
|
|
|
16983
16983
|
return n;
|
|
16984
16984
|
}
|
|
16985
16985
|
function splitRefs(s, lineNo) {
|
|
16986
|
-
const refs = s.split(",").map((
|
|
16987
|
-
for (const
|
|
16988
|
-
if (!isId(
|
|
16986
|
+
const refs = s.split(",").map((r7) => r7.trim()).filter(Boolean);
|
|
16987
|
+
for (const r7 of refs) {
|
|
16988
|
+
if (!isId(r7)) throw new FaultTreeParseError(`invalid event reference "${r7}"`, lineNo);
|
|
16989
16989
|
}
|
|
16990
16990
|
if (refs.length === 0) throw new FaultTreeParseError(`empty input list`, lineNo);
|
|
16991
16991
|
return refs;
|
|
@@ -17703,10 +17703,10 @@ function renderEvent(e, showProb) {
|
|
|
17703
17703
|
parts.push(text({ x: e.cx, y: cy + 3, class: "sx-ft-id", "text-anchor": "middle" }, e.event.id));
|
|
17704
17704
|
parts.push(...leafCaption(e, cy + FAULTTREE_CONST.BASIC_R, label, showProb));
|
|
17705
17705
|
} else if (e.role === "undeveloped") {
|
|
17706
|
-
const
|
|
17707
|
-
parts.push(path({ d: `M ${e.cx} ${cy -
|
|
17706
|
+
const r7 = FAULTTREE_CONST.DIAMOND_W / 2;
|
|
17707
|
+
parts.push(path({ d: `M ${e.cx} ${cy - r7} L ${e.cx + r7} ${cy} L ${e.cx} ${cy + r7} L ${e.cx - r7} ${cy} Z`, class: "sx-ft-undeveloped" }));
|
|
17708
17708
|
parts.push(text({ x: e.cx, y: cy + 3, class: "sx-ft-id", "text-anchor": "middle" }, e.event.id));
|
|
17709
|
-
parts.push(...leafCaption(e, cy +
|
|
17709
|
+
parts.push(...leafCaption(e, cy + r7, label, showProb));
|
|
17710
17710
|
} else if (e.role === "house") {
|
|
17711
17711
|
const w = FAULTTREE_CONST.HOUSE_W, h = FAULTTREE_CONST.HOUSE_H, roofH = h * 0.34;
|
|
17712
17712
|
const top = cy - h / 2, bottom = cy + h / 2, L = e.cx - w / 2, R = e.cx + w / 2;
|
|
@@ -19528,7 +19528,7 @@ function analyseFmea(ast) {
|
|
|
19528
19528
|
}
|
|
19529
19529
|
for (const act of ast.actions) {
|
|
19530
19530
|
const target = flat.find(
|
|
19531
|
-
(
|
|
19531
|
+
(r7) => r7.mode === act.mode && (act.cause === void 0 || r7.cause === act.cause)
|
|
19532
19532
|
);
|
|
19533
19533
|
if (!target) {
|
|
19534
19534
|
notes.push(`Action references unknown mode/cause "${act.mode}"${act.cause ? ` / "${act.cause}"` : ""}.`);
|
|
@@ -19551,41 +19551,41 @@ function analyseFmea(ast) {
|
|
|
19551
19551
|
rpnDelta: rpn(target.sev, target.occ, target.det) - afterRpn
|
|
19552
19552
|
};
|
|
19553
19553
|
}
|
|
19554
|
-
const rows = flat.map((
|
|
19555
|
-
const r0 = rpn(
|
|
19556
|
-
const ap = actionPriority(
|
|
19554
|
+
const rows = flat.map((r7) => {
|
|
19555
|
+
const r0 = rpn(r7.sev, r7.occ, r7.det);
|
|
19556
|
+
const ap = actionPriority(r7.sev, r7.occ, r7.det);
|
|
19557
19557
|
const flagged = ast.flag ? meetsThreshold(ast.flag, r0, ap) : false;
|
|
19558
19558
|
return {
|
|
19559
19559
|
index: 0,
|
|
19560
|
-
item:
|
|
19561
|
-
fn:
|
|
19562
|
-
mode:
|
|
19563
|
-
effect:
|
|
19564
|
-
effects:
|
|
19565
|
-
sev:
|
|
19566
|
-
cause:
|
|
19567
|
-
occ:
|
|
19568
|
-
det:
|
|
19569
|
-
controls:
|
|
19560
|
+
item: r7.item,
|
|
19561
|
+
fn: r7.fn,
|
|
19562
|
+
mode: r7.mode,
|
|
19563
|
+
effect: r7.effect,
|
|
19564
|
+
effects: r7.effects,
|
|
19565
|
+
sev: r7.sev,
|
|
19566
|
+
cause: r7.cause,
|
|
19567
|
+
occ: r7.occ,
|
|
19568
|
+
det: r7.det,
|
|
19569
|
+
controls: r7.controls,
|
|
19570
19570
|
rpn: r0,
|
|
19571
19571
|
ap,
|
|
19572
19572
|
flagged,
|
|
19573
|
-
action:
|
|
19573
|
+
action: r7.action,
|
|
19574
19574
|
itemFirst: false,
|
|
19575
19575
|
itemSpan: 1,
|
|
19576
19576
|
modeFirst: false,
|
|
19577
19577
|
modeSpan: 1
|
|
19578
19578
|
};
|
|
19579
19579
|
});
|
|
19580
|
-
const orig = new Map(rows.map((
|
|
19580
|
+
const orig = new Map(rows.map((r7, i) => [r7, i]));
|
|
19581
19581
|
rows.sort((a, b) => compareRows(a, b, ast.rank, orig));
|
|
19582
|
-
rows.forEach((
|
|
19583
|
-
|
|
19582
|
+
rows.forEach((r7, i) => {
|
|
19583
|
+
r7.index = i + 1;
|
|
19584
19584
|
});
|
|
19585
19585
|
computeSpans(rows);
|
|
19586
|
-
const flaggedCount = rows.filter((
|
|
19587
|
-
const maxRpn = rows.reduce((m,
|
|
19588
|
-
const hasActions = rows.some((
|
|
19586
|
+
const flaggedCount = rows.filter((r7) => r7.flagged).length;
|
|
19587
|
+
const maxRpn = rows.reduce((m, r7) => Math.max(m, r7.rpn), 0);
|
|
19588
|
+
const hasActions = rows.some((r7) => r7.action !== void 0);
|
|
19589
19589
|
return { rank: ast.rank, rows, flaggedCount, maxRpn, hasActions, notes };
|
|
19590
19590
|
}
|
|
19591
19591
|
function compareRows(a, b, rank, orig) {
|
|
@@ -19649,39 +19649,39 @@ var FMEA_CONST = {
|
|
|
19649
19649
|
function buildColumnSpecs(hasActions, rank) {
|
|
19650
19650
|
const C2 = FMEA_CONST;
|
|
19651
19651
|
const specs = [
|
|
19652
|
-
{ key: "no", label: "#", width: 28, align: "middle", numeric: true, field: (
|
|
19652
|
+
{ key: "no", label: "#", width: 28, align: "middle", numeric: true, field: (r7) => String(r7.index) },
|
|
19653
19653
|
{
|
|
19654
19654
|
key: "item",
|
|
19655
19655
|
label: "Item / Function",
|
|
19656
19656
|
width: 130,
|
|
19657
19657
|
align: "start",
|
|
19658
19658
|
numeric: false,
|
|
19659
|
-
field: (
|
|
19660
|
-
\u2014 ${
|
|
19659
|
+
field: (r7) => r7.fn ? `${r7.item}
|
|
19660
|
+
\u2014 ${r7.fn}` : r7.item
|
|
19661
19661
|
},
|
|
19662
|
-
{ key: "mode", label: "Failure Mode", width: 120, align: "start", numeric: false, field: (
|
|
19662
|
+
{ key: "mode", label: "Failure Mode", width: 120, align: "start", numeric: false, field: (r7) => r7.mode },
|
|
19663
19663
|
{
|
|
19664
19664
|
key: "effect",
|
|
19665
19665
|
label: "Effect(s)",
|
|
19666
19666
|
width: 120,
|
|
19667
19667
|
align: "start",
|
|
19668
19668
|
numeric: false,
|
|
19669
|
-
field: (
|
|
19669
|
+
field: (r7) => r7.effects.length > 1 ? r7.effects.join("; ") : r7.effect
|
|
19670
19670
|
},
|
|
19671
|
-
{ key: "sev", label: "S", width: C2.NUM_COL_W, align: "middle", band: "before", numeric: true, field: (
|
|
19672
|
-
{ key: "cause", label: "Cause(s)", width: 120, align: "start", numeric: false, field: (
|
|
19673
|
-
{ key: "occ", label: "O", width: C2.NUM_COL_W, align: "middle", band: "before", numeric: true, field: (
|
|
19671
|
+
{ key: "sev", label: "S", width: C2.NUM_COL_W, align: "middle", band: "before", numeric: true, field: (r7) => String(r7.sev) },
|
|
19672
|
+
{ key: "cause", label: "Cause(s)", width: 120, align: "start", numeric: false, field: (r7) => r7.cause },
|
|
19673
|
+
{ key: "occ", label: "O", width: C2.NUM_COL_W, align: "middle", band: "before", numeric: true, field: (r7) => String(r7.occ) },
|
|
19674
19674
|
{
|
|
19675
19675
|
key: "controls",
|
|
19676
19676
|
label: "Current Controls",
|
|
19677
19677
|
width: 120,
|
|
19678
19678
|
align: "start",
|
|
19679
19679
|
numeric: false,
|
|
19680
|
-
field: (
|
|
19680
|
+
field: (r7) => controlsText(r7)
|
|
19681
19681
|
},
|
|
19682
|
-
{ key: "det", label: "D", width: C2.NUM_COL_W, align: "middle", band: "before", numeric: true, field: (
|
|
19683
|
-
{ key: "rpn", label: "RPN", width: C2.RPN_COL_W, align: "middle", band: "before", numeric: true, field: (
|
|
19684
|
-
{ key: "ap", label: "AP", width: C2.AP_COL_W, align: "middle", band: "before", numeric: true, field: (
|
|
19682
|
+
{ key: "det", label: "D", width: C2.NUM_COL_W, align: "middle", band: "before", numeric: true, field: (r7) => String(r7.det) },
|
|
19683
|
+
{ key: "rpn", label: "RPN", width: C2.RPN_COL_W, align: "middle", band: "before", numeric: true, field: (r7) => String(r7.rpn) },
|
|
19684
|
+
{ key: "ap", label: "AP", width: C2.AP_COL_W, align: "middle", band: "before", numeric: true, field: (r7) => r7.ap }
|
|
19685
19685
|
];
|
|
19686
19686
|
if (hasActions) {
|
|
19687
19687
|
specs.push(
|
|
@@ -19692,7 +19692,7 @@ function buildColumnSpecs(hasActions, rank) {
|
|
|
19692
19692
|
align: "start",
|
|
19693
19693
|
numeric: false,
|
|
19694
19694
|
afterOnly: true,
|
|
19695
|
-
field: (
|
|
19695
|
+
field: (r7) => actionText(r7)
|
|
19696
19696
|
},
|
|
19697
19697
|
{
|
|
19698
19698
|
key: "rsev",
|
|
@@ -19702,7 +19702,7 @@ function buildColumnSpecs(hasActions, rank) {
|
|
|
19702
19702
|
band: "after",
|
|
19703
19703
|
numeric: true,
|
|
19704
19704
|
afterOnly: true,
|
|
19705
|
-
field: (
|
|
19705
|
+
field: (r7) => r7.action ? String(r7.action.sev) : ""
|
|
19706
19706
|
},
|
|
19707
19707
|
{
|
|
19708
19708
|
key: "rocc",
|
|
@@ -19712,7 +19712,7 @@ function buildColumnSpecs(hasActions, rank) {
|
|
|
19712
19712
|
band: "after",
|
|
19713
19713
|
numeric: true,
|
|
19714
19714
|
afterOnly: true,
|
|
19715
|
-
field: (
|
|
19715
|
+
field: (r7) => r7.action ? String(r7.action.occ) : ""
|
|
19716
19716
|
},
|
|
19717
19717
|
{
|
|
19718
19718
|
key: "rdet",
|
|
@@ -19722,7 +19722,7 @@ function buildColumnSpecs(hasActions, rank) {
|
|
|
19722
19722
|
band: "after",
|
|
19723
19723
|
numeric: true,
|
|
19724
19724
|
afterOnly: true,
|
|
19725
|
-
field: (
|
|
19725
|
+
field: (r7) => r7.action ? String(r7.action.det) : ""
|
|
19726
19726
|
},
|
|
19727
19727
|
{
|
|
19728
19728
|
key: "rrpn",
|
|
@@ -19732,7 +19732,7 @@ function buildColumnSpecs(hasActions, rank) {
|
|
|
19732
19732
|
band: "after",
|
|
19733
19733
|
numeric: true,
|
|
19734
19734
|
afterOnly: true,
|
|
19735
|
-
field: (
|
|
19735
|
+
field: (r7) => r7.action ? String(r7.action.rpn) : ""
|
|
19736
19736
|
},
|
|
19737
19737
|
{
|
|
19738
19738
|
key: "rap",
|
|
@@ -19742,26 +19742,26 @@ function buildColumnSpecs(hasActions, rank) {
|
|
|
19742
19742
|
band: "after",
|
|
19743
19743
|
numeric: true,
|
|
19744
19744
|
afterOnly: true,
|
|
19745
|
-
field: (
|
|
19745
|
+
field: (r7) => r7.action ? r7.action.ap : ""
|
|
19746
19746
|
}
|
|
19747
19747
|
);
|
|
19748
19748
|
}
|
|
19749
19749
|
return specs;
|
|
19750
19750
|
}
|
|
19751
|
-
function controlsText(
|
|
19751
|
+
function controlsText(r7) {
|
|
19752
19752
|
const parts = [];
|
|
19753
|
-
if (
|
|
19754
|
-
if (
|
|
19753
|
+
if (r7.controls?.prevention) parts.push(`P: ${r7.controls.prevention}`);
|
|
19754
|
+
if (r7.controls?.detection) parts.push(`D: ${r7.controls.detection}`);
|
|
19755
19755
|
return parts.join("\n");
|
|
19756
19756
|
}
|
|
19757
|
-
function actionText(
|
|
19758
|
-
if (!
|
|
19757
|
+
function actionText(r7) {
|
|
19758
|
+
if (!r7.action) return "";
|
|
19759
19759
|
const parts = [];
|
|
19760
|
-
if (
|
|
19760
|
+
if (r7.action.recommendation) parts.push(r7.action.recommendation);
|
|
19761
19761
|
const meta = [];
|
|
19762
|
-
if (
|
|
19763
|
-
if (
|
|
19764
|
-
if (
|
|
19762
|
+
if (r7.action.owner) meta.push(r7.action.owner);
|
|
19763
|
+
if (r7.action.target) meta.push(r7.action.target);
|
|
19764
|
+
if (r7.action.status) meta.push(`[${r7.action.status}]`);
|
|
19765
19765
|
if (meta.length) parts.push(meta.join(" \xB7 "));
|
|
19766
19766
|
return parts.join("\n");
|
|
19767
19767
|
}
|
|
@@ -20235,6 +20235,658 @@ var fmea = {
|
|
|
20235
20235
|
}
|
|
20236
20236
|
};
|
|
20237
20237
|
|
|
20238
|
+
// src/diagrams/rbd/parser.ts
|
|
20239
|
+
function normalizeQuotes2(text2) {
|
|
20240
|
+
return text2.replace(/[“”„«»「」『』"]/g, '"').replace(/[‘’‚']/g, "'");
|
|
20241
|
+
}
|
|
20242
|
+
var RbdParseError = class extends Error {
|
|
20243
|
+
constructor(message) {
|
|
20244
|
+
super(message);
|
|
20245
|
+
this.name = "RbdParseError";
|
|
20246
|
+
}
|
|
20247
|
+
};
|
|
20248
|
+
var HEADER_RE = /^\s*(rbd|reliability(?:blockdiagram)?|reliability-block-diagram)\b/i;
|
|
20249
|
+
var GROUP_KW = /* @__PURE__ */ new Set(["series", "parallel", "kofn", "k-of-n", "voting"]);
|
|
20250
|
+
function parseRbd(text2) {
|
|
20251
|
+
const normalized = normalizeQuotes2(text2);
|
|
20252
|
+
const lines = normalized.split("\n");
|
|
20253
|
+
let headerIdx = -1;
|
|
20254
|
+
for (let i = 0; i < lines.length; i++) {
|
|
20255
|
+
if (lines[i].trim() === "") continue;
|
|
20256
|
+
if (!HEADER_RE.test(lines[i])) {
|
|
20257
|
+
throw new RbdParseError(
|
|
20258
|
+
`RBD must start with 'rbd' (or 'reliability'). Example: rbd "My System"`
|
|
20259
|
+
);
|
|
20260
|
+
}
|
|
20261
|
+
headerIdx = i;
|
|
20262
|
+
break;
|
|
20263
|
+
}
|
|
20264
|
+
if (headerIdx < 0) throw new RbdParseError("Empty RBD input.");
|
|
20265
|
+
const warnings = [];
|
|
20266
|
+
const metadata = {};
|
|
20267
|
+
const headerRest = lines[headerIdx].replace(HEADER_RE, "").trim();
|
|
20268
|
+
const title2 = extractQuoted(headerRest);
|
|
20269
|
+
const body = lines.slice(headerIdx + 1).join("\n");
|
|
20270
|
+
const tokens = tokenize6(stripBodyDirectives(body, metadata));
|
|
20271
|
+
const seenIds = /* @__PURE__ */ new Set();
|
|
20272
|
+
let pos = 0;
|
|
20273
|
+
const peek = () => tokens[pos];
|
|
20274
|
+
const parseBlock = () => {
|
|
20275
|
+
const idTok = tokens[pos++];
|
|
20276
|
+
if (idTok.t !== "word") throw new RbdParseError("Expected a block id.");
|
|
20277
|
+
const id = idTok.v;
|
|
20278
|
+
if (seenIds.has(id)) warnings.push(`Duplicate block id "${id}" \u2014 later definition rendered, ids should be unique.`);
|
|
20279
|
+
seenIds.add(id);
|
|
20280
|
+
let label;
|
|
20281
|
+
let R;
|
|
20282
|
+
if (peek()?.t === "string") {
|
|
20283
|
+
label = tokens[pos++].v;
|
|
20284
|
+
}
|
|
20285
|
+
while (peek()?.t === "word") {
|
|
20286
|
+
const w = peek().v;
|
|
20287
|
+
const attr = parseAttr(w);
|
|
20288
|
+
if (!attr) break;
|
|
20289
|
+
pos++;
|
|
20290
|
+
if (attr.key === "p") R = clamp01(1 - attr.value, w, warnings);
|
|
20291
|
+
else R = clamp01(attr.value, w, warnings);
|
|
20292
|
+
}
|
|
20293
|
+
return { kind: "block", id, ...label !== void 0 ? { label } : {}, ...R !== void 0 ? { R } : {} };
|
|
20294
|
+
};
|
|
20295
|
+
const parseGroup = (kwRaw) => {
|
|
20296
|
+
const kw = kwRaw.toLowerCase();
|
|
20297
|
+
let k;
|
|
20298
|
+
let n;
|
|
20299
|
+
if (kw === "kofn" || kw === "k-of-n" || kw === "voting") {
|
|
20300
|
+
const spec = peek();
|
|
20301
|
+
if (spec?.t === "word" && /^\d+\s*\/\s*\d+$/.test(spec.v)) {
|
|
20302
|
+
pos++;
|
|
20303
|
+
const [ks, ns] = spec.v.split("/");
|
|
20304
|
+
k = parseInt(ks, 10);
|
|
20305
|
+
n = parseInt(ns, 10);
|
|
20306
|
+
} else {
|
|
20307
|
+
throw new RbdParseError(`'${kwRaw}' needs a k/n threshold, e.g. 'kofn 2/3 { \u2026 }'.`);
|
|
20308
|
+
}
|
|
20309
|
+
}
|
|
20310
|
+
if (peek()?.t !== "lbrace") throw new RbdParseError(`Expected '{' after '${kwRaw}'.`);
|
|
20311
|
+
pos++;
|
|
20312
|
+
const children = parseList();
|
|
20313
|
+
if (peek()?.t !== "rbrace") throw new RbdParseError(`Unclosed '${kwRaw}' group \u2014 missing '}'.`);
|
|
20314
|
+
pos++;
|
|
20315
|
+
if (children.length === 0) warnings.push(`Empty '${kwRaw}' group ignored.`);
|
|
20316
|
+
const kind = kw === "series" ? "series" : "parallel";
|
|
20317
|
+
const isKofn = kw === "kofn" || kw === "k-of-n" || kw === "voting";
|
|
20318
|
+
if (isKofn) {
|
|
20319
|
+
const total = n ?? children.length;
|
|
20320
|
+
let thr = k ?? total;
|
|
20321
|
+
if (thr > total) {
|
|
20322
|
+
warnings.push(`k-of-n threshold k=${thr} exceeds n=${total} \u2014 clamped to ${total}.`);
|
|
20323
|
+
thr = total;
|
|
20324
|
+
}
|
|
20325
|
+
if (thr < 1) {
|
|
20326
|
+
warnings.push(`k-of-n threshold k=${thr} < 1 \u2014 clamped to 1.`);
|
|
20327
|
+
thr = 1;
|
|
20328
|
+
}
|
|
20329
|
+
return { kind: "kofn", k: thr, n: total, children };
|
|
20330
|
+
}
|
|
20331
|
+
return { kind, children };
|
|
20332
|
+
};
|
|
20333
|
+
const parseStructure = () => {
|
|
20334
|
+
const tok = peek();
|
|
20335
|
+
if (!tok) throw new RbdParseError("Unexpected end of input.");
|
|
20336
|
+
if (tok.t === "rbrace") throw new RbdParseError("Unexpected '}'.");
|
|
20337
|
+
if (tok.t === "string") throw new RbdParseError(`Unexpected quoted text "${tok.v}" \u2014 labels attach to a block.`);
|
|
20338
|
+
if (tok.t === "lbrace") throw new RbdParseError("Unexpected '{' \u2014 a group keyword (series/parallel/kofn) must precede it.");
|
|
20339
|
+
const w = tok.v;
|
|
20340
|
+
if (GROUP_KW.has(w.toLowerCase())) {
|
|
20341
|
+
pos++;
|
|
20342
|
+
return parseGroup(w);
|
|
20343
|
+
}
|
|
20344
|
+
if (w.toLowerCase() === "block") {
|
|
20345
|
+
pos++;
|
|
20346
|
+
return parseBlock();
|
|
20347
|
+
}
|
|
20348
|
+
return parseBlock();
|
|
20349
|
+
};
|
|
20350
|
+
function parseList() {
|
|
20351
|
+
const items = [];
|
|
20352
|
+
while (pos < tokens.length && peek()?.t !== "rbrace") {
|
|
20353
|
+
items.push(parseStructure());
|
|
20354
|
+
}
|
|
20355
|
+
return items;
|
|
20356
|
+
}
|
|
20357
|
+
const top = parseList();
|
|
20358
|
+
if (pos < tokens.length) throw new RbdParseError("Unbalanced '}' in RBD body.");
|
|
20359
|
+
let root;
|
|
20360
|
+
if (top.length === 0) {
|
|
20361
|
+
throw new RbdParseError("RBD has no blocks. Add at least one `block ID R=\u2026`.");
|
|
20362
|
+
} else if (top.length === 1 && top[0].kind !== "block") {
|
|
20363
|
+
root = top[0];
|
|
20364
|
+
} else {
|
|
20365
|
+
root = { kind: "series", children: top };
|
|
20366
|
+
}
|
|
20367
|
+
return {
|
|
20368
|
+
type: "rbd",
|
|
20369
|
+
...title2 ? { title: title2 } : {},
|
|
20370
|
+
root,
|
|
20371
|
+
warnings,
|
|
20372
|
+
...Object.keys(metadata).length > 0 ? { metadata } : {}
|
|
20373
|
+
};
|
|
20374
|
+
}
|
|
20375
|
+
function tokenize6(src) {
|
|
20376
|
+
const out = [];
|
|
20377
|
+
let i = 0;
|
|
20378
|
+
const n = src.length;
|
|
20379
|
+
const isQuote2 = (c) => c === '"' || c === "'";
|
|
20380
|
+
while (i < n) {
|
|
20381
|
+
const c = src[i];
|
|
20382
|
+
if (c === "#") {
|
|
20383
|
+
while (i < n && src[i] !== "\n") i++;
|
|
20384
|
+
continue;
|
|
20385
|
+
}
|
|
20386
|
+
if (/\s/.test(c)) {
|
|
20387
|
+
i++;
|
|
20388
|
+
continue;
|
|
20389
|
+
}
|
|
20390
|
+
if (c === "{") {
|
|
20391
|
+
out.push({ t: "lbrace" });
|
|
20392
|
+
i++;
|
|
20393
|
+
continue;
|
|
20394
|
+
}
|
|
20395
|
+
if (c === "}") {
|
|
20396
|
+
out.push({ t: "rbrace" });
|
|
20397
|
+
i++;
|
|
20398
|
+
continue;
|
|
20399
|
+
}
|
|
20400
|
+
if (isQuote2(c)) {
|
|
20401
|
+
const close = c;
|
|
20402
|
+
let v2 = "";
|
|
20403
|
+
i++;
|
|
20404
|
+
while (i < n && src[i] !== close) {
|
|
20405
|
+
v2 += src[i];
|
|
20406
|
+
i++;
|
|
20407
|
+
}
|
|
20408
|
+
i++;
|
|
20409
|
+
out.push({ t: "string", v: v2.trim() });
|
|
20410
|
+
continue;
|
|
20411
|
+
}
|
|
20412
|
+
let v = "";
|
|
20413
|
+
while (i < n && !/\s/.test(src[i]) && src[i] !== "{" && src[i] !== "}" && !isQuote2(src[i])) {
|
|
20414
|
+
v += src[i];
|
|
20415
|
+
i++;
|
|
20416
|
+
}
|
|
20417
|
+
out.push({ t: "word", v });
|
|
20418
|
+
}
|
|
20419
|
+
return out;
|
|
20420
|
+
}
|
|
20421
|
+
function stripBodyDirectives(body, metadata) {
|
|
20422
|
+
return body.split("\n").filter((line2) => {
|
|
20423
|
+
const m = line2.match(/^\s*(title|standard|note)\s*:\s*(.+)$/i);
|
|
20424
|
+
if (m) {
|
|
20425
|
+
const key = m[1].toLowerCase();
|
|
20426
|
+
if (key !== "title") metadata[key] = m[2].trim();
|
|
20427
|
+
else metadata.title = m[2].trim();
|
|
20428
|
+
return false;
|
|
20429
|
+
}
|
|
20430
|
+
return true;
|
|
20431
|
+
}).join("\n");
|
|
20432
|
+
}
|
|
20433
|
+
function extractQuoted(s) {
|
|
20434
|
+
const m = s.match(/^["']([^"']*)["']/);
|
|
20435
|
+
if (m) return m[1].trim();
|
|
20436
|
+
return s.length > 0 ? s.trim() : void 0;
|
|
20437
|
+
}
|
|
20438
|
+
function parseAttr(w) {
|
|
20439
|
+
const m = w.match(/^(R|r|p|prob|q)\s*[=:]\s*(.+)$/);
|
|
20440
|
+
if (m) {
|
|
20441
|
+
const key = m[1].toLowerCase();
|
|
20442
|
+
const value = parseNum(m[2]);
|
|
20443
|
+
if (value === void 0) return null;
|
|
20444
|
+
return { key: key === "p" || key === "q" ? "p" : "R", value };
|
|
20445
|
+
}
|
|
20446
|
+
const bare = parseNum(w);
|
|
20447
|
+
if (bare !== void 0) return { key: "R", value: bare };
|
|
20448
|
+
return null;
|
|
20449
|
+
}
|
|
20450
|
+
function parseNum(s) {
|
|
20451
|
+
const t = s.trim();
|
|
20452
|
+
if (/%$/.test(t)) {
|
|
20453
|
+
const v2 = parseFloat(t.slice(0, -1));
|
|
20454
|
+
return Number.isFinite(v2) ? v2 / 100 : void 0;
|
|
20455
|
+
}
|
|
20456
|
+
const v = parseFloat(t);
|
|
20457
|
+
return Number.isFinite(v) ? v : void 0;
|
|
20458
|
+
}
|
|
20459
|
+
function clamp01(v, raw, warnings) {
|
|
20460
|
+
if (v < 0) {
|
|
20461
|
+
warnings.push(`Reliability ${raw} < 0 \u2014 clamped to 0.`);
|
|
20462
|
+
return 0;
|
|
20463
|
+
}
|
|
20464
|
+
if (v > 1) {
|
|
20465
|
+
warnings.push(`Reliability ${raw} > 1 \u2014 clamped to 1.`);
|
|
20466
|
+
return 1;
|
|
20467
|
+
}
|
|
20468
|
+
return v;
|
|
20469
|
+
}
|
|
20470
|
+
|
|
20471
|
+
// src/diagrams/rbd/analysis.ts
|
|
20472
|
+
var KOFN_ENUM_CAP = 18;
|
|
20473
|
+
function analyseRbd(ast) {
|
|
20474
|
+
const notes = [];
|
|
20475
|
+
const warnings = [...ast.warnings];
|
|
20476
|
+
const blocks = [];
|
|
20477
|
+
collectBlocks(ast.root, blocks);
|
|
20478
|
+
const missing = blocks.filter((b) => b.R === void 0).map((b) => b.id);
|
|
20479
|
+
const baseEnv = new Map(blocks.map((b) => [b.id, b.R]));
|
|
20480
|
+
const systemReliability = evalStructure(ast.root, baseEnv, notes);
|
|
20481
|
+
const results = blocks.map((b) => {
|
|
20482
|
+
if (systemReliability === void 0) {
|
|
20483
|
+
return { id: b.id, ...b.R !== void 0 ? { R: b.R } : {}, isSpof: false };
|
|
20484
|
+
}
|
|
20485
|
+
const up = new Map(baseEnv);
|
|
20486
|
+
up.set(b.id, 1);
|
|
20487
|
+
const down = new Map(baseEnv);
|
|
20488
|
+
down.set(b.id, 0);
|
|
20489
|
+
const rUp = evalStructure(ast.root, up, notes);
|
|
20490
|
+
const rDown = evalStructure(ast.root, down, notes);
|
|
20491
|
+
const importance = rUp !== void 0 && rDown !== void 0 ? rUp - rDown : void 0;
|
|
20492
|
+
const isSpof = rDown === 0;
|
|
20493
|
+
return {
|
|
20494
|
+
id: b.id,
|
|
20495
|
+
...b.R !== void 0 ? { R: b.R } : {},
|
|
20496
|
+
...importance !== void 0 ? { importance } : {},
|
|
20497
|
+
isSpof
|
|
20498
|
+
};
|
|
20499
|
+
});
|
|
20500
|
+
let criticalBlock;
|
|
20501
|
+
let best = -Infinity;
|
|
20502
|
+
for (const r7 of results) {
|
|
20503
|
+
if (r7.importance !== void 0 && r7.importance > best) {
|
|
20504
|
+
best = r7.importance;
|
|
20505
|
+
criticalBlock = r7.id;
|
|
20506
|
+
}
|
|
20507
|
+
}
|
|
20508
|
+
if (systemReliability !== void 0) {
|
|
20509
|
+
const spofs = results.filter((r7) => r7.isSpof).map((r7) => r7.id);
|
|
20510
|
+
if (spofs.length === 0) notes.push("No single point of failure \u2014 every block has redundancy in the success path.");
|
|
20511
|
+
}
|
|
20512
|
+
return {
|
|
20513
|
+
...systemReliability !== void 0 ? { systemReliability } : {},
|
|
20514
|
+
blocks: results,
|
|
20515
|
+
missing,
|
|
20516
|
+
...criticalBlock ? { criticalBlock } : {},
|
|
20517
|
+
warnings,
|
|
20518
|
+
notes
|
|
20519
|
+
};
|
|
20520
|
+
}
|
|
20521
|
+
function collectBlocks(s, out) {
|
|
20522
|
+
if (s.kind === "block") {
|
|
20523
|
+
out.push({ id: s.id, ...s.R !== void 0 ? { R: s.R } : {} });
|
|
20524
|
+
return;
|
|
20525
|
+
}
|
|
20526
|
+
for (const c of s.children) collectBlocks(c, out);
|
|
20527
|
+
}
|
|
20528
|
+
function evalStructure(s, env, notes) {
|
|
20529
|
+
if (s.kind === "block") return env.get(s.id);
|
|
20530
|
+
const childR = s.children.map((c) => evalStructure(c, env, notes));
|
|
20531
|
+
if (childR.some((r7) => r7 === void 0)) return void 0;
|
|
20532
|
+
const rs = childR;
|
|
20533
|
+
if (rs.length === 0) return 1;
|
|
20534
|
+
if (s.kind === "series") {
|
|
20535
|
+
return rs.reduce((p, r7) => p * r7, 1);
|
|
20536
|
+
}
|
|
20537
|
+
if (s.kind === "parallel") {
|
|
20538
|
+
return 1 - rs.reduce((p, r7) => p * (1 - r7), 1);
|
|
20539
|
+
}
|
|
20540
|
+
const n = rs.length;
|
|
20541
|
+
const k = Math.min(Math.max(s.k ?? n, 1), n);
|
|
20542
|
+
if (n > KOFN_ENUM_CAP) {
|
|
20543
|
+
notes.push(`k-of-n group with n=${n} exceeds the exact-enumeration cap (${KOFN_ENUM_CAP}); reported as a parallel bound.`);
|
|
20544
|
+
return 1 - rs.reduce((p, r7) => p * (1 - r7), 1);
|
|
20545
|
+
}
|
|
20546
|
+
return kofnReliability(rs, k);
|
|
20547
|
+
}
|
|
20548
|
+
function kofnReliability(rs, k) {
|
|
20549
|
+
const n = rs.length;
|
|
20550
|
+
let total = 0;
|
|
20551
|
+
for (let mask = 0; mask < 1 << n; mask++) {
|
|
20552
|
+
let working = 0;
|
|
20553
|
+
let prob = 1;
|
|
20554
|
+
for (let i = 0; i < n; i++) {
|
|
20555
|
+
if (mask & 1 << i) {
|
|
20556
|
+
working++;
|
|
20557
|
+
prob *= rs[i];
|
|
20558
|
+
} else prob *= 1 - rs[i];
|
|
20559
|
+
}
|
|
20560
|
+
if (working >= k) total += prob;
|
|
20561
|
+
}
|
|
20562
|
+
return total;
|
|
20563
|
+
}
|
|
20564
|
+
|
|
20565
|
+
// src/diagrams/rbd/layout.ts
|
|
20566
|
+
var RBD_CONST = {
|
|
20567
|
+
BLOCK_H: 46,
|
|
20568
|
+
BLOCK_MIN_W: 96,
|
|
20569
|
+
BLOCK_MAX_W: 200,
|
|
20570
|
+
BLOCK_RX: 5,
|
|
20571
|
+
CHAR_W: 6.9,
|
|
20572
|
+
PAD_X: 14,
|
|
20573
|
+
/** Horizontal wire length between series members. */
|
|
20574
|
+
H_GAP: 44,
|
|
20575
|
+
/** Vertical gap between parallel rails. */
|
|
20576
|
+
V_GAP: 26,
|
|
20577
|
+
/** Fan-out / merge horizontal stub flanking a parallel group. */
|
|
20578
|
+
SPLIT_STUB: 30,
|
|
20579
|
+
NODE_R: 3.5,
|
|
20580
|
+
/** Input/output terminal stub at the network ends. */
|
|
20581
|
+
TERM_STUB: 30,
|
|
20582
|
+
CAP_GAP: 15,
|
|
20583
|
+
CAP_LINE_H: 13,
|
|
20584
|
+
CANVAS_PAD: 28,
|
|
20585
|
+
TITLE_H: 32,
|
|
20586
|
+
HEADER_H: 26
|
|
20587
|
+
};
|
|
20588
|
+
function blockWidth(label) {
|
|
20589
|
+
const C2 = RBD_CONST;
|
|
20590
|
+
return Math.min(C2.BLOCK_MAX_W, Math.max(C2.BLOCK_MIN_W, Math.ceil(label.length * C2.CHAR_W) + 2 * C2.PAD_X));
|
|
20591
|
+
}
|
|
20592
|
+
function layoutRbd(ast) {
|
|
20593
|
+
const C2 = RBD_CONST;
|
|
20594
|
+
const analysis = analyseRbd(ast);
|
|
20595
|
+
const spof = new Set(analysis.blocks.filter((b) => b.isSpof).map((b) => b.id));
|
|
20596
|
+
const rById = new Map(analysis.blocks.map((b) => [b.id, b.R]));
|
|
20597
|
+
const blocks = [];
|
|
20598
|
+
const nodes = [];
|
|
20599
|
+
const wires = [];
|
|
20600
|
+
const marks = [];
|
|
20601
|
+
const measure = (s) => {
|
|
20602
|
+
if (s.kind === "block") {
|
|
20603
|
+
return { s, w: blockWidth(s.label ?? s.id), h: C2.BLOCK_H, children: [] };
|
|
20604
|
+
}
|
|
20605
|
+
const children = s.children.map(measure);
|
|
20606
|
+
if (children.length === 0) return { s, w: C2.BLOCK_MIN_W, h: C2.BLOCK_H, children };
|
|
20607
|
+
if (s.kind === "series") {
|
|
20608
|
+
const w2 = children.reduce((acc, c) => acc + c.w, 0) + C2.H_GAP * (children.length - 1);
|
|
20609
|
+
const h2 = Math.max(...children.map((c) => c.h));
|
|
20610
|
+
return { s, w: w2, h: h2, children };
|
|
20611
|
+
}
|
|
20612
|
+
const innerW = Math.max(...children.map((c) => c.w));
|
|
20613
|
+
const w = innerW + 2 * C2.SPLIT_STUB;
|
|
20614
|
+
const h = children.reduce((acc, c) => acc + c.h, 0) + C2.V_GAP * (children.length - 1);
|
|
20615
|
+
return { s, w, h, children };
|
|
20616
|
+
};
|
|
20617
|
+
const place = (m, x, yc2) => {
|
|
20618
|
+
const s = m.s;
|
|
20619
|
+
if (s.kind === "block") {
|
|
20620
|
+
const r7 = rById.get(s.id);
|
|
20621
|
+
blocks.push({
|
|
20622
|
+
block: s,
|
|
20623
|
+
x,
|
|
20624
|
+
y: yc2 - C2.BLOCK_H / 2,
|
|
20625
|
+
width: m.w,
|
|
20626
|
+
height: C2.BLOCK_H,
|
|
20627
|
+
...r7 !== void 0 ? { R: r7 } : {},
|
|
20628
|
+
isSpof: spof.has(s.id),
|
|
20629
|
+
critical: analysis.criticalBlock === s.id
|
|
20630
|
+
});
|
|
20631
|
+
return { entryX: x, exitX: x + m.w };
|
|
20632
|
+
}
|
|
20633
|
+
if (s.kind === "series") {
|
|
20634
|
+
let cursor = x;
|
|
20635
|
+
let prevExit = null;
|
|
20636
|
+
let firstEntry = x;
|
|
20637
|
+
let lastExit = x;
|
|
20638
|
+
m.children.forEach((cm, i) => {
|
|
20639
|
+
const ep2 = place(cm, cursor, yc2);
|
|
20640
|
+
if (i === 0) firstEntry = ep2.entryX;
|
|
20641
|
+
if (prevExit !== null) wires.push({ path: `M ${r6(prevExit)} ${r6(yc2)} L ${r6(ep2.entryX)} ${r6(yc2)}` });
|
|
20642
|
+
prevExit = ep2.exitX;
|
|
20643
|
+
lastExit = ep2.exitX;
|
|
20644
|
+
cursor = ep2.exitX + C2.H_GAP;
|
|
20645
|
+
});
|
|
20646
|
+
return { entryX: firstEntry, exitX: lastExit };
|
|
20647
|
+
}
|
|
20648
|
+
const innerW = Math.max(...m.children.map((c) => c.w));
|
|
20649
|
+
const splitX = x + C2.NODE_R;
|
|
20650
|
+
const mergeX = x + m.w - C2.NODE_R;
|
|
20651
|
+
const childBandX = x + C2.SPLIT_STUB;
|
|
20652
|
+
nodes.push({ kind: "split", x: splitX, y: yc2 });
|
|
20653
|
+
nodes.push({ kind: "join", x: mergeX, y: yc2 });
|
|
20654
|
+
let runY = yc2 - m.h / 2;
|
|
20655
|
+
for (const cm of m.children) {
|
|
20656
|
+
const childYc = runY + cm.h / 2;
|
|
20657
|
+
const childStartX = childBandX + (innerW - cm.w) / 2;
|
|
20658
|
+
const ep2 = place(cm, childStartX, childYc);
|
|
20659
|
+
wires.push({ path: `M ${r6(splitX)} ${r6(yc2)} L ${r6(splitX)} ${r6(childYc)} L ${r6(ep2.entryX)} ${r6(childYc)}` });
|
|
20660
|
+
wires.push({ path: `M ${r6(ep2.exitX)} ${r6(childYc)} L ${r6(mergeX)} ${r6(childYc)} L ${r6(mergeX)} ${r6(yc2)}` });
|
|
20661
|
+
runY += cm.h + C2.V_GAP;
|
|
20662
|
+
}
|
|
20663
|
+
if (s.kind === "kofn") {
|
|
20664
|
+
marks.push({ x: mergeX + 6, y: yc2 - m.h / 2 - 6, text: `${s.k}/${s.n ?? m.children.length}` });
|
|
20665
|
+
}
|
|
20666
|
+
return { entryX: splitX, exitX: mergeX };
|
|
20667
|
+
};
|
|
20668
|
+
const rootM = measure(ast.root);
|
|
20669
|
+
const headerH = (ast.title ? C2.TITLE_H : 0) + C2.HEADER_H;
|
|
20670
|
+
const yc = C2.CANVAS_PAD + headerH + rootM.h / 2;
|
|
20671
|
+
const originX = C2.CANVAS_PAD + C2.TERM_STUB;
|
|
20672
|
+
const ep = place(rootM, originX, yc);
|
|
20673
|
+
const inX = C2.CANVAS_PAD;
|
|
20674
|
+
const outX = ep.exitX + C2.TERM_STUB;
|
|
20675
|
+
nodes.push({ kind: "in", x: inX, y: yc });
|
|
20676
|
+
nodes.push({ kind: "out", x: outX, y: yc });
|
|
20677
|
+
wires.push({ path: `M ${r6(inX)} ${r6(yc)} L ${r6(ep.entryX)} ${r6(yc)}` });
|
|
20678
|
+
wires.push({ path: `M ${r6(ep.exitX)} ${r6(yc)} L ${r6(outX)} ${r6(yc)}` });
|
|
20679
|
+
let maxX = outX;
|
|
20680
|
+
let maxY = yc + rootM.h / 2;
|
|
20681
|
+
for (const b of blocks) {
|
|
20682
|
+
maxX = Math.max(maxX, b.x + b.width);
|
|
20683
|
+
const capLines = (b.R !== void 0 ? 1 : 0) + (b.block.label && b.block.label !== b.block.id ? 1 : 0);
|
|
20684
|
+
maxY = Math.max(maxY, b.y + b.height + (capLines > 0 ? C2.CAP_GAP + capLines * C2.CAP_LINE_H : 0));
|
|
20685
|
+
}
|
|
20686
|
+
for (const mk of marks) maxX = Math.max(maxX, mk.x + 24);
|
|
20687
|
+
return {
|
|
20688
|
+
ast,
|
|
20689
|
+
analysis,
|
|
20690
|
+
blocks,
|
|
20691
|
+
nodes,
|
|
20692
|
+
wires,
|
|
20693
|
+
marks,
|
|
20694
|
+
width: Math.ceil(maxX + C2.CANVAS_PAD),
|
|
20695
|
+
height: Math.ceil(maxY + C2.CANVAS_PAD)
|
|
20696
|
+
};
|
|
20697
|
+
}
|
|
20698
|
+
function r6(n) {
|
|
20699
|
+
return Math.round(n * 10) / 10;
|
|
20700
|
+
}
|
|
20701
|
+
|
|
20702
|
+
// src/diagrams/rbd/renderer.ts
|
|
20703
|
+
function renderRbd(text2, config) {
|
|
20704
|
+
const ast = parseRbd(text2);
|
|
20705
|
+
const layout = layoutRbd(ast);
|
|
20706
|
+
return renderRbdLayout(layout, config);
|
|
20707
|
+
}
|
|
20708
|
+
function renderRbdLayout(layout, config) {
|
|
20709
|
+
const theme = resolveReliabilityTheme(config?.theme ?? "default");
|
|
20710
|
+
const fontFamily = config?.fontFamily ?? DEFAULT_FONT_FAMILY;
|
|
20711
|
+
const pad = config?.padding ?? 0;
|
|
20712
|
+
const { ast, analysis } = layout;
|
|
20713
|
+
const width = layout.width + pad * 2;
|
|
20714
|
+
const height = layout.height + pad * 2;
|
|
20715
|
+
const a11y = ast.title ?? "Reliability block diagram";
|
|
20716
|
+
const styleBlock = el(
|
|
20717
|
+
"style",
|
|
20718
|
+
{},
|
|
20719
|
+
`
|
|
20720
|
+
.sx-rbd-bg { fill: ${theme.bg}; }
|
|
20721
|
+
.sx-rbd-wire { fill: none; stroke: ${theme.edgeStroke}; stroke-width: ${STROKE_WIDTH.normal}; }
|
|
20722
|
+
.sx-rbd-node { fill: ${theme.edgeStroke}; stroke: none; }
|
|
20723
|
+
.sx-rbd-term { fill: ${theme.eventFill}; stroke: ${theme.eventStroke}; stroke-width: ${STROKE_WIDTH.normal}; }
|
|
20724
|
+
.sx-rbd-block { fill: ${theme.eventFill}; stroke: ${theme.eventStroke}; stroke-width: ${STROKE_WIDTH.normal}; }
|
|
20725
|
+
.sx-rbd-block[data-spof="true"] { stroke: ${theme.spofStroke}; stroke-width: ${STROKE_WIDTH.thick}; }
|
|
20726
|
+
.sx-rbd-block[data-critical="true"] { stroke: ${theme.gateStroke}; stroke-width: 2.25; }
|
|
20727
|
+
.sx-rbd-label { fill: ${theme.eventStroke}; font-size: ${FONT_SIZE.label}px; font-weight: 600; }
|
|
20728
|
+
.sx-rbd-r { fill: ${theme.probText}; font-size: ${FONT_SIZE.small}px; font-weight: 600; }
|
|
20729
|
+
.sx-rbd-mark { fill: ${theme.gateStroke}; font-size: ${FONT_SIZE.small}px; font-weight: 700; }
|
|
20730
|
+
.sx-rbd-rsys { fill: ${theme.probText}; font-size: ${FONT_SIZE.label + 1}px; font-weight: 700; }
|
|
20731
|
+
.sx-rbd-title { fill: ${theme.eventStroke}; font-size: ${FONT_SIZE.title}px; font-weight: 700; }
|
|
20732
|
+
`.trim()
|
|
20733
|
+
);
|
|
20734
|
+
const children = [
|
|
20735
|
+
title(a11y),
|
|
20736
|
+
desc(summarise5(layout)),
|
|
20737
|
+
styleBlock,
|
|
20738
|
+
rect({ x: 0, y: 0, width, height, class: "sx-rbd-bg" })
|
|
20739
|
+
];
|
|
20740
|
+
const inner = [];
|
|
20741
|
+
if (ast.title) {
|
|
20742
|
+
inner.push(
|
|
20743
|
+
text(
|
|
20744
|
+
{ x: RBD_CONST.CANVAS_PAD, y: 22, class: "sx-rbd-title", "font-family": fontFamily },
|
|
20745
|
+
ast.title
|
|
20746
|
+
)
|
|
20747
|
+
);
|
|
20748
|
+
}
|
|
20749
|
+
inner.push(
|
|
20750
|
+
text(
|
|
20751
|
+
{
|
|
20752
|
+
x: layout.width / 2,
|
|
20753
|
+
y: (ast.title ? RBD_CONST.TITLE_H : 0) + 18,
|
|
20754
|
+
class: "sx-rbd-rsys",
|
|
20755
|
+
"text-anchor": "middle"
|
|
20756
|
+
},
|
|
20757
|
+
systemLabel(analysis)
|
|
20758
|
+
)
|
|
20759
|
+
);
|
|
20760
|
+
for (const w of layout.wires) inner.push(path({ d: w.path, class: "sx-rbd-wire" }));
|
|
20761
|
+
for (const n of layout.nodes) {
|
|
20762
|
+
if (n.kind === "in" || n.kind === "out") {
|
|
20763
|
+
inner.push(circle({ cx: n.x, cy: n.y, r: 6, class: "sx-rbd-term", "data-node": n.kind }));
|
|
20764
|
+
} else {
|
|
20765
|
+
inner.push(circle({ cx: n.x, cy: n.y, r: RBD_CONST.NODE_R, class: "sx-rbd-node", "data-node": n.kind }));
|
|
20766
|
+
}
|
|
20767
|
+
}
|
|
20768
|
+
for (const mk of layout.marks) {
|
|
20769
|
+
inner.push(text({ x: mk.x, y: mk.y, class: "sx-rbd-mark" }, mk.text));
|
|
20770
|
+
}
|
|
20771
|
+
for (const b of layout.blocks) inner.push(renderBlock(b));
|
|
20772
|
+
children.push(
|
|
20773
|
+
group({ transform: pad ? `translate(${pad}, ${pad})` : void 0, "font-family": fontFamily }, inner)
|
|
20774
|
+
);
|
|
20775
|
+
return svgRoot(
|
|
20776
|
+
{
|
|
20777
|
+
width,
|
|
20778
|
+
height,
|
|
20779
|
+
viewBox: `0 0 ${width} ${height}`,
|
|
20780
|
+
role: "img",
|
|
20781
|
+
"aria-label": a11y,
|
|
20782
|
+
"data-diagram-type": "rbd"
|
|
20783
|
+
},
|
|
20784
|
+
children
|
|
20785
|
+
);
|
|
20786
|
+
}
|
|
20787
|
+
function renderBlock(b) {
|
|
20788
|
+
const cx = b.x + b.width / 2;
|
|
20789
|
+
const cy = b.y + b.height / 2;
|
|
20790
|
+
const label = b.block.label ?? b.block.id;
|
|
20791
|
+
const parts = [
|
|
20792
|
+
rect({
|
|
20793
|
+
x: b.x,
|
|
20794
|
+
y: b.y,
|
|
20795
|
+
width: b.width,
|
|
20796
|
+
height: b.height,
|
|
20797
|
+
rx: RBD_CONST.BLOCK_RX,
|
|
20798
|
+
class: "sx-rbd-block",
|
|
20799
|
+
...b.isSpof ? { "data-spof": "true" } : {},
|
|
20800
|
+
...b.critical && !b.isSpof ? { "data-critical": "true" } : {}
|
|
20801
|
+
}),
|
|
20802
|
+
multilineText(
|
|
20803
|
+
{ x: cx, y: cy, class: "sx-rbd-label", "text-anchor": "middle", "dominant-baseline": "middle" },
|
|
20804
|
+
wrap4(label, 18),
|
|
20805
|
+
13
|
|
20806
|
+
)
|
|
20807
|
+
];
|
|
20808
|
+
if (b.R !== void 0) {
|
|
20809
|
+
parts.push(
|
|
20810
|
+
text(
|
|
20811
|
+
{ x: cx, y: b.y + b.height + RBD_CONST.CAP_GAP, class: "sx-rbd-r", "text-anchor": "middle" },
|
|
20812
|
+
`R=${fmtR(b.R)}`
|
|
20813
|
+
)
|
|
20814
|
+
);
|
|
20815
|
+
}
|
|
20816
|
+
return group(
|
|
20817
|
+
{
|
|
20818
|
+
class: "sx-rbd-block-g",
|
|
20819
|
+
"data-id": b.block.id,
|
|
20820
|
+
...b.R !== void 0 ? { "data-r": String(b.R) } : {},
|
|
20821
|
+
...b.isSpof ? { "data-spof": "true" } : {},
|
|
20822
|
+
...b.critical ? { "data-critical": "true" } : {}
|
|
20823
|
+
},
|
|
20824
|
+
parts
|
|
20825
|
+
);
|
|
20826
|
+
}
|
|
20827
|
+
function systemLabel(analysis) {
|
|
20828
|
+
if (analysis.systemReliability === void 0) {
|
|
20829
|
+
const miss = analysis.missing.length > 0 ? ` \u2014 missing R on ${analysis.missing.join(", ")}` : "";
|
|
20830
|
+
return `System reliability: n/a${miss}`;
|
|
20831
|
+
}
|
|
20832
|
+
return `System reliability R = ${fmtR(analysis.systemReliability)}`;
|
|
20833
|
+
}
|
|
20834
|
+
function fmtR(n) {
|
|
20835
|
+
if (n >= 1) return "1";
|
|
20836
|
+
if (n <= 0) return "0";
|
|
20837
|
+
for (let p = 5; p <= 9; p++) {
|
|
20838
|
+
const s = parseFloat(n.toPrecision(p));
|
|
20839
|
+
if (s < 1) return String(s);
|
|
20840
|
+
}
|
|
20841
|
+
return String(parseFloat(n.toPrecision(9)));
|
|
20842
|
+
}
|
|
20843
|
+
function summarise5(layout) {
|
|
20844
|
+
const { analysis } = layout;
|
|
20845
|
+
const n = layout.blocks.length;
|
|
20846
|
+
const parts = [`Reliability block diagram: ${n} block${n === 1 ? "" : "s"}.`];
|
|
20847
|
+
if (analysis.systemReliability !== void 0) {
|
|
20848
|
+
parts.push(`System reliability R = ${fmtR(analysis.systemReliability)}.`);
|
|
20849
|
+
} else if (analysis.missing.length > 0) {
|
|
20850
|
+
parts.push(`System reliability n/a \u2014 missing R on ${analysis.missing.join(", ")}.`);
|
|
20851
|
+
}
|
|
20852
|
+
const spofs = analysis.blocks.filter((b) => b.isSpof).map((b) => b.id);
|
|
20853
|
+
if (spofs.length > 0) parts.push(`Single point${spofs.length > 1 ? "s" : ""} of failure: ${spofs.join(", ")}.`);
|
|
20854
|
+
if (analysis.criticalBlock) parts.push(`Highest reliability-importance block: ${analysis.criticalBlock}.`);
|
|
20855
|
+
for (const note of analysis.notes) parts.push(note);
|
|
20856
|
+
for (const w of analysis.warnings) parts.push(w);
|
|
20857
|
+
return parts.join(" ");
|
|
20858
|
+
}
|
|
20859
|
+
function wrap4(s, perLine) {
|
|
20860
|
+
if (s.length <= perLine) return s;
|
|
20861
|
+
const words = s.split(/\s+/);
|
|
20862
|
+
const lines = [];
|
|
20863
|
+
let cur = "";
|
|
20864
|
+
for (const w of words) {
|
|
20865
|
+
if (cur && cur.length + 1 + w.length > perLine) {
|
|
20866
|
+
lines.push(cur);
|
|
20867
|
+
cur = w;
|
|
20868
|
+
} else cur = cur ? `${cur} ${w}` : w;
|
|
20869
|
+
}
|
|
20870
|
+
if (cur) lines.push(cur);
|
|
20871
|
+
if (lines.length > 2) {
|
|
20872
|
+
lines.length = 2;
|
|
20873
|
+
lines[1] = lines[1].slice(0, perLine - 1) + "\u2026";
|
|
20874
|
+
}
|
|
20875
|
+
return lines.join("<br/>");
|
|
20876
|
+
}
|
|
20877
|
+
|
|
20878
|
+
// src/diagrams/rbd/index.ts
|
|
20879
|
+
var rbd = {
|
|
20880
|
+
type: "rbd",
|
|
20881
|
+
detect(text2) {
|
|
20882
|
+
return /^\s*(rbd|reliability(?:blockdiagram)?|reliability-block-diagram)\b/i.test(text2);
|
|
20883
|
+
},
|
|
20884
|
+
parse: parseRbd,
|
|
20885
|
+
render(text2, config) {
|
|
20886
|
+
return renderRbd(text2, config);
|
|
20887
|
+
}
|
|
20888
|
+
};
|
|
20889
|
+
|
|
20238
20890
|
// src/diagrams/causalloop/parser.ts
|
|
20239
20891
|
var CausalLoopParseError = class extends Error {
|
|
20240
20892
|
constructor(message, line2) {
|
|
@@ -20928,7 +21580,7 @@ function renderCausalLoopLayout(layout, config) {
|
|
|
20928
21580
|
);
|
|
20929
21581
|
const children = [
|
|
20930
21582
|
title(a11y),
|
|
20931
|
-
desc(
|
|
21583
|
+
desc(summarise6(layout)),
|
|
20932
21584
|
styleBlock,
|
|
20933
21585
|
el("rect", { x: 0, y: 0, width, height, class: "sx-cld-bg" })
|
|
20934
21586
|
];
|
|
@@ -21042,17 +21694,17 @@ function arrowhead(x, y, tx, ty) {
|
|
|
21042
21694
|
return polygon({ points: `${tip} ${p1} ${p2}`, class: "sx-cld-arrow" });
|
|
21043
21695
|
}
|
|
21044
21696
|
function renderGlyph(g) {
|
|
21045
|
-
const
|
|
21697
|
+
const r7 = g.r;
|
|
21046
21698
|
const startAng = -Math.PI / 2;
|
|
21047
21699
|
const sweep = 300 * Math.PI / 180;
|
|
21048
21700
|
const endAng = g.clockwise ? startAng + sweep : startAng - sweep;
|
|
21049
|
-
const sx = g.cx +
|
|
21050
|
-
const sy = g.cy +
|
|
21051
|
-
const ex = g.cx +
|
|
21052
|
-
const ey = g.cy +
|
|
21701
|
+
const sx = g.cx + r7 * Math.cos(startAng);
|
|
21702
|
+
const sy = g.cy + r7 * Math.sin(startAng);
|
|
21703
|
+
const ex = g.cx + r7 * Math.cos(endAng);
|
|
21704
|
+
const ey = g.cy + r7 * Math.sin(endAng);
|
|
21053
21705
|
const largeArc = 1;
|
|
21054
21706
|
const sweepFlag = g.clockwise ? 1 : 0;
|
|
21055
|
-
const arc = `M ${fmt4(sx)} ${fmt4(sy)} A ${
|
|
21707
|
+
const arc = `M ${fmt4(sx)} ${fmt4(sy)} A ${r7} ${r7} 0 ${largeArc} ${sweepFlag} ${fmt4(ex)} ${fmt4(ey)}`;
|
|
21056
21708
|
const dir = g.clockwise ? 1 : -1;
|
|
21057
21709
|
const tx = -Math.sin(endAng) * dir;
|
|
21058
21710
|
const ty = Math.cos(endAng) * dir;
|
|
@@ -21097,7 +21749,7 @@ function glyphArrow(x, y, tx, ty) {
|
|
|
21097
21749
|
const p2 = `${fmt4(bx - px * wide)},${fmt4(by - py * wide)}`;
|
|
21098
21750
|
return polygon({ points: `${fmt4(x)},${fmt4(y)} ${p1} ${p2}`, class: "sx-cld-glyph-head" });
|
|
21099
21751
|
}
|
|
21100
|
-
function
|
|
21752
|
+
function summarise6(layout) {
|
|
21101
21753
|
const { ast, analysis } = layout;
|
|
21102
21754
|
const parts = [
|
|
21103
21755
|
`Causal loop diagram${ast.title ? ` "${ast.title}"` : ""}: ${ast.variables.length} variable${ast.variables.length === 1 ? "" : "s"}, ${ast.links.length} causal link${ast.links.length === 1 ? "" : "s"}.`
|
|
@@ -21146,7 +21798,7 @@ var MarkovParseError = class extends Error {
|
|
|
21146
21798
|
};
|
|
21147
21799
|
var OPENERS2 = ['"', "\u201C", "\u300C", "\u300E", "\xAB"];
|
|
21148
21800
|
var CLOSERS2 = ['"', "\u201D", "\u300D", "\u300F", "\xBB"];
|
|
21149
|
-
function
|
|
21801
|
+
function tokenize7(s) {
|
|
21150
21802
|
const out = [];
|
|
21151
21803
|
let i = 0;
|
|
21152
21804
|
while (i < s.length) {
|
|
@@ -21231,7 +21883,7 @@ function parseMarkov(text2) {
|
|
|
21231
21883
|
if (trimmed.startsWith("#") || trimmed.startsWith("//")) continue;
|
|
21232
21884
|
if (!sawHeader && /^(markov|markovchain)\b/i.test(trimmed)) {
|
|
21233
21885
|
sawHeader = true;
|
|
21234
|
-
const toks =
|
|
21886
|
+
const toks = tokenize7(trimmed);
|
|
21235
21887
|
const titleTok = toks.find((t, idx) => idx > 0 && t.quoted);
|
|
21236
21888
|
if (titleTok) ast.title = titleTok.text;
|
|
21237
21889
|
else if (toks[1] && !toks[1].quoted) ast.title = toks.slice(1).map((t) => t.text).join(" ");
|
|
@@ -21289,7 +21941,7 @@ function parseMarkov(text2) {
|
|
|
21289
21941
|
return ast;
|
|
21290
21942
|
}
|
|
21291
21943
|
function parseStateDecl(line2, lineNo, ensureState) {
|
|
21292
|
-
const toks =
|
|
21944
|
+
const toks = tokenize7(normalizeKeyNums2(line2));
|
|
21293
21945
|
const idTok = toks[1];
|
|
21294
21946
|
if (!idTok || idTok.quoted) throw new MarkovParseError(`state is missing an id`, lineNo);
|
|
21295
21947
|
const id = idTok.text;
|
|
@@ -21563,22 +22215,22 @@ function computeAbsorbing(P, order, classification) {
|
|
|
21563
22215
|
const absorbing = order.filter((id) => absorbingSet.has(id));
|
|
21564
22216
|
const pos = new Map(order.map((id, i) => [id, i]));
|
|
21565
22217
|
const t = transient.length;
|
|
21566
|
-
const
|
|
22218
|
+
const r7 = absorbing.length;
|
|
21567
22219
|
const Q = Array.from({ length: t }, () => new Array(t).fill(0));
|
|
21568
|
-
const R = Array.from({ length: t }, () => new Array(
|
|
22220
|
+
const R = Array.from({ length: t }, () => new Array(r7).fill(0));
|
|
21569
22221
|
for (let a = 0; a < t; a++) {
|
|
21570
22222
|
const fi = pos.get(transient[a]);
|
|
21571
22223
|
for (let b = 0; b < t; b++) Q[a][b] = P[fi][pos.get(transient[b])];
|
|
21572
|
-
for (let b = 0; b <
|
|
22224
|
+
for (let b = 0; b < r7; b++) R[a][b] = P[fi][pos.get(absorbing[b])];
|
|
21573
22225
|
}
|
|
21574
22226
|
const ImQ = Array.from(
|
|
21575
22227
|
{ length: t },
|
|
21576
22228
|
(_, a) => Array.from({ length: t }, (_2, b) => (a === b ? 1 : 0) - Q[a][b])
|
|
21577
22229
|
);
|
|
21578
22230
|
const N = invert(ImQ);
|
|
21579
|
-
const B = Array.from({ length: t }, () => new Array(
|
|
22231
|
+
const B = Array.from({ length: t }, () => new Array(r7).fill(0));
|
|
21580
22232
|
for (let a = 0; a < t; a++) {
|
|
21581
|
-
for (let b = 0; b <
|
|
22233
|
+
for (let b = 0; b < r7; b++) {
|
|
21582
22234
|
let s = 0;
|
|
21583
22235
|
for (let c = 0; c < t; c++) s += N[a][c] * R[c][b];
|
|
21584
22236
|
B[a][b] = s;
|
|
@@ -21850,11 +22502,11 @@ function curvedArcGeom(tr, a, b, bow, C2) {
|
|
|
21850
22502
|
labelY: mid.y
|
|
21851
22503
|
};
|
|
21852
22504
|
}
|
|
21853
|
-
function aimToBoundary(centre, target,
|
|
22505
|
+
function aimToBoundary(centre, target, r7) {
|
|
21854
22506
|
const dx = target.x - centre.x;
|
|
21855
22507
|
const dy = target.y - centre.y;
|
|
21856
22508
|
const len = Math.hypot(dx, dy) || 1;
|
|
21857
|
-
return { x: centre.x + dx / len *
|
|
22509
|
+
return { x: centre.x + dx / len * r7, y: centre.y + dy / len * r7 };
|
|
21858
22510
|
}
|
|
21859
22511
|
function selfLoopGeom(tr, c, ringCenter, layout, C2) {
|
|
21860
22512
|
let ox = c.x - ringCenter.x;
|
|
@@ -22088,8 +22740,8 @@ function renderMarkov(textOrAst, config) {
|
|
|
22088
22740
|
}
|
|
22089
22741
|
function fmt5(x) {
|
|
22090
22742
|
if (!Number.isFinite(x)) return String(x);
|
|
22091
|
-
const
|
|
22092
|
-
return String(
|
|
22743
|
+
const r7 = Math.round(x * 1e3) / 1e3;
|
|
22744
|
+
return String(r7);
|
|
22093
22745
|
}
|
|
22094
22746
|
function num(x) {
|
|
22095
22747
|
return Math.round(x * 100) / 100;
|
|
@@ -22766,7 +23418,7 @@ function renderGitGraphLayout(layout, config) {
|
|
|
22766
23418
|
const styleBlock = buildStyle2(pal, ast.showBranches);
|
|
22767
23419
|
const children = [
|
|
22768
23420
|
title(a11y),
|
|
22769
|
-
desc(
|
|
23421
|
+
desc(summarise7(layout)),
|
|
22770
23422
|
styleBlock,
|
|
22771
23423
|
rect({ x: 0, y: 0, width, height, class: "sx-gg-bg" })
|
|
22772
23424
|
];
|
|
@@ -22889,13 +23541,13 @@ function renderCommit(lc, ast, pal, fontFamily) {
|
|
|
22889
23541
|
if (node.commitType !== "NORMAL") dataAttrs2["data-type"] = node.commitType;
|
|
22890
23542
|
if (node.tag) dataAttrs2["data-tag"] = node.tag;
|
|
22891
23543
|
if (node.commitType === "HIGHLIGHT") {
|
|
22892
|
-
const
|
|
23544
|
+
const r7 = GITGRAPH_CONST.SQUARE_R;
|
|
22893
23545
|
parts.push(
|
|
22894
23546
|
rect({
|
|
22895
|
-
x: x -
|
|
22896
|
-
y: y -
|
|
22897
|
-
width:
|
|
22898
|
-
height:
|
|
23547
|
+
x: x - r7,
|
|
23548
|
+
y: y - r7,
|
|
23549
|
+
width: r7 * 2,
|
|
23550
|
+
height: r7 * 2,
|
|
22899
23551
|
rx: 2,
|
|
22900
23552
|
class: `sx-gg-node sx-gg-highlight sx-gg-stroke-c${ci}`
|
|
22901
23553
|
})
|
|
@@ -23016,7 +23668,7 @@ ${laneRules}
|
|
|
23016
23668
|
function num2(n) {
|
|
23017
23669
|
return Number.isInteger(n) ? String(n) : n.toFixed(2);
|
|
23018
23670
|
}
|
|
23019
|
-
function
|
|
23671
|
+
function summarise7(layout) {
|
|
23020
23672
|
const c = layout.replay.commits.length;
|
|
23021
23673
|
const b = layout.replay.branches.length;
|
|
23022
23674
|
const merges = layout.replay.commits.filter((n) => n.isMerge).length;
|
|
@@ -23573,33 +24225,33 @@ function layoutEpc(ast) {
|
|
|
23573
24225
|
const isLR = ast.direction === "lr";
|
|
23574
24226
|
const layerCenter = [];
|
|
23575
24227
|
let primary = EPC_CONST.CANVAS_PAD + (ast.title ? EPC_CONST.TITLE_H : 0);
|
|
23576
|
-
for (let
|
|
24228
|
+
for (let r7 = 0; r7 <= maxLayer; r7++) {
|
|
23577
24229
|
const bandThickness = Math.max(
|
|
23578
24230
|
0,
|
|
23579
|
-
...ranks[
|
|
24231
|
+
...ranks[r7].map((id) => isLR ? sized.get(id).w : sized.get(id).h)
|
|
23580
24232
|
);
|
|
23581
|
-
layerCenter[
|
|
24233
|
+
layerCenter[r7] = primary + bandThickness / 2;
|
|
23582
24234
|
primary += bandThickness + EPC_CONST.LAYER_GAP;
|
|
23583
24235
|
}
|
|
23584
24236
|
const primaryExtent = primary - EPC_CONST.LAYER_GAP + EPC_CONST.CANVAS_PAD;
|
|
23585
24237
|
const crossPos = /* @__PURE__ */ new Map();
|
|
23586
24238
|
let maxCrossExtent = 0;
|
|
23587
24239
|
const rankWidths = [];
|
|
23588
|
-
for (let
|
|
24240
|
+
for (let r7 = 0; r7 <= maxLayer; r7++) {
|
|
23589
24241
|
let cursor = 0;
|
|
23590
|
-
for (const id of ranks[
|
|
24242
|
+
for (const id of ranks[r7]) {
|
|
23591
24243
|
const s = sized.get(id);
|
|
23592
24244
|
const span = isLR ? s.h : s.w;
|
|
23593
24245
|
crossPos.set(id, cursor + span / 2);
|
|
23594
24246
|
cursor += span + EPC_CONST.NODE_GAP;
|
|
23595
24247
|
}
|
|
23596
24248
|
const total = Math.max(0, cursor - EPC_CONST.NODE_GAP);
|
|
23597
|
-
rankWidths[
|
|
24249
|
+
rankWidths[r7] = total;
|
|
23598
24250
|
maxCrossExtent = Math.max(maxCrossExtent, total);
|
|
23599
24251
|
}
|
|
23600
|
-
for (let
|
|
23601
|
-
const shift = (maxCrossExtent - rankWidths[
|
|
23602
|
-
for (const id of ranks[
|
|
24252
|
+
for (let r7 = 0; r7 <= maxLayer; r7++) {
|
|
24253
|
+
const shift = (maxCrossExtent - rankWidths[r7]) / 2 + EPC_CONST.CANVAS_PAD;
|
|
24254
|
+
for (const id of ranks[r7]) crossPos.set(id, crossPos.get(id) + shift);
|
|
23603
24255
|
}
|
|
23604
24256
|
const backMargin = backSet.size > 0 ? EPC_CONST.BACK_MARGIN : 0;
|
|
23605
24257
|
const crossExtent = maxCrossExtent + EPC_CONST.CANVAS_PAD * 2 + backMargin;
|
|
@@ -23677,15 +24329,15 @@ function longestPathLayers(ast, dagOut, dagIn) {
|
|
|
23677
24329
|
}
|
|
23678
24330
|
function orderRanks2(ranks, dagIn, ast) {
|
|
23679
24331
|
const declIndex = new Map(ast.nodes.map((n, i) => [n.id, i]));
|
|
23680
|
-
for (let
|
|
24332
|
+
for (let r7 = 1; r7 < ranks.length; r7++) {
|
|
23681
24333
|
const prevIndex = /* @__PURE__ */ new Map();
|
|
23682
|
-
ranks[
|
|
24334
|
+
ranks[r7 - 1].forEach((id, i) => prevIndex.set(id, i));
|
|
23683
24335
|
const bary = /* @__PURE__ */ new Map();
|
|
23684
|
-
for (const id of ranks[
|
|
24336
|
+
for (const id of ranks[r7]) {
|
|
23685
24337
|
const preds = (dagIn.get(id) ?? []).map((p) => prevIndex.get(p)).filter((v) => v !== void 0);
|
|
23686
24338
|
bary.set(id, preds.length ? preds.reduce((a, b) => a + b, 0) / preds.length : declIndex.get(id) ?? 0);
|
|
23687
24339
|
}
|
|
23688
|
-
ranks[
|
|
24340
|
+
ranks[r7].sort((a, b) => {
|
|
23689
24341
|
const d = (bary.get(a) ?? 0) - (bary.get(b) ?? 0);
|
|
23690
24342
|
if (Math.abs(d) > 1e-9) return d;
|
|
23691
24343
|
return (declIndex.get(a) ?? 0) - (declIndex.get(b) ?? 0);
|
|
@@ -23716,7 +24368,7 @@ function detectBackEdges(ast, out) {
|
|
|
23716
24368
|
}
|
|
23717
24369
|
colour.set(id, BLACK);
|
|
23718
24370
|
};
|
|
23719
|
-
for (const
|
|
24371
|
+
for (const r7 of visitOrder) if ((colour.get(r7) ?? WHITE) === WHITE) dfs(r7);
|
|
23720
24372
|
return back;
|
|
23721
24373
|
}
|
|
23722
24374
|
function routeEdge3(e, nodePos, crossExtent, back, isLR) {
|
|
@@ -23753,9 +24405,9 @@ function borderPoint(from, to, _isLR) {
|
|
|
23753
24405
|
const dx = to.cx - from.cx;
|
|
23754
24406
|
const dy = to.cy - from.cy;
|
|
23755
24407
|
if (from.node.kind === "connector") {
|
|
23756
|
-
const
|
|
24408
|
+
const r7 = EPC_CONST.CONN_R;
|
|
23757
24409
|
const len = Math.hypot(dx, dy) || 1;
|
|
23758
|
-
return { x: from.cx + dx / len *
|
|
24410
|
+
return { x: from.cx + dx / len * r7, y: from.cy + dy / len * r7 };
|
|
23759
24411
|
}
|
|
23760
24412
|
const hw = from.width / 2;
|
|
23761
24413
|
const hh = from.height / 2;
|
|
@@ -23857,7 +24509,7 @@ function renderEpcLayout(layout, config) {
|
|
|
23857
24509
|
);
|
|
23858
24510
|
const children = [
|
|
23859
24511
|
title(a11y),
|
|
23860
|
-
desc(
|
|
24512
|
+
desc(summarise8(layout)),
|
|
23861
24513
|
styleBlock,
|
|
23862
24514
|
defs([
|
|
23863
24515
|
el("marker", {
|
|
@@ -23910,7 +24562,7 @@ function renderNode3(n) {
|
|
|
23910
24562
|
parts.push(hexagon(n.cx, n.cy, n.width, n.height, "sx-epc-event"));
|
|
23911
24563
|
parts.push(multilineText(
|
|
23912
24564
|
{ x: n.cx, y: n.cy, class: "sx-epc-label", "text-anchor": "middle", "dominant-baseline": "middle" },
|
|
23913
|
-
|
|
24565
|
+
wrap5(label, 18),
|
|
23914
24566
|
14
|
|
23915
24567
|
));
|
|
23916
24568
|
} else if (node.kind === "function") {
|
|
@@ -23925,7 +24577,7 @@ function renderNode3(n) {
|
|
|
23925
24577
|
}));
|
|
23926
24578
|
parts.push(multilineText(
|
|
23927
24579
|
{ x: n.cx, y: n.cy, class: "sx-epc-label", "text-anchor": "middle", "dominant-baseline": "middle" },
|
|
23928
|
-
|
|
24580
|
+
wrap5(label, 18),
|
|
23929
24581
|
14
|
|
23930
24582
|
));
|
|
23931
24583
|
} else {
|
|
@@ -23936,9 +24588,9 @@ function renderNode3(n) {
|
|
|
23936
24588
|
));
|
|
23937
24589
|
}
|
|
23938
24590
|
if (n.flagged) {
|
|
23939
|
-
const
|
|
24591
|
+
const r7 = node.kind === "connector" ? EPC_CONST.CONN_R + 5 : 0;
|
|
23940
24592
|
if (node.kind === "connector") {
|
|
23941
|
-
parts.push(circle({ cx: n.cx, cy: n.cy, r:
|
|
24593
|
+
parts.push(circle({ cx: n.cx, cy: n.cy, r: r7, class: "sx-epc-flagring" }));
|
|
23942
24594
|
} else {
|
|
23943
24595
|
parts.push(rect({
|
|
23944
24596
|
x: n.cx - n.width / 2 - 5,
|
|
@@ -24001,7 +24653,7 @@ function renderEdge6(e) {
|
|
|
24001
24653
|
parts
|
|
24002
24654
|
);
|
|
24003
24655
|
}
|
|
24004
|
-
function
|
|
24656
|
+
function summarise8(layout) {
|
|
24005
24657
|
const { ast, analysis } = layout;
|
|
24006
24658
|
const counts = { event: 0, function: 0, connector: 0 };
|
|
24007
24659
|
for (const n of ast.nodes) counts[n.kind]++;
|
|
@@ -24024,7 +24676,7 @@ function describeWellFormed(analysis) {
|
|
|
24024
24676
|
function clip4(s, n) {
|
|
24025
24677
|
return s.length <= n ? s : s.slice(0, n - 1) + "\u2026";
|
|
24026
24678
|
}
|
|
24027
|
-
function
|
|
24679
|
+
function wrap5(s, perLine) {
|
|
24028
24680
|
if (s.length <= perLine) return s;
|
|
24029
24681
|
const words = s.split(/\s+/);
|
|
24030
24682
|
const lines = [];
|
|
@@ -24614,7 +25266,7 @@ function renderIdef0Layout(layout, config) {
|
|
|
24614
25266
|
);
|
|
24615
25267
|
const children = [
|
|
24616
25268
|
title(a11y),
|
|
24617
|
-
desc(
|
|
25269
|
+
desc(summarise9(layout)),
|
|
24618
25270
|
styleBlock,
|
|
24619
25271
|
rect({ x: 0, y: 0, width, height, class: "sx-idef0-bg" })
|
|
24620
25272
|
];
|
|
@@ -24665,7 +25317,7 @@ function renderBox5(b) {
|
|
|
24665
25317
|
"text-anchor": "middle",
|
|
24666
25318
|
"dominant-baseline": "middle"
|
|
24667
25319
|
},
|
|
24668
|
-
|
|
25320
|
+
wrap6(b.box.name, 18),
|
|
24669
25321
|
14
|
|
24670
25322
|
),
|
|
24671
25323
|
// Box number in the lower-right interior corner.
|
|
@@ -24772,7 +25424,7 @@ function renderTitleBlock(width, height, node, title2) {
|
|
|
24772
25424
|
text({ x: c2 + 6, y: y + 13, class: "sx-idef0-tb-key" }, "NUMBER")
|
|
24773
25425
|
]);
|
|
24774
25426
|
}
|
|
24775
|
-
function
|
|
25427
|
+
function summarise9(layout) {
|
|
24776
25428
|
const { ast } = layout;
|
|
24777
25429
|
const counts = {};
|
|
24778
25430
|
for (const a of ast.arrows) counts[a.role] = (counts[a.role] ?? 0) + 1;
|
|
@@ -24790,7 +25442,7 @@ function summarise8(layout) {
|
|
|
24790
25442
|
function clip5(s, n) {
|
|
24791
25443
|
return s.length <= n ? s : s.slice(0, n - 1) + "\u2026";
|
|
24792
25444
|
}
|
|
24793
|
-
function
|
|
25445
|
+
function wrap6(s, perLine) {
|
|
24794
25446
|
if (s.length <= perLine) return s;
|
|
24795
25447
|
const words = s.split(/\s+/);
|
|
24796
25448
|
const lines = [];
|
|
@@ -24837,7 +25489,7 @@ for (const [open, close] of Object.entries(QUOTE_PAIRS)) {
|
|
|
24837
25489
|
QUOTE_FOLD.set(close, '"');
|
|
24838
25490
|
}
|
|
24839
25491
|
}
|
|
24840
|
-
function
|
|
25492
|
+
function normalizeQuotes3(text2) {
|
|
24841
25493
|
let out = "";
|
|
24842
25494
|
for (const ch of text2) out += QUOTE_FOLD.get(ch) ?? ch;
|
|
24843
25495
|
return out;
|
|
@@ -24868,7 +25520,7 @@ function parseThreatModel(text2) {
|
|
|
24868
25520
|
flows: [],
|
|
24869
25521
|
boundaries: []
|
|
24870
25522
|
};
|
|
24871
|
-
const rawLines =
|
|
25523
|
+
const rawLines = normalizeQuotes3(text2).split(/\r?\n/);
|
|
24872
25524
|
const byId = /* @__PURE__ */ new Map();
|
|
24873
25525
|
const declareNode = (id, kind, label, lineNo, logStore) => {
|
|
24874
25526
|
if (byId.has(id)) {
|
|
@@ -25327,13 +25979,13 @@ function layoutThreatModel(ast) {
|
|
|
25327
25979
|
}
|
|
25328
25980
|
const boundaries = [];
|
|
25329
25981
|
for (const b of ast.boundaries) {
|
|
25330
|
-
let l = Infinity, t = Infinity,
|
|
25982
|
+
let l = Infinity, t = Infinity, r7 = -Infinity, bm = -Infinity;
|
|
25331
25983
|
for (const m of b.members) {
|
|
25332
25984
|
const mn = nodeMap.get(m);
|
|
25333
25985
|
if (!mn) continue;
|
|
25334
25986
|
l = Math.min(l, mn.x);
|
|
25335
25987
|
t = Math.min(t, mn.y);
|
|
25336
|
-
|
|
25988
|
+
r7 = Math.max(r7, mn.x + mn.w);
|
|
25337
25989
|
bm = Math.max(bm, mn.y + mn.h);
|
|
25338
25990
|
}
|
|
25339
25991
|
if (!Number.isFinite(l)) continue;
|
|
@@ -25342,7 +25994,7 @@ function layoutThreatModel(ast) {
|
|
|
25342
25994
|
name: b.name,
|
|
25343
25995
|
x: l - p,
|
|
25344
25996
|
y: t - p - TM_CONST.BOUNDARY_HEADER,
|
|
25345
|
-
w:
|
|
25997
|
+
w: r7 - l + p * 2,
|
|
25346
25998
|
h: bm - t + p * 2 + TM_CONST.BOUNDARY_HEADER
|
|
25347
25999
|
});
|
|
25348
26000
|
}
|
|
@@ -25376,9 +26028,9 @@ function edgePoint2(n, tx, ty) {
|
|
|
25376
26028
|
const dy = ty - n.cy;
|
|
25377
26029
|
if (dx === 0 && dy === 0) return { x: n.cx, y: n.cy };
|
|
25378
26030
|
if (n.kind === "process") {
|
|
25379
|
-
const
|
|
26031
|
+
const r7 = TM_CONST.PROCESS_R;
|
|
25380
26032
|
const len = Math.hypot(dx, dy);
|
|
25381
|
-
return { x: n.cx + dx / len *
|
|
26033
|
+
return { x: n.cx + dx / len * r7, y: n.cy + dy / len * r7 };
|
|
25382
26034
|
}
|
|
25383
26035
|
const hw = n.w / 2;
|
|
25384
26036
|
const hh = n.h / 2;
|
|
@@ -25433,7 +26085,7 @@ function renderThreatModelLayout(layout, config) {
|
|
|
25433
26085
|
]);
|
|
25434
26086
|
const children = [
|
|
25435
26087
|
title(a11y),
|
|
25436
|
-
desc(
|
|
26088
|
+
desc(summarise10(layout)),
|
|
25437
26089
|
styleBlock,
|
|
25438
26090
|
markerDefs,
|
|
25439
26091
|
rect({ x: 0, y: 0, width, height, class: "sx-tm-bg" })
|
|
@@ -25650,7 +26302,7 @@ function arrowMarker2(id, cls, crossing) {
|
|
|
25650
26302
|
function round8(n) {
|
|
25651
26303
|
return Math.round(n * 100) / 100;
|
|
25652
26304
|
}
|
|
25653
|
-
function
|
|
26305
|
+
function summarise10(layout) {
|
|
25654
26306
|
const a = layout.analysis;
|
|
25655
26307
|
const counts = {
|
|
25656
26308
|
external: layout.nodes.filter((n) => n.kind === "external").length,
|
|
@@ -26028,9 +26680,9 @@ function weldGlyph(type, cx, y, dir, cls) {
|
|
|
26028
26680
|
return [path({ d: `M ${round9(cx - rr)} ${round9(y)} A ${round9(rr)} ${round9(rr)} 0 0 ${sweep} ${round9(cx + rr)} ${round9(y)}`, class: cls, fill: "none" })];
|
|
26029
26681
|
}
|
|
26030
26682
|
case "surfacing": {
|
|
26031
|
-
const
|
|
26683
|
+
const r7 = W / 4;
|
|
26032
26684
|
const yy = y + dir * 3;
|
|
26033
|
-
const bump = (off) => path({ d: `M ${round9(cx - W / 2)} ${round9(off)} a ${round9(
|
|
26685
|
+
const bump = (off) => path({ d: `M ${round9(cx - W / 2)} ${round9(off)} a ${round9(r7)} ${round9(r7)} 0 0 ${dir > 0 ? 1 : 0} ${round9(W / 2)} 0 a ${round9(r7)} ${round9(r7)} 0 0 ${dir > 0 ? 1 : 0} ${round9(W / 2)} 0`, class: cls, fill: "none" });
|
|
26034
26686
|
return [bump(y), bump(yy)];
|
|
26035
26687
|
}
|
|
26036
26688
|
case "edge":
|
|
@@ -26902,7 +27554,7 @@ function computeMaxLW(subtreeRoots, maxLabelWidth) {
|
|
|
26902
27554
|
if (maxLW[n.depth] === void 0 || m.width > maxLW[n.depth]) maxLW[n.depth] = m.width;
|
|
26903
27555
|
for (const c of n.children) walk(c);
|
|
26904
27556
|
};
|
|
26905
|
-
for (const
|
|
27557
|
+
for (const r7 of subtreeRoots) walk(r7);
|
|
26906
27558
|
return maxLW;
|
|
26907
27559
|
}
|
|
26908
27560
|
function buildColumns(maxLW, firstColStartX, rootDepth) {
|
|
@@ -27269,9 +27921,9 @@ function renderNode5(n, color, theme, fontFamily, orderClass) {
|
|
|
27269
27921
|
for (let i = 0; i < lineCount; i++) {
|
|
27270
27922
|
const line2 = n.lines[i];
|
|
27271
27923
|
const cy = topY + (i + 0.5) * lh;
|
|
27272
|
-
const
|
|
27273
|
-
decorations.push(...
|
|
27274
|
-
children.push(
|
|
27924
|
+
const r7 = renderLine2(line2, textLeft, cy, fs, fontFamily, weight, theme);
|
|
27925
|
+
decorations.push(...r7.decorations);
|
|
27926
|
+
children.push(r7.textElement);
|
|
27275
27927
|
}
|
|
27276
27928
|
const ux1 = n.x - n.labelWidth / 2;
|
|
27277
27929
|
const ux2 = n.x + n.labelWidth / 2;
|
|
@@ -27995,11 +28647,11 @@ function parseMatrix(text2) {
|
|
|
27995
28647
|
const gm = v.match(/^(\d+)\s*x\s*(\d+)$/);
|
|
27996
28648
|
if (gm) {
|
|
27997
28649
|
const c = Number(gm[1]);
|
|
27998
|
-
const
|
|
28650
|
+
const r7 = Number(gm[2]);
|
|
27999
28651
|
st.ast.cols = c;
|
|
28000
|
-
st.ast.rows =
|
|
28001
|
-
if (c === 2 &&
|
|
28002
|
-
else if (c === 3 &&
|
|
28652
|
+
st.ast.rows = r7;
|
|
28653
|
+
if (c === 2 && r7 === 2) st.ast.grid = "2x2";
|
|
28654
|
+
else if (c === 3 && r7 === 3) st.ast.grid = "3x3";
|
|
28003
28655
|
else st.ast.grid = "NxM";
|
|
28004
28656
|
}
|
|
28005
28657
|
continue;
|
|
@@ -28212,11 +28864,11 @@ function punnettFooter(result) {
|
|
|
28212
28864
|
}
|
|
28213
28865
|
function computeQfdImportance(qfd) {
|
|
28214
28866
|
const raw = qfd.hows.map(() => 0);
|
|
28215
|
-
for (const
|
|
28216
|
-
if (
|
|
28217
|
-
if (
|
|
28218
|
-
const w = qfd.whats[
|
|
28219
|
-
raw[
|
|
28867
|
+
for (const r7 of qfd.relationships) {
|
|
28868
|
+
if (r7.how < 0 || r7.how >= qfd.hows.length) continue;
|
|
28869
|
+
if (r7.what < 0 || r7.what >= qfd.whats.length) continue;
|
|
28870
|
+
const w = qfd.whats[r7.what].weight;
|
|
28871
|
+
raw[r7.how] += w * r7.strength;
|
|
28220
28872
|
}
|
|
28221
28873
|
const total = raw.reduce((acc, v) => acc + v, 0);
|
|
28222
28874
|
return raw.map((importance, how) => ({
|
|
@@ -28237,12 +28889,12 @@ function estimateWidth(text2) {
|
|
|
28237
28889
|
const cjk = (text2.match(/[\u3000-\u9fff]/g) ?? []).length;
|
|
28238
28890
|
return (text2.length - cjk) * CHAR_W2 + cjk * 12 + 8;
|
|
28239
28891
|
}
|
|
28240
|
-
function
|
|
28892
|
+
function clamp012(v) {
|
|
28241
28893
|
return Math.max(0.02, Math.min(0.98, v));
|
|
28242
28894
|
}
|
|
28243
28895
|
function placePoint(p, plot) {
|
|
28244
|
-
const nx =
|
|
28245
|
-
const ny =
|
|
28896
|
+
const nx = clamp012(p.x);
|
|
28897
|
+
const ny = clamp012(p.y);
|
|
28246
28898
|
const px = plot.x0 + nx * plot.w;
|
|
28247
28899
|
const py = plot.y0 + (1 - ny) * plot.h;
|
|
28248
28900
|
return { px, py };
|
|
@@ -28258,8 +28910,8 @@ function computeRadius(p, maxSize, plot, scale) {
|
|
|
28258
28910
|
}
|
|
28259
28911
|
const maxArea = Math.PI * maxRadius * maxRadius;
|
|
28260
28912
|
const area = ratio * maxArea;
|
|
28261
|
-
const
|
|
28262
|
-
return Math.max(minRadius,
|
|
28913
|
+
const r7 = Math.sqrt(area / Math.PI);
|
|
28914
|
+
return Math.max(minRadius, r7);
|
|
28263
28915
|
}
|
|
28264
28916
|
function resolveLabelCollisions(points, plot, mode) {
|
|
28265
28917
|
if (mode === "off") {
|
|
@@ -28460,20 +29112,20 @@ function layoutMatrix(ast) {
|
|
|
28460
29112
|
}
|
|
28461
29113
|
for (const p of ast.points) {
|
|
28462
29114
|
const { px, py } = placePoint(p, plot);
|
|
28463
|
-
const
|
|
29115
|
+
const r7 = computeRadius(p, maxSize, plot, ast.config.bubbleScale);
|
|
28464
29116
|
const width = estimateWidth(p.label);
|
|
28465
29117
|
const label = {
|
|
28466
29118
|
text: p.label,
|
|
28467
29119
|
ax: px,
|
|
28468
29120
|
ay: py,
|
|
28469
|
-
lx: px +
|
|
28470
|
-
ly: py -
|
|
29121
|
+
lx: px + r7 + 4 + width / 2,
|
|
29122
|
+
ly: py - r7 - 4,
|
|
28471
29123
|
width,
|
|
28472
29124
|
height: LABEL_H,
|
|
28473
29125
|
external: false,
|
|
28474
29126
|
textAnchor: "middle"
|
|
28475
29127
|
};
|
|
28476
|
-
points.push({ point: p, px, py, r:
|
|
29128
|
+
points.push({ point: p, px, py, r: r7, label });
|
|
28477
29129
|
if (p.category) categoriesSet.add(p.category);
|
|
28478
29130
|
}
|
|
28479
29131
|
resolveLabelCollisions(points, plot, ast.config.labelCollision);
|
|
@@ -28623,7 +29275,7 @@ function renderQuadrantBackground(ast, lay) {
|
|
|
28623
29275
|
return group(
|
|
28624
29276
|
{ id: "sx-matrix-quad-bg" },
|
|
28625
29277
|
rects.map(
|
|
28626
|
-
(
|
|
29278
|
+
(r7) => rect({ x: r7.x, y: r7.y, width: r7.w, height: r7.h, fill: r7.fill, "fill-opacity": 0.55 })
|
|
28627
29279
|
)
|
|
28628
29280
|
);
|
|
28629
29281
|
}
|
|
@@ -29275,9 +29927,9 @@ function renderOnePoint(pl2, categories) {
|
|
|
29275
29927
|
class: "sx-matrix-bubble"
|
|
29276
29928
|
});
|
|
29277
29929
|
} else if (shape === "diamond") {
|
|
29278
|
-
const
|
|
29930
|
+
const r7 = pl2.r;
|
|
29279
29931
|
shapeEl = polygon({
|
|
29280
|
-
points: `${pl2.px},${pl2.py -
|
|
29932
|
+
points: `${pl2.px},${pl2.py - r7} ${pl2.px + r7},${pl2.py} ${pl2.px},${pl2.py + r7} ${pl2.px - r7},${pl2.py}`,
|
|
29281
29933
|
fill: color,
|
|
29282
29934
|
"fill-opacity": fillOpacity,
|
|
29283
29935
|
stroke,
|
|
@@ -29285,9 +29937,9 @@ function renderOnePoint(pl2, categories) {
|
|
|
29285
29937
|
class: "sx-matrix-bubble"
|
|
29286
29938
|
});
|
|
29287
29939
|
} else {
|
|
29288
|
-
const
|
|
29940
|
+
const r7 = pl2.r;
|
|
29289
29941
|
shapeEl = polygon({
|
|
29290
|
-
points: `${pl2.px},${pl2.py -
|
|
29942
|
+
points: `${pl2.px},${pl2.py - r7} ${pl2.px + r7},${pl2.py + r7 * 0.8} ${pl2.px - r7},${pl2.py + r7 * 0.8}`,
|
|
29291
29943
|
fill: color,
|
|
29292
29944
|
"fill-opacity": fillOpacity,
|
|
29293
29945
|
stroke,
|
|
@@ -29419,15 +30071,15 @@ function renderSipocAST(ast, config) {
|
|
|
29419
30071
|
const items = sipoc[def.key];
|
|
29420
30072
|
const isProcess = def.key === "process";
|
|
29421
30073
|
const cellNodes = [];
|
|
29422
|
-
for (let
|
|
29423
|
-
const cellY = lay.y0 + lay.headerH +
|
|
29424
|
-
const item = items[
|
|
29425
|
-
const cellClass = isProcess ? "sx-sipoc-process" :
|
|
30074
|
+
for (let r7 = 0; r7 < lay.rows; r7++) {
|
|
30075
|
+
const cellY = lay.y0 + lay.headerH + r7 * lay.rowH;
|
|
30076
|
+
const item = items[r7];
|
|
30077
|
+
const cellClass = isProcess ? "sx-sipoc-process" : r7 % 2 === 0 ? "sx-sipoc-cell" : "sx-sipoc-cell-alt";
|
|
29426
30078
|
cellNodes.push(
|
|
29427
30079
|
rect({ x: colX, y: cellY, width: lay.colW, height: lay.rowH, class: cellClass })
|
|
29428
30080
|
);
|
|
29429
30081
|
if (item) {
|
|
29430
|
-
const label = isProcess ? `${
|
|
30082
|
+
const label = isProcess ? `${r7 + 1}. ${item}` : item;
|
|
29431
30083
|
const lines = wrapToLines(label, maxChars, 2);
|
|
29432
30084
|
const lineH = 14;
|
|
29433
30085
|
const startY = cellY + lay.rowH / 2 - (lines.length - 1) * lineH / 2;
|
|
@@ -29490,17 +30142,17 @@ var CORR_LABEL = {
|
|
|
29490
30142
|
"-": "negative",
|
|
29491
30143
|
"--": "strong negative"
|
|
29492
30144
|
};
|
|
29493
|
-
function renderQfdRelationshipSymbol(strength, cx, cy,
|
|
30145
|
+
function renderQfdRelationshipSymbol(strength, cx, cy, r7) {
|
|
29494
30146
|
if (strength === 9) {
|
|
29495
30147
|
return group({}, [
|
|
29496
|
-
circle({ cx, cy, r:
|
|
29497
|
-
circle({ cx, cy, r:
|
|
30148
|
+
circle({ cx, cy, r: r7, fill: "none", stroke: "#2563eb", "stroke-width": 1.4 }),
|
|
30149
|
+
circle({ cx, cy, r: r7 * 0.5, class: "sx-qfd-rel-strong" })
|
|
29498
30150
|
]);
|
|
29499
30151
|
}
|
|
29500
30152
|
if (strength === 3) {
|
|
29501
|
-
return circle({ cx, cy, r:
|
|
30153
|
+
return circle({ cx, cy, r: r7, class: "sx-qfd-rel-medium" });
|
|
29502
30154
|
}
|
|
29503
|
-
const t =
|
|
30155
|
+
const t = r7 * 0.95;
|
|
29504
30156
|
return polygon({
|
|
29505
30157
|
points: `${cx},${cy - t} ${cx + t},${cy + t * 0.85} ${cx - t},${cy + t * 0.85}`,
|
|
29506
30158
|
class: "sx-qfd-rel-weak"
|
|
@@ -29598,15 +30250,15 @@ function renderQfdAST(ast, config) {
|
|
|
29598
30250
|
)
|
|
29599
30251
|
);
|
|
29600
30252
|
const gridNodes = [];
|
|
29601
|
-
for (let
|
|
29602
|
-
const y = lay.gridY0 +
|
|
30253
|
+
for (let r7 = 0; r7 < lay.rows; r7++) {
|
|
30254
|
+
const y = lay.gridY0 + r7 * lay.cellH;
|
|
29603
30255
|
gridNodes.push(
|
|
29604
30256
|
rect({
|
|
29605
30257
|
x: lay.gridX0,
|
|
29606
30258
|
y,
|
|
29607
30259
|
width: lay.cols * lay.cellW,
|
|
29608
30260
|
height: lay.cellH,
|
|
29609
|
-
class:
|
|
30261
|
+
class: r7 % 2 === 0 ? "sx-qfd-cellbg" : "sx-qfd-cellbg-alt"
|
|
29610
30262
|
})
|
|
29611
30263
|
);
|
|
29612
30264
|
}
|
|
@@ -29784,18 +30436,18 @@ function renderPunnettAST(ast, config) {
|
|
|
29784
30436
|
nodes.push(rect({ x: cx, y: lay.y0, width: lay.cellW, height: lay.headerH, class: "sx-punnett-header" }));
|
|
29785
30437
|
nodes.push(text({ x: cx + lay.cellW / 2, y: lay.y0 + lay.headerH / 2, class: "sx-punnett-gamete" }, g));
|
|
29786
30438
|
});
|
|
29787
|
-
result.gametes2.forEach((g,
|
|
29788
|
-
const cy = gy0 +
|
|
30439
|
+
result.gametes2.forEach((g, r7) => {
|
|
30440
|
+
const cy = gy0 + r7 * lay.cellH;
|
|
29789
30441
|
nodes.push(rect({ x: lay.x0, y: cy, width: lay.headerW, height: lay.cellH, class: "sx-punnett-header" }));
|
|
29790
30442
|
nodes.push(text({ x: lay.x0 + lay.headerW / 2, y: cy + lay.cellH / 2, class: "sx-punnett-gamete" }, g));
|
|
29791
30443
|
});
|
|
29792
|
-
for (let
|
|
29793
|
-
const row = result.grid[
|
|
30444
|
+
for (let r7 = 0; r7 < result.grid.length; r7++) {
|
|
30445
|
+
const row = result.grid[r7];
|
|
29794
30446
|
for (let c = 0; c < row.length; c++) {
|
|
29795
30447
|
const cell = row[c];
|
|
29796
30448
|
const color = phenoColor.get(cell.phenotypeKey);
|
|
29797
30449
|
const cx = gx0 + c * lay.cellW;
|
|
29798
|
-
const cy = gy0 +
|
|
30450
|
+
const cy = gy0 + r7 * lay.cellH;
|
|
29799
30451
|
nodes.push(rect({ x: cx, y: cy, width: lay.cellW, height: lay.cellH, fill: color.tint, class: "sx-punnett-cell" }));
|
|
29800
30452
|
nodes.push(text({ x: cx + lay.cellW / 2, y: cy + lay.cellH / 2, class: "sx-punnett-genotype" }, cell.genotype));
|
|
29801
30453
|
}
|
|
@@ -30348,12 +31000,12 @@ function buildColumnAssignment(ast) {
|
|
|
30348
31000
|
const ids = ast.entities.map((e) => e.id);
|
|
30349
31001
|
const idToIdx = new Map(ids.map((id, i) => [id, i]));
|
|
30350
31002
|
const pairs = [];
|
|
30351
|
-
for (const
|
|
30352
|
-
const f = parseRefSide(
|
|
30353
|
-
const t = parseRefSide(
|
|
31003
|
+
for (const r7 of ast.refs) {
|
|
31004
|
+
const f = parseRefSide(r7.from);
|
|
31005
|
+
const t = parseRefSide(r7.to);
|
|
30354
31006
|
if (idToIdx.has(f.table) && idToIdx.has(t.table)) {
|
|
30355
|
-
const oneIsTo = isOne(
|
|
30356
|
-
const oneIsFrom = isOne(
|
|
31007
|
+
const oneIsTo = isOne(r7.toCard) && !isOne(r7.fromCard);
|
|
31008
|
+
const oneIsFrom = isOne(r7.fromCard) && !isOne(r7.toCard);
|
|
30357
31009
|
if (oneIsTo) pairs.push({ from: t.table, to: f.table });
|
|
30358
31010
|
else if (oneIsFrom) pairs.push({ from: f.table, to: t.table });
|
|
30359
31011
|
else pairs.push({ from: f.table, to: t.table });
|
|
@@ -30388,9 +31040,9 @@ function isOne(c) {
|
|
|
30388
31040
|
function reorderByBarycenter(layerToEnts, layers, refs) {
|
|
30389
31041
|
if (layers.length < 2) return;
|
|
30390
31042
|
const neighbors = /* @__PURE__ */ new Map();
|
|
30391
|
-
for (const
|
|
30392
|
-
const a = parseRefSide(
|
|
30393
|
-
const b = parseRefSide(
|
|
31043
|
+
for (const r7 of refs) {
|
|
31044
|
+
const a = parseRefSide(r7.from).table;
|
|
31045
|
+
const b = parseRefSide(r7.to).table;
|
|
30394
31046
|
if (!neighbors.has(a)) neighbors.set(a, /* @__PURE__ */ new Set());
|
|
30395
31047
|
if (!neighbors.has(b)) neighbors.set(b, /* @__PURE__ */ new Set());
|
|
30396
31048
|
neighbors.get(a).add(b);
|
|
@@ -30520,9 +31172,9 @@ function layoutErd(ast) {
|
|
|
30520
31172
|
const layers = Array.from(layerToEnts.keys()).sort((a, b) => a - b);
|
|
30521
31173
|
reorderByBarycenter(layerToEnts, layers, ast.refs);
|
|
30522
31174
|
const neighbors = /* @__PURE__ */ new Map();
|
|
30523
|
-
for (const
|
|
30524
|
-
const a = parseRefSide(
|
|
30525
|
-
const b = parseRefSide(
|
|
31175
|
+
for (const r7 of ast.refs) {
|
|
31176
|
+
const a = parseRefSide(r7.from).table;
|
|
31177
|
+
const b = parseRefSide(r7.to).table;
|
|
30526
31178
|
if (!neighbors.has(a)) neighbors.set(a, /* @__PURE__ */ new Set());
|
|
30527
31179
|
if (!neighbors.has(b)) neighbors.set(b, /* @__PURE__ */ new Set());
|
|
30528
31180
|
neighbors.get(a).add(b);
|
|
@@ -30600,17 +31252,17 @@ function layoutErd(ast) {
|
|
|
30600
31252
|
const placedById = new Map(placed.map((p) => [p.entity.id, p]));
|
|
30601
31253
|
const edges = [];
|
|
30602
31254
|
const bendBucketUses = /* @__PURE__ */ new Map();
|
|
30603
|
-
for (const
|
|
30604
|
-
const fromTable = parseRefSide(
|
|
30605
|
-
const toTable = parseRefSide(
|
|
31255
|
+
for (const r7 of ast.refs) {
|
|
31256
|
+
const fromTable = parseRefSide(r7.from).table;
|
|
31257
|
+
const toTable = parseRefSide(r7.to).table;
|
|
30606
31258
|
const a = placedById.get(fromTable);
|
|
30607
31259
|
const b = placedById.get(toTable);
|
|
30608
31260
|
if (!a || !b) continue;
|
|
30609
|
-
const fromCol = parseRefSide(
|
|
30610
|
-
const toCol = parseRefSide(
|
|
31261
|
+
const fromCol = parseRefSide(r7.from).column;
|
|
31262
|
+
const toCol = parseRefSide(r7.to).column;
|
|
30611
31263
|
const route = routeOrthogonal(a, b, fromCol, toCol, bendBucketUses);
|
|
30612
31264
|
edges.push({
|
|
30613
|
-
ref:
|
|
31265
|
+
ref: r7,
|
|
30614
31266
|
path: route.path,
|
|
30615
31267
|
fromAnchor: route.fromAnchor,
|
|
30616
31268
|
toAnchor: route.toAnchor,
|
|
@@ -30627,7 +31279,7 @@ function layoutErd(ast) {
|
|
|
30627
31279
|
}
|
|
30628
31280
|
function rowYByColumn(e, col) {
|
|
30629
31281
|
if (col) {
|
|
30630
|
-
const idx = e.rows.findIndex((
|
|
31282
|
+
const idx = e.rows.findIndex((r7) => r7.attribute.name.toLowerCase() === col.toLowerCase());
|
|
30631
31283
|
if (idx >= 0) return e.y + e.rows[idx].yCenter;
|
|
30632
31284
|
}
|
|
30633
31285
|
return e.y + e.height / 2;
|
|
@@ -31407,8 +32059,8 @@ var PITCH = 14;
|
|
|
31407
32059
|
function rectShape(x, y, w, h, attrs) {
|
|
31408
32060
|
return el("rect", { x, y, width: w, height: h, ...attrs });
|
|
31409
32061
|
}
|
|
31410
|
-
function circShape(cx, cy,
|
|
31411
|
-
return el("circle", { cx, cy, r:
|
|
32062
|
+
function circShape(cx, cy, r7, attrs) {
|
|
32063
|
+
return el("circle", { cx, cy, r: r7, ...attrs });
|
|
31412
32064
|
}
|
|
31413
32065
|
function lineShape(x1, y1, x2, y2, attrs) {
|
|
31414
32066
|
return el("line", { x1, y1, x2, y2, ...attrs });
|
|
@@ -32129,13 +32781,13 @@ function renderSubstrate(sub) {
|
|
|
32129
32781
|
{ y: sub.y + BB_CONST.BOARD_PAD_Y, type: "top" },
|
|
32130
32782
|
{ y: sub.y + sub.height - BB_CONST.BOARD_PAD_Y - BB_CONST.RAIL_HEIGHT, type: "bottom" }
|
|
32131
32783
|
];
|
|
32132
|
-
for (const
|
|
32784
|
+
for (const r7 of rails) {
|
|
32133
32785
|
elements.push(path({
|
|
32134
|
-
d: `M ${sub.x + BB_CONST.BOARD_PAD_X} ${
|
|
32786
|
+
d: `M ${sub.x + BB_CONST.BOARD_PAD_X} ${r7.y + 4} L ${sub.x + sub.width - BB_CONST.BOARD_PAD_X} ${r7.y + 4}`,
|
|
32135
32787
|
class: "lt-bb-rail-stripe-pos"
|
|
32136
32788
|
}));
|
|
32137
32789
|
elements.push(path({
|
|
32138
|
-
d: `M ${sub.x + BB_CONST.BOARD_PAD_X} ${
|
|
32790
|
+
d: `M ${sub.x + BB_CONST.BOARD_PAD_X} ${r7.y + BB_CONST.RAIL_HEIGHT - 4} L ${sub.x + sub.width - BB_CONST.BOARD_PAD_X} ${r7.y + BB_CONST.RAIL_HEIGHT - 4}`,
|
|
32139
32791
|
class: "lt-bb-rail-stripe-neg"
|
|
32140
32792
|
}));
|
|
32141
32793
|
if (sub.railsBreak) {
|
|
@@ -32143,7 +32795,7 @@ function renderSubstrate(sub) {
|
|
|
32143
32795
|
const breakX2 = breakX1 + PITCH2;
|
|
32144
32796
|
elements.push(rect({
|
|
32145
32797
|
x: breakX1,
|
|
32146
|
-
y:
|
|
32798
|
+
y: r7.y,
|
|
32147
32799
|
width: breakX2 - breakX1,
|
|
32148
32800
|
height: BB_CONST.RAIL_HEIGHT,
|
|
32149
32801
|
fill: "#e7d8b6"
|
|
@@ -32151,8 +32803,8 @@ function renderSubstrate(sub) {
|
|
|
32151
32803
|
}
|
|
32152
32804
|
for (let c = 1; c <= sub.cols; c++) {
|
|
32153
32805
|
const cx = sub.x + BB_CONST.BOARD_PAD_X + BB_CONST.ROW_LABEL_W + PITCH2 / 2 + (c - 1) * PITCH2;
|
|
32154
|
-
elements.push(circle({ cx, cy:
|
|
32155
|
-
elements.push(circle({ cx, cy:
|
|
32806
|
+
elements.push(circle({ cx, cy: r7.y + 4, r: 1.4, class: "lt-bb-hole-rail" }));
|
|
32807
|
+
elements.push(circle({ cx, cy: r7.y + BB_CONST.RAIL_HEIGHT - 4, r: 1.4, class: "lt-bb-hole-rail" }));
|
|
32156
32808
|
}
|
|
32157
32809
|
}
|
|
32158
32810
|
}
|
|
@@ -32179,10 +32831,10 @@ function renderSubstrate(sub) {
|
|
|
32179
32831
|
elements.push(text({ x: sub.x + sub.width - BB_CONST.BOARD_PAD_X - 4, y: yBot, class: "lt-bb-row-label" }, rowsBot[i]));
|
|
32180
32832
|
}
|
|
32181
32833
|
for (let c = 1; c <= sub.cols; c++) {
|
|
32182
|
-
for (let
|
|
32834
|
+
for (let r7 = 0; r7 < 10; r7++) {
|
|
32183
32835
|
const cx = sub.x + BB_CONST.BOARD_PAD_X + BB_CONST.ROW_LABEL_W + PITCH2 / 2 + (c - 1) * PITCH2;
|
|
32184
|
-
let cy = gridY0 +
|
|
32185
|
-
if (
|
|
32836
|
+
let cy = gridY0 + r7 * PITCH2;
|
|
32837
|
+
if (r7 >= 5) cy += BB_CONST.TROUGH;
|
|
32186
32838
|
elements.push(circle({ cx, cy, r: 1.6, class: "lt-bb-hole" }));
|
|
32187
32839
|
}
|
|
32188
32840
|
}
|
|
@@ -32684,34 +33336,34 @@ function parseFlowLine(ln, flows, objectOwner, poolByLabel) {
|
|
|
32684
33336
|
connectorLen = 3;
|
|
32685
33337
|
} else if (rest.startsWith("--?")) {
|
|
32686
33338
|
kind = "conditional";
|
|
32687
|
-
let
|
|
32688
|
-
const q = takeQuoted(
|
|
33339
|
+
let r7 = rest.slice(3).trimStart();
|
|
33340
|
+
const q = takeQuoted(r7);
|
|
32689
33341
|
if (q) {
|
|
32690
33342
|
connectorLabel = q.value;
|
|
32691
|
-
|
|
33343
|
+
r7 = q.rest.trimStart();
|
|
32692
33344
|
}
|
|
32693
|
-
if (!
|
|
33345
|
+
if (!r7.startsWith("-->")) {
|
|
32694
33346
|
throw new BpmnParseError(
|
|
32695
|
-
`conditional flow must end with --> (got '${
|
|
33347
|
+
`conditional flow must end with --> (got '${r7.slice(0, 20)}')`,
|
|
32696
33348
|
ln.no
|
|
32697
33349
|
);
|
|
32698
33350
|
}
|
|
32699
|
-
connectorLen = rest.length -
|
|
33351
|
+
connectorLen = rest.length - r7.length + 3;
|
|
32700
33352
|
} else if (rest.startsWith("--*")) {
|
|
32701
33353
|
kind = "default";
|
|
32702
|
-
let
|
|
32703
|
-
const q = takeQuoted(
|
|
33354
|
+
let r7 = rest.slice(3).trimStart();
|
|
33355
|
+
const q = takeQuoted(r7);
|
|
32704
33356
|
if (q) {
|
|
32705
33357
|
connectorLabel = q.value;
|
|
32706
|
-
|
|
33358
|
+
r7 = q.rest.trimStart();
|
|
32707
33359
|
}
|
|
32708
|
-
if (!
|
|
33360
|
+
if (!r7.startsWith("-->")) {
|
|
32709
33361
|
throw new BpmnParseError(
|
|
32710
|
-
`default flow must end with --> (got '${
|
|
33362
|
+
`default flow must end with --> (got '${r7.slice(0, 20)}')`,
|
|
32711
33363
|
ln.no
|
|
32712
33364
|
);
|
|
32713
33365
|
}
|
|
32714
|
-
connectorLen = rest.length -
|
|
33366
|
+
connectorLen = rest.length - r7.length + 3;
|
|
32715
33367
|
} else if (rest.startsWith("-->")) {
|
|
32716
33368
|
kind = "sequence";
|
|
32717
33369
|
connectorLen = 3;
|
|
@@ -32804,8 +33456,8 @@ function objBox(o) {
|
|
|
32804
33456
|
if ("gatewayKind" in o) {
|
|
32805
33457
|
return { w: BPMN_CONST.gatewaySize, h: BPMN_CONST.gatewaySize };
|
|
32806
33458
|
}
|
|
32807
|
-
const
|
|
32808
|
-
return { w:
|
|
33459
|
+
const r7 = BPMN_CONST.eventRadius;
|
|
33460
|
+
return { w: r7 * 2, h: r7 * 2 };
|
|
32809
33461
|
}
|
|
32810
33462
|
function layoutBpmn(ast) {
|
|
32811
33463
|
const allObjects = [
|
|
@@ -33416,11 +34068,11 @@ function renderGateway(ol, t) {
|
|
|
33416
34068
|
const g = ol.obj;
|
|
33417
34069
|
const cx = ol.x + ol.width / 2;
|
|
33418
34070
|
const cy = ol.y + ol.height / 2;
|
|
33419
|
-
const
|
|
33420
|
-
const points = `${cx},${cy -
|
|
34071
|
+
const r7 = ol.width / 2;
|
|
34072
|
+
const points = `${cx},${cy - r7} ${cx + r7},${cy} ${cx},${cy + r7} ${cx - r7},${cy}`;
|
|
33421
34073
|
const inner = [];
|
|
33422
34074
|
if (g.gatewayKind === "xor") {
|
|
33423
|
-
const a =
|
|
34075
|
+
const a = r7 * 0.42;
|
|
33424
34076
|
inner.push(
|
|
33425
34077
|
el("path", {
|
|
33426
34078
|
d: `M ${cx - a} ${cy - a} L ${cx + a} ${cy + a} M ${cx + a} ${cy - a} L ${cx - a} ${cy + a}`,
|
|
@@ -33430,7 +34082,7 @@ function renderGateway(ol, t) {
|
|
|
33430
34082
|
})
|
|
33431
34083
|
);
|
|
33432
34084
|
} else if (g.gatewayKind === "and") {
|
|
33433
|
-
const a =
|
|
34085
|
+
const a = r7 * 0.5;
|
|
33434
34086
|
inner.push(
|
|
33435
34087
|
el("path", {
|
|
33436
34088
|
d: `M ${cx - a} ${cy} L ${cx + a} ${cy} M ${cx} ${cy - a} L ${cx} ${cy + a}`,
|
|
@@ -33444,7 +34096,7 @@ function renderGateway(ol, t) {
|
|
|
33444
34096
|
el("circle", {
|
|
33445
34097
|
cx,
|
|
33446
34098
|
cy,
|
|
33447
|
-
r:
|
|
34099
|
+
r: r7 * 0.45,
|
|
33448
34100
|
fill: "none",
|
|
33449
34101
|
stroke: t.gatewayGlyph,
|
|
33450
34102
|
"stroke-width": 2
|
|
@@ -33455,13 +34107,13 @@ function renderGateway(ol, t) {
|
|
|
33455
34107
|
el("circle", {
|
|
33456
34108
|
cx,
|
|
33457
34109
|
cy,
|
|
33458
|
-
r:
|
|
34110
|
+
r: r7 * 0.55,
|
|
33459
34111
|
fill: "none",
|
|
33460
34112
|
stroke: t.gatewayGlyph,
|
|
33461
34113
|
"stroke-width": 1
|
|
33462
34114
|
})
|
|
33463
34115
|
);
|
|
33464
|
-
const pr =
|
|
34116
|
+
const pr = r7 * 0.32;
|
|
33465
34117
|
const pts = [];
|
|
33466
34118
|
for (let k = 0; k < 5; k++) {
|
|
33467
34119
|
const ang = -Math.PI / 2 + k * 2 * Math.PI / 5;
|
|
@@ -33503,7 +34155,7 @@ function renderEvent2(ol, t) {
|
|
|
33503
34155
|
const e = ol.obj;
|
|
33504
34156
|
const cx = ol.x + ol.width / 2;
|
|
33505
34157
|
const cy = ol.y + ol.height / 2;
|
|
33506
|
-
const
|
|
34158
|
+
const r7 = ol.width / 2;
|
|
33507
34159
|
const isEnd = e.kind === "end";
|
|
33508
34160
|
const isIntermediate = e.kind === "intermediate";
|
|
33509
34161
|
const strokeW = isEnd ? 3 : 1.2;
|
|
@@ -33514,7 +34166,7 @@ function renderEvent2(ol, t) {
|
|
|
33514
34166
|
el("circle", {
|
|
33515
34167
|
cx,
|
|
33516
34168
|
cy,
|
|
33517
|
-
r:
|
|
34169
|
+
r: r7,
|
|
33518
34170
|
fill,
|
|
33519
34171
|
stroke: ring,
|
|
33520
34172
|
"stroke-width": strokeW
|
|
@@ -33525,7 +34177,7 @@ function renderEvent2(ol, t) {
|
|
|
33525
34177
|
el("circle", {
|
|
33526
34178
|
cx,
|
|
33527
34179
|
cy,
|
|
33528
|
-
r:
|
|
34180
|
+
r: r7 - 3,
|
|
33529
34181
|
fill: "none",
|
|
33530
34182
|
stroke: ring,
|
|
33531
34183
|
"stroke-width": 1.2
|
|
@@ -33534,9 +34186,9 @@ function renderEvent2(ol, t) {
|
|
|
33534
34186
|
}
|
|
33535
34187
|
const filled = e.throwCatch === "throw" && (isIntermediate || isEnd);
|
|
33536
34188
|
if (e.trigger === "message") {
|
|
33537
|
-
children.push(messageGlyph(cx, cy,
|
|
34189
|
+
children.push(messageGlyph(cx, cy, r7 * 0.55, filled, t));
|
|
33538
34190
|
} else if (e.trigger === "timer") {
|
|
33539
|
-
children.push(timerGlyph(cx, cy,
|
|
34191
|
+
children.push(timerGlyph(cx, cy, r7 * 0.55, t));
|
|
33540
34192
|
}
|
|
33541
34193
|
if (e.label) {
|
|
33542
34194
|
children.push(
|
|
@@ -33579,22 +34231,22 @@ function messageGlyph(cx, cy, size, filled, t) {
|
|
|
33579
34231
|
]);
|
|
33580
34232
|
}
|
|
33581
34233
|
function timerGlyph(cx, cy, size, t) {
|
|
33582
|
-
const
|
|
34234
|
+
const r7 = size / 2;
|
|
33583
34235
|
const ticks = [];
|
|
33584
34236
|
for (let k = 0; k < 12; k++) {
|
|
33585
34237
|
const ang = k * Math.PI / 6 - Math.PI / 2;
|
|
33586
|
-
const t1x = cx + (
|
|
33587
|
-
const t1y = cy + (
|
|
33588
|
-
const t2x = cx +
|
|
33589
|
-
const t2y = cy +
|
|
34238
|
+
const t1x = cx + (r7 - 1.5) * Math.cos(ang);
|
|
34239
|
+
const t1y = cy + (r7 - 1.5) * Math.sin(ang);
|
|
34240
|
+
const t2x = cx + r7 * Math.cos(ang);
|
|
34241
|
+
const t2y = cy + r7 * Math.sin(ang);
|
|
33590
34242
|
ticks.push(`M ${t1x} ${t1y} L ${t2x} ${t2y}`);
|
|
33591
34243
|
}
|
|
33592
34244
|
return el("g", { class: "trigger-timer" }, [
|
|
33593
|
-
el("circle", { cx, cy, r:
|
|
34245
|
+
el("circle", { cx, cy, r: r7, fill: "none", stroke: t.bpmnStroke, "stroke-width": 1 }),
|
|
33594
34246
|
el("path", { d: ticks.join(" "), stroke: t.bpmnStroke, "stroke-width": 0.8 }),
|
|
33595
34247
|
// Hands
|
|
33596
34248
|
el("path", {
|
|
33597
|
-
d: `M ${cx} ${cy} L ${cx} ${cy -
|
|
34249
|
+
d: `M ${cx} ${cy} L ${cx} ${cy - r7 * 0.7} M ${cx} ${cy} L ${cx + r7 * 0.5} ${cy}`,
|
|
33598
34250
|
stroke: t.bpmnStroke,
|
|
33599
34251
|
"stroke-width": 1.2,
|
|
33600
34252
|
"stroke-linecap": "round"
|
|
@@ -33665,8 +34317,8 @@ function parseStart(d) {
|
|
|
33665
34317
|
if (!m) return null;
|
|
33666
34318
|
return { x: parseFloat(m[1]), y: parseFloat(m[2]) };
|
|
33667
34319
|
}
|
|
33668
|
-
function diamondPoints(cx, cy,
|
|
33669
|
-
return `${cx -
|
|
34320
|
+
function diamondPoints(cx, cy, r7) {
|
|
34321
|
+
return `${cx - r7},${cy} ${cx},${cy - r7} ${cx + r7},${cy} ${cx},${cy + r7}`;
|
|
33670
34322
|
}
|
|
33671
34323
|
|
|
33672
34324
|
// src/diagrams/bpmn/index.ts
|
|
@@ -34869,7 +35521,7 @@ function wireClass(t) {
|
|
|
34869
35521
|
return "lt-fbd-wire-any";
|
|
34870
35522
|
}
|
|
34871
35523
|
}
|
|
34872
|
-
function
|
|
35524
|
+
function renderBlock2(lb) {
|
|
34873
35525
|
const { x, y, width, height, block } = lb;
|
|
34874
35526
|
const headerH = FBD_CONST.block_header_h;
|
|
34875
35527
|
const parts = [];
|
|
@@ -35005,7 +35657,7 @@ function renderNetwork2(ln) {
|
|
|
35005
35657
|
for (const j of ln.junctions) {
|
|
35006
35658
|
parts.push(circle({ class: "lt-fbd-junction", cx: j.x, cy: j.y, r: 3 }));
|
|
35007
35659
|
}
|
|
35008
|
-
for (const b of ln.blocks) parts.push(
|
|
35660
|
+
for (const b of ln.blocks) parts.push(renderBlock2(b));
|
|
35009
35661
|
return group({ class: "lt-fbd-network", "data-network": ln.network.index }, parts);
|
|
35010
35662
|
}
|
|
35011
35663
|
function renderFbdLayout(layout) {
|
|
@@ -36075,14 +36727,14 @@ function roundTable(seats, diaM) {
|
|
|
36075
36727
|
draw: (c) => {
|
|
36076
36728
|
const half = Math.min(c.w, c.h) / 2;
|
|
36077
36729
|
const ring = Math.min(RING, half * 0.37);
|
|
36078
|
-
const
|
|
36730
|
+
const r7 = half - ring;
|
|
36079
36731
|
const cx = c.w / 2;
|
|
36080
36732
|
const cy = c.h / 2;
|
|
36081
|
-
const parts = [circle({ class: "sx-fp-furn", cx: c.px(cx), cy: c.px(cy), r: c.px(
|
|
36733
|
+
const parts = [circle({ class: "sx-fp-furn", cx: c.px(cx), cy: c.px(cy), r: c.px(r7) })];
|
|
36082
36734
|
for (let i = 0; i < seats; i++) {
|
|
36083
36735
|
const a = i / seats * 2 * Math.PI - Math.PI / 2;
|
|
36084
|
-
const px0 = cx + (
|
|
36085
|
-
const py0 = cy + (
|
|
36736
|
+
const px0 = cx + (r7 + ring * 0.55) * Math.cos(a);
|
|
36737
|
+
const py0 = cy + (r7 + ring * 0.55) * Math.sin(a);
|
|
36086
36738
|
parts.push(chairAt(c.px, px0, py0, a * 180 / Math.PI + 90));
|
|
36087
36739
|
}
|
|
36088
36740
|
return parts.join("");
|
|
@@ -36232,11 +36884,11 @@ function uStairs(c) {
|
|
|
36232
36884
|
return parts.join("");
|
|
36233
36885
|
}
|
|
36234
36886
|
function spiralStairs(c) {
|
|
36235
|
-
const
|
|
36887
|
+
const r7 = Math.min(c.w, c.h) / 2 - 0.02;
|
|
36236
36888
|
const cx = c.w / 2;
|
|
36237
36889
|
const cy = c.h / 2;
|
|
36238
36890
|
const parts = [
|
|
36239
|
-
circle({ class: "sx-fp-furn", cx: c.px(cx), cy: c.px(cy), r: c.px(
|
|
36891
|
+
circle({ class: "sx-fp-furn", cx: c.px(cx), cy: c.px(cy), r: c.px(r7) }),
|
|
36240
36892
|
circle({ class: "sx-fp-furn-line", cx: c.px(cx), cy: c.px(cy), r: c.px(0.08) })
|
|
36241
36893
|
];
|
|
36242
36894
|
for (let i = 0; i < 12; i++) {
|
|
@@ -36246,12 +36898,12 @@ function spiralStairs(c) {
|
|
|
36246
36898
|
class: "sx-fp-furn-line",
|
|
36247
36899
|
x1: c.px(cx + 0.08 * Math.cos(a)),
|
|
36248
36900
|
y1: c.px(cy + 0.08 * Math.sin(a)),
|
|
36249
|
-
x2: c.px(cx +
|
|
36250
|
-
y2: c.px(cy +
|
|
36901
|
+
x2: c.px(cx + r7 * Math.cos(a)),
|
|
36902
|
+
y2: c.px(cy + r7 * Math.sin(a))
|
|
36251
36903
|
})
|
|
36252
36904
|
);
|
|
36253
36905
|
}
|
|
36254
|
-
const wr =
|
|
36906
|
+
const wr = r7 * 0.62;
|
|
36255
36907
|
const a0 = Math.PI * 0.75;
|
|
36256
36908
|
const a1 = Math.PI * 1.9;
|
|
36257
36909
|
const steps = 5;
|
|
@@ -36323,8 +36975,8 @@ var FLOORPLAN_SYMBOLS = {
|
|
|
36323
36975
|
w: 0.5,
|
|
36324
36976
|
h: 0.5,
|
|
36325
36977
|
draw: (c) => {
|
|
36326
|
-
const
|
|
36327
|
-
const parts = [circle({ class: "sx-fp-furn", cx: c.px(c.w / 2), cy: c.px(c.h / 2), r: c.px(
|
|
36978
|
+
const r7 = Math.min(c.w, c.h) / 2;
|
|
36979
|
+
const parts = [circle({ class: "sx-fp-furn", cx: c.px(c.w / 2), cy: c.px(c.h / 2), r: c.px(r7) })];
|
|
36328
36980
|
for (const a of [0, 60, 120, 180, 240, 300]) {
|
|
36329
36981
|
const rad = a * Math.PI / 180;
|
|
36330
36982
|
parts.push(
|
|
@@ -36332,8 +36984,8 @@ var FLOORPLAN_SYMBOLS = {
|
|
|
36332
36984
|
class: "sx-fp-furn-line",
|
|
36333
36985
|
x1: c.px(c.w / 2),
|
|
36334
36986
|
y1: c.px(c.h / 2),
|
|
36335
|
-
x2: c.px(c.w / 2 + (
|
|
36336
|
-
y2: c.px(c.h / 2 + (
|
|
36987
|
+
x2: c.px(c.w / 2 + (r7 - 0.03) * Math.cos(rad)),
|
|
36988
|
+
y2: c.px(c.h / 2 + (r7 - 0.03) * Math.sin(rad))
|
|
36337
36989
|
})
|
|
36338
36990
|
);
|
|
36339
36991
|
}
|
|
@@ -36393,11 +37045,11 @@ var FLOORPLAN_SYMBOLS = {
|
|
|
36393
37045
|
w: 0.35,
|
|
36394
37046
|
h: 0.35,
|
|
36395
37047
|
draw: (c) => {
|
|
36396
|
-
const
|
|
37048
|
+
const r7 = Math.min(c.w, c.h) / 2;
|
|
36397
37049
|
return [
|
|
36398
|
-
circle({ class: "sx-fp-furn", cx: c.px(c.w / 2), cy: c.px(c.h / 2), r: c.px(
|
|
36399
|
-
line({ class: "sx-fp-furn-line", x1: c.px(c.w / 2 -
|
|
36400
|
-
line({ class: "sx-fp-furn-line", x1: c.px(c.w / 2), y1: c.px(c.h / 2 -
|
|
37050
|
+
circle({ class: "sx-fp-furn", cx: c.px(c.w / 2), cy: c.px(c.h / 2), r: c.px(r7) }),
|
|
37051
|
+
line({ class: "sx-fp-furn-line", x1: c.px(c.w / 2 - r7), y1: c.px(c.h / 2), x2: c.px(c.w / 2 + r7), y2: c.px(c.h / 2) }),
|
|
37052
|
+
line({ class: "sx-fp-furn-line", x1: c.px(c.w / 2), y1: c.px(c.h / 2 - r7), x2: c.px(c.w / 2), y2: c.px(c.h / 2 + r7) })
|
|
36401
37053
|
].join("");
|
|
36402
37054
|
}
|
|
36403
37055
|
},
|
|
@@ -36473,23 +37125,23 @@ var FLOORPLAN_SYMBOLS = {
|
|
|
36473
37125
|
underlay: true,
|
|
36474
37126
|
// overhead fixture — never collides with floor furniture
|
|
36475
37127
|
draw: (c) => {
|
|
36476
|
-
const
|
|
37128
|
+
const r7 = Math.min(c.w, c.h) / 2;
|
|
36477
37129
|
const cx = c.w / 2;
|
|
36478
37130
|
const cy = c.h / 2;
|
|
36479
37131
|
const parts = [
|
|
36480
|
-
circle({ class: "sx-fp-furn-dash", cx: c.px(cx), cy: c.px(cy), r: c.px(
|
|
36481
|
-
circle({ class: "sx-fp-furn", cx: c.px(cx), cy: c.px(cy), r: c.px(
|
|
37132
|
+
circle({ class: "sx-fp-furn-dash", cx: c.px(cx), cy: c.px(cy), r: c.px(r7) }),
|
|
37133
|
+
circle({ class: "sx-fp-furn", cx: c.px(cx), cy: c.px(cy), r: c.px(r7 * 0.18) })
|
|
36482
37134
|
];
|
|
36483
37135
|
for (const a of [20, 110, 200, 290]) {
|
|
36484
37136
|
const rad = a * Math.PI / 180;
|
|
36485
37137
|
parts.push(
|
|
36486
37138
|
el("ellipse", {
|
|
36487
37139
|
class: "sx-fp-furn-line",
|
|
36488
|
-
cx: c.px(cx +
|
|
36489
|
-
cy: c.px(cy +
|
|
36490
|
-
rx: c.px(
|
|
36491
|
-
ry: c.px(
|
|
36492
|
-
transform: `rotate(${a} ${c.px(cx +
|
|
37140
|
+
cx: c.px(cx + r7 * 0.55 * Math.cos(rad)),
|
|
37141
|
+
cy: c.px(cy + r7 * 0.55 * Math.sin(rad)),
|
|
37142
|
+
rx: c.px(r7 * 0.42),
|
|
37143
|
+
ry: c.px(r7 * 0.15),
|
|
37144
|
+
transform: `rotate(${a} ${c.px(cx + r7 * 0.55 * Math.cos(rad))} ${c.px(cy + r7 * 0.55 * Math.sin(rad))})`
|
|
36493
37145
|
})
|
|
36494
37146
|
);
|
|
36495
37147
|
}
|
|
@@ -36866,11 +37518,11 @@ var FLOORPLAN_SYMBOLS = {
|
|
|
36866
37518
|
w: 1,
|
|
36867
37519
|
h: 1,
|
|
36868
37520
|
draw: (c) => {
|
|
36869
|
-
const
|
|
37521
|
+
const r7 = Math.min(c.w, c.h) / 2;
|
|
36870
37522
|
const cx = c.w / 2;
|
|
36871
37523
|
const cy = c.h / 2;
|
|
36872
37524
|
const parts = [
|
|
36873
|
-
circle({ class: "sx-fp-furn-nofill", cx: c.px(cx), cy: c.px(cy), r: c.px(
|
|
37525
|
+
circle({ class: "sx-fp-furn-nofill", cx: c.px(cx), cy: c.px(cy), r: c.px(r7) }),
|
|
36874
37526
|
circle({ class: "sx-fp-furn-dot", cx: c.px(cx), cy: c.px(cy), r: c.px(0.04) })
|
|
36875
37527
|
];
|
|
36876
37528
|
for (const a of [0, 45, 90, 135, 180, 225, 270, 315]) {
|
|
@@ -36878,10 +37530,10 @@ var FLOORPLAN_SYMBOLS = {
|
|
|
36878
37530
|
parts.push(
|
|
36879
37531
|
line({
|
|
36880
37532
|
class: "sx-fp-furn-line",
|
|
36881
|
-
x1: c.px(cx + (
|
|
36882
|
-
y1: c.px(cy + (
|
|
36883
|
-
x2: c.px(cx +
|
|
36884
|
-
y2: c.px(cy +
|
|
37533
|
+
x1: c.px(cx + (r7 - 0.09) * Math.cos(rad)),
|
|
37534
|
+
y1: c.px(cy + (r7 - 0.09) * Math.sin(rad)),
|
|
37535
|
+
x2: c.px(cx + r7 * Math.cos(rad)),
|
|
37536
|
+
y2: c.px(cy + r7 * Math.sin(rad))
|
|
36885
37537
|
})
|
|
36886
37538
|
);
|
|
36887
37539
|
}
|
|
@@ -37031,10 +37683,10 @@ var FLOORPLAN_SYMBOLS = {
|
|
|
37031
37683
|
w: 2,
|
|
37032
37684
|
h: 2,
|
|
37033
37685
|
draw: (c) => {
|
|
37034
|
-
const
|
|
37686
|
+
const r7 = Math.min(c.w, c.h) / 2;
|
|
37035
37687
|
return [
|
|
37036
|
-
circle({ class: "sx-fp-furn", cx: c.px(c.w / 2), cy: c.px(c.h / 2), r: c.px(
|
|
37037
|
-
circle({ class: "sx-fp-furn-line", cx: c.px(c.w / 2), cy: c.px(c.h / 2), r: c.px(
|
|
37688
|
+
circle({ class: "sx-fp-furn", cx: c.px(c.w / 2), cy: c.px(c.h / 2), r: c.px(r7) }),
|
|
37689
|
+
circle({ class: "sx-fp-furn-line", cx: c.px(c.w / 2), cy: c.px(c.h / 2), r: c.px(r7 * 0.6) }),
|
|
37038
37690
|
circle({ class: "sx-fp-furn-dot", cx: c.px(c.w / 2), cy: c.px(c.h / 2), r: c.px(0.07) })
|
|
37039
37691
|
].join("");
|
|
37040
37692
|
}
|
|
@@ -37068,10 +37720,10 @@ var FloorplanParseError = class extends Error {
|
|
|
37068
37720
|
};
|
|
37069
37721
|
var isStr = (t) => t !== void 0 && "str" in t;
|
|
37070
37722
|
var isWord = (t, w) => t !== void 0 && "word" in t && (w === void 0 || t.word === w);
|
|
37071
|
-
function
|
|
37723
|
+
function normalizeQuotes4(line2) {
|
|
37072
37724
|
return line2.replace(/[“”「」『』]/g, '"').replace(/[‘’]/g, "'");
|
|
37073
37725
|
}
|
|
37074
|
-
function
|
|
37726
|
+
function tokenize8(line2) {
|
|
37075
37727
|
const out = [];
|
|
37076
37728
|
const re = /"([^"]*)"|(\S+)/g;
|
|
37077
37729
|
let m;
|
|
@@ -37081,7 +37733,7 @@ function tokenize7(line2) {
|
|
|
37081
37733
|
}
|
|
37082
37734
|
return out;
|
|
37083
37735
|
}
|
|
37084
|
-
function
|
|
37736
|
+
function parseNum2(t, what, ln) {
|
|
37085
37737
|
if (!isWord(t)) throw new FloorplanParseError(`expected a number for ${what}`, ln);
|
|
37086
37738
|
const v = Number(t.word);
|
|
37087
37739
|
if (!Number.isFinite(v)) throw new FloorplanParseError(`expected a number for ${what}, got "${t.word}"`, ln);
|
|
@@ -37134,7 +37786,7 @@ function parseHeader3(tok, ast, ln) {
|
|
|
37134
37786
|
}
|
|
37135
37787
|
function parseRoom(tok, ast, ln) {
|
|
37136
37788
|
const id = parseId(tok.shift(), "a room id", ln);
|
|
37137
|
-
if (ast.rooms.some((
|
|
37789
|
+
if (ast.rooms.some((r7) => r7.id === id)) {
|
|
37138
37790
|
throw new FloorplanParseError(`duplicate room id "${id}"`, ln);
|
|
37139
37791
|
}
|
|
37140
37792
|
const room = { id, label: id, w: 4, h: 3, line: ln };
|
|
@@ -37151,7 +37803,7 @@ function parseRoom(tok, ast, ln) {
|
|
|
37151
37803
|
};
|
|
37152
37804
|
} else if (t.word === "offset") {
|
|
37153
37805
|
if (!room.rel) throw new FloorplanParseError(`"offset" requires a relative placement (right-of/left-of/above/below)`, ln);
|
|
37154
|
-
room.rel.offset =
|
|
37806
|
+
room.rel.offset = parseNum2(tok.shift(), "offset", ln);
|
|
37155
37807
|
} else if (t.word === "align") {
|
|
37156
37808
|
if (!room.rel) throw new FloorplanParseError(`"align" requires a relative placement (right-of/left-of/above/below)`, ln);
|
|
37157
37809
|
const a = parseId(tok.shift(), "align (start|center|end)", ln);
|
|
@@ -37185,7 +37837,7 @@ function parseExtend(tok, ast, ln) {
|
|
|
37185
37837
|
};
|
|
37186
37838
|
} else if (t.word === "offset") {
|
|
37187
37839
|
if (!ext.rel) throw new FloorplanParseError(`"offset" requires a relative placement (right-of/left-of/above/below)`, ln);
|
|
37188
|
-
ext.rel.offset =
|
|
37840
|
+
ext.rel.offset = parseNum2(tok.shift(), "offset", ln);
|
|
37189
37841
|
} else if (t.word === "align") {
|
|
37190
37842
|
if (!ext.rel) throw new FloorplanParseError(`"align" requires a relative placement (right-of/left-of/above/below)`, ln);
|
|
37191
37843
|
const a = parseId(tok.shift(), "align (start|center|end)", ln);
|
|
@@ -37230,7 +37882,7 @@ function parseOpening(kind, tok, ast, ln) {
|
|
|
37230
37882
|
const t = tok.shift();
|
|
37231
37883
|
if (!isWord(t)) throw new FloorplanParseError(`${kind}: unexpected string "${t.str}"`, ln);
|
|
37232
37884
|
else if (t.word === "at") op.pct = parsePct(tok.shift(), ln);
|
|
37233
|
-
else if (t.word === "width") op.width =
|
|
37885
|
+
else if (t.word === "width") op.width = parseNum2(tok.shift(), "width", ln);
|
|
37234
37886
|
else if (t.word === "hinge") {
|
|
37235
37887
|
const h = parseId(tok.shift(), "hinge (left|right)", ln);
|
|
37236
37888
|
if (h !== "left" && h !== "right") throw new FloorplanParseError(`hinge must be left|right, got "${h}"`, ln);
|
|
@@ -37271,7 +37923,7 @@ function parseFurniture(tok, ast, ln) {
|
|
|
37271
37923
|
f.x = c.x;
|
|
37272
37924
|
f.y = c.y;
|
|
37273
37925
|
} else if (t.word === "size") f.size = parseDims(tok.shift(), "size", ln);
|
|
37274
|
-
else if (t.word === "rotate") f.rotate =
|
|
37926
|
+
else if (t.word === "rotate") f.rotate = parseNum2(tok.shift(), "rotate", ln);
|
|
37275
37927
|
else throw new FloorplanParseError(`furniture: unexpected token "${t.word}"`, ln);
|
|
37276
37928
|
}
|
|
37277
37929
|
ast.furniture.push(f);
|
|
@@ -37291,18 +37943,18 @@ function parseArray(mode, tok, ast, ln) {
|
|
|
37291
37943
|
const t = tok.shift();
|
|
37292
37944
|
if (!isWord(t)) throw new FloorplanParseError(`${mode}: unexpected string "${t.str}"`, ln);
|
|
37293
37945
|
else if (t.word === "in") a.room = parseId(tok.shift(), `a room id after "in"`, ln);
|
|
37294
|
-
else if (t.word === "rows") a.rows =
|
|
37295
|
-
else if (t.word === "cols") a.cols =
|
|
37296
|
-
else if (t.word === "count") a.count =
|
|
37946
|
+
else if (t.word === "rows") a.rows = parseNum2(tok.shift(), "rows", ln);
|
|
37947
|
+
else if (t.word === "cols") a.cols = parseNum2(tok.shift(), "cols", ln);
|
|
37948
|
+
else if (t.word === "count") a.count = parseNum2(tok.shift(), "count", ln);
|
|
37297
37949
|
else if (t.word === "area") {
|
|
37298
37950
|
a.p1 = parseCoord2(tok.shift(), "area p1", ln);
|
|
37299
37951
|
a.p2 = parseCoord2(tok.shift(), "area p2", ln);
|
|
37300
37952
|
} else if (t.word === "itemsize") a.itemsize = parseDims(tok.shift(), "itemsize", ln);
|
|
37301
|
-
else if (t.word === "rotate") a.rotate =
|
|
37953
|
+
else if (t.word === "rotate") a.rotate = parseNum2(tok.shift(), "rotate", ln);
|
|
37302
37954
|
else if (t.word === "center") a.center = parseCoord2(tok.shift(), "center", ln);
|
|
37303
|
-
else if (t.word === "radius") a.radius =
|
|
37304
|
-
else if (t.word === "from") a.fromDeg =
|
|
37305
|
-
else if (t.word === "to") a.toDeg =
|
|
37955
|
+
else if (t.word === "radius") a.radius = parseNum2(tok.shift(), "radius", ln);
|
|
37956
|
+
else if (t.word === "from") a.fromDeg = parseNum2(tok.shift(), "from", ln);
|
|
37957
|
+
else if (t.word === "to") a.toDeg = parseNum2(tok.shift(), "to", ln);
|
|
37306
37958
|
else throw new FloorplanParseError(`${mode}: unexpected token "${t.word}"`, ln);
|
|
37307
37959
|
}
|
|
37308
37960
|
ast.arrays.push(a);
|
|
@@ -37322,9 +37974,9 @@ function parseFloorplan(text2) {
|
|
|
37322
37974
|
const lines = text2.split(/\r?\n/);
|
|
37323
37975
|
for (let i = 0; i < lines.length; i++) {
|
|
37324
37976
|
const ln = i + 1;
|
|
37325
|
-
const raw =
|
|
37977
|
+
const raw = normalizeQuotes4(lines[i]).trim();
|
|
37326
37978
|
if (!raw) continue;
|
|
37327
|
-
const all =
|
|
37979
|
+
const all = tokenize8(raw);
|
|
37328
37980
|
const tok = [];
|
|
37329
37981
|
for (let k = 0; k < all.length; k++) {
|
|
37330
37982
|
const t = all[k];
|
|
@@ -37349,7 +38001,7 @@ function parseFloorplan(text2) {
|
|
|
37349
38001
|
throw new FloorplanParseError(`the first statement must be the "floorplan" header`, ln);
|
|
37350
38002
|
} else if (kw === "room") parseRoom(tok, ast, ln);
|
|
37351
38003
|
else if (kw === "north") {
|
|
37352
|
-
ast.north = tok.length ?
|
|
38004
|
+
ast.north = tok.length ? parseNum2(tok.shift(), "north rotation (degrees)", ln) : 0;
|
|
37353
38005
|
if (tok.length) throw new FloorplanParseError(`north: unexpected trailing tokens`, ln);
|
|
37354
38006
|
} else if (kw === "extend") parseExtend(tok, ast, ln);
|
|
37355
38007
|
else if (kw === "door" || kw === "window" || kw === "opening") parseOpening(kw, tok, ast, ln);
|
|
@@ -37612,14 +38264,14 @@ function layoutFloorplan(ast) {
|
|
|
37612
38264
|
].sort((a, b) => a.line - b.line);
|
|
37613
38265
|
for (const stmt of stmts) {
|
|
37614
38266
|
if (stmt.room) {
|
|
37615
|
-
const
|
|
37616
|
-
const w =
|
|
37617
|
-
const h =
|
|
37618
|
-
const pos = resolvePlacement(
|
|
38267
|
+
const r7 = stmt.room;
|
|
38268
|
+
const w = r7.w * u;
|
|
38269
|
+
const h = r7.h * u;
|
|
38270
|
+
const pos = resolvePlacement(r7, w, h, byId, rooms, u, `room "${r7.id}"`, errors) ?? { x: 0, y: 0 };
|
|
37619
38271
|
const part = { x: pos.x, y: pos.y, w, h };
|
|
37620
38272
|
const room = {
|
|
37621
|
-
id:
|
|
37622
|
-
label:
|
|
38273
|
+
id: r7.id,
|
|
38274
|
+
label: r7.label,
|
|
37623
38275
|
x: part.x,
|
|
37624
38276
|
y: part.y,
|
|
37625
38277
|
w,
|
|
@@ -37627,11 +38279,11 @@ function layoutFloorplan(ast) {
|
|
|
37627
38279
|
parts: [part],
|
|
37628
38280
|
areaM2: 0,
|
|
37629
38281
|
areaText: "",
|
|
37630
|
-
fill:
|
|
37631
|
-
nolabel:
|
|
38282
|
+
fill: r7.fill,
|
|
38283
|
+
nolabel: r7.nolabel ?? false
|
|
37632
38284
|
};
|
|
37633
38285
|
refreshRoomBounds(room, ast.unit);
|
|
37634
|
-
byId.set(
|
|
38286
|
+
byId.set(r7.id, rooms.length);
|
|
37635
38287
|
rooms.push(room);
|
|
37636
38288
|
} else if (stmt.ext) {
|
|
37637
38289
|
const e = stmt.ext;
|
|
@@ -37744,10 +38396,10 @@ function layoutFloorplan(ast) {
|
|
|
37744
38396
|
const spanW = p2.x - p1.x;
|
|
37745
38397
|
const spanH = p2.y - p1.y;
|
|
37746
38398
|
let placed = 0;
|
|
37747
|
-
for (let
|
|
38399
|
+
for (let r7 = 0; r7 < nRows && placed < cap2; r7++) {
|
|
37748
38400
|
for (let col = 0; col < nCols && placed < cap2; col++) {
|
|
37749
38401
|
const cx = p1.x + (nCols === 1 ? spanW / 2 : col * spanW / (nCols - 1));
|
|
37750
|
-
const cy = p1.y + (nRows === 1 ? spanH / 2 :
|
|
38402
|
+
const cy = p1.y + (nRows === 1 ? spanH / 2 : r7 * spanH / (nRows - 1));
|
|
37751
38403
|
place(a.type, idx, cx - iw / 2, cy - ih / 2, iw, ih, a.rotate);
|
|
37752
38404
|
placed++;
|
|
37753
38405
|
}
|
|
@@ -37768,7 +38420,7 @@ function layoutFloorplan(ast) {
|
|
|
37768
38420
|
}
|
|
37769
38421
|
}
|
|
37770
38422
|
const roomOf = /* @__PURE__ */ new Map();
|
|
37771
|
-
for (const
|
|
38423
|
+
for (const r7 of rooms) roomOf.set(r7.id, r7);
|
|
37772
38424
|
const warnItems = /* @__PURE__ */ new Set();
|
|
37773
38425
|
for (const it of items) {
|
|
37774
38426
|
const room = roomOf.get(it.roomId);
|
|
@@ -37827,11 +38479,11 @@ function layoutFloorplan(ast) {
|
|
|
37827
38479
|
let minY = Infinity;
|
|
37828
38480
|
let maxX = -Infinity;
|
|
37829
38481
|
let maxY = -Infinity;
|
|
37830
|
-
for (const
|
|
37831
|
-
minX = Math.min(minX,
|
|
37832
|
-
minY = Math.min(minY,
|
|
37833
|
-
maxX = Math.max(maxX,
|
|
37834
|
-
maxY = Math.max(maxY,
|
|
38482
|
+
for (const r7 of rooms) {
|
|
38483
|
+
minX = Math.min(minX, r7.x);
|
|
38484
|
+
minY = Math.min(minY, r7.y);
|
|
38485
|
+
maxX = Math.max(maxX, r7.x + r7.w);
|
|
38486
|
+
maxY = Math.max(maxY, r7.y + r7.h);
|
|
37835
38487
|
}
|
|
37836
38488
|
if (rooms.length === 0) {
|
|
37837
38489
|
minX = minY = 0;
|
|
@@ -37857,8 +38509,8 @@ function layoutFloorplan(ast) {
|
|
|
37857
38509
|
minor: false
|
|
37858
38510
|
});
|
|
37859
38511
|
const topSegs = [];
|
|
37860
|
-
for (const
|
|
37861
|
-
for (const sg of sideSegments(
|
|
38512
|
+
for (const r7 of rooms) {
|
|
38513
|
+
for (const sg of sideSegments(r7, "north")) {
|
|
37862
38514
|
if (Math.abs(sg.along - minY) < 0.01) topSegs.push({ lo: sg.lo, hi: sg.hi });
|
|
37863
38515
|
}
|
|
37864
38516
|
}
|
|
@@ -37875,8 +38527,8 @@ function layoutFloorplan(ast) {
|
|
|
37875
38527
|
}
|
|
37876
38528
|
}
|
|
37877
38529
|
const leftSegs = [];
|
|
37878
|
-
for (const
|
|
37879
|
-
for (const sg of sideSegments(
|
|
38530
|
+
for (const r7 of rooms) {
|
|
38531
|
+
for (const sg of sideSegments(r7, "west")) {
|
|
37880
38532
|
if (Math.abs(sg.along - minX) < 0.01) leftSegs.push({ lo: sg.lo, hi: sg.hi });
|
|
37881
38533
|
}
|
|
37882
38534
|
}
|
|
@@ -37904,7 +38556,7 @@ function layoutFloorplan(ast) {
|
|
|
37904
38556
|
dims,
|
|
37905
38557
|
bounds: { minX, minY, maxX, maxY },
|
|
37906
38558
|
wallT: FLOORPLAN_CONST.wallT,
|
|
37907
|
-
totalAreaM2: rooms.reduce((s,
|
|
38559
|
+
totalAreaM2: rooms.reduce((s, r7) => s + r7.areaM2, 0),
|
|
37908
38560
|
errors,
|
|
37909
38561
|
warnings,
|
|
37910
38562
|
warnItems: [...warnItems]
|
|
@@ -37956,11 +38608,11 @@ function resolveOpening(op, rooms, byId, u, unit, errors, warnings) {
|
|
|
37956
38608
|
return null;
|
|
37957
38609
|
}
|
|
37958
38610
|
owner = idx;
|
|
37959
|
-
const
|
|
38611
|
+
const r7 = rooms[idx];
|
|
37960
38612
|
const side = op.side;
|
|
37961
|
-
const segs = sideSegments(
|
|
38613
|
+
const segs = sideSegments(r7, side);
|
|
37962
38614
|
if (segs.length === 0) {
|
|
37963
|
-
errors.push(`${op.kind} on "${
|
|
38615
|
+
errors.push(`${op.kind} on "${r7.id}" ${side}: that side has no exterior wall segment`);
|
|
37964
38616
|
return null;
|
|
37965
38617
|
}
|
|
37966
38618
|
const total = segs.reduce((s, sg) => s + (sg.hi - sg.lo), 0);
|
|
@@ -38301,13 +38953,13 @@ function renderFloorplanLayout(lay, config) {
|
|
|
38301
38953
|
const openings = [];
|
|
38302
38954
|
const labels = [];
|
|
38303
38955
|
const dims = [];
|
|
38304
|
-
for (const
|
|
38956
|
+
for (const r7 of lay.rooms) {
|
|
38305
38957
|
floors.push(
|
|
38306
38958
|
group(
|
|
38307
|
-
{ class: "sx-fp-floor", "data-room":
|
|
38308
|
-
|
|
38959
|
+
{ class: "sx-fp-floor", "data-room": r7.id },
|
|
38960
|
+
r7.parts.map(
|
|
38309
38961
|
(p) => rect({
|
|
38310
|
-
fill:
|
|
38962
|
+
fill: r7.fill ?? t.floorFill,
|
|
38311
38963
|
x: X(p.x),
|
|
38312
38964
|
y: Y(p.y),
|
|
38313
38965
|
width: px(p.w),
|
|
@@ -38316,12 +38968,12 @@ function renderFloorplanLayout(lay, config) {
|
|
|
38316
38968
|
)
|
|
38317
38969
|
)
|
|
38318
38970
|
);
|
|
38319
|
-
if (!
|
|
38320
|
-
const main =
|
|
38971
|
+
if (!r7.nolabel) {
|
|
38972
|
+
const main = r7.parts.reduce((a, b) => b.w * b.h > a.w * a.h ? b : a);
|
|
38321
38973
|
const cx = X(main.x + main.w / 2);
|
|
38322
38974
|
const cy = Y(main.y + main.h / 2);
|
|
38323
|
-
labels.push(text({ class: "sx-fp-room-name", x: cx, y: r24(cy - 3), "text-anchor": "middle" },
|
|
38324
|
-
labels.push(text({ class: "sx-fp-room-area", x: cx, y: r24(cy + 13), "text-anchor": "middle" },
|
|
38975
|
+
labels.push(text({ class: "sx-fp-room-name", x: cx, y: r24(cy - 3), "text-anchor": "middle" }, r7.label));
|
|
38976
|
+
labels.push(text({ class: "sx-fp-room-area", x: cx, y: r24(cy + 13), "text-anchor": "middle" }, r7.areaText));
|
|
38325
38977
|
}
|
|
38326
38978
|
}
|
|
38327
38979
|
const warnSet = new Set(lay.warnItems);
|
|
@@ -38351,8 +39003,8 @@ function renderFloorplanLayout(lay, config) {
|
|
|
38351
39003
|
}
|
|
38352
39004
|
});
|
|
38353
39005
|
const tw = lay.wallT;
|
|
38354
|
-
for (const
|
|
38355
|
-
for (const p of
|
|
39006
|
+
for (const r7 of lay.rooms) {
|
|
39007
|
+
for (const p of r7.parts) {
|
|
38356
39008
|
walls.push(rect({ class: "sx-fp-wall", x: r24(X(p.x) - px(tw / 2)), y: r24(Y(p.y) - px(tw / 2)), width: r24(px(p.w + tw)), height: px(tw) }));
|
|
38357
39009
|
walls.push(rect({ class: "sx-fp-wall", x: r24(X(p.x) - px(tw / 2)), y: r24(Y(p.y + p.h) - px(tw / 2)), width: r24(px(p.w + tw)), height: px(tw) }));
|
|
38358
39010
|
walls.push(rect({ class: "sx-fp-wall", x: r24(X(p.x) - px(tw / 2)), y: r24(Y(p.y) - px(tw / 2)), width: px(tw), height: r24(px(p.h + tw)) }));
|
|
@@ -38485,8 +39137,8 @@ var PlaybookParseError = class extends Error {
|
|
|
38485
39137
|
var isStr2 = (t) => t !== void 0 && "str" in t;
|
|
38486
39138
|
var isWord2 = (t, w) => t !== void 0 && "word" in t && (w === void 0 || t.word.toLowerCase() === w);
|
|
38487
39139
|
var tokDisplay = (t) => "word" in t ? t.word : `"${t.str}"`;
|
|
38488
|
-
var
|
|
38489
|
-
function
|
|
39140
|
+
var normalizeQuotes5 = (s) => s.replace(/[“”「」『』]/g, '"').replace(/[‘’]/g, "'");
|
|
39141
|
+
function tokenize9(line2) {
|
|
38490
39142
|
const out = [];
|
|
38491
39143
|
const re = /"([^"]*)"|(\S+)/g;
|
|
38492
39144
|
let m;
|
|
@@ -38496,7 +39148,7 @@ function tokenize8(line2) {
|
|
|
38496
39148
|
}
|
|
38497
39149
|
return out;
|
|
38498
39150
|
}
|
|
38499
|
-
function
|
|
39151
|
+
function parseNum3(t, what, ln) {
|
|
38500
39152
|
if (!isWord2(t)) throw new PlaybookParseError(`expected a number for ${what}`, ln);
|
|
38501
39153
|
const v = Number(t.word);
|
|
38502
39154
|
if (!Number.isFinite(v)) throw new PlaybookParseError(`expected a number for ${what}, got "${t.word}"`, ln);
|
|
@@ -38603,10 +39255,10 @@ function parseHeader4(tok, ast, ln) {
|
|
|
38603
39255
|
function parseField(tok, ast, ln) {
|
|
38604
39256
|
while (tok.length) {
|
|
38605
39257
|
const t = tok.shift();
|
|
38606
|
-
if (isWord2(t, "down")) ast.down =
|
|
38607
|
-
else if (isWord2(t, "distance") || isWord2(t, "togo")) ast.distance =
|
|
38608
|
-
else if (isWord2(t, "los") || isWord2(t, "ball")) ast.losYard =
|
|
38609
|
-
else if (isWord2(t, "goal") || isWord2(t, "togoal")) ast.toGoal =
|
|
39258
|
+
if (isWord2(t, "down")) ast.down = parseNum3(tok.shift(), "down", ln);
|
|
39259
|
+
else if (isWord2(t, "distance") || isWord2(t, "togo")) ast.distance = parseNum3(tok.shift(), "distance", ln);
|
|
39260
|
+
else if (isWord2(t, "los") || isWord2(t, "ball")) ast.losYard = parseNum3(tok.shift(), "los", ln);
|
|
39261
|
+
else if (isWord2(t, "goal") || isWord2(t, "togoal")) ast.toGoal = parseNum3(tok.shift(), "goal", ln);
|
|
38610
39262
|
else if (isWord2(t, "view")) {
|
|
38611
39263
|
const v = parseId2(tok.shift(), "view (full|half)", ln).toLowerCase();
|
|
38612
39264
|
if (v !== "full" && v !== "half" && v !== "auto") throw new PlaybookParseError(`view must be full|half`, ln);
|
|
@@ -38710,7 +39362,7 @@ function parseRouteRun(kind, tok, ast, ln) {
|
|
|
38710
39362
|
const t = tok.shift();
|
|
38711
39363
|
if (isWord2(t) && DIRS.includes(t.word.toLowerCase())) m.dir = t.word.toLowerCase();
|
|
38712
39364
|
else if (isWord2(t) && Number.isFinite(Number(t.word))) m.depth = Number(t.word);
|
|
38713
|
-
else if (isWord2(t, "depth")) m.depth =
|
|
39365
|
+
else if (isWord2(t, "depth")) m.depth = parseNum3(tok.shift(), "depth", ln);
|
|
38714
39366
|
else throw new PlaybookParseError(`${kind}: unexpected token "${tokDisplay(t)}"`, ln);
|
|
38715
39367
|
}
|
|
38716
39368
|
ast.moves.push(m);
|
|
@@ -38815,9 +39467,9 @@ function parsePlaybook(text2) {
|
|
|
38815
39467
|
const lines = text2.split(/\r?\n/);
|
|
38816
39468
|
for (let i = 0; i < lines.length; i++) {
|
|
38817
39469
|
const ln = i + 1;
|
|
38818
|
-
const raw =
|
|
39470
|
+
const raw = normalizeQuotes5(lines[i]).trim();
|
|
38819
39471
|
if (!raw) continue;
|
|
38820
|
-
const all =
|
|
39472
|
+
const all = tokenize9(raw);
|
|
38821
39473
|
const tok = [];
|
|
38822
39474
|
for (const t of all) {
|
|
38823
39475
|
if (isWord2(t) && (t.word.startsWith("#") || t.word.startsWith("//"))) break;
|
|
@@ -39663,12 +40315,12 @@ function resolveGeneric(m, src, byId, players, mod, sport, warnings) {
|
|
|
39663
40315
|
let cur = { x: src.x, y: src.y };
|
|
39664
40316
|
for (const p of m.points) {
|
|
39665
40317
|
if (p.ref) {
|
|
39666
|
-
const
|
|
39667
|
-
if (!
|
|
40318
|
+
const r7 = resolveRef(p.ref, byId, players, mod);
|
|
40319
|
+
if (!r7) {
|
|
39668
40320
|
warnings.push(`${m.kind} ${m.player}: unknown destination "${p.ref}" \u2014 skipped`);
|
|
39669
40321
|
return null;
|
|
39670
40322
|
}
|
|
39671
|
-
cur =
|
|
40323
|
+
cur = r7;
|
|
39672
40324
|
} else if (p.rel) {
|
|
39673
40325
|
cur = { x: cur.x + (p.x ?? 0), y: cur.y + (p.y ?? 0) };
|
|
39674
40326
|
} else {
|
|
@@ -39811,22 +40463,22 @@ function renderMove(mv, ctx) {
|
|
|
39811
40463
|
return group({ class: "sx-pb-move-g", "data-kind": mv.kind, "data-player": mv.player }, parts);
|
|
39812
40464
|
}
|
|
39813
40465
|
function playerSymbol(p, ctx) {
|
|
39814
|
-
const cx = ctx.X(p.x), cy = ctx.Y(p.y),
|
|
40466
|
+
const cx = ctx.X(p.x), cy = ctx.Y(p.y), r7 = 10;
|
|
39815
40467
|
const parts = [];
|
|
39816
40468
|
if (p.side === "defense" || p.pos === "x") {
|
|
39817
|
-
const k =
|
|
40469
|
+
const k = r7 * 0.78;
|
|
39818
40470
|
parts.push(line({ class: "sx-pb-x", x1: r28(cx - k), y1: r28(cy - k), x2: r28(cx + k), y2: r28(cy + k) }));
|
|
39819
40471
|
parts.push(line({ class: "sx-pb-x", x1: r28(cx - k), y1: r28(cy + k), x2: r28(cx + k), y2: r28(cy - k) }));
|
|
39820
40472
|
if (p.label) parts.push(text({ class: "sx-pb-x-text", x: r28(cx + k + 5), y: r28(cy - k + 2), "text-anchor": "middle" }, p.label));
|
|
39821
40473
|
} else if (p.pos === "gk") {
|
|
39822
|
-
const h =
|
|
40474
|
+
const h = r7 * 1.15;
|
|
39823
40475
|
parts.push(polygon({ class: "sx-pb-gk", points: `${r28(cx)},${r28(cy - h)} ${r28(cx + h)},${r28(cy + h * 0.8)} ${r28(cx - h)},${r28(cy + h * 0.8)}` }));
|
|
39824
40476
|
parts.push(text({ class: "sx-pb-o-text", x: r28(cx), y: r28(cy + 6), "text-anchor": "middle" }, p.label));
|
|
39825
40477
|
} else if (p.pos === "c") {
|
|
39826
|
-
parts.push(rect({ class: "sx-pb-o", x: r28(cx -
|
|
40478
|
+
parts.push(rect({ class: "sx-pb-o", x: r28(cx - r7 * 0.82), y: r28(cy - r7 * 0.82), width: r28(r7 * 1.64), height: r28(r7 * 1.64) }));
|
|
39827
40479
|
parts.push(text({ class: "sx-pb-o-text", x: r28(cx), y: r28(cy + 3.6), "text-anchor": "middle" }, p.label));
|
|
39828
40480
|
} else {
|
|
39829
|
-
parts.push(circle({ class: "sx-pb-o", cx: r28(cx), cy: r28(cy), r:
|
|
40481
|
+
parts.push(circle({ class: "sx-pb-o", cx: r28(cx), cy: r28(cy), r: r7 }));
|
|
39830
40482
|
parts.push(text({ class: "sx-pb-o-text", x: r28(cx), y: r28(cy + 3.6), "text-anchor": "middle" }, p.label));
|
|
39831
40483
|
}
|
|
39832
40484
|
return group({ class: "sx-pb-player", "data-side": p.side, "data-id": p.id }, parts);
|
|
@@ -40033,6 +40685,7 @@ var plugins = [
|
|
|
40033
40685
|
bowtie2,
|
|
40034
40686
|
eventtree,
|
|
40035
40687
|
fmea,
|
|
40688
|
+
rbd,
|
|
40036
40689
|
causalloop,
|
|
40037
40690
|
markov,
|
|
40038
40691
|
gitgraph,
|
|
@@ -40052,7 +40705,7 @@ function detectPlugin(text2, config) {
|
|
|
40052
40705
|
if (plugin.detect(text2)) return plugin;
|
|
40053
40706
|
}
|
|
40054
40707
|
throw new Error(
|
|
40055
|
-
"Cannot detect diagram type. Start your text with 'genogram', 'ecomap', 'pedigree', 'phylo', 'sociogram', 'timing', 'logic', 'circuit', 'blockdiagram', 'ladder', 'sld', 'entity-structure', 'fishbone', 'venn', 'flowchart', 'mindmap', 'matrix', 'orgchart', 'state', 'pid', 'erd', 'breadboard', 'bpmn', 'fbd', 'sfc', 'prisma', 'usecase', 'pert', 'sequence', 'petri', 'network', 'umlclass', 'faulttree', 'bowtie', 'floorplan', or 'playbook'."
|
|
40708
|
+
"Cannot detect diagram type. Start your text with 'genogram', 'ecomap', 'pedigree', 'phylo', 'sociogram', 'timing', 'logic', 'circuit', 'blockdiagram', 'ladder', 'sld', 'entity-structure', 'fishbone', 'venn', 'flowchart', 'mindmap', 'matrix', 'orgchart', 'state', 'pid', 'erd', 'breadboard', 'bpmn', 'fbd', 'sfc', 'prisma', 'usecase', 'pert', 'sequence', 'petri', 'network', 'umlclass', 'faulttree', 'bowtie', 'rbd', 'floorplan', or 'playbook'."
|
|
40056
40709
|
);
|
|
40057
40710
|
}
|
|
40058
40711
|
function stripCodeFences(text2) {
|
|
@@ -40189,6 +40842,6 @@ function renderWithPlugin(prepared, plugin, config) {
|
|
|
40189
40842
|
return plugin.render(prepared, renderConfig);
|
|
40190
40843
|
}
|
|
40191
40844
|
|
|
40192
|
-
export { FLOORPLAN_SYMBOLS, GEOMETRY, bowtie2 as bowtie, causalloop, decisiontree, drawDeviceIcon, epc, eventtree, faulttree, fmea, gitgraph, iconSize, idef0, markov, network, parse, parseResult, pert, petri, pid, prisma, render, renderEquip, renderPreview, renderResult, sequence, state, threatmodel, timeline, umlclass, usecase, welding };
|
|
40193
|
-
//# sourceMappingURL=chunk-
|
|
40194
|
-
//# sourceMappingURL=chunk-
|
|
40845
|
+
export { FLOORPLAN_SYMBOLS, GEOMETRY, bowtie2 as bowtie, causalloop, decisiontree, drawDeviceIcon, epc, eventtree, faulttree, fmea, gitgraph, iconSize, idef0, markov, network, parse, parseResult, pert, petri, pid, prisma, rbd, render, renderEquip, renderPreview, renderResult, sequence, state, threatmodel, timeline, umlclass, usecase, welding };
|
|
40846
|
+
//# sourceMappingURL=chunk-LMNWUZMD.js.map
|
|
40847
|
+
//# sourceMappingURL=chunk-LMNWUZMD.js.map
|