markdownfly 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/index.ts","../src/parser/index.ts","../src/parser/frontmatter.ts","../src/config/defaults.ts","../src/utils/progress.ts","../src/parser/splitter.ts","../src/parser/preprocess.ts","../src/renderer/pptx-renderer.ts","../src/renderer/layouts/title.ts","../src/renderer/layouts/section.ts","../src/utils/png-size.ts","../src/utils/image-fit.ts","../src/utils/table-chart.ts","../src/renderer/layouts/content.ts","../src/renderer/layouts/code.ts","../src/renderer/layouts/quote.ts","../src/renderer/layouts/index.ts","../src/renderer/code-highlighter.ts","../src/renderer/image-handler.ts","../src/diagrams/svg-to-png.ts","../src/diagrams/theme.ts","../src/diagrams/mermaid-renderer.ts","../src/diagrams/graphviz-renderer.ts","../src/diagrams/echarts-renderer.ts","../src/diagrams/index.ts","../src/utils/gradient.ts","../src/renderer/background.ts","../src/themes/clean.ts","../src/themes/academic.ts","../src/themes/dark.ts","../src/themes/business.ts","../src/themes/warm.ts","../src/themes/aurora.ts","../src/themes/neon.ts","../src/themes/nord.ts","../src/themes/dracula.ts","../src/themes/beige.ts","../src/themes/ink.ts","../src/themes/default.ts","../src/themes/index.ts","../src/utils/output-namer.ts","../src/utils/glob.ts"],"sourcesContent":["/**\n * MarkdownFly CLI\n * Usage: mfly <files...> [-o output.pptx] [-t theme] [--quiet|--json]\n */\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport { readFileSync } from 'node:fs';\nimport { convert } from './index.js';\nimport { expandGlob } from './utils/glob.js';\nimport { ProgressReporter, log, setQuiet } from './utils/progress.js';\nimport { themes } from './themes/index.js';\n\nconst pkg = JSON.parse(\n readFileSync(new URL('../package.json', import.meta.url), 'utf-8'),\n) as { version?: string };\n\nconst program = new Command();\n\nprogram\n .name('mfly')\n .description('Markdown to PowerPoint (PPTX)')\n .version(pkg.version ?? '0.0.0');\n\nconst themeChoices = Object.keys(themes).filter((name) => name !== 'default');\n\n// Main convert command\nprogram\n .argument('<files...>', 'Markdown files to convert (supports glob)')\n .option('-o, --output <path>', 'Output file path (single file only)')\n .option('-t, --theme <name>', `Theme name (${themeChoices.join(', ')})`)\n .option('--quiet', 'Suppress per-file progress output')\n .option('--json', 'Print machine-readable JSON result to stdout')\n .action(async (\n filePatterns: string[],\n options: { output?: string; theme: string; quiet?: boolean; json?: boolean },\n ) => {\n const jsonMode = Boolean(options.json);\n if (jsonMode || options.quiet) setQuiet(true);\n\n const usageError = (msg: string): never => {\n log.error(msg);\n if (jsonMode) console.log(JSON.stringify({ ok: false, error: msg }));\n process.exit(1);\n };\n\n try {\n const files = await expandGlob(filePatterns);\n\n if (files.length === 0) {\n usageError('No .md files found matching the given pattern(s)');\n }\n\n if (options.output && files.length > 1) {\n usageError('--output can only be used with a single input file');\n }\n\n // Strict theme validation. When -t is omitted, the theme comes from\n // frontmatter (unknown frontmatter themes fall back to clean with a warning).\n if (options.theme && !themes[options.theme.toLowerCase()]) {\n usageError(`Unknown theme \"${options.theme}\". Available themes: ${themeChoices.join(', ')}`);\n }\n\n const startTime = Date.now();\n const results: Array<{ input: string; output?: string; ok: boolean; error?: string }> = [];\n\n for (const file of files) {\n const progress = new ProgressReporter();\n const fileName = file.split(/[\\\\/]/).pop() ?? file;\n\n progress.start(`Converting ${chalk.cyan(fileName)}...`);\n\n try {\n const outputPath = await convert(file, {\n output: options.output,\n theme: options.theme,\n });\n\n const outName = outputPath.split(/[\\\\/]/).pop() ?? outputPath;\n progress.succeed(`${chalk.cyan(fileName)} → ${chalk.green(outName)}`);\n results.push({ input: file, output: outputPath, ok: true });\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n progress.fail(`${chalk.cyan(fileName)}: ${chalk.red(msg)}`);\n results.push({ input: file, ok: false, error: msg });\n }\n }\n\n const failed = results.filter((r) => !r.ok);\n\n if (jsonMode) {\n console.log(JSON.stringify({\n ok: failed.length === 0,\n durationMs: Date.now() - startTime,\n files: results,\n }));\n } else {\n if (failed.length > 0) {\n log.error(`${failed.length} of ${files.length} file(s) failed`);\n }\n const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);\n log.info(`Done in ${elapsed}s`);\n }\n\n if (failed.length > 0) {\n process.exit(1);\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n log.error(msg);\n if (jsonMode) console.log(JSON.stringify({ ok: false, error: msg }));\n process.exit(1);\n }\n });\n\nprogram.parse();\n","/**\n * MarkdownFly — Main orchestration\n * Public API: convert(inputPath, options) → outputPath\n */\n\nimport { readFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport { parseMarkdown } from './parser/index.js';\nimport { renderPresentation } from './renderer/index.js';\nimport { getTheme } from './themes/index.js';\nimport { getOutputPath } from './utils/output-namer.js';\n\nexport interface ConvertOptions {\n output?: string;\n theme?: string;\n}\n\n/**\n * Convert a Markdown file to PPTX\n * @returns Absolute path of the generated .pptx file\n */\nexport async function convert(inputPath: string, options: ConvertOptions = {}): Promise<string> {\n const absInput = resolve(inputPath);\n const markdown = readFileSync(absInput, 'utf-8');\n\n // Parse\n const presentation = parseMarkdown(markdown);\n\n // Merge CLI options into config\n if (options.theme) presentation.config.theme = options.theme;\n\n // Get theme\n const theme = getTheme(presentation.config.theme);\n\n // Determine output path\n const outputPath = resolve(getOutputPath(absInput, options.output));\n\n // Render PPTX\n await renderPresentation(presentation, theme, outputPath, absInput);\n\n return outputPath;\n}\n\n// Re-export for library use\nexport { parseMarkdown } from './parser/index.js';\nexport {\n getTheme,\n themes,\n cleanTheme,\n academicTheme,\n darkTheme,\n businessTheme,\n warmTheme,\n defaultTheme,\n} from './themes/index.js';\nexport { renderDiagram, isDiagramLanguage } from './diagrams/index.js';\nexport type { Presentation, SlideNode, SlideElement } from './models/slide.js';\nexport type { Theme } from './models/theme.js';\nexport type { MarkdownFlyConfig } from './config/types.js';\n","/**\n * Markdown Parser\n * Main entry point: markdown string → Presentation\n */\n\nimport { unified } from 'unified';\nimport remarkParse from 'remark-parse';\nimport remarkFrontmatter from 'remark-frontmatter';\nimport remarkGfm from 'remark-gfm';\nimport type { Root } from 'mdast';\nimport type { Presentation } from '../models/slide.js';\nimport { extractFrontmatter } from './frontmatter.js';\nimport { splitIntoSlides } from './splitter.js';\nimport { preprocessMarkdown } from './preprocess.js';\n\n/**\n * Parse a markdown string into a Presentation\n */\nexport function parseMarkdown(markdown: string): Presentation {\n const processor = unified()\n .use(remarkParse)\n .use(remarkFrontmatter, ['yaml'])\n .use(remarkGfm); // GFM: tables, task lists, autolinks, strikethrough\n\n // Rewrite layout markers (<-> / === / @(...)) before parsing so they\n // never collide with setext headings or paragraph text.\n const tree = processor.parse(preprocessMarkdown(markdown)) as Root;\n\n const config = extractFrontmatter(tree);\n const slides = splitIntoSlides(tree, config.layout);\n\n return { config, slides };\n}\n","/**\n * Frontmatter extractor\n * Extracts YAML frontmatter from remark AST and merges with defaults\n */\n\nimport type { Root } from 'mdast';\nimport { parse as parseYaml } from 'yaml';\nimport type { MarkdownFlyConfig } from '../config/types.js';\nimport { DEFAULT_CONFIG } from '../config/defaults.js';\nimport { log } from '../utils/progress.js';\n\n/**\n * Extract and parse frontmatter from remark AST\n */\nexport function extractFrontmatter(tree: Root): MarkdownFlyConfig {\n const yamlNode = tree.children.find((node) => node.type === 'yaml') as\n | { type: 'yaml'; value: string }\n | undefined;\n\n if (!yamlNode) {\n return { ...DEFAULT_CONFIG };\n }\n\n try {\n const parsed = parseYaml(yamlNode.value) as Partial<MarkdownFlyConfig> & {\n resource_dir?: string; // snake_case alias\n };\n const { resource_dir, ...parsedOnly } = parsed;\n const merged: MarkdownFlyConfig = {\n ...DEFAULT_CONFIG,\n ...parsedOnly,\n };\n if (resource_dir && !merged.resourceDir) {\n merged.resourceDir = resource_dir;\n }\n return merged;\n } catch {\n log.warn('Failed to parse frontmatter YAML, using defaults');\n return { ...DEFAULT_CONFIG };\n }\n}\n","/**\n * Default configuration values\n */\n\nimport type { MarkdownFlyConfig } from './types.js';\n\nexport const DEFAULT_CONFIG: MarkdownFlyConfig = {\n theme: 'clean',\n};\n","/**\n * Progress display using ora spinner + chalk\n */\n\nimport ora, { type Ora } from 'ora';\nimport chalk from 'chalk';\n\nlet quiet = false;\n\n/** Suppress all per-file progress output (errors/summaries are still printed). */\nexport function setQuiet(value: boolean): void {\n quiet = value;\n}\n\nexport class ProgressReporter {\n private spinner: Ora;\n\n constructor() {\n this.spinner = ora();\n }\n\n start(text: string): void {\n if (quiet) return;\n this.spinner.start(text);\n }\n\n update(text: string): void {\n if (quiet) return;\n this.spinner.text = text;\n }\n\n succeed(text: string): void {\n if (quiet) return;\n this.spinner.succeed(text);\n }\n\n fail(text: string): void {\n if (quiet) return;\n this.spinner.fail(text);\n }\n\n info(text: string): void {\n if (quiet) return;\n this.spinner.info(text);\n }\n}\n\nexport const log = {\n info: (msg: string) => console.log(chalk.blue('ℹ'), msg),\n success: (msg: string) => console.log(chalk.green('✔'), msg),\n warn: (msg: string) => console.error(chalk.yellow('⚠'), msg),\n error: (msg: string) => console.error(chalk.red('✖'), msg),\n};\n","/**\n * Slide Splitter\n * Converts remark AST into SlideNode[] with automatic layout detection\n */\n\nimport type { Root, Content, PhrasingContent } from 'mdast';\nimport type {\n SlideNode,\n SlideElement,\n SlideLayout,\n SlideDirectives,\n TextElement,\n HeadingElement,\n ListElement,\n CodeElement,\n ImageElement,\n TableElement,\n BlockquoteElement,\n DiagramElement,\n BreakElement,\n CalloutElement,\n ImageAlign,\n} from '../models/slide.js';\n\n/** Diagram languages that trigger DiagramElement instead of CodeElement */\nconst DIAGRAM_LANGUAGES = new Set(['mermaid', 'dot', 'graphviz', 'echarts']);\n\n/** Callout variants recognized in blockquotes: > [!NOTE] / [!TIP] / ... */\nconst CALLOUT_VARIANTS = new Set([\n 'note', 'info', 'tip', 'success', 'warning', 'caution', 'danger',\n]);\n\n/**\n * Recursively extract plain text from mdast inline/phrasing nodes\n */\nfunction extractText(node: PhrasingContent | Content): string {\n if ('value' in node && typeof node.value === 'string') {\n return node.value;\n }\n // Soft line breaks inside blockquotes/lists map to \"\\n\"\n // (@types/mdast 4.0.4 omits Softbreak from its unions — cast to check)\n if ((node as { type: string }).type === 'softbreak') {\n return '\\n';\n }\n if ('children' in node && Array.isArray(node.children)) {\n return (node.children as PhrasingContent[]).map(extractText).join('');\n }\n return '';\n}\n\n/**\n * Parse an HTML comment node produced by preprocess.ts\n * Returns a BreakElement or directive key/values\n */\nfunction parseComment(value: string): BreakElement | { directives: Record<string, string> } | null {\n const match = value.match(/<!--\\s*mfly:(row|col|dir)\\s*(.*?)\\s*-->/s);\n if (!match) return null;\n\n if (match[1] === 'row' || match[1] === 'col') {\n return { type: 'break', direction: match[1] } satisfies BreakElement;\n }\n\n if (match[1] === 'dir') {\n const raw = decodeURIComponent(match[2]);\n return { directives: parseDirectiveString(raw) };\n }\n\n return null;\n}\n\n/**\n * Parse \"@(key=value, key=value, ...)\" into a record.\n * Values may be quoted (\"...\", '...') to contain commas or parens.\n */\nexport function parseDirectiveString(input: string): Record<string, string> {\n const inner = input.replace(/^@\\(/, '').replace(/\\)$/, '').trim();\n const result: Record<string, string> = {};\n if (!inner) return result;\n\n const re = /([A-Za-z][A-Za-z0-9_-]*)\\s*=\\s*(\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'|[^,)]+)/g;\n let m: RegExpExecArray | null;\n while ((m = re.exec(inner)) !== null) {\n let value = m[2].trim();\n if ((value.startsWith('\"') && value.endsWith('\"')) || (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\n value = value.slice(1, -1);\n }\n result[m[1]] = value;\n }\n return result;\n}\n\n/** Build the typed directive object for a slide */\nfunction toDirectives(raw: Record<string, string>): SlideDirectives {\n const d: SlideDirectives = {};\n if (raw.layout) d.layout = raw.layout;\n if (raw.notes) d.notes = raw.notes;\n if (raw.chart) d.chart = raw.chart;\n if (raw.highlight) d.highlight = raw.highlight;\n if (raw.background) d.background = raw.background;\n if (raw.steps) d.steps = raw.steps === 'true' || raw.steps === 'yes' || raw.steps === '1';\n return d;\n}\n\n/** Parse \"2-4,6,8-9\" style line ranges into a list of 1-based numbers */\nexport function parseHighlightRanges(spec: string): number[] {\n const lines = new Set<number>();\n for (const part of spec.split(',')) {\n const range = part.trim().match(/^(\\d+)\\s*-\\s*(\\d+)$/);\n if (range) {\n const from = Number(range[1]);\n const to = Number(range[2]);\n for (let n = Math.min(from, to); n <= Math.max(from, to); n++) lines.add(n);\n } else {\n const single = part.trim().match(/^\\d+$/);\n if (single) lines.add(Number(single));\n }\n }\n return [...lines].sort((a, b) => a - b);\n}\n\n/** Detect \"> [!NOTE] Custom title ...\" style callouts (moffee-compatible). */\nfunction parseCallout(content: string): CalloutElement | null {\n const lines = content.split('\\n');\n const markerMatch = lines[0]?.match(/^\\s*\\[!(.*?)\\]\\s*(.*?)\\s*$/);\n if (!markerMatch) return null;\n const variant = markerMatch[1].toLowerCase();\n if (!CALLOUT_VARIANTS.has(variant)) return null;\n const title = markerMatch[2].trim() || undefined;\n return {\n type: 'callout',\n variant,\n title,\n content: lines.slice(1).join('\\n').trim(),\n } satisfies CalloutElement;\n}\n\n/**\n * Parse a `{w=6in,h=40mm,align=left}` suffix into image element params.\n * Keys: w/width, h/height, align. Invalid pieces are silently ignored, so a\n * `![alt](src){w=200}` line still renders the image.\n */\nfunction parseImageParams(text: string): Pick<ImageElement, 'width' | 'height' | 'align'> {\n const result: Pick<ImageElement, 'width' | 'height' | 'align'> = {};\n const body = text.replace(/^\\{\\s*|\\s*\\}$/g, '');\n for (const part of body.split(',')) {\n const eq = part.indexOf('=');\n if (eq === -1) continue;\n const key = part.slice(0, eq).trim().toLowerCase();\n const value = part.slice(eq + 1).trim();\n switch (key) {\n case 'w':\n case 'width': {\n const normalized = normalizeImageSize(value);\n if (normalized) result.width = normalized;\n break;\n }\n case 'h':\n case 'height': {\n const normalized = normalizeImageSize(value);\n if (normalized) result.height = normalized;\n break;\n }\n case 'align': {\n if (value === 'left' || value === 'center' || value === 'right') {\n result.align = value as ImageAlign;\n }\n break;\n }\n }\n }\n return result;\n}\n\n/** Normalize to '<n>in' or '<n>%'; bare numbers are px (96 dpi). Invalid → undefined. */\nfunction normalizeImageSize(value: string): string | undefined {\n const match = value.match(/^(\\d+(?:\\.\\d+)?)(px|pt|cm|mm|in|inch|%)?$/i);\n if (!match) return undefined;\n const n = parseFloat(match[1]);\n if (!(n > 0)) return undefined;\n const unit = (match[2] || 'px').toLowerCase();\n if (unit === '%') return `${n}%`;\n const inches =\n unit === 'px' ? n / 96 : unit === 'pt' ? n / 72 : unit === 'cm' ? n / 2.54 : unit === 'mm' ? n / 25.4 : n;\n return `${Math.round(inches * 100) / 100}in`;\n}\n\n/**\n * Convert an mdast content node to a SlideElement\n */\nfunction nodeToElement(node: Content): SlideElement | null {\n switch (node.type) {\n case 'heading': {\n return {\n type: 'heading',\n content: node.children.map(extractText).join(''),\n level: node.depth,\n } satisfies HeadingElement;\n }\n\n case 'paragraph': {\n // A paragraph holding exactly one image — optionally followed by a\n // {w=...,align=...} suffix, which CommonMark parses as a plain text node.\n const first = node.children[0];\n if (first?.type === 'image') {\n const rest = node.children.slice(1);\n const paramsFromText = (() => {\n if (rest.length === 0) return {};\n if (!rest.every((c) => c.type === 'text')) return null;\n const suffix = rest\n .map((c) => (c.type === 'text' ? c.value : ''))\n .join('')\n .trim();\n const match = suffix.match(/^\\{.*\\}$/);\n return match ? parseImageParams(match[0]) : null;\n })();\n if (paramsFromText !== null) {\n return {\n type: 'image',\n src: first.url,\n alt: first.alt ?? undefined,\n ...paramsFromText,\n } satisfies ImageElement;\n }\n }\n return {\n type: 'text',\n content: node.children.map(extractText).join(''),\n } satisfies TextElement;\n }\n\n case 'list': {\n // remark-gfm sets checked to true/false for task items and null for\n // plain items — only treat boolean values as task-list markers.\n const hasCheckboxes = node.children.some(\n (item) => typeof item.checked === 'boolean',\n );\n const items = node.children.map((item) => {\n return item.children.map((child) => extractText(child)).join('');\n });\n const result: ListElement = {\n type: 'list',\n items,\n ordered: node.ordered ?? false,\n };\n if (hasCheckboxes) {\n result.checked = node.children.map((item) =>\n typeof item.checked === 'boolean' ? item.checked : false,\n );\n }\n return result;\n }\n\n case 'code': {\n const lang = node.lang?.toLowerCase() ?? '';\n if (DIAGRAM_LANGUAGES.has(lang)) {\n return {\n type: 'diagram',\n diagramType: lang === 'graphviz' ? 'dot' : lang,\n content: node.value,\n } satisfies DiagramElement;\n }\n const element = {\n type: 'code',\n content: node.value,\n language: node.lang ?? undefined,\n } satisfies CodeElement;\n return element;\n }\n\n case 'image': {\n return {\n type: 'image',\n src: node.url,\n alt: node.alt ?? undefined,\n } satisfies ImageElement;\n }\n\n case 'table': {\n const rows = node.children.map((row) =>\n row.children.map((cell) =>\n cell.children.map(extractText).join(''),\n ),\n );\n const headers = rows.length > 0 ? rows[0] : [];\n const bodyRows = rows.slice(1);\n return {\n type: 'table',\n headers,\n rows: bodyRows,\n } satisfies TableElement;\n }\n\n case 'blockquote': {\n const content = node.children\n .map((child) => extractText(child))\n .join('\\n');\n const callout = parseCallout(content);\n if (callout) return callout;\n return {\n type: 'blockquote',\n content,\n } satisfies BlockquoteElement;\n }\n\n case 'html': {\n const parsed = parseComment(node.value);\n if (parsed === null) return null;\n if ('direction' in parsed) return parsed;\n // Directive comments are collected by the caller — see splitIntoSlides\n return null;\n }\n\n default:\n return null;\n }\n}\n\n/**\n * Determine slide layout based on content (rule engine)\n */\nfunction detectLayout(\n title: string | undefined,\n elements: SlideElement[],\n isFirstSlide: boolean,\n headingLevel: number,\n): SlideLayout {\n // First slide with H1 → title\n if (isFirstSlide && headingLevel === 1) {\n return 'title';\n }\n\n // H2 with no body content → section divider\n if (headingLevel === 2 && elements.length === 0) {\n return 'section';\n }\n\n // Only code elements → code layout\n const nonEmptyElements = elements.filter(\n (e) => e.type !== 'text' || e.content.trim() !== '',\n );\n if (\n nonEmptyElements.length > 0 &&\n nonEmptyElements.every((e) => e.type === 'code')\n ) {\n return 'code';\n }\n\n // Only blockquote → quote layout\n if (\n nonEmptyElements.length > 0 &&\n nonEmptyElements.every((e) => e.type === 'blockquote')\n ) {\n return 'quote';\n }\n\n return 'content';\n}\n\n/**\n * Split remark AST into SlideNode array\n * @param defaultLayout Optional frontmatter layout; the auto-detection rule\n * engine runs first, @(layout=...) directives override it.\n */\nexport function splitIntoSlides(tree: Root, defaultLayout?: string): SlideNode[] {\n const slides: SlideNode[] = [];\n let currentTitle: string | undefined;\n let currentSubtitle: string | undefined;\n let currentElements: SlideElement[] = [];\n let currentDirectives: Record<string, string> = {};\n let currentHeadingLevel = 0;\n let isFirstSlide = true;\n\n function flushSlide(): void {\n // Don't create empty slides (but keep slides that carry directives/notes)\n if (!currentTitle && currentElements.length === 0 && Object.keys(currentDirectives).length === 0) {\n return;\n }\n\n // Apply @(highlight=...) to the slide's code block if not already applied\n if (currentDirectives.highlight && currentElements.length > 0) {\n const ranges = parseHighlightRanges(currentDirectives.highlight);\n if (ranges.length > 0) {\n const code = currentElements.find(\n (e): e is CodeElement => e.type === 'code' && !e.highlightLines,\n );\n if (code) code.highlightLines = ranges;\n }\n }\n\n const autoLayout = detectLayout(\n currentTitle,\n currentElements,\n isFirstSlide && slides.length === 0,\n currentHeadingLevel,\n );\n // Precedence: @(layout=...) directive > structural auto-detection\n // (title/section/code/quote) > frontmatter fallback (only for generic\n // content slides) > generic content.\n const layout: SlideLayout = (currentDirectives.layout as SlideLayout | undefined) ??\n (autoLayout === 'content' ? (defaultLayout as SlideLayout | undefined) : autoLayout) ??\n 'content';\n\n slides.push({\n layout,\n title: currentTitle,\n subtitle: currentSubtitle,\n elements: currentElements,\n notes: currentDirectives.notes,\n directives: toDirectives(currentDirectives),\n });\n\n currentTitle = undefined;\n currentSubtitle = undefined;\n currentElements = [];\n currentDirectives = {};\n currentHeadingLevel = 0;\n isFirstSlide = false;\n }\n\n for (const node of tree.children) {\n // Skip frontmatter\n if (node.type === 'yaml') continue;\n\n // --- separator → new slide\n if (node.type === 'thematicBreak') {\n flushSlide();\n continue;\n }\n\n // H1 or H2 → new slide\n if (node.type === 'heading' && (node.depth === 1 || node.depth === 2)) {\n flushSlide();\n currentTitle = node.children.map(extractText).join('');\n currentHeadingLevel = node.depth;\n continue;\n }\n\n // Directive comment may precede content in any position — collect it,\n // but preserve ordering by pushing to elements when it's a break marker.\n if (node.type === 'html') {\n const parsed = parseComment(node.value);\n if (parsed !== null) {\n if ('direction' in parsed) {\n currentElements.push(parsed);\n } else {\n Object.assign(currentDirectives, parsed.directives);\n }\n }\n continue;\n }\n\n // Other content → add to current slide\n const element = nodeToElement(node);\n if (element) {\n currentElements.push(element);\n }\n }\n\n // Flush remaining content\n flushSlide();\n\n return slides;\n}\n","/**\n * Preprocess the raw markdown before remark parsing.\n *\n * Converts inline layout markers that are NOT valid CommonMark into HTML\n * comment nodes, which remark keeps intact and our splitter can recognize:\n *\n * === (standalone line) → <!-- mfly:row --> vertical block separator\n * <-> (standalone line) → <!-- mfly:col --> horizontal column separator\n * @(...) (standalone line) → <!-- mfly:dir:... --> slide-level directive\n *\n * Standalone lines starting with `%%` are removed entirely (like moffee's\n * comment syntax) — handy for drafting notes that never reach the deck.\n *\n * Why comments: `===` collides with setext heading underlines, and `<->`\n * would otherwise be a plain paragraph. Encoding them as comments makes the\n * AST explicit and keeps the rest of the markdown untouched.\n *\n * Lines inside fenced code blocks are never rewritten.\n */\n\nconst ROW_RE = /^={3,}$/;\nconst COL_RE = /^<->$/;\nconst DIR_RE = /^@\\(.+\\)$/;\nconst COMMENT_RE = /^%%/;\n\nexport function preprocessMarkdown(markdown: string): string {\n const lines = markdown.split('\\n');\n const out: string[] = [];\n\n let inFence = false;\n let fenceChar = '';\n\n for (const line of lines) {\n const trimmed = line.trim();\n const fenceMatch = trimmed.match(/^(`{3,}|~{3,})/);\n\n if (!inFence) {\n if (fenceMatch) {\n inFence = true;\n fenceChar = fenceMatch[1][0];\n out.push(line);\n continue;\n }\n if (COMMENT_RE.test(trimmed)) {\n // Drop %% comment lines entirely\n out.push('');\n continue;\n }\n if (COL_RE.test(trimmed)) {\n out.push('<!-- mfly:col -->');\n continue;\n }\n if (ROW_RE.test(trimmed)) {\n out.push('<!-- mfly:row -->');\n continue;\n }\n if (DIR_RE.test(trimmed)) {\n // Encode so anything inside (parens, \"--\", etc.) is comment-safe\n out.push(`<!-- mfly:dir:${encodeURIComponent(trimmed)} -->`);\n continue;\n }\n out.push(line);\n continue;\n }\n\n // Inside a fenced block: only watch for the closing fence\n out.push(line);\n if (fenceMatch && trimmed.startsWith(fenceChar)) {\n inFence = false;\n }\n }\n\n return out.join('\\n');\n}\n","/**\n * PPTX Renderer\n * Orchestrates pptxgenjs to produce .pptx files from Presentation\n */\n\nimport PptxGenJS from 'pptxgenjs';\nimport type { Presentation } from '../models/slide.js';\nimport type { Theme } from '../models/theme.js';\nimport { renderSlideLayout } from './layouts/index.js';\nimport { highlightCode } from './code-highlighter.js';\nimport { resolveImage } from './image-handler.js';\nimport { renderDiagram } from '../diagrams/index.js';\nimport { slideBackground } from './background.js';\n\nimport { writeFileSync } from 'node:fs';\nimport { dirname, resolve } from 'node:path';\n\n/**\n * Render a Presentation to a .pptx file\n */\nexport async function renderPresentation(\n presentation: Presentation,\n theme: Theme,\n outputPath: string,\n inputPath: string = '',\n): Promise<void> {\n const pptx = new PptxGenJS();\n\n // Configure presentation\n pptx.layout = 'LAYOUT_WIDE'; // 16:9 = 13.33\" x 7.5\"\n pptx.author = presentation.config.author ?? 'MarkdownFly';\n pptx.title = presentation.slides[0]?.title ?? 'Presentation';\n\n const { resourceDir } = presentation.config;\n // Frontmatter resource_dir: relative paths are relative to the source file,\n // not the process cwd (agents may run from anywhere). basePath is a directory.\n const resourceBase = resourceDir\n ? resolve(dirname(inputPath), resourceDir)\n : dirname(inputPath);\n const backgroundProps = slideBackground(theme);\n\n // Build render context\n const ctx = {\n highlightCode: async (code: string, language: string, highlightLines: number[] = []) => {\n return highlightCode(code, language, theme, highlightLines) as unknown as Promise<PptxGenJS.TextProps[]>;\n },\n resolveImage: async (src: string) => {\n return resolveImage(src, resourceBase);\n },\n renderDiagram: async (diagramType: string, code: string) => {\n return renderDiagram(diagramType, code, theme);\n },\n footerTemplate: presentation.config.footer,\n pageNumber: 0,\n totalSlides: presentation.slides.length,\n currentSection: '',\n };\n\n // Render each slide\n for (let i = 0; i < presentation.slides.length; i++) {\n const node = presentation.slides[i];\n const slide = pptx.addSlide();\n\n // Set default background (flat color or theme gradient image)\n slide.background = backgroundProps;\n\n ctx.pageNumber = i + 1;\n if (node.layout === 'section' && node.title) {\n ctx.currentSection = node.title;\n }\n\n await renderSlideLayout(slide, node, theme, ctx);\n }\n\n // Write file using nodebuffer for 100% reliable path handling across OS\n const buffer = (await pptx.write({ outputType: 'nodebuffer' })) as Buffer;\n writeFileSync(outputPath, Buffer.from(buffer));\n}\n","/**\n * Title slide layout — cover/opening slide\n */\n\nimport PptxGenJS from 'pptxgenjs';\nimport type { SlideNode } from '../../models/slide.js';\nimport type { Theme } from '../../models/theme.js';\n\nexport function renderTitleSlide(\n slide: PptxGenJS.Slide,\n node: SlideNode,\n theme: Theme,\n): void {\n const textColor = theme.colors.titleText ?? 'FFFFFF';\n const subtitleColor = textColor === 'FFFFFF' ? 'FFFFFFCC' : theme.colors.secondary;\n const metaColor = textColor === 'FFFFFF' ? 'FFFFFF99' : theme.colors.secondary;\n\n // Gradient themes keep the gradient background on the cover slide too;\n // flat themes fall back to their solid titleBackground / primary design.\n const bgColor = theme.colors.backgroundGradient\n ? undefined\n : theme.colors.titleBackground ?? theme.colors.primary;\n if (bgColor) {\n slide.background = { color: bgColor };\n }\n if (node.title) {\n slide.addText(node.title, {\n x: 0.8,\n y: 2.0,\n w: 11.7,\n h: 1.5,\n fontSize: theme.fontSize.title,\n fontFace: theme.fonts.heading,\n color: textColor,\n bold: true,\n align: 'center',\n valign: 'middle',\n });\n }\n\n // Subtitle\n if (node.subtitle) {\n slide.addText(node.subtitle, {\n x: 0.8,\n y: 3.8,\n w: 11.7,\n h: 0.8,\n fontSize: theme.fontSize.body,\n fontFace: theme.fonts.body,\n color: subtitleColor,\n align: 'center',\n valign: 'middle',\n });\n }\n\n // Author / Date from elements\n const textElements = node.elements.filter((e) => e.type === 'text');\n if (textElements.length > 0) {\n const metaText = textElements.map((e) => e.content).join(' · ');\n slide.addText(metaText, {\n x: 0.8,\n y: 5.5,\n w: 11.7,\n h: 0.6,\n fontSize: theme.fontSize.small,\n fontFace: theme.fonts.body,\n color: metaColor,\n align: 'center',\n });\n }\n}\n","/**\n * Section divider slide layout\n */\n\nimport PptxGenJS from 'pptxgenjs';\nimport type { SlideNode } from '../../models/slide.js';\nimport type { Theme } from '../../models/theme.js';\n\nexport function renderSectionSlide(\n slide: PptxGenJS.Slide,\n node: SlideNode,\n theme: Theme,\n): void {\n // Accent strip on left\n slide.addShape('rect' as PptxGenJS.ShapeType, {\n x: 0,\n y: 0,\n w: 0.15,\n h: 7.5,\n fill: { color: theme.colors.accent },\n });\n\n // Section title centered\n if (node.title) {\n slide.addText(node.title, {\n x: 1.0,\n y: 2.5,\n w: 11.3,\n h: 2.0,\n fontSize: theme.fontSize.heading + 4,\n fontFace: theme.fonts.heading,\n color: theme.colors.text,\n bold: true,\n align: 'left',\n valign: 'middle',\n });\n }\n}\n","/**\n * PNG size helpers\n */\n\nexport interface PngSize {\n width: number;\n height: number;\n}\n\n/**\n * Read pixel dimensions from a PNG buffer (IHDR chunk, no dependencies)\n * Returns null when the data is not a valid PNG\n */\nexport function getPngSize(data: Buffer): PngSize | null {\n if (data.length < 24) return null;\n if (data.readUInt32BE(0) !== 0x89504e47) return null;\n const width = data.readUInt32BE(16);\n const height = data.readUInt32BE(20);\n if (!(width > 0 && height > 0)) return null;\n return { width, height };\n}\n","/**\n * Image placement helpers\n */\n\nexport interface Size {\n width: number;\n height: number;\n}\n\nexport interface FitOptions {\n /** Normalized size, e.g. '6in' or '60%' (percent is relative to the box width) */\n width?: string;\n /** Normalized size, e.g. '4in' or '70%' (percent is relative to the box height) */\n height?: string;\n align?: 'left' | 'center' | 'right';\n}\n\nexport interface PlacedImage {\n /** Horizontal offset inside the box, per `align` */\n x: number;\n width: number;\n height: number;\n}\n\n/**\n * Scale an image to fit inside a max-width/max-height box while preserving\n * its aspect ratio. Returns the largest size that fits the box.\n */\nexport function fitInBox(img: Size, maxWidth: number, maxHeight: number): Size {\n if (!(img.width > 0 && img.height > 0) || !(maxWidth > 0 && maxHeight > 0)) {\n return { width: maxWidth, height: maxHeight };\n }\n const ar = img.height / img.width;\n let width = maxWidth;\n let height = width * ar;\n if (height > maxHeight) {\n height = maxHeight;\n width = height / ar;\n }\n return { width, height };\n}\n\n/** Convert a normalized size ('6in' / '60%') to inches; `of` is the reference for percentages. */\nexport function resolveImageSize(value: string | undefined, of: number): number | undefined {\n if (!value) return undefined;\n if (value.endsWith('%')) {\n const pct = parseFloat(value);\n if (Number.isNaN(pct) || pct <= 0) return undefined;\n return (of * pct) / 100;\n }\n const n = parseFloat(value);\n if (Number.isNaN(n) || n <= 0) return undefined;\n return n;\n}\n\n/**\n * Resolve the requested width/height (either may be undefined, meaning\n * \"derive from the other side / the image ratio\"). Returns concrete numbers.\n */\nfunction resolveSizes(img: Size, box: Size, widthStr?: string, heightStr?: string): Size {\n const width = resolveImageSize(widthStr, box.width);\n const height = resolveImageSize(heightStr, box.height);\n const ar = img.height > 0 && img.width > 0 ? img.height / img.width : 0.5;\n\n if (width === undefined && height === undefined) {\n return fitInBox(\n { width: img.width > 0 ? img.width : 6, height: img.height > 0 ? img.height : 3 },\n box.width,\n box.height,\n );\n }\n if (height === undefined) {\n // width is defined here: the both-undefined branch above was skipped\n return { width: width!, height: width! * ar };\n }\n if (width === undefined) {\n return { width: height! / ar, height: height! };\n }\n return { width, height };\n}\n\n/**\n * Place an image inside a box honoring `![alt](src){w=...,h=...,align=...}`:\n * - only one size given → aspect ratio preserved, the other side derived\n * - both sizes given → explicit (aspect not preserved)\n * - the result is always shrunk back into the box\n * `img` is the source pixel size (or the renderer's fallback when unknown).\n */\nexport function fitImageWithOptions(img: Size, box: Size, options: FitOptions = {}): PlacedImage {\n let { width, height } = resolveSizes(img, box, options.width, options.height);\n\n // Never overflow the box (explicit sizes are clamped by proportional shrink)\n if (width > box.width || height > box.height) {\n const fitted = fitInBox({ width, height }, box.width, box.height);\n width = fitted.width;\n height = fitted.height;\n }\n\n const align = options.align ?? 'center';\n const x = align === 'left' ? 0 : align === 'right' ? box.width - width : (box.width - width) / 2;\n return { x, width, height };\n}\n","/**\n * Table → ECharts option converter\n * Powers the @(chart=bar|line|pie) directive: a plain Markdown table\n * becomes a rendered chart without writing JSON by hand.\n */\n\nimport type { TableElement } from '../models/slide.js';\n\n/**\n * Convert a Markdown table into an ECharts option JSON string.\n *\n * bar/line: first column = category, every other column = one series.\n * pie: first column = slice name, second column = value.\n */\nexport function tableToChartOption(\n table: TableElement,\n type: string,\n): string {\n const { headers, rows } = table;\n\n if (headers.length < 2 || rows.length === 0) {\n throw new Error('chart: table needs at least 2 columns and 1 data row');\n }\n\n if (type === 'pie') {\n const series = {\n name: headers[1],\n type: 'pie',\n radius: '55%',\n data: rows.map((r) => ({ name: r[0], value: Number(r[1]) || 0 })),\n };\n return JSON.stringify({\n toolbox: { show: false },\n series: [series],\n });\n }\n\n // bar / line / others → category axis + one series per data column\n const categories = rows.map((r) => r[0]);\n const series = headers.slice(1).map((name, i) => ({\n name,\n type,\n data: rows.map((r) => Number(r[i + 1]) || 0),\n }));\n\n return JSON.stringify({\n xAxis: { type: 'category', data: categories, axisLabel: { hideOverlap: true } },\n yAxis: { type: 'value' },\n series,\n });\n}\n","/**\n * Content slide layout — the most common, handles mixed content.\n *\n * Supports grid layout via break elements:\n * - BreakElement('row') (from `===`): stack content vertically\n * - BreakElement('col') (from `<->`): lay content out side-by-side\n * Columns and rows split the content area evenly.\n */\n\nimport PptxGenJS from 'pptxgenjs';\nimport type { SlideNode, SlideElement } from '../../models/slide.js';\nimport type { Theme } from '../../models/theme.js';\nimport type { RenderContext } from './index.js';\nimport { getPngSize } from '../../utils/png-size.js';\nimport { fitInBox, fitImageWithOptions } from '../../utils/image-fit.js';\nimport { tableToChartOption } from '../../utils/table-chart.js';\nimport { log } from '../../utils/progress.js';\nimport { readFileSync } from 'node:fs';\n\n// Slide dimensions (16:9 LAYOUT_WIDE)\nconst SLIDE_W = 13.33;\nconst SLIDE_H = 7.5;\nconst MARGIN = 0.6;\nconst CONTENT_W = SLIDE_W - MARGIN * 2;\nconst TITLE_H = 0.9;\nconst BOTTOM_MARGIN = 0.45;\nconst GRID_GAP = 0.25;\n\n/** Extension → MIME map used when embedding images as base64 data */\nconst IMAGE_MIME: Record<string, string> = {\n png: 'image/png',\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n gif: 'image/gif',\n webp: 'image/webp',\n bmp: 'image/bmp',\n svg: 'image/svg+xml',\n};\n\n/** Vertical space available below the title bar */\nfunction contentAreaInsets(node: SlideNode): { top: number; bottom: number } {\n return {\n top: node.title ? 0.3 + TITLE_H + 0.2 : 0.3,\n bottom: BOTTOM_MARGIN,\n };\n}\n\n/**\n * Split the element stream into rows (by row breaks), then each row\n * into columns (by col breaks). A slide with no breaks is one row of one column.\n */\nfunction splitGrid(elements: SlideElement[]): SlideElement[][][] {\n const rows: SlideElement[][] = [];\n let currentRow: SlideElement[] = [];\n\n for (const el of elements) {\n if (el.type === 'break' && el.direction === 'row') {\n rows.push(currentRow);\n currentRow = [];\n continue;\n }\n // col breaks and content stay in the row; col splitting happens next\n currentRow.push(el);\n }\n rows.push(currentRow);\n\n return rows.map((row) => {\n const columns: SlideElement[][] = [];\n let currentCol: SlideElement[] = [];\n for (const el of row) {\n if (el.type === 'break' && el.direction === 'col') {\n columns.push(currentCol);\n currentCol = [];\n continue;\n }\n currentCol.push(el);\n }\n columns.push(currentCol);\n return columns;\n });\n}\n\nexport async function renderContentSlide(\n slide: PptxGenJS.Slide,\n node: SlideNode,\n theme: Theme,\n ctx: RenderContext,\n): Promise<void> {\n const { top } = contentAreaInsets(node);\n\n // Title bar\n if (node.title) {\n slide.addShape('rect' as PptxGenJS.ShapeType, {\n x: MARGIN,\n y: 0.3 + TITLE_H - 0.05,\n w: CONTENT_W,\n h: 0.04,\n fill: { color: theme.colors.primary },\n });\n\n slide.addText(node.title, {\n x: MARGIN,\n y: 0.3,\n w: CONTENT_W,\n h: TITLE_H,\n fontSize: theme.fontSize.heading,\n fontFace: theme.fonts.heading,\n color: theme.colors.primary,\n bold: true,\n valign: 'bottom',\n });\n }\n\n const grid = splitGrid(prepareElements(node));\n const rows = grid.length;\n const availH = SLIDE_H - top - BOTTOM_MARGIN - GRID_GAP * (rows - 1);\n\n // Rows are sized by estimated content weight (like flexbox), not evenly —\n // a row with one short line shouldn't eat half the slide. Shrunk to fit.\n const ests = grid.map((columns) =>\n Math.max(\n 0.8,\n ...columns.map((c) => estimateColumnHeight(c, (CONTENT_W - GRID_GAP * (columns.length - 1)) / columns.length)),\n ),\n );\n const totalEst = ests.reduce((a, b) => a + b, 0);\n const scale = totalEst > availH ? availH / totalEst : 1;\n\n let y = top;\n for (let r = 0; r < rows; r++) {\n const columns = grid[r];\n const cols = columns.length;\n const colW = (CONTENT_W - GRID_GAP * (cols - 1)) / cols;\n const rowH = ests[r] * scale;\n\n for (let c = 0; c < cols; c++) {\n await renderColumn(\n slide,\n columns[c],\n { x: MARGIN + c * (colW + GRID_GAP), y, w: colW, h: rowH },\n node,\n theme,\n ctx,\n );\n }\n y += rowH + GRID_GAP;\n }\n}\n\n/**\n * Rewrites the slide's elements for rendering:\n * - @(chart=...) converts the first table into an echarts diagram so that\n * layout estimation treats it as an image (big row) instead of a table.\n */\nfunction prepareElements(node: SlideNode): SlideElement[] {\n const chart = node.directives?.chart;\n if (!chart) return node.elements;\n\n const elements = [...node.elements];\n const idx = elements.findIndex((e) => e.type === 'table');\n if (idx === -1) return elements;\n\n const table = elements[idx] as Extract<SlideElement, { type: 'table' }>;\n try {\n elements[idx] = {\n type: 'diagram',\n diagramType: 'echarts',\n content: tableToChartOption(table, chart),\n };\n } catch {\n // Invalid chart table — fall through to rendering as a table\n }\n return elements;\n}\n\n/** Estimate wrapped text lines for a string in a column of width w (inches). */\nfunction estimateTextLines(content: string, w: number): number {\n const charsPerLine = Math.max(20, Math.floor(w * 60));\n return Math.max(1, Math.ceil(content.length / charsPerLine));\n}\n\n/** Cheap height estimate for a column of elements (inches). */\nfunction estimateColumnHeight(elements: SlideElement[], w: number): number {\n let h = 0;\n for (const el of elements) {\n switch (el.type) {\n case 'text':\n h += Math.max(0.5, Math.ceil(el.content.length / Math.max(20, Math.floor(w * 60))) * 0.35);\n break;\n case 'heading':\n h += 0.7;\n break;\n case 'list':\n h += el.items.length * 0.5;\n break;\n case 'code':\n h += Math.max(1.0, el.content.split('\\n').length * 0.25);\n break;\n case 'diagram':\n case 'image':\n // Most diagrams are wide (aspect ~1.5-3:1); assume ~2:1 and let the\n // actual render down-scale. Enough height to look deliberate.\n // Explicit image sizes are honored so a small icon doesn't eat the row.\n if (el.type === 'image' && el.height && !el.height.endsWith('%')) {\n h += parseFloat(el.height) + 0.2;\n } else if (el.type === 'image' && el.width && !el.width.endsWith('%')) {\n h += parseFloat(el.width) * 0.5 + 0.2;\n } else {\n h += Math.min(4.5, Math.max(1.2, w * 0.5));\n }\n break;\n case 'table':\n h += (el.rows.length + 1) * 0.4;\n break;\n case 'callout':\n // Same adaptive sizing as the renderer: label row + one line per wrap\n h += Math.min(4.5, 0.72 + estimateTextLines(el.content, w) * 0.3);\n break;\n case 'blockquote':\n h += 1.0;\n break;\n case 'break':\n break;\n default:\n h += 0.5;\n }\n }\n return h;\n}\n\ninterface Box {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\n/** Render a stream of elements inside a fixed box; content exceeding the box is clipped (kept simple). */\nasync function renderColumn(\n slide: PptxGenJS.Slide,\n elements: SlideElement[],\n box: Box,\n node: SlideNode,\n theme: Theme,\n ctx: RenderContext,\n): Promise<void> {\n // Vertically center content that is shorter than its grid cell — a\n // two-line column next to a diagram shouldn't hug the row's top edge.\n const est = estimateColumnHeight(elements, box.w);\n const yPos = box.h > est ? box.y + (box.h - est) / 2 : box.y;\n let cursor = yPos;\n for (const element of elements) {\n const consumed = await renderElement(slide, element, cursor, box, node, theme, ctx);\n cursor += consumed;\n }\n}\n\nasync function renderElement(\n slide: PptxGenJS.Slide,\n element: SlideElement,\n yPos: number,\n box: Box,\n node: SlideNode,\n theme: Theme,\n ctx: RenderContext,\n): Promise<number> {\n const { x, w } = box;\n const maxH = Math.max(0.5, box.y + box.h - yPos);\n\n switch (element.type) {\n case 'text': {\n if (!element.content.trim()) return 0;\n slide.addText(element.content, {\n x,\n y: yPos,\n w,\n h: 0.6,\n fontSize: theme.fontSize.body,\n fontFace: theme.fonts.body,\n color: theme.colors.text,\n bold: element.bold,\n italic: element.italic,\n valign: 'top',\n wrap: true,\n });\n // Rough estimate: ~0.5 inch per 80 chars (scaled to column width)\n const charsPerLine = Math.max(20, Math.floor(w * 60));\n const lines = Math.ceil(element.content.length / charsPerLine);\n return Math.max(0.5, lines * 0.35);\n }\n\n case 'heading': {\n slide.addText(element.content, {\n x,\n y: yPos,\n w,\n h: 0.6,\n fontSize: theme.fontSize.heading - (element.level - 2) * 4,\n fontFace: theme.fonts.heading,\n color: theme.colors.primary,\n bold: true,\n });\n return 0.7;\n }\n\n case 'list': {\n const items = element.items.map((item, i) => {\n const checked = element.checked?.[i];\n const isTask = checked !== undefined;\n let text = item;\n const options: Record<string, unknown> = {\n // Task items have no bullet, so they need an explicit break line;\n // bulleted items break lines on their own.\n breakLine: isTask ? true : undefined,\n bullet: element.ordered\n ? { type: 'number' as const, startAt: i + 1 }\n : isTask\n ? false\n : true,\n color: theme.colors.text,\n fontSize: theme.fontSize.body,\n fontFace: theme.fonts.body,\n paraSpaceBefore: 4,\n paraSpaceAfter: 4,\n };\n if (isTask) {\n // Task list: prefix glyph, done items get muted color\n text = `${checked ? '☑' : '☐'} ${item}`;\n if (checked) options.color = theme.colors.secondary;\n }\n return { text, options };\n });\n\n const height = Math.max(0.8, Math.min(maxH, items.length * 0.5));\n slide.addText(items as PptxGenJS.TextProps[], {\n x,\n y: yPos,\n w,\n h: height,\n valign: 'top',\n });\n return height + 0.15;\n }\n\n case 'code': {\n const runs = await ctx.highlightCode(\n element.content,\n element.language ?? 'text',\n element.highlightLines,\n );\n const lines = element.content.split('\\n').length;\n const height = Math.min(maxH, Math.max(1.0, lines * 0.25));\n\n slide.addText(runs, {\n x,\n y: yPos,\n w,\n h: height,\n fill: { color: theme.colors.codeBackground },\n fontFace: theme.fonts.code,\n fontSize: theme.fontSize.code,\n color: theme.colors.codeText,\n valign: 'top',\n margin: [8, 12, 8, 12],\n });\n return height + 0.2;\n }\n\n case 'diagram': {\n try {\n const pngBuffer = await ctx.renderDiagram(element.diagramType, element.content);\n // Diagrams can be very wide (graphviz chains) or very tall (mermaid\n // flows) — scale into the box, aspect preserved.\n const imgSize = getPngSize(pngBuffer) ?? { width: 8, height: 3.5 };\n const boxH = Math.max(1.2, maxH);\n const fitted = fitInBox(imgSize, w, boxH);\n const base64 = pngBuffer.toString('base64');\n\n slide.addImage({\n data: `image/png;base64,${base64}`,\n x: x + (w - fitted.width) / 2,\n y: yPos,\n w: fitted.width,\n h: fitted.height,\n });\n return fitted.height + 0.2;\n } catch (err) {\n slide.addText(`[Diagram render error: ${err instanceof Error ? err.message : 'unknown'}]`, {\n x,\n y: yPos,\n w,\n h: 0.5,\n fontSize: theme.fontSize.small,\n color: 'FF0000',\n italic: true,\n });\n return 0.6;\n }\n }\n\n case 'image': {\n try {\n const resolved = await ctx.resolveImage(element.src);\n if (!resolved.ok) {\n log.warn(`[${node.title ?? 'slide'}] ${resolved.error}`);\n return 0;\n }\n const imgSize = getPngSize(readFileSync(resolved.path)) ?? { width: 6, height: 3.0 };\n const boxH = Math.max(1.2, maxH);\n const placed = fitImageWithOptions(\n imgSize,\n { width: w, height: boxH },\n { width: element.width, height: element.height, align: element.align },\n );\n // Base64 data (not a path): avoids pptxgenjs' Node-vs-browser media\n // encoding, which crashes under ESM hosts (no `require` → XHR path).\n const ext = resolved.path.split('.').pop()?.toLowerCase() ?? 'png';\n const mime = IMAGE_MIME[ext] ?? 'image/png';\n const data = `${mime};base64,${readFileSync(resolved.path).toString('base64')}`;\n slide.addImage({\n data,\n path: 'preencoded.png',\n x: x + placed.x,\n y: yPos,\n w: placed.width,\n h: placed.height,\n });\n return placed.height + 0.2;\n } catch (err) {\n log.warn(\n `Failed to embed image ${element.src}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n return 0;\n }\n\n case 'table': {\n const headerRow = element.headers.map((h) => ({\n text: h,\n options: {\n bold: true,\n color: 'FFFFFF',\n fill: { color: theme.colors.primary },\n fontSize: theme.fontSize.body - 2,\n fontFace: theme.fonts.body,\n align: 'center' as const,\n border: { type: 'solid' as const, pt: 0.5, color: theme.colors.primary },\n },\n }));\n\n const bodyRows = element.rows.map((row) =>\n row.map((cell) => ({\n text: cell,\n options: {\n fontSize: theme.fontSize.body - 2,\n fontFace: theme.fonts.body,\n color: theme.colors.text,\n border: { type: 'solid' as const, pt: 0.5, color: 'D1D5DB' },\n },\n })),\n );\n\n const allRows = [headerRow, ...bodyRows];\n const tableH = Math.min(maxH, allRows.length * 0.4);\n\n slide.addTable(allRows as PptxGenJS.TableRow[], {\n x,\n y: yPos,\n w,\n h: tableH,\n colW: Array(element.headers.length).fill(w / element.headers.length),\n margin: [4, 6, 4, 6],\n border: { type: 'solid', pt: 0.5, color: 'D1D5DB' },\n autoPage: false,\n });\n return tableH + 0.2;\n }\n\n case 'blockquote': {\n // Left accent border + italic text\n slide.addShape('rect' as PptxGenJS.ShapeType, {\n x,\n y: yPos,\n w: 0.06,\n h: Math.min(0.8, maxH),\n fill: { color: theme.colors.accent },\n });\n\n slide.addText(element.content, {\n x: x + 0.2,\n y: yPos,\n w: w - 0.2,\n h: Math.min(0.8, maxH),\n fontSize: theme.fontSize.body,\n fontFace: theme.fonts.body,\n color: theme.colors.secondary,\n italic: true,\n valign: 'middle',\n });\n return 1.0;\n }\n\n case 'callout': {\n const palette: Record<string, string> = {\n note: theme.colors.primary,\n info: theme.colors.primary,\n tip: theme.colors.accent,\n success: theme.colors.accent,\n warning: 'EAB308',\n caution: 'EAB308',\n danger: 'DC2626',\n };\n const color = palette[element.variant] ?? theme.colors.primary;\n const label = element.title ?? element.variant.toUpperCase();\n\n // Card height adapts to content: label row + one line per wrapped line\n const textLines = estimateTextLines(element.content, w);\n const cardH = Math.min(maxH, 0.72 + textLines * 0.3);\n const textH = cardH - 0.44;\n\n // Soft background + left accent bar\n slide.addShape('roundRect' as PptxGenJS.ShapeType, {\n x,\n y: yPos,\n w,\n h: cardH,\n fill: { color, transparency: 88 },\n line: { color, width: 0.75, transparency: 70 },\n rectRadius: 0.08,\n });\n slide.addShape('rect' as PptxGenJS.ShapeType, {\n x,\n y: yPos + 0.12,\n w: 0.07,\n h: cardH - 0.24,\n fill: { color },\n });\n\n slide.addText(label, {\n x: x + 0.2,\n y: yPos + 0.08,\n w: w - 0.4,\n h: 0.3,\n fontSize: theme.fontSize.small,\n fontFace: theme.fonts.heading,\n color,\n bold: true,\n });\n slide.addText(element.content, {\n x: x + 0.2,\n y: yPos + 0.4,\n w: w - 0.4,\n h: textH,\n fontSize: theme.fontSize.body - 1,\n fontFace: theme.fonts.body,\n color: theme.colors.text,\n valign: 'top',\n wrap: true,\n });\n return cardH + 0.1;\n }\n\n default:\n return 0;\n }\n}\n","/**\n * Code-focused slide layout\n */\n\nimport PptxGenJS from 'pptxgenjs';\nimport type { SlideNode } from '../../models/slide.js';\nimport type { Theme } from '../../models/theme.js';\nimport type { RenderContext } from './index.js';\n\nexport async function renderCodeSlide(\n slide: PptxGenJS.Slide,\n node: SlideNode,\n theme: Theme,\n ctx: RenderContext,\n): Promise<void> {\n let yPos = 0.3;\n\n // Title\n if (node.title) {\n slide.addText(node.title, {\n x: 0.5,\n y: yPos,\n w: 12.3,\n h: 0.7,\n fontSize: theme.fontSize.heading,\n fontFace: theme.fonts.heading,\n color: theme.colors.primary,\n bold: true,\n });\n yPos += 0.9;\n }\n\n // Code blocks\n for (const element of node.elements) {\n if (element.type === 'code') {\n const runs = await ctx.highlightCode(\n element.content,\n element.language ?? 'text',\n element.highlightLines,\n );\n\n slide.addText(runs, {\n x: 0.5,\n y: yPos,\n w: 12.3,\n h: 7.5 - yPos - 0.5,\n fill: { color: theme.colors.codeBackground },\n color: theme.colors.codeText,\n fontFace: theme.fonts.code,\n fontSize: theme.fontSize.code,\n valign: 'top',\n paraSpaceAfter: 2,\n margin: [10, 15, 10, 15],\n });\n yPos += 5.0;\n }\n }\n}\n","/**\n * Quote slide layout\n */\n\nimport PptxGenJS from 'pptxgenjs';\nimport type { SlideNode } from '../../models/slide.js';\nimport type { Theme } from '../../models/theme.js';\n\nexport function renderQuoteSlide(\n slide: PptxGenJS.Slide,\n node: SlideNode,\n theme: Theme,\n): void {\n // Big opening quote mark\n slide.addText('\\u201C', {\n x: 1.5,\n y: 1.0,\n w: 2.0,\n h: 1.5,\n fontSize: 72,\n fontFace: 'Georgia',\n color: theme.colors.accent,\n bold: true,\n });\n\n // Quote text\n const quoteElement = node.elements.find((e) => e.type === 'blockquote');\n if (quoteElement && quoteElement.type === 'blockquote') {\n let quoteText = quoteElement.content;\n let attribution = '';\n\n // Extract attribution (— Author pattern)\n const attrMatch = quoteText.match(/\\n?\\s*[—\\u2014-]\\s*(.+)$/);\n if (attrMatch) {\n attribution = attrMatch[1].trim();\n quoteText = quoteText.slice(0, attrMatch.index).trim();\n }\n\n slide.addText(quoteText, {\n x: 1.8,\n y: 2.5,\n w: 9.7,\n h: 2.5,\n fontSize: theme.fontSize.heading,\n fontFace: theme.fonts.body,\n color: theme.colors.text,\n italic: true,\n align: 'center',\n valign: 'middle',\n });\n\n // Attribution\n if (attribution) {\n slide.addText(`— ${attribution}`, {\n x: 1.8,\n y: 5.2,\n w: 9.7,\n h: 0.6,\n fontSize: theme.fontSize.body,\n fontFace: theme.fonts.body,\n color: theme.colors.secondary,\n align: 'right',\n });\n }\n }\n}\n","/**\n * Layout Registry\n * Routes SlideNode to the correct layout renderer\n */\n\nimport PptxGenJS from 'pptxgenjs';\nimport type { SlideNode } from '../../models/slide.js';\nimport type { Theme } from '../../models/theme.js';\nimport type { ImageResolution } from '../image-handler.js';\nimport { log } from '../../utils/progress.js';\nimport { renderTitleSlide } from './title.js';\nimport { renderSectionSlide } from './section.js';\nimport { renderContentSlide } from './content.js';\nimport { renderCodeSlide } from './code.js';\nimport { renderQuoteSlide } from './quote.js';\n\n/** Context passed to layout renderers for async operations */\nexport interface RenderContext {\n highlightCode: (code: string, language: string, highlightLines?: number[]) => Promise<PptxGenJS.TextProps[]>;\n resolveImage: (src: string) => Promise<ImageResolution>;\n renderDiagram: (diagramType: string, code: string) => Promise<Buffer>;\n /** Page footer template with {page}/{total}/{section}/{title} placeholders */\n footerTemplate?: string;\n pageNumber?: number;\n totalSlides?: number;\n /** Title of the most recent section layout slide ({section} placeholder) */\n currentSection?: string;\n}\n\n/**\n * Render a slide using the appropriate layout\n */\nexport async function renderSlideLayout(\n slide: PptxGenJS.Slide,\n node: SlideNode,\n theme: Theme,\n ctx: RenderContext,\n): Promise<void> {\n // @(background=...) overrides the slide's background (image or theme color)\n if (node.directives?.background) {\n const resolved = await ctx.resolveImage(node.directives.background);\n if (resolved.ok && resolved.path) {\n slide.background = { path: resolved.path };\n } else if (node.directives.background.startsWith('#')) {\n slide.background = { color: node.directives.background.replace(/^#/, '') };\n } else if (!resolved.ok) {\n log.warn(`[${node.title ?? 'slide'}] ${resolved.error}`);\n }\n }\n\n switch (node.layout) {\n case 'title':\n renderTitleSlide(slide, node, theme);\n break;\n\n case 'section':\n renderSectionSlide(slide, node, theme);\n break;\n\n case 'code':\n await renderCodeSlide(slide, node, theme, ctx);\n break;\n\n case 'quote':\n renderQuoteSlide(slide, node, theme);\n break;\n\n case 'content':\n default:\n await renderContentSlide(slide, node, theme, ctx);\n break;\n }\n\n // Add speaker notes if present\n if (node.notes) {\n slide.addNotes(node.notes);\n }\n\n // Footer / page number (skip cover slides)\n if (node.layout !== 'title' && node.layout !== 'closing' && node.layout !== 'blank') {\n const footerText = renderFooter(node, theme, ctx);\n if (footerText) {\n slide.addText(footerText, {\n x: 0.6,\n y: 7.16,\n w: 12.13,\n h: 0.28,\n fontSize: theme.fontSize.small - 1,\n fontFace: theme.fonts.body,\n color: theme.colors.secondary,\n align: 'right',\n valign: 'middle',\n });\n }\n }\n}\n\n/** Compose the per-slide footer line from context (section tracking + config footer) */\nfunction renderFooter(node: SlideNode, theme: Theme, ctx: RenderContext): string {\n const template = ctx.footerTemplate;\n if (!template) return '';\n return template\n .replace('{page}', String(ctx.pageNumber))\n .replace('{total}', String(ctx.totalSlides))\n .replace('{section}', ctx.currentSection || '')\n .replace('{title}', node.title ?? '');\n}\n","/**\n * Code Highlighter\n * Uses Shiki for token-level syntax highlighting → pptxgenjs text runs\n */\n\nimport { createHighlighter, type Highlighter } from 'shiki';\nimport type { Theme } from '../models/theme.js';\n\ninterface PptxTextRun {\n text: string;\n options: {\n color?: string;\n fontFace?: string;\n fontSize?: number;\n bold?: boolean;\n italic?: boolean;\n highlight?: string;\n };\n}\n\nlet highlighterInstance: Highlighter | null = null;\n\nasync function getHighlighter(): Promise<Highlighter> {\n if (!highlighterInstance) {\n highlighterInstance = await createHighlighter({\n themes: ['github-dark', 'dracula'],\n langs: [\n 'javascript', 'typescript', 'python', 'java', 'c', 'cpp', 'csharp',\n 'go', 'rust', 'ruby', 'php', 'swift', 'kotlin', 'bash', 'shell',\n 'sql', 'html', 'css', 'json', 'yaml', 'markdown', 'xml', 'docker',\n ],\n });\n }\n return highlighterInstance;\n}\n\n/**\n * Strip '#' prefix from hex color\n */\nfunction cleanColor(color: string | undefined): string {\n if (!color) return 'E2E8F0';\n return color.replace(/^#/, '');\n}\n\n/**\n * Highlight code and return pptxgenjs text runs\n * @param highlightLines 1-based line numbers drawn with a highlight background\n */\nexport async function highlightCode(\n code: string,\n language: string,\n theme: Theme,\n highlightLines: number[] = [],\n): Promise<PptxTextRun[]> {\n const highlighter = await getHighlighter();\n const runs: PptxTextRun[] = [];\n const shikiThemeName = theme.shikiTheme ?? 'github-dark';\n const highlightColor = theme.colors.highlightBackground ?? 'FFF3C4';\n\n try {\n // Load language if not already loaded\n const loadedLangs = highlighter.getLoadedLanguages();\n if (!loadedLangs.includes(language as never)) {\n try {\n await highlighter.loadLanguage(language as never);\n } catch {\n // Language not supported — fall back to plain text\n return [\n {\n text: code,\n options: {\n color: theme.colors.codeText,\n fontFace: theme.fonts.code,\n fontSize: theme.fontSize.code,\n },\n },\n ];\n }\n }\n\n // Load theme if not loaded\n const loadedThemes = highlighter.getLoadedThemes();\n if (!loadedThemes.includes(shikiThemeName as never)) {\n try {\n await highlighter.loadTheme(shikiThemeName as never);\n } catch {\n // Theme not supported — use github-dark fallback\n }\n }\n\n const effectiveTheme = highlighter.getLoadedThemes().includes(shikiThemeName as never)\n ? shikiThemeName\n : 'github-dark';\n\n const result = highlighter.codeToTokens(code, {\n lang: language as never,\n theme: effectiveTheme,\n });\n\n for (let i = 0; i < result.tokens.length; i++) {\n const lineNumber = i + 1;\n const line = result.tokens[i];\n const isHighlighted = highlightLines.includes(lineNumber);\n for (const token of line) {\n const options: PptxTextRun['options'] = {\n color: cleanColor(token.color),\n fontFace: theme.fonts.code,\n fontSize: theme.fontSize.code,\n };\n if (isHighlighted) {\n options.highlight = highlightColor;\n }\n runs.push({ text: token.content, options });\n }\n // Add line break between lines (except last)\n if (i < result.tokens.length - 1) {\n runs.push({\n text: '\\n',\n options: {\n fontFace: theme.fonts.code,\n fontSize: theme.fontSize.code,\n },\n });\n }\n }\n } catch {\n // Fallback: plain text\n runs.push({\n text: code,\n options: {\n color: theme.colors.codeText,\n fontFace: theme.fonts.code,\n fontSize: theme.fontSize.code,\n },\n });\n }\n\n return runs;\n}\n","/**\n * Image Handler\n * Resolves and downloads images for embedding in PPTX\n */\n\nimport { existsSync, writeFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport { randomUUID } from 'node:crypto';\n\n/** Outcome of resolving an image source. Failure carries a human-readable reason. */\nexport type ImageResolution =\n | { ok: true; path: string }\n | { ok: false; error: string };\n\nconst REMOTE_FETCH_TIMEOUT_MS = 10_000;\n\n/**\n * Resolve an image source to a local file path or base64 data\n * Never throws — failures are returned as { ok: false, error }.\n */\nexport async function resolveImage(\n src: string,\n basePath: string,\n): Promise<ImageResolution> {\n try {\n // data: URI\n if (src.startsWith('data:')) {\n const match = src.match(/^data:image\\/(\\w+);base64,(.+)/);\n if (match) {\n const ext = match[1];\n const base64 = match[2];\n const tmpPath = join(tmpdir(), `mfly-${randomUUID().slice(0, 8)}.${ext}`);\n writeFileSync(tmpPath, Buffer.from(base64, 'base64'));\n return { ok: true, path: tmpPath };\n }\n return { ok: false, error: `Unsupported data URI: ${src.slice(0, 48)}` };\n }\n\n // URL (http/https)\n if (src.startsWith('http://') || src.startsWith('https://')) {\n let response: Response;\n try {\n response = await fetch(src, { signal: AbortSignal.timeout(REMOTE_FETCH_TIMEOUT_MS) });\n } catch (err) {\n const name = err instanceof Error ? err.name : '';\n const reason = name === 'TimeoutError' || name === 'AbortError'\n ? `request timed out after ${REMOTE_FETCH_TIMEOUT_MS / 1000}s`\n : err instanceof Error ? err.message : String(err);\n return { ok: false, error: `Failed to fetch ${src}: ${reason}` };\n }\n if (!response.ok) {\n return { ok: false, error: `Failed to fetch ${src}: HTTP ${response.status}` };\n }\n\n const buffer = Buffer.from(await response.arrayBuffer());\n const ext = src.split('.').pop()?.split('?')[0] ?? 'png';\n const tmpPath = join(tmpdir(), `mfly-${randomUUID().slice(0, 8)}.${ext}`);\n writeFileSync(tmpPath, buffer);\n return { ok: true, path: tmpPath };\n }\n\n // Local file path (basePath is always a directory)\n const absolutePath = resolve(basePath, src);\n if (existsSync(absolutePath)) {\n return { ok: true, path: absolutePath };\n }\n\n return { ok: false, error: `Image not found: ${src} (resolved to ${absolutePath})` };\n } catch (err) {\n return {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n}\n","/**\n * SVG to PNG conversion using @resvg/resvg-js (native N-API binding)\n */\n\n/**\n * Normalize SVG string to guarantee valid dimensions and viewBox for Resvg\n */\nfunction normalizeSvg(svg: string): string {\n let clean = svg.trim();\n\n // Ensure xmlns\n if (!clean.includes('xmlns=')) {\n clean = clean.replace(/<svg\\b([^>]*)>/i, '<svg xmlns=\"http://www.w3.org/2000/svg\" $1>');\n }\n\n // Remove existing width and height attributes (with any units pt/px/%/em) to prevent duplicates or percentage panics\n clean = clean.replace(/(<svg\\b[^>]*)\\s+width=[\"'][^\"']*[\"']/gi, '$1');\n clean = clean.replace(/(<svg\\b[^>]*)\\s+height=[\"'][^\"']*[\"']/gi, '$1');\n\n // Strip SVG marker definitions and references that cause Rust panics in Resvg's geom.rs\n clean = clean.replace(/<marker\\b[\\s\\S]*?<\\/marker>/gi, '');\n clean = clean.replace(/\\s+marker-(end|start|mid)=[\"'][^\"']*[\"']/gi, '');\n\n // Check for viewBox\n const viewBoxMatch = clean.match(/viewBox\\s*=\\s*[\"']([^\"']+)[\"']/i);\n\n if (viewBoxMatch) {\n const parts = viewBoxMatch[1].trim().split(/[\\s,]+/).map(Number);\n if (parts.length === 4 && parts[2] > 0 && parts[3] > 0) {\n const w = parts[2];\n const h = parts[3];\n clean = clean.replace(/<svg\\b([^>]*)>/i, `<svg width=\"${w}\" height=\"${h}\" $1>`);\n }\n } else {\n clean = clean.replace(/<svg\\b([^>]*)>/i, `<svg width=\"800\" height=\"600\" viewBox=\"0 0 800 600\" $1>`);\n }\n\n return clean;\n}\n\n/**\n * Convert SVG string to PNG Buffer\n * @resvg/resvg-js is a native addon — loaded lazily so that runs without\n * diagrams (or on platforms lacking the prebuilt binary) never touch it.\n */\nexport async function svgToPng(svg: string, width: number = 800): Promise<Buffer> {\n const normalized = normalizeSvg(svg);\n const { Resvg } = await import('@resvg/resvg-js');\n const resvg = new Resvg(normalized, {\n fitTo: { mode: 'width' as const, value: width },\n });\n const pngData = resvg.render();\n return Buffer.from(pngData.asPng());\n}\n","/**\n * Diagram theme helpers\n * Shared between mermaid/dot renderers so diagrams follow the presentation theme\n */\n\nimport type { Theme } from '../models/theme.js';\n\n/**\n * True when the theme background is dark (perceived luminance below 50%)\n */\nexport function isDarkColor(hex: string): boolean {\n const clean = hex.replace(/^#/, '');\n if (clean.length < 6) return false;\n const r = parseInt(clean.slice(0, 2), 16);\n const g = parseInt(clean.slice(2, 4), 16);\n const b = parseInt(clean.slice(4, 6), 16);\n if ([r, g, b].some((n) => Number.isNaN(n))) return false;\n return 0.299 * r + 0.587 * g + 0.114 * b < 128;\n}\n\nexport function isDarkTheme(theme?: Theme): boolean {\n return theme ? isDarkColor(theme.colors.background) : false;\n}\n\n/**\n * Font stack for diagram text: prefers the theme's CJK font so Chinese labels\n * do not fall back to a Latin-only face, e.g. `\"微软雅黑\", \"Segoe UI\", sans-serif`\n */\nexport function diagramFontFamily(theme?: Theme): string {\n if (!theme) return '\"trebuchet ms\", sans-serif';\n return `\"${theme.fonts.cjk}\", \"${theme.fonts.body}\", sans-serif`;\n}\n","/**\n * Mermaid Diagram Renderer\n * Uses mermaid + jsdom to render diagrams to SVG in Node.js\n */\n\nimport type { DiagramRenderer } from './renderer.js';\nimport type { Theme } from '../models/theme.js';\nimport { svgToPng } from './svg-to-png.js';\nimport { isDarkTheme, diagramFontFamily } from './theme.js';\n\nlet initialized = false;\n\n// ---------------------------------------------------------------------------\n// SVG geometry measurement\n//\n// jsdom has no layout engine, so every getBBox() mermaid relies on is a fake.\n// Mermaid sizes its output via `svg.getBBox()` on the root <svg> (its\n// `setupGraphViewbox`), which previously returned a constant 80x40 — far\n// smaller than the actual drawing — so the produced viewBox was tiny and the\n// rasterized PNG turned into a huge zoomed crop (the \"giant purple box\" bug).\n// The polyfills below measure REAL geometry (rect/path/circle/line/... with\n// translate/rotate/scale chains) for the root <svg>; other elements keep the\n// old text heuristics because mermaid's internal node layout already works\n// with them.\n// ---------------------------------------------------------------------------\n\ntype Matrix = [number, number, number, number, number, number];\n\nconst IDENTITY: Matrix = [1, 0, 0, 1, 0, 0];\n\nconst SKIP_TAGS = new Set([\n 'style', 'script', 'defs', 'clippath', 'marker', 'filter', 'mask', 'pattern', 'foreignobject',\n]);\n\n/** 2x3 affine multiply: result = m1·m2 (right operand applies to points first) */\nfunction mul(m1: Matrix, m2: Matrix): Matrix {\n return [\n m1[0] * m2[0] + m1[2] * m2[1],\n m1[1] * m2[0] + m1[3] * m2[1],\n m1[0] * m2[2] + m1[2] * m2[3],\n m1[1] * m2[2] + m1[3] * m2[3],\n m1[0] * m2[4] + m1[2] * m2[5] + m1[4],\n m1[1] * m2[4] + m1[3] * m2[5] + m1[5],\n ];\n}\n\nfunction parseTransform(attr: string | null): Matrix {\n if (!attr) return IDENTITY;\n let m: Matrix = IDENTITY;\n const re = /([a-zA-Z]+)\\s*\\(([^)]*)\\)/g;\n let mt: RegExpExecArray | null;\n while ((mt = re.exec(attr))) {\n const name = mt[1];\n const args = mt[2].trim().split(/[\\s,]+/).filter(Boolean).map(Number);\n if (args.some((n) => !Number.isFinite(n))) continue;\n let next: Matrix | null = null;\n switch (name) {\n case 'matrix':\n if (args.length >= 6) next = [args[0], args[1], args[2], args[3], args[4], args[5]];\n break;\n case 'translate':\n next = [1, 0, 0, 1, args[0] || 0, args[1] || 0];\n break;\n case 'scale': {\n const sx = args[0] || 1;\n const sy = args.length > 1 ? args[1] || 1 : sx;\n next = [sx, 0, 0, sy, 0, 0];\n break;\n }\n case 'rotate': {\n const rad = ((args[0] || 0) * Math.PI) / 180;\n const cos = Math.cos(rad);\n const sin = Math.sin(rad);\n const rot: Matrix = [cos, sin, -sin, cos, 0, 0];\n next =\n args.length >= 3\n ? mul(mul([1, 0, 0, 1, args[1], args[2]], rot), [1, 0, 0, 1, -args[1], -args[2]])\n : rot;\n break;\n }\n case 'skewX':\n next = [1, 0, Math.tan((args[0] || 0) * Math.PI / 180), 1, 0, 0];\n break;\n case 'skewY':\n next = [1, Math.tan((args[0] || 0) * Math.PI / 180), 0, 1, 0, 0];\n break;\n }\n if (next) m = mul(m, next);\n }\n return m;\n}\n\nfunction expandedBox(m: Matrix, b: { x: number; y: number; width: number; height: number }) {\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n const pts = [\n [b.x, b.y],\n [b.x + b.width, b.y],\n [b.x, b.y + b.height],\n [b.x + b.width, b.y + b.height],\n ];\n for (const [px, py] of pts) {\n const x = m[0] * px + m[2] * py + m[4];\n const y = m[1] * px + m[3] * py + m[5];\n if (x < minX) minX = x;\n if (y < minY) minY = y;\n if (x > maxX) maxX = x;\n if (y > maxY) maxY = y;\n }\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n}\n\n/** Rough text width: CJK chars ≈ 1em, others ≈ 0.55em (mermaid default 16px) */\nfunction textWidth(el: Element): number {\n let width = 0;\n const collect = (e: Element): void => {\n for (const child of Array.from(e.childNodes)) {\n if (child.nodeType === 3) {\n for (const ch of child.textContent ?? '') {\n width += (ch.codePointAt(0) ?? 0) > 0x2e80 ? 16 : 9;\n }\n } else if (child.nodeType === 1) {\n collect(child as Element);\n }\n }\n };\n collect(el);\n return width;\n}\n\n/** Bounds of a path's geometry; control points included (over-estimate is safe) */\nfunction pathBounds(d: string): { x: number; y: number; width: number; height: number } | null {\n const re = /([a-zA-Z])|(-?\\d*\\.?\\d+(?:e[-+]?\\d+)?)/gi;\n const toks: Array<string | number> = [];\n let m: RegExpExecArray | null;\n while ((m = re.exec(d))) toks.push(m[1] ?? parseFloat(m[2]));\n\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n const add = (x: number, y: number): void => {\n if (x < minX) minX = x;\n if (y < minY) minY = y;\n if (x > maxX) maxX = x;\n if (y > maxY) maxY = y;\n };\n\n let i = 0;\n let x = 0;\n let y = 0;\n let sx = 0;\n let sy = 0;\n let lastCmd = '';\n let lastRel = false;\n const nums = (count: number): number[] | null => {\n const out: number[] = [];\n while (count-- > 0) {\n const t = toks[i++];\n if (typeof t !== 'number') return null;\n out.push(t);\n }\n return out;\n };\n\n while (i < toks.length) {\n let cmd = toks[i];\n let rel: boolean;\n if (typeof cmd === 'string') {\n rel = cmd === cmd.toLowerCase();\n cmd = cmd.toUpperCase();\n lastCmd = cmd;\n lastRel = rel;\n i++;\n } else {\n // Implicit repeat of the previous command (e.g. value pairs after M)\n cmd = lastCmd;\n rel = lastRel;\n }\n switch (cmd) {\n case 'M': {\n const v = nums(2);\n if (!v) return null;\n x = rel ? x + v[0] : v[0];\n y = rel ? y + v[1] : v[1];\n sx = x;\n sy = y;\n add(x, y);\n lastCmd = 'L'; // subsequent value pairs are implicit lineto\n lastRel = rel;\n break;\n }\n case 'L': {\n const v = nums(2);\n if (!v) return null;\n x = rel ? x + v[0] : v[0];\n y = rel ? y + v[1] : v[1];\n add(x, y);\n break;\n }\n case 'H': {\n const v = nums(1);\n if (!v) return null;\n x = rel ? x + v[0] : v[0];\n add(x, y);\n break;\n }\n case 'V': {\n const v = nums(1);\n if (!v) return null;\n y = rel ? y + v[0] : v[0];\n add(x, y);\n break;\n }\n case 'C': {\n const v = nums(6);\n if (!v) return null;\n // Control points are included; curves stay inside their convex hull\n add(rel ? x + v[0] : v[0], rel ? y + v[1] : v[1]);\n add(rel ? x + v[2] : v[2], rel ? y + v[3] : v[3]);\n x = rel ? x + v[4] : v[4];\n y = rel ? y + v[5] : v[5];\n add(x, y);\n break;\n }\n case 'S':\n case 'Q': {\n const v = nums(4);\n if (!v) return null;\n add(rel ? x + v[0] : v[0], rel ? y + v[1] : v[1]);\n x = rel ? x + v[2] : v[2];\n y = rel ? y + v[3] : v[3];\n add(x, y);\n break;\n }\n case 'T': {\n const v = nums(2);\n if (!v) return null;\n x = rel ? x + v[0] : v[0];\n y = rel ? y + v[1] : v[1];\n add(x, y);\n break;\n }\n case 'A': {\n const v = nums(7);\n if (!v) return null;\n x = rel ? x + v[5] : v[5];\n y = rel ? y + v[6] : v[6];\n add(x, y);\n break;\n }\n case 'Z':\n x = sx;\n y = sy;\n break;\n default:\n return null;\n }\n }\n if (!Number.isFinite(minX)) return null;\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n}\n\n/** Bounds of one element's own geometry, in its local coordinate space */\nfunction elementLocalBox(el: Element): { x: number; y: number; width: number; height: number } | null {\n const tag = el.tagName ? el.tagName.toLowerCase() : '';\n const num = (name: string): number => {\n const v = parseFloat(el.getAttribute(name) ?? '');\n return Number.isFinite(v) ? v : 0;\n };\n switch (tag) {\n case 'rect': {\n const w = num('width');\n const h = num('height');\n if (!(w > 0 && h > 0)) return null;\n return { x: num('x'), y: num('y'), width: w, height: h };\n }\n case 'circle': {\n const r = num('r');\n if (!(r > 0)) return null;\n return { x: num('cx') - r, y: num('cy') - r, width: 2 * r, height: 2 * r };\n }\n case 'ellipse': {\n const rx = num('rx');\n const ry = num('ry');\n if (!(rx > 0 && ry > 0)) return null;\n return { x: num('cx') - rx, y: num('cy') - ry, width: 2 * rx, height: 2 * ry };\n }\n case 'line': {\n const x1 = num('x1');\n const y1 = num('y1');\n const x2 = num('x2');\n const y2 = num('y2');\n return { x: Math.min(x1, x2), y: Math.min(y1, y2), width: Math.abs(x2 - x1), height: Math.abs(y2 - y1) };\n }\n case 'polygon':\n case 'polyline': {\n const pts = (el.getAttribute('points') ?? '').split(/[\\s,]+/).filter(Boolean).map(Number);\n if (pts.length < 4 || pts.some((n) => !Number.isFinite(n))) return null;\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for (let k = 0; k + 1 < pts.length; k += 2) {\n const px = pts[k];\n const py = pts[k + 1];\n if (px < minX) minX = px;\n if (py < minY) minY = py;\n if (px > maxX) maxX = px;\n if (py > maxY) maxY = py;\n }\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n }\n case 'path':\n return pathBounds(el.getAttribute('d') ?? '');\n case 'text':\n case 'tspan': {\n const w = textWidth(el);\n // Mermaid centers node labels (text-anchor: middle); degenerate (empty)\n // labels are dropped so they do not pollute the bounds\n if (w <= 4) return null;\n return { x: num('x') - w / 2, y: num('y') - 14, width: w, height: 24 };\n }\n default:\n return null;\n }\n}\n\n/** Union of all descendant geometry, expressed in the root element's space */\nfunction contentBBox(root: Element): { x: number; y: number; width: number; height: number } | null {\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n const accumulate = (b: { x: number; y: number; width: number; height: number }): void => {\n if (b.x < minX) minX = b.x;\n if (b.y < minY) minY = b.y;\n if (b.x + b.width > maxX) maxX = b.x + b.width;\n if (b.y + b.height > maxY) maxY = b.y + b.height;\n };\n const walk = (el: Element, m: Matrix): void => {\n for (const child of Array.from(el.children)) {\n const tag = child.tagName ? child.tagName.toLowerCase() : '';\n if (SKIP_TAGS.has(tag)) continue;\n const cm = mul(m, parseTransform(child.getAttribute('transform')));\n const local = elementLocalBox(child);\n if (local) {\n const b = expandedBox(cm, local);\n // Skip zero-area geometry (empty labels, straight lines) that would\n // only stretch the bounds by a point\n if (b.width > 0.5 || b.height > 0.5) accumulate(b);\n }\n walk(child, cm);\n }\n };\n walk(root, IDENTITY);\n if (!Number.isFinite(minX)) return null;\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n}\n\nexport class MermaidDiagramRenderer implements DiagramRenderer {\n readonly type = 'mermaid';\n private renderCounter = 0;\n\n async initialize(): Promise<void> {\n if (initialized) return;\n\n // Set up jsdom globals for mermaid\n const { JSDOM } = await import('jsdom');\n const dom = new JSDOM('<!DOCTYPE html><html><body></body></html>', {\n pretendToBeVisual: true,\n });\n\n // Mermaid requires browser globals\n const assignGlobal = (key: string, value: unknown) => {\n try {\n Object.defineProperty(globalThis, key, {\n value,\n configurable: true,\n writable: true,\n });\n } catch {\n (globalThis as Record<string, unknown>)[key] = value;\n }\n };\n\n assignGlobal('window', dom.window);\n assignGlobal('document', dom.window.document);\n assignGlobal('navigator', dom.window.navigator);\n assignGlobal('DOMParser', dom.window.DOMParser);\n assignGlobal('XMLSerializer', dom.window.XMLSerializer);\n assignGlobal('HTMLElement', dom.window.HTMLElement);\n assignGlobal('SVGElement', dom.window.SVGElement);\n assignGlobal('Element', dom.window.Element);\n assignGlobal('Node', dom.window.Node);\n assignGlobal('Text', dom.window.Text);\n assignGlobal('getComputedStyle', dom.window.getComputedStyle);\n assignGlobal('CustomEvent', dom.window.CustomEvent);\n assignGlobal('Event', dom.window.Event);\n assignGlobal('EventTarget', dom.window.EventTarget);\n assignGlobal('HTMLCollection', dom.window.HTMLCollection);\n assignGlobal('NodeList', dom.window.NodeList);\n assignGlobal('MutationObserver', dom.window.MutationObserver);\n\n // CSSStyleSheet polyfill / bind\n if (dom.window.CSSStyleSheet) {\n assignGlobal('CSSStyleSheet', dom.window.CSSStyleSheet);\n } else {\n class MockCSSStyleSheet {\n cssRules = [];\n insertRule() { return 0; }\n deleteRule() {}\n replaceSync() {}\n replace() { return Promise.resolve(this); }\n }\n assignGlobal('CSSStyleSheet', MockCSSStyleSheet);\n }\n\n // Extract text from direct text nodes or text elements, ignoring <style> and <script>\n const getDirectText = (el: Element): string => {\n const tag = el.tagName ? el.tagName.toLowerCase() : '';\n if (tag === 'style' || tag === 'script' || tag === 'defs' || tag === 'marker') return '';\n let text = '';\n for (const child of Array.from(el.childNodes)) {\n if (child.nodeType === 3) {\n text += child.textContent || '';\n } else if (child.nodeType === 1) {\n const ctag = (child as Element).tagName.toLowerCase();\n if (ctag === 'tspan' || ctag === 'text' || ctag === 'span' || ctag === 'div' || ctag === 'p') {\n text += getDirectText(child as Element);\n }\n }\n }\n return text;\n };\n\n const toRect = (b: { x: number; y: number; width: number; height: number }) => ({\n x: b.x,\n y: b.y,\n width: b.width,\n height: b.height,\n top: b.y,\n right: b.x + b.width,\n bottom: b.y + b.height,\n left: b.x,\n toJSON: () => ({}),\n });\n\n // Polyfill SVG layout methods that JSDOM lacks\n const polyfillBBox = function (this: Element) {\n const tag = this.tagName ? this.tagName.toLowerCase() : '';\n if (tag === 'style' || tag === 'script' || tag === 'defs' || tag === 'clippath' || tag === 'marker') {\n return toRect({ x: 0, y: 0, width: 0, height: 0 });\n }\n // Mermaid sizes the output SVG from getBBox() on the root <svg>. Measure\n // the real geometry instead of a constant, so the viewBox matches content.\n if (tag === 'svg') {\n const box = contentBBox(this);\n if (box) return toRect(box);\n }\n const text = getDirectText(this);\n const width = text ? Math.max(30, text.length * 9 + 20) : 80;\n const height = text ? 28 : 40;\n return toRect({ x: 0, y: 0, width, height });\n };\n\n if (!(dom.window.SVGElement.prototype as unknown as Record<string, unknown>).getBBox) {\n (dom.window.SVGElement.prototype as unknown as Record<string, unknown>).getBBox = polyfillBBox;\n }\n if (!(dom.window.Element.prototype as unknown as Record<string, unknown>).getBBox) {\n (dom.window.Element.prototype as unknown as Record<string, unknown>).getBBox = polyfillBBox;\n }\n if (!dom.window.Element.prototype.getBoundingClientRect) {\n dom.window.Element.prototype.getBoundingClientRect = polyfillBBox as unknown as () => DOMRect;\n }\n const computeTextLength = function (this: Element) {\n const text = getDirectText(this);\n return text.length * 9;\n };\n (dom.window.Element.prototype as unknown as Record<string, unknown>).getComputedTextLength = computeTextLength;\n (dom.window.SVGElement.prototype as unknown as Record<string, unknown>).getComputedTextLength = computeTextLength;\n (dom.window.HTMLElement.prototype as unknown as Record<string, unknown>).getComputedTextLength = computeTextLength;\n\n if (dom.window.HTMLCanvasElement) {\n dom.window.HTMLCanvasElement.prototype.getContext = (() => ({\n measureText: (text: string) => ({ width: text.length * 8 }),\n fillRect: () => {},\n clearRect: () => {},\n getImageData: () => ({ data: new Array(4) }),\n putImageData: () => {},\n createImageData: () => [],\n setTransform: () => {},\n drawImage: () => {},\n save: () => {},\n fillText: () => {},\n restore: () => {},\n beginPath: () => {},\n moveTo: () => {},\n lineTo: () => {},\n closePath: () => {},\n stroke: () => {},\n translate: () => {},\n scale: () => {},\n rotate: () => {},\n arc: () => {},\n fill: () => {},\n })) as unknown as typeof dom.window.HTMLCanvasElement.prototype.getContext;\n }\n\n if (dom.window.SVGSVGElement) {\n if (!dom.window.SVGSVGElement.prototype.createSVGMatrix) {\n dom.window.SVGSVGElement.prototype.createSVGMatrix = () => ({\n a: 1, b: 0, c: 0, d: 1, e: 0, f: 0,\n multiply: function () { return this; },\n inverse: function () { return this; },\n translate: function () { return this; },\n scale: function () { return this; },\n rotate: function () { return this; },\n } as unknown as DOMMatrix);\n }\n if (!dom.window.SVGSVGElement.prototype.createSVGPoint) {\n dom.window.SVGSVGElement.prototype.createSVGPoint = () => ({\n x: 0, y: 0,\n matrixTransform: function () { return this; },\n } as unknown as DOMPoint);\n }\n }\n\n // Mock matchMedia if missing\n if (!dom.window.matchMedia) {\n dom.window.matchMedia = () => ({\n matches: false,\n media: '',\n onchange: null,\n addListener: () => {},\n removeListener: () => {},\n addEventListener: () => {},\n removeEventListener: () => {},\n dispatchEvent: () => false,\n }) as unknown as MediaQueryList;\n }\n\n // Import and initialize mermaid\n const mermaid = (await import('mermaid')).default;\n mermaid.initialize(this.buildConfig() as unknown as Parameters<typeof mermaid.initialize>[0]);\n\n initialized = true;\n }\n\n private buildConfig(theme?: Theme) {\n return {\n startOnLoad: false,\n securityLevel: 'loose',\n // Top-level htmlLabels is required: flowchart-v2 reads it (the\n // flowchart.htmlLabels key is ignored) and html labels rely on real DOM\n // layout (scrollWidth) that jsdom does not provide — with them on, nodes\n // collapse to 60x30 stubs and resvg drops the HTML content entirely.\n htmlLabels: false,\n theme: isDarkTheme(theme) ? 'dark' : 'default',\n themeVariables: {\n fontFamily: diagramFontFamily(theme),\n background: 'transparent',\n },\n flowchart: { htmlLabels: false, curve: 'basis', useMaxWidth: false },\n sequence: { useMaxWidth: false },\n };\n }\n\n async render(code: string, theme?: Theme): Promise<Buffer> {\n await this.initialize();\n\n const mermaid = (await import('mermaid')).default;\n const id = `mfly-mermaid-${Date.now()}-${this.renderCounter++}`;\n\n // Re-apply per render so diagram follows the selected presentation theme\n mermaid.initialize(this.buildConfig(theme) as unknown as Parameters<typeof mermaid.initialize>[0]);\n\n try {\n const { svg } = await mermaid.render(id, code.trim());\n return svgToPng(svg, 1200);\n } catch (err) {\n throw new Error(\n `Mermaid render failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n}\n","/**\n * Graphviz/DOT Diagram Renderer\n * Uses @viz-js/viz (WASM) — works natively in Node.js, no DOM needed\n */\n\nimport type { DiagramRenderer } from './renderer.js';\nimport type { Theme } from '../models/theme.js';\nimport { svgToPng } from './svg-to-png.js';\nimport { isDarkTheme } from './theme.js';\n\nexport class GraphvizDiagramRenderer implements DiagramRenderer {\n readonly type = 'dot';\n private viz: Awaited<ReturnType<typeof import('@viz-js/viz').instance>> | null = null;\n\n async initialize(): Promise<void> {\n if (this.viz) return;\n const vizModule = await import('@viz-js/viz');\n this.viz = await vizModule.instance();\n }\n\n /**\n * Dark theme support: prepend default node/edge/graph attributes so nodes,\n * edges, and labels become light-on-dark. User-specified attrs in the DOT\n * code still win because they appear after these defaults.\n */\n private themeDefaults(code: string, dark: boolean): string {\n if (!dark) return code;\n const prelude =\n ' graph [fontcolor=\"#c9d1d9\" bgcolor=\"transparent\"];\\n' +\n ' node [color=\"#8b949e\" fontcolor=\"#c9d1d9\"];\\n' +\n ' edge [color=\"#8b949e\" fontcolor=\"#c9d1d9\"];\\n';\n return code.replace(/\\{/, `{\\n${prelude}`);\n }\n\n async render(code: string, theme?: Theme): Promise<Buffer> {\n await this.initialize();\n\n try {\n const dark = isDarkTheme(theme);\n const svg = this.viz!.renderString(this.themeDefaults(code.trim(), dark), {\n format: 'svg',\n engine: 'dot',\n graphAttributes: {\n bgcolor: 'transparent',\n },\n });\n return svgToPng(svg, 1200);\n } catch (err) {\n throw new Error(\n `Graphviz render failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n}\n","/**\n * ECharts Diagram Renderer\n * Uses ECharts SSR mode — pure Node.js, no DOM/canvas needed\n */\n\nimport type { DiagramRenderer } from './renderer.js';\nimport type { Theme } from '../models/theme.js';\nimport { svgToPng } from './svg-to-png.js';\n\nexport class EChartsDiagramRenderer implements DiagramRenderer {\n readonly type = 'echarts';\n\n async initialize(): Promise<void> {\n // ECharts SSR mode needs no initialization\n }\n\n async render(code: string, _theme?: Theme): Promise<Buffer> {\n const echarts = await import('echarts');\n\n let option: Record<string, unknown>;\n try {\n option = JSON.parse(code.trim());\n } catch {\n throw new Error('ECharts: invalid JSON option');\n }\n\n // Extract optional size hints\n const width = typeof option.width === 'number' ? option.width : 800;\n const height = typeof option.height === 'number' ? option.height : 450;\n delete option.width;\n delete option.height;\n\n // SSR mode: no DOM required\n const chart = echarts.init(null, null, {\n renderer: 'svg',\n ssr: true,\n width,\n height,\n });\n\n try {\n chart.setOption({\n ...option,\n animation: false,\n });\n\n const svg = chart.renderToSVGString();\n return svgToPng(svg, width * 2); // 2x for retina quality\n } finally {\n chart.dispose();\n }\n }\n}\n","/**\n * Diagram Registry\n * Unified entry point for all diagram renderers\n */\n\nimport type { DiagramRenderer } from './renderer.js';\nimport type { Theme } from '../models/theme.js';\nimport { MermaidDiagramRenderer } from './mermaid-renderer.js';\nimport { GraphvizDiagramRenderer } from './graphviz-renderer.js';\nimport { EChartsDiagramRenderer } from './echarts-renderer.js';\n\n/** Language identifiers that are diagrams */\nconst DIAGRAM_LANGUAGES: Record<string, () => DiagramRenderer> = {\n mermaid: () => new MermaidDiagramRenderer(),\n dot: () => new GraphvizDiagramRenderer(),\n graphviz: () => new GraphvizDiagramRenderer(),\n echarts: () => new EChartsDiagramRenderer(),\n};\n\n/** Cached renderer instances (lazy init) */\nconst instances = new Map<string, DiagramRenderer>();\n\nfunction getOrCreate(language: string): DiagramRenderer | undefined {\n // Normalize 'graphviz' → 'dot' for caching\n const key = language === 'graphviz' ? 'dot' : language;\n\n if (instances.has(key)) return instances.get(key)!;\n\n const factory = DIAGRAM_LANGUAGES[language];\n if (!factory) return undefined;\n\n const renderer = factory();\n instances.set(key, renderer);\n return renderer;\n}\n\n/** Check if a code block language is a diagram type */\nexport function isDiagramLanguage(language: string): boolean {\n return language.toLowerCase() in DIAGRAM_LANGUAGES;\n}\n\n/** Get a diagram renderer by language */\nexport function getDiagramRenderer(language: string): DiagramRenderer | undefined {\n return getOrCreate(language.toLowerCase());\n}\n\n/**\n * Render a diagram code block to PNG\n * @returns PNG image as Buffer\n */\nexport async function renderDiagram(\n language: string,\n code: string,\n theme?: Theme,\n): Promise<Buffer> {\n const renderer = getOrCreate(language.toLowerCase());\n if (!renderer) {\n throw new Error(`No diagram renderer for language: ${language}`);\n }\n\n await renderer.initialize();\n return renderer.render(code, theme);\n}\n","/**\n * PNG gradient generator\n * PptxGenJS slide backgrounds only support solid colors or images, so linear\n * gradient backgrounds are rendered here to a small PNG that gets stretched\n * over the whole slide (pptxgenjs emits <a:stretch><a:fillRect/></a:stretch>).\n *\n * Pure Node implementation (zlib + hand-rolled PNG chunks) — no dependencies.\n */\n\nimport { deflateSync } from 'node:zlib';\n\nexport type RgbTuple = readonly [number, number, number];\n\nconst CRC_TABLE = (() => {\n const table = new Uint32Array(256);\n for (let n = 0; n < 256; n++) {\n let c = n;\n for (let k = 0; k < 8; k++) {\n c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;\n }\n table[n] = c >>> 0;\n }\n return table;\n})();\n\nfunction crc32(bytes: Uint8Array): number {\n let crc = 0xffffffff;\n for (let i = 0; i < bytes.length; i++) {\n crc = CRC_TABLE[(crc ^ bytes[i]) & 0xff] ^ (crc >>> 8);\n }\n return (crc ^ 0xffffffff) >>> 0;\n}\n\nfunction pngChunk(type: string, data: Uint8Array): Buffer {\n const length = Buffer.alloc(4);\n length.writeUInt32BE(data.length);\n const payload = Buffer.concat([Buffer.from(type, 'latin1'), Buffer.from(data)]);\n const crc = Buffer.alloc(4);\n crc.writeUInt32BE(crc32(payload));\n return Buffer.concat([length, payload, crc]);\n}\n\n/** Encode a width×height truecolor (RGB, no alpha) PNG. */\nexport function encodePngRgb(\n width: number,\n height: number,\n pixelAt: (x: number, y: number) => RgbTuple,\n): Buffer {\n const ihdr = Buffer.alloc(13);\n ihdr.writeUInt32BE(width, 0);\n ihdr.writeUInt32BE(height, 4);\n ihdr[8] = 8; // bit depth\n ihdr[9] = 2; // color type: truecolor RGB\n // bytes 10-12 (compression/filter/interlace) stay 0\n\n // Scanlines: filter byte 0 (none) + width * RGB\n const raw = Buffer.alloc(height * (1 + width * 3));\n let offset = 0;\n for (let y = 0; y < height; y++) {\n raw[offset++] = 0;\n for (let x = 0; x < width; x++) {\n const [r, g, b] = pixelAt(x, y);\n raw[offset++] = r;\n raw[offset++] = g;\n raw[offset++] = b;\n }\n }\n const idat = deflateSync(raw, { level: 9 });\n\n return Buffer.concat([\n Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]),\n pngChunk('IHDR', ihdr),\n pngChunk('IDAT', new Uint8Array(idat)),\n pngChunk('IEND', new Uint8Array(0)),\n ]);\n}\n\n/** Parse '#RRGGBB' / 'RRGGBB' / '#RGB' / 'RGB' into an RGB tuple. */\nexport function hexToRgb(hex: string): RgbTuple {\n let s = hex.replace(/^#/, '');\n if (s.length === 3) s = s.split('').map((ch) => ch + ch).join('');\n if (!/^[0-9a-fA-F]{6}$/.test(s)) throw new Error(`Invalid hex color: ${hex}`);\n return [\n parseInt(s.slice(0, 2), 16),\n parseInt(s.slice(2, 4), 16),\n parseInt(s.slice(4, 6), 16),\n ];\n}\n\nexport interface GradientOptions {\n width?: number;\n height?: number;\n}\n\n/**\n * Create a linear-gradient PNG.\n * Angle follows the CSS convention (0° = to top, 90° = to right, 135° = to\n * bottom-right, 180° = to bottom). The default canvas matches the 16:9 slide,\n * so the visual angle survives stretching.\n */\nexport function createLinearGradientPng(\n from: string,\n to: string,\n angleDeg = 180,\n options: GradientOptions = {},\n): Buffer {\n const width = options.width ?? 192;\n const height = options.height ?? 108;\n const angle = (angleDeg * Math.PI) / 180;\n // CSS gradient-line direction in screen coords (y grows downward)\n const dx = Math.sin(angle);\n const dy = -Math.cos(angle);\n // Half the L1 extent of the unit square: keeps the gradient spans 0..1\n // across the full diagonal no matter which angle is given.\n const extent = (Math.abs(dx) + Math.abs(dy)) / 2;\n\n const c1 = hexToRgb(from);\n const c2 = hexToRgb(to);\n\n return encodePngRgb(width, height, (x, y) => {\n const px = x / (width - 1) - 0.5;\n const py = y / (height - 1) - 0.5;\n let t = 0.5 + (px * dx + py * dy) / (2 * extent);\n t = t < 0 ? 0 : t > 1 ? 1 : t;\n return [\n Math.round(c1[0] + (c2[0] - c1[0]) * t),\n Math.round(c1[1] + (c2[1] - c1[1]) * t),\n Math.round(c1[2] + (c2[2] - c1[2]) * t),\n ];\n });\n}\n","/**\n * Slide background resolver\n * Turns the theme's flat color (or linear gradient) into pptxgenjs background props.\n * Gradient PNGs are generated once and cached per gradient definition.\n */\n\nimport type { Theme } from '../models/theme.js';\nimport { createLinearGradientPng } from '../utils/gradient.js';\n\nconst cache = new Map<string, string>();\n\nexport interface SlideBackgroundProps {\n /** Flat fallback color; pptxgenjs ignores it when an image `data` is present */\n color: string;\n /** Base64 PNG stretched over the slide (gradient themes only) */\n data?: string;\n}\n\nexport function slideBackground(theme: Theme): SlideBackgroundProps {\n const gradient = theme.colors.backgroundGradient;\n if (!gradient) return { color: theme.colors.background };\n\n const key = `${gradient.from}|${gradient.to}|${gradient.angle ?? 180}`;\n let data = cache.get(key);\n if (!data) {\n // 192×108 keeps 16:9 so angles look the same as the rendered slide\n const png = createLinearGradientPng(gradient.from, gradient.to, gradient.angle ?? 180, {\n width: 192,\n height: 108,\n });\n data = `image/png;base64,${png.toString('base64')}`;\n cache.set(key, data);\n }\n return { color: theme.colors.background, data };\n}\n","import type { Theme } from '../models/theme.js';\n\nexport const cleanTheme: Theme = {\n name: 'clean',\n colors: {\n primary: '2563EB',\n secondary: '4B5563',\n background: 'FFFFFF',\n text: '1F2937',\n accent: '10B981',\n codeBackground: '1E293B',\n codeText: 'E2E8F0',\n titleBackground: '2563EB',\n titleText: 'FFFFFF',\n },\n fonts: {\n heading: 'Segoe UI',\n body: 'Segoe UI',\n code: 'Consolas',\n cjk: '微软雅黑',\n },\n fontSize: {\n title: 36,\n heading: 28,\n body: 18,\n code: 14,\n small: 12,\n },\n shikiTheme: 'github-dark',\n};\n","import type { Theme } from '../models/theme.js';\n\nexport const academicTheme: Theme = {\n name: 'academic',\n colors: {\n primary: '003366',\n secondary: '4A5568',\n background: 'FFFFFF',\n text: '111827',\n accent: '991B1B',\n codeBackground: '1E293B',\n codeText: 'E2E8F0',\n titleBackground: '003366',\n titleText: 'FFFFFF',\n },\n fonts: {\n heading: 'Times New Roman',\n body: 'Segoe UI',\n code: 'Consolas',\n cjk: '宋体',\n },\n fontSize: {\n title: 36,\n heading: 28,\n body: 18,\n code: 14,\n small: 12,\n },\n shikiTheme: 'github-dark',\n};\n","import type { Theme } from '../models/theme.js';\n\nexport const darkTheme: Theme = {\n name: 'dark',\n colors: {\n primary: '38BDF8',\n secondary: '94A3B8',\n background: '0F172A',\n text: 'F8FAFC',\n accent: 'A855F7',\n codeBackground: '020617',\n codeText: '38BDF8',\n titleBackground: '0F172A',\n titleText: '38BDF8',\n highlightBackground: '334155',\n backgroundGradient: { from: '0F172A', to: '1E293B', angle: 135 },\n },\n fonts: {\n heading: 'Segoe UI',\n body: 'Segoe UI',\n code: 'Consolas',\n cjk: '微软雅黑',\n },\n fontSize: {\n title: 36,\n heading: 28,\n body: 18,\n code: 14,\n small: 12,\n },\n shikiTheme: 'dracula',\n};\n","import type { Theme } from '../models/theme.js';\n\nexport const businessTheme: Theme = {\n name: 'business',\n colors: {\n primary: '1E3A8A',\n secondary: '64748B',\n background: 'F8FAFC',\n text: '0F172A',\n accent: 'D97706',\n codeBackground: '0F172A',\n codeText: 'E2E8F0',\n titleBackground: '1E3A8A',\n titleText: 'FFFFFF',\n },\n fonts: {\n heading: 'Segoe UI',\n body: 'Segoe UI',\n code: 'Consolas',\n cjk: '微软雅黑',\n },\n fontSize: {\n title: 36,\n heading: 28,\n body: 18,\n code: 14,\n small: 12,\n },\n shikiTheme: 'github-dark',\n};\n","import type { Theme } from '../models/theme.js';\n\nexport const warmTheme: Theme = {\n name: 'warm',\n colors: {\n primary: '065F46',\n secondary: '78716C',\n background: 'FDFBF7',\n text: '292524',\n accent: 'C2410C',\n codeBackground: '292524',\n codeText: 'FDFBF7',\n titleBackground: '065F46',\n titleText: '292524',\n backgroundGradient: { from: 'FDFBF7', to: 'F5EEDF', angle: 180 },\n },\n fonts: {\n heading: 'Georgia',\n body: 'Segoe UI',\n code: 'Consolas',\n cjk: '微软雅黑',\n },\n fontSize: {\n title: 36,\n heading: 28,\n body: 18,\n code: 14,\n small: 12,\n },\n shikiTheme: 'github-dark',\n};\n","import type { Theme } from '../models/theme.js';\n\n/**\n * Aurora — dark neon gradient (mint/blue/purple accents on deep navy),\n * inspired by the SlideForge \"aurora\" deck palette.\n */\nexport const auroraTheme: Theme = {\n name: 'aurora',\n colors: {\n primary: '7AA2FF',\n secondary: '8FA3C9',\n background: '06091C',\n text: 'E8F0FF',\n accent: '5EF2C6',\n codeBackground: '0B1128',\n codeText: 'AECAF5',\n titleText: 'F4F8FF',\n highlightBackground: '233152',\n backgroundGradient: { from: '101A3A', to: '05060F', angle: 135 },\n },\n fonts: {\n heading: 'Segoe UI',\n body: 'Segoe UI',\n code: 'Consolas',\n cjk: '微软雅黑',\n },\n fontSize: {\n title: 36,\n heading: 28,\n body: 18,\n code: 14,\n small: 12,\n },\n shikiTheme: 'dracula',\n};\n","import type { Theme } from '../models/theme.js';\n\n/**\n * Neon — high-contrast dark tech theme with cyan/magenta accents,\n * inspired by ppt-agents' \"dark\" (cyan + magenta high contrast).\n */\nexport const neonTheme: Theme = {\n name: 'neon',\n colors: {\n primary: '00E5FF',\n secondary: '9AA4B5',\n background: '121212',\n text: 'FFFFFF',\n accent: 'FF4081',\n codeBackground: '0C0C0C',\n codeText: '85E7F7',\n titleBackground: '121212',\n titleText: '00E5FF',\n highlightBackground: '2A2A32',\n },\n fonts: {\n heading: 'Segoe UI',\n body: 'Segoe UI',\n code: 'Consolas',\n cjk: '微软雅黑',\n },\n fontSize: {\n title: 36,\n heading: 28,\n body: 18,\n code: 14,\n small: 12,\n },\n shikiTheme: 'dracula',\n};\n","import type { Theme } from '../models/theme.js';\n\n/**\n * Nord — the classic Arctic Frost palette (frost blues + aurora warm accents).\n */\nexport const nordTheme: Theme = {\n name: 'nord',\n colors: {\n primary: '88C0D0',\n secondary: '81A1C1',\n background: '2E3440',\n text: 'D8DEE9',\n accent: 'EBCB8B',\n codeBackground: '272C36',\n codeText: 'A9BBD3',\n titleBackground: '2E3440',\n titleText: '88C0D0',\n highlightBackground: '3B4252',\n },\n fonts: {\n heading: 'Segoe UI',\n body: 'Segoe UI',\n code: 'Consolas',\n cjk: '微软雅黑',\n },\n fontSize: {\n title: 36,\n heading: 28,\n body: 18,\n code: 14,\n small: 12,\n },\n shikiTheme: 'nord',\n};\n","import type { Theme } from '../models/theme.js';\n\n/**\n * Dracula — the official Dracula palette (purple primary + pink accent on charcoal).\n */\nexport const draculaTheme: Theme = {\n name: 'dracula',\n colors: {\n primary: 'BD93F9',\n secondary: '6272A4',\n background: '282A36',\n text: 'F8F8F2',\n accent: 'FF79C6',\n codeBackground: '21222C',\n codeText: 'F8F8F2',\n titleBackground: '282A36',\n titleText: 'BD93F9',\n highlightBackground: '44475A',\n },\n fonts: {\n heading: 'Segoe UI',\n body: 'Segoe UI',\n code: 'Consolas',\n cjk: '微软雅黑',\n },\n fontSize: {\n title: 36,\n heading: 28,\n body: 18,\n code: 14,\n small: 12,\n },\n shikiTheme: 'dracula',\n};\n","import type { Theme } from '../models/theme.js';\n\n/**\n * Beige — warm minimal light theme (paper beige, bronze + terracotta accents),\n * inspired by reveal.js' \"beige\" palette.\n */\nexport const beigeTheme: Theme = {\n name: 'beige',\n colors: {\n primary: '8B6F3D',\n secondary: '6B6455',\n background: 'F7F3DE',\n text: '2F2A1F',\n accent: 'C0563C',\n codeBackground: '3A352B',\n codeText: 'E8E0CC',\n titleBackground: '8B6F3D',\n titleText: '2F2A1F',\n highlightBackground: 'F0E2B8',\n backgroundGradient: { from: 'F7F3DE', to: 'F1E8D2', angle: 180 },\n },\n fonts: {\n heading: 'Georgia',\n body: 'Segoe UI',\n code: 'Consolas',\n cjk: '微软雅黑',\n },\n fontSize: {\n title: 36,\n heading: 28,\n body: 18,\n code: 14,\n small: 12,\n },\n shikiTheme: 'github-dark',\n};\n","import type { Theme } from '../models/theme.js';\n\n/**\n * Ink — Chinese ink-wash style (rice-paper background, ink blacks,\n * vermilion seal-red accent, Kai serif typography).\n */\nexport const inkTheme: Theme = {\n name: 'ink',\n colors: {\n primary: '2F3530',\n secondary: '6F6A5E',\n background: 'F7F4EC',\n text: '262626',\n accent: 'C0272D',\n codeBackground: '2B2924',\n codeText: 'D8D2C0',\n titleBackground: '30352F',\n titleText: '262626',\n highlightBackground: 'EBDDCD',\n backgroundGradient: { from: 'F7F4EC', to: 'EFE8DA', angle: 180 },\n },\n fonts: {\n heading: 'KaiTi',\n body: 'KaiTi',\n code: 'Consolas',\n cjk: 'KaiTi',\n },\n fontSize: {\n title: 36,\n heading: 28,\n body: 18,\n code: 14,\n small: 12,\n },\n shikiTheme: 'github-dark',\n};\n","import type { Theme } from '../models/theme.js';\nimport { cleanTheme } from './clean.js';\n\nexport const defaultTheme: Theme = {\n ...cleanTheme,\n name: 'default',\n};\n","import type { Theme } from '../models/theme.js';\nimport { cleanTheme } from './clean.js';\nimport { academicTheme } from './academic.js';\nimport { darkTheme } from './dark.js';\nimport { businessTheme } from './business.js';\nimport { warmTheme } from './warm.js';\nimport { auroraTheme } from './aurora.js';\nimport { neonTheme } from './neon.js';\nimport { nordTheme } from './nord.js';\nimport { draculaTheme } from './dracula.js';\nimport { beigeTheme } from './beige.js';\nimport { inkTheme } from './ink.js';\nimport { defaultTheme } from './default.js';\n\nexport const themes: Record<string, Theme> = {\n clean: cleanTheme,\n academic: academicTheme,\n dark: darkTheme,\n business: businessTheme,\n warm: warmTheme,\n aurora: auroraTheme,\n neon: neonTheme,\n nord: nordTheme,\n dracula: draculaTheme,\n beige: beigeTheme,\n ink: inkTheme,\n default: defaultTheme,\n};\n\nexport function getTheme(name?: string): Theme {\n if (!name) {\n return cleanTheme;\n }\n if (typeof name !== 'string') {\n throw new Error(`Invalid theme value: expected a string, got ${typeof name}`);\n }\n const theme = themes[name.toLowerCase()];\n if (!theme) {\n console.warn(`Theme \"${name}\" not found, using \"clean\"`);\n return cleanTheme;\n }\n return theme;\n}\n\nexport {\n cleanTheme,\n academicTheme,\n darkTheme,\n businessTheme,\n warmTheme,\n auroraTheme,\n neonTheme,\n nordTheme,\n draculaTheme,\n beigeTheme,\n inkTheme,\n defaultTheme,\n};\n","/**\n * Smart output file naming\n */\n\nimport { existsSync } from 'node:fs';\nimport { basename, extname, dirname, join } from 'node:path';\nimport { randomUUID } from 'node:crypto';\n\n/**\n * Determine output path:\n * 1. If specified, use it\n * 2. Otherwise: input.md → input.pptx\n * 3. If exists: add timestamp\n * 4. If still exists: add 4-char uuid\n */\nexport function getOutputPath(inputPath: string, specifiedOutput?: string): string {\n if (specifiedOutput) return specifiedOutput;\n\n const dir = dirname(inputPath);\n const name = basename(inputPath, extname(inputPath));\n\n // Try simple name\n const simple = join(dir, `${name}.pptx`);\n if (!existsSync(simple)) return simple;\n\n // Add timestamp\n const now = new Date();\n const ts = now.getFullYear().toString() +\n String(now.getMonth() + 1).padStart(2, '0') +\n String(now.getDate()).padStart(2, '0') +\n '-' +\n String(now.getHours()).padStart(2, '0') +\n String(now.getMinutes()).padStart(2, '0') +\n String(now.getSeconds()).padStart(2, '0');\n\n const withTimestamp = join(dir, `${name}-${ts}.pptx`);\n if (!existsSync(withTimestamp)) return withTimestamp;\n\n // Add random suffix\n const uuid = randomUUID().slice(0, 4);\n return join(dir, `${name}-${ts}-${uuid}.pptx`);\n}\n","/**\n * Windows-compatible glob expansion\n */\n\nimport fg from 'fast-glob';\nimport { resolve } from 'node:path';\n\n/**\n * Expand glob patterns to absolute .md file paths\n */\nexport async function expandGlob(patterns: string[]): Promise<string[]> {\n // fast-glob needs forward slashes even on Windows\n const normalized = patterns.map((p) => p.replace(/\\\\/g, '/'));\n\n const files = await fg(normalized, {\n absolute: true,\n onlyFiles: true,\n });\n\n // Filter to .md files and sort\n return files\n .filter((f) => f.toLowerCase().endsWith('.md'))\n .sort();\n}\n"],"mappings":"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","names":["chalk","readFileSync","readFileSync","resolve","series","x","y","DIAGRAM_LANGUAGES","writeFileSync","resolve","existsSync","dirname","join","randomUUID","resolve","readFileSync","readFileSync","chalk"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/index.ts","../src/parser/index.ts","../src/parser/frontmatter.ts","../src/models/theme-preset.ts","../src/config/defaults.ts","../src/utils/progress.ts","../src/diagrams/languages.ts","../src/parser/splitter.ts","../src/parser/preprocess.ts","../src/renderer/pptx-renderer.ts","../src/renderer/layouts/layout-spec.ts","../src/renderer/layouts/title.ts","../src/renderer/layouts/section.ts","../src/utils/image-size.ts","../src/utils/image-fit.ts","../src/utils/table-chart.ts","../src/renderer/layouts/content.ts","../src/renderer/layouts/code.ts","../src/renderer/layouts/quote.ts","../src/renderer/layouts/closing.ts","../src/renderer/layouts/image-pages.ts","../src/renderer/layouts/index.ts","../src/renderer/code-highlighter.ts","../src/utils/gradient.ts","../src/renderer/image-handler.ts","../src/diagrams/svg-to-png.ts","../src/diagrams/theme.ts","../src/diagrams/mermaid-renderer.ts","../src/diagrams/graphviz-renderer.ts","../src/diagrams/echarts-renderer.ts","../src/diagrams/plantuml-renderer.ts","../src/diagrams/index.ts","../src/renderer/background.ts","../src/utils/color-mix.ts","../src/models/color-scheme.ts","../src/themes/color-schemes/ocean.ts","../src/themes/color-schemes/ocean-dark.ts","../src/themes/color-schemes/forest.ts","../src/themes/color-schemes/champagne.ts","../src/themes/color-schemes/graphite.ts","../src/themes/color-schemes/index.ts","../src/models/text-set.ts","../src/themes/resolve-scheme.ts","../src/themes/layout-schemes/folio/title.ts","../src/themes/layout-schemes/folio/section.ts","../src/themes/layout-schemes/folio/content.ts","../src/themes/layout-schemes/folio/code.ts","../src/themes/layout-schemes/folio/quote.ts","../src/themes/layout-schemes/folio/closing.ts","../src/themes/layout-schemes/folio/images.ts","../src/themes/layout-schemes/folio/footer.ts","../src/themes/layout-schemes/folio/styles.ts","../src/themes/layout-schemes/folio/index.ts","../src/themes/layout-schemes/legacy/title.ts","../src/themes/layout-schemes/legacy/section.ts","../src/themes/layout-schemes/legacy/content.ts","../src/themes/layout-schemes/legacy/code.ts","../src/themes/layout-schemes/legacy/quote.ts","../src/themes/layout-schemes/legacy/footer.ts","../src/themes/layout-schemes/legacy/styles.ts","../src/themes/layout-schemes/legacy/index.ts","../src/themes/layout-schemes/golden/title.ts","../src/themes/layout-schemes/golden/section.ts","../src/themes/layout-schemes/golden/content.ts","../src/themes/layout-schemes/golden/code.ts","../src/themes/layout-schemes/golden/quote.ts","../src/themes/layout-schemes/golden/closing.ts","../src/themes/layout-schemes/golden/images.ts","../src/themes/layout-schemes/golden/footer.ts","../src/themes/layout-schemes/golden/styles.ts","../src/themes/layout-schemes/golden/index.ts","../src/themes/layout-schemes/minimal/title.ts","../src/themes/layout-schemes/minimal/section.ts","../src/themes/layout-schemes/minimal/content.ts","../src/themes/layout-schemes/minimal/code.ts","../src/themes/layout-schemes/minimal/quote.ts","../src/themes/layout-schemes/minimal/closing.ts","../src/themes/layout-schemes/minimal/images.ts","../src/themes/layout-schemes/minimal/footer.ts","../src/themes/layout-schemes/minimal/styles.ts","../src/themes/layout-schemes/minimal/index.ts","../src/themes/layout-schemes/index.ts","../src/themes/presets/blue.ts","../src/themes/presets/emerald.ts","../src/themes/presets/gold.ts","../src/themes/presets/slate.ts","../src/themes/presets/index.ts","../src/themes/text-entries.ts","../src/themes/text-schemes/academic.ts","../src/themes/text-schemes/system.ts","../src/themes/text-schemes/kai.ts","../src/themes/text-schemes/source-han-serif.ts","../src/themes/text-schemes/text-index.ts","../src/themes/from-scheme.ts","../src/themes/index.ts","../src/utils/output-namer.ts","../src/utils/glob.ts"],"sourcesContent":["/**\r\n * MarkdownFly CLI\r\n * Usage: mfly <files...> [-o output.pptx] [-t theme] [--color c] [--text t]\r\n * [--layout l] [--quiet|--json]\r\n *\r\n * `-t` is the user-facing theme name:\r\n * - ThemePreset (e.g. blue) — color × text × layout\r\n * - ColorScheme (e.g. ocean, ocean-dark) — color only\r\n * Default theme when omitted: blue\r\n *\r\n * Free composition (each optional and overrides the theme's slot):\r\n * --color <name> color scheme override\r\n * --text <name> text / font scheme override\r\n * --layout <name> layout scheme override\r\n */\r\n\r\nimport { Command } from 'commander';\r\nimport chalk from 'chalk';\r\nimport { readFileSync } from 'node:fs';\r\nimport { convert } from './index.js';\r\nimport { expandGlob } from './utils/glob.js';\r\nimport { ProgressReporter, log, setQuiet } from './utils/progress.js';\r\nimport {\r\n hasTheme,\r\n themeNames,\r\n getColorScheme,\r\n getTextScheme,\r\n getLayoutScheme,\r\n listColorSchemes,\r\n listTextSchemes,\r\n listLayoutSchemes,\r\n} from './themes/index.js';\r\n\r\nconst pkg = JSON.parse(\r\n readFileSync(new URL('../package.json', import.meta.url), 'utf-8'),\r\n) as { version?: string };\r\n\r\nconst program = new Command();\r\n\r\nprogram\r\n .name('mfly')\r\n .description('Markdown to PowerPoint (PPTX)')\r\n .version(pkg.version ?? '0.0.0');\r\n\r\nconst themeChoices = themeNames();\r\n\r\nconst colorChoices = listColorSchemes()\r\n .map((s) => s.name)\r\n .join(', ');\r\nconst textChoices = listTextSchemes()\r\n .map((s) => s.name)\r\n .join(', ');\r\nconst layoutChoices = listLayoutSchemes()\r\n .map((s) => s.name)\r\n .join(', ');\r\n\r\n// Main convert command\r\nprogram\r\n .argument('<files...>', 'Markdown files to convert (supports glob)')\r\n .option('-o, --output <path>', 'Output file path (single file only)')\r\n .option('-t, --theme <name>', `Theme name (${themeChoices.join(', ')})`)\r\n .option('--color <name>', `Color scheme override (${colorChoices})`)\r\n .option('--text <name>', `Text scheme override (${textChoices})`)\r\n .option('--layout <name>', `Layout scheme override (${layoutChoices})`)\r\n .option('--quiet', 'Suppress per-file progress output')\r\n .option('--json', 'Print machine-readable JSON result to stdout')\r\n .action(async (\r\n filePatterns: string[],\r\n options: {\r\n output?: string;\r\n theme: string;\r\n color?: string;\r\n text?: string;\r\n layout?: string;\r\n quiet?: boolean;\r\n json?: boolean;\r\n },\r\n ) => {\r\n const jsonMode = Boolean(options.json);\r\n if (jsonMode || options.quiet) setQuiet(true);\r\n\r\n const usageError = (msg: string): never => {\r\n log.error(msg);\r\n if (jsonMode) console.log(JSON.stringify({ ok: false, error: msg }));\r\n process.exit(1);\r\n };\r\n\r\n try {\r\n const files = await expandGlob(filePatterns);\r\n\r\n if (files.length === 0) {\r\n usageError('No .md files found matching the given pattern(s)');\r\n }\r\n\r\n if (options.output && files.length > 1) {\r\n usageError('--output can only be used with a single input file');\r\n }\r\n\r\n // Strict theme validation. When -t is omitted, the theme comes from\r\n // frontmatter or the default theme (blue).\r\n if (options.theme && !hasTheme(options.theme)) {\r\n usageError(`Unknown theme \"${options.theme}\". Available themes: ${themeChoices.join(', ')}`);\r\n }\r\n\r\n // Strict slot validation for the free-composition flags.\r\n if (options.color && !getColorScheme(options.color)) {\r\n usageError(`Unknown color scheme \"${options.color}\". Available: ${colorChoices}`);\r\n }\r\n if (options.text && !getTextScheme(options.text)) {\r\n usageError(`Unknown text scheme \"${options.text}\". Available: ${textChoices}`);\r\n }\r\n if (options.layout && !getLayoutScheme(options.layout)) {\r\n usageError(`Unknown layout scheme \"${options.layout}\". Available: ${layoutChoices}`);\r\n }\r\n\r\n const startTime = Date.now();\r\n const results: Array<{ input: string; output?: string; ok: boolean; error?: string }> = [];\r\n\r\n for (const file of files) {\r\n const progress = new ProgressReporter();\r\n const fileName = file.split(/[\\\\/]/).pop() ?? file;\r\n\r\n progress.start(`Converting ${chalk.cyan(fileName)}...`);\r\n\r\n try {\r\n const outputPath = await convert(file, {\r\n output: options.output,\r\n theme: options.theme,\r\n colorScheme: options.color,\r\n textScheme: options.text,\r\n layoutScheme: options.layout,\r\n });\r\n\r\n const outName = outputPath.split(/[\\\\/]/).pop() ?? outputPath;\r\n progress.succeed(`${chalk.cyan(fileName)} → ${chalk.green(outName)}`);\r\n results.push({ input: file, output: outputPath, ok: true });\r\n } catch (err) {\r\n const msg = err instanceof Error ? err.message : String(err);\r\n progress.fail(`${chalk.cyan(fileName)}: ${chalk.red(msg)}`);\r\n results.push({ input: file, ok: false, error: msg });\r\n }\r\n }\r\n\r\n const failed = results.filter((r) => !r.ok);\r\n\r\n if (jsonMode) {\r\n console.log(JSON.stringify({\r\n ok: failed.length === 0,\r\n durationMs: Date.now() - startTime,\r\n files: results,\r\n }));\r\n } else {\r\n if (failed.length > 0) {\r\n log.error(`${failed.length} of ${files.length} file(s) failed`);\r\n }\r\n const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);\r\n log.info(`Done in ${elapsed}s`);\r\n }\r\n\r\n if (failed.length > 0) {\r\n process.exit(1);\r\n }\r\n } catch (err) {\r\n const msg = err instanceof Error ? err.message : String(err);\r\n log.error(msg);\r\n if (jsonMode) console.log(JSON.stringify({ ok: false, error: msg }));\r\n process.exit(1);\r\n }\r\n });\r\n\r\nprogram.parse();\r\n","/**\r\n * MarkdownFly — Main orchestration\r\n * Public API: convert(inputPath, options) → outputPath\r\n */\r\n\r\nimport { readFileSync } from 'node:fs';\r\nimport { resolve } from 'node:path';\r\nimport { parseMarkdown } from './parser/index.js';\r\nimport { renderPresentation } from './renderer/index.js';\r\nimport { getTheme } from './themes/index.js';\r\nimport { getOutputPath } from './utils/output-namer.js';\r\n\r\nexport interface ConvertOptions {\r\n output?: string;\r\n /**\r\n * User-facing theme name (same as CLI `-t` / frontmatter `theme`).\r\n * ThemePreset first (e.g. 'blue'), then ColorScheme (e.g. 'ocean').\r\n */\r\n theme?: string;\r\n /** ColorScheme override (CLI `--color` / frontmatter `color_scheme`) */\r\n colorScheme?: string;\r\n /** TextScheme override (CLI `--text` / frontmatter `text_scheme`) */\r\n textScheme?: string;\r\n /** LayoutScheme override (CLI `--layout` / frontmatter `layout_scheme`) */\r\n layoutScheme?: string;\r\n}\r\n\r\n/**\r\n * Convert a Markdown file to PPTX\r\n * @returns Absolute path of the generated .pptx file\r\n */\r\nexport async function convert(inputPath: string, options: ConvertOptions = {}): Promise<string> {\r\n const absInput = resolve(inputPath);\r\n const markdown = readFileSync(absInput, 'utf-8');\r\n\r\n // Parse\r\n const presentation = parseMarkdown(markdown);\r\n\r\n // Theme + slot overrides come from frontmatter as base, CLI/API wins.\r\n // Slots: explicit CLI/API > frontmatter > theme preset slots (> default).\r\n const baseTheme = options.theme ?? presentation.config.theme;\r\n const colorScheme = options.colorScheme ?? presentation.config.colorScheme;\r\n const textScheme = options.textScheme ?? presentation.config.textScheme;\r\n const layoutScheme = options.layoutScheme ?? presentation.config.layoutScheme;\r\n\r\n const theme = getTheme(baseTheme, { colorScheme, textScheme, layoutScheme });\r\n\r\n // Determine output path\r\n const outputPath = resolve(getOutputPath(absInput, options.output));\r\n\r\n // Render PPTX\r\n await renderPresentation(presentation, theme, outputPath, absInput);\r\n\r\n return outputPath;\r\n}\r\n\r\n// Re-export for library use\r\nexport { parseMarkdown } from './parser/index.js';\r\nexport {\r\n getTheme,\r\n themeNames,\r\n hasTheme,\r\n DEFAULT_SCHEME_NAME,\r\n resolveColorScheme,\r\n createThemeFromScheme,\r\n getColorScheme,\r\n listColorSchemes,\r\n registerColorScheme,\r\n oceanScheme,\r\n oceanDarkScheme,\r\n getTextScheme,\r\n listTextSchemes,\r\n registerTextScheme,\r\n textSchemes,\r\n systemTextScheme,\r\n academicTextScheme,\r\n kaiTextScheme,\r\n sourceHanSerifTextScheme,\r\n DEFAULT_TEXT_SCHEME_NAME,\r\n defineUniformTextScheme,\r\n layoutSchemes,\r\n getLayoutScheme,\r\n listLayoutSchemes,\r\n registerLayoutScheme,\r\n folioLayoutScheme,\r\n legacyLayoutScheme,\r\n DEFAULT_LAYOUT_SCHEME_NAME,\r\n themePresets,\r\n getThemePreset,\r\n listThemePresets,\r\n registerThemePreset,\r\n themePresetNames,\r\n hasThemePreset,\r\n bluePreset,\r\n DEFAULT_THEME_NAME,\r\n DEFAULT_PRESET_NAME,\r\n resolveThemePresetOption,\r\n} from './themes/index.js';\r\nexport { renderDiagram, isDiagramLanguage } from './diagrams/index.js';\r\nexport { renderPresentation } from './renderer/index.js';\r\nexport type { Presentation, SlideNode, SlideElement } from './models/slide.js';\r\nexport type { Theme } from './models/theme.js';\r\nexport type { MarkdownFlyConfig } from './config/types.js';\r\nexport type { ColorScheme, ColorSchemeMode } from './models/color-scheme.js';\r\nexport type { LayoutScheme } from './models/layout-scheme.js';\r\nexport type { ThemePreset } from './models/theme-preset.js';\r\nexport type {\r\n FontStyleEntry,\r\n TextScheme,\r\n TextSchemePositionKey,\r\n UniformTextSchemeOptions,\r\n} from './models/text-set.js';\r\nexport { resolveSchemeMode, CHROMATIC_SLOTS } from './models/color-scheme.js';\r\nexport { TEXT_SCHEME_POSITION_KEYS } from './models/text-set.js';\r\n","/**\n * Markdown Parser\n * Main entry point: markdown string → Presentation\n */\n\nimport { unified } from 'unified';\nimport remarkParse from 'remark-parse';\nimport remarkFrontmatter from 'remark-frontmatter';\nimport remarkGfm from 'remark-gfm';\nimport type { Root } from 'mdast';\nimport type { Presentation } from '../models/slide.js';\nimport { extractFrontmatter } from './frontmatter.js';\nimport { splitIntoSlides } from './splitter.js';\nimport { preprocessMarkdown } from './preprocess.js';\n\n/**\n * Parse a markdown string into a Presentation\n */\nexport function parseMarkdown(markdown: string): Presentation {\n const processor = unified()\n .use(remarkParse)\n .use(remarkFrontmatter, ['yaml'])\n .use(remarkGfm); // GFM: tables, task lists, autolinks, strikethrough\n\n // Rewrite layout markers (<-> / === / @(...)) before parsing so they\n // never collide with setext headings or paragraph text.\n const tree = processor.parse(preprocessMarkdown(markdown)) as Root;\n\n const config = extractFrontmatter(tree);\n const slides = splitIntoSlides(tree, config.layout);\n\n return { config, slides };\n}\n","/**\r\n * Frontmatter extractor\r\n * Extracts YAML frontmatter from remark AST and merges with defaults\r\n */\r\n\r\nimport type { Root } from 'mdast';\r\nimport { parse as parseYaml } from 'yaml';\r\nimport type { MarkdownFlyConfig } from '../config/types.js';\r\nimport { DEFAULT_CONFIG } from '../config/defaults.js';\r\nimport { log } from '../utils/progress.js';\r\n\r\n/**\r\n * Extract and parse frontmatter from remark AST\r\n */\r\nexport function extractFrontmatter(tree: Root): MarkdownFlyConfig {\r\n const yamlNode = tree.children.find((node) => node.type === 'yaml') as\r\n | { type: 'yaml'; value: string }\r\n | undefined;\r\n\r\n if (!yamlNode) {\r\n return { ...DEFAULT_CONFIG };\r\n }\r\n\r\n try {\r\n const parsed = parseYaml(yamlNode.value) as Partial<MarkdownFlyConfig> & {\r\n resource_dir?: string; // snake_case alias\r\n color_scheme?: string; // snake_case alias\r\n text_scheme?: string; // snake_case alias\r\n layout_scheme?: string; // snake_case alias\r\n };\r\n const { resource_dir, color_scheme, text_scheme, layout_scheme, ...parsedOnly } = parsed;\r\n const merged: MarkdownFlyConfig = {\r\n ...DEFAULT_CONFIG,\r\n ...parsedOnly,\r\n };\r\n if (resource_dir && !merged.resourceDir) {\r\n merged.resourceDir = resource_dir;\r\n }\r\n if (color_scheme && !merged.colorScheme) {\r\n merged.colorScheme = color_scheme;\r\n }\r\n if (text_scheme && !merged.textScheme) {\r\n merged.textScheme = text_scheme;\r\n }\r\n if (layout_scheme && !merged.layoutScheme) {\r\n merged.layoutScheme = layout_scheme;\r\n }\r\n return merged;\r\n } catch {\r\n log.warn('Failed to parse frontmatter YAML, using defaults');\r\n return { ...DEFAULT_CONFIG };\r\n }\r\n}\r\n","/**\r\n * ThemePreset — named package selecting one ColorScheme × TextScheme × LayoutScheme.\r\n *\r\n * User-facing theme names resolve via `theme` / `-t`:\r\n * ThemePreset first, then ColorScheme (legacy color-only path).\r\n */\r\n\r\nexport interface ThemePreset {\r\n /** Stable id used as the user-facing theme name, e.g. 'blue' */\r\n name: string;\r\n /** Registered ColorScheme name */\r\n colorScheme: string;\r\n /** Registered TextScheme name */\r\n textScheme: string;\r\n /** Registered LayoutScheme name */\r\n layoutScheme: string;\r\n /** Reserved for step 4 background-set — not consumed yet */\r\n backgroundScheme?: string;\r\n /** Documentation only */\r\n note?: string;\r\n}\r\n\r\n/** Default theme when `-t` / frontmatter `theme` is omitted. */\r\nexport const DEFAULT_THEME_NAME = 'blue';\r\n\r\n/** @deprecated Use DEFAULT_THEME_NAME; kept as alias for older imports. */\r\nexport const DEFAULT_PRESET_NAME = DEFAULT_THEME_NAME;\r\n","/**\r\n * Default configuration values\r\n */\r\n\r\nimport type { MarkdownFlyConfig } from './types.js';\r\nimport { DEFAULT_THEME_NAME } from '../models/theme-preset.js';\r\n\r\nexport const DEFAULT_CONFIG: MarkdownFlyConfig = {\r\n theme: DEFAULT_THEME_NAME,\r\n};\r\n","/**\n * Progress display using ora spinner + chalk\n */\n\nimport ora, { type Ora } from 'ora';\nimport chalk from 'chalk';\n\nlet quiet = false;\n\n/** Suppress all per-file progress output (errors/summaries are still printed). */\nexport function setQuiet(value: boolean): void {\n quiet = value;\n}\n\nexport class ProgressReporter {\n private spinner: Ora;\n\n constructor() {\n this.spinner = ora();\n }\n\n start(text: string): void {\n if (quiet) return;\n this.spinner.start(text);\n }\n\n update(text: string): void {\n if (quiet) return;\n this.spinner.text = text;\n }\n\n succeed(text: string): void {\n if (quiet) return;\n this.spinner.succeed(text);\n }\n\n fail(text: string): void {\n if (quiet) return;\n this.spinner.fail(text);\n }\n\n info(text: string): void {\n if (quiet) return;\n this.spinner.info(text);\n }\n}\n\nexport const log = {\n info: (msg: string) => console.log(chalk.blue('ℹ'), msg),\n success: (msg: string) => console.log(chalk.green('✔'), msg),\n warn: (msg: string) => console.error(chalk.yellow('⚠'), msg),\n error: (msg: string) => console.error(chalk.red('✖'), msg),\n};\n","/**\r\n * Diagram language registry — the single source of truth.\r\n *\r\n * Both the parser (a fenced block becomes a DiagramElement) and the renderer\r\n * registry dispatch on these names. They used to keep one hardcoded list each,\r\n * which meant a new language had to be added in two places or the block would\r\n * silently ship as a code block.\r\n */\r\n\r\n/** Canonical language → the renderer key it resolves to. */\r\nconst ALIASES: Record<string, string> = {\r\n graphviz: 'dot',\r\n puml: 'plantuml',\r\n};\r\n\r\n/** Languages that have a renderer, keyed by canonical name. */\r\nconst CANONICAL = new Set(['mermaid', 'dot', 'echarts', 'plantuml']);\r\n\r\n/**\r\n * Resolve any accepted spelling to its canonical language, or undefined when\r\n * the language is not a diagram. A Set is used rather than `in`/property\r\n * access so prototype keys ('constructor', 'toString') are not false positives.\r\n */\r\nexport function normalizeDiagramLanguage(language: string): string | undefined {\r\n const lang = language.toLowerCase();\r\n const canonical = ALIASES[lang] ?? lang;\r\n return CANONICAL.has(canonical) ? canonical : undefined;\r\n}\r\n\r\n/** Check if a code block language is a diagram type. */\r\nexport function isDiagramLanguage(language: string): boolean {\r\n return normalizeDiagramLanguage(language) !== undefined;\r\n}\r\n","/**\r\n * Slide Splitter\r\n * Converts remark AST into SlideNode[] with automatic layout detection\r\n */\r\n\r\nimport type { Root, Content, PhrasingContent } from 'mdast';\r\nimport type {\r\n SlideNode,\r\n SlideElement,\r\n SlideLayout,\r\n SlideDirectives,\r\n TextElement,\r\n HeadingElement,\r\n ListElement,\r\n CodeElement,\r\n ImageElement,\r\n TableElement,\r\n BlockquoteElement,\r\n DiagramElement,\r\n BreakElement,\r\n CalloutElement,\r\n ImageAlign,\r\n} from '../models/slide.js';\r\nimport { normalizeDiagramLanguage } from '../diagrams/languages.js';\r\n\r\n/** Callout variants recognized in blockquotes: > [!NOTE] / [!TIP] / ... */\r\nconst CALLOUT_VARIANTS = new Set([\r\n 'note', 'info', 'tip', 'success', 'warning', 'caution', 'danger',\r\n]);\r\n\r\n/**\r\n * Recursively extract plain text from mdast inline/phrasing nodes\r\n */\r\nfunction extractText(node: PhrasingContent | Content): string {\r\n if ('value' in node && typeof node.value === 'string') {\r\n return node.value;\r\n }\r\n // Soft line breaks inside blockquotes/lists map to \"\\n\"\r\n // (@types/mdast 4.0.4 omits Softbreak from its unions — cast to check)\r\n if ((node as { type: string }).type === 'softbreak') {\r\n return '\\n';\r\n }\r\n if ('children' in node && Array.isArray(node.children)) {\r\n return (node.children as PhrasingContent[]).map(extractText).join('');\r\n }\r\n return '';\r\n}\r\n\r\n/**\r\n * Parse an HTML comment node produced by preprocess.ts\r\n * Returns a BreakElement or directive key/values\r\n */\r\nfunction parseComment(value: string): BreakElement | { directives: Record<string, string> } | null {\r\n const match = value.match(/<!--\\s*mfly:(row|col|dir)\\s*(.*?)\\s*-->/s);\r\n if (!match) return null;\r\n\r\n if (match[1] === 'row' || match[1] === 'col') {\r\n return { type: 'break', direction: match[1] } satisfies BreakElement;\r\n }\r\n\r\n if (match[1] === 'dir') {\r\n const raw = decodeURIComponent(match[2]);\r\n return { directives: parseDirectiveString(raw) };\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Parse \"@(key=value, key=value, ...)\" into a record.\r\n * Values may be quoted (\"...\", '...') to contain commas or parens.\r\n */\r\nexport function parseDirectiveString(input: string): Record<string, string> {\r\n const inner = input.replace(/^@\\(/, '').replace(/\\)$/, '').trim();\r\n const result: Record<string, string> = {};\r\n if (!inner) return result;\r\n\r\n const re = /([A-Za-z][A-Za-z0-9_-]*)\\s*=\\s*(\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'|[^,)]+)/g;\r\n let m: RegExpExecArray | null;\r\n while ((m = re.exec(inner)) !== null) {\r\n let value = m[2].trim();\r\n if ((value.startsWith('\"') && value.endsWith('\"')) || (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\r\n value = value.slice(1, -1);\r\n }\r\n result[m[1]] = value;\r\n }\r\n return result;\r\n}\r\n\r\n/** Build the typed directive object for a slide */\r\nfunction toDirectives(raw: Record<string, string>): SlideDirectives {\r\n const d: SlideDirectives = {};\r\n if (raw.layout) d.layout = raw.layout;\r\n if (raw.notes) d.notes = raw.notes;\r\n if (raw.chart) d.chart = raw.chart;\r\n if (raw.highlight) d.highlight = raw.highlight;\r\n if (raw.background) d.background = raw.background;\r\n if (raw.steps) d.steps = raw.steps === 'true' || raw.steps === 'yes' || raw.steps === '1';\r\n return d;\r\n}\r\n\r\n/** Parse \"2-4,6,8-9\" style line ranges into a list of 1-based numbers */\r\nexport function parseHighlightRanges(spec: string): number[] {\r\n const lines = new Set<number>();\r\n for (const part of spec.split(',')) {\r\n const range = part.trim().match(/^(\\d+)\\s*-\\s*(\\d+)$/);\r\n if (range) {\r\n const from = Number(range[1]);\r\n const to = Number(range[2]);\r\n for (let n = Math.min(from, to); n <= Math.max(from, to); n++) lines.add(n);\r\n } else {\r\n const single = part.trim().match(/^\\d+$/);\r\n if (single) lines.add(Number(single));\r\n }\r\n }\r\n return [...lines].sort((a, b) => a - b);\r\n}\r\n\r\n/** Detect \"> [!NOTE] Custom title ...\" style callouts (moffee-compatible). */\r\nfunction parseCallout(content: string): CalloutElement | null {\r\n const lines = content.split('\\n');\r\n const markerMatch = lines[0]?.match(/^\\s*\\[!(.*?)\\]\\s*(.*?)\\s*$/);\r\n if (!markerMatch) return null;\r\n const variant = markerMatch[1].toLowerCase();\r\n if (!CALLOUT_VARIANTS.has(variant)) return null;\r\n const title = markerMatch[2].trim() || undefined;\r\n return {\r\n type: 'callout',\r\n variant,\r\n title,\r\n content: lines.slice(1).join('\\n').trim(),\r\n } satisfies CalloutElement;\r\n}\r\n\r\n/**\r\n * Parse a `{w=6in,h=40mm,align=left}` suffix into image element params.\r\n * Keys: w/width, h/height, align. Invalid pieces are silently ignored, so a\r\n * `![alt](src){w=200}` line still renders the image.\r\n */\r\nfunction parseImageParams(text: string): Pick<ImageElement, 'width' | 'height' | 'align'> {\r\n const result: Pick<ImageElement, 'width' | 'height' | 'align'> = {};\r\n const body = text.replace(/^\\{\\s*|\\s*\\}$/g, '');\r\n for (const part of body.split(',')) {\r\n const eq = part.indexOf('=');\r\n if (eq === -1) continue;\r\n const key = part.slice(0, eq).trim().toLowerCase();\r\n const value = part.slice(eq + 1).trim();\r\n switch (key) {\r\n case 'w':\r\n case 'width': {\r\n const normalized = normalizeImageSize(value);\r\n if (normalized) result.width = normalized;\r\n break;\r\n }\r\n case 'h':\r\n case 'height': {\r\n const normalized = normalizeImageSize(value);\r\n if (normalized) result.height = normalized;\r\n break;\r\n }\r\n case 'align': {\r\n if (value === 'left' || value === 'center' || value === 'right') {\r\n result.align = value as ImageAlign;\r\n }\r\n break;\r\n }\r\n }\r\n }\r\n return result;\r\n}\r\n\r\n/** Normalize to '<n>in' or '<n>%'; bare numbers are px (96 dpi). Invalid → undefined. */\r\nfunction normalizeImageSize(value: string): string | undefined {\r\n const match = value.match(/^(\\d+(?:\\.\\d+)?)(px|pt|cm|mm|in|inch|%)?$/i);\r\n if (!match) return undefined;\r\n const n = parseFloat(match[1]);\r\n if (!(n > 0)) return undefined;\r\n const unit = (match[2] || 'px').toLowerCase();\r\n if (unit === '%') return `${n}%`;\r\n const inches =\r\n unit === 'px' ? n / 96 : unit === 'pt' ? n / 72 : unit === 'cm' ? n / 2.54 : unit === 'mm' ? n / 25.4 : n;\r\n return `${Math.round(inches * 100) / 100}in`;\r\n}\r\n\r\n/**\r\n * Convert an mdast content node to a SlideElement\r\n */\r\nfunction nodeToElement(node: Content): SlideElement | null {\r\n switch (node.type) {\r\n case 'heading': {\r\n return {\r\n type: 'heading',\r\n content: node.children.map(extractText).join(''),\r\n level: node.depth,\r\n } satisfies HeadingElement;\r\n }\r\n\r\n case 'paragraph': {\r\n // A paragraph holding exactly one image — optionally followed by a\r\n // {w=...,align=...} suffix, which CommonMark parses as a plain text node.\r\n const first = node.children[0];\r\n if (first?.type === 'image') {\r\n const rest = node.children.slice(1);\r\n const paramsFromText = (() => {\r\n if (rest.length === 0) return {};\r\n if (!rest.every((c) => c.type === 'text')) return null;\r\n const suffix = rest\r\n .map((c) => (c.type === 'text' ? c.value : ''))\r\n .join('')\r\n .trim();\r\n const match = suffix.match(/^\\{.*\\}$/);\r\n return match ? parseImageParams(match[0]) : null;\r\n })();\r\n if (paramsFromText !== null) {\r\n return {\r\n type: 'image',\r\n src: first.url,\r\n alt: first.alt ?? undefined,\r\n ...paramsFromText,\r\n } satisfies ImageElement;\r\n }\r\n }\r\n return {\r\n type: 'text',\r\n content: node.children.map(extractText).join(''),\r\n } satisfies TextElement;\r\n }\r\n\r\n case 'list': {\r\n // remark-gfm sets checked to true/false for task items and null for\r\n // plain items — only treat boolean values as task-list markers.\r\n const hasCheckboxes = node.children.some(\r\n (item) => typeof item.checked === 'boolean',\r\n );\r\n const items = node.children.map((item) => {\r\n return item.children.map((child) => extractText(child)).join('');\r\n });\r\n const result: ListElement = {\r\n type: 'list',\r\n items,\r\n ordered: node.ordered ?? false,\r\n };\r\n if (hasCheckboxes) {\r\n result.checked = node.children.map((item) =>\r\n typeof item.checked === 'boolean' ? item.checked : false,\r\n );\r\n }\r\n return result;\r\n }\r\n\r\n case 'code': {\r\n const lang = node.lang?.toLowerCase() ?? '';\r\n const diagramType = normalizeDiagramLanguage(lang);\r\n if (diagramType) {\r\n return {\r\n type: 'diagram',\r\n diagramType,\r\n content: node.value,\r\n } satisfies DiagramElement;\r\n }\r\n const element = {\r\n type: 'code',\r\n content: node.value,\r\n language: node.lang ?? undefined,\r\n } satisfies CodeElement;\r\n return element;\r\n }\r\n\r\n case 'image': {\r\n return {\r\n type: 'image',\r\n src: node.url,\r\n alt: node.alt ?? undefined,\r\n } satisfies ImageElement;\r\n }\r\n\r\n case 'table': {\r\n const rows = node.children.map((row) =>\r\n row.children.map((cell) =>\r\n cell.children.map(extractText).join(''),\r\n ),\r\n );\r\n const headers = rows.length > 0 ? rows[0] : [];\r\n const bodyRows = rows.slice(1);\r\n return {\r\n type: 'table',\r\n headers,\r\n rows: bodyRows,\r\n } satisfies TableElement;\r\n }\r\n\r\n case 'blockquote': {\r\n const content = node.children\r\n .map((child) => extractText(child))\r\n .join('\\n');\r\n const callout = parseCallout(content);\r\n if (callout) return callout;\r\n return {\r\n type: 'blockquote',\r\n content,\r\n } satisfies BlockquoteElement;\r\n }\r\n\r\n case 'html': {\r\n const parsed = parseComment(node.value);\r\n if (parsed === null) return null;\r\n if ('direction' in parsed) return parsed;\r\n // Directive comments are collected by the caller — see splitIntoSlides\r\n return null;\r\n }\r\n\r\n default:\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Determine slide layout based on content (rule engine)\r\n */\r\nfunction detectLayout(\r\n title: string | undefined,\r\n elements: SlideElement[],\r\n isFirstSlide: boolean,\r\n headingLevel: number,\r\n): SlideLayout {\r\n // First slide with H1 → title\r\n if (isFirstSlide && headingLevel === 1) {\r\n return 'title';\r\n }\r\n\r\n // H2 with no body content → section divider\r\n if (headingLevel === 2 && elements.length === 0) {\r\n return 'section';\r\n }\r\n\r\n // Only code elements → code layout\r\n const nonEmptyElements = elements.filter(\r\n (e) => e.type !== 'text' || e.content.trim() !== '',\r\n );\r\n if (\r\n nonEmptyElements.length > 0 &&\r\n nonEmptyElements.every((e) => e.type === 'code')\r\n ) {\r\n return 'code';\r\n }\r\n\r\n // Only blockquote → quote layout\r\n if (\r\n nonEmptyElements.length > 0 &&\r\n nonEmptyElements.every((e) => e.type === 'blockquote')\r\n ) {\r\n return 'quote';\r\n }\r\n\r\n // Pure image pages (layout-set step 3): 1–3 images, no substantial body.\r\n // Existing rules above win; only additive. Mixed / heavy text stays `content`.\r\n if (nonEmptyElements.length > 0) {\r\n const images = nonEmptyElements.filter((e) => e.type === 'image');\r\n const others = nonEmptyElements.filter(\r\n (e) => e.type !== 'image' && e.type !== 'text',\r\n );\r\n const texts = nonEmptyElements.filter((e) => e.type === 'text');\r\n const substantialText = texts.some((e) => e.type === 'text' && e.content.trim().length > 40);\r\n if (\r\n others.length === 0 &&\r\n !substantialText &&\r\n images.length >= 1 &&\r\n images.length <= 3\r\n ) {\r\n if (images.length === 1) return 'image-single';\r\n if (images.length === 2) return 'image-double';\r\n return 'image-triple';\r\n }\r\n }\r\n\r\n return 'content';\r\n}\r\n\r\n/**\r\n * Split remark AST into SlideNode array\r\n * @param defaultLayout Optional frontmatter layout; the auto-detection rule\r\n * engine runs first, @(layout=...) directives override it.\r\n */\r\nexport function splitIntoSlides(tree: Root, defaultLayout?: string): SlideNode[] {\r\n const slides: SlideNode[] = [];\r\n let currentTitle: string | undefined;\r\n let currentSubtitle: string | undefined;\r\n let currentElements: SlideElement[] = [];\r\n let currentDirectives: Record<string, string> = {};\r\n let currentHeadingLevel = 0;\r\n let isFirstSlide = true;\r\n // 封面作者 / 日期:识别 `作者:…` / `日期:…` 前缀段,独立于正文元素存储\r\n let currentAuthor: string | undefined;\r\n let currentDate: string | undefined;\r\n\r\n function flushSlide(): void {\r\n // Don't create empty slides (but keep slides that carry directives/notes)\r\n if (!currentTitle && currentElements.length === 0 && Object.keys(currentDirectives).length === 0) {\r\n return;\r\n }\r\n\r\n // Apply @(highlight=...) to the slide's code block if not already applied\r\n if (currentDirectives.highlight && currentElements.length > 0) {\r\n const ranges = parseHighlightRanges(currentDirectives.highlight);\r\n if (ranges.length > 0) {\r\n const code = currentElements.find(\r\n (e): e is CodeElement => e.type === 'code' && !e.highlightLines,\r\n );\r\n if (code) code.highlightLines = ranges;\r\n }\r\n }\r\n\r\n const autoLayout = detectLayout(\r\n currentTitle,\r\n currentElements,\r\n isFirstSlide && slides.length === 0,\r\n currentHeadingLevel,\r\n );\r\n // Precedence: @(layout=...) directive > structural auto-detection\r\n // (title/section/code/quote) > frontmatter fallback (only for generic\r\n // content slides) > generic content.\r\n const layout: SlideLayout = (currentDirectives.layout as SlideLayout | undefined) ??\r\n (autoLayout === 'content' ? (defaultLayout as SlideLayout | undefined) : autoLayout) ??\r\n 'content';\r\n\r\n const metadata: SlideNode['metadata'] =\r\n currentAuthor || currentDate\r\n ? { author: currentAuthor, date: currentDate }\r\n : undefined;\r\n\r\n slides.push({\r\n layout,\r\n title: currentTitle,\r\n subtitle: currentSubtitle,\r\n elements: currentElements,\r\n notes: currentDirectives.notes,\r\n directives: toDirectives(currentDirectives),\r\n ...(metadata ? { metadata } : {}),\r\n });\r\n\r\n currentTitle = undefined;\r\n currentSubtitle = undefined;\r\n currentElements = [];\r\n currentDirectives = {};\r\n currentHeadingLevel = 0;\r\n currentAuthor = undefined;\r\n currentDate = undefined;\r\n isFirstSlide = false;\r\n }\r\n\r\n for (const node of tree.children) {\r\n // Skip frontmatter\r\n if (node.type === 'yaml') continue;\r\n\r\n // --- separator → new slide\r\n if (node.type === 'thematicBreak') {\r\n flushSlide();\r\n continue;\r\n }\r\n\r\n // H1 or H2 → new slide\r\n if (node.type === 'heading' && (node.depth === 1 || node.depth === 2)) {\r\n flushSlide();\r\n currentTitle = node.children.map(extractText).join('');\r\n currentHeadingLevel = node.depth;\r\n continue;\r\n }\r\n\r\n // Directive comment may precede content in any position — collect it,\r\n // but preserve ordering by pushing to elements when it's a break marker.\r\n if (node.type === 'html') {\r\n const parsed = parseComment(node.value);\r\n if (parsed !== null) {\r\n if ('direction' in parsed) {\r\n currentElements.push(parsed);\r\n } else {\r\n Object.assign(currentDirectives, parsed.directives);\r\n }\r\n }\r\n continue;\r\n }\r\n\r\n // 封面元信息段:仅在首页封面识别「作者:…」/「日期:…」前缀行,\r\n // 提取后不入正文元素。允许多行(软换行或空行分隔);仅当段落由这些\r\n // 元信息行构成时才提取,避免吞掉真正的正文。\r\n if (node.type === 'paragraph' && isFirstSlide && slides.length === 0) {\r\n const lines = node.children.map(extractText).join('').trim().split('\\n');\r\n let metaAuthor: string | undefined;\r\n let metaDate: string | undefined;\r\n const metaOnly = lines.every((raw) => {\r\n const line = raw.trim();\r\n if (!line) return true;\r\n const authorMatch = line.match(/^作者\\s*[::]\\s*(.+)$/);\r\n if (authorMatch) {\r\n metaAuthor = authorMatch[1].trim();\r\n return true;\r\n }\r\n const dateMatch = line.match(/^日期\\s*[::]\\s*(.+)$/);\r\n if (dateMatch) {\r\n metaDate = dateMatch[1].trim();\r\n return true;\r\n }\r\n return false;\r\n });\r\n if (metaOnly && (metaAuthor || metaDate)) {\r\n if (metaAuthor) currentAuthor = metaAuthor;\r\n if (metaDate) currentDate = metaDate;\r\n continue;\r\n }\r\n }\r\n\r\n // Other content → add to current slide\r\n const element = nodeToElement(node);\r\n if (element) {\r\n currentElements.push(element);\r\n }\r\n }\r\n\r\n // Flush remaining content\r\n flushSlide();\r\n\r\n return slides;\r\n}\r\n","/**\n * Preprocess the raw markdown before remark parsing.\n *\n * Converts inline layout markers that are NOT valid CommonMark into HTML\n * comment nodes, which remark keeps intact and our splitter can recognize:\n *\n * === (standalone line) → <!-- mfly:row --> vertical block separator\n * <-> (standalone line) → <!-- mfly:col --> horizontal column separator\n * @(...) (standalone line) → <!-- mfly:dir:... --> slide-level directive\n *\n * Standalone lines starting with `%%` are removed entirely (like moffee's\n * comment syntax) — handy for drafting notes that never reach the deck.\n *\n * Why comments: `===` collides with setext heading underlines, and `<->`\n * would otherwise be a plain paragraph. Encoding them as comments makes the\n * AST explicit and keeps the rest of the markdown untouched.\n *\n * Lines inside fenced code blocks are never rewritten.\n */\n\nconst ROW_RE = /^={3,}$/;\nconst COL_RE = /^<->$/;\nconst DIR_RE = /^@\\(.+\\)$/;\nconst COMMENT_RE = /^%%/;\n\nexport function preprocessMarkdown(markdown: string): string {\n const lines = markdown.split('\\n');\n const out: string[] = [];\n\n let inFence = false;\n let fenceChar = '';\n\n for (const line of lines) {\n const trimmed = line.trim();\n const fenceMatch = trimmed.match(/^(`{3,}|~{3,})/);\n\n if (!inFence) {\n if (fenceMatch) {\n inFence = true;\n fenceChar = fenceMatch[1][0];\n out.push(line);\n continue;\n }\n if (COMMENT_RE.test(trimmed)) {\n // Drop %% comment lines entirely\n out.push('');\n continue;\n }\n if (COL_RE.test(trimmed)) {\n out.push('<!-- mfly:col -->');\n continue;\n }\n if (ROW_RE.test(trimmed)) {\n out.push('<!-- mfly:row -->');\n continue;\n }\n if (DIR_RE.test(trimmed)) {\n // Encode so anything inside (parens, \"--\", etc.) is comment-safe\n out.push(`<!-- mfly:dir:${encodeURIComponent(trimmed)} -->`);\n continue;\n }\n out.push(line);\n continue;\n }\n\n // Inside a fenced block: only watch for the closing fence\n out.push(line);\n if (fenceMatch && trimmed.startsWith(fenceChar)) {\n inFence = false;\n }\n }\n\n return out.join('\\n');\n}\n","/**\r\n * PPTX Renderer\r\n * Orchestrates pptxgenjs to produce .pptx files from Presentation\r\n */\r\n\r\nimport PptxGenJS from 'pptxgenjs';\r\nimport type { Presentation } from '../models/slide.js';\r\nimport type { Theme } from '../models/theme.js';\r\nimport { renderSlideLayout } from './layouts/index.js';\r\nimport { highlightCode } from './code-highlighter.js';\r\nimport { resolveImage } from './image-handler.js';\r\nimport { renderDiagram } from '../diagrams/index.js';\r\nimport { slideBackground } from './background.js';\r\n\r\nimport { writeFileSync } from 'node:fs';\r\nimport { dirname, resolve } from 'node:path';\r\n\r\n/**\r\n * Render a Presentation to a .pptx file\r\n */\r\nexport async function renderPresentation(\r\n presentation: Presentation,\r\n theme: Theme,\r\n outputPath: string,\r\n inputPath: string = '',\r\n): Promise<void> {\r\n const pptx = new PptxGenJS();\r\n\r\n // Configure presentation\r\n pptx.layout = 'LAYOUT_WIDE'; // 16:9 = 13.33\" x 7.5\"\r\n pptx.author = presentation.config.author ?? 'MarkdownFly';\r\n pptx.title = presentation.slides[0]?.title ?? 'Presentation';\r\n\r\n const { resourceDir } = presentation.config;\r\n // Frontmatter resource_dir: relative paths are relative to the source file,\r\n // not the process cwd (agents may run from anywhere). basePath is a directory.\r\n const resourceBase = resourceDir\r\n ? resolve(dirname(inputPath), resourceDir)\r\n : dirname(inputPath);\r\n const backgroundProps = slideBackground(theme);\r\n\r\n // Build render context\r\n const ctx = {\r\n highlightCode: async (code: string, language: string, highlightLines: number[] = []) => {\r\n return highlightCode(code, language, theme, highlightLines) as unknown as Promise<PptxGenJS.TextProps[]>;\r\n },\r\n resolveImage: async (src: string) => {\r\n return resolveImage(src, resourceBase);\r\n },\r\n renderDiagram: async (diagramType: string, code: string) => {\r\n return renderDiagram(diagramType, code, theme);\r\n },\r\n footerTemplate: presentation.config.footer,\r\n pageNumber: 0,\r\n totalSlides: presentation.slides.length,\r\n currentSection: '',\r\n sectionNumber: 0,\r\n };\r\n\r\n // Render each slide\r\n for (let i = 0; i < presentation.slides.length; i++) {\r\n const node = presentation.slides[i];\r\n const slide = pptx.addSlide();\r\n\r\n // Set default background (flat color or theme gradient image)\r\n slide.background = backgroundProps;\r\n\r\n ctx.pageNumber = i + 1;\r\n if (node.layout === 'section') {\r\n if (node.title) ctx.currentSection = node.title;\r\n // Auto-increment section sequence before drawing, so the first section\r\n // slide shows \"01\" and every following one continues the count.\r\n ctx.sectionNumber = (ctx.sectionNumber ?? 0) + 1;\r\n }\r\n\r\n await renderSlideLayout(slide, node, theme, ctx);\r\n }\r\n\r\n // Write file using nodebuffer for 100% reliable path handling across OS\r\n const buffer = (await pptx.write({ outputType: 'nodebuffer' })) as Buffer;\r\n writeFileSync(outputPath, Buffer.from(buffer));\r\n}\r\n","/**\r\n * Shared layout-spec helpers — theme.layouts.* with hard-coded fallbacks.\r\n */\r\n\r\nimport type PptxGenJS from 'pptxgenjs';\r\nimport type { Theme, ThemeLayoutSpec, ThemeLayouts } from '../../models/theme.js';\r\n\r\nexport function layoutSpec(theme: Theme, key: keyof ThemeLayouts): ThemeLayoutSpec {\r\n return theme.layouts?.[key] ?? {};\r\n}\r\n\r\nexport function specNumber(\r\n value: number | undefined,\r\n fallback: number,\r\n): number {\r\n return typeof value === 'number' && Number.isFinite(value) ? value : fallback;\r\n}\r\n\r\nexport function specAlign(\r\n value: 'left' | 'center' | 'right' | undefined,\r\n fallback: 'left' | 'center' | 'right',\r\n): 'left' | 'center' | 'right' {\r\n return value ?? fallback;\r\n}\r\n\r\nexport function extraNumber(\r\n spec: ThemeLayoutSpec,\r\n key: string,\r\n fallback: number,\r\n): number {\r\n const v = spec.extra?.[key];\r\n return typeof v === 'number' && Number.isFinite(v) ? v : fallback;\r\n}\r\n\r\nexport function extraBoolean(\r\n spec: ThemeLayoutSpec,\r\n key: string,\r\n fallback: boolean,\r\n): boolean {\r\n const v = spec.extra?.[key];\r\n return typeof v === 'boolean' ? v : fallback;\r\n}\r\n\r\nexport function extraString(\r\n spec: ThemeLayoutSpec,\r\n key: string,\r\n fallback: string,\r\n): string {\r\n const v = spec.extra?.[key];\r\n return typeof v === 'string' && v ? v : fallback;\r\n}\r\n\r\n/**\r\n * Resolve horizontal margins from a layout spec.\r\n * `margin` applies to both sides; `marginLeft`/`marginRight` override each side.\r\n */\r\nexport function resolveSideMargins(\r\n spec: ThemeLayoutSpec,\r\n fallback: number,\r\n): { left: number; right: number } {\r\n const base = specNumber(spec.margin, fallback);\r\n return {\r\n left: specNumber(spec.extra?.marginLeft as number | undefined, base),\r\n right: specNumber(spec.extra?.marginRight as number | undefined, base),\r\n };\r\n}\r\n\r\nexport function titleRuleHeight(spec: ThemeLayoutSpec, fallback: number): number {\r\n return extraNumber(spec, 'titleRuleHeight', fallback);\r\n}\r\n\r\nexport function titleRuleRole(spec: ThemeLayoutSpec): 'primary' | 'secondary' | 'divider' {\r\n const v = spec.extra?.titleRuleColor;\r\n return v === 'secondary' || v === 'divider' ? v : 'primary';\r\n}\r\n\r\nexport function ruleColor(\r\n theme: Theme,\r\n role: 'primary' | 'secondary' | 'divider',\r\n): string {\r\n if (role === 'secondary') return theme.colors.secondary;\r\n if (role === 'divider') return theme.colors.divider ?? theme.colors.secondary;\r\n return theme.colors.primary;\r\n}\r\n\r\n/** Draw a solid rectangle rule (horizontal or vertical depending on w/h) */\r\nexport function addHRuler(\r\n slide: PptxGenJS.Slide,\r\n opts: { x: number; y: number; w: number; h: number; color: string },\r\n): void {\r\n slide.addShape('rect' as PptxGenJS.ShapeType, {\r\n x: opts.x,\r\n y: opts.y,\r\n w: opts.w,\r\n h: opts.h,\r\n fill: { color: opts.color },\r\n });\r\n}\r\n","/**\r\n * Title slide layout — cover/opening slide\r\n *\r\n * Creative extras (folio etc., all optional; omit → legacy-centered cover):\r\n * - extra.spineWidth: left full-height spine bar (inches)\r\n * - extra.titleY / subtitleY / metaY: vertical anchors\r\n * - extra.titleRule: draw a horizontal rule under the title\r\n * - extra.metaBottom: park meta near the slide bottom\r\n */\r\n\r\nimport PptxGenJS from 'pptxgenjs';\r\nimport type { SlideNode } from '../../models/slide.js';\r\nimport type { Theme } from '../../models/theme.js';\r\nimport {\r\n addHRuler,\r\n extraBoolean,\r\n extraNumber,\r\n layoutSpec,\r\n resolveSideMargins,\r\n ruleColor,\r\n specAlign,\r\n titleRuleRole,\r\n} from './layout-spec.js';\r\n\r\nexport function renderTitleSlide(\r\n slide: PptxGenJS.Slide,\r\n node: SlideNode,\r\n theme: Theme,\r\n): void {\r\n const spec = layoutSpec(theme, 'title');\r\n\r\n // minimal 封面:左侧竖装饰线 + 主/副标题沿竖线左对齐 + 作者/日期沉底\r\n if (extraBoolean(spec, 'minimalTitle', false)) {\r\n renderMinimalTitle(slide, node, theme);\r\n return;\r\n }\r\n\r\n const align = specAlign(spec.titleAlign, 'center');\r\n const { left, right } = resolveSideMargins(spec, 0.8);\r\n const spineW = extraNumber(spec, 'spineWidth', 0);\r\n const boxX = left + spineW;\r\n const contentW = Math.max(2, 13.33 - boxX - right);\r\n\r\n const textColor = theme.colors.titleText ?? 'FFFFFF';\r\n const subtitleColor = textColor === 'FFFFFF' ? 'FFFFFFCC' : theme.colors.secondary;\r\n const metaColor = textColor === 'FFFFFF' ? 'FFFFFF99' : theme.colors.secondary;\r\n\r\n const bgColor = theme.colors.backgroundGradient\r\n ? undefined\r\n : theme.colors.titleBackground ?? theme.colors.primary;\r\n if (bgColor) {\r\n slide.background = { color: bgColor };\r\n }\r\n\r\n // Editorial spine on the left edge\r\n if (spineW > 0) {\r\n slide.addShape('rect' as PptxGenJS.ShapeType, {\r\n x: 0,\r\n y: 0,\r\n w: spineW,\r\n h: 7.5,\r\n fill: { color: theme.colors.primary },\r\n });\r\n }\r\n\r\n const titleY = extraNumber(spec, 'titleY', 2.0);\r\n const subtitleY = extraNumber(spec, 'subtitleY', 3.8);\r\n const metaBottom = extraBoolean(spec, 'metaBottom', false);\r\n const metaY = extraNumber(spec, 'metaY', metaBottom ? 6.55 : 5.5);\r\n\r\n if (node.title) {\r\n // Optional scale-up for the cover title (layout-driven; default 1 = legacy/folio)\r\n const titleScale = extraNumber(spec, 'titleFontSizeScale', 1);\r\n slide.addText(node.title, {\r\n x: boxX,\r\n y: titleY,\r\n w: contentW,\r\n h: 1.5,\r\n fontSize: Math.round(theme.fontSize.title * titleScale),\r\n fontFace: theme.fonts.heading,\r\n color: textColor,\r\n bold: true,\r\n align,\r\n valign: 'middle',\r\n });\r\n\r\n if (extraBoolean(spec, 'titleRule', false)) {\r\n const ruleH = extraNumber(spec, 'titleRuleHeight', 0.03);\r\n const ruleY = extraNumber(spec, 'titleRuleY', titleY + 1.55);\r\n const ruleW = extraNumber(spec, 'titleRuleWidth', Math.min(contentW, 4.2));\r\n // Anchor the rule to the same edge as the title alignment (right → right edge)\r\n let ruleX = boxX;\r\n if (align === 'center') ruleX = boxX + (contentW - ruleW) / 2;\r\n else if (align === 'right') ruleX = boxX + contentW - ruleW;\r\n addHRuler(slide, { x: ruleX, y: ruleY, w: ruleW, h: ruleH, color: ruleColor(theme, titleRuleRole(spec)) });\r\n }\r\n }\r\n\r\n if (node.subtitle) {\r\n slide.addText(node.subtitle, {\r\n x: boxX,\r\n y: subtitleY,\r\n w: contentW,\r\n h: 0.8,\r\n fontSize: theme.fontSize.body,\r\n fontFace: theme.fonts.body,\r\n color: subtitleColor,\r\n align,\r\n valign: 'middle',\r\n });\r\n }\r\n\r\n // 作者 / 日期:来自封面前缀段元信息,作者在上、日期在下叠排。\r\n const meta = node.metadata ?? {};\r\n const author = typeof meta.author === 'string' ? meta.author : undefined;\r\n const date = typeof meta.date === 'string' ? meta.date : undefined;\r\n const textElements = node.elements.filter((e) => e.type === 'text');\r\n if (author || date) {\r\n const lineH = 0.31;\r\n if (author) {\r\n slide.addText(author, {\r\n x: boxX,\r\n y: metaY,\r\n w: contentW,\r\n h: lineH,\r\n fontSize: theme.fontSize.small,\r\n fontFace: theme.fonts.body,\r\n color: metaColor,\r\n align,\r\n valign: 'middle',\r\n });\r\n }\r\n if (date) {\r\n slide.addText(date, {\r\n x: boxX,\r\n y: metaY + lineH + 0.03,\r\n w: contentW,\r\n h: lineH,\r\n fontSize: theme.fontSize.small,\r\n fontFace: theme.fonts.body,\r\n color: metaColor,\r\n align,\r\n valign: 'middle',\r\n });\r\n }\r\n } else if (textElements.length > 0) {\r\n const metaText = textElements.map((e) => e.content).join(' · ');\r\n slide.addText(metaText, {\r\n x: boxX,\r\n y: metaY,\r\n w: contentW,\r\n h: 0.6,\r\n fontSize: theme.fontSize.small,\r\n fontFace: theme.fonts.body,\r\n color: metaColor,\r\n align,\r\n });\r\n }\r\n}\r\n\r\n/**\r\n * minimal 封面:统一边距上的左侧竖装饰线;主/副标题沿竖线右缘左对齐;\r\n * 作者与日期沉底,整页留白充足。\r\n */\r\nfunction renderMinimalTitle(\r\n slide: PptxGenJS.Slide,\r\n node: SlideNode,\r\n theme: Theme,\r\n): void {\r\n const spec = layoutSpec(theme, 'title');\r\n\r\n // 页面背景用主色块(方案「元素 1」)\r\n const bgColor =\r\n theme.colors.backgroundGradient\r\n ? undefined\r\n : theme.colors.titleBackground ?? theme.colors.primary;\r\n if (bgColor) {\r\n slide.background = { color: bgColor };\r\n }\r\n const textColor = theme.colors.titleText ?? 'FFFFFF';\r\n const softColor = textColor === 'FFFFFF' ? 'FFFFFFCC' : theme.colors.secondary;\r\n\r\n // 左侧竖装饰线(x=左边距,垂直居中于标题组高度)\r\n const lineX = extraNumber(spec, 'minimalLineX', 0.83);\r\n const lineY1 = extraNumber(spec, 'minimalLineY1', 2.64);\r\n const lineH = extraNumber(spec, 'minimalLineH', 1.94);\r\n const lineW = extraNumber(spec, 'minimalLineW', 0.04);\r\n slide.addShape('rect' as PptxGenJS.ShapeType, {\r\n x: lineX,\r\n y: lineY1,\r\n w: lineW,\r\n h: lineH,\r\n fill: { color: textColor },\r\n });\r\n\r\n const boxX = extraNumber(spec, 'minimalBoxX', 1.11);\r\n const contentW = extraNumber(spec, 'minimalBoxW', 8.89);\r\n\r\n if (node.title) {\r\n slide.addText(node.title, {\r\n x: boxX,\r\n y: extraNumber(spec, 'minimalTitleY', 2.64),\r\n w: contentW,\r\n h: 0.89,\r\n fontSize: theme.fontSize.title,\r\n fontFace: theme.fonts.heading,\r\n color: textColor,\r\n bold: true,\r\n align: 'left',\r\n valign: 'middle',\r\n });\r\n }\r\n\r\n if (node.subtitle) {\r\n slide.addText(node.subtitle, {\r\n x: boxX,\r\n y: extraNumber(spec, 'minimalSubtitleY', 3.64),\r\n w: contentW,\r\n h: 0.44,\r\n fontSize: theme.fontSize.body,\r\n fontFace: theme.fonts.body,\r\n color: softColor,\r\n align: 'left',\r\n valign: 'middle',\r\n });\r\n }\r\n\r\n // 作者 / 日期:来自封面前缀段元信息,作者在上(5.28)、日期在下(5.64)。\r\n const meta = node.metadata ?? {};\r\n const author = typeof meta.author === 'string' ? meta.author : undefined;\r\n const date = typeof meta.date === 'string' ? meta.date : undefined;\r\n const metaX = boxX;\r\n const metaW = extraNumber(spec, 'minimalMetaW', 4.17);\r\n const metaH = 0.31;\r\n if (author) {\r\n slide.addText(author, {\r\n x: metaX,\r\n y: extraNumber(spec, 'minimalAuthorY', 5.28),\r\n w: metaW,\r\n h: metaH,\r\n fontSize: theme.fontSize.small,\r\n fontFace: theme.fonts.body,\r\n color: softColor,\r\n align: 'left',\r\n valign: 'middle',\r\n });\r\n }\r\n if (date) {\r\n slide.addText(date, {\r\n x: metaX,\r\n y: extraNumber(spec, 'minimalDateY', 5.64),\r\n w: metaW,\r\n h: metaH,\r\n fontSize: theme.fontSize.small,\r\n fontFace: theme.fonts.body,\r\n color: softColor,\r\n align: 'left',\r\n valign: 'middle',\r\n });\r\n }\r\n}\r\n","/**\r\n * Section divider slide layout\r\n *\r\n * Creative extras:\r\n * - accentBar 'none' + extra.doubleRules → magazine band framed by two rules\r\n * - extra.ruleWeight / extra.bandY / extra.bandH control the ruled band\r\n */\r\n\r\nimport PptxGenJS from 'pptxgenjs';\r\nimport type { SlideNode } from '../../models/slide.js';\r\nimport type { Theme } from '../../models/theme.js';\r\nimport type { RenderContext } from './index.js';\r\nimport {\r\n addHRuler,\r\n extraBoolean,\r\n extraNumber,\r\n extraString,\r\n layoutSpec,\r\n resolveSideMargins,\r\n ruleColor,\r\n specAlign,\r\n titleRuleRole,\r\n} from './layout-spec.js';\r\n\r\n/** Zero-pad a number to two digits (1 → \"01\", 12 → \"12\"). */\r\nexport function formatSectionNumber(n: number): string {\r\n return String(n).padStart(2, '0');\r\n}\r\n\r\nexport function renderSectionSlide(\r\n slide: PptxGenJS.Slide,\r\n node: SlideNode,\r\n theme: Theme,\r\n ctx?: RenderContext,\r\n): void {\r\n const spec = layoutSpec(theme, 'section');\r\n\r\n // minimal: 超大章节序号 + 竖分隔线 + 标题 的横排布局\r\n if (extraBoolean(spec, 'minimalNumber', false)) {\r\n renderMinimalSection(slide, node, theme, ctx);\r\n return;\r\n }\r\n\r\n const barW = theme.styles?.sectionBarWidth ?? extraNumber(spec, 'sectionBarWidth', 0.15);\r\n const accentBar = spec.accentBar ?? 'left';\r\n const titleAlign = specAlign(spec.titleAlign, 'left');\r\n const { left, right } = resolveSideMargins(spec, accentBar === 'left' ? 1.0 : 0.9);\r\n\r\n if (accentBar !== 'none') {\r\n if (accentBar === 'left') {\r\n slide.addShape('rect' as PptxGenJS.ShapeType, {\r\n x: 0,\r\n y: 0,\r\n w: barW,\r\n h: 7.5,\r\n fill: { color: theme.colors.accent },\r\n });\r\n } else if (accentBar === 'top') {\r\n slide.addShape('rect' as PptxGenJS.ShapeType, {\r\n x: 0,\r\n y: 0,\r\n w: 13.33,\r\n h: barW,\r\n fill: { color: theme.colors.accent },\r\n });\r\n } else if (accentBar === 'bottom') {\r\n slide.addShape('rect' as PptxGenJS.ShapeType, {\r\n x: 0,\r\n y: 7.5 - barW,\r\n w: 13.33,\r\n h: barW,\r\n fill: { color: theme.colors.accent },\r\n });\r\n }\r\n }\r\n\r\n const leftPad = accentBar === 'left' ? Math.max(left, barW + 0.85) : left;\r\n const textW = Math.max(3, 13.33 - leftPad - right);\r\n\r\n // Ruled editorial band (innovative section: no side bar)\r\n if (extraBoolean(spec, 'doubleRules', false)) {\r\n const weight = extraNumber(spec, 'ruleWeight', 0.035);\r\n const bandY = extraNumber(spec, 'bandY', 2.35);\r\n const bandH = extraNumber(spec, 'bandH', 1.7);\r\n const color = ruleColor(theme, titleRuleRole(spec) === 'primary' ? 'primary' : titleRuleRole(spec));\r\n const ruleX = leftPad;\r\n const ruleW = textW;\r\n addHRuler(slide, { x: ruleX, y: bandY, w: ruleW, h: weight, color });\r\n addHRuler(slide, { x: ruleX, y: bandY + bandH, w: ruleW, h: weight, color });\r\n\r\n if (node.title) {\r\n slide.addText(node.title, {\r\n x: leftPad,\r\n y: bandY + weight + 0.08,\r\n w: textW,\r\n h: bandH - weight * 2 - 0.16,\r\n fontSize: theme.fontSize.heading + 6,\r\n fontFace: theme.fonts.heading,\r\n color: theme.colors.text,\r\n bold: true,\r\n align: titleAlign,\r\n valign: 'middle',\r\n });\r\n }\r\n\r\n const sub = node.subtitle?.trim();\r\n if (sub) {\r\n slide.addText(sub, {\r\n x: leftPad,\r\n y: bandY + bandH + 0.35,\r\n w: textW,\r\n h: 0.45,\r\n fontSize: theme.fontSize.small,\r\n fontFace: theme.fonts.body,\r\n color: theme.colors.secondary,\r\n align: titleAlign,\r\n });\r\n }\r\n return;\r\n }\r\n\r\n // Golden-ratio section rule (single decorative line spanning wider than the text area)\r\n if (extraBoolean(spec, 'sectionRule', false)) {\r\n const secRuleY = extraNumber(spec, 'sectionRuleY', 4.64);\r\n const secRuleW = extraNumber(spec, 'sectionRuleWidth', 5);\r\n const secRuleH = extraNumber(spec, 'sectionRuleHeight', 0.04);\r\n const secRuleX = extraNumber(\r\n spec,\r\n 'sectionRuleX',\r\n titleAlign === 'right' ? 13.33 - right - secRuleW : leftPad,\r\n );\r\n addHRuler(slide, {\r\n x: secRuleX,\r\n y: secRuleY,\r\n w: secRuleW,\r\n h: secRuleH,\r\n color: ruleColor(\r\n theme,\r\n extraString(spec, 'sectionRuleColor', 'primary') as 'primary' | 'secondary' | 'divider',\r\n ),\r\n });\r\n }\r\n\r\n if (node.subtitle) {\r\n const subY = extraNumber(spec, 'subtitleY', 0.85);\r\n const subH = extraNumber(spec, 'subtitleH', 0.45);\r\n slide.addText(node.subtitle, {\r\n x: leftPad,\r\n y: subY,\r\n w: textW,\r\n h: subH,\r\n fontSize: theme.fontSize.body,\r\n fontFace: theme.fonts.body,\r\n color: theme.colors.secondary,\r\n align: titleAlign,\r\n valign: 'middle',\r\n });\r\n }\r\n\r\n if (node.title) {\r\n const tY = extraNumber(spec, 'titleY', 2.5);\r\n const tH = extraNumber(spec, 'titleH', 2.0);\r\n slide.addText(node.title, {\r\n x: leftPad,\r\n y: tY,\r\n w: textW,\r\n h: tH,\r\n fontSize: theme.fontSize.heading + 4,\r\n fontFace: theme.fonts.heading,\r\n color: theme.colors.text,\r\n bold: true,\r\n align: titleAlign,\r\n valign: 'middle',\r\n });\r\n }\r\n}\r\n\r\n/**\r\n * minimal 章节页:左侧超大章节序号 + 竖分隔线 + 章节标题 的横排布局。\r\n * 序号由 ctx.sectionNumber 自动递增(01、02…),见 pptx-renderer.ts。\r\n */\r\nfunction renderMinimalSection(\r\n slide: PptxGenJS.Slide,\r\n node: SlideNode,\r\n theme: Theme,\r\n ctx?: RenderContext,\r\n): void {\r\n const spec = layoutSpec(theme, 'section');\r\n const num = formatSectionNumber(ctx?.sectionNumber ?? 1);\r\n\r\n // 章节序号(超大号,左对齐)\r\n const nX = extraNumber(spec, 'minimalNumberX', 1.11);\r\n const nY = extraNumber(spec, 'minimalNumberY', 2.43);\r\n const nW = extraNumber(spec, 'minimalNumberW', 2.5);\r\n const nH = extraNumber(spec, 'minimalNumberH', 1.53);\r\n slide.addText(num, {\r\n x: nX,\r\n y: nY,\r\n w: nW,\r\n h: nH,\r\n fontSize: theme.fontSize.title,\r\n fontFace: theme.fonts.heading,\r\n color: theme.colors.primary,\r\n bold: true,\r\n align: 'left',\r\n valign: 'middle',\r\n });\r\n\r\n // 竖分隔线\r\n const rX = extraNumber(spec, 'minimalRuleX', 3.89);\r\n const rY1 = extraNumber(spec, 'minimalRuleY1', 2.71);\r\n const rH = extraNumber(spec, 'minimalRuleH', 1.11);\r\n const rW = extraNumber(spec, 'minimalRuleW', 0.03);\r\n slide.addShape('rect' as PptxGenJS.ShapeType, {\r\n x: rX,\r\n y: rY1,\r\n w: rW,\r\n h: rH,\r\n fill: { color: theme.colors.divider ?? theme.colors.secondary },\r\n });\r\n\r\n // 章节标题(左对齐,与竖线对齐)\r\n if (node.title) {\r\n const tX = extraNumber(spec, 'minimalTitleX', 4.31);\r\n const tY = extraNumber(spec, 'minimalTitleY', rY1);\r\n const tW = extraNumber(spec, 'minimalTitleW', 6.94);\r\n const tH = extraNumber(spec, 'minimalTitleH', 0.69);\r\n slide.addText(node.title, {\r\n x: tX,\r\n y: tY,\r\n w: tW,\r\n h: tH,\r\n fontSize: theme.fontSize.heading,\r\n fontFace: theme.fonts.heading,\r\n color: theme.colors.text,\r\n bold: true,\r\n align: 'left',\r\n valign: 'middle',\r\n });\r\n }\r\n}\r\n","/**\r\n * Image size reader\r\n *\r\n * Reads pixel dimensions straight from the file header — no dependencies, in the\r\n * same spirit as the PNG-only reader this replaces. The formats covered mirror\r\n * what `IMAGE_MIME` can embed: PNG, JPEG, GIF, WebP, BMP and SVG.\r\n *\r\n * Getting this wrong is not cosmetic: the renderer derives a missing dimension\r\n * from the source aspect ratio, so a size that cannot be read makes the image\r\n * render stretched.\r\n */\r\n\r\nexport interface ImageSize {\r\n width: number;\r\n height: number;\r\n}\r\n\r\n/** Both dimensions must be usable; anything else is treated as \"unknown\". */\r\nfunction positive(width: number, height: number): ImageSize | null {\r\n if (!(width > 0 && height > 0)) return null;\r\n return { width, height };\r\n}\r\n\r\nfunction pngSize(data: Buffer): ImageSize | null {\r\n if (data.length < 24) return null;\r\n if (data.readUInt32BE(0) !== 0x89504e47) return null;\r\n // IHDR is always the first chunk: width/height are big-endian at 16/20\r\n return positive(data.readUInt32BE(16), data.readUInt32BE(20));\r\n}\r\n\r\n/** Start-of-frame markers carry the dimensions; DHT/JPG/DAC share the range. */\r\nfunction isFrameMarker(marker: number): boolean {\r\n return (\r\n marker >= 0xc0 &&\r\n marker <= 0xcf &&\r\n marker !== 0xc4 && // DHT\r\n marker !== 0xc8 && // JPG\r\n marker !== 0xcc // DAC\r\n );\r\n}\r\n\r\nfunction jpegSize(data: Buffer): ImageSize | null {\r\n if (data.length < 4 || data[0] !== 0xff || data[1] !== 0xd8) return null;\r\n\r\n let offset = 2;\r\n while (offset + 3 < data.length) {\r\n if (data[offset] !== 0xff) {\r\n // Not at a marker boundary — resync rather than give up on the file\r\n offset++;\r\n continue;\r\n }\r\n\r\n // Fill bytes (FF FF ...) are legal between segments\r\n let marker = data[offset + 1];\r\n while (marker === 0xff && offset + 2 < data.length) {\r\n offset++;\r\n marker = data[offset + 1];\r\n }\r\n offset += 2;\r\n\r\n // Standalone markers carry no payload\r\n if (marker === 0x01 || (marker >= 0xd0 && marker <= 0xd8)) continue;\r\n // A scan means no frame header was found before the pixel data\r\n if (marker === 0xda || marker === 0xd9) return null;\r\n\r\n if (offset + 2 > data.length) return null;\r\n const length = data.readUInt16BE(offset);\r\n if (length < 2) return null;\r\n\r\n if (isFrameMarker(marker)) {\r\n // length(2) + precision(1), then height, then width\r\n if (offset + 7 > data.length) return null;\r\n return positive(data.readUInt16BE(offset + 5), data.readUInt16BE(offset + 3));\r\n }\r\n\r\n offset += length;\r\n }\r\n return null;\r\n}\r\n\r\nfunction gifSize(data: Buffer): ImageSize | null {\r\n if (data.length < 10) return null;\r\n const signature = data.toString('latin1', 0, 6);\r\n if (signature !== 'GIF87a' && signature !== 'GIF89a') return null;\r\n // Logical screen descriptor: little-endian, right after the signature\r\n return positive(data.readUInt16LE(6), data.readUInt16LE(8));\r\n}\r\n\r\nfunction webpSize(data: Buffer): ImageSize | null {\r\n if (data.length < 30) return null;\r\n if (data.toString('latin1', 0, 4) !== 'RIFF') return null;\r\n if (data.toString('latin1', 8, 12) !== 'WEBP') return null;\r\n\r\n const chunk = data.toString('latin1', 12, 16);\r\n\r\n if (chunk === 'VP8X') {\r\n // Extended format: 24-bit little-endian canvas dimensions, stored minus one\r\n return positive(data.readUIntLE(24, 3) + 1, data.readUIntLE(27, 3) + 1);\r\n }\r\n\r\n if (chunk === 'VP8 ') {\r\n // Lossy: 14-bit dimensions after the keyframe start code\r\n if (data[23] !== 0x9d || data[24] !== 0x01 || data[25] !== 0x2a) return null;\r\n return positive(data.readUInt16LE(26) & 0x3fff, data.readUInt16LE(28) & 0x3fff);\r\n }\r\n\r\n if (chunk === 'VP8L') {\r\n // Lossless: 0x2f signature, then two 14-bit values packed into 32 bits\r\n if (data[20] !== 0x2f) return null;\r\n const bits = data.readUInt32LE(21);\r\n return positive((bits & 0x3fff) + 1, ((bits >>> 14) & 0x3fff) + 1);\r\n }\r\n\r\n return null;\r\n}\r\n\r\nfunction bmpSize(data: Buffer): ImageSize | null {\r\n if (data.length < 26) return null;\r\n if (data[0] !== 0x42 || data[1] !== 0x4d) return null; // 'BM'\r\n\r\n const headerSize = data.readUInt32LE(14);\r\n if (headerSize === 12) {\r\n // BITMAPCOREHEADER: 16-bit dimensions\r\n return positive(data.readUInt16LE(18), data.readUInt16LE(20));\r\n }\r\n if (headerSize >= 40) {\r\n // BITMAPINFOHEADER and later: signed 32-bit. A negative height only means\r\n // the rows are stored top-down, so the magnitude is the height.\r\n return positive(Math.abs(data.readInt32LE(18)), Math.abs(data.readInt32LE(22)));\r\n }\r\n return null;\r\n}\r\n\r\n/** Absolute length units an SVG attribute can carry, expressed in px. */\r\nconst SVG_UNITS: Record<string, number> = {\r\n px: 1,\r\n pt: 96 / 72,\r\n pc: 16,\r\n mm: 96 / 25.4,\r\n cm: 96 / 2.54,\r\n in: 96,\r\n q: 96 / 101.6,\r\n};\r\n\r\n/** Parse an SVG length into px. Percentages have no absolute meaning here. */\r\nfunction parseSvgLength(value: string | undefined): number | undefined {\r\n if (!value) return undefined;\r\n const match = value.match(/^([\\d.]+)\\s*([a-z%]*)$/i);\r\n if (!match) return undefined;\r\n const n = parseFloat(match[1]);\r\n if (!(n > 0)) return undefined;\r\n const unit = match[2].toLowerCase();\r\n if (unit === '%') return undefined;\r\n const scale = SVG_UNITS[unit || 'px'];\r\n return scale === undefined ? undefined : n * scale;\r\n}\r\n\r\n/** The SVG root tag, or null when the buffer is not SVG markup. */\r\nfunction findSvgRoot(data: Buffer): RegExpMatchArray | null {\r\n // SVG is text and the root tag is at the front; a prefix is enough\r\n const head = data.toString('utf8', 0, Math.min(data.length, 4096));\r\n return head.match(/<svg\\b[^>]*>/i);\r\n}\r\n\r\n/**\r\n * True when the buffer is SVG markup.\r\n *\r\n * Sniffed from the bytes rather than a file extension: remote URLs and `data:`\r\n * URIs carry SVG under all sorts of names, and the extension a caller happened\r\n * to derive says nothing about what is actually inside.\r\n */\r\nexport function isSvgImage(data: Buffer): boolean {\r\n return findSvgRoot(data) !== null;\r\n}\r\n\r\nfunction svgSize(data: Buffer): ImageSize | null {\r\n const root = findSvgRoot(data);\r\n if (!root) return null;\r\n\r\n const attribute = (name: string): string | undefined => {\r\n const match = root[0].match(new RegExp(`\\\\b${name}\\\\s*=\\\\s*[\"']([^\"']*)[\"']`, 'i'));\r\n return match?.[1]?.trim();\r\n };\r\n\r\n // viewBox is unitless and therefore the most reliable aspect ratio source\r\n const viewBox = attribute('viewBox');\r\n if (viewBox) {\r\n const parts = viewBox.split(/[\\s,]+/).map(Number);\r\n if (parts.length === 4 && parts[2] > 0 && parts[3] > 0) {\r\n return { width: parts[2], height: parts[3] };\r\n }\r\n }\r\n\r\n const width = parseSvgLength(attribute('width'));\r\n const height = parseSvgLength(attribute('height'));\r\n if (width === undefined || height === undefined) return null;\r\n return positive(width, height);\r\n}\r\n\r\n/**\r\n * Read pixel dimensions from an image buffer.\r\n * Returns null when the format is unsupported or the header is unusable.\r\n */\r\nexport function getImageSize(data: Buffer): ImageSize | null {\r\n if (data.length < 10) return null;\r\n return (\r\n pngSize(data) ??\r\n jpegSize(data) ??\r\n gifSize(data) ??\r\n webpSize(data) ??\r\n bmpSize(data) ??\r\n svgSize(data)\r\n );\r\n}\r\n","/**\n * Image placement helpers\n */\n\nexport interface Size {\n width: number;\n height: number;\n}\n\nexport interface FitOptions {\n /** Normalized size, e.g. '6in' or '60%' (percent is relative to the box width) */\n width?: string;\n /** Normalized size, e.g. '4in' or '70%' (percent is relative to the box height) */\n height?: string;\n align?: 'left' | 'center' | 'right';\n}\n\nexport interface PlacedImage {\n /** Horizontal offset inside the box, per `align` */\n x: number;\n width: number;\n height: number;\n}\n\n/**\n * Scale an image to fit inside a max-width/max-height box while preserving\n * its aspect ratio. Returns the largest size that fits the box.\n */\nexport function fitInBox(img: Size, maxWidth: number, maxHeight: number): Size {\n if (!(img.width > 0 && img.height > 0) || !(maxWidth > 0 && maxHeight > 0)) {\n return { width: maxWidth, height: maxHeight };\n }\n const ar = img.height / img.width;\n let width = maxWidth;\n let height = width * ar;\n if (height > maxHeight) {\n height = maxHeight;\n width = height / ar;\n }\n return { width, height };\n}\n\n/** Convert a normalized size ('6in' / '60%') to inches; `of` is the reference for percentages. */\nexport function resolveImageSize(value: string | undefined, of: number): number | undefined {\n if (!value) return undefined;\n if (value.endsWith('%')) {\n const pct = parseFloat(value);\n if (Number.isNaN(pct) || pct <= 0) return undefined;\n return (of * pct) / 100;\n }\n const n = parseFloat(value);\n if (Number.isNaN(n) || n <= 0) return undefined;\n return n;\n}\n\n/**\n * Resolve the requested width/height (either may be undefined, meaning\n * \"derive from the other side / the image ratio\"). Returns concrete numbers.\n */\nfunction resolveSizes(img: Size, box: Size, widthStr?: string, heightStr?: string): Size {\n const width = resolveImageSize(widthStr, box.width);\n const height = resolveImageSize(heightStr, box.height);\n const ar = img.height > 0 && img.width > 0 ? img.height / img.width : 0.5;\n\n if (width === undefined && height === undefined) {\n return fitInBox(\n { width: img.width > 0 ? img.width : 6, height: img.height > 0 ? img.height : 3 },\n box.width,\n box.height,\n );\n }\n if (height === undefined) {\n // width is defined here: the both-undefined branch above was skipped\n return { width: width!, height: width! * ar };\n }\n if (width === undefined) {\n return { width: height! / ar, height: height! };\n }\n return { width, height };\n}\n\n/**\n * Place an image inside a box honoring `![alt](src){w=...,h=...,align=...}`:\n * - only one size given → aspect ratio preserved, the other side derived\n * - both sizes given → explicit (aspect not preserved)\n * - the result is always shrunk back into the box\n * `img` is the source pixel size (or the renderer's fallback when unknown).\n */\nexport function fitImageWithOptions(img: Size, box: Size, options: FitOptions = {}): PlacedImage {\n let { width, height } = resolveSizes(img, box, options.width, options.height);\n\n // Never overflow the box (explicit sizes are clamped by proportional shrink)\n if (width > box.width || height > box.height) {\n const fitted = fitInBox({ width, height }, box.width, box.height);\n width = fitted.width;\n height = fitted.height;\n }\n\n const align = options.align ?? 'center';\n const x = align === 'left' ? 0 : align === 'right' ? box.width - width : (box.width - width) / 2;\n return { x, width, height };\n}\n","/**\n * Table → ECharts option converter\n * Powers the @(chart=bar|line|pie) directive: a plain Markdown table\n * becomes a rendered chart without writing JSON by hand.\n */\n\nimport type { TableElement } from '../models/slide.js';\n\n/**\n * Convert a Markdown table into an ECharts option JSON string.\n *\n * bar/line: first column = category, every other column = one series.\n * pie: first column = slice name, second column = value.\n */\nexport function tableToChartOption(\n table: TableElement,\n type: string,\n): string {\n const { headers, rows } = table;\n\n if (headers.length < 2 || rows.length === 0) {\n throw new Error('chart: table needs at least 2 columns and 1 data row');\n }\n\n if (type === 'pie') {\n const series = {\n name: headers[1],\n type: 'pie',\n radius: '55%',\n data: rows.map((r) => ({ name: r[0], value: Number(r[1]) || 0 })),\n };\n return JSON.stringify({\n toolbox: { show: false },\n series: [series],\n });\n }\n\n // bar / line / others → category axis + one series per data column\n const categories = rows.map((r) => r[0]);\n const series = headers.slice(1).map((name, i) => ({\n name,\n type,\n data: rows.map((r) => Number(r[i + 1]) || 0),\n }));\n\n return JSON.stringify({\n xAxis: { type: 'category', data: categories, axisLabel: { hideOverlap: true } },\n yAxis: { type: 'value' },\n series,\n });\n}\n","/**\r\n * Content slide layout — the most common, handles mixed content.\r\n *\r\n * Supports grid layout via break elements:\r\n * - BreakElement('row') (from `===`): stack content vertically\r\n * - BreakElement('col') (from `<->`): lay content out side-by-side\r\n * Columns and rows split the content area evenly.\r\n */\r\n\r\nimport PptxGenJS from 'pptxgenjs';\r\nimport type { SlideNode, SlideElement } from '../../models/slide.js';\r\nimport type { Theme } from '../../models/theme.js';\r\nimport type { RenderContext } from './index.js';\r\nimport { getImageSize } from '../../utils/image-size.js';\r\nimport { fitInBox, fitImageWithOptions } from '../../utils/image-fit.js';\r\nimport { tableToChartOption } from '../../utils/table-chart.js';\r\nimport { log } from '../../utils/progress.js';\r\nimport { readFileSync } from 'node:fs';\r\nimport {\r\n addHRuler,\r\n extraBoolean,\r\n extraNumber,\r\n layoutSpec,\r\n resolveSideMargins,\r\n ruleColor,\r\n specNumber,\r\n titleRuleHeight,\r\n titleRuleRole,\r\n} from './layout-spec.js';\r\n\r\n// Slide dimensions (16:9 LAYOUT_WIDE)\r\nconst SLIDE_W = 13.33;\r\nconst SLIDE_H = 7.5;\r\n/** Fallbacks matching production hard-coded values (layout-scheme legacy) */\r\nconst DEFAULT_MARGIN = 0.6;\r\nconst DEFAULT_TITLE_H = 0.9;\r\nconst DEFAULT_BOTTOM_MARGIN = 0.45;\r\nconst DEFAULT_GRID_GAP = 0.25;\r\n\r\ninterface ContentMetrics {\r\n marginLeft: number;\r\n marginRight: number;\r\n titleH: number;\r\n titleY: number;\r\n contentW: number;\r\n bottom: number;\r\n gridGap: number;\r\n contentPadding: number;\r\n titleRule: boolean;\r\n titleRuleH: number;\r\n titleRuleWidth: number;\r\n titleRuleColor: 'primary' | 'secondary' | 'divider';\r\n}\r\n\r\nfunction contentMetrics(theme: Theme): ContentMetrics {\r\n const spec = layoutSpec(theme, 'content');\r\n const { left, right } = resolveSideMargins(spec, DEFAULT_MARGIN);\r\n const titleH = specNumber(spec.titleHeight, DEFAULT_TITLE_H);\r\n const contentPadding = specNumber(spec.contentPadding, 0);\r\n const contentW = Math.max(2, SLIDE_W - left - right);\r\n return {\r\n marginLeft: left,\r\n marginRight: right,\r\n titleH,\r\n titleY: extraNumber(spec, 'titleY', 0.3),\r\n contentW,\r\n bottom: DEFAULT_BOTTOM_MARGIN,\r\n gridGap: DEFAULT_GRID_GAP,\r\n contentPadding,\r\n titleRule: extraBoolean(spec, 'titleRule', true),\r\n titleRuleH: titleRuleHeight(spec, 0.04),\r\n titleRuleWidth: extraNumber(spec, 'titleRuleWidth', contentW),\r\n titleRuleColor: titleRuleRole(spec),\r\n };\r\n}\r\n\r\n/** Extension → MIME map used when embedding images as base64 data */\r\nconst IMAGE_MIME: Record<string, string> = {\r\n png: 'image/png',\r\n jpg: 'image/jpeg',\r\n jpeg: 'image/jpeg',\r\n gif: 'image/gif',\r\n webp: 'image/webp',\r\n bmp: 'image/bmp',\r\n svg: 'image/svg+xml',\r\n};\r\n\r\n/** Vertical space available below the title bar */\r\nfunction contentAreaInsets(\r\n node: SlideNode,\r\n metrics: ContentMetrics,\r\n): { top: number; bottom: number } {\r\n return {\r\n top: node.title ? metrics.titleY + metrics.titleH + 0.2 : metrics.titleY,\r\n bottom: metrics.bottom,\r\n };\r\n}\r\n\r\n/**\r\n * Split the element stream into rows (by row breaks), then each row\r\n * into columns (by col breaks). A slide with no breaks is one row of one column.\r\n */\r\nfunction splitGrid(elements: SlideElement[]): SlideElement[][][] {\r\n const rows: SlideElement[][] = [];\r\n let currentRow: SlideElement[] = [];\r\n\r\n for (const el of elements) {\r\n if (el.type === 'break' && el.direction === 'row') {\r\n rows.push(currentRow);\r\n currentRow = [];\r\n continue;\r\n }\r\n // col breaks and content stay in the row; col splitting happens next\r\n currentRow.push(el);\r\n }\r\n rows.push(currentRow);\r\n\r\n return rows.map((row) => {\r\n const columns: SlideElement[][] = [];\r\n let currentCol: SlideElement[] = [];\r\n for (const el of row) {\r\n if (el.type === 'break' && el.direction === 'col') {\r\n columns.push(currentCol);\r\n currentCol = [];\r\n continue;\r\n }\r\n currentCol.push(el);\r\n }\r\n columns.push(currentCol);\r\n return columns;\r\n });\r\n}\r\n\r\nexport async function renderContentSlide(\r\n slide: PptxGenJS.Slide,\r\n node: SlideNode,\r\n theme: Theme,\r\n ctx: RenderContext,\r\n): Promise<void> {\r\n const spec = layoutSpec(theme, 'content');\r\n\r\n // minimal 正文:标题在上、标题下短横线,内容收进带边框容器\r\n if (extraBoolean(spec, 'minimalBox', false)) {\r\n await renderMinimalContent(slide, node, theme, ctx);\r\n return;\r\n }\r\n\r\n const metrics = contentMetrics(theme);\r\n const { marginLeft, titleH, titleY, contentW, gridGap, contentPadding, titleRuleWidth } = metrics;\r\n const { top } = contentAreaInsets(node, metrics);\r\n const pad = contentPadding > 0 ? contentPadding : 0;\r\n const drawX = marginLeft + pad;\r\n const drawW = contentW - pad * 2;\r\n\r\n // Title bar + rule\r\n if (node.title) {\r\n if (metrics.titleRule && metrics.titleRuleH > 0) {\r\n addHRuler(slide, {\r\n x: marginLeft,\r\n y: titleY + titleH - metrics.titleRuleH - 0.01,\r\n w: titleRuleWidth,\r\n h: metrics.titleRuleH,\r\n color: ruleColor(theme, metrics.titleRuleColor),\r\n });\r\n }\r\n\r\n slide.addText(node.title, {\r\n x: marginLeft,\r\n y: titleY,\r\n w: contentW,\r\n h: titleH,\r\n fontSize: theme.fontSize.heading,\r\n fontFace: theme.fonts.heading,\r\n color: theme.colors.primary,\r\n bold: true,\r\n valign: 'bottom',\r\n });\r\n }\r\n\r\n const grid = splitGrid(prepareElements(node));\r\n const rows = grid.length;\r\n const availH = SLIDE_H - top - metrics.bottom - gridGap * (rows - 1);\r\n\r\n // Rows are sized by estimated content weight (like flexbox), not evenly —\r\n // a row with one short line shouldn't eat half the slide. Shrunk to fit.\r\n const ests = grid.map((columns) =>\r\n Math.max(\r\n 0.8,\r\n ...columns.map((c) => estimateColumnHeight(c, (drawW - gridGap * (columns.length - 1)) / columns.length, theme)),\r\n ),\r\n );\r\n const totalEst = ests.reduce((a, b) => a + b, 0);\r\n const scale = totalEst > availH ? availH / totalEst : 1;\r\n\r\n let y = top;\r\n for (let r = 0; r < rows; r++) {\r\n const columns = grid[r];\r\n const cols = columns.length;\r\n const colW = (drawW - gridGap * (cols - 1)) / cols;\r\n const rowH = ests[r] * scale;\r\n\r\n for (let c = 0; c < cols; c++) {\r\n await renderColumn(\r\n slide,\r\n columns[c],\r\n { x: drawX + c * (colW + gridGap), y, w: colW, h: rowH },\r\n node,\r\n theme,\r\n ctx,\r\n );\r\n }\r\n y += rowH + gridGap;\r\n }\r\n}\r\n\r\n/**\r\n * Rewrites the slide's elements for rendering:\r\n * - @(chart=...) converts the first table into an echarts diagram so that\r\n * layout estimation treats it as an image (big row) instead of a table.\r\n */\r\nfunction prepareElements(node: SlideNode): SlideElement[] {\r\n const chart = node.directives?.chart;\r\n if (!chart) return node.elements;\r\n\r\n const elements = [...node.elements];\r\n const idx = elements.findIndex((e) => e.type === 'table');\r\n if (idx === -1) return elements;\r\n\r\n const table = elements[idx] as Extract<SlideElement, { type: 'table' }>;\r\n try {\r\n elements[idx] = {\r\n type: 'diagram',\r\n diagramType: 'echarts',\r\n content: tableToChartOption(table, chart),\r\n };\r\n } catch {\r\n // Invalid chart table — fall through to rendering as a table\r\n }\r\n return elements;\r\n}\r\n\r\n/** Text-box insets on a code block (margin: [8, 12, 8, 12], in points). */\r\nconst CODE_INSET_IN = 16 / 72;\r\n\r\n/**\r\n * PowerPoint lays a line out at roughly 1.2-1.25x its font size; rounding up\r\n * keeps the box slightly taller than the text rather than clipping it.\r\n */\r\nconst CODE_LINE_FACTOR = 1.3;\r\n\r\n/**\r\n * Height a code block needs, in inches.\r\n *\r\n * The insets matter: they are 16pt of the total, which a bare lines x per-line\r\n * estimate misses — that is what left the last line of a block sticking out\r\n * below the dark fill.\r\n */\r\nfunction codeBlockHeight(lines: number, fontSizePt: number): number {\r\n return Math.max(1.0, (lines * fontSizePt * CODE_LINE_FACTOR) / 72 + CODE_INSET_IN);\r\n}\r\n\r\n/** Display width of a string in Latin-equivalent units (CJK takes two). */\r\nfunction displayWidth(text: string): number {\r\n let units = 0;\r\n for (const char of text) {\r\n units += (char.codePointAt(0) ?? 0) > 0x2e80 ? 2 : 1;\r\n }\r\n return units;\r\n}\r\n\r\n/**\r\n * Characters that fit on one line of `fontSizePt` text in a column `widthIn`\r\n * inches wide. Average advance is about half an em for Latin, so a 12in column\r\n * of 18pt text holds roughly 97 units — the previous estimate assumed 60 per\r\n * inch, ~7x too many, which made every paragraph look like a single line and\r\n * let the next element overlap it.\r\n */\r\nfunction charsPerLine(widthIn: number, fontSizePt: number): number {\r\n return Math.max(8, Math.floor((widthIn * 72) / (fontSizePt * 0.5)));\r\n}\r\n\r\n/** Estimate wrapped text lines for a string in a column of width w (inches). */\r\nfunction estimateTextLines(content: string, w: number, fontSizePt: number): number {\r\n return Math.max(1, Math.ceil(displayWidth(content) / charsPerLine(w, fontSizePt)));\r\n}\r\n\r\n/** Cheap height estimate for a column of elements (inches). */\r\nfunction estimateColumnHeight(elements: SlideElement[], w: number, theme: Theme): number {\r\n let h = 0;\r\n for (const el of elements) {\r\n switch (el.type) {\r\n case 'text':\r\n h += Math.max(0.5, estimateTextLines(el.content, w, theme.fontSize.body) * 0.35);\r\n break;\r\n case 'heading':\r\n h += 0.7;\r\n break;\r\n case 'list':\r\n h += el.items.length * 0.5;\r\n break;\r\n case 'code':\r\n h += codeBlockHeight(el.content.split('\\n').length, theme.fontSize.code);\r\n break;\r\n case 'diagram':\r\n case 'image':\r\n // Most diagrams are wide (aspect ~1.5-3:1); assume ~2:1 and let the\r\n // actual render down-scale. Enough height to look deliberate.\r\n // Explicit image sizes are honored so a small icon doesn't eat the row.\r\n if (el.type === 'image' && el.height && !el.height.endsWith('%')) {\r\n h += parseFloat(el.height) + 0.2;\r\n } else if (el.type === 'image' && el.width && !el.width.endsWith('%')) {\r\n h += parseFloat(el.width) * 0.5 + 0.2;\r\n } else {\r\n h += Math.min(4.5, Math.max(1.2, w * 0.5));\r\n }\r\n break;\r\n case 'table':\r\n h += (el.rows.length + 1) * 0.4;\r\n break;\r\n case 'callout':\r\n // Same adaptive sizing as the renderer: label row + one line per wrap\r\n h += Math.min(4.5, 0.72 + estimateTextLines(el.content, w, theme.fontSize.body) * 0.3);\r\n break;\r\n case 'blockquote':\r\n h += 1.0;\r\n break;\r\n case 'break':\r\n break;\r\n default:\r\n h += 0.5;\r\n }\r\n }\r\n return h;\r\n}\r\n\r\ninterface Box {\r\n x: number;\r\n y: number;\r\n w: number;\r\n h: number;\r\n}\r\n\r\n/** Render a stream of elements inside a fixed box; content exceeding the box is clipped (kept simple). */\r\nasync function renderColumn(\r\n slide: PptxGenJS.Slide,\r\n elements: SlideElement[],\r\n box: Box,\r\n node: SlideNode,\r\n theme: Theme,\r\n ctx: RenderContext,\r\n): Promise<void> {\r\n // Vertically center content that is shorter than its grid cell — a\r\n // two-line column next to a diagram shouldn't hug the row's top edge.\r\n const est = estimateColumnHeight(elements, box.w, theme);\r\n const yPos = box.h > est ? box.y + (box.h - est) / 2 : box.y;\r\n let cursor = yPos;\r\n for (const element of elements) {\r\n const consumed = await renderElement(slide, element, cursor, box, node, theme, ctx);\r\n cursor += consumed;\r\n }\r\n}\r\n\r\nasync function renderElement(\r\n slide: PptxGenJS.Slide,\r\n element: SlideElement,\r\n yPos: number,\r\n box: Box,\r\n node: SlideNode,\r\n theme: Theme,\r\n ctx: RenderContext,\r\n): Promise<number> {\r\n const { x, w } = box;\r\n const maxH = Math.max(0.5, box.y + box.h - yPos);\r\n\r\n switch (element.type) {\r\n case 'text': {\r\n if (!element.content.trim()) return 0;\r\n // Size the box and advance the cursor by the same estimate, so whatever\r\n // follows cannot land on top of a line that wrapped further than assumed.\r\n const lines = estimateTextLines(element.content, w, theme.fontSize.body);\r\n const height = Math.max(0.5, lines * 0.35);\r\n slide.addText(element.content, {\r\n x,\r\n y: yPos,\r\n w,\r\n h: height,\r\n fontSize: theme.fontSize.body,\r\n fontFace: theme.fonts.body,\r\n color: theme.colors.text,\r\n bold: element.bold,\r\n italic: element.italic,\r\n valign: 'top',\r\n wrap: true,\r\n });\r\n return height;\r\n }\r\n\r\n case 'heading': {\r\n slide.addText(element.content, {\r\n x,\r\n y: yPos,\r\n w,\r\n h: 0.6,\r\n fontSize: theme.fontSize.heading - (element.level - 2) * 4,\r\n fontFace: theme.fonts.heading,\r\n color: theme.colors.primary,\r\n bold: true,\r\n });\r\n return 0.7;\r\n }\r\n\r\n case 'list': {\r\n const items = element.items.map((item, i) => {\r\n const checked = element.checked?.[i];\r\n const isTask = checked !== undefined;\r\n let text = item;\r\n const options: Record<string, unknown> = {\r\n // Task items have no bullet, so they need an explicit break line;\r\n // bulleted items break lines on their own.\r\n breakLine: isTask ? true : undefined,\r\n bullet: element.ordered\r\n ? { type: 'number' as const, startAt: i + 1 }\r\n : isTask\r\n ? false\r\n : true,\r\n color: theme.colors.text,\r\n fontSize: theme.fontSize.body,\r\n fontFace: theme.fonts.body,\r\n paraSpaceBefore: 4,\r\n paraSpaceAfter: 4,\r\n };\r\n if (isTask) {\r\n // Task list: prefix glyph, done items get muted color\r\n text = `${checked ? '☑' : '☐'} ${item}`;\r\n if (checked) options.color = theme.colors.secondary;\r\n }\r\n return { text, options };\r\n });\r\n\r\n const height = Math.max(0.8, Math.min(maxH, items.length * 0.5));\r\n slide.addText(items as PptxGenJS.TextProps[], {\r\n x,\r\n y: yPos,\r\n w,\r\n h: height,\r\n valign: 'top',\r\n });\r\n return height + 0.15;\r\n }\r\n\r\n case 'code': {\r\n const runs = await ctx.highlightCode(\r\n element.content,\r\n element.language ?? 'text',\r\n element.highlightLines,\r\n );\r\n const lines = element.content.split('\\n').length;\r\n const height = Math.min(maxH, codeBlockHeight(lines, theme.fontSize.code));\r\n\r\n slide.addText(runs, {\r\n x,\r\n y: yPos,\r\n w,\r\n h: height,\r\n fill: { color: theme.colors.codeBackground },\r\n fontFace: theme.fonts.code,\r\n fontSize: theme.fontSize.code,\r\n color: theme.colors.codeText,\r\n valign: 'top',\r\n margin: [8, 12, 8, 12],\r\n });\r\n return height + 0.2;\r\n }\r\n\r\n case 'diagram': {\r\n try {\r\n const pngBuffer = await ctx.renderDiagram(element.diagramType, element.content);\r\n // Diagrams can be very wide (graphviz chains) or very tall (mermaid\r\n // flows) — scale into the box, aspect preserved.\r\n const imgSize = getImageSize(pngBuffer) ?? { width: 8, height: 3.5 };\r\n const boxH = Math.max(1.2, maxH);\r\n const fitted = fitInBox(imgSize, w, boxH);\r\n const base64 = pngBuffer.toString('base64');\r\n\r\n slide.addImage({\r\n data: `image/png;base64,${base64}`,\r\n // A diagram has no alt text of its own, so the slide title describes\r\n // it best; without one, name the notation at least. Passing nothing\r\n // would leave pptxgenjs' internal placeholder filename as the alt text.\r\n altText: node.title || `${element.diagramType} diagram`,\r\n x: x + (w - fitted.width) / 2,\r\n y: yPos,\r\n w: fitted.width,\r\n h: fitted.height,\r\n });\r\n return fitted.height + 0.2;\r\n } catch (err) {\r\n const reason = err instanceof Error ? err.message : 'unknown';\r\n const message = `[Diagram render error: ${reason}]`;\r\n // Mirrors the image path below: the deck still generates with a\r\n // placeholder on the slide, but headless runs need to hear about it.\r\n log.warn(`[${node.title ?? 'slide'}] ${message}`);\r\n slide.addText(message, {\r\n x,\r\n y: yPos,\r\n w,\r\n h: 0.5,\r\n fontSize: theme.fontSize.small,\r\n color: 'FF0000',\r\n italic: true,\r\n });\r\n return 0.6;\r\n }\r\n }\r\n\r\n case 'image': {\r\n try {\r\n const resolved = await ctx.resolveImage(element.src);\r\n if (!resolved.ok) {\r\n log.warn(`[${node.title ?? 'slide'}] ${resolved.error}`);\r\n return 0;\r\n }\r\n const fileData = readFileSync(resolved.path);\r\n const imgSize = getImageSize(fileData) ?? { width: 6, height: 3.0 };\r\n const boxH = Math.max(1.2, maxH);\r\n const placed = fitImageWithOptions(\r\n imgSize,\r\n { width: w, height: boxH },\r\n { width: element.width, height: element.height, align: element.align },\r\n );\r\n // Base64 data (not a path): avoids pptxgenjs' Node-vs-browser media\r\n // encoding, which crashes under ESM hosts (no `require` → XHR path).\r\n const ext = resolved.path.split('.').pop()?.toLowerCase() ?? 'png';\r\n const mime = IMAGE_MIME[ext] ?? 'image/png';\r\n const data = `${mime};base64,${fileData.toString('base64')}`;\r\n\r\n // The deck stores WebP faithfully, but a common reader cannot decode it:\r\n // PowerPoint for the web and Office 2019 and earlier show a broken image.\r\n // Converting would mean taking on a WebP decoder, so say so instead.\r\n if (ext === 'webp') {\r\n log.warn(\r\n `[${node.title ?? 'slide'}] WebP does not render in PowerPoint for the web ` +\r\n `or Office 2019 and earlier — some recipients may see a broken image (${element.src})`,\r\n );\r\n }\r\n\r\n slide.addImage({\r\n data,\r\n path: 'preencoded.png',\r\n // The author's alt text when they wrote one; otherwise the source they\r\n // referenced, which at least beats pptxgenjs' internal placeholder name.\r\n // Falsy, not nullish: `![](...)` parses to an empty alt string.\r\n altText: element.alt || element.src,\r\n x: x + placed.x,\r\n y: yPos,\r\n w: placed.width,\r\n h: placed.height,\r\n });\r\n return placed.height + 0.2;\r\n } catch (err) {\r\n log.warn(\r\n `Failed to embed image ${element.src}: ${err instanceof Error ? err.message : String(err)}`,\r\n );\r\n }\r\n return 0;\r\n }\r\n\r\n case 'table': {\r\n const headerRow = element.headers.map((h) => ({\r\n text: h,\r\n options: {\r\n bold: true,\r\n color: 'FFFFFF',\r\n fill: { color: theme.colors.primary },\r\n fontSize: theme.fontSize.body - 2,\r\n fontFace: theme.fonts.body,\r\n align: 'center' as const,\r\n border: { type: 'solid' as const, pt: 0.5, color: theme.colors.primary },\r\n },\r\n }));\r\n\r\n const bodyRows = element.rows.map((row) =>\r\n row.map((cell) => ({\r\n text: cell,\r\n options: {\r\n fontSize: theme.fontSize.body - 2,\r\n fontFace: theme.fonts.body,\r\n color: theme.colors.text,\r\n border: { type: 'solid' as const, pt: 0.5, color: 'D1D5DB' },\r\n },\r\n })),\r\n );\r\n\r\n const allRows = [headerRow, ...bodyRows];\r\n const tableH = Math.min(maxH, allRows.length * 0.4);\r\n\r\n slide.addTable(allRows as PptxGenJS.TableRow[], {\r\n x,\r\n y: yPos,\r\n w,\r\n h: tableH,\r\n colW: Array(element.headers.length).fill(w / element.headers.length),\r\n margin: [4, 6, 4, 6],\r\n border: { type: 'solid', pt: 0.5, color: 'D1D5DB' },\r\n autoPage: false,\r\n });\r\n return tableH + 0.2;\r\n }\r\n\r\n case 'blockquote': {\r\n // Left accent border + italic text\r\n slide.addShape('rect' as PptxGenJS.ShapeType, {\r\n x,\r\n y: yPos,\r\n w: 0.06,\r\n h: Math.min(0.8, maxH),\r\n fill: { color: theme.colors.accent },\r\n });\r\n\r\n slide.addText(element.content, {\r\n x: x + 0.2,\r\n y: yPos,\r\n w: w - 0.2,\r\n h: Math.min(0.8, maxH),\r\n fontSize: theme.fontSize.body,\r\n fontFace: theme.fonts.body,\r\n color: theme.colors.secondary,\r\n italic: true,\r\n valign: 'middle',\r\n });\r\n return 1.0;\r\n }\r\n\r\n case 'callout': {\r\n const palette: Record<string, string> = {\r\n note: theme.colors.primary,\r\n info: theme.colors.primary,\r\n tip: theme.colors.accent,\r\n success: theme.colors.accent,\r\n warning: 'EAB308',\r\n caution: 'EAB308',\r\n danger: 'DC2626',\r\n };\r\n const color = palette[element.variant] ?? theme.colors.primary;\r\n const label = element.title ?? element.variant.toUpperCase();\r\n\r\n // Card height adapts to content: label row + one line per wrapped line\r\n const textLines = estimateTextLines(element.content, w, theme.fontSize.body);\r\n const cardH = Math.min(maxH, 0.72 + textLines * 0.3);\r\n const textH = cardH - 0.44;\r\n\r\n // Soft background + left accent bar\r\n slide.addShape('roundRect' as PptxGenJS.ShapeType, {\r\n x,\r\n y: yPos,\r\n w,\r\n h: cardH,\r\n fill: { color, transparency: 88 },\r\n line: { color, width: 0.75, transparency: 70 },\r\n rectRadius: 0.08,\r\n });\r\n slide.addShape('rect' as PptxGenJS.ShapeType, {\r\n x,\r\n y: yPos + 0.12,\r\n w: 0.07,\r\n h: cardH - 0.24,\r\n fill: { color },\r\n });\r\n\r\n slide.addText(label, {\r\n x: x + 0.2,\r\n y: yPos + 0.08,\r\n w: w - 0.4,\r\n h: 0.3,\r\n fontSize: theme.fontSize.small,\r\n fontFace: theme.fonts.heading,\r\n color,\r\n bold: true,\r\n });\r\n slide.addText(element.content, {\r\n x: x + 0.2,\r\n y: yPos + 0.4,\r\n w: w - 0.4,\r\n h: textH,\r\n fontSize: theme.fontSize.body - 1,\r\n fontFace: theme.fonts.body,\r\n color: theme.colors.text,\r\n valign: 'top',\r\n wrap: true,\r\n });\r\n return cardH + 0.1;\r\n }\r\n\r\n default:\r\n return 0;\r\n }\r\n}\r\n\r\n/**\r\n * minimal 正文页:页标题 + 标题下短横线(非贯穿)+ 带边框内容容器。\r\n * 内容在容器内部按 grid 布局排布,与方案「内容区起始 y=1.33、底部收于 6.61」一致。\r\n */\r\nasync function renderMinimalContent(\r\n slide: PptxGenJS.Slide,\r\n node: SlideNode,\r\n theme: Theme,\r\n ctx: RenderContext,\r\n): Promise<void> {\r\n const spec = layoutSpec(theme, 'content');\r\n const margin = specNumber(spec.margin, 0.83);\r\n const boxX = extraNumber(spec, 'minimalBoxX', margin);\r\n const boxY = extraNumber(spec, 'minimalBoxY', 1.33);\r\n const boxW = extraNumber(spec, 'minimalBoxW', SLIDE_W - margin * 2);\r\n const boxH = extraNumber(spec, 'minimalBoxH', 5.28);\r\n const lineColor = theme.colors.divider ?? theme.colors.secondary;\r\n\r\n if (node.title) {\r\n slide.addText(node.title, {\r\n x: boxX,\r\n y: extraNumber(spec, 'minimalTitleY', 0.5),\r\n w: boxW,\r\n h: 0.44,\r\n fontSize: theme.fontSize.heading,\r\n fontFace: theme.fonts.heading,\r\n color: theme.colors.primary,\r\n bold: true,\r\n align: 'left',\r\n valign: 'middle',\r\n });\r\n // 标题下装饰短横线(左缘与页标题左缘对齐,长度约 0.56,不贯穿整行)\r\n addHRuler(slide, {\r\n x: boxX,\r\n y: extraNumber(spec, 'minimalTitleRuleY', 1.03),\r\n w: extraNumber(spec, 'minimalTitleRuleW', 0.56),\r\n h: extraNumber(spec, 'minimalTitleRuleH', 0.03),\r\n color: lineColor,\r\n });\r\n }\r\n\r\n // 内容容器(占位边界,实际填充列表/表格/图表等)\r\n slide.addShape('rect' as PptxGenJS.ShapeType, {\r\n x: boxX,\r\n y: boxY,\r\n w: boxW,\r\n h: boxH,\r\n fill: { transparency: 100 },\r\n line: { color: lineColor, width: 0.01 },\r\n });\r\n\r\n // 容器内排布内容\r\n const gap = 0.25;\r\n const pad = 0.3;\r\n const inner = { x: boxX + pad, y: boxY + pad, w: boxW - pad * 2, h: boxH - pad * 2 };\r\n const innerBox = {\r\n x: inner.x,\r\n y: inner.y,\r\n w: inner.w,\r\n h: inner.h,\r\n };\r\n const grid = splitGrid(prepareElements(node));\r\n const rows = grid.length;\r\n const availH = innerBox.h - gap * (rows - 1);\r\n const ests = grid.map((columns) =>\r\n Math.max(\r\n 0.8,\r\n ...columns.map((c) => estimateColumnHeight(c, (innerBox.w - gap * (columns.length - 1)) / columns.length, theme)),\r\n ),\r\n );\r\n const totalEst = ests.reduce((a, b) => a + b, 0);\r\n const scale = totalEst > availH ? availH / totalEst : 1;\r\n\r\n let y = innerBox.y;\r\n for (let r = 0; r < rows; r++) {\r\n const columns = grid[r];\r\n const cols = columns.length;\r\n const colW = (innerBox.w - gap * (cols - 1)) / cols;\r\n const rowH = ests[r] * scale;\r\n for (let c = 0; c < cols; c++) {\r\n await renderColumn(\r\n slide,\r\n columns[c],\r\n { x: innerBox.x + c * (colW + gap), y, w: colW, h: rowH },\r\n node,\r\n theme,\r\n ctx,\r\n );\r\n }\r\n y += rowH + gap;\r\n }\r\n}\r\n","/**\r\n * Code-focused slide layout\r\n * Supports asymmetric margins + optional title rule via layout spec extras.\r\n */\r\n\r\nimport PptxGenJS from 'pptxgenjs';\r\nimport type { SlideNode } from '../../models/slide.js';\r\nimport type { Theme } from '../../models/theme.js';\r\nimport type { RenderContext } from './index.js';\r\nimport {\r\n addHRuler,\r\n extraBoolean,\r\n extraNumber,\r\n layoutSpec,\r\n resolveSideMargins,\r\n ruleColor,\r\n specAlign,\r\n specNumber,\r\n titleRuleHeight,\r\n titleRuleRole,\r\n} from './layout-spec.js';\r\n\r\nexport async function renderCodeSlide(\r\n slide: PptxGenJS.Slide,\r\n node: SlideNode,\r\n theme: Theme,\r\n ctx: RenderContext,\r\n): Promise<void> {\r\n const spec = layoutSpec(theme, 'code');\r\n\r\n // minimal 代码页:标题 + 短横线 + 圆角代码卡片\r\n if (extraBoolean(spec, 'minimalCard', false)) {\r\n await renderMinimalCode(slide, node, theme, ctx);\r\n return;\r\n }\r\n\r\n const { left, right } = resolveSideMargins(spec, 0.5);\r\n const titleH = specNumber(spec.titleHeight, 0.7);\r\n const titleAlign = specAlign(spec.titleAlign, 'left');\r\n const contentW = Math.max(3, 13.33 - left - right);\r\n const titleGap = 0.2;\r\n\r\n let yPos = extraNumber(spec, 'titleY', 0.3);\r\n\r\n if (node.title) {\r\n slide.addText(node.title, {\r\n x: left,\r\n y: yPos,\r\n w: contentW,\r\n h: titleH,\r\n fontSize: theme.fontSize.heading,\r\n fontFace: theme.fonts.heading,\r\n color: theme.colors.primary,\r\n bold: true,\r\n align: titleAlign === 'center' ? 'center' : 'left',\r\n });\r\n\r\n if (extraBoolean(spec, 'titleRule', false)) {\r\n const rh = titleRuleHeight(spec, 0.03);\r\n const ruleW = extraNumber(spec, 'titleRuleWidth', contentW);\r\n addHRuler(slide, {\r\n x: left,\r\n y: yPos + titleH + 0.02,\r\n w: ruleW,\r\n h: rh,\r\n color: ruleColor(theme, titleRuleRole(spec)),\r\n });\r\n }\r\n yPos += titleH + titleGap;\r\n }\r\n\r\n for (const element of node.elements) {\r\n if (element.type === 'code') {\r\n const runs = await ctx.highlightCode(\r\n element.content,\r\n element.language ?? 'text',\r\n element.highlightLines,\r\n );\r\n\r\n slide.addText(runs, {\r\n x: left,\r\n y: yPos,\r\n w: contentW,\r\n h: 7.5 - yPos - 0.45,\r\n fill: { color: theme.colors.codeBackground },\r\n color: theme.colors.codeText,\r\n fontFace: theme.fonts.code,\r\n fontSize: theme.fontSize.code,\r\n valign: 'top',\r\n paraSpaceAfter: 2,\r\n margin: [10, 15, 10, 15],\r\n });\r\n yPos += 5.0;\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * minimal 代码页:页标题 + 短横线 + 独立圆角代码卡片。\r\n * 代码文本铺满卡片内部,底色为 codeBackground,边框为 divider/secondary 细线。\r\n */\r\nasync function renderMinimalCode(\r\n slide: PptxGenJS.Slide,\r\n node: SlideNode,\r\n theme: Theme,\r\n ctx: RenderContext,\r\n): Promise<void> {\r\n const spec = layoutSpec(theme, 'code');\r\n const margin = specNumber(spec.margin, 0.83);\r\n const boxX = extraNumber(spec, 'minimalCardX', margin);\r\n const boxY = extraNumber(spec, 'minimalCardY', 1.33);\r\n const boxW = extraNumber(spec, 'minimalCardW', 13.33 - margin * 2);\r\n const boxH = extraNumber(spec, 'minimalCardH', 5.28);\r\n const lineColor = theme.colors.divider ?? theme.colors.secondary;\r\n const radius = extraNumber(spec, 'minimalCardRadius', 0.08);\r\n\r\n if (node.title) {\r\n slide.addText(node.title, {\r\n x: boxX,\r\n y: extraNumber(spec, 'minimalTitleY', 0.5),\r\n w: boxW,\r\n h: 0.44,\r\n fontSize: theme.fontSize.heading,\r\n fontFace: theme.fonts.heading,\r\n color: theme.colors.primary,\r\n bold: true,\r\n align: 'left',\r\n valign: 'middle',\r\n });\r\n addHRuler(slide, {\r\n x: boxX,\r\n y: extraNumber(spec, 'minimalTitleRuleY', 1.03),\r\n w: extraNumber(spec, 'minimalTitleRuleW', 0.56),\r\n h: extraNumber(spec, 'minimalTitleRuleH', 0.03),\r\n color: lineColor,\r\n });\r\n }\r\n\r\n // 圆角代码卡片(独立卡片,底色 codeBackground)\r\n slide.addShape('roundRect' as PptxGenJS.ShapeType, {\r\n x: boxX,\r\n y: boxY,\r\n w: boxW,\r\n h: boxH,\r\n rectRadius: radius,\r\n fill: { color: theme.colors.codeBackground },\r\n line: { color: lineColor, width: 0.01 },\r\n });\r\n\r\n const pad = 0.3;\r\n for (const element of node.elements) {\r\n if (element.type !== 'code') continue;\r\n const runs = await ctx.highlightCode(\r\n element.content,\r\n element.language ?? 'text',\r\n element.highlightLines,\r\n );\r\n slide.addText(runs, {\r\n x: boxX + pad,\r\n y: boxY + pad,\r\n w: boxW - pad * 2,\r\n h: boxH - pad * 2,\r\n fill: { color: theme.colors.codeBackground },\r\n color: theme.colors.codeText,\r\n fontFace: theme.fonts.code,\r\n fontSize: theme.fontSize.code,\r\n valign: 'top',\r\n paraSpaceAfter: 2,\r\n margin: [8, 12, 8, 12],\r\n });\r\n break;\r\n }\r\n}\r\n","/**\r\n * Quote slide layout\r\n *\r\n * Creative extras:\r\n * - extra.quoteBar: thick left pull-quote rule instead of a giant “ mark\r\n * - extra.quoteMark=false hides the decorative mark\r\n * - extra.attributionAlign: left | right (default right for legacy)\r\n */\r\n\r\nimport PptxGenJS from 'pptxgenjs';\r\nimport type { SlideNode } from '../../models/slide.js';\r\nimport type { Theme } from '../../models/theme.js';\r\nimport {\r\n addHRuler,\r\n extraBoolean,\r\n extraNumber,\r\n extraString,\r\n layoutSpec,\r\n resolveSideMargins,\r\n ruleColor,\r\n specAlign,\r\n} from './layout-spec.js';\r\n\r\nexport function renderQuoteSlide(\r\n slide: PptxGenJS.Slide,\r\n node: SlideNode,\r\n theme: Theme,\r\n): void {\r\n const spec = layoutSpec(theme, 'quote');\r\n\r\n // minimal 引用页:左侧竖引用标记 + 引用文案沿竖线左对齐,无大引号\r\n if (extraBoolean(spec, 'minimalQuote', false)) {\r\n renderMinimalQuote(slide, node, theme);\r\n return;\r\n }\r\n\r\n const showMark = extraBoolean(spec, 'quoteMark', true);\r\n const markSize = extraNumber(spec, 'quoteMarkSize', 72);\r\n const align = specAlign(spec.titleAlign, 'center');\r\n const { left, right } = resolveSideMargins(spec, 1.5);\r\n const quoteBar = extraBoolean(spec, 'quoteBar', false);\r\n const barW = extraNumber(spec, 'quoteBarWidth', 0.09);\r\n const attrAlign = extraString(spec, 'attributionAlign', 'right') as 'left' | 'right' | 'center';\r\n\r\n if (showMark && !quoteBar) {\r\n slide.addText('“', {\r\n x: left,\r\n y: 1.0,\r\n w: 2.0,\r\n h: 1.5,\r\n fontSize: markSize,\r\n fontFace: 'Georgia',\r\n color: theme.colors.accent,\r\n bold: true,\r\n });\r\n }\r\n\r\n const quoteElement = node.elements.find((e) => e.type === 'blockquote');\r\n if (!quoteElement || quoteElement.type !== 'blockquote') return;\r\n\r\n let quoteText = quoteElement.content;\r\n let attribution = '';\r\n const attrMatch = quoteText.match(/\\n?\\s*[—–-]\\s*(.+)$/);\r\n if (attrMatch) {\r\n attribution = attrMatch[1].trim();\r\n quoteText = quoteText.slice(0, attrMatch.index).trim();\r\n }\r\n\r\n const textX = quoteBar ? left + barW + 0.35 : Math.max(left, showMark && !quoteBar ? 1.8 : left);\r\n const textW = Math.max(4, 13.33 - textX - right);\r\n const textY = extraNumber(spec, 'textY', quoteBar ? 2.2 : 2.5);\r\n const textH = extraNumber(spec, 'textH', quoteBar ? 2.8 : 2.5);\r\n\r\n if (quoteBar) {\r\n addHRuler(slide, {\r\n // vertical bar via tall thin rect\r\n x: left,\r\n y: textY,\r\n w: barW,\r\n h: textH,\r\n color: theme.colors.accent,\r\n });\r\n }\r\n\r\n // Centered decorative rule above quote (golden-style)\r\n const quoteRule = extraBoolean(spec, 'quoteRule', false);\r\n if (quoteRule) {\r\n const qRuleY = extraNumber(spec, 'quoteRuleY', 2.19);\r\n const qRuleW = extraNumber(spec, 'quoteRuleWidth', 1.33);\r\n const qRuleH = extraNumber(spec, 'quoteRuleHeight', 0.04);\r\n const qRuleColor = ruleColor(\r\n theme,\r\n extraString(spec, 'quoteRuleColor', 'primary') as 'primary' | 'secondary' | 'divider',\r\n );\r\n const qRuleX = (13.33 - qRuleW) / 2; // centered on page\r\n addHRuler(slide, {\r\n x: qRuleX,\r\n y: qRuleY,\r\n w: qRuleW,\r\n h: qRuleH,\r\n color: qRuleColor,\r\n });\r\n }\r\n\r\n slide.addText(quoteText, {\r\n x: textX,\r\n y: textY,\r\n w: textW,\r\n h: textH,\r\n fontSize: theme.fontSize.heading,\r\n fontFace: theme.fonts.body,\r\n color: theme.colors.text,\r\n italic: true,\r\n align,\r\n valign: 'middle',\r\n });\r\n\r\n if (attribution) {\r\n slide.addText(`— ${attribution}`, {\r\n x: textX,\r\n y: textY + textH + 0.25,\r\n w: textW,\r\n h: 0.55,\r\n fontSize: theme.fontSize.body,\r\n fontFace: theme.fonts.body,\r\n color: theme.colors.secondary,\r\n align: attrAlign === 'left' ? 'left' : attrAlign === 'center' ? 'center' : 'right',\r\n });\r\n }\r\n}\r\n\r\n/**\r\n * minimal 引用页:左侧竖引用标记 + 引用文案沿竖线左对齐;无大引号、留白充足。\r\n * 与「内容页标题+容器」结构区分,自带页脚。\r\n */\r\nfunction renderMinimalQuote(\r\n slide: PptxGenJS.Slide,\r\n node: SlideNode,\r\n theme: Theme,\r\n): void {\r\n const spec = layoutSpec(theme, 'quote');\r\n const lineX = extraNumber(spec, 'minimalRuleX', 1.67);\r\n const lineY = extraNumber(spec, 'minimalRuleY', 2.78);\r\n const lineH = extraNumber(spec, 'minimalRuleH', 1.39);\r\n const lineW = extraNumber(spec, 'minimalRuleW', 0.04);\r\n const color = theme.colors.divider ?? theme.colors.secondary;\r\n\r\n const textX = extraNumber(spec, 'minimalTextX', 2.08);\r\n const textY = lineY;\r\n const textW = extraNumber(spec, 'minimalTextW', 9.58);\r\n const textH = extraNumber(spec, 'minimalTextH', 1.39);\r\n\r\n const quoteElement = node.elements.find((e) => e.type === 'blockquote');\r\n if (!quoteElement || quoteElement.type !== 'blockquote') return;\r\n\r\n let quoteText = quoteElement.content;\r\n let attribution = '';\r\n const attrMatch = quoteText.match(/\\n?\\s*[—–-]\\s*(.+)$/);\r\n if (attrMatch) {\r\n attribution = attrMatch[1].trim();\r\n quoteText = quoteText.slice(0, attrMatch.index).trim();\r\n }\r\n\r\n // 左侧竖装饰引用标记\r\n slide.addShape('rect' as PptxGenJS.ShapeType, {\r\n x: lineX,\r\n y: lineY,\r\n w: lineW,\r\n h: lineH,\r\n fill: { color },\r\n });\r\n\r\n slide.addText(quoteText, {\r\n x: textX,\r\n y: textY,\r\n w: textW,\r\n h: textH,\r\n fontSize: theme.fontSize.heading,\r\n fontFace: theme.fonts.body,\r\n color: theme.colors.text,\r\n italic: true,\r\n align: 'left',\r\n valign: 'middle',\r\n wrap: true,\r\n });\r\n\r\n if (attribution) {\r\n slide.addText(`— ${attribution}`, {\r\n x: textX,\r\n y: textY + textH + 0.3,\r\n w: textW,\r\n h: 0.4,\r\n fontSize: theme.fontSize.body,\r\n fontFace: theme.fonts.body,\r\n color: theme.colors.secondary,\r\n align: 'left',\r\n });\r\n }\r\n}\r\n","/**\r\n * Closing slide layout — fixed “Thank you” page (@(layout=closing)).\r\n * Extras: thankText, titleRule (rules above/below the word).\r\n */\r\n\r\nimport PptxGenJS from 'pptxgenjs';\r\nimport type { SlideNode } from '../../models/slide.js';\r\nimport type { Theme } from '../../models/theme.js';\r\nimport {\r\n addHRuler,\r\n extraBoolean,\r\n extraNumber,\r\n extraString,\r\n layoutSpec,\r\n resolveSideMargins,\r\n ruleColor,\r\n specAlign,\r\n titleRuleRole,\r\n} from './layout-spec.js';\r\n\r\nexport function renderClosingSlide(\r\n slide: PptxGenJS.Slide,\r\n node: SlideNode,\r\n theme: Theme,\r\n): void {\r\n const spec = layoutSpec(theme, 'closing');\r\n\r\n // minimal 结尾页:上方短横线 + 居中致谢语 + 下方居中联系方式,无页脚\r\n if (extraBoolean(spec, 'minimalClosing', false)) {\r\n renderMinimalClosing(slide, node, theme);\r\n return;\r\n }\r\n\r\n const align = specAlign(spec.titleAlign, 'center');\r\n const { left, right } = resolveSideMargins(spec, 0.8);\r\n const contentW = Math.max(3, 13.33 - left - right);\r\n const thankText = extraString(spec, 'thankText', 'Thank you');\r\n const primary = node.title?.trim() || thankText;\r\n const textY = extraNumber(spec, 'textY', 2.7);\r\n const showRules = extraBoolean(spec, 'titleRule', false);\r\n const color = ruleColor(theme, titleRuleRole(spec) === 'primary' ? 'primary' : titleRuleRole(spec));\r\n const ruleW = extraNumber(spec, 'ruleWidth', Math.min(contentW, 3.2));\r\n // closingRule: 'both' (default legacy, above+below) | 'above' | 'below'\r\n const closingRule = extraString(spec, 'closingRule', 'both') as 'both' | 'above' | 'below';\r\n const ruleH = extraNumber(spec, 'ruleHeight', 0.03);\r\n const ruleY = extraNumber(spec, 'ruleY', textY + 1.5);\r\n const ruleX =\r\n align === 'center'\r\n ? left + (contentW - ruleW) / 2\r\n : align === 'right'\r\n ? left + contentW - ruleW\r\n : left;\r\n\r\n const drawAbove = showRules && (closingRule === 'both' || closingRule === 'above');\r\n const drawBelow = showRules && (closingRule === 'both' || closingRule === 'below');\r\n\r\n if (drawAbove) {\r\n addHRuler(slide, { x: ruleX, y: textY - 0.35, w: ruleW, h: ruleH, color });\r\n }\r\n\r\n slide.addText(primary, {\r\n x: left,\r\n y: textY,\r\n w: contentW,\r\n h: 1.3,\r\n fontSize: theme.fontSize.title,\r\n fontFace: theme.fonts.heading,\r\n color: theme.colors.primary,\r\n bold: true,\r\n align,\r\n valign: 'middle',\r\n });\r\n\r\n if (drawBelow) {\r\n addHRuler(slide, { x: ruleX, y: ruleY, w: ruleW, h: ruleH, color });\r\n }\r\n\r\n const secondary = node.subtitle?.trim();\r\n if (secondary) {\r\n slide.addText(secondary, {\r\n x: left,\r\n y: textY + 1.7,\r\n w: contentW,\r\n h: 0.6,\r\n fontSize: theme.fontSize.body,\r\n fontFace: theme.fonts.body,\r\n color: theme.colors.secondary,\r\n align,\r\n valign: 'middle',\r\n });\r\n }\r\n}\r\n\r\n/**\r\n * minimal 结尾页:上方短装饰横线(居中)+ 致谢语(居中)+ 联系方式(居中),\r\n * 整页居中对称、不带页脚,与封面首尾呼应。\r\n */\r\nfunction renderMinimalClosing(\r\n slide: PptxGenJS.Slide,\r\n node: SlideNode,\r\n theme: Theme,\r\n): void {\r\n const spec = layoutSpec(theme, 'closing');\r\n const color = theme.colors.divider ?? theme.colors.secondary;\r\n const thankText = extraString(spec, 'thankText', 'Thank you');\r\n const primary = node.title?.trim() || thankText;\r\n\r\n // 上方短装饰横线(水平居中于页面)\r\n const ruleW = extraNumber(spec, 'minimalRuleW', 1.11);\r\n const ruleH = extraNumber(spec, 'minimalRuleH', 0.03);\r\n const ruleY = extraNumber(spec, 'minimalRuleY', 2.78);\r\n addHRuler(slide, {\r\n x: (13.33 - ruleW) / 2,\r\n y: ruleY,\r\n w: ruleW,\r\n h: ruleH,\r\n color,\r\n });\r\n\r\n // 致谢语(水平居中)\r\n slide.addText(primary, {\r\n x: extraNumber(spec, 'minimalThankX', 2.5),\r\n y: extraNumber(spec, 'minimalThankY', 3.06),\r\n w: extraNumber(spec, 'minimalThankW', 8.33),\r\n h: 0.83,\r\n fontSize: theme.fontSize.title,\r\n fontFace: theme.fonts.heading,\r\n color: theme.colors.primary,\r\n bold: true,\r\n align: 'center',\r\n valign: 'middle',\r\n });\r\n\r\n // 联系方式(居中,位于致谢语下方)\r\n const contact = node.subtitle?.trim() ?? '';\r\n if (contact) {\r\n slide.addText(contact, {\r\n x: extraNumber(spec, 'minimalContactX', 3.89),\r\n y: extraNumber(spec, 'minimalContactY', 4.31),\r\n w: extraNumber(spec, 'minimalContactW', 5.56),\r\n h: 0.33,\r\n fontSize: theme.fontSize.body,\r\n fontFace: theme.fonts.body,\r\n color: theme.colors.secondary,\r\n align: 'center',\r\n valign: 'middle',\r\n });\r\n }\r\n}\r\n","/**\r\n * Image-focused slide layouts — single / double / triple.\r\n * Trigger: @(layout=image-single|image-double|image-triple) or pure-image auto-detect.\r\n */\r\n\r\nimport { readFileSync } from 'node:fs';\r\nimport PptxGenJS from 'pptxgenjs';\r\nimport type { SlideNode, SlideElement } from '../../models/slide.js';\r\nimport type { Theme, ThemeLayoutSpec } from '../../models/theme.js';\r\nimport type { RenderContext } from './index.js';\r\nimport { getImageSize } from '../../utils/image-size.js';\r\nimport { fitInBox } from '../../utils/image-fit.js';\r\nimport { log } from '../../utils/progress.js';\r\nimport {\r\n addHRuler,\r\n extraBoolean,\r\n extraNumber,\r\n layoutSpec,\r\n resolveSideMargins,\r\n ruleColor,\r\n specAlign,\r\n specNumber,\r\n titleRuleHeight,\r\n titleRuleRole,\r\n} from './layout-spec.js';\r\n\r\nconst SLIDE_W = 13.33;\r\nconst SLIDE_H = 7.5;\r\n\r\nconst IMAGE_MIME: Record<string, string> = {\r\n png: 'image/png',\r\n jpg: 'image/jpeg',\r\n jpeg: 'image/jpeg',\r\n gif: 'image/gif',\r\n webp: 'image/webp',\r\n bmp: 'image/bmp',\r\n svg: 'image/svg+xml',\r\n};\r\n\r\nexport type ImageSlots = 1 | 2 | 3;\r\n\r\nfunction specFor(theme: Theme, slots: ImageSlots): ThemeLayoutSpec {\r\n if (slots === 1) return layoutSpec(theme, 'imageSingle');\r\n if (slots === 2) return layoutSpec(theme, 'imageDouble');\r\n return layoutSpec(theme, 'imageTriple');\r\n}\r\n\r\nfunction pickImages(node: SlideNode, slots: ImageSlots): {\r\n images: Extract<SlideElement, { type: 'image' }>[];\r\n captions: string[];\r\n} {\r\n const images = node.elements\r\n .filter((e): e is Extract<SlideElement, { type: 'image' }> => e.type === 'image')\r\n .slice(0, slots);\r\n const captions = node.elements\r\n .filter((e) => e.type === 'text')\r\n .map((e) => (e.type === 'text' ? e.content.trim() : ''))\r\n .filter((t) => t.length > 0 && t.length <= 40);\r\n return { images, captions };\r\n}\r\n\r\nasync function placeImage(\r\n slide: PptxGenJS.Slide,\r\n element: Extract<SlideElement, { type: 'image' }>,\r\n box: { x: number; y: number; w: number; h: number },\r\n node: SlideNode,\r\n ctx: RenderContext,\r\n): Promise<void> {\r\n try {\r\n const resolved = await ctx.resolveImage(element.src);\r\n if (!resolved.ok) {\r\n log.warn(`[${node.title ?? 'slide'}] ${resolved.error}`);\r\n return;\r\n }\r\n const fileData = readFileSync(resolved.path);\r\n const imgSize = getImageSize(fileData) ?? { width: 6, height: 3.0 };\r\n const fitted = fitInBox(imgSize, box.w, box.h);\r\n const ext = resolved.path.split('.').pop()?.toLowerCase() ?? 'png';\r\n const mime = IMAGE_MIME[ext] ?? 'image/png';\r\n const data = `${mime};base64,${fileData.toString('base64')}`;\r\n\r\n if (ext === 'webp') {\r\n log.warn(\r\n `[${node.title ?? 'slide'}] WebP does not render in PowerPoint for the web ` +\r\n `or Office 2019 and earlier — some recipients may see a broken image (${element.src})`,\r\n );\r\n }\r\n\r\n const x = box.x + (box.w - fitted.width) / 2;\r\n const y = box.y + (box.h - fitted.height) / 2;\r\n slide.addImage({\r\n data,\r\n altText: element.alt || element.src,\r\n x,\r\n y,\r\n w: fitted.width,\r\n h: fitted.height,\r\n });\r\n } catch (err) {\r\n const reason = err instanceof Error ? err.message : 'unknown';\r\n log.warn(`[${node.title ?? 'slide'}] image error: ${reason}`);\r\n slide.addText(`[Image error: ${reason}]`, {\r\n x: box.x,\r\n y: box.y,\r\n w: box.w,\r\n h: 0.4,\r\n fontSize: 12,\r\n color: 'FF0000',\r\n });\r\n }\r\n}\r\n\r\nexport async function renderImageSlide(\r\n slide: PptxGenJS.Slide,\r\n node: SlideNode,\r\n theme: Theme,\r\n ctx: RenderContext,\r\n slots: ImageSlots,\r\n): Promise<void> {\r\n const spec = specFor(theme, slots);\r\n\r\n // minimal 图文页:页标题 + 短横线 + 虚线图片占位框 + 页脚\r\n if (extraBoolean(spec, 'minimalImage', false)) {\r\n await renderMinimalImage(slide, node, theme, ctx, slots, spec);\r\n return;\r\n }\r\n\r\n const { left, right } = resolveSideMargins(spec, 0.6);\r\n const titleH = specNumber(spec.titleHeight, 0.9);\r\n const titleAlign = specAlign(spec.titleAlign, 'left');\r\n const contentW = Math.max(2, SLIDE_W - left - right);\r\n\r\n let top = extraNumber(spec, 'titleY', 0.3);\r\n if (node.title) {\r\n if (extraBoolean(spec, 'titleRule', true)) {\r\n const rh = titleRuleHeight(spec, 0.04);\r\n const ruleW = extraNumber(spec, 'titleRuleWidth', contentW);\r\n addHRuler(slide, {\r\n x: left,\r\n y: top + titleH - rh - 0.01,\r\n w: ruleW,\r\n h: rh,\r\n color: ruleColor(theme, titleRuleRole(spec)),\r\n });\r\n }\r\n slide.addText(node.title, {\r\n x: left,\r\n y: top,\r\n w: contentW,\r\n h: titleH,\r\n fontSize: theme.fontSize.heading,\r\n fontFace: theme.fonts.heading,\r\n color: theme.colors.primary,\r\n bold: true,\r\n align: titleAlign === 'center' ? 'center' : 'left',\r\n valign: 'bottom',\r\n });\r\n top = top + titleH + 0.2;\r\n }\r\n\r\n const bottom = 0.45;\r\n const zoneH = SLIDE_H - top - bottom;\r\n const { images, captions } = pickImages(node, slots);\r\n\r\n if (images.length === 0) {\r\n const fallback = captions[0] ?? node.title ?? 'No image';\r\n slide.addText(fallback, {\r\n x: left,\r\n y: top,\r\n w: contentW,\r\n h: zoneH,\r\n fontSize: theme.fontSize.body,\r\n fontFace: theme.fonts.body,\r\n color: theme.colors.secondary,\r\n align: 'center',\r\n valign: 'middle',\r\n });\r\n return;\r\n }\r\n\r\n const gap = 0.25;\r\n const captionH = 0.35;\r\n const cellW = (contentW - gap * (slots - 1)) / slots;\r\n const cellH = zoneH - captionH;\r\n\r\n for (let i = 0; i < images.length; i++) {\r\n const x = left + i * (cellW + gap);\r\n await placeImage(\r\n slide,\r\n images[i],\r\n { x, y: top, w: cellW, h: cellH },\r\n node,\r\n ctx,\r\n );\r\n const caption = images[i].alt?.trim() || captions[i];\r\n if (caption) {\r\n slide.addText(caption, {\r\n x,\r\n y: top + cellH + 0.05,\r\n w: cellW,\r\n h: captionH,\r\n fontSize: theme.fontSize.small,\r\n fontFace: theme.fonts.body,\r\n color: theme.colors.secondary,\r\n align: 'center',\r\n valign: 'top',\r\n });\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * minimal 图文页:页标题 + 短横线,下方为虚线图片占位框(等宽并排),\r\n * 有真实图片时嵌入框内,否则展示占位提示文字。底部统一页脚。\r\n */\r\nasync function renderMinimalImage(\r\n slide: PptxGenJS.Slide,\r\n node: SlideNode,\r\n theme: Theme,\r\n ctx: RenderContext,\r\n slots: ImageSlots,\r\n spec: ThemeLayoutSpec,\r\n): Promise<void> {\r\n const margin = specNumber(spec.margin, 0.83);\r\n const boxX = margin;\r\n const boxY = extraNumber(spec, 'minimalImageY', 1.33);\r\n const boxH = extraNumber(spec, 'minimalImageH', 5.28);\r\n const contentW = 13.33 - margin * 2;\r\n const lineColor = theme.colors.divider ?? theme.colors.secondary;\r\n\r\n if (node.title) {\r\n slide.addText(node.title, {\r\n x: boxX,\r\n y: extraNumber(spec, 'minimalTitleY', 0.5),\r\n w: contentW,\r\n h: 0.44,\r\n fontSize: theme.fontSize.heading,\r\n fontFace: theme.fonts.heading,\r\n color: theme.colors.primary,\r\n bold: true,\r\n align: 'left',\r\n valign: 'middle',\r\n });\r\n addHRuler(slide, {\r\n x: boxX,\r\n y: extraNumber(spec, 'minimalTitleRuleY', 1.03),\r\n w: extraNumber(spec, 'minimalTitleRuleW', 0.56),\r\n h: extraNumber(spec, 'minimalTitleRuleH', 0.03),\r\n color: lineColor,\r\n });\r\n }\r\n\r\n // 每个槽位的占位框宽度(等宽并排)\r\n const gaps: Record<ImageSlots, number> = { 1: 0, 2: 0.28, 3: 0.21 };\r\n const gap = gaps[slots];\r\n const cellW = (contentW - gap * (slots - 1)) / slots;\r\n\r\n const { images } = pickImages(node, slots);\r\n for (let i = 0; i < slots; i++) {\r\n const x = boxX + i * (cellW + gap);\r\n // 虚线图片占位框\r\n slide.addShape('rect' as PptxGenJS.ShapeType, {\r\n x,\r\n y: boxY,\r\n w: cellW,\r\n h: boxH,\r\n fill: { transparency: 100 },\r\n line: { color: lineColor, width: 0.01, dashType: 'dash' },\r\n });\r\n if (images[i]) {\r\n await placeImage(slide, images[i], { x, y: boxY, w: cellW, h: boxH }, node, ctx);\r\n } else {\r\n // 无图时的占位提示文字(框内水平垂直居中)\r\n slide.addText('Image', {\r\n x: x + (cellW - 2.22) / 2,\r\n y: boxY + (boxH - 0.56) / 2,\r\n w: 2.22,\r\n h: 0.56,\r\n fontSize: theme.fontSize.small,\r\n fontFace: theme.fonts.body,\r\n color: lineColor,\r\n align: 'center',\r\n valign: 'middle',\r\n });\r\n }\r\n }\r\n}\r\n","/**\r\n * Layout Registry\r\n * Routes SlideNode to the correct layout renderer\r\n */\r\n\r\nimport PptxGenJS from 'pptxgenjs';\r\nimport type { SlideNode } from '../../models/slide.js';\r\nimport type { Theme } from '../../models/theme.js';\r\nimport type { ImageResolution } from '../image-handler.js';\r\nimport { log } from '../../utils/progress.js';\r\nimport { renderTitleSlide } from './title.js';\r\nimport { renderSectionSlide } from './section.js';\r\nimport { renderContentSlide } from './content.js';\r\nimport { renderCodeSlide } from './code.js';\r\nimport { renderQuoteSlide } from './quote.js';\r\nimport { renderClosingSlide } from './closing.js';\r\nimport { renderImageSlide } from './image-pages.js';\r\nimport { extraNumber, extraString, layoutSpec, resolveSideMargins, specNumber } from './layout-spec.js';\r\n\r\n/** Context passed to layout renderers for async operations */\r\nexport interface RenderContext {\r\n highlightCode: (code: string, language: string, highlightLines?: number[]) => Promise<PptxGenJS.TextProps[]>;\r\n resolveImage: (src: string) => Promise<ImageResolution>;\r\n renderDiagram: (diagramType: string, code: string) => Promise<Buffer>;\r\n /** Page footer template with {page}/{total}/{section}/{title} placeholders */\r\n footerTemplate?: string;\r\n pageNumber?: number;\r\n totalSlides?: number;\r\n /** Title of the most recent section layout slide ({section} placeholder) */\r\n currentSection?: string;\r\n /**\r\n * Auto-incrementing section number, started at 1 and incremented once per\r\n * section layout slide. Formatted by section renderers (minimal → \"01\").\r\n */\r\n sectionNumber?: number;\r\n}\r\n\r\n/**\r\n * Render a slide using the appropriate layout\r\n */\r\nexport async function renderSlideLayout(\r\n slide: PptxGenJS.Slide,\r\n node: SlideNode,\r\n theme: Theme,\r\n ctx: RenderContext,\r\n): Promise<void> {\r\n // @(background=...) overrides the slide's background (image or theme color)\r\n if (node.directives?.background) {\r\n const resolved = await ctx.resolveImage(node.directives.background);\r\n if (resolved.ok && resolved.path) {\r\n slide.background = { path: resolved.path };\r\n } else if (node.directives.background.startsWith('#')) {\r\n slide.background = { color: node.directives.background.replace(/^#/, '') };\r\n } else if (!resolved.ok) {\r\n log.warn(`[${node.title ?? 'slide'}] ${resolved.error}`);\r\n }\r\n }\r\n\r\n switch (node.layout) {\r\n case 'title':\r\n renderTitleSlide(slide, node, theme);\r\n break;\r\n\r\n case 'section':\r\n renderSectionSlide(slide, node, theme, ctx);\r\n break;\r\n\r\n case 'code':\r\n await renderCodeSlide(slide, node, theme, ctx);\r\n break;\r\n\r\n case 'quote':\r\n renderQuoteSlide(slide, node, theme);\r\n break;\r\n\r\n case 'closing':\r\n renderClosingSlide(slide, node, theme);\r\n break;\r\n\r\n case 'image-single':\r\n await renderImageSlide(slide, node, theme, ctx, 1);\r\n break;\r\n\r\n case 'image-double':\r\n await renderImageSlide(slide, node, theme, ctx, 2);\r\n break;\r\n\r\n case 'image-triple':\r\n await renderImageSlide(slide, node, theme, ctx, 3);\r\n break;\r\n\r\n case 'content':\r\n default:\r\n await renderContentSlide(slide, node, theme, ctx);\r\n break;\r\n }\r\n\r\n // Add speaker notes if present\r\n if (node.notes) {\r\n slide.addNotes(node.notes);\r\n }\r\n\r\n // Footer / page number (skip cover, closing, blank, and section pages that opt out)\r\n const sectionSpec = layoutSpec(theme, 'section');\r\n const sectionNoFooter = extraString(sectionSpec, 'footer', 'on') === 'off';\r\n if (\r\n node.layout !== 'title' &&\r\n node.layout !== 'closing' &&\r\n node.layout !== 'blank' &&\r\n !(node.layout === 'section' && sectionNoFooter)\r\n ) {\r\n const footerText = renderFooter(node, theme, ctx);\r\n const footerSpec = layoutSpec(theme, 'footer');\r\n const sides = resolveSideMargins(\r\n footerSpec,\r\n specNumber(theme.layouts?.content?.margin, 0.6),\r\n );\r\n // Prefer content-side asymmetric margins when footer omits its own\r\n const marginLeft =\r\n footerSpec.extra?.marginLeft !== undefined\r\n ? sides.left\r\n : specNumber(\r\n theme.layouts?.content?.extra?.marginLeft as number | undefined,\r\n specNumber(theme.layouts?.content?.margin, sides.left),\r\n );\r\n const marginRight =\r\n footerSpec.extra?.marginRight !== undefined\r\n ? sides.right\r\n : specNumber(\r\n theme.layouts?.content?.extra?.marginRight as number | undefined,\r\n specNumber(theme.layouts?.content?.margin, sides.right),\r\n );\r\n const contentW = Math.max(2, 13.33 - marginLeft - marginRight);\r\n const showDivider =\r\n theme.styles?.footerDivider ?? footerSpec.footerDivider ?? false;\r\n const footerAlign = extraString(footerSpec, 'footerAlign', 'right') as\r\n | 'left'\r\n | 'center'\r\n | 'right';\r\n\r\n if (showDivider) {\r\n slide.addShape('rect' as PptxGenJS.ShapeType, {\r\n x: marginLeft,\r\n y: extraNumber(footerSpec, 'dividerY', 7.08),\r\n w: contentW,\r\n h: 0.015,\r\n fill: { color: theme.colors.divider ?? theme.colors.secondary },\r\n });\r\n }\r\n\r\n if (footerText) {\r\n slide.addText(footerText, {\r\n x: marginLeft,\r\n y: extraNumber(footerSpec, 'footerY', 7.16),\r\n w: contentW,\r\n h: 0.28,\r\n fontSize: theme.fontSize.small - 1,\r\n fontFace: theme.fonts.body,\r\n color: theme.colors.secondary,\r\n align: footerAlign,\r\n valign: 'middle',\r\n });\r\n }\r\n }\r\n}\r\n\r\n/** Compose the per-slide footer line from context (section tracking + config footer) */\r\nfunction renderFooter(node: SlideNode, theme: Theme, ctx: RenderContext): string {\r\n const template = ctx.footerTemplate;\r\n if (!template) return '';\r\n return template\r\n .replace('{page}', String(ctx.pageNumber))\r\n .replace('{total}', String(ctx.totalSlides))\r\n .replace('{section}', ctx.currentSection || '')\r\n .replace('{title}', node.title ?? '');\r\n}\r\n","/**\n * Code Highlighter\n * Uses Shiki for token-level syntax highlighting → pptxgenjs text runs\n */\n\nimport { createHighlighter, type Highlighter } from 'shiki';\nimport type { Theme } from '../models/theme.js';\nimport { hexToRgb } from '../utils/gradient.js';\n\ninterface PptxTextRun {\n text: string;\n options: {\n color?: string;\n fontFace?: string;\n fontSize?: number;\n bold?: boolean;\n italic?: boolean;\n highlight?: string;\n };\n}\n\nlet highlighterInstance: Highlighter | null = null;\n\nasync function getHighlighter(): Promise<Highlighter> {\n if (!highlighterInstance) {\n highlighterInstance = await createHighlighter({\n themes: ['github-dark', 'dracula'],\n langs: [\n 'javascript', 'typescript', 'python', 'java', 'c', 'cpp', 'csharp',\n 'go', 'rust', 'ruby', 'php', 'swift', 'kotlin', 'bash', 'shell',\n 'sql', 'html', 'css', 'json', 'yaml', 'markdown', 'xml', 'docker',\n ],\n });\n }\n return highlighterInstance;\n}\n\n/**\n * Strip '#' prefix from hex color\n */\nfunction cleanColor(color: string | undefined): string {\n if (!color) return 'E2E8F0';\n return color.replace(/^#/, '');\n}\n\n/** Mix a hex colour toward white. */\nfunction tint(hex: string, amount: number): string {\n const mix = (channel: number): string =>\n Math.round(channel + (255 - channel) * amount)\n .toString(16)\n .padStart(2, '0');\n const [r, g, b] = hexToRgb(hex);\n return `${mix(r)}${mix(g)}${mix(b)}`;\n}\n\n/**\n * Colour of the band drawn behind a highlighted line.\n *\n * The tokens on that band come from Shiki's dark theme, so they are light: the\n * band has to be dark for them to stay legible. A theme may name its own band,\n * but one picked for a light surface (or no value at all) produced pale-on-pale\n * text — the highlight was effectively unreadable in most themes. A missing\n * value is therefore derived from the code background rather than defaulted to\n * a light colour.\n */\nexport function highlightBackgroundFor(theme: Theme): string {\n const explicit = theme.colors.highlightBackground;\n if (explicit) return explicit;\n return tint(theme.colors.codeBackground, 0.25);\n}\n\n/**\n * Highlight code and return pptxgenjs text runs\n * @param highlightLines 1-based line numbers drawn with a highlight background\n */\nexport async function highlightCode(\n code: string,\n language: string,\n theme: Theme,\n highlightLines: number[] = [],\n): Promise<PptxTextRun[]> {\n const highlighter = await getHighlighter();\n const runs: PptxTextRun[] = [];\n const shikiThemeName = theme.shikiTheme ?? 'github-dark';\n const highlightColor = highlightBackgroundFor(theme);\n\n try {\n // Load language if not already loaded\n const loadedLangs = highlighter.getLoadedLanguages();\n if (!loadedLangs.includes(language as never)) {\n try {\n await highlighter.loadLanguage(language as never);\n } catch {\n // Language not supported — fall back to plain text\n return [\n {\n text: code,\n options: {\n color: theme.colors.codeText,\n fontFace: theme.fonts.code,\n fontSize: theme.fontSize.code,\n },\n },\n ];\n }\n }\n\n // Load theme if not loaded\n const loadedThemes = highlighter.getLoadedThemes();\n if (!loadedThemes.includes(shikiThemeName as never)) {\n try {\n await highlighter.loadTheme(shikiThemeName as never);\n } catch {\n // Theme not supported — use github-dark fallback\n }\n }\n\n const effectiveTheme = highlighter.getLoadedThemes().includes(shikiThemeName as never)\n ? shikiThemeName\n : 'github-dark';\n\n const result = highlighter.codeToTokens(code, {\n lang: language as never,\n theme: effectiveTheme,\n });\n\n for (let i = 0; i < result.tokens.length; i++) {\n const lineNumber = i + 1;\n const line = result.tokens[i];\n const isHighlighted = highlightLines.includes(lineNumber);\n for (const token of line) {\n const options: PptxTextRun['options'] = {\n color: cleanColor(token.color),\n fontFace: theme.fonts.code,\n fontSize: theme.fontSize.code,\n };\n if (isHighlighted) {\n options.highlight = highlightColor;\n }\n runs.push({ text: token.content, options });\n }\n // Add line break between lines (except last)\n if (i < result.tokens.length - 1) {\n runs.push({\n text: '\\n',\n options: {\n fontFace: theme.fonts.code,\n fontSize: theme.fontSize.code,\n },\n });\n }\n }\n } catch {\n // Fallback: plain text\n runs.push({\n text: code,\n options: {\n color: theme.colors.codeText,\n fontFace: theme.fonts.code,\n fontSize: theme.fontSize.code,\n },\n });\n }\n\n return runs;\n}\n","/**\n * PNG gradient generator\n * PptxGenJS slide backgrounds only support solid colors or images, so linear\n * gradient backgrounds are rendered here to a small PNG that gets stretched\n * over the whole slide (pptxgenjs emits <a:stretch><a:fillRect/></a:stretch>).\n *\n * Pure Node implementation (zlib + hand-rolled PNG chunks) — no dependencies.\n */\n\nimport { deflateSync } from 'node:zlib';\n\nexport type RgbTuple = readonly [number, number, number];\n\nconst CRC_TABLE = (() => {\n const table = new Uint32Array(256);\n for (let n = 0; n < 256; n++) {\n let c = n;\n for (let k = 0; k < 8; k++) {\n c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;\n }\n table[n] = c >>> 0;\n }\n return table;\n})();\n\nfunction crc32(bytes: Uint8Array): number {\n let crc = 0xffffffff;\n for (let i = 0; i < bytes.length; i++) {\n crc = CRC_TABLE[(crc ^ bytes[i]) & 0xff] ^ (crc >>> 8);\n }\n return (crc ^ 0xffffffff) >>> 0;\n}\n\nfunction pngChunk(type: string, data: Uint8Array): Buffer {\n const length = Buffer.alloc(4);\n length.writeUInt32BE(data.length);\n const payload = Buffer.concat([Buffer.from(type, 'latin1'), Buffer.from(data)]);\n const crc = Buffer.alloc(4);\n crc.writeUInt32BE(crc32(payload));\n return Buffer.concat([length, payload, crc]);\n}\n\n/** Encode a width×height truecolor (RGB, no alpha) PNG. */\nexport function encodePngRgb(\n width: number,\n height: number,\n pixelAt: (x: number, y: number) => RgbTuple,\n): Buffer {\n const ihdr = Buffer.alloc(13);\n ihdr.writeUInt32BE(width, 0);\n ihdr.writeUInt32BE(height, 4);\n ihdr[8] = 8; // bit depth\n ihdr[9] = 2; // color type: truecolor RGB\n // bytes 10-12 (compression/filter/interlace) stay 0\n\n // Scanlines: filter byte 0 (none) + width * RGB\n const raw = Buffer.alloc(height * (1 + width * 3));\n let offset = 0;\n for (let y = 0; y < height; y++) {\n raw[offset++] = 0;\n for (let x = 0; x < width; x++) {\n const [r, g, b] = pixelAt(x, y);\n raw[offset++] = r;\n raw[offset++] = g;\n raw[offset++] = b;\n }\n }\n const idat = deflateSync(raw, { level: 9 });\n\n return Buffer.concat([\n Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]),\n pngChunk('IHDR', ihdr),\n pngChunk('IDAT', new Uint8Array(idat)),\n pngChunk('IEND', new Uint8Array(0)),\n ]);\n}\n\n/** Parse '#RRGGBB' / 'RRGGBB' / '#RGB' / 'RGB' into an RGB tuple. */\nexport function hexToRgb(hex: string): RgbTuple {\n let s = hex.replace(/^#/, '');\n if (s.length === 3) s = s.split('').map((ch) => ch + ch).join('');\n if (!/^[0-9a-fA-F]{6}$/.test(s)) throw new Error(`Invalid hex color: ${hex}`);\n return [\n parseInt(s.slice(0, 2), 16),\n parseInt(s.slice(2, 4), 16),\n parseInt(s.slice(4, 6), 16),\n ];\n}\n\nexport interface GradientOptions {\n width?: number;\n height?: number;\n}\n\n/**\n * Create a linear-gradient PNG.\n * Angle follows the CSS convention (0° = to top, 90° = to right, 135° = to\n * bottom-right, 180° = to bottom). The default canvas matches the 16:9 slide,\n * so the visual angle survives stretching.\n */\nexport function createLinearGradientPng(\n from: string,\n to: string,\n angleDeg = 180,\n options: GradientOptions = {},\n): Buffer {\n const width = options.width ?? 192;\n const height = options.height ?? 108;\n const angle = (angleDeg * Math.PI) / 180;\n // CSS gradient-line direction in screen coords (y grows downward)\n const dx = Math.sin(angle);\n const dy = -Math.cos(angle);\n // Half the L1 extent of the unit square: keeps the gradient spans 0..1\n // across the full diagonal no matter which angle is given.\n const extent = (Math.abs(dx) + Math.abs(dy)) / 2;\n\n const c1 = hexToRgb(from);\n const c2 = hexToRgb(to);\n\n return encodePngRgb(width, height, (x, y) => {\n const px = x / (width - 1) - 0.5;\n const py = y / (height - 1) - 0.5;\n let t = 0.5 + (px * dx + py * dy) / (2 * extent);\n t = t < 0 ? 0 : t > 1 ? 1 : t;\n return [\n Math.round(c1[0] + (c2[0] - c1[0]) * t),\n Math.round(c1[1] + (c2[1] - c1[1]) * t),\n Math.round(c1[2] + (c2[2] - c1[2]) * t),\n ];\n });\n}\n","/**\r\n * Image Handler\r\n * Resolves and downloads images for embedding in PPTX\r\n */\r\n\r\nimport { existsSync, readFileSync, writeFileSync } from 'node:fs';\r\nimport { resolve } from 'node:path';\r\nimport { tmpdir } from 'node:os';\r\nimport { join } from 'node:path';\r\nimport { randomUUID } from 'node:crypto';\r\nimport { isSvgImage } from '../utils/image-size.js';\r\nimport { rasterizeSvg, SVG_EMBED_WIDTH } from '../diagrams/svg-to-png.js';\r\nimport { log } from '../utils/progress.js';\r\n\r\n/** Outcome of resolving an image source. Failure carries a human-readable reason. */\r\nexport type ImageResolution =\r\n | { ok: true; path: string }\r\n | { ok: false; error: string };\r\n\r\nconst REMOTE_FETCH_TIMEOUT_MS = 10_000;\r\n\r\n/**\r\n * Resolve an image source to a local file path ready for embedding.\r\n *\r\n * Never throws — failures are returned as { ok: false, error }.\r\n */\r\nexport async function resolveImage(\r\n src: string,\r\n basePath: string,\r\n): Promise<ImageResolution> {\r\n const located = await locateImage(src, basePath);\r\n if (!located.ok) return located;\r\n return rasterizeIfSvg(located);\r\n}\r\n\r\n/**\r\n * Replace an SVG with a PNG raster of it.\r\n *\r\n * Done here rather than at the point of use because everything funnels through\r\n * this path: a local file, a downloaded URL and a `data:` URI all arrive as a\r\n * local file, and both consumers (the image element and the `@(background=...)`\r\n * directive) only look at the returned path. The PPTX then carries a PNG, which\r\n * every reader can decode — storing the SVG instead needs the `svgBlip`\r\n * extension, whose PNG fallback is a broken-image placeholder.\r\n *\r\n * If resvg cannot parse the file the original SVG is returned unchanged, so a\r\n * malformed SVG degrades to the previous behaviour rather than losing the image.\r\n */\r\nasync function rasterizeIfSvg(resolved: ImageResolution): Promise<ImageResolution> {\r\n if (!resolved.ok) return resolved;\r\n\r\n try {\r\n const data = readFileSync(resolved.path);\r\n if (!isSvgImage(data)) return resolved;\r\n\r\n const png = await rasterizeSvg(data.toString('utf8'), SVG_EMBED_WIDTH);\r\n // `.png` extension matters: the MIME type is derived from it downstream.\r\n const tmpPath = join(tmpdir(), `mfly-${randomUUID().slice(0, 8)}.png`);\r\n writeFileSync(tmpPath, png);\r\n return { ok: true, path: tmpPath };\r\n } catch (err) {\r\n log.warn(\r\n `Could not rasterize ${resolved.path}: ${err instanceof Error ? err.message : String(err)} — embedding the SVG as-is`,\r\n );\r\n return resolved;\r\n }\r\n}\r\n\r\n/**\r\n * Find the image on disk, downloading or unpacking it when needed.\r\n * Never throws — failures are returned as { ok: false, error }.\r\n */\r\nasync function locateImage(src: string, basePath: string): Promise<ImageResolution> {\r\n try {\r\n // data: URI\r\n if (src.startsWith('data:')) {\r\n // Subtypes can carry a suffix — `image/svg+xml` is the common one, and\r\n // `\\w+` alone rejected it outright. Only the base type becomes the file\r\n // extension, so `svg+xml` lands as `.svg` and keeps a usable MIME.\r\n const match = src.match(/^data:image\\/([\\w.+-]+);base64,(.+)/);\r\n if (match) {\r\n const ext = match[1].split('+')[0];\r\n const base64 = match[2];\r\n const tmpPath = join(tmpdir(), `mfly-${randomUUID().slice(0, 8)}.${ext}`);\r\n writeFileSync(tmpPath, Buffer.from(base64, 'base64'));\r\n return { ok: true, path: tmpPath };\r\n }\r\n return { ok: false, error: `Unsupported data URI: ${src.slice(0, 48)}` };\r\n }\r\n\r\n // URL (http/https)\r\n if (src.startsWith('http://') || src.startsWith('https://')) {\r\n let response: Response;\r\n try {\r\n response = await fetch(src, { signal: AbortSignal.timeout(REMOTE_FETCH_TIMEOUT_MS) });\r\n } catch (err) {\r\n const name = err instanceof Error ? err.name : '';\r\n const reason = name === 'TimeoutError' || name === 'AbortError'\r\n ? `request timed out after ${REMOTE_FETCH_TIMEOUT_MS / 1000}s`\r\n : err instanceof Error ? err.message : String(err);\r\n return { ok: false, error: `Failed to fetch ${src}: ${reason}` };\r\n }\r\n if (!response.ok) {\r\n return { ok: false, error: `Failed to fetch ${src}: HTTP ${response.status}` };\r\n }\r\n\r\n const buffer = Buffer.from(await response.arrayBuffer());\r\n const ext = src.split('.').pop()?.split('?')[0] ?? 'png';\r\n const tmpPath = join(tmpdir(), `mfly-${randomUUID().slice(0, 8)}.${ext}`);\r\n writeFileSync(tmpPath, buffer);\r\n return { ok: true, path: tmpPath };\r\n }\r\n\r\n // Local file path (basePath is always a directory)\r\n const absolutePath = resolve(basePath, src);\r\n if (existsSync(absolutePath)) {\r\n return { ok: true, path: absolutePath };\r\n }\r\n\r\n return { ok: false, error: `Image not found: ${src} (resolved to ${absolutePath})` };\r\n } catch (err) {\r\n return {\r\n ok: false,\r\n error: err instanceof Error ? err.message : String(err),\r\n };\r\n }\r\n}\r\n","/**\r\n * SVG to PNG conversion using @resvg/resvg-js (native N-API binding)\r\n */\r\n\r\n// Type-only: erased at build time, so importing it never loads the addon.\r\nimport type { Resvg } from '@resvg/resvg-js';\r\n\r\n/** A normalized SVG plus whether its declared frame can be measured against. */\r\ninterface NormalizedSvg {\r\n svg: string;\r\n /**\r\n * False when the SVG declares a degenerate viewBox (zero/negative extent, e.g.\r\n * mermaid's `viewBox=\"0 0 0 148\"`). Resvg still draws such a file via its\r\n * content-bounds fallback, but its coordinate space is meaningless, so a\r\n * measured reframe cannot be trusted and must be skipped.\r\n */\r\n frameUsable: boolean;\r\n}\r\n\r\n/** Resvg requires the SVG namespace, which some exports leave implicit. */\r\nfunction ensureSvgNamespace(svg: string): string {\r\n if (svg.includes('xmlns=')) return svg;\r\n return svg.replace(/<svg\\b([^>]*)>/i, '<svg xmlns=\"http://www.w3.org/2000/svg\" $1>');\r\n}\r\n\r\n/**\r\n * Normalize SVG string to guarantee valid dimensions and viewBox for Resvg\r\n */\r\nfunction normalizeSvg(svg: string): NormalizedSvg {\r\n let clean = ensureSvgNamespace(svg.trim());\r\n\r\n // Remove existing width and height attributes (with any units pt/px/%/em) to prevent duplicates or percentage panics\r\n clean = clean.replace(/(<svg\\b[^>]*)\\s+width=[\"'][^\"']*[\"']/gi, '$1');\r\n clean = clean.replace(/(<svg\\b[^>]*)\\s+height=[\"'][^\"']*[\"']/gi, '$1');\r\n\r\n // NOTE: `<marker>` definitions and marker-end/start/mid references used to be\r\n // stripped here, to dodge a Rust panic in Resvg's geom.rs. That is not\r\n // reproducible on the installed @resvg/resvg-js (2.6.2): real mermaid marker\r\n // definitions render fine, as do deliberately degenerate ones. Stripping them\r\n // instead deleted drawn arrowheads from every mermaid sequence, state, class\r\n // and ER diagram. Only mermaid emits markers at all — Graphviz and PlantUML\r\n // draw arrowheads as inline polygons — and markers do not affect getBBox(), so\r\n // removing this cannot change framing. `test/mermaid-renderer.test.ts` fails\r\n // if marker ink ever stops reaching the raster.\r\n\r\n // Check for viewBox\r\n const viewBoxMatch = clean.match(/viewBox\\s*=\\s*[\"']([^\"']+)[\"']/i);\r\n let frameUsable = true;\r\n\r\n if (viewBoxMatch) {\r\n const parts = viewBoxMatch[1].trim().split(/[\\s,]+/).map(Number);\r\n if (parts.length === 4 && parts[2] > 0 && parts[3] > 0) {\r\n const w = parts[2];\r\n const h = parts[3];\r\n clean = clean.replace(/<svg\\b([^>]*)>/i, `<svg width=\"${w}\" height=\"${h}\" $1>`);\r\n } else {\r\n frameUsable = false;\r\n }\r\n } else {\r\n clean = clean.replace(/<svg\\b([^>]*)>/i, `<svg width=\"800\" height=\"600\" viewBox=\"0 0 800 600\" $1>`);\r\n }\r\n\r\n return { svg: clean, frameUsable };\r\n}\r\n\r\n/**\r\n * Convert SVG string to PNG Buffer\r\n * @resvg/resvg-js is a native addon — loaded lazily so that runs without\r\n * diagrams (or on platforms lacking the prebuilt binary) never touch it.\r\n */\r\nexport async function svgToPng(svg: string, width: number = 800): Promise<Buffer> {\r\n const { svg: normalized, frameUsable } = normalizeSvg(svg);\r\n const { Resvg } = await import('@resvg/resvg-js');\r\n const resvg = new Resvg(normalized, {\r\n fitTo: { mode: 'width' as const, value: width },\r\n });\r\n if (frameUsable) reframeToContent(resvg);\r\n const pngData = resvg.render();\r\n return Buffer.from(pngData.asPng());\r\n}\r\n\r\n/**\r\n * Width, in pixels, that an author-supplied SVG is rasterized to. Matches what\r\n * the diagram renderers use, so an embedded SVG and a diagram land at a\r\n * comparable resolution.\r\n */\r\nexport const SVG_EMBED_WIDTH = 1200;\r\n\r\n/**\r\n * Rasterize an SVG the author supplied, as opposed to one a diagram engine\r\n * emitted.\r\n *\r\n * Deliberately none of what `svgToPng` does to engine output, because here the\r\n * author's frame is authoritative:\r\n *\r\n * - no reframing. Rebuilding the viewport around the drawn geometry trims the\r\n * padding a logo or icon was designed with — measured on a padded 2:1 icon it\r\n * changed the aspect from 2.000 to 1.556, which would also stretch the image\r\n * on the slide, since placement is derived from the same measurement.\r\n * - no width/height stripping and no synthesised viewBox. An SVG declaring only\r\n * `width`/`height` is valid and common; forcing an 800x600 frame on it would\r\n * shrink the drawing into the corner of a 4:3 box.\r\n */\r\nexport async function rasterizeSvg(svg: string, width: number): Promise<Buffer> {\r\n const { Resvg } = await import('@resvg/resvg-js');\r\n const resvg = new Resvg(ensureSvgNamespace(svg.trim()), {\r\n fitTo: { mode: 'width' as const, value: width },\r\n });\r\n return Buffer.from(resvg.render().asPng());\r\n}\r\n\r\n/** Breathing room kept around the drawing, in SVG user units. */\r\nconst CONTENT_PADDING = 4;\r\n\r\n/**\r\n * How far the content aspect may stray from the declared frame before the\r\n * measurement is treated as untrustworthy.\r\n *\r\n * A genuine correction — revealing clipped content or trimming padding — shifts\r\n * the aspect by a few tens of a percent. Pathological cases differ by orders of\r\n * magnitude: mermaid's gantt places a decorative \"today\" marker thousands of\r\n * units off-chart (it is meant to be clipped away by the viewBox), and\r\n * measuring that would drag the frame out into a sliver. `getBBox()` reports a\r\n * single maximum box with no way to exclude one stray element, so an\r\n * implausible result is rejected rather than trusted.\r\n */\r\nconst MAX_ASPECT_SHIFT = 3;\r\n\r\n/**\r\n * Rebuild the viewport around what is actually drawn.\r\n *\r\n * Every engine decides its own viewBox from measurements taken outside a real\r\n * layout engine, so the emitted frame regularly disagrees with the drawing:\r\n * mermaid measures text with a jsdom polyfill (and falls back to constants for\r\n * elements it cannot measure), which leaves class diagrams and pies overflowing\r\n * the frame, block diagrams framed at a fraction of their width, and flowcharts\r\n * with a sliced-off bottom edge. Resvg can measure the real geometry, so the\r\n * frame is rebuilt from that instead of trusting the engine's own numbers.\r\n *\r\n * Content larger than the frame is revealed; content smaller than it is trimmed\r\n * of the padding the engine added for a viewport it cannot know about here.\r\n */\r\nfunction reframeToContent(resvg: Resvg, padding: number = CONTENT_PADDING): void {\r\n const bbox = resvg.getBBox();\r\n // getBBox() is undefined for an empty drawing, and a zero-area box would\r\n // collapse the frame rather than describe it.\r\n if (!bbox || !(bbox.width > 0) || !(bbox.height > 0)) return;\r\n\r\n const frameAspect = resvg.width / resvg.height;\r\n if (!Number.isFinite(frameAspect) || frameAspect <= 0) return;\r\n const contentAspect = bbox.width / bbox.height;\r\n const shift = Math.max(contentAspect / frameAspect, frameAspect / contentAspect);\r\n if (shift > MAX_ASPECT_SHIFT) return;\r\n\r\n try {\r\n // Grown in place so the padding is honoured. These fields are native\r\n // accessors, so if they turn out to be read-only the exact content frame is\r\n // still a correct (if tighter) result.\r\n bbox.x -= padding;\r\n bbox.y -= padding;\r\n bbox.width += padding * 2;\r\n bbox.height += padding * 2;\r\n } catch {\r\n /* fall through to the unpadded box */\r\n }\r\n\r\n resvg.cropByBBox(bbox);\r\n}\r\n","/**\n * Diagram theme helpers\n * Shared between mermaid/dot renderers so diagrams follow the presentation theme\n */\n\nimport type { Theme } from '../models/theme.js';\n\n/**\n * True when the theme background is dark (perceived luminance below 50%)\n */\nexport function isDarkColor(hex: string): boolean {\n const clean = hex.replace(/^#/, '');\n if (clean.length < 6) return false;\n const r = parseInt(clean.slice(0, 2), 16);\n const g = parseInt(clean.slice(2, 4), 16);\n const b = parseInt(clean.slice(4, 6), 16);\n if ([r, g, b].some((n) => Number.isNaN(n))) return false;\n return 0.299 * r + 0.587 * g + 0.114 * b < 128;\n}\n\nexport function isDarkTheme(theme?: Theme): boolean {\n return theme ? isDarkColor(theme.colors.background) : false;\n}\n\n/**\n * Font stack for diagram text: prefers the theme's CJK font so Chinese labels\n * do not fall back to a Latin-only face, e.g. `\"微软雅黑\", \"Segoe UI\", sans-serif`\n */\nexport function diagramFontFamily(theme?: Theme): string {\n if (!theme) return '\"trebuchet ms\", sans-serif';\n return `\"${theme.fonts.cjk}\", \"${theme.fonts.body}\", sans-serif`;\n}\n","/**\r\n * Mermaid Diagram Renderer\r\n * Uses mermaid + jsdom to render diagrams to SVG in Node.js\r\n */\r\n\r\nimport type { DiagramRenderer } from './renderer.js';\r\nimport type { Theme } from '../models/theme.js';\r\nimport { svgToPng } from './svg-to-png.js';\r\nimport { isDarkTheme, diagramFontFamily } from './theme.js';\r\n\r\nlet initialized = false;\r\n\r\n// ---------------------------------------------------------------------------\r\n// SVG geometry measurement\r\n//\r\n// jsdom has no layout engine, so every getBBox() mermaid relies on is a fake.\r\n// Mermaid sizes its output via `svg.getBBox()` on the root <svg> (its\r\n// `setupGraphViewbox`), which previously returned a constant 80x40 — far\r\n// smaller than the actual drawing — so the produced viewBox was tiny and the\r\n// rasterized PNG turned into a huge zoomed crop (the \"giant purple box\" bug).\r\n// The polyfills below measure REAL geometry (rect/path/circle/line/... with\r\n// translate/rotate/scale chains) for the root <svg>; other elements keep the\r\n// old text heuristics because mermaid's internal node layout already works\r\n// with them.\r\n// ---------------------------------------------------------------------------\r\n\r\ntype Matrix = [number, number, number, number, number, number];\r\n\r\nconst IDENTITY: Matrix = [1, 0, 0, 1, 0, 0];\r\n\r\nconst SKIP_TAGS = new Set([\r\n 'style', 'script', 'defs', 'clippath', 'marker', 'filter', 'mask', 'pattern', 'foreignobject',\r\n]);\r\n\r\n/** 2x3 affine multiply: result = m1·m2 (right operand applies to points first) */\r\nfunction mul(m1: Matrix, m2: Matrix): Matrix {\r\n return [\r\n m1[0] * m2[0] + m1[2] * m2[1],\r\n m1[1] * m2[0] + m1[3] * m2[1],\r\n m1[0] * m2[2] + m1[2] * m2[3],\r\n m1[1] * m2[2] + m1[3] * m2[3],\r\n m1[0] * m2[4] + m1[2] * m2[5] + m1[4],\r\n m1[1] * m2[4] + m1[3] * m2[5] + m1[5],\r\n ];\r\n}\r\n\r\nfunction parseTransform(attr: string | null): Matrix {\r\n if (!attr) return IDENTITY;\r\n let m: Matrix = IDENTITY;\r\n const re = /([a-zA-Z]+)\\s*\\(([^)]*)\\)/g;\r\n let mt: RegExpExecArray | null;\r\n while ((mt = re.exec(attr))) {\r\n const name = mt[1];\r\n const args = mt[2].trim().split(/[\\s,]+/).filter(Boolean).map(Number);\r\n if (args.some((n) => !Number.isFinite(n))) continue;\r\n let next: Matrix | null = null;\r\n switch (name) {\r\n case 'matrix':\r\n if (args.length >= 6) next = [args[0], args[1], args[2], args[3], args[4], args[5]];\r\n break;\r\n case 'translate':\r\n next = [1, 0, 0, 1, args[0] || 0, args[1] || 0];\r\n break;\r\n case 'scale': {\r\n const sx = args[0] || 1;\r\n const sy = args.length > 1 ? args[1] || 1 : sx;\r\n next = [sx, 0, 0, sy, 0, 0];\r\n break;\r\n }\r\n case 'rotate': {\r\n const rad = ((args[0] || 0) * Math.PI) / 180;\r\n const cos = Math.cos(rad);\r\n const sin = Math.sin(rad);\r\n const rot: Matrix = [cos, sin, -sin, cos, 0, 0];\r\n next =\r\n args.length >= 3\r\n ? mul(mul([1, 0, 0, 1, args[1], args[2]], rot), [1, 0, 0, 1, -args[1], -args[2]])\r\n : rot;\r\n break;\r\n }\r\n case 'skewX':\r\n next = [1, 0, Math.tan((args[0] || 0) * Math.PI / 180), 1, 0, 0];\r\n break;\r\n case 'skewY':\r\n next = [1, Math.tan((args[0] || 0) * Math.PI / 180), 0, 1, 0, 0];\r\n break;\r\n }\r\n if (next) m = mul(m, next);\r\n }\r\n return m;\r\n}\r\n\r\nfunction expandedBox(m: Matrix, b: { x: number; y: number; width: number; height: number }) {\r\n let minX = Infinity;\r\n let minY = Infinity;\r\n let maxX = -Infinity;\r\n let maxY = -Infinity;\r\n const pts = [\r\n [b.x, b.y],\r\n [b.x + b.width, b.y],\r\n [b.x, b.y + b.height],\r\n [b.x + b.width, b.y + b.height],\r\n ];\r\n for (const [px, py] of pts) {\r\n const x = m[0] * px + m[2] * py + m[4];\r\n const y = m[1] * px + m[3] * py + m[5];\r\n if (x < minX) minX = x;\r\n if (y < minY) minY = y;\r\n if (x > maxX) maxX = x;\r\n if (y > maxY) maxY = y;\r\n }\r\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\r\n}\r\n\r\n/** Rough text width: CJK chars ≈ 1em, others ≈ 0.55em (mermaid default 16px) */\r\nfunction textWidth(el: Element): number {\r\n let width = 0;\r\n const collect = (e: Element): void => {\r\n for (const child of Array.from(e.childNodes)) {\r\n if (child.nodeType === 3) {\r\n for (const ch of child.textContent ?? '') {\r\n width += (ch.codePointAt(0) ?? 0) > 0x2e80 ? 16 : 9;\r\n }\r\n } else if (child.nodeType === 1) {\r\n collect(child as Element);\r\n }\r\n }\r\n };\r\n collect(el);\r\n return width;\r\n}\r\n\r\n/** Bounds of a path's geometry; control points included (over-estimate is safe) */\r\nfunction pathBounds(d: string): { x: number; y: number; width: number; height: number } | null {\r\n const re = /([a-zA-Z])|(-?\\d*\\.?\\d+(?:e[-+]?\\d+)?)/gi;\r\n const toks: Array<string | number> = [];\r\n let m: RegExpExecArray | null;\r\n while ((m = re.exec(d))) toks.push(m[1] ?? parseFloat(m[2]));\r\n\r\n let minX = Infinity;\r\n let minY = Infinity;\r\n let maxX = -Infinity;\r\n let maxY = -Infinity;\r\n const add = (x: number, y: number): void => {\r\n if (x < minX) minX = x;\r\n if (y < minY) minY = y;\r\n if (x > maxX) maxX = x;\r\n if (y > maxY) maxY = y;\r\n };\r\n\r\n let i = 0;\r\n let x = 0;\r\n let y = 0;\r\n let sx = 0;\r\n let sy = 0;\r\n let lastCmd = '';\r\n let lastRel = false;\r\n const nums = (count: number): number[] | null => {\r\n const out: number[] = [];\r\n while (count-- > 0) {\r\n const t = toks[i++];\r\n if (typeof t !== 'number') return null;\r\n out.push(t);\r\n }\r\n return out;\r\n };\r\n\r\n while (i < toks.length) {\r\n let cmd = toks[i];\r\n let rel: boolean;\r\n if (typeof cmd === 'string') {\r\n rel = cmd === cmd.toLowerCase();\r\n cmd = cmd.toUpperCase();\r\n lastCmd = cmd;\r\n lastRel = rel;\r\n i++;\r\n } else {\r\n // Implicit repeat of the previous command (e.g. value pairs after M)\r\n cmd = lastCmd;\r\n rel = lastRel;\r\n }\r\n switch (cmd) {\r\n case 'M': {\r\n const v = nums(2);\r\n if (!v) return null;\r\n x = rel ? x + v[0] : v[0];\r\n y = rel ? y + v[1] : v[1];\r\n sx = x;\r\n sy = y;\r\n add(x, y);\r\n lastCmd = 'L'; // subsequent value pairs are implicit lineto\r\n lastRel = rel;\r\n break;\r\n }\r\n case 'L': {\r\n const v = nums(2);\r\n if (!v) return null;\r\n x = rel ? x + v[0] : v[0];\r\n y = rel ? y + v[1] : v[1];\r\n add(x, y);\r\n break;\r\n }\r\n case 'H': {\r\n const v = nums(1);\r\n if (!v) return null;\r\n x = rel ? x + v[0] : v[0];\r\n add(x, y);\r\n break;\r\n }\r\n case 'V': {\r\n const v = nums(1);\r\n if (!v) return null;\r\n y = rel ? y + v[0] : v[0];\r\n add(x, y);\r\n break;\r\n }\r\n case 'C': {\r\n const v = nums(6);\r\n if (!v) return null;\r\n // Control points are included; curves stay inside their convex hull\r\n add(rel ? x + v[0] : v[0], rel ? y + v[1] : v[1]);\r\n add(rel ? x + v[2] : v[2], rel ? y + v[3] : v[3]);\r\n x = rel ? x + v[4] : v[4];\r\n y = rel ? y + v[5] : v[5];\r\n add(x, y);\r\n break;\r\n }\r\n case 'S':\r\n case 'Q': {\r\n const v = nums(4);\r\n if (!v) return null;\r\n add(rel ? x + v[0] : v[0], rel ? y + v[1] : v[1]);\r\n x = rel ? x + v[2] : v[2];\r\n y = rel ? y + v[3] : v[3];\r\n add(x, y);\r\n break;\r\n }\r\n case 'T': {\r\n const v = nums(2);\r\n if (!v) return null;\r\n x = rel ? x + v[0] : v[0];\r\n y = rel ? y + v[1] : v[1];\r\n add(x, y);\r\n break;\r\n }\r\n case 'A': {\r\n const v = nums(7);\r\n if (!v) return null;\r\n x = rel ? x + v[5] : v[5];\r\n y = rel ? y + v[6] : v[6];\r\n add(x, y);\r\n break;\r\n }\r\n case 'Z':\r\n x = sx;\r\n y = sy;\r\n break;\r\n default:\r\n return null;\r\n }\r\n }\r\n if (!Number.isFinite(minX)) return null;\r\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\r\n}\r\n\r\n/** Bounds of one element's own geometry, in its local coordinate space */\r\nfunction elementLocalBox(el: Element): { x: number; y: number; width: number; height: number } | null {\r\n const tag = el.tagName ? el.tagName.toLowerCase() : '';\r\n const num = (name: string): number => {\r\n const v = parseFloat(el.getAttribute(name) ?? '');\r\n return Number.isFinite(v) ? v : 0;\r\n };\r\n switch (tag) {\r\n case 'rect': {\r\n const w = num('width');\r\n const h = num('height');\r\n if (!(w > 0 && h > 0)) return null;\r\n return { x: num('x'), y: num('y'), width: w, height: h };\r\n }\r\n case 'circle': {\r\n const r = num('r');\r\n if (!(r > 0)) return null;\r\n return { x: num('cx') - r, y: num('cy') - r, width: 2 * r, height: 2 * r };\r\n }\r\n case 'ellipse': {\r\n const rx = num('rx');\r\n const ry = num('ry');\r\n if (!(rx > 0 && ry > 0)) return null;\r\n return { x: num('cx') - rx, y: num('cy') - ry, width: 2 * rx, height: 2 * ry };\r\n }\r\n case 'line': {\r\n const x1 = num('x1');\r\n const y1 = num('y1');\r\n const x2 = num('x2');\r\n const y2 = num('y2');\r\n return { x: Math.min(x1, x2), y: Math.min(y1, y2), width: Math.abs(x2 - x1), height: Math.abs(y2 - y1) };\r\n }\r\n case 'polygon':\r\n case 'polyline': {\r\n const pts = (el.getAttribute('points') ?? '').split(/[\\s,]+/).filter(Boolean).map(Number);\r\n if (pts.length < 4 || pts.some((n) => !Number.isFinite(n))) return null;\r\n let minX = Infinity;\r\n let minY = Infinity;\r\n let maxX = -Infinity;\r\n let maxY = -Infinity;\r\n for (let k = 0; k + 1 < pts.length; k += 2) {\r\n const px = pts[k];\r\n const py = pts[k + 1];\r\n if (px < minX) minX = px;\r\n if (py < minY) minY = py;\r\n if (px > maxX) maxX = px;\r\n if (py > maxY) maxY = py;\r\n }\r\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\r\n }\r\n case 'path':\r\n return pathBounds(el.getAttribute('d') ?? '');\r\n case 'text':\r\n case 'tspan': {\r\n const w = textWidth(el);\r\n // Mermaid centers node labels (text-anchor: middle); degenerate (empty)\r\n // labels are dropped so they do not pollute the bounds\r\n if (w <= 4) return null;\r\n return { x: num('x') - w / 2, y: num('y') - 14, width: w, height: 24 };\r\n }\r\n default:\r\n return null;\r\n }\r\n}\r\n\r\n/** Union of all descendant geometry, expressed in the root element's space */\r\nfunction contentBBox(root: Element): { x: number; y: number; width: number; height: number } | null {\r\n let minX = Infinity;\r\n let minY = Infinity;\r\n let maxX = -Infinity;\r\n let maxY = -Infinity;\r\n const accumulate = (b: { x: number; y: number; width: number; height: number }): void => {\r\n if (b.x < minX) minX = b.x;\r\n if (b.y < minY) minY = b.y;\r\n if (b.x + b.width > maxX) maxX = b.x + b.width;\r\n if (b.y + b.height > maxY) maxY = b.y + b.height;\r\n };\r\n const walk = (el: Element, m: Matrix): void => {\r\n for (const child of Array.from(el.children)) {\r\n const tag = child.tagName ? child.tagName.toLowerCase() : '';\r\n if (SKIP_TAGS.has(tag)) continue;\r\n const cm = mul(m, parseTransform(child.getAttribute('transform')));\r\n const local = elementLocalBox(child);\r\n if (local) {\r\n const b = expandedBox(cm, local);\r\n // Skip zero-area geometry (empty labels, straight lines) that would\r\n // only stretch the bounds by a point\r\n if (b.width > 0.5 || b.height > 0.5) accumulate(b);\r\n }\r\n walk(child, cm);\r\n }\r\n };\r\n walk(root, IDENTITY);\r\n if (!Number.isFinite(minX)) return null;\r\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Browser global scoping\r\n//\r\n// Mermaid needs a DOM, and jsdom's objects must be reachable as globals while it\r\n// runs. They are installed only for the duration of a mermaid call and removed\r\n// again: a lingering global `window` makes other libraries take their browser\r\n// code paths. pptxgenjs picks between `fs` and `XMLHttpRequest` when it encodes\r\n// media with `typeof window === 'undefined'`, so a window left behind turns every\r\n// path-based image (backgrounds, SVG previews) into a hard crash at write time.\r\n// ---------------------------------------------------------------------------\r\n\r\n/** Globals to install while mermaid runs, collected during initialize() */\r\nlet browserGlobals: Array<[string, unknown]> = [];\r\n\r\n/** Install the collected browser globals; returns a function that restores them. */\r\nfunction installBrowserGlobals(): () => void {\r\n const saved = browserGlobals.map(\r\n ([key]) => [key, Object.getOwnPropertyDescriptor(globalThis, key)] as const,\r\n );\r\n\r\n for (const [key, value] of browserGlobals) {\r\n try {\r\n Object.defineProperty(globalThis, key, {\r\n value,\r\n configurable: true,\r\n writable: true,\r\n });\r\n } catch {\r\n (globalThis as Record<string, unknown>)[key] = value;\r\n }\r\n }\r\n\r\n return () => {\r\n for (const [key, descriptor] of saved) {\r\n // Node defines some of these itself (e.g. `navigator`), so the original\r\n // descriptor is put back rather than blanket-deleting the key.\r\n if (descriptor) {\r\n Object.defineProperty(globalThis, key, descriptor);\r\n } else {\r\n delete (globalThis as Record<string, unknown>)[key];\r\n }\r\n }\r\n };\r\n}\r\n\r\nexport class MermaidDiagramRenderer implements DiagramRenderer {\r\n readonly type = 'mermaid';\r\n private renderCounter = 0;\r\n\r\n async initialize(): Promise<void> {\r\n if (initialized) return;\r\n\r\n // Rebuilt from scratch so a retry after a failed init cannot accumulate\r\n // duplicates (the list must mirror exactly what install() will undo).\r\n browserGlobals = [];\r\n\r\n // Set up jsdom globals for mermaid\r\n const { JSDOM } = await import('jsdom');\r\n const dom = new JSDOM('<!DOCTYPE html><html><body></body></html>', {\r\n pretendToBeVisual: true,\r\n });\r\n\r\n // jsdom reports unset CSS padding as \"\" rather than a length, which makes\r\n // `parseFloat` return NaN. cytoscape — which mermaid uses for the mindmap\r\n // layout — sizes its container as\r\n // `clientWidth - parseFloat(getComputedStyle(el).getPropertyValue('padding-left')) - ...`,\r\n // so that NaN propagates into a bounding box it then dereferences\r\n // (\"Cannot read properties of undefined (reading 'h')\"). Patched on the\r\n // window itself: cytoscape looks it up through `cy.window().getComputedStyle`.\r\n const jsdomGetComputedStyle = dom.window.getComputedStyle.bind(dom.window);\r\n dom.window.getComputedStyle = ((element: Element, pseudo?: string | null) => {\r\n const style = jsdomGetComputedStyle(element, pseudo);\r\n const read = style.getPropertyValue.bind(style);\r\n style.getPropertyValue = (property: string) => {\r\n const value = read(property);\r\n if (value !== '' && value != null) return value;\r\n return property.startsWith('padding') ? '0px' : value;\r\n };\r\n return style;\r\n }) as typeof dom.window.getComputedStyle;\r\n\r\n // Mermaid requires browser globals\r\n const assignGlobal = (key: string, value: unknown) => {\r\n browserGlobals.push([key, value]);\r\n };\r\n\r\n assignGlobal('window', dom.window);\r\n assignGlobal('document', dom.window.document);\r\n assignGlobal('navigator', dom.window.navigator);\r\n assignGlobal('DOMParser', dom.window.DOMParser);\r\n assignGlobal('XMLSerializer', dom.window.XMLSerializer);\r\n assignGlobal('HTMLElement', dom.window.HTMLElement);\r\n assignGlobal('SVGElement', dom.window.SVGElement);\r\n assignGlobal('Element', dom.window.Element);\r\n assignGlobal('Node', dom.window.Node);\r\n assignGlobal('Text', dom.window.Text);\r\n assignGlobal('getComputedStyle', dom.window.getComputedStyle);\r\n assignGlobal('CustomEvent', dom.window.CustomEvent);\r\n assignGlobal('Event', dom.window.Event);\r\n assignGlobal('EventTarget', dom.window.EventTarget);\r\n assignGlobal('HTMLCollection', dom.window.HTMLCollection);\r\n assignGlobal('NodeList', dom.window.NodeList);\r\n assignGlobal('MutationObserver', dom.window.MutationObserver);\r\n\r\n // CSSStyleSheet polyfill / bind\r\n if (dom.window.CSSStyleSheet) {\r\n assignGlobal('CSSStyleSheet', dom.window.CSSStyleSheet);\r\n } else {\r\n class MockCSSStyleSheet {\r\n cssRules = [];\r\n insertRule() { return 0; }\r\n deleteRule() {}\r\n replaceSync() {}\r\n replace() { return Promise.resolve(this); }\r\n }\r\n assignGlobal('CSSStyleSheet', MockCSSStyleSheet);\r\n }\r\n\r\n // Extract text from direct text nodes or text elements, ignoring <style> and <script>\r\n const getDirectText = (el: Element): string => {\r\n const tag = el.tagName ? el.tagName.toLowerCase() : '';\r\n if (tag === 'style' || tag === 'script' || tag === 'defs' || tag === 'marker') return '';\r\n let text = '';\r\n for (const child of Array.from(el.childNodes)) {\r\n if (child.nodeType === 3) {\r\n text += child.textContent || '';\r\n } else if (child.nodeType === 1) {\r\n const ctag = (child as Element).tagName.toLowerCase();\r\n if (ctag === 'tspan' || ctag === 'text' || ctag === 'span' || ctag === 'div' || ctag === 'p') {\r\n text += getDirectText(child as Element);\r\n }\r\n }\r\n }\r\n return text;\r\n };\r\n\r\n /**\r\n * An SVGRect as browsers report it: x/y/width/height and nothing else.\r\n *\r\n * The derived edges (left/top/right/bottom) must NOT be invented here: a\r\n * real SVGRect has no such fields, and mermaid cancels the text-anchor\r\n * offset with `-(bbox.x - (bbox.left ?? 0))`. Reporting `left === x` made\r\n * that term zero, which pushed shape labels out to the side (the cylinder\r\n * node's label sat 55 units left of its node).\r\n */\r\n const toRect = (b: { x: number; y: number; width: number; height: number }) => ({\r\n x: b.x,\r\n y: b.y,\r\n width: b.width,\r\n height: b.height,\r\n toJSON: () => ({}),\r\n });\r\n\r\n /** A DOMRect, for the getBoundingClientRect fallback below. */\r\n const toDomRect = (b: { x: number; y: number; width: number; height: number }) => ({\r\n ...toRect(b),\r\n top: b.y,\r\n right: b.x + b.width,\r\n bottom: b.y + b.height,\r\n left: b.x,\r\n });\r\n\r\n /** Mermaid collects the nodes it lays out in a `<g class=\"nodes\">` group. */\r\n const isMeasuredNode = (el: Element): boolean => {\r\n const parent = el.parentElement;\r\n if (!parent) return false;\r\n return (parent.getAttribute('class') ?? '').split(/\\s+/).includes('nodes');\r\n };\r\n\r\n // Polyfill SVG layout methods that JSDOM lacks\r\n const polyfillBBox = function (this: Element) {\r\n const tag = this.tagName ? this.tagName.toLowerCase() : '';\r\n if (tag === 'style' || tag === 'script' || tag === 'defs' || tag === 'clippath' || tag === 'marker') {\r\n return toRect({ x: 0, y: 0, width: 0, height: 0 });\r\n }\r\n // Mermaid sizes the output SVG from getBBox() on the root <svg>, and it\r\n // measures each node the same way (insertMeasuredNode stores the result as\r\n // the node's width/height for the layout). Both need real geometry: the\r\n // constant fallback below reported every node as 80x40 while the shapes\r\n // were painted up to 188x58, so dagre overlapped neighbouring nodes and\r\n // clipped every edge against a box smaller than the shape the edge ends\r\n // in — which buried the arrowhead under the node's fill.\r\n if (tag === 'svg' || isMeasuredNode(this)) {\r\n const box = contentBBox(this);\r\n if (box) return toRect(box);\r\n }\r\n const text = getDirectText(this);\r\n const width = text ? Math.max(30, text.length * 9 + 20) : 80;\r\n const height = text ? 28 : 40;\r\n // A browser reports a centred <text> box as starting at x - width/2; the\r\n // same convention elementLocalBox already uses when measuring the frame.\r\n const isText = tag === 'text' || tag === 'tspan';\r\n const anchor = parseFloat(this.getAttribute('x') ?? '');\r\n const x = isText ? (Number.isFinite(anchor) ? anchor : 0) - width / 2 : 0;\r\n return toRect({ x, y: 0, width, height });\r\n };\r\n\r\n if (!(dom.window.SVGElement.prototype as unknown as Record<string, unknown>).getBBox) {\r\n (dom.window.SVGElement.prototype as unknown as Record<string, unknown>).getBBox = polyfillBBox;\r\n }\r\n if (!(dom.window.Element.prototype as unknown as Record<string, unknown>).getBBox) {\r\n (dom.window.Element.prototype as unknown as Record<string, unknown>).getBBox = polyfillBBox;\r\n }\r\n if (!dom.window.Element.prototype.getBoundingClientRect) {\r\n dom.window.Element.prototype.getBoundingClientRect = (function (this: Element) {\r\n const box = polyfillBBox.call(this);\r\n return toDomRect(box);\r\n }) as unknown as () => DOMRect;\r\n }\r\n const computeTextLength = function (this: Element) {\r\n const text = getDirectText(this);\r\n return text.length * 9;\r\n };\r\n (dom.window.Element.prototype as unknown as Record<string, unknown>).getComputedTextLength = computeTextLength;\r\n (dom.window.SVGElement.prototype as unknown as Record<string, unknown>).getComputedTextLength = computeTextLength;\r\n (dom.window.HTMLElement.prototype as unknown as Record<string, unknown>).getComputedTextLength = computeTextLength;\r\n\r\n if (dom.window.HTMLCanvasElement) {\r\n dom.window.HTMLCanvasElement.prototype.getContext = (() => ({\r\n measureText: (text: string) => ({ width: text.length * 8 }),\r\n fillRect: () => {},\r\n clearRect: () => {},\r\n getImageData: () => ({ data: new Array(4) }),\r\n putImageData: () => {},\r\n createImageData: () => [],\r\n setTransform: () => {},\r\n drawImage: () => {},\r\n save: () => {},\r\n fillText: () => {},\r\n restore: () => {},\r\n beginPath: () => {},\r\n moveTo: () => {},\r\n lineTo: () => {},\r\n closePath: () => {},\r\n stroke: () => {},\r\n translate: () => {},\r\n scale: () => {},\r\n rotate: () => {},\r\n arc: () => {},\r\n fill: () => {},\r\n })) as unknown as typeof dom.window.HTMLCanvasElement.prototype.getContext;\r\n }\r\n\r\n if (dom.window.SVGSVGElement) {\r\n if (!dom.window.SVGSVGElement.prototype.createSVGMatrix) {\r\n dom.window.SVGSVGElement.prototype.createSVGMatrix = () => ({\r\n a: 1, b: 0, c: 0, d: 1, e: 0, f: 0,\r\n multiply: function () { return this; },\r\n inverse: function () { return this; },\r\n translate: function () { return this; },\r\n scale: function () { return this; },\r\n rotate: function () { return this; },\r\n } as unknown as DOMMatrix);\r\n }\r\n if (!dom.window.SVGSVGElement.prototype.createSVGPoint) {\r\n dom.window.SVGSVGElement.prototype.createSVGPoint = () => ({\r\n x: 0, y: 0,\r\n matrixTransform: function () { return this; },\r\n } as unknown as DOMPoint);\r\n }\r\n }\r\n\r\n // Mock matchMedia if missing\r\n if (!dom.window.matchMedia) {\r\n dom.window.matchMedia = () => ({\r\n matches: false,\r\n media: '',\r\n onchange: null,\r\n addListener: () => {},\r\n removeListener: () => {},\r\n addEventListener: () => {},\r\n removeEventListener: () => {},\r\n dispatchEvent: () => false,\r\n }) as unknown as MediaQueryList;\r\n }\r\n\r\n // Import and initialize mermaid, with the DOM globals in place for the\r\n // import itself (mermaid touches browser APIs as its modules evaluate).\r\n const restore = installBrowserGlobals();\r\n try {\r\n const mermaid = (await import('mermaid')).default;\r\n mermaid.initialize(this.buildConfig() as unknown as Parameters<typeof mermaid.initialize>[0]);\r\n } finally {\r\n restore();\r\n }\r\n\r\n initialized = true;\r\n }\r\n\r\n private buildConfig(theme?: Theme) {\r\n return {\r\n startOnLoad: false,\r\n securityLevel: 'loose',\r\n // Top-level htmlLabels is required: flowchart-v2 reads it (the\r\n // flowchart.htmlLabels key is ignored) and html labels rely on real DOM\r\n // layout (scrollWidth) that jsdom does not provide — with them on, nodes\r\n // collapse to 60x30 stubs and resvg drops the HTML content entirely.\r\n htmlLabels: false,\r\n theme: isDarkTheme(theme) ? 'dark' : 'default',\r\n themeVariables: {\r\n fontFamily: diagramFontFamily(theme),\r\n background: 'transparent',\r\n },\r\n flowchart: { htmlLabels: false, curve: 'basis', useMaxWidth: false },\r\n sequence: { useMaxWidth: false },\r\n // jsdom has no layout engine: offsetWidth is 0 rather than undefined, so\r\n // mermaid's own \"no parent width\" fallback never fires and the gantt chart\r\n // ends up with a zero-width viewBox. Pin the viewport width instead.\r\n gantt: { useWidth: 1200 },\r\n };\r\n }\r\n\r\n async render(code: string, theme?: Theme): Promise<Buffer> {\r\n await this.initialize();\r\n\r\n const mermaid = (await import('mermaid')).default;\r\n const id = `mfly-mermaid-${Date.now()}-${this.renderCounter++}`;\r\n\r\n let svg: string;\r\n const restore = installBrowserGlobals();\r\n try {\r\n // Re-apply per render so diagram follows the selected presentation theme\r\n mermaid.initialize(this.buildConfig(theme) as unknown as Parameters<typeof mermaid.initialize>[0]);\r\n ({ svg } = await mermaid.render(id, code.trim()));\r\n } catch (err) {\r\n throw new Error(\r\n `Mermaid render failed: ${err instanceof Error ? err.message : String(err)}`,\r\n );\r\n } finally {\r\n restore();\r\n }\r\n\r\n // Rasterized after the globals are gone, so the native addon also loads in a\r\n // clean Node environment.\r\n return svgToPng(svg, 1200);\r\n }\r\n}\r\n","/**\n * Graphviz/DOT Diagram Renderer\n * Uses @viz-js/viz (WASM) — works natively in Node.js, no DOM needed\n */\n\nimport type { DiagramRenderer } from './renderer.js';\nimport type { Theme } from '../models/theme.js';\nimport { svgToPng } from './svg-to-png.js';\nimport { isDarkTheme } from './theme.js';\n\nexport class GraphvizDiagramRenderer implements DiagramRenderer {\n readonly type = 'dot';\n private viz: Awaited<ReturnType<typeof import('@viz-js/viz').instance>> | null = null;\n\n async initialize(): Promise<void> {\n if (this.viz) return;\n const vizModule = await import('@viz-js/viz');\n this.viz = await vizModule.instance();\n }\n\n /**\n * Dark theme support: prepend default node/edge/graph attributes so nodes,\n * edges, and labels become light-on-dark. User-specified attrs in the DOT\n * code still win because they appear after these defaults.\n */\n private themeDefaults(code: string, dark: boolean): string {\n if (!dark) return code;\n const prelude =\n ' graph [fontcolor=\"#c9d1d9\" bgcolor=\"transparent\"];\\n' +\n ' node [color=\"#8b949e\" fontcolor=\"#c9d1d9\"];\\n' +\n ' edge [color=\"#8b949e\" fontcolor=\"#c9d1d9\"];\\n';\n return code.replace(/\\{/, `{\\n${prelude}`);\n }\n\n async render(code: string, theme?: Theme): Promise<Buffer> {\n await this.initialize();\n\n try {\n const dark = isDarkTheme(theme);\n const svg = this.viz!.renderString(this.themeDefaults(code.trim(), dark), {\n format: 'svg',\n engine: 'dot',\n graphAttributes: {\n bgcolor: 'transparent',\n },\n });\n return svgToPng(svg, 1200);\n } catch (err) {\n throw new Error(\n `Graphviz render failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n}\n","/**\n * ECharts Diagram Renderer\n * Uses ECharts SSR mode — pure Node.js, no DOM/canvas needed\n */\n\nimport type { DiagramRenderer } from './renderer.js';\nimport type { Theme } from '../models/theme.js';\nimport { svgToPng } from './svg-to-png.js';\n\nexport class EChartsDiagramRenderer implements DiagramRenderer {\n readonly type = 'echarts';\n\n async initialize(): Promise<void> {\n // ECharts SSR mode needs no initialization\n }\n\n async render(code: string, _theme?: Theme): Promise<Buffer> {\n const echarts = await import('echarts');\n\n let option: Record<string, unknown>;\n try {\n option = JSON.parse(code.trim());\n } catch {\n throw new Error('ECharts: invalid JSON option');\n }\n\n // Extract optional size hints\n const width = typeof option.width === 'number' ? option.width : 800;\n const height = typeof option.height === 'number' ? option.height : 450;\n delete option.width;\n delete option.height;\n\n // SSR mode: no DOM required\n const chart = echarts.init(null, null, {\n renderer: 'svg',\n ssr: true,\n width,\n height,\n });\n\n try {\n chart.setOption({\n ...option,\n animation: false,\n });\n\n const svg = chart.renderToSVGString();\n return svgToPng(svg, width * 2); // 2x for retina quality\n } finally {\n chart.dispose();\n }\n }\n}\n","/**\r\n * PlantUML Diagram Renderer\r\n *\r\n * Uses the official TeaVM-compiled PlantUML engine, which runs as plain JS —\r\n * no JVM jar and no Graphviz binary, so the package keeps its promise of zero\r\n * native binary dependencies.\r\n *\r\n * The dependency is on `@plantuml/mcp-js`, whose `engine.js` is the *headless*\r\n * build (renderSvg → SVG string). `@plantuml/core` is the same engine but only\r\n * exposes DOM-facing entry points (`render(lines, targetId)`), which would mean\r\n * driving it through jsdom. Graphviz layout is supplied by `@viz-js/viz` — the\r\n * WASM build the DOT renderer already depends on.\r\n */\r\n\r\nimport type { DiagramRenderer } from './renderer.js';\r\nimport type { Theme } from '../models/theme.js';\r\nimport { svgToPng } from './svg-to-png.js';\r\nimport { isDarkTheme } from './theme.js';\r\nimport { log } from '../utils/progress.js';\r\n\r\ntype Engine = typeof import('@plantuml/mcp-js/engine.js');\r\n\r\n/** Rasterized width; matches the other diagram renderers. */\r\nconst RENDER_WIDTH = 1200;\r\n\r\n/**\r\n * A render that never settles would hang the whole CLI, and the engine can do\r\n * exactly that: a `!theme` line makes it look for themes.js, which the headless\r\n * build does not ship (see `stripUnsupported`). Every render is bounded.\r\n */\r\nconst RENDER_TIMEOUT_MS = 30_000;\r\n\r\n/** Payload delivered by renderSvg as a JSON string. */\r\ninterface EngineResult {\r\n valid?: boolean;\r\n diagramType?: string;\r\n errorLineNumber?: number;\r\n errorMessage?: string;\r\n svg?: string;\r\n}\r\n\r\n/** Prepared source plus the bookkeeping needed to read error lines back. */\r\ninterface PreparedSource {\r\n source: string;\r\n warnings: string[];\r\n /** How many lines the injected prelude (and envelope) add. */\r\n lineShift: number;\r\n /** Last 1-based source line that is not shifted; later lines shift by lineShift. */\r\n shiftAfter: number;\r\n}\r\n\r\n/** Map an engine-reported line back to the line the author actually wrote. */\r\nfunction originalLine(\r\n reported: number | undefined,\r\n prepared: PreparedSource,\r\n): number | undefined {\r\n if (reported === undefined) return undefined;\r\n return reported > prepared.shiftAfter ? reported - prepared.lineShift : reported;\r\n}\r\n\r\n/**\r\n * The engine maps Java's System.out to console.log and narrates its internals\r\n * there — dozens of `[TimLoader]`/`[PSystemBuilder2]` lines per diagram. That is\r\n * engine bookkeeping rather than something an author can act on (real problems\r\n * come back through the render result, which is reported with a line number), so\r\n * it is muted: stdout stays reserved for the summary line and the `--json`\r\n * payload, and stderr stays readable. MFLY_DEBUG=1 forwards it to stderr.\r\n *\r\n * The writers are restored afterwards — replacing them for good would push\r\n * `log.info` and the \"Done in Xs\" summary off stdout.\r\n */\r\nasync function withEngineLogsMuted<T>(fn: () => Promise<T>): Promise<T> {\r\n const originals = { log: console.log, info: console.info, debug: console.debug };\r\n const sink: (...args: unknown[]) => void = process.env.MFLY_DEBUG\r\n ? (...args) => console.error(...args)\r\n : () => {};\r\n console.log = sink;\r\n console.info = sink;\r\n console.debug = sink;\r\n try {\r\n return await fn();\r\n } finally {\r\n console.log = originals.log;\r\n console.info = originals.info;\r\n console.debug = originals.debug;\r\n }\r\n}\r\n\r\n/** Quote a font family for a skinparam value. */\r\nfunction fontValue(theme: Theme): string {\r\n return `\"${theme.fonts.cjk.replace(/\"/g, '')}\"`;\r\n}\r\n\r\n/**\r\n * Styling the engine omits from bare `<line>` elements, taken from what the\r\n * reference PlantUML server emits for the same diagrams.\r\n */\r\nconst LINE_STROKE = 'stroke:#181818;stroke-width:0.5;';\r\n\r\n/** Sequence lifelines are dashed on top of the base stroke. */\r\nconst LIFELINE_STROKE = `${LINE_STROKE}stroke-dasharray:5,5;`;\r\n\r\n/**\r\n * Give bare `<line>` elements their stroke back.\r\n *\r\n * The TeaVM-compiled engine emits line geometry but drops the styling:\r\n * `<line x1=\"22\" y1=\"79\" x2=\"22\" y2=\"205\"/>` with no `stroke` or `style`, no\r\n * class, no `<style>` block and no styled ancestor. Per SVG that means\r\n * `stroke: none`, so every renderer draws nothing. Two visible casualties:\r\n * sequence lifelines, which left the participants floating with nothing between\r\n * them, and the compartment dividers of a class diagram.\r\n *\r\n * The geometry is intact, so the styling is restored from the reference\r\n * server's output — a 0.5pt solid stroke, dashed for sequence lifelines.\r\n */\r\nfunction restoreLineStrokes(svg: string, diagramType: string | undefined): string {\r\n const dashed = /sequence/i.test(diagramType ?? '');\r\n return svg.replace(/<line\\b([^>]*?)\\/>/g, (match, attributes: string) =>\r\n /\\b(stroke|style)=/.test(attributes)\r\n ? match\r\n : `<line${attributes} style=\"${dashed ? LIFELINE_STROKE : LINE_STROKE}\"/>`,\r\n );\r\n}\r\n\r\nexport class PlantUmlDiagramRenderer implements DiagramRenderer {\r\n readonly type = 'plantuml';\r\n private engine: Engine | null = null;\r\n\r\n async initialize(): Promise<void> {\r\n if (this.engine) return;\r\n\r\n // Loaded lazily: a deck without PlantUML blocks never touches the engine.\r\n this.engine = await withEngineLogsMuted(async () => {\r\n // The engine reaches Graphviz through a global `Viz` shaped like Viz.js in\r\n // a browser; @viz-js/viz is that shape in Node. Left untouched if a host\r\n // already provided one.\r\n const globalWithViz = globalThis as { Viz?: unknown };\r\n if (!globalWithViz.Viz) {\r\n const vizModule = await import('@viz-js/viz');\r\n let instancePromise: ReturnType<typeof vizModule.instance> | null = null;\r\n globalWithViz.Viz = {\r\n instance: () => (instancePromise ??= vizModule.instance()),\r\n };\r\n }\r\n return import('@plantuml/mcp-js/engine.js');\r\n });\r\n }\r\n\r\n /**\r\n * PlantUML has no dark-mode switch in this build, so the palette is injected\r\n * as skinparams — the same shape as the DOT renderer's attribute prelude.\r\n * Anything the author writes after the prelude still wins.\r\n *\r\n * `backgroundColor transparent` is stated explicitly rather than left to the\r\n * default: PlantUML otherwise writes `background:#FFFFFF` into the SVG style,\r\n * which only stays invisible because the rasterizer happens to ignore it.\r\n */\r\n private skinparams(theme?: Theme): string {\r\n const lines = ['skinparam backgroundColor transparent'];\r\n\r\n if (theme) {\r\n lines.push(`skinparam defaultFontName ${fontValue(theme)}`);\r\n }\r\n\r\n if (!isDarkTheme(theme)) {\r\n lines.push('skinparam defaultFontColor #1F2328');\r\n return lines.join('\\n');\r\n }\r\n\r\n lines.push(\r\n 'skinparam defaultFontColor #C9D1D9',\r\n 'skinparam shadowing false',\r\n // Boxes are light by default, so the fills have to move with the text or\r\n // labels end up dark-on-dark.\r\n 'skinparam classBackgroundColor #1F2937',\r\n 'skinparam classBorderColor #6B7280',\r\n 'skinparam classFontColor #E5E7EB',\r\n 'skinparam classAttributeFontColor #CBD5E1',\r\n 'skinparam participantBackgroundColor #1F2937',\r\n 'skinparam participantBorderColor #6B7280',\r\n 'skinparam actorBackgroundColor #1F2937',\r\n 'skinparam actorBorderColor #6B7280',\r\n 'skinparam sequenceArrowColor #9CA3AF',\r\n 'skinparam sequenceLifeLineBorderColor #6B7280',\r\n 'skinparam noteBackgroundColor #374151',\r\n 'skinparam noteBorderColor #6B7280',\r\n 'skinparam activityBackgroundColor #1F2937',\r\n 'skinparam activityBorderColor #6B7280',\r\n 'skinparam activityDiamondBackgroundColor #1F2937',\r\n 'skinparam activityDiamondBorderColor #6B7280',\r\n 'skinparam stateBackgroundColor #1F2937',\r\n 'skinparam stateBorderColor #6B7280',\r\n 'skinparam componentBackgroundColor #1F2937',\r\n 'skinparam componentBorderColor #6B7280',\r\n 'skinparam componentFontColor #E5E7EB',\r\n );\r\n return lines.join('\\n');\r\n }\r\n\r\n /**\r\n * Drop `!theme` directives and inject the theme prelude.\r\n *\r\n * `!theme` needs themes.js, which the headless build does not ship — the\r\n * directive is ignored with a warning anyway. Dropping it up front also avoids\r\n * the theme loader entirely, which is what can leave renderSvg without ever\r\n * calling back (a second *distinct* theme in one process is enough).\r\n */\r\n private prepare(code: string, theme?: Theme): PreparedSource {\r\n const warnings: string[] = [];\r\n const kept: string[] = [];\r\n\r\n for (const line of code.trim().split('\\n')) {\r\n if (/^\\s*!theme\\b/i.test(line)) {\r\n warnings.push(\r\n `\"${line.trim()}\" ignored — the bundled PlantUML engine ships no themes; use skinparam instead`,\r\n );\r\n continue;\r\n }\r\n kept.push(line);\r\n }\r\n\r\n const prelude = this.skinparams(theme);\r\n const preludeLines = prelude.split('\\n').length;\r\n const startIndex = kept.findIndex((line) => /^\\s*@start\\w+/i.test(line));\r\n\r\n // Without an @start…/@end… envelope PlantUML cannot tell what to draw, so\r\n // authoring a bare diagram (as the other renderers accept) is supported.\r\n if (startIndex === -1) {\r\n return {\r\n source: `@startuml\\n${prelude}\\n${kept.join('\\n')}\\n@enduml`,\r\n warnings,\r\n lineShift: preludeLines + 1,\r\n shiftAfter: 1,\r\n };\r\n }\r\n\r\n kept.splice(startIndex + 1, 0, prelude);\r\n\r\n // A start tag with no matching @end… is closed here rather than left to fail:\r\n // bare source is already accepted, so a half-written envelope should not be\r\n // the one shape that errors out.\r\n if (!kept.some((line) => /^\\s*@end\\w+/i.test(line))) {\r\n const kind = kept[startIndex].match(/^\\s*@start(\\w+)/i)?.[1] ?? 'uml';\r\n kept.push(`@end${kind}`);\r\n }\r\n\r\n return {\r\n source: kept.join('\\n'),\r\n warnings,\r\n lineShift: preludeLines,\r\n shiftAfter: startIndex + 1,\r\n };\r\n }\r\n\r\n async render(code: string, theme?: Theme): Promise<Buffer> {\r\n await this.initialize();\r\n const prepared = this.prepare(code, theme);\r\n for (const warning of prepared.warnings) log.warn(`[PlantUML] ${warning}`);\r\n\r\n try {\r\n const result = await this.renderToSvg(prepared.source);\r\n if (!result.valid || !result.svg) {\r\n // The engine counts lines in the source it was handed, which includes\r\n // the injected prelude — report the author's line numbers instead.\r\n const line = originalLine(result.errorLineNumber, prepared);\r\n const at = line ? ` (line ${line})` : '';\r\n throw new Error(`${result.errorMessage ?? 'invalid diagram'}${at}`);\r\n }\r\n return svgToPng(restoreLineStrokes(result.svg, result.diagramType), RENDER_WIDTH);\r\n } catch (err) {\r\n throw new Error(\r\n `PlantUML render failed: ${err instanceof Error ? err.message : String(err)}`,\r\n );\r\n }\r\n }\r\n\r\n private async renderToSvg(source: string): Promise<EngineResult> {\r\n const engine = this.engine!;\r\n\r\n const json = await withEngineLogsMuted(\r\n () =>\r\n new Promise<string>((resolve, reject) => {\r\n let settled = false;\r\n const timer = setTimeout(() => {\r\n if (settled) return;\r\n settled = true;\r\n reject(new Error(`timed out after ${RENDER_TIMEOUT_MS / 1000}s`));\r\n }, RENDER_TIMEOUT_MS);\r\n\r\n engine.renderSvg(source, (result) => {\r\n if (settled) return;\r\n settled = true;\r\n clearTimeout(timer);\r\n resolve(result);\r\n });\r\n }),\r\n );\r\n\r\n try {\r\n return JSON.parse(json) as EngineResult;\r\n } catch {\r\n throw new Error('engine returned malformed JSON');\r\n }\r\n }\r\n}\r\n","/**\r\n * Diagram Registry\r\n * Unified entry point for all diagram renderers\r\n */\r\n\r\nimport type { DiagramRenderer } from './renderer.js';\r\nimport type { Theme } from '../models/theme.js';\r\nimport { MermaidDiagramRenderer } from './mermaid-renderer.js';\r\nimport { GraphvizDiagramRenderer } from './graphviz-renderer.js';\r\nimport { EChartsDiagramRenderer } from './echarts-renderer.js';\r\nimport { PlantUmlDiagramRenderer } from './plantuml-renderer.js';\r\nimport { normalizeDiagramLanguage } from './languages.js';\r\n\r\nexport { isDiagramLanguage } from './languages.js';\r\n\r\n/**\r\n * Canonical language → renderer factory. Factories (not instances) so that\r\n * merely knowing a language never constructs a renderer or loads its engine.\r\n */\r\nconst RENDERERS: Record<string, () => DiagramRenderer> = {\r\n mermaid: () => new MermaidDiagramRenderer(),\r\n dot: () => new GraphvizDiagramRenderer(),\r\n echarts: () => new EChartsDiagramRenderer(),\r\n plantuml: () => new PlantUmlDiagramRenderer(),\r\n};\r\n\r\n/** Cached renderer instances (lazy init), keyed by canonical language */\r\nconst instances = new Map<string, DiagramRenderer>();\r\n\r\nfunction getOrCreate(language: string): DiagramRenderer | undefined {\r\n // Resolve aliases first so the cache key and the factory lookup agree.\r\n const canonical = normalizeDiagramLanguage(language);\r\n if (!canonical) return undefined;\r\n\r\n const cached = instances.get(canonical);\r\n if (cached) return cached;\r\n\r\n const renderer = RENDERERS[canonical]();\r\n instances.set(canonical, renderer);\r\n return renderer;\r\n}\r\n\r\n/** Get a diagram renderer by language */\r\nexport function getDiagramRenderer(language: string): DiagramRenderer | undefined {\r\n return getOrCreate(language);\r\n}\r\n\r\n/**\r\n * Render a diagram code block to PNG\r\n * @returns PNG image as Buffer\r\n */\r\nexport async function renderDiagram(\r\n language: string,\r\n code: string,\r\n theme?: Theme,\r\n): Promise<Buffer> {\r\n const renderer = getOrCreate(language);\r\n if (!renderer) {\r\n throw new Error(`No diagram renderer for language: ${language}`);\r\n }\r\n\r\n await renderer.initialize();\r\n return renderer.render(code, theme);\r\n}\r\n","/**\n * Slide background resolver\n * Turns the theme's flat color (or linear gradient) into pptxgenjs background props.\n * Gradient PNGs are generated once and cached per gradient definition.\n */\n\nimport type { Theme } from '../models/theme.js';\nimport { createLinearGradientPng } from '../utils/gradient.js';\n\nconst cache = new Map<string, string>();\n\nexport interface SlideBackgroundProps {\n /** Flat fallback color; pptxgenjs ignores it when an image `data` is present */\n color: string;\n /** Base64 PNG stretched over the slide (gradient themes only) */\n data?: string;\n}\n\nexport function slideBackground(theme: Theme): SlideBackgroundProps {\n const gradient = theme.colors.backgroundGradient;\n if (!gradient) return { color: theme.colors.background };\n\n const key = `${gradient.from}|${gradient.to}|${gradient.angle ?? 180}`;\n let data = cache.get(key);\n if (!data) {\n // 192×108 keeps 16:9 so angles look the same as the rendered slide\n const png = createLinearGradientPng(gradient.from, gradient.to, gradient.angle ?? 180, {\n width: 192,\n height: 108,\n });\n data = `image/png;base64,${png.toString('base64')}`;\n cache.set(key, data);\n }\n return { color: theme.colors.background, data };\n}\n","/**\r\n * Small hex color helpers (no '#' prefix — project convention).\r\n * Used to derive ThemeColors roles from a compact ColorScheme.\r\n */\r\n\r\nexport type Rgb = [number, number, number];\r\n\r\nconst HEX6 = /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/;\r\n\r\nexport function parseHex(hex: string): Rgb {\r\n const raw = hex.startsWith('#') ? hex.slice(1) : hex;\r\n const m = HEX6.exec(raw);\r\n if (!m) {\r\n throw new Error(`Invalid hex color (expected RRGGBB): ${hex}`);\r\n }\r\n return [parseInt(m[1], 16), parseInt(m[2], 16), parseInt(m[3], 16)];\r\n}\r\n\r\nexport function toHex(r: number, g: number, b: number): string {\r\n const c = (n: number) =>\r\n Math.max(0, Math.min(255, Math.round(n)))\r\n .toString(16)\r\n .padStart(2, '0')\r\n .toUpperCase();\r\n return `${c(r)}${c(g)}${c(b)}`;\r\n}\r\n\r\n/**\r\n * Linear mix in sRGB. t=0 → a, t=1 → b.\r\n */\r\nexport function mixHex(a: string, b: string, t: number): string {\r\n const [ar, ag, ab] = parseHex(a);\r\n const [br, bg, bb] = parseHex(b);\r\n const k = Math.max(0, Math.min(1, t));\r\n return toHex(ar + (br - ar) * k, ag + (bg - ag) * k, ab + (bb - ab) * k);\r\n}\r\n\r\n/** Relative luminance (WCAG), 0..1 */\r\nexport function relativeLuminance(hex: string): number {\r\n const [r, g, b] = parseHex(hex).map((v) => {\r\n const s = v / 255;\r\n return s <= 0.03928 ? s / 12.92 : Math.pow((s + 0.055) / 1.055, 2.4);\r\n }) as [number, number, number];\r\n return 0.2126 * r + 0.7152 * g + 0.0722 * b;\r\n}\r\n\r\nexport function isDarkColor(hex: string): boolean {\r\n return relativeLuminance(hex) < 0.4;\r\n}\r\n","/**\r\n * ColorScheme — minimal user-facing palette for the PPT design system.\r\n *\r\n * A scheme is exactly four slots:\r\n * ink — text (titles, body)\r\n * paper — page background\r\n * primary — main decoration bars / large color blocks\r\n * secondary— auxiliary elements / secondary info\r\n *\r\n * Emphasis is expressed by weight, size, rules, and whitespace — not by an\r\n * extra chromatic slot. `ThemeColors.accent` is still produced for legacy\r\n * renderers, derived from primary (deeper mix toward ink).\r\n *\r\n * Built-in presets and user customs share this exact shape.\r\n */\r\n\r\nimport { isDarkColor } from '../utils/color-mix.js';\r\n\r\nexport type ColorSchemeMode = 'light' | 'dark';\r\n\r\nexport interface ColorScheme {\r\n /** Stable id, e.g. 'ocean' */\r\n name: string;\r\n /**\r\n * Surface polarity hint (drives shiki default). Optional — inferred from\r\n * paper luminance when omitted. Does NOT swap ink/paper: ink is always\r\n * text, paper is always background.\r\n */\r\n mode?: ColorSchemeMode;\r\n /** Text color: titles + body */\r\n ink: string;\r\n /** Page background */\r\n paper: string;\r\n /** Primary: main decoration bars, large color blocks */\r\n primary: string;\r\n /** Secondary: auxiliary elements, secondary information */\r\n secondary: string;\r\n}\r\n\r\n/** Chromatic slots exposed on ThemeColors.accents[] (emphasis is non-chromatic) */\r\nexport const CHROMATIC_SLOTS = ['primary', 'secondary'] as const;\r\n\r\nexport type ChromaticSlot = (typeof CHROMATIC_SLOTS)[number];\r\n\r\n/** light/dark from paper luminance (explicit mode wins); ink/paper are never swapped */\r\nexport function resolveSchemeMode(scheme: ColorScheme): ColorSchemeMode {\r\n if (scheme.mode) return scheme.mode;\r\n return isDarkColor(scheme.paper) ? 'dark' : 'light';\r\n}\r\n","import type { ColorScheme } from '../../models/color-scheme.js';\r\n\r\n/**\r\n * Ocean(海洋)— 单色克制蓝。\r\n * ink 深海墨蓝作文字,paper 近白海沫作底,primary 亮蓝主装饰,\r\n * secondary 中蓝辅助。强调靠字重/字号/线条,不额外占彩槽。\r\n */\r\nexport const oceanScheme: ColorScheme = {\r\n name: 'ocean',\r\n mode: 'light',\r\n ink: '1E4A6F',\r\n paper: 'F0F8FF',\r\n primary: '4F9FD9',\r\n secondary: '2D6A9F',\r\n};\r\n","import type { ColorScheme } from '../../models/color-scheme.js';\r\n\r\n/**\r\n * Ocean Dark(深海)— ocean 的暗色对位。\r\n * paper 深海作底,ink 浅沫作字;primary/secondary 提亮以保证深底对比。\r\n * 代码块底为派生深色面板 + github-dark 高亮。\r\n */\r\nexport const oceanDarkScheme: ColorScheme = {\r\n name: 'ocean-dark',\r\n mode: 'dark',\r\n ink: 'D6E7F5',\r\n paper: '0B1C2E',\r\n primary: '5BAAE8',\r\n secondary: '8BBCDD',\r\n};\r\n","import type { ColorScheme } from '../../models/color-scheme.js';\r\n\r\n/**\r\n * Forest(森林)— 低饱和清新绿。\r\n * ink 深墨绿作文字,paper 淡白绿作底,primary 亮青绿主装饰,\r\n * secondary 中绿辅助。强调靠字重/字号/线条,不额外占彩槽。\r\n */\r\nexport const forestScheme: ColorScheme = {\r\n name: 'forest',\r\n mode: 'light',\r\n ink: '2A4A3F',\r\n paper: 'F0FFF5',\r\n primary: '5F9A8A',\r\n secondary: '3F6A5A',\r\n};\r\n","import type { ColorScheme } from '../../models/color-scheme.js';\r\n\r\n/**\r\n * Champagne(香槟)— 温暖金属金光。\r\n * ink 暗金作文字,paper 米白奶油作底,primary 亮金主装饰,\r\n * secondary 淡金辅助。强调靠字重/字号/线条,不额外占彩槽。\r\n */\r\nexport const champagneScheme: ColorScheme = {\r\n name: 'champagne',\r\n mode: 'light',\r\n ink: 'CFB53B',\r\n paper: 'FFFCE6',\r\n primary: 'E5CD5F',\r\n secondary: 'F5E08A',\r\n};\r\n","import type { ColorScheme } from '../../models/color-scheme.js';\r\n\r\n/**\r\n * Graphite(石墨)— 灰白中性极简。\r\n * ink 深灰作文字,paper 浅灰近白作底,primary 中灰主装饰,\r\n * secondary 灰阶辅助。强调靠字重/字号/线条,不额外占彩槽。\r\n */\r\nexport const graphiteScheme: ColorScheme = {\r\n name: 'graphite',\r\n mode: 'light',\r\n ink: '4D4D4D',\r\n paper: 'F8F8F8',\r\n primary: 'D9D9D9',\r\n secondary: 'A6A6A6',\r\n};\r\n","/**\r\n * Built-in ColorScheme registry.\r\n *\r\n * Convention: one scheme per file in this folder (`kebab-case.ts`), each\r\n * exporting a single `ColorScheme`. To add a built-in scheme:\r\n * 1. create `color-schemes/<name>.ts` exporting `{name}Scheme`\r\n * 2. import it below and append to `builtInSchemes`\r\n *\r\n * Step 2 is the only registry touch; values never live in this file.\r\n * `test/color-schemes-folder.test.ts` fails if a scheme file is not registered.\r\n */\r\n\r\nimport type { ColorScheme } from '../../models/color-scheme.js';\r\nimport { oceanScheme } from './ocean.js';\r\nimport { oceanDarkScheme } from './ocean-dark.js';\r\nimport { forestScheme } from './forest.js';\r\nimport { champagneScheme } from './champagne.js';\r\nimport { graphiteScheme } from './graphite.js';\r\n\r\n/** All built-in schemes. Keep in sync with *.ts files in this folder. */\r\nconst builtInSchemes: ColorScheme[] = \r\n [ oceanScheme, \r\n oceanDarkScheme, \r\n forestScheme,\r\n champagneScheme,\r\n graphiteScheme\r\n];\r\n\r\nexport const colorSchemes: Record<string, ColorScheme> = Object.fromEntries(\r\n builtInSchemes.map((s) => [s.name.toLowerCase(), s]),\r\n);\r\n\r\nexport function getColorScheme(name?: string): ColorScheme | undefined {\r\n if (!name) return undefined;\r\n return colorSchemes[name.toLowerCase()];\r\n}\r\n\r\nexport function listColorSchemes(): ColorScheme[] {\r\n return Object.values(colorSchemes);\r\n}\r\n\r\nexport function registerColorScheme(scheme: ColorScheme): void {\r\n colorSchemes[scheme.name.toLowerCase()] = scheme;\r\n}\r\n\r\nexport { oceanScheme, oceanDarkScheme, forestScheme, champagneScheme, graphiteScheme };\r\n","/**\r\n * Text-set types — three layers: registry → TextScheme → shared FontStyleEntry.\r\n *\r\n * Policy (user decision): one scheme uses ONE typeface for Chinese and\r\n * English alike. No sentence-level dual fonts, no OOXML a:ea rewrite.\r\n * `cjkFace` remains only as an optional bridge hint for diagrams (`fonts.cjk`);\r\n * when omitted, diagrams fall back to `face`.\r\n *\r\n * Compatibility: additive on Theme; existing fields unchanged.\r\n * Entries carry no color (ColorScheme owns color) and no text transform.\r\n */\r\n\r\n/** One font-style entry. `face` is the typeface used for all scripts. */\r\nexport interface FontStyleEntry {\r\n /** Typeface for this position (pptxgenjs `fontFace`) */\r\n face: string;\r\n /**\r\n * Optional CJK hint for diagram bridge (`theme.fonts.cjk`).\r\n * Omit for uniform schemes — bridge uses `face`.\r\n */\r\n cjkFace?: string;\r\n size: number;\r\n bold?: boolean;\r\n italic?: boolean;\r\n underline?: boolean;\r\n letterSpacing?: number;\r\n lineSpacing?: number;\r\n}\r\n\r\n/** Fixed position keys — every TextScheme must supply all six. */\r\nexport type TextSchemePositionKey =\r\n | 'coverTitle'\r\n | 'slideTitle'\r\n | 'body'\r\n | 'quote'\r\n | 'code'\r\n | 'small';\r\n\r\nexport const TEXT_SCHEME_POSITION_KEYS = [\r\n 'coverTitle',\r\n 'slideTitle',\r\n 'body',\r\n 'quote',\r\n 'code',\r\n 'small',\r\n] as const satisfies readonly TextSchemePositionKey[];\r\n\r\nexport type TextSchemePositions = Record<TextSchemePositionKey, FontStyleEntry>;\r\n\r\nexport interface TextScheme {\r\n name: string;\r\n /** Fixed six positions → FontStyleEntry (object references for sharing) */\r\n positions: TextSchemePositions;\r\n /** Documentation only */\r\n note?: string;\r\n}\r\n\r\nexport const DEFAULT_TEXT_SCHEME_NAME = 'system';\r\n\r\nexport const DEFAULT_UNIFORM_SIZES: Record<TextSchemePositionKey, number> = {\r\n coverTitle: 36,\r\n slideTitle: 28,\r\n body: 18,\r\n quote: 20,\r\n code: 14,\r\n small: 12,\r\n};\r\n\r\nexport interface UniformTextSchemeOptions {\r\n name: string;\r\n /** Single typeface for titles, body, quote, small (CN + EN) */\r\n face: string;\r\n /** Code face; defaults to Consolas */\r\n codeFace?: string;\r\n /** Reuse a shared code entry (object identity) instead of creating one */\r\n codeEntry?: FontStyleEntry;\r\n sizes?: Partial<Record<TextSchemePositionKey, number>>;\r\n /** Defaults: coverTitle + slideTitle bold */\r\n bold?: Partial<Record<TextSchemePositionKey, boolean>>;\r\n /** Defaults: quote italic */\r\n italic?: Partial<Record<TextSchemePositionKey, boolean>>;\r\n note?: string;\r\n}\r\n\r\n/**\r\n * Build a complete TextScheme from one typeface — the happy path for\r\n * adding a scheme: one file + one registry line.\r\n */\r\nexport function defineUniformTextScheme(options: UniformTextSchemeOptions): TextScheme {\r\n const sizes = { ...DEFAULT_UNIFORM_SIZES, ...options.sizes };\r\n const boldOn: Partial<Record<TextSchemePositionKey, boolean>> = {\r\n coverTitle: true,\r\n slideTitle: true,\r\n ...options.bold,\r\n };\r\n const italicOn: Partial<Record<TextSchemePositionKey, boolean>> = {\r\n quote: true,\r\n ...options.italic,\r\n };\r\n\r\n const make = (key: TextSchemePositionKey, face: string): FontStyleEntry => {\r\n const entry: FontStyleEntry = { face, size: sizes[key] };\r\n if (boldOn[key]) entry.bold = true;\r\n if (italicOn[key]) entry.italic = true;\r\n return entry;\r\n };\r\n\r\n return {\r\n name: options.name,\r\n note: options.note ?? `Uniform typeface: ${options.face}`,\r\n positions: {\r\n coverTitle: make('coverTitle', options.face),\r\n slideTitle: make('slideTitle', options.face),\r\n body: make('body', options.face),\r\n quote: make('quote', options.face),\r\n code:\r\n options.codeEntry ??\r\n make('code', options.codeFace ?? 'Consolas'),\r\n small: make('small', options.face),\r\n },\r\n };\r\n}\r\n","/**\r\n * Resolve a compact ColorScheme (ink/paper/primary/secondary) into ThemeColors.\r\n *\r\n * Compatibility: output uses only current ThemeColors fields. Renderer and\r\n * diagrams/theme.ts (isDarkTheme → colors.background) keep working unchanged.\r\n * background is always a bare hex without '#'.\r\n *\r\n * Role contract (author-facing, never swapped):\r\n * paper → colors.background\r\n * ink → colors.text\r\n *\r\n * `accent` is required on ThemeColors but is NOT a ColorScheme slot — it is\r\n * derived (primary mixed toward ink) so existing accent consumers keep working\r\n * while the authored palette stays at four colors.\r\n */\r\n\r\nimport type { ColorScheme } from '../models/color-scheme.js';\r\nimport { resolveSchemeMode } from '../models/color-scheme.js';\r\nimport type { ThemeColors } from '../models/theme.js';\r\nimport { mixHex } from '../utils/color-mix.js';\r\n\r\nexport function resolveColorScheme(scheme: ColorScheme): ThemeColors {\r\n const { primary, secondary, ink, paper } = scheme;\r\n // paper is always the page surface; dark only tunes derived surfaces\r\n const dark = resolveSchemeMode(scheme) === 'dark';\r\n\r\n const background = paper;\r\n const text = ink;\r\n\r\n // Emphasis stand-in for legacy accent consumers: deeper primary\r\n const accent = mixHex(primary, ink, 0.45);\r\n\r\n // Code block: light decks use a fixed white panel (matches github-light\r\n // shiki); dark decks keep a lifted dark panel so tokens stay readable.\r\n const codeBackground = dark ? mixHex(paper, ink, 0.35) : 'FFFFFF';\r\n const codeText = dark ? mixHex(ink, paper, 0.15) : ink;\r\n\r\n // Cover: primary-tinted surface + ink text\r\n const titleBackground = mixHex(paper, primary, 0.12);\r\n const titleText = ink;\r\n\r\n // Marked lines in code: lift from codeBackground toward primary\r\n const highlightBackground = mixHex(codeBackground, primary, 0.28);\r\n\r\n // Secondary body text: secondary mixed with reading ink\r\n const secondaryText = mixHex(secondary, ink, 0.25);\r\n\r\n return {\r\n primary,\r\n secondary: secondaryText,\r\n background,\r\n text,\r\n accent,\r\n codeBackground,\r\n codeText,\r\n titleBackground,\r\n titleText,\r\n highlightBackground,\r\n accents: [primary, secondary],\r\n subtitle: secondaryText,\r\n divider: mixHex(ink, paper, 0.45),\r\n muted: mixHex(ink, paper, 0.35),\r\n tableHeader: mixHex(paper, primary, 0.12),\r\n tableZebra: mixHex(paper, ink, 0.04),\r\n };\r\n}\r\n","import type { ThemeLayoutSpec } from '../../../models/theme.js';\r\n\r\n/** folio 封面:左侧书脊 + 左对齐 + 标题下短线 + 元信息沉底 */\r\nexport const titleLayout: ThemeLayoutSpec = {\r\n titleAlign: 'left',\r\n margin: 0.9,\r\n extra: {\r\n spineWidth: 0.2,\r\n marginLeft: 0.55,\r\n marginRight: 0.7,\r\n titleY: 2.35,\r\n subtitleY: 4.05,\r\n titleRule: true,\r\n titleRuleHeight: 0.035,\r\n titleRuleWidth: 3.6,\r\n titleRuleColor: 'primary',\r\n metaBottom: true,\r\n },\r\n};\r\n","import type { ThemeLayoutSpec } from '../../../models/theme.js';\r\n\r\n/**\r\n * folio 章节:无左/顶条;上下双横线构成「标题带」\r\n * 与 legacy 的左侧竖条章节页刻意区分\r\n */\r\nexport const sectionLayout: ThemeLayoutSpec = {\r\n accentBar: 'none',\r\n titleAlign: 'left',\r\n margin: 1.0,\r\n extra: {\r\n doubleRules: true,\r\n ruleWeight: 0.04,\r\n bandY: 2.55,\r\n bandH: 1.55,\r\n titleRuleColor: 'primary',\r\n marginLeft: 1.0,\r\n marginRight: 0.7,\r\n },\r\n};\r\n","import type { ThemeLayoutSpec } from '../../../models/theme.js';\r\n\r\n/**\r\n * folio 正文:左宽右窄的编辑页边距 + 标题下粗线(次级色)\r\n * 与 legacy 对称边距 + 细主线区分\r\n */\r\nexport const contentLayout: ThemeLayoutSpec = {\r\n titleAlign: 'left',\r\n margin: 0.55,\r\n titleHeight: 0.82,\r\n contentPadding: 0,\r\n extra: {\r\n marginLeft: 0.72,\r\n marginRight: 0.38,\r\n titleRule: true,\r\n titleRuleHeight: 0.07,\r\n titleRuleColor: 'secondary',\r\n },\r\n};\r\n","import type { ThemeLayoutSpec } from '../../../models/theme.js';\r\n\r\n/** folio 代码页:近满幅图版,标题区矮 + 标题下细线 */\r\nexport const codeLayout: ThemeLayoutSpec = {\r\n titleAlign: 'left',\r\n margin: 0.35,\r\n titleHeight: 0.55,\r\n extra: {\r\n marginLeft: 0.4,\r\n marginRight: 0.4,\r\n titleRule: true,\r\n titleRuleHeight: 0.025,\r\n titleRuleColor: 'secondary',\r\n },\r\n};\r\n","import type { ThemeLayoutSpec } from '../../../models/theme.js';\r\n\r\n/**\r\n * folio 引用:左侧粗竖条 pull-quote,无大引号,文案左对齐\r\n * 与 legacy「大引号 + 居中」区分\r\n */\r\nexport const quoteLayout: ThemeLayoutSpec = {\r\n titleAlign: 'left',\r\n accentBar: 'none',\r\n margin: 0.9,\r\n extra: {\r\n quoteMark: false,\r\n quoteBar: true,\r\n quoteBarWidth: 0.1,\r\n marginLeft: 0.9,\r\n marginRight: 0.7,\r\n attributionAlign: 'left',\r\n },\r\n};\r\n","import type { ThemeLayoutSpec } from '../../../models/theme.js';\r\n\r\n/** folio 结尾:Thank you 上下短线,与封面短横线呼应 */\r\nexport const closingLayout: ThemeLayoutSpec = {\r\n titleAlign: 'center',\r\n margin: 0.7,\r\n extra: {\r\n thankText: 'Thank you',\r\n titleRule: true,\r\n ruleWidth: 2.8,\r\n textY: 2.85,\r\n },\r\n};\r\n","import type { ThemeLayoutSpec } from '../../../models/theme.js';\r\n\r\nconst imageBase = {\r\n titleAlign: 'left' as const,\r\n margin: 0.55,\r\n titleHeight: 0.75,\r\n extra: {\r\n marginLeft: 0.72,\r\n marginRight: 0.38,\r\n titleRule: true,\r\n titleRuleHeight: 0.055,\r\n titleRuleColor: 'secondary' as const,\r\n },\r\n};\r\n\r\nexport const imageSingleLayout: ThemeLayoutSpec = { ...imageBase };\r\nexport const imageDoubleLayout: ThemeLayoutSpec = { ...imageBase };\r\nexport const imageTripleLayout: ThemeLayoutSpec = { ...imageBase };\r\n","import type { ThemeLayoutSpec } from '../../../models/theme.js';\r\n\r\n/** folio 页脚:分割线 + 居中(legacy 为右对齐、无分割线) */\r\nexport const footerLayout: ThemeLayoutSpec = {\r\n margin: 0.55,\r\n footerDivider: true,\r\n extra: {\r\n footerAlign: 'center',\r\n },\r\n};\r\n","import type { ThemeStyles } from '../../../models/theme.js';\r\n\r\n/** folio 装饰:章节走双线,不用左侧竖条宽度;页脚分割线开 */\r\nexport const folioLayoutStyles: ThemeStyles = {\r\n sectionBarWidth: 0.04,\r\n footerDivider: true,\r\n coverBadge: false,\r\n};\r\n","/**\r\n * folio LayoutScheme — 编辑册页风(创新版式,不仿 legacy)。\r\n *\r\n * 设计语言:杂志/技术报告册页\r\n * - 封面:左侧书脊色带 + 左对齐标题 + 标题下短横线 + 元信息沉底\r\n * - 章节:无侧边条;上下双横线夹住标题带\r\n * - 正文:不对称页边距(左宽右窄)+ 标题下粗线(次级色)\r\n * - 代码:近满幅「图版」式\r\n * - 引用:左侧竖条 pull-quote,无大引号,出处左对齐\r\n * - 页脚:分割线 + 居中\r\n * - 结尾:Thank you 上下短线\r\n * - 图文:与正文同款不对称边距\r\n */\r\n\r\nimport type { LayoutScheme } from '../../../models/layout-scheme.js';\r\nimport { titleLayout } from './title.js';\r\nimport { sectionLayout } from './section.js';\r\nimport { contentLayout } from './content.js';\r\nimport { codeLayout } from './code.js';\r\nimport { quoteLayout } from './quote.js';\r\nimport { closingLayout } from './closing.js';\r\nimport { imageSingleLayout, imageDoubleLayout, imageTripleLayout } from './images.js';\r\nimport { footerLayout } from './footer.js';\r\nimport { folioLayoutStyles } from './styles.js';\r\n\r\nexport const folioLayoutScheme: LayoutScheme = {\r\n name: 'folio',\r\n layouts: {\r\n title: titleLayout,\r\n section: sectionLayout,\r\n content: contentLayout,\r\n code: codeLayout,\r\n quote: quoteLayout,\r\n closing: closingLayout,\r\n imageSingle: imageSingleLayout,\r\n imageDouble: imageDoubleLayout,\r\n imageTriple: imageTripleLayout,\r\n footer: footerLayout,\r\n },\r\n styles: folioLayoutStyles,\r\n note: '编辑册页:书脊封面、双线章节、不对称正文、pull-quote、页脚居中。',\r\n};\r\n","import type { ThemeLayoutSpec } from '../../../models/theme.js';\r\n\r\n/** 旧版封面:居中,边距 0.8 */\r\nexport const titleLayout: ThemeLayoutSpec = {\r\n titleAlign: 'center',\r\n margin: 0.8,\r\n};\r\n","import type { ThemeLayoutSpec } from '../../../models/theme.js';\r\n\r\n/** 旧版章节页:左侧装饰条 0.15 + 标题左对齐 */\r\nexport const sectionLayout: ThemeLayoutSpec = {\r\n accentBar: 'left',\r\n titleAlign: 'left',\r\n margin: 1.0,\r\n};\r\n","import type { ThemeLayoutSpec } from '../../../models/theme.js';\r\n\r\n/** 旧版正文页:MARGIN=0.6、TITLE_H=0.9 */\r\nexport const contentLayout: ThemeLayoutSpec = {\r\n titleAlign: 'left',\r\n margin: 0.6,\r\n titleHeight: 0.9,\r\n contentPadding: 0,\r\n};\r\n","import type { ThemeLayoutSpec } from '../../../models/theme.js';\r\n\r\n/** 旧版代码页:边距 0.5、标题区约 0.7 */\r\nexport const codeLayout: ThemeLayoutSpec = {\r\n titleAlign: 'left',\r\n margin: 0.5,\r\n titleHeight: 0.7,\r\n};\r\n","import type { ThemeLayoutSpec } from '../../../models/theme.js';\r\n\r\n/** 旧版引用页:大引号 + 居中 */\r\nexport const quoteLayout: ThemeLayoutSpec = {\r\n titleAlign: 'center',\r\n accentBar: 'none',\r\n extra: {\r\n quoteMark: true,\r\n quoteMarkSize: 72,\r\n },\r\n};\r\n","import type { ThemeLayoutSpec } from '../../../models/theme.js';\r\n\r\n/** 旧版页脚:边距 0.6、无分割线 */\r\nexport const footerLayout: ThemeLayoutSpec = {\r\n margin: 0.6,\r\n footerDivider: false,\r\n};\r\n","import type { ThemeStyles } from '../../../models/theme.js';\r\n\r\n/** legacy 装饰开关:与改造前硬编码一致 */\r\nexport const legacyLayoutStyles: ThemeStyles = {\r\n sectionBarWidth: 0.15,\r\n footerDivider: false,\r\n coverBadge: false,\r\n};\r\n","/**\r\n * legacy LayoutScheme — 旧版版式(改造前写死在 layout 函数里的那套)。\r\n *\r\n * 仅覆盖旧有基础页:封面 / 章节 / 正文 / 代码 / 引用 + 页脚。\r\n * 不含结尾页、图文页——使用本方案时,新页型走 layout 函数内硬编码默认。\r\n */\r\n\r\nimport type { LayoutScheme } from '../../../models/layout-scheme.js';\r\nimport { titleLayout } from './title.js';\r\nimport { sectionLayout } from './section.js';\r\nimport { contentLayout } from './content.js';\r\nimport { codeLayout } from './code.js';\r\nimport { quoteLayout } from './quote.js';\r\nimport { footerLayout } from './footer.js';\r\nimport { legacyLayoutStyles } from './styles.js';\r\n\r\nexport const legacyLayoutScheme: LayoutScheme = {\r\n name: 'legacy',\r\n layouts: {\r\n title: titleLayout,\r\n section: sectionLayout,\r\n content: contentLayout,\r\n code: codeLayout,\r\n quote: quoteLayout,\r\n footer: footerLayout,\r\n },\r\n styles: legacyLayoutStyles,\r\n note: '旧版版式:现网五种基础页 + 页脚;无结尾/图文条目。',\r\n};\r\n","import type { ThemeLayoutSpec } from '../../../models/theme.js';\r\n\r\n/**\r\n * golden 封面:右对齐 + 大量留白 + 标题下黄金分割横线。\r\n * 主标题/副标题右上方,横线下方排作者与日期。\r\n * 横线长 8.22 ≈ 页宽 × 0.618;横线 y=4.64 将页高分为 1.618:1。\r\n */\r\nexport const titleLayout: ThemeLayoutSpec = {\r\n titleAlign: 'right',\r\n margin: 0.83,\r\n extra: {\r\n marginLeft: 6.94,\r\n marginRight: 0.83,\r\n titleY: 3.0,\r\n subtitleY: 4.0,\r\n titleRule: true,\r\n titleRuleHeight: 0.04,\r\n titleRuleWidth: 8.22,\r\n titleRuleY: 4.64,\r\n titleRuleColor: 'primary',\r\n metaBottom: true,\r\n metaY: 5.0,\r\n },\r\n};\r\n","import type { ThemeLayoutSpec } from '../../../models/theme.js';\r\n\r\n/**\r\n * golden 章节:延续封面语言——序号与标题右对齐、左侧留白,\r\n * 标题下方同一条黄金分割横线。与内容页明显区分。\r\n */\r\nexport const sectionLayout: ThemeLayoutSpec = {\r\n accentBar: 'none',\r\n titleAlign: 'right',\r\n margin: 0.83,\r\n extra: {\r\n marginLeft: 6.67,\r\n marginRight: 0.83,\r\n // 章节序号占位(node.subtitle)+ 标题\r\n subtitleY: 3.03,\r\n subtitleH: 0.36,\r\n titleY: 3.5,\r\n titleH: 0.89,\r\n // 黄金分割横线\r\n sectionRule: true,\r\n sectionRuleY: 4.64,\r\n sectionRuleWidth: 8.22,\r\n sectionRuleHeight: 0.04,\r\n sectionRuleColor: 'primary',\r\n },\r\n};\r\n","import type { ThemeLayoutSpec } from '../../../models/theme.js';\r\n\r\n/**\r\n * golden 正文:页标题左上,标题下一条短装饰线(左缘对齐),\r\n * 底部页脚分割线 + 左文案右页码(由 layouts/index.ts 统一渲染)。\r\n */\r\nexport const contentLayout: ThemeLayoutSpec = {\r\n titleAlign: 'left',\r\n margin: 1.11,\r\n titleHeight: 1.3,\r\n contentPadding: 0,\r\n extra: {\r\n marginLeft: 1.11,\r\n marginRight: 1.11,\r\n titleY: 0.72,\r\n titleRule: true,\r\n titleRuleWidth: 0.89,\r\n titleRuleHeight: 0.04,\r\n titleRuleColor: 'primary',\r\n },\r\n};\r\n","import type { ThemeLayoutSpec } from '../../../models/theme.js';\r\n\r\n/**\r\n * golden 代码页:与正文共用骨架(页标题左对齐 + 短装饰线)。\r\n * 内容区替换为独立圆角代码容器,圆角由 styles.codeRadius 控制。\r\n */\r\nexport const codeLayout: ThemeLayoutSpec = {\r\n titleAlign: 'left',\r\n margin: 1.11,\r\n titleHeight: 0.6,\r\n extra: {\r\n marginLeft: 1.11,\r\n marginRight: 1.11,\r\n titleY: 0.72,\r\n titleRule: true,\r\n titleRuleWidth: 0.89,\r\n titleRuleHeight: 0.04,\r\n titleRuleColor: 'primary',\r\n },\r\n};\r\n","import type { ThemeLayoutSpec } from '../../../models/theme.js';\r\n\r\n/**\r\n * golden 引用:视觉安静——引用文本居中、上下大留白,\r\n * 文本上方一条居中短横线呼应横线语言,无大引号、无左竖条。\r\n */\r\nexport const quoteLayout: ThemeLayoutSpec = {\r\n titleAlign: 'center',\r\n accentBar: 'none',\r\n margin: 2.22,\r\n extra: {\r\n quoteMark: false,\r\n quoteBar: false,\r\n marginLeft: 2.22,\r\n marginRight: 2.22,\r\n quoteRule: true,\r\n quoteRuleY: 2.19,\r\n quoteRuleWidth: 1.33,\r\n quoteRuleHeight: 0.04,\r\n quoteRuleColor: 'primary',\r\n textY: 2.58,\r\n textH: 1.94,\r\n attributionAlign: 'center',\r\n },\r\n};\r\n","import type { ThemeLayoutSpec } from '../../../models/theme.js';\r\n\r\n/**\r\n * golden 结尾:与封面同构——右对齐致谢语、黄金分割横线、横线下联系方式区。\r\n * 单线模式(横线在致谢语下方),右对齐贴右侧缘。\r\n */\r\nexport const closingLayout: ThemeLayoutSpec = {\r\n titleAlign: 'right',\r\n margin: 0.83,\r\n extra: {\r\n thankText: 'Thank you',\r\n marginLeft: 5.83,\r\n marginRight: 0.83,\r\n textY: 3.22,\r\n titleRule: true,\r\n closingRule: 'below',\r\n ruleWidth: 8.22,\r\n ruleHeight: 0.04,\r\n ruleY: 4.64,\r\n },\r\n};\r\n","import type { ThemeLayoutSpec } from '../../../models/theme.js';\r\n\r\n/**\r\n * golden 图文页:与正文共用骨架(页标题左对齐 + 短装饰线 + 页脚)。\r\n * 单图/双图/三图除占位框数量外几何参数一致。\r\n */\r\nconst imageBase = {\r\n titleAlign: 'left' as const,\r\n margin: 1.11,\r\n titleHeight: 1.3,\r\n extra: {\r\n marginLeft: 1.11,\r\n marginRight: 1.11,\r\n titleY: 0.72,\r\n titleRule: true,\r\n titleRuleWidth: 0.89,\r\n titleRuleHeight: 0.04,\r\n titleRuleColor: 'primary' as const,\r\n },\r\n};\r\n\r\nexport const imageSingleLayout: ThemeLayoutSpec = { ...imageBase };\r\nexport const imageDoubleLayout: ThemeLayoutSpec = { ...imageBase };\r\nexport const imageTripleLayout: ThemeLayoutSpec = { ...imageBase };\r\n","import type { ThemeLayoutSpec } from '../../../models/theme.js';\r\n\r\n/**\r\n * golden 页脚:分割线 + 左文案右页码(页码右缘对齐分割线右缘 x=12.22)。\r\n */\r\nexport const footerLayout: ThemeLayoutSpec = {\r\n margin: 1.11,\r\n footerDivider: true,\r\n extra: {\r\n footerAlign: 'left',\r\n marginLeft: 1.11,\r\n marginRight: 1.11,\r\n },\r\n};\r\n","import type { ThemeStyles } from '../../../models/theme.js';\r\n\r\n/**\r\n * golden 装饰:代码容器圆角 0.22 英寸(≈16pt);页脚分割线开;无封面角标。\r\n */\r\nexport const goldenLayoutStyles: ThemeStyles = {\r\n sectionBarWidth: 0.04,\r\n footerDivider: true,\r\n coverBadge: false,\r\n codeRadius: 16,\r\n};\r\n","/**\r\n * golden LayoutScheme — 黄金比例版式。\r\n *\r\n * 设计语言:右对齐 + 留白 + 黄金分割横线\r\n * - 封面:右上方标题,标题下一条黄金横线,横线下作者与日期\r\n * - 章节:序号与标题右对齐,标题下同一条黄金横线\r\n * - 正文:左对齐标题 + 短装饰线,内容区满幅,底部页脚\r\n * - 代码:与正文同骨架,内容区替换为圆角代码容器\r\n * - 引用:居中极简,文本上方一条居中短横线\r\n * - 结尾:右对齐致谢语 + 黄金横线 + 联系方式\r\n * - 图文:与正文同款骨架\r\n *\r\n * 黄金分割取值:页面 13.33 × 7.50,\r\n * 横线长 8.22 ≈ W × 0.618,横线 y=4.64 将页高分为 1.618:1。\r\n */\r\n\r\nimport type { LayoutScheme } from '../../../models/layout-scheme.js';\r\nimport { titleLayout } from './title.js';\r\nimport { sectionLayout } from './section.js';\r\nimport { contentLayout } from './content.js';\r\nimport { codeLayout } from './code.js';\r\nimport { quoteLayout } from './quote.js';\r\nimport { closingLayout } from './closing.js';\r\nimport { imageSingleLayout, imageDoubleLayout, imageTripleLayout } from './images.js';\r\nimport { footerLayout } from './footer.js';\r\nimport { goldenLayoutStyles } from './styles.js';\r\n\r\nexport const goldenLayoutScheme: LayoutScheme = {\r\n name: 'golden',\r\n layouts: {\r\n title: titleLayout,\r\n section: sectionLayout,\r\n content: contentLayout,\r\n code: codeLayout,\r\n quote: quoteLayout,\r\n closing: closingLayout,\r\n imageSingle: imageSingleLayout,\r\n imageDouble: imageDoubleLayout,\r\n imageTriple: imageTripleLayout,\r\n footer: footerLayout,\r\n },\r\n styles: goldenLayoutStyles,\r\n note: '黄金比例:右对齐留白封面/章节/结尾 + 黄金分割横线,正文/代码/引用/图文共用骨架语言。',\r\n};\r\n","import type { ThemeLayoutSpec } from '../../../models/theme.js';\r\n\r\n/**\r\n * minimal 封面:左侧竖装饰线作视觉锚点,主/副标题沿竖线右缘左对齐,\r\n * 作者与日期沉底。整页留白充足,视觉重心偏左上。\r\n */\r\nexport const titleLayout: ThemeLayoutSpec = {\r\n titleAlign: 'left',\r\n margin: 0.83,\r\n extra: {\r\n minimalTitle: true,\r\n minimalLineX: 0.83,\r\n minimalLineY1: 2.64,\r\n minimalLineH: 1.94,\r\n minimalLineW: 0.04,\r\n minimalBoxX: 1.11,\r\n minimalBoxW: 8.89,\r\n minimalTitleY: 2.64,\r\n minimalSubtitleY: 3.64,\r\n minimalAuthorY: 5.28,\r\n minimalDateY: 5.64,\r\n minimalMetaW: 4.17,\r\n },\r\n};\r\n","import type { ThemeLayoutSpec } from '../../../models/theme.js';\r\n\r\n/**\r\n * minimal 章节页:左侧超大章节序号 + 竖分隔线 + 章节标题 的横排布局。\r\n * 章节序号由通用计数功能自动递增(从 01 开始),footer 关(`footer: 'off'`)。\r\n */\r\nexport const sectionLayout: ThemeLayoutSpec = {\r\n titleAlign: 'left',\r\n margin: 0.83,\r\n extra: {\r\n minimalNumber: true,\r\n footer: 'off',\r\n minimalNumberX: 1.11,\r\n minimalNumberY: 2.43,\r\n minimalNumberW: 2.5,\r\n minimalNumberH: 1.53,\r\n minimalRuleX: 3.89,\r\n minimalRuleY1: 2.71,\r\n minimalRuleW: 0.03,\r\n minimalRuleH: 1.11,\r\n minimalTitleX: 4.31,\r\n minimalTitleY: 2.71,\r\n minimalTitleW: 6.94,\r\n minimalTitleH: 0.69,\r\n },\r\n};\r\n","import type { ThemeLayoutSpec } from '../../../models/theme.js';\r\n\r\n/**\r\n * minimal 正文页:页标题 + 标题下短横线(非贯穿)+ 带边框内容容器。\r\n * 内容区起始 y=1.33、底部收于 y=6.61(高 5.28),页脚统一置于下方。\r\n */\r\nexport const contentLayout: ThemeLayoutSpec = {\r\n titleAlign: 'left',\r\n margin: 0.83,\r\n titleHeight: 0.44,\r\n extra: {\r\n minimalBox: true,\r\n minimalBoxX: 0.83,\r\n minimalBoxY: 1.33,\r\n minimalBoxW: 11.67,\r\n minimalBoxH: 5.28,\r\n minimalTitleY: 0.5,\r\n minimalTitleRuleY: 1.03,\r\n minimalTitleRuleW: 0.56,\r\n minimalTitleRuleH: 0.03,\r\n },\r\n};\r\n","import type { ThemeLayoutSpec } from '../../../models/theme.js';\r\n\r\n/**\r\n * minimal 代码页:页标题与正文一致;标题下方为独立圆角代码卡片,\r\n * 以圆角边框暗示此处为等宽字体代码文本。\r\n */\r\nexport const codeLayout: ThemeLayoutSpec = {\r\n titleAlign: 'left',\r\n margin: 0.83,\r\n extra: {\r\n minimalCard: true,\r\n minimalCardX: 0.83,\r\n minimalCardY: 1.33,\r\n minimalCardW: 11.67,\r\n minimalCardH: 5.28,\r\n minimalCardRadius: 0.08,\r\n minimalTitleY: 0.5,\r\n minimalTitleRuleY: 1.03,\r\n minimalTitleRuleW: 0.56,\r\n minimalTitleRuleH: 0.03,\r\n },\r\n};\r\n","import type { ThemeLayoutSpec } from '../../../models/theme.js';\r\n\r\n/**\r\n * minimal 引用页:左侧竖引用标记 + 引用文案沿竖线左对齐;文字较大留白充足,\r\n * 与内容页「标题+容器」结构明显区分,自带页脚。\r\n */\r\nexport const quoteLayout: ThemeLayoutSpec = {\r\n titleAlign: 'left',\r\n margin: 0.83,\r\n extra: {\r\n minimalQuote: true,\r\n minimalRuleX: 1.67,\r\n minimalRuleY: 2.78,\r\n minimalRuleH: 1.39,\r\n minimalRuleW: 0.04,\r\n minimalTextX: 2.08,\r\n minimalTextW: 9.58,\r\n minimalTextH: 1.39,\r\n },\r\n};\r\n","import type { ThemeLayoutSpec } from '../../../models/theme.js';\r\n\r\n/**\r\n * minimal 结尾页:上方短装饰横线(居中)+ 致谢语(居中)+ 联系方式(居中),\r\n * 整页居中对称、不带页脚,与封面页首尾呼应。\r\n */\r\nexport const closingLayout: ThemeLayoutSpec = {\r\n titleAlign: 'center',\r\n margin: 0.83,\r\n extra: {\r\n minimalClosing: true,\r\n thankText: 'Thank you',\r\n minimalRuleW: 1.11,\r\n minimalRuleH: 0.03,\r\n minimalRuleY: 2.78,\r\n minimalThankX: 2.5,\r\n minimalThankY: 3.06,\r\n minimalThankW: 8.33,\r\n minimalContactX: 3.89,\r\n minimalContactY: 4.31,\r\n minimalContactW: 5.56,\r\n },\r\n};\r\n","import type { ThemeLayoutSpec } from '../../../models/theme.js';\r\n\r\nconst imageBase = {\r\n titleAlign: 'left' as const,\r\n margin: 0.83,\r\n extra: {\r\n minimalImage: true,\r\n minimalImageY: 1.33,\r\n minimalImageH: 5.28,\r\n minimalTitleY: 0.5,\r\n minimalTitleRuleY: 1.03,\r\n minimalTitleRuleW: 0.56,\r\n minimalTitleRuleH: 0.03,\r\n },\r\n};\r\n\r\n/** minimal 单图:占满内容区宽度的虚线占位框 + 页脚 */\r\nexport const imageSingleLayout: ThemeLayoutSpec = { ...imageBase };\r\n/** minimal 双图:两个等宽虚线占位框左右并排(间距 0.28) */\r\nexport const imageDoubleLayout: ThemeLayoutSpec = { ...imageBase };\r\n/** minimal 三图:三个等宽虚线占位框横排(间距 0.21) */\r\nexport const imageTripleLayout: ThemeLayoutSpec = { ...imageBase };\r\n","import type { ThemeLayoutSpec } from '../../../models/theme.js';\r\n\r\n/** minimal 页脚:分割线 + 文案/页码,几何沿用方案统一坐标(线 y=6.94,文 y=7.03)。 */\r\nexport const footerLayout: ThemeLayoutSpec = {\r\n margin: 0.83,\r\n footerDivider: true,\r\n extra: {\r\n footerAlign: 'left',\r\n dividerY: 6.94,\r\n footerY: 7.03,\r\n },\r\n};\r\n","import type { ThemeStyles } from '../../../models/theme.js';\r\n\r\n/** minimal 装饰开关:页脚带分割线,封面无角标。 */\r\nexport const minimalLayoutStyles: ThemeStyles = {\r\n footerDivider: true,\r\n coverBadge: false,\r\n};\r\n","/**\r\n * minimal LayoutScheme — 极简档案风(第四套版式方案)。\r\n *\r\n * 设计语言:统一几何 + 线性装饰 + 清晰分层\r\n * - 封面:左侧竖装饰线 + 左对齐标题堆叠 + 作者/日期沉底\r\n * - 章节:超大章节序号(01 自动递增)+ 竖分隔线 + 标题\r\n * - 正文:标题 + 标题下短横线(非贯穿)+ 带边框内容容器\r\n * - 代码:标题 + 短横线 + 独立圆角代码卡片\r\n * - 引用:左侧竖引用标记 + 左对齐引用文字\r\n * - 结尾:上方短横线(居中)+ 致谢语 + 联系方式,无页脚\r\n * - 图文:标题 + 短横线 + 虚线图片占位框\r\n * - 页脚:分割线 + 文案/页码,几何 y=6.94/7.03 全局统一\r\n *\r\n * 全部页面统一左右边距 0.83 英寸,装饰仅用「短横线 / 竖线」两类线性装饰。\r\n */\r\n\r\nimport type { LayoutScheme } from '../../../models/layout-scheme.js';\r\nimport { titleLayout } from './title.js';\r\nimport { sectionLayout } from './section.js';\r\nimport { contentLayout } from './content.js';\r\nimport { codeLayout } from './code.js';\r\nimport { quoteLayout } from './quote.js';\r\nimport { closingLayout } from './closing.js';\r\nimport { imageSingleLayout, imageDoubleLayout, imageTripleLayout } from './images.js';\r\nimport { footerLayout } from './footer.js';\r\nimport { minimalLayoutStyles } from './styles.js';\r\n\r\nexport const minimalLayoutScheme: LayoutScheme = {\r\n name: 'minimal',\r\n layouts: {\r\n title: titleLayout,\r\n section: sectionLayout,\r\n content: contentLayout,\r\n code: codeLayout,\r\n quote: quoteLayout,\r\n closing: closingLayout,\r\n imageSingle: imageSingleLayout,\r\n imageDouble: imageDoubleLayout,\r\n imageTriple: imageTripleLayout,\r\n footer: footerLayout,\r\n },\r\n styles: minimalLayoutStyles,\r\n note: '极简档案:统一0.83边距、横/竖线性装饰、超大章序号、圆角代码卡片、虚线图片占位。',\r\n};\r\n","/**\r\n * Built-in LayoutScheme registry — 主题体系中的版式集。\r\n *\r\n * 数据流与色彩集 / 文字集相同:\r\n * layout-schemes/<name>/ → getTheme(..., { layoutScheme }) → Theme.layouts/styles\r\n *\r\n * 一套版式方案 = 一个文件夹。内置:\r\n * - legacy:旧版(改造前写死摆法)\r\n * - folio:编辑册页(创新版式,不仿 legacy)\r\n * - golden:黄金比例(右对齐留白 + 黄金分割横线)\r\n * - minimal:极简档案(统一 0.83 边距 + 线性装饰 + 超大章序号)\r\n *\r\n * `test/layout-schemes-folder.test.ts`:文件夹 ↔ 注册表一致性。\r\n */\r\n\r\nimport type { LayoutScheme } from '../../models/layout-scheme.js';\r\nimport { folioLayoutScheme } from './folio/index.js';\r\nimport { legacyLayoutScheme } from './legacy/index.js';\r\nimport { goldenLayoutScheme } from './golden/index.js';\r\nimport { minimalLayoutScheme } from './minimal/index.js';\r\n\r\n/** All built-in schemes. Keep in sync with scheme folders in this directory. */\r\nconst builtInLayoutSchemes: LayoutScheme[] = [\r\n folioLayoutScheme,\r\n legacyLayoutScheme,\r\n goldenLayoutScheme,\r\n minimalLayoutScheme,\r\n];\r\n\r\nexport const layoutSchemes: Record<string, LayoutScheme> = Object.fromEntries(\r\n builtInLayoutSchemes.map((s) => [s.name.toLowerCase(), s]),\r\n);\r\n\r\nexport function getLayoutScheme(name?: string): LayoutScheme | undefined {\r\n if (!name) return undefined;\r\n return layoutSchemes[name.toLowerCase()];\r\n}\r\n\r\nexport function listLayoutSchemes(): LayoutScheme[] {\r\n return Object.values(layoutSchemes);\r\n}\r\n\r\nexport function registerLayoutScheme(scheme: LayoutScheme): void {\r\n layoutSchemes[scheme.name.toLowerCase()] = scheme;\r\n}\r\n\r\nexport {\r\n folioLayoutScheme,\r\n legacyLayoutScheme,\r\n goldenLayoutScheme,\r\n minimalLayoutScheme,\r\n};\r\n","import type { ThemePreset } from '../../models/theme-preset.js';\r\n\r\n/** blue:ocean + academic + legacy */\r\nexport const bluePreset: ThemePreset = {\r\n name: 'blue',\r\n colorScheme: 'ocean',\r\n textScheme: 'academic',\r\n layoutScheme: 'legacy',\r\n};\r\n","import type { ThemePreset } from '../../models/theme-preset.js';\r\n\r\n/** emerald:forest + system + folio */\r\nexport const emeraldPreset: ThemePreset = {\r\n name: 'emerald',\r\n colorScheme: 'forest',\r\n textScheme: 'system',\r\n layoutScheme: 'folio',\r\n};\r\n","import type { ThemePreset } from '../../models/theme-preset.js';\r\n\r\n/** gold:champagne + kai + golden */\r\nexport const goldPreset: ThemePreset = {\r\n name: 'gold',\r\n colorScheme: 'champagne',\r\n textScheme: 'kai',\r\n layoutScheme: 'golden',\r\n};\r\n","import type { ThemePreset } from '../../models/theme-preset.js';\r\n\r\n/** slate:graphite + source-han-serif + minimal */\r\nexport const slatePreset: ThemePreset = {\r\n name: 'slate',\r\n colorScheme: 'graphite',\r\n textScheme: 'source-han-serif',\r\n layoutScheme: 'minimal',\r\n};\r\n","/**\r\n * Built-in ThemePreset registry — 主题预设(色彩 × 文字 × 版式 组合包)。\r\n *\r\n * 数据流:\r\n * presets/<name>.ts → getTheme(..., { preset }) / convert(..., { preset }) → Theme\r\n *\r\n * 契约(第 5 步拍板):\r\n * - `-t` / frontmatter `theme:` 仍只表示 ColorScheme 名\r\n * - 预设走独立入口 `preset` / `--preset`;不传 = 现网行为(不自动套默认预设)\r\n * - 显式 textScheme / layoutScheme / theme 覆盖预设对应槽位\r\n *\r\n * 内置 4 套预设(色彩 × 文字 × 版式,各集不重复按顺序组合):\r\n * - blue = ocean + academic + legacy\r\n * - emerald = forest + system + folio\r\n * - gold = champagne + kai + golden\r\n * - slate = graphite + source-han-serif + minimal\r\n * (ocean-dark 为 ocean 的反色,与 ocean 共用文字/版式,不单列)\r\n */\r\n\r\nimport type { ThemePreset } from '../../models/theme-preset.js';\r\nimport { bluePreset } from './blue.js';\r\nimport { emeraldPreset } from './emerald.js';\r\nimport { goldPreset } from './gold.js';\r\nimport { slatePreset } from './slate.js';\r\n\r\n/** All built-in presets. Keep in sync with *.ts files in this directory. */\r\nconst builtInThemePresets: ThemePreset[] = [\r\n bluePreset,\r\n emeraldPreset,\r\n goldPreset,\r\n slatePreset,\r\n];\r\n\r\nexport const themePresets: Record<string, ThemePreset> = Object.fromEntries(\r\n builtInThemePresets.map((p) => [p.name.toLowerCase(), p]),\r\n);\r\n\r\nexport function getThemePreset(name?: string): ThemePreset | undefined {\r\n if (!name) return undefined;\r\n return themePresets[name.toLowerCase()];\r\n}\r\n\r\nexport function listThemePresets(): ThemePreset[] {\r\n return Object.values(themePresets);\r\n}\r\n\r\nexport function registerThemePreset(preset: ThemePreset): void {\r\n themePresets[preset.name.toLowerCase()] = preset;\r\n}\r\n\r\nexport function themePresetNames(): string[] {\r\n return listThemePresets().map((p) => p.name);\r\n}\r\n\r\nexport function hasThemePreset(name?: string): boolean {\r\n return Boolean(name && getThemePreset(name));\r\n}\r\n\r\nexport {\r\n bluePreset,\r\n emeraldPreset,\r\n goldPreset,\r\n slatePreset,\r\n};\r\n","/**\r\n * Shared FontStyleEntry pool — optional reuse across TextSchemes.\r\n * Prefer `defineUniformTextScheme` for new schemes; use this pool only\r\n * when several schemes must share the exact same entry object (e.g. code).\r\n */\r\n\r\nimport type { FontStyleEntry } from '../models/text-set.js';\r\n\r\n/** Shared mono code entry — reference via `codeEntry` when defining schemes. */\r\nexport const sharedCode: FontStyleEntry = {\r\n face: 'Consolas',\r\n cjkFace: 'Consolas',\r\n size: 14,\r\n};\r\n","/**\r\n * academic TextScheme — uniform typeface: 宋体.\r\n * Titles sized up for the `blue` theme package (user request).\r\n */\r\n\r\nimport { defineUniformTextScheme } from '../../models/text-set.js';\r\nimport { sharedCode } from '../text-entries.js';\r\n\r\nexport const academicTextScheme = defineUniformTextScheme({\r\n name: 'academic',\r\n face: '宋体',\r\n codeEntry: sharedCode,\r\n sizes: {\r\n coverTitle: 42,\r\n slideTitle: 32,\r\n },\r\n note: '学术:正文/标题统一宋体,代码 Consolas;标题加大(封面 42 / 页标题 32)。',\r\n});\r\n","/**\r\n * system TextScheme — default. Uniform typeface: 微软雅黑.\r\n * code 位置使用共享 Consolas 条目。\r\n */\r\n\r\nimport { defineUniformTextScheme } from '../../models/text-set.js';\r\nimport { sharedCode } from '../text-entries.js';\r\n\r\nexport const systemTextScheme = defineUniformTextScheme({\r\n name: 'system',\r\n face: '微软雅黑',\r\n codeEntry: sharedCode,\r\n note: '系统默认:正文/标题统一微软雅黑,代码 Consolas。',\r\n});\r\n","/**\r\n * kai TextScheme — uniform typeface: KaiTi(楷体).\r\n */\r\n\r\nimport { defineUniformTextScheme } from '../../models/text-set.js';\r\nimport { sharedCode } from '../text-entries.js';\r\n\r\nexport const kaiTextScheme = defineUniformTextScheme({\r\n name: 'kai',\r\n face: 'KaiTi',\r\n codeEntry: sharedCode,\r\n note: '楷体:正文/标题统一 KaiTi,代码 Consolas。',\r\n});\r\n","/**\r\n * source-han-serif TextScheme — uniform typeface: 思源宋体.\r\n * 本机安装名也可能是 Source Han Serif SC / Noto Serif CJK SC,不一致时改 face。\r\n */\r\n\r\nimport { defineUniformTextScheme } from '../../models/text-set.js';\r\nimport { sharedCode } from '../text-entries.js';\r\n\r\nexport const sourceHanSerifTextScheme = defineUniformTextScheme({\r\n name: 'source-han-serif',\r\n face: '思源宋体',\r\n codeEntry: sharedCode,\r\n note: '思源宋体:正文/标题统一思源宋体,代码 Consolas。',\r\n});\r\n","/**\r\n * Built-in TextScheme registry.\r\n *\r\n * Add a scheme (two steps):\r\n * 1. create `text-schemes/<name>.ts` exporting a TextScheme\r\n * (usually via `defineUniformTextScheme({ name, face, codeEntry: sharedCode })`)\r\n * 2. import it below and append to `builtInTextSchemes`\r\n *\r\n * `test/text-schemes-folder.test.ts` fails if a scheme file is not registered.\r\n */\r\n\r\nimport {\r\n DEFAULT_TEXT_SCHEME_NAME,\r\n type TextScheme,\r\n} from '../../models/text-set.js';\r\nimport { academicTextScheme } from './academic.js';\r\nimport { systemTextScheme } from './system.js';\r\nimport { kaiTextScheme } from './kai.js';\r\nimport { sourceHanSerifTextScheme } from './source-han-serif.js';\r\n\r\n/** All built-in schemes. Keep in sync with *.ts files in this folder. */\r\nconst builtInTextSchemes: TextScheme[] = [\r\n systemTextScheme,\r\n academicTextScheme,\r\n kaiTextScheme,\r\n sourceHanSerifTextScheme,\r\n];\r\n\r\nexport const textSchemes: Record<string, TextScheme> = Object.fromEntries(\r\n builtInTextSchemes.map((s) => [s.name.toLowerCase(), s]),\r\n);\r\n\r\nexport function getTextScheme(name?: string): TextScheme | undefined {\r\n if (!name) return undefined;\r\n return textSchemes[name.toLowerCase()];\r\n}\r\n\r\nexport function listTextSchemes(): TextScheme[] {\r\n return Object.values(textSchemes);\r\n}\r\n\r\nexport function registerTextScheme(scheme: TextScheme): void {\r\n textSchemes[scheme.name.toLowerCase()] = scheme;\r\n}\r\n\r\nexport {\r\n systemTextScheme,\r\n academicTextScheme,\r\n kaiTextScheme,\r\n sourceHanSerifTextScheme,\r\n DEFAULT_TEXT_SCHEME_NAME,\r\n};\r\n","/**\r\n * Build a full Theme from a ColorScheme (+ optional font / text-set overrides).\r\n *\r\n * Text-set layer is the only font source: `textScheme` (default `system`)\r\n * bridges into Theme.fonts / Theme.fontSize. Explicit `options.fonts` /\r\n * `options.fontSize` still win when provided.\r\n *\r\n * The legacy `font-sets/` folder has been removed; do not reintroduce it.\r\n */\r\n\r\nimport type { ColorScheme } from '../models/color-scheme.js';\r\nimport { resolveSchemeMode } from '../models/color-scheme.js';\r\nimport { getColorScheme } from './color-schemes/index.js';\r\nimport type { LayoutScheme } from '../models/layout-scheme.js';\r\nimport type { Theme, ThemeFonts, ThemeFontSizes, ThemeLayouts, ThemeStyles } from '../models/theme.js';\r\nimport type { ThemePreset } from '../models/theme-preset.js';\r\nimport {\r\n DEFAULT_TEXT_SCHEME_NAME,\r\n type FontStyleEntry,\r\n type TextScheme,\r\n type TextSchemePositionKey,\r\n} from '../models/text-set.js';\r\nimport { resolveColorScheme } from './resolve-scheme.js';\r\nimport { getLayoutScheme } from './layout-schemes/index.js';\r\nimport { getThemePreset } from './presets/index.js';\r\nimport { getTextScheme } from './text-schemes/text-index.js';\r\n\r\nexport interface ThemeFromSchemeOptions {\r\n fonts?: ThemeFonts;\r\n fontSize?: ThemeFontSizes;\r\n shikiTheme?: string;\r\n layouts?: Theme['layouts'];\r\n styles?: Theme['styles'];\r\n typography?: Theme['typography'];\r\n avoid?: string[];\r\n /** Color scheme name or object; defaults to the `scheme` argument */\r\n colorScheme?: string | ColorScheme;\r\n /** Text scheme name or object; defaults to `system` */\r\n textScheme?: string | TextScheme;\r\n /** Layout scheme name or object; omitted → layouts/styles stay unset (legacy) */\r\n layoutScheme?: string | LayoutScheme;\r\n /** ThemePreset name for provenance (`theme.presetSet`); does not drive slots here */\r\n presetSet?: string;\r\n}\r\n\r\n/** Resolve preset option → object; unknown name warns and returns undefined. */\r\nexport function resolveThemePresetOption(\r\n input?: string | ThemePreset,\r\n): ThemePreset | undefined {\r\n if (input === undefined || input === null) return undefined;\r\n if (typeof input === 'object') return input;\r\n const name = input.trim();\r\n if (!name) return undefined;\r\n const preset = getThemePreset(name);\r\n if (!preset) {\r\n console.warn(`Theme preset \"${name}\" not found; using scheme defaults only`);\r\n return undefined;\r\n }\r\n return preset;\r\n}\r\n\r\nexport function resolveColorSchemeOption(\r\n input?: string | ColorScheme,\r\n): ColorScheme | undefined {\r\n if (input && typeof input === 'object') return input;\r\n if (typeof input !== 'string' || !input.trim()) return undefined;\r\n const name = input.trim();\r\n const scheme = getColorScheme(name);\r\n if (!scheme) {\r\n console.warn(`Color scheme \"${name}\" not found`);\r\n return undefined;\r\n }\r\n return scheme;\r\n}\r\n\r\nexport function resolveTextSchemeOption(\r\n input?: string | TextScheme,\r\n): TextScheme {\r\n if (input && typeof input === 'object') return input;\r\n const name =\r\n typeof input === 'string' && input.trim() ? input.trim() : DEFAULT_TEXT_SCHEME_NAME;\r\n const scheme = getTextScheme(name);\r\n if (!scheme) {\r\n if (typeof input === 'string' && input.trim()) {\r\n console.warn(`Text scheme \"${name}\" not found, using \"${DEFAULT_TEXT_SCHEME_NAME}\"`);\r\n }\r\n const fallback = getTextScheme(DEFAULT_TEXT_SCHEME_NAME);\r\n if (!fallback) {\r\n throw new Error(`Default text scheme \"${DEFAULT_TEXT_SCHEME_NAME}\" is not registered`);\r\n }\r\n return fallback;\r\n }\r\n return scheme;\r\n}\r\n\r\n/** Bridge TextScheme → ThemeFonts. Red-line `fonts.cjk` always written. */\r\nexport function bridgeFontsFromTextScheme(scheme: TextScheme): ThemeFonts {\r\n const p = scheme.positions;\r\n const body = p.body;\r\n const headingSource = p.slideTitle ?? p.coverTitle;\r\n return {\r\n body: body.face,\r\n cjk: body.cjkFace ?? body.face,\r\n heading: headingSource.face ?? body.face,\r\n code: p.code.face,\r\n };\r\n}\r\n\r\nexport function bridgeFontSizesFromTextScheme(scheme: TextScheme): ThemeFontSizes {\r\n const p = scheme.positions;\r\n return {\r\n title: p.coverTitle.size,\r\n heading: p.slideTitle.size,\r\n body: p.body.size,\r\n code: p.code.size,\r\n small: p.small.size,\r\n };\r\n}\r\n\r\nfunction textStylesFromScheme(\r\n scheme: TextScheme,\r\n): Partial<Record<TextSchemePositionKey, FontStyleEntry>> {\r\n return { ...scheme.positions };\r\n}\r\n\r\n/**\r\n * Resolve optional layoutScheme → scheme payload + layouts/styles.\r\n * Omitted or unknown name → layouts/styles/layoutSet undefined (legacy hard-coded fallbacks).\r\n */\r\nexport function resolveLayoutSchemeOption(\r\n input?: string | LayoutScheme,\r\n): {\r\n layouts?: ThemeLayouts;\r\n styles?: ThemeStyles;\r\n layoutSet?: string;\r\n scheme?: LayoutScheme;\r\n} {\r\n if (input === undefined) return {};\r\n if (typeof input === 'object' && input !== null) {\r\n return {\r\n layouts: input.layouts,\r\n styles: input.styles,\r\n layoutSet: input.name,\r\n scheme: input,\r\n };\r\n }\r\n const name = input.trim();\r\n if (!name) return {};\r\n const scheme = getLayoutScheme(name);\r\n if (!scheme) {\r\n console.warn(`Layout scheme \"${name}\" not found, using built-in layout defaults`);\r\n return {};\r\n }\r\n return {\r\n layouts: scheme.layouts,\r\n styles: scheme.styles,\r\n layoutSet: scheme.name,\r\n scheme,\r\n };\r\n}\r\n\r\nexport function createThemeFromScheme(\r\n scheme: ColorScheme,\r\n options: ThemeFromSchemeOptions = {},\r\n): Theme {\r\n const colorScheme = resolveColorSchemeOption(options.colorScheme) ?? scheme;\r\n const textScheme = resolveTextSchemeOption(options.textScheme);\r\n\r\n const fonts = options.fonts ?? bridgeFontsFromTextScheme(textScheme);\r\n const fontSize = options.fontSize ?? bridgeFontSizesFromTextScheme(textScheme);\r\n const fromLayout = resolveLayoutSchemeOption(options.layoutScheme);\r\n\r\n return {\r\n name: scheme.name,\r\n colors: resolveColorScheme(colorScheme),\r\n fonts,\r\n fontSize,\r\n shikiTheme:\r\n options.shikiTheme ??\r\n (resolveSchemeMode(colorScheme) === 'dark' ? 'github-dark' : 'github-light'),\r\n layouts: options.layouts ?? fromLayout.layouts,\r\n styles: options.styles ?? fromLayout.styles,\r\n typography: options.typography,\r\n avoid: options.avoid,\r\n textSet: textScheme.name,\r\n textScheme,\r\n textStyles: textStylesFromScheme(textScheme),\r\n layoutSet: fromLayout.layoutSet,\r\n presetSet: options.presetSet,\r\n };\r\n}\r\n","import type { Theme } from '../models/theme.js';\r\nimport type { ColorScheme } from '../models/color-scheme.js';\r\nimport type { LayoutScheme } from '../models/layout-scheme.js';\r\nimport type { TextScheme } from '../models/text-set.js';\r\nimport type { ThemePreset } from '../models/theme-preset.js';\r\nimport { DEFAULT_THEME_NAME } from '../models/theme-preset.js';\r\nimport { createThemeFromScheme } from './from-scheme.js';\r\nimport { getColorScheme, listColorSchemes } from './color-schemes/index.js';\r\nimport { getThemePreset, listThemePresets } from './presets/index.js';\r\nimport { DEFAULT_TEXT_SCHEME_NAME } from './text-schemes/text-index.js';\r\nimport { resolveThemePresetOption } from './from-scheme.js';\r\n\r\n/** Color-only fallback when a ColorScheme name is unknown */\r\nexport const DEFAULT_SCHEME_NAME = 'ocean';\r\n\r\nexport interface GetThemeOptions {\r\n /** Color scheme name or resolved ColorScheme (overrides preset slot) */\r\n colorScheme?: string | ColorScheme;\r\n /** Text scheme name or resolved TextScheme (overrides preset slot) */\r\n textScheme?: string | TextScheme;\r\n /** Layout scheme name or resolved LayoutScheme (overrides preset slot) */\r\n layoutScheme?: string | LayoutScheme;\r\n /**\r\n * Optional ThemePreset object for advanced callers.\r\n * The user-facing path is the `name` argument (`-t` / frontmatter `theme`).\r\n */\r\n preset?: string | ThemePreset;\r\n}\r\n\r\ntype ThemeNameResolution =\r\n | { kind: 'preset'; preset: ThemePreset }\r\n | { kind: 'color'; colorName: string }\r\n | { kind: 'default' };\r\n\r\n/**\r\n * Resolve a user-facing theme name (CLI `-t` / frontmatter `theme`).\r\n * Order: ThemePreset → ColorScheme → default theme (blue).\r\n */\r\nfunction resolveThemeName(name?: string | null): ThemeNameResolution {\r\n const trimmed = typeof name === 'string' ? name.trim() : '';\r\n const key = trimmed || DEFAULT_THEME_NAME;\r\n\r\n const preset = getThemePreset(key);\r\n if (preset) return { kind: 'preset', preset };\r\n\r\n if (getColorScheme(key)) return { kind: 'color', colorName: key };\r\n\r\n return { kind: 'default' };\r\n}\r\n\r\n/**\r\n * Build a Theme from a user-facing theme name.\r\n *\r\n * - `blue` (or any ThemePreset) → full package (color × text × layout)\r\n * - `ocean` / `ocean-dark` (ColorScheme only) → color path; text `system`;\r\n * layouts stay unset unless `options.layoutScheme` is passed\r\n * - omitted / unknown → default theme `blue` (unknown warns)\r\n *\r\n * Non-string `name` values still throw (CLI contract).\r\n */\r\nexport function getTheme(name?: string, options: GetThemeOptions = {}): Theme {\r\n if (name !== undefined && name !== null && typeof name !== 'string') {\r\n throw new Error(`Invalid theme value: expected a string, got ${typeof name}`);\r\n }\r\n\r\n // Advanced: explicit preset object still wins for its slots when provided\r\n const explicitPreset = resolveThemePresetOption(options.preset);\r\n const resolved = resolveThemeName(name);\r\n\r\n if (resolved.kind === 'preset' || (resolved.kind === 'default' && !explicitPreset)) {\r\n const preset =\r\n resolved.kind === 'preset'\r\n ? resolved.preset\r\n : (getThemePreset(DEFAULT_THEME_NAME) as ThemePreset);\r\n\r\n if (resolved.kind === 'default' && name?.trim()) {\r\n console.warn(`Theme \"${name}\" not found, using \"${preset.name}\"`);\r\n }\r\n\r\n return createThemeFromScheme(getColorScheme(preset.colorScheme)!, {\r\n colorScheme: options.colorScheme,\r\n textScheme: options.textScheme ?? preset.textScheme,\r\n layoutScheme: options.layoutScheme ?? preset.layoutScheme,\r\n presetSet: preset.name,\r\n });\r\n }\r\n\r\n if (resolved.kind === 'default' && explicitPreset) {\r\n // unknown name but options.preset provided\r\n console.warn(`Theme \"${name}\" not found, using preset \"${explicitPreset.name}\"`);\r\n return createThemeFromScheme(getColorScheme(explicitPreset.colorScheme)!, {\r\n colorScheme: options.colorScheme,\r\n textScheme: options.textScheme ?? explicitPreset.textScheme,\r\n layoutScheme: options.layoutScheme ?? explicitPreset.layoutScheme,\r\n presetSet: explicitPreset.name,\r\n });\r\n }\r\n\r\n // ColorScheme-only path (README `-t ocean` / `-t ocean-dark`)\r\n const colorName =\r\n resolved.kind === 'color' ? resolved.colorName : explicitPreset!.colorScheme;\r\n return createThemeFromScheme(getColorScheme(colorName)!, {\r\n colorScheme: options.colorScheme,\r\n textScheme: options.textScheme ?? explicitPreset?.textScheme,\r\n layoutScheme: options.layoutScheme ?? explicitPreset?.layoutScheme,\r\n presetSet: explicitPreset?.name,\r\n });\r\n}\r\n\r\n/** User-facing theme names: presets first, then color-only schemes. */\r\nexport function themeNames(): string[] {\r\n const presets = listThemePresets().map((p) => p.name.toLowerCase());\r\n const colors = listColorSchemes().map((s) => s.name.toLowerCase());\r\n return [...presets, ...colors.filter((c) => !presets.includes(c))];\r\n}\r\n\r\n/** Whether `name` is a known user-facing theme (preset or color scheme). */\r\nexport function hasTheme(name?: string): boolean {\r\n if (!name) return false;\r\n return Boolean(getThemePreset(name) || getColorScheme(name));\r\n}\r\n\r\n// ColorScheme pipeline\r\nexport { resolveColorScheme } from './resolve-scheme.js';\r\nexport { createThemeFromScheme } from './from-scheme.js';\r\nexport type { ThemeFromSchemeOptions } from './from-scheme.js';\r\nexport {\r\n colorSchemes,\r\n getColorScheme,\r\n listColorSchemes,\r\n registerColorScheme,\r\n oceanScheme,\r\n oceanDarkScheme,\r\n} from './color-schemes/index.js';\r\n\r\n// Text-set pipeline (v5.1)\r\nexport {\r\n textSchemes,\r\n getTextScheme,\r\n listTextSchemes,\r\n registerTextScheme,\r\n systemTextScheme,\r\n academicTextScheme,\r\n kaiTextScheme,\r\n sourceHanSerifTextScheme,\r\n DEFAULT_TEXT_SCHEME_NAME,\r\n} from './text-schemes/text-index.js';\r\nexport {\r\n bridgeFontsFromTextScheme,\r\n bridgeFontSizesFromTextScheme,\r\n resolveTextSchemeOption,\r\n resolveLayoutSchemeOption,\r\n} from './from-scheme.js';\r\nexport { defineUniformTextScheme } from '../models/text-set.js';\r\n\r\n// Layout-set pipeline (step 3)\r\nexport {\r\n layoutSchemes,\r\n getLayoutScheme,\r\n listLayoutSchemes,\r\n registerLayoutScheme,\r\n folioLayoutScheme,\r\n legacyLayoutScheme,\r\n} from './layout-schemes/index.js';\r\nexport { DEFAULT_LAYOUT_SCHEME_NAME } from '../models/layout-scheme.js';\r\nexport type { LayoutScheme } from '../models/layout-scheme.js';\r\n\r\n// Theme-preset pipeline (step 5) — presets are user-facing theme names\r\nexport {\r\n themePresets,\r\n getThemePreset,\r\n listThemePresets,\r\n registerThemePreset,\r\n themePresetNames,\r\n hasThemePreset,\r\n bluePreset,\r\n emeraldPreset,\r\n goldPreset,\r\n slatePreset,\r\n} from './presets/index.js';\r\nexport { DEFAULT_THEME_NAME, DEFAULT_PRESET_NAME } from '../models/theme-preset.js';\r\nexport type { ThemePreset } from '../models/theme-preset.js';\r\nexport { resolveThemePresetOption } from './from-scheme.js';\r\n","/**\n * Smart output file naming\n */\n\nimport { existsSync } from 'node:fs';\nimport { basename, extname, dirname, join } from 'node:path';\nimport { randomUUID } from 'node:crypto';\n\n/**\n * Determine output path:\n * 1. If specified, use it\n * 2. Otherwise: input.md → input.pptx\n * 3. If exists: add timestamp\n * 4. If still exists: add 4-char uuid\n */\nexport function getOutputPath(inputPath: string, specifiedOutput?: string): string {\n if (specifiedOutput) return specifiedOutput;\n\n const dir = dirname(inputPath);\n const name = basename(inputPath, extname(inputPath));\n\n // Try simple name\n const simple = join(dir, `${name}.pptx`);\n if (!existsSync(simple)) return simple;\n\n // Add timestamp\n const now = new Date();\n const ts = now.getFullYear().toString() +\n String(now.getMonth() + 1).padStart(2, '0') +\n String(now.getDate()).padStart(2, '0') +\n '-' +\n String(now.getHours()).padStart(2, '0') +\n String(now.getMinutes()).padStart(2, '0') +\n String(now.getSeconds()).padStart(2, '0');\n\n const withTimestamp = join(dir, `${name}-${ts}.pptx`);\n if (!existsSync(withTimestamp)) return withTimestamp;\n\n // Add random suffix\n const uuid = randomUUID().slice(0, 4);\n return join(dir, `${name}-${ts}-${uuid}.pptx`);\n}\n","/**\n * Windows-compatible glob expansion\n */\n\nimport fg from 'fast-glob';\nimport { resolve } from 'node:path';\n\n/**\n * Expand glob patterns to absolute .md file paths\n */\nexport async function expandGlob(patterns: string[]): Promise<string[]> {\n // fast-glob needs forward slashes even on Windows\n const normalized = patterns.map((p) => p.replace(/\\\\/g, '/'));\n\n const files = await fg(normalized, {\n absolute: true,\n onlyFiles: true,\n });\n\n // Filter to .md files and sort\n return files\n .filter((f) => f.toLowerCase().endsWith('.md'))\n .sort();\n}\n"],"mappings":"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","names":["chalk","readFileSync","readFileSync","resolve","series","readFileSync","SLIDE_W","SLIDE_H","IMAGE_MIME","readFileSync","readFileSync","readFileSync","x","y","resolve","writeFileSync","resolve","isDarkColor","isDarkColor","titleLayout","sectionLayout","contentLayout","codeLayout","quoteLayout","footerLayout","titleLayout","sectionLayout","contentLayout","codeLayout","quoteLayout","footerLayout","titleLayout","sectionLayout","contentLayout","codeLayout","quoteLayout","closingLayout","imageBase","imageSingleLayout","imageDoubleLayout","imageTripleLayout","footerLayout","titleLayout","sectionLayout","contentLayout","codeLayout","quoteLayout","closingLayout","imageSingleLayout","imageDoubleLayout","imageTripleLayout","footerLayout","titleLayout","sectionLayout","contentLayout","codeLayout","quoteLayout","closingLayout","imageBase","imageSingleLayout","imageDoubleLayout","imageTripleLayout","footerLayout","titleLayout","sectionLayout","contentLayout","codeLayout","quoteLayout","closingLayout","imageSingleLayout","imageDoubleLayout","imageTripleLayout","footerLayout","existsSync","dirname","join","randomUUID","resolve","readFileSync","readFileSync","chalk"]}