@bendyline/squisq 1.5.0 → 1.5.1
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/README.md +14 -1
- package/dist/{ContentContainer-DNx460y8.d.ts → ContentContainer-BXUlIf18.d.ts} +6 -2
- package/dist/{Doc-BsMkmzH8.d.ts → Doc-BBVGq1_9.d.ts} +94 -15
- package/dist/{ImageEditDoc-DvoeHMP9.d.ts → ImageEditDoc-FuyGtt6o.d.ts} +1 -1
- package/dist/{chunk-KZNXZ5SM.js → chunk-6ATE2PSM.js} +18 -7
- package/dist/chunk-6ATE2PSM.js.map +1 -0
- package/dist/{chunk-7MQGNR76.js → chunk-A4O7GIWE.js} +2 -27
- package/dist/chunk-A4O7GIWE.js.map +1 -0
- package/dist/chunk-ET53IIEP.js +1 -0
- package/dist/chunk-ET53IIEP.js.map +1 -0
- package/dist/{chunk-OKJOQXK4.js → chunk-HWVFJAAH.js} +38 -2
- package/dist/chunk-HWVFJAAH.js.map +1 -0
- package/dist/{chunk-2TMAWB4Y.js → chunk-IMSCRLLV.js} +1 -1
- package/dist/chunk-IMSCRLLV.js.map +1 -0
- package/dist/{chunk-4AKUQPEE.js → chunk-KKNUBQ6Y.js} +1 -1
- package/dist/chunk-KKNUBQ6Y.js.map +1 -0
- package/dist/{chunk-TVSGLUID.js → chunk-LDQ2HJIX.js} +3 -3
- package/dist/{chunk-4ZFRZBU2.js → chunk-LH7I6SH7.js} +777 -151
- package/dist/chunk-LH7I6SH7.js.map +1 -0
- package/dist/{chunk-K32VJONL.js → chunk-T5UK6YOB.js} +41 -2
- package/dist/chunk-T5UK6YOB.js.map +1 -0
- package/dist/{chunk-OH43RPTP.js → chunk-TEEEILMP.js} +12 -2
- package/dist/chunk-TEEEILMP.js.map +1 -0
- package/dist/{chunk-FR2RBTKO.js → chunk-TQWLI6S2.js} +93 -27
- package/dist/chunk-TQWLI6S2.js.map +1 -0
- package/dist/{chunk-LRCV7N7F.js → chunk-UY7KGQ5R.js} +2 -2
- package/dist/{chunk-3E5F2XMR.js → chunk-VWUFZ6ZG.js} +29 -2
- package/dist/chunk-VWUFZ6ZG.js.map +1 -0
- package/dist/doc/index.d.ts +4 -4
- package/dist/doc/index.js +16 -7
- package/dist/generate/index.d.ts +2 -80
- package/dist/generate/index.js +2 -7
- package/dist/imageEdit/index.d.ts +4 -4
- package/dist/index.d.ts +8 -8
- package/dist/index.js +32 -23
- package/dist/jsonForm/index.d.ts +42 -1
- package/dist/jsonForm/index.js +9 -1
- package/dist/markdown/index.d.ts +18 -2
- package/dist/markdown/index.js +5 -3
- package/dist/recommend/index.js +2 -2
- package/dist/schemas/index.d.ts +4 -4
- package/dist/schemas/index.js +3 -5
- package/dist/storage/index.d.ts +2 -2
- package/dist/storage/index.js +1 -1
- package/dist/story/index.d.ts +125 -11
- package/dist/story/index.js +16 -7
- package/dist/{themeLibrary-DQQKuRMx.d.ts → themeLibrary-CehcJhzz.d.ts} +1 -1
- package/dist/timing/index.js +3 -5
- package/dist/transform/index.d.ts +2 -2
- package/dist/transform/index.js +3 -3
- package/dist/versions/index.d.ts +1 -1
- package/package.json +1 -1
- package/src/__tests__/contentExtractor.test.ts +60 -0
- package/src/__tests__/coverBlock.test.ts +46 -1
- package/src/__tests__/customTemplateSample.test.ts +63 -2
- package/src/__tests__/customTemplatesFrontmatter.test.ts +31 -0
- package/src/__tests__/customThemesFrontmatter.test.ts +27 -0
- package/src/__tests__/inputDescriptors.test.ts +162 -0
- package/src/__tests__/jsonForm.tokens.test.ts +84 -0
- package/src/__tests__/markdown.test.ts +64 -0
- package/src/__tests__/markdownSanitize.test.ts +15 -0
- package/src/__tests__/markdownToDoc.test.ts +168 -0
- package/src/__tests__/mediaAnnotations.test.ts +27 -0
- package/src/__tests__/structuredData.test.ts +73 -3
- package/src/__tests__/templateMetadata.test.ts +11 -1
- package/src/__tests__/templates.test.ts +112 -0
- package/src/__tests__/validateDoc.test.ts +160 -0
- package/src/doc/annotationBlocks.ts +117 -0
- package/src/doc/customTemplatesFrontmatter.ts +7 -1
- package/src/doc/customThemesFrontmatter.ts +6 -1
- package/src/doc/docToMarkdown.ts +31 -1
- package/src/doc/getLayers.ts +11 -2
- package/src/doc/index.ts +12 -0
- package/src/doc/markdownToDoc.ts +80 -3
- package/src/doc/mediaAnnotations.ts +15 -33
- package/src/doc/standaloneAnnotation.ts +58 -0
- package/src/doc/structuredData.ts +92 -21
- package/src/doc/templates/__tests__/customTemplate.test.ts +21 -2
- package/src/doc/templates/comparisonBar.ts +8 -1
- package/src/doc/templates/coverBlock.ts +29 -2
- package/src/doc/templates/customTemplate.ts +10 -4
- package/src/doc/templates/factCard.ts +4 -2
- package/src/doc/templates/imageWithCaption.ts +10 -8
- package/src/doc/templates/index.ts +12 -2
- package/src/doc/templates/inputDescriptors.ts +432 -0
- package/src/doc/templates/photoGrid.ts +16 -39
- package/src/doc/templates/tokens/__tests__/resolveTokens.test.ts +267 -1
- package/src/doc/templates/tokens/resolveTokens.ts +0 -0
- package/src/doc/templates/videoWithCaption.ts +15 -14
- package/src/doc/utils/nearest.ts +59 -0
- package/src/doc/validate.ts +153 -54
- package/src/generate/contentExtractor.ts +148 -35
- package/src/generate/index.ts +0 -3
- package/src/jsonForm/index.ts +2 -0
- package/src/jsonForm/tokens.ts +78 -0
- package/src/markdown/annotationCoercion.ts +1 -1
- package/src/markdown/attrTokens.ts +19 -0
- package/src/markdown/index.ts +2 -1
- package/src/markdown/sanitize.ts +22 -2
- package/src/markdown/stringify.ts +12 -3
- package/src/markdown/utils.ts +62 -1
- package/src/schemas/CustomTemplates.ts +56 -4
- package/src/schemas/Doc.ts +39 -41
- package/src/schemas/themeCompile.ts +1 -1
- package/src/storage/ContentContainer.ts +6 -2
- package/src/transform/types.ts +1 -1
- package/dist/chunk-2TMAWB4Y.js.map +0 -1
- package/dist/chunk-3E5F2XMR.js.map +0 -1
- package/dist/chunk-4AKUQPEE.js.map +0 -1
- package/dist/chunk-4X3JQXNM.js +0 -35
- package/dist/chunk-4X3JQXNM.js.map +0 -1
- package/dist/chunk-4ZFRZBU2.js.map +0 -1
- package/dist/chunk-7MQGNR76.js.map +0 -1
- package/dist/chunk-FBKP5CAO.js +0 -145
- package/dist/chunk-FBKP5CAO.js.map +0 -1
- package/dist/chunk-FR2RBTKO.js.map +0 -1
- package/dist/chunk-K32VJONL.js.map +0 -1
- package/dist/chunk-KZNXZ5SM.js.map +0 -1
- package/dist/chunk-OH43RPTP.js.map +0 -1
- package/dist/chunk-OKJOQXK4.js.map +0 -1
- package/src/__tests__/slideshowGenerator.test.ts +0 -128
- package/src/generate/slideshowGenerator.ts +0 -280
- /package/dist/{chunk-TVSGLUID.js.map → chunk-LDQ2HJIX.js.map} +0 -0
- /package/dist/{chunk-LRCV7N7F.js.map → chunk-UY7KGQ5R.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/generate/contentExtractor.ts","../src/generate/templateMapper.ts"],"sourcesContent":["/**\n * Content Extractor\n *\n * Pattern-based extraction of compelling content from plain text.\n * Identifies statistics, dates, quotes, comparisons, facts, impact lines,\n * lists, and definitions that can be turned into slideshow slides.\n *\n * Extraction is purely regex-based — no AI calls, no runtime costs,\n * deterministic and reproducible.\n */\n\n// ── Types ──────────────────────────────────────────────────────────\n\n/** Kinds of content the extractor recognises. */\nexport type ExtractionType =\n | 'stat'\n | 'date'\n | 'quote'\n | 'comparison'\n | 'fact'\n | 'impactLine'\n | 'list'\n | 'definition';\n\n/** An extracted content element with source position. */\nexport interface ExtractedElement {\n type: ExtractionType;\n /** Full extracted text (usually the surrounding sentence). */\n text: string;\n /** Confidence score 0–1. */\n confidence: number;\n /** Character offset in the source text. */\n sourcePosition: number;\n /** Character offset where element ends. */\n endPosition: number;\n /** Type-specific structured payload. */\n data:\n | StatData\n | DateData\n | QuoteData\n | ComparisonData\n | FactData\n | ImpactLineData\n | ListData\n | DefinitionData;\n}\n\nexport interface StatData {\n type: 'stat';\n value: string;\n unit?: string;\n description: string;\n}\n\nexport interface DateData {\n type: 'date';\n date: string;\n description: string;\n mood?: 'neutral' | 'somber' | 'celebratory';\n}\n\nexport interface QuoteData {\n type: 'quote';\n quote: string;\n attribution?: string;\n}\n\nexport interface ComparisonData {\n type: 'comparison';\n left: { label: string; sublabel?: string };\n right: { label: string; sublabel?: string };\n header?: string;\n}\n\nexport interface FactData {\n type: 'fact';\n fact: string;\n explanation?: string;\n}\n\nexport interface ImpactLineData {\n type: 'impactLine';\n text: string;\n}\n\nexport interface ListData {\n type: 'list';\n items: string[];\n title?: string;\n}\n\nexport interface DefinitionData {\n type: 'definition';\n term: string;\n definition: string;\n origin?: string;\n}\n\n/** Options for `extractContent`. */\nexport interface ExtractionOptions {\n /** Minimum confidence threshold (default: 0.3). */\n minConfidence?: number;\n /** Which types to extract (default: all). */\n types?: ExtractionType[];\n /** Maximum extractions per type (default: unlimited). */\n maxPerType?: number;\n}\n\n/** Result of `extractContent`. */\nexport interface ExtractionResult {\n elements: ExtractedElement[];\n sourceLength: number;\n stats: {\n statCount: number;\n dateCount: number;\n quoteCount: number;\n comparisonCount: number;\n factCount: number;\n impactLineCount: number;\n listCount: number;\n definitionCount: number;\n totalCount: number;\n };\n}\n\n// ── Patterns ───────────────────────────────────────────────────────\n\nconst STAT_PATTERNS = [\n /\\b(roughly |about |approximately |nearly |over |under |more than |less than )?([\\d,]+(?:\\.\\d+)?)\\s*%/gi,\n /\\b([\\d,]+(?:\\.\\d+)?)\\s*(million|billion|trillion|thousand|hundred)\\b/gi,\n /\\b([\\d,]+(?:\\.\\d+)?)\\s*(miles?|feet|ft|meters?|m|kilometers?|km|acres?|square miles?|sq mi|hectares?)\\b/gi,\n /\\b([\\d,]+(?:\\.\\d+)?)\\s*(x|times)\\b/gi,\n /\\b([$€£¥])\\s*([\\d,]+(?:\\.\\d+)?)\\s*(million|billion|thousand)?\\b/gi,\n /\\b(\\d+)(st|nd|rd|th)\\s+(largest|smallest|oldest|newest|most|least)/gi,\n];\n\nconst DATE_PATTERNS = [\n /\\b(January|February|March|April|May|June|July|August|September|October|November|December)\\s+(\\d{1,2},?\\s+)?(\\d{4})\\b/gi,\n /\\b(\\d{4})s\\b|\\b(\\d{1,2})(st|nd|rd|th)\\s+century\\b/gi,\n /\\b(from\\s+)?(\\d{4})\\s*(to|–|-|through)\\s*(\\d{4})\\b/gi,\n /\\b(in|by|since|after|before|during)\\s+(\\d{4})\\b/gi,\n];\n\nconst QUOTE_PATTERNS = [\n /\"([^\"]{15,200})\"/g,\n /\\u201c([^\\u201d]{15,200})\\u201d/g,\n /(\\w+(?:\\s+\\w+)?)\\s+(?:said|stated|wrote|noted|observed|commented),?\\s*\"([^\"]+)\"/gi,\n];\n\n// A single side of a comparison (\"X\" in \"from X to Y\"). Deliberately excludes\n// sentence/clause terminators (. ! ? ;) and newlines so a capture group can\n// never swallow text from an adjacent sentence. Without this, greedy `.{2,30}`\n// matches across a period — e.g. \"…contradicted from witness to witness.\n// Robertson said…\" yields right=\"witness. Robertson\", producing a nonsensical\n// \"witness → witness. Robertson\" slide. Commas and colons are allowed (ranges\n// like \"9:00 to 17:00\", ratios); downstream label truncation trims commas.\nconst COMPARISON_SIDE = '[^.!?;\\\\r\\\\n]{2,30}';\n\nconst COMPARISON_PATTERNS = [\n new RegExp(`from\\\\s+(${COMPARISON_SIDE})\\\\s+to\\\\s+(${COMPARISON_SIDE})`, 'gi'),\n new RegExp(`(${COMPARISON_SIDE})\\\\s+(?:vs\\\\.?|versus)\\\\s+(${COMPARISON_SIDE})`, 'gi'),\n new RegExp(`(${COMPARISON_SIDE})\\\\s+compared\\\\s+to\\\\s+(${COMPARISON_SIDE})`, 'gi'),\n];\n\n// Words whose trailing period is an abbreviation, not a sentence end. Used by\n// isSentenceBoundary() so names like \"George W. Tibbetts\" or \"Quong Chong & Co.\"\n// don't get split into fragments. Matched only when the entire preceding word\n// equals one of these (case-insensitive), so \"canal.\" / \"taco.\" are unaffected.\nconst SENTENCE_ABBREVIATIONS = new Set([\n 'mr',\n 'mrs',\n 'ms',\n 'dr',\n 'prof',\n 'st',\n 'mt',\n 'jr',\n 'sr',\n 'gen',\n 'col',\n 'capt',\n 'lt',\n 'sgt',\n 'rev',\n 'hon',\n 'sen',\n 'rep',\n 'gov',\n 'pres',\n 'vs',\n 'etc',\n 'inc',\n 'co',\n 'ltd',\n 'corp',\n 'al',\n 'fig',\n 'eg',\n 'ie',\n 'approx',\n 'dept',\n 'univ',\n 'assn',\n 'bros',\n 'ave',\n 'blvd',\n 'rd',\n]);\n\nconst FACT_INDICATORS = [\n 'largest',\n 'smallest',\n 'oldest',\n 'newest',\n 'first',\n 'last',\n 'most',\n 'least',\n 'only',\n 'unique',\n 'rare',\n 'famous',\n 'important',\n 'significant',\n 'notable',\n 'remarkable',\n 'extraordinary',\n 'crucial',\n 'essential',\n 'critical',\n 'major',\n 'key',\n 'discovered',\n 'founded',\n 'established',\n 'created',\n 'built',\n 'invented',\n 'developed',\n 'introduced',\n 'pioneered',\n 'transformed',\n 'revolutionized',\n 'changed',\n 'shaped',\n];\n\nconst SOMBER_INDICATORS = [\n 'disaster',\n 'tragedy',\n 'death',\n 'died',\n 'killed',\n 'destroyed',\n 'devastated',\n 'collapsed',\n 'lost',\n 'abandoned',\n 'declined',\n 'war',\n 'battle',\n 'conflict',\n 'earthquake',\n 'fire',\n 'flood',\n];\n\nconst CELEBRATORY_INDICATORS = [\n 'celebration',\n 'victory',\n 'success',\n 'achievement',\n 'triumph',\n 'opened',\n 'completed',\n 'inaugurated',\n 'launched',\n 'won',\n 'record',\n 'breakthrough',\n 'milestone',\n 'golden',\n 'grand',\n];\n\nconst IMPACT_VERBS = [\n 'check',\n 'watch',\n 'stop',\n 'prepare',\n 'imagine',\n 'consider',\n 'look',\n 'listen',\n 'notice',\n 'remember',\n 'discover',\n 'explore',\n 'visit',\n 'try',\n 'experience',\n 'avoid',\n 'beware',\n 'enjoy',\n];\n\nconst LIST_PATTERNS = [\n /(?:including|such as|namely|like|features?|offers?)\\s+([^.]{10,150})/gi,\n /(?:three|four|five|six|several|many|various)\\s+(?:main|key|primary|notable|popular|important)?\\s*\\w+(?:\\s+\\w+)?:\\s*([^.]{10,150})/gi,\n];\n\nconst DEFINITION_PATTERNS = [\n /\\b([A-Z][a-z]+(?:\\s+[A-Z]?[a-z]+){0,3})\\s+is\\s+(?:a|an|the)\\s+([^.]{10,120})/g,\n /known\\s+as\\s+([A-Z][a-z]+(?:\\s+[A-Z]?[a-z]+){0,3}),\\s+([^.]{10,120})/gi,\n /\\b([A-Z][a-z]+(?:\\s+[A-Z]?[a-z]+){0,3})\\s+refers?\\s+to\\s+([^.]{10,120})/g,\n /called\\s+([A-Z][a-z]+(?:\\s+[A-Z]?[a-z]+){0,3}),?\\s+(?:which|meaning|a)\\s+([^.]{10,120})/gi,\n];\n\n// ── Main ───────────────────────────────────────────────────────────\n\n/**\n * Extract compelling content from plain text.\n *\n * Call `stripMarkdown(text)` first if the input contains markdown.\n */\nexport function extractContent(text: string, options: ExtractionOptions = {}): ExtractionResult {\n const {\n minConfidence = 0.3,\n types = ['stat', 'date', 'quote', 'comparison', 'fact', 'impactLine', 'list', 'definition'],\n maxPerType,\n } = options;\n\n const elements: ExtractedElement[] = [];\n\n if (types.includes('stat')) elements.push(...extractStats(text));\n if (types.includes('date')) elements.push(...extractDates(text));\n if (types.includes('quote')) elements.push(...extractQuotes(text));\n if (types.includes('comparison')) elements.push(...extractComparisons(text));\n if (types.includes('fact')) elements.push(...extractFacts(text));\n if (types.includes('impactLine')) elements.push(...extractImpactLines(text));\n if (types.includes('list')) elements.push(...extractLists(text));\n if (types.includes('definition')) elements.push(...extractDefinitions(text));\n\n let filtered = elements.filter((e) => e.confidence >= minConfidence);\n\n if (maxPerType !== undefined) {\n const byType = new Map<ExtractionType, ExtractedElement[]>();\n for (const elem of filtered) {\n const list = byType.get(elem.type) || [];\n list.push(elem);\n byType.set(elem.type, list);\n }\n filtered = [];\n for (const [, list] of byType) {\n list.sort((a, b) => b.confidence - a.confidence);\n filtered.push(...list.slice(0, maxPerType));\n }\n }\n\n filtered.sort((a, b) => a.sourcePosition - b.sourcePosition);\n filtered = deduplicateOverlapping(filtered);\n\n return {\n elements: filtered,\n sourceLength: text.length,\n stats: {\n statCount: filtered.filter((e) => e.type === 'stat').length,\n dateCount: filtered.filter((e) => e.type === 'date').length,\n quoteCount: filtered.filter((e) => e.type === 'quote').length,\n comparisonCount: filtered.filter((e) => e.type === 'comparison').length,\n factCount: filtered.filter((e) => e.type === 'fact').length,\n impactLineCount: filtered.filter((e) => e.type === 'impactLine').length,\n listCount: filtered.filter((e) => e.type === 'list').length,\n definitionCount: filtered.filter((e) => e.type === 'definition').length,\n totalCount: filtered.length,\n },\n };\n}\n\n// ── Per-type extractors ────────────────────────────────────────────\n\nfunction extractStats(text: string): ExtractedElement[] {\n const elements: ExtractedElement[] = [];\n const seen = new Set<number>();\n\n for (const pattern of STAT_PATTERNS) {\n pattern.lastIndex = 0;\n let match;\n while ((match = pattern.exec(text)) !== null) {\n const position = match.index;\n if (seen.has(position)) continue;\n seen.add(position);\n\n const context = getSentenceContext(text, position, match[0].length);\n const value = match[0].trim();\n\n elements.push({\n type: 'stat',\n text: context.sentence,\n confidence: calculateStatConfidence(value, context.sentence),\n sourcePosition: context.start,\n endPosition: context.end,\n data: { type: 'stat', value, description: cleanDescription(context.sentence, value) },\n });\n }\n }\n return elements;\n}\n\nfunction extractDates(text: string): ExtractedElement[] {\n const elements: ExtractedElement[] = [];\n const seen = new Set<number>();\n\n for (const pattern of DATE_PATTERNS) {\n pattern.lastIndex = 0;\n let match;\n while ((match = pattern.exec(text)) !== null) {\n const position = match.index;\n if (seen.has(position)) continue;\n seen.add(position);\n\n const context = getSentenceContext(text, position, match[0].length);\n const dateStr = match[0].trim();\n\n elements.push({\n type: 'date',\n text: context.sentence,\n confidence: calculateDateConfidence(dateStr, context.sentence),\n sourcePosition: context.start,\n endPosition: context.end,\n data: {\n type: 'date',\n date: dateStr,\n description: cleanDescription(context.sentence, dateStr),\n mood: detectMood(context.sentence),\n },\n });\n }\n }\n return elements;\n}\n\nfunction extractQuotes(text: string): ExtractedElement[] {\n const elements: ExtractedElement[] = [];\n const seen = new Set<number>();\n\n for (const pattern of QUOTE_PATTERNS) {\n pattern.lastIndex = 0;\n let match;\n while ((match = pattern.exec(text)) !== null) {\n const position = match.index;\n if (seen.has(position)) continue;\n seen.add(position);\n\n const quote = match.length > 2 ? match[2] : match[1];\n const attribution = match.length > 2 ? match[1] : undefined;\n if (quote.length < 15 || quote.length > 200) continue;\n\n elements.push({\n type: 'quote',\n text: match[0],\n confidence: calculateQuoteConfidence(quote),\n sourcePosition: position,\n endPosition: position + match[0].length,\n data: { type: 'quote', quote: quote.trim(), attribution: attribution?.trim() },\n });\n }\n }\n return elements;\n}\n\nfunction extractComparisons(text: string): ExtractedElement[] {\n const elements: ExtractedElement[] = [];\n const seen = new Set<number>();\n\n for (const pattern of COMPARISON_PATTERNS) {\n pattern.lastIndex = 0;\n let match;\n while ((match = pattern.exec(text)) !== null) {\n const position = match.index;\n if (seen.has(position)) continue;\n seen.add(position);\n\n // Trim a trailing clause introduced by a comma + space (\"retired\n // airliners, arranged in rows\" → \"retired airliners\"). A greedy side\n // match often swallows the words after the compared thing; the comma is a\n // clause boundary, not part of the value. Numeric grouping commas\n // (\"4,000\") survive because those are comma+digit, not comma+space.\n const trimClause = (s: string) => s.replace(/,\\s+.*$/, '').trim();\n const left = trimClause(match[1].trim());\n const right = trimClause(match[2].trim());\n if (left.length < 2 || left.length > 30) continue;\n if (right.length < 2 || right.length > 30) continue;\n // Reject \"from X to X\"-style idioms — \"from witness to witness\",\n // \"from day to day\", \"from generation to generation\". These mean \"it\n // varied\", not \"A versus B\", and render as a pointless \"X → X\" card.\n // The signature is a word repeated across the connector: the last word\n // of the left side equals the first word of the right side. (Greedy\n // matching may append trailing context to the right side, so a whole-\n // string equality check is not enough.)\n const wordsOf = (s: string) =>\n s\n .toLowerCase()\n .split(/\\s+/)\n .map((w) => w.replace(/[^a-z0-9]+/g, ''))\n .filter(Boolean);\n const leftWords = wordsOf(left);\n const rightWords = wordsOf(right);\n if (\n leftWords.length > 0 &&\n rightWords.length > 0 &&\n leftWords[leftWords.length - 1] === rightWords[0]\n ) {\n continue;\n }\n\n const context = getSentenceContext(text, position, match[0].length);\n\n elements.push({\n type: 'comparison',\n text: context.sentence,\n confidence: 0.6,\n sourcePosition: context.start,\n endPosition: context.end,\n data: { type: 'comparison', left: { label: left }, right: { label: right } },\n });\n }\n }\n return elements;\n}\n\n/**\n * Whether the `. ! ?` at `index` is a real sentence terminator rather than a\n * period inside an abbreviation (\"George W. Tibbetts\", \"M. DeWitt\", \"Mr.\",\n * \"U.S.\"), a single-letter initial, a decimal (\"3.5\"), or an ellipsis. Naive\n * splitting on every period produces broken fragments — e.g. the standalone\n * slide \"They were met at George W\" from \"…at George W. Tibbetts' store…\".\n * Returns false for any non-terminator character so callers can scan freely.\n */\nfunction isSentenceBoundary(text: string, index: number): boolean {\n const ch = text[index];\n if (ch === '!' || ch === '?') return true;\n if (ch !== '.') return false;\n\n // Ellipsis: defer the boundary to the final dot in a run of dots.\n if (text[index + 1] === '.') return false;\n // Decimal number: digit \".\" digit → \"3.5\".\n if (/[0-9]/.test(text[index - 1] ?? '') && /[0-9]/.test(text[index + 1] ?? '')) return false;\n\n // The run of letters immediately preceding the period.\n let w = index - 1;\n while (w >= 0 && /[A-Za-z]/.test(text[w])) w--;\n const word = text.slice(w + 1, index);\n if (word.length === 1) return false; // single-letter initial: \"George W.\"\n if (word && SENTENCE_ABBREVIATIONS.has(word.toLowerCase())) return false;\n\n // A genuine sentence starts with an uppercase letter, digit, or opening\n // quote/bracket. A lowercase continuation means the period was mid-sentence\n // (an abbreviation we didn't enumerate).\n let j = index + 1;\n while (j < text.length && /\\s/.test(text[j])) j++;\n if (j >= text.length) return true; // end of text\n return !/[a-z]/.test(text[j]);\n}\n\n/**\n * Iterate over sentence-like spans in the text, yielding trimmed text and\n * accurate start/end indices within the original string.\n *\n * Boundaries are detected by isSentenceBoundary() so abbreviations, initials,\n * decimals, and ellipses do not split a sentence. Leading whitespace and\n * trailing whitespace/terminators are excluded from each span.\n */\nfunction forEachSentenceSpan(\n text: string,\n callback: (trimmed: string, start: number, end: number) => void,\n): void {\n const emit = (rawStart: number, rawEnd: number) => {\n let start = rawStart;\n while (start < rawEnd && /\\s/.test(text[start])) start++;\n let end = rawEnd;\n while (end > start && /[\\s.!?]/.test(text[end - 1])) end--;\n if (end <= start) return;\n const trimmed = text.slice(start, end);\n if (trimmed) callback(trimmed, start, end);\n };\n\n let spanStart = 0;\n let i = 0;\n while (i < text.length) {\n if (isSentenceBoundary(text, i)) {\n // Consume any consecutive terminators (\"?!\", \"…\") as one boundary.\n let end = i + 1;\n while (end < text.length && /[.!?]/.test(text[end])) end++;\n emit(spanStart, end);\n spanStart = end;\n i = end;\n } else {\n i++;\n }\n }\n if (spanStart < text.length) emit(spanStart, text.length);\n}\n\nfunction extractFacts(text: string): ExtractedElement[] {\n const elements: ExtractedElement[] = [];\n\n forEachSentenceSpan(text, (trimmed, start, end) => {\n if (trimmed.length <= 20) return;\n\n const score = scoreSentenceAsFact(trimmed);\n if (score < 0.4) return;\n\n elements.push({\n type: 'fact',\n text: trimmed,\n confidence: score,\n sourcePosition: start,\n endPosition: end,\n data: { type: 'fact', fact: trimmed },\n });\n });\n\n return elements;\n}\n\nfunction extractImpactLines(text: string): ExtractedElement[] {\n const elements: ExtractedElement[] = [];\n\n forEachSentenceSpan(text, (trimmed, start, end) => {\n if (trimmed.length < 8 || trimmed.length > 60) return;\n\n let score = 0.3;\n const lower = trimmed.toLowerCase();\n\n for (const verb of IMPACT_VERBS) {\n if (lower.startsWith(verb)) {\n score += 0.25;\n break;\n }\n }\n\n if (end < text.length && text[end] === '!') score += 0.15;\n if (trimmed.length < 30) score += 0.1;\n if (trimmed.includes(',')) score -= 0.1;\n if (/^(and|but|or|the|a|an)\\b/i.test(trimmed)) score -= 0.15;\n if (score < 0.5) return;\n\n elements.push({\n type: 'impactLine',\n text: trimmed,\n confidence: Math.min(1, score),\n sourcePosition: start,\n endPosition: end,\n data: { type: 'impactLine', text: trimmed },\n });\n });\n\n return elements;\n}\n\nfunction extractLists(text: string): ExtractedElement[] {\n const elements: ExtractedElement[] = [];\n const seen = new Set<number>();\n\n for (const pattern of LIST_PATTERNS) {\n pattern.lastIndex = 0;\n let match;\n while ((match = pattern.exec(text)) !== null) {\n const position = match.index;\n if (seen.has(position)) continue;\n seen.add(position);\n\n const listContent = match[1].trim();\n const items = listContent\n .split(/,\\s*(?:and|or)\\s+|,\\s+|\\s+and\\s+|\\s+or\\s+/)\n .map((item) => item.trim())\n .filter((item) => item.length >= 2 && item.length <= 60);\n\n if (items.length < 3 || items.length > 5) continue;\n\n const context = getSentenceContext(text, position, match[0].length);\n\n elements.push({\n type: 'list',\n text: context.sentence,\n confidence: 0.65,\n sourcePosition: context.start,\n endPosition: context.end,\n data: { type: 'list', items },\n });\n }\n }\n return elements;\n}\n\nfunction extractDefinitions(text: string): ExtractedElement[] {\n const elements: ExtractedElement[] = [];\n const seen = new Set<number>();\n\n for (const pattern of DEFINITION_PATTERNS) {\n pattern.lastIndex = 0;\n let match;\n while ((match = pattern.exec(text)) !== null) {\n const position = match.index;\n if (seen.has(position)) continue;\n seen.add(position);\n\n const term = match[1].trim();\n const definition = match[2].trim();\n if (term.length < 3 || term.length > 30) continue;\n if (definition.length < 10 || definition.length > 120) continue;\n\n const context = getSentenceContext(text, position, match[0].length);\n\n elements.push({\n type: 'definition',\n text: context.sentence,\n confidence: 0.6,\n sourcePosition: context.start,\n endPosition: context.end,\n data: { type: 'definition', term, definition },\n });\n }\n }\n return elements;\n}\n\n// ── Helpers ────────────────────────────────────────────────────────\n\nfunction getSentenceContext(\n text: string,\n matchStart: number,\n matchLength: number,\n): { sentence: string; start: number; end: number } {\n let start = matchStart;\n while (start > 0 && !isSentenceBoundary(text, start - 1)) start--;\n while (start < matchStart && /\\s/.test(text[start])) start++;\n\n let end = matchStart + matchLength;\n while (end < text.length && !isSentenceBoundary(text, end)) end++;\n if (end < text.length) end++;\n\n return { sentence: text.slice(start, end).trim(), start, end };\n}\n\nfunction calculateStatConfidence(value: string, context: string): number {\n let score = 0.5;\n if (value.includes('%')) score += 0.2;\n if (/million|billion|trillion/i.test(value)) score += 0.15;\n if (/increased|decreased|grew|dropped|rose|fell/i.test(context)) score += 0.15;\n if (context.length < 30) score -= 0.2;\n return Math.min(1, Math.max(0, score));\n}\n\nfunction calculateDateConfidence(date: string, context: string): number {\n let score = 0.5;\n if (\n /January|February|March|April|May|June|July|August|September|October|November|December/i.test(\n date,\n )\n )\n score += 0.2;\n if (/founded|established|built|opened|discovered|created/i.test(context)) score += 0.2;\n if (/happened|occurred|took place|began|ended/i.test(context)) score += 0.15;\n return Math.min(1, Math.max(0, score));\n}\n\nfunction calculateQuoteConfidence(quote: string): number {\n let score = 0.5;\n if (quote.length >= 30 && quote.length <= 150) score += 0.2;\n if (/\\b(I|we|our|my)\\b/i.test(quote)) score += 0.1;\n if (!/[.!?]$/.test(quote)) score -= 0.1;\n return Math.min(1, Math.max(0, score));\n}\n\nfunction scoreSentenceAsFact(sentence: string): number {\n let score = 0.3;\n const lower = sentence.toLowerCase();\n for (const indicator of FACT_INDICATORS) {\n if (lower.includes(indicator)) {\n score += 0.1;\n break;\n }\n }\n const properNouns = sentence.match(/\\b[A-Z][a-z]+\\b/g);\n if (properNouns && properNouns.length >= 2) score += 0.15;\n if (/\\d/.test(sentence)) score += 0.1;\n if (sentence.endsWith('?')) score -= 0.3;\n if (sentence.length > 200) score -= 0.15;\n return Math.min(1, Math.max(0, score));\n}\n\nfunction detectMood(sentence: string): 'neutral' | 'somber' | 'celebratory' {\n const lower = sentence.toLowerCase();\n for (const word of SOMBER_INDICATORS) {\n if (lower.includes(word)) return 'somber';\n }\n for (const word of CELEBRATORY_INDICATORS) {\n if (lower.includes(word)) return 'celebratory';\n }\n return 'neutral';\n}\n\nfunction cleanDescription(sentence: string, value: string): string {\n const prepositionPatterns = [\n new RegExp(`\\\\b[Ii]n\\\\s+${escapeRegex(value)}[,.]?\\\\s*`, 'g'),\n new RegExp(`\\\\b[Oo]n\\\\s+${escapeRegex(value)}[,.]?\\\\s*`, 'g'),\n new RegExp(`\\\\b[Dd]uring\\\\s+${escapeRegex(value)}[,.]?\\\\s*`, 'g'),\n new RegExp(`\\\\b[Bb]y\\\\s+${escapeRegex(value)}[,.]?\\\\s*`, 'g'),\n new RegExp(`\\\\b[Ss]ince\\\\s+${escapeRegex(value)}[,.]?\\\\s*`, 'g'),\n new RegExp(`\\\\b[Ff]rom\\\\s+${escapeRegex(value)}[,.]?\\\\s*`, 'g'),\n ];\n\n let desc = sentence;\n for (const pattern of prepositionPatterns) {\n desc = desc.replace(pattern, '');\n }\n if (desc === sentence) {\n desc = sentence.replace(value, '').trim();\n }\n\n desc = desc.replace(/^[,:\\-–—]+\\s*/, '').replace(/\\s*[,:\\-–—]+$/, '');\n desc = desc.replace(\n /\\s+(?:of|on|in|at|by|to|for|from|with|about|over|under|between|than|into|onto|upon)\\s*([,.])/gi,\n '$1',\n );\n desc = desc.replace(\n /\\s+(?:for|of|to|in|at|by|with|from|about|over|under|between|than|into|onto|upon)\\s*[.!?]?\\s*$/i,\n '.',\n );\n desc = desc.replace(/\\s{2,}/g, ' ').replace(/\\s+([,.])/g, '$1');\n desc = desc.charAt(0).toUpperCase() + desc.slice(1);\n return desc.trim();\n}\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nconst TYPE_SPECIFICITY: Record<ExtractionType, number> = {\n stat: 5,\n date: 4,\n quote: 3,\n definition: 3,\n comparison: 2,\n list: 2,\n impactLine: 2,\n fact: 1,\n};\n\nfunction deduplicateOverlapping(elements: ExtractedElement[]): ExtractedElement[] {\n if (elements.length <= 1) return elements;\n\n const toRemove = new Set<number>();\n\n for (let i = 0; i < elements.length; i++) {\n if (toRemove.has(i)) continue;\n const a = elements[i];\n\n for (let j = i + 1; j < elements.length; j++) {\n if (toRemove.has(j)) continue;\n const b = elements[j];\n\n if (elementsOverlap(a, b)) {\n const aSpec = TYPE_SPECIFICITY[a.type];\n const bSpec = TYPE_SPECIFICITY[b.type];\n if (aSpec >= bSpec) {\n toRemove.add(j);\n } else {\n toRemove.add(i);\n break;\n }\n }\n }\n }\n\n return elements.filter((_, index) => !toRemove.has(index));\n}\n\nfunction elementsOverlap(a: ExtractedElement, b: ExtractedElement): boolean {\n if (a.sourcePosition === b.sourcePosition) return true;\n if (a.sourcePosition <= b.sourcePosition && a.endPosition >= b.endPosition) return true;\n if (b.sourcePosition <= a.sourcePosition && b.endPosition >= a.endPosition) return true;\n\n const overlapStart = Math.max(a.sourcePosition, b.sourcePosition);\n const overlapEnd = Math.min(a.endPosition, b.endPosition);\n if (overlapEnd > overlapStart) {\n const overlapLength = overlapEnd - overlapStart;\n const minLength = Math.min(a.endPosition - a.sourcePosition, b.endPosition - b.sourcePosition);\n if (overlapLength > minLength * 0.5) return true;\n }\n\n return false;\n}\n\n/**\n * Strip markdown formatting from text, returning plain prose.\n * Call this before `extractContent` if the input is markdown.\n */\nexport function stripMarkdown(markdown: string): string {\n return (\n markdown\n // Remove code blocks (before inline code)\n .replace(/```[\\s\\S]*?```/g, '')\n // Remove images (before links — `![` prefix distinguishes them)\n .replace(/!\\[([^\\]]*)\\]\\([^)]+\\)/g, '')\n // Remove links, keeping text\n .replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1')\n .replace(/^#{1,6}\\s+/gm, '')\n .replace(/\\*\\*([^*]+)\\*\\*/g, '$1')\n .replace(/\\*([^*]+)\\*/g, '$1')\n .replace(/__([^_]+)__/g, '$1')\n .replace(/_([^_]+)_/g, '$1')\n .replace(/`([^`]+)`/g, '$1')\n .replace(/^>\\s+/gm, '')\n .replace(/^[-*_]{3,}$/gm, '')\n .replace(/\\n{3,}/g, '\\n\\n')\n .trim()\n );\n}\n","/**\n * Template Mapper\n *\n * Converts extracted content elements into squisq TemplateBlock inputs.\n * Each ExtractionType maps to a specific template from BlockTemplates.\n */\n\nimport type {\n ExtractedElement,\n StatData,\n DateData,\n QuoteData,\n ComparisonData,\n FactData,\n ImpactLineData,\n ListData,\n DefinitionData,\n} from './contentExtractor.js';\n\nimport type {\n StatHighlightInput,\n QuoteBlockInput,\n FactCardInput,\n TwoColumnInput,\n DateEventInput,\n FullBleedQuoteInput,\n ListBlockInput,\n DefinitionCardInput,\n TemplateBlock,\n ColorScheme,\n AccentImage,\n} from '../schemas/BlockTemplates.js';\n\n/** Options for mapping an element to a template block. */\nexport interface MapOptions {\n id: string;\n duration: number;\n audioSegment: number;\n colorScheme?: ColorScheme;\n accentImage?: AccentImage;\n sourceStartTime?: number;\n sourceDuration?: number;\n}\n\n/**\n * Convert an extracted element into the matching squisq TemplateBlock.\n */\nexport function mapElementToBlock(element: ExtractedElement, options: MapOptions): TemplateBlock {\n const base = {\n id: options.id,\n duration: options.duration,\n audioSegment: options.audioSegment,\n sourceStartTime: options.sourceStartTime,\n sourceDuration: options.sourceDuration,\n };\n\n switch (element.data.type) {\n case 'stat':\n return mapStat(element.data, base, options);\n case 'date':\n return mapDate(element.data, base, options);\n case 'quote':\n return mapQuote(element.data, base, options);\n case 'comparison':\n return mapComparison(element.data, base, options);\n case 'fact':\n return mapFact(element.data, base, options);\n case 'impactLine':\n return mapImpactLine(element.data, base, options);\n case 'list':\n return mapList(element.data, base, options);\n case 'definition':\n return mapDefinition(element.data, base, options);\n }\n}\n\n// ── Per-type mappers ───────────────────────────────────────────────\n\ntype Base = {\n id: string;\n duration: number;\n audioSegment: number;\n sourceStartTime?: number;\n sourceDuration?: number;\n};\n\nfunction mapStat(data: StatData, base: Base, opts: MapOptions): StatHighlightInput {\n return {\n ...base,\n template: 'statHighlight',\n stat: data.value,\n description: data.description,\n colorScheme: opts.colorScheme,\n accentImage: opts.accentImage,\n };\n}\n\nfunction mapDate(data: DateData, base: Base, opts: MapOptions): DateEventInput {\n return {\n ...base,\n template: 'dateEvent',\n date: data.date,\n description: data.description,\n mood: data.mood,\n accentImage: opts.accentImage,\n };\n}\n\nfunction mapQuote(data: QuoteData, base: Base, opts: MapOptions): QuoteBlockInput {\n return {\n ...base,\n template: 'quote',\n quote: data.quote,\n attribution: data.attribution,\n accentImage: opts.accentImage,\n };\n}\n\nfunction mapComparison(data: ComparisonData, base: Base, opts: MapOptions): TwoColumnInput {\n return {\n ...base,\n template: 'twoColumn',\n left: data.left,\n right: data.right,\n header: data.header,\n leftColor: opts.colorScheme,\n };\n}\n\nfunction mapFact(data: FactData, base: Base, opts: MapOptions): FactCardInput {\n return {\n ...base,\n template: 'factCard',\n fact: data.fact,\n explanation: data.explanation ?? '',\n accentImage: opts.accentImage,\n };\n}\n\nfunction mapImpactLine(data: ImpactLineData, base: Base, opts: MapOptions): FullBleedQuoteInput {\n return {\n ...base,\n template: 'fullBleedQuote',\n text: data.text,\n colorScheme: opts.colorScheme,\n };\n}\n\nfunction mapList(data: ListData, base: Base, opts: MapOptions): ListBlockInput {\n return {\n ...base,\n template: 'list',\n items: data.items,\n title: data.title,\n colorScheme: opts.colorScheme,\n accentImage: opts.accentImage,\n };\n}\n\nfunction mapDefinition(data: DefinitionData, base: Base, opts: MapOptions): DefinitionCardInput {\n return {\n ...base,\n template: 'definitionCard',\n term: data.term,\n definition: data.definition,\n origin: data.origin,\n colorScheme: opts.colorScheme,\n accentImage: opts.accentImage,\n };\n}\n"],"mappings":";AA+HA,IAAM,gBAAgB;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,gBAAgB;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,iBAAiB;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AACF;AASA,IAAM,kBAAkB;AAExB,IAAM,sBAAsB;AAAA,EAC1B,IAAI,OAAO,YAAY,eAAe,eAAe,eAAe,KAAK,IAAI;AAAA,EAC7E,IAAI,OAAO,IAAI,eAAe,8BAA8B,eAAe,KAAK,IAAI;AAAA,EACpF,IAAI,OAAO,IAAI,eAAe,2BAA2B,eAAe,KAAK,IAAI;AACnF;AAMA,IAAM,yBAAyB,oBAAI,IAAI;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,kBAAkB;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,oBAAoB;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,yBAAyB;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,eAAe;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,gBAAgB;AAAA,EACpB;AAAA,EACA;AACF;AAEA,IAAM,sBAAsB;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AASO,SAAS,eAAe,MAAc,UAA6B,CAAC,GAAqB;AAC9F,QAAM;AAAA,IACJ,gBAAgB;AAAA,IAChB,QAAQ,CAAC,QAAQ,QAAQ,SAAS,cAAc,QAAQ,cAAc,QAAQ,YAAY;AAAA,IAC1F;AAAA,EACF,IAAI;AAEJ,QAAM,WAA+B,CAAC;AAEtC,MAAI,MAAM,SAAS,MAAM,EAAG,UAAS,KAAK,GAAG,aAAa,IAAI,CAAC;AAC/D,MAAI,MAAM,SAAS,MAAM,EAAG,UAAS,KAAK,GAAG,aAAa,IAAI,CAAC;AAC/D,MAAI,MAAM,SAAS,OAAO,EAAG,UAAS,KAAK,GAAG,cAAc,IAAI,CAAC;AACjE,MAAI,MAAM,SAAS,YAAY,EAAG,UAAS,KAAK,GAAG,mBAAmB,IAAI,CAAC;AAC3E,MAAI,MAAM,SAAS,MAAM,EAAG,UAAS,KAAK,GAAG,aAAa,IAAI,CAAC;AAC/D,MAAI,MAAM,SAAS,YAAY,EAAG,UAAS,KAAK,GAAG,mBAAmB,IAAI,CAAC;AAC3E,MAAI,MAAM,SAAS,MAAM,EAAG,UAAS,KAAK,GAAG,aAAa,IAAI,CAAC;AAC/D,MAAI,MAAM,SAAS,YAAY,EAAG,UAAS,KAAK,GAAG,mBAAmB,IAAI,CAAC;AAE3E,MAAI,WAAW,SAAS,OAAO,CAAC,MAAM,EAAE,cAAc,aAAa;AAEnE,MAAI,eAAe,QAAW;AAC5B,UAAM,SAAS,oBAAI,IAAwC;AAC3D,eAAW,QAAQ,UAAU;AAC3B,YAAM,OAAO,OAAO,IAAI,KAAK,IAAI,KAAK,CAAC;AACvC,WAAK,KAAK,IAAI;AACd,aAAO,IAAI,KAAK,MAAM,IAAI;AAAA,IAC5B;AACA,eAAW,CAAC;AACZ,eAAW,CAAC,EAAE,IAAI,KAAK,QAAQ;AAC7B,WAAK,KAAK,CAAC,GAAG,MAAM,EAAE,aAAa,EAAE,UAAU;AAC/C,eAAS,KAAK,GAAG,KAAK,MAAM,GAAG,UAAU,CAAC;AAAA,IAC5C;AAAA,EACF;AAEA,WAAS,KAAK,CAAC,GAAG,MAAM,EAAE,iBAAiB,EAAE,cAAc;AAC3D,aAAW,uBAAuB,QAAQ;AAE1C,SAAO;AAAA,IACL,UAAU;AAAA,IACV,cAAc,KAAK;AAAA,IACnB,OAAO;AAAA,MACL,WAAW,SAAS,OAAO,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE;AAAA,MACrD,WAAW,SAAS,OAAO,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE;AAAA,MACrD,YAAY,SAAS,OAAO,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE;AAAA,MACvD,iBAAiB,SAAS,OAAO,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE;AAAA,MACjE,WAAW,SAAS,OAAO,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE;AAAA,MACrD,iBAAiB,SAAS,OAAO,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE;AAAA,MACjE,WAAW,SAAS,OAAO,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE;AAAA,MACrD,iBAAiB,SAAS,OAAO,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE;AAAA,MACjE,YAAY,SAAS;AAAA,IACvB;AAAA,EACF;AACF;AAIA,SAAS,aAAa,MAAkC;AACtD,QAAM,WAA+B,CAAC;AACtC,QAAM,OAAO,oBAAI,IAAY;AAE7B,aAAW,WAAW,eAAe;AACnC,YAAQ,YAAY;AACpB,QAAI;AACJ,YAAQ,QAAQ,QAAQ,KAAK,IAAI,OAAO,MAAM;AAC5C,YAAM,WAAW,MAAM;AACvB,UAAI,KAAK,IAAI,QAAQ,EAAG;AACxB,WAAK,IAAI,QAAQ;AAEjB,YAAM,UAAU,mBAAmB,MAAM,UAAU,MAAM,CAAC,EAAE,MAAM;AAClE,YAAM,QAAQ,MAAM,CAAC,EAAE,KAAK;AAE5B,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,MAAM,QAAQ;AAAA,QACd,YAAY,wBAAwB,OAAO,QAAQ,QAAQ;AAAA,QAC3D,gBAAgB,QAAQ;AAAA,QACxB,aAAa,QAAQ;AAAA,QACrB,MAAM,EAAE,MAAM,QAAQ,OAAO,aAAa,iBAAiB,QAAQ,UAAU,KAAK,EAAE;AAAA,MACtF,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,aAAa,MAAkC;AACtD,QAAM,WAA+B,CAAC;AACtC,QAAM,OAAO,oBAAI,IAAY;AAE7B,aAAW,WAAW,eAAe;AACnC,YAAQ,YAAY;AACpB,QAAI;AACJ,YAAQ,QAAQ,QAAQ,KAAK,IAAI,OAAO,MAAM;AAC5C,YAAM,WAAW,MAAM;AACvB,UAAI,KAAK,IAAI,QAAQ,EAAG;AACxB,WAAK,IAAI,QAAQ;AAEjB,YAAM,UAAU,mBAAmB,MAAM,UAAU,MAAM,CAAC,EAAE,MAAM;AAClE,YAAM,UAAU,MAAM,CAAC,EAAE,KAAK;AAE9B,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,MAAM,QAAQ;AAAA,QACd,YAAY,wBAAwB,SAAS,QAAQ,QAAQ;AAAA,QAC7D,gBAAgB,QAAQ;AAAA,QACxB,aAAa,QAAQ;AAAA,QACrB,MAAM;AAAA,UACJ,MAAM;AAAA,UACN,MAAM;AAAA,UACN,aAAa,iBAAiB,QAAQ,UAAU,OAAO;AAAA,UACvD,MAAM,WAAW,QAAQ,QAAQ;AAAA,QACnC;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,cAAc,MAAkC;AACvD,QAAM,WAA+B,CAAC;AACtC,QAAM,OAAO,oBAAI,IAAY;AAE7B,aAAW,WAAW,gBAAgB;AACpC,YAAQ,YAAY;AACpB,QAAI;AACJ,YAAQ,QAAQ,QAAQ,KAAK,IAAI,OAAO,MAAM;AAC5C,YAAM,WAAW,MAAM;AACvB,UAAI,KAAK,IAAI,QAAQ,EAAG;AACxB,WAAK,IAAI,QAAQ;AAEjB,YAAM,QAAQ,MAAM,SAAS,IAAI,MAAM,CAAC,IAAI,MAAM,CAAC;AACnD,YAAM,cAAc,MAAM,SAAS,IAAI,MAAM,CAAC,IAAI;AAClD,UAAI,MAAM,SAAS,MAAM,MAAM,SAAS,IAAK;AAE7C,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,MAAM,MAAM,CAAC;AAAA,QACb,YAAY,yBAAyB,KAAK;AAAA,QAC1C,gBAAgB;AAAA,QAChB,aAAa,WAAW,MAAM,CAAC,EAAE;AAAA,QACjC,MAAM,EAAE,MAAM,SAAS,OAAO,MAAM,KAAK,GAAG,aAAa,aAAa,KAAK,EAAE;AAAA,MAC/E,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,mBAAmB,MAAkC;AAC5D,QAAM,WAA+B,CAAC;AACtC,QAAM,OAAO,oBAAI,IAAY;AAE7B,aAAW,WAAW,qBAAqB;AACzC,YAAQ,YAAY;AACpB,QAAI;AACJ,YAAQ,QAAQ,QAAQ,KAAK,IAAI,OAAO,MAAM;AAC5C,YAAM,WAAW,MAAM;AACvB,UAAI,KAAK,IAAI,QAAQ,EAAG;AACxB,WAAK,IAAI,QAAQ;AAOjB,YAAM,aAAa,CAAC,MAAc,EAAE,QAAQ,WAAW,EAAE,EAAE,KAAK;AAChE,YAAM,OAAO,WAAW,MAAM,CAAC,EAAE,KAAK,CAAC;AACvC,YAAM,QAAQ,WAAW,MAAM,CAAC,EAAE,KAAK,CAAC;AACxC,UAAI,KAAK,SAAS,KAAK,KAAK,SAAS,GAAI;AACzC,UAAI,MAAM,SAAS,KAAK,MAAM,SAAS,GAAI;AAQ3C,YAAM,UAAU,CAAC,MACf,EACG,YAAY,EACZ,MAAM,KAAK,EACX,IAAI,CAAC,MAAM,EAAE,QAAQ,eAAe,EAAE,CAAC,EACvC,OAAO,OAAO;AACnB,YAAM,YAAY,QAAQ,IAAI;AAC9B,YAAM,aAAa,QAAQ,KAAK;AAChC,UACE,UAAU,SAAS,KACnB,WAAW,SAAS,KACpB,UAAU,UAAU,SAAS,CAAC,MAAM,WAAW,CAAC,GAChD;AACA;AAAA,MACF;AAEA,YAAM,UAAU,mBAAmB,MAAM,UAAU,MAAM,CAAC,EAAE,MAAM;AAElE,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,MAAM,QAAQ;AAAA,QACd,YAAY;AAAA,QACZ,gBAAgB,QAAQ;AAAA,QACxB,aAAa,QAAQ;AAAA,QACrB,MAAM,EAAE,MAAM,cAAc,MAAM,EAAE,OAAO,KAAK,GAAG,OAAO,EAAE,OAAO,MAAM,EAAE;AAAA,MAC7E,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;AAUA,SAAS,mBAAmB,MAAc,OAAwB;AAChE,QAAM,KAAK,KAAK,KAAK;AACrB,MAAI,OAAO,OAAO,OAAO,IAAK,QAAO;AACrC,MAAI,OAAO,IAAK,QAAO;AAGvB,MAAI,KAAK,QAAQ,CAAC,MAAM,IAAK,QAAO;AAEpC,MAAI,QAAQ,KAAK,KAAK,QAAQ,CAAC,KAAK,EAAE,KAAK,QAAQ,KAAK,KAAK,QAAQ,CAAC,KAAK,EAAE,EAAG,QAAO;AAGvF,MAAI,IAAI,QAAQ;AAChB,SAAO,KAAK,KAAK,WAAW,KAAK,KAAK,CAAC,CAAC,EAAG;AAC3C,QAAM,OAAO,KAAK,MAAM,IAAI,GAAG,KAAK;AACpC,MAAI,KAAK,WAAW,EAAG,QAAO;AAC9B,MAAI,QAAQ,uBAAuB,IAAI,KAAK,YAAY,CAAC,EAAG,QAAO;AAKnE,MAAI,IAAI,QAAQ;AAChB,SAAO,IAAI,KAAK,UAAU,KAAK,KAAK,KAAK,CAAC,CAAC,EAAG;AAC9C,MAAI,KAAK,KAAK,OAAQ,QAAO;AAC7B,SAAO,CAAC,QAAQ,KAAK,KAAK,CAAC,CAAC;AAC9B;AAUA,SAAS,oBACP,MACA,UACM;AACN,QAAM,OAAO,CAAC,UAAkB,WAAmB;AACjD,QAAI,QAAQ;AACZ,WAAO,QAAQ,UAAU,KAAK,KAAK,KAAK,KAAK,CAAC,EAAG;AACjD,QAAI,MAAM;AACV,WAAO,MAAM,SAAS,UAAU,KAAK,KAAK,MAAM,CAAC,CAAC,EAAG;AACrD,QAAI,OAAO,MAAO;AAClB,UAAM,UAAU,KAAK,MAAM,OAAO,GAAG;AACrC,QAAI,QAAS,UAAS,SAAS,OAAO,GAAG;AAAA,EAC3C;AAEA,MAAI,YAAY;AAChB,MAAI,IAAI;AACR,SAAO,IAAI,KAAK,QAAQ;AACtB,QAAI,mBAAmB,MAAM,CAAC,GAAG;AAE/B,UAAI,MAAM,IAAI;AACd,aAAO,MAAM,KAAK,UAAU,QAAQ,KAAK,KAAK,GAAG,CAAC,EAAG;AACrD,WAAK,WAAW,GAAG;AACnB,kBAAY;AACZ,UAAI;AAAA,IACN,OAAO;AACL;AAAA,IACF;AAAA,EACF;AACA,MAAI,YAAY,KAAK,OAAQ,MAAK,WAAW,KAAK,MAAM;AAC1D;AAEA,SAAS,aAAa,MAAkC;AACtD,QAAM,WAA+B,CAAC;AAEtC,sBAAoB,MAAM,CAAC,SAAS,OAAO,QAAQ;AACjD,QAAI,QAAQ,UAAU,GAAI;AAE1B,UAAM,QAAQ,oBAAoB,OAAO;AACzC,QAAI,QAAQ,IAAK;AAEjB,aAAS,KAAK;AAAA,MACZ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,aAAa;AAAA,MACb,MAAM,EAAE,MAAM,QAAQ,MAAM,QAAQ;AAAA,IACtC,CAAC;AAAA,EACH,CAAC;AAED,SAAO;AACT;AAEA,SAAS,mBAAmB,MAAkC;AAC5D,QAAM,WAA+B,CAAC;AAEtC,sBAAoB,MAAM,CAAC,SAAS,OAAO,QAAQ;AACjD,QAAI,QAAQ,SAAS,KAAK,QAAQ,SAAS,GAAI;AAE/C,QAAI,QAAQ;AACZ,UAAM,QAAQ,QAAQ,YAAY;AAElC,eAAW,QAAQ,cAAc;AAC/B,UAAI,MAAM,WAAW,IAAI,GAAG;AAC1B,iBAAS;AACT;AAAA,MACF;AAAA,IACF;AAEA,QAAI,MAAM,KAAK,UAAU,KAAK,GAAG,MAAM,IAAK,UAAS;AACrD,QAAI,QAAQ,SAAS,GAAI,UAAS;AAClC,QAAI,QAAQ,SAAS,GAAG,EAAG,UAAS;AACpC,QAAI,4BAA4B,KAAK,OAAO,EAAG,UAAS;AACxD,QAAI,QAAQ,IAAK;AAEjB,aAAS,KAAK;AAAA,MACZ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,YAAY,KAAK,IAAI,GAAG,KAAK;AAAA,MAC7B,gBAAgB;AAAA,MAChB,aAAa;AAAA,MACb,MAAM,EAAE,MAAM,cAAc,MAAM,QAAQ;AAAA,IAC5C,CAAC;AAAA,EACH,CAAC;AAED,SAAO;AACT;AAEA,SAAS,aAAa,MAAkC;AACtD,QAAM,WAA+B,CAAC;AACtC,QAAM,OAAO,oBAAI,IAAY;AAE7B,aAAW,WAAW,eAAe;AACnC,YAAQ,YAAY;AACpB,QAAI;AACJ,YAAQ,QAAQ,QAAQ,KAAK,IAAI,OAAO,MAAM;AAC5C,YAAM,WAAW,MAAM;AACvB,UAAI,KAAK,IAAI,QAAQ,EAAG;AACxB,WAAK,IAAI,QAAQ;AAEjB,YAAM,cAAc,MAAM,CAAC,EAAE,KAAK;AAClC,YAAM,QAAQ,YACX,MAAM,2CAA2C,EACjD,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,EACzB,OAAO,CAAC,SAAS,KAAK,UAAU,KAAK,KAAK,UAAU,EAAE;AAEzD,UAAI,MAAM,SAAS,KAAK,MAAM,SAAS,EAAG;AAE1C,YAAM,UAAU,mBAAmB,MAAM,UAAU,MAAM,CAAC,EAAE,MAAM;AAElE,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,MAAM,QAAQ;AAAA,QACd,YAAY;AAAA,QACZ,gBAAgB,QAAQ;AAAA,QACxB,aAAa,QAAQ;AAAA,QACrB,MAAM,EAAE,MAAM,QAAQ,MAAM;AAAA,MAC9B,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,mBAAmB,MAAkC;AAC5D,QAAM,WAA+B,CAAC;AACtC,QAAM,OAAO,oBAAI,IAAY;AAE7B,aAAW,WAAW,qBAAqB;AACzC,YAAQ,YAAY;AACpB,QAAI;AACJ,YAAQ,QAAQ,QAAQ,KAAK,IAAI,OAAO,MAAM;AAC5C,YAAM,WAAW,MAAM;AACvB,UAAI,KAAK,IAAI,QAAQ,EAAG;AACxB,WAAK,IAAI,QAAQ;AAEjB,YAAM,OAAO,MAAM,CAAC,EAAE,KAAK;AAC3B,YAAM,aAAa,MAAM,CAAC,EAAE,KAAK;AACjC,UAAI,KAAK,SAAS,KAAK,KAAK,SAAS,GAAI;AACzC,UAAI,WAAW,SAAS,MAAM,WAAW,SAAS,IAAK;AAEvD,YAAM,UAAU,mBAAmB,MAAM,UAAU,MAAM,CAAC,EAAE,MAAM;AAElE,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,MAAM,QAAQ;AAAA,QACd,YAAY;AAAA,QACZ,gBAAgB,QAAQ;AAAA,QACxB,aAAa,QAAQ;AAAA,QACrB,MAAM,EAAE,MAAM,cAAc,MAAM,WAAW;AAAA,MAC/C,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;AAIA,SAAS,mBACP,MACA,YACA,aACkD;AAClD,MAAI,QAAQ;AACZ,SAAO,QAAQ,KAAK,CAAC,mBAAmB,MAAM,QAAQ,CAAC,EAAG;AAC1D,SAAO,QAAQ,cAAc,KAAK,KAAK,KAAK,KAAK,CAAC,EAAG;AAErD,MAAI,MAAM,aAAa;AACvB,SAAO,MAAM,KAAK,UAAU,CAAC,mBAAmB,MAAM,GAAG,EAAG;AAC5D,MAAI,MAAM,KAAK,OAAQ;AAEvB,SAAO,EAAE,UAAU,KAAK,MAAM,OAAO,GAAG,EAAE,KAAK,GAAG,OAAO,IAAI;AAC/D;AAEA,SAAS,wBAAwB,OAAe,SAAyB;AACvE,MAAI,QAAQ;AACZ,MAAI,MAAM,SAAS,GAAG,EAAG,UAAS;AAClC,MAAI,4BAA4B,KAAK,KAAK,EAAG,UAAS;AACtD,MAAI,8CAA8C,KAAK,OAAO,EAAG,UAAS;AAC1E,MAAI,QAAQ,SAAS,GAAI,UAAS;AAClC,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,CAAC;AACvC;AAEA,SAAS,wBAAwB,MAAc,SAAyB;AACtE,MAAI,QAAQ;AACZ,MACE,yFAAyF;AAAA,IACvF;AAAA,EACF;AAEA,aAAS;AACX,MAAI,uDAAuD,KAAK,OAAO,EAAG,UAAS;AACnF,MAAI,4CAA4C,KAAK,OAAO,EAAG,UAAS;AACxE,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,CAAC;AACvC;AAEA,SAAS,yBAAyB,OAAuB;AACvD,MAAI,QAAQ;AACZ,MAAI,MAAM,UAAU,MAAM,MAAM,UAAU,IAAK,UAAS;AACxD,MAAI,qBAAqB,KAAK,KAAK,EAAG,UAAS;AAC/C,MAAI,CAAC,SAAS,KAAK,KAAK,EAAG,UAAS;AACpC,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,CAAC;AACvC;AAEA,SAAS,oBAAoB,UAA0B;AACrD,MAAI,QAAQ;AACZ,QAAM,QAAQ,SAAS,YAAY;AACnC,aAAW,aAAa,iBAAiB;AACvC,QAAI,MAAM,SAAS,SAAS,GAAG;AAC7B,eAAS;AACT;AAAA,IACF;AAAA,EACF;AACA,QAAM,cAAc,SAAS,MAAM,kBAAkB;AACrD,MAAI,eAAe,YAAY,UAAU,EAAG,UAAS;AACrD,MAAI,KAAK,KAAK,QAAQ,EAAG,UAAS;AAClC,MAAI,SAAS,SAAS,GAAG,EAAG,UAAS;AACrC,MAAI,SAAS,SAAS,IAAK,UAAS;AACpC,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,CAAC;AACvC;AAEA,SAAS,WAAW,UAAwD;AAC1E,QAAM,QAAQ,SAAS,YAAY;AACnC,aAAW,QAAQ,mBAAmB;AACpC,QAAI,MAAM,SAAS,IAAI,EAAG,QAAO;AAAA,EACnC;AACA,aAAW,QAAQ,wBAAwB;AACzC,QAAI,MAAM,SAAS,IAAI,EAAG,QAAO;AAAA,EACnC;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,UAAkB,OAAuB;AACjE,QAAM,sBAAsB;AAAA,IAC1B,IAAI,OAAO,eAAe,YAAY,KAAK,CAAC,aAAa,GAAG;AAAA,IAC5D,IAAI,OAAO,eAAe,YAAY,KAAK,CAAC,aAAa,GAAG;AAAA,IAC5D,IAAI,OAAO,mBAAmB,YAAY,KAAK,CAAC,aAAa,GAAG;AAAA,IAChE,IAAI,OAAO,eAAe,YAAY,KAAK,CAAC,aAAa,GAAG;AAAA,IAC5D,IAAI,OAAO,kBAAkB,YAAY,KAAK,CAAC,aAAa,GAAG;AAAA,IAC/D,IAAI,OAAO,iBAAiB,YAAY,KAAK,CAAC,aAAa,GAAG;AAAA,EAChE;AAEA,MAAI,OAAO;AACX,aAAW,WAAW,qBAAqB;AACzC,WAAO,KAAK,QAAQ,SAAS,EAAE;AAAA,EACjC;AACA,MAAI,SAAS,UAAU;AACrB,WAAO,SAAS,QAAQ,OAAO,EAAE,EAAE,KAAK;AAAA,EAC1C;AAEA,SAAO,KAAK,QAAQ,iBAAiB,EAAE,EAAE,QAAQ,iBAAiB,EAAE;AACpE,SAAO,KAAK;AAAA,IACV;AAAA,IACA;AAAA,EACF;AACA,SAAO,KAAK;AAAA,IACV;AAAA,IACA;AAAA,EACF;AACA,SAAO,KAAK,QAAQ,WAAW,GAAG,EAAE,QAAQ,cAAc,IAAI;AAC9D,SAAO,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC;AAClD,SAAO,KAAK,KAAK;AACnB;AAEA,SAAS,YAAY,KAAqB;AACxC,SAAO,IAAI,QAAQ,uBAAuB,MAAM;AAClD;AAEA,IAAM,mBAAmD;AAAA,EACvD,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,MAAM;AAAA,EACN,YAAY;AAAA,EACZ,MAAM;AACR;AAEA,SAAS,uBAAuB,UAAkD;AAChF,MAAI,SAAS,UAAU,EAAG,QAAO;AAEjC,QAAM,WAAW,oBAAI,IAAY;AAEjC,WAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,QAAI,SAAS,IAAI,CAAC,EAAG;AACrB,UAAM,IAAI,SAAS,CAAC;AAEpB,aAAS,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AAC5C,UAAI,SAAS,IAAI,CAAC,EAAG;AACrB,YAAM,IAAI,SAAS,CAAC;AAEpB,UAAI,gBAAgB,GAAG,CAAC,GAAG;AACzB,cAAM,QAAQ,iBAAiB,EAAE,IAAI;AACrC,cAAM,QAAQ,iBAAiB,EAAE,IAAI;AACrC,YAAI,SAAS,OAAO;AAClB,mBAAS,IAAI,CAAC;AAAA,QAChB,OAAO;AACL,mBAAS,IAAI,CAAC;AACd;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,SAAS,OAAO,CAAC,GAAG,UAAU,CAAC,SAAS,IAAI,KAAK,CAAC;AAC3D;AAEA,SAAS,gBAAgB,GAAqB,GAA8B;AAC1E,MAAI,EAAE,mBAAmB,EAAE,eAAgB,QAAO;AAClD,MAAI,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,eAAe,EAAE,YAAa,QAAO;AACnF,MAAI,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,eAAe,EAAE,YAAa,QAAO;AAEnF,QAAM,eAAe,KAAK,IAAI,EAAE,gBAAgB,EAAE,cAAc;AAChE,QAAM,aAAa,KAAK,IAAI,EAAE,aAAa,EAAE,WAAW;AACxD,MAAI,aAAa,cAAc;AAC7B,UAAM,gBAAgB,aAAa;AACnC,UAAM,YAAY,KAAK,IAAI,EAAE,cAAc,EAAE,gBAAgB,EAAE,cAAc,EAAE,cAAc;AAC7F,QAAI,gBAAgB,YAAY,IAAK,QAAO;AAAA,EAC9C;AAEA,SAAO;AACT;AAMO,SAAS,cAAc,UAA0B;AACtD,SACE,SAEG,QAAQ,mBAAmB,EAAE,EAE7B,QAAQ,2BAA2B,EAAE,EAErC,QAAQ,0BAA0B,IAAI,EACtC,QAAQ,gBAAgB,EAAE,EAC1B,QAAQ,oBAAoB,IAAI,EAChC,QAAQ,gBAAgB,IAAI,EAC5B,QAAQ,gBAAgB,IAAI,EAC5B,QAAQ,cAAc,IAAI,EAC1B,QAAQ,cAAc,IAAI,EAC1B,QAAQ,WAAW,EAAE,EACrB,QAAQ,iBAAiB,EAAE,EAC3B,QAAQ,WAAW,MAAM,EACzB,KAAK;AAEZ;;;ACz2BO,SAAS,kBAAkB,SAA2B,SAAoC;AAC/F,QAAM,OAAO;AAAA,IACX,IAAI,QAAQ;AAAA,IACZ,UAAU,QAAQ;AAAA,IAClB,cAAc,QAAQ;AAAA,IACtB,iBAAiB,QAAQ;AAAA,IACzB,gBAAgB,QAAQ;AAAA,EAC1B;AAEA,UAAQ,QAAQ,KAAK,MAAM;AAAA,IACzB,KAAK;AACH,aAAO,QAAQ,QAAQ,MAAM,MAAM,OAAO;AAAA,IAC5C,KAAK;AACH,aAAO,QAAQ,QAAQ,MAAM,MAAM,OAAO;AAAA,IAC5C,KAAK;AACH,aAAO,SAAS,QAAQ,MAAM,MAAM,OAAO;AAAA,IAC7C,KAAK;AACH,aAAO,cAAc,QAAQ,MAAM,MAAM,OAAO;AAAA,IAClD,KAAK;AACH,aAAO,QAAQ,QAAQ,MAAM,MAAM,OAAO;AAAA,IAC5C,KAAK;AACH,aAAO,cAAc,QAAQ,MAAM,MAAM,OAAO;AAAA,IAClD,KAAK;AACH,aAAO,QAAQ,QAAQ,MAAM,MAAM,OAAO;AAAA,IAC5C,KAAK;AACH,aAAO,cAAc,QAAQ,MAAM,MAAM,OAAO;AAAA,EACpD;AACF;AAYA,SAAS,QAAQ,MAAgB,MAAY,MAAsC;AACjF,SAAO;AAAA,IACL,GAAG;AAAA,IACH,UAAU;AAAA,IACV,MAAM,KAAK;AAAA,IACX,aAAa,KAAK;AAAA,IAClB,aAAa,KAAK;AAAA,IAClB,aAAa,KAAK;AAAA,EACpB;AACF;AAEA,SAAS,QAAQ,MAAgB,MAAY,MAAkC;AAC7E,SAAO;AAAA,IACL,GAAG;AAAA,IACH,UAAU;AAAA,IACV,MAAM,KAAK;AAAA,IACX,aAAa,KAAK;AAAA,IAClB,MAAM,KAAK;AAAA,IACX,aAAa,KAAK;AAAA,EACpB;AACF;AAEA,SAAS,SAAS,MAAiB,MAAY,MAAmC;AAChF,SAAO;AAAA,IACL,GAAG;AAAA,IACH,UAAU;AAAA,IACV,OAAO,KAAK;AAAA,IACZ,aAAa,KAAK;AAAA,IAClB,aAAa,KAAK;AAAA,EACpB;AACF;AAEA,SAAS,cAAc,MAAsB,MAAY,MAAkC;AACzF,SAAO;AAAA,IACL,GAAG;AAAA,IACH,UAAU;AAAA,IACV,MAAM,KAAK;AAAA,IACX,OAAO,KAAK;AAAA,IACZ,QAAQ,KAAK;AAAA,IACb,WAAW,KAAK;AAAA,EAClB;AACF;AAEA,SAAS,QAAQ,MAAgB,MAAY,MAAiC;AAC5E,SAAO;AAAA,IACL,GAAG;AAAA,IACH,UAAU;AAAA,IACV,MAAM,KAAK;AAAA,IACX,aAAa,KAAK,eAAe;AAAA,IACjC,aAAa,KAAK;AAAA,EACpB;AACF;AAEA,SAAS,cAAc,MAAsB,MAAY,MAAuC;AAC9F,SAAO;AAAA,IACL,GAAG;AAAA,IACH,UAAU;AAAA,IACV,MAAM,KAAK;AAAA,IACX,aAAa,KAAK;AAAA,EACpB;AACF;AAEA,SAAS,QAAQ,MAAgB,MAAY,MAAkC;AAC7E,SAAO;AAAA,IACL,GAAG;AAAA,IACH,UAAU;AAAA,IACV,OAAO,KAAK;AAAA,IACZ,OAAO,KAAK;AAAA,IACZ,aAAa,KAAK;AAAA,IAClB,aAAa,KAAK;AAAA,EACpB;AACF;AAEA,SAAS,cAAc,MAAsB,MAAY,MAAuC;AAC9F,SAAO;AAAA,IACL,GAAG;AAAA,IACH,UAAU;AAAA,IACV,MAAM,KAAK;AAAA,IACX,YAAY,KAAK;AAAA,IACjB,QAAQ,KAAK;AAAA,IACb,aAAa,KAAK;AAAA,IAClB,aAAa,KAAK;AAAA,EACpB;AACF;","names":[]}
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
extractPlainText,
|
|
3
3
|
findNodesByType,
|
|
4
4
|
walkMarkdownTree
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-HWVFJAAH.js";
|
|
6
6
|
|
|
7
7
|
// src/recommend/templates.ts
|
|
8
8
|
var EMPTY_PROFILE = Object.freeze({
|
|
@@ -189,4 +189,4 @@ export {
|
|
|
189
189
|
pickAutoTemplate,
|
|
190
190
|
recommendTemplatesForBlock
|
|
191
191
|
};
|
|
192
|
-
//# sourceMappingURL=chunk-
|
|
192
|
+
//# sourceMappingURL=chunk-UY7KGQ5R.js.map
|
|
@@ -118,12 +118,39 @@ function estimateNarrationDuration(text, wordsPerSecond = DEFAULT_WORDS_PER_SECO
|
|
|
118
118
|
return spokenWords / wordsPerSecond;
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
+
// src/timing/readingTime.ts
|
|
122
|
+
var DEFAULT_READING_WPM = 200;
|
|
123
|
+
function estimateReadingTime(text, options) {
|
|
124
|
+
const configuredWpm = options?.wordsPerMinute;
|
|
125
|
+
const wpm = typeof configuredWpm === "number" && configuredWpm > 0 ? configuredWpm : DEFAULT_READING_WPM;
|
|
126
|
+
const words = text.split(/\s+/).filter((w) => w.length > 0).length;
|
|
127
|
+
const minutes = words / wpm;
|
|
128
|
+
return {
|
|
129
|
+
words,
|
|
130
|
+
minutes,
|
|
131
|
+
seconds: Math.round(minutes * 60)
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
function estimateNarrationTime(text, options) {
|
|
135
|
+
const providedWps = options?.wordsPerSecond;
|
|
136
|
+
const wps = typeof providedWps === "number" && providedWps > 0 ? providedWps : DEFAULT_WORDS_PER_SECOND;
|
|
137
|
+
const spokenWords = countSpokenWords(text);
|
|
138
|
+
const totalSeconds = spokenWords / wps;
|
|
139
|
+
return {
|
|
140
|
+
spokenWords,
|
|
141
|
+
minutes: totalSeconds / 60,
|
|
142
|
+
seconds: Math.round(totalSeconds)
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
121
146
|
export {
|
|
122
147
|
DEFAULT_WORDS_PER_SECOND,
|
|
123
148
|
estimateSpokenWordCount,
|
|
124
149
|
countSpokenWords,
|
|
125
150
|
estimateTimeFromText,
|
|
126
151
|
calculatePrefixDuration,
|
|
127
|
-
estimateNarrationDuration
|
|
152
|
+
estimateNarrationDuration,
|
|
153
|
+
estimateReadingTime,
|
|
154
|
+
estimateNarrationTime
|
|
128
155
|
};
|
|
129
|
-
//# sourceMappingURL=chunk-
|
|
156
|
+
//# sourceMappingURL=chunk-VWUFZ6ZG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/timing/narrationTiming.ts","../src/timing/readingTime.ts"],"sourcesContent":["/**\n * Narration timing estimation.\n *\n * Estimates how long text takes to speak aloud, accounting for:\n * - Numbers spoken as multiple words (e.g., \"1910\" → \"nineteen ten\")\n * - Pauses at commas\n * - Year pronunciation conventions (1000–2099)\n *\n * Ported from qualla-internal's AudioTiming.ts (pure functions, no Node.js deps).\n */\n\n/** Numbers are spoken more slowly than regular words (1.3× multiplier). */\nconst NUMBER_SPEAKING_MULTIPLIER = 1.3;\n\n/** Comma pause in \"word equivalents\" — speakers pause ~0.3 words at commas. */\nconst COMMA_PAUSE_PENALTY = 0.3;\n\n/** Default speaking rate in words per second (~150 WPM). */\nexport const DEFAULT_WORDS_PER_SECOND = 2.5;\n\n/**\n * Estimate how many \"spoken word equivalents\" a single token represents.\n * Numbers get expanded (e.g., \"175,000\" → ~5 words × 1.3 multiplier).\n */\nexport function estimateSpokenWordCount(token: string): number {\n const cleaned = token.replace(/,/g, '');\n const num = parseFloat(cleaned);\n\n if (isNaN(num) || !isFinite(num)) {\n return 1; // Not a number — count as 1 word\n }\n\n return estimateNumberWordCount(cleaned, num) * NUMBER_SPEAKING_MULTIPLIER;\n}\n\n/**\n * Raw word count for a number (before the speaking multiplier).\n */\nfunction estimateNumberWordCount(cleaned: string, num: number): number {\n // Handle decimals: \"3.14\" → words(\"3\") + \"point\" + 2 digits\n if (cleaned.includes('.')) {\n const [whole, decimal] = cleaned.split('.');\n const wholeNum = parseFloat(whole) || 0;\n return estimateNumberWordCount(whole, wholeNum) + 1 + decimal.length;\n }\n\n const absNum = Math.abs(num);\n let words = num < 0 ? 1 : 0; // \"negative\" / \"minus\"\n\n if (absNum === 0) return 1; // \"zero\"\n\n // Years (1000–2099) are spoken as two two-digit groups:\n // \"1910\" → \"nineteen ten\", \"2024\" → \"twenty twenty-four\"\n if (absNum >= 1000 && absNum <= 2099 && Number.isInteger(absNum)) {\n const yearStr = absNum.toString();\n if (yearStr.length === 4) {\n const firstTwo = parseInt(yearStr.slice(0, 2));\n const lastTwo = parseInt(yearStr.slice(2));\n\n // First part\n if (firstTwo >= 10 && firstTwo <= 19) {\n words += 1;\n } else if (firstTwo >= 20 && firstTwo <= 99) {\n words += firstTwo % 10 === 0 ? 1 : 2;\n } else {\n words += 2; // \"two thousand\"\n }\n\n // Second part\n if (lastTwo === 0) {\n if (firstTwo >= 10 && firstTwo <= 99 && firstTwo !== 20) {\n words += 1; // \"hundred\"\n }\n } else if (lastTwo >= 1 && lastTwo <= 9) {\n words += 2; // \"oh five\"\n } else if (lastTwo >= 10 && lastTwo <= 19) {\n words += 1;\n } else {\n words += lastTwo % 10 === 0 ? 1 : 2;\n }\n\n return Math.max(words, 2);\n }\n }\n\n // General number handling — each magnitude group adds words\n let remaining = absNum;\n\n if (remaining >= 1_000_000_000) {\n const billions = Math.floor(remaining / 1_000_000_000);\n words += estimateNumberWordCount(String(billions), billions);\n words += 1; // \"billion\"\n remaining %= 1_000_000_000;\n }\n\n if (remaining >= 1_000_000) {\n const millions = Math.floor(remaining / 1_000_000);\n words += estimateNumberWordCount(String(millions), millions);\n words += 1; // \"million\"\n remaining %= 1_000_000;\n }\n\n if (remaining >= 1_000) {\n const thousands = Math.floor(remaining / 1_000);\n words += estimateNumberWordCount(String(thousands), thousands);\n words += 1; // \"thousand\"\n remaining %= 1_000;\n }\n\n if (remaining >= 100) {\n words += 2; // digit + \"hundred\"\n remaining %= 100;\n }\n\n if (remaining >= 1) {\n if (remaining >= 20) {\n words += remaining % 10 === 0 ? 1 : 2;\n } else {\n words += 1; // 1–19\n }\n }\n\n return Math.max(words, 1);\n}\n\n/**\n * Count \"spoken word equivalents\" in a block of text,\n * expanding numbers and adding comma pauses.\n */\nexport function countSpokenWords(text: string): number {\n const tokens = text.split(/\\s+/).filter((w) => w.length > 0);\n let count = 0;\n\n for (const token of tokens) {\n // Strip punctuation only at token boundaries so internal punctuation\n // (e.g., decimals like \"3.14\" or digit-grouping commas \"1,000\") is preserved.\n const stripped = token.replace(/^[.,!?;:'\"()[\\]{}]+|[.,!?;:'\"()[\\]{}]+$/g, '');\n count += estimateSpokenWordCount(stripped);\n\n // Count only punctuation commas for pauses: exclude digit-grouping commas\n // (i.e., commas with digits on both sides, like in \"1,234\").\n let punctuationCommaCount = 0;\n for (let i = 0; i < token.length; i++) {\n if (token[i] === ',') {\n const prev = i > 0 ? token[i - 1] : '';\n const next = i < token.length - 1 ? token[i + 1] : '';\n const prevIsDigit = prev >= '0' && prev <= '9';\n const nextIsDigit = next >= '0' && next <= '9';\n if (!(prevIsDigit && nextIsDigit)) {\n punctuationCommaCount++;\n }\n }\n }\n count += punctuationCommaCount * COMMA_PAUSE_PENALTY;\n }\n\n return count;\n}\n\n/**\n * Estimate audio time at a character offset using word-proportion mapping.\n *\n * Given the full source text and a character position, returns the\n * estimated time (in seconds) at which that position would be spoken.\n *\n * @param text - Full source text\n * @param charOffset - Character offset to estimate timing for\n * @param totalDuration - Total audio duration in seconds\n * @returns Estimated time in seconds\n */\nexport function estimateTimeFromText(\n text: string,\n charOffset: number,\n totalDuration: number,\n): number {\n const textBefore = text.slice(0, charOffset);\n const spokenWordsBefore = countSpokenWords(textBefore);\n const totalSpokenWords = countSpokenWords(text);\n\n if (totalSpokenWords === 0) return 0;\n return (spokenWordsBefore / totalSpokenWords) * totalDuration;\n}\n\n/**\n * Estimate how long a spoken prefix adds to audio duration.\n *\n * When audio includes a spoken title or header before the main content,\n * this calculates the extra duration to offset timing calculations.\n *\n * @param prefix - Prefix text (e.g., an article title spoken before the body)\n * @param wordsPerSecond - Speaking rate (default: 2.5)\n * @returns Estimated duration in seconds\n */\nexport function calculatePrefixDuration(\n prefix: string,\n wordsPerSecond: number = DEFAULT_WORDS_PER_SECOND,\n): number {\n if (!prefix) return 0;\n\n const words = prefix.split(/\\s+/).filter((w) => w.length > 0);\n const newlineCount = (prefix.match(/\\n\\n/g) || []).length;\n const pauseTime = newlineCount * 0.5;\n\n return words.length / wordsPerSecond + pauseTime;\n}\n\n/**\n * Estimate narration duration for a block of text.\n *\n * @param text - The text to estimate\n * @param wordsPerSecond - Speaking rate (default: 2.5, i.e. ~150 WPM)\n * @returns Duration in seconds\n */\nexport function estimateNarrationDuration(\n text: string,\n wordsPerSecond: number = DEFAULT_WORDS_PER_SECOND,\n): number {\n const spokenWords = countSpokenWords(text);\n return spokenWords / wordsPerSecond;\n}\n","/**\n * Reading time estimation.\n *\n * Estimates how long it takes to read text silently vs. narrate it aloud.\n * Uses configurable words-per-minute rates.\n */\n\nimport { countSpokenWords, DEFAULT_WORDS_PER_SECOND } from './narrationTiming.js';\n\n/** Default silent reading rate (adults average ~200–250 WPM). */\nconst DEFAULT_READING_WPM = 200;\n\n/** Result of a reading-time estimate. */\nexport interface ReadingTimeEstimate {\n /** Number of words (plain word count, not spoken equivalents). */\n words: number;\n /** Estimated minutes (decimal). */\n minutes: number;\n /** Estimated seconds (rounded). */\n seconds: number;\n}\n\n/** Options for reading-time estimation. */\nexport interface ReadingTimeOptions {\n /** Words per minute for silent reading (default: 200). */\n wordsPerMinute?: number;\n}\n\n/**\n * Estimate silent reading time for a block of text.\n *\n * @param text - The text to estimate\n * @param options - Optional configuration\n * @returns Word count + time estimate\n */\nexport function estimateReadingTime(\n text: string,\n options?: ReadingTimeOptions,\n): ReadingTimeEstimate {\n const configuredWpm = options?.wordsPerMinute;\n const wpm =\n typeof configuredWpm === 'number' && configuredWpm > 0 ? configuredWpm : DEFAULT_READING_WPM;\n const words = text.split(/\\s+/).filter((w) => w.length > 0).length;\n const minutes = words / wpm;\n\n return {\n words,\n minutes,\n seconds: Math.round(minutes * 60),\n };\n}\n\n/** Result of a narration-time estimate. */\nexport interface NarrationTimeEstimate {\n /** Spoken word equivalents (numbers expanded, comma pauses added). */\n spokenWords: number;\n /** Estimated minutes (decimal). */\n minutes: number;\n /** Estimated seconds (rounded). */\n seconds: number;\n}\n\n/** Options for narration-time estimation. */\nexport interface NarrationTimeOptions {\n /** Words per second for narration (default: 2.5 ≈ 150 WPM). */\n wordsPerSecond?: number;\n}\n\n/**\n * Estimate narration (spoken) time for a block of text.\n *\n * Unlike silent reading, this accounts for numbers being spoken as\n * multiple words and pauses at commas.\n *\n * @param text - The text to estimate\n * @param options - Optional configuration\n * @returns Spoken word equivalents + time estimate\n */\nexport function estimateNarrationTime(\n text: string,\n options?: NarrationTimeOptions,\n): NarrationTimeEstimate {\n const providedWps = options?.wordsPerSecond;\n const wps =\n typeof providedWps === 'number' && providedWps > 0 ? providedWps : DEFAULT_WORDS_PER_SECOND;\n const spokenWords = countSpokenWords(text);\n const totalSeconds = spokenWords / wps;\n\n return {\n spokenWords,\n minutes: totalSeconds / 60,\n seconds: Math.round(totalSeconds),\n };\n}\n"],"mappings":"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","names":[]}
|
package/dist/doc/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { AccentLayout, AudioSegmentTiming, CONTAINER_TEMPLATES, ClipBox, ConnectorRouting, CoverBlockInput, DEFAULT_LAYOUT, DataFenceParseResult, DeriveTemplateInputsOptions, DiagramEdge, DiagramLayout, DiagramLayoutOptions, DiagramNodePosition, DocStylePreset, DrawingConnector, DrawingLayout, DrawingLayoutOptions, DrawingShape, DrawingShapeKind, ExpandDocBlocksOptions, ExtractedTableData, FirstImage, LayoutLayerDefaults, LayoutLayersResult, MarkdownToDocOptions, MarkdownValidationResult, PATH_SHAPE_KINDS, RenderContext, RuntimeTemplateRegistry, SHAPE_NAMES, TEMPLATE_ALIASES, TEMPLATE_METADATA, TemplateMetadata, ValidateOptions, adjustY, applyRenderStyleToLayers, buildRegistry, clipEndpoints, clipPoint, comparisonBar, computeDiagramLayout, computeDrawingLayout, computeLayoutLayers, connectorPath, countBlocks, coverBlock, createAccentLayers, cssFilterForTreatment, dataTable, dateEvent, decodeLayersFromFrontmatter, definitionCard, deriveTemplateInputs, diagramBlock, docToMarkdown, drawingBlock, encodeLayersForFrontmatter, expandCoverBlock, expandDocBlocks, expandPersistentLayers, expandTemplateBlock, extractBlockquoteText, extractBodyPlainText, extractFirstImage, extractImages, extractListItems, extractTableData, extractTableFromContents, factCard, fallbackBlockLayers, findFirstTable, flattenBlocks, flattenRenderableBlocks, fullBleedQuote, getAccentLayout, getAnimationProgress, getAnimationStyle, getAvailableTemplates, getBlockDepth, getDefaultAnimation, getDefaultAnimationDuration, getDocStyleConfig, getLayers, getOverlayOpacity, getPersistentLayersFromTheme, getTemplateHint, getThemeFont, getTransitionClass, hasTemplate, imageWithCaption, isContainerTemplate, isDataFence, isShapeName, layoutBlock, leftFeature, lineStyleDasharray, listBlock, mapBlock, markdownToDoc, markerPath, normalizeShapeKind, parseDataFence, parseYamlSubset, photoGrid, pullQuote, quoteBlock, readCustomTemplatesFromFrontmatter, readCustomThemesFromFrontmatter, resolveAudioMapping, resolveColorScheme, resolvePersistentLayers, resolveTemplateName, resolveThemeForDoc, rightFeature, scaleAnimationDuration, scoreTextSimilarity, sectionHeader, shapePath, shouldUseShadow, statHighlight, templateRegistry, themeWantsAmbientMotion, themedEntrance, themedFontSize, themedImageTreatment, themedScrim, themedSurfaceGradient, titleBlock, twoColumn, validateMarkdownDoc, validateMarkdownSource, videoPullQuote, videoWithCaption, wrapWithPersistentLayers, writeCustomTemplatesToFrontmatter, writeCustomThemesToFrontmatter } from '../story/index.js';
|
|
2
|
-
export { D as DEFAULT_THEME, g as getAvailableThemes, b as getThemeSummaries, r as resolveTheme } from '../themeLibrary-
|
|
3
|
-
export {
|
|
1
|
+
export { AccentLayout, AudioSegmentTiming, BASE_INPUT_DESCRIPTORS, CONTAINER_TEMPLATES, ClipBox, ConnectorRouting, CoverBlockInput, DEFAULT_LAYOUT, DataFenceParseResult, DeriveTemplateInputsOptions, DiagramEdge, DiagramLayout, DiagramLayoutOptions, DiagramNodePosition, DocStylePreset, DrawingConnector, DrawingLayout, DrawingLayoutOptions, DrawingShape, DrawingShapeKind, ExpandDocBlocksOptions, ExtractedTableData, FirstImage, InputCoercion, LayoutLayerDefaults, LayoutLayersResult, MarkdownToDocOptions, MarkdownValidationResult, PATH_SHAPE_KINDS, RenderContext, RuntimeTemplateRegistry, SHAPE_NAMES, TEMPLATE_ALIASES, TEMPLATE_INPUT_DESCRIPTORS, TEMPLATE_METADATA, TemplateInputDescriptor, TemplateMetadata, TemplateParamFinding, ValidateOptions, adjustY, applyRenderStyleToLayers, buildRegistry, clipEndpoints, clipPoint, coerceTemplateParams, comparisonBar, computeDiagramLayout, computeDrawingLayout, computeLayoutLayers, connectorPath, countBlocks, coverBlock, createAccentLayers, cssFilterForTreatment, dataTable, dateEvent, decodeLayersFromFrontmatter, definitionCard, deriveTemplateInputs, diagramBlock, docToMarkdown, drawingBlock, encodeLayersForFrontmatter, expandCoverBlock, expandDocBlocks, expandPersistentLayers, expandTemplateBlock, extractBlockquoteText, extractBodyPlainText, extractFirstImage, extractImages, extractListItems, extractTableData, extractTableFromContents, factCard, fallbackBlockLayers, findFirstTable, flattenBlocks, flattenRenderableBlocks, fullBleedQuote, getAccentLayout, getAnimationProgress, getAnimationStyle, getAvailableTemplates, getBlockDepth, getDefaultAnimation, getDefaultAnimationDuration, getDocStyleConfig, getLayers, getOverlayOpacity, getPersistentLayersFromTheme, getTemplateHint, getThemeFont, getTransitionClass, hasTemplate, imageWithCaption, isContainerTemplate, isDataFence, isShapeName, layoutBlock, leftFeature, lineStyleDasharray, lintTemplateParams, listBlock, mapBlock, markdownToDoc, markerPath, normalizeShapeKind, parseDataFence, parseYamlSubset, photoGrid, pullQuote, quoteBlock, readCustomTemplatesFromFrontmatter, readCustomThemesFromFrontmatter, replaceDataFence, resolveAudioMapping, resolveColorScheme, resolvePersistentLayers, resolveTemplateName, resolveThemeForDoc, rightFeature, scaleAnimationDuration, scoreTextSimilarity, sectionHeader, shapePath, shouldUseShadow, statHighlight, templateRegistry, themeWantsAmbientMotion, themedEntrance, themedFontSize, themedImageTreatment, themedScrim, themedSurfaceGradient, titleBlock, twoColumn, validateMarkdownDoc, validateMarkdownSource, videoPullQuote, videoWithCaption, wrapWithPersistentLayers, writeCustomTemplatesToFrontmatter, writeCustomThemesToFrontmatter } from '../story/index.js';
|
|
2
|
+
export { D as DEFAULT_THEME, g as getAvailableThemes, b as getThemeSummaries, r as resolveTheme } from '../themeLibrary-CehcJhzz.js';
|
|
3
|
+
export { z as DocBlock, G as FRONTMATTER_CUSTOM_TEMPLATES_KEY, H as FRONTMATTER_CUSTOM_THEMES_KEY, U as LayoutHints, a5 as PersistentLayerConfig, af as RenderStyle, at as TemplateBlock, au as TemplateContext, az as Theme, aA as ThemeColorPalette, aB as ThemeColorScheme, aE as ThemeStyle, aF as ThemeTypography, aJ as VIEWPORT_PRESETS, aN as ViewportConfig, aO as ViewportOrientation, aP as ViewportPreset, aU as createTemplateContext, a_ as getLayoutHints, b2 as getTwoColumnPositions, b3 as getViewport, b4 as getViewportOrientation, b6 as isTemplateBlock, bb as scaledFontSize } from '../Doc-BBVGq1_9.js';
|
|
4
4
|
import '../types-DlAZ7MW4.js';
|
|
5
|
-
import '../ContentContainer-
|
|
5
|
+
import '../ContentContainer-BXUlIf18.js';
|
package/dist/doc/index.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
|
+
BASE_INPUT_DESCRIPTORS,
|
|
2
3
|
CONTAINER_TEMPLATES,
|
|
3
4
|
DEFAULT_LAYOUT,
|
|
4
5
|
SHAPE_NAMES,
|
|
5
6
|
TEMPLATE_ALIASES,
|
|
7
|
+
TEMPLATE_INPUT_DESCRIPTORS,
|
|
6
8
|
TEMPLATE_METADATA,
|
|
7
9
|
adjustY,
|
|
8
10
|
applyRenderStyleToLayers,
|
|
9
11
|
buildRegistry,
|
|
12
|
+
coerceTemplateParams,
|
|
10
13
|
comparisonBar,
|
|
11
14
|
computeDiagramLayout,
|
|
12
15
|
computeDrawingLayout,
|
|
@@ -62,6 +65,7 @@ import {
|
|
|
62
65
|
isShapeName,
|
|
63
66
|
layoutBlock,
|
|
64
67
|
leftFeature,
|
|
68
|
+
lintTemplateParams,
|
|
65
69
|
listBlock,
|
|
66
70
|
mapBlock,
|
|
67
71
|
markdownToDoc,
|
|
@@ -73,6 +77,7 @@ import {
|
|
|
73
77
|
quoteBlock,
|
|
74
78
|
readCustomTemplatesFromFrontmatter,
|
|
75
79
|
readCustomThemesFromFrontmatter,
|
|
80
|
+
replaceDataFence,
|
|
76
81
|
resolveAudioMapping,
|
|
77
82
|
resolveColorScheme,
|
|
78
83
|
resolvePersistentLayers,
|
|
@@ -100,8 +105,8 @@ import {
|
|
|
100
105
|
wrapWithPersistentLayers,
|
|
101
106
|
writeCustomTemplatesToFrontmatter,
|
|
102
107
|
writeCustomThemesToFrontmatter
|
|
103
|
-
} from "../chunk-
|
|
104
|
-
import "../chunk-
|
|
108
|
+
} from "../chunk-LH7I6SH7.js";
|
|
109
|
+
import "../chunk-UY7KGQ5R.js";
|
|
105
110
|
import "../chunk-V543AI2F.js";
|
|
106
111
|
import "../chunk-FVTQSNR7.js";
|
|
107
112
|
import {
|
|
@@ -120,7 +125,7 @@ import {
|
|
|
120
125
|
getAvailableThemes,
|
|
121
126
|
getThemeSummaries,
|
|
122
127
|
resolveTheme
|
|
123
|
-
} from "../chunk-
|
|
128
|
+
} from "../chunk-KKNUBQ6Y.js";
|
|
124
129
|
import {
|
|
125
130
|
VIEWPORT_PRESETS,
|
|
126
131
|
createTemplateContext,
|
|
@@ -131,13 +136,13 @@ import {
|
|
|
131
136
|
isTemplateBlock,
|
|
132
137
|
scaledFontSize2 as scaledFontSize
|
|
133
138
|
} from "../chunk-DLXZMS5K.js";
|
|
134
|
-
import "../chunk-
|
|
135
|
-
import "../chunk-
|
|
139
|
+
import "../chunk-TEEEILMP.js";
|
|
140
|
+
import "../chunk-HWVFJAAH.js";
|
|
136
141
|
import "../chunk-DBS6RIFL.js";
|
|
137
142
|
import "../chunk-QE7TWGVT.js";
|
|
138
|
-
import "../chunk-
|
|
139
|
-
import "../chunk-3E5F2XMR.js";
|
|
143
|
+
import "../chunk-VWUFZ6ZG.js";
|
|
140
144
|
export {
|
|
145
|
+
BASE_INPUT_DESCRIPTORS,
|
|
141
146
|
CONTAINER_TEMPLATES,
|
|
142
147
|
DEFAULT_LAYOUT,
|
|
143
148
|
DEFAULT_THEME,
|
|
@@ -146,6 +151,7 @@ export {
|
|
|
146
151
|
PATH_SHAPE_KINDS,
|
|
147
152
|
SHAPE_NAMES,
|
|
148
153
|
TEMPLATE_ALIASES,
|
|
154
|
+
TEMPLATE_INPUT_DESCRIPTORS,
|
|
149
155
|
TEMPLATE_METADATA,
|
|
150
156
|
VIEWPORT_PRESETS,
|
|
151
157
|
adjustY,
|
|
@@ -153,6 +159,7 @@ export {
|
|
|
153
159
|
buildRegistry,
|
|
154
160
|
clipEndpoints,
|
|
155
161
|
clipPoint,
|
|
162
|
+
coerceTemplateParams,
|
|
156
163
|
comparisonBar,
|
|
157
164
|
computeDiagramLayout,
|
|
158
165
|
computeDrawingLayout,
|
|
@@ -218,6 +225,7 @@ export {
|
|
|
218
225
|
layoutBlock,
|
|
219
226
|
leftFeature,
|
|
220
227
|
lineStyleDasharray,
|
|
228
|
+
lintTemplateParams,
|
|
221
229
|
listBlock,
|
|
222
230
|
mapBlock,
|
|
223
231
|
markdownToDoc,
|
|
@@ -230,6 +238,7 @@ export {
|
|
|
230
238
|
quoteBlock,
|
|
231
239
|
readCustomTemplatesFromFrontmatter,
|
|
232
240
|
readCustomThemesFromFrontmatter,
|
|
241
|
+
replaceDataFence,
|
|
233
242
|
resolveAudioMapping,
|
|
234
243
|
resolveColorScheme,
|
|
235
244
|
resolvePersistentLayers,
|
package/dist/generate/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { E as ExtractedElement } from '../contentExtractor-BNfVJV2U.js';
|
|
2
2
|
export { C as ComparisonData, D as DateData, a as DefinitionData, b as ExtractionOptions, c as ExtractionResult, d as ExtractionType, F as FactData, I as ImpactLineData, L as ListData, Q as QuoteData, S as StatData, e as extractContent, s as stripMarkdown } from '../contentExtractor-BNfVJV2U.js';
|
|
3
|
-
import { m as ColorScheme, A as AccentImage,
|
|
3
|
+
import { m as ColorScheme, A as AccentImage, at as TemplateBlock } from '../Doc-BBVGq1_9.js';
|
|
4
4
|
import '../types-DlAZ7MW4.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -25,82 +25,4 @@ interface MapOptions {
|
|
|
25
25
|
*/
|
|
26
26
|
declare function mapElementToBlock(element: ExtractedElement, options: MapOptions): TemplateBlock;
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
* Slideshow Generator
|
|
30
|
-
*
|
|
31
|
-
* Turns plain text + optional images into a complete squisq `Doc`.
|
|
32
|
-
*
|
|
33
|
-
* Pipeline:
|
|
34
|
-
* 1. Strip markdown (if needed)
|
|
35
|
-
* 2. Extract compelling content (stats, dates, quotes, …)
|
|
36
|
-
* 3. Estimate narration timing
|
|
37
|
-
* 4. Map extractions → template blocks
|
|
38
|
-
* 5. Interleave image slides
|
|
39
|
-
* 6. Return a ready-to-render `Doc`
|
|
40
|
-
*/
|
|
41
|
-
|
|
42
|
-
/** A Doc variant whose blocks are TemplateBlocks (no startTime required). */
|
|
43
|
-
type SlideshowDoc = Omit<Doc, 'blocks'> & {
|
|
44
|
-
blocks: TemplateBlock[];
|
|
45
|
-
};
|
|
46
|
-
/** Image metadata passed to the generator. */
|
|
47
|
-
interface SlideshowImage {
|
|
48
|
-
/** Image source path or URL. */
|
|
49
|
-
src: string;
|
|
50
|
-
/** Alt text for accessibility. */
|
|
51
|
-
alt?: string;
|
|
52
|
-
/** Photo credit. */
|
|
53
|
-
credit?: string;
|
|
54
|
-
/** License identifier. */
|
|
55
|
-
license?: string;
|
|
56
|
-
}
|
|
57
|
-
/** Options for `generateSlideshow`. */
|
|
58
|
-
interface SlideshowOptions {
|
|
59
|
-
/** Deterministic seed (default: hash of the text). */
|
|
60
|
-
seed?: number;
|
|
61
|
-
/** Title slide text. Omit to skip the title slide. */
|
|
62
|
-
title?: string;
|
|
63
|
-
/** Subtitle for the title slide. */
|
|
64
|
-
subtitle?: string;
|
|
65
|
-
/** Explicit total duration in seconds. When omitted, estimated from text. */
|
|
66
|
-
duration?: number;
|
|
67
|
-
/** Target number of content slides (default: 5–8, auto-scaled). */
|
|
68
|
-
targetSlides?: number;
|
|
69
|
-
/** Color schemes to rotate (default: ['blue','green','purple','orange','red']). */
|
|
70
|
-
colorSchemes?: ColorScheme[];
|
|
71
|
-
/** Ambient motions to rotate on images. */
|
|
72
|
-
ambientMotions?: Array<'zoomIn' | 'zoomOut' | 'panLeft' | 'panRight'>;
|
|
73
|
-
/** Accent positions to rotate on text slides. */
|
|
74
|
-
accentPositions?: AccentPosition[];
|
|
75
|
-
/** Minimum slide duration in seconds (default: 4). */
|
|
76
|
-
minSlideDuration?: number;
|
|
77
|
-
/** Maximum slide duration in seconds (default: 15). */
|
|
78
|
-
maxSlideDuration?: number;
|
|
79
|
-
/** Theme identifier to embed in the Doc. */
|
|
80
|
-
themeId?: string;
|
|
81
|
-
/** Whether the input text is markdown (default: false). */
|
|
82
|
-
isMarkdown?: boolean;
|
|
83
|
-
/** Minimum extraction confidence (default: 0.3). */
|
|
84
|
-
minConfidence?: number;
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Generate a slideshow `Doc` from text and optional images.
|
|
88
|
-
*
|
|
89
|
-
* @deprecated Prefer the transform pipeline: convert content with
|
|
90
|
-
* `markdownToDoc` (content-aware auto templates are on by default) and
|
|
91
|
-
* shape it with `applyTransform` from `@bendyline/squisq/transform` —
|
|
92
|
-
* one engine for text→slides, with styles, theme pairing, pacing, and a
|
|
93
|
-
* duration budget (`TransformStyleConfig.budget`). This standalone
|
|
94
|
-
* generator is kept for API stability but no longer gains features.
|
|
95
|
-
*
|
|
96
|
-
* ```ts
|
|
97
|
-
* const doc = generateSlideshow(articleText, myImages, {
|
|
98
|
-
* title: 'Mount Rainier',
|
|
99
|
-
* themeId: 'documentary',
|
|
100
|
-
* });
|
|
101
|
-
* // doc is a complete Doc ready for DocPlayer / LinearDocView
|
|
102
|
-
* ```
|
|
103
|
-
*/
|
|
104
|
-
declare function generateSlideshow(text: string, images?: SlideshowImage[], options?: SlideshowOptions): SlideshowDoc;
|
|
105
|
-
|
|
106
|
-
export { ExtractedElement, type MapOptions, type SlideshowDoc, type SlideshowImage, type SlideshowOptions, generateSlideshow, mapElementToBlock };
|
|
28
|
+
export { ExtractedElement, type MapOptions, mapElementToBlock };
|
package/dist/generate/index.js
CHANGED
|
@@ -1,16 +1,11 @@
|
|
|
1
|
-
import
|
|
2
|
-
generateSlideshow
|
|
3
|
-
} from "../chunk-FBKP5CAO.js";
|
|
1
|
+
import "../chunk-ET53IIEP.js";
|
|
4
2
|
import {
|
|
5
3
|
extractContent,
|
|
6
4
|
mapElementToBlock,
|
|
7
5
|
stripMarkdown
|
|
8
|
-
} from "../chunk-
|
|
9
|
-
import "../chunk-FVTQSNR7.js";
|
|
10
|
-
import "../chunk-3E5F2XMR.js";
|
|
6
|
+
} from "../chunk-TQWLI6S2.js";
|
|
11
7
|
export {
|
|
12
8
|
extractContent,
|
|
13
|
-
generateSlideshow,
|
|
14
9
|
mapElementToBlock,
|
|
15
10
|
stripMarkdown
|
|
16
11
|
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { a as ImageEditDoc, b as ImageEditLayer } from '../ImageEditDoc-
|
|
2
|
-
export { E as EditorLayerMeta, I as ImageEditCanvas, c as ImageEditLayerKind, d as ImageEditMeta } from '../ImageEditDoc-
|
|
3
|
-
import { C as ContentContainer } from '../ContentContainer-
|
|
1
|
+
import { a as ImageEditDoc, b as ImageEditLayer } from '../ImageEditDoc-FuyGtt6o.js';
|
|
2
|
+
export { E as EditorLayerMeta, I as ImageEditCanvas, c as ImageEditLayerKind, d as ImageEditMeta } from '../ImageEditDoc-FuyGtt6o.js';
|
|
3
|
+
import { C as ContentContainer } from '../ContentContainer-BXUlIf18.js';
|
|
4
4
|
import { V as Version, C as CoalesceOptions, P as PrunePolicy } from '../types-D98li1gV.js';
|
|
5
|
-
import '../Doc-
|
|
5
|
+
import '../Doc-BBVGq1_9.js';
|
|
6
6
|
import '../types-DlAZ7MW4.js';
|
|
7
7
|
|
|
8
8
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
export { B as BoundingBox, C as Coordinates } from './Types-sh2VRxfo.js';
|
|
2
|
-
export { A as AccentImage, a as AccentPosition, b as AmbientGradientConfig, c as Animation, d as AnimationType, e as AudioBookmark, f as AudioSegment, g as AudioTimingData, h as AudioTrack, B as Block, i as BlockConnection, j as BorderStyle, C as CaptionPhrase, k as CaptionTrack, l as CaptionWord, m as ColorScheme, n as ComparisonBarInput, o as CornerBrandingConfig, p as CustomTemplateDefinition,
|
|
2
|
+
export { A as AccentImage, a as AccentPosition, b as AmbientGradientConfig, c as Animation, d as AnimationType, e as AudioBookmark, f as AudioSegment, g as AudioTimingData, h as AudioTrack, B as Block, i as BlockConnection, j as BorderStyle, C as CaptionPhrase, k as CaptionTrack, l as CaptionWord, m as ColorScheme, n as ComparisonBarInput, o as CornerBrandingConfig, p as CustomTemplateDefinition, q as CustomTemplateLayer, D as DARK_SURFACE, r as DEFAULT_DOC_FONT, s as DEFAULT_TITLE_FONT, t as DataTableInput, u as DateEventInput, v as DeepPartial, w as DefinitionCardInput, x as DiagramBlockInput, y as Doc, z as DocBlock, E as DocDiagnostic, F as DrawingBlockInput, G as FRONTMATTER_CUSTOM_TEMPLATES_KEY, H as FRONTMATTER_CUSTOM_THEMES_KEY, I as FactCardInput, J as FontFamily, K as FontFamilyKind, L as FullBleedQuoteInput, M as GradientBackgroundConfig, N as ImageBackgroundConfig, O as ImageLayer, P as ImageTreatment, Q as ImageWithCaptionInput, R as LIGHT_SURFACE, S as Layer, T as LayerRepeat, U as LayoutHints, V as LeftFeatureInput, W as LinearGradient, X as ListBlockInput, Y as MapBlockInput, Z as MapLayer, _ as MapMarker, $ as MapTileStyle, a0 as MarkerStyle, a1 as MediaClip, a2 as PathLayer, a3 as PatternBackgroundConfig, a4 as PersistentLayer, a5 as PersistentLayerConfig, a6 as PersistentLayerTemplate, a7 as PersistentLayerTemplateConfig, a8 as PersistentLayerTemplateType, a9 as PhotoGridInput, aa as Position, ab as ProgressIndicatorConfig, ac as PullQuoteInput, ad as QuoteBlockInput, ae as RawLayersInput, af as RenderStyle, ag as RightFeatureInput, ah as ScheduledClip, ai as SectionHeaderInput, aj as ShapeFilter, ak as ShapeLayer, al as ShapePattern, am as SolidBackgroundConfig, an as StartBlockConfig, ao as StatHighlightInput, ap as SurfaceScheme, aq as THEME_SCHEMA_VERSION, ar as TableLayer, as as TableLayerStyle, at as TemplateBlock, au as TemplateContext, av as TemplateFunction, aw as TemplateRegistry, ax as TextLayer, ay as TextStyle, az as Theme, aA as ThemeColorPalette, aB as ThemeColorScheme, aC as ThemeSchemaVersion, aD as ThemeSeedColors, aE as ThemeStyle, aF as ThemeTypography, aG as TitleBlockInput, aH as TitleCaptionConfig, aI as TwoColumnInput, aJ as VIEWPORT_PRESETS, aK as VideoLayer, aL as VideoPullQuoteInput, aM as VideoWithCaptionInput, aN as ViewportConfig, aO as ViewportOrientation, aP as ViewportPreset, aQ as VignetteConfig, aR as applySurface, aS as calculateDuration, aT as calculateFontScale, aU as createTemplateContext, aV as createTheme, aW as getAspectRatioString, aX as getBlockAtTime, aY as getCaptionAtTime, aZ as getDocPlaybackDuration, a_ as getLayoutHints, a$ as getRegisteredThemes, b0 as getSafeTextBounds, b1 as getSegmentAtTime, b2 as getTwoColumnPositions, b3 as getViewport, b4 as getViewportOrientation, b5 as isPersistentLayerTemplate, b6 as isTemplateBlock, b7 as layoutScaledFontSize, b8 as lookupRegisteredTheme, b9 as registerTheme, ba as resolveMediaSchedule, bb as scaledFontSize, bc as unregisterTheme } from './Doc-BBVGq1_9.js';
|
|
3
3
|
export { D as DEFAULT_TRANSITION_DURATION_SECONDS, H as HeadingAttributes, a as HeadingTemplateAnnotation, b as HtmlComment, c as HtmlElement, d as HtmlNode, e as HtmlText, M as MarkdownBlockNode, f as MarkdownBlockquote, g as MarkdownBreak, h as MarkdownCodeBlock, i as MarkdownContainerDirective, j as MarkdownDefinitionDescription, k as MarkdownDefinitionList, l as MarkdownDefinitionTerm, m as MarkdownDocument, n as MarkdownEmphasis, o as MarkdownFootnoteDefinition, p as MarkdownFootnoteReference, q as MarkdownHeading, r as MarkdownHtmlBlock, s as MarkdownImage, t as MarkdownImageReference, u as MarkdownInlineCode, v as MarkdownInlineHtml, w as MarkdownInlineMath, x as MarkdownInlineNode, y as MarkdownLeafDirective, z as MarkdownLink, A as MarkdownLinkDefinition, B as MarkdownLinkReference, C as MarkdownList, E as MarkdownListItem, F as MarkdownMathBlock, G as MarkdownMention, I as MarkdownNode, J as MarkdownParagraph, K as MarkdownPoint, L as MarkdownSourcePosition, N as MarkdownStrikethrough, O as MarkdownStrong, P as MarkdownTable, Q as MarkdownTableCell, R as MarkdownTableRow, S as MarkdownText, T as MarkdownTextDirective, U as MarkdownThematicBreak, V as ParseOptions, W as StringifyOptions, X as TRANSITION_DIRECTIONS, Y as TRANSITION_TYPES, Z as Transition, _ as TransitionDirection, $ as TransitionType, a0 as isTransitionType, a1 as normalizeTransitionDirection, a2 as normalizeTransitionType, a3 as resolveBlockTransition, a4 as resolveTransitionDuration } from './types-DlAZ7MW4.js';
|
|
4
|
-
export { D as DEFAULT_THEME, a as DEFAULT_THEME_ID, T as THEMES, g as getAvailableThemes, b as getThemeSummaries, r as resolveTheme } from './themeLibrary-
|
|
4
|
+
export { D as DEFAULT_THEME, a as DEFAULT_THEME_ID, T as THEMES, g as getAvailableThemes, b as getThemeSummaries, r as resolveTheme } from './themeLibrary-CehcJhzz.js';
|
|
5
5
|
export { AVAILABLE_FONT_STACKS, CompileOptions, ContrastPreset, FONT_FALLBACKS, FontStack, STARTER_THEME, ValidationError, ValidationResult, assertTheme, buildGoogleFontsUrl, compileTheme, contrastRatio, deriveColorPalette, deriveScale, fontStack, getFontStack, hexHueDegrees, isHex, oklchDarken, oklchLighten, oklchSetChroma, parseTheme, pickContrastingText, relativeLuminance, resolveFontFamily, serializeTheme, validateTheme, withAlpha } from './schemas/index.js';
|
|
6
6
|
export { M as MediaEntry, a as MediaProvider } from './MediaProvider-wpSe21B3.js';
|
|
7
|
-
export { E as EditorLayerMeta, I as ImageEditCanvas, a as ImageEditDoc, b as ImageEditLayer, c as ImageEditLayerKind, d as ImageEditMeta } from './ImageEditDoc-
|
|
8
|
-
export { AccentLayout, AudioSegmentTiming, CONTAINER_TEMPLATES, ClipBox, ConnectorRouting, CoverBlockInput, DEFAULT_LAYOUT, DataFenceParseResult, DeriveTemplateInputsOptions, DiagramEdge, DiagramLayout, DiagramLayoutOptions, DiagramNodePosition, DocStylePreset, DrawingConnector, DrawingLayout, DrawingLayoutOptions, DrawingShape, DrawingShapeKind, ExpandDocBlocksOptions, ExtractedTableData, FirstImage, LayoutLayerDefaults, LayoutLayersResult, MarkdownToDocOptions, MarkdownValidationResult, PATH_SHAPE_KINDS, RenderContext, RuntimeTemplateRegistry, SHAPE_NAMES, TEMPLATE_ALIASES, TEMPLATE_METADATA, TemplateMetadata, ValidateOptions, adjustY, applyRenderStyleToLayers, buildRegistry, clipEndpoints, clipPoint, comparisonBar, computeDiagramLayout, computeDrawingLayout, computeLayoutLayers, connectorPath, countBlocks, coverBlock, createAccentLayers, cssFilterForTreatment, dataTable, dateEvent, decodeLayersFromFrontmatter, definitionCard, deriveTemplateInputs, diagramBlock, docToMarkdown, drawingBlock, encodeLayersForFrontmatter, expandCoverBlock, expandDocBlocks, expandPersistentLayers, expandTemplateBlock, extractBlockquoteText, extractBodyPlainText, extractFirstImage, extractImages, extractListItems, extractTableData, extractTableFromContents, factCard, fallbackBlockLayers, findFirstTable, flattenBlocks, flattenRenderableBlocks, fullBleedQuote, getAccentLayout, getAnimationProgress, getAnimationStyle, getAvailableTemplates, getBlockDepth, getDefaultAnimation, getDefaultAnimationDuration, getDocStyleConfig, getLayers, getOverlayOpacity, getPersistentLayersFromTheme, getTemplateHint, getThemeFont, getTransitionClass, hasTemplate, imageWithCaption, isContainerTemplate, isDataFence, isShapeName, layoutBlock, leftFeature, lineStyleDasharray, listBlock, mapBlock, markdownToDoc, markerPath, normalizeShapeKind, parseDataFence, parseYamlSubset, photoGrid, pullQuote, quoteBlock, readCustomTemplatesFromFrontmatter, readCustomThemesFromFrontmatter, resolveAudioMapping, resolveColorScheme, resolvePersistentLayers, resolveTemplateName, resolveThemeForDoc, rightFeature, scaleAnimationDuration, scoreTextSimilarity, sectionHeader, shapePath, shouldUseShadow, statHighlight, templateRegistry, themeWantsAmbientMotion, themedEntrance, themedFontSize, themedImageTreatment, themedScrim, themedSurfaceGradient, titleBlock, twoColumn, validateMarkdownDoc, validateMarkdownSource, videoPullQuote, videoWithCaption, wrapWithPersistentLayers, writeCustomTemplatesToFrontmatter, writeCustomThemesToFrontmatter } from './story/index.js';
|
|
7
|
+
export { E as EditorLayerMeta, I as ImageEditCanvas, a as ImageEditDoc, b as ImageEditLayer, c as ImageEditLayerKind, d as ImageEditMeta } from './ImageEditDoc-FuyGtt6o.js';
|
|
8
|
+
export { AccentLayout, AudioSegmentTiming, BASE_INPUT_DESCRIPTORS, CONTAINER_TEMPLATES, ClipBox, ConnectorRouting, CoverBlockInput, DEFAULT_LAYOUT, DataFenceParseResult, DeriveTemplateInputsOptions, DiagramEdge, DiagramLayout, DiagramLayoutOptions, DiagramNodePosition, DocStylePreset, DrawingConnector, DrawingLayout, DrawingLayoutOptions, DrawingShape, DrawingShapeKind, ExpandDocBlocksOptions, ExtractedTableData, FirstImage, InputCoercion, LayoutLayerDefaults, LayoutLayersResult, MarkdownToDocOptions, MarkdownValidationResult, PATH_SHAPE_KINDS, RenderContext, RuntimeTemplateRegistry, SHAPE_NAMES, TEMPLATE_ALIASES, TEMPLATE_INPUT_DESCRIPTORS, TEMPLATE_METADATA, TemplateInputDescriptor, TemplateMetadata, TemplateParamFinding, ValidateOptions, adjustY, applyRenderStyleToLayers, buildRegistry, clipEndpoints, clipPoint, coerceTemplateParams, comparisonBar, computeDiagramLayout, computeDrawingLayout, computeLayoutLayers, connectorPath, countBlocks, coverBlock, createAccentLayers, cssFilterForTreatment, dataTable, dateEvent, decodeLayersFromFrontmatter, definitionCard, deriveTemplateInputs, diagramBlock, docToMarkdown, drawingBlock, encodeLayersForFrontmatter, expandCoverBlock, expandDocBlocks, expandPersistentLayers, expandTemplateBlock, extractBlockquoteText, extractBodyPlainText, extractFirstImage, extractImages, extractListItems, extractTableData, extractTableFromContents, factCard, fallbackBlockLayers, findFirstTable, flattenBlocks, flattenRenderableBlocks, fullBleedQuote, getAccentLayout, getAnimationProgress, getAnimationStyle, getAvailableTemplates, getBlockDepth, getDefaultAnimation, getDefaultAnimationDuration, getDocStyleConfig, getLayers, getOverlayOpacity, getPersistentLayersFromTheme, getTemplateHint, getThemeFont, getTransitionClass, hasTemplate, imageWithCaption, isContainerTemplate, isDataFence, isShapeName, layoutBlock, leftFeature, lineStyleDasharray, lintTemplateParams, listBlock, mapBlock, markdownToDoc, markerPath, normalizeShapeKind, parseDataFence, parseYamlSubset, photoGrid, pullQuote, quoteBlock, readCustomTemplatesFromFrontmatter, readCustomThemesFromFrontmatter, replaceDataFence, resolveAudioMapping, resolveColorScheme, resolvePersistentLayers, resolveTemplateName, resolveThemeForDoc, rightFeature, scaleAnimationDuration, scoreTextSimilarity, sectionHeader, shapePath, shouldUseShadow, statHighlight, templateRegistry, themeWantsAmbientMotion, themedEntrance, themedFontSize, themedImageTreatment, themedScrim, themedSurfaceGradient, titleBlock, twoColumn, validateMarkdownDoc, validateMarkdownSource, videoPullQuote, videoWithCaption, wrapWithPersistentLayers, writeCustomTemplatesToFrontmatter, writeCustomThemesToFrontmatter } from './story/index.js';
|
|
9
9
|
export { calculateBearing, decodeGeohash, encodeGeohash, geohashOverlapsBounds, geohashToHierarchicalPath, getGeohash4Neighbors, getGeohashPath, getGeohashPrefix, getNeighbors, haversineDistance } from './spatial/index.js';
|
|
10
10
|
export { LocalForageAdapter, LocalForageAdapterOptions, LocalStorageAdapter, MemoryStorageAdapter, ScopedContentContainer, StorageAdapter, createMediaProviderFromContainer, scopeContainer } from './storage/index.js';
|
|
11
|
-
export { C as ContentContainer, a as ContentEntry, M as MemoryContentContainer, f as findDocumentPath } from './ContentContainer-
|
|
12
|
-
export { BLOCK_META_KEY_DESCRIPTORS, BlockMetaKeyDescriptor, HtmlPolicy, KNOWN_BLOCK_META_KEYS, KnownBlockMetaKey, TrailingAnnotationMatch, UrlKind, countNodes, createDocument, extractPlainText, findNodesByType, fromMdast, getChildren, inferDocumentTitle, matchTrailingPandocAttr, matchTrailingTemplateAnnotation, needsQuoting, parseFrontmatter, parseHtmlToNodes, parseMarkdown, parsePandocAttrTokens, parseTimeSeconds, plainTextFromInlineHtml, quoteAttrValue, readFrontmatterThemeId, sanitizeHtmlNodes, sanitizeUrl, serializePandocAttributes, setFrontmatterValues, splitKeyValueToken, stringifyHtmlNodes, stringifyMarkdown, toMdast, tokenizeAttrTokens, unquoteAttrValue, walkMarkdownTree } from './markdown/index.js';
|
|
11
|
+
export { C as ContentContainer, a as ContentEntry, M as MemoryContentContainer, f as findDocumentPath } from './ContentContainer-BXUlIf18.js';
|
|
12
|
+
export { BLOCK_META_KEY_DESCRIPTORS, BlockMetaKeyDescriptor, HtmlPolicy, KNOWN_BLOCK_META_KEYS, KnownBlockMetaKey, SanitizeUrlOptions, TrailingAnnotationMatch, UrlKind, countNodes, createDocument, extractPlainText, findNodesByType, formatBlockScalar, fromMdast, getChildren, inferDocumentTitle, matchTrailingPandocAttr, matchTrailingTemplateAnnotation, needsQuoting, parseFrontmatter, parseHtmlToNodes, parseMarkdown, parsePandocAttrTokens, parseTimeSeconds, plainTextFromInlineHtml, quoteAttrValue, readFrontmatterThemeId, sanitizeHtmlNodes, sanitizeUrl, serializePandocAttributes, setFrontmatterValues, splitKeyValueToken, stringifyHtmlNodes, stringifyMarkdown, toMdast, tokenizeAttrTokens, unquoteAttrValue, walkMarkdownTree } from './markdown/index.js';
|
|
13
13
|
export { DEFAULT_WORDS_PER_SECOND, NarrationTimeEstimate, NarrationTimeOptions, ReadingTimeEstimate, ReadingTimeOptions, calculatePrefixDuration, countSpokenWords, estimateNarrationDuration, estimateNarrationTime, estimateReadingTime, estimateSpokenWordCount, estimateTimeFromText } from './timing/index.js';
|
|
14
14
|
export { SeededRandom, hashString } from './random/index.js';
|
|
15
15
|
export { C as ComparisonData, D as DateData, a as DefinitionData, E as ExtractedElement, b as ExtractionOptions, c as ExtractionResult, d as ExtractionType, F as FactData, I as ImpactLineData, L as ListData, Q as QuoteData, S as StatData, e as extractContent, s as stripMarkdown } from './contentExtractor-BNfVJV2U.js';
|
|
16
|
-
export { MapOptions,
|
|
16
|
+
export { MapOptions, mapElementToBlock } from './generate/index.js';
|
|
17
17
|
export { AnalyzedBlock, BlockImage, DEFAULT_TRANSFORM_STYLE_ID, TransformImage, TransformOptions, TransformResult, TransformStyleConfig, TransformStyleId, TransformStyleSummary, analyzeBlocks, applyTransform, extractDocImages, getTransformStyleIds, getTransformStyleSummaries, registerTransformStyle, resolveTransformStyle, unregisterTransformStyle } from './transform/index.js';
|
|
18
18
|
export { C as CoalesceOptions, P as PrunePolicy, R as RevertOptions, S as SaveVersionOptions, a as SaveVersionResult, V as Version } from './types-D98li1gV.js';
|
|
19
19
|
export { DocumentVersionManager, DocumentVersionManagerOptions, VERSIONS_PREFIX, VERSION_TIMESTAMP_PATTERN, buildVersionPath, coalesceVersions, formatVersionTimestamp, getDocBasename, listVersions, parseVersionPath, parseVersionTimestamp, pruneVersions, readVersion, revertToVersion, saveVersion } from './versions/index.js';
|
|
20
|
-
export { ControlKind, InferSchemaOptions, JsonFormValidationError, JsonFormValidator, SquisqAnnotatedSchema, SquisqHints, SquisqWhen, arrayItemKind, chooseControl, evaluateWhen, getByPointer, inferSchema, pointerSegments, primaryType, resolveFlag, resolveRef, setByPointer, toPointer } from './jsonForm/index.js';
|
|
20
|
+
export { BuildJsonFormTokensOptions, ControlKind, InferSchemaOptions, JsonFormValidationError, JsonFormValidator, SquisqAnnotatedSchema, SquisqHints, SquisqWhen, arrayItemKind, buildJsonFormTokens, chooseControl, evaluateWhen, getByPointer, inferSchema, pointerSegments, primaryType, resolveFlag, resolveJsonFormTheme, resolveRef, setByPointer, toPointer } from './jsonForm/index.js';
|
|
21
21
|
export { IMAGE_EDIT_ASSETS_PREFIX, IMAGE_EDIT_DEFAULT_BASENAME, IMAGE_EDIT_STATE_FILENAME, IMAGE_EDIT_VERSIONS_PREFIX, ImageEditExportFormat, ImageEditExportOptions, ImageEditVersionManager, ImageEditVersionManagerOptions, RevertImageEditOptions, SaveImageEditVersionOptions, SaveImageEditVersionResult, addLayer, buildImageEditVersionPath, buildSvgString, coalesceImageEditVersions, createEmptyImageEditDoc, exportImageEditDoc, listImageEditVersions, parseImageEditVersionPath, pruneImageEditVersions, readImageEditDoc, readImageEditVersion, readImageEditVersionText, removeLayer, reorderLayer, revertToImageEditVersion, saveImageEditVersion, setCanvas, touch, updateLayer, writeImageEditDoc } from './imageEdit/index.js';
|
|
22
22
|
export { I as ICONS, a as IconEntry, b as IconFamily, c as IconTextRun, h as hasIconMarker, i as iconClass, d as iconMarker, s as splitIconMarkers, e as stripIconMarkers } from './inlineIconMarker-CiE8Hlvz.js';
|
|
23
23
|
export { IconSuggestion, canonicalIconToken, iconGlyph, looksLikeIconToken, resolveIcon, suggestIcons } from './icons/index.js';
|