@draftably/mermaid 0.0.0-stage → 0.1.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.
Files changed (43) hide show
  1. package/README.md +64 -2
  2. package/dist/LICENSE +21 -0
  3. package/dist/cdn/font-data-DbrpaYkG-vzB__apN.mjs +30 -0
  4. package/dist/cdn/index-MjBeFYcO.mjs +7738 -0
  5. package/dist/cdn/mermaid-facade-BoLWBerE.mjs +289 -0
  6. package/dist/cdn/mermaid-importer-SlRnjUhj.mjs +3753 -0
  7. package/dist/chunks/mermaid-facade-BoLWBerE.js +289 -0
  8. package/dist/chunks/mermaid-importer-IVovOQE9.js +3753 -0
  9. package/dist/mermaid.esm.min.mjs +13 -0
  10. package/dist/mermaid.js +117 -0
  11. package/dist/types/packages/mermaid/src/index.d.ts +59 -0
  12. package/dist/types/src/dsl/cells.d.ts +91 -0
  13. package/dist/types/src/dsl/channels.d.ts +53 -0
  14. package/dist/types/src/dsl/compile.d.ts +162 -0
  15. package/dist/types/src/dsl/frame.d.ts +38 -0
  16. package/dist/types/src/dsl/lanes.d.ts +23 -0
  17. package/dist/types/src/dsl/legend-notes.d.ts +3 -0
  18. package/dist/types/src/dsl/project.d.ts +39 -0
  19. package/dist/types/src/dsl/syntax.d.ts +317 -0
  20. package/dist/types/src/import/import-core.d.ts +105 -0
  21. package/dist/types/src/import/mermaid-facade.d.ts +120 -0
  22. package/dist/types/src/import/mermaid-importer.d.ts +4 -0
  23. package/dist/types/src/import/mermaid-sequence.d.ts +8 -0
  24. package/dist/types/src/model/appearance.d.ts +209 -0
  25. package/dist/types/src/model/bounds.d.ts +19 -0
  26. package/dist/types/src/model/document.d.ts +24 -0
  27. package/dist/types/src/model/font-faces.d.ts +24 -0
  28. package/dist/types/src/model/fonts.d.ts +47 -0
  29. package/dist/types/src/model/footnote.d.ts +34 -0
  30. package/dist/types/src/model/geometry.d.ts +29 -0
  31. package/dist/types/src/model/graph.d.ts +53 -0
  32. package/dist/types/src/model/heading.d.ts +38 -0
  33. package/dist/types/src/model/icons.d.ts +2 -0
  34. package/dist/types/src/model/labels.d.ts +88 -0
  35. package/dist/types/src/model/link.d.ts +63 -0
  36. package/dist/types/src/model/markers.d.ts +47 -0
  37. package/dist/types/src/model/note.d.ts +75 -0
  38. package/dist/types/src/model/rich-text.d.ts +24 -0
  39. package/dist/types/src/model/routes.d.ts +170 -0
  40. package/dist/types/src/model/status.d.ts +84 -0
  41. package/dist/types/src/model/styles.d.ts +13 -0
  42. package/dist/types/src/model/types.d.ts +277 -0
  43. package/package.json +36 -3
@@ -0,0 +1,13 @@
1
+ import { c as e, m as s, g as t, i, p as n, r as o, a as d, b as g, d as l, s as f } from "./cdn/index-MjBeFYcO.mjs";
2
+ export {
3
+ e as contentLoaded,
4
+ s as default,
5
+ t as getConfig,
6
+ i as initialize,
7
+ n as parse,
8
+ o as registerExternalDiagrams,
9
+ d as registerLayoutLoaders,
10
+ g as render,
11
+ l as run,
12
+ f as setParseErrorHandler
13
+ };
@@ -0,0 +1,117 @@
1
+ import { renderSvg as E, validate as A } from "@draftably/runtime";
2
+ let s = { startOnLoad: !0 }, P, d, x = 0, u;
3
+ const o = () => P ??= import("mermaid-upstream").then((r) => r.default), p = (r) => /^\s*(?:%%.*\n\s*)*(?:diagram\s+"|(?:node|group|edge|layout|theme)\s)/.test(r), y = (r) => {
4
+ const n = r.replace(/^\s*\n/, "").replace(/\s+$/, "").split(`
5
+ `), a = Math.min(...n.filter((e) => e.trim()).map((e) => /^\s*/.exec(e)[0].length));
6
+ return n.map((e) => e.slice(Number.isFinite(a) ? a : 0)).join(`
7
+ `);
8
+ }, w = (r) => Object.assign(new Error(r), { name: "DraftablyError" });
9
+ async function F(r) {
10
+ if (s.draftably?.mermaid === "off") return null;
11
+ u ??= import("./chunks/mermaid-facade-BoLWBerE.js").then(
12
+ (i) => i.createMermaidFlowParser(o)
13
+ );
14
+ const [{ makePlainLabel: n }, { importMermaidFlow: a }] = await Promise.all([
15
+ import("./chunks/mermaid-facade-BoLWBerE.js"),
16
+ import("./chunks/mermaid-importer-IVovOQE9.js")
17
+ ]), e = await (await u)(r);
18
+ if (!e.ok) return null;
19
+ const t = a(e, n(document), "");
20
+ return t.nativeSource ? { source: t.nativeSource, family: t.family } : null;
21
+ }
22
+ async function l(r, n, a) {
23
+ const e = await E(n, { target: "inline", idPrefix: r });
24
+ if (!e.ok) throw w(e.diagnostics.map((t) => t.message).join(`
25
+ `));
26
+ return { svg: e.value.svg, diagramType: a, renderer: "draftably" };
27
+ }
28
+ async function S(r, n, a) {
29
+ const e = await o();
30
+ e.initialize({ ...s, startOnLoad: !1 });
31
+ const t = await e.render(r, n, a);
32
+ return {
33
+ svg: t.svg,
34
+ diagramType: t.diagramType,
35
+ renderer: "mermaid",
36
+ bindFunctions: t.bindFunctions
37
+ };
38
+ }
39
+ async function c(r, n, a) {
40
+ const e = y(n);
41
+ if (p(e)) return l(r, e, "draftably");
42
+ const t = await F(e);
43
+ return t ? l(r, t.source, t.family) : S(r, e, a);
44
+ }
45
+ async function m(r, n = {}) {
46
+ const a = y(r);
47
+ try {
48
+ if (p(a)) {
49
+ const t = await A(a);
50
+ if (!t.ok) throw w(t.diagnostics.map((i) => i.message).join(`
51
+ `));
52
+ return { diagramType: "draftably", config: s };
53
+ }
54
+ const e = await (await o()).parse(a);
55
+ return e ? { diagramType: e.diagramType, config: s } : !1;
56
+ } catch (e) {
57
+ if (d?.(e), n.suppressErrors) return !1;
58
+ throw e;
59
+ }
60
+ }
61
+ async function b(r = {}) {
62
+ const n = r.nodes ?? document.querySelectorAll(r.querySelector ?? ".mermaid"), a = [];
63
+ for (const e of Array.from(n)) {
64
+ if (e.getAttribute("data-processed")) continue;
65
+ e.setAttribute("data-processed", "true");
66
+ const t = `mermaid-${x++}`;
67
+ try {
68
+ const { svg: i, bindFunctions: v, renderer: L } = await c(t, e.textContent ?? "", e);
69
+ e.innerHTML = i, e.setAttribute("data-renderer", L), v?.(e), r.postRenderCallback?.(t);
70
+ } catch (i) {
71
+ d?.(i), a.push(i), e.setAttribute("data-draftably-error", String(i.message ?? i));
72
+ }
73
+ }
74
+ if (a.length && !r.suppressErrors) throw a[0];
75
+ }
76
+ function f(r) {
77
+ s = { ...s, ...r };
78
+ }
79
+ const g = () => s;
80
+ function T(r) {
81
+ d = r;
82
+ }
83
+ async function h() {
84
+ s.startOnLoad && await b();
85
+ }
86
+ async function k(...r) {
87
+ await (await o()).registerExternalDiagrams(...r);
88
+ }
89
+ async function D(...r) {
90
+ (await o()).registerLayoutLoaders(...r);
91
+ }
92
+ const j = {
93
+ initialize: f,
94
+ run: b,
95
+ render: c,
96
+ parse: m,
97
+ contentLoaded: h,
98
+ getConfig: g,
99
+ setParseErrorHandler: T,
100
+ registerExternalDiagrams: k,
101
+ registerLayoutLoaders: D,
102
+ mermaidAPI: { initialize: f, render: c, parse: m, getConfig: g }
103
+ };
104
+ typeof window < "u" && window.addEventListener("load", () => void h().catch(() => {
105
+ }), { once: !0 });
106
+ export {
107
+ h as contentLoaded,
108
+ j as default,
109
+ g as getConfig,
110
+ f as initialize,
111
+ m as parse,
112
+ k as registerExternalDiagrams,
113
+ D as registerLayoutLoaders,
114
+ c as render,
115
+ b as run,
116
+ T as setParseErrorHandler
117
+ };
@@ -0,0 +1,59 @@
1
+ export interface MermaidConfig {
2
+ startOnLoad?: boolean;
3
+ /** Drop-in settings. Every other key passes through to Mermaid for families it still draws. */
4
+ draftably?: {
5
+ /** `convert` (default) draws Mermaid flowcharts and sequences with Draftably; `off` leaves them to Mermaid. */
6
+ mermaid?: 'convert' | 'off';
7
+ };
8
+ [key: string]: unknown;
9
+ }
10
+ export interface RunOptions {
11
+ querySelector?: string;
12
+ nodes?: ArrayLike<HTMLElement>;
13
+ suppressErrors?: boolean;
14
+ postRenderCallback?: (id: string) => unknown;
15
+ }
16
+ export interface RenderResult {
17
+ svg: string;
18
+ diagramType: string;
19
+ /** Who drew it: `draftably`, or `mermaid` for a family Draftably does not draw yet. */
20
+ renderer: 'draftably' | 'mermaid';
21
+ bindFunctions?: (element: Element) => void;
22
+ }
23
+ export interface ParseResult {
24
+ diagramType: string;
25
+ config: MermaidConfig;
26
+ }
27
+ type Upstream = (typeof import('mermaid-upstream'))['default'];
28
+ export declare function render(id: string, text: string, container?: Element): Promise<RenderResult>;
29
+ export declare function parse(text: string, options?: {
30
+ suppressErrors?: boolean;
31
+ }): Promise<ParseResult | false>;
32
+ export declare function run(options?: RunOptions): Promise<void>;
33
+ export declare function initialize(next: MermaidConfig): void;
34
+ export declare const getConfig: () => MermaidConfig;
35
+ export declare function setParseErrorHandler(handler: (err: unknown, hash?: unknown) => void): void;
36
+ /** Mermaid's page-load hook: render every `.mermaid` element when `startOnLoad` is on. */
37
+ export declare function contentLoaded(): Promise<void>;
38
+ /** Diagram families from plugins render through Mermaid, so register them there. */
39
+ export declare function registerExternalDiagrams(...args: Parameters<Upstream['registerExternalDiagrams']>): Promise<void>;
40
+ /** Layout plugins such as `@mermaid-js/layout-elk` apply to the charts Mermaid still draws. */
41
+ export declare function registerLayoutLoaders(...args: Parameters<Upstream['registerLayoutLoaders']>): Promise<void>;
42
+ declare const mermaid: {
43
+ initialize: typeof initialize;
44
+ run: typeof run;
45
+ render: typeof render;
46
+ parse: typeof parse;
47
+ contentLoaded: typeof contentLoaded;
48
+ getConfig: () => MermaidConfig;
49
+ setParseErrorHandler: typeof setParseErrorHandler;
50
+ registerExternalDiagrams: typeof registerExternalDiagrams;
51
+ registerLayoutLoaders: typeof registerLayoutLoaders;
52
+ mermaidAPI: {
53
+ initialize: typeof initialize;
54
+ render: typeof render;
55
+ parse: typeof parse;
56
+ getConfig: () => MermaidConfig;
57
+ };
58
+ };
59
+ export default mermaid;
@@ -0,0 +1,91 @@
1
+ import type { ResolvedAppearance } from '../model/appearance';
2
+ /** Width of a marker's bar, centred on the seam it marks. */
3
+ export declare const MARKER_WIDTH = 8;
4
+ /** How far a marker's bar runs past the cells, so a line meets it clear of their corners. */
5
+ export declare const MARKER_TAIL = 16;
6
+ /** Height of a cells group's title band for a title type of this line height. */
7
+ export declare const cellsBandFor: (lineHeight: number) => number;
8
+ export interface CellInput {
9
+ id: string;
10
+ label: string;
11
+ marker: boolean;
12
+ /** Columns the cell covers in a grid. */
13
+ span?: number;
14
+ /** From a `size` line. */
15
+ size?: {
16
+ width: number;
17
+ height?: number;
18
+ };
19
+ }
20
+ export interface CellBox {
21
+ x: number;
22
+ y: number;
23
+ w: number;
24
+ h: number;
25
+ }
26
+ /** A cell's own size: one line of title when it fits in `MAX_CELL`, wrapped when it does not. */
27
+ export declare function cellSize(c: CellInput, look: ResolvedAppearance): {
28
+ w: number;
29
+ h: number;
30
+ };
31
+ /**
32
+ * Cells edge to edge, in rows of `columns` columns filled in order; a cell's `span` covers that
33
+ * many columns, and a cell that does not fit the rest of a row starts the next one. Without
34
+ * `columns`, the cells form one row (`right`) or one column (`down`). Each column is as wide as
35
+ * its widest single cell, widened at its last column for a wider spanning cell, and each row is
36
+ * as tall as its tallest cell. Cells narrower than `minWidth` in all, the title band's width,
37
+ * widen the last column.
38
+ *
39
+ * A marker takes no room: in one row or column, its bar sits on the seam before the next cell
40
+ * and spans the band above as well, so it cuts the whole object, and runs a short tail past the
41
+ * cells where lines meet it.
42
+ */
43
+ export declare function layoutCells(cells: CellInput[], shape: {
44
+ direction: 'right' | 'down';
45
+ columns?: number;
46
+ }, look: ResolvedAppearance, minWidth?: number): {
47
+ boxes: Map<string, CellBox>;
48
+ w: number;
49
+ h: number;
50
+ };
51
+ /** Width of one unit of a byte or bit layout, and the units in each row, unless the file says. */
52
+ export declare const UNIT_WIDTH: {
53
+ readonly bit: 24;
54
+ readonly byte: 48;
55
+ };
56
+ export declare const UNIT_COLUMNS: {
57
+ readonly bit: 32;
58
+ readonly byte: 16;
59
+ };
60
+ export interface UnitCells {
61
+ /** Each field's main box: the longest piece, which holds its title. */
62
+ boxes: Map<string, CellBox>;
63
+ /** The other pieces of a field that runs on past a row's end. */
64
+ pieces: Map<string, CellBox[]>;
65
+ /** Fields of variable length, drawn with broken ends. */
66
+ open: string[];
67
+ /** Unit numbers above the first row: their centres, and the room they take above the cells. */
68
+ ruler?: {
69
+ h: number;
70
+ ticks: Array<{
71
+ x: number;
72
+ label: string;
73
+ }>;
74
+ };
75
+ w: number;
76
+ h: number;
77
+ }
78
+ /**
79
+ * A byte or bit layout: every unit has one width, so a field's width is its size. Rows hold
80
+ * `columns` units. A field longer than the rest of its row runs on into the next rows; a field of
81
+ * variable length (`span: 'var'`) fills the rest of its row, or a whole row, with broken ends.
82
+ * Every row has the height of the tallest title.
83
+ */
84
+ export declare function layoutUnits(cells: Array<CellInput & {
85
+ open?: boolean;
86
+ }>, shape: {
87
+ unit: 'bit' | 'byte';
88
+ columns?: number;
89
+ unitWidth?: number;
90
+ ruler: boolean;
91
+ }, look: ResolvedAppearance): UnitCells;
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Routing channels inside groups.
3
+ *
4
+ * A group leaves `GROUP_INSET` between its members and its border. That is padding, not room for
5
+ * a line: a line routed through it runs beside a member and along the border at once. When a
6
+ * connection has to travel inside a group (a member boxed in by its neighbours, or a link between
7
+ * two of the group's children that can't go straight across), the group grows a channel on one
8
+ * side, wide enough for each such line to run a full standoff from the members,
9
+ * the border and each other. A link between children takes the side of them both ends lean
10
+ * toward, and a return (up or left) takes the left or top when they lean neither way, so a
11
+ * forward line and its return don't cross. The compiler lays the scene out once, plans channels
12
+ * from that geometry, and lays it out again with them.
13
+ */
14
+ import type { ModelEdge } from './syntax';
15
+ /**
16
+ * Room a group leaves round its content: the inset on the left, right and bottom (at least
17
+ * `GROUP_INSET`), and extra room under the title band on top (0 without a channel there).
18
+ */
19
+ export interface Channel {
20
+ left: number;
21
+ right: number;
22
+ top: number;
23
+ bottom: number;
24
+ /** How many lines each side's channel was planned for. */
25
+ lines: Record<Side, number>;
26
+ }
27
+ /** Channels may grow the drawing's area by this much at most. */
28
+ export declare const CHANNEL_BUDGET = 1.1;
29
+ /**
30
+ * Drop the channels that carry fewest lines until the drawing laid out with the rest (`measure`)
31
+ * is within `CHANNEL_BUDGET` of its area without any (`plain`).
32
+ */
33
+ export declare function trimChannels(plan: Map<string, Channel>, plain: number, measure: (channels: Map<string, Channel>) => number): Map<string, Channel>;
34
+ interface Box {
35
+ id: string;
36
+ type: string;
37
+ parent: string;
38
+ x: number;
39
+ y: number;
40
+ w: number;
41
+ h: number;
42
+ }
43
+ export type Side = 'left' | 'right' | 'top' | 'bottom';
44
+ /**
45
+ * Channels for the scene laid out as `objects`. A group is keyed by id; groups with no traffic
46
+ * are left out.
47
+ */
48
+ export declare function planChannels(objects: Box[], edges: ModelEdge[], routing?: {
49
+ edgeGap?: number;
50
+ portGap?: number;
51
+ standoff?: number;
52
+ }): Map<string, Channel>;
53
+ export {};
@@ -0,0 +1,162 @@
1
+ import { type ResolvedAppearance } from '../model/appearance';
2
+ import type { CellsChrome, Lane, SequenceLayout } from '../model/types';
3
+ import { GROUP_HEADER, GROUP_INSET, contentOrigin } from './frame';
4
+ import { type Model, type ModelEdge, type ModelLayout, type ModelObject } from './syntax';
5
+ /** The single render context. Browser window size changes the camera, never the layout. */
6
+ export declare const RENDER_CONTEXT: {
7
+ readonly width: 1100;
8
+ readonly height: 720;
9
+ };
10
+ export { GROUP_HEADER, GROUP_INSET, contentOrigin };
11
+ export interface SceneObject extends ModelObject {
12
+ /** World (diagram) coordinates. */
13
+ x: number;
14
+ y: number;
15
+ w: number;
16
+ h: number;
17
+ /** Position relative to the parent's content origin; `pin` and `stay` use these. */
18
+ localX: number;
19
+ localY: number;
20
+ /** Local position from the automatic recipe alone, before refinements; `nudge` offsets this. */
21
+ baseX: number;
22
+ baseY: number;
23
+ depth: number;
24
+ /** Sequence participants: how far the dashed lifeline runs below the box. */
25
+ lifeline?: number;
26
+ /** Soft groups: the tint's rectangles, relative to the group's top left; the first holds the label. */
27
+ hull?: Array<{
28
+ x: number;
29
+ y: number;
30
+ w: number;
31
+ h: number;
32
+ }>;
33
+ /** Groups: lines the title wraps to, when more than one. */
34
+ titleLines?: number;
35
+ }
36
+ export interface Diagnostic {
37
+ level: 'error' | 'warning' | 'info';
38
+ code: string;
39
+ message: string;
40
+ /** Source line of the rule involved, when there is one. */
41
+ line?: number;
42
+ ids: string[];
43
+ }
44
+ /** A connection as the file declares it, plus the lane a fold's wrap edge returns along. */
45
+ export interface SceneEdge extends ModelEdge {
46
+ lane?: Lane;
47
+ /** A sequence message: the height of its row; it is drawn straight between lifelines there. */
48
+ row?: number;
49
+ }
50
+ export interface Scene {
51
+ model: Model;
52
+ title: string;
53
+ objects: SceneObject[];
54
+ byId: Map<string, SceneObject>;
55
+ edges: SceneEdge[];
56
+ diagnostics: Diagnostic[];
57
+ /** The file's resolved appearance: the spacing and type every size above was computed with. */
58
+ look: ResolvedAppearance;
59
+ /** Rulers and run-on pieces of byte and bit layouts, by group. */
60
+ cells: Map<string, CellsChrome>;
61
+ /** Sequence diagrams: the panel they are drawn on and their phases' row bands. */
62
+ sequence?: SequenceLayout;
63
+ }
64
+ type Size = {
65
+ w: number;
66
+ h: number;
67
+ };
68
+ type Pos = {
69
+ x: number;
70
+ y: number;
71
+ };
72
+ export declare function compile(source: string): Promise<Scene>;
73
+ /**
74
+ * Check source synchronously: every error `compile` can report, without running layout engines
75
+ * (they never add errors). Engine-governed scopes keep their built-in recipe in the result.
76
+ */
77
+ export declare function checkSource(source: string): Scene;
78
+ /**
79
+ * The scene as layout sees it, for edits that write positions: soft and frameless groups left
80
+ * out, and each object under the container that lays it out, which its local position is
81
+ * relative to.
82
+ */
83
+ export declare function layoutView(scene: Scene): Scene;
84
+ /** How far a soft refinement may give way before `check` warns that it no longer holds. */
85
+ export declare const RELAXED_WARNING = 16;
86
+ /** Solver budget for engine recipes; the same budget Compare and the timeline use. */
87
+ export declare const ENGINE_ITERATIONS = 640;
88
+ /** A labelled edge between two siblings, with the room its label needs across and down a gap. */
89
+ interface LabelRoom {
90
+ a: string;
91
+ b: string;
92
+ w: number;
93
+ h: number;
94
+ }
95
+ export declare function layoutFor(m: Model, scope: string): ModelLayout;
96
+ /**
97
+ * Size of a node: its requested size, or the default width with a height that fits the title in
98
+ * the theme's type and padding. A requested size is kept exactly; `overflow` reports a title that
99
+ * no longer fits in it.
100
+ */
101
+ export declare function leafSize(o: ModelObject, size: {
102
+ width: number;
103
+ height?: number;
104
+ } | undefined, look: ResolvedAppearance): {
105
+ w: number;
106
+ h: number;
107
+ overflow: boolean;
108
+ };
109
+ /**
110
+ * Longest-path ranks, in declaration order. Cycles are broken first: a depth-first walk from the
111
+ * sources (then any node not yet reached), in declaration order, sets aside each edge that returns
112
+ * to a node still on the walk. A loop therefore keeps its path along the reading direction and
113
+ * only its return edge runs backwards.
114
+ */
115
+ export declare function rankLayers(ids: string[], pairs: Array<[string, string]>): string[][];
116
+ /** A folded run: each band's ids in reading order, and the axis the bands read along. */
117
+ export interface Fold {
118
+ bands: string[][];
119
+ axis: 'right' | 'down';
120
+ }
121
+ /**
122
+ * Fold a long run of ranks into bands, like lines of text: each band starts again at the
123
+ * beginning of the reading direction, and the bands stack across it. A run that is longer than
124
+ * the render context and more than `FOLD_ASPECT` times its depth is cut only between ranks (where
125
+ * no box spans the cut), into the fewest bands that bring it within both. Within a quarter of an
126
+ * even share, a cut is chosen for the fewest edges across it, keeping each decision with its
127
+ * branches and each loop whole, before an exact balance. Other runs are returned unchanged.
128
+ *
129
+ * `plan` is the same run laid out without its edge labels. Whether to fold, how many bands and
130
+ * where to cut are decided on it, so relabelling an edge never adds a band or moves a cut: the
131
+ * labels only widen the gaps they need inside their own band.
132
+ */
133
+ export declare function foldRanks(items: Array<{
134
+ id: string;
135
+ w: number;
136
+ h: number;
137
+ }>, positions: Map<string, Pos>, axis: 'right' | 'down', gap: number, pairs: Array<[string, string]>, rooms?: LabelRoom[], decisions?: Set<string>, plan?: Map<string, Pos>, { aspect, fewest, room, }?: {
138
+ aspect?: number;
139
+ fewest?: number;
140
+ room?: number;
141
+ }): {
142
+ positions: Map<string, Pos>;
143
+ fold?: Fold;
144
+ };
145
+ /** How many times orthogonal paths, given as points along and across, cross one another. */
146
+ export declare function crossings(paths: Array<Array<{
147
+ u: number;
148
+ v: number;
149
+ }>>): number;
150
+ /** The order of up to six items that scores fewest crossings; the first such, from `items`. */
151
+ export declare function fewestCrossings<T>(items: T[], score: (order: T[]) => number): T[];
152
+ /**
153
+ * Lay out a model. `arranged` holds world positions from layout engines; scopes that an engine
154
+ * governs take their children's relative placement from it instead of their built-in recipe.
155
+ *
156
+ * Nodes are laid out on slots: their size in the reference appearance (the default theme, with
157
+ * the file's own overrides), so a theme switch keeps rows, order and positions. Each node is drawn
158
+ * at its theme's size in its slot. A slot grows only where the theme's size is larger
159
+ * than the scope's gap can absorb (`SLOT_SPILL`), or where spilling would bring two boxes closer
160
+ * than `MIN_GAP`. With `slots`, objects come out at their slot size (the engines' input).
161
+ */
162
+ export declare function layoutModel(m: Model, arranged?: Map<string, Pos & Size>, slots?: boolean): Scene;
@@ -0,0 +1,38 @@
1
+ /** Group frame metrics shared by the compiler, the projection and the translator. */
2
+ /** Space between a group's frame and its content, on the sides and bottom. */
3
+ export declare const GROUP_INSET = 24;
4
+ /**
5
+ * Space between a group's top edge and its content in the default theme; the title sits in it.
6
+ * Themes with taller titles reserve more (`ResolvedAppearance.groupHeader`).
7
+ */
8
+ export declare const GROUP_HEADER = 48;
9
+ /**
10
+ * Horizontal room a group title needs besides its text: the icon and gap before it (33) and the
11
+ * frame controls after it (64), as `GroupView` and the SVG export truncate titles.
12
+ */
13
+ export declare const GROUP_TITLE_CHROME: number;
14
+ /** Room a soft group's tint leaves round its members, and above them for its label. */
15
+ export declare const SOFT_PAD = 10;
16
+ export declare const SOFT_LABEL = 18;
17
+ /** Where a soft group's label sits in its tint: in the annotation face, at the top left. */
18
+ export declare const SOFT_TITLE: {
19
+ x: number;
20
+ y: number;
21
+ };
22
+ /** Corner radius of each rectangle of a tint; small, so joined rectangles read as one shape. */
23
+ export declare const SOFT_RADIUS = 6;
24
+ /** Dash of a sequence participant's lifeline; quieter than a message line. */
25
+ export declare const LIFELINE: {
26
+ dash: string;
27
+ width: number;
28
+ };
29
+ /** Top-left of a group's content area, which its children's local positions are relative to. */
30
+ export declare const contentOrigin: (group: {
31
+ x: number;
32
+ y: number;
33
+ }, header?: number) => {
34
+ x: number;
35
+ y: number;
36
+ };
37
+ /** Horizontal room a `cells` group's title needs besides its text: padding and the collapse control. */
38
+ export declare const CELLS_TITLE_CHROME: number;
@@ -0,0 +1,23 @@
1
+ import type { Lane } from '../model/types';
2
+ import type { ModelEdge } from './syntax';
3
+ interface Box {
4
+ id: string;
5
+ type: string;
6
+ shape?: string;
7
+ parent: string;
8
+ x: number;
9
+ y: number;
10
+ w: number;
11
+ h: number;
12
+ }
13
+ /** A scope arranged along a reading axis, with its fold's bands when it folded. */
14
+ export interface FlowScope {
15
+ scope: string;
16
+ axis: 'right' | 'down';
17
+ bands?: string[][];
18
+ }
19
+ export declare function returnLanes(flows: FlowScope[], edges: ModelEdge[], byId: Map<string, Box>, taken: Set<string>, labelSize?: (label: string) => {
20
+ w: number;
21
+ h: number;
22
+ }): Map<string, Lane>;
23
+ export {};
@@ -0,0 +1,3 @@
1
+ import type { Diagnostic } from './compile';
2
+ import type { Model } from './syntax';
3
+ export declare function legendNotes(m: Model): Diagnostic[];
@@ -0,0 +1,39 @@
1
+ import type { Diagram, Rect } from '../model/types';
2
+ import type { Scene } from './compile';
3
+ /** Editor state that is not part of the source and survives a reprojection. */
4
+ export type ViewState = Partial<Pick<Diagram, 'settings' | 'camera' | 'theme' | 'collapsed'>>;
5
+ export declare function projectScene(scene: Scene, view?: ViewState): Diagram;
6
+ export interface CanonicalGeometry {
7
+ nodes: Array<{
8
+ id: string;
9
+ parent: string;
10
+ x: number;
11
+ y: number;
12
+ w: number;
13
+ h: number;
14
+ }>;
15
+ routes: Array<{
16
+ id: string;
17
+ points: Array<{
18
+ x: number;
19
+ y: number;
20
+ }>;
21
+ }>;
22
+ }
23
+ /** Rectangles for everything visible, as the canvas draws them. */
24
+ export declare function visibleRects(doc: Diagram): {
25
+ vg: import("../model/graph").VisibleGraph;
26
+ rects: Map<string, Rect>;
27
+ };
28
+ /**
29
+ * Node rectangles and route points for a projected document. Edge label positions are left out:
30
+ * the browser measures label text with real fonts, which Node cannot reproduce.
31
+ */
32
+ export declare function canonicalGeometry(doc: Diagram): CanonicalGeometry;
33
+ export declare function measured(doc: Diagram, rects: Map<string, Rect>, routes: Array<{
34
+ id: string;
35
+ points: Array<{
36
+ x: number;
37
+ y: number;
38
+ }>;
39
+ }>): CanonicalGeometry;