//#region src/render.ts
const renderers = /* @__PURE__ */ new Map();
/**
* Register a custom renderer for a format.
*
* @example
* ```ts
* registerRenderer('thermal', {
*   render(node, options) {
*     // Walk nodes → ESC/POS commands
*     return escPosBuffer
*   },
* })
*
* await render(receipt, 'thermal')
* ```
*/
function registerRenderer(format, renderer) {
	renderers.set(format, renderer);
}
/**
* Remove a registered renderer.
*/
function unregisterRenderer(format) {
	renderers.delete(format);
}
registerRenderer("html", () => import("./html-B5biprN2.js").then((m) => m.htmlRenderer));
registerRenderer("email", () => import("./email-D0bbfWq4.js").then((m) => m.emailRenderer));
registerRenderer("md", () => import("./markdown-CdtlFGC0.js").then((m) => m.markdownRenderer));
registerRenderer("text", () => import("./text-l1XNXBOC.js").then((m) => m.textRenderer));
registerRenderer("csv", () => import("./csv-COrS4qdy.js").then((m) => m.csvRenderer));
registerRenderer("pdf", () => import("./pdf-IuBgTb3T.js").then((m) => m.pdfRenderer));
registerRenderer("docx", () => import("./docx-uNAel545.js").then((m) => m.docxRenderer));
registerRenderer("xlsx", () => import("./xlsx-Cvu4LBNy.js").then((m) => m.xlsxRenderer));
registerRenderer("pptx", () => import("./pptx-DXiMiYFM.js").then((m) => m.pptxRenderer));
registerRenderer("slack", () => import("./slack-BI3EQwYm.js").then((m) => m.slackRenderer));
registerRenderer("svg", () => import("./svg-BKxumy-p.js").then((m) => m.svgRenderer));
registerRenderer("teams", () => import("./teams-Cwz9lce0.js").then((m) => m.teamsRenderer));
registerRenderer("discord", () => import("./discord-BLUnkEh9.js").then((m) => m.discordRenderer));
registerRenderer("telegram", () => import("./telegram-gYFqyMXb.js").then((m) => m.telegramRenderer));
registerRenderer("notion", () => import("./notion-iG2C5bEY.js").then((m) => m.notionRenderer));
registerRenderer("confluence", () => import("./confluence-Bd3ua1Ut.js").then((m) => m.confluenceRenderer));
registerRenderer("whatsapp", () => import("./whatsapp-CjSGoOKx.js").then((m) => m.whatsappRenderer));
registerRenderer("google-chat", () => import("./google-chat-CkKCBUWC.js").then((m) => m.googleChatRenderer));
async function resolveRenderer(format) {
	const entry = renderers.get(format);
	if (!entry) throw new Error(`[@pyreon/document] No renderer registered for format '${format}'. Available: ${[...renderers.keys()].join(", ")}`);
	if (typeof entry === "function") {
		const renderer = await entry();
		renderers.set(format, renderer);
		return renderer;
	}
	return entry;
}
/**
* Render a document node tree to the specified format.
*
* @example
* ```tsx
* const doc = <Document title="Report"><Page>...</Page></Document>
*
* const html = await render(doc, 'html')    // → HTML string
* const pdf = await render(doc, 'pdf')      // → PDF Uint8Array
* const docx = await render(doc, 'docx')    // → DOCX Uint8Array
* const email = await render(doc, 'email')  // → email-safe HTML string
* const md = await render(doc, 'md')        // → Markdown string
* ```
*/
async function render(node, format, options) {
	return (await resolveRenderer(format)).render(node, options);
}
/** @internal For testing — reset renderer registry to defaults. */
function _resetRenderers() {
	renderers.clear();
	registerRenderer("html", () => import("./html-B5biprN2.js").then((m) => m.htmlRenderer));
	registerRenderer("email", () => import("./email-D0bbfWq4.js").then((m) => m.emailRenderer));
	registerRenderer("md", () => import("./markdown-CdtlFGC0.js").then((m) => m.markdownRenderer));
	registerRenderer("text", () => import("./text-l1XNXBOC.js").then((m) => m.textRenderer));
	registerRenderer("csv", () => import("./csv-COrS4qdy.js").then((m) => m.csvRenderer));
	registerRenderer("pdf", () => import("./pdf-IuBgTb3T.js").then((m) => m.pdfRenderer));
	registerRenderer("docx", () => import("./docx-uNAel545.js").then((m) => m.docxRenderer));
	registerRenderer("xlsx", () => import("./xlsx-Cvu4LBNy.js").then((m) => m.xlsxRenderer));
	registerRenderer("pptx", () => import("./pptx-DXiMiYFM.js").then((m) => m.pptxRenderer));
	registerRenderer("slack", () => import("./slack-BI3EQwYm.js").then((m) => m.slackRenderer));
	registerRenderer("svg", () => import("./svg-BKxumy-p.js").then((m) => m.svgRenderer));
	registerRenderer("teams", () => import("./teams-Cwz9lce0.js").then((m) => m.teamsRenderer));
	registerRenderer("discord", () => import("./discord-BLUnkEh9.js").then((m) => m.discordRenderer));
	registerRenderer("telegram", () => import("./telegram-gYFqyMXb.js").then((m) => m.telegramRenderer));
	registerRenderer("notion", () => import("./notion-iG2C5bEY.js").then((m) => m.notionRenderer));
	registerRenderer("confluence", () => import("./confluence-Bd3ua1Ut.js").then((m) => m.confluenceRenderer));
	registerRenderer("whatsapp", () => import("./whatsapp-CjSGoOKx.js").then((m) => m.whatsappRenderer));
	registerRenderer("google-chat", () => import("./google-chat-CkKCBUWC.js").then((m) => m.googleChatRenderer));
}

//#endregion
//#region src/download.ts
const FORMAT_MAP = {
	html: "html",
	htm: "html",
	pdf: "pdf",
	docx: "docx",
	doc: "docx",
	xlsx: "xlsx",
	xls: "xlsx",
	pptx: "pptx",
	ppt: "pptx",
	md: "md",
	txt: "text",
	csv: "csv",
	svg: "svg"
};
const MIME_TYPES = {
	html: "text/html",
	pdf: "application/pdf",
	docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
	xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
	pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
	email: "text/html",
	md: "text/markdown",
	text: "text/plain",
	csv: "text/csv",
	svg: "image/svg+xml"
};
/**
* Download a document in the browser.
*
* @example
* ```tsx
* await download(doc, 'report.pdf')
* await download(doc, 'report.docx')
* ```
*/
async function download(node, filename, options) {
	const ext = filename.split(".").pop()?.toLowerCase();
	if (!ext) throw new Error("[@pyreon/document] Filename must have an extension (e.g., report.pdf).");
	const format = FORMAT_MAP[ext];
	if (!format) throw new Error(`[@pyreon/document] Unknown file extension '.${ext}'. Supported: ${Object.keys(FORMAT_MAP).join(", ")}`);
	const result = await render(node, format, options);
	const blob = result instanceof Uint8Array ? new Blob([result]) : new Blob([result], { type: MIME_TYPES[format] ?? "application/octet-stream" });
	if (typeof document === "undefined") throw new Error("[@pyreon/document] download() requires a browser environment.");
	const url = URL.createObjectURL(blob);
	const a = document.createElement("a");
	a.href = url;
	a.download = filename;
	a.click();
	URL.revokeObjectURL(url);
}

//#endregion
//#region src/nodes.ts
function createNode(type, props, children) {
	return {
		type,
		props,
		children: normalizeChildren(children)
	};
}
function normalizeChildren(children) {
	if (children == null || children === false) return [];
	if (typeof children === "string") return [children];
	if (typeof children === "number") return [String(children)];
	if (Array.isArray(children)) return children.flatMap(normalizeChildren);
	if (isDocNode(children)) return [children];
	if (typeof children === "object") throw new Error("[@pyreon/document] Invalid child: plain objects are not valid document children. Use a document node (Text, Heading, etc.) instead.");
	return [String(children)];
}
/** Type guard — checks if a value is a DocNode. */
function isDocNode(value) {
	return typeof value === "object" && value !== null && "type" in value && "props" in value && "children" in value;
}
/**
* Root document container. Holds metadata and pages.
*
* @example
* ```tsx
* <Document title="Invoice #1234" author="Acme Corp">
*   <Page>...</Page>
* </Document>
* ```
*/
function Document(props) {
	const { children, ...rest } = props;
	return createNode("document", rest, children);
}
Document._documentType = "document";
/**
* Page container. Maps to a PDF page, DOCX section, or email block.
*
* @example
* ```tsx
* <Page size="A4" margin={40}>
*   <Heading>Title</Heading>
* </Page>
* ```
*/
function Page(props) {
	const { children, ...rest } = props;
	return createNode("page", rest, children);
}
Page._documentType = "page";
/**
* Layout section — groups content with optional direction, padding, background.
*
* @example
* ```tsx
* <Section background="#f5f5f5" padding={20} direction="row" gap={12}>
*   <Text>Left</Text>
*   <Text>Right</Text>
* </Section>
* ```
*/
function Section(props) {
	const { children, ...rest } = props;
	return createNode("section", rest, children);
}
Section._documentType = "section";
/**
* Horizontal layout container.
*
* @example
* ```tsx
* <Row gap={20}>
*   <Column width="60%"><Text>Main</Text></Column>
*   <Column width="40%"><Text>Side</Text></Column>
* </Row>
* ```
*/
function Row(props) {
	const { children, ...rest } = props;
	return createNode("row", rest, children);
}
Row._documentType = "row";
/**
* Column within a Row.
*/
function Column(props) {
	const { children, ...rest } = props;
	return createNode("column", rest, children);
}
Column._documentType = "column";
/**
* Heading text (h1–h6).
*
* @example
* ```tsx
* <Heading level={1}>Invoice #1234</Heading>
* <Heading level={2} color="#666">Details</Heading>
* ```
*/
function Heading(props) {
	const { children, ...rest } = props;
	return createNode("heading", {
		level: 1,
		...rest
	}, children);
}
Heading._documentType = "heading";
/**
* Text paragraph with optional formatting.
*
* @example
* ```tsx
* <Text bold size={14} color="#333">Hello World</Text>
* <Text italic align="right">Subtotal: $100</Text>
* ```
*/
function Text(props) {
	const { children, ...rest } = props;
	return createNode("text", rest, children);
}
Text._documentType = "text";
/**
* Hyperlink.
*
* @example
* ```tsx
* <Link href="https://example.com">Visit site</Link>
* ```
*/
function Link(props) {
	const { children, ...rest } = props;
	return createNode("link", rest, children);
}
Link._documentType = "link";
/**
* Image with optional sizing and caption.
*
* @example
* ```tsx
* <Image src="/logo.png" width={120} alt="Company Logo" />
* <Image src={chartDataUrl} width={500} caption="Revenue Chart" />
* ```
*/
function Image(props) {
	return createNode("image", props, []);
}
Image._documentType = "image";
/**
* Data table with columns and rows.
*
* @example
* ```tsx
* <Table
*   columns={['Name', 'Price', 'Qty']}
*   rows={[['Widget', '$10', '5'], ['Gadget', '$20', '3']]}
*   striped
*   headerStyle={{ background: '#1a1a2e', color: '#fff' }}
* />
* ```
*/
function Table(props) {
	return createNode("table", props, []);
}
Table._documentType = "table";
/**
* Ordered or unordered list.
*
* @example
* ```tsx
* <List ordered>
*   <ListItem>First item</ListItem>
*   <ListItem>Second item</ListItem>
* </List>
* ```
*/
function List(props) {
	const { children, ...rest } = props;
	return createNode("list", rest, children);
}
List._documentType = "list";
/**
* Single list item within a List.
*/
function ListItem(props) {
	const { children } = props;
	return createNode("list-item", {}, children);
}
ListItem._documentType = "list-item";
/**
* Code block with optional language hint.
*
* @example
* ```tsx
* <Code language="typescript">const x = 42</Code>
* ```
*/
function Code(props) {
	const { children, ...rest } = props;
	return createNode("code", rest, children);
}
Code._documentType = "code";
/**
* Horizontal divider line.
*
* @example
* ```tsx
* <Divider color="#ddd" thickness={2} />
* ```
*/
function Divider(props = {}) {
	return createNode("divider", props, []);
}
Divider._documentType = "divider";
/**
* Page break — forces content after this point to the next page (PDF/DOCX)
* or inserts a visual separator (HTML/email).
*
* @example
* ```tsx
* <PageBreak />
* ```
*/
function PageBreak() {
	return createNode("page-break", {}, []);
}
PageBreak._documentType = "page-break";
/**
* Vertical spacer.
*
* @example
* ```tsx
* <Spacer height={20} />
* ```
*/
function Spacer(props) {
	return createNode("spacer", props, []);
}
Spacer._documentType = "spacer";
/**
* CTA button — renders as a bulletproof button in email, styled link in PDF/DOCX.
*
* @example
* ```tsx
* <Button href="https://acme.com/pay" background="#4f46e5" color="#fff">
*   Pay Now
* </Button>
* ```
*/
function Button(props) {
	const { children, ...rest } = props;
	return createNode("button", rest, children);
}
Button._documentType = "button";
/**
* Block quote.
*
* @example
* ```tsx
* <Quote borderColor="#4f46e5">This is a quote.</Quote>
* ```
*/
function Quote(props) {
	const { children, ...rest } = props;
	return createNode("quote", rest, children);
}
Quote._documentType = "quote";

//#endregion
//#region src/builder.ts
/**
* Create a document using the builder pattern — no JSX needed.
*
* @example
* ```ts
* const doc = createDocument({ title: 'Report' })
*   .heading('Sales Report')
*   .text('Q4 performance summary.')
*   .table({ columns: ['Region', 'Revenue'], rows: [['US', '$1M']] })
*
* await doc.toPdf()
* await doc.download('report.pdf')
* ```
*/
function createDocument(props = {}) {
	const sections = [];
	function getNode() {
		return Document({
			...props,
			children: [Page({ children: sections })]
		});
	}
	const builder = {
		heading(text, p) {
			sections.push(Heading({
				...p,
				children: text
			}));
			return builder;
		},
		text(text, p) {
			sections.push(Text({
				...p,
				children: text
			}));
			return builder;
		},
		paragraph(text, p) {
			return builder.text(text, p);
		},
		image(src, p) {
			sections.push(Image({
				src,
				...p
			}));
			return builder;
		},
		table(p) {
			sections.push(Table(p));
			return builder;
		},
		list(items, p) {
			sections.push(List({
				...p,
				children: items.map((item) => ListItem({ children: item }))
			}));
			return builder;
		},
		code(text, p) {
			sections.push(Code({
				...p,
				children: text
			}));
			return builder;
		},
		divider(p) {
			sections.push(Divider(p));
			return builder;
		},
		spacer(height) {
			sections.push(Spacer({ height }));
			return builder;
		},
		quote(text, p) {
			sections.push(Quote({
				...p,
				children: text
			}));
			return builder;
		},
		button(text, p) {
			sections.push(Button({
				...p,
				children: text
			}));
			return builder;
		},
		link(text, p) {
			sections.push(Link({
				...p,
				children: text
			}));
			return builder;
		},
		pageBreak() {
			sections.push(PageBreak());
			return builder;
		},
		add(node) {
			if (Array.isArray(node)) sections.push(...node);
			else sections.push(node);
			return builder;
		},
		section(children) {
			sections.push(Section({ children }));
			return builder;
		},
		chart(instance, p) {
			const inst = instance;
			if (inst?.getDataURL) {
				const dataUrl = inst.getDataURL({
					type: "png",
					pixelRatio: 2
				});
				sections.push(Image({
					src: dataUrl,
					...p?.width != null ? { width: p.width } : {},
					...p?.height != null ? { height: p.height } : {},
					...p?.caption != null ? { caption: p.caption } : {}
				}));
			} else sections.push(Text({
				children: "[Chart]",
				italic: true,
				color: "#999"
			}));
			return builder;
		},
		flow(instance, p) {
			const inst = instance;
			if (inst?.toSVG) {
				const svg = inst.toSVG();
				sections.push(Image({
					src: `data:image/svg+xml,${encodeURIComponent(svg)}`,
					...p?.width != null ? { width: p.width } : {},
					...p?.height != null ? { height: p.height } : {},
					...p?.caption != null ? { caption: p.caption } : {}
				}));
			} else sections.push(Text({
				children: "[Flow Diagram]",
				italic: true,
				color: "#999"
			}));
			return builder;
		},
		build() {
			return getNode();
		},
		async toHtml(options) {
			return render(getNode(), "html", options);
		},
		async toPdf(options) {
			return render(getNode(), "pdf", options);
		},
		async toDocx(options) {
			return render(getNode(), "docx", options);
		},
		async toEmail(options) {
			return render(getNode(), "email", options);
		},
		async toPptx(options) {
			return render(getNode(), "pptx", options);
		},
		async toXlsx(options) {
			return render(getNode(), "xlsx", options);
		},
		async toMarkdown(options) {
			return render(getNode(), "md", options);
		},
		async toText(options) {
			return render(getNode(), "text", options);
		},
		async toCsv(options) {
			return render(getNode(), "csv", options);
		},
		async toSlack(options) {
			return render(getNode(), "slack", options);
		},
		async toSvg(options) {
			return render(getNode(), "svg", options);
		},
		async toTeams(options) {
			return render(getNode(), "teams", options);
		},
		async toDiscord(options) {
			return render(getNode(), "discord", options);
		},
		async toTelegram(options) {
			return render(getNode(), "telegram", options);
		},
		async toNotion(options) {
			return render(getNode(), "notion", options);
		},
		async toConfluence(options) {
			return render(getNode(), "confluence", options);
		},
		async toWhatsApp(options) {
			return render(getNode(), "whatsapp", options);
		},
		async toGoogleChat(options) {
			return render(getNode(), "google-chat", options);
		},
		async download(filename, options) {
			return download(getNode(), filename, options);
		}
	};
	return builder;
}

//#endregion
export { Button, Code, Column, Divider, Document, Heading, Image, Link, List, ListItem, Page, PageBreak, Quote, Row, Section, Spacer, Table, Text, _resetRenderers, createDocument, download, isDocNode, registerRenderer, render, unregisterRenderer };
//# sourceMappingURL=index.js.map