@andesine/converters 0.4.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/README.md +19 -10
- package/dist/anchors.d.ts +1 -1
- package/dist/chunks/{adapter-CeNgvE5W.js → adapter-BlLPQGXb.js} +3 -3
- package/dist/chunks/{adapter-CeNgvE5W.js.map → adapter-BlLPQGXb.js.map} +1 -1
- package/dist/chunks/{core-DC64ddB7.js → core-CJ7Hlymb.js} +62 -16
- package/dist/chunks/core-CJ7Hlymb.js.map +1 -0
- package/dist/chunks/{decode-B-xzTJFV.js → decode-BJK_KI3W.js} +2 -2
- package/dist/chunks/{decode-B-xzTJFV.js.map → decode-BJK_KI3W.js.map} +1 -1
- package/dist/chunks/{types-SDFWRP3z.d.ts → types-DoSWxQAZ.d.ts} +14 -6
- package/dist/html.d.ts +1 -1
- package/dist/html.js +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/markdoc.d.ts +1 -1
- package/dist/markdoc.js +2 -2
- package/dist/markdown.d.ts +1 -1
- package/dist/markdown.js +2 -2
- package/dist/mdx.d.ts +1 -1
- package/dist/mdx.js +2 -2
- package/dist/text.d.ts +1 -1
- package/dist/text.js +1 -1
- package/package.json +1 -1
- package/dist/chunks/core-DC64ddB7.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.7.0
|
|
4
|
+
|
|
5
|
+
- Add the `properties: { as: "element", name }` mapping: each property becomes a self-closing
|
|
6
|
+
element in its position, with `name`, `value`, and `type` when the value doesn't show it.
|
|
7
|
+
Imports with a property mapping read both frontmatter and matching elements.
|
|
8
|
+
|
|
9
|
+
## 0.6.0
|
|
10
|
+
|
|
11
|
+
- No changes; versioned with the other public Andesine packages.
|
|
12
|
+
|
|
3
13
|
## 0.4.0
|
|
4
14
|
|
|
5
15
|
- Align the version with the other Andesine packages. No functional changes.
|
package/README.md
CHANGED
|
@@ -69,11 +69,11 @@ Factory names are `createMarkdownConverter`, `createMDXConverter`,
|
|
|
69
69
|
Per-call options override saved options; handler maps and named fragment mappings
|
|
70
70
|
merge by key.
|
|
71
71
|
|
|
72
|
-
| Field | Default | Other mappings
|
|
73
|
-
| ---------- | ------------------- |
|
|
74
|
-
| Title | First-level heading | `"omit"`, `{ as: "frontmatter", key: "title" }`
|
|
75
|
-
| Properties | Omit | `{ as: "frontmatter" }`
|
|
76
|
-
| Fragments | `"unwrap"` | `"omit"`, `{ as: "element", name: "Fragment" }`
|
|
72
|
+
| Field | Default | Other mappings |
|
|
73
|
+
| ---------- | ------------------- | -------------------------------------------------------------- |
|
|
74
|
+
| Title | First-level heading | `"omit"`, `{ as: "frontmatter", key: "title" }` |
|
|
75
|
+
| Properties | Omit | `{ as: "frontmatter" }`, `{ as: "element", name: "Property" }` |
|
|
76
|
+
| Fragments | `"unwrap"` | `"omit"`, `{ as: "element", name: "Fragment" }` |
|
|
77
77
|
|
|
78
78
|
Unwrap removes the fragment boundary and retains its content in document order.
|
|
79
79
|
Omit removes the content too. The number of fragments does not change the default.
|
|
@@ -86,11 +86,20 @@ On import, matching named wrappers become fragments. Unwrapped boundaries cannot
|
|
|
86
86
|
be recovered. With heading mapping, only the first root heading, at level one,
|
|
87
87
|
becomes the title. With frontmatter mapping, the selected field becomes the title.
|
|
88
88
|
|
|
89
|
-
|
|
90
|
-
with the title field, cause an error.
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
89
|
+
With frontmatter mapping, property labels become frontmatter keys. Duplicate keys,
|
|
90
|
+
including a collision with the title field, cause an error. Frontmatter has no
|
|
91
|
+
position, so imported properties come first.
|
|
92
|
+
|
|
93
|
+
With element mapping, each property becomes a self-closing element in its
|
|
94
|
+
position, for example `<Property name="Status" type="select" value="Draft" />` in
|
|
95
|
+
MDX. `type` is written only when the value doesn't show it. The format must
|
|
96
|
+
support elements, as MDX, Markdoc, and HTML do.
|
|
97
|
+
|
|
98
|
+
Imports with either mapping read both frontmatter and matching elements. Import
|
|
99
|
+
infers text, number, checkbox, and multi-select properties from scalar values and
|
|
100
|
+
string arrays; an element `type` sets date, URL, and select types. Select options
|
|
101
|
+
and schema metadata are not retained. Object-valued properties need custom
|
|
102
|
+
handling. Unmapped frontmatter is ignored.
|
|
94
103
|
|
|
95
104
|
## Heading anchors
|
|
96
105
|
|
package/dist/anchors.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { c as textContent, i as ConversionError } from "./core-
|
|
2
|
-
import { t as decodeMarkdown } from "./decode-
|
|
1
|
+
import { c as textContent, i as ConversionError } from "./core-CJ7Hlymb.js";
|
|
2
|
+
import { t as decodeMarkdown } from "./decode-BJK_KI3W.js";
|
|
3
3
|
import { n as normalizeMarkdown, t as markdownStringifyOptions } from "./stringify-DdPaV2y4.js";
|
|
4
4
|
import { unified } from "unified";
|
|
5
5
|
import remarkParse from "remark-parse";
|
|
@@ -174,4 +174,4 @@ const createMarkdownAdapter = (mdx) => {
|
|
|
174
174
|
//#endregion
|
|
175
175
|
export { createMarkdownAdapter as t };
|
|
176
176
|
|
|
177
|
-
//# sourceMappingURL=adapter-
|
|
177
|
+
//# sourceMappingURL=adapter-BlLPQGXb.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter-CeNgvE5W.js","names":[],"sources":["../../src/markdown/encode.ts","../../src/markdown/adapter.ts"],"sourcesContent":["import type {\n RootContent,\n PhrasingContent,\n BlockContent,\n ListContent,\n TableContent,\n RowContent\n} from \"mdast\";\nimport { ConversionError, textContent } from \"../utils\";\nimport type { ContentMark, ContentNode, EncodeContext } from \"../types\";\n\nconst encodeMarkdown = async (\n node: ContentNode,\n context: EncodeContext<RootContent>\n): Promise<RootContent> => {\n const attrs = node.attrs || {};\n const children = await context.children(node);\n\n switch (node.type) {\n case \"text\":\n return { type: \"text\", value: node.text || \"\" };\n case \"paragraph\":\n return { type: \"paragraph\", children: children as PhrasingContent[] };\n case \"heading\":\n return {\n type: \"heading\",\n ...(context.anchor ? { data: { hProperties: { id: context.anchor } } } : {}),\n depth: Number(attrs.level || 1) as 1 | 2 | 3 | 4 | 5 | 6,\n children: children as PhrasingContent[]\n };\n case \"blockquote\":\n return { type: \"blockquote\", children: children as BlockContent[] };\n case \"bulletList\":\n case \"orderedList\":\n case \"taskList\":\n return {\n type: \"list\",\n ordered: node.type === \"orderedList\",\n ...(node.type === \"orderedList\" ? { start: Number(attrs.start || 1) } : {}),\n spread: false,\n children: children as ListContent[]\n };\n case \"listItem\":\n case \"taskItem\":\n return {\n type: \"listItem\",\n ...(node.type === \"taskItem\" ? { checked: Boolean(attrs.checked) } : {}),\n spread: false,\n children: children as BlockContent[]\n };\n case \"hardBreak\":\n return { type: \"break\" };\n case \"horizontalRule\":\n return { type: \"thematicBreak\" };\n case \"codeBlock\":\n return {\n type: \"code\",\n lang: typeof attrs.language === \"string\" ? attrs.language : null,\n value: textContent(node)\n };\n case \"image\":\n return {\n type: \"image\",\n url: await context.imageURL(node),\n alt: String(attrs.alt || \"\"),\n title: attrs.caption ? String(attrs.caption) : null\n };\n case \"table\":\n return { type: \"table\", children: children as TableContent[] };\n case \"tableRow\":\n return { type: \"tableRow\", children: children as RowContent[] };\n case \"tableCell\":\n case \"tableHeader\": {\n if (\n Number(attrs.colspan || 1) !== 1 ||\n Number(attrs.rowspan || 1) !== 1 ||\n children.some((child) => child.type !== \"paragraph\") ||\n children.length > 1\n ) {\n throw new ConversionError(\n \"Markdown tables require single-paragraph cells without spans\",\n context.path\n );\n }\n return {\n type: \"tableCell\",\n children: children.flatMap((child) => (child.type === \"paragraph\" ? child.children : []))\n };\n }\n default:\n throw new ConversionError(`Unsupported Markdown node: ${node.type}`, context.path);\n }\n};\nconst encodeMarkdownMark = (\n mark: ContentMark,\n children: RootContent[],\n context: EncodeContext<RootContent>\n): RootContent => {\n const content = children as PhrasingContent[];\n\n switch (mark.type) {\n case \"bold\":\n return { type: \"strong\", children: content };\n case \"italic\":\n return { type: \"emphasis\", children: content };\n case \"strike\":\n return { type: \"delete\", children: content };\n case \"link\":\n return { type: \"link\", url: String(mark.attrs?.href || \"\"), title: null, children: content };\n case \"code\": {\n if (children.some((node) => node.type !== \"text\"))\n throw new ConversionError(\"Code marks must wrap plain text\", context.path);\n\n return {\n type: \"inlineCode\",\n value: children.map((node) => (node.type === \"text\" ? node.value : \"\")).join(\"\")\n };\n }\n default:\n throw new ConversionError(`Unsupported Markdown mark: ${mark.type}`, context.path);\n }\n};\n\nexport { encodeMarkdown, encodeMarkdownMark };\n","import { unified, type Plugin } from \"unified\";\nimport remarkParse from \"remark-parse\";\nimport remarkStringify from \"remark-stringify\";\nimport remarkGFM from \"remark-gfm\";\nimport type { Definition, PhrasingContent, Root, RootContent } from \"mdast\";\nimport { encodeMarkdown, encodeMarkdownMark } from \"./encode\";\nimport { decodeMarkdown, type MarkdownNode } from \"./decode\";\nimport { normalizeMarkdown } from \"./normalize\";\nimport { markdownStringifyOptions } from \"./stringify\";\nimport { ConversionError } from \"../utils\";\nimport type { FormatAdapter } from \"../types\";\n\nconst createMarkdownAdapter = (mdx?: Plugin): FormatAdapter<MarkdownNode> => {\n const processor = unified()\n .use(remarkParse)\n .use(remarkGFM)\n .use(remarkStringify, markdownStringifyOptions);\n\n if (mdx) processor.use(mdx);\n\n const marks: Record<string, string> = {\n strong: \"bold\",\n emphasis: \"italic\",\n delete: \"strike\",\n inlineCode: \"code\",\n link: \"link\"\n };\n\n return {\n name: mdx ? \"MDX\" : \"Markdown\",\n frontmatter: true,\n type: (node) => node.type,\n markName: (node) => marks[node.type],\n root: (children) => ({\n type: \"root\",\n children: children.map((node) =>\n node.type === \"image\" ? { type: \"paragraph\", children: [node] } : node\n ) as RootContent[]\n }),\n parse(source) {\n const root = processor.parse(source);\n const definitions = new Map<string, Definition>();\n const collectDefinitions = (node: MarkdownNode): void => {\n if (node.type === \"definition\") {\n const identifier = node.identifier.toUpperCase();\n\n if (!definitions.has(identifier)) definitions.set(identifier, node);\n }\n\n if (\"children\" in node) node.children.forEach(collectDefinitions);\n };\n const resolve = (node: MarkdownNode): MarkdownNode => {\n if (node.type === \"linkReference\" || node.type === \"imageReference\") {\n const definition = definitions.get(node.identifier.toUpperCase());\n\n if (!definition)\n throw new ConversionError(`Missing Markdown definition: ${node.identifier}`);\n if (node.type === \"imageReference\")\n return { type: \"image\", url: definition.url, title: definition.title, alt: node.alt };\n\n return {\n type: \"link\",\n url: definition.url,\n title: definition.title,\n children: node.children.map(resolve) as PhrasingContent[]\n };\n }\n if (\"children\" in node)\n return { ...node, children: node.children.map(resolve) } as MarkdownNode;\n\n return node;\n };\n collectDefinitions(root);\n return resolve(root);\n },\n stringify: (root) => processor.stringify(normalizeMarkdown(root as Root)),\n encode: (node, context) =>\n encodeMarkdown(node, context as Parameters<typeof encodeMarkdown>[1]),\n mark: (mark, children, context) =>\n encodeMarkdownMark(\n mark,\n children as RootContent[],\n context as Parameters<typeof encodeMarkdownMark>[2]\n ),\n decode: decodeMarkdown\n };\n};\n\nexport { createMarkdownAdapter };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"adapter-BlLPQGXb.js","names":[],"sources":["../../src/markdown/encode.ts","../../src/markdown/adapter.ts"],"sourcesContent":["import type {\n RootContent,\n PhrasingContent,\n BlockContent,\n ListContent,\n TableContent,\n RowContent\n} from \"mdast\";\nimport { ConversionError, textContent } from \"../utils\";\nimport type { ContentMark, ContentNode, EncodeContext } from \"../types\";\n\nconst encodeMarkdown = async (\n node: ContentNode,\n context: EncodeContext<RootContent>\n): Promise<RootContent> => {\n const attrs = node.attrs || {};\n const children = await context.children(node);\n\n switch (node.type) {\n case \"text\":\n return { type: \"text\", value: node.text || \"\" };\n case \"paragraph\":\n return { type: \"paragraph\", children: children as PhrasingContent[] };\n case \"heading\":\n return {\n type: \"heading\",\n ...(context.anchor ? { data: { hProperties: { id: context.anchor } } } : {}),\n depth: Number(attrs.level || 1) as 1 | 2 | 3 | 4 | 5 | 6,\n children: children as PhrasingContent[]\n };\n case \"blockquote\":\n return { type: \"blockquote\", children: children as BlockContent[] };\n case \"bulletList\":\n case \"orderedList\":\n case \"taskList\":\n return {\n type: \"list\",\n ordered: node.type === \"orderedList\",\n ...(node.type === \"orderedList\" ? { start: Number(attrs.start || 1) } : {}),\n spread: false,\n children: children as ListContent[]\n };\n case \"listItem\":\n case \"taskItem\":\n return {\n type: \"listItem\",\n ...(node.type === \"taskItem\" ? { checked: Boolean(attrs.checked) } : {}),\n spread: false,\n children: children as BlockContent[]\n };\n case \"hardBreak\":\n return { type: \"break\" };\n case \"horizontalRule\":\n return { type: \"thematicBreak\" };\n case \"codeBlock\":\n return {\n type: \"code\",\n lang: typeof attrs.language === \"string\" ? attrs.language : null,\n value: textContent(node)\n };\n case \"image\":\n return {\n type: \"image\",\n url: await context.imageURL(node),\n alt: String(attrs.alt || \"\"),\n title: attrs.caption ? String(attrs.caption) : null\n };\n case \"table\":\n return { type: \"table\", children: children as TableContent[] };\n case \"tableRow\":\n return { type: \"tableRow\", children: children as RowContent[] };\n case \"tableCell\":\n case \"tableHeader\": {\n if (\n Number(attrs.colspan || 1) !== 1 ||\n Number(attrs.rowspan || 1) !== 1 ||\n children.some((child) => child.type !== \"paragraph\") ||\n children.length > 1\n ) {\n throw new ConversionError(\n \"Markdown tables require single-paragraph cells without spans\",\n context.path\n );\n }\n return {\n type: \"tableCell\",\n children: children.flatMap((child) => (child.type === \"paragraph\" ? child.children : []))\n };\n }\n default:\n throw new ConversionError(`Unsupported Markdown node: ${node.type}`, context.path);\n }\n};\nconst encodeMarkdownMark = (\n mark: ContentMark,\n children: RootContent[],\n context: EncodeContext<RootContent>\n): RootContent => {\n const content = children as PhrasingContent[];\n\n switch (mark.type) {\n case \"bold\":\n return { type: \"strong\", children: content };\n case \"italic\":\n return { type: \"emphasis\", children: content };\n case \"strike\":\n return { type: \"delete\", children: content };\n case \"link\":\n return { type: \"link\", url: String(mark.attrs?.href || \"\"), title: null, children: content };\n case \"code\": {\n if (children.some((node) => node.type !== \"text\"))\n throw new ConversionError(\"Code marks must wrap plain text\", context.path);\n\n return {\n type: \"inlineCode\",\n value: children.map((node) => (node.type === \"text\" ? node.value : \"\")).join(\"\")\n };\n }\n default:\n throw new ConversionError(`Unsupported Markdown mark: ${mark.type}`, context.path);\n }\n};\n\nexport { encodeMarkdown, encodeMarkdownMark };\n","import { unified, type Plugin } from \"unified\";\nimport remarkParse from \"remark-parse\";\nimport remarkStringify from \"remark-stringify\";\nimport remarkGFM from \"remark-gfm\";\nimport type { Definition, PhrasingContent, Root, RootContent } from \"mdast\";\nimport { encodeMarkdown, encodeMarkdownMark } from \"./encode\";\nimport { decodeMarkdown, type MarkdownNode } from \"./decode\";\nimport { normalizeMarkdown } from \"./normalize\";\nimport { markdownStringifyOptions } from \"./stringify\";\nimport { ConversionError } from \"../utils\";\nimport type { FormatAdapter } from \"../types\";\n\nconst createMarkdownAdapter = (mdx?: Plugin): FormatAdapter<MarkdownNode> => {\n const processor = unified()\n .use(remarkParse)\n .use(remarkGFM)\n .use(remarkStringify, markdownStringifyOptions);\n\n if (mdx) processor.use(mdx);\n\n const marks: Record<string, string> = {\n strong: \"bold\",\n emphasis: \"italic\",\n delete: \"strike\",\n inlineCode: \"code\",\n link: \"link\"\n };\n\n return {\n name: mdx ? \"MDX\" : \"Markdown\",\n frontmatter: true,\n type: (node) => node.type,\n markName: (node) => marks[node.type],\n root: (children) => ({\n type: \"root\",\n children: children.map((node) =>\n node.type === \"image\" ? { type: \"paragraph\", children: [node] } : node\n ) as RootContent[]\n }),\n parse(source) {\n const root = processor.parse(source);\n const definitions = new Map<string, Definition>();\n const collectDefinitions = (node: MarkdownNode): void => {\n if (node.type === \"definition\") {\n const identifier = node.identifier.toUpperCase();\n\n if (!definitions.has(identifier)) definitions.set(identifier, node);\n }\n\n if (\"children\" in node) node.children.forEach(collectDefinitions);\n };\n const resolve = (node: MarkdownNode): MarkdownNode => {\n if (node.type === \"linkReference\" || node.type === \"imageReference\") {\n const definition = definitions.get(node.identifier.toUpperCase());\n\n if (!definition)\n throw new ConversionError(`Missing Markdown definition: ${node.identifier}`);\n if (node.type === \"imageReference\")\n return { type: \"image\", url: definition.url, title: definition.title, alt: node.alt };\n\n return {\n type: \"link\",\n url: definition.url,\n title: definition.title,\n children: node.children.map(resolve) as PhrasingContent[]\n };\n }\n if (\"children\" in node)\n return { ...node, children: node.children.map(resolve) } as MarkdownNode;\n\n return node;\n };\n collectDefinitions(root);\n return resolve(root);\n },\n stringify: (root) => processor.stringify(normalizeMarkdown(root as Root)),\n encode: (node, context) =>\n encodeMarkdown(node, context as Parameters<typeof encodeMarkdown>[1]),\n mark: (mark, children, context) =>\n encodeMarkdownMark(\n mark,\n children as RootContent[],\n context as Parameters<typeof encodeMarkdownMark>[2]\n ),\n decode: decodeMarkdown\n };\n};\n\nexport { createMarkdownAdapter };\n"],"mappings":"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"}
|
|
@@ -159,13 +159,28 @@ const createExportConverter = (adapter, defaults = {}) => {
|
|
|
159
159
|
attrs: { level: 1 }
|
|
160
160
|
}, context));
|
|
161
161
|
} else if (node.type === "property") {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
162
|
+
const mapping = settings.properties ?? "omit";
|
|
163
|
+
const name = String(node.attrs?.label || "Property");
|
|
164
|
+
const type = String(node.attrs?.type || "text");
|
|
165
|
+
const value = node.attrs?.value ?? "";
|
|
166
|
+
const normalized = type === "number" ? value === "" ? null : Number(value) : value;
|
|
167
|
+
if (mapping === "omit") return [];
|
|
168
|
+
if (mapping.as === "frontmatter") {
|
|
166
169
|
setMetadata(frontmatter, name, normalized);
|
|
170
|
+
return [];
|
|
167
171
|
}
|
|
168
|
-
|
|
172
|
+
result = await context.encode({
|
|
173
|
+
type: "element",
|
|
174
|
+
attrs: {
|
|
175
|
+
name: mapping.name,
|
|
176
|
+
props: {
|
|
177
|
+
name,
|
|
178
|
+
...getPropertyType(normalized) !== type && { type },
|
|
179
|
+
value: normalized
|
|
180
|
+
},
|
|
181
|
+
selfClosing: true
|
|
182
|
+
}
|
|
183
|
+
});
|
|
169
184
|
} else if (node.type === "fragment") {
|
|
170
185
|
const name = String(node.attrs?.name || "Content");
|
|
171
186
|
const mapping = lookup(settings.fragments?.named, name) ?? settings.fragments?.default ?? "unwrap";
|
|
@@ -247,6 +262,10 @@ const createImportConverter = (adapter, defaults = {}) => {
|
|
|
247
262
|
return array(await (handler ? handler(node, context) : adapter.decode(node, context))).flatMap((content) => {
|
|
248
263
|
if (content.type !== "element") return [content];
|
|
249
264
|
const props = content.attrs?.props;
|
|
265
|
+
if ((typeof settings.properties === "object" && settings.properties.as === "element" ? settings.properties : void 0)?.name === content.attrs?.name) {
|
|
266
|
+
if (typeof props?.name !== "string") throw new ConversionError("Property elements require a name", path);
|
|
267
|
+
return [createProperty(props.name, props.value, props.type)];
|
|
268
|
+
}
|
|
250
269
|
const fragmentName = typeof props?.name === "string" ? props.name : void 0;
|
|
251
270
|
const mapping = fragmentName ? lookup(settings.fragments?.named, fragmentName) ?? settings.fragments?.default : void 0;
|
|
252
271
|
if (mapping && typeof mapping === "object" && mapping.name === content.attrs?.name) return [{
|
|
@@ -266,16 +285,7 @@ const createImportConverter = (adapter, defaults = {}) => {
|
|
|
266
285
|
if (title === "heading" && settings.document !== "fragment" && content[0]?.type === "heading" && content[0].attrs?.level === 1) titleText = textContent(content.shift());
|
|
267
286
|
if (settings.properties && settings.properties !== "omit") for (const [label, value] of Object.entries(input.frontmatter)) {
|
|
268
287
|
if (label === titleKey) continue;
|
|
269
|
-
|
|
270
|
-
if (type === "text" && value !== null && typeof value !== "string") throw new ConversionError(`Property ${label} cannot represent this frontmatter value`);
|
|
271
|
-
properties.push({
|
|
272
|
-
type: "property",
|
|
273
|
-
attrs: {
|
|
274
|
-
label,
|
|
275
|
-
type,
|
|
276
|
-
value: value ?? ""
|
|
277
|
-
}
|
|
278
|
-
});
|
|
288
|
+
properties.push(createProperty(label, value));
|
|
279
289
|
}
|
|
280
290
|
const body = settings.targetFragment ? [{
|
|
281
291
|
type: "fragment",
|
|
@@ -322,6 +332,42 @@ const createConverter = (adapter, defaults = {}) => ({
|
|
|
322
332
|
...createExportConverter(adapter, defaults),
|
|
323
333
|
...createImportConverter(adapter, defaults)
|
|
324
334
|
});
|
|
335
|
+
const PROPERTY_TYPES = [
|
|
336
|
+
"text",
|
|
337
|
+
"number",
|
|
338
|
+
"checkbox",
|
|
339
|
+
"date",
|
|
340
|
+
"url",
|
|
341
|
+
"select",
|
|
342
|
+
"multi-select"
|
|
343
|
+
];
|
|
344
|
+
const getPropertyType = (value) => {
|
|
345
|
+
const stringArray = Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
346
|
+
if (typeof value === "number") return "number";
|
|
347
|
+
if (typeof value === "boolean") return "checkbox";
|
|
348
|
+
if (stringArray) return "multi-select";
|
|
349
|
+
return "text";
|
|
350
|
+
};
|
|
351
|
+
const createProperty = (label, value, type) => {
|
|
352
|
+
const propertyType = type === void 0 ? getPropertyType(value) : type;
|
|
353
|
+
const textValue = ![
|
|
354
|
+
"number",
|
|
355
|
+
"checkbox",
|
|
356
|
+
"multi-select"
|
|
357
|
+
].includes(String(propertyType));
|
|
358
|
+
const supportedType = typeof propertyType === "string" && PROPERTY_TYPES.includes(propertyType);
|
|
359
|
+
const unsupportedValue = textValue && value !== null && value !== void 0 && typeof value !== "string";
|
|
360
|
+
if (!supportedType) throw new ConversionError(`Property ${label} has an unsupported type: ${String(type)}`);
|
|
361
|
+
if (unsupportedValue) throw new ConversionError(`Property ${label} cannot represent this value`);
|
|
362
|
+
return {
|
|
363
|
+
type: "property",
|
|
364
|
+
attrs: {
|
|
365
|
+
label,
|
|
366
|
+
type: propertyType,
|
|
367
|
+
value: value ?? ""
|
|
368
|
+
}
|
|
369
|
+
};
|
|
370
|
+
};
|
|
325
371
|
const setMetadata = (metadata, key, value) => {
|
|
326
372
|
if (Object.hasOwn(metadata, key)) throw new ConversionError(`Duplicate frontmatter field: ${key}`);
|
|
327
373
|
metadata[key] = value;
|
|
@@ -369,4 +415,4 @@ const mergeOptions = (defaults, options) => ({
|
|
|
369
415
|
//#endregion
|
|
370
416
|
export { element as a, textContent as c, ConversionError as i, textNode as l, createExportConverter as n, isJSONValue as o, createImportConverter as r, lookup as s, createConverter as t, withMark as u };
|
|
371
417
|
|
|
372
|
-
//# sourceMappingURL=core-
|
|
418
|
+
//# sourceMappingURL=core-CJ7Hlymb.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core-CJ7Hlymb.js","names":[],"sources":["../../src/utils.ts","../../src/frontmatter.ts","../../src/core.ts"],"sourcesContent":["import type { ContentMark, ContentNode, HandlerResult } from \"./types\";\n\n/** A conversion failure, optionally located at a child-index path in the source tree. */\nclass ConversionError extends Error {\n /**\n * @param message - Description of the unsupported content or invalid mapping.\n * @param path - Child indexes appended to the message; defaults to the document root.\n */\n constructor(\n message: string,\n readonly path: readonly number[] = []\n ) {\n super(`${message}${path.length ? ` at content[${path.join(\"][\")}]` : \"\"}`);\n this.name = \"ConversionError\";\n }\n}\n\nconst lookup = <T>(record: Record<string, T> | undefined, name: string): T | undefined => {\n return record && Object.hasOwn(record, name) ? record[name] : undefined;\n};\nconst array = <T>(value: HandlerResult<T>): T[] =>\n value === null ? [] : Array.isArray(value) ? value : [value];\n/**\n * Concatenate a node's descendant text without changing the source.\n * @param node - ProseMirror node to read.\n * @returns Raw text with no added block separators, markup, or hard-break replacement.\n */\nconst textContent = (node: ContentNode): string =>\n node.text ?? (node.content || []).map(textContent).join(\"\");\n/**\n * Create text content suitable for a node handler.\n * @param text - Literal text to include.\n * @returns One text node, or an empty array for an empty string.\n */\nconst textNode = (text: string): ContentNode[] => (text ? [{ type: \"text\", text }] : []);\n/**\n * Append a mark to all descendant text nodes without modifying the input nodes.\n * @param nodes - Content to mark. Existing marks are retained, including duplicates.\n * @param mark - Mark to append to each text node.\n * @returns Mapped nodes; unchanged leaf nodes and existing marks may retain their references.\n */\nconst withMark = (nodes: ContentNode[], mark: ContentMark): ContentNode[] =>\n nodes.map((node) => {\n if (node.type === \"text\") return { ...node, marks: [...(node.marks || []), mark] };\n\n return node.content ? { ...node, content: withMark(node.content, mark) } : node;\n });\nconst isJSONValue = (value: unknown): boolean => {\n if (value === null || typeof value === \"string\" || typeof value === \"boolean\") return true;\n if (typeof value === \"number\") return Number.isFinite(value);\n if (Array.isArray(value)) return value.every(isJSONValue);\n if (typeof value !== \"object\" || Object.getPrototypeOf(value) !== Object.prototype) return false;\n\n return Object.values(value).every(isJSONValue);\n};\n/**\n * Create an Andesine element node with static JSON properties and a source representation.\n * @param name - Element name, starting with a letter and containing letters, digits, _, ., or -.\n * @param props - Static JSON properties with valid attribute names; executable expressions are rejected.\n * @param content - Child nodes. The supplied content array is retained.\n * @param selfClosing - Whether the source uses a self-closing tag; defaults to true for empty content.\n * @returns A ProseMirror element node for use in import handlers.\n * @throws ConversionError for invalid names, property keys, or non-JSON property values.\n */\nconst element = (\n name: string,\n props: Record<string, unknown>,\n content: ContentNode[],\n selfClosing = !content.length\n): ContentNode => {\n if (!/^[A-Za-z][\\w.-]*$/.test(name) || !isJSONValue(props)) {\n throw new ConversionError(\"Elements require a valid name and static JSON properties\");\n }\n const attributes = Object.entries(props)\n .map(([key, value]) => {\n if (!/^[A-Za-z][\\w-]*$/.test(key))\n throw new ConversionError(`Invalid element property: ${key}`);\n\n return typeof value === \"string\"\n ? ` ${key}=${JSON.stringify(value)}`\n : ` ${key}={${JSON.stringify(value)}}`;\n })\n .join(\"\");\n\n return {\n type: \"element\",\n attrs: { name, props, selfClosing, source: `<${name}${attributes}${selfClosing ? \" /\" : \"\"}>` },\n ...(content.length ? { content } : {})\n };\n};\n\nexport { ConversionError, lookup, array, element, isJSONValue, textContent, textNode, withMark };\n","import { parseDocument, stringify } from \"yaml\";\nimport { ConversionError, isJSONValue } from \"./utils\";\n\nconst readFrontmatter = (\n source: string\n): { source: string; frontmatter: Record<string, unknown> } => {\n const match = /^(?:\\uFEFF)?---\\r?\\n([\\s\\S]*?)\\r?\\n---(?:\\r?\\n|$)/.exec(source);\n\n if (!match) return { source, frontmatter: {} };\n\n const document = parseDocument(match[1], { schema: \"core\", uniqueKeys: true });\n\n if (document.errors.length)\n throw new ConversionError(`Invalid frontmatter: ${document.errors[0].message}`);\n\n const value: unknown = document.toJS({ maxAliasCount: 100 });\n\n if (!value || Array.isArray(value) || typeof value !== \"object\" || !isJSONValue(value)) {\n throw new ConversionError(\"Frontmatter must contain an object with static JSON values\");\n }\n return { source: source.slice(match[0].length), frontmatter: value as Record<string, unknown> };\n};\nconst writeFrontmatter = (frontmatter: Record<string, unknown>, source: string): string => {\n return Object.keys(frontmatter).length\n ? `---\\n${stringify(frontmatter)}---\\n\\n${source}`\n : source;\n};\n\nexport { readFrontmatter, writeFrontmatter };\n","import { getHeadingAnchors } from \"./anchors\";\nimport { readFrontmatter, writeFrontmatter } from \"./frontmatter\";\nimport { array, ConversionError, lookup, textContent, textNode } from \"./utils\";\nimport type {\n ContentNode,\n ConvertedAST,\n Converter,\n ConverterOptions,\n DecodeContext,\n EncodeContext,\n ExportConverter,\n ExportConverterOptions,\n ExportFormatAdapter,\n ImportConverter,\n ImportConverterOptions,\n ImportFormatAdapter,\n FormatAdapter\n} from \"./types\";\n\n/**\n * Build an async export-only converter using the shared content mappings.\n *\n * @param adapter - Root builder, serializer, and export node/mark handlers. No import stubs are needed.\n * @param defaults - Reusable options. Per-call handler maps and named fragment mappings merge by key.\n * @returns Only encode() and toAST(), both async. Handlers and image callbacks may be async.\n * Import methods are absent at runtime and in TypeScript. No content is saved.\n * Unsupported nodes and marks are handled by the adapter, usually by throwing ConversionError.\n * Defaults render titles as H1s, unwrap fragments, and omit properties. Removed boundaries and\n * omitted data cannot be recovered on import; choose explicit mappings when preservation matters.\n */\nconst createExportConverter = <T>(\n adapter: ExportFormatAdapter<T>,\n defaults: ExportConverterOptions<T> = {}\n): ExportConverter<T> => {\n const toAST = async (\n document: ContentNode,\n options: ExportConverterOptions<T> = {}\n ): Promise<ConvertedAST<T>> => {\n const settings = mergeOptions(defaults, options);\n const anchors = new Map(\n getHeadingAnchors(document).map((heading) => [heading.path.join(\".\"), heading.anchor])\n );\n const frontmatter: Record<string, unknown> = Object.create(null);\n const encode = async (node: ContentNode, path: readonly number[]): Promise<T[]> => {\n // Code handlers consume plain text, so code must be the innermost mark.\n const marks = [...(node.marks || [])].sort(\n (first, second) => Number(first.type === \"code\") - Number(second.type === \"code\")\n );\n const context: EncodeContext<T> = {\n anchor: node.type === \"heading\" ? anchors.get(path.join(\".\")) : undefined,\n options: settings,\n path,\n encode: (child) => encode(child, path),\n children: async (parent) => {\n const children: T[] = [];\n\n for (const [index, child] of (parent.content || []).entries())\n children.push(...(await encode(child, [...path, index])));\n return children;\n },\n imageURL: async (image) => {\n const url = await settings.imageURL?.(image);\n\n if (!url)\n throw new ConversionError(\"An imageURL callback must resolve the image asset\", path);\n return url;\n }\n };\n const handlers = settings.encode;\n const elementName = node.type === \"element\" ? String(node.attrs?.name || \"\") : undefined;\n const handler = elementName\n ? (lookup(handlers?.elements, elementName) ??\n lookup(handlers?.elements, \"*\") ??\n lookup(handlers?.nodes, \"element\") ??\n lookup(handlers?.nodes, \"*\"))\n : (lookup(handlers?.nodes, node.type) ?? lookup(handlers?.nodes, \"*\"));\n let result: T[];\n\n if (handler) {\n result = array(await handler(node, context));\n } else if (node.type === \"doc\") {\n result = await context.children(node);\n } else if (node.type === \"title\") {\n const title = settings.title ?? \"heading\";\n\n if (title === \"omit\") return [];\n if (typeof title === \"object\") {\n setMetadata(frontmatter, title.key || \"title\", textContent(node));\n return [];\n }\n result = array(\n await adapter.encode({ ...node, type: \"heading\", attrs: { level: 1 } }, context)\n );\n } else if (node.type === \"property\") {\n const mapping = settings.properties ?? \"omit\";\n const name = String(node.attrs?.label || \"Property\");\n const type = String(node.attrs?.type || \"text\");\n const value = node.attrs?.value ?? \"\";\n const normalized = type === \"number\" ? (value === \"\" ? null : Number(value)) : value;\n\n if (mapping === \"omit\") return [];\n\n if (mapping.as === \"frontmatter\") {\n setMetadata(frontmatter, name, normalized);\n return [];\n }\n result = await context.encode({\n type: \"element\",\n attrs: {\n name: mapping.name,\n // The type is written only when import can't infer it from the value.\n props: {\n name,\n ...(getPropertyType(normalized) !== type && { type }),\n value: normalized\n },\n selfClosing: true\n }\n });\n } else if (node.type === \"fragment\") {\n const name = String(node.attrs?.name || \"Content\");\n const mapping =\n lookup(settings.fragments?.named, name) ?? settings.fragments?.default ?? \"unwrap\";\n\n if (mapping === \"omit\") return [];\n if (mapping === \"unwrap\") return context.children(node);\n\n result = await context.encode({\n type: \"element\",\n attrs: { name: mapping.name, props: { name }, selfClosing: false },\n content: node.content\n });\n } else {\n result = array(await adapter.encode(node, context));\n }\n if (!result.length) return result;\n\n for (const mark of marks.reverse()) {\n const handler = lookup(handlers?.marks, mark.type) ?? lookup(handlers?.marks, \"*\");\n\n result = array(\n await (handler ? handler(mark, result, context) : adapter.mark(mark, result, context))\n );\n }\n return result;\n };\n const children = await encode(document, []);\n\n if (!adapter.frontmatter && Object.keys(frontmatter).length)\n throw new ConversionError(`${adapter.name} does not support frontmatter`);\n\n return { tree: adapter.root(children), frontmatter };\n };\n\n return {\n toAST,\n async encode(document: ContentNode, options?: ExportConverterOptions<T>): Promise<string> {\n const result = await toAST(document, options);\n\n return writeFrontmatter(result.frontmatter, await adapter.stringify(result.tree));\n }\n };\n};\n\n/**\n * Build an async import-only converter using the shared content mappings.\n *\n * @param adapter - Parser, decode handler, and node-type lookup. No export stubs are needed.\n * @param defaults - Reusable import mappings and handlers, merged by key with per-call overrides.\n * @returns Only decode() and fromAST(), both async. Parsers, handlers, and image callbacks may\n * be async. Export methods are absent at runtime and in TypeScript. No content is saved.\n * Imports create an entry with a title by default; document: \"fragment\" retains headings as body\n * content. Unsupported input is handled by the adapter; parser and handler errors pass through.\n */\nconst createImportConverter = <T>(\n adapter: ImportFormatAdapter<T>,\n defaults: ImportConverterOptions<T> = {}\n): ImportConverter<T> => {\n const fromAST = async (\n input: ConvertedAST<T>,\n options: ImportConverterOptions<T> = {}\n ): Promise<ContentNode> => {\n const settings = mergeOptions(defaults, options);\n const decode = async (node: T, path: readonly number[]): Promise<ContentNode[]> => {\n const context: DecodeContext<T> = {\n options: settings,\n path,\n decode: (child) => decode(child, path),\n children: async (children) => {\n const output: ContentNode[] = [];\n\n for (const [index, child] of children.entries())\n output.push(...(await decode(child, [...path, index])));\n return output;\n },\n image: async (image) => {\n const assetID = await settings.imageAssetID?.(image);\n\n if (!assetID)\n throw new ConversionError(\"An imageAssetID callback must resolve the image URL\", path);\n return { type: \"image\", attrs: { assetID, alt: image.alt, caption: image.title || \"\" } };\n }\n };\n const handlers = settings.decode;\n const type = adapter.type(node);\n const name = adapter.elementName?.(node);\n const mark = adapter.markName?.(node);\n const handler =\n (name\n ? (lookup(handlers?.elements, name) ?? lookup(handlers?.elements, \"*\"))\n : undefined) ??\n (mark ? (lookup(handlers?.marks, mark) ?? lookup(handlers?.marks, \"*\")) : undefined) ??\n lookup(handlers?.nodes, type) ??\n lookup(handlers?.nodes, \"*\");\n const result = array(\n await (handler ? handler(node, context) : adapter.decode(node, context))\n );\n\n return result.flatMap((content) => {\n if (content.type !== \"element\") return [content];\n\n const props = content.attrs?.props as Record<string, unknown> | undefined;\n const propertyMapping =\n typeof settings.properties === \"object\" && settings.properties.as === \"element\"\n ? settings.properties\n : undefined;\n\n if (propertyMapping?.name === content.attrs?.name) {\n if (typeof props?.name !== \"string\") {\n throw new ConversionError(\"Property elements require a name\", path);\n }\n\n return [createProperty(props.name, props.value, props.type)];\n }\n\n const fragmentName = typeof props?.name === \"string\" ? props.name : undefined;\n const mapping = fragmentName\n ? (lookup(settings.fragments?.named, fragmentName) ?? settings.fragments?.default)\n : undefined;\n\n if (mapping && typeof mapping === \"object\" && mapping.name === content.attrs?.name) {\n return [\n {\n type: \"fragment\",\n attrs: { name: fragmentName },\n content: content.content || [{ type: \"paragraph\" }]\n }\n ];\n }\n return [content];\n });\n };\n const content = await decode(input.tree, []);\n const title = settings.title ?? \"heading\";\n const titleKey = typeof title === \"object\" ? title.key || \"title\" : undefined;\n const properties: ContentNode[] = [];\n let titleText = \"\";\n\n if (titleKey && input.frontmatter[titleKey] !== undefined)\n titleText = String(input.frontmatter[titleKey]);\n if (\n title === \"heading\" &&\n settings.document !== \"fragment\" &&\n content[0]?.type === \"heading\" &&\n content[0].attrs?.level === 1\n ) {\n titleText = textContent(content.shift()!);\n }\n if (settings.properties && settings.properties !== \"omit\") {\n for (const [label, value] of Object.entries(input.frontmatter)) {\n if (label === titleKey) continue;\n\n properties.push(createProperty(label, value));\n }\n }\n const body: ContentNode[] = settings.targetFragment\n ? [\n {\n type: \"fragment\",\n attrs: { name: settings.targetFragment },\n content: content.length ? content : [{ type: \"paragraph\" }]\n }\n ]\n : content;\n\n return {\n type: \"doc\",\n content: [\n ...(settings.document === \"fragment\"\n ? []\n : [{ type: \"title\", content: textNode(titleText) }]),\n ...properties,\n ...(body.length ? body : [{ type: \"paragraph\" }])\n ]\n };\n };\n\n return {\n fromAST,\n async decode(source: string, options?: ImportConverterOptions<T>): Promise<ContentNode> {\n const input = adapter.frontmatter ? readFrontmatter(source) : { source, frontmatter: {} };\n\n return fromAST(\n { tree: await adapter.parse(input.source), frontmatter: input.frontmatter },\n options\n );\n }\n };\n};\n\n/**\n * Build an async converter for a custom format that supports both import and export.\n *\n * @param adapter - Full adapter with parser, serializer, and mappings for both directions.\n * @param defaults - Shared defaults and direction-specific handlers. Per-call maps merge by key.\n * @returns encode(), toAST(), decode(), and fromAST(), composed from the one-way factories.\n * Each method accepts options for its own direction. No content is saved or uploaded.\n * Defaults render titles as H1s, unwrap fragments, and omit properties. Removed boundaries and\n * omitted data cannot be recovered on import; choose explicit mappings when preservation matters.\n */\nconst createConverter = <T>(\n adapter: FormatAdapter<T>,\n defaults: ConverterOptions<T> = {}\n): Converter<T> => ({\n ...createExportConverter(adapter, defaults),\n ...createImportConverter(adapter, defaults)\n});\nconst PROPERTY_TYPES = [\"text\", \"number\", \"checkbox\", \"date\", \"url\", \"select\", \"multi-select\"];\nconst getPropertyType = (value: unknown): string => {\n const stringArray = Array.isArray(value) && value.every((item) => typeof item === \"string\");\n\n if (typeof value === \"number\") return \"number\";\n if (typeof value === \"boolean\") return \"checkbox\";\n if (stringArray) return \"multi-select\";\n\n return \"text\";\n};\nconst createProperty = (label: string, value: unknown, type?: unknown): ContentNode => {\n const propertyType = type === undefined ? getPropertyType(value) : type;\n const textValue = ![\"number\", \"checkbox\", \"multi-select\"].includes(String(propertyType));\n const supportedType = typeof propertyType === \"string\" && PROPERTY_TYPES.includes(propertyType);\n const unsupportedValue =\n textValue && value !== null && value !== undefined && typeof value !== \"string\";\n\n if (!supportedType) {\n throw new ConversionError(`Property ${label} has an unsupported type: ${String(type)}`);\n }\n\n if (unsupportedValue) throw new ConversionError(`Property ${label} cannot represent this value`);\n\n return { type: \"property\", attrs: { label, type: propertyType, value: value ?? \"\" } };\n};\nconst setMetadata = (metadata: Record<string, unknown>, key: string, value: unknown): void => {\n if (Object.hasOwn(metadata, key))\n throw new ConversionError(`Duplicate frontmatter field: ${key}`);\n\n metadata[key] = value;\n};\nconst mergeOptions = <T>(\n defaults: ConverterOptions<T>,\n options: ConverterOptions<T>\n): ConverterOptions<T> => ({\n ...defaults,\n ...options,\n fragments: {\n ...defaults.fragments,\n ...options.fragments,\n named: { ...defaults.fragments?.named, ...options.fragments?.named }\n },\n encode: {\n nodes: { ...defaults.encode?.nodes, ...options.encode?.nodes },\n marks: { ...defaults.encode?.marks, ...options.encode?.marks },\n elements: { ...defaults.encode?.elements, ...options.encode?.elements }\n },\n decode: {\n nodes: { ...defaults.decode?.nodes, ...options.decode?.nodes },\n marks: { ...defaults.decode?.marks, ...options.decode?.marks },\n elements: { ...defaults.decode?.elements, ...options.decode?.elements }\n }\n});\n\nexport { createConverter, createExportConverter, createImportConverter };\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as ConversionError, l as textNode, u as withMark } from "./core-
|
|
1
|
+
import { i as ConversionError, l as textNode, u as withMark } from "./core-CJ7Hlymb.js";
|
|
2
2
|
//#region src/markdown/decode.ts
|
|
3
3
|
const paragraphContent = (children) => {
|
|
4
4
|
const blocks = [];
|
|
@@ -99,4 +99,4 @@ const decodeMarkdown = async (node, context) => {
|
|
|
99
99
|
//#endregion
|
|
100
100
|
export { paragraphContent as n, decodeMarkdown as t };
|
|
101
101
|
|
|
102
|
-
//# sourceMappingURL=decode-
|
|
102
|
+
//# sourceMappingURL=decode-BJK_KI3W.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decode-
|
|
1
|
+
{"version":3,"file":"decode-BJK_KI3W.js","names":[],"sources":["../../src/markdown/decode.ts"],"sourcesContent":["import type { Root, RootContent } from \"mdast\";\nimport { ConversionError, textNode, withMark } from \"../utils\";\nimport type { ContentNode, DecodeContext } from \"../types\";\n\ntype MarkdownNode = Root | RootContent;\n\nconst paragraphContent = (children: ContentNode[]): ContentNode[] => {\n const blocks: ContentNode[] = [];\n let inline: ContentNode[] = [];\n\n for (const child of children) {\n if ([\"text\", \"hardBreak\"].includes(child.type)) {\n inline.push(child);\n } else {\n if (inline.length) blocks.push({ type: \"paragraph\", content: inline });\n inline = [];\n blocks.push(child);\n }\n }\n if (inline.length || !blocks.length) blocks.push({ type: \"paragraph\", content: inline });\n\n return blocks;\n};\nconst decodeMarkdown = async (\n node: MarkdownNode,\n context: DecodeContext<MarkdownNode>\n): Promise<ContentNode | ContentNode[] | null> => {\n const children = \"children\" in node ? await context.children(node.children) : [];\n\n switch (node.type) {\n case \"root\":\n return children;\n case \"text\":\n return textNode(node.value);\n case \"paragraph\":\n return paragraphContent(children);\n case \"heading\":\n return { type: \"heading\", attrs: { level: node.depth }, content: children };\n case \"blockquote\":\n return { type: \"blockquote\", content: children };\n case \"list\": {\n const tasks = children.some((child) => child.type === \"taskItem\");\n\n if (node.ordered && tasks)\n throw new ConversionError(\"Ordered task lists require a custom handler\", context.path);\n\n return {\n type: node.ordered ? \"orderedList\" : tasks ? \"taskList\" : \"bulletList\",\n ...(node.ordered ? { attrs: { start: node.start || 1 } } : {}),\n content: tasks\n ? children.map((child) => ({\n ...child,\n type: \"taskItem\",\n attrs: { checked: false, ...child.attrs }\n }))\n : children\n };\n }\n case \"listItem\":\n return {\n type: typeof node.checked === \"boolean\" ? \"taskItem\" : \"listItem\",\n ...(typeof node.checked === \"boolean\" ? { attrs: { checked: node.checked } } : {}),\n content: children\n };\n case \"break\":\n return { type: \"hardBreak\" };\n case \"thematicBreak\":\n return { type: \"horizontalRule\" };\n case \"code\":\n return {\n type: \"codeBlock\",\n attrs: { language: node.lang || null },\n content: textNode(node.value)\n };\n case \"inlineCode\":\n return withMark(textNode(node.value), { type: \"code\" });\n case \"strong\":\n return withMark(children, { type: \"bold\" });\n case \"emphasis\":\n return withMark(children, { type: \"italic\" });\n case \"delete\":\n return withMark(children, { type: \"strike\" });\n case \"link\":\n return withMark(children, { type: \"link\", attrs: { href: node.url } });\n case \"image\":\n return context.image({ url: node.url, alt: node.alt || \"\", title: node.title || undefined });\n case \"table\":\n return {\n type: \"table\",\n content: children.map((row, index) =>\n index\n ? row\n : { ...row, content: row.content?.map((cell) => ({ ...cell, type: \"tableHeader\" })) }\n )\n };\n case \"tableRow\":\n return { type: \"tableRow\", content: children };\n case \"tableCell\":\n return { type: \"tableCell\", content: paragraphContent(children) };\n case \"definition\":\n return null;\n default:\n throw new ConversionError(`Unsupported Markdown syntax: ${node.type}`, context.path);\n }\n};\n\nexport { decodeMarkdown, paragraphContent };\nexport type { MarkdownNode };\n"],"mappings":"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"}
|
|
@@ -63,10 +63,12 @@ interface BaseConverterOptions {
|
|
|
63
63
|
as: "frontmatter";
|
|
64
64
|
key?: string;
|
|
65
65
|
};
|
|
66
|
-
/**
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
66
|
+
/**
|
|
67
|
+
* Omit properties by default, map labels and values to frontmatter (duplicate keys throw), or
|
|
68
|
+
* map each property to a self-closing element in its position. Imports with a mapping read both
|
|
69
|
+
* frontmatter and matching elements.
|
|
70
|
+
*/
|
|
71
|
+
properties?: "omit" | PropertyMapping;
|
|
70
72
|
/** Fragment mappings. Defaults to unwrapping content; unwrapped boundaries cannot be restored. */
|
|
71
73
|
fragments?: {
|
|
72
74
|
/** Fallback for fragments without a named mapping. Defaults to "unwrap". */
|
|
@@ -180,6 +182,12 @@ type FragmentMapping = "unwrap" | "omit" | {
|
|
|
180
182
|
as: "element";
|
|
181
183
|
name: string;
|
|
182
184
|
};
|
|
185
|
+
type PropertyMapping = {
|
|
186
|
+
as: "frontmatter";
|
|
187
|
+
} | {
|
|
188
|
+
as: "element";
|
|
189
|
+
name: string;
|
|
190
|
+
};
|
|
183
191
|
//#endregion
|
|
184
|
-
export { ImageReference as _, Converter as a, ImportFormatAdapter as b, DecodeHandlers as c, ExportConverter as d, ExportConverterOptions as f, HandlerResult as g, FragmentMapping as h, ConvertedAST as i, EncodeContext as l, FormatAdapter as m, ContentMark as n, ConverterOptions as o, ExportFormatAdapter as p, ContentNode as r, DecodeContext as s, Awaitable as t, EncodeHandlers as u, ImportConverter as v, ImportConverterOptions as y };
|
|
185
|
-
//# sourceMappingURL=types-
|
|
192
|
+
export { ImageReference as _, Converter as a, ImportFormatAdapter as b, DecodeHandlers as c, ExportConverter as d, ExportConverterOptions as f, HandlerResult as g, FragmentMapping as h, ConvertedAST as i, EncodeContext as l, FormatAdapter as m, ContentMark as n, ConverterOptions as o, ExportFormatAdapter as p, ContentNode as r, DecodeContext as s, Awaitable as t, EncodeHandlers as u, ImportConverter as v, PropertyMapping as x, ImportConverterOptions as y };
|
|
193
|
+
//# sourceMappingURL=types-DoSWxQAZ.d.ts.map
|
package/dist/html.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as Converter, f as ExportConverterOptions, i as ConvertedAST, m as FormatAdapter, o as ConverterOptions, r as ContentNode, y as ImportConverterOptions } from "./chunks/types-
|
|
1
|
+
import { a as Converter, f as ExportConverterOptions, i as ConvertedAST, m as FormatAdapter, o as ConverterOptions, r as ContentNode, y as ImportConverterOptions } from "./chunks/types-DoSWxQAZ.js";
|
|
2
2
|
import { Root, RootContent } from "hast";
|
|
3
3
|
//#region src/html.d.ts
|
|
4
4
|
type HTMLNode = Root | RootContent;
|
package/dist/html.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as element, c as textContent, i as ConversionError, l as textNode, s as lookup, t as createConverter, u as withMark } from "./chunks/core-
|
|
2
|
-
import { n as paragraphContent } from "./chunks/decode-
|
|
1
|
+
import { a as element, c as textContent, i as ConversionError, l as textNode, s as lookup, t as createConverter, u as withMark } from "./chunks/core-CJ7Hlymb.js";
|
|
2
|
+
import { n as paragraphContent } from "./chunks/decode-BJK_KI3W.js";
|
|
3
3
|
import { fromHtml } from "hast-util-from-html";
|
|
4
4
|
import { toHtml } from "hast-util-to-html";
|
|
5
5
|
//#region src/html.ts
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as ImageReference, a as Converter, b as ImportFormatAdapter, c as DecodeHandlers, d as ExportConverter, f as ExportConverterOptions, g as HandlerResult, h as FragmentMapping, i as ConvertedAST, l as EncodeContext, m as FormatAdapter, n as ContentMark, o as ConverterOptions, p as ExportFormatAdapter, r as ContentNode, s as DecodeContext, t as Awaitable, u as EncodeHandlers, v as ImportConverter, y as ImportConverterOptions } from "./chunks/types-
|
|
1
|
+
import { _ as ImageReference, a as Converter, b as ImportFormatAdapter, c as DecodeHandlers, d as ExportConverter, f as ExportConverterOptions, g as HandlerResult, h as FragmentMapping, i as ConvertedAST, l as EncodeContext, m as FormatAdapter, n as ContentMark, o as ConverterOptions, p as ExportFormatAdapter, r as ContentNode, s as DecodeContext, t as Awaitable, u as EncodeHandlers, v as ImportConverter, x as PropertyMapping, y as ImportConverterOptions } from "./chunks/types-DoSWxQAZ.js";
|
|
2
2
|
import { HeadingAnchor, getHeadingAnchors } from "./anchors.js";
|
|
3
3
|
//#region src/core.d.ts
|
|
4
4
|
/**
|
|
@@ -111,5 +111,5 @@ declare const publishedContentOptions: (page: PublishedImageContent, options?: I
|
|
|
111
111
|
imageURL: (node: ContentNode) => Promise<string>;
|
|
112
112
|
};
|
|
113
113
|
//#endregion
|
|
114
|
-
export { type Awaitable, type ContentMark, type ContentNode, ConversionError, type ConvertedAST, type Converter, type ConverterOptions, type DecodeContext, type DecodeHandlers, type EncodeContext, type EncodeHandlers, type ExportConverter, type ExportConverterOptions, type ExportFormatAdapter, type FormatAdapter, type FragmentMapping, type HandlerResult, type HeadingAnchor, type ImageAsset, type ImageReference, type ImageURLOptions, type ImportConverter, type ImportConverterOptions, type ImportFormatAdapter, type PublishedImageContent, createConverter, createExportConverter, createImageURLResolver, createImportConverter, element, getHeadingAnchors, publishedContentOptions, textContent, textNode, withMark };
|
|
114
|
+
export { type Awaitable, type ContentMark, type ContentNode, ConversionError, type ConvertedAST, type Converter, type ConverterOptions, type DecodeContext, type DecodeHandlers, type EncodeContext, type EncodeHandlers, type ExportConverter, type ExportConverterOptions, type ExportFormatAdapter, type FormatAdapter, type FragmentMapping, type HandlerResult, type HeadingAnchor, type ImageAsset, type ImageReference, type ImageURLOptions, type ImportConverter, type ImportConverterOptions, type ImportFormatAdapter, type PropertyMapping, type PublishedImageContent, createConverter, createExportConverter, createImageURLResolver, createImportConverter, element, getHeadingAnchors, publishedContentOptions, textContent, textNode, withMark };
|
|
115
115
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getHeadingAnchors } from "./anchors.js";
|
|
2
|
-
import { a as element, c as textContent, i as ConversionError, l as textNode, n as createExportConverter, r as createImportConverter, t as createConverter, u as withMark } from "./chunks/core-
|
|
2
|
+
import { a as element, c as textContent, i as ConversionError, l as textNode, n as createExportConverter, r as createImportConverter, t as createConverter, u as withMark } from "./chunks/core-CJ7Hlymb.js";
|
|
3
3
|
//#region src/images.ts
|
|
4
4
|
/**
|
|
5
5
|
* Create an async imageURL callback from published asset references.
|
package/dist/markdoc.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as Converter, f as ExportConverterOptions, i as ConvertedAST, m as FormatAdapter, o as ConverterOptions, r as ContentNode, y as ImportConverterOptions } from "./chunks/types-
|
|
1
|
+
import { a as Converter, f as ExportConverterOptions, i as ConvertedAST, m as FormatAdapter, o as ConverterOptions, r as ContentNode, y as ImportConverterOptions } from "./chunks/types-DoSWxQAZ.js";
|
|
2
2
|
import Markdoc from "@markdoc/markdoc";
|
|
3
3
|
//#region src/markdoc.d.ts
|
|
4
4
|
type MarkdocNode = InstanceType<typeof Markdoc.Ast.Node>;
|
package/dist/markdoc.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as element, c as textContent, i as ConversionError, l as textNode, o as isJSONValue, s as lookup, t as createConverter, u as withMark } from "./chunks/core-
|
|
2
|
-
import { n as paragraphContent } from "./chunks/decode-
|
|
1
|
+
import { a as element, c as textContent, i as ConversionError, l as textNode, o as isJSONValue, s as lookup, t as createConverter, u as withMark } from "./chunks/core-CJ7Hlymb.js";
|
|
2
|
+
import { n as paragraphContent } from "./chunks/decode-BJK_KI3W.js";
|
|
3
3
|
import { n as normalizeMarkdown, t as markdownStringifyOptions } from "./chunks/stringify-DdPaV2y4.js";
|
|
4
4
|
import { unified } from "unified";
|
|
5
5
|
import remarkStringify from "remark-stringify";
|
package/dist/markdown.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as Converter, f as ExportConverterOptions, i as ConvertedAST, m as FormatAdapter, o as ConverterOptions, r as ContentNode, y as ImportConverterOptions } from "./chunks/types-
|
|
1
|
+
import { a as Converter, f as ExportConverterOptions, i as ConvertedAST, m as FormatAdapter, o as ConverterOptions, r as ContentNode, y as ImportConverterOptions } from "./chunks/types-DoSWxQAZ.js";
|
|
2
2
|
import { t as MarkdownNode } from "./chunks/decode-BLP2Olia.js";
|
|
3
3
|
//#region src/markdown.d.ts
|
|
4
4
|
type MarkdownOptions = ConverterOptions<MarkdownNode>;
|
package/dist/markdown.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as createConverter } from "./chunks/core-
|
|
2
|
-
import { t as createMarkdownAdapter } from "./chunks/adapter-
|
|
1
|
+
import { t as createConverter } from "./chunks/core-CJ7Hlymb.js";
|
|
2
|
+
import { t as createMarkdownAdapter } from "./chunks/adapter-BlLPQGXb.js";
|
|
3
3
|
//#region src/markdown.ts
|
|
4
4
|
/** Markdown/GFM adapter for createConverter(), including its parser and node/mark mappings. */
|
|
5
5
|
const markdownAdapter = createMarkdownAdapter();
|
package/dist/mdx.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as Converter, f as ExportConverterOptions, i as ConvertedAST, m as FormatAdapter, o as ConverterOptions, r as ContentNode, y as ImportConverterOptions } from "./chunks/types-
|
|
1
|
+
import { a as Converter, f as ExportConverterOptions, i as ConvertedAST, m as FormatAdapter, o as ConverterOptions, r as ContentNode, y as ImportConverterOptions } from "./chunks/types-DoSWxQAZ.js";
|
|
2
2
|
import { t as MarkdownNode } from "./chunks/decode-BLP2Olia.js";
|
|
3
3
|
import { MdxJsxFlowElement } from "mdast-util-mdx-jsx";
|
|
4
4
|
//#region src/mdx.d.ts
|
package/dist/mdx.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as element, i as ConversionError, o as isJSONValue, t as createConverter } from "./chunks/core-
|
|
2
|
-
import { t as createMarkdownAdapter } from "./chunks/adapter-
|
|
1
|
+
import { a as element, i as ConversionError, o as isJSONValue, t as createConverter } from "./chunks/core-CJ7Hlymb.js";
|
|
2
|
+
import { t as createMarkdownAdapter } from "./chunks/adapter-BlLPQGXb.js";
|
|
3
3
|
import remarkMDX from "remark-mdx";
|
|
4
4
|
import { parseExpressionAt } from "acorn";
|
|
5
5
|
//#region src/static-expression.ts
|
package/dist/text.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { d as ExportConverter, f as ExportConverterOptions, i as ConvertedAST, p as ExportFormatAdapter, r as ContentNode } from "./chunks/types-
|
|
1
|
+
import { d as ExportConverter, f as ExportConverterOptions, i as ConvertedAST, p as ExportFormatAdapter, r as ContentNode } from "./chunks/types-DoSWxQAZ.js";
|
|
2
2
|
//#region src/text.d.ts
|
|
3
3
|
interface TextNode {
|
|
4
4
|
type: "text" | "root";
|
package/dist/text.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as textContent, i as ConversionError, n as createExportConverter } from "./chunks/core-
|
|
1
|
+
import { c as textContent, i as ConversionError, n as createExportConverter } from "./chunks/core-CJ7Hlymb.js";
|
|
2
2
|
//#region src/text.ts
|
|
3
3
|
const getText = (node) => node.value ?? (node.children || []).map(getText).join("");
|
|
4
4
|
/** Export-only plain-text adapter. Formatting is discarded; import methods are not provided. */
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"core-DC64ddB7.js","names":[],"sources":["../../src/utils.ts","../../src/frontmatter.ts","../../src/core.ts"],"sourcesContent":["import type { ContentMark, ContentNode, HandlerResult } from \"./types\";\n\n/** A conversion failure, optionally located at a child-index path in the source tree. */\nclass ConversionError extends Error {\n /**\n * @param message - Description of the unsupported content or invalid mapping.\n * @param path - Child indexes appended to the message; defaults to the document root.\n */\n constructor(\n message: string,\n readonly path: readonly number[] = []\n ) {\n super(`${message}${path.length ? ` at content[${path.join(\"][\")}]` : \"\"}`);\n this.name = \"ConversionError\";\n }\n}\n\nconst lookup = <T>(record: Record<string, T> | undefined, name: string): T | undefined => {\n return record && Object.hasOwn(record, name) ? record[name] : undefined;\n};\nconst array = <T>(value: HandlerResult<T>): T[] =>\n value === null ? [] : Array.isArray(value) ? value : [value];\n/**\n * Concatenate a node's descendant text without changing the source.\n * @param node - ProseMirror node to read.\n * @returns Raw text with no added block separators, markup, or hard-break replacement.\n */\nconst textContent = (node: ContentNode): string =>\n node.text ?? (node.content || []).map(textContent).join(\"\");\n/**\n * Create text content suitable for a node handler.\n * @param text - Literal text to include.\n * @returns One text node, or an empty array for an empty string.\n */\nconst textNode = (text: string): ContentNode[] => (text ? [{ type: \"text\", text }] : []);\n/**\n * Append a mark to all descendant text nodes without modifying the input nodes.\n * @param nodes - Content to mark. Existing marks are retained, including duplicates.\n * @param mark - Mark to append to each text node.\n * @returns Mapped nodes; unchanged leaf nodes and existing marks may retain their references.\n */\nconst withMark = (nodes: ContentNode[], mark: ContentMark): ContentNode[] =>\n nodes.map((node) => {\n if (node.type === \"text\") return { ...node, marks: [...(node.marks || []), mark] };\n\n return node.content ? { ...node, content: withMark(node.content, mark) } : node;\n });\nconst isJSONValue = (value: unknown): boolean => {\n if (value === null || typeof value === \"string\" || typeof value === \"boolean\") return true;\n if (typeof value === \"number\") return Number.isFinite(value);\n if (Array.isArray(value)) return value.every(isJSONValue);\n if (typeof value !== \"object\" || Object.getPrototypeOf(value) !== Object.prototype) return false;\n\n return Object.values(value).every(isJSONValue);\n};\n/**\n * Create an Andesine element node with static JSON properties and a source representation.\n * @param name - Element name, starting with a letter and containing letters, digits, _, ., or -.\n * @param props - Static JSON properties with valid attribute names; executable expressions are rejected.\n * @param content - Child nodes. The supplied content array is retained.\n * @param selfClosing - Whether the source uses a self-closing tag; defaults to true for empty content.\n * @returns A ProseMirror element node for use in import handlers.\n * @throws ConversionError for invalid names, property keys, or non-JSON property values.\n */\nconst element = (\n name: string,\n props: Record<string, unknown>,\n content: ContentNode[],\n selfClosing = !content.length\n): ContentNode => {\n if (!/^[A-Za-z][\\w.-]*$/.test(name) || !isJSONValue(props)) {\n throw new ConversionError(\"Elements require a valid name and static JSON properties\");\n }\n const attributes = Object.entries(props)\n .map(([key, value]) => {\n if (!/^[A-Za-z][\\w-]*$/.test(key))\n throw new ConversionError(`Invalid element property: ${key}`);\n\n return typeof value === \"string\"\n ? ` ${key}=${JSON.stringify(value)}`\n : ` ${key}={${JSON.stringify(value)}}`;\n })\n .join(\"\");\n\n return {\n type: \"element\",\n attrs: { name, props, selfClosing, source: `<${name}${attributes}${selfClosing ? \" /\" : \"\"}>` },\n ...(content.length ? { content } : {})\n };\n};\n\nexport { ConversionError, lookup, array, element, isJSONValue, textContent, textNode, withMark };\n","import { parseDocument, stringify } from \"yaml\";\nimport { ConversionError, isJSONValue } from \"./utils\";\n\nconst readFrontmatter = (\n source: string\n): { source: string; frontmatter: Record<string, unknown> } => {\n const match = /^(?:\\uFEFF)?---\\r?\\n([\\s\\S]*?)\\r?\\n---(?:\\r?\\n|$)/.exec(source);\n\n if (!match) return { source, frontmatter: {} };\n\n const document = parseDocument(match[1], { schema: \"core\", uniqueKeys: true });\n\n if (document.errors.length)\n throw new ConversionError(`Invalid frontmatter: ${document.errors[0].message}`);\n\n const value: unknown = document.toJS({ maxAliasCount: 100 });\n\n if (!value || Array.isArray(value) || typeof value !== \"object\" || !isJSONValue(value)) {\n throw new ConversionError(\"Frontmatter must contain an object with static JSON values\");\n }\n return { source: source.slice(match[0].length), frontmatter: value as Record<string, unknown> };\n};\nconst writeFrontmatter = (frontmatter: Record<string, unknown>, source: string): string => {\n return Object.keys(frontmatter).length\n ? `---\\n${stringify(frontmatter)}---\\n\\n${source}`\n : source;\n};\n\nexport { readFrontmatter, writeFrontmatter };\n","import { getHeadingAnchors } from \"./anchors\";\nimport { readFrontmatter, writeFrontmatter } from \"./frontmatter\";\nimport { array, ConversionError, lookup, textContent, textNode } from \"./utils\";\nimport type {\n ContentNode,\n ConvertedAST,\n Converter,\n ConverterOptions,\n DecodeContext,\n EncodeContext,\n ExportConverter,\n ExportConverterOptions,\n ExportFormatAdapter,\n ImportConverter,\n ImportConverterOptions,\n ImportFormatAdapter,\n FormatAdapter\n} from \"./types\";\n\n/**\n * Build an async export-only converter using the shared content mappings.\n *\n * @param adapter - Root builder, serializer, and export node/mark handlers. No import stubs are needed.\n * @param defaults - Reusable options. Per-call handler maps and named fragment mappings merge by key.\n * @returns Only encode() and toAST(), both async. Handlers and image callbacks may be async.\n * Import methods are absent at runtime and in TypeScript. No content is saved.\n * Unsupported nodes and marks are handled by the adapter, usually by throwing ConversionError.\n * Defaults render titles as H1s, unwrap fragments, and omit properties. Removed boundaries and\n * omitted data cannot be recovered on import; choose explicit mappings when preservation matters.\n */\nconst createExportConverter = <T>(\n adapter: ExportFormatAdapter<T>,\n defaults: ExportConverterOptions<T> = {}\n): ExportConverter<T> => {\n const toAST = async (\n document: ContentNode,\n options: ExportConverterOptions<T> = {}\n ): Promise<ConvertedAST<T>> => {\n const settings = mergeOptions(defaults, options);\n const anchors = new Map(\n getHeadingAnchors(document).map((heading) => [heading.path.join(\".\"), heading.anchor])\n );\n const frontmatter: Record<string, unknown> = Object.create(null);\n const encode = async (node: ContentNode, path: readonly number[]): Promise<T[]> => {\n // Code handlers consume plain text, so code must be the innermost mark.\n const marks = [...(node.marks || [])].sort(\n (first, second) => Number(first.type === \"code\") - Number(second.type === \"code\")\n );\n const context: EncodeContext<T> = {\n anchor: node.type === \"heading\" ? anchors.get(path.join(\".\")) : undefined,\n options: settings,\n path,\n encode: (child) => encode(child, path),\n children: async (parent) => {\n const children: T[] = [];\n\n for (const [index, child] of (parent.content || []).entries())\n children.push(...(await encode(child, [...path, index])));\n return children;\n },\n imageURL: async (image) => {\n const url = await settings.imageURL?.(image);\n\n if (!url)\n throw new ConversionError(\"An imageURL callback must resolve the image asset\", path);\n return url;\n }\n };\n const handlers = settings.encode;\n const elementName = node.type === \"element\" ? String(node.attrs?.name || \"\") : undefined;\n const handler = elementName\n ? (lookup(handlers?.elements, elementName) ??\n lookup(handlers?.elements, \"*\") ??\n lookup(handlers?.nodes, \"element\") ??\n lookup(handlers?.nodes, \"*\"))\n : (lookup(handlers?.nodes, node.type) ?? lookup(handlers?.nodes, \"*\"));\n let result: T[];\n\n if (handler) {\n result = array(await handler(node, context));\n } else if (node.type === \"doc\") {\n result = await context.children(node);\n } else if (node.type === \"title\") {\n const title = settings.title ?? \"heading\";\n\n if (title === \"omit\") return [];\n if (typeof title === \"object\") {\n setMetadata(frontmatter, title.key || \"title\", textContent(node));\n return [];\n }\n result = array(\n await adapter.encode({ ...node, type: \"heading\", attrs: { level: 1 } }, context)\n );\n } else if (node.type === \"property\") {\n if (settings.properties !== undefined && settings.properties !== \"omit\") {\n const name = String(node.attrs?.label || \"Property\");\n const value = node.attrs?.value ?? \"\";\n const normalized =\n node.attrs?.type === \"number\" ? (value === \"\" ? null : Number(value)) : value;\n\n setMetadata(frontmatter, name, normalized);\n }\n return [];\n } else if (node.type === \"fragment\") {\n const name = String(node.attrs?.name || \"Content\");\n const mapping =\n lookup(settings.fragments?.named, name) ?? settings.fragments?.default ?? \"unwrap\";\n\n if (mapping === \"omit\") return [];\n if (mapping === \"unwrap\") return context.children(node);\n\n result = await context.encode({\n type: \"element\",\n attrs: { name: mapping.name, props: { name }, selfClosing: false },\n content: node.content\n });\n } else {\n result = array(await adapter.encode(node, context));\n }\n if (!result.length) return result;\n\n for (const mark of marks.reverse()) {\n const handler = lookup(handlers?.marks, mark.type) ?? lookup(handlers?.marks, \"*\");\n\n result = array(\n await (handler ? handler(mark, result, context) : adapter.mark(mark, result, context))\n );\n }\n return result;\n };\n const children = await encode(document, []);\n\n if (!adapter.frontmatter && Object.keys(frontmatter).length)\n throw new ConversionError(`${adapter.name} does not support frontmatter`);\n\n return { tree: adapter.root(children), frontmatter };\n };\n\n return {\n toAST,\n async encode(document: ContentNode, options?: ExportConverterOptions<T>): Promise<string> {\n const result = await toAST(document, options);\n\n return writeFrontmatter(result.frontmatter, await adapter.stringify(result.tree));\n }\n };\n};\n\n/**\n * Build an async import-only converter using the shared content mappings.\n *\n * @param adapter - Parser, decode handler, and node-type lookup. No export stubs are needed.\n * @param defaults - Reusable import mappings and handlers, merged by key with per-call overrides.\n * @returns Only decode() and fromAST(), both async. Parsers, handlers, and image callbacks may\n * be async. Export methods are absent at runtime and in TypeScript. No content is saved.\n * Imports create an entry with a title by default; document: \"fragment\" retains headings as body\n * content. Unsupported input is handled by the adapter; parser and handler errors pass through.\n */\nconst createImportConverter = <T>(\n adapter: ImportFormatAdapter<T>,\n defaults: ImportConverterOptions<T> = {}\n): ImportConverter<T> => {\n const fromAST = async (\n input: ConvertedAST<T>,\n options: ImportConverterOptions<T> = {}\n ): Promise<ContentNode> => {\n const settings = mergeOptions(defaults, options);\n const decode = async (node: T, path: readonly number[]): Promise<ContentNode[]> => {\n const context: DecodeContext<T> = {\n options: settings,\n path,\n decode: (child) => decode(child, path),\n children: async (children) => {\n const output: ContentNode[] = [];\n\n for (const [index, child] of children.entries())\n output.push(...(await decode(child, [...path, index])));\n return output;\n },\n image: async (image) => {\n const assetID = await settings.imageAssetID?.(image);\n\n if (!assetID)\n throw new ConversionError(\"An imageAssetID callback must resolve the image URL\", path);\n return { type: \"image\", attrs: { assetID, alt: image.alt, caption: image.title || \"\" } };\n }\n };\n const handlers = settings.decode;\n const type = adapter.type(node);\n const name = adapter.elementName?.(node);\n const mark = adapter.markName?.(node);\n const handler =\n (name\n ? (lookup(handlers?.elements, name) ?? lookup(handlers?.elements, \"*\"))\n : undefined) ??\n (mark ? (lookup(handlers?.marks, mark) ?? lookup(handlers?.marks, \"*\")) : undefined) ??\n lookup(handlers?.nodes, type) ??\n lookup(handlers?.nodes, \"*\");\n const result = array(\n await (handler ? handler(node, context) : adapter.decode(node, context))\n );\n\n return result.flatMap((content) => {\n if (content.type !== \"element\") return [content];\n\n const props = content.attrs?.props as Record<string, unknown> | undefined;\n const fragmentName = typeof props?.name === \"string\" ? props.name : undefined;\n const mapping = fragmentName\n ? (lookup(settings.fragments?.named, fragmentName) ?? settings.fragments?.default)\n : undefined;\n\n if (mapping && typeof mapping === \"object\" && mapping.name === content.attrs?.name) {\n return [\n {\n type: \"fragment\",\n attrs: { name: fragmentName },\n content: content.content || [{ type: \"paragraph\" }]\n }\n ];\n }\n return [content];\n });\n };\n const content = await decode(input.tree, []);\n const title = settings.title ?? \"heading\";\n const titleKey = typeof title === \"object\" ? title.key || \"title\" : undefined;\n const properties: ContentNode[] = [];\n let titleText = \"\";\n\n if (titleKey && input.frontmatter[titleKey] !== undefined)\n titleText = String(input.frontmatter[titleKey]);\n if (\n title === \"heading\" &&\n settings.document !== \"fragment\" &&\n content[0]?.type === \"heading\" &&\n content[0].attrs?.level === 1\n ) {\n titleText = textContent(content.shift()!);\n }\n if (settings.properties && settings.properties !== \"omit\") {\n for (const [label, value] of Object.entries(input.frontmatter)) {\n if (label === titleKey) continue;\n\n const type =\n typeof value === \"number\"\n ? \"number\"\n : typeof value === \"boolean\"\n ? \"checkbox\"\n : Array.isArray(value) && value.every((item) => typeof item === \"string\")\n ? \"multi-select\"\n : \"text\";\n\n if (type === \"text\" && value !== null && typeof value !== \"string\")\n throw new ConversionError(`Property ${label} cannot represent this frontmatter value`);\n\n properties.push({ type: \"property\", attrs: { label, type, value: value ?? \"\" } });\n }\n }\n const body: ContentNode[] = settings.targetFragment\n ? [\n {\n type: \"fragment\",\n attrs: { name: settings.targetFragment },\n content: content.length ? content : [{ type: \"paragraph\" }]\n }\n ]\n : content;\n\n return {\n type: \"doc\",\n content: [\n ...(settings.document === \"fragment\"\n ? []\n : [{ type: \"title\", content: textNode(titleText) }]),\n ...properties,\n ...(body.length ? body : [{ type: \"paragraph\" }])\n ]\n };\n };\n\n return {\n fromAST,\n async decode(source: string, options?: ImportConverterOptions<T>): Promise<ContentNode> {\n const input = adapter.frontmatter ? readFrontmatter(source) : { source, frontmatter: {} };\n\n return fromAST(\n { tree: await adapter.parse(input.source), frontmatter: input.frontmatter },\n options\n );\n }\n };\n};\n\n/**\n * Build an async converter for a custom format that supports both import and export.\n *\n * @param adapter - Full adapter with parser, serializer, and mappings for both directions.\n * @param defaults - Shared defaults and direction-specific handlers. Per-call maps merge by key.\n * @returns encode(), toAST(), decode(), and fromAST(), composed from the one-way factories.\n * Each method accepts options for its own direction. No content is saved or uploaded.\n * Defaults render titles as H1s, unwrap fragments, and omit properties. Removed boundaries and\n * omitted data cannot be recovered on import; choose explicit mappings when preservation matters.\n */\nconst createConverter = <T>(\n adapter: FormatAdapter<T>,\n defaults: ConverterOptions<T> = {}\n): Converter<T> => ({\n ...createExportConverter(adapter, defaults),\n ...createImportConverter(adapter, defaults)\n});\nconst setMetadata = (metadata: Record<string, unknown>, key: string, value: unknown): void => {\n if (Object.hasOwn(metadata, key))\n throw new ConversionError(`Duplicate frontmatter field: ${key}`);\n\n metadata[key] = value;\n};\nconst mergeOptions = <T>(\n defaults: ConverterOptions<T>,\n options: ConverterOptions<T>\n): ConverterOptions<T> => ({\n ...defaults,\n ...options,\n fragments: {\n ...defaults.fragments,\n ...options.fragments,\n named: { ...defaults.fragments?.named, ...options.fragments?.named }\n },\n encode: {\n nodes: { ...defaults.encode?.nodes, ...options.encode?.nodes },\n marks: { ...defaults.encode?.marks, ...options.encode?.marks },\n elements: { ...defaults.encode?.elements, ...options.encode?.elements }\n },\n decode: {\n nodes: { ...defaults.decode?.nodes, ...options.decode?.nodes },\n marks: { ...defaults.decode?.marks, ...options.decode?.marks },\n elements: { ...defaults.decode?.elements, ...options.decode?.elements }\n }\n});\n\nexport { createConverter, createExportConverter, createImportConverter };\n"],"mappings":";;;;AAGA,IAAM,kBAAN,cAA8B,MAAM;CAOvB;;;;;CAFX,YACE,SACA,OAAmC,CAAC,GACpC;EACA,MAAM,GAAG,UAAU,KAAK,SAAS,eAAe,KAAK,KAAK,IAAI,EAAE,KAAK,IAAI;EAFhE,KAAA,OAAA;EAGT,KAAK,OAAO;CACd;AACF;AAEA,MAAM,UAAa,QAAuC,SAAgC;CACxF,OAAO,UAAU,OAAO,OAAO,QAAQ,IAAI,IAAI,OAAO,QAAQ,KAAA;AAChE;AACA,MAAM,SAAY,UAChB,UAAU,OAAO,CAAC,IAAI,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;;;;;;AAM7D,MAAM,eAAe,SACnB,KAAK,SAAS,KAAK,WAAW,CAAC,EAAA,CAAG,IAAI,WAAW,CAAC,CAAC,KAAK,EAAE;;;;;;AAM5D,MAAM,YAAY,SAAiC,OAAO,CAAC;CAAE,MAAM;CAAQ;AAAK,CAAC,IAAI,CAAC;;;;;;;AAOtF,MAAM,YAAY,OAAsB,SACtC,MAAM,KAAK,SAAS;CAClB,IAAI,KAAK,SAAS,QAAQ,OAAO;EAAE,GAAG;EAAM,OAAO,CAAC,GAAI,KAAK,SAAS,CAAC,GAAI,IAAI;CAAE;CAEjF,OAAO,KAAK,UAAU;EAAE,GAAG;EAAM,SAAS,SAAS,KAAK,SAAS,IAAI;CAAE,IAAI;AAC7E,CAAC;AACH,MAAM,eAAe,UAA4B;CAC/C,IAAI,UAAU,QAAQ,OAAO,UAAU,YAAY,OAAO,UAAU,WAAW,OAAO;CACtF,IAAI,OAAO,UAAU,UAAU,OAAO,OAAO,SAAS,KAAK;CAC3D,IAAI,MAAM,QAAQ,KAAK,GAAG,OAAO,MAAM,MAAM,WAAW;CACxD,IAAI,OAAO,UAAU,YAAY,OAAO,eAAe,KAAK,MAAM,OAAO,WAAW,OAAO;CAE3F,OAAO,OAAO,OAAO,KAAK,CAAC,CAAC,MAAM,WAAW;AAC/C;;;;;;;;;;AAUA,MAAM,WACJ,MACA,OACA,SACA,cAAc,CAAC,QAAQ,WACP;CAChB,IAAI,CAAC,oBAAoB,KAAK,IAAI,KAAK,CAAC,YAAY,KAAK,GACvD,MAAM,IAAI,gBAAgB,0DAA0D;CAatF,OAAO;EACL,MAAM;EACN,OAAO;GAAE;GAAM;GAAO;GAAa,QAAQ,IAAI,OAb9B,OAAO,QAAQ,KAAK,CAAC,CACrC,KAAK,CAAC,KAAK,WAAW;IACrB,IAAI,CAAC,mBAAmB,KAAK,GAAG,GAC9B,MAAM,IAAI,gBAAgB,6BAA6B,KAAK;IAE9D,OAAO,OAAO,UAAU,WACpB,IAAI,IAAI,GAAG,KAAK,UAAU,KAAK,MAC/B,IAAI,IAAI,IAAI,KAAK,UAAU,KAAK,EAAE;GACxC,CAAC,CAAC,CACD,KAAK,EAIyD,IAAI,cAAc,OAAO,GAAG;EAAG;EAC9F,GAAI,QAAQ,SAAS,EAAE,QAAQ,IAAI,CAAC;CACtC;AACF;;;ACtFA,MAAM,mBACJ,WAC6D;CAC7D,MAAM,QAAQ,oDAAoD,KAAK,MAAM;CAE7E,IAAI,CAAC,OAAO,OAAO;EAAE;EAAQ,aAAa,CAAC;CAAE;CAE7C,MAAM,WAAW,cAAc,MAAM,IAAI;EAAE,QAAQ;EAAQ,YAAY;CAAK,CAAC;CAE7E,IAAI,SAAS,OAAO,QAClB,MAAM,IAAI,gBAAgB,wBAAwB,SAAS,OAAO,EAAE,CAAC,SAAS;CAEhF,MAAM,QAAiB,SAAS,KAAK,EAAE,eAAe,IAAI,CAAC;CAE3D,IAAI,CAAC,SAAS,MAAM,QAAQ,KAAK,KAAK,OAAO,UAAU,YAAY,CAAC,YAAY,KAAK,GACnF,MAAM,IAAI,gBAAgB,4DAA4D;CAExF,OAAO;EAAE,QAAQ,OAAO,MAAM,MAAM,EAAE,CAAC,MAAM;EAAG,aAAa;CAAiC;AAChG;AACA,MAAM,oBAAoB,aAAsC,WAA2B;CACzF,OAAO,OAAO,KAAK,WAAW,CAAC,CAAC,SAC5B,QAAQ,UAAU,WAAW,EAAE,SAAS,WACxC;AACN;;;;;;;;;;;;;;ACIA,MAAM,yBACJ,SACA,WAAsC,CAAC,MAChB;CACvB,MAAM,QAAQ,OACZ,UACA,UAAqC,CAAC,MACT;EAC7B,MAAM,WAAW,aAAa,UAAU,OAAO;EAC/C,MAAM,UAAU,IAAI,IAClB,kBAAkB,QAAQ,CAAC,CAAC,KAAK,YAAY,CAAC,QAAQ,KAAK,KAAK,GAAG,GAAG,QAAQ,MAAM,CAAC,CACvF;EACA,MAAM,cAAuC,OAAO,OAAO,IAAI;EAC/D,MAAM,SAAS,OAAO,MAAmB,SAA0C;GAEjF,MAAM,QAAQ,CAAC,GAAI,KAAK,SAAS,CAAC,CAAE,CAAC,CAAC,MACnC,OAAO,WAAW,OAAO,MAAM,SAAS,MAAM,IAAI,OAAO,OAAO,SAAS,MAAM,CAClF;GACA,MAAM,UAA4B;IAChC,QAAQ,KAAK,SAAS,YAAY,QAAQ,IAAI,KAAK,KAAK,GAAG,CAAC,IAAI,KAAA;IAChE,SAAS;IACT;IACA,SAAS,UAAU,OAAO,OAAO,IAAI;IACrC,UAAU,OAAO,WAAW;KAC1B,MAAM,WAAgB,CAAC;KAEvB,KAAK,MAAM,CAAC,OAAO,WAAW,OAAO,WAAW,CAAC,EAAA,CAAG,QAAQ,GAC1D,SAAS,KAAK,GAAI,MAAM,OAAO,OAAO,CAAC,GAAG,MAAM,KAAK,CAAC,CAAE;KAC1D,OAAO;IACT;IACA,UAAU,OAAO,UAAU;KACzB,MAAM,MAAM,MAAM,SAAS,WAAW,KAAK;KAE3C,IAAI,CAAC,KACH,MAAM,IAAI,gBAAgB,qDAAqD,IAAI;KACrF,OAAO;IACT;GACF;GACA,MAAM,WAAW,SAAS;GAC1B,MAAM,cAAc,KAAK,SAAS,YAAY,OAAO,KAAK,OAAO,QAAQ,EAAE,IAAI,KAAA;GAC/E,MAAM,UAAU,cACX,OAAO,UAAU,UAAU,WAAW,KACvC,OAAO,UAAU,UAAU,GAAG,KAC9B,OAAO,UAAU,OAAO,SAAS,KACjC,OAAO,UAAU,OAAO,GAAG,IAC1B,OAAO,UAAU,OAAO,KAAK,IAAI,KAAK,OAAO,UAAU,OAAO,GAAG;GACtE,IAAI;GAEJ,IAAI,SACF,SAAS,MAAM,MAAM,QAAQ,MAAM,OAAO,CAAC;QACtC,IAAI,KAAK,SAAS,OACvB,SAAS,MAAM,QAAQ,SAAS,IAAI;QAC/B,IAAI,KAAK,SAAS,SAAS;IAChC,MAAM,QAAQ,SAAS,SAAS;IAEhC,IAAI,UAAU,QAAQ,OAAO,CAAC;IAC9B,IAAI,OAAO,UAAU,UAAU;KAC7B,YAAY,aAAa,MAAM,OAAO,SAAS,YAAY,IAAI,CAAC;KAChE,OAAO,CAAC;IACV;IACA,SAAS,MACP,MAAM,QAAQ,OAAO;KAAE,GAAG;KAAM,MAAM;KAAW,OAAO,EAAE,OAAO,EAAE;IAAE,GAAG,OAAO,CACjF;GACF,OAAO,IAAI,KAAK,SAAS,YAAY;IACnC,IAAI,SAAS,eAAe,KAAA,KAAa,SAAS,eAAe,QAAQ;KACvE,MAAM,OAAO,OAAO,KAAK,OAAO,SAAS,UAAU;KACnD,MAAM,QAAQ,KAAK,OAAO,SAAS;KACnC,MAAM,aACJ,KAAK,OAAO,SAAS,WAAY,UAAU,KAAK,OAAO,OAAO,KAAK,IAAK;KAE1E,YAAY,aAAa,MAAM,UAAU;IAC3C;IACA,OAAO,CAAC;GACV,OAAO,IAAI,KAAK,SAAS,YAAY;IACnC,MAAM,OAAO,OAAO,KAAK,OAAO,QAAQ,SAAS;IACjD,MAAM,UACJ,OAAO,SAAS,WAAW,OAAO,IAAI,KAAK,SAAS,WAAW,WAAW;IAE5E,IAAI,YAAY,QAAQ,OAAO,CAAC;IAChC,IAAI,YAAY,UAAU,OAAO,QAAQ,SAAS,IAAI;IAEtD,SAAS,MAAM,QAAQ,OAAO;KAC5B,MAAM;KACN,OAAO;MAAE,MAAM,QAAQ;MAAM,OAAO,EAAE,KAAK;MAAG,aAAa;KAAM;KACjE,SAAS,KAAK;IAChB,CAAC;GACH,OACE,SAAS,MAAM,MAAM,QAAQ,OAAO,MAAM,OAAO,CAAC;GAEpD,IAAI,CAAC,OAAO,QAAQ,OAAO;GAE3B,KAAK,MAAM,QAAQ,MAAM,QAAQ,GAAG;IAClC,MAAM,UAAU,OAAO,UAAU,OAAO,KAAK,IAAI,KAAK,OAAO,UAAU,OAAO,GAAG;IAEjF,SAAS,MACP,OAAO,UAAU,QAAQ,MAAM,QAAQ,OAAO,IAAI,QAAQ,KAAK,MAAM,QAAQ,OAAO,EACtF;GACF;GACA,OAAO;EACT;EACA,MAAM,WAAW,MAAM,OAAO,UAAU,CAAC,CAAC;EAE1C,IAAI,CAAC,QAAQ,eAAe,OAAO,KAAK,WAAW,CAAC,CAAC,QACnD,MAAM,IAAI,gBAAgB,GAAG,QAAQ,KAAK,8BAA8B;EAE1E,OAAO;GAAE,MAAM,QAAQ,KAAK,QAAQ;GAAG;EAAY;CACrD;CAEA,OAAO;EACL;EACA,MAAM,OAAO,UAAuB,SAAsD;GACxF,MAAM,SAAS,MAAM,MAAM,UAAU,OAAO;GAE5C,OAAO,iBAAiB,OAAO,aAAa,MAAM,QAAQ,UAAU,OAAO,IAAI,CAAC;EAClF;CACF;AACF;;;;;;;;;;;AAYA,MAAM,yBACJ,SACA,WAAsC,CAAC,MAChB;CACvB,MAAM,UAAU,OACd,OACA,UAAqC,CAAC,MACb;EACzB,MAAM,WAAW,aAAa,UAAU,OAAO;EAC/C,MAAM,SAAS,OAAO,MAAS,SAAoD;GACjF,MAAM,UAA4B;IAChC,SAAS;IACT;IACA,SAAS,UAAU,OAAO,OAAO,IAAI;IACrC,UAAU,OAAO,aAAa;KAC5B,MAAM,SAAwB,CAAC;KAE/B,KAAK,MAAM,CAAC,OAAO,UAAU,SAAS,QAAQ,GAC5C,OAAO,KAAK,GAAI,MAAM,OAAO,OAAO,CAAC,GAAG,MAAM,KAAK,CAAC,CAAE;KACxD,OAAO;IACT;IACA,OAAO,OAAO,UAAU;KACtB,MAAM,UAAU,MAAM,SAAS,eAAe,KAAK;KAEnD,IAAI,CAAC,SACH,MAAM,IAAI,gBAAgB,uDAAuD,IAAI;KACvF,OAAO;MAAE,MAAM;MAAS,OAAO;OAAE;OAAS,KAAK,MAAM;OAAK,SAAS,MAAM,SAAS;MAAG;KAAE;IACzF;GACF;GACA,MAAM,WAAW,SAAS;GAC1B,MAAM,OAAO,QAAQ,KAAK,IAAI;GAC9B,MAAM,OAAO,QAAQ,cAAc,IAAI;GACvC,MAAM,OAAO,QAAQ,WAAW,IAAI;GACpC,MAAM,WACH,OACI,OAAO,UAAU,UAAU,IAAI,KAAK,OAAO,UAAU,UAAU,GAAG,IACnE,KAAA,OACH,OAAQ,OAAO,UAAU,OAAO,IAAI,KAAK,OAAO,UAAU,OAAO,GAAG,IAAK,KAAA,MAC1E,OAAO,UAAU,OAAO,IAAI,KAC5B,OAAO,UAAU,OAAO,GAAG;GAK7B,OAJe,MACb,OAAO,UAAU,QAAQ,MAAM,OAAO,IAAI,QAAQ,OAAO,MAAM,OAAO,EAG5D,CAAC,CAAC,SAAS,YAAY;IACjC,IAAI,QAAQ,SAAS,WAAW,OAAO,CAAC,OAAO;IAE/C,MAAM,QAAQ,QAAQ,OAAO;IAC7B,MAAM,eAAe,OAAO,OAAO,SAAS,WAAW,MAAM,OAAO,KAAA;IACpE,MAAM,UAAU,eACX,OAAO,SAAS,WAAW,OAAO,YAAY,KAAK,SAAS,WAAW,UACxE,KAAA;IAEJ,IAAI,WAAW,OAAO,YAAY,YAAY,QAAQ,SAAS,QAAQ,OAAO,MAC5E,OAAO,CACL;KACE,MAAM;KACN,OAAO,EAAE,MAAM,aAAa;KAC5B,SAAS,QAAQ,WAAW,CAAC,EAAE,MAAM,YAAY,CAAC;IACpD,CACF;IAEF,OAAO,CAAC,OAAO;GACjB,CAAC;EACH;EACA,MAAM,UAAU,MAAM,OAAO,MAAM,MAAM,CAAC,CAAC;EAC3C,MAAM,QAAQ,SAAS,SAAS;EAChC,MAAM,WAAW,OAAO,UAAU,WAAW,MAAM,OAAO,UAAU,KAAA;EACpE,MAAM,aAA4B,CAAC;EACnC,IAAI,YAAY;EAEhB,IAAI,YAAY,MAAM,YAAY,cAAc,KAAA,GAC9C,YAAY,OAAO,MAAM,YAAY,SAAS;EAChD,IACE,UAAU,aACV,SAAS,aAAa,cACtB,QAAQ,EAAE,EAAE,SAAS,aACrB,QAAQ,EAAE,CAAC,OAAO,UAAU,GAE5B,YAAY,YAAY,QAAQ,MAAM,CAAE;EAE1C,IAAI,SAAS,cAAc,SAAS,eAAe,QACjD,KAAK,MAAM,CAAC,OAAO,UAAU,OAAO,QAAQ,MAAM,WAAW,GAAG;GAC9D,IAAI,UAAU,UAAU;GAExB,MAAM,OACJ,OAAO,UAAU,WACb,WACA,OAAO,UAAU,YACf,aACA,MAAM,QAAQ,KAAK,KAAK,MAAM,OAAO,SAAS,OAAO,SAAS,QAAQ,IACpE,iBACA;GAEV,IAAI,SAAS,UAAU,UAAU,QAAQ,OAAO,UAAU,UACxD,MAAM,IAAI,gBAAgB,YAAY,MAAM,yCAAyC;GAEvF,WAAW,KAAK;IAAE,MAAM;IAAY,OAAO;KAAE;KAAO;KAAM,OAAO,SAAS;IAAG;GAAE,CAAC;EAClF;EAEF,MAAM,OAAsB,SAAS,iBACjC,CACE;GACE,MAAM;GACN,OAAO,EAAE,MAAM,SAAS,eAAe;GACvC,SAAS,QAAQ,SAAS,UAAU,CAAC,EAAE,MAAM,YAAY,CAAC;EAC5D,CACF,IACA;EAEJ,OAAO;GACL,MAAM;GACN,SAAS;IACP,GAAI,SAAS,aAAa,aACtB,CAAC,IACD,CAAC;KAAE,MAAM;KAAS,SAAS,SAAS,SAAS;IAAE,CAAC;IACpD,GAAG;IACH,GAAI,KAAK,SAAS,OAAO,CAAC,EAAE,MAAM,YAAY,CAAC;GACjD;EACF;CACF;CAEA,OAAO;EACL;EACA,MAAM,OAAO,QAAgB,SAA2D;GACtF,MAAM,QAAQ,QAAQ,cAAc,gBAAgB,MAAM,IAAI;IAAE;IAAQ,aAAa,CAAC;GAAE;GAExF,OAAO,QACL;IAAE,MAAM,MAAM,QAAQ,MAAM,MAAM,MAAM;IAAG,aAAa,MAAM;GAAY,GAC1E,OACF;EACF;CACF;AACF;;;;;;;;;;;AAYA,MAAM,mBACJ,SACA,WAAgC,CAAC,OACf;CAClB,GAAG,sBAAsB,SAAS,QAAQ;CAC1C,GAAG,sBAAsB,SAAS,QAAQ;AAC5C;AACA,MAAM,eAAe,UAAmC,KAAa,UAAyB;CAC5F,IAAI,OAAO,OAAO,UAAU,GAAG,GAC7B,MAAM,IAAI,gBAAgB,gCAAgC,KAAK;CAEjE,SAAS,OAAO;AAClB;AACA,MAAM,gBACJ,UACA,aACyB;CACzB,GAAG;CACH,GAAG;CACH,WAAW;EACT,GAAG,SAAS;EACZ,GAAG,QAAQ;EACX,OAAO;GAAE,GAAG,SAAS,WAAW;GAAO,GAAG,QAAQ,WAAW;EAAM;CACrE;CACA,QAAQ;EACN,OAAO;GAAE,GAAG,SAAS,QAAQ;GAAO,GAAG,QAAQ,QAAQ;EAAM;EAC7D,OAAO;GAAE,GAAG,SAAS,QAAQ;GAAO,GAAG,QAAQ,QAAQ;EAAM;EAC7D,UAAU;GAAE,GAAG,SAAS,QAAQ;GAAU,GAAG,QAAQ,QAAQ;EAAS;CACxE;CACA,QAAQ;EACN,OAAO;GAAE,GAAG,SAAS,QAAQ;GAAO,GAAG,QAAQ,QAAQ;EAAM;EAC7D,OAAO;GAAE,GAAG,SAAS,QAAQ;GAAO,GAAG,QAAQ,QAAQ;EAAM;EAC7D,UAAU;GAAE,GAAG,SAAS,QAAQ;GAAU,GAAG,QAAQ,QAAQ;EAAS;CACxE;AACF"}
|