@oh-just-another/importers 0.57.0
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/CHANGELOG.md +14 -0
- package/LICENSE +21 -0
- package/README.md +76 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/dot.d.ts +19 -0
- package/dist/dot.d.ts.map +1 -0
- package/dist/dot.js +246 -0
- package/dist/dot.js.map +1 -0
- package/dist/drawio.d.ts +19 -0
- package/dist/drawio.d.ts.map +1 -0
- package/dist/drawio.js +121 -0
- package/dist/drawio.js.map +1 -0
- package/dist/graph.d.ts +40 -0
- package/dist/graph.d.ts.map +1 -0
- package/dist/graph.js +2 -0
- package/dist/graph.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/layout.d.ts +22 -0
- package/dist/layout.d.ts.map +1 -0
- package/dist/layout.js +78 -0
- package/dist/layout.js.map +1 -0
- package/dist/mermaid.d.ts +22 -0
- package/dist/mermaid.d.ts.map +1 -0
- package/dist/mermaid.js +131 -0
- package/dist/mermaid.js.map +1 -0
- package/dist/to-scene.d.ts +12 -0
- package/dist/to-scene.d.ts.map +1 -0
- package/dist/to-scene.js +146 -0
- package/dist/to-scene.js.map +1 -0
- package/package.json +55 -0
package/dist/drawio.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal drawio importer. Targets the *uncompressed* `mxGraphModel` XML
|
|
3
|
+
* payload — what you get from `<mxfile>...<diagram>...<mxGraphModel>...`
|
|
4
|
+
* when "Pretty print" is on, or the inner `<root>...</root>` of a saved
|
|
5
|
+
* `.drawio` file.
|
|
6
|
+
*
|
|
7
|
+
* Supports:
|
|
8
|
+
* - `<mxCell vertex="1" style="..." value="..."><mxGeometry .../></mxCell>`
|
|
9
|
+
* → `GraphNode` with explicit position (so layout is skipped).
|
|
10
|
+
* - `<mxCell edge="1" source="..." target="..." value="..." />`
|
|
11
|
+
* → `GraphEdge`.
|
|
12
|
+
*
|
|
13
|
+
* Element is inferred from the `style="..."` attribute (`ellipse`,
|
|
14
|
+
* `rhombus`/`diamond`, otherwise rectangle). Drawio-style colour stops,
|
|
15
|
+
* groups, swimlanes, etc. are ignored.
|
|
16
|
+
*/
|
|
17
|
+
export const parseDrawio = (source) => {
|
|
18
|
+
// Pull out cells with a single regex sweep. drawio XML has stable
|
|
19
|
+
// structure within a `<root>`; we don't need a full XML parser to read
|
|
20
|
+
// it.
|
|
21
|
+
const cellRe = /<mxCell\b([^>]*?)(?:\/>|>([\s\S]*?)<\/mxCell>)/g;
|
|
22
|
+
const nodes = new Map();
|
|
23
|
+
const edges = [];
|
|
24
|
+
let m;
|
|
25
|
+
while ((m = cellRe.exec(source)) !== null) {
|
|
26
|
+
const attrs = parseAttrs(m[1] ?? "");
|
|
27
|
+
const inner = m[2] ?? "";
|
|
28
|
+
const id = attrs.id ?? "";
|
|
29
|
+
if (!id)
|
|
30
|
+
continue;
|
|
31
|
+
if (attrs.edge === "1") {
|
|
32
|
+
if (!attrs.source || !attrs.target)
|
|
33
|
+
continue;
|
|
34
|
+
const edge = {
|
|
35
|
+
source: attrs.source,
|
|
36
|
+
target: attrs.target,
|
|
37
|
+
direction: "directed",
|
|
38
|
+
...(attrs.value !== undefined && attrs.value !== ""
|
|
39
|
+
? { label: decodeEntities(attrs.value) }
|
|
40
|
+
: {}),
|
|
41
|
+
};
|
|
42
|
+
edges.push(edge);
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (attrs.vertex === "1") {
|
|
46
|
+
const geom = extractGeometry(inner);
|
|
47
|
+
const shape = shapeFromStyle(attrs.style);
|
|
48
|
+
const node = {
|
|
49
|
+
id,
|
|
50
|
+
...(attrs.value !== undefined && attrs.value !== ""
|
|
51
|
+
? { label: decodeEntities(attrs.value) }
|
|
52
|
+
: {}),
|
|
53
|
+
...(shape !== undefined ? { shape } : {}),
|
|
54
|
+
...(geom?.size !== undefined ? { width: geom.size.width, height: geom.size.height } : {}),
|
|
55
|
+
...(geom?.position !== undefined ? { position: geom.position } : {}),
|
|
56
|
+
};
|
|
57
|
+
nodes.set(id, node);
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return { nodes: [...nodes.values()], edges };
|
|
62
|
+
};
|
|
63
|
+
// --- helpers ---
|
|
64
|
+
const parseAttrs = (s) => {
|
|
65
|
+
const out = {};
|
|
66
|
+
const re = /([A-Za-z_:][\w:.-]*)\s*=\s*"([^"]*)"/g;
|
|
67
|
+
let m;
|
|
68
|
+
while ((m = re.exec(s)) !== null) {
|
|
69
|
+
const key = m[1];
|
|
70
|
+
if (key === undefined)
|
|
71
|
+
continue;
|
|
72
|
+
out[key] = m[2] ?? "";
|
|
73
|
+
}
|
|
74
|
+
return out;
|
|
75
|
+
};
|
|
76
|
+
const extractGeometry = (inner) => {
|
|
77
|
+
const g = /<mxGeometry\b([^>]*?)(?:\/>|>[\s\S]*?<\/mxGeometry>)/.exec(inner);
|
|
78
|
+
if (!g)
|
|
79
|
+
return null;
|
|
80
|
+
const a = parseAttrs(g[1] ?? "");
|
|
81
|
+
const num = (s) => {
|
|
82
|
+
if (!s)
|
|
83
|
+
return null;
|
|
84
|
+
const n = Number(s);
|
|
85
|
+
return Number.isFinite(n) ? n : null;
|
|
86
|
+
};
|
|
87
|
+
const x = num(a.x);
|
|
88
|
+
const y = num(a.y);
|
|
89
|
+
const w = num(a.width);
|
|
90
|
+
const h = num(a.height);
|
|
91
|
+
return {
|
|
92
|
+
...(x !== null && y !== null ? { position: { x, y } } : {}),
|
|
93
|
+
...(w !== null && h !== null ? { size: { width: w, height: h } } : {}),
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
const shapeFromStyle = (style) => {
|
|
97
|
+
if (style === undefined)
|
|
98
|
+
return undefined;
|
|
99
|
+
const lower = style.toLowerCase();
|
|
100
|
+
// Custom shapes / images — let the caller decide what to do.
|
|
101
|
+
if (lower.includes("shape=mxgraph") || lower.includes("shape=image"))
|
|
102
|
+
return undefined;
|
|
103
|
+
if (lower.includes("ellipse"))
|
|
104
|
+
return "ellipse";
|
|
105
|
+
if (lower.includes("rhombus") || lower.includes("diamond"))
|
|
106
|
+
return "diamond";
|
|
107
|
+
if (lower.includes("rounded=1"))
|
|
108
|
+
return "round";
|
|
109
|
+
// Drawio's default vertex style is `""` or `rounded=0;whiteSpace=wrap;` —
|
|
110
|
+
// both mean "plain rectangle". Fall through to rectangle.
|
|
111
|
+
return "rectangle";
|
|
112
|
+
};
|
|
113
|
+
const decodeEntities = (s) => s
|
|
114
|
+
.replace(/&/g, "&")
|
|
115
|
+
.replace(/</g, "<")
|
|
116
|
+
.replace(/>/g, ">")
|
|
117
|
+
.replace(/"/g, '"')
|
|
118
|
+
.replace(/'/g, "'")
|
|
119
|
+
.replace(/<br>/g, "\n")
|
|
120
|
+
.replace(/<br\/>/g, "\n");
|
|
121
|
+
//# sourceMappingURL=drawio.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drawio.js","sourceRoot":"","sources":["../src/drawio.ts"],"names":[],"mappings":"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"}
|
package/dist/graph.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Backend-neutral graph model that every importer produces. Layout +
|
|
3
|
+
* scene-conversion live in `layout.ts` / `to-scene.ts`; each format
|
|
4
|
+
* importer just has to fill this shape.
|
|
5
|
+
*
|
|
6
|
+
* Nodes have *logical* sizes (`width` / `height`). If a format ships
|
|
7
|
+
* explicit coordinates (e.g. drawio), the importer can write them into
|
|
8
|
+
* `position` and skip the layout step; otherwise the dagre layout assigns
|
|
9
|
+
* them.
|
|
10
|
+
*/
|
|
11
|
+
export type NodeShape = "rectangle" | "ellipse" | "diamond" | "round";
|
|
12
|
+
export interface GraphNode {
|
|
13
|
+
readonly id: string;
|
|
14
|
+
readonly label?: string;
|
|
15
|
+
readonly shape?: NodeShape;
|
|
16
|
+
readonly width?: number;
|
|
17
|
+
readonly height?: number;
|
|
18
|
+
/** Explicit world-coordinate position, in pixels. Overrides layout. */
|
|
19
|
+
readonly position?: {
|
|
20
|
+
readonly x: number;
|
|
21
|
+
readonly y: number;
|
|
22
|
+
};
|
|
23
|
+
readonly fill?: string;
|
|
24
|
+
readonly stroke?: string;
|
|
25
|
+
}
|
|
26
|
+
export type LinkDirection = "directed" | "undirected";
|
|
27
|
+
export interface GraphEdge {
|
|
28
|
+
readonly source: string;
|
|
29
|
+
readonly target: string;
|
|
30
|
+
readonly label?: string;
|
|
31
|
+
readonly direction?: LinkDirection;
|
|
32
|
+
}
|
|
33
|
+
export type GraphLayoutDirection = "TB" | "BT" | "LR" | "RL";
|
|
34
|
+
export interface GraphDocument {
|
|
35
|
+
readonly nodes: readonly GraphNode[];
|
|
36
|
+
readonly edges: readonly GraphEdge[];
|
|
37
|
+
/** Hint for the layout engine. Defaults to `"TB"`. */
|
|
38
|
+
readonly layout?: GraphLayoutDirection;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,MAAM,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAEtE,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,uEAAuE;IACvE,QAAQ,CAAC,QAAQ,CAAC,EAAE;QAAE,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/D,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,YAAY,CAAC;AAEtD,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,CAAC;CACpC;AAED,MAAM,MAAM,oBAAoB,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE7D,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,CAAC;IACrC,sDAAsD;IACtD,QAAQ,CAAC,MAAM,CAAC,EAAE,oBAAoB,CAAC;CACxC"}
|
package/dist/graph.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":""}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Scene } from "@oh-just-another/scene";
|
|
2
|
+
export type { GraphDocument, GraphNode, GraphEdge, NodeShape, LinkDirection, GraphLayoutDirection, } from "./graph.js";
|
|
3
|
+
export type { LayoutedNode } from "./layout.js";
|
|
4
|
+
export { parseMermaid } from "./mermaid.js";
|
|
5
|
+
export { parseDot } from "./dot.js";
|
|
6
|
+
export { parseDrawio } from "./drawio.js";
|
|
7
|
+
export { layoutGraph } from "./layout.js";
|
|
8
|
+
export { graphToScene } from "./to-scene.js";
|
|
9
|
+
/**
|
|
10
|
+
* One-shot helpers — parse + layout + materialise into a `Scene` in a
|
|
11
|
+
* single call. Use these when you don't need intermediate access to the
|
|
12
|
+
* `GraphDocument`.
|
|
13
|
+
*/
|
|
14
|
+
export declare const importMermaid: (source: string) => Scene;
|
|
15
|
+
export declare const importDot: (source: string) => Scene;
|
|
16
|
+
export declare const importDrawio: (source: string) => Scene;
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAMpD,YAAY,EACV,aAAa,EACb,SAAS,EACT,SAAS,EACT,SAAS,EACT,aAAa,EACb,oBAAoB,GACrB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,QAAQ,MAAM,KAAG,KAA2C,CAAC;AAC3F,eAAO,MAAM,SAAS,GAAI,QAAQ,MAAM,KAAG,KAAuC,CAAC;AACnF,eAAO,MAAM,YAAY,GAAI,QAAQ,MAAM,KAAG,KAA0C,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { parseMermaid } from "./mermaid.js";
|
|
2
|
+
import { parseDot } from "./dot.js";
|
|
3
|
+
import { parseDrawio } from "./drawio.js";
|
|
4
|
+
import { graphToScene } from "./to-scene.js";
|
|
5
|
+
export { parseMermaid } from "./mermaid.js";
|
|
6
|
+
export { parseDot } from "./dot.js";
|
|
7
|
+
export { parseDrawio } from "./drawio.js";
|
|
8
|
+
export { layoutGraph } from "./layout.js";
|
|
9
|
+
export { graphToScene } from "./to-scene.js";
|
|
10
|
+
/**
|
|
11
|
+
* One-shot helpers — parse + layout + materialise into a `Scene` in a
|
|
12
|
+
* single call. Use these when you don't need intermediate access to the
|
|
13
|
+
* `GraphDocument`.
|
|
14
|
+
*/
|
|
15
|
+
export const importMermaid = (source) => graphToScene(parseMermaid(source));
|
|
16
|
+
export const importDot = (source) => graphToScene(parseDot(source));
|
|
17
|
+
export const importDrawio = (source) => graphToScene(parseDrawio(source));
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAY7C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,MAAc,EAAS,EAAE,CAAC,YAAY,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;AAC3F,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,MAAc,EAAS,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;AACnF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,MAAc,EAAS,EAAE,CAAC,YAAY,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC"}
|
package/dist/layout.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { GraphDocument, GraphNode } from "./graph.js";
|
|
2
|
+
export interface LayoutedNode extends GraphNode {
|
|
3
|
+
readonly position: {
|
|
4
|
+
readonly x: number;
|
|
5
|
+
readonly y: number;
|
|
6
|
+
};
|
|
7
|
+
readonly width: number;
|
|
8
|
+
readonly height: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Compute world-space coordinates for every node. Nodes that already have
|
|
12
|
+
* a `position` are kept as-is; the rest are run through dagre with the
|
|
13
|
+
* direction hinted by `graph.layout`.
|
|
14
|
+
*
|
|
15
|
+
* Returns a new graph where every node has explicit `position`, `width`,
|
|
16
|
+
* and `height`. Links are unchanged.
|
|
17
|
+
*/
|
|
18
|
+
export declare const layoutGraph: (graph: GraphDocument) => {
|
|
19
|
+
readonly nodes: readonly LayoutedNode[];
|
|
20
|
+
readonly edges: GraphDocument["edges"];
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../src/layout.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAwB,SAAS,EAAE,MAAM,YAAY,CAAC;AAOjF,MAAM,WAAW,YAAa,SAAQ,SAAS;IAC7C,QAAQ,CAAC,QAAQ,EAAE;QAAE,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,GACtB,OAAO,aAAa,KACnB;IACD,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IACxC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;CAsExC,CAAC"}
|
package/dist/layout.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import dagre from "@dagrejs/dagre";
|
|
2
|
+
const DEFAULT_NODE_W = 120;
|
|
3
|
+
const DEFAULT_NODE_H = 60;
|
|
4
|
+
const NODE_SEP = 40;
|
|
5
|
+
const RANK_SEP = 60;
|
|
6
|
+
/**
|
|
7
|
+
* Compute world-space coordinates for every node. Nodes that already have
|
|
8
|
+
* a `position` are kept as-is; the rest are run through dagre with the
|
|
9
|
+
* direction hinted by `graph.layout`.
|
|
10
|
+
*
|
|
11
|
+
* Returns a new graph where every node has explicit `position`, `width`,
|
|
12
|
+
* and `height`. Links are unchanged.
|
|
13
|
+
*/
|
|
14
|
+
export const layoutGraph = (graph) => {
|
|
15
|
+
const direction = graph.layout ?? "TB";
|
|
16
|
+
// Skip dagre entirely if every node already carries an explicit position
|
|
17
|
+
// (drawio is the typical case).
|
|
18
|
+
const allPositioned = graph.nodes.length > 0 && graph.nodes.every((n) => n.position !== undefined);
|
|
19
|
+
if (allPositioned) {
|
|
20
|
+
return {
|
|
21
|
+
nodes: graph.nodes.map((n) => ({
|
|
22
|
+
...n,
|
|
23
|
+
position: n.position ?? { x: 0, y: 0 },
|
|
24
|
+
width: n.width ?? DEFAULT_NODE_W,
|
|
25
|
+
height: n.height ?? DEFAULT_NODE_H,
|
|
26
|
+
})),
|
|
27
|
+
edges: graph.edges,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
const g = new dagre.graphlib.Graph({
|
|
31
|
+
multigraph: true,
|
|
32
|
+
directed: true,
|
|
33
|
+
});
|
|
34
|
+
g.setGraph({
|
|
35
|
+
rankdir: dagreDirection(direction),
|
|
36
|
+
nodesep: NODE_SEP,
|
|
37
|
+
ranksep: RANK_SEP,
|
|
38
|
+
marginx: 20,
|
|
39
|
+
marginy: 20,
|
|
40
|
+
});
|
|
41
|
+
g.setDefaultEdgeLabel(() => ({}));
|
|
42
|
+
for (const n of graph.nodes) {
|
|
43
|
+
g.setNode(n.id, {
|
|
44
|
+
width: n.width ?? DEFAULT_NODE_W,
|
|
45
|
+
height: n.height ?? DEFAULT_NODE_H,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
for (const e of graph.edges) {
|
|
49
|
+
g.setEdge(e.source, e.target);
|
|
50
|
+
}
|
|
51
|
+
dagre.layout(g);
|
|
52
|
+
const out = [];
|
|
53
|
+
for (const n of graph.nodes) {
|
|
54
|
+
const dagreNode = g.node(n.id);
|
|
55
|
+
if (n.position) {
|
|
56
|
+
// Keep explicit position even when dagre ran for the other nodes.
|
|
57
|
+
out.push({
|
|
58
|
+
...n,
|
|
59
|
+
position: n.position,
|
|
60
|
+
width: n.width ?? dagreNode.width,
|
|
61
|
+
height: n.height ?? dagreNode.height,
|
|
62
|
+
});
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
// dagre returns the *centre* of each node; we want the top-left.
|
|
66
|
+
const w = n.width ?? dagreNode.width;
|
|
67
|
+
const h = n.height ?? dagreNode.height;
|
|
68
|
+
out.push({
|
|
69
|
+
...n,
|
|
70
|
+
width: w,
|
|
71
|
+
height: h,
|
|
72
|
+
position: { x: dagreNode.x - w / 2, y: dagreNode.y - h / 2 },
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
return { nodes: out, edges: graph.edges };
|
|
76
|
+
};
|
|
77
|
+
const dagreDirection = (d) => d;
|
|
78
|
+
//# sourceMappingURL=layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.js","sourceRoot":"","sources":["../src/layout.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { GraphDocument } from "./graph.js";
|
|
2
|
+
/**
|
|
3
|
+
* Minimal Mermaid flowchart importer. Supports the most common subset:
|
|
4
|
+
*
|
|
5
|
+
* flowchart TD (or `graph LR/TB/BT/RL`)
|
|
6
|
+
* A — node by id, default rectangle
|
|
7
|
+
* A[Label] — rectangle with label
|
|
8
|
+
* A(Round) — rounded (rendered as ellipse)
|
|
9
|
+
* A((Circle)) — ellipse
|
|
10
|
+
* A{Decision} — diamond
|
|
11
|
+
* A --> B — directed edge
|
|
12
|
+
* A --- B — undirected edge
|
|
13
|
+
* A -->|label| B — labelled edge
|
|
14
|
+
* A --> B --> C — chained edges
|
|
15
|
+
* %% comment — line ignored
|
|
16
|
+
* class statements — ignored (no styling support yet)
|
|
17
|
+
*
|
|
18
|
+
* Anything we don't understand is skipped silently. Hosts that need full
|
|
19
|
+
* Mermaid fidelity should preprocess with the official Mermaid parser.
|
|
20
|
+
*/
|
|
21
|
+
export declare const parseMermaid: (source: string) => GraphDocument;
|
|
22
|
+
//# sourceMappingURL=mermaid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mermaid.d.ts","sourceRoot":"","sources":["../src/mermaid.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EAKd,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,YAAY,GAAI,QAAQ,MAAM,KAAG,aAyB7C,CAAC"}
|
package/dist/mermaid.js
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal Mermaid flowchart importer. Supports the most common subset:
|
|
3
|
+
*
|
|
4
|
+
* flowchart TD (or `graph LR/TB/BT/RL`)
|
|
5
|
+
* A — node by id, default rectangle
|
|
6
|
+
* A[Label] — rectangle with label
|
|
7
|
+
* A(Round) — rounded (rendered as ellipse)
|
|
8
|
+
* A((Circle)) — ellipse
|
|
9
|
+
* A{Decision} — diamond
|
|
10
|
+
* A --> B — directed edge
|
|
11
|
+
* A --- B — undirected edge
|
|
12
|
+
* A -->|label| B — labelled edge
|
|
13
|
+
* A --> B --> C — chained edges
|
|
14
|
+
* %% comment — line ignored
|
|
15
|
+
* class statements — ignored (no styling support yet)
|
|
16
|
+
*
|
|
17
|
+
* Anything we don't understand is skipped silently. Hosts that need full
|
|
18
|
+
* Mermaid fidelity should preprocess with the official Mermaid parser.
|
|
19
|
+
*/
|
|
20
|
+
export const parseMermaid = (source) => {
|
|
21
|
+
const lines = source.split(/\r?\n/);
|
|
22
|
+
let layout = "TB";
|
|
23
|
+
const nodes = new Map();
|
|
24
|
+
const edges = [];
|
|
25
|
+
for (const raw of lines) {
|
|
26
|
+
const line = raw.trim();
|
|
27
|
+
if (!line || line.startsWith("%%"))
|
|
28
|
+
continue;
|
|
29
|
+
if (line.startsWith("class ") || line.startsWith("classDef ") || line.startsWith("style ")) {
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
if (line.startsWith("subgraph") || line === "end")
|
|
33
|
+
continue;
|
|
34
|
+
const header = /^(?:graph|flowchart)\s+(TD|TB|BT|LR|RL)\b/i.exec(line);
|
|
35
|
+
if (header) {
|
|
36
|
+
const dir = (header[1] ?? "").toUpperCase();
|
|
37
|
+
layout = dir === "TD" ? "TB" : dir;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
parseStatement(line, nodes, edges);
|
|
41
|
+
}
|
|
42
|
+
return { nodes: [...nodes.values()], edges, layout };
|
|
43
|
+
};
|
|
44
|
+
const NODE_RE = /^([A-Za-z_][A-Za-z0-9_]*)(\[\[?[^\]]*\]?\]|\(\(?[^)]*\)?\)|\{[^}]*\})?/;
|
|
45
|
+
const EDGE_RE = /^(<?[-=.]+>?)(?:\|([^|]*)\|)?/;
|
|
46
|
+
const parseStatement = (text, nodes, edges) => {
|
|
47
|
+
let i = 0;
|
|
48
|
+
let prev = null;
|
|
49
|
+
let pendingLink = null;
|
|
50
|
+
while (i < text.length) {
|
|
51
|
+
while (i < text.length && /\s/.test(text.charAt(i)))
|
|
52
|
+
i++;
|
|
53
|
+
if (i >= text.length)
|
|
54
|
+
break;
|
|
55
|
+
const nodeMatch = matchNode(text.slice(i));
|
|
56
|
+
if (nodeMatch) {
|
|
57
|
+
// Merge with any earlier definition of the same id.
|
|
58
|
+
const existing = nodes.get(nodeMatch.node.id);
|
|
59
|
+
if (existing) {
|
|
60
|
+
// Keep the more informative one (later definition with label wins).
|
|
61
|
+
nodes.set(nodeMatch.node.id, { ...existing, ...nodeMatch.node });
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
nodes.set(nodeMatch.node.id, nodeMatch.node);
|
|
65
|
+
}
|
|
66
|
+
if (prev && pendingLink) {
|
|
67
|
+
const edge = {
|
|
68
|
+
source: prev,
|
|
69
|
+
target: nodeMatch.node.id,
|
|
70
|
+
direction: pendingLink.direction,
|
|
71
|
+
...(pendingLink.label !== undefined ? { label: pendingLink.label } : {}),
|
|
72
|
+
};
|
|
73
|
+
edges.push(edge);
|
|
74
|
+
}
|
|
75
|
+
prev = nodeMatch.node.id;
|
|
76
|
+
pendingLink = null;
|
|
77
|
+
i += nodeMatch.length;
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
const edgeMatch = EDGE_RE.exec(text.slice(i));
|
|
81
|
+
if (edgeMatch) {
|
|
82
|
+
const arrow = edgeMatch[1] ?? "";
|
|
83
|
+
const label = edgeMatch[2];
|
|
84
|
+
const direction = arrow.includes(">") || arrow.includes("<") ? "directed" : "undirected";
|
|
85
|
+
pendingLink = label !== undefined ? { direction, label } : { direction };
|
|
86
|
+
i += edgeMatch[0].length;
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
// Unknown token — skip a char to avoid infinite loop.
|
|
90
|
+
i += 1;
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
const matchNode = (input) => {
|
|
94
|
+
const m = NODE_RE.exec(input);
|
|
95
|
+
if (!m)
|
|
96
|
+
return null;
|
|
97
|
+
const id = m[1] ?? "";
|
|
98
|
+
const bracket = m[2] ?? "";
|
|
99
|
+
let shape;
|
|
100
|
+
let label;
|
|
101
|
+
if (bracket.startsWith("[[") && bracket.endsWith("]]")) {
|
|
102
|
+
shape = "rectangle";
|
|
103
|
+
label = bracket.slice(2, -2).trim() || undefined;
|
|
104
|
+
}
|
|
105
|
+
else if (bracket.startsWith("[") && bracket.endsWith("]")) {
|
|
106
|
+
shape = "rectangle";
|
|
107
|
+
label = bracket.slice(1, -1).trim() || undefined;
|
|
108
|
+
}
|
|
109
|
+
else if (bracket.startsWith("((") && bracket.endsWith("))")) {
|
|
110
|
+
shape = "ellipse";
|
|
111
|
+
label = bracket.slice(2, -2).trim() || undefined;
|
|
112
|
+
}
|
|
113
|
+
else if (bracket.startsWith("(") && bracket.endsWith(")")) {
|
|
114
|
+
shape = "round";
|
|
115
|
+
label = bracket.slice(1, -1).trim() || undefined;
|
|
116
|
+
}
|
|
117
|
+
else if (bracket.startsWith("{") && bracket.endsWith("}")) {
|
|
118
|
+
shape = "diamond";
|
|
119
|
+
label = bracket.slice(1, -1).trim() || undefined;
|
|
120
|
+
}
|
|
121
|
+
// Strip optional quotes around label.
|
|
122
|
+
if (label && /^".*"$/.test(label))
|
|
123
|
+
label = label.slice(1, -1);
|
|
124
|
+
const node = {
|
|
125
|
+
id,
|
|
126
|
+
...(label !== undefined ? { label } : {}),
|
|
127
|
+
...(shape !== undefined ? { shape } : {}),
|
|
128
|
+
};
|
|
129
|
+
return { node, length: m[0].length };
|
|
130
|
+
};
|
|
131
|
+
//# sourceMappingURL=mermaid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mermaid.js","sourceRoot":"","sources":["../src/mermaid.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,MAAc,EAAiB,EAAE;IAC5D,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACpC,IAAI,MAAM,GAAyB,IAAI,CAAC;IACxC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAqB,CAAC;IAC3C,MAAM,KAAK,GAAgB,EAAE,CAAC;IAE9B,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QACxB,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,SAAS;QAC7C,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC3F,SAAS;QACX,CAAC;QACD,IAAI,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,IAAI,KAAK,KAAK;YAAE,SAAS;QAE5D,MAAM,MAAM,GAAG,4CAA4C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvE,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;YAC5C,MAAM,GAAG,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAE,GAA4B,CAAC;YAC7D,SAAS;QACX,CAAC;QAED,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IACrC,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AACvD,CAAC,CAAC;AAOF,MAAM,OAAO,GAAG,wEAAwE,CAAC;AAEzF,MAAM,OAAO,GAAG,+BAA+B,CAAC;AAEhD,MAAM,cAAc,GAAG,CAAC,IAAY,EAAE,KAA6B,EAAE,KAAkB,EAAQ,EAAE;IAC/F,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,IAAI,IAAI,GAAkB,IAAI,CAAC;IAC/B,IAAI,WAAW,GAAoE,IAAI,CAAC;IAExF,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAAE,CAAC,EAAE,CAAC;QACzD,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM;YAAE,MAAM;QAE5B,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3C,IAAI,SAAS,EAAE,CAAC;YACd,oDAAoD;YACpD,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC9C,IAAI,QAAQ,EAAE,CAAC;gBACb,oEAAoE;gBACpE,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,QAAQ,EAAE,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;YACnE,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;YAC/C,CAAC;YACD,IAAI,IAAI,IAAI,WAAW,EAAE,CAAC;gBACxB,MAAM,IAAI,GAAc;oBACtB,MAAM,EAAE,IAAI;oBACZ,MAAM,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE;oBACzB,SAAS,EAAE,WAAW,CAAC,SAAS;oBAChC,GAAG,CAAC,WAAW,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACzE,CAAC;gBACF,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnB,CAAC;YACD,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,WAAW,GAAG,IAAI,CAAC;YACnB,CAAC,IAAI,SAAS,CAAC,MAAM,CAAC;YACtB,SAAS;QACX,CAAC;QAED,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9C,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACjC,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;YAC3B,MAAM,SAAS,GACb,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC;YACzE,WAAW,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC;YACzE,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YACzB,SAAS;QACX,CAAC;QAED,sDAAsD;QACtD,CAAC,IAAI,CAAC,CAAC;IACT,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,SAAS,GAAG,CAAC,KAAa,EAAoB,EAAE;IACpD,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9B,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACpB,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACtB,MAAM,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3B,IAAI,KAA4B,CAAC;IACjC,IAAI,KAAyB,CAAC;IAE9B,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACvD,KAAK,GAAG,WAAW,CAAC;QACpB,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,SAAS,CAAC;IACnD,CAAC;SAAM,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5D,KAAK,GAAG,WAAW,CAAC;QACpB,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,SAAS,CAAC;IACnD,CAAC;SAAM,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9D,KAAK,GAAG,SAAS,CAAC;QAClB,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,SAAS,CAAC;IACnD,CAAC;SAAM,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5D,KAAK,GAAG,OAAO,CAAC;QAChB,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,SAAS,CAAC;IACnD,CAAC;SAAM,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5D,KAAK,GAAG,SAAS,CAAC;QAClB,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,SAAS,CAAC;IACnD,CAAC;IAED,sCAAsC;IACtC,IAAI,KAAK,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAE9D,MAAM,IAAI,GAAc;QACtB,EAAE;QACF,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzC,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC1C,CAAC;IACF,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;AACvC,CAAC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type Scene } from "@oh-just-another/scene";
|
|
2
|
+
import type { GraphDocument } from "./graph.js";
|
|
3
|
+
/**
|
|
4
|
+
* Convert a backend-neutral `GraphDocument` into a `Scene`. Runs layout
|
|
5
|
+
* (`layoutGraph`) first, then materialises each node as a built-in shape
|
|
6
|
+
* and each edge as a `straight`-routed connector between named anchors.
|
|
7
|
+
*
|
|
8
|
+
* Scene viewport size is fitted around the layouted bounding box plus a
|
|
9
|
+
* small margin so the result looks centered when handed to the renderer.
|
|
10
|
+
*/
|
|
11
|
+
export declare const graphToScene: (graph: GraphDocument) => Scene;
|
|
12
|
+
//# sourceMappingURL=to-scene.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"to-scene.d.ts","sourceRoot":"","sources":["../src/to-scene.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,KAAK,EAEX,MAAM,wBAAwB,CAAC;AAOhC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGhD;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,GAAI,OAAO,aAAa,KAAG,KA8HnD,CAAC"}
|