@glw907/cairn-cms 0.8.0 → 0.10.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/dist/components/ComponentForm.svelte +178 -0
- package/dist/components/ComponentForm.svelte.d.ts +20 -0
- package/dist/components/ComponentForm.svelte.d.ts.map +1 -0
- package/dist/components/ComponentInsertDialog.svelte +92 -0
- package/dist/components/ComponentInsertDialog.svelte.d.ts +20 -0
- package/dist/components/ComponentInsertDialog.svelte.d.ts.map +1 -0
- package/dist/components/EditPage.svelte +9 -8
- package/dist/components/EditPage.svelte.d.ts +4 -3
- package/dist/components/EditPage.svelte.d.ts.map +1 -1
- package/dist/components/EditorToolbar.svelte +61 -0
- package/dist/components/EditorToolbar.svelte.d.ts +15 -0
- package/dist/components/EditorToolbar.svelte.d.ts.map +1 -0
- package/dist/components/IconPicker.svelte +51 -0
- package/dist/components/IconPicker.svelte.d.ts +20 -0
- package/dist/components/IconPicker.svelte.d.ts.map +1 -0
- package/dist/components/MarkdownEditor.svelte +96 -57
- package/dist/components/MarkdownEditor.svelte.d.ts +5 -6
- package/dist/components/MarkdownEditor.svelte.d.ts.map +1 -1
- package/dist/components/index.d.ts +3 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +3 -1
- package/dist/components/markdown-format.d.ts +13 -0
- package/dist/components/markdown-format.d.ts.map +1 -0
- package/dist/components/markdown-format.js +23 -0
- package/dist/content/compose.d.ts.map +1 -1
- package/dist/content/compose.js +1 -0
- package/dist/content/types.d.ts +5 -0
- package/dist/content/types.d.ts.map +1 -1
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/render/component-grammar.d.ts +10 -0
- package/dist/render/component-grammar.d.ts.map +1 -0
- package/dist/render/component-grammar.js +140 -0
- package/dist/render/component-insert.d.ts +14 -0
- package/dist/render/component-insert.d.ts.map +1 -0
- package/dist/render/component-insert.js +9 -0
- package/dist/render/component-reference.d.ts +11 -0
- package/dist/render/component-reference.d.ts.map +1 -0
- package/dist/render/component-reference.js +34 -0
- package/dist/render/component-validate.d.ts +10 -0
- package/dist/render/component-validate.d.ts.map +1 -0
- package/dist/render/component-validate.js +30 -0
- package/dist/render/pipeline.d.ts +1 -1
- package/dist/render/pipeline.js +1 -1
- package/dist/render/registry.d.ts +45 -1
- package/dist/render/registry.d.ts.map +1 -1
- package/dist/render/registry.js +13 -0
- package/dist/render/sanitize.js +2 -2
- package/package.json +8 -3
- package/src/lib/components/ComponentForm.svelte +178 -0
- package/src/lib/components/ComponentInsertDialog.svelte +92 -0
- package/src/lib/components/EditPage.svelte +9 -8
- package/src/lib/components/EditorToolbar.svelte +61 -0
- package/src/lib/components/IconPicker.svelte +51 -0
- package/src/lib/components/MarkdownEditor.svelte +96 -57
- package/src/lib/components/index.ts +3 -1
- package/src/lib/components/markdown-format.ts +39 -0
- package/src/lib/content/compose.ts +1 -0
- package/src/lib/content/types.ts +5 -0
- package/src/lib/index.ts +16 -2
- package/src/lib/render/component-grammar.ts +167 -0
- package/src/lib/render/component-insert.ts +15 -0
- package/src/lib/render/component-reference.ts +38 -0
- package/src/lib/render/component-validate.ts +36 -0
- package/src/lib/render/pipeline.ts +1 -1
- package/src/lib/render/registry.ts +61 -1
- package/src/lib/render/sanitize.ts +2 -2
- package/dist/components/ComponentPalette.svelte +0 -50
- package/dist/components/ComponentPalette.svelte.d.ts +0 -16
- package/dist/components/ComponentPalette.svelte.d.ts.map +0 -1
- package/src/lib/components/ComponentPalette.svelte +0 -50
|
@@ -1,81 +1,120 @@
|
|
|
1
1
|
<!--
|
|
2
2
|
@component
|
|
3
|
-
The `MarkdownEditor` seam (spec §6, seam 5): a thin wrapper over
|
|
4
|
-
and a cursor-insert callback.
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
The `MarkdownEditor` seam (spec §6, seam 5): a thin wrapper over CodeMirror 6 exposing a bindable
|
|
4
|
+
value and a cursor-insert callback. CodeMirror is client-only, so it mounts after the component does
|
|
5
|
+
through a dynamic import; until then a plain textarea carries the value so the form still submits, and
|
|
6
|
+
the hidden field mirrors the value throughout. The edit surface owns its toolbar; the design-accurate
|
|
7
|
+
preview lives in EditPage through the adapter's render. Swapping the editor stays a one-file change.
|
|
7
8
|
-->
|
|
8
9
|
<script lang="ts">
|
|
9
|
-
import { onMount } from 'svelte';
|
|
10
|
+
import { onMount, onDestroy } from 'svelte';
|
|
11
|
+
import EditorToolbar from './EditorToolbar.svelte';
|
|
12
|
+
import { applyMarkdownFormat, type FormatKind } from './markdown-format.js';
|
|
10
13
|
|
|
11
14
|
interface Props {
|
|
12
15
|
/** The markdown source; bindable so the parent reads edits back. */
|
|
13
16
|
value: string;
|
|
14
17
|
/** The hidden field name the value is mirrored to for form submit. */
|
|
15
18
|
name: string;
|
|
16
|
-
/** Carta extensions from the adapter, for the design-accurate preview. */
|
|
17
|
-
plugins?: unknown[];
|
|
18
19
|
/** Receives a `(text) => void` that inserts at the cursor; the palette calls it. */
|
|
19
20
|
registerInsert?: (insert: (text: string) => void) => void;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
let { value = $bindable(), name,
|
|
23
|
-
|
|
24
|
-
// Local structural type for the Carta editing surface this seam uses. carta-md re-exports its
|
|
25
|
-
// Svelte components from the package entry, so its `Carta` class is not reachable as a named
|
|
26
|
-
// export under NodeNext; a structural type stays compatible without naming it (the shape
|
|
27
|
-
// legacy/src/lib/editor.ts relied on, verified against carta-md@4.11).
|
|
28
|
-
interface CartaInput {
|
|
29
|
-
getSelection(): { start: number };
|
|
30
|
-
insertAt(position: number, text: string): void;
|
|
31
|
-
update(): boolean;
|
|
32
|
-
}
|
|
33
|
-
interface CartaLike {
|
|
34
|
-
input?: CartaInput;
|
|
35
|
-
}
|
|
23
|
+
let { value = $bindable(), name, registerInsert }: Props = $props();
|
|
36
24
|
|
|
25
|
+
let host = $state<HTMLDivElement | null>(null);
|
|
37
26
|
let mounted = $state(false);
|
|
38
|
-
//
|
|
39
|
-
//
|
|
40
|
-
//
|
|
41
|
-
|
|
42
|
-
let Editor = $state<(typeof import('carta-md'))['MarkdownEditor'] | null>(null);
|
|
43
|
-
let carta = $state<CartaLike | null>(null);
|
|
27
|
+
// The CodeMirror view, untyped at the runtime boundary because @codemirror/* loads only in the
|
|
28
|
+
// browser. The type-only `import(...)` annotation is erased; the value import is dynamic in onMount,
|
|
29
|
+
// so the server bundle never pulls CodeMirror (guarded by the editor-boundary test).
|
|
30
|
+
let view: import('@codemirror/view').EditorView | null = null;
|
|
44
31
|
|
|
45
32
|
onMount(async () => {
|
|
46
|
-
const
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
)
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
33
|
+
const viewMod = await import('@codemirror/view');
|
|
34
|
+
const stateMod = await import('@codemirror/state');
|
|
35
|
+
const markdownMod = await import('@codemirror/lang-markdown');
|
|
36
|
+
const commandsMod = await import('@codemirror/commands');
|
|
37
|
+
const languageMod = await import('@codemirror/language');
|
|
38
|
+
|
|
39
|
+
if (!host) return;
|
|
40
|
+
|
|
41
|
+
const { EditorView, keymap } = viewMod;
|
|
42
|
+
const theme = EditorView.theme(
|
|
43
|
+
{
|
|
44
|
+
'&': { backgroundColor: 'var(--color-base-100)', color: 'var(--color-base-content)', fontSize: '0.875rem' },
|
|
45
|
+
'.cm-content': { fontFamily: 'ui-monospace, monospace', padding: '0.75rem', lineHeight: '1.7' },
|
|
46
|
+
'.cm-cursor': { borderLeftColor: 'var(--color-primary)' },
|
|
47
|
+
'&.cm-focused': { outline: '2px solid var(--color-primary)', outlineOffset: '-2px' },
|
|
48
|
+
'.cm-line': { padding: '0' },
|
|
49
|
+
},
|
|
50
|
+
{ dark: false },
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
view = new EditorView({
|
|
54
|
+
parent: host,
|
|
55
|
+
state: stateMod.EditorState.create({
|
|
56
|
+
doc: value,
|
|
57
|
+
extensions: [
|
|
58
|
+
commandsMod.history(),
|
|
59
|
+
keymap.of([...commandsMod.defaultKeymap, ...commandsMod.historyKeymap]),
|
|
60
|
+
markdownMod.markdown(),
|
|
61
|
+
EditorView.lineWrapping,
|
|
62
|
+
languageMod.syntaxHighlighting(languageMod.defaultHighlightStyle, { fallback: true }),
|
|
63
|
+
theme,
|
|
64
|
+
EditorView.updateListener.of((update) => {
|
|
65
|
+
if (update.docChanged) value = update.state.doc.toString();
|
|
66
|
+
}),
|
|
67
|
+
],
|
|
68
|
+
}),
|
|
69
69
|
});
|
|
70
|
+
|
|
71
|
+
registerInsert?.(insertAtCursor);
|
|
70
72
|
mounted = true;
|
|
71
73
|
});
|
|
74
|
+
|
|
75
|
+
onDestroy(() => view?.destroy());
|
|
76
|
+
|
|
77
|
+
// Reconcile an externally reassigned `value` into the mounted editor. A no-op until `view` exists,
|
|
78
|
+
// and the doc-equality guard ignores the updateListener's own writes so the two never feed back.
|
|
79
|
+
$effect(() => {
|
|
80
|
+
const incoming = value;
|
|
81
|
+
if (!view) return;
|
|
82
|
+
const current = view.state.doc.toString();
|
|
83
|
+
if (incoming === current) return;
|
|
84
|
+
view.dispatch({ changes: { from: 0, to: current.length, insert: incoming } });
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
function insertAtCursor(text: string) {
|
|
88
|
+
if (!view) {
|
|
89
|
+
value = value ? `${value}\n\n${text}` : text;
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const pos = view.state.selection.main.head;
|
|
93
|
+
const prefix = pos > 0 ? '\n\n' : '';
|
|
94
|
+
const insert = `${prefix}${text}`;
|
|
95
|
+
view.dispatch({ changes: { from: pos, insert }, selection: { anchor: pos + insert.length } });
|
|
96
|
+
view.focus();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function applyFormat(kind: FormatKind) {
|
|
100
|
+
if (!view) return;
|
|
101
|
+
const { from, to } = view.state.selection.main;
|
|
102
|
+
const doc = view.state.doc.toString();
|
|
103
|
+
const next = applyMarkdownFormat(doc, from, to, kind);
|
|
104
|
+
view.dispatch({
|
|
105
|
+
changes: { from: 0, to: doc.length, insert: next.doc },
|
|
106
|
+
selection: { anchor: next.from, head: next.to },
|
|
107
|
+
});
|
|
108
|
+
view.focus();
|
|
109
|
+
}
|
|
72
110
|
</script>
|
|
73
111
|
|
|
74
|
-
<input type="hidden" {name}
|
|
112
|
+
<input type="hidden" {name} {value} />
|
|
75
113
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
<
|
|
79
|
-
{
|
|
80
|
-
|
|
81
|
-
{/if}
|
|
114
|
+
<div class="border-base-300 overflow-hidden rounded-box border">
|
|
115
|
+
<EditorToolbar format={applyFormat} />
|
|
116
|
+
<div bind:this={host}></div>
|
|
117
|
+
{#if !mounted}
|
|
118
|
+
<textarea class="textarea min-h-64 w-full font-mono text-sm" bind:value aria-label="Markdown source"></textarea>
|
|
119
|
+
{/if}
|
|
120
|
+
</div>
|
|
@@ -3,16 +3,15 @@ interface Props {
|
|
|
3
3
|
value: string;
|
|
4
4
|
/** The hidden field name the value is mirrored to for form submit. */
|
|
5
5
|
name: string;
|
|
6
|
-
/** Carta extensions from the adapter, for the design-accurate preview. */
|
|
7
|
-
plugins?: unknown[];
|
|
8
6
|
/** Receives a `(text) => void` that inserts at the cursor; the palette calls it. */
|
|
9
7
|
registerInsert?: (insert: (text: string) => void) => void;
|
|
10
8
|
}
|
|
11
9
|
/**
|
|
12
|
-
* The `MarkdownEditor` seam (spec §6, seam 5): a thin wrapper over
|
|
13
|
-
* and a cursor-insert callback.
|
|
14
|
-
*
|
|
15
|
-
*
|
|
10
|
+
* The `MarkdownEditor` seam (spec §6, seam 5): a thin wrapper over CodeMirror 6 exposing a bindable
|
|
11
|
+
* value and a cursor-insert callback. CodeMirror is client-only, so it mounts after the component does
|
|
12
|
+
* through a dynamic import; until then a plain textarea carries the value so the form still submits, and
|
|
13
|
+
* the hidden field mirrors the value throughout. The edit surface owns its toolbar; the design-accurate
|
|
14
|
+
* preview lives in EditPage through the adapter's render. Swapping the editor stays a one-file change.
|
|
16
15
|
*/
|
|
17
16
|
declare const MarkdownEditor: import("svelte").Component<Props, {}, "value">;
|
|
18
17
|
type MarkdownEditor = ReturnType<typeof MarkdownEditor>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MarkdownEditor.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/components/MarkdownEditor.svelte.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MarkdownEditor.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/components/MarkdownEditor.svelte.ts"],"names":[],"mappings":"AAQE,UAAU,KAAK;IACb,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAC;IACb,oFAAoF;IACpF,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,KAAK,IAAI,CAAC;CAC3D;AA6GH;;;;;;GAMG;AACH,QAAA,MAAM,cAAc,gDAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
|
|
@@ -5,6 +5,8 @@ export { default as ConceptList } from './ConceptList.svelte';
|
|
|
5
5
|
export { default as EditPage } from './EditPage.svelte';
|
|
6
6
|
export { default as ManageEditors } from './ManageEditors.svelte';
|
|
7
7
|
export { default as MarkdownEditor } from './MarkdownEditor.svelte';
|
|
8
|
-
export { default as
|
|
8
|
+
export { default as ComponentInsertDialog } from './ComponentInsertDialog.svelte';
|
|
9
|
+
export { default as ComponentForm } from './ComponentForm.svelte';
|
|
10
|
+
export { default as IconPicker } from './IconPicker.svelte';
|
|
9
11
|
export { default as NavTree } from './NavTree.svelte';
|
|
10
12
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/components/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,OAAO,IAAI,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/components/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAClF,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/components/index.js
CHANGED
|
@@ -7,5 +7,7 @@ export { default as ConceptList } from './ConceptList.svelte';
|
|
|
7
7
|
export { default as EditPage } from './EditPage.svelte';
|
|
8
8
|
export { default as ManageEditors } from './ManageEditors.svelte';
|
|
9
9
|
export { default as MarkdownEditor } from './MarkdownEditor.svelte';
|
|
10
|
-
export { default as
|
|
10
|
+
export { default as ComponentInsertDialog } from './ComponentInsertDialog.svelte';
|
|
11
|
+
export { default as ComponentForm } from './ComponentForm.svelte';
|
|
12
|
+
export { default as IconPicker } from './IconPicker.svelte';
|
|
11
13
|
export { default as NavTree } from './NavTree.svelte';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure markdown selection transforms for the editor toolbar. Each call maps a document and a
|
|
3
|
+
* selection range to a new document and a new selection, with no DOM. The MarkdownEditor view
|
|
4
|
+
* dispatches the result; keeping the logic here lets it unit-test without a browser.
|
|
5
|
+
*/
|
|
6
|
+
export type FormatKind = 'bold' | 'italic' | 'code' | 'heading' | 'quote' | 'ul' | 'link';
|
|
7
|
+
export interface FormatResult {
|
|
8
|
+
doc: string;
|
|
9
|
+
from: number;
|
|
10
|
+
to: number;
|
|
11
|
+
}
|
|
12
|
+
export declare function applyMarkdownFormat(doc: string, from: number, to: number, kind: FormatKind): FormatResult;
|
|
13
|
+
//# sourceMappingURL=markdown-format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown-format.d.ts","sourceRoot":"","sources":["../../src/lib/components/markdown-format.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,IAAI,GAAG,MAAM,CAAC;AAE1F,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAKD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,YAAY,CAsBzG"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const WRAP = { bold: '**', italic: '_', code: '`' };
|
|
2
|
+
const LINE_PREFIX = { heading: '# ', quote: '> ', ul: '- ' };
|
|
3
|
+
export function applyMarkdownFormat(doc, from, to, kind) {
|
|
4
|
+
if (kind === 'bold' || kind === 'italic' || kind === 'code') {
|
|
5
|
+
const marker = WRAP[kind];
|
|
6
|
+
const next = doc.slice(0, from) + marker + doc.slice(from, to) + marker + doc.slice(to);
|
|
7
|
+
return { doc: next, from: from + marker.length, to: to + marker.length };
|
|
8
|
+
}
|
|
9
|
+
if (kind === 'link') {
|
|
10
|
+
const text = doc.slice(from, to);
|
|
11
|
+
const placeholder = 'url';
|
|
12
|
+
const lead = `[${text}](`; // everything before the url placeholder
|
|
13
|
+
const inserted = `${lead}${placeholder})`;
|
|
14
|
+
const urlStart = from + lead.length;
|
|
15
|
+
return { doc: doc.slice(0, from) + inserted + doc.slice(to), from: urlStart, to: urlStart + placeholder.length };
|
|
16
|
+
}
|
|
17
|
+
const prefix = LINE_PREFIX[kind];
|
|
18
|
+
const lineStart = doc.lastIndexOf('\n', from - 1) + 1; // 0 when the selection is on the first line
|
|
19
|
+
const region = doc.slice(lineStart, to);
|
|
20
|
+
const prefixed = region.replace(/^/gm, prefix);
|
|
21
|
+
const added = prefixed.length - region.length;
|
|
22
|
+
return { doc: doc.slice(0, lineStart) + prefixed + doc.slice(to), from: from + prefix.length, to: to + added };
|
|
23
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../../src/lib/content/compose.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAc,YAAY,EAAE,cAAc,EAAE,YAAY,EAAiB,gBAAgB,EAAgB,MAAM,YAAY,CAAC;AAGxI;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,YAAY,EACrB,UAAU,GAAE,cAAc,EAAO,EACjC,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,GAAG,SAAS,CAAM,GAC3D,YAAY,
|
|
1
|
+
{"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../../src/lib/content/compose.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAc,YAAY,EAAE,cAAc,EAAE,YAAY,EAAiB,gBAAgB,EAAgB,MAAM,YAAY,CAAC;AAGxI;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,YAAY,EACrB,UAAU,GAAE,cAAc,EAAO,EACjC,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,GAAG,SAAS,CAAM,GAC3D,YAAY,CAwBd"}
|
package/dist/content/compose.js
CHANGED
package/dist/content/types.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ComponentRegistry } from '../render/registry.js';
|
|
2
|
+
import type { IconSet } from '../render/glyph.js';
|
|
2
3
|
import type { DatePrefix } from './ids.js';
|
|
3
4
|
/** Common to every frontmatter field: the frontmatter key, the form label, and whether it is required. */
|
|
4
5
|
interface FieldBase {
|
|
@@ -131,6 +132,8 @@ export interface CairnAdapter {
|
|
|
131
132
|
}): string | Promise<string>;
|
|
132
133
|
/** Directive component registry; the renderer and the future palette derive from it (seam 3). */
|
|
133
134
|
registry?: ComponentRegistry;
|
|
135
|
+
/** The site's glyph name to SVG path-data map, for the admin icon picker and the renderer. */
|
|
136
|
+
icons?: IconSet;
|
|
134
137
|
navMenu?: NavMenuConfig;
|
|
135
138
|
assets?: AssetConfig;
|
|
136
139
|
}
|
|
@@ -219,6 +222,8 @@ export interface CairnRuntime {
|
|
|
219
222
|
stagger?: boolean;
|
|
220
223
|
}): string | Promise<string>;
|
|
221
224
|
registry?: ComponentRegistry;
|
|
225
|
+
/** The site's glyph name to SVG path-data map, for the admin icon picker and the renderer. */
|
|
226
|
+
icons?: IconSet;
|
|
222
227
|
navMenu?: NavMenuConfig;
|
|
223
228
|
assets?: AssetConfig;
|
|
224
229
|
/** Admin panels contributed by extensions (Mode 2). Empty until Plan 09 wires the dispatch route. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/content/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/content/types.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -9,8 +9,14 @@ export { frontmatterFromForm, dateInputValue, serializeMarkdown, parseMarkdown,
|
|
|
9
9
|
export { validateFields } from './content/validate.js';
|
|
10
10
|
export { isValidId, idFromFilename, filenameFromId, slugify, slugFromId, composeDatedId, } from './content/ids.js';
|
|
11
11
|
export type { DatePrefix } from './content/ids.js';
|
|
12
|
-
export { defineRegistry } from './render/registry.js';
|
|
13
|
-
export type { ComponentDef, ComponentRegistry } from './render/registry.js';
|
|
12
|
+
export { defineRegistry, emptyValues } from './render/registry.js';
|
|
13
|
+
export type { ComponentDef, ComponentRegistry, FieldType, AttributeField, SlotKind, SlotDef, ComponentValues, } from './render/registry.js';
|
|
14
|
+
export { serializeComponent, parseComponent } from './render/component-grammar.js';
|
|
15
|
+
export { validateComponent } from './render/component-validate.js';
|
|
16
|
+
export type { ComponentValidation } from './render/component-validate.js';
|
|
17
|
+
export { buildComponentInsert, type ComponentInsert } from './render/component-insert.js';
|
|
18
|
+
export { generateComponentReference } from './render/component-reference.js';
|
|
19
|
+
export type { ReferenceOptions } from './render/component-reference.js';
|
|
14
20
|
export { glyph } from './render/glyph.js';
|
|
15
21
|
export type { IconSet } from './render/glyph.js';
|
|
16
22
|
export { remarkDirectiveStamp } from './render/remark-directives.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/lib/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC7D,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChF,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGnE,YAAY,EACV,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,SAAS,EACT,aAAa,EACb,SAAS,EACT,YAAY,EACZ,SAAS,EACT,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,aAAa,EACb,WAAW,EACX,WAAW,EACX,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,YAAY,EACZ,UAAU,EACV,YAAY,GACb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACxF,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,iBAAiB,EACjB,aAAa,GACd,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EACL,SAAS,EACT,cAAc,EACd,cAAc,EACd,OAAO,EACP,UAAU,EACV,cAAc,GACf,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/lib/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,11 @@ export { frontmatterFromForm, dateInputValue, serializeMarkdown, parseMarkdown,
|
|
|
8
8
|
export { validateFields } from './content/validate.js';
|
|
9
9
|
export { isValidId, idFromFilename, filenameFromId, slugify, slugFromId, composeDatedId, } from './content/ids.js';
|
|
10
10
|
// Render engine (Plan 04): generic directive pipeline; sites own the component registry.
|
|
11
|
-
export { defineRegistry } from './render/registry.js';
|
|
11
|
+
export { defineRegistry, emptyValues } from './render/registry.js';
|
|
12
|
+
export { serializeComponent, parseComponent } from './render/component-grammar.js';
|
|
13
|
+
export { validateComponent } from './render/component-validate.js';
|
|
14
|
+
export { buildComponentInsert } from './render/component-insert.js';
|
|
15
|
+
export { generateComponentReference } from './render/component-reference.js';
|
|
12
16
|
export { glyph } from './render/glyph.js';
|
|
13
17
|
export { remarkDirectiveStamp } from './render/remark-directives.js';
|
|
14
18
|
export { rehypeDispatch, isElement, strProp, iconSpan, splitHead, cardShell, markFirstList, } from './render/rehype-dispatch.js';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ComponentDef, ComponentValues } from './registry.js';
|
|
2
|
+
export declare function serializeComponent(def: ComponentDef, values: ComponentValues): string;
|
|
3
|
+
/** Parse a serialized component directive back into guided-form values, the inverse of
|
|
4
|
+
* {@link serializeComponent}. The grammar is reversible, so the editor can round-trip a
|
|
5
|
+
* saved directive through the form. */
|
|
6
|
+
export declare function parseComponent(markdown: string, def: ComponentDef): Promise<ComponentValues>;
|
|
7
|
+
/** The raw attribute keys present on the component's opening directive, read from the parsed tree
|
|
8
|
+
* (quote-aware, unlike a regex over the source). Used by validation to flag unknown keys. */
|
|
9
|
+
export declare function parseRawAttributeKeys(markdown: string, def: ComponentDef): string[];
|
|
10
|
+
//# sourceMappingURL=component-grammar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component-grammar.d.ts","sourceRoot":"","sources":["../../src/lib/render/component-grammar.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAW,MAAM,eAAe,CAAC;AA8B5E,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,eAAe,GAAG,MAAM,CA2BrF;AAwBD;;wCAEwC;AACxC,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC,CAqClG;AAED;8FAC8F;AAC9F,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,GAAG,MAAM,EAAE,CAMnF"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { unified } from 'unified';
|
|
2
|
+
import remarkParse from 'remark-parse';
|
|
3
|
+
import remarkDirective from 'remark-directive';
|
|
4
|
+
import remarkStringify from 'remark-stringify';
|
|
5
|
+
const COLON = ':';
|
|
6
|
+
function attrBlock(def, values) {
|
|
7
|
+
const parts = [];
|
|
8
|
+
for (const field of def.attributes ?? []) {
|
|
9
|
+
const v = values.attributes[field.key];
|
|
10
|
+
if (field.type === 'boolean') {
|
|
11
|
+
if (v === true)
|
|
12
|
+
parts.push(`${field.key}="true"`);
|
|
13
|
+
}
|
|
14
|
+
else if (typeof v === 'string' && v !== '') {
|
|
15
|
+
// The directive attribute grammar (mdast-util-directive) treats a literal `"` as the value
|
|
16
|
+
// terminator and decodes HTML entities, so a backslash escape does not survive a round-trip.
|
|
17
|
+
// Encode `&` first (so existing entities are not double-decoded) then `"`; the parser decodes
|
|
18
|
+
// both back. A backslash is literal in this grammar and needs no escaping.
|
|
19
|
+
const escaped = v.replace(/&/g, '&').replace(/"/g, '"');
|
|
20
|
+
parts.push(`${field.key}="${escaped}"`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return parts.length ? `{${parts.join(' ')}}` : '';
|
|
24
|
+
}
|
|
25
|
+
function slotByName(def, name) {
|
|
26
|
+
return (def.slots ?? []).find((s) => s.name === name);
|
|
27
|
+
}
|
|
28
|
+
function nestedSlots(def) {
|
|
29
|
+
return (def.slots ?? []).filter((s) => s.name !== 'title' && s.name !== 'body');
|
|
30
|
+
}
|
|
31
|
+
export function serializeComponent(def, values) {
|
|
32
|
+
const fence = COLON.repeat(nestedSlots(def).length > 0 ? 4 : 3);
|
|
33
|
+
const title = slotByName(def, 'title') ? values.slots.title ?? '' : '';
|
|
34
|
+
// Escape brackets in the label so a `[` or `]` in the title does not break the directive label
|
|
35
|
+
// grammar; remark un-escapes them back to literal text on parse, so readLabel recovers them.
|
|
36
|
+
const label = title ? `[${title.replace(/\[/g, '\\[').replace(/\]/g, '\\]')}]` : '';
|
|
37
|
+
const open = `${fence}${def.name}${label}${attrBlock(def, values)}`;
|
|
38
|
+
const lines = [open];
|
|
39
|
+
const body = slotByName(def, 'body') ? values.slots.body ?? '' : '';
|
|
40
|
+
if (body)
|
|
41
|
+
lines.push(body);
|
|
42
|
+
for (const slot of nestedSlots(def)) {
|
|
43
|
+
const raw = values.slots[slot.name];
|
|
44
|
+
const content = slot.kind === 'repeatable'
|
|
45
|
+
? (Array.isArray(raw) ? raw : []).filter((i) => i !== '').map((i) => `- ${i}`).join('\n')
|
|
46
|
+
: (raw ?? '');
|
|
47
|
+
if (!content)
|
|
48
|
+
continue;
|
|
49
|
+
if (lines.length > 1)
|
|
50
|
+
lines.push(''); // blank line before this block
|
|
51
|
+
lines.push(`${COLON.repeat(3)}${slot.name}`, content, COLON.repeat(3));
|
|
52
|
+
}
|
|
53
|
+
lines.push(fence);
|
|
54
|
+
return lines.join('\n');
|
|
55
|
+
}
|
|
56
|
+
function isContainer(node) {
|
|
57
|
+
return node.type === 'containerDirective';
|
|
58
|
+
}
|
|
59
|
+
// Pin the bullet to `-` so a markdown body or slot that uses dash bullets round-trips unchanged
|
|
60
|
+
// rather than drifting to remark-stringify's default `*`, which would silently mutate author content.
|
|
61
|
+
const toMd = unified().use(remarkStringify, { bullet: '-' });
|
|
62
|
+
/** Render mdast children back to trimmed markdown text. */
|
|
63
|
+
function childrenToText(children) {
|
|
64
|
+
const root = { type: 'root', children };
|
|
65
|
+
return String(toMd.stringify(root)).trim();
|
|
66
|
+
}
|
|
67
|
+
/** Parse a serialized component directive back into guided-form values, the inverse of
|
|
68
|
+
* {@link serializeComponent}. The grammar is reversible, so the editor can round-trip a
|
|
69
|
+
* saved directive through the form. */
|
|
70
|
+
export async function parseComponent(markdown, def) {
|
|
71
|
+
const tree = unified().use(remarkParse).use(remarkDirective).parse(markdown);
|
|
72
|
+
const root = tree.children.find((c) => isContainer(c) && c.name === def.name);
|
|
73
|
+
const values = emptyComponentValues(def);
|
|
74
|
+
if (!root)
|
|
75
|
+
return values;
|
|
76
|
+
for (const field of def.attributes ?? []) {
|
|
77
|
+
const raw = root.attributes?.[field.key];
|
|
78
|
+
if (field.type === 'boolean')
|
|
79
|
+
values.attributes[field.key] = raw === 'true';
|
|
80
|
+
else if (typeof raw === 'string')
|
|
81
|
+
values.attributes[field.key] = raw;
|
|
82
|
+
}
|
|
83
|
+
const titleSlot = slotByName(def, 'title');
|
|
84
|
+
const bodySlot = slotByName(def, 'body');
|
|
85
|
+
const nested = nestedSlots(def);
|
|
86
|
+
const nestedNames = new Set(nested.map((s) => s.name));
|
|
87
|
+
const directChildren = root.children.filter((c) => !(isContainer(c) && nestedNames.has(c.name)) && !isDirectiveLabel(c));
|
|
88
|
+
const nestedChildren = root.children.filter((c) => isContainer(c) && nestedNames.has(c.name));
|
|
89
|
+
if (titleSlot)
|
|
90
|
+
values.slots.title = readLabel(root) ?? '';
|
|
91
|
+
if (bodySlot)
|
|
92
|
+
values.slots.body = childrenToText(directChildren);
|
|
93
|
+
for (const slot of nested) {
|
|
94
|
+
const node = nestedChildren.find((c) => c.name === slot.name);
|
|
95
|
+
if (!node)
|
|
96
|
+
continue;
|
|
97
|
+
if (slot.kind === 'repeatable')
|
|
98
|
+
values.slots[slot.name] = readListItems(node.children);
|
|
99
|
+
else
|
|
100
|
+
values.slots[slot.name] = childrenToText(node.children);
|
|
101
|
+
}
|
|
102
|
+
return values;
|
|
103
|
+
}
|
|
104
|
+
/** The raw attribute keys present on the component's opening directive, read from the parsed tree
|
|
105
|
+
* (quote-aware, unlike a regex over the source). Used by validation to flag unknown keys. */
|
|
106
|
+
export function parseRawAttributeKeys(markdown, def) {
|
|
107
|
+
const tree = unified().use(remarkParse).use(remarkDirective).parse(markdown);
|
|
108
|
+
const root = tree.children.find((c) => isContainer(c) && c.name === def.name);
|
|
109
|
+
return Object.keys(root?.attributes ?? {});
|
|
110
|
+
}
|
|
111
|
+
// A bare parse base: empty strings, false, and empty lists, with no attribute defaults applied. The
|
|
112
|
+
// `emptyValues` helper in registry.ts seeds form defaults instead, so it is deliberately not reused
|
|
113
|
+
// here; the parse must overwrite only the fields actually present in the markdown.
|
|
114
|
+
function emptyComponentValues(def) {
|
|
115
|
+
const attributes = {};
|
|
116
|
+
for (const f of def.attributes ?? [])
|
|
117
|
+
attributes[f.key] = f.type === 'boolean' ? false : '';
|
|
118
|
+
const slots = {};
|
|
119
|
+
for (const s of def.slots ?? [])
|
|
120
|
+
slots[s.name] = s.kind === 'repeatable' ? [] : '';
|
|
121
|
+
return { attributes, slots };
|
|
122
|
+
}
|
|
123
|
+
// mdast-util-directive carries the `[label]` as a paragraph whose `data.directiveLabel` is set.
|
|
124
|
+
function isDirectiveLabel(node) {
|
|
125
|
+
return Boolean(node.data?.directiveLabel);
|
|
126
|
+
}
|
|
127
|
+
function readLabel(root) {
|
|
128
|
+
for (const child of root.children) {
|
|
129
|
+
const p = child;
|
|
130
|
+
if (p.type === 'paragraph' && p.data?.directiveLabel)
|
|
131
|
+
return (p.children ?? []).map((c) => c.value ?? '').join('');
|
|
132
|
+
}
|
|
133
|
+
return undefined;
|
|
134
|
+
}
|
|
135
|
+
function readListItems(children) {
|
|
136
|
+
const list = children.find((c) => c.type === 'list');
|
|
137
|
+
if (!list?.children)
|
|
138
|
+
return [];
|
|
139
|
+
return list.children.map((li) => childrenToText(li.children ?? []));
|
|
140
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ComponentDef, ComponentValues } from './registry.js';
|
|
2
|
+
/** The outcome of preparing a guided-form component for insertion: the markdown to insert, or the
|
|
3
|
+
* field-keyed errors to show on the form. */
|
|
4
|
+
export type ComponentInsert = {
|
|
5
|
+
ok: true;
|
|
6
|
+
markdown: string;
|
|
7
|
+
} | {
|
|
8
|
+
ok: false;
|
|
9
|
+
errors: Record<string, string>;
|
|
10
|
+
};
|
|
11
|
+
/** Serialize a component's form values, then validate the result against its schema. Returns the
|
|
12
|
+
* markdown to insert at the cursor, or the field errors keyed by attribute key or slot name. */
|
|
13
|
+
export declare function buildComponentInsert(def: ComponentDef, values: ComponentValues): Promise<ComponentInsert>;
|
|
14
|
+
//# sourceMappingURL=component-insert.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component-insert.d.ts","sourceRoot":"","sources":["../../src/lib/render/component-insert.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEnE;8CAC8C;AAC9C,MAAM,MAAM,eAAe,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAAC;AAE7G;iGACiG;AACjG,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAI/G"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { serializeComponent } from './component-grammar.js';
|
|
2
|
+
import { validateComponent } from './component-validate.js';
|
|
3
|
+
/** Serialize a component's form values, then validate the result against its schema. Returns the
|
|
4
|
+
* markdown to insert at the cursor, or the field errors keyed by attribute key or slot name. */
|
|
5
|
+
export async function buildComponentInsert(def, values) {
|
|
6
|
+
const markdown = serializeComponent(def, values);
|
|
7
|
+
const verdict = await validateComponent(markdown, def);
|
|
8
|
+
return verdict.ok ? { ok: true, markdown } : { ok: false, errors: verdict.errors };
|
|
9
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type ComponentRegistry } from './registry.js';
|
|
2
|
+
export interface ReferenceOptions {
|
|
3
|
+
/** The H1 title of the reference document. */
|
|
4
|
+
title: string;
|
|
5
|
+
/** The one-line blockquote summary under the title. */
|
|
6
|
+
summary: string;
|
|
7
|
+
}
|
|
8
|
+
/** Build a self-contained markdown reference (the llms-full.txt shape) for a component registry, for
|
|
9
|
+
* authors and for pointing an LLM at one curated file. */
|
|
10
|
+
export declare function generateComponentReference(registry: ComponentRegistry, opts: ReferenceOptions): string;
|
|
11
|
+
//# sourceMappingURL=component-reference.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component-reference.d.ts","sourceRoot":"","sources":["../../src/lib/render/component-reference.ts"],"names":[],"mappings":"AACA,OAAO,EAAkC,KAAK,iBAAiB,EAAwB,MAAM,eAAe,CAAC;AAE7G,MAAM,WAAW,gBAAgB;IAC/B,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;2DAC2D;AAC3D,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,iBAAiB,EAAE,IAAI,EAAE,gBAAgB,GAAG,MAAM,CAGtG"}
|