@zukhruf/diagram 0.3.30 → 0.3.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/layouts/graph/areas.d.ts +27 -0
- package/dist/lib/layouts/graph/areas.d.ts.map +1 -0
- package/dist/lib/layouts/graph/areas.js +196 -0
- package/dist/lib/layouts/graph/areas.js.map +1 -0
- package/dist/lib/layouts/graph/graph-layout-result.d.ts +95 -0
- package/dist/lib/layouts/graph/graph-layout-result.d.ts.map +1 -0
- package/dist/lib/layouts/graph/graph-layout-result.js +2 -0
- package/dist/lib/layouts/graph/graph-layout-result.js.map +1 -0
- package/dist/lib/layouts/graph/graph-layout.d.ts +2 -1
- package/dist/lib/layouts/graph/graph-layout.d.ts.map +1 -1
- package/dist/lib/layouts/graph/graph-layout.js +5 -3
- package/dist/lib/layouts/graph/graph-layout.js.map +1 -1
- package/dist/lib/layouts/graph/gutters.d.ts +25 -0
- package/dist/lib/layouts/graph/gutters.d.ts.map +1 -0
- package/dist/lib/layouts/graph/gutters.js +124 -0
- package/dist/lib/layouts/graph/gutters.js.map +1 -0
- package/dist/lib/layouts/graph/layout.d.ts +10 -0
- package/dist/lib/layouts/graph/layout.d.ts.map +1 -0
- package/dist/lib/layouts/graph/layout.js +164 -0
- package/dist/lib/layouts/graph/layout.js.map +1 -0
- package/dist/lib/layouts/graph/legacy-graph-layout.d.ts +6 -0
- package/dist/lib/layouts/graph/legacy-graph-layout.d.ts.map +1 -0
- package/dist/lib/layouts/graph/legacy-graph-layout.js +542 -0
- package/dist/lib/layouts/graph/legacy-graph-layout.js.map +1 -0
- package/dist/lib/layouts/graph/measure.d.ts +44 -0
- package/dist/lib/layouts/graph/measure.d.ts.map +1 -0
- package/dist/lib/layouts/graph/measure.js +372 -0
- package/dist/lib/layouts/graph/measure.js.map +1 -0
- package/dist/lib/layouts/graph/node-content.d.ts +16 -0
- package/dist/lib/layouts/graph/node-content.d.ts.map +1 -0
- package/dist/lib/layouts/graph/node-content.js +323 -0
- package/dist/lib/layouts/graph/node-content.js.map +1 -0
- package/dist/lib/layouts/graph/text-block.d.ts +19 -0
- package/dist/lib/layouts/graph/text-block.d.ts.map +1 -0
- package/dist/lib/layouts/graph/text-block.js +86 -0
- package/dist/lib/layouts/graph/text-block.js.map +1 -0
- package/dist/lib/layouts/graph/tokens.d.ts +53 -0
- package/dist/lib/layouts/graph/tokens.d.ts.map +1 -0
- package/dist/lib/layouts/graph/tokens.js +95 -0
- package/dist/lib/layouts/graph/tokens.js.map +1 -0
- package/dist/lib/layouts/graph/tracks.d.ts +20 -0
- package/dist/lib/layouts/graph/tracks.d.ts.map +1 -0
- package/dist/lib/layouts/graph/tracks.js +47 -0
- package/dist/lib/layouts/graph/tracks.js.map +1 -0
- package/dist/lib/layouts/text/font-metrics.generated.d.ts +18 -0
- package/dist/lib/layouts/text/font-metrics.generated.d.ts.map +1 -0
- package/dist/lib/layouts/text/font-metrics.generated.js +1043 -0
- package/dist/lib/layouts/text/font-metrics.generated.js.map +1 -0
- package/dist/lib/layouts/text/font.d.ts +14 -0
- package/dist/lib/layouts/text/font.d.ts.map +1 -0
- package/dist/lib/layouts/text/font.js +11 -0
- package/dist/lib/layouts/text/font.js.map +1 -0
- package/dist/lib/layouts/text/measure-text.d.ts +13 -0
- package/dist/lib/layouts/text/measure-text.d.ts.map +1 -0
- package/dist/lib/layouts/text/measure-text.js +67 -0
- package/dist/lib/layouts/text/measure-text.js.map +1 -0
- package/dist/lib/model/diagram-ir.d.ts +11 -1
- package/dist/lib/model/diagram-ir.d.ts.map +1 -1
- package/dist/lib/model/diagram-ir.js.map +1 -1
- package/dist/lib/renderers/canvas/graph-canvas.d.ts.map +1 -1
- package/dist/lib/renderers/canvas/graph-canvas.js +148 -138
- package/dist/lib/renderers/canvas/graph-canvas.js.map +1 -1
- package/dist/lib/renderers/html/graph-html.d.ts.map +1 -1
- package/dist/lib/renderers/html/graph-html.js +462 -511
- package/dist/lib/renderers/html/graph-html.js.map +1 -1
- package/dist/lib/renderers/shared/graph-parts.d.ts +15 -13
- package/dist/lib/renderers/shared/graph-parts.d.ts.map +1 -1
- package/dist/lib/renderers/shared/graph-parts.js +649 -644
- package/dist/lib/renderers/shared/graph-parts.js.map +1 -1
- package/dist/lib/renderers/shared/node-parts.d.ts +20 -19
- package/dist/lib/renderers/shared/node-parts.d.ts.map +1 -1
- package/dist/lib/renderers/shared/node-parts.js +678 -811
- package/dist/lib/renderers/shared/node-parts.js.map +1 -1
- package/dist/lib/renderers/shared/run-spans.d.ts +8 -0
- package/dist/lib/renderers/shared/run-spans.d.ts.map +1 -0
- package/dist/lib/renderers/shared/run-spans.js +18 -0
- package/dist/lib/renderers/shared/run-spans.js.map +1 -0
- package/dist/lib/renderers/shared/text-runs.d.ts +21 -0
- package/dist/lib/renderers/shared/text-runs.d.ts.map +1 -0
- package/dist/lib/renderers/shared/text-runs.js +44 -0
- package/dist/lib/renderers/shared/text-runs.js.map +1 -0
- package/dist/lib/renderers/svg/graph-svg.d.ts.map +1 -1
- package/dist/lib/renderers/svg/graph-svg.js +304 -465
- package/dist/lib/renderers/svg/graph-svg.js.map +1 -1
- package/dist/lib/renderers/svg/timeline-svg.d.ts.map +1 -1
- package/dist/lib/renderers/svg/timeline-svg.js +10 -5
- package/dist/lib/renderers/svg/timeline-svg.js.map +1 -1
- package/dist/lib/renderers/webgpu/graph-flow-effects.d.ts +2 -2
- package/dist/lib/renderers/webgpu/graph-flow-effects.d.ts.map +1 -1
- package/dist/lib/renderers/webgpu/graph-flow-effects.js.map +1 -1
- package/package.json +3 -1
- package/styles.css +8 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { Box, DiagramEdge, DiagramGroup, DiagramNode, DiagramSide } from '../../model/diagram-ir.ts';
|
|
2
|
+
import type { NodeLayout, TextRun } from './graph-layout-result.ts';
|
|
3
|
+
import type { LayoutTokens } from './tokens.ts';
|
|
4
|
+
type Sides = Record<DiagramSide, number>;
|
|
5
|
+
export type MeasuredNode = {
|
|
6
|
+
/** The smallest frame that holds the node's content. */
|
|
7
|
+
frame: {
|
|
8
|
+
w: number;
|
|
9
|
+
h: number;
|
|
10
|
+
};
|
|
11
|
+
/** How far the stacked frames and the caption reach outside the frame. */
|
|
12
|
+
overhang: Sides;
|
|
13
|
+
/** Whether the frame grows to fill its grid area. */
|
|
14
|
+
stretch: boolean;
|
|
15
|
+
/** Positions everything the node draws, given its final frame (at least `frame`). */
|
|
16
|
+
place(box: Box): Omit<NodeLayout, 'node'>;
|
|
17
|
+
};
|
|
18
|
+
export declare function measureNode(node: DiagramNode, tokens: LayoutTokens): MeasuredNode;
|
|
19
|
+
export type MeasuredGroupTitle = {
|
|
20
|
+
/** The height the title reserves on its side, BAND_PAD above and below included; 0 without a label. */
|
|
21
|
+
height: number;
|
|
22
|
+
place(rect: Box): {
|
|
23
|
+
band?: Box;
|
|
24
|
+
label: TextRun[];
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
export declare function measureGroupTitle(group: DiagramGroup, tokens: LayoutTokens): MeasuredGroupTitle;
|
|
28
|
+
export type MeasuredEdgeLabel = {
|
|
29
|
+
w: number;
|
|
30
|
+
h: number;
|
|
31
|
+
place(box: Box): TextRun[];
|
|
32
|
+
};
|
|
33
|
+
export declare function measureEdgeLabel(edge: DiagramEdge, tokens: LayoutTokens): MeasuredEdgeLabel;
|
|
34
|
+
export type MeasuredEdgeBadge = {
|
|
35
|
+
w: number;
|
|
36
|
+
h: number;
|
|
37
|
+
place(box: Box): {
|
|
38
|
+
icon?: Box;
|
|
39
|
+
text: TextRun[];
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
export declare function measureEdgeBadge(edge: DiagramEdge, tokens: LayoutTokens): MeasuredEdgeBadge;
|
|
43
|
+
export {};
|
|
44
|
+
//# sourceMappingURL=measure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"measure.d.ts","sourceRoot":"","sources":["../../../../src/lib/layouts/graph/measure.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,GAAG,EACH,WAAW,EACX,YAAY,EACZ,WAAW,EAEX,WAAW,EACZ,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAGpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,KAAK,KAAK,GAAG,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;AAEzC,MAAM,MAAM,YAAY,GAAG;IACzB,wDAAwD;IACxD,KAAK,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAChC,0EAA0E;IAC1E,QAAQ,EAAE,KAAK,CAAC;IAChB,qDAAqD;IACrD,OAAO,EAAE,OAAO,CAAC;IACjB,qFAAqF;IACrF,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;CAC3C,CAAC;AAWF,wBAAgB,WAAW,CACzB,IAAI,EAAE,WAAW,EACjB,MAAM,EAAE,YAAY,GACnB,YAAY,CAiDd;AA6MD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,uGAAuG;IACvG,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,IAAI,EAAE,GAAG,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,OAAO,EAAE,CAAA;KAAE,CAAC;CACpD,CAAC;AAEF,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,YAAY,GACnB,kBAAkB,CAwBpB;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,EAAE,CAAC;CAC5B,CAAC;AAEF,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,WAAW,EACjB,MAAM,EAAE,YAAY,GACnB,iBAAiB,CAQnB;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,IAAI,EAAE,OAAO,EAAE,CAAA;KAAE,CAAC;CAClD,CAAC;AAEF,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,WAAW,EACjB,MAAM,EAAE,YAAY,GACnB,iBAAiB,CAiBnB"}
|
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
import { nodeContent } from "./node-content.js";
|
|
2
|
+
import { labelLines, textBlock } from "./text-block.js";
|
|
3
|
+
/** The distance from a port's point to its label: the port marker's radius plus a gap. */
|
|
4
|
+
const PORT_LABEL_OFFSET = 8;
|
|
5
|
+
const EDGE_LABEL_FRAME_PAD = 4;
|
|
6
|
+
/** Mirrors the badge drawn before content sizing: 8px side inset, 6px above and below, 24px content at least. */
|
|
7
|
+
const BADGE_PAD = {
|
|
8
|
+
x: 8,
|
|
9
|
+
y: 6
|
|
10
|
+
};
|
|
11
|
+
const BADGE_MIN_CONTENT = 24;
|
|
12
|
+
const SIDES = ['top', 'right', 'bottom', 'left'];
|
|
13
|
+
export function measureNode(node, tokens) {
|
|
14
|
+
const kind = node.kind ?? 'node';
|
|
15
|
+
if (node.hidden && kind === 'node') return hiddenNode();
|
|
16
|
+
const content = nodeContent(node, tokens);
|
|
17
|
+
const ports = portGeometry(node.ports ?? [], tokens);
|
|
18
|
+
const w = Math.max(content.w + 2 * content.pad.x + ports.inset.left + ports.inset.right, ports.minLength.top, ports.minLength.bottom);
|
|
19
|
+
const h = Math.max(content.h + 2 * content.pad.y + ports.inset.top + ports.inset.bottom, ports.minLength.left, ports.minLength.right);
|
|
20
|
+
const place = box => {
|
|
21
|
+
const inner = inset(inset(box, ports.inset), {
|
|
22
|
+
top: content.pad.y,
|
|
23
|
+
bottom: content.pad.y,
|
|
24
|
+
left: content.pad.x,
|
|
25
|
+
right: content.pad.x
|
|
26
|
+
});
|
|
27
|
+
const frames = stackFrames(node, box, tokens);
|
|
28
|
+
const caption = placeCaption(node, union([box, ...frames]), tokens);
|
|
29
|
+
return {
|
|
30
|
+
box,
|
|
31
|
+
visual: union([box, ...frames, ...(caption ? [caption.box] : [])]),
|
|
32
|
+
frames,
|
|
33
|
+
radius: frameRadius(node, box, tokens),
|
|
34
|
+
...content.place(inner),
|
|
35
|
+
...(caption ? {
|
|
36
|
+
caption
|
|
37
|
+
} : {}),
|
|
38
|
+
ports: ports.place(box)
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
const {
|
|
42
|
+
visual
|
|
43
|
+
} = place({
|
|
44
|
+
x: 0,
|
|
45
|
+
y: 0,
|
|
46
|
+
w,
|
|
47
|
+
h
|
|
48
|
+
});
|
|
49
|
+
return {
|
|
50
|
+
frame: {
|
|
51
|
+
w,
|
|
52
|
+
h
|
|
53
|
+
},
|
|
54
|
+
overhang: {
|
|
55
|
+
top: 0 - visual.y,
|
|
56
|
+
left: 0 - visual.x,
|
|
57
|
+
bottom: visual.y + visual.h - h,
|
|
58
|
+
right: visual.x + visual.w - w
|
|
59
|
+
},
|
|
60
|
+
stretch: kind === 'node' && (node.stretch ?? true),
|
|
61
|
+
place
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function hiddenNode() {
|
|
65
|
+
return {
|
|
66
|
+
frame: {
|
|
67
|
+
w: 0,
|
|
68
|
+
h: 0
|
|
69
|
+
},
|
|
70
|
+
overhang: {
|
|
71
|
+
top: 0,
|
|
72
|
+
right: 0,
|
|
73
|
+
bottom: 0,
|
|
74
|
+
left: 0
|
|
75
|
+
},
|
|
76
|
+
stretch: false,
|
|
77
|
+
place: box => ({
|
|
78
|
+
box,
|
|
79
|
+
visual: box,
|
|
80
|
+
frames: [],
|
|
81
|
+
radius: 0,
|
|
82
|
+
text: [],
|
|
83
|
+
bullets: [],
|
|
84
|
+
ports: []
|
|
85
|
+
})
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function frameRadius(node, box, tokens) {
|
|
89
|
+
switch (node.kind) {
|
|
90
|
+
case 'connector':
|
|
91
|
+
return box.h / 2;
|
|
92
|
+
case 'junction':
|
|
93
|
+
return Math.min(box.w, box.h) / 2;
|
|
94
|
+
case 'marker':
|
|
95
|
+
case 'appliance':
|
|
96
|
+
case 'note':
|
|
97
|
+
return 0;
|
|
98
|
+
default:
|
|
99
|
+
if (node.frame === 'none') return 0;
|
|
100
|
+
return node.frame === 'flat' ? tokens.FLAT_RADIUS : tokens.RADIUS;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Ports sit evenly along their side, with their labels inside the frame. A
|
|
106
|
+
* side's labels push the content inward, and a side with k ports is long
|
|
107
|
+
* enough for k + 1 port spacings.
|
|
108
|
+
*/
|
|
109
|
+
function portGeometry(ports, tokens) {
|
|
110
|
+
const font = tokens.fonts.portLabel;
|
|
111
|
+
const bySide = new Map(SIDES.map(side => [side, ports.filter(port => port.side === side).map(port => ({
|
|
112
|
+
port,
|
|
113
|
+
label: port.label ? textBlock(labelLines(port.label, port.accent ? 'accent' : undefined), font) : undefined
|
|
114
|
+
}))]));
|
|
115
|
+
const widest = side => Math.max(0, ...bySide.get(side).map(({
|
|
116
|
+
label
|
|
117
|
+
}) => label?.w ?? 0));
|
|
118
|
+
const tallest = side => Math.max(0, ...bySide.get(side).map(({
|
|
119
|
+
label
|
|
120
|
+
}) => label?.h ?? 0));
|
|
121
|
+
const labelDepth = side => {
|
|
122
|
+
const depth = side === 'left' || side === 'right' ? widest(side) : tallest(side);
|
|
123
|
+
return depth > 0 ? PORT_LABEL_OFFSET + depth : 0;
|
|
124
|
+
};
|
|
125
|
+
const sideLength = side => {
|
|
126
|
+
const count = bySide.get(side).length;
|
|
127
|
+
if (count === 0) return 0;
|
|
128
|
+
const labelLength = side === 'top' || side === 'bottom' ? widest(side) : tallest(side);
|
|
129
|
+
const pitch = Math.max(tokens.PORT_SPACING, labelLength + tokens.LABEL_GAP);
|
|
130
|
+
return (count + 1) * pitch;
|
|
131
|
+
};
|
|
132
|
+
return {
|
|
133
|
+
inset: sidesOf(labelDepth),
|
|
134
|
+
minLength: sidesOf(sideLength),
|
|
135
|
+
place: box => SIDES.flatMap(side => {
|
|
136
|
+
const onSide = bySide.get(side);
|
|
137
|
+
return onSide.map(({
|
|
138
|
+
port,
|
|
139
|
+
label
|
|
140
|
+
}, index) => {
|
|
141
|
+
const fraction = (index + 1) / (onSide.length + 1);
|
|
142
|
+
const point = portPoint(box, side, fraction);
|
|
143
|
+
const run = label && placePortLabel(label, point, side)[0];
|
|
144
|
+
return {
|
|
145
|
+
id: port.id,
|
|
146
|
+
side,
|
|
147
|
+
point,
|
|
148
|
+
...(run ? {
|
|
149
|
+
label: run
|
|
150
|
+
} : {})
|
|
151
|
+
};
|
|
152
|
+
});
|
|
153
|
+
})
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** The point `fraction` of the way along `side` of `box`. */
|
|
158
|
+
function portPoint(box, side, fraction) {
|
|
159
|
+
switch (side) {
|
|
160
|
+
case 'top':
|
|
161
|
+
return {
|
|
162
|
+
x: box.x + box.w * fraction,
|
|
163
|
+
y: box.y
|
|
164
|
+
};
|
|
165
|
+
case 'bottom':
|
|
166
|
+
return {
|
|
167
|
+
x: box.x + box.w * fraction,
|
|
168
|
+
y: box.y + box.h
|
|
169
|
+
};
|
|
170
|
+
case 'left':
|
|
171
|
+
return {
|
|
172
|
+
x: box.x,
|
|
173
|
+
y: box.y + box.h * fraction
|
|
174
|
+
};
|
|
175
|
+
case 'right':
|
|
176
|
+
return {
|
|
177
|
+
x: box.x + box.w,
|
|
178
|
+
y: box.y + box.h * fraction
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
function placePortLabel(label, point, side) {
|
|
183
|
+
switch (side) {
|
|
184
|
+
case 'left':
|
|
185
|
+
return label.place(point.x + PORT_LABEL_OFFSET, point.y - label.h / 2, 'start');
|
|
186
|
+
case 'right':
|
|
187
|
+
return label.place(point.x - PORT_LABEL_OFFSET, point.y - label.h / 2, 'end');
|
|
188
|
+
case 'top':
|
|
189
|
+
return label.place(point.x, point.y + PORT_LABEL_OFFSET, 'middle');
|
|
190
|
+
case 'bottom':
|
|
191
|
+
return label.place(point.x, point.y - PORT_LABEL_OFFSET - label.h, 'middle');
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/** The back frames of a stack, farthest first, each one STACK_STEP further in the stack direction. */
|
|
196
|
+
function stackFrames(node, box, tokens) {
|
|
197
|
+
const count = Math.max(1, Math.floor(node.stack ?? 1));
|
|
198
|
+
const kind = node.kind ?? 'node';
|
|
199
|
+
if (count === 1 || kind !== 'node' || node.frame === 'none') return [];
|
|
200
|
+
const direction = node.stackDirection ?? 'up-left';
|
|
201
|
+
const dx = (direction.endsWith('left') ? -1 : 1) * tokens.STACK_STEP.x;
|
|
202
|
+
const dy = (direction.startsWith('up') ? -1 : 1) * tokens.STACK_STEP.y;
|
|
203
|
+
return Array.from({
|
|
204
|
+
length: count - 1
|
|
205
|
+
}, (_, index) => {
|
|
206
|
+
const level = count - 1 - index;
|
|
207
|
+
return {
|
|
208
|
+
...box,
|
|
209
|
+
x: box.x + level * dx,
|
|
210
|
+
y: box.y + level * dy
|
|
211
|
+
};
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/** The caption sits beside `box`, the frame together with its stacked back frames. */
|
|
216
|
+
function placeCaption(node, box, tokens) {
|
|
217
|
+
const font = tokens.fonts.caption;
|
|
218
|
+
const lines = textBlock(labelLines([node.caption ?? []].flat().map(line => line.trim()), node.captionColor), font);
|
|
219
|
+
if (lines.h === 0) return undefined;
|
|
220
|
+
const framed = node.captionFrame ?? false;
|
|
221
|
+
const pad = framed ? {
|
|
222
|
+
x: 0.9 * font.size,
|
|
223
|
+
y: 0.55 * font.size
|
|
224
|
+
} : {
|
|
225
|
+
x: 0,
|
|
226
|
+
y: 0
|
|
227
|
+
};
|
|
228
|
+
const w = lines.w + 2 * pad.x;
|
|
229
|
+
const h = lines.h + 2 * pad.y;
|
|
230
|
+
const gap = tokens.CAPTION_GAP;
|
|
231
|
+
const side = node.captionSide ?? 'bottom';
|
|
232
|
+
const centreX = box.x + (box.w - w) / 2;
|
|
233
|
+
const centreY = box.y + (box.h - h) / 2;
|
|
234
|
+
const captionBox = {
|
|
235
|
+
top: {
|
|
236
|
+
x: centreX,
|
|
237
|
+
y: box.y - gap - h,
|
|
238
|
+
w,
|
|
239
|
+
h
|
|
240
|
+
},
|
|
241
|
+
bottom: {
|
|
242
|
+
x: centreX,
|
|
243
|
+
y: box.y + box.h + gap,
|
|
244
|
+
w,
|
|
245
|
+
h
|
|
246
|
+
},
|
|
247
|
+
left: {
|
|
248
|
+
x: box.x - gap - w,
|
|
249
|
+
y: centreY,
|
|
250
|
+
w,
|
|
251
|
+
h
|
|
252
|
+
},
|
|
253
|
+
right: {
|
|
254
|
+
x: box.x + box.w + gap,
|
|
255
|
+
y: centreY,
|
|
256
|
+
w,
|
|
257
|
+
h
|
|
258
|
+
}
|
|
259
|
+
}[side];
|
|
260
|
+
const top = captionBox.y + pad.y;
|
|
261
|
+
let text;
|
|
262
|
+
if (side === 'left') {
|
|
263
|
+
text = lines.place(captionBox.x + w - pad.x, top, 'end');
|
|
264
|
+
} else if (side === 'right') {
|
|
265
|
+
text = lines.place(captionBox.x + pad.x, top, 'start');
|
|
266
|
+
} else {
|
|
267
|
+
text = lines.place(captionBox.x + w / 2, top, 'middle');
|
|
268
|
+
}
|
|
269
|
+
return {
|
|
270
|
+
box: captionBox,
|
|
271
|
+
framed,
|
|
272
|
+
text
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
export function measureGroupTitle(group, tokens) {
|
|
276
|
+
const lines = textBlock(labelLines(group.label), tokens.fonts.groupLabel);
|
|
277
|
+
const height = lines.h > 0 ? lines.h + 2 * tokens.BAND_PAD : 0;
|
|
278
|
+
return {
|
|
279
|
+
height,
|
|
280
|
+
place(rect) {
|
|
281
|
+
if (height === 0) return {
|
|
282
|
+
label: []
|
|
283
|
+
};
|
|
284
|
+
const y = group.labelSide === 'bottom' ? rect.y + rect.h - height : rect.y;
|
|
285
|
+
const top = y + tokens.BAND_PAD;
|
|
286
|
+
const align = group.labelAlign ?? 'center';
|
|
287
|
+
let label;
|
|
288
|
+
if (align === 'start') {
|
|
289
|
+
label = lines.place(rect.x + tokens.PAD_X, top, 'start');
|
|
290
|
+
} else if (align === 'end') {
|
|
291
|
+
label = lines.place(rect.x + rect.w - tokens.PAD_X, top, 'end');
|
|
292
|
+
} else {
|
|
293
|
+
label = lines.place(rect.x + rect.w / 2, top, 'middle');
|
|
294
|
+
}
|
|
295
|
+
return group.titleBand ? {
|
|
296
|
+
band: {
|
|
297
|
+
x: rect.x,
|
|
298
|
+
y,
|
|
299
|
+
w: rect.w,
|
|
300
|
+
h: height
|
|
301
|
+
},
|
|
302
|
+
label
|
|
303
|
+
} : {
|
|
304
|
+
label
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
export function measureEdgeLabel(edge, tokens) {
|
|
310
|
+
const lines = textBlock(labelLines(edge.label), tokens.fonts.edgeLabel);
|
|
311
|
+
const pad = edge.labelFrame ? EDGE_LABEL_FRAME_PAD : 0;
|
|
312
|
+
return {
|
|
313
|
+
w: lines.w + 2 * pad,
|
|
314
|
+
h: lines.h + 2 * pad,
|
|
315
|
+
place: box => lines.place(box.x + box.w / 2, box.y + pad, 'middle')
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
export function measureEdgeBadge(edge, tokens) {
|
|
319
|
+
const lines = textBlock(labelLines(edge.badgeLabel), tokens.fonts.badge);
|
|
320
|
+
const icon = edge.badgeIcon ? tokens.BADGE_ICON : 0;
|
|
321
|
+
const gap = icon > 0 && lines.w > 0 ? tokens.BLOCK_GAP : 0;
|
|
322
|
+
const rowW = icon + gap + lines.w;
|
|
323
|
+
return {
|
|
324
|
+
w: Math.max(BADGE_MIN_CONTENT, rowW) + 2 * BADGE_PAD.x,
|
|
325
|
+
h: Math.max(BADGE_MIN_CONTENT, lines.h) + 2 * BADGE_PAD.y,
|
|
326
|
+
place(box) {
|
|
327
|
+
const x = box.x + (box.w - rowW) / 2;
|
|
328
|
+
const cy = box.y + box.h / 2;
|
|
329
|
+
const text = lines.place(x + icon + gap, cy - lines.h / 2, 'start');
|
|
330
|
+
return icon > 0 ? {
|
|
331
|
+
icon: {
|
|
332
|
+
x,
|
|
333
|
+
y: cy - icon / 2,
|
|
334
|
+
w: icon,
|
|
335
|
+
h: icon
|
|
336
|
+
},
|
|
337
|
+
text
|
|
338
|
+
} : {
|
|
339
|
+
text
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
function sidesOf(value) {
|
|
345
|
+
return {
|
|
346
|
+
top: value('top'),
|
|
347
|
+
right: value('right'),
|
|
348
|
+
bottom: value('bottom'),
|
|
349
|
+
left: value('left')
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
function inset(box, by) {
|
|
353
|
+
return {
|
|
354
|
+
x: box.x + by.left,
|
|
355
|
+
y: box.y + by.top,
|
|
356
|
+
w: box.w - by.left - by.right,
|
|
357
|
+
h: box.h - by.top - by.bottom
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
function union(boxes) {
|
|
361
|
+
const left = Math.min(...boxes.map(box => box.x));
|
|
362
|
+
const top = Math.min(...boxes.map(box => box.y));
|
|
363
|
+
const right = Math.max(...boxes.map(box => box.x + box.w));
|
|
364
|
+
const bottom = Math.max(...boxes.map(box => box.y + box.h));
|
|
365
|
+
return {
|
|
366
|
+
x: left,
|
|
367
|
+
y: top,
|
|
368
|
+
w: right - left,
|
|
369
|
+
h: bottom - top
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
//# sourceMappingURL=measure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"measure.js","names":["nodeContent","labelLines","textBlock","PORT_LABEL_OFFSET","EDGE_LABEL_FRAME_PAD","BADGE_PAD","x","y","BADGE_MIN_CONTENT","SIDES","measureNode","node","tokens","kind","hidden","hiddenNode","content","ports","portGeometry","w","Math","max","pad","inset","left","right","minLength","top","bottom","h","place","box","inner","frames","stackFrames","caption","placeCaption","union","visual","radius","frameRadius","frame","overhang","stretch","text","bullets","min","FLAT_RADIUS","RADIUS","font","fonts","portLabel","bySide","Map","map","side","filter","port","label","accent","undefined","widest","get","tallest","labelDepth","depth","sideLength","count","length","labelLength","pitch","PORT_SPACING","LABEL_GAP","sidesOf","flatMap","onSide","index","fraction","point","portPoint","run","placePortLabel","id","floor","stack","direction","stackDirection","dx","endsWith","STACK_STEP","dy","startsWith","Array","from","_","level","lines","flat","line","trim","captionColor","framed","captionFrame","size","gap","CAPTION_GAP","captionSide","centreX","centreY","captionBox","measureGroupTitle","group","groupLabel","height","BAND_PAD","rect","labelSide","align","labelAlign","PAD_X","titleBand","band","measureEdgeLabel","edge","edgeLabel","labelFrame","measureEdgeBadge","badgeLabel","badge","icon","badgeIcon","BADGE_ICON","BLOCK_GAP","rowW","cy","value","by","boxes"],"sources":["../../../../src/lib/layouts/graph/measure.ts"],"sourcesContent":["import type {\n Box,\n DiagramEdge,\n DiagramGroup,\n DiagramNode,\n DiagramNodePort,\n DiagramSide,\n} from '../../model/diagram-ir.ts';\nimport type { NodeLayout, TextRun } from './graph-layout-result.ts';\nimport { nodeContent } from './node-content.ts';\nimport { type TextBlock, labelLines, textBlock } from './text-block.ts';\nimport type { LayoutTokens } from './tokens.ts';\n\ntype Sides = Record<DiagramSide, number>;\n\nexport type MeasuredNode = {\n /** The smallest frame that holds the node's content. */\n frame: { w: number; h: number };\n /** How far the stacked frames and the caption reach outside the frame. */\n overhang: Sides;\n /** Whether the frame grows to fill its grid area. */\n stretch: boolean;\n /** Positions everything the node draws, given its final frame (at least `frame`). */\n place(box: Box): Omit<NodeLayout, 'node'>;\n};\n\n/** The distance from a port's point to its label: the port marker's radius plus a gap. */\nconst PORT_LABEL_OFFSET = 8;\nconst EDGE_LABEL_FRAME_PAD = 4;\n/** Mirrors the badge drawn before content sizing: 8px side inset, 6px above and below, 24px content at least. */\nconst BADGE_PAD = { x: 8, y: 6 };\nconst BADGE_MIN_CONTENT = 24;\n\nconst SIDES: DiagramSide[] = ['top', 'right', 'bottom', 'left'];\n\nexport function measureNode(\n node: DiagramNode,\n tokens: LayoutTokens,\n): MeasuredNode {\n const kind = node.kind ?? 'node';\n if (node.hidden && kind === 'node') return hiddenNode();\n\n const content = nodeContent(node, tokens);\n const ports = portGeometry(node.ports ?? [], tokens);\n const w = Math.max(\n content.w + 2 * content.pad.x + ports.inset.left + ports.inset.right,\n ports.minLength.top,\n ports.minLength.bottom,\n );\n const h = Math.max(\n content.h + 2 * content.pad.y + ports.inset.top + ports.inset.bottom,\n ports.minLength.left,\n ports.minLength.right,\n );\n\n const place = (box: Box): Omit<NodeLayout, 'node'> => {\n const inner = inset(inset(box, ports.inset), {\n top: content.pad.y,\n bottom: content.pad.y,\n left: content.pad.x,\n right: content.pad.x,\n });\n const frames = stackFrames(node, box, tokens);\n const caption = placeCaption(node, union([box, ...frames]), tokens);\n return {\n box,\n visual: union([box, ...frames, ...(caption ? [caption.box] : [])]),\n frames,\n radius: frameRadius(node, box, tokens),\n ...content.place(inner),\n ...(caption ? { caption } : {}),\n ports: ports.place(box),\n };\n };\n\n const { visual } = place({ x: 0, y: 0, w, h });\n return {\n frame: { w, h },\n overhang: {\n top: 0 - visual.y,\n left: 0 - visual.x,\n bottom: visual.y + visual.h - h,\n right: visual.x + visual.w - w,\n },\n stretch: kind === 'node' && (node.stretch ?? true),\n place,\n };\n}\n\nfunction hiddenNode(): MeasuredNode {\n return {\n frame: { w: 0, h: 0 },\n overhang: { top: 0, right: 0, bottom: 0, left: 0 },\n stretch: false,\n place: (box) => ({\n box,\n visual: box,\n frames: [],\n radius: 0,\n text: [],\n bullets: [],\n ports: [],\n }),\n };\n}\n\nfunction frameRadius(\n node: DiagramNode,\n box: Box,\n tokens: LayoutTokens,\n): number {\n switch (node.kind) {\n case 'connector':\n return box.h / 2;\n case 'junction':\n return Math.min(box.w, box.h) / 2;\n case 'marker':\n case 'appliance':\n case 'note':\n return 0;\n default:\n if (node.frame === 'none') return 0;\n return node.frame === 'flat' ? tokens.FLAT_RADIUS : tokens.RADIUS;\n }\n}\n\n/**\n * Ports sit evenly along their side, with their labels inside the frame. A\n * side's labels push the content inward, and a side with k ports is long\n * enough for k + 1 port spacings.\n */\nfunction portGeometry(ports: DiagramNodePort[], tokens: LayoutTokens) {\n const font = tokens.fonts.portLabel;\n const bySide = new Map(\n SIDES.map((side) => [\n side,\n ports\n .filter((port) => port.side === side)\n .map((port) => ({\n port,\n label: port.label\n ? textBlock(\n labelLines(port.label, port.accent ? 'accent' : undefined),\n font,\n )\n : undefined,\n })),\n ]),\n );\n const widest = (side: DiagramSide) =>\n Math.max(0, ...bySide.get(side)!.map(({ label }) => label?.w ?? 0));\n const tallest = (side: DiagramSide) =>\n Math.max(0, ...bySide.get(side)!.map(({ label }) => label?.h ?? 0));\n const labelDepth = (side: DiagramSide) => {\n const depth =\n side === 'left' || side === 'right' ? widest(side) : tallest(side);\n return depth > 0 ? PORT_LABEL_OFFSET + depth : 0;\n };\n const sideLength = (side: DiagramSide) => {\n const count = bySide.get(side)!.length;\n if (count === 0) return 0;\n const labelLength =\n side === 'top' || side === 'bottom' ? widest(side) : tallest(side);\n const pitch = Math.max(tokens.PORT_SPACING, labelLength + tokens.LABEL_GAP);\n return (count + 1) * pitch;\n };\n\n return {\n inset: sidesOf(labelDepth),\n minLength: sidesOf(sideLength),\n place: (box: Box): NodeLayout['ports'] =>\n SIDES.flatMap((side) => {\n const onSide = bySide.get(side)!;\n return onSide.map(({ port, label }, index) => {\n const fraction = (index + 1) / (onSide.length + 1);\n const point = portPoint(box, side, fraction);\n const run = label && placePortLabel(label, point, side)[0];\n return {\n id: port.id,\n side,\n point,\n ...(run ? { label: run } : {}),\n };\n });\n }),\n };\n}\n\n/** The point `fraction` of the way along `side` of `box`. */\nfunction portPoint(\n box: Box,\n side: DiagramSide,\n fraction: number,\n): { x: number; y: number } {\n switch (side) {\n case 'top':\n return { x: box.x + box.w * fraction, y: box.y };\n case 'bottom':\n return { x: box.x + box.w * fraction, y: box.y + box.h };\n case 'left':\n return { x: box.x, y: box.y + box.h * fraction };\n case 'right':\n return { x: box.x + box.w, y: box.y + box.h * fraction };\n }\n}\n\nfunction placePortLabel(\n label: TextBlock,\n point: { x: number; y: number },\n side: DiagramSide,\n): TextRun[] {\n switch (side) {\n case 'left':\n return label.place(\n point.x + PORT_LABEL_OFFSET,\n point.y - label.h / 2,\n 'start',\n );\n case 'right':\n return label.place(\n point.x - PORT_LABEL_OFFSET,\n point.y - label.h / 2,\n 'end',\n );\n case 'top':\n return label.place(point.x, point.y + PORT_LABEL_OFFSET, 'middle');\n case 'bottom':\n return label.place(\n point.x,\n point.y - PORT_LABEL_OFFSET - label.h,\n 'middle',\n );\n }\n}\n\n/** The back frames of a stack, farthest first, each one STACK_STEP further in the stack direction. */\nfunction stackFrames(node: DiagramNode, box: Box, tokens: LayoutTokens): Box[] {\n const count = Math.max(1, Math.floor(node.stack ?? 1));\n const kind = node.kind ?? 'node';\n if (count === 1 || kind !== 'node' || node.frame === 'none') return [];\n const direction = node.stackDirection ?? 'up-left';\n const dx = (direction.endsWith('left') ? -1 : 1) * tokens.STACK_STEP.x;\n const dy = (direction.startsWith('up') ? -1 : 1) * tokens.STACK_STEP.y;\n return Array.from({ length: count - 1 }, (_, index) => {\n const level = count - 1 - index;\n return { ...box, x: box.x + level * dx, y: box.y + level * dy };\n });\n}\n\n/** The caption sits beside `box`, the frame together with its stacked back frames. */\nfunction placeCaption(\n node: DiagramNode,\n box: Box,\n tokens: LayoutTokens,\n): NodeLayout['caption'] {\n const font = tokens.fonts.caption;\n const lines = textBlock(\n labelLines(\n [node.caption ?? []].flat().map((line) => line.trim()),\n node.captionColor,\n ),\n font,\n );\n if (lines.h === 0) return undefined;\n const framed = node.captionFrame ?? false;\n const pad = framed\n ? { x: 0.9 * font.size, y: 0.55 * font.size }\n : { x: 0, y: 0 };\n const w = lines.w + 2 * pad.x;\n const h = lines.h + 2 * pad.y;\n const gap = tokens.CAPTION_GAP;\n const side = node.captionSide ?? 'bottom';\n const centreX = box.x + (box.w - w) / 2;\n const centreY = box.y + (box.h - h) / 2;\n const captionBox: Box = {\n top: { x: centreX, y: box.y - gap - h, w, h },\n bottom: { x: centreX, y: box.y + box.h + gap, w, h },\n left: { x: box.x - gap - w, y: centreY, w, h },\n right: { x: box.x + box.w + gap, y: centreY, w, h },\n }[side];\n const top = captionBox.y + pad.y;\n let text: TextRun[];\n if (side === 'left') {\n text = lines.place(captionBox.x + w - pad.x, top, 'end');\n } else if (side === 'right') {\n text = lines.place(captionBox.x + pad.x, top, 'start');\n } else {\n text = lines.place(captionBox.x + w / 2, top, 'middle');\n }\n return { box: captionBox, framed, text };\n}\n\nexport type MeasuredGroupTitle = {\n /** The height the title reserves on its side, BAND_PAD above and below included; 0 without a label. */\n height: number;\n place(rect: Box): { band?: Box; label: TextRun[] };\n};\n\nexport function measureGroupTitle(\n group: DiagramGroup,\n tokens: LayoutTokens,\n): MeasuredGroupTitle {\n const lines = textBlock(labelLines(group.label), tokens.fonts.groupLabel);\n const height = lines.h > 0 ? lines.h + 2 * tokens.BAND_PAD : 0;\n return {\n height,\n place(rect) {\n if (height === 0) return { label: [] };\n const y =\n group.labelSide === 'bottom' ? rect.y + rect.h - height : rect.y;\n const top = y + tokens.BAND_PAD;\n const align = group.labelAlign ?? 'center';\n let label: TextRun[];\n if (align === 'start') {\n label = lines.place(rect.x + tokens.PAD_X, top, 'start');\n } else if (align === 'end') {\n label = lines.place(rect.x + rect.w - tokens.PAD_X, top, 'end');\n } else {\n label = lines.place(rect.x + rect.w / 2, top, 'middle');\n }\n return group.titleBand\n ? { band: { x: rect.x, y, w: rect.w, h: height }, label }\n : { label };\n },\n };\n}\n\nexport type MeasuredEdgeLabel = {\n w: number;\n h: number;\n place(box: Box): TextRun[];\n};\n\nexport function measureEdgeLabel(\n edge: DiagramEdge,\n tokens: LayoutTokens,\n): MeasuredEdgeLabel {\n const lines = textBlock(labelLines(edge.label), tokens.fonts.edgeLabel);\n const pad = edge.labelFrame ? EDGE_LABEL_FRAME_PAD : 0;\n return {\n w: lines.w + 2 * pad,\n h: lines.h + 2 * pad,\n place: (box) => lines.place(box.x + box.w / 2, box.y + pad, 'middle'),\n };\n}\n\nexport type MeasuredEdgeBadge = {\n w: number;\n h: number;\n place(box: Box): { icon?: Box; text: TextRun[] };\n};\n\nexport function measureEdgeBadge(\n edge: DiagramEdge,\n tokens: LayoutTokens,\n): MeasuredEdgeBadge {\n const lines = textBlock(labelLines(edge.badgeLabel), tokens.fonts.badge);\n const icon = edge.badgeIcon ? tokens.BADGE_ICON : 0;\n const gap = icon > 0 && lines.w > 0 ? tokens.BLOCK_GAP : 0;\n const rowW = icon + gap + lines.w;\n return {\n w: Math.max(BADGE_MIN_CONTENT, rowW) + 2 * BADGE_PAD.x,\n h: Math.max(BADGE_MIN_CONTENT, lines.h) + 2 * BADGE_PAD.y,\n place(box) {\n const x = box.x + (box.w - rowW) / 2;\n const cy = box.y + box.h / 2;\n const text = lines.place(x + icon + gap, cy - lines.h / 2, 'start');\n return icon > 0\n ? { icon: { x, y: cy - icon / 2, w: icon, h: icon }, text }\n : { text };\n },\n };\n}\n\nfunction sidesOf(value: (side: DiagramSide) => number): Sides {\n return {\n top: value('top'),\n right: value('right'),\n bottom: value('bottom'),\n left: value('left'),\n };\n}\n\nfunction inset(box: Box, by: Sides): Box {\n return {\n x: box.x + by.left,\n y: box.y + by.top,\n w: box.w - by.left - by.right,\n h: box.h - by.top - by.bottom,\n };\n}\n\nfunction union(boxes: Box[]): Box {\n const left = Math.min(...boxes.map((box) => box.x));\n const top = Math.min(...boxes.map((box) => box.y));\n const right = Math.max(...boxes.map((box) => box.x + box.w));\n const bottom = Math.max(...boxes.map((box) => box.y + box.h));\n return { x: left, y: top, w: right - left, h: bottom - top };\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Box, DiagramNode } from '../../model/diagram-ir.ts';
|
|
2
|
+
import type { NodeLayout } from './graph-layout-result.ts';
|
|
3
|
+
import type { LayoutTokens } from './tokens.ts';
|
|
4
|
+
export type ContentPlacement = Pick<NodeLayout, 'text' | 'bullets'> & Partial<Pick<NodeLayout, 'icon' | 'appliance'>>;
|
|
5
|
+
/** What a node draws inside its frame: its measured size, the padding around it, and where it goes. */
|
|
6
|
+
export type NodeContent = {
|
|
7
|
+
w: number;
|
|
8
|
+
h: number;
|
|
9
|
+
pad: {
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
};
|
|
13
|
+
place(inner: Box): ContentPlacement;
|
|
14
|
+
};
|
|
15
|
+
export declare function nodeContent(node: DiagramNode, tokens: LayoutTokens): NodeContent;
|
|
16
|
+
//# sourceMappingURL=node-content.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-content.d.ts","sourceRoot":"","sources":["../../../../src/lib/layouts/graph/node-content.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAS,MAAM,2BAA2B,CAAC;AACzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC,GACjE,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC;AAElD,uGAAuG;AACvG,MAAM,MAAM,WAAW,GAAG;IACxB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,GAAG,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9B,KAAK,CAAC,KAAK,EAAE,GAAG,GAAG,gBAAgB,CAAC;CACrC,CAAC;AAQF,wBAAgB,WAAW,CACzB,IAAI,EAAE,WAAW,EACjB,MAAM,EAAE,YAAY,GACnB,WAAW,CAeb"}
|