@restless-dreams/orbit 0.0.0-stage → 0.2.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/LICENSE +21 -0
- package/README.md +168 -2
- package/dist/bin/orbit.js +11666 -0
- package/dist/bin/orbit.js.map +60 -0
- package/dist/chunk-fkdfgtx9.js +17295 -0
- package/dist/chunk-fkdfgtx9.js.map +75 -0
- package/dist/chunk-y748hzcr.js +82 -0
- package/dist/chunk-y748hzcr.js.map +10 -0
- package/dist/chunk-zze4tc9n.js +408 -0
- package/dist/chunk-zze4tc9n.js.map +10 -0
- package/dist/core/auto-render.d.ts +85 -0
- package/dist/core/branch-colors.d.ts +57 -0
- package/dist/core/browser.d.ts +23 -0
- package/dist/core/create.d.ts +23 -0
- package/dist/core/diagnostics.d.ts +40 -0
- package/dist/core/dispatch.d.ts +23 -0
- package/dist/core/document-options.d.ts +18 -0
- package/dist/core/document-source.d.ts +128 -0
- package/dist/core/editing.d.ts +66 -0
- package/dist/core/engine/animation-clock.d.ts +40 -0
- package/dist/core/engine/camera.d.ts +70 -0
- package/dist/core/engine/colors.d.ts +51 -0
- package/dist/core/engine/display.d.ts +125 -0
- package/dist/core/engine/export.d.ts +32 -0
- package/dist/core/engine/glide.d.ts +34 -0
- package/dist/core/engine/labels.d.ts +106 -0
- package/dist/core/engine/node-drag.d.ts +49 -0
- package/dist/core/engine/scene.d.ts +160 -0
- package/dist/core/engine/spin.d.ts +62 -0
- package/dist/core/engine/surface-pattern.d.ts +20 -0
- package/dist/core/engine/text-measure.d.ts +116 -0
- package/dist/core/engine/views.d.ts +361 -0
- package/dist/core/extensions.d.ts +155 -0
- package/dist/core/format-upgrades.d.ts +33 -0
- package/dist/core/index.d.ts +46 -0
- package/dist/core/input-controller.d.ts +116 -0
- package/dist/core/languages.d.ts +201 -0
- package/dist/core/layout.d.ts +61 -0
- package/dist/core/map-tools/definitions.d.ts +71 -0
- package/dist/core/map-tools/input.d.ts +62 -0
- package/dist/core/map-tools/reading.d.ts +40 -0
- package/dist/core/map-tools/tools.d.ts +51 -0
- package/dist/core/markdown-writing.d.ts +87 -0
- package/dist/core/material.d.ts +25 -0
- package/dist/core/media.d.ts +42 -0
- package/dist/core/node-attributes.d.ts +31 -0
- package/dist/core/node-links.d.ts +25 -0
- package/dist/core/other-apps/freemind.d.ts +8 -0
- package/dist/core/other-apps/icons.d.ts +16 -0
- package/dist/core/other-apps/ideas.d.ts +76 -0
- package/dist/core/other-apps/import.d.ts +28 -0
- package/dist/core/other-apps/inflate.d.ts +22 -0
- package/dist/core/other-apps/markup.d.ts +51 -0
- package/dist/core/other-apps/notes.d.ts +80 -0
- package/dist/core/other-apps/opml.d.ts +26 -0
- package/dist/core/other-apps/reading.d.ts +36 -0
- package/dist/core/other-apps/xmind.d.ts +14 -0
- package/dist/core/other-apps/zip.d.ts +37 -0
- package/dist/core/parser-markdown.d.ts +42 -0
- package/dist/core/parser-yaml.d.ts +8 -0
- package/dist/core/print-layout.d.ts +70 -0
- package/dist/core/render-to-svg.d.ts +57 -0
- package/dist/core/renderer/content-painter.d.ts +30 -0
- package/dist/core/renderer/dom.d.ts +15 -0
- package/dist/core/renderer/families.d.ts +35 -0
- package/dist/core/renderer/label-painter.d.ts +93 -0
- package/dist/core/renderer/node-painter.d.ts +113 -0
- package/dist/core/renderer/numbers.d.ts +2 -0
- package/dist/core/renderer/options.d.ts +12 -0
- package/dist/core/renderer/rings-and-links.d.ts +23 -0
- package/dist/core/renderer/scene-helpers.d.ts +33 -0
- package/dist/core/renderer/trees.d.ts +22 -0
- package/dist/core/serializer-markdown.d.ts +18 -0
- package/dist/core/serializer-yaml.d.ts +2 -0
- package/dist/core/source-patch.d.ts +24 -0
- package/dist/core/source.d.ts +27 -0
- package/dist/core/styles.d.ts +6 -0
- package/dist/core/suggest.d.ts +8 -0
- package/dist/core/svg-renderer.d.ts +626 -0
- package/dist/core/text-layout.d.ts +54 -0
- package/dist/core/themes.d.ts +62 -0
- package/dist/core/types.d.ts +471 -0
- package/dist/core/ui/actions.d.ts +75 -0
- package/dist/core/ui/controls.d.ts +61 -0
- package/dist/core/ui/detail-sheet.d.ts +88 -0
- package/dist/core/ui/frames.d.ts +11 -0
- package/dist/core/ui/icons.d.ts +14 -0
- package/dist/core/ui/inline-editor.d.ts +79 -0
- package/dist/core/ui/media-players.d.ts +65 -0
- package/dist/core/ui/media-viewer.d.ts +169 -0
- package/dist/core/ui/media-zoom.d.ts +51 -0
- package/dist/core/ui/note-markdown.d.ts +19 -0
- package/dist/core/ui/outline.d.ts +44 -0
- package/dist/core/url-guard.d.ts +40 -0
- package/dist/core/utils.d.ts +23 -0
- package/dist/core/web-page/page.d.ts +59 -0
- package/dist/core/web-page/runtime.d.ts +13 -0
- package/dist/core/web-page/start.d.ts +1 -0
- package/dist/core/yaml-mini.d.ts +54 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +4357 -0
- package/dist/index.js.map +29 -0
- package/dist/marked/index.d.ts +31 -0
- package/dist/marked/index.js +110 -0
- package/dist/marked/index.js.map +10 -0
- package/dist/react/index.d.ts +55 -0
- package/dist/react/index.js +352 -0
- package/dist/react/index.js.map +1 -0
- package/dist/web-page.d.ts +2 -0
- package/dist/web-page.js +130 -0
- package/llms-full.txt +2785 -0
- package/llms.txt +36 -0
- package/package.json +118 -4
- package/skills/orbit/SKILL.md +140 -0
- package/skills/orbit/references/editing.md +195 -0
- package/skills/orbit/references/extending.md +247 -0
- package/skills/orbit/references/format.md +331 -0
- package/skills/orbit/references/guide.md +546 -0
- package/skills/orbit/references/import-export.md +115 -0
- package/skills/orbit/references/languages.md +160 -0
- package/skills/orbit/references/map-tools.md +188 -0
- package/skills/orbit/references/media.md +160 -0
- package/skills/orbit/references/recipes.md +236 -0
- package/skills/orbit/references/theming.md +199 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* marked integration: turns ```orbit (or ~~~orbit) fences into map
|
|
3
|
+
* placeholders that `hydrateOrbitBlocks()` brings to life in the browser.
|
|
4
|
+
*/
|
|
5
|
+
import type { MarkedExtension, RendererExtension, TokenizerExtension } from 'marked';
|
|
6
|
+
import type { AutoRenderOptions } from '../core/auto-render.js';
|
|
7
|
+
import type { OrbitSVGRenderer } from '../core/svg-renderer.js';
|
|
8
|
+
/**
|
|
9
|
+
* The marked extension, for `new Marked(orbitMarked())` or
|
|
10
|
+
* `marked.use(orbitMarked())`.
|
|
11
|
+
*/
|
|
12
|
+
export declare const orbitMarked: () => MarkedExtension;
|
|
13
|
+
/** The tokenizer and renderer that `orbitMarked()` wraps. */
|
|
14
|
+
export declare const createOrbitExtension: () => TokenizerExtension & RendererExtension;
|
|
15
|
+
/**
|
|
16
|
+
* Renders markdown to HTML with orbit fences turned into placeholders. Uses
|
|
17
|
+
* its own marked instance, so the global `marked` is left untouched.
|
|
18
|
+
*/
|
|
19
|
+
export declare const renderOrbitMarkdown: (markdown: string) => Promise<string>;
|
|
20
|
+
/**
|
|
21
|
+
* Registers the extension on a marked instance (the global `marked` by
|
|
22
|
+
* default) and returns it. Calling it again for the same instance is a no-op.
|
|
23
|
+
*/
|
|
24
|
+
export declare const configureMarked: <Instance extends {
|
|
25
|
+
use: (...extensions: MarkedExtension[]) => unknown;
|
|
26
|
+
}>(instance?: Instance) => Instance;
|
|
27
|
+
/**
|
|
28
|
+
* Turns every orbit placeholder under `root` (default: the whole document)
|
|
29
|
+
* into a live map. Call it after inserting the rendered HTML.
|
|
30
|
+
*/
|
|
31
|
+
export declare const hydrateOrbitBlocks: (root?: ParentNode, options?: AutoRenderOptions) => OrbitSVGRenderer[];
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import {
|
|
2
|
+
renderOrbitMarkdownBlocks2
|
|
3
|
+
} from "../chunk-zze4tc9n.js";
|
|
4
|
+
import {
|
|
5
|
+
parseOrbit2
|
|
6
|
+
} from "../chunk-fkdfgtx9.js";
|
|
7
|
+
|
|
8
|
+
// src/marked/index.ts
|
|
9
|
+
import { Marked, marked } from "marked";
|
|
10
|
+
var SETTING_ATTRIBUTES = {
|
|
11
|
+
height: "data-height",
|
|
12
|
+
theme: "data-theme",
|
|
13
|
+
view: "data-view-mode",
|
|
14
|
+
"view-mode": "data-view-mode",
|
|
15
|
+
"max-depth": "data-max-depth",
|
|
16
|
+
maxDepth: "data-max-depth",
|
|
17
|
+
palette: "data-palette",
|
|
18
|
+
animation: "data-animation",
|
|
19
|
+
interactive: "data-interactive"
|
|
20
|
+
};
|
|
21
|
+
var FENCE_START = /^ {0,3}(?:`{3,}|~{3,})orbit(?=\s|$)/m;
|
|
22
|
+
var FENCE = /^ {0,3}(`{3,}|~{3,})orbit(?=\s|$)([^\n`]*)\n([\s\S]*?)(?:\n {0,3}\1[`~]*[ \t]*(?:\n+|$)|$)/;
|
|
23
|
+
var orbitMarked = () => {
|
|
24
|
+
return { extensions: [createOrbitExtension()] };
|
|
25
|
+
};
|
|
26
|
+
var createOrbitExtension = () => {
|
|
27
|
+
return {
|
|
28
|
+
name: "orbit",
|
|
29
|
+
level: "block",
|
|
30
|
+
start(source) {
|
|
31
|
+
const match = FENCE_START.exec(source);
|
|
32
|
+
return match ? match.index : undefined;
|
|
33
|
+
},
|
|
34
|
+
tokenizer(source) {
|
|
35
|
+
const match = FENCE.exec(source);
|
|
36
|
+
if (!match) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
type: "orbit",
|
|
41
|
+
raw: match[0],
|
|
42
|
+
text: match[3],
|
|
43
|
+
settings: parseSettings(match[2])
|
|
44
|
+
};
|
|
45
|
+
},
|
|
46
|
+
renderer(token) {
|
|
47
|
+
const orbitToken = token;
|
|
48
|
+
if (orbitToken.type !== "orbit") {
|
|
49
|
+
return "";
|
|
50
|
+
}
|
|
51
|
+
const attributes = [`class="orbit-mind-map"`, `data-orbit="${escapeHtml(orbitToken.text.trim())}"`];
|
|
52
|
+
for (const [key, value] of Object.entries(orbitToken.settings)) {
|
|
53
|
+
const attribute = SETTING_ATTRIBUTES[key];
|
|
54
|
+
if (attribute) {
|
|
55
|
+
attributes.push(`${attribute}="${escapeHtml(value)}"`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return `<div ${attributes.join(" ")}>${fallbackOutline(orbitToken.text)}</div>
|
|
59
|
+
`;
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
var privateInstance = null;
|
|
64
|
+
var renderOrbitMarkdown = async (markdown) => {
|
|
65
|
+
privateInstance ??= new Marked(orbitMarked());
|
|
66
|
+
return privateInstance.parse(markdown);
|
|
67
|
+
};
|
|
68
|
+
var configuredInstances = new WeakSet;
|
|
69
|
+
var configureMarked = (instance = marked) => {
|
|
70
|
+
if (!configuredInstances.has(instance)) {
|
|
71
|
+
instance.use(orbitMarked());
|
|
72
|
+
configuredInstances.add(instance);
|
|
73
|
+
}
|
|
74
|
+
return instance;
|
|
75
|
+
};
|
|
76
|
+
var hydrateOrbitBlocks = (root, options = {}) => {
|
|
77
|
+
return renderOrbitMarkdownBlocks2(root, options);
|
|
78
|
+
};
|
|
79
|
+
var parseSettings = (infoString) => {
|
|
80
|
+
const settings = {};
|
|
81
|
+
for (const match of infoString.matchAll(/([\w-]+)=(?:"([^"]*)"|'([^']*)'|(\S+))/g)) {
|
|
82
|
+
settings[match[1]] = match[2] ?? match[3] ?? match[4];
|
|
83
|
+
}
|
|
84
|
+
return settings;
|
|
85
|
+
};
|
|
86
|
+
var fallbackOutline = (source) => {
|
|
87
|
+
const { root } = parseOrbit2(source);
|
|
88
|
+
if (!root.text && root.children.length === 0) {
|
|
89
|
+
return "";
|
|
90
|
+
}
|
|
91
|
+
return `<ul class="orbit-mind-map__outline">${outlineItem(root)}</ul>`;
|
|
92
|
+
};
|
|
93
|
+
var outlineItem = (node) => {
|
|
94
|
+
const label = escapeHtml([node.icon, node.text].filter(Boolean).join(" "));
|
|
95
|
+
const children = node.children.length > 0 ? `<ul>${node.children.map(outlineItem).join("")}</ul>` : "";
|
|
96
|
+
return `<li>${label}${children}</li>`;
|
|
97
|
+
};
|
|
98
|
+
var escapeHtml = (value) => {
|
|
99
|
+
return value.replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">");
|
|
100
|
+
};
|
|
101
|
+
export {
|
|
102
|
+
configureMarked,
|
|
103
|
+
createOrbitExtension,
|
|
104
|
+
hydrateOrbitBlocks,
|
|
105
|
+
orbitMarked,
|
|
106
|
+
renderOrbitMarkdown
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
//# debugId=2A6B8BC2016EF60F64756E2164756E21
|
|
110
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/marked/index.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * marked integration: turns ```orbit (or ~~~orbit) fences into map\n * placeholders that `hydrateOrbitBlocks()` brings to life in the browser.\n */\n\nimport { Marked, marked } from 'marked';\nimport type { MarkedExtension, RendererExtension, TokenizerExtension } from 'marked';\nimport { parseOrbit } from '../core/dispatch.js';\nimport { renderOrbitMarkdownBlocks } from '../core/auto-render.js';\nimport type { AutoRenderOptions } from '../core/auto-render.js';\nimport type { OrbitSVGRenderer } from '../core/svg-renderer.js';\nimport type { OrbitNode } from '../core/types.js';\n\ninterface OrbitToken {\n type: 'orbit';\n raw: string;\n text: string;\n settings: Record<string, string>;\n}\n\n// Options written after the language name: ```orbit height=480 theme=glass view=all\nconst SETTING_ATTRIBUTES: Record<string, string> = {\n height: 'data-height',\n theme: 'data-theme',\n view: 'data-view-mode',\n 'view-mode': 'data-view-mode',\n 'max-depth': 'data-max-depth',\n maxDepth: 'data-max-depth',\n palette: 'data-palette',\n animation: 'data-animation',\n interactive: 'data-interactive',\n};\n\nconst FENCE_START = /^ {0,3}(?:`{3,}|~{3,})orbit(?=\\s|$)/m;\nconst FENCE = /^ {0,3}(`{3,}|~{3,})orbit(?=\\s|$)([^\\n`]*)\\n([\\s\\S]*?)(?:\\n {0,3}\\1[`~]*[ \\t]*(?:\\n+|$)|$)/;\n\n/**\n * The marked extension, for `new Marked(orbitMarked())` or\n * `marked.use(orbitMarked())`.\n */\nexport const orbitMarked = (): MarkedExtension => {\n return { extensions: [createOrbitExtension()] };\n};\n\n/** The tokenizer and renderer that `orbitMarked()` wraps. */\nexport const createOrbitExtension = (): TokenizerExtension & RendererExtension => {\n return {\n name: 'orbit',\n level: 'block',\n start(source: string): number | undefined {\n const match = FENCE_START.exec(source);\n return match ? match.index : undefined;\n },\n tokenizer(source: string): OrbitToken | undefined {\n const match = FENCE.exec(source);\n\n if (!match) {\n return undefined;\n }\n\n return {\n type: 'orbit',\n raw: match[0],\n text: match[3],\n settings: parseSettings(match[2]),\n };\n },\n renderer(token): string {\n const orbitToken = token as unknown as OrbitToken;\n\n if (orbitToken.type !== 'orbit') {\n return '';\n }\n\n const attributes = [`class=\"orbit-mind-map\"`, `data-orbit=\"${escapeHtml(orbitToken.text.trim())}\"`];\n\n for (const [key, value] of Object.entries(orbitToken.settings)) {\n const attribute = SETTING_ATTRIBUTES[key];\n\n if (attribute) {\n attributes.push(`${attribute}=\"${escapeHtml(value)}\"`);\n }\n }\n\n return `<div ${attributes.join(' ')}>${fallbackOutline(orbitToken.text)}</div>\\n`;\n },\n };\n};\n\nlet privateInstance: Marked | null = null;\n\n/**\n * Renders markdown to HTML with orbit fences turned into placeholders. Uses\n * its own marked instance, so the global `marked` is left untouched.\n */\nexport const renderOrbitMarkdown = async (markdown: string): Promise<string> => {\n privateInstance ??= new Marked(orbitMarked());\n return privateInstance.parse(markdown);\n};\n\nconst configuredInstances = new WeakSet<object>();\n\n/**\n * Registers the extension on a marked instance (the global `marked` by\n * default) and returns it. Calling it again for the same instance is a no-op.\n */\nexport const configureMarked = <Instance extends { use: (...extensions: MarkedExtension[]) => unknown }>(\n instance: Instance = marked as unknown as Instance,\n): Instance => {\n if (!configuredInstances.has(instance)) {\n instance.use(orbitMarked());\n configuredInstances.add(instance);\n }\n\n return instance;\n};\n\n/**\n * Turns every orbit placeholder under `root` (default: the whole document)\n * into a live map. Call it after inserting the rendered HTML.\n */\nexport const hydrateOrbitBlocks = (root?: ParentNode, options: AutoRenderOptions = {}): OrbitSVGRenderer[] => {\n return renderOrbitMarkdownBlocks(root, options);\n};\n\nconst parseSettings = (infoString: string): Record<string, string> => {\n const settings: Record<string, string> = {};\n\n for (const match of infoString.matchAll(/([\\w-]+)=(?:\"([^\"]*)\"|'([^']*)'|(\\S+))/g)) {\n settings[match[1]] = match[2] ?? match[3] ?? match[4];\n }\n\n return settings;\n};\n\n/** A nested list of the map, shown to readers without JavaScript and replaced when the map hydrates. */\nconst fallbackOutline = (source: string): string => {\n const { root } = parseOrbit(source);\n\n if (!root.text && root.children.length === 0) {\n return '';\n }\n\n return `<ul class=\"orbit-mind-map__outline\">${outlineItem(root)}</ul>`;\n};\n\nconst outlineItem = (node: OrbitNode): string => {\n const label = escapeHtml([node.icon, node.text].filter(Boolean).join(' '));\n const children = node.children.length > 0 ? `<ul>${node.children.map(outlineItem).join('')}</ul>` : '';\n return `<li>${label}${children}</li>`;\n};\n\nconst escapeHtml = (value: string): string => {\n return value\n .replace(/&/g, '&')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/</g, '<')\n .replace(/>/g, '>');\n};\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "2A6B8BC2016EF60F64756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React wrapper around the framework-agnostic `OrbitSVGRenderer`.
|
|
3
|
+
*/
|
|
4
|
+
import type { HTMLAttributes } from 'react';
|
|
5
|
+
import { OrbitSVGRenderer } from '../core/svg-renderer.js';
|
|
6
|
+
import type { OrbitDocument, OrbitNode, RendererOptions, ViewMode } from '../core/types.js';
|
|
7
|
+
export interface OrbitMindMapProps extends RendererOptions, Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
8
|
+
/** Markdown or YAML source, parsed with `parseOrbit`. Its frontmatter options apply unless a prop overrides them. */
|
|
9
|
+
source?: string;
|
|
10
|
+
/** A parsed document. Its frontmatter options apply unless a prop overrides them. */
|
|
11
|
+
document?: OrbitDocument;
|
|
12
|
+
/** A node tree, for maps built in code. */
|
|
13
|
+
data?: OrbitNode;
|
|
14
|
+
/**
|
|
15
|
+
* The focused node's id, to control focus from your state. The map flies
|
|
16
|
+
* to it when it changes; pair it with `onFocusChange` to follow the reader.
|
|
17
|
+
*/
|
|
18
|
+
focusedId?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Render a static SVG of the map until the live one mounts, so server
|
|
21
|
+
* rendering and slow connections show the map right away. Default true.
|
|
22
|
+
*/
|
|
23
|
+
staticFallback?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface OrbitMindMapRef {
|
|
26
|
+
/** The renderer, once the map has mounted. */
|
|
27
|
+
readonly renderer: OrbitSVGRenderer | null;
|
|
28
|
+
/** Flies to a node by id, in focus mode. Returns false when there's no such node. */
|
|
29
|
+
flyTo(nodeId: string): boolean;
|
|
30
|
+
/** Flies out to the overview of the whole map. */
|
|
31
|
+
overview(): void;
|
|
32
|
+
getViewMode(): ViewMode | null;
|
|
33
|
+
setViewMode(mode: ViewMode): void;
|
|
34
|
+
/** Zooms by `factor` around the middle of the map (above 1 zooms in). */
|
|
35
|
+
zoomBy(factor: number): void;
|
|
36
|
+
/** Returns the camera to the fitted view. */
|
|
37
|
+
fit(): void;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Renders an orbit map that fills its parent element, so give the parent a
|
|
41
|
+
* size. Pass the map as `source` (markdown or YAML), `document` or `data`.
|
|
42
|
+
*
|
|
43
|
+
* Callback props can be inline functions and `theme` / `palette` can be
|
|
44
|
+
* inline objects: they never rebuild the map unless their values change.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```tsx
|
|
48
|
+
* import { OrbitMindMap } from '@restless-dreams/orbit/react';
|
|
49
|
+
*
|
|
50
|
+
* <div style={{ height: 480 }}>
|
|
51
|
+
* <OrbitMindMap source={'# Launch\n## Research\n## Build'} theme="night" onFocusChange={(node) => console.log(node.text)} />
|
|
52
|
+
* </div>
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export declare const OrbitMindMap: import("react").ForwardRefExoticComponent<OrbitMindMapProps & import("react").RefAttributes<OrbitMindMapRef>>;
|
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
renderToSVGString2
|
|
4
|
+
} from "../chunk-y748hzcr.js";
|
|
5
|
+
import {
|
|
6
|
+
reportParseDiagnostics,
|
|
7
|
+
parseOrbit2,
|
|
8
|
+
OrbitWords,
|
|
9
|
+
OrbitSVGRenderer2
|
|
10
|
+
} from "../chunk-fkdfgtx9.js";
|
|
11
|
+
|
|
12
|
+
// src/react/index.ts
|
|
13
|
+
import { createElement, forwardRef, useEffect, useId, useImperativeHandle, useMemo, useRef, useState } from "react";
|
|
14
|
+
var actionsKey = (actions) => {
|
|
15
|
+
return actions.map((action) => [action.id, typeof action.label === "string" ? action.label : null, action.icon ?? null, Boolean(action.when)]);
|
|
16
|
+
};
|
|
17
|
+
var nodeTypesKey = (types) => {
|
|
18
|
+
return JSON.stringify(Object.entries(types).map(([name, type]) => [
|
|
19
|
+
name,
|
|
20
|
+
type.label ?? null,
|
|
21
|
+
type.icon ?? null,
|
|
22
|
+
type.color ?? null,
|
|
23
|
+
type.tokens ?? null,
|
|
24
|
+
type.version ?? null,
|
|
25
|
+
Boolean(type.render),
|
|
26
|
+
Boolean(type.details),
|
|
27
|
+
Boolean(type.upgrade),
|
|
28
|
+
type.actions ? actionsKey(type.actions) : null
|
|
29
|
+
]));
|
|
30
|
+
};
|
|
31
|
+
var delegateActions = (actions, read) => {
|
|
32
|
+
return actions.map((action) => {
|
|
33
|
+
const latest = () => read()?.find((candidate) => candidate.id === action.id) ?? action;
|
|
34
|
+
return {
|
|
35
|
+
id: action.id,
|
|
36
|
+
icon: action.icon,
|
|
37
|
+
label: typeof action.label === "function" ? (node) => {
|
|
38
|
+
const label = latest().label;
|
|
39
|
+
return typeof label === "function" ? label(node) : label;
|
|
40
|
+
} : action.label,
|
|
41
|
+
when: action.when ? (node) => latest().when?.(node) ?? true : undefined,
|
|
42
|
+
run: (node, event) => latest().run(node, event)
|
|
43
|
+
};
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
var delegateNodeTypes = (types, read) => {
|
|
47
|
+
return Object.fromEntries(Object.entries(types).map(([name, type]) => [name, {
|
|
48
|
+
label: type.label,
|
|
49
|
+
icon: type.icon,
|
|
50
|
+
color: type.color,
|
|
51
|
+
tokens: type.tokens,
|
|
52
|
+
version: type.version,
|
|
53
|
+
upgrade: type.upgrade ? (node, from) => read()?.[name]?.upgrade?.(node, from) : undefined,
|
|
54
|
+
render: type.render ? (node, element) => read()?.[name]?.render?.(node, element) : undefined,
|
|
55
|
+
details: type.details ? (node, element) => read()?.[name]?.details?.(node, element) : undefined,
|
|
56
|
+
actions: type.actions ? delegateActions(type.actions, () => read()?.[name]?.actions) : undefined
|
|
57
|
+
}]));
|
|
58
|
+
};
|
|
59
|
+
var OrbitMindMap = forwardRef(({
|
|
60
|
+
source,
|
|
61
|
+
document: orbitDocument,
|
|
62
|
+
data,
|
|
63
|
+
viewMode,
|
|
64
|
+
showRings,
|
|
65
|
+
interactive,
|
|
66
|
+
orbitAnimation,
|
|
67
|
+
orbitSpeed,
|
|
68
|
+
maxDepth,
|
|
69
|
+
palette,
|
|
70
|
+
theme,
|
|
71
|
+
ariaLabel,
|
|
72
|
+
language,
|
|
73
|
+
strings,
|
|
74
|
+
showControls,
|
|
75
|
+
showActionButtons,
|
|
76
|
+
showDetailSheet,
|
|
77
|
+
mediaViewer,
|
|
78
|
+
baseUrl,
|
|
79
|
+
spin,
|
|
80
|
+
zoom,
|
|
81
|
+
insets,
|
|
82
|
+
transitionDuration,
|
|
83
|
+
onNodeClick,
|
|
84
|
+
onViewModeChange,
|
|
85
|
+
onAction,
|
|
86
|
+
onFocusChange,
|
|
87
|
+
onSpinSettle,
|
|
88
|
+
onNodeContext,
|
|
89
|
+
onEdit,
|
|
90
|
+
onEditorOpen,
|
|
91
|
+
onEditorClose,
|
|
92
|
+
onNodeDrag,
|
|
93
|
+
onMediaOpen,
|
|
94
|
+
onMediaClose,
|
|
95
|
+
onMediaState,
|
|
96
|
+
editable,
|
|
97
|
+
editingKeys,
|
|
98
|
+
longPressDelay,
|
|
99
|
+
noteRenderer,
|
|
100
|
+
nodeTypeFor,
|
|
101
|
+
nodeTypes,
|
|
102
|
+
actions,
|
|
103
|
+
statuses,
|
|
104
|
+
focusedId,
|
|
105
|
+
focus,
|
|
106
|
+
staticFallback = true,
|
|
107
|
+
style,
|
|
108
|
+
...elementProps
|
|
109
|
+
}, ref) => {
|
|
110
|
+
const containerRef = useRef(null);
|
|
111
|
+
const staticRef = useRef(null);
|
|
112
|
+
const rendererRef = useRef(null);
|
|
113
|
+
const [mounted, setMounted] = useState(false);
|
|
114
|
+
const staticId = useId();
|
|
115
|
+
useImperativeHandle(ref, () => ({
|
|
116
|
+
get renderer() {
|
|
117
|
+
return rendererRef.current;
|
|
118
|
+
},
|
|
119
|
+
flyTo: (nodeId) => rendererRef.current?.flyTo(nodeId) ?? false,
|
|
120
|
+
overview: () => rendererRef.current?.overview(),
|
|
121
|
+
getViewMode: () => rendererRef.current?.getViewMode() ?? null,
|
|
122
|
+
setViewMode: (mode) => rendererRef.current?.setViewMode(mode),
|
|
123
|
+
zoomBy: (factor) => rendererRef.current?.zoomBy(factor),
|
|
124
|
+
fit: () => rendererRef.current?.fit()
|
|
125
|
+
}), []);
|
|
126
|
+
const callbacksRef = useRef({});
|
|
127
|
+
useEffect(() => {
|
|
128
|
+
callbacksRef.current = {
|
|
129
|
+
onNodeClick,
|
|
130
|
+
onViewModeChange,
|
|
131
|
+
onAction,
|
|
132
|
+
onFocusChange,
|
|
133
|
+
onSpinSettle,
|
|
134
|
+
onNodeContext,
|
|
135
|
+
onEdit,
|
|
136
|
+
onEditorOpen,
|
|
137
|
+
onEditorClose,
|
|
138
|
+
onNodeDrag,
|
|
139
|
+
onMediaOpen,
|
|
140
|
+
onMediaClose,
|
|
141
|
+
onMediaState,
|
|
142
|
+
noteRenderer,
|
|
143
|
+
nodeTypeFor
|
|
144
|
+
};
|
|
145
|
+
});
|
|
146
|
+
const hasNoteRenderer = noteRenderer !== undefined;
|
|
147
|
+
const hasNodeTypeFor = nodeTypeFor !== undefined;
|
|
148
|
+
const hasNodeContext = onNodeContext !== undefined;
|
|
149
|
+
const callbacks = useMemo(() => ({
|
|
150
|
+
onNodeClick: (node) => callbacksRef.current.onNodeClick?.(node),
|
|
151
|
+
onViewModeChange: (mode) => callbacksRef.current.onViewModeChange?.(mode),
|
|
152
|
+
onAction: (event) => callbacksRef.current.onAction?.(event),
|
|
153
|
+
onFocusChange: (node) => callbacksRef.current.onFocusChange?.(node),
|
|
154
|
+
onSpinSettle: (planet) => callbacksRef.current.onSpinSettle?.(planet),
|
|
155
|
+
onEdit: (edit) => callbacksRef.current.onEdit?.(edit),
|
|
156
|
+
onEditorOpen: (event) => callbacksRef.current.onEditorOpen?.(event),
|
|
157
|
+
onEditorClose: (event) => callbacksRef.current.onEditorClose?.(event),
|
|
158
|
+
onNodeDrag: (event) => callbacksRef.current.onNodeDrag?.(event),
|
|
159
|
+
onMediaOpen: (event) => callbacksRef.current.onMediaOpen?.(event),
|
|
160
|
+
onMediaClose: (event) => callbacksRef.current.onMediaClose?.(event),
|
|
161
|
+
onMediaState: (state) => callbacksRef.current.onMediaState?.(state),
|
|
162
|
+
onNodeContext: hasNodeContext ? (event) => callbacksRef.current.onNodeContext?.(event) : undefined,
|
|
163
|
+
noteRenderer: hasNoteRenderer ? (note, context) => callbacksRef.current.noteRenderer?.(note, context) ?? "" : undefined,
|
|
164
|
+
nodeTypeFor: hasNodeTypeFor ? (node) => callbacksRef.current.nodeTypeFor?.(node) : undefined
|
|
165
|
+
}), [hasNoteRenderer, hasNodeContext, hasNodeTypeFor]);
|
|
166
|
+
const extensionsRef = useRef({ nodeTypes, actions });
|
|
167
|
+
useEffect(() => {
|
|
168
|
+
extensionsRef.current = { nodeTypes, actions };
|
|
169
|
+
});
|
|
170
|
+
const typesKey = nodeTypes === undefined ? undefined : nodeTypesKey(nodeTypes);
|
|
171
|
+
const actionKey = actions === undefined ? undefined : JSON.stringify(actionsKey(actions));
|
|
172
|
+
const statusesKey = statuses === undefined ? undefined : JSON.stringify(statuses);
|
|
173
|
+
const stableNodeTypes = useMemo(() => nodeTypes === undefined ? undefined : delegateNodeTypes(nodeTypes, () => extensionsRef.current.nodeTypes), [typesKey]);
|
|
174
|
+
const stableActions = useMemo(() => actions === undefined ? undefined : delegateActions(actions, () => extensionsRef.current.actions), [actionKey]);
|
|
175
|
+
const stableStatuses = useMemo(() => statusesKey === undefined ? undefined : JSON.parse(statusesKey), [statusesKey]);
|
|
176
|
+
const themeKey = theme === undefined ? undefined : JSON.stringify(theme);
|
|
177
|
+
const paletteKey = palette === undefined ? undefined : JSON.stringify(palette);
|
|
178
|
+
const spinKey = spin === undefined ? undefined : JSON.stringify(spin);
|
|
179
|
+
const stringsKey = strings === undefined ? undefined : JSON.stringify(strings);
|
|
180
|
+
const zoomKey = zoom === undefined ? undefined : JSON.stringify(zoom);
|
|
181
|
+
const insetsKey = insets === undefined ? undefined : JSON.stringify(insets);
|
|
182
|
+
const stableTheme = useMemo(() => themeKey === undefined ? undefined : JSON.parse(themeKey), [themeKey]);
|
|
183
|
+
const stablePalette = useMemo(() => paletteKey === undefined ? undefined : JSON.parse(paletteKey), [paletteKey]);
|
|
184
|
+
const stableSpin = useMemo(() => spinKey === undefined ? undefined : JSON.parse(spinKey), [spinKey]);
|
|
185
|
+
const stableStrings = useMemo(() => stringsKey === undefined ? undefined : JSON.parse(stringsKey), [stringsKey]);
|
|
186
|
+
const stableZoom = useMemo(() => zoomKey === undefined ? undefined : JSON.parse(zoomKey), [zoomKey]);
|
|
187
|
+
const stableInsets = useMemo(() => insetsKey === undefined ? undefined : JSON.parse(insetsKey), [insetsKey]);
|
|
188
|
+
const options = useMemo(() => ({
|
|
189
|
+
viewMode,
|
|
190
|
+
showRings,
|
|
191
|
+
interactive,
|
|
192
|
+
orbitAnimation,
|
|
193
|
+
orbitSpeed,
|
|
194
|
+
maxDepth,
|
|
195
|
+
palette: stablePalette,
|
|
196
|
+
theme: stableTheme,
|
|
197
|
+
ariaLabel,
|
|
198
|
+
language,
|
|
199
|
+
strings: stableStrings,
|
|
200
|
+
showControls,
|
|
201
|
+
showActionButtons,
|
|
202
|
+
showDetailSheet,
|
|
203
|
+
mediaViewer,
|
|
204
|
+
editable,
|
|
205
|
+
editingKeys,
|
|
206
|
+
longPressDelay,
|
|
207
|
+
baseUrl,
|
|
208
|
+
spin: stableSpin,
|
|
209
|
+
zoom: stableZoom,
|
|
210
|
+
insets: stableInsets,
|
|
211
|
+
transitionDuration,
|
|
212
|
+
nodeTypes: stableNodeTypes,
|
|
213
|
+
actions: stableActions,
|
|
214
|
+
statuses: stableStatuses,
|
|
215
|
+
...callbacks
|
|
216
|
+
}), [
|
|
217
|
+
viewMode,
|
|
218
|
+
showRings,
|
|
219
|
+
interactive,
|
|
220
|
+
orbitAnimation,
|
|
221
|
+
orbitSpeed,
|
|
222
|
+
maxDepth,
|
|
223
|
+
stablePalette,
|
|
224
|
+
stableTheme,
|
|
225
|
+
ariaLabel,
|
|
226
|
+
language,
|
|
227
|
+
stableStrings,
|
|
228
|
+
showControls,
|
|
229
|
+
showActionButtons,
|
|
230
|
+
showDetailSheet,
|
|
231
|
+
mediaViewer,
|
|
232
|
+
editable,
|
|
233
|
+
editingKeys,
|
|
234
|
+
longPressDelay,
|
|
235
|
+
baseUrl,
|
|
236
|
+
stableSpin,
|
|
237
|
+
stableZoom,
|
|
238
|
+
stableInsets,
|
|
239
|
+
transitionDuration,
|
|
240
|
+
stableNodeTypes,
|
|
241
|
+
stableActions,
|
|
242
|
+
stableStatuses,
|
|
243
|
+
callbacks
|
|
244
|
+
]);
|
|
245
|
+
const input = useMemo(() => {
|
|
246
|
+
if (orbitDocument) {
|
|
247
|
+
return orbitDocument;
|
|
248
|
+
}
|
|
249
|
+
if (source !== undefined) {
|
|
250
|
+
const parsed = parseOrbit2(source, { untitled: language ? new OrbitWords(language, stableStrings).text("untitledMap") : undefined });
|
|
251
|
+
reportParseDiagnostics(parsed);
|
|
252
|
+
return parsed;
|
|
253
|
+
}
|
|
254
|
+
return data;
|
|
255
|
+
}, [orbitDocument, source, data, language, stableStrings]);
|
|
256
|
+
const optionsRef = useRef(options);
|
|
257
|
+
const initialFocusRef = useRef(focusedId ?? focus);
|
|
258
|
+
useEffect(() => {
|
|
259
|
+
optionsRef.current = options;
|
|
260
|
+
});
|
|
261
|
+
useEffect(() => {
|
|
262
|
+
if (staticRef.current) {
|
|
263
|
+
staticRef.current.hidden = true;
|
|
264
|
+
}
|
|
265
|
+
const renderer = new OrbitSVGRenderer2(containerRef.current, { ...optionsRef.current, focus: initialFocusRef.current });
|
|
266
|
+
rendererRef.current = renderer;
|
|
267
|
+
setMounted(true);
|
|
268
|
+
return () => {
|
|
269
|
+
renderer.destroy();
|
|
270
|
+
rendererRef.current = null;
|
|
271
|
+
};
|
|
272
|
+
}, []);
|
|
273
|
+
useEffect(() => {
|
|
274
|
+
rendererRef.current?.setOptions(options);
|
|
275
|
+
}, [options]);
|
|
276
|
+
useEffect(() => {
|
|
277
|
+
if (input) {
|
|
278
|
+
rendererRef.current?.render(input);
|
|
279
|
+
}
|
|
280
|
+
}, [input]);
|
|
281
|
+
useEffect(() => {
|
|
282
|
+
const renderer = rendererRef.current;
|
|
283
|
+
if (!renderer || focusedId === undefined) {
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
const path = renderer.getFocusPath();
|
|
287
|
+
if (path[path.length - 1] !== focusedId) {
|
|
288
|
+
renderer.focusNode(focusedId);
|
|
289
|
+
}
|
|
290
|
+
}, [focusedId, input]);
|
|
291
|
+
const staticMarkup = useMemo(() => {
|
|
292
|
+
if (!staticFallback || mounted || !input) {
|
|
293
|
+
return "";
|
|
294
|
+
}
|
|
295
|
+
return renderToSVGString2(input, {
|
|
296
|
+
responsive: true,
|
|
297
|
+
idPrefix: `orbit-static-${staticId.replace(/[^a-zA-Z0-9_-]/g, "")}`,
|
|
298
|
+
viewMode,
|
|
299
|
+
focus: focusedId ?? focus,
|
|
300
|
+
theme: stableTheme,
|
|
301
|
+
palette: stablePalette,
|
|
302
|
+
maxDepth,
|
|
303
|
+
showRings,
|
|
304
|
+
title: ariaLabel,
|
|
305
|
+
language,
|
|
306
|
+
strings: stableStrings,
|
|
307
|
+
baseUrl,
|
|
308
|
+
nodeTypes: stableNodeTypes,
|
|
309
|
+
statuses: stableStatuses
|
|
310
|
+
});
|
|
311
|
+
}, [
|
|
312
|
+
staticFallback,
|
|
313
|
+
mounted,
|
|
314
|
+
input,
|
|
315
|
+
staticId,
|
|
316
|
+
viewMode,
|
|
317
|
+
focusedId,
|
|
318
|
+
focus,
|
|
319
|
+
stableTheme,
|
|
320
|
+
stablePalette,
|
|
321
|
+
maxDepth,
|
|
322
|
+
showRings,
|
|
323
|
+
ariaLabel,
|
|
324
|
+
language,
|
|
325
|
+
stableStrings,
|
|
326
|
+
baseUrl,
|
|
327
|
+
stableNodeTypes,
|
|
328
|
+
stableStatuses
|
|
329
|
+
]);
|
|
330
|
+
return createElement("div", {
|
|
331
|
+
...elementProps,
|
|
332
|
+
ref: containerRef,
|
|
333
|
+
style: {
|
|
334
|
+
width: "100%",
|
|
335
|
+
height: "100%",
|
|
336
|
+
overflow: "hidden",
|
|
337
|
+
...style
|
|
338
|
+
}
|
|
339
|
+
}, staticMarkup ? createElement("div", {
|
|
340
|
+
ref: staticRef,
|
|
341
|
+
"data-orbit-static": "",
|
|
342
|
+
style: { width: "100%", height: "100%" },
|
|
343
|
+
dangerouslySetInnerHTML: { __html: staticMarkup }
|
|
344
|
+
}) : null);
|
|
345
|
+
});
|
|
346
|
+
OrbitMindMap.displayName = "OrbitMindMap";
|
|
347
|
+
export {
|
|
348
|
+
OrbitMindMap
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
//# debugId=86D75E1C55FAF80F64756E2164756E21
|
|
352
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/react/index.ts"],"sourcesContent":["/**\n * React wrapper around the framework-agnostic `OrbitSVGRenderer`.\n */\n\nimport { createElement, forwardRef, useEffect, useId, useImperativeHandle, useMemo, useRef, useState } from 'react';\nimport type { HTMLAttributes } from 'react';\nimport { OrbitSVGRenderer } from '../core/svg-renderer.js';\nimport { parseOrbit } from '../core/dispatch.js';\nimport { reportParseDiagnostics } from '../core/diagnostics.js';\nimport { OrbitWords } from '../core/languages.js';\nimport { renderToSVGString } from '../core/render-to-svg.js';\nimport type { OrbitAction, OrbitNodeType } from '../core/extensions.js';\nimport type { OrbitDocument, OrbitNode, RendererOptions, ViewMode } from '../core/types.js';\n\nexport interface OrbitMindMapProps extends RendererOptions, Omit<HTMLAttributes<HTMLDivElement>, 'children'> {\n /** Markdown or YAML source, parsed with `parseOrbit`. Its frontmatter options apply unless a prop overrides them. */\n source?: string;\n\n /** A parsed document. Its frontmatter options apply unless a prop overrides them. */\n document?: OrbitDocument;\n\n /** A node tree, for maps built in code. */\n data?: OrbitNode;\n\n /**\n * The focused node's id, to control focus from your state. The map flies\n * to it when it changes; pair it with `onFocusChange` to follow the reader.\n */\n focusedId?: string;\n\n /**\n * Render a static SVG of the map until the live one mounts, so server\n * rendering and slow connections show the map right away. Default true.\n */\n staticFallback?: boolean;\n}\n\nexport interface OrbitMindMapRef {\n /** The renderer, once the map has mounted. */\n readonly renderer: OrbitSVGRenderer | null;\n\n /** Flies to a node by id, in focus mode. Returns false when there's no such node. */\n flyTo(nodeId: string): boolean;\n\n /** Flies out to the overview of the whole map. */\n overview(): void;\n\n getViewMode(): ViewMode | null;\n setViewMode(mode: ViewMode): void;\n\n /** Zooms by `factor` around the middle of the map (above 1 zooms in). */\n zoomBy(factor: number): void;\n\n /** Returns the camera to the fitted view. */\n fit(): void;\n}\n\ntype Callbacks = Pick<\n RendererOptions,\n | 'onNodeClick' | 'onViewModeChange' | 'onAction' | 'onFocusChange' | 'onSpinSettle' | 'onNodeContext' | 'onEdit' | 'onEditorOpen' | 'onEditorClose' | 'onNodeDrag'\n | 'onMediaOpen' | 'onMediaClose' | 'onMediaState' | 'noteRenderer' | 'nodeTypeFor'\n>;\n\n/** What actions declare, as a value to compare: their functions count only as being there. */\nconst actionsKey = (actions: OrbitAction[]): unknown[] => {\n return actions.map((action) => [action.id, typeof action.label === 'string' ? action.label : null, action.icon ?? null, Boolean(action.when)]);\n};\n\n/** What node types declare, as a value to compare. */\nconst nodeTypesKey = (types: Record<string, OrbitNodeType>): string => {\n return JSON.stringify(Object.entries(types).map(([name, type]) => [\n name, type.label ?? null, type.icon ?? null, type.color ?? null, type.tokens ?? null, type.version ?? null,\n Boolean(type.render), Boolean(type.details), Boolean(type.upgrade), type.actions ? actionsKey(type.actions) : null,\n ]));\n};\n\n/** Actions that call the latest props' functions, so new identities on every render never redraw the map. */\nconst delegateActions = (actions: OrbitAction[], read: () => OrbitAction[] | undefined): OrbitAction[] => {\n return actions.map((action) => {\n const latest = () => read()?.find((candidate) => candidate.id === action.id) ?? action;\n return {\n id: action.id,\n icon: action.icon,\n label: typeof action.label === 'function'\n ? (node) => {\n const label = latest().label;\n return typeof label === 'function' ? label(node) : label;\n }\n : action.label,\n when: action.when ? (node) => latest().when?.(node) ?? true : undefined,\n run: (node, event) => latest().run(node, event),\n };\n });\n};\n\n/** Node types that call the latest props' functions. */\nconst delegateNodeTypes = (types: Record<string, OrbitNodeType>, read: () => Record<string, OrbitNodeType> | undefined): Record<string, OrbitNodeType> => {\n return Object.fromEntries(Object.entries(types).map(([name, type]) => [name, {\n label: type.label,\n icon: type.icon,\n color: type.color,\n tokens: type.tokens,\n version: type.version,\n upgrade: type.upgrade ? (node, from) => read()?.[name]?.upgrade?.(node, from) : undefined,\n render: type.render ? (node, element) => read()?.[name]?.render?.(node, element) : undefined,\n details: type.details ? (node, element) => read()?.[name]?.details?.(node, element) : undefined,\n actions: type.actions ? delegateActions(type.actions, () => read()?.[name]?.actions) : undefined,\n } satisfies OrbitNodeType]));\n};\n\n/**\n * Renders an orbit map that fills its parent element, so give the parent a\n * size. Pass the map as `source` (markdown or YAML), `document` or `data`.\n *\n * Callback props can be inline functions and `theme` / `palette` can be\n * inline objects: they never rebuild the map unless their values change.\n *\n * @example\n * ```tsx\n * import { OrbitMindMap } from '@restless-dreams/orbit/react';\n *\n * <div style={{ height: 480 }}>\n * <OrbitMindMap source={'# Launch\\n## Research\\n## Build'} theme=\"night\" onFocusChange={(node) => console.log(node.text)} />\n * </div>\n * ```\n */\nexport const OrbitMindMap = forwardRef<OrbitMindMapRef, OrbitMindMapProps>(\n ({\n source,\n document: orbitDocument,\n data,\n viewMode,\n showRings,\n interactive,\n orbitAnimation,\n orbitSpeed,\n maxDepth,\n palette,\n theme,\n ariaLabel,\n language,\n strings,\n showControls,\n showActionButtons,\n showDetailSheet,\n mediaViewer,\n baseUrl,\n spin,\n zoom,\n insets,\n transitionDuration,\n onNodeClick,\n onViewModeChange,\n onAction,\n onFocusChange,\n onSpinSettle,\n onNodeContext,\n onEdit,\n onEditorOpen,\n onEditorClose,\n onNodeDrag,\n onMediaOpen,\n onMediaClose,\n onMediaState,\n editable,\n editingKeys,\n longPressDelay,\n noteRenderer,\n nodeTypeFor,\n nodeTypes,\n actions,\n statuses,\n focusedId,\n focus,\n staticFallback = true,\n style,\n ...elementProps\n }, ref) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const staticRef = useRef<HTMLDivElement>(null);\n const rendererRef = useRef<OrbitSVGRenderer | null>(null);\n const [mounted, setMounted] = useState(false);\n const staticId = useId();\n\n // Read the renderer at call time, so the handle works from the first commit.\n useImperativeHandle(ref, () => ({\n get renderer() {\n return rendererRef.current;\n },\n flyTo: (nodeId) => rendererRef.current?.flyTo(nodeId) ?? false,\n overview: () => rendererRef.current?.overview(),\n getViewMode: () => rendererRef.current?.getViewMode() ?? null,\n setViewMode: (mode) => rendererRef.current?.setViewMode(mode),\n zoomBy: (factor) => rendererRef.current?.zoomBy(factor),\n fit: () => rendererRef.current?.fit(),\n }), []);\n\n // The renderer holds stable wrappers that call the latest props, so new\n // function identities on every render never reach it.\n const callbacksRef = useRef<Callbacks>({});\n\n useEffect(() => {\n callbacksRef.current = {\n onNodeClick, onViewModeChange, onAction, onFocusChange, onSpinSettle, onNodeContext, onEdit, onEditorOpen, onEditorClose, onNodeDrag,\n onMediaOpen, onMediaClose, onMediaState, noteRenderer, nodeTypeFor,\n };\n });\n\n const hasNoteRenderer = noteRenderer !== undefined;\n const hasNodeTypeFor = nodeTypeFor !== undefined;\n const hasNodeContext = onNodeContext !== undefined;\n const callbacks = useMemo<Callbacks>(() => ({\n onNodeClick: (node) => callbacksRef.current.onNodeClick?.(node),\n onViewModeChange: (mode) => callbacksRef.current.onViewModeChange?.(mode),\n onAction: (event) => callbacksRef.current.onAction?.(event),\n onFocusChange: (node) => callbacksRef.current.onFocusChange?.(node),\n onSpinSettle: (planet) => callbacksRef.current.onSpinSettle?.(planet),\n onEdit: (edit) => callbacksRef.current.onEdit?.(edit),\n onEditorOpen: (event) => callbacksRef.current.onEditorOpen?.(event),\n onEditorClose: (event) => callbacksRef.current.onEditorClose?.(event),\n onNodeDrag: (event) => callbacksRef.current.onNodeDrag?.(event),\n onMediaOpen: (event) => callbacksRef.current.onMediaOpen?.(event),\n onMediaClose: (event) => callbacksRef.current.onMediaClose?.(event),\n onMediaState: (state) => callbacksRef.current.onMediaState?.(state),\n // Left undefined without a prop: having one takes long presses from the map.\n onNodeContext: hasNodeContext ? (event) => callbacksRef.current.onNodeContext?.(event) : undefined,\n // Left undefined without a prop so the built-in note view applies.\n noteRenderer: hasNoteRenderer\n ? (note, context) => callbacksRef.current.noteRenderer?.(note, context) ?? ''\n : undefined,\n // Asks the latest prop each time the map draws: a new function on every render never redraws the map.\n nodeTypeFor: hasNodeTypeFor ? (node) => callbacksRef.current.nodeTypeFor?.(node) : undefined,\n }), [hasNoteRenderer, hasNodeContext, hasNodeTypeFor]);\n\n // Node types and actions hold functions: compare what they declare by\n // value, and call their latest functions through stable wrappers.\n const extensionsRef = useRef({ nodeTypes, actions });\n\n useEffect(() => {\n extensionsRef.current = { nodeTypes, actions };\n });\n\n const typesKey = nodeTypes === undefined ? undefined : nodeTypesKey(nodeTypes);\n const actionKey = actions === undefined ? undefined : JSON.stringify(actionsKey(actions));\n const statusesKey = statuses === undefined ? undefined : JSON.stringify(statuses);\n // eslint-disable-next-line react-hooks/exhaustive-deps -- the key stands for nodeTypes\n const stableNodeTypes = useMemo(() => (nodeTypes === undefined ? undefined : delegateNodeTypes(nodeTypes, () => extensionsRef.current.nodeTypes)), [typesKey]);\n // eslint-disable-next-line react-hooks/exhaustive-deps -- the key stands for actions\n const stableActions = useMemo(() => (actions === undefined ? undefined : delegateActions(actions, () => extensionsRef.current.actions)), [actionKey]);\n const stableStatuses = useMemo(() => (statusesKey === undefined ? undefined : JSON.parse(statusesKey)), [statusesKey]);\n\n // Compare object props by value: inline objects are fine.\n const themeKey = theme === undefined ? undefined : JSON.stringify(theme);\n const paletteKey = palette === undefined ? undefined : JSON.stringify(palette);\n const spinKey = spin === undefined ? undefined : JSON.stringify(spin);\n const stringsKey = strings === undefined ? undefined : JSON.stringify(strings);\n const zoomKey = zoom === undefined ? undefined : JSON.stringify(zoom);\n const insetsKey = insets === undefined ? undefined : JSON.stringify(insets);\n const stableTheme = useMemo(() => (themeKey === undefined ? undefined : JSON.parse(themeKey)), [themeKey]);\n const stablePalette = useMemo(() => (paletteKey === undefined ? undefined : JSON.parse(paletteKey)), [paletteKey]);\n const stableSpin = useMemo(() => (spinKey === undefined ? undefined : JSON.parse(spinKey)), [spinKey]);\n const stableStrings = useMemo(() => (stringsKey === undefined ? undefined : JSON.parse(stringsKey)), [stringsKey]);\n const stableZoom = useMemo(() => (zoomKey === undefined ? undefined : JSON.parse(zoomKey)), [zoomKey]);\n const stableInsets = useMemo(() => (insetsKey === undefined ? undefined : JSON.parse(insetsKey)), [insetsKey]);\n\n const options = useMemo<RendererOptions>(() => ({\n viewMode,\n showRings,\n interactive,\n orbitAnimation,\n orbitSpeed,\n maxDepth,\n palette: stablePalette,\n theme: stableTheme,\n ariaLabel,\n language,\n strings: stableStrings,\n showControls,\n showActionButtons,\n showDetailSheet,\n mediaViewer,\n editable,\n editingKeys,\n longPressDelay,\n baseUrl,\n spin: stableSpin,\n zoom: stableZoom,\n insets: stableInsets,\n transitionDuration,\n nodeTypes: stableNodeTypes,\n actions: stableActions,\n statuses: stableStatuses,\n ...callbacks,\n }), [\n viewMode, showRings, interactive, orbitAnimation, orbitSpeed, maxDepth, stablePalette, stableTheme,\n ariaLabel, language, stableStrings, showControls, showActionButtons, showDetailSheet, mediaViewer, editable, editingKeys, longPressDelay, baseUrl,\n stableSpin, stableZoom, stableInsets, transitionDuration, stableNodeTypes, stableActions, stableStatuses, callbacks,\n ]);\n\n const input = useMemo<OrbitDocument | OrbitNode | undefined>(() => {\n if (orbitDocument) {\n return orbitDocument;\n }\n\n if (source !== undefined) {\n // A made-up root takes the language's name; without the language prop, it's the renderer's to find on the page.\n const parsed = parseOrbit(source, { untitled: language ? new OrbitWords(language, stableStrings).text('untitledMap') : undefined });\n reportParseDiagnostics(parsed);\n return parsed;\n }\n\n return data;\n }, [orbitDocument, source, data, language, stableStrings]);\n\n // Create the renderer once. The effects below keep its options and map\n // current; on mount they set the same options (a no-op) and draw once.\n const optionsRef = useRef(options);\n const initialFocusRef = useRef(focusedId ?? focus);\n\n useEffect(() => {\n optionsRef.current = options;\n });\n\n useEffect(() => {\n // The static picture steps aside before the live map measures its space.\n if (staticRef.current) {\n staticRef.current.hidden = true;\n }\n\n // A controlled focus opens the map on that node, without a flight to it.\n const renderer = new OrbitSVGRenderer(containerRef.current!, { ...optionsRef.current, focus: initialFocusRef.current });\n rendererRef.current = renderer;\n setMounted(true);\n\n return () => {\n renderer.destroy();\n rendererRef.current = null;\n };\n }, []);\n\n useEffect(() => {\n rendererRef.current?.setOptions(options);\n }, [options]);\n\n useEffect(() => {\n if (input) {\n rendererRef.current?.render(input);\n }\n }, [input]);\n\n useEffect(() => {\n const renderer = rendererRef.current;\n\n if (!renderer || focusedId === undefined) {\n return;\n }\n\n const path = renderer.getFocusPath();\n\n if (path[path.length - 1] !== focusedId) {\n renderer.focusNode(focusedId);\n }\n }, [focusedId, input]);\n\n // Server rendering and the first client render draw a static picture of\n // the map; the live map replaces it once it mounts.\n const staticMarkup = useMemo(() => {\n if (!staticFallback || mounted || !input) {\n return '';\n }\n\n return renderToSVGString(input, {\n responsive: true,\n idPrefix: `orbit-static-${staticId.replace(/[^a-zA-Z0-9_-]/g, '')}`,\n viewMode,\n focus: focusedId ?? focus,\n theme: stableTheme,\n palette: stablePalette,\n maxDepth,\n showRings,\n title: ariaLabel,\n language,\n strings: stableStrings,\n baseUrl,\n nodeTypes: stableNodeTypes,\n statuses: stableStatuses,\n });\n }, [\n staticFallback, mounted, input, staticId, viewMode, focusedId, focus, stableTheme, stablePalette, maxDepth, showRings, ariaLabel, language, stableStrings,\n baseUrl, stableNodeTypes, stableStatuses,\n ]);\n\n return createElement(\n 'div',\n {\n ...elementProps,\n ref: containerRef,\n style: {\n width: '100%',\n height: '100%',\n overflow: 'hidden',\n ...style,\n },\n },\n staticMarkup\n ? createElement('div', {\n ref: staticRef,\n 'data-orbit-static': '',\n style: { width: '100%', height: '100%' },\n dangerouslySetInnerHTML: { __html: staticMarkup },\n })\n : null,\n );\n },\n);\n\nOrbitMindMap.displayName = 'OrbitMindMap';\n\n"],"mappings":";;;;;;;;;;;;AAIA;AA4DA,IAAM,aAAa,CAAC,YAAsC;AAAA,EACxD,OAAO,QAAQ,IAAI,CAAC,WAAW,CAAC,OAAO,IAAI,OAAO,OAAO,UAAU,WAAW,OAAO,QAAQ,MAAM,OAAO,QAAQ,MAAM,QAAQ,OAAO,IAAI,CAAC,CAAC;AAAA;AAI/I,IAAM,eAAe,CAAC,UAAiD;AAAA,EACrE,OAAO,KAAK,UAAU,OAAO,QAAQ,KAAK,EAAE,IAAI,EAAE,MAAM,UAAU;AAAA,IAChE;AAAA,IAAM,KAAK,SAAS;AAAA,IAAM,KAAK,QAAQ;AAAA,IAAM,KAAK,SAAS;AAAA,IAAM,KAAK,UAAU;AAAA,IAAM,KAAK,WAAW;AAAA,IACtG,QAAQ,KAAK,MAAM;AAAA,IAAG,QAAQ,KAAK,OAAO;AAAA,IAAG,QAAQ,KAAK,OAAO;AAAA,IAAG,KAAK,UAAU,WAAW,KAAK,OAAO,IAAI;AAAA,EAChH,CAAC,CAAC;AAAA;AAIJ,IAAM,kBAAkB,CAAC,SAAwB,SAAyD;AAAA,EACxG,OAAO,QAAQ,IAAI,CAAC,WAAW;AAAA,IAC7B,MAAM,SAAS,MAAM,KAAK,GAAG,KAAK,CAAC,cAAc,UAAU,OAAO,OAAO,EAAE,KAAK;AAAA,IAChF,OAAO;AAAA,MACL,IAAI,OAAO;AAAA,MACX,MAAM,OAAO;AAAA,MACb,OAAO,OAAO,OAAO,UAAU,aAC3B,CAAC,SAAS;AAAA,QACV,MAAM,QAAQ,OAAO,EAAE;AAAA,QACvB,OAAO,OAAO,UAAU,aAAa,MAAM,IAAI,IAAI;AAAA,UAEnD,OAAO;AAAA,MACX,MAAM,OAAO,OAAO,CAAC,SAAS,OAAO,EAAE,OAAO,IAAI,KAAK,OAAO;AAAA,MAC9D,KAAK,CAAC,MAAM,UAAU,OAAO,EAAE,IAAI,MAAM,KAAK;AAAA,IAChD;AAAA,GACD;AAAA;AAIH,IAAM,oBAAoB,CAAC,OAAsC,SAAyF;AAAA,EACxJ,OAAO,OAAO,YAAY,OAAO,QAAQ,KAAK,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC,MAAM;AAAA,IAC3E,OAAO,KAAK;AAAA,IACZ,MAAM,KAAK;AAAA,IACX,OAAO,KAAK;AAAA,IACZ,QAAQ,KAAK;AAAA,IACb,SAAS,KAAK;AAAA,IACd,SAAS,KAAK,UAAU,CAAC,MAAM,SAAS,KAAK,IAAI,OAAO,UAAU,MAAM,IAAI,IAAI;AAAA,IAChF,QAAQ,KAAK,SAAS,CAAC,MAAM,YAAY,KAAK,IAAI,OAAO,SAAS,MAAM,OAAO,IAAI;AAAA,IACnF,SAAS,KAAK,UAAU,CAAC,MAAM,YAAY,KAAK,IAAI,OAAO,UAAU,MAAM,OAAO,IAAI;AAAA,IACtF,SAAS,KAAK,UAAU,gBAAgB,KAAK,SAAS,MAAM,KAAK,IAAI,OAAO,OAAO,IAAI;AAAA,EACzF,CAAyB,CAAC,CAAC;AAAA;AAmBtB,IAAM,eAAe,WAC1B;AAAA,EACE;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB;AAAA,KACG;AAAA,GACF,QAAQ;AAAA,EACT,MAAM,eAAe,OAAuB,IAAI;AAAA,EAChD,MAAM,YAAY,OAAuB,IAAI;AAAA,EAC7C,MAAM,cAAc,OAAgC,IAAI;AAAA,EACxD,OAAO,SAAS,cAAc,SAAS,KAAK;AAAA,EAC5C,MAAM,WAAW,MAAM;AAAA,EAGvB,oBAAoB,KAAK,OAAO;AAAA,QAC1B,QAAQ,GAAG;AAAA,MACb,OAAO,YAAY;AAAA;AAAA,IAErB,OAAO,CAAC,WAAW,YAAY,SAAS,MAAM,MAAM,KAAK;AAAA,IACzD,UAAU,MAAM,YAAY,SAAS,SAAS;AAAA,IAC9C,aAAa,MAAM,YAAY,SAAS,YAAY,KAAK;AAAA,IACzD,aAAa,CAAC,SAAS,YAAY,SAAS,YAAY,IAAI;AAAA,IAC5D,QAAQ,CAAC,WAAW,YAAY,SAAS,OAAO,MAAM;AAAA,IACtD,KAAK,MAAM,YAAY,SAAS,IAAI;AAAA,EACtC,IAAI,CAAC,CAAC;AAAA,EAIN,MAAM,eAAe,OAAkB,CAAC,CAAC;AAAA,EAEzC,UAAU,MAAM;AAAA,IACd,aAAa,UAAU;AAAA,MACrB;AAAA,MAAa;AAAA,MAAkB;AAAA,MAAU;AAAA,MAAe;AAAA,MAAc;AAAA,MAAe;AAAA,MAAQ;AAAA,MAAc;AAAA,MAAe;AAAA,MAC1H;AAAA,MAAa;AAAA,MAAc;AAAA,MAAc;AAAA,MAAc;AAAA,IACzD;AAAA,GACD;AAAA,EAED,MAAM,kBAAkB,iBAAiB;AAAA,EACzC,MAAM,iBAAiB,gBAAgB;AAAA,EACvC,MAAM,iBAAiB,kBAAkB;AAAA,EACzC,MAAM,YAAY,QAAmB,OAAO;AAAA,IAC1C,aAAa,CAAC,SAAS,aAAa,QAAQ,cAAc,IAAI;AAAA,IAC9D,kBAAkB,CAAC,SAAS,aAAa,QAAQ,mBAAmB,IAAI;AAAA,IACxE,UAAU,CAAC,UAAU,aAAa,QAAQ,WAAW,KAAK;AAAA,IAC1D,eAAe,CAAC,SAAS,aAAa,QAAQ,gBAAgB,IAAI;AAAA,IAClE,cAAc,CAAC,WAAW,aAAa,QAAQ,eAAe,MAAM;AAAA,IACpE,QAAQ,CAAC,SAAS,aAAa,QAAQ,SAAS,IAAI;AAAA,IACpD,cAAc,CAAC,UAAU,aAAa,QAAQ,eAAe,KAAK;AAAA,IAClE,eAAe,CAAC,UAAU,aAAa,QAAQ,gBAAgB,KAAK;AAAA,IACpE,YAAY,CAAC,UAAU,aAAa,QAAQ,aAAa,KAAK;AAAA,IAC9D,aAAa,CAAC,UAAU,aAAa,QAAQ,cAAc,KAAK;AAAA,IAChE,cAAc,CAAC,UAAU,aAAa,QAAQ,eAAe,KAAK;AAAA,IAClE,cAAc,CAAC,UAAU,aAAa,QAAQ,eAAe,KAAK;AAAA,IAElE,eAAe,iBAAiB,CAAC,UAAU,aAAa,QAAQ,gBAAgB,KAAK,IAAI;AAAA,IAEzF,cAAc,kBACV,CAAC,MAAM,YAAY,aAAa,QAAQ,eAAe,MAAM,OAAO,KAAK,KACzE;AAAA,IAEJ,aAAa,iBAAiB,CAAC,SAAS,aAAa,QAAQ,cAAc,IAAI,IAAI;AAAA,EACrF,IAAI,CAAC,iBAAiB,gBAAgB,cAAc,CAAC;AAAA,EAIrD,MAAM,gBAAgB,OAAO,EAAE,WAAW,QAAQ,CAAC;AAAA,EAEnD,UAAU,MAAM;AAAA,IACd,cAAc,UAAU,EAAE,WAAW,QAAQ;AAAA,GAC9C;AAAA,EAED,MAAM,WAAW,cAAc,YAAY,YAAY,aAAa,SAAS;AAAA,EAC7E,MAAM,YAAY,YAAY,YAAY,YAAY,KAAK,UAAU,WAAW,OAAO,CAAC;AAAA,EACxF,MAAM,cAAc,aAAa,YAAY,YAAY,KAAK,UAAU,QAAQ;AAAA,EAEhF,MAAM,kBAAkB,QAAQ,MAAO,cAAc,YAAY,YAAY,kBAAkB,WAAW,MAAM,cAAc,QAAQ,SAAS,GAAI,CAAC,QAAQ,CAAC;AAAA,EAE7J,MAAM,gBAAgB,QAAQ,MAAO,YAAY,YAAY,YAAY,gBAAgB,SAAS,MAAM,cAAc,QAAQ,OAAO,GAAI,CAAC,SAAS,CAAC;AAAA,EACpJ,MAAM,iBAAiB,QAAQ,MAAO,gBAAgB,YAAY,YAAY,KAAK,MAAM,WAAW,GAAI,CAAC,WAAW,CAAC;AAAA,EAGrH,MAAM,WAAW,UAAU,YAAY,YAAY,KAAK,UAAU,KAAK;AAAA,EACvE,MAAM,aAAa,YAAY,YAAY,YAAY,KAAK,UAAU,OAAO;AAAA,EAC7E,MAAM,UAAU,SAAS,YAAY,YAAY,KAAK,UAAU,IAAI;AAAA,EACpE,MAAM,aAAa,YAAY,YAAY,YAAY,KAAK,UAAU,OAAO;AAAA,EAC7E,MAAM,UAAU,SAAS,YAAY,YAAY,KAAK,UAAU,IAAI;AAAA,EACpE,MAAM,YAAY,WAAW,YAAY,YAAY,KAAK,UAAU,MAAM;AAAA,EAC1E,MAAM,cAAc,QAAQ,MAAO,aAAa,YAAY,YAAY,KAAK,MAAM,QAAQ,GAAI,CAAC,QAAQ,CAAC;AAAA,EACzG,MAAM,gBAAgB,QAAQ,MAAO,eAAe,YAAY,YAAY,KAAK,MAAM,UAAU,GAAI,CAAC,UAAU,CAAC;AAAA,EACjH,MAAM,aAAa,QAAQ,MAAO,YAAY,YAAY,YAAY,KAAK,MAAM,OAAO,GAAI,CAAC,OAAO,CAAC;AAAA,EACrG,MAAM,gBAAgB,QAAQ,MAAO,eAAe,YAAY,YAAY,KAAK,MAAM,UAAU,GAAI,CAAC,UAAU,CAAC;AAAA,EACjH,MAAM,aAAa,QAAQ,MAAO,YAAY,YAAY,YAAY,KAAK,MAAM,OAAO,GAAI,CAAC,OAAO,CAAC;AAAA,EACrG,MAAM,eAAe,QAAQ,MAAO,cAAc,YAAY,YAAY,KAAK,MAAM,SAAS,GAAI,CAAC,SAAS,CAAC;AAAA,EAE7G,MAAM,UAAU,QAAyB,OAAO;AAAA,IAC9C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,IACR;AAAA,IACA,WAAW;AAAA,IACX,SAAS;AAAA,IACT,UAAU;AAAA,OACP;AAAA,EACL,IAAI;AAAA,IACF;AAAA,IAAU;AAAA,IAAW;AAAA,IAAa;AAAA,IAAgB;AAAA,IAAY;AAAA,IAAU;AAAA,IAAe;AAAA,IACvF;AAAA,IAAW;AAAA,IAAU;AAAA,IAAe;AAAA,IAAc;AAAA,IAAmB;AAAA,IAAiB;AAAA,IAAa;AAAA,IAAU;AAAA,IAAa;AAAA,IAAgB;AAAA,IAC1I;AAAA,IAAY;AAAA,IAAY;AAAA,IAAc;AAAA,IAAoB;AAAA,IAAiB;AAAA,IAAe;AAAA,IAAgB;AAAA,EAC5G,CAAC;AAAA,EAED,MAAM,QAAQ,QAA+C,MAAM;AAAA,IACjE,IAAI,eAAe;AAAA,MACjB,OAAO;AAAA,IACT;AAAA,IAEA,IAAI,WAAW,WAAW;AAAA,MAExB,MAAM,SAAS,YAAW,QAAQ,EAAE,UAAU,WAAW,IAAI,WAAW,UAAU,aAAa,EAAE,KAAK,aAAa,IAAI,UAAU,CAAC;AAAA,MAClI,uBAAuB,MAAM;AAAA,MAC7B,OAAO;AAAA,IACT;AAAA,IAEA,OAAO;AAAA,KACN,CAAC,eAAe,QAAQ,MAAM,UAAU,aAAa,CAAC;AAAA,EAIzD,MAAM,aAAa,OAAO,OAAO;AAAA,EACjC,MAAM,kBAAkB,OAAO,aAAa,KAAK;AAAA,EAEjD,UAAU,MAAM;AAAA,IACd,WAAW,UAAU;AAAA,GACtB;AAAA,EAED,UAAU,MAAM;AAAA,IAEd,IAAI,UAAU,SAAS;AAAA,MACrB,UAAU,QAAQ,SAAS;AAAA,IAC7B;AAAA,IAGA,MAAM,WAAW,IAAI,kBAAiB,aAAa,SAAU,KAAK,WAAW,SAAS,OAAO,gBAAgB,QAAQ,CAAC;AAAA,IACtH,YAAY,UAAU;AAAA,IACtB,WAAW,IAAI;AAAA,IAEf,OAAO,MAAM;AAAA,MACX,SAAS,QAAQ;AAAA,MACjB,YAAY,UAAU;AAAA;AAAA,KAEvB,CAAC,CAAC;AAAA,EAEL,UAAU,MAAM;AAAA,IACd,YAAY,SAAS,WAAW,OAAO;AAAA,KACtC,CAAC,OAAO,CAAC;AAAA,EAEZ,UAAU,MAAM;AAAA,IACd,IAAI,OAAO;AAAA,MACT,YAAY,SAAS,OAAO,KAAK;AAAA,IACnC;AAAA,KACC,CAAC,KAAK,CAAC;AAAA,EAEV,UAAU,MAAM;AAAA,IACd,MAAM,WAAW,YAAY;AAAA,IAE7B,IAAI,CAAC,YAAY,cAAc,WAAW;AAAA,MACxC;AAAA,IACF;AAAA,IAEA,MAAM,OAAO,SAAS,aAAa;AAAA,IAEnC,IAAI,KAAK,KAAK,SAAS,OAAO,WAAW;AAAA,MACvC,SAAS,UAAU,SAAS;AAAA,IAC9B;AAAA,KACC,CAAC,WAAW,KAAK,CAAC;AAAA,EAIrB,MAAM,eAAe,QAAQ,MAAM;AAAA,IACjC,IAAI,CAAC,kBAAkB,WAAW,CAAC,OAAO;AAAA,MACxC,OAAO;AAAA,IACT;AAAA,IAEA,OAAO,mBAAkB,OAAO;AAAA,MAC9B,YAAY;AAAA,MACZ,UAAU,gBAAgB,SAAS,QAAQ,mBAAmB,EAAE;AAAA,MAChE;AAAA,MACA,OAAO,aAAa;AAAA,MACpB,OAAO;AAAA,MACP,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MACA,OAAO;AAAA,MACP;AAAA,MACA,SAAS;AAAA,MACT;AAAA,MACA,WAAW;AAAA,MACX,UAAU;AAAA,IACZ,CAAC;AAAA,KACA;AAAA,IACD;AAAA,IAAgB;AAAA,IAAS;AAAA,IAAO;AAAA,IAAU;AAAA,IAAU;AAAA,IAAW;AAAA,IAAO;AAAA,IAAa;AAAA,IAAe;AAAA,IAAU;AAAA,IAAW;AAAA,IAAW;AAAA,IAAU;AAAA,IAC5I;AAAA,IAAS;AAAA,IAAiB;AAAA,EAC5B,CAAC;AAAA,EAED,OAAO,cACL,OACA;AAAA,OACK;AAAA,IACH,KAAK;AAAA,IACL,OAAO;AAAA,MACL,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,UAAU;AAAA,SACP;AAAA,IACL;AAAA,EACF,GACA,eACI,cAAc,OAAO;AAAA,IACrB,KAAK;AAAA,IACL,qBAAqB;AAAA,IACrB,OAAO,EAAE,OAAO,QAAQ,QAAQ,OAAO;AAAA,IACvC,yBAAyB,EAAE,QAAQ,aAAa;AAAA,EAClD,CAAC,IACC,IACN;AAAA,CAEJ;AAEA,aAAa,cAAc;","debugId":"86D75E1C55FAF80F64756E2164756E21","names":[]}
|