@bendyline/squisq-react 1.0.3 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../node_modules/preact/src/constants.js","../../../node_modules/preact/src/util.js","../../../node_modules/preact/src/options.js","../../../node_modules/preact/src/create-element.js","../../../node_modules/preact/src/component.js","../../../node_modules/preact/src/diff/props.js","../../../node_modules/preact/src/create-context.js","../../../node_modules/preact/src/diff/children.js","../../../node_modules/preact/src/diff/index.js","../../../node_modules/preact/src/render.js","../../../node_modules/preact/src/diff/catch-error.js","../../../node_modules/preact/hooks/src/index.js","../../../node_modules/preact/compat/src/util.js","../../../node_modules/preact/compat/src/hooks.js","../../../node_modules/preact/compat/src/PureComponent.js","../../../node_modules/preact/compat/src/forwardRef.js","../../../node_modules/preact/compat/src/Children.js","../../../node_modules/preact/compat/src/suspense.js","../../../node_modules/preact/compat/src/suspense-list.js","../../../node_modules/preact/compat/src/render.js","../../../node_modules/preact/compat/src/index.js","../../../node_modules/preact/compat/client.mjs","../../core/src/schemas/Doc.ts","../../core/src/schemas/themeLibrary.ts","../../core/src/schemas/Viewport.ts","../../core/src/schemas/LayoutStrategy.ts","../../core/src/schemas/BlockTemplates.ts","../../core/src/markdown/utils.ts","../../core/src/doc/templates/persistentLayers.ts","../../core/src/doc/utils/themeUtils.ts","../../core/src/doc/templates/titleBlock.ts","../../core/src/doc/templates/sectionHeader.ts","../../core/src/doc/templates/accentImage.ts","../../core/src/doc/templates/captionUtils.ts","../../core/src/doc/templates/statHighlight.ts","../../core/src/doc/templates/quoteBlock.ts","../../core/src/doc/templates/factCard.ts","../../core/src/doc/templates/twoColumn.ts","../../core/src/doc/templates/dateEvent.ts","../../core/src/doc/templates/imageWithCaption.ts","../../core/src/doc/templates/mapBlock.ts","../../core/src/doc/templates/fullBleedQuote.ts","../../core/src/doc/templates/listBlock.ts","../../core/src/doc/templates/photoGrid.ts","../../core/src/doc/templates/definitionCard.ts","../../core/src/doc/templates/comparisonBar.ts","../../core/src/doc/templates/pullQuote.ts","../../core/src/doc/templates/videoWithCaption.ts","../../core/src/doc/templates/videoPullQuote.ts","../../core/src/doc/templates/coverBlock.ts","../../core/src/doc/templates/index.ts","../../core/src/doc/utils/animationUtils.ts","../../core/src/doc/markdownToDoc.ts","../../core/src/doc/getLayers.ts","../src/utils/layerUtils.ts","../src/hooks/MediaContext.tsx","../../../node_modules/preact/jsx-runtime/src/index.js","../src/layers/ImageLayer.tsx","../src/layers/TextLayer.tsx","../src/layers/ShapeLayer.tsx","../src/utils/mapTileUtils.ts","../src/layers/MapLayer.tsx","../src/layers/VideoLayer.tsx","../src/BlockRenderer.tsx","../src/SocialCaptionOverlay.tsx","../src/CaptionOverlay.tsx","../src/hooks/useAudioSync.ts","../src/hooks/useDocPlayback.ts","../src/hooks/useViewportOrientation.ts","../src/types.ts","../src/DocProgressBar.tsx","../src/DocControlsOverlay.tsx","../src/DocControlsSlideshow.tsx","../src/MarkdownRenderer.tsx","../src/LinearDocView.tsx","../src/DocPlayer.tsx","../src/styles/doc-animations.css","../src/standalone-entry.tsx"],"names":["slice","options","vnodeId","rerenderQueue","prevDebounce","defer","depthSort","CAPTURE_REGEX","eventClock","eventProxy","eventProxyCapture","i","EMPTY_OBJ","EMPTY_ARR","IS_NON_DIMENSIONAL","isArray","Array","assign","obj","props","removeNode","node","parentNode","removeChild","createElement","type","children","key","ref","normalizedProps","arguments","length","call","defaultProps","createVNode","original","vnode","__k","__","__b","__e","__c","constructor","__v","__i","__u","Fragment","BaseComponent","context","this","getDomSibling","childIndex","sibling","renderComponent","component","__P","__d","oldVNode","oldDom","commitQueue","refQueue","newVNode","diff","__n","namespaceURI","commitRoot","updateParentDomPointers","base","some","child","enqueueRender","c","push","process","__r","debounceRendering","l","sort","shift","diffChildren","parentDom","renderResult","newParentVNode","oldParentVNode","globalContext","namespace","excessDomChildren","isHydrating","childVNode","newDom","firstChildDom","result","shouldPlace","oldChildren","newChildrenLength","constructNewChildrenArray","applyRef","insert","nextSibling","skewedIndex","matchingIndex","oldChildrenLength","remainingOldChildren","skew","String","findMatchingIndex","unmount","parentVNode","insertBefore","nodeType","toChildArray","out","x","y","matched","shouldSearch","setStyle","style","value","setProperty","test","dom","name","oldValue","useCapture","lowerCaseName","o","cssText","replace","toLowerCase","_attached","addEventListener","removeEventListener","e","removeAttribute","setAttribute","createEventProxy","eventHandler","_dispatched","event","tmp","isNew","oldProps","oldState","snapshot","clearProcessingException","newProps","isClassComponent","provider","componentContext","renderHook","count","newType","outer","prototype","render","contextType","__E","doRender","sub","state","__h","_sb","__s","getDerivedStateFromProps","componentWillMount","componentDidMount","componentWillReceiveProps","shouldComponentUpdate","apply","componentWillUpdate","componentDidUpdate","getChildContext","getSnapshotBeforeUpdate","cloneNode","then","MODE_HYDRATE","indexOf","markAsForce","diffElementNodes","diffed","root","cb","map","newHtml","oldHtml","newChildren","inputValue","checked","localName","document","createTextNode","createElementNS","is","__m","data","childNodes","attributes","__html","innerHTML","content","undefined","hasRefUnmount","current","skipRemove","r","componentWillUnmount","replaceNode","documentElement","firstChild","createContext","defaultValue","Context","subs","ctx","Set","_props","forEach","add","old","delete","Provider","__l","Consumer","contextValue","error","errorInfo","ctor","handled","getDerivedStateFromError","setState","componentDidCatch","update","callback","s","forceUpdate","Promise","bind","resolve","setTimeout","a","b","currentIndex","currentComponent","previousComponent","prevRaf","currentHook","afterPaintEffects","_options","oldBeforeDiff","oldBeforeRender","oldAfterDiff","oldCommit","oldBeforeUnmount","oldRoot","getHookState","index","hooks","__H","useState","initialState","useReducer","invokeOrReturn","reducer","init","hookState","_reducer","action","currentValue","__N","nextValue","__f","updateHookState","p","stateHooks","filter","every","prevScu","shouldUpdate","hookItem","prevCWU","useEffect","args","argsChanged","_pendingArgs","useRef","initialValue","useMemo","factory","useCallback","useContext","flushAfterPaintEffects","invokeCleanup","invokeEffect","requestAnimationFrame","afterNextFrame","hasErrored","HAS_RAF","raf","done","clearTimeout","timeout","cancelAnimationFrame","hook","comp","cleanup","oldArgs","newArgs","arg","f","shallowDiffers","useLayoutEffect","PureComponent","Component","isPureReactComponent","oldDiffHook","oldCatchError","oldUnmount","detachedClone","detachedParent","effect","removeOriginal","originalParent","appendChild","Suspense","_suspenders","suspended","__a","SuspenseList","_next","_map","__z","__R","promise","suspendingVNode","suspendingComponent","resolved","onResolved","onSuspensionComplete","originalParentDom","suspendedVNode","__O","pop","detachedComponent","fallback","list","revealOrder","size","delegated","get","unsuspend","wrappedUnsuspend","Map","reverse","set","_this","REACT_ELEMENT_TYPE","Symbol","for","CAMEL_PROPS","ON_ANI","CAMEL_REPLACE","IS_DOM","onChangeInputType","parent","textContent","preactRender","isReactComponent","Object","defineProperty","configurable","v","writable","oldEventHook","persist","isPropagationStopped","cancelBubble","isDefaultPrevented","defaultPrevented","nativeEvent","classNameDescriptorNonEnumberable","class","oldVNodeHook","isNonDashedType","lowerCased","multiple","selected","className","$$typeof","oldDiffed","unmountComponentAtNode","container","createRoot","nn","pn","getBlockAtTime","blocks","time","block","getCaptionAtTime","captions","phrase","SYSTEM_SANS","SYSTEM_SERIF","SYSTEM_MONO","CLASSIC_COLOR_SCHEMES","standard","DEFAULT_THEME","VIEWPORT_PRESETS","REFERENCE_DIAGONAL","calculateFontScale","viewport","getViewportOrientation","ratio","LAYOUT_CONFIGS","getLayoutHints","orientation","scaledFontSize","basePx","isTitle","fontScale","layout","typeScale","getTwoColumnPositions","DEFAULT_DOC_FONT","isTemplateBlock","createTemplateContext","theme","blockIndex","totalBlocks","isPersistentLayerTemplate","layer","getChildren","extractPlainText","GRADIENT_PRESETS","expandSolidBackground","config","expandGradientBackground","expandImageBackground","layers","opacity","imageLayer","expandPatternBackground","expandTitleCaption","fontSize","hasSubtitle","isBottom","isLeft","pad","pillHeight","bgYPos","bgXPos","thumbW","thumbH","thumbPad","textX","textWidth","titleYPos","thumbX","thumbY","subtitleYPos","expandCornerBranding","xPos","yPos","expandProgressIndicator","color","expandPersistentLayer","expandPersistentLayers","acc","FALLBACK_COLOR_SCHEME","resolveColorScheme","schemes","keys","FALLBACK_BODY","FALLBACK_TITLE","FALLBACK_MONO","getThemeFont","role","typography","titleBlock","input","title","subtitle","backgroundColor","titleFontSize","scaledFontSize2","subtitleFontSize","sectionHeader","colorScheme","imageSrc","imageAlt","ambientMotion","colors","PERCENTAGE_RE","DEFAULT_LAYOUT","mapAmbientMotion","motion","duration","STRIP_SIZE","STRIP_SIZE_PCT","getAccentLayout","position","createAccentLayers","accent","slideId","src","alt","credit","license","createStripImage","createStripGradient","createBottomStripImage","createBottomStripGradient","createCornerInsetImage","createCornerVignette","side","gradientId","adjustY","originalY","yStr","match","yValue","TRAILING_PUNCT_RE","cleanCaption","text","createBackgroundLayer","id","fill","statHighlight","stat","description","detail","accentImage","accentLayout","statFontSize","descFontSize","detailFontSize","quoteBlock","quote","attribution","quoteFontSize","attrFontSize","decorativeQuoteFontSize","quoteY","factCard","fact","explanation","source","factFontSize","explainFontSize","sourceFontSize","twoColumn","left","right","header","leftColor","rightColor","leftColors","rightColors","positions","isStacked","columnWidth","headerFontSize","labelFontSize","sublabelFontSize","headerY","leftY","leftSublabelY","rightY","rightSublabelY","baseY","sublabelOffset","connectorFontSize","connectorY","connectorSymbol","MOOD_COLORS","dateEvent","date","footer","mood","dateFontSize","footerFontSize","imageWithCaption","rawCaption","_captionPosition","imageCredit","imageLicense","caption","captionFontSize","legacyKenBurns","imageAnimation","mapBlock","center","zoom","mapStyle","markers","staticSrc","mapAnimation","fullBleedQuote","textFontSize","listBlock","items","itemFontSize","startY","spacing","itemText","GAP","photoGrid","images","captionHeight","gridHeight","getGridPositions","altFontSize","img","pos","stacked","halfW","halfH","thirdH","leftW","rightW","definitionCard","term","definition","origin","termFontSize","defFontSize","originFontSize","comparisonBar","leftLabel","leftValue","rightLabel","rightValue","unit","valueFontSize","maxValue","maxBarWidth","leftBarWidth","rightBarWidth","barStartX","barHeight","topBarY","bottomBarY","formatValue","leftDisplay","rightDisplay","pullQuote","backgroundImage","decoFontSize","videoWithCaption","videoSrc","posterSrc","videoAlt","clipStart","clipEnd","sourceDuration","captionPosition","videoCredit","videoLicense","creditFontSize","captionY","videoPullQuote","backgroundVideo","coverBlock","heroSrc","heroAlt","heroCredit","heroLicense","startBlockToCoverInput","expandCoverBlock","templateRegistry","expandTemplateBlock","templateBlock","templateFn","err","expandDocBlocks","opts","persistentLayers","audioSegments","bottomLayers","topLayers","currentTime","expandedBlock","useBottom","useTop","blocksBySegment","segmentIndex","expandedBlocks","segmentBlocks","audioSegment","offsetTime","originalIndex","sectionHeaderBlocks","contentBlocks","item","fixedDuration","sum","contentBlockDuration","remainingDuration","scaleFactor","expandedInfos","hasAnySourceTiming","info","aIsHeader","bIsHeader","offsetWithinSegment","sourceStart","scaledDuration","segmentExpandedBlocks","next","currentEnd","MIN_TRANSITION_GAP","segmentEnd","lastBlock","prevBlock","onlyBlock","changed","prev","blockEnd","MAX_BLOCK_DURATION","numParts","partDuration","splitBlock","hasTemplate","getAnimationStyle","animation","_currentTime","getAnimationClassName","getAnimationCSSVars","direction","panDirection","vars","getTransitionClass","entering","flattenBlocks","getLayers","existingLayers","injectPersistentLayers","templateName","templateCtx","resolveValue","dimension","getAnchorOffset","anchor","width","height","MediaContext","R","useMediaProvider","useMediaUrl","relativePath","basePath","isAbsolute","T","needsProvider","url","setUrl","d","cancelled","isStaticChildren","__source","__self","ImageLayer","blockTime","offset","finalX","finalY","animStyle","preserveAspectRatio","getPreserveAspectRatio","isCover","isSpatialAnim","SPATIAL_ANIMATION_TYPES","kbAnim","remapToKenBurns","kbStyle","u","fit","anim","TextLayer","maxWidth","textAnchor","getTextAnchor","dominantBaseline","getDominantBaseline","rawLines","lines","line","wrapText","last","lineHeight","lineHeightPx","textStyles","filterId","getTextBoxWidth","align","avgCharWidth","charsPerLine","words","currentLine","word","testLine","remaining","ShapeLayer","rawX","rawY","anchorOffset","isCSSGradient","shapeProps","TILE_PROVIDERS","latLngToTile","lat","lng","n","latRad","getPixelOffset","tileSize","xTile","yTile","getTilesForViewport","centerLat","centerLng","viewportWidth","viewportHeight","centerTile","pixelOffset","tilesX","tilesY","startX","centerScreenX","centerScreenY","tiles","dy","dx","tileX","tileY","screenX","screenY","buildTileUrl","z","fetchTileImage","reject","composeMapImage","showAttribution","clampedZoom","canvas","tilePromises","tile","marker","drawMarker","drawAttribution","markerTile","centerOffset","markerOffset","icon","drawStar","cx","cy","spikes","outerRadius","innerRadius","rot","step","padding","MapLayer","mapImageUrl","setMapImageUrl","isLoading","setIsLoading","setError","dataUrl","VideoLayer","_blockTime","isPlaying","videoRef","A","hasStartedRef","resolvedPoster","video","playPromise","handleTimeUpdate","VIEWPORT","BlockRenderer","isEntering","isExiting","transitionClass","transitionStyle","clipId","LayerRenderer","TARGET_CHUNK_SIZE","MIN_CHUNK_SIZE","MAX_CHUNK_SIZE","resolvePhraseTiming","w","rawWords","wordDuration","buildWordStream","allWords","chunkSize","numChunks","chunks","chunkWords","SocialCaptionOverlay","enabled","activeChunk","activeWordIndex","chunk","primaryColor","fontFamily","baseFontSize","isActive","CaptionOverlay","captionStyle","captionText","useAudioSync","audioRef","audioTrack","setCurrentTime","setIsPlaying","currentSegment","setCurrentSegment","isEnded","setIsEnded","isAudioReady","setIsAudioReady","totalDuration","setTotalDuration","segmentStarts","pendingSeekTime","shouldPlayAfterLoad","blobUrls","loadingPromises","fallbackMode","seg","start","preloadAudio","q","audioUrl","loadPromise","response","blob","blobUrl","segment","currentBlobUrls","audio","overallTime","handlePlay","handlePause","handleError","handleEnded","applyPendingSeek","segmentStart","segmentTime","currentSrc","cachedBlobUrl","handleCanPlay","play","pause","toggle","seekTo","clampedTime","segEnd","wasPlaying","skipToSegment","restart","lastTime","tick","now","dt","useDocPlayback","script","renderMode","transitionState","setTransitionState","flatBlocks","currentBlock","currentBlockIndex","blockProgress","docProgress","transitionDuration","timer","renderPrevBlockRef","oldPrev","renderTransitionDuration","renderIsEntering","renderIsExiting","goToBlock","targetBlock","nextBlock","getOrientationFromWindow","getViewportForOrientation","useViewportOrientation","windowSize","setWindowSize","handleResize","timeoutId","debouncedResize","formatTime","seconds","mins","secs","DocProgressBar","actions","blockMarkers","getBlockTitle","progressBarRef","hoverPosition","setHoverPosition","handleProgressHover","bar","rect","progress","handleProgressLeave","getBlockAtTimeLocal","blk","hoverTime","slideInfo","DocControlsOverlay","DocControlsSlideshow","slideNav","isFirst","isLast","renderInline","nodes","keyPrefix","k","renderBlock","Tag","renderBlocks","renderListItem","renderTable","isTask","rows","headerRow","bodyRows","cell","ci","row","ri","MarkdownRenderer","isAnnotatedBlock","annotation","countAll","BlockSection","renderContext","isAnnotated","visualBlock","headingText","bodyText","extractBodyPlainText","getTemplateDefaults","contents","extractListItems","LinearDocView","doc","activeViewport","activeTheme","bgColor","textColor","mutedColor","bodyFont","titleFont","lineHt","SMALL_WORDS","buildSegmentTitleMap","segIdx","titled","idx","DocPlayer","autoPlay","onEnded","onTimeUpdate","externalAudioProvider","showControls","showScrubber","muted","captionsEnabledProp","onCaptionsToggle","onPlaybackStateChange","onControlsReady","isFullscreen","onFullscreenToggle","onBlockMarkers","forceViewport","displayMode","isSlideshowMode","isLinearMode","containerRef","tapFeedback","setTapFeedback","tapFeedbackTimer","isDebugMode","internalAudio","isAvailable","unavailableMessage","_skipToSegment","currentTimeRef","totalDurationRef","expandedBlocksLenRef","handleContainerClick","previousBlock","startBlockConfig","coverForced","setCoverForced","coverGraceActive","setCoverGraceActive","coverGraceTimer","coverWasShowing","showCoverBlock","hasAutoPlayed","blockStartTime","elapsedMs","target","blockElapsed","videoSeekPromises","activeBlockEl","el","targetTime","titleMap","defaultMode","captionMode","setCaptionMode","captionsEnabled","activeCaptionStyle","setCaptionsEnabled","cycleCaptionMode","hasCaptions","segmentTitleMap","playbackState","playbackActions","slideNavActions","docBlock","firstLine","textLayer","prevSegment","isSectionStart","handleKeyDown","activeEl","debugPhrase","debugEnabled","doc_animations_default","cssInjected","injectCss","createInlineMediaProvider","inferMimeType","filename","ext","rewriteAudioUrls","audioMap","segments","roots","mount","element","mode","finalDoc","mediaProvider","_","mountStatic","version"],"mappings":"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","file":"squisq-player.global.js","sourcesContent":["/** Normal hydration that attaches to a DOM tree but does not diff it. */\nexport const MODE_HYDRATE = 1 << 5;\n/** Signifies this VNode suspended on the previous render */\nexport const MODE_SUSPENDED = 1 << 7;\n/** Indicates that this node needs to be inserted while patching children */\nexport const INSERT_VNODE = 1 << 2;\n/** Indicates a VNode has been matched with another VNode in the diff */\nexport const MATCHED = 1 << 1;\n\n/** Reset all mode flags */\nexport const RESET_MODE = ~(MODE_HYDRATE | MODE_SUSPENDED);\n\nexport const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\nexport const XHTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';\nexport const MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';\n\nexport const NULL = null;\nexport const UNDEFINED = undefined;\nexport const EMPTY_OBJ = /** @type {any} */ ({});\nexport const EMPTY_ARR = [];\nexport const IS_NON_DIMENSIONAL =\n\t/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;\n","import { EMPTY_ARR } from './constants';\n\nexport const isArray = Array.isArray;\n\n/**\n * Assign properties from `props` to `obj`\n * @template O, P The obj and props types\n * @param {O} obj The object to copy properties to\n * @param {P} props The object to copy properties from\n * @returns {O & P}\n */\nexport function assign(obj, props) {\n\t// @ts-expect-error We change the type of `obj` to be `O & P`\n\tfor (let i in props) obj[i] = props[i];\n\treturn /** @type {O & P} */ (obj);\n}\n\n/**\n * Remove a child node from its parent if attached. This is a workaround for\n * IE11 which doesn't support `Element.prototype.remove()`. Using this function\n * is smaller than including a dedicated polyfill.\n * @param {import('./index').ContainerNode} node The node to remove\n */\nexport function removeNode(node) {\n\tif (node && node.parentNode) node.parentNode.removeChild(node);\n}\n\nexport const slice = EMPTY_ARR.slice;\n","import { _catchError } from './diff/catch-error';\n\n/**\n * The `option` object can potentially contain callback functions\n * that are called during various stages of our renderer. This is the\n * foundation on which all our addons like `preact/debug`, `preact/compat`,\n * and `preact/hooks` are based on. See the `Options` type in `internal.d.ts`\n * for a full list of available option hooks (most editors/IDEs allow you to\n * ctrl+click or cmd+click on mac the type definition below).\n * @type {import('./internal').Options}\n */\nconst options = {\n\t_catchError\n};\n\nexport default options;\n","import { slice } from './util';\nimport options from './options';\nimport { NULL, UNDEFINED } from './constants';\n\nlet vnodeId = 0;\n\n/**\n * Create an virtual node (used for JSX)\n * @param {import('./internal').VNode[\"type\"]} type The node name or Component constructor for this\n * virtual node\n * @param {object | null | undefined} [props] The properties of the virtual node\n * @param {Array<import('.').ComponentChildren>} [children] The children of the\n * virtual node\n * @returns {import('./internal').VNode}\n */\nexport function createElement(type, props, children) {\n\tlet normalizedProps = {},\n\t\tkey,\n\t\tref,\n\t\ti;\n\tfor (i in props) {\n\t\tif (i == 'key') key = props[i];\n\t\telse if (i == 'ref') ref = props[i];\n\t\telse normalizedProps[i] = props[i];\n\t}\n\n\tif (arguments.length > 2) {\n\t\tnormalizedProps.children =\n\t\t\targuments.length > 3 ? slice.call(arguments, 2) : children;\n\t}\n\n\t// If a Component VNode, check for and apply defaultProps\n\t// Note: type may be undefined in development, must never error here.\n\tif (typeof type == 'function' && type.defaultProps != NULL) {\n\t\tfor (i in type.defaultProps) {\n\t\t\tif (normalizedProps[i] === UNDEFINED) {\n\t\t\t\tnormalizedProps[i] = type.defaultProps[i];\n\t\t\t}\n\t\t}\n\t}\n\n\treturn createVNode(type, normalizedProps, key, ref, NULL);\n}\n\n/**\n * Create a VNode (used internally by Preact)\n * @param {import('./internal').VNode[\"type\"]} type The node name or Component\n * Constructor for this virtual node\n * @param {object | string | number | null} props The properties of this virtual node.\n * If this virtual node represents a text node, this is the text of the node (string or number).\n * @param {string | number | null} key The key for this virtual node, used when\n * diffing it against its children\n * @param {import('./internal').VNode[\"ref\"]} ref The ref property that will\n * receive a reference to its created child\n * @returns {import('./internal').VNode}\n */\nexport function createVNode(type, props, key, ref, original) {\n\t// V8 seems to be better at detecting type shapes if the object is allocated from the same call site\n\t// Do not inline into createElement and coerceToVNode!\n\t/** @type {import('./internal').VNode} */\n\tconst vnode = {\n\t\ttype,\n\t\tprops,\n\t\tkey,\n\t\tref,\n\t\t_children: NULL,\n\t\t_parent: NULL,\n\t\t_depth: 0,\n\t\t_dom: NULL,\n\t\t_component: NULL,\n\t\tconstructor: UNDEFINED,\n\t\t_original: original == NULL ? ++vnodeId : original,\n\t\t_index: -1,\n\t\t_flags: 0\n\t};\n\n\t// Only invoke the vnode hook if this was *not* a direct copy:\n\tif (original == NULL && options.vnode != NULL) options.vnode(vnode);\n\n\treturn vnode;\n}\n\nexport function createRef() {\n\treturn { current: NULL };\n}\n\nexport function Fragment(props) {\n\treturn props.children;\n}\n\n/**\n * Check if a the argument is a valid Preact VNode.\n * @param {*} vnode\n * @returns {vnode is VNode}\n */\nexport const isValidElement = vnode =>\n\tvnode != NULL && vnode.constructor === UNDEFINED;\n","import { assign } from './util';\nimport { diff, commitRoot } from './diff/index';\nimport options from './options';\nimport { Fragment } from './create-element';\nimport { MODE_HYDRATE, NULL } from './constants';\n\n/**\n * Base Component class. Provides `setState()` and `forceUpdate()`, which\n * trigger rendering\n * @param {object} props The initial component props\n * @param {object} context The initial context from parent components'\n * getChildContext\n */\nexport function BaseComponent(props, context) {\n\tthis.props = props;\n\tthis.context = context;\n}\n\n/**\n * Update component state and schedule a re-render.\n * @this {import('./internal').Component}\n * @param {object | ((s: object, p: object) => object)} update A hash of state\n * properties to update with new values or a function that given the current\n * state and props returns a new partial state\n * @param {() => void} [callback] A function to be called once component state is\n * updated\n */\nBaseComponent.prototype.setState = function (update, callback) {\n\t// only clone state when copying to nextState the first time.\n\tlet s;\n\tif (this._nextState != NULL && this._nextState != this.state) {\n\t\ts = this._nextState;\n\t} else {\n\t\ts = this._nextState = assign({}, this.state);\n\t}\n\n\tif (typeof update == 'function') {\n\t\t// Some libraries like `immer` mark the current state as readonly,\n\t\t// preventing us from mutating it, so we need to clone it. See #2716\n\t\tupdate = update(assign({}, s), this.props);\n\t}\n\n\tif (update) {\n\t\tassign(s, update);\n\t}\n\n\t// Skip update if updater function returned null\n\tif (update == NULL) return;\n\n\tif (this._vnode) {\n\t\tif (callback) {\n\t\t\tthis._stateCallbacks.push(callback);\n\t\t}\n\t\tenqueueRender(this);\n\t}\n};\n\n/**\n * Immediately perform a synchronous re-render of the component\n * @this {import('./internal').Component}\n * @param {() => void} [callback] A function to be called after component is\n * re-rendered\n */\nBaseComponent.prototype.forceUpdate = function (callback) {\n\tif (this._vnode) {\n\t\t// Set render mode so that we can differentiate where the render request\n\t\t// is coming from. We need this because forceUpdate should never call\n\t\t// shouldComponentUpdate\n\t\tthis._force = true;\n\t\tif (callback) this._renderCallbacks.push(callback);\n\t\tenqueueRender(this);\n\t}\n};\n\n/**\n * Accepts `props` and `state`, and returns a new Virtual DOM tree to build.\n * Virtual DOM is generally constructed via [JSX](https://jasonformat.com/wtf-is-jsx).\n * @param {object} props Props (eg: JSX attributes) received from parent\n * element/component\n * @param {object} state The component's current state\n * @param {object} context Context object, as returned by the nearest\n * ancestor's `getChildContext()`\n * @returns {ComponentChildren | void}\n */\nBaseComponent.prototype.render = Fragment;\n\n/**\n * @param {import('./internal').VNode} vnode\n * @param {number | null} [childIndex]\n */\nexport function getDomSibling(vnode, childIndex) {\n\tif (childIndex == NULL) {\n\t\t// Use childIndex==null as a signal to resume the search from the vnode's sibling\n\t\treturn vnode._parent\n\t\t\t? getDomSibling(vnode._parent, vnode._index + 1)\n\t\t\t: NULL;\n\t}\n\n\tlet sibling;\n\tfor (; childIndex < vnode._children.length; childIndex++) {\n\t\tsibling = vnode._children[childIndex];\n\n\t\tif (sibling != NULL && sibling._dom != NULL) {\n\t\t\t// Since updateParentDomPointers keeps _dom pointer correct,\n\t\t\t// we can rely on _dom to tell us if this subtree contains a\n\t\t\t// rendered DOM node, and what the first rendered DOM node is\n\t\t\treturn sibling._dom;\n\t\t}\n\t}\n\n\t// If we get here, we have not found a DOM node in this vnode's children.\n\t// We must resume from this vnode's sibling (in it's parent _children array)\n\t// Only climb up and search the parent if we aren't searching through a DOM\n\t// VNode (meaning we reached the DOM parent of the original vnode that began\n\t// the search)\n\treturn typeof vnode.type == 'function' ? getDomSibling(vnode) : NULL;\n}\n\n/**\n * Trigger in-place re-rendering of a component.\n * @param {import('./internal').Component} component The component to rerender\n */\nfunction renderComponent(component) {\n\tif (component._parentDom && component._dirty) {\n\t\tlet oldVNode = component._vnode,\n\t\t\toldDom = oldVNode._dom,\n\t\t\tcommitQueue = [],\n\t\t\trefQueue = [],\n\t\t\tnewVNode = assign({}, oldVNode);\n\t\tnewVNode._original = oldVNode._original + 1;\n\t\tif (options.vnode) options.vnode(newVNode);\n\n\t\tdiff(\n\t\t\tcomponent._parentDom,\n\t\t\tnewVNode,\n\t\t\toldVNode,\n\t\t\tcomponent._globalContext,\n\t\t\tcomponent._parentDom.namespaceURI,\n\t\t\toldVNode._flags & MODE_HYDRATE ? [oldDom] : NULL,\n\t\t\tcommitQueue,\n\t\t\toldDom == NULL ? getDomSibling(oldVNode) : oldDom,\n\t\t\t!!(oldVNode._flags & MODE_HYDRATE),\n\t\t\trefQueue\n\t\t);\n\n\t\tnewVNode._original = oldVNode._original;\n\t\tnewVNode._parent._children[newVNode._index] = newVNode;\n\t\tcommitRoot(commitQueue, newVNode, refQueue);\n\t\toldVNode._dom = oldVNode._parent = null;\n\n\t\tif (newVNode._dom != oldDom) {\n\t\t\tupdateParentDomPointers(newVNode);\n\t\t}\n\t}\n}\n\n/**\n * @param {import('./internal').VNode} vnode\n */\nfunction updateParentDomPointers(vnode) {\n\tif ((vnode = vnode._parent) != NULL && vnode._component != NULL) {\n\t\tvnode._dom = vnode._component.base = NULL;\n\t\tvnode._children.some(child => {\n\t\t\tif (child != NULL && child._dom != NULL) {\n\t\t\t\treturn (vnode._dom = vnode._component.base = child._dom);\n\t\t\t}\n\t\t});\n\n\t\treturn updateParentDomPointers(vnode);\n\t}\n}\n\n/**\n * The render queue\n * @type {Array<import('./internal').Component>}\n */\nlet rerenderQueue = [];\n\n/*\n * The value of `Component.debounce` must asynchronously invoke the passed in callback. It is\n * important that contributors to Preact can consistently reason about what calls to `setState`, etc.\n * do, and when their effects will be applied. See the links below for some further reading on designing\n * asynchronous APIs.\n * * [Designing APIs for Asynchrony](https://blog.izs.me/2013/08/designing-apis-for-asynchrony)\n * * [Callbacks synchronous and asynchronous](https://blog.ometer.com/2011/07/24/callbacks-synchronous-and-asynchronous/)\n */\n\nlet prevDebounce;\n\nconst defer =\n\ttypeof Promise == 'function'\n\t\t? Promise.prototype.then.bind(Promise.resolve())\n\t\t: setTimeout;\n\n/**\n * Enqueue a rerender of a component\n * @param {import('./internal').Component} c The component to rerender\n */\nexport function enqueueRender(c) {\n\tif (\n\t\t(!c._dirty &&\n\t\t\t(c._dirty = true) &&\n\t\t\trerenderQueue.push(c) &&\n\t\t\t!process._rerenderCount++) ||\n\t\tprevDebounce != options.debounceRendering\n\t) {\n\t\tprevDebounce = options.debounceRendering;\n\t\t(prevDebounce || defer)(process);\n\t}\n}\n\n/**\n * @param {import('./internal').Component} a\n * @param {import('./internal').Component} b\n */\nconst depthSort = (a, b) => a._vnode._depth - b._vnode._depth;\n\n/** Flush the render queue by rerendering all queued components */\nfunction process() {\n\ttry {\n\t\tlet c,\n\t\t\tl = 1;\n\n\t\t// Don't update `renderCount` yet. Keep its value non-zero to prevent unnecessary\n\t\t// process() calls from getting scheduled while `queue` is still being consumed.\n\t\twhile (rerenderQueue.length) {\n\t\t\t// Keep the rerender queue sorted by (depth, insertion order). The queue\n\t\t\t// will initially be sorted on the first iteration only if it has more than 1 item.\n\t\t\t//\n\t\t\t// New items can be added to the queue e.g. when rerendering a provider, so we want to\n\t\t\t// keep the order from top to bottom with those new items so we can handle them in a\n\t\t\t// single pass\n\t\t\tif (rerenderQueue.length > l) {\n\t\t\t\trerenderQueue.sort(depthSort);\n\t\t\t}\n\n\t\t\tc = rerenderQueue.shift();\n\t\t\tl = rerenderQueue.length;\n\n\t\t\trenderComponent(c);\n\t\t}\n\t} finally {\n\t\trerenderQueue.length = process._rerenderCount = 0;\n\t}\n}\n\nprocess._rerenderCount = 0;\n","import { IS_NON_DIMENSIONAL, NULL, SVG_NAMESPACE } from '../constants';\nimport options from '../options';\n\nfunction setStyle(style, key, value) {\n\tif (key[0] == '-') {\n\t\tstyle.setProperty(key, value == NULL ? '' : value);\n\t} else if (value == NULL) {\n\t\tstyle[key] = '';\n\t} else if (typeof value != 'number' || IS_NON_DIMENSIONAL.test(key)) {\n\t\tstyle[key] = value;\n\t} else {\n\t\tstyle[key] = value + 'px';\n\t}\n}\n\nconst CAPTURE_REGEX = /(PointerCapture)$|Capture$/i;\n\n// A logical clock to solve issues like https://github.com/preactjs/preact/issues/3927.\n// When the DOM performs an event it leaves micro-ticks in between bubbling up which means that\n// an event can trigger on a newly reated DOM-node while the event bubbles up.\n//\n// Originally inspired by Vue\n// (https://github.com/vuejs/core/blob/caeb8a68811a1b0f79/packages/runtime-dom/src/modules/events.ts#L90-L101),\n// but modified to use a logical clock instead of Date.now() in case event handlers get attached\n// and events get dispatched during the same millisecond.\n//\n// The clock is incremented after each new event dispatch. This allows 1 000 000 new events\n// per second for over 280 years before the value reaches Number.MAX_SAFE_INTEGER (2**53 - 1).\nlet eventClock = 0;\n\n/**\n * Set a property value on a DOM node\n * @param {import('../internal').PreactElement} dom The DOM node to modify\n * @param {string} name The name of the property to set\n * @param {*} value The value to set the property to\n * @param {*} oldValue The old value the property had\n * @param {string} namespace Whether or not this DOM node is an SVG node or not\n */\nexport function setProperty(dom, name, value, oldValue, namespace) {\n\tlet useCapture;\n\n\to: if (name == 'style') {\n\t\tif (typeof value == 'string') {\n\t\t\tdom.style.cssText = value;\n\t\t} else {\n\t\t\tif (typeof oldValue == 'string') {\n\t\t\t\tdom.style.cssText = oldValue = '';\n\t\t\t}\n\n\t\t\tif (oldValue) {\n\t\t\t\tfor (name in oldValue) {\n\t\t\t\t\tif (!(value && name in value)) {\n\t\t\t\t\t\tsetStyle(dom.style, name, '');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (value) {\n\t\t\t\tfor (name in value) {\n\t\t\t\t\tif (!oldValue || value[name] != oldValue[name]) {\n\t\t\t\t\t\tsetStyle(dom.style, name, value[name]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t// Benchmark for comparison: https://esbench.com/bench/574c954bdb965b9a00965ac6\n\telse if (name[0] == 'o' && name[1] == 'n') {\n\t\tuseCapture = name != (name = name.replace(CAPTURE_REGEX, '$1'));\n\t\tconst lowerCaseName = name.toLowerCase();\n\n\t\t// Infer correct casing for DOM built-in events:\n\t\tif (lowerCaseName in dom || name == 'onFocusOut' || name == 'onFocusIn')\n\t\t\tname = lowerCaseName.slice(2);\n\t\telse name = name.slice(2);\n\n\t\tif (!dom._listeners) dom._listeners = {};\n\t\tdom._listeners[name + useCapture] = value;\n\n\t\tif (value) {\n\t\t\tif (!oldValue) {\n\t\t\t\tvalue._attached = eventClock;\n\t\t\t\tdom.addEventListener(\n\t\t\t\t\tname,\n\t\t\t\t\tuseCapture ? eventProxyCapture : eventProxy,\n\t\t\t\t\tuseCapture\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tvalue._attached = oldValue._attached;\n\t\t\t}\n\t\t} else {\n\t\t\tdom.removeEventListener(\n\t\t\t\tname,\n\t\t\t\tuseCapture ? eventProxyCapture : eventProxy,\n\t\t\t\tuseCapture\n\t\t\t);\n\t\t}\n\t} else {\n\t\tif (namespace == SVG_NAMESPACE) {\n\t\t\t// Normalize incorrect prop usage for SVG:\n\t\t\t// - xlink:href / xlinkHref --> href (xlink:href was removed from SVG and isn't needed)\n\t\t\t// - className --> class\n\t\t\tname = name.replace(/xlink(H|:h)/, 'h').replace(/sName$/, 's');\n\t\t} else if (\n\t\t\tname != 'width' &&\n\t\t\tname != 'height' &&\n\t\t\tname != 'href' &&\n\t\t\tname != 'list' &&\n\t\t\tname != 'form' &&\n\t\t\t// Default value in browsers is `-1` and an empty string is\n\t\t\t// cast to `0` instead\n\t\t\tname != 'tabIndex' &&\n\t\t\tname != 'download' &&\n\t\t\tname != 'rowSpan' &&\n\t\t\tname != 'colSpan' &&\n\t\t\tname != 'role' &&\n\t\t\tname != 'popover' &&\n\t\t\tname in dom\n\t\t) {\n\t\t\ttry {\n\t\t\t\tdom[name] = value == NULL ? '' : value;\n\t\t\t\t// labelled break is 1b smaller here than a return statement (sorry)\n\t\t\t\tbreak o;\n\t\t\t} catch (e) {}\n\t\t}\n\n\t\t// aria- and data- attributes have no boolean representation.\n\t\t// A `false` value is different from the attribute not being\n\t\t// present, so we can't remove it. For non-boolean aria\n\t\t// attributes we could treat false as a removal, but the\n\t\t// amount of exceptions would cost too many bytes. On top of\n\t\t// that other frameworks generally stringify `false`.\n\n\t\tif (typeof value == 'function') {\n\t\t\t// never serialize functions as attribute values\n\t\t} else if (value != NULL && (value !== false || name[4] == '-')) {\n\t\t\tdom.setAttribute(name, name == 'popover' && value == true ? '' : value);\n\t\t} else {\n\t\t\tdom.removeAttribute(name);\n\t\t}\n\t}\n}\n\n/**\n * Create an event proxy function.\n * @param {boolean} useCapture Is the event handler for the capture phase.\n * @private\n */\nfunction createEventProxy(useCapture) {\n\t/**\n\t * Proxy an event to hooked event handlers\n\t * @param {import('../internal').PreactEvent} e The event object from the browser\n\t * @private\n\t */\n\treturn function (e) {\n\t\tif (this._listeners) {\n\t\t\tconst eventHandler = this._listeners[e.type + useCapture];\n\t\t\tif (e._dispatched == NULL) {\n\t\t\t\te._dispatched = eventClock++;\n\n\t\t\t\t// When `e._dispatched` is smaller than the time when the targeted event\n\t\t\t\t// handler was attached we know we have bubbled up to an element that was added\n\t\t\t\t// during patching the DOM.\n\t\t\t} else if (e._dispatched < eventHandler._attached) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\treturn eventHandler(options.event ? options.event(e) : e);\n\t\t}\n\t};\n}\n\nconst eventProxy = createEventProxy(false);\nconst eventProxyCapture = createEventProxy(true);\n","import { enqueueRender } from './component';\nimport { NULL } from './constants';\n\nexport let i = 0;\n\nexport function createContext(defaultValue) {\n\tfunction Context(props) {\n\t\tif (!this.getChildContext) {\n\t\t\t/** @type {Set<import('./internal').Component> | null} */\n\t\t\tlet subs = new Set();\n\t\t\tlet ctx = {};\n\t\t\tctx[Context._id] = this;\n\n\t\t\tthis.getChildContext = () => ctx;\n\n\t\t\tthis.componentWillUnmount = () => {\n\t\t\t\tsubs = NULL;\n\t\t\t};\n\n\t\t\tthis.shouldComponentUpdate = function (_props) {\n\t\t\t\t// @ts-expect-error even\n\t\t\t\tif (this.props.value != _props.value) {\n\t\t\t\t\tsubs.forEach(c => {\n\t\t\t\t\t\tc._force = true;\n\t\t\t\t\t\tenqueueRender(c);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tthis.sub = c => {\n\t\t\t\tsubs.add(c);\n\t\t\t\tlet old = c.componentWillUnmount;\n\t\t\t\tc.componentWillUnmount = () => {\n\t\t\t\t\tif (subs) {\n\t\t\t\t\t\tsubs.delete(c);\n\t\t\t\t\t}\n\t\t\t\t\tif (old) old.call(c);\n\t\t\t\t};\n\t\t\t};\n\t\t}\n\n\t\treturn props.children;\n\t}\n\n\tContext._id = '__cC' + i++;\n\tContext._defaultValue = defaultValue;\n\n\t/** @type {import('./internal').FunctionComponent} */\n\tContext.Consumer = (props, contextValue) => {\n\t\treturn props.children(contextValue);\n\t};\n\n\t// we could also get rid of _contextRef entirely\n\tContext.Provider =\n\t\tContext._contextRef =\n\t\tContext.Consumer.contextType =\n\t\t\tContext;\n\n\treturn Context;\n}\n","import { diff, unmount, applyRef } from './index';\nimport { createVNode, Fragment } from '../create-element';\nimport {\n\tEMPTY_OBJ,\n\tEMPTY_ARR,\n\tINSERT_VNODE,\n\tMATCHED,\n\tUNDEFINED,\n\tNULL\n} from '../constants';\nimport { isArray } from '../util';\nimport { getDomSibling } from '../component';\n\n/**\n * @typedef {import('../internal').ComponentChildren} ComponentChildren\n * @typedef {import('../internal').Component} Component\n * @typedef {import('../internal').PreactElement} PreactElement\n * @typedef {import('../internal').VNode} VNode\n */\n\n/**\n * Diff the children of a virtual node\n * @param {PreactElement} parentDom The DOM element whose children are being\n * diffed\n * @param {ComponentChildren[]} renderResult\n * @param {VNode} newParentVNode The new virtual node whose children should be\n * diff'ed against oldParentVNode\n * @param {VNode} oldParentVNode The old virtual node whose children should be\n * diff'ed against newParentVNode\n * @param {object} globalContext The current context object - modified by\n * getChildContext\n * @param {string} namespace Current namespace of the DOM node (HTML, SVG, or MathML)\n * @param {Array<PreactElement>} excessDomChildren\n * @param {Array<Component>} commitQueue List of components which have callbacks\n * to invoke in commitRoot\n * @param {PreactElement} oldDom The current attached DOM element any new dom\n * elements should be placed around. Likely `null` on first render (except when\n * hydrating). Can be a sibling DOM element when diffing Fragments that have\n * siblings. In most cases, it starts out as `oldChildren[0]._dom`.\n * @param {boolean} isHydrating Whether or not we are in hydration\n * @param {any[]} refQueue an array of elements needed to invoke refs\n */\nexport function diffChildren(\n\tparentDom,\n\trenderResult,\n\tnewParentVNode,\n\toldParentVNode,\n\tglobalContext,\n\tnamespace,\n\texcessDomChildren,\n\tcommitQueue,\n\toldDom,\n\tisHydrating,\n\trefQueue\n) {\n\tlet i,\n\t\t/** @type {VNode} */\n\t\toldVNode,\n\t\t/** @type {VNode} */\n\t\tchildVNode,\n\t\t/** @type {PreactElement} */\n\t\tnewDom,\n\t\t/** @type {PreactElement} */\n\t\tfirstChildDom;\n\n\t// This is a compression of oldParentVNode!=null && oldParentVNode != EMPTY_OBJ && oldParentVNode._children || EMPTY_ARR\n\t// as EMPTY_OBJ._children should be `undefined`.\n\t/** @type {VNode[]} */\n\tlet oldChildren = (oldParentVNode && oldParentVNode._children) || EMPTY_ARR;\n\n\tlet newChildrenLength = renderResult.length;\n\n\toldDom = constructNewChildrenArray(\n\t\tnewParentVNode,\n\t\trenderResult,\n\t\toldChildren,\n\t\toldDom,\n\t\tnewChildrenLength\n\t);\n\n\tfor (i = 0; i < newChildrenLength; i++) {\n\t\tchildVNode = newParentVNode._children[i];\n\t\tif (childVNode == NULL) continue;\n\n\t\t// At this point, constructNewChildrenArray has assigned _index to be the\n\t\t// matchingIndex for this VNode's oldVNode (or -1 if there is no oldVNode).\n\t\toldVNode =\n\t\t\t(childVNode._index != -1 && oldChildren[childVNode._index]) || EMPTY_OBJ;\n\n\t\t// Update childVNode._index to its final index\n\t\tchildVNode._index = i;\n\n\t\t// Morph the old element into the new one, but don't append it to the dom yet\n\t\tlet result = diff(\n\t\t\tparentDom,\n\t\t\tchildVNode,\n\t\t\toldVNode,\n\t\t\tglobalContext,\n\t\t\tnamespace,\n\t\t\texcessDomChildren,\n\t\t\tcommitQueue,\n\t\t\toldDom,\n\t\t\tisHydrating,\n\t\t\trefQueue\n\t\t);\n\n\t\t// Adjust DOM nodes\n\t\tnewDom = childVNode._dom;\n\t\tif (childVNode.ref && oldVNode.ref != childVNode.ref) {\n\t\t\tif (oldVNode.ref) {\n\t\t\t\tapplyRef(oldVNode.ref, NULL, childVNode);\n\t\t\t}\n\t\t\trefQueue.push(\n\t\t\t\tchildVNode.ref,\n\t\t\t\tchildVNode._component || newDom,\n\t\t\t\tchildVNode\n\t\t\t);\n\t\t}\n\n\t\tif (firstChildDom == NULL && newDom != NULL) {\n\t\t\tfirstChildDom = newDom;\n\t\t}\n\n\t\tlet shouldPlace = !!(childVNode._flags & INSERT_VNODE);\n\t\tif (shouldPlace || oldVNode._children === childVNode._children) {\n\t\t\toldDom = insert(childVNode, oldDom, parentDom, shouldPlace);\n\t\t} else if (typeof childVNode.type == 'function' && result !== UNDEFINED) {\n\t\t\toldDom = result;\n\t\t} else if (newDom) {\n\t\t\toldDom = newDom.nextSibling;\n\t\t}\n\n\t\t// Unset diffing flags\n\t\tchildVNode._flags &= ~(INSERT_VNODE | MATCHED);\n\t}\n\n\tnewParentVNode._dom = firstChildDom;\n\n\treturn oldDom;\n}\n\n/**\n * @param {VNode} newParentVNode\n * @param {ComponentChildren[]} renderResult\n * @param {VNode[]} oldChildren\n */\nfunction constructNewChildrenArray(\n\tnewParentVNode,\n\trenderResult,\n\toldChildren,\n\toldDom,\n\tnewChildrenLength\n) {\n\t/** @type {number} */\n\tlet i;\n\t/** @type {VNode} */\n\tlet childVNode;\n\t/** @type {VNode} */\n\tlet oldVNode;\n\n\tlet oldChildrenLength = oldChildren.length,\n\t\tremainingOldChildren = oldChildrenLength;\n\n\tlet skew = 0;\n\n\tnewParentVNode._children = new Array(newChildrenLength);\n\tfor (i = 0; i < newChildrenLength; i++) {\n\t\t// @ts-expect-error We are reusing the childVNode variable to hold both the\n\t\t// pre and post normalized childVNode\n\t\tchildVNode = renderResult[i];\n\n\t\tif (\n\t\t\tchildVNode == NULL ||\n\t\t\ttypeof childVNode == 'boolean' ||\n\t\t\ttypeof childVNode == 'function'\n\t\t) {\n\t\t\tnewParentVNode._children[i] = NULL;\n\t\t\tcontinue;\n\t\t}\n\t\t// If this newVNode is being reused (e.g. <div>{reuse}{reuse}</div>) in the same diff,\n\t\t// or we are rendering a component (e.g. setState) copy the oldVNodes so it can have\n\t\t// it's own DOM & etc. pointers\n\t\telse if (\n\t\t\ttypeof childVNode == 'string' ||\n\t\t\ttypeof childVNode == 'number' ||\n\t\t\t// eslint-disable-next-line valid-typeof\n\t\t\ttypeof childVNode == 'bigint' ||\n\t\t\tchildVNode.constructor == String\n\t\t) {\n\t\t\tchildVNode = newParentVNode._children[i] = createVNode(\n\t\t\t\tNULL,\n\t\t\t\tchildVNode,\n\t\t\t\tNULL,\n\t\t\t\tNULL,\n\t\t\t\tNULL\n\t\t\t);\n\t\t} else if (isArray(childVNode)) {\n\t\t\tchildVNode = newParentVNode._children[i] = createVNode(\n\t\t\t\tFragment,\n\t\t\t\t{ children: childVNode },\n\t\t\t\tNULL,\n\t\t\t\tNULL,\n\t\t\t\tNULL\n\t\t\t);\n\t\t} else if (childVNode.constructor === UNDEFINED && childVNode._depth > 0) {\n\t\t\t// VNode is already in use, clone it. This can happen in the following\n\t\t\t// scenario:\n\t\t\t// const reuse = <div />\n\t\t\t// <div>{reuse}<span />{reuse}</div>\n\t\t\tchildVNode = newParentVNode._children[i] = createVNode(\n\t\t\t\tchildVNode.type,\n\t\t\t\tchildVNode.props,\n\t\t\t\tchildVNode.key,\n\t\t\t\tchildVNode.ref ? childVNode.ref : NULL,\n\t\t\t\tchildVNode._original\n\t\t\t);\n\t\t} else {\n\t\t\tnewParentVNode._children[i] = childVNode;\n\t\t}\n\n\t\tconst skewedIndex = i + skew;\n\t\tchildVNode._parent = newParentVNode;\n\t\tchildVNode._depth = newParentVNode._depth + 1;\n\n\t\t// Temporarily store the matchingIndex on the _index property so we can pull\n\t\t// out the oldVNode in diffChildren. We'll override this to the VNode's\n\t\t// final index after using this property to get the oldVNode\n\t\tconst matchingIndex = (childVNode._index = findMatchingIndex(\n\t\t\tchildVNode,\n\t\t\toldChildren,\n\t\t\tskewedIndex,\n\t\t\tremainingOldChildren\n\t\t));\n\n\t\toldVNode = NULL;\n\t\tif (matchingIndex != -1) {\n\t\t\toldVNode = oldChildren[matchingIndex];\n\t\t\tremainingOldChildren--;\n\t\t\tif (oldVNode) {\n\t\t\t\toldVNode._flags |= MATCHED;\n\t\t\t}\n\t\t}\n\n\t\t// Here, we define isMounting for the purposes of the skew diffing\n\t\t// algorithm. Nodes that are unsuspending are considered mounting and we detect\n\t\t// this by checking if oldVNode._original == null\n\t\tconst isMounting = oldVNode == NULL || oldVNode._original == NULL;\n\n\t\tif (isMounting) {\n\t\t\tif (matchingIndex == -1) {\n\t\t\t\t// When the array of children is growing we need to decrease the skew\n\t\t\t\t// as we are adding a new element to the array.\n\t\t\t\t// Example:\n\t\t\t\t// [1, 2, 3] --> [0, 1, 2, 3]\n\t\t\t\t// oldChildren newChildren\n\t\t\t\t//\n\t\t\t\t// The new element is at index 0, so our skew is 0,\n\t\t\t\t// we need to decrease the skew as we are adding a new element.\n\t\t\t\t// The decrease will cause us to compare the element at position 1\n\t\t\t\t// with value 1 with the element at position 0 with value 0.\n\t\t\t\t//\n\t\t\t\t// A linear concept is applied when the array is shrinking,\n\t\t\t\t// if the length is unchanged we can assume that no skew\n\t\t\t\t// changes are needed.\n\t\t\t\tif (newChildrenLength > oldChildrenLength) {\n\t\t\t\t\tskew--;\n\t\t\t\t} else if (newChildrenLength < oldChildrenLength) {\n\t\t\t\t\tskew++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If we are mounting a DOM VNode, mark it for insertion\n\t\t\tif (typeof childVNode.type != 'function') {\n\t\t\t\tchildVNode._flags |= INSERT_VNODE;\n\t\t\t}\n\t\t} else if (matchingIndex != skewedIndex) {\n\t\t\t// When we move elements around i.e. [0, 1, 2] --> [1, 0, 2]\n\t\t\t// --> we diff 1, we find it at position 1 while our skewed index is 0 and our skew is 0\n\t\t\t// we set the skew to 1 as we found an offset.\n\t\t\t// --> we diff 0, we find it at position 0 while our skewed index is at 2 and our skew is 1\n\t\t\t// this makes us increase the skew again.\n\t\t\t// --> we diff 2, we find it at position 2 while our skewed index is at 4 and our skew is 2\n\t\t\t//\n\t\t\t// this becomes an optimization question where currently we see a 1 element offset as an insertion\n\t\t\t// or deletion i.e. we optimize for [0, 1, 2] --> [9, 0, 1, 2]\n\t\t\t// while a more than 1 offset we see as a swap.\n\t\t\t// We could probably build heuristics for having an optimized course of action here as well, but\n\t\t\t// might go at the cost of some bytes.\n\t\t\t//\n\t\t\t// If we wanted to optimize for i.e. only swaps we'd just do the last two code-branches and have\n\t\t\t// only the first item be a re-scouting and all the others fall in their skewed counter-part.\n\t\t\t// We could also further optimize for swaps\n\t\t\tif (matchingIndex == skewedIndex - 1) {\n\t\t\t\tskew--;\n\t\t\t} else if (matchingIndex == skewedIndex + 1) {\n\t\t\t\tskew++;\n\t\t\t} else {\n\t\t\t\tif (matchingIndex > skewedIndex) {\n\t\t\t\t\tskew--;\n\t\t\t\t} else {\n\t\t\t\t\tskew++;\n\t\t\t\t}\n\n\t\t\t\t// Move this VNode's DOM if the original index (matchingIndex) doesn't\n\t\t\t\t// match the new skew index (i + new skew)\n\t\t\t\t// In the former two branches we know that it matches after skewing\n\t\t\t\tchildVNode._flags |= INSERT_VNODE;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Remove remaining oldChildren if there are any. Loop forwards so that as we\n\t// unmount DOM from the beginning of the oldChildren, we can adjust oldDom to\n\t// point to the next child, which needs to be the first DOM node that won't be\n\t// unmounted.\n\tif (remainingOldChildren) {\n\t\tfor (i = 0; i < oldChildrenLength; i++) {\n\t\t\toldVNode = oldChildren[i];\n\t\t\tif (oldVNode != NULL && (oldVNode._flags & MATCHED) == 0) {\n\t\t\t\tif (oldVNode._dom == oldDom) {\n\t\t\t\t\toldDom = getDomSibling(oldVNode);\n\t\t\t\t}\n\n\t\t\t\tunmount(oldVNode, oldVNode);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn oldDom;\n}\n\n/**\n * @param {VNode} parentVNode\n * @param {PreactElement} oldDom\n * @param {PreactElement} parentDom\n * @param {boolean} shouldPlace\n * @returns {PreactElement}\n */\nfunction insert(parentVNode, oldDom, parentDom, shouldPlace) {\n\t// Note: VNodes in nested suspended trees may be missing _children.\n\n\tif (typeof parentVNode.type == 'function') {\n\t\tlet children = parentVNode._children;\n\t\tfor (let i = 0; children && i < children.length; i++) {\n\t\t\tif (children[i]) {\n\t\t\t\t// If we enter this code path on sCU bailout, where we copy\n\t\t\t\t// oldVNode._children to newVNode._children, we need to update the old\n\t\t\t\t// children's _parent pointer to point to the newVNode (parentVNode\n\t\t\t\t// here).\n\t\t\t\tchildren[i]._parent = parentVNode;\n\t\t\t\toldDom = insert(children[i], oldDom, parentDom, shouldPlace);\n\t\t\t}\n\t\t}\n\n\t\treturn oldDom;\n\t} else if (parentVNode._dom != oldDom) {\n\t\tif (shouldPlace) {\n\t\t\tif (oldDom && parentVNode.type && !oldDom.parentNode) {\n\t\t\t\toldDom = getDomSibling(parentVNode);\n\t\t\t}\n\t\t\tparentDom.insertBefore(parentVNode._dom, oldDom || NULL);\n\t\t}\n\t\toldDom = parentVNode._dom;\n\t}\n\n\tdo {\n\t\toldDom = oldDom && oldDom.nextSibling;\n\t} while (oldDom != NULL && oldDom.nodeType == 8);\n\n\treturn oldDom;\n}\n\n/**\n * Flatten and loop through the children of a virtual node\n * @param {ComponentChildren} children The unflattened children of a virtual\n * node\n * @returns {VNode[]}\n */\nexport function toChildArray(children, out) {\n\tout = out || [];\n\tif (children == NULL || typeof children == 'boolean') {\n\t} else if (isArray(children)) {\n\t\tchildren.some(child => {\n\t\t\ttoChildArray(child, out);\n\t\t});\n\t} else {\n\t\tout.push(children);\n\t}\n\treturn out;\n}\n\n/**\n * @param {VNode} childVNode\n * @param {VNode[]} oldChildren\n * @param {number} skewedIndex\n * @param {number} remainingOldChildren\n * @returns {number}\n */\nfunction findMatchingIndex(\n\tchildVNode,\n\toldChildren,\n\tskewedIndex,\n\tremainingOldChildren\n) {\n\tconst key = childVNode.key;\n\tconst type = childVNode.type;\n\tlet oldVNode = oldChildren[skewedIndex];\n\tconst matched = oldVNode != NULL && (oldVNode._flags & MATCHED) == 0;\n\n\t// We only need to perform a search if there are more children\n\t// (remainingOldChildren) to search. However, if the oldVNode we just looked\n\t// at skewedIndex was not already used in this diff, then there must be at\n\t// least 1 other (so greater than 1) remainingOldChildren to attempt to match\n\t// against. So the following condition checks that ensuring\n\t// remainingOldChildren > 1 if the oldVNode is not already used/matched. Else\n\t// if the oldVNode was null or matched, then there could needs to be at least\n\t// 1 (aka `remainingOldChildren > 0`) children to find and compare against.\n\t//\n\t// If there is an unkeyed functional VNode, that isn't a built-in like our Fragment,\n\t// we should not search as we risk re-using state of an unrelated VNode. (reverted for now)\n\tlet shouldSearch =\n\t\t// (typeof type != 'function' || type === Fragment || key) &&\n\t\tremainingOldChildren > (matched ? 1 : 0);\n\n\tif (\n\t\t(oldVNode === NULL && key == null) ||\n\t\t(matched && key == oldVNode.key && type == oldVNode.type)\n\t) {\n\t\treturn skewedIndex;\n\t} else if (shouldSearch) {\n\t\tlet x = skewedIndex - 1;\n\t\tlet y = skewedIndex + 1;\n\t\twhile (x >= 0 || y < oldChildren.length) {\n\t\t\tconst childIndex = x >= 0 ? x-- : y++;\n\t\t\toldVNode = oldChildren[childIndex];\n\t\t\tif (\n\t\t\t\toldVNode != NULL &&\n\t\t\t\t(oldVNode._flags & MATCHED) == 0 &&\n\t\t\t\tkey == oldVNode.key &&\n\t\t\t\ttype == oldVNode.type\n\t\t\t) {\n\t\t\t\treturn childIndex;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn -1;\n}\n","import {\n\tEMPTY_ARR,\n\tEMPTY_OBJ,\n\tMATH_NAMESPACE,\n\tMODE_HYDRATE,\n\tMODE_SUSPENDED,\n\tNULL,\n\tRESET_MODE,\n\tSVG_NAMESPACE,\n\tUNDEFINED,\n\tXHTML_NAMESPACE\n} from '../constants';\nimport { BaseComponent, getDomSibling } from '../component';\nimport { Fragment } from '../create-element';\nimport { diffChildren } from './children';\nimport { setProperty } from './props';\nimport { assign, isArray, removeNode, slice } from '../util';\nimport options from '../options';\n\n/**\n * @typedef {import('../internal').ComponentChildren} ComponentChildren\n * @typedef {import('../internal').Component} Component\n * @typedef {import('../internal').PreactElement} PreactElement\n * @typedef {import('../internal').VNode} VNode\n */\n\n/**\n * @template {any} T\n * @typedef {import('../internal').Ref<T>} Ref<T>\n */\n\n/**\n * Diff two virtual nodes and apply proper changes to the DOM\n * @param {PreactElement} parentDom The parent of the DOM element\n * @param {VNode} newVNode The new virtual node\n * @param {VNode} oldVNode The old virtual node\n * @param {object} globalContext The current context object. Modified by\n * getChildContext\n * @param {string} namespace Current namespace of the DOM node (HTML, SVG, or MathML)\n * @param {Array<PreactElement>} excessDomChildren\n * @param {Array<Component>} commitQueue List of components which have callbacks\n * to invoke in commitRoot\n * @param {PreactElement} oldDom The current attached DOM element any new dom\n * elements should be placed around. Likely `null` on first render (except when\n * hydrating). Can be a sibling DOM element when diffing Fragments that have\n * siblings. In most cases, it starts out as `oldChildren[0]._dom`.\n * @param {boolean} isHydrating Whether or not we are in hydration\n * @param {any[]} refQueue an array of elements needed to invoke refs\n */\nexport function diff(\n\tparentDom,\n\tnewVNode,\n\toldVNode,\n\tglobalContext,\n\tnamespace,\n\texcessDomChildren,\n\tcommitQueue,\n\toldDom,\n\tisHydrating,\n\trefQueue\n) {\n\t/** @type {any} */\n\tlet tmp,\n\t\tnewType = newVNode.type;\n\n\t// When passing through createElement it assigns the object\n\t// constructor as undefined. This to prevent JSON-injection.\n\tif (newVNode.constructor !== UNDEFINED) return NULL;\n\n\t// If the previous diff bailed out, resume creating/hydrating.\n\tif (oldVNode._flags & MODE_SUSPENDED) {\n\t\tisHydrating = !!(oldVNode._flags & MODE_HYDRATE);\n\t\toldDom = newVNode._dom = oldVNode._dom;\n\t\texcessDomChildren = [oldDom];\n\t}\n\n\tif ((tmp = options._diff)) tmp(newVNode);\n\n\touter: if (typeof newType == 'function') {\n\t\ttry {\n\t\t\tlet c, isNew, oldProps, oldState, snapshot, clearProcessingException;\n\t\t\tlet newProps = newVNode.props;\n\t\t\tconst isClassComponent = newType.prototype && newType.prototype.render;\n\n\t\t\t// Necessary for createContext api. Setting this property will pass\n\t\t\t// the context value as `this.context` just for this component.\n\t\t\ttmp = newType.contextType;\n\t\t\tlet provider = tmp && globalContext[tmp._id];\n\t\t\tlet componentContext = tmp\n\t\t\t\t? provider\n\t\t\t\t\t? provider.props.value\n\t\t\t\t\t: tmp._defaultValue\n\t\t\t\t: globalContext;\n\n\t\t\t// Get component and set it to `c`\n\t\t\tif (oldVNode._component) {\n\t\t\t\tc = newVNode._component = oldVNode._component;\n\t\t\t\tclearProcessingException = c._processingException = c._pendingError;\n\t\t\t} else {\n\t\t\t\t// Instantiate the new component\n\t\t\t\tif (isClassComponent) {\n\t\t\t\t\t// @ts-expect-error The check above verifies that newType is suppose to be constructed\n\t\t\t\t\tnewVNode._component = c = new newType(newProps, componentContext); // eslint-disable-line new-cap\n\t\t\t\t} else {\n\t\t\t\t\t// @ts-expect-error Trust me, Component implements the interface we want\n\t\t\t\t\tnewVNode._component = c = new BaseComponent(\n\t\t\t\t\t\tnewProps,\n\t\t\t\t\t\tcomponentContext\n\t\t\t\t\t);\n\t\t\t\t\tc.constructor = newType;\n\t\t\t\t\tc.render = doRender;\n\t\t\t\t}\n\t\t\t\tif (provider) provider.sub(c);\n\n\t\t\t\tif (!c.state) c.state = {};\n\t\t\t\tc._globalContext = globalContext;\n\t\t\t\tisNew = c._dirty = true;\n\t\t\t\tc._renderCallbacks = [];\n\t\t\t\tc._stateCallbacks = [];\n\t\t\t}\n\n\t\t\t// Invoke getDerivedStateFromProps\n\t\t\tif (isClassComponent && c._nextState == NULL) {\n\t\t\t\tc._nextState = c.state;\n\t\t\t}\n\n\t\t\tif (isClassComponent && newType.getDerivedStateFromProps != NULL) {\n\t\t\t\tif (c._nextState == c.state) {\n\t\t\t\t\tc._nextState = assign({}, c._nextState);\n\t\t\t\t}\n\n\t\t\t\tassign(\n\t\t\t\t\tc._nextState,\n\t\t\t\t\tnewType.getDerivedStateFromProps(newProps, c._nextState)\n\t\t\t\t);\n\t\t\t}\n\n\t\t\toldProps = c.props;\n\t\t\toldState = c.state;\n\t\t\tc._vnode = newVNode;\n\n\t\t\t// Invoke pre-render lifecycle methods\n\t\t\tif (isNew) {\n\t\t\t\tif (\n\t\t\t\t\tisClassComponent &&\n\t\t\t\t\tnewType.getDerivedStateFromProps == NULL &&\n\t\t\t\t\tc.componentWillMount != NULL\n\t\t\t\t) {\n\t\t\t\t\tc.componentWillMount();\n\t\t\t\t}\n\n\t\t\t\tif (isClassComponent && c.componentDidMount != NULL) {\n\t\t\t\t\tc._renderCallbacks.push(c.componentDidMount);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (\n\t\t\t\t\tisClassComponent &&\n\t\t\t\t\tnewType.getDerivedStateFromProps == NULL &&\n\t\t\t\t\tnewProps !== oldProps &&\n\t\t\t\t\tc.componentWillReceiveProps != NULL\n\t\t\t\t) {\n\t\t\t\t\tc.componentWillReceiveProps(newProps, componentContext);\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\tnewVNode._original == oldVNode._original ||\n\t\t\t\t\t(!c._force &&\n\t\t\t\t\t\tc.shouldComponentUpdate != NULL &&\n\t\t\t\t\t\tc.shouldComponentUpdate(\n\t\t\t\t\t\t\tnewProps,\n\t\t\t\t\t\t\tc._nextState,\n\t\t\t\t\t\t\tcomponentContext\n\t\t\t\t\t\t) === false)\n\t\t\t\t) {\n\t\t\t\t\t// More info about this here: https://gist.github.com/JoviDeCroock/bec5f2ce93544d2e6070ef8e0036e4e8\n\t\t\t\t\tif (newVNode._original != oldVNode._original) {\n\t\t\t\t\t\t// When we are dealing with a bail because of sCU we have to update\n\t\t\t\t\t\t// the props, state and dirty-state.\n\t\t\t\t\t\t// when we are dealing with strict-equality we don't as the child could still\n\t\t\t\t\t\t// be dirtied see #3883\n\t\t\t\t\t\tc.props = newProps;\n\t\t\t\t\t\tc.state = c._nextState;\n\t\t\t\t\t\tc._dirty = false;\n\t\t\t\t\t}\n\n\t\t\t\t\tnewVNode._dom = oldVNode._dom;\n\t\t\t\t\tnewVNode._children = oldVNode._children;\n\t\t\t\t\tnewVNode._children.some(vnode => {\n\t\t\t\t\t\tif (vnode) vnode._parent = newVNode;\n\t\t\t\t\t});\n\n\t\t\t\t\tEMPTY_ARR.push.apply(c._renderCallbacks, c._stateCallbacks);\n\t\t\t\t\tc._stateCallbacks = [];\n\n\t\t\t\t\tif (c._renderCallbacks.length) {\n\t\t\t\t\t\tcommitQueue.push(c);\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak outer;\n\t\t\t\t}\n\n\t\t\t\tif (c.componentWillUpdate != NULL) {\n\t\t\t\t\tc.componentWillUpdate(newProps, c._nextState, componentContext);\n\t\t\t\t}\n\n\t\t\t\tif (isClassComponent && c.componentDidUpdate != NULL) {\n\t\t\t\t\tc._renderCallbacks.push(() => {\n\t\t\t\t\t\tc.componentDidUpdate(oldProps, oldState, snapshot);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tc.context = componentContext;\n\t\t\tc.props = newProps;\n\t\t\tc._parentDom = parentDom;\n\t\t\tc._force = false;\n\n\t\t\tlet renderHook = options._render,\n\t\t\t\tcount = 0;\n\t\t\tif (isClassComponent) {\n\t\t\t\tc.state = c._nextState;\n\t\t\t\tc._dirty = false;\n\n\t\t\t\tif (renderHook) renderHook(newVNode);\n\n\t\t\t\ttmp = c.render(c.props, c.state, c.context);\n\n\t\t\t\tEMPTY_ARR.push.apply(c._renderCallbacks, c._stateCallbacks);\n\t\t\t\tc._stateCallbacks = [];\n\t\t\t} else {\n\t\t\t\tdo {\n\t\t\t\t\tc._dirty = false;\n\t\t\t\t\tif (renderHook) renderHook(newVNode);\n\n\t\t\t\t\ttmp = c.render(c.props, c.state, c.context);\n\n\t\t\t\t\t// Handle setState called in render, see #2553\n\t\t\t\t\tc.state = c._nextState;\n\t\t\t\t} while (c._dirty && ++count < 25);\n\t\t\t}\n\n\t\t\t// Handle setState called in render, see #2553\n\t\t\tc.state = c._nextState;\n\n\t\t\tif (c.getChildContext != NULL) {\n\t\t\t\tglobalContext = assign(assign({}, globalContext), c.getChildContext());\n\t\t\t}\n\n\t\t\tif (isClassComponent && !isNew && c.getSnapshotBeforeUpdate != NULL) {\n\t\t\t\tsnapshot = c.getSnapshotBeforeUpdate(oldProps, oldState);\n\t\t\t}\n\n\t\t\tlet renderResult =\n\t\t\t\ttmp != NULL && tmp.type === Fragment && tmp.key == NULL\n\t\t\t\t\t? cloneNode(tmp.props.children)\n\t\t\t\t\t: tmp;\n\n\t\t\toldDom = diffChildren(\n\t\t\t\tparentDom,\n\t\t\t\tisArray(renderResult) ? renderResult : [renderResult],\n\t\t\t\tnewVNode,\n\t\t\t\toldVNode,\n\t\t\t\tglobalContext,\n\t\t\t\tnamespace,\n\t\t\t\texcessDomChildren,\n\t\t\t\tcommitQueue,\n\t\t\t\toldDom,\n\t\t\t\tisHydrating,\n\t\t\t\trefQueue\n\t\t\t);\n\n\t\t\tc.base = newVNode._dom;\n\n\t\t\t// We successfully rendered this VNode, unset any stored hydration/bailout state:\n\t\t\tnewVNode._flags &= RESET_MODE;\n\n\t\t\tif (c._renderCallbacks.length) {\n\t\t\t\tcommitQueue.push(c);\n\t\t\t}\n\n\t\t\tif (clearProcessingException) {\n\t\t\t\tc._pendingError = c._processingException = NULL;\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tnewVNode._original = NULL;\n\t\t\t// if hydrating or creating initial tree, bailout preserves DOM:\n\t\t\tif (isHydrating || excessDomChildren != NULL) {\n\t\t\t\tif (e.then) {\n\t\t\t\t\tnewVNode._flags |= isHydrating\n\t\t\t\t\t\t? MODE_HYDRATE | MODE_SUSPENDED\n\t\t\t\t\t\t: MODE_SUSPENDED;\n\n\t\t\t\t\twhile (oldDom && oldDom.nodeType == 8 && oldDom.nextSibling) {\n\t\t\t\t\t\toldDom = oldDom.nextSibling;\n\t\t\t\t\t}\n\n\t\t\t\t\texcessDomChildren[excessDomChildren.indexOf(oldDom)] = NULL;\n\t\t\t\t\tnewVNode._dom = oldDom;\n\t\t\t\t} else {\n\t\t\t\t\tfor (let i = excessDomChildren.length; i--; ) {\n\t\t\t\t\t\tremoveNode(excessDomChildren[i]);\n\t\t\t\t\t}\n\t\t\t\t\tmarkAsForce(newVNode);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tnewVNode._dom = oldVNode._dom;\n\t\t\t\tnewVNode._children = oldVNode._children;\n\t\t\t\tif (!e.then) markAsForce(newVNode);\n\t\t\t}\n\t\t\toptions._catchError(e, newVNode, oldVNode);\n\t\t}\n\t} else if (\n\t\texcessDomChildren == NULL &&\n\t\tnewVNode._original == oldVNode._original\n\t) {\n\t\tnewVNode._children = oldVNode._children;\n\t\tnewVNode._dom = oldVNode._dom;\n\t} else {\n\t\toldDom = newVNode._dom = diffElementNodes(\n\t\t\toldVNode._dom,\n\t\t\tnewVNode,\n\t\t\toldVNode,\n\t\t\tglobalContext,\n\t\t\tnamespace,\n\t\t\texcessDomChildren,\n\t\t\tcommitQueue,\n\t\t\tisHydrating,\n\t\t\trefQueue\n\t\t);\n\t}\n\n\tif ((tmp = options.diffed)) tmp(newVNode);\n\n\treturn newVNode._flags & MODE_SUSPENDED ? undefined : oldDom;\n}\n\nfunction markAsForce(vnode) {\n\tif (vnode) {\n\t\tif (vnode._component) vnode._component._force = true;\n\t\tif (vnode._children) vnode._children.some(markAsForce);\n\t}\n}\n\n/**\n * @param {Array<Component>} commitQueue List of components\n * which have callbacks to invoke in commitRoot\n * @param {VNode} root\n */\nexport function commitRoot(commitQueue, root, refQueue) {\n\tfor (let i = 0; i < refQueue.length; i++) {\n\t\tapplyRef(refQueue[i], refQueue[++i], refQueue[++i]);\n\t}\n\n\tif (options._commit) options._commit(root, commitQueue);\n\n\tcommitQueue.some(c => {\n\t\ttry {\n\t\t\t// @ts-expect-error Reuse the commitQueue variable here so the type changes\n\t\t\tcommitQueue = c._renderCallbacks;\n\t\t\tc._renderCallbacks = [];\n\t\t\tcommitQueue.some(cb => {\n\t\t\t\t// @ts-expect-error See above comment on commitQueue\n\t\t\t\tcb.call(c);\n\t\t\t});\n\t\t} catch (e) {\n\t\t\toptions._catchError(e, c._vnode);\n\t\t}\n\t});\n}\n\nfunction cloneNode(node) {\n\tif (typeof node != 'object' || node == NULL || node._depth > 0) {\n\t\treturn node;\n\t}\n\n\tif (isArray(node)) {\n\t\treturn node.map(cloneNode);\n\t}\n\n\treturn assign({}, node);\n}\n\n/**\n * Diff two virtual nodes representing DOM element\n * @param {PreactElement} dom The DOM element representing the virtual nodes\n * being diffed\n * @param {VNode} newVNode The new virtual node\n * @param {VNode} oldVNode The old virtual node\n * @param {object} globalContext The current context object\n * @param {string} namespace Current namespace of the DOM node (HTML, SVG, or MathML)\n * @param {Array<PreactElement>} excessDomChildren\n * @param {Array<Component>} commitQueue List of components which have callbacks\n * to invoke in commitRoot\n * @param {boolean} isHydrating Whether or not we are in hydration\n * @param {any[]} refQueue an array of elements needed to invoke refs\n * @returns {PreactElement}\n */\nfunction diffElementNodes(\n\tdom,\n\tnewVNode,\n\toldVNode,\n\tglobalContext,\n\tnamespace,\n\texcessDomChildren,\n\tcommitQueue,\n\tisHydrating,\n\trefQueue\n) {\n\tlet oldProps = oldVNode.props || EMPTY_OBJ;\n\tlet newProps = newVNode.props;\n\tlet nodeType = /** @type {string} */ (newVNode.type);\n\t/** @type {any} */\n\tlet i;\n\t/** @type {{ __html?: string }} */\n\tlet newHtml;\n\t/** @type {{ __html?: string }} */\n\tlet oldHtml;\n\t/** @type {ComponentChildren} */\n\tlet newChildren;\n\tlet value;\n\tlet inputValue;\n\tlet checked;\n\n\t// Tracks entering and exiting namespaces when descending through the tree.\n\tif (nodeType == 'svg') namespace = SVG_NAMESPACE;\n\telse if (nodeType == 'math') namespace = MATH_NAMESPACE;\n\telse if (!namespace) namespace = XHTML_NAMESPACE;\n\n\tif (excessDomChildren != NULL) {\n\t\tfor (i = 0; i < excessDomChildren.length; i++) {\n\t\t\tvalue = excessDomChildren[i];\n\n\t\t\t// if newVNode matches an element in excessDomChildren or the `dom`\n\t\t\t// argument matches an element in excessDomChildren, remove it from\n\t\t\t// excessDomChildren so it isn't later removed in diffChildren\n\t\t\tif (\n\t\t\t\tvalue &&\n\t\t\t\t'setAttribute' in value == !!nodeType &&\n\t\t\t\t(nodeType ? value.localName == nodeType : value.nodeType == 3)\n\t\t\t) {\n\t\t\t\tdom = value;\n\t\t\t\texcessDomChildren[i] = NULL;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (dom == NULL) {\n\t\tif (nodeType == NULL) {\n\t\t\treturn document.createTextNode(newProps);\n\t\t}\n\n\t\tdom = document.createElementNS(\n\t\t\tnamespace,\n\t\t\tnodeType,\n\t\t\tnewProps.is && newProps\n\t\t);\n\n\t\t// we are creating a new node, so we can assume this is a new subtree (in\n\t\t// case we are hydrating), this deopts the hydrate\n\t\tif (isHydrating) {\n\t\t\tif (options._hydrationMismatch)\n\t\t\t\toptions._hydrationMismatch(newVNode, excessDomChildren);\n\t\t\tisHydrating = false;\n\t\t}\n\t\t// we created a new parent, so none of the previously attached children can be reused:\n\t\texcessDomChildren = NULL;\n\t}\n\n\tif (nodeType == NULL) {\n\t\t// During hydration, we still have to split merged text from SSR'd HTML.\n\t\tif (oldProps !== newProps && (!isHydrating || dom.data != newProps)) {\n\t\t\tdom.data = newProps;\n\t\t}\n\t} else {\n\t\t// If excessDomChildren was not null, repopulate it with the current element's children:\n\t\texcessDomChildren = excessDomChildren && slice.call(dom.childNodes);\n\n\t\t// If we are in a situation where we are not hydrating but are using\n\t\t// existing DOM (e.g. replaceNode) we should read the existing DOM\n\t\t// attributes to diff them\n\t\tif (!isHydrating && excessDomChildren != NULL) {\n\t\t\toldProps = {};\n\t\t\tfor (i = 0; i < dom.attributes.length; i++) {\n\t\t\t\tvalue = dom.attributes[i];\n\t\t\t\toldProps[value.name] = value.value;\n\t\t\t}\n\t\t}\n\n\t\tfor (i in oldProps) {\n\t\t\tvalue = oldProps[i];\n\t\t\tif (i == 'dangerouslySetInnerHTML') {\n\t\t\t\toldHtml = value;\n\t\t\t} else if (\n\t\t\t\ti != 'children' &&\n\t\t\t\t!(i in newProps) &&\n\t\t\t\t!(i == 'value' && 'defaultValue' in newProps) &&\n\t\t\t\t!(i == 'checked' && 'defaultChecked' in newProps)\n\t\t\t) {\n\t\t\t\tsetProperty(dom, i, NULL, value, namespace);\n\t\t\t}\n\t\t}\n\n\t\t// During hydration, props are not diffed at all (including dangerouslySetInnerHTML)\n\t\t// @TODO we should warn in debug mode when props don't match here.\n\t\tfor (i in newProps) {\n\t\t\tvalue = newProps[i];\n\t\t\tif (i == 'children') {\n\t\t\t\tnewChildren = value;\n\t\t\t} else if (i == 'dangerouslySetInnerHTML') {\n\t\t\t\tnewHtml = value;\n\t\t\t} else if (i == 'value') {\n\t\t\t\tinputValue = value;\n\t\t\t} else if (i == 'checked') {\n\t\t\t\tchecked = value;\n\t\t\t} else if (\n\t\t\t\t(!isHydrating || typeof value == 'function') &&\n\t\t\t\toldProps[i] !== value\n\t\t\t) {\n\t\t\t\tsetProperty(dom, i, value, oldProps[i], namespace);\n\t\t\t}\n\t\t}\n\n\t\t// If the new vnode didn't have dangerouslySetInnerHTML, diff its children\n\t\tif (newHtml) {\n\t\t\t// Avoid re-applying the same '__html' if it did not changed between re-render\n\t\t\tif (\n\t\t\t\t!isHydrating &&\n\t\t\t\t(!oldHtml ||\n\t\t\t\t\t(newHtml.__html != oldHtml.__html && newHtml.__html != dom.innerHTML))\n\t\t\t) {\n\t\t\t\tdom.innerHTML = newHtml.__html;\n\t\t\t}\n\n\t\t\tnewVNode._children = [];\n\t\t} else {\n\t\t\tif (oldHtml) dom.innerHTML = '';\n\n\t\t\tdiffChildren(\n\t\t\t\t// @ts-expect-error\n\t\t\t\tnewVNode.type == 'template' ? dom.content : dom,\n\t\t\t\tisArray(newChildren) ? newChildren : [newChildren],\n\t\t\t\tnewVNode,\n\t\t\t\toldVNode,\n\t\t\t\tglobalContext,\n\t\t\t\tnodeType == 'foreignObject' ? XHTML_NAMESPACE : namespace,\n\t\t\t\texcessDomChildren,\n\t\t\t\tcommitQueue,\n\t\t\t\texcessDomChildren\n\t\t\t\t\t? excessDomChildren[0]\n\t\t\t\t\t: oldVNode._children && getDomSibling(oldVNode, 0),\n\t\t\t\tisHydrating,\n\t\t\t\trefQueue\n\t\t\t);\n\n\t\t\t// Remove children that are not part of any vnode.\n\t\t\tif (excessDomChildren != NULL) {\n\t\t\t\tfor (i = excessDomChildren.length; i--; ) {\n\t\t\t\t\tremoveNode(excessDomChildren[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// As above, don't diff props during hydration\n\t\tif (!isHydrating) {\n\t\t\ti = 'value';\n\t\t\tif (nodeType == 'progress' && inputValue == NULL) {\n\t\t\t\tdom.removeAttribute('value');\n\t\t\t} else if (\n\t\t\t\tinputValue != UNDEFINED &&\n\t\t\t\t// #2756 For the <progress>-element the initial value is 0,\n\t\t\t\t// despite the attribute not being present. When the attribute\n\t\t\t\t// is missing the progress bar is treated as indeterminate.\n\t\t\t\t// To fix that we'll always update it when it is 0 for progress elements\n\t\t\t\t(inputValue !== dom[i] ||\n\t\t\t\t\t(nodeType == 'progress' && !inputValue) ||\n\t\t\t\t\t// This is only for IE 11 to fix <select> value not being updated.\n\t\t\t\t\t// To avoid a stale select value we need to set the option.value\n\t\t\t\t\t// again, which triggers IE11 to re-evaluate the select value\n\t\t\t\t\t(nodeType == 'option' && inputValue != oldProps[i]))\n\t\t\t) {\n\t\t\t\tsetProperty(dom, i, inputValue, oldProps[i], namespace);\n\t\t\t}\n\n\t\t\ti = 'checked';\n\t\t\tif (checked != UNDEFINED && checked != dom[i]) {\n\t\t\t\tsetProperty(dom, i, checked, oldProps[i], namespace);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn dom;\n}\n\n/**\n * Invoke or update a ref, depending on whether it is a function or object ref.\n * @param {Ref<any> & { _unmount?: unknown }} ref\n * @param {any} value\n * @param {VNode} vnode\n */\nexport function applyRef(ref, value, vnode) {\n\ttry {\n\t\tif (typeof ref == 'function') {\n\t\t\tlet hasRefUnmount = typeof ref._unmount == 'function';\n\t\t\tif (hasRefUnmount) {\n\t\t\t\t// @ts-ignore TS doesn't like moving narrowing checks into variables\n\t\t\t\tref._unmount();\n\t\t\t}\n\n\t\t\tif (!hasRefUnmount || value != NULL) {\n\t\t\t\t// Store the cleanup function on the function\n\t\t\t\t// instance object itself to avoid shape\n\t\t\t\t// transitioning vnode\n\t\t\t\tref._unmount = ref(value);\n\t\t\t}\n\t\t} else ref.current = value;\n\t} catch (e) {\n\t\toptions._catchError(e, vnode);\n\t}\n}\n\n/**\n * Unmount a virtual node from the tree and apply DOM changes\n * @param {VNode} vnode The virtual node to unmount\n * @param {VNode} parentVNode The parent of the VNode that initiated the unmount\n * @param {boolean} [skipRemove] Flag that indicates that a parent node of the\n * current element is already detached from the DOM.\n */\nexport function unmount(vnode, parentVNode, skipRemove) {\n\tlet r;\n\tif (options.unmount) options.unmount(vnode);\n\n\tif ((r = vnode.ref)) {\n\t\tif (!r.current || r.current == vnode._dom) {\n\t\t\tapplyRef(r, NULL, parentVNode);\n\t\t}\n\t}\n\n\tif ((r = vnode._component) != NULL) {\n\t\tif (r.componentWillUnmount) {\n\t\t\ttry {\n\t\t\t\tr.componentWillUnmount();\n\t\t\t} catch (e) {\n\t\t\t\toptions._catchError(e, parentVNode);\n\t\t\t}\n\t\t}\n\n\t\tr.base = r._parentDom = NULL;\n\t}\n\n\tif ((r = vnode._children)) {\n\t\tfor (let i = 0; i < r.length; i++) {\n\t\t\tif (r[i]) {\n\t\t\t\tunmount(\n\t\t\t\t\tr[i],\n\t\t\t\t\tparentVNode,\n\t\t\t\t\tskipRemove || typeof vnode.type != 'function'\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!skipRemove) {\n\t\tremoveNode(vnode._dom);\n\t}\n\n\tvnode._component = vnode._parent = vnode._dom = UNDEFINED;\n}\n\n/** The `.render()` method for a PFC backing instance. */\nfunction doRender(props, state, context) {\n\treturn this.constructor(props, context);\n}\n","import { EMPTY_OBJ, NULL } from './constants';\nimport { commitRoot, diff } from './diff/index';\nimport { createElement, Fragment } from './create-element';\nimport options from './options';\nimport { slice } from './util';\n\n/**\n * Render a Preact virtual node into a DOM element\n * @param {import('./internal').ComponentChild} vnode The virtual node to render\n * @param {import('./internal').PreactElement} parentDom The DOM element to render into\n * @param {import('./internal').PreactElement | object} [replaceNode] Optional: Attempt to re-use an\n * existing DOM tree rooted at `replaceNode`\n */\nexport function render(vnode, parentDom, replaceNode) {\n\t// https://github.com/preactjs/preact/issues/3794\n\tif (parentDom == document) {\n\t\tparentDom = document.documentElement;\n\t}\n\n\tif (options._root) options._root(vnode, parentDom);\n\n\t// We abuse the `replaceNode` parameter in `hydrate()` to signal if we are in\n\t// hydration mode or not by passing the `hydrate` function instead of a DOM\n\t// element..\n\tlet isHydrating = typeof replaceNode == 'function';\n\n\t// To be able to support calling `render()` multiple times on the same\n\t// DOM node, we need to obtain a reference to the previous tree. We do\n\t// this by assigning a new `_children` property to DOM nodes which points\n\t// to the last rendered tree. By default this property is not present, which\n\t// means that we are mounting a new tree for the first time.\n\tlet oldVNode = isHydrating\n\t\t? NULL\n\t\t: (replaceNode && replaceNode._children) || parentDom._children;\n\n\tvnode = ((!isHydrating && replaceNode) || parentDom)._children =\n\t\tcreateElement(Fragment, NULL, [vnode]);\n\n\t// List of effects that need to be called after diffing.\n\tlet commitQueue = [],\n\t\trefQueue = [];\n\tdiff(\n\t\tparentDom,\n\t\t// Determine the new vnode tree and store it on the DOM element on\n\t\t// our custom `_children` property.\n\t\tvnode,\n\t\toldVNode || EMPTY_OBJ,\n\t\tEMPTY_OBJ,\n\t\tparentDom.namespaceURI,\n\t\t!isHydrating && replaceNode\n\t\t\t? [replaceNode]\n\t\t\t: oldVNode\n\t\t\t\t? NULL\n\t\t\t\t: parentDom.firstChild\n\t\t\t\t\t? slice.call(parentDom.childNodes)\n\t\t\t\t\t: NULL,\n\t\tcommitQueue,\n\t\t!isHydrating && replaceNode\n\t\t\t? replaceNode\n\t\t\t: oldVNode\n\t\t\t\t? oldVNode._dom\n\t\t\t\t: parentDom.firstChild,\n\t\tisHydrating,\n\t\trefQueue\n\t);\n\n\t// Flush all queued effects\n\tcommitRoot(commitQueue, vnode, refQueue);\n}\n\n/**\n * Update an existing DOM element with data from a Preact virtual node\n * @param {import('./internal').ComponentChild} vnode The virtual node to render\n * @param {import('./internal').PreactElement} parentDom The DOM element to update\n */\nexport function hydrate(vnode, parentDom) {\n\trender(vnode, parentDom, hydrate);\n}\n","import { NULL } from '../constants';\n\n/**\n * Find the closest error boundary to a thrown error and call it\n * @param {object} error The thrown value\n * @param {import('../internal').VNode} vnode The vnode that threw the error that was caught (except\n * for unmounting when this parameter is the highest parent that was being\n * unmounted)\n * @param {import('../internal').VNode} [oldVNode]\n * @param {import('../internal').ErrorInfo} [errorInfo]\n */\nexport function _catchError(error, vnode, oldVNode, errorInfo) {\n\t/** @type {import('../internal').Component} */\n\tlet component,\n\t\t/** @type {import('../internal').ComponentType} */\n\t\tctor,\n\t\t/** @type {boolean} */\n\t\thandled;\n\n\tfor (; (vnode = vnode._parent); ) {\n\t\tif ((component = vnode._component) && !component._processingException) {\n\t\t\ttry {\n\t\t\t\tctor = component.constructor;\n\n\t\t\t\tif (ctor && ctor.getDerivedStateFromError != NULL) {\n\t\t\t\t\tcomponent.setState(ctor.getDerivedStateFromError(error));\n\t\t\t\t\thandled = component._dirty;\n\t\t\t\t}\n\n\t\t\t\tif (component.componentDidCatch != NULL) {\n\t\t\t\t\tcomponent.componentDidCatch(error, errorInfo || {});\n\t\t\t\t\thandled = component._dirty;\n\t\t\t\t}\n\n\t\t\t\t// This is an error boundary. Mark it as having bailed out, and whether it was mid-hydration.\n\t\t\t\tif (handled) {\n\t\t\t\t\treturn (component._pendingError = component);\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\terror = e;\n\t\t\t}\n\t\t}\n\t}\n\n\tthrow error;\n}\n","import { options as _options } from 'preact';\n\n/** @type {number} */\nlet currentIndex;\n\n/** @type {import('./internal').Component} */\nlet currentComponent;\n\n/** @type {import('./internal').Component} */\nlet previousComponent;\n\n/** @type {number} */\nlet currentHook = 0;\n\n/** @type {Array<import('./internal').Component>} */\nlet afterPaintEffects = [];\n\n// Cast to use internal Options type\nconst options = /** @type {import('./internal').Options} */ (_options);\n\nlet oldBeforeDiff = options._diff;\nlet oldBeforeRender = options._render;\nlet oldAfterDiff = options.diffed;\nlet oldCommit = options._commit;\nlet oldBeforeUnmount = options.unmount;\nlet oldRoot = options._root;\n\n// We take the minimum timeout for requestAnimationFrame to ensure that\n// the callback is invoked after the next frame. 35ms is based on a 30hz\n// refresh rate, which is the minimum rate for a smooth user experience.\nconst RAF_TIMEOUT = 35;\nlet prevRaf;\n\n/** @type {(vnode: import('./internal').VNode) => void} */\noptions._diff = vnode => {\n\tcurrentComponent = null;\n\tif (oldBeforeDiff) oldBeforeDiff(vnode);\n};\n\noptions._root = (vnode, parentDom) => {\n\tif (vnode && parentDom._children && parentDom._children._mask) {\n\t\tvnode._mask = parentDom._children._mask;\n\t}\n\n\tif (oldRoot) oldRoot(vnode, parentDom);\n};\n\n/** @type {(vnode: import('./internal').VNode) => void} */\noptions._render = vnode => {\n\tif (oldBeforeRender) oldBeforeRender(vnode);\n\n\tcurrentComponent = vnode._component;\n\tcurrentIndex = 0;\n\n\tconst hooks = currentComponent.__hooks;\n\tif (hooks) {\n\t\tif (previousComponent === currentComponent) {\n\t\t\thooks._pendingEffects = [];\n\t\t\tcurrentComponent._renderCallbacks = [];\n\t\t\thooks._list.some(hookItem => {\n\t\t\t\tif (hookItem._nextValue) {\n\t\t\t\t\thookItem._value = hookItem._nextValue;\n\t\t\t\t}\n\t\t\t\thookItem._pendingArgs = hookItem._nextValue = undefined;\n\t\t\t});\n\t\t} else {\n\t\t\thooks._pendingEffects.some(invokeCleanup);\n\t\t\thooks._pendingEffects.some(invokeEffect);\n\t\t\thooks._pendingEffects = [];\n\t\t\tcurrentIndex = 0;\n\t\t}\n\t}\n\tpreviousComponent = currentComponent;\n};\n\n/** @type {(vnode: import('./internal').VNode) => void} */\noptions.diffed = vnode => {\n\tif (oldAfterDiff) oldAfterDiff(vnode);\n\n\tconst c = vnode._component;\n\tif (c && c.__hooks) {\n\t\tif (c.__hooks._pendingEffects.length) afterPaint(afterPaintEffects.push(c));\n\t\tc.__hooks._list.some(hookItem => {\n\t\t\tif (hookItem._pendingArgs) {\n\t\t\t\thookItem._args = hookItem._pendingArgs;\n\t\t\t}\n\t\t\thookItem._pendingArgs = undefined;\n\t\t});\n\t}\n\tpreviousComponent = currentComponent = null;\n};\n\n// TODO: Improve typing of commitQueue parameter\n/** @type {(vnode: import('./internal').VNode, commitQueue: any) => void} */\noptions._commit = (vnode, commitQueue) => {\n\tcommitQueue.some(component => {\n\t\ttry {\n\t\t\tcomponent._renderCallbacks.some(invokeCleanup);\n\t\t\tcomponent._renderCallbacks = component._renderCallbacks.filter(cb =>\n\t\t\t\tcb._value ? invokeEffect(cb) : true\n\t\t\t);\n\t\t} catch (e) {\n\t\t\tcommitQueue.some(c => {\n\t\t\t\tif (c._renderCallbacks) c._renderCallbacks = [];\n\t\t\t});\n\t\t\tcommitQueue = [];\n\t\t\toptions._catchError(e, component._vnode);\n\t\t}\n\t});\n\n\tif (oldCommit) oldCommit(vnode, commitQueue);\n};\n\n/** @type {(vnode: import('./internal').VNode) => void} */\noptions.unmount = vnode => {\n\tif (oldBeforeUnmount) oldBeforeUnmount(vnode);\n\n\tconst c = vnode._component;\n\tif (c && c.__hooks) {\n\t\tlet hasErrored;\n\t\tc.__hooks._list.some(s => {\n\t\t\ttry {\n\t\t\t\tinvokeCleanup(s);\n\t\t\t} catch (e) {\n\t\t\t\thasErrored = e;\n\t\t\t}\n\t\t});\n\t\tc.__hooks = undefined;\n\t\tif (hasErrored) options._catchError(hasErrored, c._vnode);\n\t}\n};\n\n/**\n * Get a hook's state from the currentComponent\n * @param {number} index The index of the hook to get\n * @param {number} type The index of the hook to get\n * @returns {any}\n */\nfunction getHookState(index, type) {\n\tif (options._hook) {\n\t\toptions._hook(currentComponent, index, currentHook || type);\n\t}\n\tcurrentHook = 0;\n\n\t// Largely inspired by:\n\t// * https://github.com/michael-klein/funcy.js/blob/f6be73468e6ec46b0ff5aa3cc4c9baf72a29025a/src/hooks/core_hooks.mjs\n\t// * https://github.com/michael-klein/funcy.js/blob/650beaa58c43c33a74820a3c98b3c7079cf2e333/src/renderer.mjs\n\t// Other implementations to look at:\n\t// * https://codesandbox.io/s/mnox05qp8\n\tconst hooks =\n\t\tcurrentComponent.__hooks ||\n\t\t(currentComponent.__hooks = {\n\t\t\t_list: [],\n\t\t\t_pendingEffects: []\n\t\t});\n\n\tif (index >= hooks._list.length) {\n\t\thooks._list.push({});\n\t}\n\n\treturn hooks._list[index];\n}\n\n/**\n * @template {unknown} S\n * @param {import('./index').Dispatch<import('./index').StateUpdater<S>>} [initialState]\n * @returns {[S, (state: S) => void]}\n */\nexport function useState(initialState) {\n\tcurrentHook = 1;\n\treturn useReducer(invokeOrReturn, initialState);\n}\n\n/**\n * @template {unknown} S\n * @template {unknown} A\n * @param {import('./index').Reducer<S, A>} reducer\n * @param {import('./index').Dispatch<import('./index').StateUpdater<S>>} initialState\n * @param {(initialState: any) => void} [init]\n * @returns {[ S, (state: S) => void ]}\n */\nexport function useReducer(reducer, initialState, init) {\n\t/** @type {import('./internal').ReducerHookState} */\n\tconst hookState = getHookState(currentIndex++, 2);\n\thookState._reducer = reducer;\n\tif (!hookState._component) {\n\t\thookState._value = [\n\t\t\t!init ? invokeOrReturn(undefined, initialState) : init(initialState),\n\n\t\t\taction => {\n\t\t\t\tconst currentValue = hookState._nextValue\n\t\t\t\t\t? hookState._nextValue[0]\n\t\t\t\t\t: hookState._value[0];\n\t\t\t\tconst nextValue = hookState._reducer(currentValue, action);\n\n\t\t\t\tif (currentValue !== nextValue) {\n\t\t\t\t\thookState._nextValue = [nextValue, hookState._value[1]];\n\t\t\t\t\thookState._component.setState({});\n\t\t\t\t}\n\t\t\t}\n\t\t];\n\n\t\thookState._component = currentComponent;\n\n\t\tif (!currentComponent._hasScuFromHooks) {\n\t\t\tcurrentComponent._hasScuFromHooks = true;\n\t\t\tlet prevScu = currentComponent.shouldComponentUpdate;\n\t\t\tconst prevCWU = currentComponent.componentWillUpdate;\n\n\t\t\t// If we're dealing with a forced update `shouldComponentUpdate` will\n\t\t\t// not be called. But we use that to update the hook values, so we\n\t\t\t// need to call it.\n\t\t\tcurrentComponent.componentWillUpdate = function (p, s, c) {\n\t\t\t\tif (this._force) {\n\t\t\t\t\tlet tmp = prevScu;\n\t\t\t\t\t// Clear to avoid other sCU hooks from being called\n\t\t\t\t\tprevScu = undefined;\n\t\t\t\t\tupdateHookState(p, s, c);\n\t\t\t\t\tprevScu = tmp;\n\t\t\t\t}\n\n\t\t\t\tif (prevCWU) prevCWU.call(this, p, s, c);\n\t\t\t};\n\n\t\t\t// This SCU has the purpose of bailing out after repeated updates\n\t\t\t// to stateful hooks.\n\t\t\t// we store the next value in _nextValue[0] and keep doing that for all\n\t\t\t// state setters, if we have next states and\n\t\t\t// all next states within a component end up being equal to their original state\n\t\t\t// we are safe to bail out for this specific component.\n\t\t\t/**\n\t\t\t *\n\t\t\t * @type {import('./internal').Component[\"shouldComponentUpdate\"]}\n\t\t\t */\n\t\t\t// @ts-ignore - We don't use TS to downtranspile\n\t\t\t// eslint-disable-next-line no-inner-declarations\n\t\t\tfunction updateHookState(p, s, c) {\n\t\t\t\tif (!hookState._component.__hooks) return true;\n\n\t\t\t\tconst stateHooks = hookState._component.__hooks._list.filter(\n\t\t\t\t\tx => x._component\n\t\t\t\t);\n\n\t\t\t\tconst allHooksEmpty = stateHooks.every(x => !x._nextValue);\n\t\t\t\t// When we have no updated hooks in the component we invoke the previous SCU or\n\t\t\t\t// traverse the VDOM tree further.\n\t\t\t\tif (allHooksEmpty) {\n\t\t\t\t\treturn prevScu ? prevScu.call(this, p, s, c) : true;\n\t\t\t\t}\n\n\t\t\t\t// We check whether we have components with a nextValue set that\n\t\t\t\t// have values that aren't equal to one another this pushes\n\t\t\t\t// us to update further down the tree\n\t\t\t\tlet shouldUpdate = hookState._component.props !== p;\n\t\t\t\tstateHooks.some(hookItem => {\n\t\t\t\t\tif (hookItem._nextValue) {\n\t\t\t\t\t\tconst currentValue = hookItem._value[0];\n\t\t\t\t\t\thookItem._value = hookItem._nextValue;\n\t\t\t\t\t\thookItem._nextValue = undefined;\n\t\t\t\t\t\tif (currentValue !== hookItem._value[0]) shouldUpdate = true;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\treturn prevScu\n\t\t\t\t\t? prevScu.call(this, p, s, c) || shouldUpdate\n\t\t\t\t\t: shouldUpdate;\n\t\t\t}\n\n\t\t\tcurrentComponent.shouldComponentUpdate = updateHookState;\n\t\t}\n\t}\n\n\treturn hookState._nextValue || hookState._value;\n}\n\n/**\n * @param {import('./internal').Effect} callback\n * @param {unknown[]} args\n * @returns {void}\n */\nexport function useEffect(callback, args) {\n\t/** @type {import('./internal').EffectHookState} */\n\tconst state = getHookState(currentIndex++, 3);\n\tif (!options._skipEffects && argsChanged(state._args, args)) {\n\t\tstate._value = callback;\n\t\tstate._pendingArgs = args;\n\n\t\tcurrentComponent.__hooks._pendingEffects.push(state);\n\t}\n}\n\n/**\n * @param {import('./internal').Effect} callback\n * @param {unknown[]} args\n * @returns {void}\n */\nexport function useLayoutEffect(callback, args) {\n\t/** @type {import('./internal').EffectHookState} */\n\tconst state = getHookState(currentIndex++, 4);\n\tif (!options._skipEffects && argsChanged(state._args, args)) {\n\t\tstate._value = callback;\n\t\tstate._pendingArgs = args;\n\n\t\tcurrentComponent._renderCallbacks.push(state);\n\t}\n}\n\n/** @type {(initialValue: unknown) => unknown} */\nexport function useRef(initialValue) {\n\tcurrentHook = 5;\n\treturn useMemo(() => ({ current: initialValue }), []);\n}\n\n/**\n * @param {object} ref\n * @param {() => object} createHandle\n * @param {unknown[]} args\n * @returns {void}\n */\nexport function useImperativeHandle(ref, createHandle, args) {\n\tcurrentHook = 6;\n\tuseLayoutEffect(\n\t\t() => {\n\t\t\tif (typeof ref == 'function') {\n\t\t\t\tconst result = ref(createHandle());\n\t\t\t\treturn () => {\n\t\t\t\t\tref(null);\n\t\t\t\t\tif (result && typeof result == 'function') result();\n\t\t\t\t};\n\t\t\t} else if (ref) {\n\t\t\t\tref.current = createHandle();\n\t\t\t\treturn () => (ref.current = null);\n\t\t\t}\n\t\t},\n\t\targs == null ? args : args.concat(ref)\n\t);\n}\n\n/**\n * @template {unknown} T\n * @param {() => T} factory\n * @param {unknown[]} args\n * @returns {T}\n */\nexport function useMemo(factory, args) {\n\t/** @type {import('./internal').MemoHookState<T>} */\n\tconst state = getHookState(currentIndex++, 7);\n\tif (argsChanged(state._args, args)) {\n\t\tstate._value = factory();\n\t\tstate._args = args;\n\t\tstate._factory = factory;\n\t}\n\n\treturn state._value;\n}\n\n/**\n * @param {() => void} callback\n * @param {unknown[]} args\n * @returns {() => void}\n */\nexport function useCallback(callback, args) {\n\tcurrentHook = 8;\n\treturn useMemo(() => callback, args);\n}\n\n/**\n * @param {import('./internal').PreactContext} context\n */\nexport function useContext(context) {\n\tconst provider = currentComponent.context[context._id];\n\t// We could skip this call here, but than we'd not call\n\t// `options._hook`. We need to do that in order to make\n\t// the devtools aware of this hook.\n\t/** @type {import('./internal').ContextHookState} */\n\tconst state = getHookState(currentIndex++, 9);\n\t// The devtools needs access to the context object to\n\t// be able to pull of the default value when no provider\n\t// is present in the tree.\n\tstate._context = context;\n\tif (!provider) return context._defaultValue;\n\t// This is probably not safe to convert to \"!\"\n\tif (state._value == null) {\n\t\tstate._value = true;\n\t\tprovider.sub(currentComponent);\n\t}\n\treturn provider.props.value;\n}\n\n/**\n * Display a custom label for a custom hook for the devtools panel\n * @type {<T>(value: T, cb?: (value: T) => string | number) => void}\n */\nexport function useDebugValue(value, formatter) {\n\tif (options.useDebugValue) {\n\t\toptions.useDebugValue(\n\t\t\tformatter ? formatter(value) : /** @type {any}*/ (value)\n\t\t);\n\t}\n}\n\n/**\n * @param {(error: unknown, errorInfo: import('preact').ErrorInfo) => void} cb\n * @returns {[unknown, () => void]}\n */\nexport function useErrorBoundary(cb) {\n\t/** @type {import('./internal').ErrorBoundaryHookState} */\n\tconst state = getHookState(currentIndex++, 10);\n\tconst errState = useState();\n\tstate._value = cb;\n\tif (!currentComponent.componentDidCatch) {\n\t\tcurrentComponent.componentDidCatch = (err, errorInfo) => {\n\t\t\tif (state._value) state._value(err, errorInfo);\n\t\t\terrState[1](err);\n\t\t};\n\t}\n\treturn [\n\t\terrState[0],\n\t\t() => {\n\t\t\terrState[1](undefined);\n\t\t}\n\t];\n}\n\n/** @type {() => string} */\nexport function useId() {\n\t/** @type {import('./internal').IdHookState} */\n\tconst state = getHookState(currentIndex++, 11);\n\tif (!state._value) {\n\t\t// Grab either the root node or the nearest async boundary node.\n\t\t/** @type {import('./internal').VNode} */\n\t\tlet root = currentComponent._vnode;\n\t\twhile (root !== null && !root._mask && root._parent !== null) {\n\t\t\troot = root._parent;\n\t\t}\n\n\t\tlet mask = root._mask || (root._mask = [0, 0]);\n\t\tstate._value = 'P' + mask[0] + '-' + mask[1]++;\n\t}\n\n\treturn state._value;\n}\n\n/**\n * After paint effects consumer.\n */\nfunction flushAfterPaintEffects() {\n\tlet component;\n\twhile ((component = afterPaintEffects.shift())) {\n\t\tconst hooks = component.__hooks;\n\t\tif (!component._parentDom || !hooks) continue;\n\t\ttry {\n\t\t\thooks._pendingEffects.some(invokeCleanup);\n\t\t\thooks._pendingEffects.some(invokeEffect);\n\t\t\thooks._pendingEffects = [];\n\t\t} catch (e) {\n\t\t\thooks._pendingEffects = [];\n\t\t\toptions._catchError(e, component._vnode);\n\t\t}\n\t}\n}\n\nlet HAS_RAF = typeof requestAnimationFrame == 'function';\n\n/**\n * Schedule a callback to be invoked after the browser has a chance to paint a new frame.\n * Do this by combining requestAnimationFrame (rAF) + setTimeout to invoke a callback after\n * the next browser frame.\n *\n * Also, schedule a timeout in parallel to the the rAF to ensure the callback is invoked\n * even if RAF doesn't fire (for example if the browser tab is not visible)\n *\n * @param {() => void} callback\n */\nfunction afterNextFrame(callback) {\n\tconst done = () => {\n\t\tclearTimeout(timeout);\n\t\tif (HAS_RAF) cancelAnimationFrame(raf);\n\t\tsetTimeout(callback);\n\t};\n\tconst timeout = setTimeout(done, RAF_TIMEOUT);\n\n\tlet raf;\n\tif (HAS_RAF) {\n\t\traf = requestAnimationFrame(done);\n\t}\n}\n\n// Note: if someone used options.debounceRendering = requestAnimationFrame,\n// then effects will ALWAYS run on the NEXT frame instead of the current one, incurring a ~16ms delay.\n// Perhaps this is not such a big deal.\n/**\n * Schedule afterPaintEffects flush after the browser paints\n * @param {number} newQueueLength\n * @returns {void}\n */\nfunction afterPaint(newQueueLength) {\n\tif (newQueueLength === 1 || prevRaf !== options.requestAnimationFrame) {\n\t\tprevRaf = options.requestAnimationFrame;\n\t\t(prevRaf || afterNextFrame)(flushAfterPaintEffects);\n\t}\n}\n\n/**\n * @param {import('./internal').HookState} hook\n * @returns {void}\n */\nfunction invokeCleanup(hook) {\n\t// A hook cleanup can introduce a call to render which creates a new root, this will call options.vnode\n\t// and move the currentComponent away.\n\tconst comp = currentComponent;\n\tlet cleanup = hook._cleanup;\n\tif (typeof cleanup == 'function') {\n\t\thook._cleanup = undefined;\n\t\tcleanup();\n\t}\n\n\tcurrentComponent = comp;\n}\n\n/**\n * Invoke a Hook's effect\n * @param {import('./internal').EffectHookState} hook\n * @returns {void}\n */\nfunction invokeEffect(hook) {\n\t// A hook call can introduce a call to render which creates a new root, this will call options.vnode\n\t// and move the currentComponent away.\n\tconst comp = currentComponent;\n\thook._cleanup = hook._value();\n\tcurrentComponent = comp;\n}\n\n/**\n * @param {unknown[]} oldArgs\n * @param {unknown[]} newArgs\n * @returns {boolean}\n */\nfunction argsChanged(oldArgs, newArgs) {\n\treturn (\n\t\t!oldArgs ||\n\t\toldArgs.length !== newArgs.length ||\n\t\tnewArgs.some((arg, index) => arg !== oldArgs[index])\n\t);\n}\n\n/**\n * @template Arg\n * @param {Arg} arg\n * @param {(arg: Arg) => any} f\n * @returns {any}\n */\nfunction invokeOrReturn(arg, f) {\n\treturn typeof f == 'function' ? f(arg) : f;\n}\n","/**\n * Assign properties from `props` to `obj`\n * @template O, P The obj and props types\n * @param {O} obj The object to copy properties to\n * @param {P} props The object to copy properties from\n * @returns {O & P}\n */\nexport function assign(obj, props) {\n\tfor (let i in props) obj[i] = props[i];\n\treturn /** @type {O & P} */ (obj);\n}\n\n/**\n * Check if two objects have a different shape\n * @param {object} a\n * @param {object} b\n * @returns {boolean}\n */\nexport function shallowDiffers(a, b) {\n\tfor (let i in a) if (i !== '__source' && !(i in b)) return true;\n\tfor (let i in b) if (i !== '__source' && a[i] !== b[i]) return true;\n\treturn false;\n}\n\n/**\n * Check if two values are the same value\n * @param {*} x\n * @param {*} y\n * @returns {boolean}\n */\nexport function is(x, y) {\n\treturn (x === y && (x !== 0 || 1 / x === 1 / y)) || (x !== x && y !== y);\n}\n","import { useState, useLayoutEffect, useEffect } from 'preact/hooks';\nimport { is } from './util';\n\n/**\n * This is taken from https://github.com/facebook/react/blob/main/packages/use-sync-external-store/src/useSyncExternalStoreShimClient.js#L84\n * on a high level this cuts out the warnings, ... and attempts a smaller implementation\n * @typedef {{ _value: any; _getSnapshot: () => any }} Store\n */\nexport function useSyncExternalStore(subscribe, getSnapshot) {\n\tconst value = getSnapshot();\n\n\t/**\n\t * @typedef {{ _instance: Store }} StoreRef\n\t * @type {[StoreRef, (store: StoreRef) => void]}\n\t */\n\tconst [{ _instance }, forceUpdate] = useState({\n\t\t_instance: { _value: value, _getSnapshot: getSnapshot }\n\t});\n\n\tuseLayoutEffect(() => {\n\t\t_instance._value = value;\n\t\t_instance._getSnapshot = getSnapshot;\n\n\t\tif (didSnapshotChange(_instance)) {\n\t\t\tforceUpdate({ _instance });\n\t\t}\n\t}, [subscribe, value, getSnapshot]);\n\n\tuseEffect(() => {\n\t\tif (didSnapshotChange(_instance)) {\n\t\t\tforceUpdate({ _instance });\n\t\t}\n\n\t\treturn subscribe(() => {\n\t\t\tif (didSnapshotChange(_instance)) {\n\t\t\t\tforceUpdate({ _instance });\n\t\t\t}\n\t\t});\n\t}, [subscribe]);\n\n\treturn value;\n}\n\n/** @type {(inst: Store) => boolean} */\nfunction didSnapshotChange(inst) {\n\ttry {\n\t\treturn !is(inst._value, inst._getSnapshot());\n\t} catch (error) {\n\t\treturn true;\n\t}\n}\n\nexport function startTransition(cb) {\n\tcb();\n}\n\nexport function useDeferredValue(val) {\n\treturn val;\n}\n\nexport function useTransition() {\n\treturn [false, startTransition];\n}\n\n// TODO: in theory this should be done after a VNode is diffed as we want to insert\n// styles/... before it attaches\nexport const useInsertionEffect = useLayoutEffect;\n","import { Component } from 'preact';\nimport { shallowDiffers } from './util';\n\n/**\n * Component class with a predefined `shouldComponentUpdate` implementation\n */\nexport function PureComponent(p, c) {\n\tthis.props = p;\n\tthis.context = c;\n}\nPureComponent.prototype = new Component();\n// Some third-party libraries check if this property is present\nPureComponent.prototype.isPureReactComponent = true;\nPureComponent.prototype.shouldComponentUpdate = function (props, state) {\n\treturn shallowDiffers(this.props, props) || shallowDiffers(this.state, state);\n};\n","import { options } from 'preact';\nimport { assign } from './util';\n\nlet oldDiffHook = options._diff;\noptions._diff = vnode => {\n\tif (vnode.type && vnode.type._forwarded && vnode.ref) {\n\t\tvnode.props.ref = vnode.ref;\n\t\tvnode.ref = null;\n\t}\n\tif (oldDiffHook) oldDiffHook(vnode);\n};\n\nexport const REACT_FORWARD_SYMBOL =\n\t(typeof Symbol != 'undefined' &&\n\t\tSymbol.for &&\n\t\tSymbol.for('react.forward_ref')) ||\n\t0xf47;\n\n/**\n * Pass ref down to a child. This is mainly used in libraries with HOCs that\n * wrap components. Using `forwardRef` there is an easy way to get a reference\n * of the wrapped component instead of one of the wrapper itself.\n * @param {import('./index').ForwardFn} fn\n * @returns {import('./internal').FunctionComponent}\n */\nexport function forwardRef(fn) {\n\tfunction Forwarded(props) {\n\t\tlet clone = assign({}, props);\n\t\tdelete clone.ref;\n\t\treturn fn(clone, props.ref || null);\n\t}\n\n\t// mobx-react checks for this being present\n\tForwarded.$$typeof = REACT_FORWARD_SYMBOL;\n\t// mobx-react heavily relies on implementation details.\n\t// It expects an object here with a `render` property,\n\t// and prototype.render will fail. Without this\n\t// mobx-react throws.\n\tForwarded.render = fn;\n\n\tForwarded.prototype.isReactComponent = Forwarded._forwarded = true;\n\tForwarded.displayName = 'ForwardRef(' + (fn.displayName || fn.name) + ')';\n\treturn Forwarded;\n}\n","import { toChildArray } from 'preact';\n\nconst mapFn = (children, fn) => {\n\tif (children == null) return null;\n\treturn toChildArray(toChildArray(children).map(fn));\n};\n\n// This API is completely unnecessary for Preact, so it's basically passthrough.\nexport const Children = {\n\tmap: mapFn,\n\tforEach: mapFn,\n\tcount(children) {\n\t\treturn children ? toChildArray(children).length : 0;\n\t},\n\tonly(children) {\n\t\tconst normalized = toChildArray(children);\n\t\tif (normalized.length !== 1) throw 'Children.only';\n\t\treturn normalized[0];\n\t},\n\ttoArray: toChildArray\n};\n","import { Component, createElement, options, Fragment } from 'preact';\nimport { MODE_HYDRATE } from '../../src/constants';\nimport { assign } from './util';\n\nconst oldCatchError = options._catchError;\noptions._catchError = function (error, newVNode, oldVNode, errorInfo) {\n\tif (error.then) {\n\t\t/** @type {import('./internal').Component} */\n\t\tlet component;\n\t\tlet vnode = newVNode;\n\n\t\tfor (; (vnode = vnode._parent); ) {\n\t\t\tif ((component = vnode._component) && component._childDidSuspend) {\n\t\t\t\tif (newVNode._dom == null) {\n\t\t\t\t\tnewVNode._dom = oldVNode._dom;\n\t\t\t\t\tnewVNode._children = oldVNode._children;\n\t\t\t\t}\n\t\t\t\t// Don't call oldCatchError if we found a Suspense\n\t\t\t\treturn component._childDidSuspend(error, newVNode);\n\t\t\t}\n\t\t}\n\t}\n\toldCatchError(error, newVNode, oldVNode, errorInfo);\n};\n\nconst oldUnmount = options.unmount;\noptions.unmount = function (vnode) {\n\t/** @type {import('./internal').Component} */\n\tconst component = vnode._component;\n\tif (component) component._unmounted = true;\n\tif (component && component._onResolve) {\n\t\tcomponent._onResolve();\n\t}\n\n\t// if the component is still hydrating\n\t// most likely it is because the component is suspended\n\t// we set the vnode.type as `null` so that it is not a typeof function\n\t// so the unmount will remove the vnode._dom\n\tif (component && vnode._flags & MODE_HYDRATE) {\n\t\tvnode.type = null;\n\t}\n\n\tif (oldUnmount) oldUnmount(vnode);\n};\n\nfunction detachedClone(vnode, detachedParent, parentDom) {\n\tif (vnode) {\n\t\tif (vnode._component && vnode._component.__hooks) {\n\t\t\tvnode._component.__hooks._list.forEach(effect => {\n\t\t\t\tif (typeof effect._cleanup == 'function') effect._cleanup();\n\t\t\t});\n\n\t\t\tvnode._component.__hooks = null;\n\t\t}\n\n\t\tvnode = assign({}, vnode);\n\t\tif (vnode._component != null) {\n\t\t\tif (vnode._component._parentDom === parentDom) {\n\t\t\t\tvnode._component._parentDom = detachedParent;\n\t\t\t}\n\n\t\t\tvnode._component._force = true;\n\n\t\t\tvnode._component = null;\n\t\t}\n\n\t\tvnode._children =\n\t\t\tvnode._children &&\n\t\t\tvnode._children.map(child =>\n\t\t\t\tdetachedClone(child, detachedParent, parentDom)\n\t\t\t);\n\t}\n\n\treturn vnode;\n}\n\nfunction removeOriginal(vnode, detachedParent, originalParent) {\n\tif (vnode && originalParent) {\n\t\tvnode._original = null;\n\t\tvnode._children =\n\t\t\tvnode._children &&\n\t\t\tvnode._children.map(child =>\n\t\t\t\tremoveOriginal(child, detachedParent, originalParent)\n\t\t\t);\n\n\t\tif (vnode._component) {\n\t\t\tif (vnode._component._parentDom === detachedParent) {\n\t\t\t\tif (vnode._dom) {\n\t\t\t\t\toriginalParent.appendChild(vnode._dom);\n\t\t\t\t}\n\t\t\t\tvnode._component._force = true;\n\t\t\t\tvnode._component._parentDom = originalParent;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn vnode;\n}\n\n// having custom inheritance instead of a class here saves a lot of bytes\nexport function Suspense() {\n\t// we do not call super here to golf some bytes...\n\tthis._pendingSuspensionCount = 0;\n\tthis._suspenders = null;\n\tthis._detachOnNextRender = null;\n}\n\n// Things we do here to save some bytes but are not proper JS inheritance:\n// - call `new Component()` as the prototype\n// - do not set `Suspense.prototype.constructor` to `Suspense`\nSuspense.prototype = new Component();\n\n/**\n * @this {import('./internal').SuspenseComponent}\n * @param {Promise} promise The thrown promise\n * @param {import('./internal').VNode<any, any>} suspendingVNode The suspending component\n */\nSuspense.prototype._childDidSuspend = function (promise, suspendingVNode) {\n\tconst suspendingComponent = suspendingVNode._component;\n\n\t/** @type {import('./internal').SuspenseComponent} */\n\tconst c = this;\n\n\tif (c._suspenders == null) {\n\t\tc._suspenders = [];\n\t}\n\tc._suspenders.push(suspendingComponent);\n\n\tconst resolve = suspended(c._vnode);\n\n\tlet resolved = false;\n\tconst onResolved = () => {\n\t\tif (resolved || c._unmounted) return;\n\n\t\tresolved = true;\n\t\tsuspendingComponent._onResolve = null;\n\n\t\tif (resolve) {\n\t\t\tresolve(onSuspensionComplete);\n\t\t} else {\n\t\t\tonSuspensionComplete();\n\t\t}\n\t};\n\n\tsuspendingComponent._onResolve = onResolved;\n\n\t// Store and null _parentDom to prevent setState/forceUpdate from\n\t// scheduling renders while suspended. Render would be a no-op anyway\n\t// since renderComponent checks _parentDom, but this avoids queue churn.\n\tconst originalParentDom = suspendingComponent._parentDom;\n\tsuspendingComponent._parentDom = null;\n\n\tconst onSuspensionComplete = () => {\n\t\tif (!--c._pendingSuspensionCount) {\n\t\t\t// If the suspension was during hydration we don't need to restore the\n\t\t\t// suspended children into the _children array\n\t\t\tif (c.state._suspended) {\n\t\t\t\tconst suspendedVNode = c.state._suspended;\n\t\t\t\tc._vnode._children[0] = removeOriginal(\n\t\t\t\t\tsuspendedVNode,\n\t\t\t\t\tsuspendedVNode._component._parentDom,\n\t\t\t\t\tsuspendedVNode._component._originalParentDom\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tc.setState({ _suspended: (c._detachOnNextRender = null) });\n\n\t\t\tlet suspended;\n\t\t\twhile ((suspended = c._suspenders.pop())) {\n\t\t\t\t// Restore _parentDom before forceUpdate so render can proceed\n\t\t\t\tsuspended._parentDom = originalParentDom;\n\t\t\t\tsuspended.forceUpdate();\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * We do not set `suspended: true` during hydration because we want the actual markup\n\t * to remain on screen and hydrate it when the suspense actually gets resolved.\n\t * While in non-hydration cases the usual fallback -> component flow would occour.\n\t */\n\tif (\n\t\t!c._pendingSuspensionCount++ &&\n\t\t!(suspendingVNode._flags & MODE_HYDRATE)\n\t) {\n\t\tc.setState({ _suspended: (c._detachOnNextRender = c._vnode._children[0]) });\n\t}\n\tpromise.then(onResolved, onResolved);\n};\n\nSuspense.prototype.componentWillUnmount = function () {\n\tthis._suspenders = [];\n};\n\n/**\n * @this {import('./internal').SuspenseComponent}\n * @param {import('./internal').SuspenseComponent[\"props\"]} props\n * @param {import('./internal').SuspenseState} state\n */\nSuspense.prototype.render = function (props, state) {\n\tif (this._detachOnNextRender) {\n\t\t// When the Suspense's _vnode was created by a call to createVNode\n\t\t// (i.e. due to a setState further up in the tree)\n\t\t// it's _children prop is null, in this case we \"forget\" about the parked vnodes to detach\n\t\tif (this._vnode._children) {\n\t\t\tconst detachedParent = document.createElement('div');\n\t\t\tconst detachedComponent = this._vnode._children[0]._component;\n\t\t\tthis._vnode._children[0] = detachedClone(\n\t\t\t\tthis._detachOnNextRender,\n\t\t\t\tdetachedParent,\n\t\t\t\t(detachedComponent._originalParentDom = detachedComponent._parentDom)\n\t\t\t);\n\t\t}\n\n\t\tthis._detachOnNextRender = null;\n\t}\n\n\t// Wrap fallback tree in a VNode that prevents itself from being marked as aborting mid-hydration:\n\t/** @type {import('./internal').VNode} */\n\tconst fallback =\n\t\tstate._suspended && createElement(Fragment, null, props.fallback);\n\tif (fallback) fallback._flags &= ~MODE_HYDRATE;\n\n\treturn [\n\t\tcreateElement(Fragment, null, state._suspended ? null : props.children),\n\t\tfallback\n\t];\n};\n\n/**\n * Checks and calls the parent component's _suspended method, passing in the\n * suspended vnode. This is a way for a parent (e.g. SuspenseList) to get notified\n * that one of its children/descendants suspended.\n *\n * The parent MAY return a callback. The callback will get called when the\n * suspension resolves, notifying the parent of the fact.\n * Moreover, the callback gets function `unsuspend` as a parameter. The resolved\n * child descendant will not actually get unsuspended until `unsuspend` gets called.\n * This is a way for the parent to delay unsuspending.\n *\n * If the parent does not return a callback then the resolved vnode\n * gets unsuspended immediately when it resolves.\n *\n * @param {import('./internal').VNode} vnode\n * @returns {((unsuspend: () => void) => void)?}\n */\nexport function suspended(vnode) {\n\tlet component = vnode._parent && vnode._parent._component;\n\treturn component && component._suspended && component._suspended(vnode);\n}\n\nexport function lazy(loader) {\n\tlet prom;\n\tlet component = null;\n\tlet error;\n\tlet resolved;\n\n\tfunction Lazy(props) {\n\t\tif (!prom) {\n\t\t\tprom = loader();\n\t\t\tprom.then(\n\t\t\t\texports => {\n\t\t\t\t\tif (exports) {\n\t\t\t\t\t\tcomponent = exports.default || exports;\n\t\t\t\t\t}\n\t\t\t\t\tresolved = true;\n\t\t\t\t},\n\t\t\t\te => {\n\t\t\t\t\terror = e;\n\t\t\t\t\tresolved = true;\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\n\t\tif (error) {\n\t\t\tthrow error;\n\t\t}\n\n\t\tif (!resolved) {\n\t\t\tthrow prom;\n\t\t}\n\n\t\treturn component ? createElement(component, props) : null;\n\t}\n\n\tLazy.displayName = 'Lazy';\n\tLazy._forwarded = true;\n\treturn Lazy;\n}\n","import { Component, toChildArray } from 'preact';\nimport { suspended } from './suspense.js';\n\n// Indexes to linked list nodes (nodes are stored as arrays to save bytes).\nconst SUSPENDED_COUNT = 0;\nconst RESOLVED_COUNT = 1;\nconst NEXT_NODE = 2;\n\n// Having custom inheritance instead of a class here saves a lot of bytes.\nexport function SuspenseList() {\n\tthis._next = null;\n\tthis._map = null;\n}\n\n// Mark one of child's earlier suspensions as resolved.\n// Some pending callbacks may become callable due to this\n// (e.g. the last suspended descendant gets resolved when\n// revealOrder === 'together'). Process those callbacks as well.\nconst resolve = (list, child, node) => {\n\tif (++node[RESOLVED_COUNT] === node[SUSPENDED_COUNT]) {\n\t\t// The number a child (or any of its descendants) has been suspended\n\t\t// matches the number of times it's been resolved. Therefore we\n\t\t// mark the child as completely resolved by deleting it from ._map.\n\t\t// This is used to figure out when *all* children have been completely\n\t\t// resolved when revealOrder is 'together'.\n\t\tlist._map.delete(child);\n\t}\n\n\t// If revealOrder is falsy then we can do an early exit, as the\n\t// callbacks won't get queued in the node anyway.\n\t// If revealOrder is 'together' then also do an early exit\n\t// if all suspended descendants have not yet been resolved.\n\tif (\n\t\t!list.props.revealOrder ||\n\t\t(list.props.revealOrder[0] === 't' && list._map.size)\n\t) {\n\t\treturn;\n\t}\n\n\t// Walk the currently suspended children in order, calling their\n\t// stored callbacks on the way. Stop if we encounter a child that\n\t// has not been completely resolved yet.\n\tnode = list._next;\n\twhile (node) {\n\t\twhile (node.length > 3) {\n\t\t\tnode.pop()();\n\t\t}\n\t\tif (node[RESOLVED_COUNT] < node[SUSPENDED_COUNT]) {\n\t\t\tbreak;\n\t\t}\n\t\tlist._next = node = node[NEXT_NODE];\n\t}\n};\n\n// Things we do here to save some bytes but are not proper JS inheritance:\n// - call `new Component()` as the prototype\n// - do not set `Suspense.prototype.constructor` to `Suspense`\nSuspenseList.prototype = new Component();\n\nSuspenseList.prototype._suspended = function (child) {\n\tconst list = this;\n\tconst delegated = suspended(list._vnode);\n\n\tlet node = list._map.get(child);\n\tnode[SUSPENDED_COUNT]++;\n\n\treturn unsuspend => {\n\t\tconst wrappedUnsuspend = () => {\n\t\t\tif (!list.props.revealOrder) {\n\t\t\t\t// Special case the undefined (falsy) revealOrder, as there\n\t\t\t\t// is no need to coordinate a specific order or unsuspends.\n\t\t\t\tunsuspend();\n\t\t\t} else {\n\t\t\t\tnode.push(unsuspend);\n\t\t\t\tresolve(list, child, node);\n\t\t\t}\n\t\t};\n\t\tif (delegated) {\n\t\t\tdelegated(wrappedUnsuspend);\n\t\t} else {\n\t\t\twrappedUnsuspend();\n\t\t}\n\t};\n};\n\nSuspenseList.prototype.render = function (props) {\n\tthis._next = null;\n\tthis._map = new Map();\n\n\tconst children = toChildArray(props.children);\n\tif (props.revealOrder && props.revealOrder[0] === 'b') {\n\t\t// If order === 'backwards' (or, well, anything starting with a 'b')\n\t\t// then flip the child list around so that the last child will be\n\t\t// the first in the linked list.\n\t\tchildren.reverse();\n\t}\n\t// Build the linked list. Iterate through the children in reverse order\n\t// so that `_next` points to the first linked list node to be resolved.\n\tfor (let i = children.length; i--; ) {\n\t\t// Create a new linked list node as an array of form:\n\t\t// \t[suspended_count, resolved_count, next_node]\n\t\t// where suspended_count and resolved_count are numeric counters for\n\t\t// keeping track how many times a node has been suspended and resolved.\n\t\t//\n\t\t// Note that suspended_count starts from 1 instead of 0, so we can block\n\t\t// processing callbacks until componentDidMount has been called. In a sense\n\t\t// node is suspended at least until componentDidMount gets called!\n\t\t//\n\t\t// Pending callbacks are added to the end of the node:\n\t\t// \t[suspended_count, resolved_count, next_node, callback_0, callback_1, ...]\n\t\tthis._map.set(children[i], (this._next = [1, 0, this._next]));\n\t}\n\treturn props.children;\n};\n\nSuspenseList.prototype.componentDidUpdate =\n\tSuspenseList.prototype.componentDidMount = function () {\n\t\t// Iterate through all children after mounting for two reasons:\n\t\t// 1. As each node[SUSPENDED_COUNT] starts from 1, this iteration increases\n\t\t// each node[RELEASED_COUNT] by 1, therefore balancing the counters.\n\t\t// The nodes can now be completely consumed from the linked list.\n\t\t// 2. Handle nodes that might have gotten resolved between render and\n\t\t// componentDidMount.\n\t\tthis._map.forEach((node, child) => {\n\t\t\tresolve(this, child, node);\n\t\t});\n\t};\n","import {\n\trender as preactRender,\n\thydrate as preactHydrate,\n\toptions,\n\ttoChildArray,\n\tComponent\n} from 'preact';\nimport {\n\tuseCallback,\n\tuseContext,\n\tuseDebugValue,\n\tuseEffect,\n\tuseId,\n\tuseImperativeHandle,\n\tuseLayoutEffect,\n\tuseMemo,\n\tuseReducer,\n\tuseRef,\n\tuseState\n} from 'preact/hooks';\nimport {\n\tuseDeferredValue,\n\tuseInsertionEffect,\n\tuseSyncExternalStore,\n\tuseTransition\n} from './index';\n\nexport const REACT_ELEMENT_TYPE =\n\t(typeof Symbol != 'undefined' && Symbol.for && Symbol.for('react.element')) ||\n\t0xeac7;\n\nconst CAMEL_PROPS =\n\t/^(?:accent|alignment|arabic|baseline|cap|clip(?!PathU)|color|dominant|fill|flood|font|glyph(?!R)|horiz|image(!S)|letter|lighting|marker(?!H|W|U)|overline|paint|pointer|shape|stop|strikethrough|stroke|text(?!L)|transform|underline|unicode|units|v|vector|vert|word|writing|x(?!C))[A-Z]/;\nconst ON_ANI = /^on(Ani|Tra|Tou|BeforeInp|Compo)/;\nconst CAMEL_REPLACE = /[A-Z0-9]/g;\nconst IS_DOM = typeof document !== 'undefined';\n\n// Input types for which onchange should not be converted to oninput.\n// type=\"file|checkbox|radio\", plus \"range\" in IE11.\n// (IE11 doesn't support Symbol, which we use here to turn `rad` into `ra` which matches \"range\")\nconst onChangeInputType = type =>\n\t(typeof Symbol != 'undefined' && typeof Symbol() == 'symbol'\n\t\t? /fil|che|rad/\n\t\t: /fil|che|ra/\n\t).test(type);\n\n// Some libraries like `react-virtualized` explicitly check for this.\nComponent.prototype.isReactComponent = true;\n\n// `UNSAFE_*` lifecycle hooks\n// Preact only ever invokes the unprefixed methods.\n// Here we provide a base \"fallback\" implementation that calls any defined UNSAFE_ prefixed method.\n// - If a component defines its own `componentDidMount()` (including via defineProperty), use that.\n// - If a component defines `UNSAFE_componentDidMount()`, `componentDidMount` is the alias getter/setter.\n// - If anything assigns to an `UNSAFE_*` property, the assignment is forwarded to the unprefixed property.\n// See https://github.com/preactjs/preact/issues/1941\n[\n\t'componentWillMount',\n\t'componentWillReceiveProps',\n\t'componentWillUpdate'\n].forEach(key => {\n\tObject.defineProperty(Component.prototype, key, {\n\t\tconfigurable: true,\n\t\tget() {\n\t\t\treturn this['UNSAFE_' + key];\n\t\t},\n\t\tset(v) {\n\t\t\tObject.defineProperty(this, key, {\n\t\t\t\tconfigurable: true,\n\t\t\t\twritable: true,\n\t\t\t\tvalue: v\n\t\t\t});\n\t\t}\n\t});\n});\n\n/**\n * Proxy render() since React returns a Component reference.\n * @param {import('./internal').VNode} vnode VNode tree to render\n * @param {import('./internal').PreactElement} parent DOM node to render vnode tree into\n * @param {() => void} [callback] Optional callback that will be called after rendering\n * @returns {import('./internal').Component | null} The root component reference or null\n */\nexport function render(vnode, parent, callback) {\n\t// React destroys any existing DOM nodes, see #1727\n\t// ...but only on the first render, see #1828\n\tif (parent._children == null) {\n\t\tparent.textContent = '';\n\t}\n\n\tpreactRender(vnode, parent);\n\tif (typeof callback == 'function') callback();\n\n\treturn vnode ? vnode._component : null;\n}\n\nexport function hydrate(vnode, parent, callback) {\n\tpreactHydrate(vnode, parent);\n\tif (typeof callback == 'function') callback();\n\n\treturn vnode ? vnode._component : null;\n}\n\nlet oldEventHook = options.event;\noptions.event = e => {\n\tif (oldEventHook) e = oldEventHook(e);\n\n\te.persist = () => {};\n\te.isPropagationStopped = function isPropagationStopped() {\n\t\treturn this.cancelBubble;\n\t};\n\te.isDefaultPrevented = function isDefaultPrevented() {\n\t\treturn this.defaultPrevented;\n\t};\n\treturn (e.nativeEvent = e);\n};\n\nconst classNameDescriptorNonEnumberable = {\n\tconfigurable: true,\n\tget() {\n\t\treturn this.class;\n\t}\n};\n\nfunction handleDomVNode(vnode) {\n\tlet props = vnode.props,\n\t\ttype = vnode.type,\n\t\tnormalizedProps = {},\n\t\tisNonDashedType = type.indexOf('-') == -1;\n\n\tfor (let i in props) {\n\t\tlet value = props[i];\n\n\t\tif (\n\t\t\t(i === 'value' && 'defaultValue' in props && value == null) ||\n\t\t\t// Emulate React's behavior of not rendering the contents of noscript tags on the client.\n\t\t\t(IS_DOM && i === 'children' && type === 'noscript') ||\n\t\t\ti === 'class' ||\n\t\t\ti === 'className'\n\t\t) {\n\t\t\t// Skip applying value if it is null/undefined and we already set\n\t\t\t// a default value\n\t\t\tcontinue;\n\t\t}\n\n\t\tlet lowerCased = i.toLowerCase();\n\t\tif (i === 'defaultValue' && 'value' in props && props.value == null) {\n\t\t\t// `defaultValue` is treated as a fallback `value` when a value prop is present but null/undefined.\n\t\t\t// `defaultValue` for Elements with no value prop is the same as the DOM defaultValue property.\n\t\t\ti = 'value';\n\t\t} else if (i === 'download' && value === true) {\n\t\t\t// Calling `setAttribute` with a truthy value will lead to it being\n\t\t\t// passed as a stringified value, e.g. `download=\"true\"`. React\n\t\t\t// converts it to an empty string instead, otherwise the attribute\n\t\t\t// value will be used as the file name and the file will be called\n\t\t\t// \"true\" upon downloading it.\n\t\t\tvalue = '';\n\t\t} else if (lowerCased === 'translate' && value === 'no') {\n\t\t\tvalue = false;\n\t\t} else if (lowerCased[0] === 'o' && lowerCased[1] === 'n') {\n\t\t\tif (lowerCased === 'ondoubleclick') {\n\t\t\t\ti = 'ondblclick';\n\t\t\t} else if (\n\t\t\t\tlowerCased === 'onchange' &&\n\t\t\t\t(type === 'input' || type === 'textarea') &&\n\t\t\t\t!onChangeInputType(props.type)\n\t\t\t) {\n\t\t\t\tlowerCased = i = 'oninput';\n\t\t\t} else if (lowerCased === 'onfocus') {\n\t\t\t\ti = 'onfocusin';\n\t\t\t} else if (lowerCased === 'onblur') {\n\t\t\t\ti = 'onfocusout';\n\t\t\t} else if (ON_ANI.test(i)) {\n\t\t\t\ti = lowerCased;\n\t\t\t}\n\t\t} else if (isNonDashedType && CAMEL_PROPS.test(i)) {\n\t\t\ti = i.replace(CAMEL_REPLACE, '-$&').toLowerCase();\n\t\t} else if (value === null) {\n\t\t\tvalue = undefined;\n\t\t}\n\n\t\t// Add support for onInput and onChange, see #3561\n\t\t// if we have an oninput prop already change it to oninputCapture\n\t\tif (lowerCased === 'oninput') {\n\t\t\ti = lowerCased;\n\t\t\tif (normalizedProps[i]) {\n\t\t\t\ti = 'oninputCapture';\n\t\t\t}\n\t\t}\n\n\t\tnormalizedProps[i] = value;\n\t}\n\n\tif (type == 'select') {\n\t\t// Add support for array select values: <select multiple value={[]} />\n\t\tif (normalizedProps.multiple && Array.isArray(normalizedProps.value)) {\n\t\t\t// forEach() always returns undefined, which we abuse here to unset the value prop.\n\t\t\tnormalizedProps.value = toChildArray(props.children).forEach(child => {\n\t\t\t\tchild.props.selected =\n\t\t\t\t\tnormalizedProps.value.indexOf(child.props.value) != -1;\n\t\t\t});\n\t\t}\n\n\t\t// Adding support for defaultValue in select tag\n\t\tif (normalizedProps.defaultValue != null) {\n\t\t\tnormalizedProps.value = toChildArray(props.children).forEach(child => {\n\t\t\t\tif (normalizedProps.multiple) {\n\t\t\t\t\tchild.props.selected =\n\t\t\t\t\t\tnormalizedProps.defaultValue.indexOf(child.props.value) != -1;\n\t\t\t\t} else {\n\t\t\t\t\tchild.props.selected =\n\t\t\t\t\t\tnormalizedProps.defaultValue == child.props.value;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tif (props.class && !props.className) {\n\t\tnormalizedProps.class = props.class;\n\t\tObject.defineProperty(\n\t\t\tnormalizedProps,\n\t\t\t'className',\n\t\t\tclassNameDescriptorNonEnumberable\n\t\t);\n\t} else if (props.className) {\n\t\tnormalizedProps.class = normalizedProps.className = props.className;\n\t}\n\n\tvnode.props = normalizedProps;\n}\n\nlet oldVNodeHook = options.vnode;\noptions.vnode = vnode => {\n\t// only normalize props on Element nodes\n\tif (typeof vnode.type === 'string') {\n\t\thandleDomVNode(vnode);\n\t}\n\n\tvnode.$$typeof = REACT_ELEMENT_TYPE;\n\n\tif (oldVNodeHook) oldVNodeHook(vnode);\n};\n\n// Only needed for react-relay\nlet currentComponent;\nconst oldBeforeRender = options._render;\noptions._render = function (vnode) {\n\tif (oldBeforeRender) {\n\t\toldBeforeRender(vnode);\n\t}\n\tcurrentComponent = vnode._component;\n};\n\nconst oldDiffed = options.diffed;\n/** @type {(vnode: import('./internal').VNode) => void} */\noptions.diffed = function (vnode) {\n\tif (oldDiffed) {\n\t\toldDiffed(vnode);\n\t}\n\n\tconst props = vnode.props;\n\tconst dom = vnode._dom;\n\n\tif (\n\t\tdom != null &&\n\t\tvnode.type === 'textarea' &&\n\t\t'value' in props &&\n\t\tprops.value !== dom.value\n\t) {\n\t\tdom.value = props.value == null ? '' : props.value;\n\t}\n\n\tcurrentComponent = null;\n};\n\n// This is a very very private internal function for React it\n// is used to sort-of do runtime dependency injection.\nexport const __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = {\n\tReactCurrentDispatcher: {\n\t\tcurrent: {\n\t\t\treadContext(context) {\n\t\t\t\treturn currentComponent._globalContext[context._id].props.value;\n\t\t\t},\n\t\t\tuseCallback,\n\t\t\tuseContext,\n\t\t\tuseDebugValue,\n\t\t\tuseDeferredValue,\n\t\t\tuseEffect,\n\t\t\tuseId,\n\t\t\tuseImperativeHandle,\n\t\t\tuseInsertionEffect,\n\t\t\tuseLayoutEffect,\n\t\t\tuseMemo,\n\t\t\t// useMutableSource, // experimental-only and replaced by uSES, likely not worth supporting\n\t\t\tuseReducer,\n\t\t\tuseRef,\n\t\t\tuseState,\n\t\t\tuseSyncExternalStore,\n\t\t\tuseTransition\n\t\t}\n\t}\n};\n","import {\n\tcreateElement,\n\trender as preactRender,\n\tcloneElement as preactCloneElement,\n\tcreateRef,\n\tComponent,\n\tcreateContext,\n\tFragment,\n\toptions\n} from 'preact';\nimport {\n\tuseState,\n\tuseId,\n\tuseReducer,\n\tuseEffect,\n\tuseLayoutEffect,\n\tuseRef,\n\tuseImperativeHandle,\n\tuseMemo,\n\tuseCallback,\n\tuseContext,\n\tuseDebugValue\n} from 'preact/hooks';\nimport {\n\tuseInsertionEffect,\n\tstartTransition,\n\tuseDeferredValue,\n\tuseSyncExternalStore,\n\tuseTransition\n} from './hooks';\nimport { PureComponent } from './PureComponent';\nimport { memo } from './memo';\nimport { forwardRef } from './forwardRef';\nimport { Children } from './Children';\nimport { Suspense, lazy } from './suspense';\nimport { SuspenseList } from './suspense-list';\nimport { createPortal } from './portals';\nimport {\n\thydrate,\n\trender,\n\tREACT_ELEMENT_TYPE,\n\t__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED\n} from './render';\n\nconst version = '18.3.1'; // trick libraries to think we are react\n\n/**\n * Legacy version of createElement.\n * @param {import('./internal').VNode[\"type\"]} type The node name or Component constructor\n */\nfunction createFactory(type) {\n\treturn createElement.bind(null, type);\n}\n\n/**\n * Check if the passed element is a valid (p)react node.\n * @param {*} element The element to check\n * @returns {boolean}\n */\nfunction isValidElement(element) {\n\treturn !!element && element.$$typeof === REACT_ELEMENT_TYPE;\n}\n\n/**\n * Check if the passed element is a Fragment node.\n * @param {*} element The element to check\n * @returns {boolean}\n */\nfunction isFragment(element) {\n\treturn isValidElement(element) && element.type === Fragment;\n}\n\n/**\n * Check if the passed element is a Memo node.\n * @param {*} element The element to check\n * @returns {boolean}\n */\nfunction isMemo(element) {\n\treturn (\n\t\t!!element &&\n\t\ttypeof element.displayName == 'string' &&\n\t\telement.displayName.indexOf('Memo(') == 0\n\t);\n}\n\n/**\n * Wrap `cloneElement` to abort if the passed element is not a valid element and apply\n * all vnode normalizations.\n * @param {import('./internal').VNode} element The vnode to clone\n * @param {object} props Props to add when cloning\n * @param {Array<import('./internal').ComponentChildren>} rest Optional component children\n */\nfunction cloneElement(element) {\n\tif (!isValidElement(element)) return element;\n\treturn preactCloneElement.apply(null, arguments);\n}\n\n/**\n * Remove a component tree from the DOM, including state and event handlers.\n * @param {import('./internal').PreactElement} container\n * @returns {boolean}\n */\nfunction unmountComponentAtNode(container) {\n\tif (container._children) {\n\t\tpreactRender(null, container);\n\t\treturn true;\n\t}\n\treturn false;\n}\n\n/**\n * Get the matching DOM node for a component\n * @param {import('./internal').Component} component\n * @returns {import('./internal').PreactElement | null}\n */\nfunction findDOMNode(component) {\n\treturn (\n\t\t(component &&\n\t\t\t(component.base || (component.nodeType === 1 && component))) ||\n\t\tnull\n\t);\n}\n\n/**\n * Deprecated way to control batched rendering inside the reconciler, but we\n * already schedule in batches inside our rendering code\n * @template Arg\n * @param {(arg: Arg) => void} callback function that triggers the updated\n * @param {Arg} [arg] Optional argument that can be passed to the callback\n */\n// eslint-disable-next-line camelcase\nconst unstable_batchedUpdates = (callback, arg) => callback(arg);\n\n/**\n * In React, `flushSync` flushes the entire tree and forces a rerender.\n * @template Arg\n * @template Result\n * @param {(arg: Arg) => Result} callback function that runs before the flush\n * @param {Arg} [arg] Optional argument that can be passed to the callback\n * @returns\n */\nconst flushSync = (callback, arg) => {\n\tconst prevDebounce = options.debounceRendering;\n\toptions.debounceRendering = cb => cb();\n\tconst res = callback(arg);\n\toptions.debounceRendering = prevDebounce;\n\treturn res;\n};\n\n// compat to react-is\nexport const isElement = isValidElement;\n\nexport * from 'preact/hooks';\nexport {\n\tversion,\n\tChildren,\n\trender,\n\thydrate,\n\tunmountComponentAtNode,\n\tcreatePortal,\n\tcreateElement,\n\tcreateContext,\n\tcreateFactory,\n\tcloneElement,\n\tcreateRef,\n\tFragment,\n\tisValidElement,\n\tisFragment,\n\tisMemo,\n\tfindDOMNode,\n\tComponent,\n\tPureComponent,\n\tmemo,\n\tforwardRef,\n\tflushSync,\n\tuseInsertionEffect,\n\tstartTransition,\n\tuseDeferredValue,\n\tuseSyncExternalStore,\n\tuseTransition,\n\t// eslint-disable-next-line camelcase\n\tunstable_batchedUpdates,\n\tFragment as StrictMode,\n\tSuspense,\n\tSuspenseList,\n\tlazy,\n\t__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED\n};\n\n// React copies the named exports to the default one.\nexport default {\n\tuseState,\n\tuseId,\n\tuseReducer,\n\tuseEffect,\n\tuseLayoutEffect,\n\tuseInsertionEffect,\n\tuseTransition,\n\tuseDeferredValue,\n\tuseSyncExternalStore,\n\tstartTransition,\n\tuseRef,\n\tuseImperativeHandle,\n\tuseMemo,\n\tuseCallback,\n\tuseContext,\n\tuseDebugValue,\n\tversion,\n\tChildren,\n\trender,\n\thydrate,\n\tunmountComponentAtNode,\n\tcreatePortal,\n\tcreateElement,\n\tcreateContext,\n\tcreateFactory,\n\tcloneElement,\n\tcreateRef,\n\tFragment,\n\tisValidElement,\n\tisElement,\n\tisFragment,\n\tisMemo,\n\tfindDOMNode,\n\tComponent,\n\tPureComponent,\n\tmemo,\n\tforwardRef,\n\tflushSync,\n\tunstable_batchedUpdates,\n\tStrictMode: Fragment,\n\tSuspense,\n\tSuspenseList,\n\tlazy,\n\t__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED\n};\n","import { render, hydrate, unmountComponentAtNode } from 'preact/compat';\n\nexport function createRoot(container) {\n\treturn {\n\t\t// eslint-disable-next-line\n\t\trender: function (children) {\n\t\t\trender(children, container);\n\t\t},\n\t\t// eslint-disable-next-line\n\t\tunmount: function () {\n\t\t\tunmountComponentAtNode(container);\n\t\t}\n\t};\n}\n\nexport function hydrateRoot(container, children) {\n\thydrate(children, container);\n\treturn createRoot(container);\n}\n\nexport default {\n\tcreateRoot,\n\thydrateRoot\n};\n","/**\n * Doc Schema\n *\n * Defines the JSON format for AI-scriptable visual docs that accompany\n * audio narration. A Doc describes a sequence of animated blocks\n * with text overlays, images, and transitions synchronized to audio.\n *\n * The format is designed to be:\n * 1. AI-generatable - Claude can create scripts from article content\n * 2. Browser-renderable - SVG + CSS animations (ES2015 compatible)\n * 3. Video-exportable - Frame-by-frame capture via Playwright\n *\n * Timing: Blocks are timed to match narration audio segments. Each article\n * has 3-6 MP3 files (intro + sections), and blocks are grouped by segment.\n */\n\n// ============================================\n// Core Types\n// ============================================\n\n/**\n * Configuration for the Start/resting block shown before playback begins.\n */\nexport interface StartBlockConfig {\n /** Hero image path (relative to article media) */\n heroSrc: string;\n /** Alt text for the hero image */\n heroAlt?: string;\n /** Title to display over the hero */\n title: string;\n /** Optional subtitle */\n subtitle?: string;\n /** Ambient motion for the hero image */\n ambientMotion?: 'zoomIn' | 'zoomOut' | 'panLeft' | 'panRight';\n /** Photo credit / artist name for the hero image */\n heroCredit?: string;\n /** License identifier for the hero image */\n heroLicense?: string;\n}\n\n/**\n * A complete visual doc for an article.\n */\nexport interface Doc {\n /** Article ID this doc belongs to */\n articleId: string;\n\n /** Total duration in seconds (sum of all audio segments) */\n duration: number;\n\n /** Ordered list of blocks */\n blocks: Block[];\n\n /** Audio track configuration */\n audio: AudioTrack;\n\n /** Caption track for closed captions (generated by postprocess-doc) */\n captions?: CaptionTrack;\n\n /**\n * Start/resting block shown before playback begins.\n * Displays hero image with title - acts as a \"poster\" for the doc.\n * The player shows this until the user starts playback.\n */\n startBlock?: StartBlockConfig;\n\n /**\n * Persistent layers rendered on every block (behind and/or on top of content).\n * Used for consistent branding overlays, background gradients, etc.\n */\n persistentLayers?: import('./BlockTemplates.js').PersistentLayerConfig;\n\n /**\n * Optional theme identifier. Resolved at render time via `resolveTheme()`.\n * When omitted, the renderer uses the default theme ('documentary').\n */\n themeId?: string;\n\n /** Optional metadata */\n meta?: {\n generatedAt?: string;\n generatedBy?: string;\n version?: number;\n };\n\n /**\n * YAML frontmatter from the source markdown.\n * Carries rendering hints like `document-render-as` and custom metadata.\n */\n frontmatter?: Record<string, unknown>;\n}\n\n/**\n * A single block in the doc.\n *\n * Blocks can be flat (audio-synced timeline) or nested (markdown-driven hierarchy).\n * When derived from markdown, a block corresponds to a heading section:\n * - `sourceHeading` references the original MarkdownHeading node\n * - `contents` holds the body markdown between this heading and the next\n * - `children` holds sub-heading blocks (e.g., H2s under an H1)\n */\nexport interface Block {\n /** Unique identifier for this block */\n id: string;\n\n /** When this block appears (seconds from start) */\n startTime: number;\n\n /** How long this block is visible (seconds) */\n duration: number;\n\n /** Which audio segment this block belongs to (0-indexed) */\n audioSegment: number;\n\n /**\n * Pre-computed visual layers, rendered back-to-front.\n *\n * Optional — template-derived blocks typically omit this and compute\n * layers on demand via `getLayers()` from `@bendyline/squisq/doc`.\n * Raw blocks (e.g., hand-crafted by AI) may provide layers directly.\n */\n layers?: Layer[];\n\n /** Entry transition from previous block */\n transition?: Transition;\n\n /** Template name that generated this block (for debugging) */\n template?: string;\n\n /**\n * Display title for template rendering.\n * Extracted from the sourceHeading when the block is created by markdownToDoc().\n * Templates like sectionHeader and titleBlock read this for their title layer.\n */\n title?: string;\n\n // ── Markdown-driven hierarchy (optional) ──\n\n /**\n * Nested sub-blocks (heading hierarchy).\n * When a doc is derived from markdown, sub-headings within this\n * heading's section become child blocks. For example, H2 blocks\n * under an H1 block appear here.\n */\n children?: Block[];\n\n /**\n * Markdown body content for this block's section.\n * Contains the block-level markdown nodes (paragraphs, lists, code,\n * blockquotes, etc.) that appear between this heading and the next\n * heading or sub-heading. Empty for pure structural blocks.\n */\n contents?: import('../markdown/types.js').MarkdownBlockNode[];\n\n /**\n * Reference to the MarkdownHeading node that created this block.\n * Present when the block was derived from markdown via markdownToDoc().\n * Enables round-tripping back to markdown and provides heading depth.\n * Absent for the preamble block (content before the first heading).\n */\n sourceHeading?: import('../markdown/types.js').MarkdownHeading;\n\n /**\n * Template overrides extracted from markdown directives.\n * For example, `### Data Section {template=chart colorScheme=blue}`\n * would produce `{ template: 'chart', colorScheme: 'blue' }`.\n * Allows per-block customization of template selection and parameters.\n */\n templateOverrides?: Record<string, string>;\n}\n\n// ============================================\n// Layer Types\n// ============================================\n\n/**\n * A visual element within a block.\n * Layers are composited back-to-front (first layer is background).\n */\nexport type Layer = ImageLayer | TextLayer | ShapeLayer | MapLayer | VideoLayer;\n\ninterface BaseLayer {\n /** Unique identifier for this layer */\n id: string;\n\n /** Position and size */\n position: Position;\n\n /** Animation to apply */\n animation?: Animation;\n}\n\n/**\n * Image layer - displays an image with optional Ken Burns effect.\n */\nexport interface ImageLayer extends BaseLayer {\n type: 'image';\n content: {\n /** Path to image file (relative to article media dir) */\n src: string;\n /** Alt text for accessibility */\n alt: string;\n /** How to fit image in bounds */\n fit?: 'cover' | 'contain' | 'fill';\n /** Photo credit / artist name */\n credit?: string;\n /** License identifier (e.g., 'CC BY-SA 4.0') */\n license?: string;\n };\n}\n\n/**\n * Text layer - displays text with styling.\n */\nexport interface TextLayer extends BaseLayer {\n type: 'text';\n content: {\n /** Text to display (supports \\n for line breaks) */\n text: string;\n /** Text styling */\n style: TextStyle;\n };\n}\n\n/**\n * Shape layer - simple geometric shapes for visual accents.\n */\nexport interface ShapeLayer extends BaseLayer {\n type: 'shape';\n content: {\n /** Shape type */\n shape: 'rect' | 'circle' | 'line';\n /** Fill color (CSS color or 'none') */\n fill?: string;\n /** Stroke color */\n stroke?: string;\n /** Stroke width in pixels */\n strokeWidth?: number;\n /** Corner radius for rect */\n borderRadius?: number;\n };\n}\n\n/**\n * Map layer - displays a geographic map with optional markers.\n *\n * Maps are rendered as composite tile images from free tile providers.\n * Supported styles use open-source/free tiles requiring attribution.\n */\nexport interface MapLayer extends BaseLayer {\n type: 'map';\n content: {\n /** Center coordinates for the map */\n center: {\n lat: number;\n lng: number;\n };\n /** Zoom level (0-18, typically 8-14 for doc blocks) */\n zoom: number;\n /** Map tile style */\n style: MapTileStyle;\n /** Optional markers to display on the map */\n markers?: MapMarker[];\n /** Pre-rendered static image path (for video export reliability) */\n staticSrc?: string;\n /** Show attribution text (default: true) */\n showAttribution?: boolean;\n };\n}\n\n/**\n * Video layer - displays a short video clip, always muted (narration provides audio).\n *\n * Rendered via an HTML5 <video> element inside <foreignObject>, similar to how\n * ImageLayer uses <img> for Ken Burns effects. clipStart/clipEnd define the window\n * within the source video to play. During Playwright frame capture (seekTo mode),\n * the video is seeked programmatically rather than playing in real time.\n */\nexport interface VideoLayer extends BaseLayer {\n type: 'video';\n content: {\n /** Path to video file (relative to article media dir) */\n src: string;\n /** Path to poster frame (shown before video loads / during seek) */\n posterSrc?: string;\n /** Alt text for accessibility */\n alt: string;\n /** How to fit video in bounds */\n fit?: 'cover' | 'contain' | 'fill';\n /** Start time within the source video (seconds) */\n clipStart: number;\n /** End time within the source video (seconds) */\n clipEnd: number;\n /** Total source video duration (for validation) */\n sourceDuration?: number;\n /** Video credit / artist name */\n credit?: string;\n /** License identifier (e.g., 'CC BY-SA 4.0') */\n license?: string;\n };\n}\n\n/**\n * Available map tile styles from free/open-source providers.\n */\nexport type MapTileStyle =\n | 'terrain' // OpenTopoMap - topographic/terrain (default)\n | 'satellite' // ESRI World Imagery\n | 'road' // OpenStreetMap standard\n | 'toner' // Stadia Toner (high contrast B&W)\n | 'watercolor'; // Stadia Watercolor (artistic)\n\n/**\n * A marker to display on the map.\n */\nexport interface MapMarker {\n /** Marker latitude */\n lat: number;\n /** Marker longitude */\n lng: number;\n /** Optional label text */\n label?: string;\n /** Marker color (CSS color, default: #ef4444) */\n color?: string;\n /** Marker icon type */\n icon?: 'pin' | 'circle' | 'star';\n}\n\n// ============================================\n// Position & Styling\n// ============================================\n\n/**\n * Position and dimensions for a layer.\n * Values can be pixels (number) or percentages (string like \"50%\").\n */\nexport interface Position {\n /** X position (pixels or percentage) */\n x: number | string;\n /** Y position (pixels or percentage) */\n y: number | string;\n /** Width (pixels or percentage) */\n width?: number | string;\n /** Height (pixels or percentage) */\n height?: number | string;\n /** Anchor point for positioning */\n anchor?: 'center' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';\n}\n\n/**\n * Text styling options.\n */\nexport interface TextStyle {\n /** Font size in pixels */\n fontSize: number;\n /** Font family (defaults to system sans-serif) */\n fontFamily?: string;\n /** Font weight */\n fontWeight?: 'normal' | 'bold';\n /** Text color (CSS color) */\n color: string;\n /** Text alignment */\n textAlign?: 'left' | 'center' | 'right';\n /** Line height multiplier */\n lineHeight?: number;\n /** Add drop shadow for readability over images */\n shadow?: boolean;\n /** Background color for text box */\n background?: string;\n /** Padding around text (pixels) */\n padding?: number;\n /** Maximum number of lines before truncation (adds \"...\" to last line) */\n maxLines?: number;\n}\n\n// ============================================\n// Animation & Transitions\n// ============================================\n\n/**\n * Animation to apply to a layer.\n */\nexport interface Animation {\n /** Animation type */\n type: AnimationType;\n /** Duration in seconds (defaults to layer's block duration) */\n duration?: number;\n /** Delay before animation starts (seconds) */\n delay?: number;\n /** CSS easing function */\n easing?: string;\n /** For Ken Burns: zoom direction */\n direction?: 'in' | 'out';\n /** For pan animations: pan direction */\n panDirection?: 'left' | 'right' | 'up' | 'down';\n}\n\n/**\n * Available animation types.\n */\nexport type AnimationType =\n | 'none'\n | 'fadeIn'\n | 'fadeOut'\n | 'slowZoom' // Slow zoom with optional pan\n | 'zoomIn'\n | 'zoomOut'\n | 'panLeft'\n | 'panRight'\n | 'typewriter'; // Text appears letter by letter\n\n/**\n * Transition between blocks.\n */\nexport interface Transition {\n /** Transition type */\n type: TransitionType;\n /** Duration in seconds */\n duration: number;\n}\n\nexport type TransitionType =\n | 'cut' // Instant switch\n | 'fade' // Cross-fade\n | 'dissolve' // Soft dissolve\n | 'slideLeft' // New block enters from right\n | 'slideRight'; // New block enters from left\n\n// ============================================\n// Audio Configuration\n// ============================================\n\n/**\n * Audio track configuration.\n * Articles have multiple MP3 segments (intro + sections).\n */\nexport interface AudioTrack {\n /** Audio segments in playback order */\n segments: AudioSegment[];\n}\n\n// ============================================\n// Captions\n// ============================================\n\n/**\n * A single word with precise timing, used for word-level highlighting\n * in social-style captions. Populated from TTS timing data when available.\n */\nexport interface CaptionWord {\n /** The word text */\n text: string;\n /** Start time in seconds (relative to doc start) */\n startTime: number;\n /** End time in seconds */\n endTime: number;\n}\n\n/**\n * A single caption phrase to display during playback.\n */\nexport interface CaptionPhrase {\n /** The text to display */\n text: string;\n /** Start time in seconds (relative to doc start) */\n startTime: number;\n /** End time in seconds */\n endTime: number;\n /** Which audio segment this caption belongs to (0-indexed) */\n audioSegment: number;\n /**\n * Optional per-word timing from TTS timing data.\n * When present, enables precise word-level highlighting in social\n * caption style. When absent, word timing is interpolated evenly\n * across the phrase duration.\n */\n words?: CaptionWord[];\n}\n\n/**\n * Caption track for a doc.\n */\nexport interface CaptionTrack {\n /** Caption phrases in chronological order */\n phrases: CaptionPhrase[];\n /** When the captions were generated */\n generatedAt: string;\n /** Algorithm version for regeneration detection */\n version: number;\n}\n\n/**\n * A single audio segment (one MP3 file).\n */\nexport interface AudioSegment {\n /** Path to MP3 file (relative to article media dir) */\n src: string;\n /** Segment name (e.g., \"intro\", \"history\") */\n name: string;\n /** Duration in seconds */\n duration: number;\n /** Start time in overall timeline (calculated) */\n startTime: number;\n}\n\n// ============================================\n// Audio Timing Data (from TTS)\n// ============================================\n\n/**\n * A single word-level timing bookmark from TTS synthesis.\n * Used for precise audio-to-content mapping and word-level caption sync.\n */\nexport interface AudioBookmark {\n /** Unique identifier (e.g., \"word-0\", \"word-1\") */\n id: string;\n /** Timestamp in seconds from audio start */\n time: number;\n /** Character offset in the source text */\n charOffset: number;\n /** The word text at this position */\n textFragment?: string;\n}\n\n/**\n * Timing data for an audio segment, typically from a `.timing.json` file\n * generated alongside TTS audio. Contains the source text and per-word\n * timing bookmarks for precise content matching and caption sync.\n */\nexport interface AudioTimingData {\n /** The normalized plain text that was synthesized */\n sourceText: string;\n /** Word-level timing bookmarks */\n bookmarks: AudioBookmark[];\n /** Total audio duration in seconds */\n duration: number;\n}\n\n// ============================================\n// Helper Functions\n// ============================================\n\n/**\n * Calculate total duration from audio segments.\n */\nexport function calculateDuration(audio: AudioTrack): number {\n return audio.segments.reduce((sum, seg) => sum + seg.duration, 0);\n}\n\n/**\n * Find which audio segment is playing at a given time.\n */\nexport function getSegmentAtTime(audio: AudioTrack, time: number): number {\n let elapsed = 0;\n for (let i = 0; i < audio.segments.length; i++) {\n elapsed += audio.segments[i].duration;\n if (time < elapsed) return i;\n }\n return audio.segments.length - 1;\n}\n\n/**\n * Find which block should be visible at a given time.\n */\nexport function getBlockAtTime(blocks: Block[], time: number): Block | null {\n for (let i = blocks.length - 1; i >= 0; i--) {\n const block = blocks[i];\n if (time >= block.startTime && time < block.startTime + block.duration) {\n return block;\n }\n }\n return blocks[0] || null;\n}\n\n/**\n * Find the caption phrase that should be displayed at a given time.\n */\nexport function getCaptionAtTime(\n captions: CaptionTrack | undefined,\n time: number,\n): CaptionPhrase | null {\n if (!captions || !captions.phrases.length) return null;\n\n for (const phrase of captions.phrases) {\n if (time >= phrase.startTime && time < phrase.endTime) {\n return phrase;\n }\n }\n return null;\n}\n\n/**\n * Validate a Doc for completeness.\n */\nexport function validateDoc(script: Doc): string[] {\n const errors: string[] = [];\n\n if (!script.articleId) {\n errors.push('Missing articleId');\n }\n\n if (!script.blocks || script.blocks.length === 0) {\n errors.push('No blocks defined');\n }\n\n if (!script.audio || !script.audio.segments || script.audio.segments.length === 0) {\n errors.push('No audio segments defined');\n }\n\n // Check for gaps in block coverage\n const totalDuration = script.duration;\n let covered = 0;\n for (const block of script.blocks) {\n if (block.startTime > covered + 0.1) {\n errors.push(`Gap in blocks: ${covered}s to ${block.startTime}s`);\n }\n covered = Math.max(covered, block.startTime + block.duration);\n }\n\n if (covered < totalDuration - 0.1) {\n errors.push(`Blocks end at ${covered}s but audio is ${totalDuration}s`);\n }\n\n return errors;\n}\n","/**\n * Built-in Theme Library\n *\n * Ships 8 curated themes covering documentary, editorial, minimal, and\n * cinematic styles. Each theme is fully JSON-serializable.\n *\n * Usage:\n * ```ts\n * import { THEMES, resolveTheme } from '@bendyline/squisq/schemas';\n *\n * const theme = resolveTheme('minimalist'); // look up by id\n * const theme = THEMES.documentary; // direct access\n * ```\n */\n\nimport type { Theme, ThemeColorScheme } from './Theme.js';\n\n// ============================================\n// Shared constants\n// ============================================\n\n// ── Font stacks ──────────────────────────────────────────────────\n// Each stack lists the recommended Google Font first (works when the\n// wrapping site loads it), then degrades to safe system fonts.\n// Squisq itself does NOT load Google Fonts.\n\n/** System fonts only — no external dependencies. */\nconst SYSTEM_SANS = 'system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif';\nconst SYSTEM_SERIF = 'Georgia, \"Times New Roman\", serif';\nconst SYSTEM_MONO = 'Consolas, \"Courier New\", monospace';\n\n/** Theme-specific stacks with Google Font leads. */\nconst PLAYFAIR = '\"Playfair Display\", Georgia, serif';\nconst SOURCE_SERIF = '\"Source Serif 4\", \"PT Serif\", Georgia, serif';\nconst INTER = '\"Inter\", \"Segoe UI\", Roboto, sans-serif';\nconst OSWALD = '\"Oswald\", Impact, \"Arial Black\", sans-serif';\nconst ROBOTO = '\"Roboto\", \"Segoe UI\", Arial, sans-serif';\nconst MERRIWEATHER = '\"Merriweather\", Georgia, serif';\nconst LORA = '\"Lora\", \"Merriweather\", Georgia, serif';\nconst JETBRAINS_MONO = '\"JetBrains Mono\", \"Fira Code\", Consolas, monospace';\nconst IBM_PLEX_SANS = '\"IBM Plex Sans\", \"Segoe UI\", Roboto, sans-serif';\nconst DM_SERIF = '\"DM Serif Display\", Georgia, serif';\nconst DM_SANS = '\"DM Sans\", \"Segoe UI\", Roboto, sans-serif';\nconst CORMORANT = '\"Cormorant Garamond\", Garamond, Georgia, serif';\nconst CRIMSON = '\"Crimson Text\", Georgia, serif';\nconst PT_SERIF = '\"PT Serif\", Georgia, serif';\nconst HANKEN_GROTESK = '\"Hanken Grotesk\", system-ui, sans-serif';\n\n/** Standard 6-scheme set used by the documentary theme (migrated from old COLOR_SCHEMES). */\nconst CLASSIC_COLOR_SCHEMES: Record<string, ThemeColorScheme> = {\n blue: { bg: '#1a365d', text: '#63b3ed', accent: '#90cdf4' },\n green: { bg: '#22543d', text: '#9ae6b4', accent: '#68d391' },\n purple: { bg: '#44337a', text: '#d6bcfa', accent: '#b794f4' },\n red: { bg: '#742a2a', text: '#fc8181', accent: '#feb2b2' },\n orange: { bg: '#744210', text: '#fbd38d', accent: '#f6ad55' },\n teal: { bg: '#234e52', text: '#81e6d9', accent: '#4fd1c5' },\n};\n\n// ============================================\n// 1. Standard (default — safe system fonts, no external dependencies)\n// ============================================\n\nconst standard: Theme = {\n id: 'standard',\n name: 'Standard',\n description: 'Clean and safe. System fonts only — no external font dependencies.',\n colors: {\n primary: '#3182ce',\n secondary: '#4a5568',\n background: '#1a202c',\n backgroundLight: '#2d3748',\n text: '#f7fafc',\n textMuted: '#a0aec0',\n highlight: '#4299e1',\n warning: '#fc8181',\n },\n typography: {\n bodyFontFamily: SYSTEM_SANS,\n titleFontFamily: SYSTEM_SERIF,\n monoFontFamily: SYSTEM_MONO,\n titleWeight: 'bold',\n },\n style: {\n textShadow: true,\n overlayOpacity: 0.45,\n animationSpeed: 1.0,\n },\n renderStyle: {\n name: 'standard',\n defaultTextAnimation: 'fadeIn',\n defaultImageAnimation: 'slowZoom',\n ambientMotion: true,\n defaultTransition: { type: 'fade', duration: 0.7 },\n },\n colorSchemes: CLASSIC_COLOR_SCHEMES,\n persistentLayers: {\n bottomLayers: [\n {\n template: 'gradientBackground',\n config: { type: 'gradientBackground', preset: 'dark-vignette' },\n },\n ],\n },\n};\n\n// ============================================\n// 2. Documentary\n// ============================================\n\nconst documentary: Theme = {\n id: 'documentary',\n name: 'Documentary',\n description: 'Classic dark cinematic look with elegant serif typography.',\n colors: {\n primary: '#3d5a80',\n secondary: '#63b3ed',\n background: '#1a202c',\n backgroundLight: '#2d3748',\n text: '#ffffff',\n textMuted: '#a0aec0',\n highlight: '#63b3ed',\n warning: '#fc8181',\n },\n typography: {\n bodyFontFamily: SOURCE_SERIF,\n titleFontFamily: PLAYFAIR,\n titleWeight: 'bold',\n },\n style: {\n textShadow: true,\n overlayOpacity: 0.5,\n animationSpeed: 1.0,\n },\n renderStyle: {\n name: 'documentary',\n defaultTextAnimation: 'fadeIn',\n defaultImageAnimation: 'slowZoom',\n ambientMotion: true,\n defaultTransition: { type: 'fade', duration: 0.8 },\n },\n colorSchemes: CLASSIC_COLOR_SCHEMES,\n persistentLayers: {\n bottomLayers: [\n {\n template: 'gradientBackground',\n config: { type: 'gradientBackground', preset: 'dark-vignette' },\n },\n ],\n },\n};\n\n// ============================================\n// 2. Minimalist\n// ============================================\n\nconst minimalist: Theme = {\n id: 'minimalist',\n name: 'Minimalist',\n description: 'Clean near-white background with sans-serif type and minimal animation.',\n colors: {\n primary: '#2d3748',\n secondary: '#4a5568',\n background: '#f7fafc',\n backgroundLight: '#edf2f7',\n text: '#1a202c',\n textMuted: '#718096',\n highlight: '#3182ce',\n warning: '#e53e3e',\n },\n typography: {\n bodyFontFamily: INTER,\n titleFontFamily: INTER,\n titleWeight: 'bold',\n lineHeight: 1.6,\n },\n style: {\n textShadow: false,\n overlayOpacity: 0.3,\n animationSpeed: 1.2,\n borderRadius: 8,\n },\n renderStyle: {\n name: 'minimalist',\n defaultTextAnimation: 'fadeIn',\n ambientMotion: false,\n defaultTransition: { type: 'fade', duration: 0.6 },\n templateHints: {\n titleBlock: { showAccentLine: false },\n },\n },\n colorSchemes: {\n blue: { bg: '#ebf8ff', text: '#2b6cb0', accent: '#3182ce' },\n green: { bg: '#f0fff4', text: '#276749', accent: '#38a169' },\n purple: { bg: '#faf5ff', text: '#553c9a', accent: '#805ad5' },\n red: { bg: '#fff5f5', text: '#c53030', accent: '#e53e3e' },\n orange: { bg: '#fffaf0', text: '#c05621', accent: '#dd6b20' },\n teal: { bg: '#e6fffa', text: '#285e61', accent: '#319795' },\n },\n};\n\n// ============================================\n// 3. Bold\n// ============================================\n\nconst bold: Theme = {\n id: 'bold',\n name: 'Bold',\n description: 'High-contrast black with vivid accents and dramatic animations.',\n colors: {\n primary: '#e53e3e',\n secondary: '#ed8936',\n background: '#000000',\n backgroundLight: '#1a1a1a',\n text: '#ffffff',\n textMuted: '#cbd5e0',\n highlight: '#f6e05e',\n warning: '#fc8181',\n },\n typography: {\n bodyFontFamily: ROBOTO,\n titleFontFamily: OSWALD,\n titleWeight: 'bold',\n titleScale: 1.15,\n bodyScale: 1.0,\n titleLineHeight: 1.1,\n },\n style: {\n textShadow: true,\n overlayOpacity: 0.6,\n animationSpeed: 0.8,\n },\n renderStyle: {\n name: 'bold',\n defaultTextAnimation: 'zoomIn',\n defaultImageAnimation: 'slowZoom',\n ambientMotion: true,\n defaultTransition: { type: 'dissolve', duration: 0.5 },\n templateHints: {\n statHighlight: { entrance: 'dramatic' },\n fullBleedQuote: { entrance: 'dramatic' },\n },\n },\n colorSchemes: {\n blue: { bg: '#1a202c', text: '#63b3ed', accent: '#90cdf4' },\n green: { bg: '#1a202c', text: '#48bb78', accent: '#68d391' },\n purple: { bg: '#1a202c', text: '#b794f4', accent: '#d6bcfa' },\n red: { bg: '#1a202c', text: '#fc8181', accent: '#feb2b2' },\n orange: { bg: '#1a202c', text: '#f6ad55', accent: '#fbd38d' },\n teal: { bg: '#1a202c', text: '#4fd1c5', accent: '#81e6d9' },\n },\n};\n\n// ============================================\n// 4. Morning Light\n// ============================================\n\nconst morningLight: Theme = {\n id: 'morning-light',\n name: 'Morning Light',\n description: 'Warm light background with dark text and gentle serif typography.',\n colors: {\n primary: '#744210',\n secondary: '#975a16',\n background: '#faf8f5',\n backgroundLight: '#f5f0eb',\n text: '#2d3748',\n textMuted: '#718096',\n highlight: '#dd6b20',\n warning: '#c53030',\n },\n typography: {\n bodyFontFamily: LORA,\n titleFontFamily: MERRIWEATHER,\n titleWeight: 'bold',\n lineHeight: 1.7,\n },\n style: {\n textShadow: false,\n overlayOpacity: 0.35,\n animationSpeed: 1.1,\n borderRadius: 4,\n },\n renderStyle: {\n name: 'morning-light',\n defaultTextAnimation: 'fadeIn',\n ambientMotion: false,\n defaultTransition: { type: 'fade', duration: 1.0 },\n },\n colorSchemes: {\n blue: { bg: '#ebf8ff', text: '#2c5282', accent: '#4299e1' },\n green: { bg: '#f0fff4', text: '#22543d', accent: '#48bb78' },\n purple: { bg: '#faf5ff', text: '#44337a', accent: '#9f7aea' },\n red: { bg: '#fff5f5', text: '#9b2c2c', accent: '#fc8181' },\n orange: { bg: '#fffaf0', text: '#744210', accent: '#ed8936' },\n teal: { bg: '#e6fffa', text: '#234e52', accent: '#38b2ac' },\n },\n};\n\n// ============================================\n// 5. Tech Dark\n// ============================================\n\nconst techDark: Theme = {\n id: 'tech-dark',\n name: 'Tech Dark',\n description: 'True black with neon cyan/green accents and monospace titles.',\n colors: {\n primary: '#00e5ff',\n secondary: '#00e676',\n background: '#0a0a0a',\n backgroundLight: '#1a1a2e',\n text: '#e0e0e0',\n textMuted: '#9e9e9e',\n highlight: '#00e5ff',\n warning: '#ff5252',\n },\n typography: {\n bodyFontFamily: IBM_PLEX_SANS,\n titleFontFamily: JETBRAINS_MONO,\n monoFontFamily: JETBRAINS_MONO,\n titleWeight: 'bold',\n titleScale: 0.9,\n lineHeight: 1.5,\n },\n style: {\n textShadow: true,\n overlayOpacity: 0.55,\n animationSpeed: 0.9,\n borderRadius: 2,\n },\n renderStyle: {\n name: 'tech-dark',\n defaultTextAnimation: 'typewriter',\n defaultImageAnimation: 'slowZoom',\n ambientMotion: true,\n defaultTransition: { type: 'dissolve', duration: 0.4 },\n templateHints: {\n statHighlight: { entrance: 'dramatic' },\n },\n },\n colorSchemes: {\n blue: { bg: '#0d1b2a', text: '#00b0ff', accent: '#40c4ff' },\n green: { bg: '#0d1b0d', text: '#00e676', accent: '#69f0ae' },\n purple: { bg: '#1a0d2e', text: '#d500f9', accent: '#ea80fc' },\n red: { bg: '#2e0d0d', text: '#ff5252', accent: '#ff8a80' },\n orange: { bg: '#2e1a0d', text: '#ff9100', accent: '#ffab40' },\n teal: { bg: '#0d2e2e', text: '#1de9b6', accent: '#64ffda' },\n },\n};\n\n// ============================================\n// 6. Magazine\n// ============================================\n\nconst magazine: Theme = {\n id: 'magazine',\n name: 'Magazine',\n description: 'Rich editorial palette with mixed serif/sans typography and slide transitions.',\n colors: {\n primary: '#c53030',\n secondary: '#2b6cb0',\n background: '#1a202c',\n backgroundLight: '#2d3748',\n text: '#f7fafc',\n textMuted: '#cbd5e0',\n highlight: '#ed8936',\n warning: '#fc8181',\n },\n typography: {\n bodyFontFamily: DM_SANS,\n titleFontFamily: DM_SERIF,\n titleWeight: 'bold',\n titleScale: 1.05,\n lineHeight: 1.5,\n },\n style: {\n textShadow: true,\n overlayOpacity: 0.45,\n animationSpeed: 1.0,\n borderRadius: 6,\n },\n renderStyle: {\n name: 'magazine',\n defaultTextAnimation: 'fadeIn',\n defaultImageAnimation: 'slowZoom',\n ambientMotion: true,\n defaultTransition: { type: 'slideLeft', duration: 0.7 },\n },\n colorSchemes: {\n blue: { bg: '#1a365d', text: '#90cdf4', accent: '#63b3ed' },\n green: { bg: '#1c4532', text: '#9ae6b4', accent: '#68d391' },\n purple: { bg: '#322659', text: '#d6bcfa', accent: '#b794f4' },\n red: { bg: '#63171b', text: '#feb2b2', accent: '#fc8181' },\n orange: { bg: '#652b19', text: '#fbd38d', accent: '#f6ad55' },\n teal: { bg: '#1d4044', text: '#81e6d9', accent: '#4fd1c5' },\n },\n};\n\n// ============================================\n// 7. Cinematic\n// ============================================\n\nconst cinematic: Theme = {\n id: 'cinematic',\n name: 'Cinematic',\n description: 'Ultra-dark with moody gradients, gold accents, and slow dissolve transitions.',\n colors: {\n primary: '#d69e2e',\n secondary: '#b7791f',\n background: '#0a0f1a',\n backgroundLight: '#1a202c',\n text: '#f7fafc',\n textMuted: '#a0aec0',\n highlight: '#ecc94b',\n warning: '#fc8181',\n },\n typography: {\n bodyFontFamily: CRIMSON,\n titleFontFamily: CORMORANT,\n titleWeight: 'bold',\n lineHeight: 1.5,\n titleLineHeight: 1.2,\n },\n style: {\n textShadow: true,\n overlayOpacity: 0.55,\n animationSpeed: 1.2,\n },\n renderStyle: {\n name: 'cinematic',\n defaultTextAnimation: 'fadeIn',\n defaultImageAnimation: 'slowZoom',\n ambientMotion: true,\n defaultTransition: { type: 'dissolve', duration: 1.2 },\n templateHints: {\n titleBlock: { showAccentLine: true },\n },\n },\n colorSchemes: {\n blue: { bg: '#0d1b2a', text: '#90cdf4', accent: '#63b3ed' },\n green: { bg: '#0d1b14', text: '#9ae6b4', accent: '#68d391' },\n purple: { bg: '#1a0d2e', text: '#d6bcfa', accent: '#b794f4' },\n red: { bg: '#2a0d0d', text: '#fc8181', accent: '#feb2b2' },\n orange: { bg: '#2a1a0d', text: '#fbd38d', accent: '#f6ad55' },\n teal: { bg: '#0d2a2a', text: '#81e6d9', accent: '#4fd1c5' },\n },\n persistentLayers: {\n bottomLayers: [\n {\n template: 'gradientBackground',\n config: { type: 'gradientBackground', preset: 'radial-dark' },\n },\n ],\n },\n};\n\n// ============================================\n// 8. Warm Earth\n// ============================================\n\nconst warmEarth: Theme = {\n id: 'warm-earth',\n name: 'Warm Earth',\n description: 'Natural warm tones with earthy browns and terracotta accents.',\n colors: {\n primary: '#9c4221',\n secondary: '#c05621',\n background: '#1c1410',\n backgroundLight: '#2d241e',\n text: '#faf5f0',\n textMuted: '#c4a882',\n highlight: '#dd6b20',\n warning: '#e53e3e',\n },\n typography: {\n bodyFontFamily: HANKEN_GROTESK,\n titleFontFamily: PT_SERIF,\n titleWeight: 'bold',\n lineHeight: 1.6,\n },\n style: {\n textShadow: true,\n overlayOpacity: 0.5,\n animationSpeed: 1.1,\n },\n renderStyle: {\n name: 'warm-earth',\n defaultTextAnimation: 'fadeIn',\n defaultImageAnimation: 'panLeft',\n ambientMotion: true,\n defaultTransition: { type: 'fade', duration: 0.9 },\n },\n colorSchemes: {\n blue: { bg: '#2a1f14', text: '#90cdf4', accent: '#63b3ed' },\n green: { bg: '#1e2a14', text: '#9ae6b4', accent: '#68d391' },\n purple: { bg: '#2a142a', text: '#d6bcfa', accent: '#b794f4' },\n red: { bg: '#2a1414', text: '#fc8181', accent: '#feb2b2' },\n orange: { bg: '#2a1e0a', text: '#fbd38d', accent: '#f6ad55' },\n teal: { bg: '#142a28', text: '#81e6d9', accent: '#4fd1c5' },\n },\n persistentLayers: {\n bottomLayers: [\n {\n template: 'gradientBackground',\n config: { type: 'gradientBackground', preset: 'earth-tones' },\n },\n ],\n },\n};\n\n// ============================================\n// Theme Library\n// ============================================\n\n/**\n * All built-in themes, keyed by id.\n */\nexport const THEMES: Record<string, Theme> = {\n standard,\n documentary,\n minimalist,\n bold,\n 'morning-light': morningLight,\n 'tech-dark': techDark,\n magazine,\n cinematic,\n 'warm-earth': warmEarth,\n};\n\n/** The default theme id. */\nexport const DEFAULT_THEME_ID = 'standard';\n\n/** The default theme (standard — safe system fonts, no external dependencies). */\nexport const DEFAULT_THEME: Theme = standard;\n\n/**\n * Resolve a theme by id. Returns the default theme when `id` is\n * undefined or not found in the library.\n */\nexport function resolveTheme(id: string | undefined): Theme {\n if (id && id in THEMES) return THEMES[id];\n return DEFAULT_THEME;\n}\n\n/**\n * Get all available theme ids.\n */\nexport function getAvailableThemes(): string[] {\n return Object.keys(THEMES);\n}\n\n/**\n * Get a summary of all themes (id + name + description) for theme pickers.\n */\nexport function getThemeSummaries(): Array<{ id: string; name: string; description?: string }> {\n return Object.values(THEMES).map((t) => ({\n id: t.id,\n name: t.name,\n description: t.description,\n }));\n}\n","/**\n * Viewport Configuration\n *\n * Defines viewport dimensions for doc rendering across different aspect ratios.\n * Templates use this configuration to adapt their layouts appropriately.\n *\n * Supported aspect ratios:\n * - landscape (16:9) - Default, standard video/presentation format\n * - portrait (9:16) - Vertical video, mobile stories\n * - square (1:1) - Social media posts\n * - standard (4:3) - Legacy presentation format\n */\n\n/**\n * Viewport configuration for doc rendering.\n */\nexport interface ViewportConfig {\n /** Canonical width in virtual pixels */\n width: number;\n /** Canonical height in virtual pixels */\n height: number;\n /** Human-readable name for debugging/display */\n name: string;\n}\n\n/**\n * Standard viewport presets for common aspect ratios.\n */\nexport const VIEWPORT_PRESETS = {\n /** 16:9 landscape (default, 1080p) */\n landscape: { width: 1920, height: 1080, name: '16:9 Landscape' },\n /** 9:16 portrait (vertical video, stories) */\n portrait: { width: 1080, height: 1920, name: '9:16 Portrait' },\n /** 1:1 square (social media) */\n square: { width: 1080, height: 1080, name: '1:1 Square' },\n /** 4:3 standard (legacy) */\n standard: { width: 1440, height: 1080, name: '4:3 Standard' },\n} as const;\n\n/**\n * Viewport preset name.\n */\nexport type ViewportPreset = keyof typeof VIEWPORT_PRESETS;\n\n/**\n * Viewport orientation derived from aspect ratio.\n */\nexport type ViewportOrientation = 'landscape' | 'portrait' | 'square';\n\n/**\n * Get a viewport configuration from a preset name or return the config if already a ViewportConfig.\n */\nexport function getViewport(viewport: ViewportPreset | ViewportConfig): ViewportConfig {\n if (typeof viewport === 'string') {\n return VIEWPORT_PRESETS[viewport];\n }\n return viewport;\n}\n\n/**\n * Calculate font scale factor for a viewport.\n * Based on diagonal pixels relative to 1080p landscape reference.\n * This ensures text remains readable across different viewport sizes.\n */\nconst REFERENCE_DIAGONAL = Math.sqrt(1920 * 1920 + 1080 * 1080); // ~2203\n\nexport function calculateFontScale(viewport: ViewportConfig): number {\n const currentDiagonal = Math.sqrt(\n viewport.width * viewport.width + viewport.height * viewport.height,\n );\n return currentDiagonal / REFERENCE_DIAGONAL;\n}\n\n/**\n * Determine if viewport is landscape, portrait, or square.\n */\nexport function getViewportOrientation(viewport: ViewportConfig): ViewportOrientation {\n const ratio = viewport.width / viewport.height;\n // Allow small tolerance for \"square\" classification\n if (Math.abs(ratio - 1) < 0.05) return 'square';\n return ratio > 1 ? 'landscape' : 'portrait';\n}\n\n/**\n * Get aspect ratio as a string (e.g., \"16:9\", \"9:16\", \"1:1\").\n */\nexport function getAspectRatioString(viewport: ViewportConfig): string {\n const gcd = (a: number, b: number): number => (b === 0 ? a : gcd(b, a % b));\n const divisor = gcd(viewport.width, viewport.height);\n return `${viewport.width / divisor}:${viewport.height / divisor}`;\n}\n","/**\n * Layout Strategy\n *\n * Provides orientation-specific layout hints for slide templates.\n * Templates use these hints to position content appropriately for\n * different aspect ratios (landscape, portrait, square).\n *\n * Key adaptations by orientation:\n * - Portrait: Larger relative text, stacked layouts instead of side-by-side\n * - Square: Balanced layout with moderate adjustments\n * - Landscape: Default/reference layout\n */\n\nimport type { ViewportOrientation, ViewportConfig } from './Viewport.js';\nimport { calculateFontScale } from './Viewport.js';\n\n/**\n * Layout hints for template positioning based on orientation.\n */\nexport interface LayoutHints {\n /** Primary content Y position (percentage string, e.g., \"35%\") */\n primaryY: string;\n /** Secondary content Y position (percentage string) */\n secondaryY: string;\n /** Tertiary/detail Y position (percentage string) */\n tertiaryY: string;\n /** Title font size multiplier (relative to base) */\n titleScale: number;\n /** Body text font size multiplier (relative to base) */\n bodyScale: number;\n /** Two-column: left X position (percentage string) */\n columnLeftX: string;\n /** Two-column: right X position (percentage string) */\n columnRightX: string;\n /** Two-column in portrait: top Y position for stacked layout */\n columnTopY: string;\n /** Two-column in portrait: bottom Y position for stacked layout */\n columnBottomY: string;\n /** Whether two-column should stack vertically */\n stackColumns: boolean;\n /** Max text width (percentage string) for wrapping */\n maxTextWidth: string;\n /** Horizontal padding from edges (percentage string) */\n horizontalPadding: string;\n /** Caption position Y for imageWithCaption (percentage string) */\n captionY: string;\n /** Caption font size multiplier */\n captionScale: number;\n}\n\n/**\n * Layout configurations by orientation.\n */\nconst LAYOUT_CONFIGS: Record<ViewportOrientation, LayoutHints> = {\n landscape: {\n primaryY: '35%',\n secondaryY: '55%',\n tertiaryY: '75%',\n titleScale: 1.0,\n bodyScale: 1.0,\n columnLeftX: '25%',\n columnRightX: '75%',\n columnTopY: '35%',\n columnBottomY: '65%',\n stackColumns: false,\n maxTextWidth: '80%',\n horizontalPadding: '10%',\n captionY: '85%',\n captionScale: 1.0,\n },\n portrait: {\n // Content positioned higher for thumb-reach zone on mobile\n primaryY: '25%',\n secondaryY: '42%',\n tertiaryY: '58%',\n // Titles scale down for narrower width; body text scales up to fill vertical space\n titleScale: 0.7,\n bodyScale: 1.5,\n // Stacked columns instead of side-by-side\n columnLeftX: '50%',\n columnRightX: '50%',\n columnTopY: '30%',\n columnBottomY: '55%',\n stackColumns: true,\n // Wider relative to viewport to use available space\n maxTextWidth: '90%',\n horizontalPadding: '5%',\n captionY: '75%',\n captionScale: 0.85,\n },\n square: {\n primaryY: '30%',\n secondaryY: '50%',\n tertiaryY: '70%',\n titleScale: 0.85,\n bodyScale: 0.9,\n columnLeftX: '25%',\n columnRightX: '75%',\n columnTopY: '35%',\n columnBottomY: '65%',\n stackColumns: false,\n maxTextWidth: '85%',\n horizontalPadding: '7.5%',\n captionY: '82%',\n captionScale: 0.9,\n },\n};\n\n/**\n * Get layout hints for a given orientation.\n */\nexport function getLayoutHints(orientation: ViewportOrientation): LayoutHints {\n return LAYOUT_CONFIGS[orientation];\n}\n\n/**\n * Calculate a scaled font size based on viewport and layout hints.\n *\n * @param basePx - Base font size in pixels (designed for 1920x1080)\n * @param viewport - Target viewport configuration\n * @param orientation - Viewport orientation\n * @param isTitle - Whether this is title text (uses titleScale) or body (uses bodyScale)\n */\nexport function scaledFontSize(\n basePx: number,\n viewport: ViewportConfig,\n orientation: ViewportOrientation,\n isTitle: boolean = false,\n): number {\n const fontScale = calculateFontScale(viewport);\n const layout = getLayoutHints(orientation);\n const typeScale = isTitle ? layout.titleScale : layout.bodyScale;\n return Math.round(basePx * fontScale * typeScale);\n}\n\n/**\n * Get position for two-column layout based on orientation.\n * Returns { left: {x, y}, right: {x, y} } positions.\n */\nexport function getTwoColumnPositions(orientation: ViewportOrientation): {\n left: { x: string; y: string };\n right: { x: string; y: string };\n} {\n const layout = getLayoutHints(orientation);\n\n if (layout.stackColumns) {\n // Portrait: stack vertically\n return {\n left: { x: '50%', y: layout.columnTopY },\n right: { x: '50%', y: layout.columnBottomY },\n };\n }\n\n // Landscape/square: side by side\n return {\n left: { x: layout.columnLeftX, y: '50%' },\n right: { x: layout.columnRightX, y: '50%' },\n };\n}\n\n/**\n * Get safe text bounds for a given orientation.\n * Returns margins to keep text away from edges.\n */\nexport function getSafeTextBounds(orientation: ViewportOrientation): {\n left: string;\n right: string;\n top: string;\n bottom: string;\n} {\n const layout = getLayoutHints(orientation);\n return {\n left: layout.horizontalPadding,\n right: layout.horizontalPadding,\n top: '10%',\n bottom: '10%',\n };\n}\n","/**\n * Block Templates Schema\n *\n * Defines a template system for AI-generated doc blocks. Instead of\n * specifying low-level layers, positions, and animations, AI can use\n * high-level templates like \"titleBlock\" or \"statHighlight\" with simple\n * content parameters.\n *\n * Templates are expanded into full Block structures at render time,\n * ensuring consistent styling and reducing AI generation errors.\n *\n * Template Types:\n * - titleBlock: Doc intro with title + subtitle\n * - sectionHeader: Colored section divider\n * - statHighlight: Big number/stat with description\n * - quoteBlock: Large centered quote\n * - factCard: Key fact with explanation\n * - twoColumn: Side-by-side comparison\n * - dateEvent: Timeline-style date + description\n * - imageWithCaption: Image with text overlay\n */\n\nimport type { Layer, Block, Transition, MapTileStyle, MapMarker } from './Doc.js';\nimport type { ViewportConfig, ViewportOrientation } from './Viewport.js';\nimport type { LayoutHints } from './LayoutStrategy.js';\nimport type { Theme } from './Theme.js';\nimport { VIEWPORT_PRESETS, getViewportOrientation, calculateFontScale } from './Viewport.js';\nimport { getLayoutHints, scaledFontSize as scaleFontSize } from './LayoutStrategy.js';\n\n/**\n * Name of a color scheme defined in the active theme's `colorSchemes` map.\n * Templates reference schemes by name (e.g. 'blue', 'green') and the theme\n * resolves them to actual colors at render time via `resolveColorScheme()`.\n */\nexport type ColorScheme = string;\n\n/**\n * Default font family for doc text.\n * PT Serif provides a classic, readable appearance for documentary-style content.\n * Used as a fallback in TextLayer when no font is specified.\n */\nexport const DEFAULT_DOC_FONT = 'system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif';\n\n/**\n * Default font family for titles.\n */\nexport const DEFAULT_TITLE_FONT = 'Georgia, \"Times New Roman\", serif';\n\n// ============================================\n// Accent Image System\n// ============================================\n\n/**\n * Position options for accent images on text-based blocks.\n * Accents are tasteful image additions that complement rather than overwhelm text.\n */\nexport type AccentPosition =\n | 'left-strip' // Vertical strip on left (25-30% width), text shifts right\n | 'right-strip' // Vertical strip on right (25-30% width), text shifts left\n | 'bottom-strip' // Horizontal strip at bottom (25-30% height), text shifts up\n | 'corner-inset'; // Small inset image in corner with vignette edge\n\n/**\n * Accent image configuration for text-based blocks.\n * When present, the template adjusts layout to accommodate the image tastefully.\n */\nexport interface AccentImage {\n /** Path to image file (relative to article media dir) */\n src: string;\n /** Alt text for accessibility */\n alt: string;\n /** Where to position the accent image */\n position: AccentPosition;\n /** Ambient motion effect (subtle Ken Burns) */\n ambientMotion?: 'zoomIn' | 'zoomOut' | 'panLeft' | 'panRight';\n /** Photo credit / artist name */\n credit?: string;\n /** License identifier (e.g., 'CC BY-SA 4.0') */\n license?: string;\n}\n\n// ============================================\n// Template Input Types\n// ============================================\n\n/**\n * Base properties shared by all template blocks.\n */\ninterface BaseTemplateBlock {\n /** Unique block ID */\n id: string;\n /** Block duration in seconds */\n duration: number;\n /** Which audio segment this block belongs to */\n audioSegment: number;\n /** Entry transition */\n transition?: Transition;\n /** Show doc's bottom layers (default: true) */\n useBottomLayer?: boolean;\n /** Show doc's top layers (default: true) */\n useTopLayer?: boolean;\n /**\n * Start time within the audio segment when this content is spoken.\n * Used to sync the block appearance with the narration.\n * If not provided, blocks are distributed evenly across the segment.\n */\n sourceStartTime?: number;\n /**\n * Duration of the spoken content this block represents.\n * Used with sourceStartTime to precisely position the block.\n */\n sourceDuration?: number;\n}\n\n/**\n * Title block - doc intro with large title and subtitle.\n */\nexport interface TitleBlockInput extends BaseTemplateBlock {\n template: 'titleBlock';\n /** Main title text */\n title: string;\n /** Subtitle or tagline (supports \\n for line breaks) */\n subtitle?: string;\n /** Background color (defaults to theme primary) */\n backgroundColor?: string;\n}\n\n/**\n * Section header - section title card with optional background image.\n * Displays the section title prominently, optionally over an image.\n */\nexport interface SectionHeaderInput extends BaseTemplateBlock {\n template: 'sectionHeader';\n /** Section title */\n title: string;\n /** Color scheme for the section (used for fallback background) */\n colorScheme?: ColorScheme;\n /** Optional background image path */\n imageSrc?: string;\n /** Alt text for background image */\n imageAlt?: string;\n /** Ambient motion for background image */\n ambientMotion?: 'zoomIn' | 'zoomOut' | 'panLeft' | 'panRight';\n}\n\n/**\n * Stat highlight - big number with description and optional detail.\n */\nexport interface StatHighlightInput extends BaseTemplateBlock {\n template: 'statHighlight';\n /** The statistic (e.g., \"89%\", \"2x\", \"7 miles\") */\n stat: string;\n /** Description of what the stat means */\n description: string;\n /** Additional detail or context */\n detail?: string;\n /** Color scheme for the stat */\n colorScheme?: ColorScheme;\n /** Optional accent image to complement the text */\n accentImage?: AccentImage;\n}\n\n/**\n * Quote block - large centered quote text.\n */\nexport interface QuoteBlockInput extends BaseTemplateBlock {\n template: 'quoteBlock';\n /** The quote text (supports \\n for line breaks) */\n quote: string;\n /** Attribution (author, source) */\n attribution?: string;\n /** Optional accent image to complement the text */\n accentImage?: AccentImage;\n}\n\n/**\n * Fact card - key fact with explanation.\n */\nexport interface FactCardInput extends BaseTemplateBlock {\n template: 'factCard';\n /** The main fact or statement */\n fact: string;\n /** Explanation or context */\n explanation: string;\n /** Optional source citation */\n source?: string;\n /** Optional accent image to complement the text */\n accentImage?: AccentImage;\n}\n\n/**\n * Two column - side-by-side comparison.\n */\nexport interface TwoColumnInput extends BaseTemplateBlock {\n template: 'twoColumn';\n /** Left column content */\n left: {\n label: string;\n sublabel?: string;\n };\n /** Right column content */\n right: {\n label: string;\n sublabel?: string;\n };\n /** Optional header above columns */\n header?: string;\n /** Color schemes for left and right */\n leftColor?: ColorScheme;\n rightColor?: ColorScheme;\n}\n\n/**\n * Date event - timeline-style date with description.\n */\nexport interface DateEventInput extends BaseTemplateBlock {\n template: 'dateEvent';\n /** The date (e.g., \"July 14, 1974\") */\n date: string;\n /** Description of what happened (supports \\n) */\n description: string;\n /** Optional footer text */\n footer?: string;\n /** Mood: 'neutral', 'somber', 'celebratory' */\n mood?: 'neutral' | 'somber' | 'celebratory';\n /** Optional accent image to complement the text */\n accentImage?: AccentImage;\n}\n\n/**\n * Image with caption - background image with text overlay.\n */\nexport interface ImageWithCaptionInput extends BaseTemplateBlock {\n template: 'imageWithCaption';\n /** Path to image file */\n imageSrc: string;\n /** Alt text for accessibility */\n imageAlt: string;\n /** Caption text */\n caption?: string;\n /** Caption position */\n captionPosition?: 'bottom' | 'top' | 'center';\n /** Ambient motion effect: slow zoom or pan for visual interest */\n ambientMotion?: 'zoomIn' | 'zoomOut' | 'panLeft' | 'panRight';\n /** When true, style caption as a title (larger, centered, prominent) */\n isTitle?: boolean;\n /** Optional subtitle shown below the title (only when isTitle is true) */\n subtitle?: string;\n /** Photo credit / artist name */\n imageCredit?: string;\n /** License identifier (e.g., 'CC BY-SA 4.0') */\n imageLicense?: string;\n}\n\n/**\n * Map block - geographic map showing article location.\n *\n * Displays a map centered on given coordinates with optional title,\n * caption, and markers. Great for establishing geographic context.\n * See docs/MAP_TILES.md for available tile styles and attribution.\n */\nexport interface MapBlockInput extends BaseTemplateBlock {\n template: 'mapBlock';\n /** Map center coordinates */\n center: {\n lat: number;\n lng: number;\n };\n /** Zoom level (4-16, typically 8-12 for regional context) */\n zoom: number;\n /** Map tile style (default: 'terrain') */\n mapStyle?: MapTileStyle;\n /** Optional title overlay at top */\n title?: string;\n /** Optional caption at bottom */\n caption?: string;\n /** Optional markers to show on map */\n markers?: MapMarker[];\n /** Ambient motion effect: slow zoom or pan for visual interest */\n ambientMotion?: 'zoomIn' | 'zoomOut' | 'panLeft' | 'panRight';\n /** Pre-rendered static image path (set by prerender-maps command) */\n staticSrc?: string;\n}\n\n/**\n * Full-bleed quote - dramatic short text filling the viewport.\n * Like a movie title card. For short, punchy sentences < 60 chars.\n */\nexport interface FullBleedQuoteInput extends BaseTemplateBlock {\n template: 'fullBleedQuote';\n /** Short dramatic text (< 60 chars recommended) */\n text: string;\n /** Color scheme for text tint */\n colorScheme?: ColorScheme;\n}\n\n/**\n * List block - 3-5 items stacked vertically with subtle numbering.\n * Good for enumerations like \"things to see\" or \"key features\".\n */\nexport interface ListBlockInput extends BaseTemplateBlock {\n template: 'listBlock';\n /** List items (3-5 recommended) */\n items: string[];\n /** Optional header above the list */\n title?: string;\n /** Color scheme for numbering accents */\n colorScheme?: ColorScheme;\n /** Optional accent image */\n accentImage?: AccentImage;\n}\n\n/**\n * Photo grid - 2-4 images in a tiled layout.\n * Used when multiple images are available for visual variety.\n */\nexport interface PhotoGridInput extends BaseTemplateBlock {\n template: 'photoGrid';\n /** Images to display (2-4) */\n images: { src: string; alt: string; credit?: string; license?: string }[];\n /** Optional caption below the grid */\n caption?: string;\n /** Ambient motion effect for the largest image */\n ambientMotion?: 'zoomIn' | 'zoomOut' | 'panLeft' | 'panRight';\n}\n\n/**\n * Definition card - dictionary-style term with definition.\n * Large term at top, definition below, optional origin note.\n */\nexport interface DefinitionCardInput extends BaseTemplateBlock {\n template: 'definitionCard';\n /** The term being defined */\n term: string;\n /** The definition text */\n definition: string;\n /** Optional etymology or origin note */\n origin?: string;\n /** Color scheme for term accent */\n colorScheme?: ColorScheme;\n /** Optional accent image */\n accentImage?: AccentImage;\n}\n\n/**\n * Comparison bar - two horizontal bars showing relative numeric values.\n * Good for side-by-side numeric comparisons with visual weight.\n */\nexport interface ComparisonBarInput extends BaseTemplateBlock {\n template: 'comparisonBar';\n /** Left bar label */\n leftLabel: string;\n /** Left bar numeric value */\n leftValue: number;\n /** Right bar label */\n rightLabel: string;\n /** Right bar numeric value */\n rightValue: number;\n /** Unit label (e.g., \"km\", \"people\") */\n unit?: string;\n /** Color scheme */\n colorScheme?: ColorScheme;\n}\n\n/**\n * Pull quote - quote text over a full-bleed background image with dark overlay.\n * Cinematic alternative to quoteBlock when a high-quality image is available.\n */\nexport interface PullQuoteInput extends BaseTemplateBlock {\n template: 'pullQuote';\n /** Quote text */\n text: string;\n /** Optional attribution */\n attribution?: string;\n /** Background image (fills entire viewport) */\n backgroundImage: { src: string; alt: string; credit?: string; license?: string };\n /** Ambient motion for background image */\n ambientMotion?: 'zoomIn' | 'zoomOut' | 'panLeft' | 'panRight';\n}\n\n/**\n * Video with caption - background video clip with text overlay.\n * Plays a short clip from a source video, always muted (narration is the audio track).\n * Mirrors ImageWithCaptionInput but with video-specific fields.\n */\nexport interface VideoWithCaptionInput extends BaseTemplateBlock {\n template: 'videoWithCaption';\n /** Path to video file */\n videoSrc: string;\n /** Path to poster frame (shown before video loads) */\n posterSrc?: string;\n /** Alt text for accessibility */\n videoAlt: string;\n /** Start time within source video (seconds) */\n clipStart: number;\n /** End time within source video (seconds) */\n clipEnd: number;\n /** Source video total duration (for validation) */\n sourceDuration?: number;\n /** Caption text overlay */\n caption?: string;\n /** Caption position */\n captionPosition?: 'bottom' | 'top' | 'center';\n /** Video credit / artist name */\n videoCredit?: string;\n /** License identifier */\n videoLicense?: string;\n}\n\n/**\n * Video pull quote - quote text over a video clip background with dark overlay.\n * Cinematic alternative to pullQuote when a video clip is available.\n */\nexport interface VideoPullQuoteInput extends BaseTemplateBlock {\n template: 'videoPullQuote';\n /** Quote text */\n text: string;\n /** Optional attribution */\n attribution?: string;\n /** Background video clip */\n backgroundVideo: {\n src: string;\n posterSrc?: string;\n alt: string;\n clipStart: number;\n clipEnd: number;\n credit?: string;\n license?: string;\n };\n}\n\n/**\n * Union of all template block types.\n */\nexport type TemplateBlock =\n | TitleBlockInput\n | SectionHeaderInput\n | StatHighlightInput\n | QuoteBlockInput\n | FactCardInput\n | TwoColumnInput\n | DateEventInput\n | ImageWithCaptionInput\n | MapBlockInput\n | FullBleedQuoteInput\n | ListBlockInput\n | PhotoGridInput\n | DefinitionCardInput\n | ComparisonBarInput\n | PullQuoteInput\n | VideoWithCaptionInput\n | VideoPullQuoteInput;\n\n/**\n * A block can be either a raw Block or a TemplateBlock.\n */\nexport type DocBlock = Block | TemplateBlock;\n\n/**\n * Check if a block is a template block.\n */\nexport function isTemplateBlock(block: DocBlock): block is TemplateBlock {\n return 'template' in block && typeof block.template === 'string';\n}\n\n// ============================================\n// Template Function Type\n// ============================================\n\n/**\n * Template context passed to template functions.\n * Includes viewport information for multi-aspect ratio support.\n */\nexport interface TemplateContext {\n /** Full theme (colors, typography, style, renderStyle, colorSchemes) */\n theme: Theme;\n /** Block index in the doc */\n blockIndex: number;\n /** Total number of blocks */\n totalBlocks: number;\n /** Target viewport configuration */\n viewport: ViewportConfig;\n /** Computed font scale factor for this viewport */\n fontScale: number;\n /** Viewport orientation (landscape, portrait, square) */\n orientation: ViewportOrientation;\n /** Layout hints for this orientation */\n layout: LayoutHints;\n}\n\n/**\n * Create a template context with viewport-derived values.\n */\nexport function createTemplateContext(\n theme: Theme,\n blockIndex: number,\n totalBlocks: number,\n viewport: ViewportConfig = VIEWPORT_PRESETS.landscape,\n): TemplateContext {\n const orientation = getViewportOrientation(viewport);\n return {\n theme,\n blockIndex,\n totalBlocks,\n viewport,\n fontScale: calculateFontScale(viewport),\n orientation,\n layout: getLayoutHints(orientation),\n };\n}\n\n/**\n * Calculate a scaled font size for the given context.\n * Use this in templates to ensure text scales appropriately.\n *\n * @param basePx - Base font size in pixels (designed for 1920x1080)\n * @param context - Template context with viewport info\n * @param isTitle - Whether this is title text (larger scale) or body text\n */\nexport function scaledFontSize(\n basePx: number,\n context: TemplateContext,\n isTitle: boolean = false,\n): number {\n return scaleFontSize(basePx, context.viewport, context.orientation, isTitle);\n}\n\n/**\n * Template function signature.\n * Takes template input and returns layers array.\n */\nexport type TemplateFunction<T extends TemplateBlock> = (\n input: T,\n context: TemplateContext,\n) => Layer[];\n\n/**\n * Registry of all template functions.\n */\nexport type TemplateRegistry = {\n [K in TemplateBlock['template']]: TemplateFunction<Extract<TemplateBlock, { template: K }>>;\n};\n\n// ============================================\n// Persistent Layer System\n// ============================================\n\n/**\n * Configuration for persistent doc-wide layers.\n * Bottom layers render behind all block content, top layers on top.\n */\nexport interface PersistentLayerConfig {\n /** Layers rendered behind all block content */\n bottomLayers?: PersistentLayer[];\n /** Layers rendered on top of all block content */\n topLayers?: PersistentLayer[];\n}\n\n/**\n * A persistent layer - either a template or raw Layer.\n */\nexport type PersistentLayer = PersistentLayerTemplate | Layer;\n\n/**\n * Check if a persistent layer is a template.\n */\nexport function isPersistentLayerTemplate(\n layer: PersistentLayer,\n): layer is PersistentLayerTemplate {\n return 'template' in layer && typeof layer.template === 'string';\n}\n\n/**\n * Template-based persistent layer for easy configuration.\n */\nexport interface PersistentLayerTemplate {\n template: PersistentLayerTemplateType;\n config: PersistentLayerTemplateConfig;\n}\n\n/**\n * Available persistent layer template types.\n */\nexport type PersistentLayerTemplateType =\n | 'solidBackground' // Solid color fill\n | 'gradientBackground' // CSS gradient or preset\n | 'imageBackground' // Blurred/faded hero image\n | 'patternBackground' // Subtle pattern (dots, grid)\n | 'titleCaption' // Article title in corner\n | 'cornerBranding' // Logo or text badge\n | 'progressIndicator'; // Bar/dots showing position\n\n/**\n * Union of all persistent layer template configs.\n */\nexport type PersistentLayerTemplateConfig =\n | SolidBackgroundConfig\n | GradientBackgroundConfig\n | ImageBackgroundConfig\n | PatternBackgroundConfig\n | TitleCaptionConfig\n | CornerBrandingConfig\n | ProgressIndicatorConfig;\n\n// ============================================\n// Background Layer Configs\n// ============================================\n\n/**\n * Solid color background.\n */\nexport interface SolidBackgroundConfig {\n type: 'solidBackground';\n /** CSS color value */\n color: string;\n}\n\n/**\n * Gradient background (CSS gradient or preset).\n */\nexport interface GradientBackgroundConfig {\n type: 'gradientBackground';\n /** Custom CSS gradient string */\n gradient?: string;\n /** Preset gradient name */\n preset?: 'dark-vignette' | 'radial-dark' | 'warm-sunset' | 'cool-blue' | 'earth-tones';\n}\n\n/**\n * Image background (blurred/faded hero image).\n */\nexport interface ImageBackgroundConfig {\n type: 'imageBackground';\n /** Path to image file */\n src: string;\n /** Blur radius in pixels (0-20) */\n blur?: number;\n /** Opacity (0-1) */\n opacity?: number;\n /** Ambient motion effect */\n ambientMotion?: 'zoomIn' | 'zoomOut' | 'panLeft' | 'panRight';\n}\n\n/**\n * Pattern background (subtle repeating pattern).\n */\nexport interface PatternBackgroundConfig {\n type: 'patternBackground';\n /** Pattern type */\n pattern: 'dots' | 'grid' | 'diagonal' | 'noise';\n /** Pattern color */\n color?: string;\n /** Pattern opacity (0-1) */\n opacity?: number;\n /** Pattern scale multiplier */\n scale?: number;\n}\n\n// ============================================\n// Overlay Layer Configs\n// ============================================\n\n/**\n * Title caption overlay (article title in corner).\n */\nexport interface TitleCaptionConfig {\n type: 'titleCaption';\n /** Title text */\n title: string;\n /** Subtitle text (e.g., short URL like \"qual..la/slug\") */\n subtitle?: string;\n /** Position on screen */\n position: 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right';\n /** Font size in pixels (default: 18) */\n fontSize?: number;\n /** Show thumbnail alongside title */\n showThumbnail?: boolean;\n /** Thumbnail image path */\n thumbnailSrc?: string;\n}\n\n/**\n * Corner branding overlay (logo or text badge).\n */\nexport interface CornerBrandingConfig {\n type: 'cornerBranding';\n /** Text content or image path */\n content: string;\n /** Position on screen */\n position: 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right';\n /** Whether content is an image path (vs text) */\n isImage?: boolean;\n}\n\n/**\n * Progress indicator overlay (bar or dots showing position).\n */\nexport interface ProgressIndicatorConfig {\n type: 'progressIndicator';\n /** Indicator style */\n style: 'bar' | 'dots' | 'fraction';\n /** Position on screen */\n position: 'bottom' | 'top';\n /** Indicator color */\n color?: string;\n}\n","/**\n * Markdown Tree Utilities\n *\n * Helper functions for traversing and querying the MarkdownDocument tree.\n * All functions are pure and operate on the JSON node interfaces.\n */\n\nimport type { MarkdownNode, MarkdownDocument } from './types.js';\n\n/**\n * Get the children of any markdown node, if it has children.\n * Returns an empty array for leaf nodes (text, code, break, etc.).\n *\n * This is useful for generic tree walking where you don't want to\n * check the specific node type.\n */\nexport function getChildren(node: MarkdownNode): MarkdownNode[] {\n if ('children' in node && Array.isArray(node.children)) {\n return node.children as MarkdownNode[];\n }\n return [];\n}\n\n/**\n * Walk the markdown tree depth-first, calling the visitor for each node.\n *\n * The visitor receives the current node and its parent. Return `true`\n * from the visitor to skip the node's children (prune).\n *\n * @param node - The root node to start walking from\n * @param visitor - Called for each node; return true to skip children\n * @param parent - (internal) Parent node\n */\nexport function walkMarkdownTree(\n node: MarkdownNode,\n visitor: (node: MarkdownNode, parent?: MarkdownNode) => void | boolean,\n parent?: MarkdownNode,\n): void {\n const skip = visitor(node, parent);\n if (skip === true) return;\n\n const children = getChildren(node);\n for (const child of children) {\n walkMarkdownTree(child, visitor, node);\n }\n}\n\n/**\n * Find all nodes of a specific type in the tree.\n *\n * @param root - The document or node to search within\n * @param type - The node type to find (e.g., 'heading', 'link', 'text')\n * @returns Array of matching nodes\n *\n * @example\n * ```ts\n * const headings = findNodesByType(doc, 'heading');\n * const links = findNodesByType(doc, 'link');\n * ```\n */\nexport function findNodesByType<T extends MarkdownNode>(root: MarkdownNode, type: T['type']): T[] {\n const results: T[] = [];\n walkMarkdownTree(root, (node) => {\n if (node.type === type) {\n results.push(node as T);\n }\n });\n return results;\n}\n\n/**\n * Extract all plain text content from a node and its descendants.\n * Concatenates text values, ignoring formatting, links, etc.\n *\n * @param node - The node to extract text from\n * @returns Plain text content\n *\n * @example\n * ```ts\n * const heading = doc.children[0]; // { type: 'heading', children: [{ type: 'text', value: 'Hello' }] }\n * extractPlainText(heading); // 'Hello'\n * ```\n */\nexport function extractPlainText(node: MarkdownNode): string {\n if ('value' in node && typeof node.value === 'string') {\n return node.value;\n }\n\n const children = getChildren(node);\n return children.map(extractPlainText).join('');\n}\n\n/**\n * Count the total number of nodes in the tree.\n *\n * @param node - The root node\n * @returns Total node count (including the root)\n */\nexport function countNodes(node: MarkdownNode): number {\n let count = 1;\n const children = getChildren(node);\n for (const child of children) {\n count += countNodes(child);\n }\n return count;\n}\n\n/**\n * Parse a YAML frontmatter string into a key-value record.\n *\n * Handles simple `key: value` pairs common in markdown frontmatter.\n * Values are trimmed; quoted strings have their quotes removed.\n * Returns `null` if parsing fails or the input is empty.\n *\n * @param yaml - The raw YAML string (without the `---` delimiters)\n * @returns A record of string keys to parsed values, or null\n */\nexport function parseFrontmatter(yaml: string): Record<string, unknown> | null {\n if (!yaml || !yaml.trim()) return null;\n\n const result: Record<string, unknown> = {};\n\n for (const line of yaml.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n\n const colonIdx = trimmed.indexOf(':');\n if (colonIdx < 1) continue;\n\n const key = trimmed.slice(0, colonIdx).trim();\n let value: string | boolean | number = trimmed.slice(colonIdx + 1).trim();\n\n // Remove surrounding quotes\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1);\n }\n\n // Parse booleans and numbers\n if (value === 'true') {\n result[key] = true;\n } else if (value === 'false') {\n result[key] = false;\n } else if (value !== '' && !isNaN(Number(value))) {\n result[key] = Number(value);\n } else {\n result[key] = value;\n }\n }\n\n return Object.keys(result).length > 0 ? result : null;\n}\n\n/**\n * Create a minimal MarkdownDocument from a list of block nodes.\n * Convenience function for programmatic document construction.\n */\nexport function createDocument(...children: MarkdownDocument['children']): MarkdownDocument {\n return {\n type: 'document',\n children,\n };\n}\n","/**\n * Persistent Layers Expansion\n *\n * Expands persistent layer templates (solid backgrounds, gradients, overlays)\n * into raw Layer arrays. These layers are injected into each block based on\n * per-block flags (useBottomLayer, useTopLayer).\n *\n * This is shared code used by both site and efb-app doc renderers.\n *\n * Related Files:\n * - schemas/BlockTemplates.ts - PersistentLayerConfig types\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type {\n PersistentLayer,\n PersistentLayerTemplate,\n PersistentLayerConfig,\n SolidBackgroundConfig,\n GradientBackgroundConfig,\n ImageBackgroundConfig,\n PatternBackgroundConfig,\n TitleCaptionConfig,\n CornerBrandingConfig,\n ProgressIndicatorConfig,\n} from '../../schemas/BlockTemplates.js';\nimport type { Theme } from '../../schemas/Theme.js';\nimport { isPersistentLayerTemplate } from '../../schemas/BlockTemplates.js';\n\n// ============================================\n// Gradient Presets\n// ============================================\n\nconst GRADIENT_PRESETS: Record<string, string> = {\n 'dark-vignette':\n 'radial-gradient(ellipse at center, rgba(26,32,44,0.8) 0%, rgba(0,0,0,0.95) 100%)',\n 'radial-dark': 'radial-gradient(ellipse at center, #1a202c 0%, #000000 100%)',\n 'warm-sunset': 'linear-gradient(135deg, rgba(124,58,48,0.9) 0%, rgba(26,32,44,0.95) 100%)',\n 'cool-blue': 'linear-gradient(135deg, rgba(26,54,93,0.9) 0%, rgba(26,32,44,0.95) 100%)',\n 'earth-tones': 'linear-gradient(135deg, rgba(68,51,34,0.9) 0%, rgba(26,32,44,0.95) 100%)',\n};\n\n// ============================================\n// Background Layer Expansion\n// ============================================\n\n/**\n * Expand a solid background config to a Layer.\n */\nfunction expandSolidBackground(config: SolidBackgroundConfig): Layer {\n return {\n type: 'shape',\n id: 'persistent-bg-solid',\n content: {\n shape: 'rect',\n fill: config.color,\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n };\n}\n\n/**\n * Expand a gradient background config to a Layer.\n */\nfunction expandGradientBackground(config: GradientBackgroundConfig): Layer {\n const gradient = config.gradient ?? GRADIENT_PRESETS[config.preset ?? 'dark-vignette'];\n\n return {\n type: 'shape',\n id: 'persistent-bg-gradient',\n content: {\n shape: 'rect',\n fill: gradient,\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n };\n}\n\n/**\n * Expand an image background config to Layers.\n * Returns multiple layers: base image + dark overlay for readability.\n */\nfunction expandImageBackground(config: ImageBackgroundConfig): Layer[] {\n const layers: Layer[] = [];\n const opacity = config.opacity ?? 0.4;\n\n // Base image layer\n const imageLayer: Layer = {\n type: 'image',\n id: 'persistent-bg-image',\n content: {\n src: config.src,\n alt: 'Background',\n fit: 'cover',\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n animation: config.ambientMotion\n ? {\n type: config.ambientMotion,\n duration: 30, // Long ambient motion\n }\n : undefined,\n };\n\n layers.push(imageLayer);\n\n // Add dark overlay for text readability\n layers.push({\n type: 'shape',\n id: 'persistent-bg-overlay',\n content: {\n shape: 'rect',\n fill: `rgba(0,0,0,${0.5 + (1 - opacity) * 0.3})`,\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n });\n\n return layers;\n}\n\n/**\n * Expand a pattern background config to a Layer.\n */\nfunction expandPatternBackground(config: PatternBackgroundConfig): Layer {\n const opacity = config.opacity ?? 0.1;\n const color = config.color ?? `rgba(255,255,255,${opacity})`;\n\n // Pattern as SVG data URI for rect patterns\n // For simplicity, use a solid subtle color with reduced opacity\n return {\n type: 'shape',\n id: 'persistent-bg-pattern',\n content: {\n shape: 'rect',\n fill: color,\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n };\n}\n\n// ============================================\n// Overlay Layer Expansion\n// ============================================\n\n/**\n * Expand a title caption config to Layers.\n */\nfunction expandTitleCaption(config: TitleCaptionConfig): Layer[] {\n const layers: Layer[] = [];\n const fontSize = config.fontSize ?? 18;\n const hasSubtitle = !!config.subtitle;\n\n // Position calculations\n const isBottom = config.position.includes('bottom');\n const isLeft = config.position.includes('left');\n\n // Even padding around the pill (3% from edges)\n const pad = 3; // percent\n\n // Pill dimensions — taller when subtitle present\n const pillHeight = hasSubtitle ? '15%' : '7%';\n // Position above player controls\n const bgYPos = isBottom ? (hasSubtitle ? '78%' : '84%') : '2%';\n const bgXPos = isLeft ? `${pad}%` : '68%';\n\n // Thumbnail sizing — use different width/height to appear square in 16:9 viewport\n // In 16:9, 6% of width ≈ 10.7% of height in pixels, so use ~6%w x 10%h for visual square\n const thumbW = hasSubtitle ? '6%' : '5%';\n const thumbH = hasSubtitle ? '10%' : '5%';\n const thumbPad = 1.5; // padding inside pill around thumbnail (percent)\n\n // Text X offset: after thumbnail + padding, or just pill padding\n const textX =\n config.showThumbnail && isLeft\n ? `${pad + thumbPad + 6 + thumbPad}%` // pill edge + thumb padding + thumb width + gap\n : `${pad + thumbPad}%`;\n // Text area width: pill width minus thumbnail area minus padding\n const textWidth = config.showThumbnail\n ? '19%' // narrower when thumbnail takes space\n : '24%';\n\n // Title Y: top of text area inside pill\n const titleYPos = isBottom ? (hasSubtitle ? '80%' : '86%') : '4%';\n\n // Background pill for readability\n layers.push({\n type: 'shape',\n id: 'persistent-caption-bg',\n content: {\n shape: 'rect',\n fill: 'rgba(0,0,0,0.6)',\n borderRadius: 8,\n },\n position: {\n x: bgXPos,\n y: bgYPos,\n width: config.showThumbnail ? '30%' : '28%',\n height: pillHeight,\n },\n });\n\n // Thumbnail if configured\n if (config.showThumbnail && config.thumbnailSrc) {\n const thumbX = isLeft ? `${pad + thumbPad}%` : '93%';\n // Center thumbnail vertically in pill\n const thumbY = isBottom ? (hasSubtitle ? `${78 + thumbPad}%` : '85%') : '3%';\n\n layers.push({\n type: 'image',\n id: 'persistent-caption-thumb',\n content: {\n src: config.thumbnailSrc,\n alt: 'Article thumbnail',\n fit: 'cover',\n },\n position: {\n x: thumbX,\n y: thumbY,\n width: thumbW,\n height: thumbH,\n },\n });\n }\n\n // Title text — single line, cropped with ellipsis\n layers.push({\n type: 'text',\n id: 'persistent-caption-title',\n content: {\n text: config.title,\n style: {\n fontSize,\n fontWeight: 'bold',\n color: 'rgba(255,255,255,0.9)',\n textAlign: isLeft ? 'left' : 'right',\n maxLines: 1,\n },\n },\n position: {\n x: textX,\n y: titleYPos,\n width: textWidth,\n },\n });\n\n // Subtitle text (e.g., short URL)\n if (hasSubtitle) {\n const subtitleYPos = isBottom ? '85.5%' : '8%';\n\n layers.push({\n type: 'text',\n id: 'persistent-caption-subtitle',\n content: {\n text: config.subtitle!,\n style: {\n fontSize: 18,\n fontWeight: 'normal',\n color: 'rgba(255,255,255,0.55)',\n textAlign: isLeft ? 'left' : 'right',\n },\n },\n position: {\n x: textX,\n y: subtitleYPos,\n width: textWidth,\n },\n });\n }\n\n return layers;\n}\n\n/**\n * Expand a corner branding config to a Layer.\n */\nfunction expandCornerBranding(config: CornerBrandingConfig): Layer {\n const isBottom = config.position.includes('bottom');\n const isLeft = config.position.includes('left');\n\n const xPos = isLeft ? '3%' : '90%';\n const yPos = isBottom ? '94%' : '3%';\n\n if (config.isImage) {\n return {\n type: 'image',\n id: 'persistent-branding',\n content: {\n src: config.content,\n alt: 'Branding',\n fit: 'contain',\n },\n position: {\n x: xPos,\n y: yPos,\n width: '8%',\n height: '4%',\n },\n };\n }\n\n return {\n type: 'text',\n id: 'persistent-branding',\n content: {\n text: config.content,\n style: {\n fontSize: 14,\n fontWeight: 'normal',\n color: 'rgba(255,255,255,0.6)',\n },\n },\n position: {\n x: xPos,\n y: yPos,\n },\n };\n}\n\n/**\n * Expand a progress indicator config to a Layer.\n * Note: Progress requires block context, returns placeholder bar.\n */\nfunction expandProgressIndicator(config: ProgressIndicatorConfig): Layer {\n const color = config.color ?? 'rgba(255,255,255,0.3)';\n const y = config.position === 'top' ? '1%' : '98%';\n\n // Simple bar style - actual progress would need to be set per-block\n return {\n type: 'shape',\n id: 'persistent-progress',\n content: {\n shape: 'rect',\n fill: color,\n borderRadius: 2,\n },\n position: {\n x: '5%',\n y,\n width: '90%',\n height: '0.5%',\n },\n };\n}\n\n// ============================================\n// Main Expansion Function\n// ============================================\n\n/**\n * Expand a single persistent layer (template or raw) to raw Layer(s).\n */\nexport function expandPersistentLayer(layer: PersistentLayer): Layer[] {\n // If already a raw Layer, return as-is\n if (!isPersistentLayerTemplate(layer)) {\n return [layer as Layer];\n }\n\n const template = layer as PersistentLayerTemplate;\n const config = template.config;\n\n switch (config.type) {\n case 'solidBackground':\n return [expandSolidBackground(config)];\n case 'gradientBackground':\n return [expandGradientBackground(config)];\n case 'imageBackground':\n return expandImageBackground(config);\n case 'patternBackground':\n return [expandPatternBackground(config)];\n case 'titleCaption':\n return expandTitleCaption(config);\n case 'cornerBranding':\n return [expandCornerBranding(config)];\n case 'progressIndicator':\n return [expandProgressIndicator(config)];\n default:\n console.warn('Unknown persistent layer template:', (config as Record<string, unknown>).type);\n return [];\n }\n}\n\n/**\n * Expand all persistent layers in a config to raw Layer arrays.\n */\nexport function expandPersistentLayers(layers: PersistentLayer[] | undefined): Layer[] {\n if (!layers || layers.length === 0) {\n return [];\n }\n\n // Use reduce+concat instead of flatMap for Coherent GT compatibility (ES2017)\n return layers.reduce<Layer[]>((acc, layer) => acc.concat(expandPersistentLayer(layer)), []);\n}\n\n// ============================================\n// Style Presets (legacy helper — prefer theme.persistentLayers)\n// ============================================\n\n/** Legacy style preset names. Prefer using `Theme.persistentLayers` directly. */\nexport type DocStylePreset = 'minimal' | 'documentary' | 'branded' | 'cinematic' | 'clean';\n\n/**\n * Get a PersistentLayerConfig from a style preset.\n *\n * @param preset - Style preset name\n * @param articleTitle - Article title for title caption\n * @param heroSrc - Optional hero image for cinematic style\n */\nexport function getDocStyleConfig(\n preset: DocStylePreset,\n articleTitle: string,\n heroSrc?: string,\n subtitle?: string,\n): PersistentLayerConfig {\n switch (preset) {\n case 'minimal':\n return {};\n\n case 'documentary':\n return {\n bottomLayers: [\n {\n template: 'gradientBackground',\n config: { type: 'gradientBackground', preset: 'dark-vignette' },\n },\n ],\n topLayers: [\n {\n template: 'titleCaption',\n config: {\n type: 'titleCaption',\n title: articleTitle,\n subtitle,\n position: 'bottom-left',\n fontSize: 24,\n showThumbnail: !!heroSrc,\n thumbnailSrc: heroSrc,\n },\n },\n ],\n };\n\n case 'branded':\n return {\n bottomLayers: [\n {\n template: 'gradientBackground',\n config: { type: 'gradientBackground', preset: 'cool-blue' },\n },\n ],\n topLayers: [\n {\n template: 'titleCaption',\n config: {\n type: 'titleCaption',\n title: articleTitle,\n subtitle,\n position: 'bottom-left',\n fontSize: 26,\n showThumbnail: !!heroSrc,\n thumbnailSrc: heroSrc,\n },\n },\n ],\n };\n\n case 'cinematic':\n return {\n bottomLayers: heroSrc\n ? [\n {\n template: 'imageBackground',\n config: {\n type: 'imageBackground',\n src: heroSrc,\n blur: 12,\n opacity: 0.3,\n ambientMotion: 'zoomIn',\n },\n },\n ]\n : [\n {\n template: 'gradientBackground',\n config: { type: 'gradientBackground', preset: 'radial-dark' },\n },\n ],\n topLayers: [\n {\n template: 'titleCaption',\n config: {\n type: 'titleCaption',\n title: articleTitle,\n subtitle,\n position: 'bottom-right',\n fontSize: 22,\n },\n },\n ],\n };\n\n case 'clean':\n return {\n bottomLayers: [\n {\n template: 'solidBackground',\n config: { type: 'solidBackground', color: '#1a202c' },\n },\n ],\n };\n\n default:\n return {};\n }\n}\n\n/**\n * Get persistent layers from a Theme. Returns the theme's baked-in\n * persistentLayers config, or an empty config when the theme has none.\n */\nexport function getPersistentLayersFromTheme(theme: Theme): PersistentLayerConfig {\n return theme.persistentLayers ?? {};\n}\n","/**\n * Theme Utilities\n *\n * Template-facing helpers that read from the Theme object on the\n * TemplateContext. Templates call these instead of hard-coding style\n * decisions, so the same template code adapts to any theme.\n */\n\nimport type { TemplateContext } from '../../schemas/BlockTemplates.js';\nimport type { ThemeColorScheme, RenderStyle } from '../../schemas/Theme.js';\nimport type { AnimationType } from '../../schemas/Doc.js';\n\n// ============================================\n// Color Scheme Resolution\n// ============================================\n\n/** Fallback color scheme when a name is not found in the theme. */\nconst FALLBACK_COLOR_SCHEME: ThemeColorScheme = {\n bg: '#1a365d',\n text: '#63b3ed',\n accent: '#90cdf4',\n};\n\n/**\n * Resolve a named color scheme from the theme, with a safe fallback.\n * Templates call this instead of `COLOR_SCHEMES[name]`.\n */\nexport function resolveColorScheme(\n context: TemplateContext,\n name: string | undefined,\n): ThemeColorScheme {\n const schemes = context.theme.colorSchemes;\n if (name && name in schemes) return schemes[name];\n // Fall back to first defined scheme, then hard fallback\n const keys = Object.keys(schemes);\n if (keys.length > 0) return schemes[keys[0]];\n return FALLBACK_COLOR_SCHEME;\n}\n\n// ============================================\n// Font Family Resolution\n// ============================================\n\n/** Safe system font fallbacks. */\nconst FALLBACK_BODY = 'system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif';\nconst FALLBACK_TITLE = 'Georgia, \"Times New Roman\", serif';\nconst FALLBACK_MONO = 'Consolas, \"Courier New\", monospace';\n\n/**\n * Get the theme font family for a given role.\n * Templates call this to set `fontFamily` on text layers.\n *\n * @param context Template context (includes theme with typography settings)\n * @param role 'title' for headings, 'body' for descriptions, 'mono' for code\n * @returns A CSS font-family string with the theme's font and safe fallbacks\n */\nexport function getThemeFont(context: TemplateContext, role: 'title' | 'body' | 'mono'): string {\n const { typography } = context.theme;\n switch (role) {\n case 'title':\n return typography.titleFontFamily || FALLBACK_TITLE;\n case 'body':\n return typography.bodyFontFamily || FALLBACK_BODY;\n case 'mono':\n return typography.monoFontFamily || FALLBACK_MONO;\n }\n}\n\n// ============================================\n// Font Sizing\n// ============================================\n\n/**\n * Calculate a theme-aware scaled font size.\n * Applies the theme's typography scale multipliers on top of the\n * viewport-based font scale from LayoutStrategy.\n *\n * @param basePx Base font size designed for 1920×1080\n * @param context Template context (includes fontScale, layout, theme)\n * @param isTitle Whether this is title text (uses titleScale) or body (bodyScale)\n */\nexport function themedFontSize(\n basePx: number,\n context: TemplateContext,\n isTitle: boolean = false,\n): number {\n const { fontScale, layout, theme } = context;\n\n // Base scale from viewport + orientation\n const layoutScale = isTitle ? layout.titleScale : layout.bodyScale;\n\n // Theme multiplier (defaults to 1.0 when not set)\n const themeScale = isTitle\n ? (theme.typography.titleScale ?? 1.0)\n : (theme.typography.bodyScale ?? 1.0);\n\n return Math.round(basePx * fontScale * layoutScale * themeScale);\n}\n\n// ============================================\n// Animation Helpers\n// ============================================\n\n/**\n * Scale an animation duration by the theme's animationSpeed multiplier.\n * A speed of 1.0 returns the base duration unchanged.\n */\nexport function scaleAnimationDuration(baseDuration: number, context: TemplateContext): number {\n const speed = context.theme.style.animationSpeed ?? 1.0;\n return baseDuration * speed;\n}\n\n/**\n * Get the theme's default animation type for a layer kind.\n * Returns `undefined` when the theme doesn't specify one (template picks its own).\n */\nexport function getDefaultAnimation(\n context: TemplateContext,\n layerType: 'text' | 'image',\n): AnimationType | undefined {\n const rs: RenderStyle = context.theme.renderStyle;\n return layerType === 'text' ? rs.defaultTextAnimation : rs.defaultImageAnimation;\n}\n\n// ============================================\n// Style Helpers\n// ============================================\n\n/**\n * Whether the theme defaults to text shadows.\n * Templates should consult this when choosing `shadow: true/false`.\n */\nexport function shouldUseShadow(context: TemplateContext): boolean {\n return context.theme.style.textShadow ?? true;\n}\n\n/**\n * Get the theme's overlay opacity for image-backed blocks.\n */\nexport function getOverlayOpacity(context: TemplateContext): number {\n return context.theme.style.overlayOpacity ?? 0.5;\n}\n\n// ============================================\n// Template Hint Access\n// ============================================\n\n/**\n * Read a per-template hint from the theme's renderStyle.\n * Returns `fallback` when the hint isn't defined.\n *\n * @example\n * ```ts\n * const entrance = getTemplateHint(context, 'statHighlight', 'entrance', 'subtle');\n * ```\n */\nexport function getTemplateHint<T extends string | number | boolean>(\n context: TemplateContext,\n templateName: string,\n key: string,\n fallback: T,\n): T {\n const hints = context.theme.renderStyle.templateHints;\n if (!hints) return fallback;\n const tplHints = hints[templateName];\n if (!tplHints || !(key in tplHints)) return fallback;\n return tplHints[key] as T;\n}\n","/**\n * Title Block Template\n *\n * Large title with optional subtitle for doc intros.\n * Centered text with fade-in animations.\n * Adapts font sizes and positioning for different viewports.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { TitleBlockInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { getThemeFont } from '../utils/themeUtils.js';\n\nexport function titleBlock(input: TitleBlockInput, context: TemplateContext): Layer[] {\n const { title, subtitle, backgroundColor } = input;\n const { theme, layout } = context;\n\n // Scale font sizes for viewport\n const titleFontSize = scaledFontSize(96, context, true);\n const subtitleFontSize = scaledFontSize(36, context, false);\n\n const baseBg = backgroundColor || theme.colors.primary;\n\n const layers: Layer[] = [\n // Background — radial gradient for depth instead of flat color\n {\n type: 'shape',\n id: 'bg',\n content: {\n shape: 'rect',\n fill: `radial-gradient(ellipse at 50% 40%, ${baseBg} 0%, ${theme.colors.background} 100%)`,\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n },\n // Subtle decorative line above title\n {\n type: 'shape',\n id: 'accent-line',\n content: {\n shape: 'rect',\n fill: 'rgba(255, 255, 255, 0.2)',\n },\n position: {\n x: '40%',\n y: subtitle ? '28%' : '38%',\n width: '20%',\n height: '2px',\n },\n },\n // Title\n {\n type: 'text',\n id: 'title',\n content: {\n text: title,\n style: {\n fontSize: titleFontSize,\n fontFamily: getThemeFont(context, 'title'),\n fontWeight: 'bold',\n color: theme.colors.text,\n textAlign: 'center',\n shadow: true,\n },\n },\n position: {\n x: '50%',\n y: subtitle ? layout.primaryY : '50%',\n anchor: 'center',\n width: layout.maxTextWidth,\n },\n animation: { type: 'fadeIn', duration: 2 },\n },\n ];\n\n // Add subtitle if provided\n if (subtitle) {\n layers.push({\n type: 'text',\n id: 'subtitle',\n content: {\n text: subtitle,\n style: {\n fontSize: subtitleFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.textMuted,\n textAlign: 'center',\n lineHeight: 1.5,\n },\n },\n position: {\n x: '50%',\n y: layout.secondaryY,\n anchor: 'center',\n width: layout.maxTextWidth,\n },\n animation: { type: 'fadeIn', duration: 1.5, delay: 1 },\n });\n }\n\n return layers;\n}\n","/**\n * Section Header Template\n *\n * Section title card with optional background image.\n * Used to introduce new sections of a story.\n * When an image is provided, displays like a title slide with the image as background.\n * Without an image, falls back to a colored background.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer, AnimationType } from '../../schemas/Doc.js';\nimport type { SectionHeaderInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { resolveColorScheme, getThemeFont } from '../utils/themeUtils.js';\n\nexport function sectionHeader(input: SectionHeaderInput, context: TemplateContext): Layer[] {\n const { title = '', colorScheme = 'blue', imageSrc, imageAlt, ambientMotion } = input;\n const { layout } = context;\n const colors = resolveColorScheme(context, colorScheme);\n\n // Scale font sizes for viewport\n const titleFontSize = scaledFontSize(72, context, true);\n\n const layers: Layer[] = [];\n\n // Background - either image or solid color\n if (imageSrc) {\n // Image background with Ken Burns effect\n layers.push({\n type: 'image',\n id: 'bg-image',\n content: {\n src: imageSrc,\n alt: imageAlt || title,\n fit: 'cover',\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n animation: ambientMotion\n ? { type: ambientMotion as AnimationType, duration: 8 }\n : { type: 'slowZoom', duration: 8, direction: 'in' },\n });\n\n // Dark overlay for text readability\n layers.push({\n type: 'shape',\n id: 'overlay',\n content: {\n shape: 'rect',\n fill: 'rgba(0, 0, 0, 0.5)',\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n });\n } else {\n // Solid color background\n layers.push({\n type: 'shape',\n id: 'bg',\n content: {\n shape: 'rect',\n fill: colors.bg,\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n });\n\n // Decorative lines above and below title\n layers.push({\n type: 'shape',\n id: 'line-top',\n content: { shape: 'rect', fill: `${colors.text}33` },\n position: { x: '50%', y: '40%', width: '20%', height: '2px', anchor: 'center' },\n });\n layers.push({\n type: 'shape',\n id: 'line-bottom',\n content: { shape: 'rect', fill: `${colors.text}33` },\n position: { x: '50%', y: '60%', width: '20%', height: '2px', anchor: 'center' },\n });\n }\n\n // Section title - white text with shadow for readability over images\n layers.push({\n type: 'text',\n id: 'title',\n content: {\n text: title,\n style: {\n fontSize: titleFontSize,\n fontFamily: getThemeFont(context, 'title'),\n fontWeight: 'bold',\n color: imageSrc ? '#ffffff' : colors.text,\n textAlign: 'center',\n shadow: true,\n },\n },\n position: {\n x: '50%',\n y: '50%',\n anchor: 'center',\n width: layout.maxTextWidth,\n },\n animation: { type: 'fadeIn', duration: 1.5 },\n });\n\n return layers;\n}\n","/**\n * Accent Image Utility\n *\n * Creates image layers and layout adjustments for accent images on text-based slides.\n * Accent images are tasteful additions that complement text without overwhelming it.\n *\n * Layout patterns:\n * - left-strip: 35% width vertical strip on left, text area shifted to right 65%\n * - right-strip: 35% width vertical strip on right, text area shifted to left 65%\n * - bottom-strip: 35% height horizontal strip at bottom, text area in upper 65%\n * - corner-inset: Small 25% corner image with gradient vignette\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer, ImageLayer, ShapeLayer, Animation } from '../../schemas/Doc.js';\nimport type { AccentImage, AccentPosition } from '../../schemas/BlockTemplates.js';\n\nconst PERCENTAGE_RE = /^(\\d+(?:\\.\\d+)?)\\s*%?$/;\n\n/**\n * Layout adjustments when an accent image is present.\n * Templates use these values to reposition their text content.\n */\nexport interface AccentLayout {\n /** X offset for text center (e.g., '64%' for left-strip) */\n textCenterX: string;\n /** Width available for text content */\n textWidth: string;\n /** Y offset adjustment for vertical positioning */\n textYAdjust: number;\n /** Whether to adjust Y positions (for bottom-strip) */\n adjustY: boolean;\n}\n\n/**\n * Default layout when no accent image is present.\n */\nexport const DEFAULT_LAYOUT: AccentLayout = {\n textCenterX: '50%',\n textWidth: '85%',\n textYAdjust: 0,\n adjustY: false,\n};\n\n/**\n * Map ambientMotion values to proper Ken Burns animations.\n * Uses slowZoom variants which provide smooth pan/zoom without opacity changes.\n * Supports both standard values ('zoomIn', 'panLeft', etc.) and legacy\n * aliases ('in', 'out', 'left', 'right') for backward compatibility.\n *\n * @param motion - The ambient motion value (e.g., 'zoomIn', 'panLeft')\n * @param duration - Optional animation duration in seconds\n */\nexport function mapAmbientMotion(\n motion: string | undefined,\n duration?: number,\n): Animation | undefined {\n if (!motion) return undefined;\n const base = duration !== undefined ? { duration } : {};\n switch (motion) {\n case 'zoomIn':\n case 'in':\n return { type: 'slowZoom', direction: 'in', ...base };\n case 'zoomOut':\n case 'out':\n return { type: 'slowZoom', direction: 'out', ...base };\n case 'panLeft':\n case 'left':\n return { type: 'slowZoom', panDirection: 'left', ...base };\n case 'panRight':\n case 'right':\n return { type: 'slowZoom', panDirection: 'right', ...base };\n default:\n return undefined;\n }\n}\n\n/**\n * Accent strip width/height as percentage.\n * 35% gives the image enough presence to complement the text without overwhelming it.\n */\nconst STRIP_SIZE = 35;\nconst STRIP_SIZE_PCT = `${STRIP_SIZE}%`;\n\n/**\n * Get layout adjustments based on accent position.\n */\nexport function getAccentLayout(position: AccentPosition): AccentLayout {\n switch (position) {\n case 'left-strip':\n return {\n textCenterX: `${50 + STRIP_SIZE / 2}%`, // Shift center right\n textWidth: `${100 - STRIP_SIZE - 8}%`, // Leave margin\n textYAdjust: 0,\n adjustY: false,\n };\n case 'right-strip':\n return {\n textCenterX: `${50 - STRIP_SIZE / 2}%`, // Shift center left\n textWidth: `${100 - STRIP_SIZE - 8}%`,\n textYAdjust: 0,\n adjustY: false,\n };\n case 'bottom-strip':\n return {\n textCenterX: '50%',\n textWidth: '85%',\n textYAdjust: -10, // Shift content up by 10%\n adjustY: true,\n };\n case 'corner-inset':\n return {\n textCenterX: '45%', // Slight shift to avoid corner\n textWidth: '70%',\n textYAdjust: 0,\n adjustY: false,\n };\n default:\n return DEFAULT_LAYOUT;\n }\n}\n\n/**\n * Create layers for an accent image.\n * Returns the image layer and any overlay/gradient layers needed.\n */\nexport function createAccentLayers(accent: AccentImage, slideId: string): Layer[] {\n const layers: Layer[] = [];\n const { src, alt, position, ambientMotion, credit, license } = accent;\n\n switch (position) {\n case 'left-strip':\n layers.push(createStripImage(src, alt, 'left', slideId, ambientMotion, credit, license));\n layers.push(createStripGradient('left', slideId));\n break;\n\n case 'right-strip':\n layers.push(createStripImage(src, alt, 'right', slideId, ambientMotion, credit, license));\n layers.push(createStripGradient('right', slideId));\n break;\n\n case 'bottom-strip':\n layers.push(createBottomStripImage(src, alt, slideId, ambientMotion, credit, license));\n layers.push(createBottomStripGradient(slideId));\n break;\n\n case 'corner-inset':\n layers.push(createCornerInsetImage(src, alt, slideId, ambientMotion, credit, license));\n layers.push(createCornerVignette(slideId));\n break;\n }\n\n return layers;\n}\n\n/**\n * Create a vertical strip image layer.\n */\nfunction createStripImage(\n src: string,\n alt: string,\n side: 'left' | 'right',\n slideId: string,\n ambientMotion?: AccentImage['ambientMotion'],\n credit?: string,\n license?: string,\n): ImageLayer {\n return {\n type: 'image',\n id: `${slideId}-accent-img`,\n content: {\n src,\n alt,\n fit: 'cover',\n credit,\n license,\n },\n position: {\n x: side === 'left' ? 0 : `${100 - STRIP_SIZE}%`,\n y: 0,\n width: STRIP_SIZE_PCT,\n height: '100%',\n },\n animation: mapAmbientMotion(ambientMotion, 15),\n };\n}\n\n/**\n * Create a gradient overlay for strip images (fades to background).\n */\nfunction createStripGradient(side: 'left' | 'right', slideId: string): ShapeLayer {\n // Gradient from transparent to background color at the edge\n const gradientId = side === 'left' ? 'accent-gradient-left' : 'accent-gradient-right';\n\n return {\n type: 'shape',\n id: `${slideId}-accent-fade`,\n content: {\n shape: 'rect',\n // SVG gradient will be handled by the renderer\n // Using a semi-transparent overlay as fallback\n fill: `url(#${gradientId})`,\n },\n position: {\n x: side === 'left' ? `${STRIP_SIZE - 8}%` : `${100 - STRIP_SIZE}%`,\n y: 0,\n width: '10%',\n height: '100%',\n },\n };\n}\n\n/**\n * Create a horizontal bottom strip image layer.\n */\nfunction createBottomStripImage(\n src: string,\n alt: string,\n slideId: string,\n ambientMotion?: AccentImage['ambientMotion'],\n credit?: string,\n license?: string,\n): ImageLayer {\n return {\n type: 'image',\n id: `${slideId}-accent-img`,\n content: {\n src,\n alt,\n fit: 'cover',\n credit,\n license,\n },\n position: {\n x: 0,\n y: `${100 - STRIP_SIZE}%`,\n width: '100%',\n height: STRIP_SIZE_PCT,\n },\n animation: mapAmbientMotion(ambientMotion, 15),\n };\n}\n\n/**\n * Create a gradient overlay for bottom strip (fades up to background).\n */\nfunction createBottomStripGradient(slideId: string): ShapeLayer {\n return {\n type: 'shape',\n id: `${slideId}-accent-fade`,\n content: {\n shape: 'rect',\n fill: 'url(#accent-gradient-bottom)',\n },\n position: {\n x: 0,\n y: `${100 - STRIP_SIZE - 8}%`,\n width: '100%',\n height: '12%',\n },\n };\n}\n\n/**\n * Create a corner inset image layer.\n */\nfunction createCornerInsetImage(\n src: string,\n alt: string,\n slideId: string,\n ambientMotion?: AccentImage['ambientMotion'],\n credit?: string,\n license?: string,\n): ImageLayer {\n return {\n type: 'image',\n id: `${slideId}-accent-img`,\n content: {\n src,\n alt,\n fit: 'cover',\n credit,\n license,\n },\n position: {\n x: '70%',\n y: '60%',\n width: '28%',\n height: '38%',\n anchor: 'top-left',\n },\n animation: mapAmbientMotion(ambientMotion, 15) ?? { type: 'fadeIn', duration: 2, delay: 0.5 },\n };\n}\n\n/**\n * Create a vignette overlay around corner inset.\n */\nfunction createCornerVignette(slideId: string): ShapeLayer {\n return {\n type: 'shape',\n id: `${slideId}-accent-vignette`,\n content: {\n shape: 'rect',\n fill: 'url(#accent-vignette-corner)',\n borderRadius: 8,\n },\n position: {\n x: '69%',\n y: '59%',\n width: '30%',\n height: '40%',\n },\n };\n}\n\n/**\n * Adjust a Y position value based on accent layout.\n * Used by templates to shift content when bottom-strip is present.\n */\nexport function adjustY(originalY: string | number, layout: AccentLayout): string {\n if (!layout.adjustY || layout.textYAdjust === 0) {\n return typeof originalY === 'number' ? `${originalY}%` : originalY;\n }\n\n // Parse percentage value\n const yStr = typeof originalY === 'number' ? `${originalY}` : originalY;\n const match = yStr.match(PERCENTAGE_RE);\n\n if (match) {\n const yValue = parseFloat(match[1]);\n const adjusted = Math.max(5, yValue + layout.textYAdjust);\n return `${adjusted}%`;\n }\n\n return yStr;\n}\n","/**\n * Template Utilities\n *\n * Shared helpers for doc block templates:\n * - Caption text cleaning\n * - Common layer construction patterns\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\n\nconst TRAILING_PUNCT_RE = /[.;:!?]+$/;\n\n/**\n * Strip trailing punctuation from a caption string.\n * Image captions on blocks look cleaner without terminal periods,\n * semicolons, or other sentence-ending punctuation.\n */\nexport function cleanCaption(text: string): string {\n return text.replace(TRAILING_PUNCT_RE, '').trim();\n}\n\n/**\n * Create a full-screen background shape layer.\n * Most text-based templates start with this as their first layer.\n */\nexport function createBackgroundLayer(id: string, fill: string): Layer {\n return {\n type: 'shape',\n id,\n content: { shape: 'rect', fill },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n };\n}\n","/**\n * Stat Highlight Template\n *\n * Large statistic/number with description and optional detail.\n * Great for emphasizing key data points.\n * Adapts font sizes and positioning for different viewports.\n *\n * Supports optional accent images that appear as tasteful side/bottom strips.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { StatHighlightInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { resolveColorScheme, getThemeFont } from '../utils/themeUtils.js';\nimport { createAccentLayers, getAccentLayout, adjustY, DEFAULT_LAYOUT } from './accentImage.js';\nimport { createBackgroundLayer } from './captionUtils.js';\n\nexport function statHighlight(input: StatHighlightInput, context: TemplateContext): Layer[] {\n const { stat, description, detail, colorScheme = 'blue', accentImage } = input;\n const { theme } = context;\n const colors = resolveColorScheme(context, colorScheme);\n\n // Get layout adjustments if accent image is present\n const accentLayout = accentImage ? getAccentLayout(accentImage.position) : DEFAULT_LAYOUT;\n\n // Scale font sizes — stat is dramatically large, description is understated\n const statFontSize = scaledFontSize(148, context, true);\n const descFontSize = scaledFontSize(32, context, false);\n const detailFontSize = scaledFontSize(26, context, false);\n\n const layers: Layer[] = [\n createBackgroundLayer(\n 'bg',\n `linear-gradient(180deg, ${theme.colors.background} 0%, #0f1520 100%)`,\n ),\n ];\n\n // Add accent image layers (behind text, after background)\n if (accentImage) {\n layers.push(...createAccentLayers(accentImage, input.id));\n }\n\n // Big stat — hero element, dominates the slide\n layers.push({\n type: 'text',\n id: 'stat',\n content: {\n text: stat,\n style: {\n fontSize: statFontSize,\n fontFamily: getThemeFont(context, 'title'),\n fontWeight: 'bold',\n color: colors.text,\n shadow: !!accentImage,\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY('32%', accentLayout),\n anchor: 'center',\n },\n animation: { type: 'zoomIn', duration: 0.6 },\n });\n\n // Description — smaller and understated beneath the stat\n layers.push({\n type: 'text',\n id: 'description',\n content: {\n text: description,\n style: {\n fontSize: descFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.textMuted,\n textAlign: 'center',\n lineHeight: 1.6,\n shadow: !!accentImage,\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY('58%', accentLayout),\n width: accentLayout.textWidth,\n anchor: 'center',\n },\n animation: { type: 'fadeIn', duration: 1, delay: 0.3 },\n });\n\n // Add detail if provided\n if (detail) {\n layers.push({\n type: 'text',\n id: 'detail',\n content: {\n text: detail,\n style: {\n fontSize: detailFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: colors.accent,\n textAlign: 'center',\n shadow: !!accentImage,\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY('75%', accentLayout),\n anchor: 'center',\n },\n animation: { type: 'fadeIn', duration: 1, delay: 1 },\n });\n }\n\n return layers;\n}\n","/**\n * Quote Block Template\n *\n * Large centered quote with optional attribution.\n * Good for impactful statements or descriptions.\n * Adapts font sizes and positioning for different viewports.\n *\n * Supports optional accent images that appear as tasteful side/bottom strips.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { QuoteBlockInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { getThemeFont } from '../utils/themeUtils.js';\nimport { createAccentLayers, getAccentLayout, adjustY, DEFAULT_LAYOUT } from './accentImage.js';\nimport { createBackgroundLayer } from './captionUtils.js';\n\nexport function quoteBlock(input: QuoteBlockInput, context: TemplateContext): Layer[] {\n const { quote, attribution, accentImage } = input;\n const { theme, layout } = context;\n\n // Get layout adjustments if accent image is present\n const accentLayout = accentImage ? getAccentLayout(accentImage.position) : DEFAULT_LAYOUT;\n\n // Scale font sizes for viewport\n const quoteFontSize = scaledFontSize(48, context, true);\n const attrFontSize = scaledFontSize(24, context, false);\n\n // Decorative quotation mark font size\n const decorativeQuoteFontSize = scaledFontSize(280, context, true);\n\n const layers: Layer[] = [\n createBackgroundLayer(\n 'bg',\n `linear-gradient(160deg, ${theme.colors.backgroundLight} 0%, #1e2636 100%)`,\n ),\n ];\n\n // Add accent image layers (behind text, after background)\n if (accentImage) {\n layers.push(...createAccentLayers(accentImage, input.id));\n }\n\n // Decorative opening quotation mark — oversized, low-opacity behind quote\n layers.push({\n type: 'text',\n id: 'deco-quote',\n content: {\n text: '\\u201C',\n style: {\n fontSize: decorativeQuoteFontSize,\n fontFamily: getThemeFont(context, 'title'),\n color: 'rgba(255, 255, 255, 0.06)',\n textAlign: 'center',\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY('18%', accentLayout),\n anchor: 'center',\n },\n });\n\n // Quote text - positioned based on accent layout\n const quoteY = attribution ? layout.primaryY : '50%';\n layers.push({\n type: 'text',\n id: 'quote',\n content: {\n text: quote,\n style: {\n fontSize: quoteFontSize,\n fontFamily: getThemeFont(context, 'title'),\n color: theme.colors.text,\n textAlign: 'center',\n lineHeight: 1.6,\n shadow: true,\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY(quoteY, accentLayout),\n anchor: 'center',\n width: accentLayout.textWidth,\n },\n animation: { type: 'fadeIn', duration: 2 },\n });\n\n // Add attribution if provided\n if (attribution) {\n layers.push({\n type: 'text',\n id: 'attribution',\n content: {\n text: `— ${attribution}`,\n style: {\n fontSize: attrFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.textMuted,\n textAlign: 'center',\n shadow: !!accentImage,\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY(layout.captionY, accentLayout),\n anchor: 'center',\n },\n animation: { type: 'fadeIn', duration: 1, delay: 1.5 },\n });\n }\n\n return layers;\n}\n","/**\n * Fact Card Template\n *\n * Key fact with explanation and optional source.\n * Useful for presenting important information clearly.\n * Adapts font sizes and positioning for different viewports.\n *\n * Supports optional accent images that appear as tasteful side/bottom strips.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { FactCardInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { getThemeFont } from '../utils/themeUtils.js';\nimport { createAccentLayers, getAccentLayout, adjustY, DEFAULT_LAYOUT } from './accentImage.js';\nimport { createBackgroundLayer } from './captionUtils.js';\n\nexport function factCard(input: FactCardInput, context: TemplateContext): Layer[] {\n const { fact, explanation, source, accentImage } = input;\n const { theme } = context;\n\n // Get layout adjustments if accent image is present\n const accentLayout = accentImage ? getAccentLayout(accentImage.position) : DEFAULT_LAYOUT;\n\n // Scale font sizes for viewport\n const factFontSize = scaledFontSize(56, context, true);\n const explainFontSize = scaledFontSize(32, context, false);\n const sourceFontSize = scaledFontSize(20, context, false);\n\n const layers: Layer[] = [\n createBackgroundLayer(\n 'bg',\n `linear-gradient(170deg, #1e2030 0%, ${theme.colors.background} 100%)`,\n ),\n ];\n\n // Add accent image layers (behind text, after background)\n if (accentImage) {\n layers.push(...createAccentLayers(accentImage, input.id));\n }\n\n // Fact (main statement)\n layers.push({\n type: 'text',\n id: 'fact',\n content: {\n text: fact,\n style: {\n fontSize: factFontSize,\n fontFamily: getThemeFont(context, 'title'),\n fontWeight: 'bold',\n color: theme.colors.text,\n textAlign: 'center',\n lineHeight: 1.4,\n shadow: true,\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY('35%', accentLayout),\n width: accentLayout.textWidth,\n anchor: 'center',\n },\n animation: { type: 'fadeIn', duration: 1.5 },\n });\n\n // Explanation\n layers.push({\n type: 'text',\n id: 'explanation',\n content: {\n text: explanation,\n style: {\n fontSize: explainFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.textMuted,\n textAlign: 'center',\n lineHeight: 1.5,\n shadow: !!accentImage,\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY('60%', accentLayout),\n width: accentLayout.textWidth,\n anchor: 'center',\n },\n animation: { type: 'fadeIn', duration: 1, delay: 0.8 },\n });\n\n // Add source if provided\n if (source) {\n layers.push({\n type: 'text',\n id: 'source',\n content: {\n text: source,\n style: {\n fontSize: sourceFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.textMuted,\n textAlign: 'center',\n shadow: !!accentImage,\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY('85%', accentLayout),\n anchor: 'center',\n },\n animation: { type: 'fadeIn', duration: 0.8, delay: 1.5 },\n });\n }\n\n return layers;\n}\n","/**\n * Two Column Template\n *\n * Side-by-side comparison of two items.\n * Each column has a label and optional sublabel.\n * Adapts font sizes and positioning for different viewports.\n *\n * Portrait mode: Stacks columns vertically (top/bottom) instead of side-by-side.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { TwoColumnInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { resolveColorScheme, getThemeFont } from '../utils/themeUtils.js';\nimport { getTwoColumnPositions } from '../../schemas/LayoutStrategy.js';\n\nexport function twoColumn(input: TwoColumnInput, context: TemplateContext): Layer[] {\n const { left, right, header, leftColor = 'green', rightColor = 'blue' } = input;\n\n // Guard: required fields may be absent when generated from sparse markdown\n if (!left?.label || !right?.label) return [];\n\n const { theme, layout, orientation } = context;\n const leftColors = resolveColorScheme(context, leftColor);\n const rightColors = resolveColorScheme(context, rightColor);\n\n // Get column positions based on orientation\n const positions = getTwoColumnPositions(orientation);\n const isStacked = layout.stackColumns;\n\n // Column width ~42% for side-by-side, ~85% for stacked\n const columnWidth = isStacked ? '85%' : '42%';\n\n // Calculate font sizes based on viewport\n const headerFontSize = scaledFontSize(32, context, false);\n const labelFontSize = scaledFontSize(44, context, true);\n const sublabelFontSize = scaledFontSize(22, context, false);\n\n const layers: Layer[] = [\n // Background — subtle gradient to add depth\n {\n type: 'shape',\n id: 'bg',\n content: {\n shape: 'rect',\n fill: `linear-gradient(135deg, ${theme.colors.background} 0%, #16202e 100%)`,\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n },\n ];\n\n if (!isStacked) {\n // Left column background panel\n layers.push({\n type: 'shape',\n id: 'left-panel',\n content: {\n shape: 'rect',\n fill: 'rgba(255, 255, 255, 0.04)',\n },\n position: { x: '3%', y: '15%', width: '44%', height: '70%' },\n });\n\n // Right column background panel\n layers.push({\n type: 'shape',\n id: 'right-panel',\n content: {\n shape: 'rect',\n fill: 'rgba(255, 255, 255, 0.04)',\n },\n position: { x: '53%', y: '15%', width: '44%', height: '70%' },\n });\n }\n\n // Header position adjusts based on layout\n const headerY = isStacked ? '12%' : '22%';\n\n // Add header if provided\n if (header) {\n layers.push({\n type: 'text',\n id: 'header',\n content: {\n text: header,\n style: {\n fontSize: headerFontSize,\n fontFamily: getThemeFont(context, 'title'),\n color: theme.colors.textMuted,\n textAlign: 'center',\n },\n },\n position: { x: '50%', y: headerY, anchor: 'center' },\n animation: { type: 'fadeIn', duration: 0.8 },\n });\n }\n\n // Calculate Y positions based on layout mode and header presence\n let leftY: string;\n let leftSublabelY: string;\n let rightY: string;\n let rightSublabelY: string;\n\n if (isStacked) {\n // Portrait: stacked vertically\n leftY = header ? '30%' : '25%';\n leftSublabelY = header ? '40%' : '35%';\n rightY = header ? '60%' : '55%';\n rightSublabelY = header ? '70%' : '65%';\n } else {\n // Landscape/square: side by side — vertically centered in panels (15%-85%)\n const baseY = header ? '47%' : '45%';\n const sublabelOffset = header ? '58%' : '56%';\n leftY = baseY;\n leftSublabelY = sublabelOffset;\n rightY = baseY;\n rightSublabelY = sublabelOffset;\n }\n\n // Left column (or top in portrait)\n layers.push({\n type: 'text',\n id: 'left-label',\n content: {\n text: left.label,\n style: {\n fontSize: labelFontSize,\n fontFamily: getThemeFont(context, 'body'),\n fontWeight: 'bold',\n color: leftColors.text,\n textAlign: 'center',\n lineHeight: 1.3,\n },\n },\n position: {\n x: positions.left.x,\n y: leftY,\n anchor: 'center',\n width: columnWidth,\n },\n animation: { type: 'fadeIn', duration: 1 },\n });\n\n if (left.sublabel) {\n layers.push({\n type: 'text',\n id: 'left-sublabel',\n content: {\n text: left.sublabel,\n style: {\n fontSize: sublabelFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.textMuted,\n textAlign: 'center',\n lineHeight: 1.4,\n },\n },\n position: {\n x: positions.left.x,\n y: leftSublabelY,\n anchor: 'center',\n width: columnWidth,\n },\n animation: { type: 'fadeIn', duration: 0.8, delay: 0.3 },\n });\n }\n\n // Visual connector between columns (bold arrow)\n const connectorFontSize = scaledFontSize(120, context, true);\n const connectorY = isStacked ? '48%' : '50%'; // Centered in viewport\n const connectorSymbol = isStacked ? '\\u2193' : '\\u2192'; // ↓ for stacked, → for side-by-side\n\n layers.push({\n type: 'text',\n id: 'connector',\n content: {\n text: connectorSymbol,\n style: {\n fontSize: connectorFontSize,\n fontFamily: getThemeFont(context, 'title'),\n fontWeight: 'bold',\n color: 'rgba(255, 255, 255, 0.6)',\n textAlign: 'center',\n },\n },\n position: {\n x: '50%',\n y: connectorY,\n anchor: 'center',\n },\n animation: { type: 'fadeIn', duration: 0.6, delay: 0.4 },\n });\n\n // Right column (or bottom in portrait)\n layers.push({\n type: 'text',\n id: 'right-label',\n content: {\n text: right.label,\n style: {\n fontSize: labelFontSize,\n fontFamily: getThemeFont(context, 'body'),\n fontWeight: 'bold',\n color: rightColors.text,\n textAlign: 'center',\n lineHeight: 1.3,\n },\n },\n position: {\n x: positions.right.x,\n y: rightY,\n anchor: 'center',\n width: columnWidth,\n },\n animation: { type: 'fadeIn', duration: 1, delay: 0.5 },\n });\n\n if (right.sublabel) {\n layers.push({\n type: 'text',\n id: 'right-sublabel',\n content: {\n text: right.sublabel,\n style: {\n fontSize: sublabelFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.textMuted,\n textAlign: 'center',\n lineHeight: 1.4,\n },\n },\n position: {\n x: positions.right.x,\n y: rightSublabelY,\n anchor: 'center',\n width: columnWidth,\n },\n animation: { type: 'fadeIn', duration: 0.8, delay: 0.8 },\n });\n }\n\n return layers;\n}\n","/**\n * Date Event Template\n *\n * Timeline-style slide with prominent date and description.\n * Supports different moods: neutral, somber, celebratory.\n * Adapts font sizes and positioning for different viewports.\n *\n * Supports optional accent images that appear as tasteful side/bottom strips.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { DateEventInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { getThemeFont } from '../utils/themeUtils.js';\nimport { createAccentLayers, getAccentLayout, adjustY, DEFAULT_LAYOUT } from './accentImage.js';\n\nconst MOOD_COLORS = {\n neutral: { bg: '#1a202c', date: '#63b3ed', text: '#ffffff' },\n somber: { bg: '#1a1a2e', date: '#e53e3e', text: '#a0aec0' },\n celebratory: { bg: '#1a365d', date: '#68d391', text: '#ffffff' },\n};\n\nexport function dateEvent(input: DateEventInput, context: TemplateContext): Layer[] {\n const { date, description, footer, mood = 'neutral', accentImage } = input;\n const { theme } = context;\n const colors = MOOD_COLORS[mood];\n\n // Get layout adjustments if accent image is present\n const accentLayout = accentImage ? getAccentLayout(accentImage.position) : DEFAULT_LAYOUT;\n\n // Scale font sizes — date is the hero element\n const dateFontSize = scaledFontSize(96, context, true);\n const descFontSize = scaledFontSize(30, context, false);\n const footerFontSize = scaledFontSize(26, context, false);\n\n const layers: Layer[] = [\n // Background — unique diagonal gradient to differentiate from other dark templates\n {\n type: 'shape',\n id: 'bg',\n content: {\n shape: 'rect',\n fill: `linear-gradient(135deg, ${colors.bg} 0%, #0d1117 100%)`,\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n },\n ];\n\n // Add accent image layers (behind text, after background)\n if (accentImage) {\n layers.push(...createAccentLayers(accentImage, input.id));\n }\n\n // Date — hero element, much larger\n layers.push({\n type: 'text',\n id: 'date',\n content: {\n text: date,\n style: {\n fontSize: dateFontSize,\n fontFamily: getThemeFont(context, 'title'),\n fontWeight: 'bold',\n color: colors.date,\n shadow: !!accentImage,\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY('35%', accentLayout),\n anchor: 'center',\n },\n animation: { type: 'fadeIn', duration: 1.5 },\n });\n\n // Description - constrained width for proper text wrapping\n layers.push({\n type: 'text',\n id: 'description',\n content: {\n text: description,\n style: {\n fontSize: descFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: colors.text,\n textAlign: 'center',\n lineHeight: 1.8,\n shadow: !!accentImage,\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY('58%', accentLayout),\n width: accentLayout.textWidth,\n anchor: 'center',\n },\n animation: { type: 'fadeIn', duration: 2, delay: 1 },\n });\n\n // Add footer if provided\n if (footer) {\n layers.push({\n type: 'text',\n id: 'footer',\n content: {\n text: footer,\n style: {\n fontSize: footerFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.textMuted,\n shadow: !!accentImage,\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY('82%', accentLayout),\n anchor: 'center',\n },\n animation: { type: 'fadeIn', duration: 1, delay: 3 },\n });\n }\n\n return layers;\n}\n","/**\n * Image With Caption Template\n *\n * Full-screen background image with text overlay.\n * Supports Ken Burns animation effects (zoom, pan).\n * Adapts caption positioning and font sizes for different viewports.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { ImageWithCaptionInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { getThemeFont } from '../utils/themeUtils.js';\nimport { cleanCaption } from './captionUtils.js';\nimport { mapAmbientMotion } from './accentImage.js';\n\nexport function imageWithCaption(input: ImageWithCaptionInput, context: TemplateContext): Layer[] {\n const {\n imageSrc,\n imageAlt,\n caption: rawCaption,\n captionPosition: _captionPosition = 'bottom',\n ambientMotion,\n isTitle,\n subtitle,\n imageCredit,\n imageLicense,\n } = input;\n const caption = rawCaption ? cleanCaption(rawCaption) : rawCaption;\n const { theme, layout } = context;\n\n // Scale font sizes for viewport\n const captionFontSize = scaledFontSize(36, context, false);\n const titleFontSize = scaledFontSize(96, context, true);\n const subtitleFontSize = scaledFontSize(36, context, false);\n\n // Determine animation based on ambientMotion setting\n // Support both new 'ambientMotion' and legacy 'kenBurns' property\n const legacyKenBurns = (input as unknown as Record<string, unknown>).kenBurns as\n | string\n | undefined;\n const motion: string | undefined = ambientMotion || legacyKenBurns;\n const imageAnimation = mapAmbientMotion(motion);\n\n const layers: Layer[] = [\n // Background image\n {\n type: 'image',\n id: 'bg-image',\n content: {\n src: imageSrc,\n alt: imageAlt,\n fit: 'cover',\n credit: imageCredit,\n license: imageLicense,\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n animation: imageAnimation,\n },\n ];\n\n // TITLE MODE: Large centered title over hero image (like cover slide)\n if (isTitle && caption) {\n // Full gradient overlay for title readability (similar to cover slide)\n layers.push({\n type: 'shape',\n id: 'title-gradient',\n content: {\n shape: 'rect',\n fill: 'linear-gradient(0deg, rgba(0,0,0,0.8) 0%, rgba(0,0,0,0.4) 40%, rgba(0,0,0,0.1) 70%, transparent 100%)',\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n });\n\n // Title text - large and centered in lower portion\n layers.push({\n type: 'text',\n id: 'title',\n content: {\n text: caption,\n style: {\n fontSize: titleFontSize,\n fontFamily: getThemeFont(context, 'title'),\n fontWeight: 'bold',\n color: theme.colors.text,\n textAlign: 'center',\n shadow: true,\n },\n },\n position: {\n x: '50%',\n y: subtitle ? '70%' : '75%',\n anchor: 'center',\n width: layout.maxTextWidth,\n },\n animation: { type: 'fadeIn', duration: 0.8 },\n });\n\n // Optional subtitle\n if (subtitle) {\n layers.push({\n type: 'text',\n id: 'subtitle',\n content: {\n text: subtitle,\n style: {\n fontSize: subtitleFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.textMuted,\n textAlign: 'center',\n lineHeight: 1.5,\n },\n },\n position: {\n x: '50%',\n y: '82%',\n anchor: 'center',\n width: layout.maxTextWidth,\n },\n animation: { type: 'fadeIn', duration: 0.8, delay: 0.2 },\n });\n }\n\n return layers;\n }\n\n // STANDARD MODE: Caption at bottom\n if (caption) {\n // Subtle gradient at bottom for caption readability (raised above media controls)\n layers.push({\n type: 'shape',\n id: 'caption-gradient',\n content: {\n shape: 'rect',\n fill: 'linear-gradient(0deg, rgba(0,0,0,0.7) 0%, rgba(0,0,0,0.3) 60%, transparent 100%)',\n },\n position: {\n x: 0,\n y: '65%',\n width: '100%',\n height: '35%',\n },\n });\n\n // Caption text - raised above media controls\n layers.push({\n type: 'text',\n id: 'caption',\n content: {\n text: caption,\n style: {\n fontSize: captionFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.text,\n textAlign: 'center',\n shadow: true,\n },\n },\n position: {\n x: '50%',\n y: '82%',\n anchor: 'center',\n width: layout.maxTextWidth,\n },\n animation: { type: 'fadeIn', duration: 1.5, delay: 0.5 },\n });\n }\n\n return layers;\n}\n","/**\n * Map Block Template\n *\n * Full-screen geographic map with optional title and caption overlays.\n * Great for establishing geographic context at the start of a doc\n * or when discussing location-specific content.\n * Adapts font sizes and positioning for different viewports.\n *\n * Map tiles are fetched from free/open-source providers.\n * See docs/MAP_TILES.md for available styles and attribution requirements.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { MapBlockInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { getThemeFont } from '../utils/themeUtils.js';\nimport { mapAmbientMotion } from './accentImage.js';\n\nexport function mapBlock(input: MapBlockInput, context: TemplateContext): Layer[] {\n const {\n center,\n zoom,\n mapStyle = 'terrain',\n title,\n caption,\n markers,\n ambientMotion,\n staticSrc,\n } = input;\n const { theme, layout } = context;\n\n // Scale font sizes for viewport\n const titleFontSize = scaledFontSize(64, context, true);\n const captionFontSize = scaledFontSize(32, context, false);\n\n // Determine animation based on ambientMotion setting\n const mapAnimation = mapAmbientMotion(ambientMotion);\n\n const layers: Layer[] = [\n // Map background\n {\n type: 'map',\n id: 'map-bg',\n content: {\n center,\n zoom,\n style: mapStyle,\n markers,\n showAttribution: true,\n staticSrc, // Use pre-rendered image if available\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n animation: mapAnimation,\n },\n ];\n\n // Add title overlay if provided\n if (title) {\n // Gradient overlay at top for title readability\n layers.push({\n type: 'shape',\n id: 'title-overlay',\n content: {\n shape: 'rect',\n fill: 'rgba(0,0,0,0.6)',\n },\n position: { x: 0, y: 0, width: '100%', height: '18%' },\n });\n\n // Title text - positioned at top of slide\n layers.push({\n type: 'text',\n id: 'title',\n content: {\n text: title,\n style: {\n fontSize: titleFontSize,\n fontFamily: getThemeFont(context, 'title'),\n fontWeight: 'bold',\n color: theme.colors.text,\n textAlign: 'center',\n shadow: true,\n },\n },\n position: {\n x: '50%',\n y: '9%',\n anchor: 'center',\n width: layout.maxTextWidth,\n },\n animation: { type: 'fadeIn', duration: 1, delay: 0.3 },\n });\n }\n\n // Add caption if provided\n if (caption) {\n // Gradient overlay at bottom for caption readability\n layers.push({\n type: 'shape',\n id: 'caption-overlay',\n content: {\n shape: 'rect',\n fill: 'rgba(0,0,0,0.6)',\n },\n position: { x: 0, y: '82%', width: '100%', height: '18%' },\n });\n\n // Caption text\n layers.push({\n type: 'text',\n id: 'caption',\n content: {\n text: caption,\n style: {\n fontSize: captionFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.text,\n textAlign: 'center',\n shadow: true,\n },\n },\n position: {\n x: '50%',\n y: layout.captionY,\n anchor: 'center',\n width: layout.maxTextWidth,\n },\n animation: { type: 'fadeIn', duration: 1, delay: 0.5 },\n });\n }\n\n return layers;\n}\n","/**\n * Full Bleed Quote Template\n *\n * Short dramatic text filling the viewport like a movie title card.\n * Designed for punchy text under 60 characters. Uses massive font\n * centered on a dark vignette background.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { FullBleedQuoteInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { resolveColorScheme, getThemeFont } from '../utils/themeUtils.js';\n\nexport function fullBleedQuote(input: FullBleedQuoteInput, context: TemplateContext): Layer[] {\n const { text, colorScheme = 'blue' } = input;\n const { theme } = context;\n const colors = resolveColorScheme(context, colorScheme);\n\n // Massive font for dramatic impact\n const textFontSize = scaledFontSize(120, context, true);\n\n return [\n // Background — dark radial vignette for cinematic feel\n {\n type: 'shape',\n id: 'bg',\n content: {\n shape: 'rect',\n fill: `radial-gradient(ellipse at 50% 50%, ${theme.colors.backgroundLight} 0%, #000000 100%)`,\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n },\n // The text — massive, centered\n {\n type: 'text',\n id: 'impact-text',\n content: {\n text,\n style: {\n fontSize: textFontSize,\n fontFamily: getThemeFont(context, 'title'),\n fontWeight: 'bold',\n color: colors.text,\n textAlign: 'center',\n lineHeight: 1.2,\n shadow: true,\n },\n },\n position: {\n x: '50%',\n y: '50%',\n anchor: 'center',\n width: '85%',\n },\n animation: { type: 'fadeIn', duration: 1.5 },\n },\n ];\n}\n","/**\n * List Block Template\n *\n * Displays 3-5 items in a numbered vertical list with staggered animations.\n * Good for enumerations like \"things to see\", \"key features\", or \"tips\".\n * Supports optional accent images.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { ListBlockInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { getThemeFont } from '../utils/themeUtils.js';\nimport { createAccentLayers, getAccentLayout, adjustY, DEFAULT_LAYOUT } from './accentImage.js';\n\nexport function listBlock(input: ListBlockInput, context: TemplateContext): Layer[] {\n const { items, title, accentImage } = input;\n const { theme } = context;\n\n // Get layout adjustments if accent image is present\n const accentLayout = accentImage ? getAccentLayout(accentImage.position) : DEFAULT_LAYOUT;\n\n const titleFontSize = scaledFontSize(44, context, true);\n const itemFontSize = scaledFontSize(34, context, false);\n\n const layers: Layer[] = [\n // Background — gradient\n {\n type: 'shape',\n id: 'bg',\n content: {\n shape: 'rect',\n fill: `linear-gradient(155deg, ${theme.colors.backgroundLight} 0%, ${theme.colors.background} 100%)`,\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n },\n ];\n\n // Add accent image layers\n if (accentImage) {\n layers.push(...createAccentLayers(accentImage, input.id));\n }\n\n // Title if provided\n const startY = title ? 30 : 22;\n if (title) {\n layers.push({\n type: 'text',\n id: 'list-title',\n content: {\n text: title,\n style: {\n fontSize: titleFontSize,\n fontFamily: getThemeFont(context, 'title'),\n fontWeight: 'bold',\n color: theme.colors.text,\n textAlign: 'center',\n shadow: !!accentImage,\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY('16%', accentLayout),\n anchor: 'center',\n },\n animation: { type: 'fadeIn', duration: 1 },\n });\n }\n\n // Calculate vertical spacing for items\n const endY = 80;\n const spacing = items.length > 1 ? (endY - startY) / (items.length - 1) : 0;\n\n // List items with staggered animation\n for (let i = 0; i < items.length; i++) {\n const y = startY + spacing * i;\n const itemText = `${i + 1}. ${items[i]}`;\n\n layers.push({\n type: 'text',\n id: `item-${i}`,\n content: {\n text: itemText,\n style: {\n fontSize: itemFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.text,\n lineHeight: 1.4,\n shadow: !!accentImage,\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY(`${y}%`, accentLayout),\n anchor: 'center',\n width: accentLayout.textWidth,\n },\n animation: { type: 'fadeIn', duration: 0.8, delay: 0.3 + 0.3 * i },\n });\n }\n\n return layers;\n}\n","/**\n * Photo Grid Template\n *\n * Displays 2-4 images in a tiled layout for visual variety.\n * Layout adapts based on image count and viewport orientation:\n *\n * Landscape:\n * - 2 images: side-by-side 50/50\n * - 3 images: one large left (60%) + two stacked right\n * - 4 images: 2x2 grid\n *\n * Portrait (9:16): images stack horizontally (top/bottom) instead of\n * side-by-side, giving each image full width on narrow screens.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { PhotoGridInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { getThemeFont } from '../utils/themeUtils.js';\nimport { cleanCaption } from './captionUtils.js';\n\n/** Gap between images as percentage */\nconst GAP = 0.5;\n\nexport function photoGrid(input: PhotoGridInput, context: TemplateContext): Layer[] {\n const { images, caption: rawCaption, ambientMotion } = input;\n\n // Guard: images array is required\n if (!images || images.length === 0) return [];\n\n const caption = rawCaption ? cleanCaption(rawCaption) : rawCaption;\n const { theme, layout } = context;\n\n const layers: Layer[] = [\n // Black background (visible in gaps between images)\n {\n type: 'shape',\n id: 'bg',\n content: { shape: 'rect', fill: '#000000' },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n },\n ];\n\n // Reserve bottom space for caption — more room in landscape for larger text\n const captionHeight = caption ? (layout.stackColumns ? 18 : 22) : 0;\n const gridHeight = 100 - captionHeight;\n\n // Generate image positions based on count; stack vertically in portrait\n const positions = getGridPositions(images.length, gridHeight, layout.stackColumns);\n\n const altFontSize = scaledFontSize(24, context, false);\n\n for (let i = 0; i < Math.min(images.length, 4); i++) {\n const img = images[i];\n const pos = positions[i];\n\n // Placeholder behind image (visible if image fails to load)\n layers.push({\n type: 'shape',\n id: `grid-placeholder-${i}`,\n content: { shape: 'rect', fill: theme.colors.background },\n position: { x: `${pos.x}%`, y: `${pos.y}%`, width: `${pos.w}%`, height: `${pos.h}%` },\n });\n\n // Alt-text label on placeholder\n if (img.alt) {\n layers.push({\n type: 'text',\n id: `grid-alt-${i}`,\n content: {\n text: img.alt,\n style: {\n fontSize: altFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.textMuted,\n textAlign: 'center' as const,\n },\n },\n position: { x: `${pos.x + pos.w / 2}%`, y: `${pos.y + pos.h / 2}%`, anchor: 'center' },\n });\n }\n\n // Image layer (covers placeholder when loaded)\n layers.push({\n type: 'image',\n id: `grid-img-${i}`,\n content: {\n src: img.src,\n alt: img.alt,\n fit: 'cover',\n credit: img.credit,\n license: img.license,\n },\n position: {\n x: `${pos.x}%`,\n y: `${pos.y}%`,\n width: `${pos.w}%`,\n height: `${pos.h}%`,\n },\n // Apply ambient motion to the first (largest) image only\n animation:\n i === 0 && ambientMotion\n ? { type: ambientMotion, duration: 15 }\n : { type: 'fadeIn', duration: 1, delay: 0.2 * i },\n });\n }\n\n // Caption with gradient overlay\n if (caption) {\n const captionFontSize = scaledFontSize(layout.stackColumns ? 28 : 40, context, false);\n\n layers.push({\n type: 'shape',\n id: 'caption-bg',\n content: {\n shape: 'rect',\n fill: 'linear-gradient(transparent, rgba(0,0,0,0.8))',\n },\n position: { x: 0, y: `${gridHeight - 4}%`, width: '100%', height: `${captionHeight + 4}%` },\n });\n\n layers.push({\n type: 'text',\n id: 'caption',\n content: {\n text: caption,\n style: {\n fontSize: captionFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.text,\n textAlign: 'center',\n shadow: true,\n },\n },\n position: {\n x: '50%',\n y: `${gridHeight + (layout.stackColumns ? captionHeight / 2 : captionHeight * 0.3)}%`,\n anchor: 'center',\n width: '90%',\n },\n animation: { type: 'fadeIn', duration: 1, delay: 0.5 },\n });\n }\n\n return layers;\n}\n\ninterface GridPos {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nfunction getGridPositions(count: number, gridHeight: number, stacked: boolean): GridPos[] {\n const halfW = 50 - GAP / 2;\n const halfH = gridHeight / 2 - GAP / 2;\n\n switch (count) {\n case 2:\n if (stacked) {\n // Portrait: stack top/bottom\n return [\n { x: 0, y: 0, w: 100, h: halfH },\n { x: 0, y: gridHeight / 2 + GAP / 2, w: 100, h: halfH },\n ];\n }\n return [\n { x: 0, y: 0, w: halfW, h: gridHeight },\n { x: 50 + GAP / 2, y: 0, w: halfW, h: gridHeight },\n ];\n case 3: {\n if (stacked) {\n // Portrait: stack all three vertically\n const thirdH = gridHeight / 3 - (GAP * 2) / 3;\n return [\n { x: 0, y: 0, w: 100, h: thirdH },\n { x: 0, y: gridHeight / 3 + GAP / 3, w: 100, h: thirdH },\n { x: 0, y: (gridHeight * 2) / 3 + (GAP * 2) / 3, w: 100, h: thirdH },\n ];\n }\n const leftW = 60 - GAP / 2;\n const rightW = 40 - GAP / 2;\n return [\n { x: 0, y: 0, w: leftW, h: gridHeight },\n { x: 60 + GAP / 2, y: 0, w: rightW, h: halfH },\n { x: 60 + GAP / 2, y: gridHeight / 2 + GAP / 2, w: rightW, h: halfH },\n ];\n }\n case 4:\n default:\n // 2x2 grid works well in both orientations\n return [\n { x: 0, y: 0, w: halfW, h: halfH },\n { x: 50 + GAP / 2, y: 0, w: halfW, h: halfH },\n { x: 0, y: gridHeight / 2 + GAP / 2, w: halfW, h: halfH },\n { x: 50 + GAP / 2, y: gridHeight / 2 + GAP / 2, w: halfW, h: halfH },\n ];\n }\n}\n","/**\n * Definition Card Template\n *\n * Dictionary-style slide with a large term and its definition.\n * Good for explaining local words, place names, or cultural concepts.\n * Supports optional accent images.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { DefinitionCardInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { resolveColorScheme, getThemeFont } from '../utils/themeUtils.js';\nimport { createAccentLayers, getAccentLayout, adjustY, DEFAULT_LAYOUT } from './accentImage.js';\nimport { createBackgroundLayer } from './captionUtils.js';\n\nexport function definitionCard(input: DefinitionCardInput, context: TemplateContext): Layer[] {\n const { term, definition, origin, colorScheme = 'blue', accentImage } = input;\n const { theme } = context;\n const colors = resolveColorScheme(context, colorScheme);\n\n // Get layout adjustments if accent image is present\n const accentLayout = accentImage ? getAccentLayout(accentImage.position) : DEFAULT_LAYOUT;\n\n const termFontSize = scaledFontSize(72, context, true);\n const defFontSize = scaledFontSize(32, context, false);\n const originFontSize = scaledFontSize(22, context, false);\n\n const layers: Layer[] = [\n createBackgroundLayer(\n 'bg',\n `linear-gradient(145deg, #1e2030 0%, ${theme.colors.background} 100%)`,\n ),\n ];\n\n // Add accent image layers\n if (accentImage) {\n layers.push(...createAccentLayers(accentImage, input.id));\n }\n\n // Term — large, accent-colored\n layers.push({\n type: 'text',\n id: 'term',\n content: {\n text: term,\n style: {\n fontSize: termFontSize,\n fontFamily: getThemeFont(context, 'title'),\n fontWeight: 'bold',\n color: colors.text,\n textAlign: 'center',\n shadow: !!accentImage,\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY('30%', accentLayout),\n anchor: 'center',\n },\n animation: { type: 'fadeIn', duration: 1.5 },\n });\n\n // Horizontal separator line\n layers.push({\n type: 'shape',\n id: 'separator',\n content: {\n shape: 'rect',\n fill: `${colors.text}33`, // accent color at 20% opacity\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY('42%', accentLayout),\n width: '30%',\n height: '2px',\n anchor: 'center',\n },\n });\n\n // Definition text\n layers.push({\n type: 'text',\n id: 'definition',\n content: {\n text: definition,\n style: {\n fontSize: defFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.text,\n textAlign: 'center',\n lineHeight: 1.6,\n maxLines: 4,\n shadow: !!accentImage,\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY('55%', accentLayout),\n width: accentLayout.textWidth,\n anchor: 'center',\n },\n animation: { type: 'fadeIn', duration: 1, delay: 0.8 },\n });\n\n // Origin if provided\n if (origin) {\n layers.push({\n type: 'text',\n id: 'origin',\n content: {\n text: origin,\n style: {\n fontSize: originFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.textMuted,\n textAlign: 'center',\n shadow: !!accentImage,\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY('78%', accentLayout),\n anchor: 'center',\n },\n animation: { type: 'fadeIn', duration: 0.8, delay: 1.5 },\n });\n }\n\n return layers;\n}\n","/**\n * Comparison Bar Template\n *\n * Two horizontal bars showing relative numeric values side by side.\n * Bar widths are proportional to the values for immediate visual comparison.\n * Good for population, distance, or measurement comparisons.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { ComparisonBarInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { resolveColorScheme, getThemeFont } from '../utils/themeUtils.js';\n\nexport function comparisonBar(input: ComparisonBarInput, context: TemplateContext): Layer[] {\n const { leftLabel, leftValue, rightLabel, rightValue, unit, colorScheme = 'blue' } = input;\n const { theme } = context;\n const colors = resolveColorScheme(context, colorScheme);\n\n const labelFontSize = scaledFontSize(28, context, false);\n const valueFontSize = scaledFontSize(48, context, true);\n\n // Calculate proportional bar widths (max bar = 65% of viewport width)\n const maxValue = Math.max(leftValue, rightValue, 1);\n const maxBarWidth = 65;\n const leftBarWidth = (leftValue / maxValue) * maxBarWidth;\n const rightBarWidth = (rightValue / maxValue) * maxBarWidth;\n\n // Bar positioning\n const barStartX = 15;\n const barHeight = 6; // % of viewport height\n const topBarY = 36;\n const bottomBarY = 58;\n\n // Format values for display\n const formatValue = (v: number): string => {\n if (v >= 1_000_000) return `${(v / 1_000_000).toFixed(1)}M`;\n if (v >= 1_000) return `${(v / 1_000).toFixed(v >= 10_000 ? 0 : 1)}K`;\n return v.toLocaleString();\n };\n\n const leftDisplay = unit ? `${formatValue(leftValue)} ${unit}` : formatValue(leftValue);\n const rightDisplay = unit ? `${formatValue(rightValue)} ${unit}` : formatValue(rightValue);\n\n return [\n // Background\n {\n type: 'shape',\n id: 'bg',\n content: {\n shape: 'rect',\n fill: `linear-gradient(180deg, ${theme.colors.background} 0%, #0f1520 100%)`,\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n },\n\n // Top bar label\n {\n type: 'text',\n id: 'left-label',\n content: {\n text: leftLabel,\n style: {\n fontSize: labelFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.textMuted,\n },\n },\n position: { x: `${barStartX}%`, y: `${topBarY - 8}%` },\n },\n\n // Top bar value\n {\n type: 'text',\n id: 'left-value',\n content: {\n text: leftDisplay,\n style: {\n fontSize: valueFontSize,\n fontFamily: getThemeFont(context, 'body'),\n fontWeight: 'bold',\n color: colors.text,\n },\n },\n position: { x: `${barStartX + leftBarWidth + 2}%`, y: `${topBarY - 1}%` },\n animation: { type: 'fadeIn', duration: 0.8, delay: 0.3 },\n },\n\n // Top bar\n {\n type: 'shape',\n id: 'left-bar',\n content: {\n shape: 'rect',\n fill: colors.text,\n borderRadius: 4,\n },\n position: {\n x: `${barStartX}%`,\n y: `${topBarY}%`,\n width: `${leftBarWidth}%`,\n height: `${barHeight}%`,\n },\n animation: { type: 'fadeIn', duration: 1 },\n },\n\n // Bottom bar label\n {\n type: 'text',\n id: 'right-label',\n content: {\n text: rightLabel,\n style: {\n fontSize: labelFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.textMuted,\n },\n },\n position: { x: `${barStartX}%`, y: `${bottomBarY - 8}%` },\n },\n\n // Bottom bar value\n {\n type: 'text',\n id: 'right-value',\n content: {\n text: rightDisplay,\n style: {\n fontSize: valueFontSize,\n fontFamily: getThemeFont(context, 'body'),\n fontWeight: 'bold',\n color: colors.accent,\n },\n },\n position: { x: `${barStartX + rightBarWidth + 2}%`, y: `${bottomBarY - 1}%` },\n animation: { type: 'fadeIn', duration: 0.8, delay: 0.6 },\n },\n\n // Bottom bar\n {\n type: 'shape',\n id: 'right-bar',\n content: {\n shape: 'rect',\n fill: colors.accent,\n borderRadius: 4,\n },\n position: {\n x: `${barStartX}%`,\n y: `${bottomBarY}%`,\n width: `${rightBarWidth}%`,\n height: `${barHeight}%`,\n },\n animation: { type: 'fadeIn', duration: 1, delay: 0.3 },\n },\n ];\n}\n","/**\n * Pull Quote Template\n *\n * Quote text over a full-bleed background image with dark overlay.\n * Cinematic alternative to quoteBlock when a high-quality image is available.\n * Combines the visual impact of imageWithCaption with the text focus of quoteBlock.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { PullQuoteInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { getThemeFont } from '../utils/themeUtils.js';\n\nexport function pullQuote(input: PullQuoteInput, context: TemplateContext): Layer[] {\n const { text, attribution, backgroundImage, ambientMotion } = input;\n\n // Guard: backgroundImage is required\n if (!backgroundImage?.src) return [];\n\n const quoteFontSize = scaledFontSize(52, context, true);\n const attrFontSize = scaledFontSize(24, context, false);\n const decoFontSize = scaledFontSize(200, context, true);\n\n const layers: Layer[] = [\n // Full-bleed background image\n {\n type: 'image',\n id: 'bg-image',\n content: {\n src: backgroundImage.src,\n alt: backgroundImage.alt,\n fit: 'cover',\n credit: backgroundImage.credit,\n license: backgroundImage.license,\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n animation: ambientMotion ? { type: ambientMotion, duration: 15 } : undefined,\n },\n\n // Dark overlay for text readability\n {\n type: 'shape',\n id: 'overlay',\n content: {\n shape: 'rect',\n fill: 'rgba(0, 0, 0, 0.55)',\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n },\n\n // Decorative quotation mark\n {\n type: 'text',\n id: 'deco-quote',\n content: {\n text: '\\u201C',\n style: {\n fontSize: decoFontSize,\n fontFamily: getThemeFont(context, 'title'),\n color: 'rgba(255, 255, 255, 0.08)',\n textAlign: 'center',\n },\n },\n position: {\n x: '50%',\n y: '20%',\n anchor: 'center',\n },\n },\n\n // Quote text\n {\n type: 'text',\n id: 'quote-text',\n content: {\n text,\n style: {\n fontSize: quoteFontSize,\n fontFamily: getThemeFont(context, 'title'),\n color: '#ffffff',\n textAlign: 'center',\n lineHeight: 1.5,\n shadow: true,\n },\n },\n position: {\n x: '50%',\n y: attribution ? '45%' : '50%',\n anchor: 'center',\n width: '80%',\n },\n animation: { type: 'fadeIn', duration: 2 },\n },\n ];\n\n // Attribution\n if (attribution) {\n layers.push({\n type: 'text',\n id: 'attribution',\n content: {\n text: `\\u2014 ${attribution}`,\n style: {\n fontSize: attrFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: 'rgba(255, 255, 255, 0.7)',\n textAlign: 'center',\n shadow: true,\n },\n },\n position: {\n x: '50%',\n y: '72%',\n anchor: 'center',\n },\n animation: { type: 'fadeIn', duration: 1, delay: 1.5 },\n });\n }\n\n return layers;\n}\n","/**\n * Video With Caption Template\n *\n * Full-screen background video clip with text overlay. Mirrors the structure of\n * imageWithCaption but uses a VideoLayer instead of an ImageLayer. The video\n * plays muted — narration audio is the only sound track.\n *\n * Adapts caption positioning and font sizes for different viewports.\n *\n * This is shared code used by both site and efb-app doc renderers.\n *\n * Related Files:\n * - shared/story/templates/imageWithCaption.ts — image equivalent\n * - schemas/StoryScript.ts — VideoLayer type\n * - site/src/components/story/layers/VideoLayer.tsx — rendering component\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { VideoWithCaptionInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { getThemeFont } from '../utils/themeUtils.js';\nimport { cleanCaption } from './captionUtils.js';\n\nexport function videoWithCaption(input: VideoWithCaptionInput, context: TemplateContext): Layer[] {\n const {\n videoSrc,\n posterSrc,\n videoAlt,\n clipStart,\n clipEnd,\n sourceDuration,\n caption: rawCaption,\n captionPosition = 'bottom',\n videoCredit,\n videoLicense,\n } = input;\n const caption = rawCaption ? cleanCaption(rawCaption) : rawCaption;\n const { theme, layout } = context;\n\n const captionFontSize = scaledFontSize(36, context, false);\n const creditFontSize = scaledFontSize(16, context, false);\n\n const layers: Layer[] = [\n // Background video clip\n {\n type: 'video',\n id: 'bg-video',\n content: {\n src: videoSrc,\n posterSrc,\n alt: videoAlt,\n fit: 'cover',\n clipStart,\n clipEnd,\n sourceDuration,\n credit: videoCredit,\n license: videoLicense,\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n },\n ];\n\n // Caption text at bottom with gradient for readability\n if (caption) {\n layers.push({\n type: 'shape',\n id: 'caption-gradient',\n content: {\n shape: 'rect',\n fill: 'linear-gradient(0deg, rgba(0,0,0,0.7) 0%, rgba(0,0,0,0.3) 60%, transparent 100%)',\n },\n position: {\n x: 0,\n y: captionPosition === 'top' ? 0 : '65%',\n width: '100%',\n height: '35%',\n },\n });\n\n const captionY =\n captionPosition === 'top' ? '15%' : captionPosition === 'center' ? '50%' : '82%';\n\n layers.push({\n type: 'text',\n id: 'caption',\n content: {\n text: caption,\n style: {\n fontSize: captionFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.text,\n textAlign: 'center',\n shadow: true,\n },\n },\n position: {\n x: '50%',\n y: captionY,\n anchor: 'center',\n width: layout.maxTextWidth,\n },\n animation: { type: 'fadeIn', duration: 1.5, delay: 0.5 },\n });\n }\n\n // Small credit text in bottom-right corner\n if (videoCredit) {\n layers.push({\n type: 'text',\n id: 'credit',\n content: {\n text: videoCredit,\n style: {\n fontSize: creditFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: 'rgba(255, 255, 255, 0.5)',\n textAlign: 'right',\n },\n },\n position: {\n x: '96%',\n y: '96%',\n anchor: 'bottom-right',\n },\n });\n }\n\n return layers;\n}\n","/**\n * Video Pull Quote Template\n *\n * Quote text over a video clip background with dark overlay.\n * Cinematic alternative to pullQuote when a video clip is available.\n * Combines the visual dynamism of live video with the text focus of quoteBlock.\n *\n * The video plays muted — narration audio is the only sound track.\n *\n * This is shared code used by both site and efb-app doc renderers.\n *\n * Related Files:\n * - shared/story/templates/pullQuote.ts — image-based equivalent\n * - schemas/StoryScript.ts — VideoLayer type\n * - site/src/components/story/layers/VideoLayer.tsx — rendering component\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { VideoPullQuoteInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { getThemeFont } from '../utils/themeUtils.js';\n\nexport function videoPullQuote(input: VideoPullQuoteInput, context: TemplateContext): Layer[] {\n const { text, attribution, backgroundVideo } = input;\n\n // Guard: backgroundVideo is required\n if (!backgroundVideo?.src) return [];\n\n const quoteFontSize = scaledFontSize(52, context, true);\n const attrFontSize = scaledFontSize(24, context, false);\n const decoFontSize = scaledFontSize(200, context, true);\n\n const layers: Layer[] = [\n // Full-bleed background video clip\n {\n type: 'video',\n id: 'bg-video',\n content: {\n src: backgroundVideo.src,\n posterSrc: backgroundVideo.posterSrc,\n alt: backgroundVideo.alt,\n fit: 'cover',\n clipStart: backgroundVideo.clipStart,\n clipEnd: backgroundVideo.clipEnd,\n credit: backgroundVideo.credit,\n license: backgroundVideo.license,\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n },\n\n // Dark overlay for text readability\n {\n type: 'shape',\n id: 'overlay',\n content: {\n shape: 'rect',\n fill: 'rgba(0, 0, 0, 0.55)',\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n },\n\n // Decorative quotation mark\n {\n type: 'text',\n id: 'deco-quote',\n content: {\n text: '\\u201C',\n style: {\n fontSize: decoFontSize,\n fontFamily: getThemeFont(context, 'title'),\n color: 'rgba(255, 255, 255, 0.08)',\n textAlign: 'center',\n },\n },\n position: {\n x: '50%',\n y: '20%',\n anchor: 'center',\n },\n },\n\n // Quote text\n {\n type: 'text',\n id: 'quote-text',\n content: {\n text,\n style: {\n fontSize: quoteFontSize,\n fontFamily: getThemeFont(context, 'title'),\n color: '#ffffff',\n textAlign: 'center',\n lineHeight: 1.5,\n shadow: true,\n },\n },\n position: {\n x: '50%',\n y: attribution ? '45%' : '50%',\n anchor: 'center',\n width: '80%',\n },\n animation: { type: 'fadeIn', duration: 2 },\n },\n ];\n\n // Attribution\n if (attribution) {\n layers.push({\n type: 'text',\n id: 'attribution',\n content: {\n text: `\\u2014 ${attribution}`,\n style: {\n fontSize: attrFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: 'rgba(255, 255, 255, 0.7)',\n textAlign: 'center',\n shadow: true,\n },\n },\n position: {\n x: '50%',\n y: '72%',\n anchor: 'center',\n },\n animation: { type: 'fadeIn', duration: 1, delay: 1.5 },\n });\n }\n\n return layers;\n}\n","/**\n * Cover Block Template\n *\n * Full-screen hero image with title overlay, shown before playback starts.\n * This is the \"poster for the doc, displaying the\n * article's hero image with elegant title treatment.\n *\n * Features:\n * - Full-screen hero image with Ken Burns ambient motion\n * - Gradient overlay for text readability\n * - Large centered title with optional subtitle\n * - No animation delays (shown at rest, not during playback)\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport type { StartBlockConfig } from '../../schemas/Doc.js';\nimport { getThemeFont } from '../utils/themeUtils.js';\nimport { mapAmbientMotion } from './accentImage.js';\n\n/**\n * Input for coverBlock template - matches StartBlockConfig\n */\nexport interface CoverBlockInput {\n /** Path to hero image */\n heroSrc: string;\n /** Alt text for the hero image */\n heroAlt?: string;\n /** Title to display over the hero */\n title: string;\n /** Optional subtitle */\n subtitle?: string;\n /** Ambient motion for the hero image */\n ambientMotion?: 'zoomIn' | 'zoomOut' | 'panLeft' | 'panRight';\n /** Photo credit / artist name */\n heroCredit?: string;\n /** License identifier */\n heroLicense?: string;\n}\n\n/**\n * Generate cover block layers from StartBlockConfig.\n */\nexport function coverBlock(input: CoverBlockInput, context: TemplateContext): Layer[] {\n const { heroSrc, heroAlt, title, subtitle, ambientMotion, heroCredit, heroLicense } = input;\n const { theme, layout } = context;\n\n // Scale font sizes for viewport - use larger sizes for the cover\n const titleFontSize = scaledFontSize(96, context, true);\n const subtitleFontSize = scaledFontSize(36, context, false);\n\n // Determine Ken Burns animation\n const imageAnimation = mapAmbientMotion(ambientMotion);\n\n const layers: Layer[] = [\n // Full-screen hero image\n {\n type: 'image',\n id: 'cover-hero',\n content: {\n src: heroSrc,\n alt: heroAlt || title,\n fit: 'cover',\n credit: heroCredit,\n license: heroLicense,\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n animation: imageAnimation,\n },\n // Gradient overlay for text readability - from bottom\n {\n type: 'shape',\n id: 'cover-gradient',\n content: {\n shape: 'rect',\n fill: 'linear-gradient(0deg, rgba(0,0,0,0.8) 0%, rgba(0,0,0,0.4) 40%, rgba(0,0,0,0.1) 70%, transparent 100%)',\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n },\n // Title - positioned lower in the frame to work with hero composition\n {\n type: 'text',\n id: 'cover-title',\n content: {\n text: title,\n style: {\n fontSize: titleFontSize,\n fontFamily: getThemeFont(context, 'title'),\n fontWeight: 'bold',\n color: theme.colors.text,\n textAlign: 'center',\n shadow: true,\n },\n },\n position: {\n x: '50%',\n y: subtitle ? '70%' : '75%',\n anchor: 'center',\n width: layout.maxTextWidth,\n },\n // No animation delay - shown immediately at rest\n animation: { type: 'fadeIn', duration: 0.8 },\n },\n ];\n\n // Add subtitle if provided\n if (subtitle) {\n layers.push({\n type: 'text',\n id: 'cover-subtitle',\n content: {\n text: subtitle,\n style: {\n fontSize: subtitleFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.textMuted,\n textAlign: 'center',\n lineHeight: 1.5,\n },\n },\n position: {\n x: '50%',\n y: '82%',\n anchor: 'center',\n width: layout.maxTextWidth,\n },\n animation: { type: 'fadeIn', duration: 0.8, delay: 0.2 },\n });\n }\n\n return layers;\n}\n\n/**\n * Convert StartBlockConfig to CoverBlockInput.\n */\nexport function startBlockToCoverInput(config: StartBlockConfig): CoverBlockInput {\n return {\n heroSrc: config.heroSrc,\n heroAlt: config.heroAlt,\n title: config.title,\n subtitle: config.subtitle,\n ambientMotion: config.ambientMotion,\n heroCredit: config.heroCredit,\n heroLicense: config.heroLicense,\n };\n}\n\n/**\n * Expand a StartBlockConfig into a renderable Block.\n * This is used by the player to render the cover block at rest.\n */\nexport function expandCoverBlock(config: StartBlockConfig, context: TemplateContext): Layer[] {\n const input = startBlockToCoverInput(config);\n return coverBlock(input, context);\n}\n","/**\n * Block Template Registry\n *\n * Central registry of all block templates. Provides functions to:\n * - Look up templates by name\n * - Expand template blocks into full Layer arrays\n * - Convert a template-based doc script into a renderable format\n *\n * Supports multiple viewport configurations for different aspect ratios.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Block, Layer } from '../../schemas/Doc.js';\nimport type {\n TemplateBlock,\n TemplateContext,\n TemplateRegistry,\n DocBlock,\n PersistentLayerConfig,\n} from '../../schemas/BlockTemplates.js';\nimport type { Theme } from '../../schemas/Theme.js';\nimport { isTemplateBlock, createTemplateContext } from '../../schemas/BlockTemplates.js';\nimport { DEFAULT_THEME as defaultTheme } from '../../schemas/themeLibrary.js';\nimport { expandPersistentLayers } from './persistentLayers.js';\nimport type { ViewportConfig } from '../../schemas/Viewport.js';\nimport { VIEWPORT_PRESETS } from '../../schemas/Viewport.js';\n\n// Import all template functions\nimport { titleBlock } from './titleBlock.js';\nimport { sectionHeader } from './sectionHeader.js';\nimport { statHighlight } from './statHighlight.js';\nimport { quoteBlock } from './quoteBlock.js';\nimport { factCard } from './factCard.js';\nimport { twoColumn } from './twoColumn.js';\nimport { dateEvent } from './dateEvent.js';\nimport { imageWithCaption } from './imageWithCaption.js';\nimport { mapBlock } from './mapBlock.js';\nimport { fullBleedQuote } from './fullBleedQuote.js';\nimport { listBlock } from './listBlock.js';\nimport { photoGrid } from './photoGrid.js';\nimport { definitionCard } from './definitionCard.js';\nimport { comparisonBar } from './comparisonBar.js';\nimport { pullQuote } from './pullQuote.js';\nimport { videoWithCaption } from './videoWithCaption.js';\nimport { videoPullQuote } from './videoPullQuote.js';\n\n/**\n * Registry mapping template names to their implementation functions.\n * Note: coverBlock is not in the registry as it's used directly for start blocks,\n * not as a regular template in the block sequence.\n */\nexport const templateRegistry: TemplateRegistry = {\n titleBlock,\n sectionHeader,\n statHighlight,\n quoteBlock,\n factCard,\n twoColumn,\n dateEvent,\n imageWithCaption,\n mapBlock,\n fullBleedQuote,\n listBlock,\n photoGrid,\n definitionCard,\n comparisonBar,\n pullQuote,\n videoWithCaption,\n videoPullQuote,\n};\n\n/**\n * Expand a template block into a full Block with layers.\n */\nexport function expandTemplateBlock(templateBlock: TemplateBlock, context: TemplateContext): Block {\n const templateFn = templateRegistry[templateBlock.template];\n\n if (!templateFn) {\n console.warn(`Unknown template: ${templateBlock.template}`);\n // Return block with no layers\n return {\n id: templateBlock.id,\n startTime: 0,\n duration: templateBlock.duration,\n audioSegment: templateBlock.audioSegment,\n transition: templateBlock.transition,\n template: templateBlock.template, // Preserve for debugging\n };\n }\n\n // Generate layers from template with error handling\n let layers: Layer[];\n try {\n // Each registry entry accepts its specific TemplateBlock variant; the\n // discriminated union guarantees the shapes match at runtime.\n layers = (templateFn as (input: TemplateBlock, ctx: TemplateContext) => Layer[])(\n templateBlock,\n context,\n );\n if (!Array.isArray(layers)) {\n console.error(\n `Template ${templateBlock.template} did not return an array, got:`,\n typeof layers,\n );\n layers = [];\n }\n } catch (err: unknown) {\n console.error(`Error expanding template ${templateBlock.template}:`, err);\n layers = [];\n }\n\n return {\n id: templateBlock.id,\n startTime: 0, // Will be calculated later\n duration: templateBlock.duration,\n audioSegment: templateBlock.audioSegment,\n ...(layers.length > 0 ? { layers } : {}),\n transition: templateBlock.transition,\n template: templateBlock.template, // Preserve for debugging\n };\n}\n\n/**\n * Audio segment timing info for aligning blocks with audio.\n */\nexport interface AudioSegmentTiming {\n /** Start time of this segment in the overall timeline */\n startTime: number;\n /** Duration of this segment */\n duration: number;\n}\n\n/**\n * Options for expanding doc blocks.\n */\nexport interface ExpandDocBlocksOptions {\n /** Theme for template rendering (defaults to DEFAULT_THEME) */\n theme?: Theme;\n /** Viewport configuration (defaults to 16:9 landscape) */\n viewport?: ViewportConfig;\n /** Persistent layers for visual consistency across blocks */\n persistentLayers?: PersistentLayerConfig;\n /**\n * Audio segment timing information.\n * When provided, blocks are timed relative to their audio segment's start time,\n * ensuring proper synchronization with audio playback.\n */\n audioSegments?: AudioSegmentTiming[];\n}\n\n/**\n * Expand all template blocks in a doc, calculating start times.\n * Injects persistent layers (bottom/top) based on per-block flags.\n *\n * When audioSegments is provided, blocks are timed relative to their audio segment's\n * start time, ensuring blocks appear when their audio is playing. Blocks within each\n * segment are distributed proportionally across the segment duration.\n *\n * @param blocks - Array of template or raw blocks\n * @param options - Expansion options including theme, viewport, and persistent layers\n */\nexport function expandDocBlocks(blocks: DocBlock[], options: ExpandDocBlocksOptions = {}): Block[] {\n const opts: ExpandDocBlocksOptions = options;\n\n const theme = opts.theme ?? defaultTheme;\n const viewport = opts.viewport ?? VIEWPORT_PRESETS.landscape;\n const { persistentLayers, audioSegments } = opts;\n const totalBlocks = blocks.length;\n\n // Pre-expand persistent layers once\n const bottomLayers = expandPersistentLayers(persistentLayers?.bottomLayers);\n const topLayers = expandPersistentLayers(persistentLayers?.topLayers);\n\n // If no audio segments provided, use simple cumulative timing\n if (!audioSegments || audioSegments.length === 0) {\n let currentTime = 0;\n return blocks.map((block, index) => {\n const context = createTemplateContext(theme, index, totalBlocks, viewport);\n const expandedBlock = isTemplateBlock(block)\n ? expandTemplateBlock(block, context)\n : (block as Block);\n\n // Inject persistent layers\n const templateBlock = block as TemplateBlock;\n const useBottom = templateBlock.useBottomLayer !== false;\n const useTop = templateBlock.useTopLayer !== false;\n if (bottomLayers.length > 0 || topLayers.length > 0) {\n expandedBlock.layers = [\n ...(useBottom ? bottomLayers : []),\n ...(expandedBlock.layers ?? []),\n ...(useTop ? topLayers : []),\n ];\n }\n\n expandedBlock.startTime = currentTime;\n currentTime += expandedBlock.duration;\n return expandedBlock;\n });\n }\n\n // Group blocks by their audioSegment index\n const blocksBySegment = new Map<number, { block: DocBlock; originalIndex: number }[]>();\n blocks.forEach((block, index) => {\n const segmentIndex = (block as TemplateBlock).audioSegment ?? 0;\n if (!blocksBySegment.has(segmentIndex)) {\n blocksBySegment.set(segmentIndex, []);\n }\n blocksBySegment.get(segmentIndex)!.push({ block, originalIndex: index });\n });\n\n // Expand blocks, timing them relative to their audio segment\n const expandedBlocks: Block[] = new Array(blocks.length);\n\n for (const [segmentIndex, segmentBlocks] of blocksBySegment) {\n const audioSegment = audioSegments[segmentIndex];\n if (!audioSegment) {\n // No audio segment info - use simple sequential timing within the segment\n let offsetTime = 0;\n for (const { block, originalIndex } of segmentBlocks) {\n const context = createTemplateContext(theme, originalIndex, totalBlocks, viewport);\n const expandedBlock = isTemplateBlock(block)\n ? expandTemplateBlock(block, context)\n : (block as Block);\n\n const templateBlock = block as TemplateBlock;\n const useBottom = templateBlock.useBottomLayer !== false;\n const useTop = templateBlock.useTopLayer !== false;\n if (bottomLayers.length > 0 || topLayers.length > 0) {\n expandedBlock.layers = [\n ...(useBottom ? bottomLayers : []),\n ...(expandedBlock.layers ?? []),\n ...(useTop ? topLayers : []),\n ];\n }\n\n expandedBlock.startTime = offsetTime;\n offsetTime += expandedBlock.duration;\n expandedBlocks[originalIndex] = expandedBlock;\n }\n continue;\n }\n\n // Section headers (sectionHeader template) get their original duration since\n // the title is spoken at the start of the segment. Other blocks are scaled\n // to fill the remaining time.\n const sectionHeaderBlocks: typeof segmentBlocks = [];\n const contentBlocks: typeof segmentBlocks = [];\n\n for (const item of segmentBlocks) {\n const templateBlock = item.block as TemplateBlock;\n if (templateBlock.template === 'sectionHeader') {\n sectionHeaderBlocks.push(item);\n } else {\n contentBlocks.push(item);\n }\n }\n\n // Calculate fixed duration (section headers) and scalable duration (content)\n const fixedDuration = sectionHeaderBlocks.reduce((sum, { block }) => {\n return sum + ((block as TemplateBlock).duration ?? 0);\n }, 0);\n\n const contentBlockDuration = contentBlocks.reduce((sum, { block }) => {\n return sum + ((block as TemplateBlock).duration ?? 0);\n }, 0);\n\n // Remaining time after section header(s) for content blocks\n const remainingDuration = audioSegment.duration - fixedDuration;\n\n // Scale factor only applies to content blocks\n const scaleFactor =\n contentBlockDuration > 0 && remainingDuration > 0\n ? remainingDuration / contentBlockDuration\n : 1;\n\n // First pass: expand all blocks and track which have source timing\n interface ExpandedSlideInfo {\n block: Block;\n originalIndex: number;\n templateBlock: TemplateBlock;\n hasSourceTiming: boolean;\n }\n const expandedInfos: ExpandedSlideInfo[] = [];\n\n for (const { block, originalIndex } of segmentBlocks) {\n const context = createTemplateContext(theme, originalIndex, totalBlocks, viewport);\n const expandedBlock = isTemplateBlock(block)\n ? expandTemplateBlock(block, context)\n : (block as Block);\n\n const templateBlock = block as TemplateBlock;\n const useBottom = templateBlock.useBottomLayer !== false;\n const useTop = templateBlock.useTopLayer !== false;\n if (bottomLayers.length > 0 || topLayers.length > 0) {\n expandedBlock.layers = [\n ...(useBottom ? bottomLayers : []),\n ...(expandedBlock.layers ?? []),\n ...(useTop ? topLayers : []),\n ];\n }\n\n expandedInfos.push({\n block: expandedBlock,\n originalIndex,\n templateBlock,\n hasSourceTiming: typeof templateBlock.sourceStartTime === 'number',\n });\n }\n\n // Sort blocks within this segment.\n // When ANY block has source timing (from audio analysis), section headers\n // are placed first since they are intro cards for the segment. When there\n // is no source timing (e.g., preview/synthetic mode), keep original\n // document order so the slideshow matches what the author wrote.\n const hasAnySourceTiming = expandedInfos.some((info) => info.hasSourceTiming);\n\n expandedInfos.sort((a, b) => {\n if (hasAnySourceTiming) {\n const aIsHeader = a.templateBlock.template === 'sectionHeader';\n const bIsHeader = b.templateBlock.template === 'sectionHeader';\n\n // Section headers come first when we have audio-based timing\n if (aIsHeader && !bIsHeader) return -1;\n if (!aIsHeader && bIsHeader) return 1;\n\n // Both have source timing - sort by time\n if (a.hasSourceTiming && b.hasSourceTiming) {\n return a.templateBlock.sourceStartTime! - b.templateBlock.sourceStartTime!;\n }\n\n // One has timing, one doesn't - timing comes first\n if (a.hasSourceTiming && !b.hasSourceTiming) return -1;\n if (!a.hasSourceTiming && b.hasSourceTiming) return 1;\n }\n\n // Keep original document order\n return a.originalIndex - b.originalIndex;\n });\n\n // Second pass: assign start times\n // Slides with sourceStartTime use that; others fill gaps\n let offsetWithinSegment = 0;\n for (let i = 0; i < expandedInfos.length; i++) {\n const info = expandedInfos[i];\n const { block: expandedBlock, templateBlock } = info;\n\n // Use source timing if available, otherwise use sequential offset\n if (info.hasSourceTiming) {\n // Use the source timing - this is when the content is spoken\n const sourceStart = templateBlock.sourceStartTime!;\n expandedBlock.startTime = audioSegment.startTime + sourceStart;\n // Use source duration if available, otherwise use block duration\n if (typeof templateBlock.sourceDuration === 'number') {\n expandedBlock.duration = Math.max(5, templateBlock.sourceDuration);\n }\n // Update offset for next block\n offsetWithinSegment = sourceStart + expandedBlock.duration;\n } else if (templateBlock.template === 'sectionHeader') {\n // Section headers start at the beginning of the segment\n expandedBlock.startTime = audioSegment.startTime + offsetWithinSegment;\n offsetWithinSegment += expandedBlock.duration;\n } else {\n // No source timing - place after previous block\n expandedBlock.startTime = audioSegment.startTime + offsetWithinSegment;\n // Scale content block duration to fit\n const scaledDuration = expandedBlock.duration * scaleFactor;\n expandedBlock.duration = scaledDuration;\n offsetWithinSegment += scaledDuration;\n }\n\n expandedBlocks[info.originalIndex] = expandedBlock;\n }\n\n // Third pass: fix overlaps and gaps by adjusting durations\n // Sort by startTime for overlap detection\n const segmentExpandedBlocks = expandedInfos\n .map((info) => expandedBlocks[info.originalIndex])\n .sort((a, b) => a.startTime - b.startTime);\n\n for (let i = 0; i < segmentExpandedBlocks.length - 1; i++) {\n const current = segmentExpandedBlocks[i];\n const next = segmentExpandedBlocks[i + 1];\n const currentEnd = current.startTime + current.duration;\n\n if (currentEnd > next.startTime) {\n // Overlap - shorten current block to end when next begins\n current.duration = next.startTime - current.startTime;\n } else if (currentEnd < next.startTime - 0.5) {\n // Gap > 0.5s - extend current block to fill (visual continuity)\n // Same formula as overlap: snap to next block start\n current.duration = Math.max(0.1, next.startTime - current.startTime);\n }\n }\n\n // Minimum gap between any two transitions (including section boundaries).\n // No block should be visible for less than this before a transition occurs.\n const MIN_TRANSITION_GAP = 5;\n const segmentEnd = audioSegment.startTime + audioSegment.duration;\n\n // Fourth pass: enforce minimum transition gap at section boundary.\n // Eliminate blocks from the end that would start within MIN_TRANSITION_GAP\n // of the section end (creating a jarring transition right before the next\n // section header). Loop to handle cascading eliminations.\n while (segmentExpandedBlocks.length > 1) {\n const lastBlock = segmentExpandedBlocks[segmentExpandedBlocks.length - 1];\n const timeFromLastToEnd = segmentEnd - lastBlock.startTime;\n\n if (timeFromLastToEnd < MIN_TRANSITION_GAP && lastBlock.template !== 'sectionHeader') {\n const prevBlock = segmentExpandedBlocks[segmentExpandedBlocks.length - 2];\n prevBlock.duration = segmentEnd - prevBlock.startTime;\n lastBlock.duration = 0;\n lastBlock.startTime = segmentEnd;\n segmentExpandedBlocks.pop();\n } else {\n // Extend last block to fill to segment end\n if (lastBlock.startTime + lastBlock.duration < segmentEnd) {\n lastBlock.duration = segmentEnd - lastBlock.startTime;\n }\n break;\n }\n }\n\n // Handle single-block segment\n if (segmentExpandedBlocks.length === 1) {\n const onlyBlock = segmentExpandedBlocks[0];\n if (onlyBlock.startTime + onlyBlock.duration < segmentEnd) {\n onlyBlock.duration = segmentEnd - onlyBlock.startTime;\n }\n }\n\n // Fifth pass: eliminate any remaining blocks shorter than MIN_TRANSITION_GAP.\n // Walk backwards and merge short blocks into their predecessor.\n // Skip index 0 (first block, typically section header) to preserve segment start.\n let changed = true;\n while (changed) {\n changed = false;\n for (let i = segmentExpandedBlocks.length - 1; i >= 1; i--) {\n const block = segmentExpandedBlocks[i];\n if (block.duration > 0 && block.duration < MIN_TRANSITION_GAP) {\n const prev = segmentExpandedBlocks[i - 1];\n const blockEnd = block.startTime + block.duration;\n prev.duration = blockEnd - prev.startTime;\n block.duration = 0;\n block.startTime = segmentEnd;\n segmentExpandedBlocks.splice(i, 1);\n changed = true;\n break; // Restart loop after modification\n }\n }\n }\n\n // Sixth pass: split blocks that are too long (>20s)\n // This ensures no single block lingers for too long\n const MAX_BLOCK_DURATION = 20;\n\n for (let i = 0; i < segmentExpandedBlocks.length; i++) {\n const block = segmentExpandedBlocks[i];\n\n if (block.duration > MAX_BLOCK_DURATION) {\n // Calculate how many parts we need\n const numParts = Math.ceil(block.duration / MAX_BLOCK_DURATION);\n const partDuration = block.duration / numParts;\n\n // Only split if each part would meet minimum transition gap\n if (partDuration >= MIN_TRANSITION_GAP) {\n // Shorten original block to first part\n block.duration = partDuration;\n\n // Create additional blocks for remaining parts\n for (let p = 1; p < numParts; p++) {\n const splitBlock: Block = {\n id: `${block.id}-split-${p}`,\n startTime: block.startTime + p * partDuration,\n duration: partDuration,\n audioSegment: block.audioSegment,\n layers: (block.layers ?? []).map((layer) => ({\n ...layer,\n id: `${layer.id}-split-${p}`,\n })),\n transition: { type: 'dissolve', duration: 1.0 },\n template: block.template,\n };\n // Insert into expanded blocks array\n expandedBlocks.push(splitBlock);\n }\n }\n }\n }\n }\n\n // Filter out zero-duration blocks (eliminated in earlier passes)\n return expandedBlocks.filter((block) => block && block.duration > 0);\n}\n\n/**\n * Get list of available template names.\n */\nexport function getAvailableTemplates(): string[] {\n return Object.keys(templateRegistry);\n}\n\n/**\n * Check if a template exists.\n */\nexport function hasTemplate(name: string): boolean {\n return name in templateRegistry;\n}\n\n// Re-export types and utilities from schemas\nexport {\n isTemplateBlock,\n createTemplateContext,\n scaledFontSize,\n} from '../../schemas/BlockTemplates.js';\nexport type {\n TemplateBlock,\n DocBlock,\n TemplateContext,\n PersistentLayerConfig,\n} from '../../schemas/BlockTemplates.js';\nexport {\n DEFAULT_THEME,\n resolveTheme,\n getAvailableThemes,\n getThemeSummaries,\n} from '../../schemas/themeLibrary.js';\nexport type {\n Theme,\n ThemeColorPalette,\n ThemeColorScheme,\n ThemeTypography,\n ThemeStyle,\n RenderStyle,\n} from '../../schemas/Theme.js';\nexport type { DocStylePreset } from './persistentLayers.js';\n// Re-export timing types (AudioSegmentTiming and ExpandDocBlocksOptions are already exported above)\nexport { VIEWPORT_PRESETS, getViewport, getViewportOrientation } from '../../schemas/Viewport.js';\nexport type {\n ViewportConfig,\n ViewportPreset,\n ViewportOrientation,\n} from '../../schemas/Viewport.js';\nexport { getLayoutHints, getTwoColumnPositions } from '../../schemas/LayoutStrategy.js';\nexport type { LayoutHints } from '../../schemas/LayoutStrategy.js';\nexport { expandPersistentLayers, getDocStyleConfig } from './persistentLayers.js';\n\n// Re-export individual templates for direct access\nexport { titleBlock } from './titleBlock.js';\nexport { sectionHeader } from './sectionHeader.js';\nexport { statHighlight } from './statHighlight.js';\nexport { quoteBlock } from './quoteBlock.js';\nexport { factCard } from './factCard.js';\nexport { twoColumn } from './twoColumn.js';\nexport { dateEvent } from './dateEvent.js';\nexport { imageWithCaption } from './imageWithCaption.js';\nexport { mapBlock } from './mapBlock.js';\nexport { coverBlock, expandCoverBlock } from './coverBlock.js';\nexport type { CoverBlockInput } from './coverBlock.js';\nexport { fullBleedQuote } from './fullBleedQuote.js';\nexport { listBlock } from './listBlock.js';\nexport { photoGrid } from './photoGrid.js';\nexport { definitionCard } from './definitionCard.js';\nexport { comparisonBar } from './comparisonBar.js';\nexport { pullQuote } from './pullQuote.js';\nexport { videoWithCaption } from './videoWithCaption.js';\nexport { videoPullQuote } from './videoPullQuote.js';\n\n// Re-export accent image utilities\nexport { getAccentLayout, createAccentLayers, adjustY, DEFAULT_LAYOUT } from './accentImage.js';\nexport type { AccentLayout } from './accentImage.js';\n","/**\n * Animation Utilities\n *\n * Helper functions for mapping Doc animations to CSS classes and styles.\n * Generates the appropriate animation class names and CSS custom properties\n * for duration, delay, and easing.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Animation, AnimationType, TransitionType } from '../../schemas/Doc.js';\n\ninterface AnimationResult {\n /** CSS class name to apply */\n className: string;\n /** Inline styles for CSS custom properties */\n style: Record<string, string>;\n}\n\n/**\n * Get CSS class and styles for an animation.\n */\nexport function getAnimationStyle(\n animation: Animation | undefined,\n _currentTime: number = 0,\n): AnimationResult {\n if (!animation || animation.type === 'none') {\n return { className: '', style: {} };\n }\n\n const className = getAnimationClassName(animation);\n const style = getAnimationCSSVars(animation);\n\n return { className, style };\n}\n\n/**\n * Map animation type to CSS class name.\n */\nfunction getAnimationClassName(animation: Animation): string {\n const { type, direction, panDirection } = animation;\n\n switch (type) {\n case 'fadeIn':\n return 'anim-fadeIn';\n case 'fadeOut':\n return 'anim-fadeOut';\n case 'slowZoom':\n // Slow zoom (Ken Burns style) has variants based on direction and pan\n if (panDirection === 'left') return 'anim-slowZoom-panLeft';\n if (panDirection === 'right') return 'anim-slowZoom-panRight';\n if (direction === 'out') return 'anim-slowZoom-out';\n return 'anim-slowZoom-in';\n case 'zoomIn':\n return 'anim-zoomIn';\n case 'zoomOut':\n return 'anim-zoomOut';\n case 'panLeft':\n return 'anim-panLeft';\n case 'panRight':\n return 'anim-panRight';\n case 'typewriter':\n return 'anim-typewriter';\n default:\n return '';\n }\n}\n\n/**\n * Generate CSS custom properties for animation timing.\n */\nfunction getAnimationCSSVars(animation: Animation): Record<string, string> {\n const vars: Record<string, string> = {};\n\n if (animation.duration !== undefined) {\n vars['--anim-duration'] = `${animation.duration}s`;\n }\n\n if (animation.delay !== undefined) {\n vars['--anim-delay'] = `${animation.delay}s`;\n }\n\n if (animation.easing) {\n vars['--anim-easing'] = animation.easing;\n }\n\n return vars;\n}\n\n/**\n * Get default duration for an animation type.\n */\nexport function getDefaultAnimationDuration(type: AnimationType): number {\n switch (type) {\n case 'slowZoom':\n case 'panLeft':\n case 'panRight':\n return 8; // Long, slow animations\n case 'typewriter':\n return 3;\n case 'fadeIn':\n case 'fadeOut':\n return 1;\n case 'zoomIn':\n case 'zoomOut':\n return 0.5;\n default:\n return 1;\n }\n}\n\n/**\n * Get transition class for slide entry/exit.\n */\nexport function getTransitionClass(type: TransitionType, entering: boolean): string {\n const mode = entering ? 'enter' : 'exit';\n return `transition-${type}-${mode}`;\n}\n\n/**\n * Calculate animation progress (0-1) based on current time.\n */\nexport function getAnimationProgress(\n animation: Animation,\n currentTime: number,\n slideDuration: number,\n): number {\n const delay = animation.delay || 0;\n const duration = animation.duration || slideDuration;\n\n if (currentTime < delay) return 0;\n if (currentTime >= delay + duration) return 1;\n\n return (currentTime - delay) / duration;\n}\n","/**\n * Markdown → Doc Conversion\n *\n * Converts a MarkdownDocument into a hierarchical Doc whose Block tree\n * mirrors the heading structure of the markdown. Every heading (H1–H6)\n * becomes a Block; body content between headings populates `contents`;\n * sub-headings nest as `children`.\n *\n * This enables using BlockTemplates to supply alternate visualizations\n * for each section of a markdown document.\n *\n * @example\n * ```ts\n * import { parseMarkdown } from '@bendyline/squisq/markdown';\n * import { markdownToDoc } from '@bendyline/squisq/doc';\n *\n * const md = parseMarkdown('# Intro\\n\\nHello world\\n\\n## Details\\n\\nMore text');\n * const doc = markdownToDoc(md);\n * // doc.blocks[0].sourceHeading.depth === 1 (\"# Intro\")\n * // doc.blocks[0].contents → [paragraph(\"Hello world\")]\n * // doc.blocks[0].children[0].sourceHeading.depth === 2 (\"## Details\")\n * ```\n */\n\nimport type { Doc, Block, CaptionTrack, CaptionPhrase } from '../schemas/Doc.js';\nimport type { MarkdownDocument, MarkdownBlockNode, MarkdownHeading } from '../markdown/types.js';\nimport { extractPlainText } from '../markdown/utils.js';\nimport { estimateReadingTime } from '../timing/readingTime.js';\n\n// ============================================\n// Options\n// ============================================\n\n/**\n * Options for markdownToDoc().\n */\nexport interface MarkdownToDocOptions {\n /** Article ID for the generated Doc. Default: 'markdown-doc' */\n articleId?: string;\n\n /** Default template name for heading blocks. Default: 'sectionHeader' */\n defaultTemplate?: string;\n\n /** Default duration per block in seconds. Default: 5 */\n defaultDuration?: number;\n\n /** Custom ID generator. Receives the heading node and its index. */\n generateId?: (heading: MarkdownHeading, index: number) => string;\n}\n\n// ============================================\n// ID Generation\n// ============================================\n\n/**\n * Convert text to a URL-friendly slug.\n * \"Getting Started & More\" → \"getting-started-more\"\n */\nconst SLUG_NON_WORD_RE = /[^\\w\\s-]/g;\nconst SLUG_SPACES_RE = /[\\s_]+/g;\nconst SLUG_MULTI_HYPHEN_RE = /-+/g;\nconst SLUG_TRIM_HYPHEN_RE = /^-|-$/g;\n\nfunction slugify(text: string): string {\n return (\n text\n .toLowerCase()\n .replace(SLUG_NON_WORD_RE, '') // Remove non-word chars (except spaces and hyphens)\n .replace(SLUG_SPACES_RE, '-') // Replace spaces/underscores with hyphens\n .replace(SLUG_MULTI_HYPHEN_RE, '-') // Collapse multiple hyphens\n .replace(SLUG_TRIM_HYPHEN_RE, '') || // Trim leading/trailing hyphens\n 'block'\n ); // Fallback for empty result\n}\n\n/**\n * Creates an ID generator that produces unique slugified IDs.\n * Appends -2, -3, etc. for duplicate headings.\n */\nfunction createIdGenerator() {\n const used = new Map<string, number>();\n\n return (heading: MarkdownHeading, _index: number): string => {\n const text = extractPlainText(heading);\n const base = slugify(text);\n const count = used.get(base) ?? 0;\n used.set(base, count + 1);\n\n if (count === 0) return base;\n return `${base}-${count + 1}`;\n };\n}\n\n// ============================================\n// Core Conversion\n// ============================================\n\n/**\n * Convert a MarkdownDocument into a Doc with a heading-driven Block hierarchy.\n *\n * **Algorithm:**\n * 1. Walk the document's top-level children sequentially\n * 2. Each MarkdownHeading starts a new block at its depth level\n * 3. Non-heading nodes accumulate as `contents` on the current block\n * 4. Sub-headings (deeper depth) nest as `children` of the current block\n * 5. Same-level or shallower headings close the current block and start a sibling/ancestor\n * 6. Content before the first heading goes into a \"preamble\" block with no sourceHeading\n *\n * @param markdownDoc - A parsed MarkdownDocument\n * @param options - Conversion options\n * @returns A Doc whose blocks mirror the markdown heading structure\n */\nexport function markdownToDoc(markdownDoc: MarkdownDocument, options?: MarkdownToDocOptions): Doc {\n const articleId = options?.articleId ?? 'markdown-doc';\n const defaultTemplate = options?.defaultTemplate ?? 'sectionHeader';\n const defaultDuration = options?.defaultDuration ?? 5;\n const generateId = options?.generateId ?? createIdGenerator();\n\n const rootBlocks: Block[] = [];\n let headingIndex = 0;\n\n // Stack tracks the nesting context: each entry is a block and its heading depth.\n // We push when we go deeper, pop when we come back up.\n const stack: Array<{ block: Block; depth: number }> = [];\n\n // Accumulator for content nodes that appear before any heading (preamble)\n // or between the current heading and the next heading/sub-heading.\n let pendingContents: MarkdownBlockNode[] = [];\n let currentBlock: Block | null = null;\n\n function flushContents() {\n if (currentBlock && pendingContents.length > 0) {\n currentBlock.contents = (currentBlock.contents ?? []).concat(pendingContents);\n pendingContents = [];\n }\n }\n\n function makeBlock(heading: MarkdownHeading | null): Block {\n const id = heading ? generateId(heading, headingIndex++) : 'preamble';\n\n // Use template from annotation if present, otherwise fall back to default\n const annotation = heading?.templateAnnotation;\n const template = annotation?.template ?? (heading ? defaultTemplate : undefined);\n\n // Extract heading text so templates (e.g. sectionHeader) that expect a\n // `title` property receive it without having to reach into sourceHeading.\n const title = heading ? extractPlainText(heading) : undefined;\n\n const block: Block = {\n id,\n startTime: 0,\n duration: defaultDuration,\n audioSegment: 0,\n template,\n ...(heading ? { sourceHeading: heading } : {}),\n ...(title ? { title } : {}),\n };\n\n // Propagate key-value params from annotation to templateOverrides\n if (annotation?.params) {\n block.templateOverrides = annotation.params;\n }\n\n return block;\n }\n\n for (const node of markdownDoc.children) {\n if (node.type === 'heading') {\n const heading = node as MarkdownHeading;\n const depth = heading.depth;\n\n // Flush any accumulated content to the current block\n flushContents();\n\n // Create the new block for this heading\n const newBlock = makeBlock(heading);\n\n if (stack.length === 0) {\n // If there's a preamble block with no heading, push it first\n if (currentBlock && !currentBlock.sourceHeading) {\n rootBlocks.push(currentBlock);\n }\n\n // This is a root-level block (or the first heading)\n rootBlocks.push(newBlock);\n stack.push({ block: newBlock, depth });\n } else {\n // Find where this heading fits in the hierarchy\n // Pop blocks from the stack until we find a parent with lower depth\n while (stack.length > 0 && stack[stack.length - 1].depth >= depth) {\n stack.pop();\n }\n\n if (stack.length === 0) {\n // Same level as root or shallower — new root block\n rootBlocks.push(newBlock);\n stack.push({ block: newBlock, depth });\n } else {\n // Deeper — child of the current stack top\n const parent = stack[stack.length - 1].block;\n if (!parent.children) parent.children = [];\n parent.children.push(newBlock);\n stack.push({ block: newBlock, depth });\n }\n }\n\n currentBlock = newBlock;\n } else {\n // Non-heading block node — accumulate as content\n if (!currentBlock) {\n // Content before any heading → create preamble block\n currentBlock = makeBlock(null);\n }\n pendingContents.push(node);\n }\n }\n\n // Flush remaining content\n flushContents();\n\n // If we only had preamble content (no headings at all), push it\n if (currentBlock && !currentBlock.sourceHeading && !rootBlocks.includes(currentBlock)) {\n rootBlocks.push(currentBlock);\n }\n\n // Calculate reading-time-based durations and generate captions\n const allBlocks = flattenBlocks(rootBlocks);\n const minDuration = 3; // seconds — minimum for blocks with little/no text\n const phrases: CaptionPhrase[] = [];\n\n // First pass: compute duration from body-content reading time\n for (const block of allBlocks) {\n const bodyText = getBlockBodyText(block);\n if (bodyText.length > 0) {\n const estimate = estimateReadingTime(bodyText);\n block.duration = Math.max(minDuration, estimate.seconds);\n } else {\n block.duration = defaultDuration;\n }\n }\n\n // Second pass: assign start times sequentially and build caption phrases\n let currentTime = 0;\n for (const block of allBlocks) {\n block.startTime = currentTime;\n\n // Generate caption phrases from the block's body content\n const bodyText = getBlockBodyText(block);\n if (bodyText.length > 0) {\n const sentences = splitIntoSentences(bodyText);\n if (sentences.length > 0) {\n const timePerSentence = block.duration / sentences.length;\n for (let i = 0; i < sentences.length; i++) {\n phrases.push({\n text: sentences[i],\n startTime: currentTime + i * timePerSentence,\n endTime: currentTime + (i + 1) * timePerSentence,\n audioSegment: 0,\n });\n }\n }\n }\n\n currentTime += block.duration;\n }\n\n const captions: CaptionTrack | undefined =\n phrases.length > 0 ? { phrases, generatedAt: new Date().toISOString(), version: 1 } : undefined;\n\n return {\n articleId,\n duration: currentTime,\n blocks: rootBlocks,\n audio: {\n segments: [],\n },\n ...(captions ? { captions } : {}),\n ...(markdownDoc.frontmatter ? { frontmatter: markdownDoc.frontmatter } : {}),\n };\n}\n\n// ============================================\n// Utilities\n// ============================================\n\n/**\n * Flatten a nested block tree into a depth-first ordered array.\n * Useful for calculating sequential timing or iterating all blocks.\n */\nexport function flattenBlocks(blocks: Block[]): Block[] {\n const result: Block[] = [];\n for (const block of blocks) {\n result.push(block);\n if (block.children) {\n result.push(...flattenBlocks(block.children));\n }\n }\n return result;\n}\n\n/**\n * Count the total number of blocks in a nested tree (including children at all levels).\n */\nexport function countBlocks(blocks: Block[]): number {\n let count = 0;\n for (const block of blocks) {\n count += 1;\n if (block.children) {\n count += countBlocks(block.children);\n }\n }\n return count;\n}\n\n/**\n * Get the heading depth for a block. Returns 0 for preamble blocks (no heading).\n */\nexport function getBlockDepth(block: Block): number {\n return block.sourceHeading?.depth ?? 0;\n}\n\n// ============================================\n// Internal helpers\n// ============================================\n\n/**\n * Extract the plain text from a block's body contents (excluding heading text).\n */\nfunction getBlockBodyText(block: Block): string {\n if (!block.contents || block.contents.length === 0) return '';\n // Join with newlines to preserve paragraph/list-item boundaries.\n // splitIntoPhrases uses these newlines as natural split points.\n return block.contents\n .map((node) => extractPlainText(node))\n .join('\\n')\n .trim();\n}\n\n/** Maximum words per caption phrase. Long sentences get split at this point. */\nconst MAX_PHRASE_WORDS = 12;\n\n/**\n * Split text into caption-sized phrases.\n *\n * Splits on:\n * 1. Newlines (paragraph/list-item boundaries from markdown)\n * 2. Sentence endings (.!?) followed by whitespace\n * 3. Long fragments (> MAX_PHRASE_WORDS) at clause boundaries (commas, semicolons, dashes)\n *\n * Merges very short fragments (< 15 chars) with the previous phrase.\n */\nfunction splitIntoSentences(text: string): string[] {\n // First split on newlines (each paragraph/list item becomes separate)\n const lines = text\n .split(/\\n+/)\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n\n // Then split each line on sentence boundaries\n const sentenceRe = /(?<=[.!?])\\s+/;\n const fragments: string[] = [];\n for (const line of lines) {\n const sentences = line\n .split(sentenceRe)\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n fragments.push(...sentences);\n }\n\n if (fragments.length === 0) return [];\n\n // Split long fragments at clause boundaries\n const split: string[] = [];\n for (const frag of fragments) {\n const words = frag.split(/\\s+/);\n if (words.length > MAX_PHRASE_WORDS) {\n // Try to split at comma, semicolon, or dash near the midpoint\n const mid = Math.floor(frag.length / 2);\n const clauseRe = /[,;]\\s+|\\s+—\\s+|\\s+-\\s+/g;\n let bestSplit = -1;\n let bestDist = Infinity;\n let match;\n while ((match = clauseRe.exec(frag)) !== null) {\n const dist = Math.abs(match.index - mid);\n if (dist < bestDist) {\n bestDist = dist;\n bestSplit = match.index + match[0].length;\n }\n }\n if (bestSplit > 0 && bestSplit < frag.length - 5) {\n split.push(frag.slice(0, bestSplit).trim());\n split.push(frag.slice(bestSplit).trim());\n } else {\n split.push(frag);\n }\n } else {\n split.push(frag);\n }\n }\n\n // Merge very short fragments (< 15 chars) with the previous phrase\n const merged: string[] = [split[0]];\n for (let i = 1; i < split.length; i++) {\n if (split[i].length < 15 && merged.length > 0) {\n merged[merged.length - 1] += ' ' + split[i];\n } else {\n merged.push(split[i]);\n }\n }\n return merged;\n}\n","/**\n * getLayers — Compute visual layers for a block on demand.\n *\n * This is the preferred way to obtain renderable layers for a block.\n * Instead of storing pre-computed layers on the Block object, call\n * `getLayers(block, context)` to derive them from the block's template\n * name, content, and the current render context (theme, viewport, etc.).\n *\n * For raw blocks that already carry a `layers` array, those layers are\n * returned directly (with optional persistent layer injection).\n *\n * @example\n * ```ts\n * import { getLayers } from '@bendyline/squisq/doc';\n *\n * const layers = getLayers(block, {\n * theme: DEFAULT_THEME,\n * viewport: VIEWPORT_PRESETS.landscape,\n * blockIndex: 0,\n * totalBlocks: 10,\n * });\n * ```\n */\n\nimport type { Block, Layer } from '../schemas/Doc.js';\nimport type {\n TemplateBlock,\n TemplateContext,\n PersistentLayerConfig,\n DocBlock,\n} from '../schemas/BlockTemplates.js';\nimport type { Theme } from '../schemas/Theme.js';\nimport type { ViewportConfig } from '../schemas/Viewport.js';\nimport { VIEWPORT_PRESETS } from '../schemas/Viewport.js';\nimport { createTemplateContext, isTemplateBlock } from '../schemas/BlockTemplates.js';\nimport { DEFAULT_THEME } from '../schemas/themeLibrary.js';\nimport { templateRegistry } from './templates/index.js';\nimport { expandPersistentLayers } from './templates/persistentLayers.js';\n\n// ============================================\n// RenderContext\n// ============================================\n\n/**\n * Context needed to compute layers for a block.\n *\n * Captures the visual rendering parameters: theme colors, viewport\n * configuration, persistent layers, and the block's position within\n * the doc (for template functions that vary output by index).\n */\nexport interface RenderContext {\n /** Theme for template rendering. Defaults to DEFAULT_THEME (documentary). */\n theme?: Theme;\n\n /** Target viewport configuration. Defaults to 16:9 landscape. */\n viewport?: ViewportConfig;\n\n /** Persistent layers injected behind and/or on top of all block content. */\n persistentLayers?: PersistentLayerConfig;\n\n /** 0-based index of this block in the sequence. Defaults to 0. */\n blockIndex?: number;\n\n /** Total number of blocks in the doc. Defaults to 1. */\n totalBlocks?: number;\n}\n\n// ============================================\n// getLayers\n// ============================================\n\n/**\n * Compute the visual layers for a block.\n *\n * Resolution order:\n * 1. If the block already has a non-empty `layers` array, use it (raw block).\n * 2. If the block has a `template` name that exists in the registry,\n * call the template function to generate layers.\n * 3. Otherwise return an empty array.\n *\n * Persistent layers (bottom/top) from the render context are injected\n * around the result unless the block opts out via `useBottomLayer: false`\n * or `useTopLayer: false`.\n *\n * @param block A Block or TemplateBlock to render.\n * @param context Render context (theme, viewport, persistent layers, position).\n * @returns The computed Layer[] for the block, ready for BlockRenderer.\n */\nexport function getLayers(block: DocBlock, context: RenderContext = {}): Layer[] {\n const theme = context.theme ?? DEFAULT_THEME;\n const viewport = context.viewport ?? VIEWPORT_PRESETS.landscape;\n const blockIndex = context.blockIndex ?? 0;\n const totalBlocks = context.totalBlocks ?? 1;\n\n // 1. Raw block path: block already has pre-computed layers\n const existingLayers = (block as Block).layers;\n if (existingLayers && existingLayers.length > 0 && !isTemplateBlock(block)) {\n return injectPersistentLayers(existingLayers, block, context);\n }\n\n // 2. Template path: look up and call the template function\n if (isTemplateBlock(block) && block.template in templateRegistry) {\n const templateName = block.template as keyof typeof templateRegistry;\n const templateCtx = createTemplateContext(theme, blockIndex, totalBlocks, viewport);\n let layers: Layer[];\n try {\n // Each registry entry accepts its specific TemplateBlock variant; the\n // discriminated union guarantees the shapes match at runtime.\n const templateFn = templateRegistry[templateName] as (\n input: TemplateBlock,\n ctx: TemplateContext,\n ) => Layer[];\n layers = templateFn(block, templateCtx);\n if (!Array.isArray(layers)) {\n console.error(`Template ${templateName} did not return an array, got:`, typeof layers);\n layers = [];\n }\n } catch (err: unknown) {\n console.error(`Error expanding template ${templateName}:`, err);\n layers = [];\n }\n\n return injectPersistentLayers(layers, block, context);\n }\n\n // 3. Fallback: no layers and no known template\n return injectPersistentLayers([], block, context);\n}\n\n// ============================================\n// Internal helpers\n// ============================================\n\n/**\n * Inject persistent bottom/top layers around the block's own layers,\n * respecting per-block opt-out flags.\n */\nfunction injectPersistentLayers(layers: Layer[], block: DocBlock, context: RenderContext): Layer[] {\n const { persistentLayers } = context;\n if (!persistentLayers) return layers;\n\n const bottomLayers = expandPersistentLayers(persistentLayers.bottomLayers);\n const topLayers = expandPersistentLayers(persistentLayers.topLayers);\n\n if (bottomLayers.length === 0 && topLayers.length === 0) return layers;\n\n const templateBlock = block as TemplateBlock;\n const useBottom = templateBlock.useBottomLayer !== false;\n const useTop = templateBlock.useTopLayer !== false;\n\n return [...(useBottom ? bottomLayers : []), ...layers, ...(useTop ? topLayers : [])];\n}\n","/**\n * Shared utilities for layer components.\n *\n * Resolves position values and anchor offsets used by all layer types.\n */\n\n/**\n * Resolve a position value (number or percentage string) to pixels.\n */\nexport function resolveValue(value: number | string, dimension: number): number {\n if (typeof value === 'number') {\n return value;\n }\n if (value.endsWith('%')) {\n const percent = parseFloat(value);\n return (percent / 100) * dimension;\n }\n return parseFloat(value);\n}\n\n/**\n * Get offset based on anchor point.\n */\nexport function getAnchorOffset(\n anchor: string | undefined,\n width: number,\n height: number,\n): { x: number; y: number } {\n switch (anchor) {\n case 'center':\n return { x: -width / 2, y: -height / 2 };\n case 'top-right':\n return { x: -width, y: 0 };\n case 'bottom-left':\n return { x: 0, y: -height };\n case 'bottom-right':\n return { x: -width, y: -height };\n case 'top-left':\n default:\n return { x: 0, y: 0 };\n }\n}\n","/**\n * MediaContext — React context for providing a MediaProvider to layer components.\n *\n * When a MediaProvider is available in context, layer components (ImageLayer,\n * VideoLayer) will use it to resolve media URLs instead of the basePath prop.\n * This enables slot-based media storage where binary assets are served from\n * IndexedDB as blob URLs.\n *\n * Usage:\n * const provider = createSlotMediaProvider(slotId);\n * <MediaContext.Provider value={provider}>\n * <DocPlayer doc={doc} basePath=\"/\" />\n * </MediaContext.Provider>\n */\n\nimport { createContext, useContext, useState, useEffect, useMemo } from 'react';\nimport type { MediaProvider } from '@bendyline/squisq/schemas';\n\n/**\n * React context holding the current MediaProvider (or null if none provided).\n */\nexport const MediaContext = createContext<MediaProvider | null>(null);\n\n/**\n * Hook to access the current MediaProvider from context.\n * Returns null if no provider is set.\n */\nexport function useMediaProvider(): MediaProvider | null {\n return useContext(MediaContext);\n}\n\n/**\n * Hook to resolve a media URL via the MediaProvider (if available),\n * falling back to basePath-based resolution.\n *\n * Returns the resolved URL string. Updates when the provider or path changes.\n *\n * @param relativePath - Relative media path from the document (e.g., 'hero.jpg')\n * @param basePath - Fallback base path for URL construction\n */\nexport function useMediaUrl(relativePath: string, basePath: string): string {\n const provider = useMediaProvider();\n\n // For absolute/http URLs, skip resolution entirely\n const isAbsolute =\n relativePath.startsWith('http') ||\n relativePath.startsWith('/') ||\n relativePath.startsWith('data:') ||\n relativePath.startsWith('blob:');\n\n // Memoize fallback to avoid recalculating on every render\n const fallback = useMemo(\n () => (isAbsolute ? relativePath : `${basePath}/${relativePath}`),\n [isAbsolute, relativePath, basePath],\n );\n\n // Fast path: no provider or absolute URL — return synchronously, skip effect entirely\n const needsProvider = !isAbsolute && !!provider;\n\n const [url, setUrl] = useState(fallback);\n\n useEffect(() => {\n if (!needsProvider) {\n setUrl(fallback);\n return;\n }\n\n let cancelled = false;\n provider!.resolveUrl(relativePath).then((resolved) => {\n if (!cancelled) setUrl(resolved);\n });\n\n return () => {\n cancelled = true;\n };\n }, [needsProvider, provider, relativePath, fallback]);\n\n // When provider is not needed, return fallback directly to avoid\n // the one-frame delay from the initial useState → useEffect cycle\n return needsProvider ? url : fallback;\n}\n","import { options, Fragment } from 'preact';\nimport { encodeEntities } from './utils';\nimport { IS_NON_DIMENSIONAL } from '../../src/constants';\n\nlet vnodeId = 0;\n\nconst isArray = Array.isArray;\n\n/**\n * @fileoverview\n * This file exports various methods that implement Babel's \"automatic\" JSX runtime API:\n * - jsx(type, props, key)\n * - jsxs(type, props, key)\n * - jsxDEV(type, props, key, __source, __self)\n *\n * The implementation of createVNode here is optimized for performance.\n * Benchmarks: https://esbench.com/bench/5f6b54a0b4632100a7dcd2b3\n */\n\n/**\n * JSX.Element factory used by Babel's {runtime:\"automatic\"} JSX transform\n * @param {VNode['type']} type\n * @param {VNode['props']} props\n * @param {VNode['key']} [key]\n * @param {unknown} [isStaticChildren]\n * @param {unknown} [__source]\n * @param {unknown} [__self]\n */\nfunction createVNode(type, props, key, isStaticChildren, __source, __self) {\n\tif (!props) props = {};\n\t// We'll want to preserve `ref` in props to get rid of the need for\n\t// forwardRef components in the future, but that should happen via\n\t// a separate PR.\n\tlet normalizedProps = props,\n\t\tref,\n\t\ti;\n\n\tif ('ref' in normalizedProps) {\n\t\tnormalizedProps = {};\n\t\tfor (i in props) {\n\t\t\tif (i == 'ref') {\n\t\t\t\tref = props[i];\n\t\t\t} else {\n\t\t\t\tnormalizedProps[i] = props[i];\n\t\t\t}\n\t\t}\n\t}\n\n\t/** @type {VNode & { __source: any; __self: any }} */\n\tconst vnode = {\n\t\ttype,\n\t\tprops: normalizedProps,\n\t\tkey,\n\t\tref,\n\t\t_children: null,\n\t\t_parent: null,\n\t\t_depth: 0,\n\t\t_dom: null,\n\t\t_component: null,\n\t\tconstructor: undefined,\n\t\t_original: --vnodeId,\n\t\t_index: -1,\n\t\t_flags: 0,\n\t\t__source,\n\t\t__self\n\t};\n\n\t// If a Component VNode, check for and apply defaultProps.\n\t// Note: `type` is often a String, and can be `undefined` in development.\n\tif (typeof type === 'function' && (ref = type.defaultProps)) {\n\t\tfor (i in ref)\n\t\t\tif (normalizedProps[i] === undefined) {\n\t\t\t\tnormalizedProps[i] = ref[i];\n\t\t\t}\n\t}\n\n\tif (options.vnode) options.vnode(vnode);\n\treturn vnode;\n}\n\n/**\n * Create a template vnode. This function is not expected to be\n * used directly, but rather through a precompile JSX transform\n * @param {string[]} templates\n * @param {Array<string | null | VNode>} exprs\n * @returns {VNode}\n */\nfunction jsxTemplate(templates, ...exprs) {\n\tconst vnode = createVNode(Fragment, { tpl: templates, exprs });\n\t// Bypass render to string top level Fragment optimization\n\tvnode.key = vnode._vnode;\n\treturn vnode;\n}\n\nconst JS_TO_CSS = {};\nconst CSS_REGEX = /[A-Z]/g;\n\n/**\n * Unwrap potential signals.\n * @param {*} value\n * @returns {*}\n */\nfunction normalizeAttrValue(value) {\n\treturn value !== null &&\n\t\ttypeof value === 'object' &&\n\t\ttypeof value.valueOf === 'function'\n\t\t? value.valueOf()\n\t\t: value;\n}\n\n/**\n * Serialize an HTML attribute to a string. This function is not\n * expected to be used directly, but rather through a precompile\n * JSX transform\n * @param {string} name The attribute name\n * @param {*} value The attribute value\n * @returns {string}\n */\nfunction jsxAttr(name, value) {\n\tif (options.attr) {\n\t\tconst result = options.attr(name, value);\n\t\tif (typeof result === 'string') return result;\n\t}\n\n\tvalue = normalizeAttrValue(value);\n\n\tif (name === 'ref' || name === 'key') return '';\n\tif (name === 'style' && typeof value === 'object') {\n\t\tlet str = '';\n\t\tfor (let prop in value) {\n\t\t\tlet val = value[prop];\n\t\t\tif (val != null && val !== '') {\n\t\t\t\tconst name =\n\t\t\t\t\tprop[0] == '-'\n\t\t\t\t\t\t? prop\n\t\t\t\t\t\t: JS_TO_CSS[prop] ||\n\t\t\t\t\t\t\t(JS_TO_CSS[prop] = prop.replace(CSS_REGEX, '-$&').toLowerCase());\n\n\t\t\t\tlet suffix = ';';\n\t\t\t\tif (\n\t\t\t\t\ttypeof val === 'number' &&\n\t\t\t\t\t// Exclude custom-attributes\n\t\t\t\t\t!name.startsWith('--') &&\n\t\t\t\t\t!IS_NON_DIMENSIONAL.test(name)\n\t\t\t\t) {\n\t\t\t\t\tsuffix = 'px;';\n\t\t\t\t}\n\t\t\t\tstr = str + name + ':' + val + suffix;\n\t\t\t}\n\t\t}\n\t\treturn name + '=\"' + encodeEntities(str) + '\"';\n\t}\n\n\tif (\n\t\tvalue == null ||\n\t\tvalue === false ||\n\t\ttypeof value === 'function' ||\n\t\ttypeof value === 'object'\n\t) {\n\t\treturn '';\n\t} else if (value === true) return name;\n\n\treturn name + '=\"' + encodeEntities('' + value) + '\"';\n}\n\n/**\n * Escape a dynamic child passed to `jsxTemplate`. This function\n * is not expected to be used directly, but rather through a\n * precompile JSX transform\n * @param {*} value\n * @returns {string | null | VNode | Array<string | null | VNode>}\n */\nfunction jsxEscape(value) {\n\tif (\n\t\tvalue == null ||\n\t\ttypeof value === 'boolean' ||\n\t\ttypeof value === 'function'\n\t) {\n\t\treturn null;\n\t}\n\n\tif (typeof value === 'object') {\n\t\t// Check for VNode\n\t\tif (value.constructor === undefined) return value;\n\n\t\tif (isArray(value)) {\n\t\t\tfor (let i = 0; i < value.length; i++) {\n\t\t\t\tvalue[i] = jsxEscape(value[i]);\n\t\t\t}\n\t\t\treturn value;\n\t\t}\n\t}\n\n\treturn encodeEntities('' + value);\n}\n\nexport {\n\tcreateVNode as jsx,\n\tcreateVNode as jsxs,\n\tcreateVNode as jsxDEV,\n\tFragment,\n\t// precompiled JSX transform\n\tjsxTemplate,\n\tjsxAttr,\n\tjsxEscape\n};\n","/**\n * ImageLayer Component\n *\n * Renders an image layer within an SVG block. Supports Ken Burns and other\n * animations via CSS classes. Images are rendered using SVG <image> element\n * with proper aspect ratio handling.\n */\n\nimport type { ImageLayer as ImageLayerType, Animation } from '@bendyline/squisq/schemas';\nimport { getAnimationStyle } from '../utils/animationUtils';\nimport { resolveValue, getAnchorOffset } from '../utils/layerUtils';\nimport { useMediaUrl } from '../hooks/MediaContext';\n\ninterface ImageLayerProps {\n layer: ImageLayerType;\n /** Base path for resolving relative image URLs */\n basePath: string;\n /** Viewport dimensions for percentage calculations */\n viewport: { width: number; height: number };\n /** Current time relative to block start (for animation timing) */\n blockTime: number;\n}\n\nexport function ImageLayer({ layer, basePath, viewport, blockTime }: ImageLayerProps) {\n const { content, position, animation } = layer;\n\n // Resolve position values to pixels\n const x = resolveValue(position.x, viewport.width);\n const y = resolveValue(position.y, viewport.height);\n const width = position.width ? resolveValue(position.width, viewport.width) : viewport.width;\n const height = position.height ? resolveValue(position.height, viewport.height) : viewport.height;\n\n // Apply anchor offset\n const offset = getAnchorOffset(position.anchor, width, height);\n const finalX = x + offset.x;\n const finalY = y + offset.y;\n\n // Resolve image URL via MediaProvider (if available), falling back to basePath\n const src = useMediaUrl(content.src, basePath);\n\n // Get animation styles\n const animStyle = getAnimationStyle(animation, blockTime);\n\n // SVG preserveAspectRatio based on fit mode\n const preserveAspectRatio = getPreserveAspectRatio(content.fit);\n const isCover = content.fit === 'cover';\n\n // Detect spatial (transform-based) animations that need Ken Burns treatment.\n // These animations should move the image *content* within fixed bounds rather\n // than shifting the entire image container.\n const isSpatialAnim = animation && SPATIAL_ANIMATION_TYPES.has(animation.type);\n\n // Ken Burns mode: cover image with spatial animation.\n // Keep the container static, animate the inner <img> within clipped bounds.\n if (isCover && isSpatialAnim && animation) {\n const kbAnim = remapToKenBurns(animation);\n const kbStyle = getAnimationStyle(kbAnim, blockTime);\n\n return (\n <g className=\"block-layer block-layer--image\" data-layer-id={layer.id}>\n <foreignObject x={finalX} y={finalY} width={width} height={height}>\n <div\n style={{\n width: '100%',\n height: '100%',\n overflow: 'hidden',\n }}\n >\n <img\n src={src}\n alt={content.alt || ''}\n className={kbStyle.className}\n style={{\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n objectPosition: 'center',\n display: 'block',\n pointerEvents: 'none',\n transformOrigin: 'center center',\n ...kbStyle.style,\n }}\n />\n </div>\n </foreignObject>\n </g>\n );\n }\n\n // For cover mode, use foreignObject with CSS object-fit for more reliable coverage\n // SVG's preserveAspectRatio can be inconsistent across browsers\n if (isCover) {\n return (\n <g\n className={`block-layer block-layer--image ${animStyle.className}`}\n style={animStyle.style}\n data-layer-id={layer.id}\n >\n <foreignObject x={finalX} y={finalY} width={width} height={height}>\n <img\n src={src}\n alt={content.alt || ''}\n style={{\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n objectPosition: 'center',\n display: 'block',\n pointerEvents: 'none',\n }}\n />\n </foreignObject>\n </g>\n );\n }\n\n // For contain/fill modes, use SVG image element\n return (\n <g\n className={`block-layer block-layer--image ${animStyle.className}`}\n style={animStyle.style}\n data-layer-id={layer.id}\n >\n <image\n href={src}\n x={finalX}\n y={finalY}\n width={width}\n height={height}\n preserveAspectRatio={preserveAspectRatio}\n style={{ pointerEvents: 'none' }}\n />\n </g>\n );\n}\n\n/**\n * Map fit mode to SVG preserveAspectRatio.\n */\nfunction getPreserveAspectRatio(fit?: 'cover' | 'contain' | 'fill'): string {\n switch (fit) {\n case 'cover':\n return 'xMidYMid slice';\n case 'fill':\n return 'none';\n case 'contain':\n default:\n return 'xMidYMid meet';\n }\n}\n\n// ============================================\n// Ken Burns Helpers\n// ============================================\n\n/** Animation types that use CSS transforms (translate/scale). */\nconst SPATIAL_ANIMATION_TYPES = new Set(['panLeft', 'panRight', 'slowZoom', 'zoomIn', 'zoomOut']);\n\n/**\n * Remap animation for Ken Burns inner-image rendering.\n *\n * Pure pan animations (panLeft/panRight) get remapped to combined slowZoom+pan\n * to maintain minimum scale and avoid revealing gaps at image edges.\n * zoomIn/zoomOut get remapped to slowZoom variants (no opacity change, which\n * is inappropriate for sustained ambient motion).\n */\nfunction remapToKenBurns(anim: Animation): Animation {\n switch (anim.type) {\n case 'panLeft':\n return { ...anim, type: 'slowZoom', panDirection: 'left' };\n case 'panRight':\n return { ...anim, type: 'slowZoom', panDirection: 'right' };\n case 'zoomIn':\n return { ...anim, type: 'slowZoom', direction: 'in' };\n case 'zoomOut':\n return { ...anim, type: 'slowZoom', direction: 'out' };\n default:\n return anim; // slowZoom variants are already correct\n }\n}\n\nexport default ImageLayer;\n","/**\n * TextLayer Component\n *\n * Renders a text layer within an SVG block. Supports multi-line text,\n * styling options (font, color, shadow), and animations like fadeIn\n * and typewriter effects.\n *\n * Text is rendered using SVG <text> elements with <tspan> for line breaks.\n */\n\nimport type { TextLayer as TextLayerType } from '@bendyline/squisq/schemas';\nimport { DEFAULT_DOC_FONT } from '@bendyline/squisq/schemas';\nimport { getAnimationStyle } from '../utils/animationUtils';\nimport { resolveValue } from '../utils/layerUtils';\n\ninterface TextLayerProps {\n layer: TextLayerType;\n /** Viewport dimensions for percentage calculations */\n viewport: { width: number; height: number };\n /** Current time relative to block start */\n blockTime: number;\n}\n\nexport function TextLayer({ layer, viewport, blockTime }: TextLayerProps) {\n const { content, position, animation } = layer;\n const { text, style } = content;\n\n // Resolve position values to pixels\n const x = resolveValue(position.x, viewport.width);\n const y = resolveValue(position.y, viewport.height);\n const maxWidth = position.width ? resolveValue(position.width, viewport.width) : undefined;\n\n // Apply anchor offset for text alignment\n const textAnchor = getTextAnchor(style.textAlign, position.anchor);\n const dominantBaseline = getDominantBaseline(position.anchor);\n\n // Get animation styles\n const animStyle = getAnimationStyle(animation, blockTime);\n\n // Split text into lines, and wrap if maxWidth is specified\n const rawLines = (text ?? '').split('\\n');\n let lines = maxWidth\n ? rawLines.reduce<string[]>(\n (acc, line) => acc.concat(wrapText(line, style.fontSize, maxWidth)),\n [],\n )\n : rawLines;\n\n // Truncate to maxLines if specified\n if (style.maxLines && lines.length > style.maxLines) {\n lines = lines.slice(0, style.maxLines);\n // Add ellipsis to last visible line\n const last = lines[lines.length - 1];\n lines[lines.length - 1] = last.replace(/\\s*$/, '') + '...';\n }\n const lineHeight = style.lineHeight || 1.4;\n const lineHeightPx = style.fontSize * lineHeight;\n\n // Build text styles\n const textStyles: Record<string, string | number> = {\n fontSize: `${style.fontSize}px`,\n fontFamily: style.fontFamily || DEFAULT_DOC_FONT,\n fontWeight: style.fontWeight || 'normal',\n fill: style.color,\n ...animStyle.style,\n };\n\n // Add shadow filter if requested\n const filterId = style.shadow ? `shadow-${layer.id}` : undefined;\n\n return (\n <g className={`block-layer block-layer--text ${animStyle.className}`} data-layer-id={layer.id}>\n {/* Shadow filter definition */}\n {style.shadow && (\n <defs>\n <filter id={filterId} x=\"-20%\" y=\"-20%\" width=\"140%\" height=\"140%\">\n <feDropShadow dx=\"0\" dy=\"2\" stdDeviation=\"3\" floodColor=\"rgba(0,0,0,0.7)\" />\n </filter>\n </defs>\n )}\n\n {/* Background box if specified */}\n {style.background && (\n <rect\n x={x - (style.padding || 16)}\n y={y - style.fontSize - (style.padding || 16)}\n width={getTextBoxWidth(lines, style) + (style.padding || 16) * 2}\n height={lines.length * lineHeightPx + (style.padding || 16) * 2}\n fill={style.background}\n rx={4}\n ry={4}\n />\n )}\n\n {/* Text element with tspans for each line */}\n <text\n x={x}\n y={y}\n textAnchor={textAnchor as 'start' | 'middle' | 'end'}\n dominantBaseline={dominantBaseline as 'text-before-edge' | 'middle' | 'text-after-edge'}\n style={textStyles}\n filter={filterId ? `url(#${filterId})` : undefined}\n >\n {lines.map((line, i) => (\n <tspan key={i} x={x} dy={i === 0 ? 0 : lineHeightPx}>\n {line || '\\u00A0'} {/* Non-breaking space for empty lines */}\n </tspan>\n ))}\n </text>\n </g>\n );\n}\n\n/**\n * Map text alignment to SVG text-anchor.\n */\nfunction getTextAnchor(align?: 'left' | 'center' | 'right', anchor?: string): string {\n // Explicit alignment takes precedence\n if (align === 'center') return 'middle';\n if (align === 'right') return 'end';\n if (align === 'left') return 'start';\n\n // Otherwise infer from position anchor\n if (anchor?.includes('right')) return 'end';\n if (anchor === 'center') return 'middle';\n return 'start';\n}\n\n/**\n * Map position anchor to SVG dominant-baseline.\n */\nfunction getDominantBaseline(anchor?: string): string {\n if (anchor?.includes('bottom')) return 'text-after-edge';\n if (anchor === 'center') return 'middle';\n return 'text-before-edge';\n}\n\n/**\n * Estimate text box width based on content (rough approximation).\n */\nfunction getTextBoxWidth(lines: string[], style: { fontSize: number }): number {\n const maxLineLength = Math.max(...lines.map((l) => l.length));\n // Rough estimate: average character width is ~0.5 * fontSize\n return maxLineLength * style.fontSize * 0.55;\n}\n\n/**\n * Wrap text to fit within a maximum width.\n * Uses character-based estimation for line breaking.\n */\nfunction wrapText(text: string, fontSize: number, maxWidth: number): string[] {\n if (!text.trim()) return [''];\n\n // Estimate characters per line (average char width ~0.5 * fontSize for most fonts)\n const avgCharWidth = fontSize * 0.5;\n const charsPerLine = Math.floor(maxWidth / avgCharWidth);\n\n if (charsPerLine <= 0) return [text];\n\n const words = text.split(/\\s+/);\n const lines: string[] = [];\n let currentLine = '';\n\n for (const word of words) {\n const testLine = currentLine ? `${currentLine} ${word}` : word;\n\n if (testLine.length <= charsPerLine) {\n currentLine = testLine;\n } else {\n // Current line is full, start new line\n if (currentLine) {\n lines.push(currentLine);\n }\n // Handle words longer than a line\n if (word.length > charsPerLine) {\n // Break long word\n let remaining = word;\n while (remaining.length > charsPerLine) {\n lines.push(remaining.slice(0, charsPerLine));\n remaining = remaining.slice(charsPerLine);\n }\n currentLine = remaining;\n } else {\n currentLine = word;\n }\n }\n }\n\n // Add remaining text\n if (currentLine) {\n lines.push(currentLine);\n }\n\n return lines.length > 0 ? lines : [''];\n}\n\nexport default TextLayer;\n","/**\n * ShapeLayer Component\n *\n * Renders simple geometric shapes (rect, circle, line) within an SVG block.\n * Useful for visual accents, dividers, and background elements.\n */\n\nimport type { ShapeLayer as ShapeLayerType } from '@bendyline/squisq/schemas';\nimport { getAnimationStyle } from '../utils/animationUtils';\nimport { resolveValue, getAnchorOffset } from '../utils/layerUtils';\n\ninterface ShapeLayerProps {\n layer: ShapeLayerType;\n /** Viewport dimensions for percentage calculations */\n viewport: { width: number; height: number };\n /** Current time relative to block start */\n blockTime: number;\n}\n\nexport function ShapeLayer({ layer, viewport, blockTime }: ShapeLayerProps) {\n const { content, position, animation } = layer;\n\n // Resolve position values to pixels\n const rawX = resolveValue(position.x, viewport.width);\n const rawY = resolveValue(position.y, viewport.height);\n const width = position.width ? resolveValue(position.width, viewport.width) : 100;\n const height = position.height ? resolveValue(position.height, viewport.height) : 100;\n\n // Apply anchor offset (e.g., 'center' shifts x by -width/2 and y by -height/2)\n const anchorOffset = getAnchorOffset(position.anchor, width, height);\n const x = rawX + anchorOffset.x;\n const y = rawY + anchorOffset.y;\n\n // Get animation styles\n const animStyle = getAnimationStyle(animation, blockTime);\n\n // Check if fill is a CSS gradient (SVG rect doesn't support CSS gradients natively)\n const fill = content.fill || 'none';\n const isCSSGradient = typeof fill === 'string' && fill.includes('gradient(');\n\n // For CSS gradients on rect, use foreignObject with an HTML div\n if (content.shape === 'rect' && isCSSGradient) {\n return (\n <g\n className={`block-layer block-layer--shape ${animStyle.className}`}\n style={animStyle.style}\n data-layer-id={layer.id}\n >\n <foreignObject x={x} y={y} width={width} height={height}>\n <div\n style={{\n width: '100%',\n height: '100%',\n background: fill,\n borderRadius: content.borderRadius ? `${content.borderRadius}px` : undefined,\n pointerEvents: 'none',\n }}\n />\n </foreignObject>\n </g>\n );\n }\n\n // Common style props for native SVG shapes\n const shapeProps = {\n fill: fill,\n stroke: content.stroke,\n strokeWidth: content.strokeWidth,\n };\n\n return (\n <g\n className={`block-layer block-layer--shape ${animStyle.className}`}\n style={animStyle.style}\n data-layer-id={layer.id}\n >\n {content.shape === 'rect' && (\n <rect\n x={x}\n y={y}\n width={width}\n height={height}\n rx={content.borderRadius}\n ry={content.borderRadius}\n {...shapeProps}\n />\n )}\n\n {content.shape === 'circle' && (\n <circle\n cx={x + width / 2}\n cy={y + height / 2}\n r={Math.min(width, height) / 2}\n {...shapeProps}\n />\n )}\n\n {content.shape === 'line' && (\n <line\n x1={x}\n y1={y}\n x2={x + width}\n y2={y + height}\n stroke={content.stroke || '#ffffff'}\n strokeWidth={content.strokeWidth || 2}\n />\n )}\n </g>\n );\n}\n\nexport default ShapeLayer;\n","/**\n * Map Tile Utilities\n *\n * Functions for fetching and composing map tiles from free/open-source providers.\n * Converts lat/lng to tile coordinates and composites multiple tiles into a\n * single image for SVG embedding.\n *\n * Supported Providers (all free with attribution):\n * - terrain: OpenTopoMap (CC-BY-SA)\n * - road: OpenStreetMap (ODbL)\n * - satellite: ESRI World Imagery (free with attribution)\n * - toner: Stadia/Stamen Toner (free tier)\n * - watercolor: Stadia/Stamen Watercolor (free tier)\n *\n * See docs/MAP_TILES.md for full provider details and terms.\n */\n\nimport type { MapTileStyle, MapMarker } from '@bendyline/squisq/schemas';\n\n/**\n * Tile provider configuration.\n */\nexport interface TileProvider {\n /** URL template with {z}, {x}, {y} placeholders */\n url: string;\n /** Attribution text (required for display) */\n attribution: string;\n /** Maximum zoom level */\n maxZoom: number;\n /** Tile size in pixels (default: 256) */\n tileSize?: number;\n}\n\n/**\n * Free tile providers for each map style.\n * All require attribution to be displayed.\n */\nexport const TILE_PROVIDERS: Record<MapTileStyle, TileProvider> = {\n terrain: {\n url: 'https://tile.opentopomap.org/{z}/{x}/{y}.png',\n attribution: 'Map: OpenTopoMap (CC-BY-SA)',\n maxZoom: 17,\n },\n road: {\n url: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',\n attribution: '© OpenStreetMap contributors',\n maxZoom: 19,\n },\n satellite: {\n url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',\n attribution: 'Imagery: Esri, Maxar, Earthstar',\n maxZoom: 18,\n },\n toner: {\n url: 'https://tiles.stadiamaps.com/tiles/stamen_toner/{z}/{x}/{y}.png',\n attribution: 'Map: Stadia Maps, Stamen Design',\n maxZoom: 20,\n },\n watercolor: {\n url: 'https://tiles.stadiamaps.com/tiles/stamen_watercolor/{z}/{x}/{y}.jpg',\n attribution: 'Map: Stadia Maps, Stamen Design',\n maxZoom: 16,\n },\n};\n\n/**\n * Convert latitude/longitude to tile coordinates at a given zoom level.\n * Uses Web Mercator projection (EPSG:3857).\n */\nexport function latLngToTile(lat: number, lng: number, zoom: number): { x: number; y: number } {\n const n = Math.pow(2, zoom);\n const x = Math.floor(((lng + 180) / 360) * n);\n const latRad = (lat * Math.PI) / 180;\n const y = Math.floor(((1 - Math.log(Math.tan(latRad) + 1 / Math.cos(latRad)) / Math.PI) / 2) * n);\n return { x, y };\n}\n\n/**\n * Convert tile coordinates back to lat/lng (top-left corner of tile).\n */\nexport function tileToLatLng(x: number, y: number, zoom: number): { lat: number; lng: number } {\n const n = Math.pow(2, zoom);\n const lng = (x / n) * 360 - 180;\n const latRad = Math.atan(Math.sinh(Math.PI * (1 - (2 * y) / n)));\n const lat = (latRad * 180) / Math.PI;\n return { lat, lng };\n}\n\n/**\n * Get the pixel offset within a tile for a given lat/lng.\n */\nexport function getPixelOffset(\n lat: number,\n lng: number,\n zoom: number,\n tileSize: number = 256,\n): { x: number; y: number } {\n const n = Math.pow(2, zoom);\n const xTile = ((lng + 180) / 360) * n;\n const latRad = (lat * Math.PI) / 180;\n const yTile = ((1 - Math.log(Math.tan(latRad) + 1 / Math.cos(latRad)) / Math.PI) / 2) * n;\n\n return {\n x: (xTile - Math.floor(xTile)) * tileSize,\n y: (yTile - Math.floor(yTile)) * tileSize,\n };\n}\n\n/**\n * Calculate which tiles are needed to cover a viewport centered on lat/lng.\n */\nexport function getTilesForViewport(\n centerLat: number,\n centerLng: number,\n zoom: number,\n viewportWidth: number,\n viewportHeight: number,\n tileSize: number = 256,\n): Array<{ x: number; y: number; screenX: number; screenY: number }> {\n const centerTile = latLngToTile(centerLat, centerLng, zoom);\n const pixelOffset = getPixelOffset(centerLat, centerLng, zoom, tileSize);\n\n // How many tiles we need in each direction\n const tilesX = Math.ceil(viewportWidth / tileSize) + 1;\n const tilesY = Math.ceil(viewportHeight / tileSize) + 1;\n\n // Start tile offset\n const startX = centerTile.x - Math.floor(tilesX / 2);\n const startY = centerTile.y - Math.floor(tilesY / 2);\n\n // Screen position of the center tile\n const centerScreenX = viewportWidth / 2 - pixelOffset.x;\n const centerScreenY = viewportHeight / 2 - pixelOffset.y;\n\n const tiles: Array<{ x: number; y: number; screenX: number; screenY: number }> = [];\n\n for (let dy = 0; dy < tilesY; dy++) {\n for (let dx = 0; dx < tilesX; dx++) {\n const tileX = startX + dx;\n const tileY = startY + dy;\n const screenX = centerScreenX + (tileX - centerTile.x) * tileSize;\n const screenY = centerScreenY + (tileY - centerTile.y) * tileSize;\n\n tiles.push({ x: tileX, y: tileY, screenX, screenY });\n }\n }\n\n return tiles;\n}\n\n/**\n * Build a tile URL from the provider template.\n */\nexport function buildTileUrl(provider: TileProvider, x: number, y: number, z: number): string {\n return provider.url.replace('{z}', String(z)).replace('{x}', String(x)).replace('{y}', String(y));\n}\n\n/**\n * Fetch a single tile image as an HTMLImageElement.\n */\nasync function fetchTileImage(url: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.crossOrigin = 'anonymous';\n img.onload = () => resolve(img);\n img.onerror = () => reject(new Error(`Failed to load tile: ${url}`));\n img.src = url;\n });\n}\n\n/**\n * Options for composing a map image.\n */\nexport interface ComposeMapOptions {\n /** Center coordinates */\n center: { lat: number; lng: number };\n /** Zoom level */\n zoom: number;\n /** Map tile style */\n style: MapTileStyle;\n /** Output width in pixels */\n width: number;\n /** Output height in pixels */\n height: number;\n /** Optional markers to render */\n markers?: MapMarker[];\n /** Show attribution (default: true) */\n showAttribution?: boolean;\n}\n\n/**\n * Compose map tiles into a single data URL image.\n *\n * This is the main function for generating map images for blocks.\n * It fetches all needed tiles, composites them on a canvas, and\n * returns a data URL that can be used in an SVG <image> element.\n */\nexport async function composeMapImage(options: ComposeMapOptions): Promise<string> {\n const { center, zoom, style, width, height, markers = [], showAttribution = true } = options;\n\n const provider = TILE_PROVIDERS[style];\n const tileSize = provider.tileSize || 256;\n const clampedZoom = Math.min(zoom, provider.maxZoom);\n\n // Create canvas\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext('2d');\n if (!ctx) throw new Error('Failed to get canvas context');\n\n // Fill with a neutral background in case tiles fail to load\n ctx.fillStyle = style === 'toner' ? '#ffffff' : '#e5e7eb';\n ctx.fillRect(0, 0, width, height);\n\n // Get tiles needed\n const tiles = getTilesForViewport(center.lat, center.lng, clampedZoom, width, height, tileSize);\n\n // Fetch and draw tiles\n const tilePromises = tiles.map(async (tile) => {\n const url = buildTileUrl(provider, tile.x, tile.y, clampedZoom);\n try {\n const img = await fetchTileImage(url);\n ctx.drawImage(img, tile.screenX, tile.screenY, tileSize, tileSize);\n } catch (err: unknown) {\n // Tile failed to load - leave background color\n console.warn(`Tile load failed: ${url}`, err);\n }\n });\n\n await Promise.all(tilePromises);\n\n // Draw markers\n for (const marker of markers) {\n drawMarker(ctx, marker, center, clampedZoom, width, height, tileSize);\n }\n\n // Draw attribution\n if (showAttribution) {\n drawAttribution(ctx, provider.attribution, width, height);\n }\n\n return canvas.toDataURL('image/png');\n}\n\n/**\n * Draw a marker on the canvas.\n */\nfunction drawMarker(\n ctx: CanvasRenderingContext2D,\n marker: MapMarker,\n center: { lat: number; lng: number },\n zoom: number,\n width: number,\n height: number,\n tileSize: number,\n): void {\n // Calculate screen position of marker relative to center\n const centerTile = latLngToTile(center.lat, center.lng, zoom);\n const markerTile = latLngToTile(marker.lat, marker.lng, zoom);\n\n const centerOffset = getPixelOffset(center.lat, center.lng, zoom, tileSize);\n const markerOffset = getPixelOffset(marker.lat, marker.lng, zoom, tileSize);\n\n const dx = (markerTile.x - centerTile.x) * tileSize + (markerOffset.x - centerOffset.x);\n const dy = (markerTile.y - centerTile.y) * tileSize + (markerOffset.y - centerOffset.y);\n\n const screenX = width / 2 + dx;\n const screenY = height / 2 + dy;\n\n // Draw marker\n const color = marker.color || '#ef4444';\n const icon = marker.icon || 'pin';\n\n ctx.save();\n\n if (icon === 'pin') {\n // Draw pin shape\n ctx.fillStyle = color;\n ctx.beginPath();\n ctx.arc(screenX, screenY - 12, 8, Math.PI, 0, false);\n ctx.lineTo(screenX, screenY);\n ctx.closePath();\n ctx.fill();\n\n // White dot in center\n ctx.fillStyle = '#ffffff';\n ctx.beginPath();\n ctx.arc(screenX, screenY - 12, 3, 0, Math.PI * 2);\n ctx.fill();\n } else if (icon === 'circle') {\n ctx.fillStyle = color;\n ctx.beginPath();\n ctx.arc(screenX, screenY, 8, 0, Math.PI * 2);\n ctx.fill();\n ctx.strokeStyle = '#ffffff';\n ctx.lineWidth = 2;\n ctx.stroke();\n } else if (icon === 'star') {\n ctx.fillStyle = color;\n drawStar(ctx, screenX, screenY, 5, 10, 5);\n ctx.fill();\n }\n\n // Draw label if present\n if (marker.label) {\n ctx.fillStyle = '#1f2937';\n ctx.font = 'bold 12px system-ui, sans-serif';\n ctx.textAlign = 'center';\n ctx.fillText(marker.label, screenX, screenY + 20);\n }\n\n ctx.restore();\n}\n\n/**\n * Draw a star shape.\n */\nfunction drawStar(\n ctx: CanvasRenderingContext2D,\n cx: number,\n cy: number,\n spikes: number,\n outerRadius: number,\n innerRadius: number,\n): void {\n let rot = (Math.PI / 2) * 3;\n const step = Math.PI / spikes;\n\n ctx.beginPath();\n ctx.moveTo(cx, cy - outerRadius);\n\n for (let i = 0; i < spikes; i++) {\n ctx.lineTo(cx + Math.cos(rot) * outerRadius, cy + Math.sin(rot) * outerRadius);\n rot += step;\n ctx.lineTo(cx + Math.cos(rot) * innerRadius, cy + Math.sin(rot) * innerRadius);\n rot += step;\n }\n\n ctx.lineTo(cx, cy - outerRadius);\n ctx.closePath();\n}\n\n/**\n * Draw attribution text on the canvas.\n */\nfunction drawAttribution(\n ctx: CanvasRenderingContext2D,\n text: string,\n width: number,\n height: number,\n): void {\n ctx.save();\n\n // Semi-transparent background\n ctx.fillStyle = 'rgba(255, 255, 255, 0.8)';\n const padding = 4;\n ctx.font = '10px system-ui, sans-serif';\n const textWidth = ctx.measureText(text).width;\n ctx.fillRect(width - textWidth - padding * 2 - 4, height - 16, textWidth + padding * 2, 14);\n\n // Text\n ctx.fillStyle = '#374151';\n ctx.textAlign = 'right';\n ctx.fillText(text, width - padding - 4, height - 5);\n\n ctx.restore();\n}\n\n/**\n * Get attribution text for a map style.\n */\nexport function getAttribution(style: MapTileStyle): string {\n return TILE_PROVIDERS[style].attribution;\n}\n","/**\n * MapLayer Component\n *\n * Renders a geographic map layer within an SVG block. Maps are composed from\n * static tile images fetched from free/open-source providers.\n *\n * For video export reliability, maps can use pre-rendered static images via\n * the staticSrc property, avoiding tile loading race conditions during capture.\n *\n * Tile fetching: Tiles are loaded on mount and composited into a data URL\n * for SVG embedding. This ensures correct rendering in both browser and\n * Playwright screenshot contexts.\n */\n\nimport { useState, useEffect } from 'react';\nimport type { MapLayer as MapLayerType } from '@bendyline/squisq/schemas';\nimport { getAnimationStyle } from '../utils/animationUtils';\nimport { resolveValue, getAnchorOffset } from '../utils/layerUtils';\nimport { composeMapImage } from '../utils/mapTileUtils';\n\ninterface MapLayerProps {\n layer: MapLayerType;\n /** Base path for resolving relative image URLs */\n basePath: string;\n /** Viewport dimensions for percentage calculations */\n viewport: { width: number; height: number };\n /** Current time relative to block start (for animation timing) */\n blockTime: number;\n}\n\nexport function MapLayer({ layer, basePath, viewport, blockTime }: MapLayerProps) {\n const { content, position, animation } = layer;\n const [mapImageUrl, setMapImageUrl] = useState<string | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n // Resolve position values to pixels\n const x = resolveValue(position.x, viewport.width);\n const y = resolveValue(position.y, viewport.height);\n const width = position.width ? resolveValue(position.width, viewport.width) : viewport.width;\n const height = position.height ? resolveValue(position.height, viewport.height) : viewport.height;\n\n // Apply anchor offset\n const offset = getAnchorOffset(position.anchor, width, height);\n const finalX = x + offset.x;\n const finalY = y + offset.y;\n\n // Use static image if provided, otherwise fetch and compose tiles\n useEffect(() => {\n let cancelled = false;\n\n if (content.staticSrc) {\n // Use pre-rendered static image\n const src = content.staticSrc.startsWith('http')\n ? content.staticSrc\n : `${basePath}/${content.staticSrc}`;\n setMapImageUrl(src);\n setIsLoading(false);\n return;\n }\n\n // Compose map from tiles\n setIsLoading(true);\n setError(null);\n\n composeMapImage({\n center: content.center,\n zoom: content.zoom,\n style: content.style,\n width,\n height,\n markers: content.markers,\n showAttribution: content.showAttribution !== false,\n })\n .then((dataUrl) => {\n if (!cancelled) {\n setMapImageUrl(dataUrl);\n setIsLoading(false);\n }\n })\n .catch((err: unknown) => {\n if (!cancelled) {\n console.error('Failed to compose map:', err);\n setError(err instanceof Error ? err.message : String(err));\n setIsLoading(false);\n }\n });\n\n return () => {\n cancelled = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- content properties are destructured below; center/markers/showAttribution are stable per-render\n }, [\n content.center.lat,\n content.center.lng,\n content.zoom,\n content.style,\n content.staticSrc,\n width,\n height,\n basePath,\n ]);\n\n // Get animation styles\n const animStyle = getAnimationStyle(animation, blockTime);\n\n // Render loading state\n if (isLoading) {\n return (\n <g\n className={`block-layer block-layer--map ${animStyle.className}`}\n style={animStyle.style}\n data-layer-id={layer.id}\n >\n <rect x={finalX} y={finalY} width={width} height={height} fill=\"#e5e7eb\" />\n <text\n x={finalX + width / 2}\n y={finalY + height / 2}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n fill=\"#9ca3af\"\n fontSize=\"24\"\n fontFamily=\"system-ui, sans-serif\"\n >\n Loading map...\n </text>\n </g>\n );\n }\n\n // Render error state\n if (error || !mapImageUrl) {\n return (\n <g\n className={`block-layer block-layer--map ${animStyle.className}`}\n style={animStyle.style}\n data-layer-id={layer.id}\n >\n <rect x={finalX} y={finalY} width={width} height={height} fill=\"#fef2f2\" />\n <text\n x={finalX + width / 2}\n y={finalY + height / 2}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n fill=\"#dc2626\"\n fontSize=\"18\"\n fontFamily=\"system-ui, sans-serif\"\n >\n Map failed to load\n </text>\n </g>\n );\n }\n\n return (\n <g\n className={`block-layer block-layer--map ${animStyle.className}`}\n style={animStyle.style}\n data-layer-id={layer.id}\n >\n {/* Clip path for overflow handling */}\n <defs>\n <clipPath id={`clip-${layer.id}`}>\n <rect x={finalX} y={finalY} width={width} height={height} />\n </clipPath>\n </defs>\n\n {/* Map image */}\n <g clipPath={`url(#clip-${layer.id})`}>\n <image\n href={mapImageUrl}\n x={finalX}\n y={finalY}\n width={width}\n height={height}\n preserveAspectRatio=\"xMidYMid slice\"\n style={{ pointerEvents: 'none' }}\n />\n </g>\n </g>\n );\n}\n\nexport default MapLayer;\n","/**\n * VideoLayer Component\n *\n * Renders a video clip layer within an SVG block. Uses an HTML5 <video> element\n * inside a <foreignObject> (same pattern as ImageLayer for cover-mode images).\n * Videos are always muted — narration audio is the only sound track.\n *\n * Two modes of operation:\n * 1. Normal playback: Video auto-plays from clipStart to clipEnd on mount,\n * pausing when the clip ends or when the block is no longer active.\n * 2. Render/seekTo mode (Playwright frame capture): Video is paused and seeked\n * programmatically via data attributes read by DocPlayer's seekTo handler.\n *\n * The <video> element carries data-clip-start and data-clip-end attributes so\n * the seekTo handler can calculate the correct video time for any doc time.\n *\n * Related Files:\n * - schemas/Doc.ts — VideoLayer type definition\n * - shared/doc/templates/videoWithCaption.ts — template producing VideoLayers\n * - site/src/components/doc/DocPlayer.tsx — seekTo handler for video sync\n * - site/src/components/doc/layers/ImageLayer.tsx — similar foreignObject pattern\n */\n\nimport { useRef, useEffect } from 'react';\nimport type { VideoLayer as VideoLayerType } from '@bendyline/squisq/schemas';\nimport { useMediaUrl } from '../hooks/MediaContext';\nimport { resolveValue, getAnchorOffset } from '../utils/layerUtils';\n\ninterface VideoLayerProps {\n layer: VideoLayerType;\n /** Base path for resolving relative video URLs */\n basePath: string;\n /** Viewport dimensions for percentage calculations */\n viewport: { width: number; height: number };\n /** Current time relative to block start (for playback sync) */\n blockTime: number;\n /** Whether the doc is currently playing */\n isPlaying?: boolean;\n}\n\nexport function VideoLayer({\n layer,\n basePath,\n viewport,\n blockTime: _blockTime,\n isPlaying,\n}: VideoLayerProps) {\n const { content, position } = layer;\n const videoRef = useRef<HTMLVideoElement>(null);\n const hasStartedRef = useRef(false);\n\n // Resolve position values to pixels\n const x = resolveValue(position.x, viewport.width);\n const y = resolveValue(position.y, viewport.height);\n const width = position.width ? resolveValue(position.width, viewport.width) : viewport.width;\n const height = position.height ? resolveValue(position.height, viewport.height) : viewport.height;\n\n // Apply anchor offset\n const offset = getAnchorOffset(position.anchor, width, height);\n const finalX = x + offset.x;\n const finalY = y + offset.y;\n\n // Resolve video URL via MediaProvider (if available), falling back to basePath\n const src = useMediaUrl(content.src, basePath);\n\n // Always call the hook (Rules of Hooks), but pass empty string when no poster\n const resolvedPoster = useMediaUrl(content.posterSrc || '', basePath);\n const posterSrc = content.posterSrc ? resolvedPoster : undefined;\n\n // On mount: seek to clipStart and set up clipEnd boundary.\n // The video will be muted and play silently alongside the narration.\n useEffect(() => {\n const video = videoRef.current;\n if (!video) return;\n\n // Set initial time to clipStart\n video.currentTime = content.clipStart;\n hasStartedRef.current = true;\n\n // Start playing if doc is already playing\n if (isPlaying) {\n const playPromise = video.play();\n if (playPromise) {\n playPromise.catch(() => {\n // Autoplay blocked — fine for Playwright seekTo mode\n });\n }\n }\n\n // Monitor timeupdate to pause at clipEnd\n const handleTimeUpdate = () => {\n if (video.currentTime >= content.clipEnd) {\n video.pause();\n video.currentTime = content.clipEnd;\n }\n };\n\n video.addEventListener('timeupdate', handleTimeUpdate);\n return () => {\n video.removeEventListener('timeupdate', handleTimeUpdate);\n video.pause();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- isPlaying is handled by the separate sync effect below\n }, [content.src, content.clipStart, content.clipEnd]);\n\n // Sync video play/pause with doc playback state\n useEffect(() => {\n const video = videoRef.current;\n if (!video || !hasStartedRef.current) return;\n\n // Don't resume if clip has already reached its end\n if (video.currentTime >= content.clipEnd) return;\n\n if (isPlaying) {\n const playPromise = video.play();\n if (playPromise) {\n playPromise.catch(() => {});\n }\n } else {\n video.pause();\n }\n }, [isPlaying, content.clipEnd]);\n\n return (\n <g className=\"block-layer block-layer--video\" data-layer-id={layer.id}>\n <foreignObject x={finalX} y={finalY} width={width} height={height}>\n <video\n ref={videoRef}\n src={src}\n poster={posterSrc}\n muted\n playsInline\n preload=\"auto\"\n data-clip-start={content.clipStart}\n data-clip-end={content.clipEnd}\n style={{\n width: '100%',\n height: '100%',\n objectFit: content.fit || 'cover',\n objectPosition: 'center',\n display: 'block',\n pointerEvents: 'none',\n }}\n />\n </foreignObject>\n </g>\n );\n}\n\nexport default VideoLayer;\n","/**\n * BlockRenderer Component\n *\n * Renders a single block as an SVG element with all its layers.\n * Each layer is rendered back-to-front (first layer is background).\n * Handles positioning, animations, and transitions.\n */\n\nimport type { Block, Layer } from '@bendyline/squisq/schemas';\nimport { ImageLayer } from './layers/ImageLayer';\nimport { TextLayer } from './layers/TextLayer';\nimport { ShapeLayer } from './layers/ShapeLayer';\nimport { MapLayer } from './layers/MapLayer';\nimport { VideoLayer } from './layers/VideoLayer';\nimport { getTransitionClass } from './utils/animationUtils';\n\n/** Default viewport dimensions (1080p landscape) - for backwards compatibility */\n// eslint-disable-next-line react-refresh/only-export-components\nexport const VIEWPORT = {\n width: 1920,\n height: 1080,\n};\n\n/** Viewport configuration type */\nexport interface ViewportDimensions {\n width: number;\n height: number;\n}\n\ninterface BlockRendererProps {\n /** The block to render */\n block: Block;\n /** Current time relative to block start (seconds) */\n blockTime: number;\n /** Base path for resolving media URLs */\n basePath: string;\n /** Whether this block is entering (for transition) */\n isEntering?: boolean;\n /** Whether this block is exiting (for transition) */\n isExiting?: boolean;\n /** Viewport dimensions (defaults to 1920x1080 landscape) */\n viewport?: ViewportDimensions;\n /** Whether the doc is currently playing (controls video playback) */\n isPlaying?: boolean;\n}\n\nexport function BlockRenderer({\n block,\n blockTime,\n basePath,\n isEntering = false,\n isExiting = false,\n viewport = VIEWPORT,\n isPlaying,\n}: BlockRendererProps) {\n // Build transition class and inline style for dynamic duration\n let transitionClass = '';\n const transitionStyle: Record<string, string> = {};\n if (block.transition && isEntering) {\n transitionClass = getTransitionClass(block.transition.type, true);\n transitionStyle['--transition-duration'] = `${block.transition.duration}s`;\n } else if (block.transition && isExiting) {\n transitionClass = getTransitionClass(block.transition.type, false);\n transitionStyle['--transition-duration'] = `${block.transition.duration}s`;\n }\n\n // Unique clip path ID per block to avoid conflicts when multiple blocks render simultaneously\n const clipId = `vb-clip-${block.id}`;\n\n return (\n <svg\n className={`block-svg ${transitionClass}`}\n style={transitionStyle}\n viewBox={`0 0 ${viewport.width} ${viewport.height}`}\n preserveAspectRatio=\"xMidYMid meet\"\n overflow=\"hidden\"\n data-block-id={block.id}\n >\n {/* Clip path matching the viewBox -- prevents Ken Burns animations from\n bleeding outside the block area (foreignObject + transform: scale\n can escape SVG overflow=\"hidden\" in some browsers) */}\n <defs>\n <clipPath id={clipId}>\n <rect x=\"0\" y=\"0\" width={viewport.width} height={viewport.height} />\n </clipPath>\n </defs>\n\n {/* All layers clipped to viewBox bounds */}\n <g clipPath={`url(#${clipId})`}>\n {(block.layers ?? []).map((layer) => (\n <LayerRenderer\n key={layer.id}\n layer={layer}\n basePath={basePath}\n viewport={viewport}\n blockTime={blockTime}\n isPlaying={isPlaying}\n />\n ))}\n </g>\n </svg>\n );\n}\n\ninterface LayerRendererProps {\n layer: Layer;\n basePath: string;\n viewport: { width: number; height: number };\n blockTime: number;\n isPlaying?: boolean;\n}\n\n/**\n * Dispatch to the appropriate layer component based on type.\n */\nfunction LayerRenderer({ layer, basePath, viewport, blockTime, isPlaying }: LayerRendererProps) {\n switch (layer.type) {\n case 'image':\n return (\n <ImageLayer layer={layer} basePath={basePath} viewport={viewport} blockTime={blockTime} />\n );\n case 'text':\n return <TextLayer layer={layer} viewport={viewport} blockTime={blockTime} />;\n case 'shape':\n return <ShapeLayer layer={layer} viewport={viewport} blockTime={blockTime} />;\n case 'map':\n return (\n <MapLayer layer={layer} basePath={basePath} viewport={viewport} blockTime={blockTime} />\n );\n case 'video':\n return (\n <VideoLayer\n layer={layer}\n basePath={basePath}\n viewport={viewport}\n blockTime={blockTime}\n isPlaying={isPlaying}\n />\n );\n default:\n console.warn(`Unknown layer type: ${(layer as Layer).type}`);\n return null;\n }\n}\n\nexport default BlockRenderer;\n","/**\n * SocialCaptionOverlay Component\n *\n * Social media-style captions (Instagram/TikTok): large centered words\n * showing 3-5 words at a time with the currently-spoken word highlighted\n * in the theme's primary color. Font and colors are pulled from the\n * active theme.\n *\n * Words are gathered across all caption phrases into a continuous stream,\n * then chunked into uniform groups for smooth, consistent pacing.\n *\n * Supports two timing modes:\n * 1. Precise: uses per-word timestamps from CaptionPhrase.words\n * 2. Interpolated: distributes timing evenly within each phrase\n */\n\nimport { useMemo } from 'react';\nimport type { CaptionTrack, CaptionPhrase, ViewportConfig } from '@bendyline/squisq/schemas';\nimport type { Theme } from '@bendyline/squisq/schemas';\n\n/** Target words per visible chunk. */\nconst TARGET_CHUNK_SIZE = 4;\nconst MIN_CHUNK_SIZE = 2;\nconst MAX_CHUNK_SIZE = 6;\n\n/** A timed word derived from phrase data. */\ninterface TimedWord {\n text: string;\n startTime: number;\n endTime: number;\n}\n\n/** A chunk of words displayed together. */\ninterface WordChunk {\n words: TimedWord[];\n startTime: number;\n endTime: number;\n}\n\n/**\n * Resolve per-word timing for a single phrase.\n * Uses precise word timestamps when available, otherwise interpolates.\n */\nfunction resolvePhraseTiming(phrase: CaptionPhrase): TimedWord[] {\n // Use precise timing when available\n if (phrase.words && phrase.words.length > 0) {\n return phrase.words.map((w) => ({\n text: w.text,\n startTime: w.startTime,\n endTime: w.endTime,\n }));\n }\n\n // Interpolate: split text into words, distribute evenly\n const rawWords = phrase.text.split(/\\s+/).filter((w) => w.length > 0);\n if (rawWords.length === 0) return [];\n\n const duration = phrase.endTime - phrase.startTime;\n const wordDuration = duration / rawWords.length;\n\n return rawWords.map((text, i) => ({\n text,\n startTime: phrase.startTime + i * wordDuration,\n endTime: phrase.startTime + (i + 1) * wordDuration,\n }));\n}\n\n/**\n * Build a continuous stream of timed words from ALL caption phrases,\n * then group into uniform display chunks. This eliminates the \"pulsy\"\n * feeling caused by per-phrase chunking with variable phrase lengths.\n */\nfunction buildWordStream(captions: CaptionTrack): { words: TimedWord[]; chunks: WordChunk[] } {\n // Gather all words across all phrases\n const allWords: TimedWord[] = [];\n for (const phrase of captions.phrases) {\n allWords.push(...resolvePhraseTiming(phrase));\n }\n\n if (allWords.length === 0) return { words: [], chunks: [] };\n\n // Determine uniform chunk size\n let chunkSize = TARGET_CHUNK_SIZE;\n if (allWords.length > chunkSize) {\n const numChunks = Math.ceil(allWords.length / chunkSize);\n chunkSize = Math.ceil(allWords.length / numChunks);\n chunkSize = Math.min(MAX_CHUNK_SIZE, Math.max(MIN_CHUNK_SIZE, chunkSize));\n } else {\n chunkSize = Math.max(MIN_CHUNK_SIZE, allWords.length);\n }\n\n // Build chunks\n const chunks: WordChunk[] = [];\n for (let i = 0; i < allWords.length; i += chunkSize) {\n const chunkWords = allWords.slice(i, i + chunkSize);\n chunks.push({\n words: chunkWords,\n startTime: chunkWords[0].startTime,\n endTime: chunkWords[chunkWords.length - 1].endTime,\n });\n }\n\n return { words: allWords, chunks };\n}\n\ninterface SocialCaptionOverlayProps {\n captions: CaptionTrack | undefined;\n currentTime: number;\n enabled?: boolean;\n theme?: Theme;\n viewport?: ViewportConfig;\n}\n\nexport function SocialCaptionOverlay({\n captions,\n currentTime,\n enabled = true,\n theme,\n viewport,\n}: SocialCaptionOverlayProps) {\n // Build the word stream once when captions change (memoized)\n const { chunks } = useMemo(\n () => (captions ? buildWordStream(captions) : { words: [], chunks: [] }),\n [captions],\n );\n\n if (!enabled || chunks.length === 0) {\n return (\n <div\n className=\"social-caption-overlay\"\n style={{\n position: 'absolute',\n bottom: '18%',\n left: 0,\n right: 0,\n zIndex: 50,\n pointerEvents: 'none',\n opacity: 0,\n transition: 'opacity 0.15s ease-in-out',\n }}\n />\n );\n }\n\n // Find the active chunk and word using binary-style search\n let activeChunk: WordChunk | null = null;\n let activeWordIndex = -1;\n\n for (const chunk of chunks) {\n if (currentTime >= chunk.startTime && currentTime < chunk.endTime) {\n activeChunk = chunk;\n break;\n }\n }\n\n // If between chunks (gap), show the nearest chunk\n if (!activeChunk) {\n for (let i = 0; i < chunks.length - 1; i++) {\n if (currentTime >= chunks[i].endTime && currentTime < chunks[i + 1].startTime) {\n // In a gap — show the chunk we just left (feels more natural)\n activeChunk = chunks[i];\n activeWordIndex = activeChunk.words.length - 1;\n break;\n }\n }\n // Past all chunks\n if (!activeChunk && chunks.length > 0 && currentTime >= chunks[chunks.length - 1].startTime) {\n activeChunk = chunks[chunks.length - 1];\n activeWordIndex = activeChunk.words.length - 1;\n }\n }\n\n if (!activeChunk) return null;\n\n // Find active word within chunk (if not already set from gap handling)\n if (activeWordIndex === -1) {\n for (let i = 0; i < activeChunk.words.length; i++) {\n const word = activeChunk.words[i];\n if (currentTime >= word.startTime && currentTime < word.endTime) {\n activeWordIndex = i;\n break;\n }\n }\n // Fallback: last word before currentTime\n if (activeWordIndex === -1) {\n for (let i = activeChunk.words.length - 1; i >= 0; i--) {\n if (currentTime >= activeChunk.words[i].startTime) {\n activeWordIndex = i;\n break;\n }\n }\n }\n // Final fallback\n if (activeWordIndex === -1) activeWordIndex = 0;\n }\n\n // Theme-derived styling\n const primaryColor = theme?.colors?.primary ?? '#5b9bd5';\n const fontFamily = theme?.typography?.titleFontFamily\n ? `\"${theme.typography.titleFontFamily}\", system-ui, sans-serif`\n : '\"PT Serif\", Georgia, serif';\n\n // Scale font to viewport — aim for ~5.5% of viewport height\n const viewportHeight = viewport?.height ?? 720;\n const baseFontSize = Math.round(viewportHeight * 0.055);\n const fontSize = Math.max(24, Math.min(72, baseFontSize));\n\n return (\n <div\n className=\"social-caption-overlay\"\n style={{\n position: 'absolute',\n bottom: '18%',\n left: 0,\n right: 0,\n zIndex: 50,\n pointerEvents: 'none',\n textAlign: 'center',\n padding: '0 8%',\n boxSizing: 'border-box',\n opacity: 1,\n transition: 'opacity 0.15s ease-in-out',\n }}\n >\n <div\n style={{\n display: 'inline-block',\n lineHeight: 1.3,\n }}\n >\n {activeChunk.words.map((word, i) => {\n const isActive = i === activeWordIndex;\n return (\n <span\n key={`${word.startTime}-${i}`}\n style={{\n fontFamily,\n fontSize: `${fontSize}px`,\n fontWeight: isActive ? 800 : 600,\n color: isActive ? primaryColor : 'rgba(255, 255, 255, 0.9)',\n textShadow: '0 2px 8px rgba(0,0,0,0.7), 0 0 20px rgba(0,0,0,0.4)',\n marginRight: i < activeChunk!.words.length - 1 ? '0.3em' : undefined,\n transition: 'color 0.1s ease, font-weight 0.1s ease',\n textTransform: 'uppercase',\n }}\n >\n {word.text}\n </span>\n );\n })}\n </div>\n </div>\n );\n}\n","/**\n * CaptionOverlay Component\n *\n * Displays closed captions synchronized with audio playback.\n * Supports two styles:\n *\n * - `'standard'` (default): Traditional broadcast captions — small white text\n * on a semi-transparent black badge at the top of the player.\n * - `'social'`: Social media-style (Instagram/TikTok) — large centered words\n * with the active word highlighted in the theme's primary color.\n */\n\nimport type { CaptionTrack, ViewportConfig } from '@bendyline/squisq/schemas';\nimport { getCaptionAtTime } from '@bendyline/squisq/schemas';\nimport type { Theme } from '@bendyline/squisq/schemas';\nimport type { CaptionStyle } from './types';\nimport { SocialCaptionOverlay } from './SocialCaptionOverlay';\n\ninterface CaptionOverlayProps {\n /** Caption track with timestamped phrases */\n captions: CaptionTrack | undefined;\n /** Current playback time in seconds */\n currentTime: number;\n /** Whether captions are enabled */\n enabled?: boolean;\n /** Font size in pixels for standard style (default: 16) */\n fontSize?: number;\n /** Caption display style (default: 'standard') */\n captionStyle?: CaptionStyle;\n /** Theme for social-style caption colors and fonts */\n theme?: Theme;\n /** Viewport config for social-style font scaling */\n viewport?: ViewportConfig;\n}\n\nexport function CaptionOverlay({\n captions,\n currentTime,\n enabled = true,\n fontSize = 16,\n captionStyle = 'standard',\n theme,\n viewport,\n}: CaptionOverlayProps) {\n // Delegate to social overlay when that style is active\n if (captionStyle === 'social') {\n return (\n <SocialCaptionOverlay\n captions={captions}\n currentTime={currentTime}\n enabled={enabled}\n theme={theme}\n viewport={viewport}\n />\n );\n }\n\n // Standard caption rendering\n const phrase = enabled && captions ? getCaptionAtTime(captions, currentTime) : null;\n const captionText = phrase?.text ?? null;\n\n return (\n <div\n className=\"caption-overlay\"\n style={{\n position: 'absolute',\n top: '6px',\n left: '50%',\n transform: 'translateX(-50%)',\n zIndex: 50,\n pointerEvents: 'none',\n maxWidth: '100%',\n width: '100%',\n textAlign: 'center',\n opacity: captionText ? 1 : 0,\n transition: 'opacity 0.15s ease-in-out',\n padding: '0 4px',\n boxSizing: 'border-box',\n }}\n >\n {captionText && (\n <div\n style={{\n display: 'inline-block',\n padding: '3px 10px',\n background: 'rgba(0, 0, 0, 0.65)',\n borderRadius: '4px',\n backdropFilter: 'blur(4px)',\n }}\n >\n <span\n style={{\n color: '#ffffff',\n fontSize: `${fontSize}px`,\n fontFamily: \"'Hanken Grotesk', system-ui, sans-serif\",\n fontWeight: 500,\n lineHeight: 1.25,\n textShadow: '0 1px 3px rgba(0,0,0,0.5)',\n whiteSpace: 'pre-wrap',\n wordWrap: 'break-word',\n }}\n >\n {captionText}\n </span>\n </div>\n )}\n </div>\n );\n}\n\nexport default CaptionOverlay;\n","/**\n * useAudioSync Hook\n *\n * Synchronizes playback state with an audio element. Provides current\n * playback time, playing state, and methods to control audio playback.\n *\n * Handles multiple audio segments (MP3 files) by tracking which segment\n * is currently playing and calculating the overall timeline position.\n *\n * This is the HTML5 Audio implementation of the AudioProvider interface.\n * For EFB/MSFS environments, use useCompanionAudioSync instead.\n */\n\nimport { useState, useEffect, useRef, useCallback } from 'react';\nimport type { RefObject } from 'react';\nimport type { AudioTrack } from '@bendyline/squisq/schemas';\nimport type { AudioProvider } from './AudioProvider';\n\nexport function useAudioSync(\n audioRef: RefObject<HTMLAudioElement>,\n audioTrack: AudioTrack | undefined,\n basePath: string = '',\n): AudioProvider {\n const [currentTime, setCurrentTime] = useState(0);\n const [isPlaying, setIsPlaying] = useState(false);\n const [currentSegment, setCurrentSegment] = useState(0);\n const [isEnded, setIsEnded] = useState(false);\n const [isAudioReady, setIsAudioReady] = useState(false);\n const [totalDuration, setTotalDuration] = useState(0);\n\n // Calculate segment start times\n const segmentStarts = useRef<number[]>([]);\n\n // Pending seek time (used when switching segments)\n const pendingSeekTime = useRef<number | null>(null);\n const shouldPlayAfterLoad = useRef(false);\n\n // Preloaded audio blob URLs (for seeking without range request support)\n const blobUrls = useRef<Map<string, string>>(new Map());\n const loadingPromises = useRef<Map<string, Promise<string>>>(new Map());\n\n // Fallback timer: when audio.play() is blocked (e.g., autoplay policy),\n // advance currentTime synthetically so blocks still progress without audio.\n const fallbackMode = useRef(false);\n\n useEffect(() => {\n if (!audioTrack?.segments) {\n return;\n }\n\n let time = 0;\n segmentStarts.current = audioTrack.segments.map((seg) => {\n const start = time;\n time += seg.duration;\n return start;\n });\n setTotalDuration(time);\n }, [audioTrack]);\n\n // Preload audio file as blob (enables seeking without range request support)\n const preloadAudio = useCallback(\n async (src: string): Promise<string> => {\n const audioUrl = basePath ? `${basePath}/${src}` : src;\n\n // Return cached blob URL if available\n if (blobUrls.current.has(src)) {\n return blobUrls.current.get(src)!;\n }\n\n // Return existing loading promise if in progress\n if (loadingPromises.current.has(src)) {\n return loadingPromises.current.get(src)!;\n }\n\n // Start loading\n const loadPromise = (async () => {\n try {\n const response = await fetch(audioUrl);\n if (!response.ok) throw new Error(`HTTP ${response.status}`);\n const blob = await response.blob();\n const blobUrl = URL.createObjectURL(blob);\n blobUrls.current.set(src, blobUrl);\n return blobUrl;\n } catch {\n // Fall back to direct URL if blob loading fails\n return audioUrl;\n } finally {\n loadingPromises.current.delete(src);\n }\n })();\n\n loadingPromises.current.set(src, loadPromise);\n return loadPromise;\n },\n [basePath],\n );\n\n // Preload all audio segments on mount\n useEffect(() => {\n if (!audioTrack?.segments) return;\n\n // Preload all segments in parallel\n audioTrack.segments.forEach((segment) => {\n preloadAudio(segment.src);\n });\n\n // Cleanup blob URLs on unmount\n const currentBlobUrls = blobUrls.current;\n return () => {\n currentBlobUrls.forEach((url) => {\n URL.revokeObjectURL(url);\n });\n currentBlobUrls.clear();\n };\n }, [audioTrack, preloadAudio]);\n\n // Handle audio time updates\n useEffect(() => {\n const audio = audioRef.current;\n if (!audio) return;\n\n const handleTimeUpdate = () => {\n // Calculate overall timeline position\n const segmentStart = segmentStarts.current[currentSegment] || 0;\n const overallTime = segmentStart + audio.currentTime;\n setCurrentTime(overallTime);\n };\n\n const handlePlay = () => {\n fallbackMode.current = false;\n setIsPlaying(true);\n };\n const handlePause = () => setIsPlaying(false);\n const handleError = () => {\n // Audio source failed to load (e.g., 404 in CI or missing files).\n // Set ready so the UI can still render controls and progress.\n setIsAudioReady(true);\n };\n const handleEnded = () => {\n // Move to next segment or end\n if (audioTrack && currentSegment < audioTrack.segments.length - 1) {\n // Auto-advance to next segment\n // Set shouldPlayAfterLoad so the next segment auto-plays after loading\n shouldPlayAfterLoad.current = true;\n setCurrentSegment((prev) => prev + 1);\n } else {\n setIsEnded(true);\n setIsPlaying(false);\n }\n };\n\n audio.addEventListener('timeupdate', handleTimeUpdate);\n audio.addEventListener('play', handlePlay);\n audio.addEventListener('pause', handlePause);\n audio.addEventListener('ended', handleEnded);\n audio.addEventListener('error', handleError);\n\n return () => {\n audio.removeEventListener('timeupdate', handleTimeUpdate);\n audio.removeEventListener('play', handlePlay);\n audio.removeEventListener('pause', handlePause);\n audio.removeEventListener('ended', handleEnded);\n audio.removeEventListener('error', handleError);\n };\n }, [audioRef, currentSegment, audioTrack]);\n\n // Load new segment when currentSegment changes\n useEffect(() => {\n const audio = audioRef.current;\n if (!audio || !audioTrack?.segments) return;\n\n const segment = audioTrack.segments[currentSegment];\n if (!segment) return;\n\n // Apply pending seek and play state\n const applyPendingSeek = () => {\n if (pendingSeekTime.current !== null) {\n const segmentStart = segmentStarts.current[currentSegment] || 0;\n const segmentTime = pendingSeekTime.current - segmentStart;\n audio.currentTime = Math.max(0, segmentTime);\n setCurrentTime(pendingSeekTime.current);\n pendingSeekTime.current = null;\n }\n\n if (shouldPlayAfterLoad.current) {\n audio.play().catch(() => {});\n shouldPlayAfterLoad.current = false;\n }\n };\n\n // Check if we're already on this source (avoid unnecessary reload)\n // For blob URLs, check by segment src key\n const currentSrc = audio.src;\n const cachedBlobUrl = blobUrls.current.get(segment.src);\n const isSameSource =\n currentSrc && (currentSrc === cachedBlobUrl || currentSrc.endsWith(segment.src));\n\n if (!isSameSource) {\n // Need to load new source - use preloaded blob URL\n const loadAndPlay = async () => {\n const blobUrl = await preloadAudio(segment.src);\n\n const handleCanPlay = () => {\n setIsAudioReady(true);\n applyPendingSeek();\n audio.removeEventListener('canplay', handleCanPlay);\n };\n\n audio.addEventListener('canplay', handleCanPlay);\n audio.src = blobUrl;\n audio.load();\n\n // If audio is already ready (blob is instant), canplay might not fire\n // Check after a microtask to see if it's ready\n await Promise.resolve();\n if (audio.readyState >= 3) {\n audio.removeEventListener('canplay', handleCanPlay);\n setIsAudioReady(true);\n applyPendingSeek();\n }\n };\n\n loadAndPlay();\n } else {\n // Same source - apply seek directly\n applyPendingSeek();\n }\n }, [audioRef, currentSegment, audioTrack, preloadAudio]);\n\n const play = useCallback(() => {\n const audio = audioRef.current;\n if (audio) {\n if (isEnded) {\n // Restart from beginning\n setCurrentSegment(0);\n setIsEnded(false);\n }\n audio\n .play()\n .then(() => {\n fallbackMode.current = false;\n })\n .catch(() => {\n // Audio playback failed (e.g., autoplay policy or 404).\n // Enable fallback timer so blocks progress without audio.\n fallbackMode.current = true;\n setIsPlaying(true);\n });\n }\n }, [audioRef, isEnded]);\n\n const pause = useCallback(() => {\n const audio = audioRef.current;\n if (audio) {\n audio.pause();\n }\n // Also set state directly for cases where audio isn't loaded\n // (pause event won't fire if audio has no valid source)\n setIsPlaying(false);\n }, [audioRef]);\n\n const toggle = useCallback(() => {\n const audio = audioRef.current;\n if (!audio) return;\n\n // Use component state instead of audio.paused to handle cases where\n // audio source isn't loaded (audio.paused is always true without a source)\n if (!isPlaying) {\n play();\n } else {\n pause();\n }\n }, [audioRef, isPlaying, play, pause]);\n\n const seekTo = useCallback(\n (time: number) => {\n const audio = audioRef.current;\n if (!audio || !audioTrack?.segments) return;\n\n // Clamp time to valid range.\n // When totalDuration is 0 (no audio segments), don't clamp — allow\n // seeking by block timing alone (used in render mode / preview).\n const clampedTime =\n totalDuration > 0 ? Math.max(0, Math.min(time, totalDuration)) : Math.max(0, time);\n\n // Find which segment this time falls into\n let segmentIndex = 0;\n let segmentStart = 0;\n for (let i = 0; i < audioTrack.segments.length; i++) {\n const segEnd = segmentStart + audioTrack.segments[i].duration;\n if (clampedTime < segEnd) {\n segmentIndex = i;\n break;\n }\n segmentStart = segEnd;\n // Handle edge case: time exactly at end goes to last segment\n if (i === audioTrack.segments.length - 1) {\n segmentIndex = i;\n }\n }\n\n const wasPlaying = !audio.paused;\n setIsEnded(false);\n\n // Check if we need to switch segments\n if (segmentIndex !== currentSegment) {\n // Store pending seek time - will be applied after segment loads\n pendingSeekTime.current = clampedTime;\n shouldPlayAfterLoad.current = wasPlaying;\n setCurrentSegment(segmentIndex);\n } else {\n // Same segment - seek directly\n const segmentTime = clampedTime - segmentStart;\n audio.currentTime = Math.max(0, segmentTime);\n setCurrentTime(clampedTime);\n }\n },\n [audioRef, audioTrack, currentSegment, totalDuration],\n );\n\n const skipToSegment = useCallback(\n (index: number) => {\n if (!audioTrack?.segments || index < 0 || index >= audioTrack.segments.length) {\n return;\n }\n setCurrentSegment(index);\n setIsEnded(false);\n },\n [audioTrack],\n );\n\n // Restart from beginning\n const restart = useCallback(async () => {\n seekTo(0);\n // Small delay to ensure seek completes before playing\n await new Promise((resolve) => setTimeout(resolve, 50));\n play();\n }, [seekTo, play]);\n\n // Fallback timer: advance currentTime synthetically when audio.play() was blocked\n // (e.g., autoplay policy or missing audio). Blocks progress at real-time pace\n // without sound. Stops when audio actually starts playing or playback is paused.\n useEffect(() => {\n if (!isPlaying || !fallbackMode.current || !totalDuration) return;\n\n let lastTime = performance.now();\n let raf: number;\n\n const tick = (now: number) => {\n // Audio started playing for real — stop the fallback\n if (!fallbackMode.current) return;\n\n const dt = (now - lastTime) / 1000;\n lastTime = now;\n\n setCurrentTime((prev) => {\n const next = prev + dt;\n if (next >= totalDuration) {\n fallbackMode.current = false;\n setIsEnded(true);\n setIsPlaying(false);\n return totalDuration;\n }\n return next;\n });\n\n raf = requestAnimationFrame(tick);\n };\n\n raf = requestAnimationFrame(tick);\n return () => cancelAnimationFrame(raf);\n }, [isPlaying, totalDuration]);\n\n return {\n // State\n currentTime,\n isPlaying,\n currentSegment,\n totalDuration,\n isEnded,\n isReady: isAudioReady,\n isAvailable: true, // HTML5 audio is always available in browsers\n // Actions\n play: async () => play(),\n pause: async () => pause(),\n toggle: async () => toggle(),\n seekTo: async (time: number) => seekTo(time),\n skipToSegment: async (index: number) => skipToSegment(index),\n restart,\n };\n}\n\nexport default useAudioSync;\n","/**\n * useDocPlayback Hook\n *\n * Manages the playback state for a visual doc, including which block\n * is currently active, transition states, and synchronization with audio.\n *\n * This hook provides:\n * - Current block determination based on time\n * - Transition tracking (entering/exiting blocks)\n * - Manual navigation (next/prev block)\n * - Time-based seeking\n * - Automatic expansion of template blocks\n */\n\nimport { useState, useEffect, useMemo, useCallback, useRef } from 'react';\nimport type { Doc, Block, DocBlock } from '@bendyline/squisq/schemas';\nimport type { Theme } from '@bendyline/squisq/schemas';\nimport { getBlockAtTime } from '@bendyline/squisq/schemas';\nimport {\n expandDocBlocks,\n flattenBlocks,\n isTemplateBlock,\n VIEWPORT_PRESETS,\n type ViewportConfig,\n} from '@bendyline/squisq/doc';\n\ninterface PlaybackState {\n /** Currently visible block */\n currentBlock: Block | null;\n /** Index of current block */\n currentBlockIndex: number;\n /** Previous block (for transitions) */\n previousBlock: Block | null;\n /** Whether current block is entering */\n isEntering: boolean;\n /** Whether previous block is exiting */\n isExiting: boolean;\n /** Time relative to current block start */\n blockTime: number;\n /** Progress through current block (0-1) */\n blockProgress: number;\n /** Overall progress through doc (0-1) */\n docProgress: number;\n /** Expanded blocks (templates converted to full blocks with layers) */\n blocks: Block[];\n}\n\ninterface PlaybackActions {\n /** Go to next block */\n nextBlock: () => void;\n /** Go to previous block */\n prevBlock: () => void;\n /** Go to specific block by index */\n goToBlock: (index: number) => void;\n}\n\nexport function useDocPlayback(\n script: Doc | null,\n currentTime: number,\n viewport: ViewportConfig = VIEWPORT_PRESETS.landscape,\n renderMode: boolean = false,\n theme?: Theme,\n): PlaybackState & PlaybackActions {\n const [transitionState, setTransitionState] = useState<{\n entering: boolean;\n exiting: boolean;\n previousBlock: Block | null;\n }>({\n entering: false,\n exiting: false,\n previousBlock: null,\n });\n\n // Expand any template blocks into full blocks\n const blocks = useMemo(() => {\n if (!script?.blocks) {\n return [];\n }\n\n // Flatten nested block hierarchy (markdown-derived docs have children)\n const hasChildren = script.blocks.some((b) => b.children && b.children.length > 0);\n const flatBlocks = hasChildren ? flattenBlocks(script.blocks) : script.blocks;\n\n // Check if any blocks are templates\n const hasTemplates = flatBlocks.some(isTemplateBlock);\n\n if (hasTemplates) {\n // Extract audio segment timing for proper block synchronization\n const audioSegments = script.audio?.segments?.map((seg) => ({\n startTime: seg.startTime,\n duration: seg.duration,\n }));\n\n // Expand template blocks with audio segment timing, viewport, and persistent layers\n const expanded = expandDocBlocks(flatBlocks as DocBlock[], {\n audioSegments,\n viewport,\n persistentLayers: script.persistentLayers,\n theme,\n });\n return expanded;\n }\n\n // All raw blocks, use as-is\n return flatBlocks;\n }, [script?.blocks, script?.audio?.segments, script?.persistentLayers, viewport, theme]);\n\n // Find current block based on time\n const currentBlock = useMemo(() => getBlockAtTime(blocks, currentTime), [blocks, currentTime]);\n\n const currentBlockIndex = useMemo(\n () => (currentBlock ? blocks.indexOf(currentBlock) : -1),\n [blocks, currentBlock],\n );\n\n // Calculate block-relative time\n const blockTime = useMemo(() => {\n if (!currentBlock) return 0;\n return Math.max(0, currentTime - currentBlock.startTime);\n }, [currentBlock, currentTime]);\n\n // Calculate progress values\n const blockProgress = useMemo(() => {\n if (!currentBlock || currentBlock.duration === 0) return 0;\n return Math.min(1, blockTime / currentBlock.duration);\n }, [currentBlock, blockTime]);\n\n const docProgress = useMemo(() => {\n if (!script || script.duration === 0) return 0;\n return Math.min(1, currentTime / script.duration);\n }, [script, currentTime]);\n\n // Track block transitions.\n // In render mode, transitions are computed from blockTime so they stay\n // synchronized with the seekTo timeline. In normal mode, setTimeout drives\n // transitions at the browser's real-time clock speed.\n const _prevBlockRef = useMemo(\n () => currentBlock,\n // eslint-disable-next-line react-hooks/exhaustive-deps -- intentionally keyed on index, not block reference\n [currentBlockIndex],\n );\n\n useEffect(() => {\n if (!currentBlock || renderMode) return;\n\n // When block changes, trigger transition (real-time mode only)\n if (transitionState.previousBlock?.id !== currentBlock.id) {\n const transition = currentBlock.transition;\n const transitionDuration = transition?.duration || 0;\n\n if (transitionDuration > 0) {\n // Start transition\n setTransitionState({\n entering: true,\n exiting: true,\n previousBlock: transitionState.previousBlock,\n });\n\n // End transition after duration\n const timer = setTimeout(() => {\n setTransitionState({\n entering: false,\n exiting: false,\n previousBlock: currentBlock,\n });\n }, transitionDuration * 1000);\n\n return () => clearTimeout(timer);\n } else {\n // Instant cut\n setTransitionState({\n entering: false,\n exiting: false,\n previousBlock: currentBlock,\n });\n }\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps -- intentionally keyed on currentBlock?.id only; reading transitionState.previousBlock without dep to avoid infinite loop\n }, [currentBlock?.id, renderMode]);\n\n // Render mode: track previous block via ref and compute transition from time\n const renderPrevBlockRef = useRef<Block | null>(null);\n\n useEffect(() => {\n if (!renderMode || !currentBlock) return;\n\n if (transitionState.previousBlock?.id !== currentBlock.id) {\n // Block changed — remember the old block for crossfade\n const oldPrev = transitionState.previousBlock;\n renderPrevBlockRef.current = oldPrev;\n // Store current block as the \"last seen\" for next transition\n setTransitionState((prev) => ({\n ...prev,\n previousBlock: currentBlock,\n }));\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps -- same pattern: keyed on block identity change\n }, [currentBlock?.id, renderMode]);\n\n // In render mode, derive entering/exiting from blockTime\n const renderTransitionDuration = currentBlock?.transition?.duration || 0;\n const renderIsEntering =\n renderMode && renderTransitionDuration > 0 && blockTime < renderTransitionDuration;\n const renderIsExiting = renderIsEntering && renderPrevBlockRef.current !== null;\n\n // Manual navigation\n const goToBlock = useCallback(\n (index: number) => {\n if (!script || index < 0 || index >= blocks.length) return;\n // This would need to be coordinated with seekTo from audio sync\n // For now, just return the target block's start time\n const targetBlock = blocks[index];\n if (targetBlock) {\n // Caller should use this time with audio seekTo\n return targetBlock.startTime;\n }\n },\n [script, blocks],\n );\n\n const nextBlock = useCallback(() => {\n if (currentBlockIndex < blocks.length - 1) {\n return goToBlock(currentBlockIndex + 1);\n }\n }, [currentBlockIndex, blocks.length, goToBlock]);\n\n const prevBlock = useCallback(() => {\n if (currentBlockIndex > 0) {\n return goToBlock(currentBlockIndex - 1);\n }\n }, [currentBlockIndex, goToBlock]);\n\n return {\n currentBlock,\n currentBlockIndex,\n previousBlock: renderMode\n ? renderIsExiting\n ? renderPrevBlockRef.current\n : null\n : transitionState.exiting\n ? transitionState.previousBlock\n : null,\n isEntering: renderMode ? renderIsEntering : transitionState.entering,\n isExiting: renderMode ? renderIsExiting : transitionState.exiting,\n blockTime,\n blockProgress,\n docProgress,\n nextBlock,\n prevBlock,\n goToBlock,\n /** Expanded blocks (templates converted to full blocks with layers) */\n blocks,\n };\n}\n\nexport default useDocPlayback;\n","/**\n * useViewportOrientation Hook\n *\n * Detects the current viewport orientation and returns the appropriate\n * VIEWPORT_PRESET for rendering docs. Automatically updates when\n * the window is resized.\n *\n * Thresholds:\n * - Portrait: height > width * 1.2 (significantly taller than wide)\n * - Square: width and height within 20% of each other\n * - Landscape: width > height * 1.2 (significantly wider than tall)\n */\n\nimport { useState, useEffect, useMemo } from 'react';\nimport {\n VIEWPORT_PRESETS,\n type ViewportConfig,\n type ViewportOrientation,\n} from '@bendyline/squisq/doc';\n\ninterface UseViewportOrientationResult {\n /** Current viewport preset configuration */\n viewport: ViewportConfig;\n /** Current orientation name */\n orientation: ViewportOrientation;\n /** Current window dimensions */\n windowSize: { width: number; height: number };\n}\n\n/**\n * Determine viewport orientation from window dimensions.\n */\nfunction getOrientationFromWindow(width: number, height: number): ViewportOrientation {\n const ratio = width / height;\n\n // Use thresholds to determine orientation\n // - Ratio > 1.2 = landscape (wider than tall)\n // - Ratio < 0.83 (1/1.2) = portrait (taller than wide)\n // - Otherwise = square-ish, use landscape for better readability\n if (ratio > 1.2) {\n return 'landscape';\n } else if (ratio < 0.83) {\n return 'portrait';\n } else {\n // Near-square viewports: use landscape for better text readability\n // Could also use 'square' preset if available and desired\n return 'landscape';\n }\n}\n\n/**\n * Get the appropriate viewport preset for an orientation.\n */\nfunction getViewportForOrientation(orientation: ViewportOrientation): ViewportConfig {\n switch (orientation) {\n case 'portrait':\n return VIEWPORT_PRESETS.portrait;\n case 'square':\n return VIEWPORT_PRESETS.square;\n case 'landscape':\n default:\n return VIEWPORT_PRESETS.landscape;\n }\n}\n\n/**\n * Hook to detect viewport orientation and return appropriate preset.\n * Updates automatically when window is resized.\n */\nexport function useViewportOrientation(): UseViewportOrientationResult {\n const [windowSize, setWindowSize] = useState(() => ({\n width: typeof window !== 'undefined' ? window.innerWidth : 1920,\n height: typeof window !== 'undefined' ? window.innerHeight : 1080,\n }));\n\n // Listen for window resize\n useEffect(() => {\n if (typeof window === 'undefined') return;\n\n const handleResize = () => {\n setWindowSize({\n width: window.innerWidth,\n height: window.innerHeight,\n });\n };\n\n // Debounce resize handler to avoid excessive re-renders\n let timeoutId: ReturnType<typeof setTimeout>;\n const debouncedResize = () => {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(handleResize, 100);\n };\n\n window.addEventListener('resize', debouncedResize);\n return () => {\n window.removeEventListener('resize', debouncedResize);\n clearTimeout(timeoutId);\n };\n }, []);\n\n // Calculate orientation from window size\n const orientation = useMemo(\n () => getOrientationFromWindow(windowSize.width, windowSize.height),\n [windowSize.width, windowSize.height],\n );\n\n // Get appropriate viewport preset\n const viewport = useMemo(() => getViewportForOrientation(orientation), [orientation]);\n\n return {\n viewport,\n orientation,\n windowSize,\n };\n}\n\nexport default useViewportOrientation;\n","/**\n * Doc Player Control Types\n *\n * Shared type definitions for doc player controls across different\n * layout modes (overlay, sidebar, bottom). These interfaces allow\n * control components to be decoupled from the core DocPlayer.\n *\n * Related Files:\n * - DocPlayer.tsx — Core player component\n * - DocProgressBar.tsx — Extracted progress bar\n * - DocControlsOverlay.tsx — Overlay controls (default)\n * - DocControlsSidebar.tsx — Vertical sidebar controls\n * - DocControlsBottom.tsx — Horizontal bottom strip controls\n */\n\nimport type { Block } from '@bendyline/squisq/schemas';\n\n/** Layout mode for doc player controls */\nexport type ControlsLayout = 'overlay' | 'sidebar' | 'bottom';\n\n/**\n * Display mode for DocPlayer.\n *\n * - `'video'` — Traditional video-style playback with play/pause, scrub bar,\n * and time-based auto-advance. Default mode.\n * - `'slideshow'` — PowerPoint-style presentation with prev/next navigation.\n * Blocks are treated as static slides that only change on user click.\n * No auto-advance, no scrub bar.\n * - `'linear'` — Long-scrolling document view. Renders the full markdown as\n * readable HTML with template-annotated sections shown as inline SVG cards.\n * No audio, no timeline, no controls — just a scrollable page.\n */\nexport type DisplayMode = 'video' | 'slideshow' | 'linear';\n\n/**\n * Caption display style.\n *\n * - `'standard'` — Traditional broadcast-style captions: small white text\n * on a semi-transparent black badge at the top of the player.\n * - `'social'` — Social media-style (Instagram/TikTok): large centered words\n * showing 3-5 words at a time with the active word highlighted in the\n * theme's primary color. Font and colors pulled from the active theme.\n */\nexport type CaptionStyle = 'standard' | 'social';\n\n/**\n * Caption display mode — combines enable/disable with style selection.\n * The CC button cycles through: off → standard → social → off.\n */\nexport type CaptionMode = 'off' | 'standard' | 'social';\n\n/** Slide navigation actions for slideshow display mode */\nexport interface SlideNavActions {\n /** Navigate to the next slide */\n nextSlide: () => void;\n /** Navigate to the previous slide */\n prevSlide: () => void;\n /** Navigate to a specific slide by index (0-based) */\n goToSlide: (index: number) => void;\n}\n\n/** Playback state exposed to external control components */\nexport interface PlaybackState {\n isPlaying: boolean;\n currentTime: number;\n totalDuration: number;\n currentBlockIndex: number;\n totalBlocks: number;\n docProgress: number;\n hasCaptions: boolean;\n captionsEnabled: boolean;\n /** Current caption display mode (off, standard, social). */\n captionMode: CaptionMode;\n isFullscreen?: boolean;\n /** Current audio segment index (0-based) */\n currentSegmentIndex: number;\n /** Current audio segment name (e.g., 'intro', 'history') */\n currentSegmentName: string | null;\n /** Current block data (for extracting image info, etc.) */\n currentBlock: Block | null;\n}\n\n/** Playback actions exposed to external control components */\nexport interface PlaybackActions {\n toggle: () => void;\n restart: () => void;\n seekTo: (time: number) => void;\n setCaptionsEnabled: (enabled: boolean) => void;\n /** Cycle caption mode: off → standard → social → off */\n cycleCaptionMode: () => void;\n toggleFullscreen?: () => void;\n}\n\n/** Block marker data for the progress bar */\nexport interface BlockMarker {\n block: Block;\n index: number;\n position: number;\n title: string;\n /** True if this block is the first in a new audio segment (section boundary) */\n isSectionStart: boolean;\n}\n\n// ============================================\n// Render-mode API (exposed on window for Playwright / debug)\n// ============================================\n\n/** Block metadata returned by SquisqRenderAPI.getBlocks() */\nexport interface RenderBlockInfo {\n id: string;\n template: string;\n startTime: number;\n duration: number;\n}\n\n/** Audio segment info returned by SquisqRenderAPI.getAudioSegments() */\nexport interface RenderAudioSegmentInfo {\n src: string;\n name: string;\n duration: number;\n startTime: number;\n}\n\n/** Caption phrase info returned by SquisqRenderAPI.getCaptions() */\nexport interface RenderCaptionInfo {\n text: string;\n startTime: number;\n endTime: number;\n}\n\n/** Chapter marker returned by SquisqRenderAPI.getChapters() */\nexport interface RenderChapterInfo {\n title: string;\n startTime: number;\n duration: number;\n}\n\n/**\n * API surface exposed on `window` in render mode and debug mode.\n * Used by Playwright for video export and by ?debug=true for testing.\n *\n * @example\n * ```ts\n * // In Playwright:\n * const w = window as unknown as SquisqWindow;\n * await w.seekTo!(5.0);\n * const blocks = w.getBlocks!();\n * ```\n */\nexport interface SquisqRenderAPI {\n seekTo: (time: number) => Promise<void>;\n getDuration: () => number;\n getBlocks: () => RenderBlockInfo[];\n getAudioSegments: () => RenderAudioSegmentInfo[];\n getCaptions: () => RenderCaptionInfo[];\n getChapters: () => RenderChapterInfo[];\n showCover: () => Promise<void>;\n hideCover: () => Promise<void>;\n hasCoverBlock: () => boolean;\n}\n\n/**\n * Window augmented with optional SquisqRenderAPI properties.\n * Each property is optional because they're only present in render/debug mode.\n */\nexport type SquisqWindow = Window & typeof globalThis & Partial<SquisqRenderAPI>;\n\n/** Format time in seconds to MM:SS string */\nexport function formatTime(seconds: number): string {\n const mins = Math.floor(seconds / 60);\n const secs = Math.floor(seconds % 60);\n return `${mins}:${secs.toString().padStart(2, '0')}`;\n}\n","/**\n * DocProgressBar Component\n *\n * Interactive progress/scrubber bar for doc playback. Shows a track with\n * progress fill, block markers as clickable dots, hover tooltip with time\n * and block title, and a hover line indicator.\n *\n * Extracted from DocPlayer to enable reuse across different control layouts\n * (overlay, sidebar, bottom). When used in sidebar/bottom layouts, this\n * component renders at the bottom of the video while other controls are\n * externalized.\n *\n * Related Files:\n * - DocPlayer.tsx -- Parent component\n * - DocControlsOverlay.tsx -- Uses this within the overlay\n * - types.ts -- Shared type definitions\n */\n\nimport { useRef, useState, useCallback } from 'react';\nimport type { PlaybackState, PlaybackActions, BlockMarker } from './types';\nimport { formatTime } from './types';\nimport type { Block } from '@bendyline/squisq/schemas';\n\ninterface DocProgressBarProps {\n state: PlaybackState;\n actions: PlaybackActions;\n blockMarkers: BlockMarker[];\n /** All expanded blocks for hover lookup */\n expandedBlocks: Block[];\n /** Optional: get block title for hover tooltip */\n getBlockTitle?: (block: Block) => string;\n}\n\nexport function DocProgressBar({\n state,\n actions,\n blockMarkers,\n expandedBlocks,\n getBlockTitle,\n}: DocProgressBarProps) {\n const progressBarRef = useRef<HTMLDivElement>(null);\n const [hoverPosition, setHoverPosition] = useState<number | null>(null);\n\n const handleProgressHover = useCallback((e: React.MouseEvent) => {\n const bar = progressBarRef.current;\n if (!bar) return;\n const rect = bar.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const progress = Math.max(0, Math.min(1, x / rect.width));\n setHoverPosition(progress);\n }, []);\n\n const handleProgressLeave = useCallback(() => {\n setHoverPosition(null);\n }, []);\n\n const getBlockAtTimeLocal = useCallback(\n (time: number): { block: Block; index: number } | null => {\n for (let i = expandedBlocks.length - 1; i >= 0; i--) {\n const blk = expandedBlocks[i];\n if (time >= blk.startTime) {\n return { block: blk, index: i };\n }\n }\n return expandedBlocks.length > 0 ? { block: expandedBlocks[0], index: 0 } : null;\n },\n [expandedBlocks],\n );\n\n return (\n <div\n ref={progressBarRef}\n style={{\n flex: 1,\n height: '24px',\n cursor: 'pointer',\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n }}\n onClick={(e) => {\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();\n const x = e.clientX - rect.left;\n const progress = x / rect.width;\n actions.seekTo(progress * state.totalDuration);\n }}\n onMouseMove={handleProgressHover}\n onMouseLeave={handleProgressLeave}\n >\n {/* Track background */}\n <div\n style={{\n position: 'absolute',\n left: 0,\n right: 0,\n height: '6px',\n background: 'rgba(255,255,255,0.2)',\n borderRadius: '3px',\n }}\n />\n\n {/* Progress fill */}\n <div\n style={{\n position: 'absolute',\n left: 0,\n width: `${state.docProgress * 100}%`,\n height: '6px',\n background: '#5b9bd5',\n borderRadius: '3px',\n transition: 'width 0.1s',\n }}\n />\n\n {/* Block markers (dots) */}\n {blockMarkers.map((marker, i) => (\n <div\n key={`${marker.block.id}-${i}`}\n style={{\n position: 'absolute',\n left: `${marker.position}%`,\n transform: 'translateX(-50%)',\n width: '10px',\n height: '10px',\n borderRadius: '50%',\n background:\n marker.index === state.currentBlockIndex ? '#ffffff' : 'rgba(255,255,255,0.5)',\n border: '2px solid #5b9bd5',\n cursor: 'pointer',\n zIndex: 2,\n transition: 'transform 0.15s, background 0.15s',\n }}\n title={marker.title}\n onClick={(e) => {\n e.stopPropagation();\n actions.seekTo(marker.block.startTime);\n }}\n onMouseEnter={(e) => {\n (e.currentTarget as HTMLElement).style.transform = 'translateX(-50%) scale(1.3)';\n }}\n onMouseLeave={(e) => {\n (e.currentTarget as HTMLElement).style.transform = 'translateX(-50%)';\n }}\n />\n ))}\n\n {/* Hover tooltip */}\n {hoverPosition !== null && (\n <div\n style={{\n position: 'absolute',\n left: `${hoverPosition * 100}%`,\n bottom: '100%',\n transform: 'translateX(-50%)',\n marginBottom: '8px',\n padding: '6px 10px',\n background: 'rgba(0,0,0,0.9)',\n borderRadius: '4px',\n whiteSpace: 'nowrap',\n pointerEvents: 'none',\n zIndex: 10,\n }}\n >\n <div style={{ color: 'white', fontSize: '12px', fontFamily: 'monospace' }}>\n {formatTime(hoverPosition * state.totalDuration)}\n </div>\n {(() => {\n const hoverTime = hoverPosition * state.totalDuration;\n const slideInfo = getBlockAtTimeLocal(hoverTime);\n if (slideInfo && getBlockTitle) {\n return (\n <div style={{ color: 'rgba(255,255,255,0.7)', fontSize: '11px', marginTop: '2px' }}>\n {getBlockTitle(slideInfo.block)}\n </div>\n );\n }\n return null;\n })()}\n </div>\n )}\n\n {/* Hover line indicator */}\n {hoverPosition !== null && (\n <div\n style={{\n position: 'absolute',\n left: `${hoverPosition * 100}%`,\n top: '50%',\n transform: 'translate(-50%, -50%)',\n width: '2px',\n height: '16px',\n background: 'rgba(255,255,255,0.6)',\n pointerEvents: 'none',\n zIndex: 1,\n }}\n />\n )}\n </div>\n );\n}\n","/**\n * DocControlsOverlay Component\n *\n * The default overlay controls that render at the bottom of the doc player\n * video with a gradient background. Contains all playback controls: restart,\n * play/pause, time display, progress bar with block markers, segment indicator,\n * and caption toggle.\n *\n * This is the original control layout extracted from DocPlayer. It's used\n * for the 'overlay' controls layout mode (Flow mode, landscape default).\n *\n * Related Files:\n * - DocPlayer.tsx -- Parent component\n * - DocProgressBar.tsx -- Progress bar sub-component\n * - types.ts -- Shared type definitions\n */\n\nimport { DocProgressBar } from './DocProgressBar';\nimport type { PlaybackState, PlaybackActions, BlockMarker } from './types';\nimport { formatTime } from './types';\nimport type { Block } from '@bendyline/squisq/schemas';\n\ninterface DocControlsOverlayProps {\n state: PlaybackState;\n actions: PlaybackActions;\n blockMarkers: BlockMarker[];\n expandedBlocks: Block[];\n getBlockTitle?: (block: Block) => string;\n}\n\nexport function DocControlsOverlay({\n state,\n actions,\n blockMarkers,\n expandedBlocks,\n getBlockTitle,\n}: DocControlsOverlayProps) {\n return (\n <div\n className=\"doc-player__controls\"\n style={{\n position: 'absolute',\n bottom: 0,\n left: 0,\n right: 0,\n padding: '12px 16px',\n background: 'linear-gradient(transparent, rgba(0,0,0,0.8))',\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n zIndex: 100,\n }}\n >\n {/* Restart button */}\n <button\n onClick={actions.restart}\n style={{\n background: 'none',\n border: 'none',\n color: 'rgba(255,255,255,0.7)',\n cursor: 'pointer',\n padding: '8px',\n fontSize: '14px',\n display: 'flex',\n alignItems: 'center',\n }}\n title=\"Restart\"\n aria-label=\"Restart from beginning\"\n >\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" width=\"18\" height=\"18\">\n <path d=\"M12 5V1L7 6l5 5V7c3.31 0 6 2.69 6 6s-2.69 6-6 6-6-2.69-6-6H4c0 4.42 3.58 8 8 8s8-3.58 8-8-3.58-8-8-8z\" />\n </svg>\n </button>\n\n {/* Play/Pause button */}\n <button\n onClick={actions.toggle}\n style={{\n background: 'rgba(255,255,255,0.2)',\n border: 'none',\n borderRadius: '50%',\n color: 'white',\n cursor: 'pointer',\n padding: '10px',\n fontSize: '16px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '40px',\n height: '40px',\n }}\n aria-label={state.isPlaying ? 'Pause' : 'Play'}\n >\n {state.isPlaying ? (\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" width=\"20\" height=\"20\">\n <path d=\"M6 19h4V5H6v14zm8-14v14h4V5h-4z\" />\n </svg>\n ) : (\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" width=\"20\" height=\"20\">\n <path d=\"M8 5v14l11-7z\" />\n </svg>\n )}\n </button>\n\n {/* Time display */}\n <span style={{ color: 'white', fontSize: '12px', minWidth: '80px', fontFamily: 'monospace' }}>\n {formatTime(state.currentTime)} / {formatTime(state.totalDuration)}\n </span>\n\n {/* Progress bar */}\n <DocProgressBar\n state={state}\n actions={actions}\n blockMarkers={blockMarkers}\n expandedBlocks={expandedBlocks}\n getBlockTitle={getBlockTitle}\n />\n\n {/* Segment indicator */}\n <span style={{ color: 'rgba(255,255,255,0.5)', fontSize: '11px', whiteSpace: 'nowrap' }}>\n {state.currentBlockIndex + 1}/{state.totalBlocks}\n </span>\n\n {/* Caption mode cycle button: off → standard → social → off */}\n {state.hasCaptions && (\n <button\n onClick={() => actions.cycleCaptionMode()}\n style={{\n background: state.captionMode !== 'off' ? 'rgba(255,255,255,0.2)' : 'none',\n border: 'none',\n color: state.captionMode !== 'off' ? 'white' : 'rgba(255,255,255,0.5)',\n cursor: 'pointer',\n padding: '8px',\n fontSize: '12px',\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n borderRadius: '4px',\n }}\n title={\n state.captionMode === 'off'\n ? 'Captions: Off (click for Standard)'\n : state.captionMode === 'standard'\n ? 'Captions: Standard (click for Social)'\n : 'Captions: Social (click to turn off)'\n }\n aria-label=\"Cycle caption style\"\n >\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" width=\"18\" height=\"18\">\n <path d=\"M19 4H5a2 2 0 00-2 2v12a2 2 0 002 2h14a2 2 0 002-2V6a2 2 0 00-2-2zm-8 7H9.5v-.5h-2v3h2V13H11v1a1 1 0 01-1 1H7a1 1 0 01-1-1v-4a1 1 0 011-1h3a1 1 0 011 1v1zm7 0h-1.5v-.5h-2v3h2V13H18v1a1 1 0 01-1 1h-3a1 1 0 01-1-1v-4a1 1 0 011-1h3a1 1 0 011 1v1z\" />\n </svg>\n {state.captionMode !== 'off' && (\n <span style={{ fontSize: '10px', textTransform: 'uppercase', letterSpacing: '0.5px' }}>\n {state.captionMode === 'standard' ? 'CC' : 'SM'}\n </span>\n )}\n </button>\n )}\n\n {/* Fullscreen toggle button */}\n {actions.toggleFullscreen && (\n <button\n onClick={actions.toggleFullscreen}\n style={{\n background: state.isFullscreen ? 'rgba(255,255,255,0.2)' : 'none',\n border: 'none',\n color: state.isFullscreen ? 'white' : 'rgba(255,255,255,0.5)',\n cursor: 'pointer',\n padding: '8px',\n display: 'flex',\n alignItems: 'center',\n borderRadius: '4px',\n }}\n title={state.isFullscreen ? 'Exit fullscreen (F)' : 'Fullscreen (F)'}\n aria-label={state.isFullscreen ? 'Exit fullscreen' : 'Enter fullscreen'}\n >\n {state.isFullscreen ? (\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" width=\"18\" height=\"18\">\n <path d=\"M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z\" />\n </svg>\n ) : (\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" width=\"18\" height=\"18\">\n <path d=\"M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z\" />\n </svg>\n )}\n </button>\n )}\n </div>\n );\n}\n","/**\n * DocControlsSlideshow Component\n *\n * Compact slide navigation controls for the DocPlayer slideshow display mode.\n * Renders in the lower-right corner with previous / slide counter / next buttons,\n * similar to PowerPoint/Keynote presentation navigation.\n *\n * Related Files:\n * - DocPlayer.tsx — Parent component (renders this when displayMode='slideshow')\n * - DocControlsOverlay.tsx — Video-mode controls (overlay layout)\n * - types.ts — Shared type definitions\n */\n\nimport type { PlaybackState, SlideNavActions } from './types';\n\ninterface DocControlsSlideshowProps {\n state: PlaybackState;\n slideNav: SlideNavActions;\n}\n\nexport function DocControlsSlideshow({ state, slideNav }: DocControlsSlideshowProps) {\n const { currentBlockIndex, totalBlocks } = state;\n const isFirst = currentBlockIndex <= 0;\n const isLast = currentBlockIndex >= totalBlocks - 1;\n\n return (\n <div\n className=\"doc-controls-slideshow\"\n data-testid=\"slideshow-controls\"\n style={{\n position: 'absolute',\n bottom: '16px',\n right: '16px',\n display: 'flex',\n alignItems: 'center',\n gap: '2px',\n background: 'rgba(0, 0, 0, 0.65)',\n borderRadius: '8px',\n padding: '4px 6px',\n zIndex: 100,\n userSelect: 'none',\n backdropFilter: 'blur(8px)',\n WebkitBackdropFilter: 'blur(8px)',\n }}\n >\n {/* Previous button */}\n <button\n onClick={(e) => {\n e.stopPropagation();\n slideNav.prevSlide();\n }}\n disabled={isFirst}\n data-testid=\"slide-prev\"\n aria-label=\"Previous slide\"\n title=\"Previous slide\"\n style={{\n background: 'none',\n border: 'none',\n color: isFirst ? 'rgba(255,255,255,0.3)' : 'rgba(255,255,255,0.9)',\n cursor: isFirst ? 'default' : 'pointer',\n padding: '6px 8px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: '4px',\n transition: 'background 0.15s',\n }}\n onMouseEnter={(e) => {\n if (!isFirst) e.currentTarget.style.background = 'rgba(255,255,255,0.1)';\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.background = 'none';\n }}\n >\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" width=\"18\" height=\"18\">\n <path d=\"M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z\" />\n </svg>\n </button>\n\n {/* Slide counter */}\n <span\n data-testid=\"slide-counter\"\n style={{\n color: 'rgba(255,255,255,0.9)',\n fontSize: '13px',\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n fontVariantNumeric: 'tabular-nums',\n minWidth: '48px',\n textAlign: 'center',\n padding: '0 4px',\n letterSpacing: '0.02em',\n }}\n >\n {totalBlocks > 0 ? `${currentBlockIndex + 1} / ${totalBlocks}` : '—'}\n </span>\n\n {/* Next button */}\n <button\n onClick={(e) => {\n e.stopPropagation();\n slideNav.nextSlide();\n }}\n disabled={isLast}\n data-testid=\"slide-next\"\n aria-label=\"Next slide\"\n title=\"Next slide\"\n style={{\n background: 'none',\n border: 'none',\n color: isLast ? 'rgba(255,255,255,0.3)' : 'rgba(255,255,255,0.9)',\n cursor: isLast ? 'default' : 'pointer',\n padding: '6px 8px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: '4px',\n transition: 'background 0.15s',\n }}\n onMouseEnter={(e) => {\n if (!isLast) e.currentTarget.style.background = 'rgba(255,255,255,0.1)';\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.background = 'none';\n }}\n >\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" width=\"18\" height=\"18\">\n <path d=\"M8.59 16.59L10 18l6-6-6-6-1.41 1.41L13.17 12z\" />\n </svg>\n </button>\n </div>\n );\n}\n","/**\n * MarkdownRenderer Component\n *\n * Converts a MarkdownBlockNode[] AST into React elements for rendering\n * markdown content as readable HTML. Used by LinearDocView to display\n * non-annotated document sections as flowing text.\n *\n * Supports all block and inline node types from the markdown DOM:\n * - Block: paragraph, heading, blockquote, list, code, table,\n * thematicBreak, math, htmlBlock, definitionList, directives\n * - Inline: text, emphasis, strong, delete, inlineCode, link,\n * image, break, inlineMath, htmlInline, footnoteReference\n *\n * All elements use the `squisq-md-*` CSS class prefix for styling.\n */\n\nimport { Fragment } from 'react';\nimport type {\n MarkdownBlockNode,\n MarkdownInlineNode,\n MarkdownListItem,\n MarkdownTableRow,\n MarkdownTableCell,\n} from '@bendyline/squisq/markdown';\n\n// ── Props ──────────────────────────────────────────────────────────\n\nexport interface MarkdownRendererProps {\n /** Block-level AST nodes to render */\n nodes: MarkdownBlockNode[];\n /** Optional CSS class for the wrapper element */\n className?: string;\n}\n\n// ── Inline Renderer ────────────────────────────────────────────────\n\n/** Render an array of inline nodes into React elements. */\nfunction renderInline(nodes: MarkdownInlineNode[], keyPrefix = ''): React.ReactNode[] {\n return nodes.map((node, i) => {\n const key = `${keyPrefix}i${i}`;\n switch (node.type) {\n case 'text':\n return <Fragment key={key}>{node.value}</Fragment>;\n\n case 'emphasis':\n return (\n <em key={key} className=\"squisq-md-em\">\n {renderInline(node.children, key)}\n </em>\n );\n\n case 'strong':\n return (\n <strong key={key} className=\"squisq-md-strong\">\n {renderInline(node.children, key)}\n </strong>\n );\n\n case 'delete':\n return (\n <del key={key} className=\"squisq-md-del\">\n {renderInline(node.children, key)}\n </del>\n );\n\n case 'inlineCode':\n return (\n <code key={key} className=\"squisq-md-inline-code\">\n {node.value}\n </code>\n );\n\n case 'link':\n return (\n <a\n key={key}\n className=\"squisq-md-link\"\n href={node.url}\n title={node.title ?? undefined}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {renderInline(node.children, key)}\n </a>\n );\n\n case 'image':\n return (\n <img\n key={key}\n className=\"squisq-md-image\"\n src={node.url}\n alt={node.alt ?? ''}\n title={node.title ?? undefined}\n />\n );\n\n case 'break':\n return <br key={key} />;\n\n case 'inlineMath':\n return (\n <code key={key} className=\"squisq-md-inline-math\">\n {node.value}\n </code>\n );\n\n case 'htmlInline':\n return (\n <span\n key={key}\n className=\"squisq-md-html-inline\"\n dangerouslySetInnerHTML={{ __html: node.rawHtml }}\n />\n );\n\n case 'footnoteReference':\n return (\n <sup key={key} className=\"squisq-md-footnote-ref\">\n <a href={`#fn-${node.identifier}`}>[{node.label ?? node.identifier}]</a>\n </sup>\n );\n\n case 'linkReference':\n // Render as plain text (definition targets not available at render time)\n return (\n <span key={key} className=\"squisq-md-link-ref\">\n {renderInline(node.children, key)}\n </span>\n );\n\n case 'imageReference':\n return (\n <span key={key} className=\"squisq-md-image-ref\">\n [{node.alt ?? node.identifier}]\n </span>\n );\n\n case 'textDirective':\n return (\n <span key={key} className=\"squisq-md-text-directive\" data-directive={node.name}>\n {renderInline(node.children, key)}\n </span>\n );\n\n default:\n return null;\n }\n });\n}\n\n// ── Block Renderer ─────────────────────────────────────────────────\n\n/** Render a single block-level node into a React element. */\nfunction renderBlock(node: MarkdownBlockNode, key: string): React.ReactNode {\n switch (node.type) {\n case 'paragraph':\n return (\n <p key={key} className=\"squisq-md-p\">\n {renderInline(node.children, key)}\n </p>\n );\n\n case 'heading': {\n const Tag = `h${node.depth}` as 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';\n return (\n <Tag key={key} className={`squisq-md-heading squisq-md-h${node.depth}`}>\n {renderInline(node.children, key)}\n </Tag>\n );\n }\n\n case 'blockquote':\n return (\n <blockquote key={key} className=\"squisq-md-blockquote\">\n {renderBlocks(node.children, key)}\n </blockquote>\n );\n\n case 'list':\n if (node.ordered) {\n return (\n <ol key={key} className=\"squisq-md-list squisq-md-ol\" start={node.start ?? undefined}>\n {node.children.map((item, i) => renderListItem(item, `${key}li${i}`))}\n </ol>\n );\n }\n return (\n <ul key={key} className=\"squisq-md-list squisq-md-ul\">\n {node.children.map((item, i) => renderListItem(item, `${key}li${i}`))}\n </ul>\n );\n\n case 'code':\n return (\n <pre key={key} className=\"squisq-md-code-block\">\n <code className={node.lang ? `language-${node.lang}` : undefined}>{node.value}</code>\n </pre>\n );\n\n case 'thematicBreak':\n return <hr key={key} className=\"squisq-md-hr\" />;\n\n case 'table':\n return renderTable(node.children, node.align, key);\n\n case 'htmlBlock':\n return (\n <div\n key={key}\n className=\"squisq-md-html-block\"\n dangerouslySetInnerHTML={{ __html: node.rawHtml }}\n />\n );\n\n case 'math':\n return (\n <pre key={key} className=\"squisq-md-math-block\">\n <code>{node.value}</code>\n </pre>\n );\n\n case 'definition':\n // Link definitions aren't rendered visually\n return null;\n\n case 'footnoteDefinition':\n return (\n <div key={key} className=\"squisq-md-footnote-def\" id={`fn-${node.identifier}`}>\n <sup>{node.label ?? node.identifier}</sup>\n {renderBlocks(node.children, key)}\n </div>\n );\n\n case 'containerDirective':\n return (\n <div\n key={key}\n className={`squisq-md-directive squisq-md-directive-${node.name}`}\n data-directive={node.name}\n >\n {node.label && <div className=\"squisq-md-directive-label\">{node.label}</div>}\n {renderBlocks(node.children, key)}\n </div>\n );\n\n case 'leafDirective':\n return (\n <div\n key={key}\n className={`squisq-md-directive squisq-md-directive-${node.name}`}\n data-directive={node.name}\n >\n {renderInline(node.children, key)}\n </div>\n );\n\n case 'definitionList':\n return (\n <dl key={key} className=\"squisq-md-dl\">\n {node.children.map((child, i) => {\n if (child.type === 'definitionTerm') {\n return (\n <dt key={`${key}dt${i}`} className=\"squisq-md-dt\">\n {renderInline(child.children, `${key}dt${i}`)}\n </dt>\n );\n }\n return (\n <dd key={`${key}dd${i}`} className=\"squisq-md-dd\">\n {renderBlocks(child.children, `${key}dd${i}`)}\n </dd>\n );\n })}\n </dl>\n );\n\n default:\n return null;\n }\n}\n\n/** Render a list item, including task-list checkbox support. */\nfunction renderListItem(item: MarkdownListItem, key: string): React.ReactNode {\n const isTask = item.checked !== null && item.checked !== undefined;\n return (\n <li key={key} className={`squisq-md-li${isTask ? ' squisq-md-task' : ''}`}>\n {isTask && (\n <input type=\"checkbox\" checked={!!item.checked} readOnly className=\"squisq-md-checkbox\" />\n )}\n {renderBlocks(item.children, key)}\n </li>\n );\n}\n\n/** Render a table from rows and alignment data. */\nfunction renderTable(\n rows: MarkdownTableRow[],\n align: (('left' | 'right' | 'center') | null)[] | undefined,\n key: string,\n): React.ReactNode {\n const [headerRow, ...bodyRows] = rows;\n return (\n <table key={key} className=\"squisq-md-table\">\n {headerRow && (\n <thead>\n <tr>\n {headerRow.children.map((cell: MarkdownTableCell, ci: number) => (\n <th\n key={`${key}th${ci}`}\n className=\"squisq-md-th\"\n style={align?.[ci] ? { textAlign: align[ci]! } : undefined}\n >\n {renderInline(cell.children, `${key}th${ci}`)}\n </th>\n ))}\n </tr>\n </thead>\n )}\n {bodyRows.length > 0 && (\n <tbody>\n {bodyRows.map((row, ri) => (\n <tr key={`${key}tr${ri}`}>\n {row.children.map((cell: MarkdownTableCell, ci: number) => (\n <td\n key={`${key}td${ri}-${ci}`}\n className=\"squisq-md-td\"\n style={align?.[ci] ? { textAlign: align[ci]! } : undefined}\n >\n {renderInline(cell.children, `${key}td${ri}-${ci}`)}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n )}\n </table>\n );\n}\n\n/** Render an array of block-level nodes. */\nfunction renderBlocks(nodes: MarkdownBlockNode[], keyPrefix = ''): React.ReactNode[] {\n return nodes.map((node, i) => renderBlock(node, `${keyPrefix}b${i}`));\n}\n\n// ── Main Component ─────────────────────────────────────────────────\n\n/**\n * Renders MarkdownBlockNode[] AST as React HTML elements.\n *\n * @example\n * ```tsx\n * <MarkdownRenderer nodes={block.contents} />\n * ```\n */\nexport function MarkdownRenderer({ nodes, className }: MarkdownRendererProps) {\n if (!nodes || nodes.length === 0) return null;\n\n return <div className={`squisq-md ${className || ''}`}>{renderBlocks(nodes)}</div>;\n}\n","/**\n * LinearDocView Component\n *\n * Renders a Doc as a long-scrolling document view. Each block is displayed\n * as a readable section: non-annotated blocks render their markdown content\n * as HTML, while template-annotated blocks render as inline SVG visual cards\n * via BlockRenderer.\n *\n * This is the view used when `displayMode === 'linear'` in DocPlayer.\n *\n * Layout:\n * - Scrollable container with max-width for readability\n * - Headings from the block hierarchy rendered as HTML headings\n * - Body content rendered via MarkdownRenderer\n * - Template-annotated sections show an SVG card (BlockRenderer)\n * using `getLayers()` for on-demand layer computation\n * - Blocks are rendered recursively to preserve the heading hierarchy\n */\n\nimport { useMemo } from 'react';\nimport type { Doc, Block, DocBlock } from '@bendyline/squisq/schemas';\nimport type { ViewportConfig } from '@bendyline/squisq/schemas';\nimport type { Theme } from '@bendyline/squisq/schemas';\nimport { VIEWPORT_PRESETS } from '@bendyline/squisq/schemas';\nimport { getLayers, hasTemplate, DEFAULT_THEME } from '@bendyline/squisq/doc';\nimport type { RenderContext } from '@bendyline/squisq/doc';\nimport { extractPlainText } from '@bendyline/squisq/markdown';\nimport type { MarkdownBlockNode, MarkdownList } from '@bendyline/squisq/markdown';\nimport { BlockRenderer } from './BlockRenderer';\nimport { MarkdownRenderer } from './MarkdownRenderer';\n\n// ── Props ──────────────────────────────────────────────────────────\n\nexport interface LinearDocViewProps {\n /** The Doc to render */\n doc: Doc;\n /** Base path for resolving media URLs (images, etc.) */\n basePath?: string;\n /** Viewport config for SVG card rendering (default: landscape) */\n viewport?: ViewportConfig;\n /** Optional CSS class for the outer container */\n className?: string;\n /** Theme to use for rendering (default: DEFAULT_THEME from the theme library) */\n theme?: Theme;\n}\n\n// ── Helpers ────────────────────────────────────────────────────────\n\n/**\n * Determine whether a block has a template annotation that should be\n * rendered as a visual SVG card. A block is \"annotated\" when:\n * 1. Its sourceHeading has a templateAnnotation, AND\n * 2. The annotated template exists in the registry\n */\nfunction isAnnotatedBlock(block: Block): boolean {\n const annotation = block.sourceHeading?.templateAnnotation;\n if (!annotation) return false;\n return !!annotation.template && hasTemplate(annotation.template);\n}\n\n/**\n * Count total blocks in a hierarchy (for RenderContext.totalBlocks).\n */\nfunction countAll(blocks: Block[]): number {\n let count = 0;\n for (const b of blocks) {\n count++;\n if (b.children) count += countAll(b.children);\n }\n return count;\n}\n\n// ── Block Section Renderer ─────────────────────────────────────────\n\ninterface BlockSectionProps {\n block: Block;\n basePath: string;\n viewport: ViewportConfig;\n renderContext: RenderContext;\n blockIndex: number;\n}\n\n/**\n * Render a single block section: heading + body content or SVG card.\n * Recurses into children to render the full heading tree.\n */\nfunction BlockSection({ block, basePath, viewport, renderContext, blockIndex }: BlockSectionProps) {\n const isAnnotated = isAnnotatedBlock(block);\n\n // For annotated blocks, compute layers and build a Block with them\n const visualBlock = useMemo(() => {\n if (!isAnnotated) return null;\n\n const annotation = block.sourceHeading!.templateAnnotation!;\n const headingText = extractPlainText(block.sourceHeading!);\n const bodyText = extractBodyPlainText(block.contents);\n\n // Build a TemplateBlock-compatible object\n const templateBlock: Record<string, unknown> = {\n id: block.id,\n template: annotation.template,\n startTime: 0,\n duration: 1,\n audioSegment: 0,\n title: headingText,\n ...getTemplateDefaults(\n annotation.template ?? 'sectionHeader',\n headingText,\n bodyText,\n block.contents,\n ),\n ...annotation.params,\n ...block.templateOverrides,\n };\n\n // Compute layers via getLayers\n const ctx: RenderContext = {\n ...renderContext,\n blockIndex,\n };\n const layers = getLayers(templateBlock as unknown as DocBlock, ctx);\n\n return {\n ...block,\n layers,\n template: annotation.template,\n } as Block;\n }, [block, isAnnotated, renderContext, blockIndex]);\n\n return (\n <div\n className=\"squisq-linear-section\"\n data-block-id={block.id}\n data-template={isAnnotated ? block.sourceHeading?.templateAnnotation?.template : undefined}\n >\n {/* Render the heading (if present — preamble has no sourceHeading) */}\n {block.sourceHeading && !isAnnotated && <MarkdownRenderer nodes={[block.sourceHeading]} />}\n\n {/* Annotated block: render SVG card */}\n {isAnnotated && visualBlock && (\n <div className=\"squisq-linear-card\">\n {/* Optional heading label above the card */}\n {block.sourceHeading && (\n <div className=\"squisq-linear-card-label squisq-md\">\n <MarkdownRenderer nodes={[block.sourceHeading]} />\n </div>\n )}\n <div\n className=\"squisq-linear-card-svg\"\n style={{\n width: '100%',\n aspectRatio: `${viewport.width} / ${viewport.height}`,\n overflow: 'hidden',\n borderRadius: '8px',\n boxShadow: '0 2px 8px rgba(0, 0, 0, 0.12)',\n marginBottom: '1em',\n }}\n >\n <BlockRenderer\n block={visualBlock}\n blockTime={0}\n basePath={basePath}\n viewport={viewport}\n />\n </div>\n </div>\n )}\n\n {/* Body content (always render for non-annotated blocks, skipped for annotated) */}\n {!isAnnotated && block.contents && block.contents.length > 0 && (\n <MarkdownRenderer nodes={block.contents} />\n )}\n\n {/* Recurse into children */}\n {block.children && block.children.length > 0 && (\n <div className=\"squisq-linear-children\">\n {block.children.map((child, i) => (\n <BlockSection\n key={child.id}\n block={child}\n basePath={basePath}\n viewport={viewport}\n renderContext={renderContext}\n blockIndex={blockIndex + i + 1}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n\n// ── Template Defaults (mirrored from PreviewPanel) ─────────────────\n\n/** Extract plain text from block contents. */\nfunction extractBodyPlainText(contents?: MarkdownBlockNode[]): string {\n if (!contents || contents.length === 0) return '';\n return contents\n .map((n) => extractPlainText(n))\n .join('\\n')\n .trim();\n}\n\n/** Extract list items as plain text. */\nfunction extractListItems(contents?: MarkdownBlockNode[]): string[] {\n if (!contents) return [];\n const items: string[] = [];\n for (const node of contents) {\n if (node.type === 'list') {\n for (const item of (node as MarkdownList).children) {\n const text = extractPlainText(item).trim();\n if (text) items.push(text);\n }\n }\n }\n return items;\n}\n\n/**\n * Provide sensible default fields for templates that require more than\n * just a `title`. Prevents crashes from undefined required fields.\n */\nfunction getTemplateDefaults(\n templateName: string,\n headingText: string,\n bodyText: string,\n contents?: MarkdownBlockNode[],\n): Record<string, unknown> {\n switch (templateName) {\n case 'statHighlight':\n return { stat: headingText, description: bodyText || headingText };\n case 'quoteBlock':\n case 'fullBleedQuote':\n case 'pullQuote':\n return { quote: bodyText || headingText };\n case 'factCard':\n return { fact: headingText, explanation: bodyText || headingText };\n case 'comparisonBar':\n return { leftLabel: 'A', leftValue: 60, rightLabel: 'B', rightValue: 40 };\n case 'listBlock':\n return { items: extractListItems(contents) || ['Item 1', 'Item 2', 'Item 3'] };\n case 'definitionCard':\n return { term: headingText, definition: bodyText || headingText };\n case 'dateEvent':\n return { date: headingText, description: bodyText || headingText };\n default:\n return {};\n }\n}\n\n// ── Main Component ─────────────────────────────────────────────────\n\n/**\n * Renders a Doc as a long-scrolling, readable document.\n *\n * Non-annotated blocks are rendered as HTML text (headings, paragraphs,\n * lists, etc.) via MarkdownRenderer. Template-annotated blocks are\n * rendered as inline SVG visual cards via BlockRenderer.\n *\n * @example\n * ```tsx\n * <LinearDocView doc={doc} basePath=\"/media/\" />\n * ```\n */\nexport function LinearDocView({\n doc,\n basePath = '/',\n viewport,\n className,\n theme,\n}: LinearDocViewProps) {\n const activeViewport = viewport ?? VIEWPORT_PRESETS.landscape;\n const totalBlocks = useMemo(() => countAll(doc.blocks), [doc.blocks]);\n\n const renderContext: RenderContext = useMemo(\n () => ({\n theme: theme ?? DEFAULT_THEME,\n viewport: activeViewport,\n totalBlocks,\n }),\n [activeViewport, totalBlocks, theme],\n );\n\n const activeTheme = theme ?? DEFAULT_THEME;\n const bgColor = activeTheme.colors.background;\n const textColor = activeTheme.colors.text;\n const mutedColor = activeTheme.colors.textMuted;\n const primaryColor = activeTheme.colors.primary;\n const bodyFont = activeTheme.typography.bodyFontFamily;\n const titleFont = activeTheme.typography.titleFontFamily;\n const lineHt = activeTheme.typography.lineHeight ?? 1.7;\n\n return (\n <div\n className={`squisq-linear ${className || ''}`}\n style={{\n width: '100%',\n height: '100%',\n overflowY: 'auto',\n overflowX: 'hidden',\n background: bgColor,\n }}\n >\n <div\n className=\"squisq-linear-content squisq-md\"\n style={\n {\n maxWidth: '720px',\n margin: '0 auto',\n padding: '24px 16px',\n lineHeight: lineHt,\n fontSize: '16px',\n fontFamily: bodyFont,\n color: textColor,\n // CSS custom properties for MarkdownRenderer / nested elements\n '--squisq-linear-title-font': titleFont,\n '--squisq-linear-body-font': bodyFont,\n '--squisq-linear-text': textColor,\n '--squisq-linear-muted': mutedColor,\n '--squisq-linear-primary': primaryColor,\n '--squisq-linear-bg': bgColor,\n } as React.CSSProperties\n }\n >\n {/* Theme-aware typography and layout for document mode */}\n <style>{`\n .squisq-linear-content h1,\n .squisq-linear-content h2,\n .squisq-linear-content h3,\n .squisq-linear-content h4,\n .squisq-linear-content h5,\n .squisq-linear-content h6 {\n font-family: var(--squisq-linear-title-font);\n color: var(--squisq-linear-text);\n margin-top: 1.2em;\n margin-bottom: 0.4em;\n }\n .squisq-linear-content h1 { font-size: 2em; }\n .squisq-linear-content h2 { font-size: 1.5em; }\n .squisq-linear-content h3 { font-size: 1.25em; }\n .squisq-linear-content p {\n margin-bottom: 0.75em;\n }\n .squisq-linear-content ul,\n .squisq-linear-content ol {\n padding-left: 2em;\n margin-bottom: 0.75em;\n }\n .squisq-linear-content li {\n margin-bottom: 0.3em;\n }\n .squisq-linear-content a {\n color: var(--squisq-linear-primary);\n }\n .squisq-linear-content code {\n color: var(--squisq-linear-primary);\n font-size: 0.9em;\n padding: 0.15em 0.3em;\n border-radius: 3px;\n background: rgba(128, 128, 128, 0.15);\n }\n .squisq-linear-content pre {\n padding: 1em;\n border-radius: 6px;\n background: rgba(0, 0, 0, 0.2);\n overflow-x: auto;\n margin-bottom: 0.75em;\n }\n .squisq-linear-content pre code {\n padding: 0;\n background: none;\n }\n .squisq-linear-content blockquote {\n border-left: 3px solid var(--squisq-linear-muted);\n color: var(--squisq-linear-muted);\n padding-left: 1em;\n margin-left: 0;\n margin-bottom: 0.75em;\n }\n .squisq-linear-content hr {\n border: none;\n border-top: 1px solid var(--squisq-linear-muted);\n margin: 1.5em 0;\n }\n .squisq-linear-content strong {\n font-weight: 700;\n }\n .squisq-linear-content em {\n font-style: italic;\n }\n `}</style>\n {doc.blocks.map((block, i) => (\n <BlockSection\n key={block.id}\n block={block}\n basePath={basePath}\n viewport={activeViewport}\n renderContext={renderContext}\n blockIndex={i}\n />\n ))}\n </div>\n </div>\n );\n}\n","/**\n * DocPlayer Component\n *\n * Main component for playing visual stories. Combines audio playback\n * with synchronized SVG block animations. Supports both interactive\n * browser playback and headless rendering for video export.\n *\n * Features:\n * - Audio synchronization with multiple MP3 segments\n * - Block transitions (fade, dissolve, slide)\n * - Playback controls (play/pause, seek, next/prev)\n * - Progress display\n * - Render mode for video capture (via window.seekTo)\n * - Pluggable audio provider for different environments (browser, EFB)\n * - Multiple control layouts: overlay (default), sidebar, bottom\n *\n * Related Files:\n * - DocControlsOverlay.tsx -- Default overlay controls\n * - DocProgressBar.tsx -- Extracted progress bar\n * - DocControlsSidebar.tsx -- Vertical sidebar controls\n * - DocPlayerWithSidebar.tsx -- Wrapper for sidebar layout\n * - types.ts -- Shared control types\n */\n\nimport { Fragment, useRef, useState, useEffect, useCallback, useMemo } from 'react';\nimport type { Doc, Block, TextLayer, StartBlockConfig, DocBlock } from '@bendyline/squisq/schemas';\nimport { isTemplateBlock, getCaptionAtTime } from '@bendyline/squisq/schemas';\nimport type { Theme } from '@bendyline/squisq/schemas';\nimport { BlockRenderer } from './BlockRenderer';\nimport { CaptionOverlay } from './CaptionOverlay';\nimport { useAudioSync } from './hooks/useAudioSync';\nimport { useDocPlayback } from './hooks/useDocPlayback';\nimport { useViewportOrientation } from './hooks/useViewportOrientation';\nimport type { AudioProvider } from './hooks/AudioProvider';\nimport {\n expandCoverBlock,\n createTemplateContext,\n DEFAULT_THEME,\n VIEWPORT_PRESETS,\n type ViewportConfig,\n} from '@bendyline/squisq/doc';\nimport { DocControlsOverlay } from './DocControlsOverlay';\nimport { DocControlsSlideshow } from './DocControlsSlideshow';\nimport { DocProgressBar } from './DocProgressBar';\nimport { LinearDocView } from './LinearDocView';\nimport type {\n PlaybackState,\n PlaybackActions,\n BlockMarker,\n DisplayMode,\n CaptionStyle,\n CaptionMode,\n SlideNavActions,\n SquisqWindow,\n} from './types';\n\nconst SMALL_WORDS = new Set([\n 'a',\n 'an',\n 'the',\n 'and',\n 'but',\n 'or',\n 'for',\n 'nor',\n 'on',\n 'at',\n 'to',\n 'in',\n 'of',\n 'by',\n 'is',\n]);\n\n/**\n * Build a map of audio segment index -> display-friendly title.\n * Uses sectionHeader blocks to find real titles, with fallbacks\n * for \"intro\" and slug-based names.\n */\nfunction buildSegmentTitleMap(script: Doc): Map<number, string> {\n const map = new Map<number, string>();\n\n // Scan blocks for sectionHeader templates which carry the real title\n for (const block of script.blocks as DocBlock[]) {\n if (isTemplateBlock(block) && block.template === 'sectionHeader' && 'title' in block) {\n const segIdx = block.audioSegment;\n if (!map.has(segIdx)) {\n map.set(segIdx, (block as { title: string }).title);\n }\n }\n }\n\n // Fill in any segments that weren't covered by sectionHeader blocks\n for (let i = 0; i < script.audio.segments.length; i++) {\n if (!map.has(i)) {\n const name = script.audio.segments[i].name;\n if (name === 'intro' || name.includes('intro')) {\n map.set(i, 'Introduction');\n } else if (name === 'flight-context' || name.includes('flight-context')) {\n map.set(i, 'Flight Context');\n } else {\n // Title-case the slug: \"hands-on-history\" -> \"Hands on History\"\n const words = name.split('-');\n const titled = words\n .map((w, idx) =>\n idx === 0 || !SMALL_WORDS.has(w) ? w.charAt(0).toUpperCase() + w.slice(1) : w,\n )\n .join(' ');\n map.set(i, titled);\n }\n }\n }\n\n return map;\n}\n\ninterface DocPlayerProps {\n /** Doc script to play */\n script: Doc;\n /** Base path for resolving media URLs */\n basePath: string;\n /** Render mode for video capture (hides controls, exposes seekTo) */\n renderMode?: boolean;\n /** Auto-play when loaded */\n autoPlay?: boolean;\n /** Callback when playback ends */\n onEnded?: () => void;\n /** Callback for time updates */\n onTimeUpdate?: (time: number) => void;\n /** Optional audio provider (if not provided, uses default HTML5 audio) */\n audioProvider?: AudioProvider;\n /** Show built-in controls (default: true). Set to false for custom controls. */\n showControls?: boolean;\n /** Show only the progress bar/scrubber at bottom (no other controls).\n * Only takes effect when showControls is false. Allows external controls\n * while keeping the scrubber in-video. */\n showScrubber?: boolean;\n /** Mute audio (default: false) */\n muted?: boolean;\n /** Enable captions (default: true) */\n captionsEnabled?: boolean;\n /** Callback when captions enabled state is toggled */\n onCaptionsToggle?: (enabled: boolean) => void;\n /** Callback for playback state changes (for external controls) */\n onPlaybackStateChange?: (state: PlaybackState) => void;\n /** Callback when playback controls are ready (for external controls) */\n onControlsReady?: (\n controls: PlaybackActions & {\n play: () => void;\n pause: () => void;\n },\n ) => void;\n /** Whether the player is currently in fullscreen mode */\n isFullscreen?: boolean;\n /** Callback to toggle fullscreen mode */\n onFullscreenToggle?: () => void;\n /** Callback when block markers are computed (for external progress bars) */\n onBlockMarkers?: (markers: BlockMarker[]) => void;\n /** Force a specific viewport preset, bypassing window-based orientation detection.\n * Used when the player is rendered in a constrained container (e.g., map overlay panel)\n * whose shape differs from the window's. */\n forceViewport?: ViewportConfig;\n /** Theme to use for rendering (default: DEFAULT_THEME from the theme library) */\n theme?: Theme;\n /**\n * Display mode for the player.\n * - `'video'` (default) — Traditional video playback with play/pause, scrub bar, auto-advance.\n * - `'slideshow'` — PowerPoint-style with prev/next buttons. Blocks are static slides\n * that only change on user click. No auto-advance, no scrub bar.\n * - `'linear'` — Long-scrolling document view. Renders markdown as readable HTML with\n * template-annotated sections as inline SVG cards. No audio, no timeline.\n */\n displayMode?: DisplayMode;\n /** Caption display style (default: 'standard').\n * 'social' shows large centered words with the active word highlighted. */\n captionStyle?: CaptionStyle;\n}\n\nexport function DocPlayer({\n script,\n basePath,\n renderMode = false,\n autoPlay = false,\n onEnded,\n onTimeUpdate,\n audioProvider: externalAudioProvider,\n showControls = true,\n showScrubber = false,\n muted = false,\n captionsEnabled: captionsEnabledProp,\n onCaptionsToggle,\n onPlaybackStateChange,\n onControlsReady,\n isFullscreen = false,\n onFullscreenToggle,\n onBlockMarkers,\n forceViewport,\n displayMode = 'video',\n theme,\n captionStyle = 'standard',\n}: DocPlayerProps) {\n const isSlideshowMode = displayMode === 'slideshow';\n const isLinearMode = displayMode === 'linear';\n const audioRef = useRef<HTMLAudioElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n\n // Tap-to-toggle play/pause feedback animation\n const [tapFeedback, setTapFeedback] = useState<'play' | 'pause' | null>(null);\n const tapFeedbackTimer = useRef<ReturnType<typeof setTimeout>>();\n\n // Detect viewport orientation for responsive docs\n // forceViewport takes precedence (used by render mode with explicit viewport and constrained panels)\n // In render mode without forceViewport, default to landscape for backward compatibility\n const { viewport, orientation } = useViewportOrientation();\n const activeViewport = forceViewport || (renderMode ? VIEWPORT_PRESETS.landscape : viewport);\n\n // Check for debug mode via URL parameter\n const isDebugMode = useMemo(() => {\n if (typeof window === 'undefined') return false;\n const params = new URLSearchParams(window.location.search);\n return params.get('debug') === 'true';\n }, []);\n\n // Use internal HTML5 audio sync if no external provider is given\n const internalAudio = useAudioSync(audioRef, script.audio, basePath);\n\n // Use external provider if provided, otherwise fall back to internal\n const audio = externalAudioProvider || internalAudio;\n\n // Destructure for convenience\n const {\n currentTime,\n isPlaying,\n currentSegment,\n totalDuration,\n isEnded,\n isReady: isAudioReady,\n isAvailable,\n unavailableMessage,\n play,\n pause,\n toggle,\n seekTo,\n skipToSegment: _skipToSegment,\n restart,\n } = audio;\n\n // Refs for frequently-changing values used in the keyboard handler,\n // so the handler callback doesn't need to be recreated every frame.\n const currentTimeRef = useRef(currentTime);\n currentTimeRef.current = currentTime;\n const totalDurationRef = useRef(totalDuration);\n totalDurationRef.current = totalDuration;\n const expandedBlocksLenRef = useRef(0);\n\n // Tap the player surface to toggle play/pause (disabled in slideshow and linear mode)\n const handleContainerClick = useCallback(\n (e: React.MouseEvent) => {\n if (renderMode || isSlideshowMode || isLinearMode) return;\n const target = e.target as HTMLElement;\n // Don't toggle if user clicked a control element\n if (\n target.closest(\n 'button, a, input, .doc-player__controls, .doc-player__scrubber, .doc-controls-sidebar, .doc-controls-slideshow',\n )\n )\n return;\n toggle();\n // Show visual feedback (show the state we're transitioning TO)\n const nextState = isPlaying ? 'play' : 'pause';\n setTapFeedback(nextState);\n clearTimeout(tapFeedbackTimer.current);\n tapFeedbackTimer.current = setTimeout(() => setTapFeedback(null), 600);\n },\n [renderMode, toggle, isPlaying, isSlideshowMode, isLinearMode],\n );\n\n // Doc playback hook - pass viewport for responsive template expansion\n const {\n currentBlock,\n currentBlockIndex,\n previousBlock,\n isEntering,\n isExiting,\n blockTime,\n blockProgress: _blockProgress,\n docProgress,\n nextBlock: _nextBlock,\n prevBlock: _prevBlock,\n blocks: expandedBlocks,\n } = useDocPlayback(script, currentTime, activeViewport, renderMode, theme);\n\n // Expand cover block (startBlock) if present - uses active viewport\n const coverBlock = useMemo((): Block | null => {\n const startBlockConfig = script.startBlock as StartBlockConfig | undefined;\n if (!startBlockConfig) return null;\n\n const context = createTemplateContext(theme ?? DEFAULT_THEME, 0, 1, activeViewport);\n const layers = expandCoverBlock(startBlockConfig, context);\n\n return {\n id: 'cover-block',\n startTime: -1, // Not part of timeline\n duration: 0, // Static\n audioSegment: -1,\n layers,\n };\n }, [script.startBlock, activeViewport, theme]);\n\n // Render-mode cover block control: allows Playwright to force-show the cover block\n const [coverForced, setCoverForced] = useState(false);\n\n // Grace period: keep cover block visible for 3s after first play press\n const [coverGraceActive, setCoverGraceActive] = useState(false);\n const coverGraceTimer = useRef<ReturnType<typeof setTimeout>>();\n const coverWasShowing = useRef(false);\n\n // Track when cover is showing at rest (before play)\n const atRest = !!(coverBlock && !isPlaying && currentTime === 0 && !renderMode && !autoPlay);\n if (atRest) coverWasShowing.current = true;\n\n useEffect(() => {\n if (isPlaying && coverWasShowing.current && coverBlock && !renderMode) {\n coverWasShowing.current = false;\n setCoverGraceActive(true);\n coverGraceTimer.current = setTimeout(() => setCoverGraceActive(false), 3000);\n return () => clearTimeout(coverGraceTimer.current);\n }\n }, [isPlaying, coverBlock, renderMode]);\n\n // Determine if we should show the cover block\n // Show cover when: has cover block, not playing, at time 0, not in render mode\n // OR during the grace period after first play, OR when coverForced (render mode)\n // Cover block is suppressed in slideshow and linear mode — start directly on content\n const showCoverBlock =\n !isSlideshowMode &&\n !isLinearMode &&\n coverBlock &&\n (coverForced ||\n coverGraceActive ||\n (!isPlaying && currentTime === 0 && !renderMode && !autoPlay));\n\n // Auto-play if enabled (wait for audio to be ready)\n // Use a ref to track if we've already auto-played to avoid repeating on every render\n const hasAutoPlayed = useRef(false);\n useEffect(() => {\n if (isAudioReady && autoPlay && !hasAutoPlayed.current) {\n hasAutoPlayed.current = true;\n play();\n }\n }, [isAudioReady, autoPlay, play]);\n\n // Callback for time updates\n useEffect(() => {\n onTimeUpdate?.(currentTime);\n }, [currentTime, onTimeUpdate]);\n\n // Callback for ended\n useEffect(() => {\n if (isEnded) {\n onEnded?.();\n }\n }, [isEnded, onEnded]);\n\n // Expose seekTo globally for render mode (Playwright) and debug mode (testing)\n useEffect(() => {\n if ((renderMode || isDebugMode) && typeof window !== 'undefined') {\n const w = window as SquisqWindow;\n w.seekTo = (time: number) => {\n seekTo(time);\n // After React renders the correct block, advance CSS animations\n // (Ken Burns, transitions) to match the doc timeline position.\n // Without this, animations restart from zero on each seekTo because\n // they run on the browser's real clock, not doc time.\n return new Promise<void>((resolve) => {\n requestAnimationFrame(() => {\n // Find the current block's start time\n let blockStartTime = 0;\n for (let i = expandedBlocks.length - 1; i >= 0; i--) {\n if (time >= expandedBlocks[i].startTime) {\n blockStartTime = expandedBlocks[i].startTime;\n break;\n }\n }\n const elapsedMs = (time - blockStartTime) * 1000;\n\n // Set all CSS animations to the correct timeline position\n document.getAnimations().forEach((anim) => {\n const target = (anim.effect as KeyframeEffect)?.target as Element | null;\n if (!target) return;\n\n // Animations on the active block: use current block elapsed time\n if (target.closest('.doc-player__block--active')) {\n anim.currentTime = Math.max(0, elapsedMs);\n }\n // Animations on the exiting block (during crossfade): use current\n // block elapsed for transition animations, keep Ken Burns at their\n // natural position based on when that block started\n // eslint-disable-next-line sonarjs/no-duplicated-branches\n else if (target.closest('.doc-player__block--previous')) {\n anim.currentTime = Math.max(0, elapsedMs);\n }\n });\n\n // Seek <video> elements in the active block to the correct clip position.\n // Each <video> carries data-clip-start/data-clip-end attributes set by\n // VideoLayer.tsx; we calculate targetTime = clipStart + blockElapsed.\n const blockElapsed = time - blockStartTime;\n const videoSeekPromises: Promise<void>[] = [];\n const activeBlockEl = document.querySelector('.doc-player__block--active');\n if (activeBlockEl) {\n const videos = activeBlockEl.querySelectorAll('video[data-clip-start]');\n videos.forEach((el) => {\n const video = el as HTMLVideoElement;\n const clipStart = parseFloat(video.dataset.clipStart || '0');\n const clipEnd = parseFloat(video.dataset.clipEnd || '0');\n const targetTime = Math.min(clipStart + Math.max(0, blockElapsed), clipEnd);\n\n video.pause();\n video.currentTime = targetTime;\n\n videoSeekPromises.push(\n new Promise<void>((r) => {\n if (Math.abs(video.currentTime - targetTime) < 0.1) {\n r();\n } else {\n video.addEventListener('seeked', () => r(), { once: true });\n setTimeout(r, 200); // Fallback if seeked never fires\n }\n }),\n );\n });\n }\n\n // Wait for video seeks + one more frame for the browser to render\n Promise.all(videoSeekPromises).then(() => {\n requestAnimationFrame(() => resolve());\n });\n });\n });\n };\n w.getDuration = () => {\n // When audio is present totalDuration comes from audio segments.\n // For audio-less docs, compute from block timings instead.\n if (totalDuration > 0) return totalDuration;\n if (expandedBlocks.length > 0) {\n const last = expandedBlocks[expandedBlocks.length - 1];\n return last.startTime + last.duration;\n }\n return 0;\n };\n // Expose block metadata for testing -- allows tests to find specific templates\n w.getBlocks = () =>\n expandedBlocks.map((s: Block) => ({\n id: s.id,\n template: (s as DocBlock).template ?? 'raw',\n startTime: s.startTime,\n duration: s.duration,\n }));\n // Audio segment info for video production -- returns the actual files in composition order\n w.getAudioSegments = () =>\n script.audio.segments.map((seg) => ({\n src: seg.src,\n name: seg.name,\n duration: seg.duration,\n startTime: seg.startTime,\n }));\n // Caption phrases for SRT/subtitle export\n w.getCaptions = () =>\n script.captions?.phrases?.map((p) => ({\n text: p.text,\n startTime: p.startTime,\n endTime: p.endTime,\n })) || [];\n // Chapter markers for YouTube timestamps -- uses segment titles from sectionHeader blocks\n w.getChapters = () => {\n const titleMap = buildSegmentTitleMap(script);\n return script.audio.segments.map((seg, i) => ({\n title: titleMap.get(i) || seg.name,\n startTime: seg.startTime,\n duration: seg.duration,\n }));\n };\n // Cover block control for video pre-roll -- force-show or hide the cover block\n w.showCover = () => {\n setCoverForced(true);\n return new Promise<void>((resolve) => requestAnimationFrame(() => resolve()));\n };\n w.hideCover = () => {\n setCoverForced(false);\n return new Promise<void>((resolve) => requestAnimationFrame(() => resolve()));\n };\n w.hasCoverBlock = () => !!coverBlock;\n }\n return () => {\n if (typeof window !== 'undefined') {\n const w = window as SquisqWindow;\n delete w.seekTo;\n delete w.getDuration;\n delete w.getBlocks;\n delete w.getAudioSegments;\n delete w.getCaptions;\n delete w.getChapters;\n delete w.showCover;\n delete w.hideCover;\n delete w.hasCoverBlock;\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- script is a stable prop; re-registering on every script change is unnecessary\n }, [renderMode, isDebugMode, seekTo, totalDuration, expandedBlocks, coverBlock]);\n\n // Caption mode state: cycles through off → standard → social → off\n // The captionStyle prop sets the default active style; captionsEnabledProp\n // can override the initial on/off state.\n const defaultMode: CaptionMode =\n captionsEnabledProp === false ? 'off' : captionStyle || 'standard';\n const [captionMode, setCaptionMode] = useState<CaptionMode>(defaultMode);\n\n // Derive captionsEnabled and active style from the mode\n const captionsEnabled = captionMode !== 'off';\n const activeCaptionStyle: CaptionStyle = captionMode === 'social' ? 'social' : 'standard';\n\n const setCaptionsEnabled = useCallback(\n (enabled: boolean) => {\n // When re-enabling, restore the prop-specified style rather than\n // always defaulting to 'standard'\n setCaptionMode(enabled ? captionStyle || 'standard' : 'off');\n onCaptionsToggle?.(enabled);\n },\n [onCaptionsToggle, captionStyle],\n );\n\n const cycleCaptionMode = useCallback(() => {\n setCaptionMode((prev) => {\n const next: CaptionMode =\n prev === 'off' ? 'standard' : prev === 'standard' ? 'social' : 'off';\n onCaptionsToggle?.(next !== 'off');\n return next;\n });\n }, [onCaptionsToggle]);\n\n const hasCaptions = script.captions && script.captions.phrases.length > 0;\n\n // Map segment indices to human-readable titles (from sectionHeader blocks)\n const segmentTitleMap = useMemo(() => buildSegmentTitleMap(script), [script]);\n\n // Build shared playback state for extracted controls\n const playbackState: PlaybackState = useMemo(\n () => ({\n isPlaying,\n currentTime,\n totalDuration,\n currentBlockIndex,\n totalBlocks: expandedBlocks.length,\n docProgress,\n hasCaptions: !!hasCaptions,\n captionsEnabled,\n captionMode,\n isFullscreen,\n currentSegmentIndex: currentSegment,\n currentSegmentName:\n segmentTitleMap.get(currentSegment) ?? script.audio.segments[currentSegment]?.name ?? null,\n currentBlock: currentBlock ?? null,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps -- script.audio.segments is stable within a given script\n [\n isPlaying,\n currentTime,\n totalDuration,\n currentBlockIndex,\n expandedBlocks.length,\n docProgress,\n hasCaptions,\n captionsEnabled,\n captionMode,\n isFullscreen,\n currentSegment,\n segmentTitleMap,\n currentBlock,\n ],\n );\n\n // Build shared playback actions for extracted controls\n const playbackActions: PlaybackActions = useMemo(\n () => ({\n toggle,\n restart,\n seekTo,\n setCaptionsEnabled,\n cycleCaptionMode,\n toggleFullscreen: onFullscreenToggle,\n }),\n [toggle, restart, seekTo, setCaptionsEnabled, cycleCaptionMode, onFullscreenToggle],\n );\n\n // Slide navigation actions for slideshow mode\n // These seek to the target block's startTime and keep the player paused.\n const slideNavActions: SlideNavActions = useMemo(\n () => ({\n nextSlide: () => {\n if (currentBlockIndex < expandedBlocks.length - 1) {\n const target = expandedBlocks[currentBlockIndex + 1];\n if (target) {\n seekTo(target.startTime);\n pause();\n }\n }\n },\n prevSlide: () => {\n if (currentBlockIndex > 0) {\n const target = expandedBlocks[currentBlockIndex - 1];\n if (target) {\n seekTo(target.startTime);\n pause();\n }\n }\n },\n goToSlide: (index: number) => {\n if (index >= 0 && index < expandedBlocks.length) {\n const target = expandedBlocks[index];\n if (target) {\n seekTo(target.startTime);\n pause();\n }\n }\n },\n }),\n [currentBlockIndex, expandedBlocks, seekTo, pause],\n );\n\n // Callback for playback state changes (for external controls)\n useEffect(() => {\n onPlaybackStateChange?.(playbackState);\n }, [playbackState, onPlaybackStateChange]);\n\n // Callback when controls are ready (for external controls)\n // Fires every time playbackActions change so the external sidebar always holds\n // fresh function references (toggle closes over isPlaying, so it changes often).\n useEffect(() => {\n onControlsReady?.({ play, pause, ...playbackActions });\n }, [play, pause, playbackActions, onControlsReady]);\n\n // Extract display title from a block (handles both template and expanded blocks)\n const getBlockTitle = useCallback((block: Block): string => {\n // For template blocks, extract title from template-specific properties first\n const docBlock = block as DocBlock;\n if (isTemplateBlock(docBlock)) {\n const props = docBlock as unknown as Record<string, unknown>;\n if (typeof props.title === 'string') return props.title;\n if (typeof props.stat === 'string') return props.stat;\n if (typeof props.quote === 'string') {\n const firstLine = props.quote.split('\\n')[0];\n if (firstLine.length <= 30) return firstLine;\n return firstLine.slice(0, 27) + '...';\n }\n if (typeof props.date === 'string') return props.date;\n if (typeof props.fact === 'string') return props.fact;\n }\n\n // For expanded blocks with layers, try to find text content\n if (block.layers && Array.isArray(block.layers)) {\n const textLayer = block.layers.find((l): l is TextLayer => l.type === 'text');\n if (textLayer?.content?.text) {\n // Get first line of text, truncate if too long\n const firstLine = textLayer.content.text.split('\\n')[0];\n if (firstLine.length <= 30) return firstLine;\n return firstLine.slice(0, 27) + '...';\n }\n }\n\n // Fallback to formatted id\n return block.id.replace(/-/g, ' ').replace(/\\b\\w/g, (c) => c.toUpperCase());\n }, []);\n\n // Compute block markers for progress bar (using expanded blocks)\n const blockMarkers = useMemo(() => {\n if (!totalDuration || !expandedBlocks.length) return [];\n let prevSegment = -1;\n return expandedBlocks.map((block, index) => {\n const isSectionStart = block.audioSegment !== prevSegment;\n prevSegment = block.audioSegment;\n return {\n block,\n index,\n position: (block.startTime / totalDuration) * 100,\n title: getBlockTitle(block),\n isSectionStart,\n };\n });\n }, [expandedBlocks, totalDuration, getBlockTitle]);\n\n // Notify parent when block markers are computed\n useEffect(() => {\n if (blockMarkers.length > 0) {\n onBlockMarkers?.(blockMarkers);\n }\n }, [blockMarkers, onBlockMarkers]);\n\n // Keep expandedBlocks length in a ref so keyboard handler stays stable\n expandedBlocksLenRef.current = expandedBlocks.length;\n\n // Handle keyboard controls — uses refs for frequently-changing values\n // (currentTime, totalDuration, expandedBlocks.length) to avoid\n // re-registering the event listener on every animation frame.\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n // Don't capture keyboard events when focus is on an input/textarea\n const activeEl = document.activeElement;\n if (\n activeEl &&\n (activeEl.tagName === 'INPUT' ||\n activeEl.tagName === 'TEXTAREA' ||\n activeEl.tagName === 'SELECT')\n ) {\n return;\n }\n\n // Linear mode: no keyboard shortcuts (native scrolling handles it)\n if (isLinearMode) return;\n\n if (isSlideshowMode) {\n // Slideshow mode: arrow keys navigate slides\n switch (e.key) {\n case 'ArrowRight':\n case 'ArrowDown':\n case ' ':\n e.preventDefault();\n slideNavActions.nextSlide();\n break;\n case 'ArrowLeft':\n case 'ArrowUp':\n e.preventDefault();\n slideNavActions.prevSlide();\n break;\n case 'Home':\n e.preventDefault();\n slideNavActions.goToSlide(0);\n break;\n case 'End':\n e.preventDefault();\n slideNavActions.goToSlide(expandedBlocksLenRef.current - 1);\n break;\n }\n } else {\n // Video mode: standard playback controls\n switch (e.key) {\n case ' ':\n e.preventDefault();\n toggle();\n break;\n case 'ArrowRight':\n seekTo(Math.min(currentTimeRef.current + 10, totalDurationRef.current));\n break;\n case 'ArrowLeft':\n seekTo(Math.max(currentTimeRef.current - 10, 0));\n break;\n }\n }\n },\n [isSlideshowMode, isLinearMode, toggle, seekTo, slideNavActions],\n );\n\n useEffect(() => {\n if (renderMode) return; // No keyboard in render mode\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [handleKeyDown, renderMode]);\n\n // ── Linear mode: render as scrollable document ──────────────────\n if (isLinearMode) {\n return (\n <div\n ref={containerRef}\n className=\"doc-player doc-player--linear\"\n style={{\n position: 'relative',\n width: '100%',\n height: '100%',\n overflow: 'hidden',\n }}\n >\n <LinearDocView doc={script} basePath={basePath} viewport={activeViewport} />\n </div>\n );\n }\n\n return (\n <div\n ref={containerRef}\n className=\"doc-player\"\n onClick={handleContainerClick}\n style={{\n position: 'relative',\n width: '100%',\n aspectRatio: `${activeViewport.width} / ${activeViewport.height}`,\n margin: '0 auto',\n overflow: 'hidden',\n cursor: renderMode ? undefined : 'pointer',\n }}\n >\n {/* Hidden audio element */}\n <audio ref={audioRef} preload=\"auto\" muted={muted} />\n\n {/* Block viewport */}\n <div className=\"doc-player__viewport\">\n {/* Cover block (shown at rest before playback) */}\n {showCoverBlock && coverBlock && (\n <div className=\"doc-player__block doc-player__block--cover\">\n <BlockRenderer\n block={coverBlock}\n blockTime={0}\n basePath={basePath}\n isEntering={false}\n viewport={activeViewport}\n />\n </div>\n )}\n\n {/* Previous block (during transition) */}\n {!showCoverBlock && previousBlock && isExiting && (\n <div className=\"doc-player__block doc-player__block--previous\">\n <BlockRenderer\n block={previousBlock}\n blockTime={blockTime}\n basePath={basePath}\n isExiting={true}\n viewport={activeViewport}\n />\n </div>\n )}\n\n {/* Current block */}\n {!showCoverBlock && currentBlock && (\n <div className=\"doc-player__block doc-player__block--active\">\n <BlockRenderer\n block={currentBlock}\n blockTime={blockTime}\n basePath={basePath}\n isEntering={isEntering}\n viewport={activeViewport}\n isPlaying={isPlaying}\n />\n </div>\n )}\n\n {/* Caption overlay -- shown during playback and in render mode when captions are enabled */}\n {hasCaptions && (renderMode ? captionsEnabled : true) && (\n <CaptionOverlay\n captions={script.captions}\n currentTime={currentTime}\n enabled={captionsEnabled && (renderMode || isPlaying || currentTime > 0)}\n fontSize={16}\n captionStyle={activeCaptionStyle}\n theme={theme}\n viewport={activeViewport}\n />\n )}\n\n {/* Debug overlay (when ?debug=true) */}\n {isDebugMode && (\n <div\n className=\"doc-player__debug\"\n style={{\n position: 'absolute',\n top: '8px',\n right: '8px',\n padding: '8px 12px',\n background: 'rgba(0, 0, 0, 0.85)',\n borderRadius: '6px',\n color: '#00ff00',\n fontFamily: 'monospace',\n fontSize: '11px',\n lineHeight: '1.5',\n zIndex: 200,\n maxWidth: '280px',\n pointerEvents: 'none',\n textAlign: 'left',\n }}\n >\n <div style={{ color: '#ffcc00', fontWeight: 'bold', marginBottom: '4px' }}>\n DEBUG MODE\n </div>\n <div>\n <span style={{ color: '#888' }}>template:</span>{' '}\n <span style={{ color: '#ff6b6b' }}>\n {(currentBlock as DocBlock | null)?.template ?? 'raw'}\n </span>\n </div>\n <div>\n <span style={{ color: '#888' }}>block:</span> {currentBlockIndex + 1}/\n {expandedBlocks.length}{' '}\n <span style={{ color: '#666' }}>({currentBlock?.id || 'none'})</span>\n </div>\n <div>\n <span style={{ color: '#888' }}>time:</span> {currentTime.toFixed(2)}s /{' '}\n {totalDuration.toFixed(1)}s{' '}\n <span style={{ color: '#666' }}>\n (progress: {(docProgress * 100).toFixed(1)}%, scriptDur:{' '}\n {script.duration.toFixed(1)})\n </span>\n </div>\n <div>\n <span style={{ color: '#888' }}>blockTime:</span> {blockTime.toFixed(2)}s /{' '}\n {(currentBlock?.duration || 0).toFixed(1)}s\n </div>\n <div>\n <span style={{ color: '#888' }}>segment:</span> {currentSegment}/\n {script.audio.segments.length - 1}{' '}\n <span style={{ color: '#666' }}>\n ({script.audio.segments[currentSegment]?.name || 'none'})\n </span>\n </div>\n <div>\n <span style={{ color: '#888' }}>viewport:</span>{' '}\n {activeViewport.name || `${activeViewport.width}x${activeViewport.height}`}{' '}\n <span style={{ color: '#666' }}>({orientation})</span>\n </div>\n <div>\n <span style={{ color: '#888' }}>playing:</span>{' '}\n <span style={{ color: isPlaying ? '#4ade80' : '#f87171' }}>\n {isPlaying ? 'yes' : 'no'}\n </span>\n {showCoverBlock && <span style={{ color: '#60a5fa' }}> (cover)</span>}\n </div>\n {hasCaptions &&\n (() => {\n const debugPhrase = getCaptionAtTime(script.captions!, currentTime);\n const debugEnabled = captionsEnabled && (isPlaying || currentTime > 0);\n return (\n <Fragment>\n <div>\n <span style={{ color: '#888' }}>captions:</span>{' '}\n {script.captions?.phrases.length || 0} phrases{' '}\n <span style={{ color: captionsEnabled ? '#4ade80' : '#666' }}>\n ({captionsEnabled ? 'on' : 'off'})\n </span>\n </div>\n <div>\n <span style={{ color: '#888' }}>cc.enabled:</span>{' '}\n <span style={{ color: debugEnabled ? '#4ade80' : '#f87171' }}>\n {String(debugEnabled)}\n </span>{' '}\n <span style={{ color: '#666' }}>\n (playing={String(isPlaying)} t&gt;0={String(currentTime > 0)})\n </span>\n </div>\n <div>\n <span style={{ color: '#888' }}>cc.phrase:</span>{' '}\n <span style={{ color: debugPhrase ? '#4ade80' : '#f87171' }}>\n {debugPhrase ? `\"${debugPhrase.text.slice(0, 30)}...\"` : 'null'}\n </span>\n </div>\n {debugPhrase && (\n <div>\n <span style={{ color: '#888' }}>cc.range:</span>{' '}\n <span style={{ color: '#60a5fa' }}>\n {debugPhrase.startTime.toFixed(2)}-{debugPhrase.endTime.toFixed(2)}\n </span>\n </div>\n )}\n </Fragment>\n );\n })()}\n </div>\n )}\n </div>\n\n {/* Audio unavailable overlay */}\n {!isAvailable && unavailableMessage && (\n <div\n className=\"doc-player__unavailable\"\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexDirection: 'column',\n gap: '16px',\n background: 'rgba(0, 0, 0, 0.7)',\n color: 'rgba(255, 255, 255, 0.9)',\n fontSize: '14px',\n zIndex: 50,\n }}\n >\n <span style={{ fontSize: '32px' }}>&#x1F50A;</span>\n <span>{unavailableMessage}</span>\n </div>\n )}\n\n {/* Full overlay controls (default video layout) */}\n {!renderMode && !isSlideshowMode && showControls && (\n <DocControlsOverlay\n state={playbackState}\n actions={playbackActions}\n blockMarkers={blockMarkers}\n expandedBlocks={expandedBlocks}\n getBlockTitle={getBlockTitle}\n />\n )}\n\n {/* Scrubber-only mode (for sidebar/bottom layouts where other controls are external) */}\n {!renderMode && !isSlideshowMode && !showControls && showScrubber && (\n <div\n className=\"doc-player__scrubber\"\n style={{\n position: 'absolute',\n bottom: 0,\n left: 0,\n right: 0,\n padding: '12px 16px 8px',\n background: 'linear-gradient(transparent, rgba(0,0,0,0.6))',\n display: 'flex',\n alignItems: 'center',\n zIndex: 100,\n }}\n >\n <DocProgressBar\n state={playbackState}\n actions={playbackActions}\n blockMarkers={blockMarkers}\n expandedBlocks={expandedBlocks}\n getBlockTitle={getBlockTitle}\n />\n </div>\n )}\n\n {/* Slideshow controls (prev / counter / next) */}\n {!renderMode && isSlideshowMode && (\n <DocControlsSlideshow state={playbackState} slideNav={slideNavActions} />\n )}\n\n {/* Tap feedback animation -- shows play/pause icon briefly on tap (video mode only) */}\n {!isSlideshowMode && tapFeedback && (\n <div className=\"doc-player__tap-feedback\" key={Date.now()}>\n <svg viewBox=\"0 0 24 24\" fill=\"white\" width=\"48\" height=\"48\">\n {tapFeedback === 'pause' ? (\n <path d=\"M6 19h4V5H6v14zm8-14v14h4V5h-4z\" />\n ) : (\n <path d=\"M8 5v14l11-7z\" />\n )}\n </svg>\n </div>\n )}\n </div>\n );\n}\n\nexport default DocPlayer;\n","/**\n * Doc Animations\n *\n * CSS keyframe animations for the visual doc system.\n * Designed to be ES2015/Chrome 49 compatible for Coherent GT (MSFS).\n *\n * Animation classes are applied dynamically based on Doc.\n * Each animation has variants for common durations.\n */\n\n/* ============================================\n Slow Zoom Effect\n Slow zoom with optional pan for cinematic feel\n ============================================ */\n\n@keyframes slowZoomIn {\n from {\n transform: scale(1);\n }\n to {\n transform: scale(1.15);\n }\n}\n\n@keyframes slowZoomOut {\n from {\n transform: scale(1.15);\n }\n to {\n transform: scale(1);\n }\n}\n\n@keyframes slowZoomPanLeft {\n from {\n transform: translateX(0) scale(1.1);\n }\n to {\n transform: translateX(-8%) scale(1.1);\n }\n}\n\n@keyframes slowZoomPanRight {\n from {\n transform: translateX(-8%) scale(1.1);\n }\n to {\n transform: translateX(0) scale(1.1);\n }\n}\n\n@keyframes slowZoomPanUp {\n from {\n transform: translateY(0) scale(1.1);\n }\n to {\n transform: translateY(-8%) scale(1.1);\n }\n}\n\n@keyframes slowZoomPanDown {\n from {\n transform: translateY(-8%) scale(1.1);\n }\n to {\n transform: translateY(0) scale(1.1);\n }\n}\n\n/* Slow zoom combined zoom + pan */\n@keyframes slowZoomCombinedPanLeft {\n from {\n transform: translateX(0) scale(1);\n }\n to {\n transform: translateX(-5%) scale(1.12);\n }\n}\n\n@keyframes slowZoomCombinedPanRight {\n from {\n transform: translateX(-5%) scale(1.12);\n }\n to {\n transform: translateX(0) scale(1);\n }\n}\n\n/* ============================================\n Fade Animations\n ============================================ */\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n@keyframes fadeOut {\n from {\n opacity: 1;\n }\n to {\n opacity: 0;\n }\n}\n\n@keyframes fadeInUp {\n from {\n opacity: 0;\n transform: translateY(20px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes fadeInDown {\n from {\n opacity: 0;\n transform: translateY(-20px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n/* ============================================\n Zoom Animations\n ============================================ */\n\n@keyframes zoomIn {\n from {\n transform: scale(0.9);\n opacity: 0;\n }\n to {\n transform: scale(1);\n opacity: 1;\n }\n}\n\n@keyframes zoomOut {\n from {\n transform: scale(1);\n opacity: 1;\n }\n to {\n transform: scale(0.9);\n opacity: 0;\n }\n}\n\n/* ============================================\n Pan/Slide Animations\n ============================================ */\n\n@keyframes panLeft {\n from {\n transform: translateX(0);\n }\n to {\n transform: translateX(-10%);\n }\n}\n\n@keyframes panRight {\n from {\n transform: translateX(-10%);\n }\n to {\n transform: translateX(0);\n }\n}\n\n@keyframes slideInLeft {\n from {\n transform: translateX(-100%);\n }\n to {\n transform: translateX(0);\n }\n}\n\n@keyframes slideInRight {\n from {\n transform: translateX(100%);\n }\n to {\n transform: translateX(0);\n }\n}\n\n@keyframes slideOutLeft {\n from {\n transform: translateX(0);\n }\n to {\n transform: translateX(-100%);\n }\n}\n\n@keyframes slideOutRight {\n from {\n transform: translateX(0);\n }\n to {\n transform: translateX(100%);\n }\n}\n\n/* ============================================\n Text Animations\n ============================================ */\n\n@keyframes typewriter {\n from {\n clip-path: inset(0 100% 0 0);\n }\n to {\n clip-path: inset(0 0 0 0);\n }\n}\n\n/* Fallback for browsers without clip-path */\n@keyframes typewriterFallback {\n from {\n width: 0;\n overflow: hidden;\n }\n to {\n width: 100%;\n overflow: hidden;\n }\n}\n\n/* ============================================\n Block Transitions\n Applied to entire block containers\n ============================================ */\n\n.transition-fade-enter {\n animation: fadeIn var(--transition-duration, 1.5s) ease-out forwards;\n}\n\n.transition-fade-exit {\n animation: fadeOut var(--transition-duration, 1.5s) ease-out forwards;\n}\n\n.transition-dissolve-enter {\n animation: fadeIn var(--transition-duration, 2s) ease-in-out forwards;\n}\n\n.transition-dissolve-exit {\n animation: fadeOut var(--transition-duration, 2s) ease-in-out forwards;\n}\n\n.transition-slideLeft-enter {\n animation: slideInRight var(--transition-duration, 0.8s) ease-out forwards;\n}\n\n.transition-slideLeft-exit {\n animation: slideOutLeft var(--transition-duration, 0.8s) ease-out forwards;\n}\n\n.transition-slideRight-enter {\n animation: slideInLeft var(--transition-duration, 0.8s) ease-out forwards;\n}\n\n.transition-slideRight-exit {\n animation: slideOutRight var(--transition-duration, 0.8s) ease-out forwards;\n}\n\n/* ============================================\n Animation Utility Classes\n Applied dynamically based on layer.animation\n ============================================ */\n\n.anim-none {\n animation: none;\n}\n\n.anim-fadeIn {\n animation: fadeIn var(--anim-duration, 1s) var(--anim-easing, ease-out) var(--anim-delay, 0s)\n forwards;\n}\n\n.anim-fadeOut {\n animation: fadeOut var(--anim-duration, 1s) var(--anim-easing, ease-out) var(--anim-delay, 0s)\n forwards;\n}\n\n.anim-fadeInUp {\n animation: fadeInUp var(--anim-duration, 0.6s) var(--anim-easing, ease-out) var(--anim-delay, 0s)\n forwards;\n}\n\n.anim-slowZoom-in {\n animation: slowZoomIn var(--anim-duration, 8s) var(--anim-easing, linear) var(--anim-delay, 0s)\n forwards;\n}\n\n.anim-slowZoom-out {\n animation: slowZoomOut var(--anim-duration, 8s) var(--anim-easing, linear) var(--anim-delay, 0s)\n forwards;\n}\n\n.anim-slowZoom-panLeft {\n animation: slowZoomCombinedPanLeft var(--anim-duration, 8s) var(--anim-easing, linear)\n var(--anim-delay, 0s) forwards;\n}\n\n.anim-slowZoom-panRight {\n animation: slowZoomCombinedPanRight var(--anim-duration, 8s) var(--anim-easing, linear)\n var(--anim-delay, 0s) forwards;\n}\n\n.anim-zoomIn {\n animation: zoomIn var(--anim-duration, 0.5s) var(--anim-easing, ease-out) var(--anim-delay, 0s)\n forwards;\n}\n\n.anim-zoomOut {\n animation: zoomOut var(--anim-duration, 0.5s) var(--anim-easing, ease-out) var(--anim-delay, 0s)\n forwards;\n}\n\n.anim-panLeft {\n animation: panLeft var(--anim-duration, 8s) var(--anim-easing, linear) var(--anim-delay, 0s)\n forwards;\n}\n\n.anim-panRight {\n animation: panRight var(--anim-duration, 8s) var(--anim-easing, linear) var(--anim-delay, 0s)\n forwards;\n}\n\n.anim-typewriter {\n animation: typewriter var(--anim-duration, 2s) var(--anim-easing, steps(40, end))\n var(--anim-delay, 0s) forwards;\n}\n\n/* ============================================\n Doc Player Container Styles\n ============================================ */\n\n.doc-player {\n position: relative;\n overflow: hidden;\n /* clip-path provides a hard pixel clip that catches SVG foreignObject bleed\n which can escape overflow:hidden in some browsers */\n clip-path: inset(0);\n background: #000;\n /* Ensure max dimensions work with aspect-ratio */\n max-width: 100%;\n max-height: 100%;\n}\n\n.doc-player__viewport {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n}\n\n.doc-player__block {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n}\n\n.doc-player__block--active {\n z-index: 2;\n}\n\n.doc-player__block--previous {\n z-index: 1;\n}\n\n/* Tap-to-toggle play/pause feedback */\n.doc-player__tap-feedback {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n z-index: 150;\n pointer-events: none;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 72px;\n height: 72px;\n border-radius: 50%;\n background: rgba(0, 0, 0, 0.45);\n animation: tap-feedback-fade 0.6s ease-out forwards;\n}\n\n@keyframes tap-feedback-fade {\n 0% {\n opacity: 1;\n transform: translate(-50%, -50%) scale(1);\n }\n 100% {\n opacity: 0;\n transform: translate(-50%, -50%) scale(1.3);\n }\n}\n\n/* SVG block container */\n.block-svg {\n width: 100%;\n height: 100%;\n display: block;\n}\n\n/* Layer containers within SVG */\n.block-layer {\n overflow: hidden;\n}\n\n.block-layer--image {\n /* Images need overflow visible for Ken Burns */\n overflow: visible;\n}\n\n/* ============================================\n Text Styling Helpers\n ============================================ */\n\n.text-shadow {\n text-shadow:\n 0 2px 4px rgba(0, 0, 0, 0.8),\n 0 4px 8px rgba(0, 0, 0, 0.4);\n}\n\n.text-shadow-light {\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n\n/* Text background box */\n.text-box {\n background: rgba(0, 0, 0, 0.6);\n padding: 16px 24px;\n border-radius: 4px;\n}\n\n.text-box--light {\n background: rgba(255, 255, 255, 0.9);\n color: #1a1a1a;\n}\n","/**\n * Standalone Entry Point — IIFE bundle for self-contained HTML rendering.\n *\n * This file is the entry point for the standalone `squisq-player.iife.js` bundle.\n * It bundles Preact (via preact/compat), squisq core, and all rendering components\n * into a single self-contained script that can be loaded in any HTML page.\n *\n * The bundle exposes a global `SquisqPlayer` object with methods to mount\n * interactive or static document views into any DOM element.\n *\n * Usage (in HTML):\n * <script src=\"squisq-player.iife.js\"></script>\n * <div id=\"root\"></div>\n * <script>\n * SquisqPlayer.mount(document.getElementById('root'), docJson, {\n * mode: 'slideshow',\n * images: { 'hero.jpg': 'data:image/jpeg;base64,...' }\n * });\n * </script>\n */\n\nimport { createElement } from 'react';\nimport { createRoot, type Root } from 'react-dom/client';\nimport type { Doc, MediaProvider } from '@bendyline/squisq/schemas';\nimport type { Theme } from '@bendyline/squisq/schemas';\nimport { DocPlayer } from './DocPlayer';\nimport { LinearDocView } from './LinearDocView';\nimport { MediaContext } from './hooks/MediaContext';\n\n// CSS is loaded as text via esbuild's text loader (configured in tsup.standalone.config.ts)\n// @ts-expect-error — .css import returns a string when esbuild uses 'text' loader (standalone build only)\nimport animationCss from './styles/doc-animations.css';\n\n// ── Types ──────────────────────────────────────────────────────────\n\nexport interface MountOptions {\n /** Rendering mode: 'slideshow' (interactive, default) or 'static' (scrollable) */\n mode?: 'slideshow' | 'static';\n /** Base path for resolving relative media URLs */\n basePath?: string;\n /**\n * Map of relative image paths to data URIs or blob URLs.\n * Used in single-HTML exports where images are inlined as base64.\n * Example: { 'hero.jpg': 'data:image/jpeg;base64,...' }\n */\n images?: Record<string, string>;\n /**\n * Map of audio segment names/paths to URLs (data URIs, blob URLs, or relative paths).\n * Used in ZIP exports where audio files are included alongside the HTML.\n */\n audio?: Record<string, string>;\n /** Optional theme override */\n theme?: Theme;\n /** Auto-play on mount (only for slideshow mode, default: false) */\n autoPlay?: boolean;\n /**\n * Enable render mode for headless frame capture.\n * Exposes window.seekTo(), getDuration(), getCaptions(), etc.\n * Disables controls and auto-play. Used by Playwright video export.\n */\n renderMode?: boolean;\n /** Caption style: 'standard' or 'social'. Omit or set to undefined for no captions. */\n captionStyle?: 'standard' | 'social';\n}\n\n// ── CSS Injection ──────────────────────────────────────────────────\n\nlet cssInjected = false;\n\nfunction injectCss(): void {\n if (cssInjected || typeof document === 'undefined') return;\n const style = document.createElement('style');\n style.setAttribute('data-squisq-player', 'animations');\n style.textContent = animationCss;\n document.head.appendChild(style);\n cssInjected = true;\n}\n\n// ── Inline Media Provider ──────────────────────────────────────────\n\n/**\n * Creates a MediaProvider that resolves URLs from an inline image map.\n * Falls back to basePath-based resolution for unknown paths.\n */\nfunction createInlineMediaProvider(\n images: Record<string, string>,\n basePath: string,\n): MediaProvider {\n return {\n async resolveUrl(relativePath: string): Promise<string> {\n if (relativePath in images) return images[relativePath];\n // Fallback to basePath\n if (\n relativePath.startsWith('http') ||\n relativePath.startsWith('data:') ||\n relativePath.startsWith('blob:')\n ) {\n return relativePath;\n }\n return `${basePath}/${relativePath}`;\n },\n async listMedia() {\n return Object.keys(images).map((name) => ({\n name,\n mimeType: inferMimeType(name),\n size: 0,\n }));\n },\n async addMedia() {\n throw new Error('Standalone player is read-only');\n },\n async removeMedia() {\n throw new Error('Standalone player is read-only');\n },\n dispose() {\n // no-op\n },\n };\n}\n\nfunction inferMimeType(filename: string): string {\n const ext = filename.split('.').pop()?.toLowerCase() ?? '';\n const map: Record<string, string> = {\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n png: 'image/png',\n gif: 'image/gif',\n webp: 'image/webp',\n svg: 'image/svg+xml',\n mp3: 'audio/mpeg',\n mp4: 'video/mp4',\n webm: 'video/webm',\n };\n return map[ext] ?? 'application/octet-stream';\n}\n\n// ── Audio Rewriting ────────────────────────────────────────────────\n\n/**\n * Rewrite audio segment URLs in a Doc if an audio map is provided.\n * Returns a shallow-modified copy — does not mutate the original.\n */\nfunction rewriteAudioUrls(doc: Doc, audioMap: Record<string, string>): Doc {\n if (!doc.audio?.segments?.length) return doc;\n\n const segments = doc.audio.segments.map((seg) => {\n const resolved = audioMap[seg.name] ?? audioMap[seg.src] ?? seg.src;\n return { ...seg, src: resolved };\n });\n\n return { ...doc, audio: { ...doc.audio, segments } };\n}\n\n// ── Root Tracking ──────────────────────────────────────────────────\n\nconst roots = new WeakMap<Element, Root>();\n\n// ── Public API ─────────────────────────────────────────────────────\n\n/**\n * Mount a SquisqPlayer into a DOM element.\n *\n * @param element - The DOM element to render into\n * @param doc - A Doc object (parsed JSON)\n * @param options - Rendering options\n */\nexport function mount(element: Element, doc: Doc, options: MountOptions = {}): void {\n injectCss();\n\n const {\n mode = 'slideshow',\n basePath = '.',\n images,\n audio,\n autoPlay = false,\n theme,\n renderMode = false,\n captionStyle,\n } = options;\n\n // Rewrite audio URLs if map provided\n const finalDoc = audio ? rewriteAudioUrls(doc, audio) : doc;\n\n // Build the media provider if images are provided\n const mediaProvider = images ? createInlineMediaProvider(images, basePath) : null;\n\n let content: ReturnType<typeof createElement>;\n\n if (mode === 'static') {\n content = createElement(LinearDocView, {\n doc: finalDoc,\n basePath,\n theme,\n });\n } else {\n content = createElement(DocPlayer, {\n script: finalDoc,\n basePath,\n displayMode: 'slideshow',\n autoPlay: renderMode ? false : autoPlay,\n showControls: !renderMode,\n renderMode,\n theme,\n captionsEnabled: !!captionStyle,\n captionStyle: captionStyle ?? 'standard',\n });\n }\n\n // Wrap in MediaContext if provider is available\n if (mediaProvider) {\n content = createElement(MediaContext.Provider, { value: mediaProvider }, content);\n }\n\n // Create or reuse React root\n let root = roots.get(element);\n if (!root) {\n root = createRoot(element);\n roots.set(element, root);\n }\n root.render(content);\n}\n\n/**\n * Mount a static scrollable document view (alias for mount with mode='static').\n */\nexport function mountStatic(\n element: Element,\n doc: Doc,\n options: Omit<MountOptions, 'mode'> = {},\n): void {\n mount(element, doc, { ...options, mode: 'static' });\n}\n\n/**\n * Unmount a previously mounted SquisqPlayer from an element.\n */\nexport function unmount(element: Element): void {\n const root = roots.get(element);\n if (root) {\n root.unmount();\n roots.delete(element);\n }\n}\n\n/** Package version — injected at build time via esbuild define */\ndeclare const __SQUISQ_VERSION__: string;\nexport const version: string =\n typeof __SQUISQ_VERSION__ !== 'undefined' ? __SQUISQ_VERSION__ : '0.0.0';\n"]}
1
+ {"version":3,"sources":["../../../node_modules/preact/src/constants.js","../../../node_modules/preact/src/util.js","../../../node_modules/preact/src/options.js","../../../node_modules/preact/src/create-element.js","../../../node_modules/preact/src/component.js","../../../node_modules/preact/src/diff/props.js","../../../node_modules/preact/src/create-context.js","../../../node_modules/preact/src/diff/children.js","../../../node_modules/preact/src/diff/index.js","../../../node_modules/preact/src/render.js","../../../node_modules/preact/src/diff/catch-error.js","../../../node_modules/preact/hooks/src/index.js","../../../node_modules/preact/compat/src/util.js","../../../node_modules/preact/compat/src/hooks.js","../../../node_modules/preact/compat/src/PureComponent.js","../../../node_modules/preact/compat/src/forwardRef.js","../../../node_modules/preact/compat/src/Children.js","../../../node_modules/preact/compat/src/suspense.js","../../../node_modules/preact/compat/src/suspense-list.js","../../../node_modules/preact/compat/src/render.js","../../../node_modules/preact/compat/src/index.js","../../../node_modules/preact/compat/client.mjs","../../core/src/schemas/Doc.ts","../../core/src/schemas/themeLibrary.ts","../../core/src/schemas/Viewport.ts","../../core/src/schemas/LayoutStrategy.ts","../../core/src/schemas/BlockTemplates.ts","../../core/src/markdown/utils.ts","../../core/src/doc/templates/persistentLayers.ts","../../core/src/doc/utils/themeUtils.ts","../../core/src/doc/templates/titleBlock.ts","../../core/src/doc/templates/sectionHeader.ts","../../core/src/doc/templates/accentImage.ts","../../core/src/doc/templates/captionUtils.ts","../../core/src/doc/templates/statHighlight.ts","../../core/src/doc/templates/quoteBlock.ts","../../core/src/doc/templates/factCard.ts","../../core/src/doc/templates/twoColumn.ts","../../core/src/doc/templates/dateEvent.ts","../../core/src/doc/templates/imageWithCaption.ts","../../core/src/doc/templates/mapBlock.ts","../../core/src/doc/templates/fullBleedQuote.ts","../../core/src/doc/templates/listBlock.ts","../../core/src/doc/templates/photoGrid.ts","../../core/src/doc/templates/definitionCard.ts","../../core/src/doc/templates/comparisonBar.ts","../../core/src/doc/templates/pullQuote.ts","../../core/src/doc/templates/videoWithCaption.ts","../../core/src/doc/templates/videoPullQuote.ts","../../core/src/doc/templates/dataTable.ts","../../core/src/doc/templates/coverBlock.ts","../../core/src/doc/templates/index.ts","../../core/src/doc/utils/animationUtils.ts","../../core/src/doc/markdownToDoc.ts","../../core/src/doc/getLayers.ts","../src/utils/layerUtils.ts","../src/hooks/MediaContext.tsx","../../../node_modules/preact/jsx-runtime/src/index.js","../src/layers/ImageLayer.tsx","../src/layers/TextLayer.tsx","../src/layers/ShapeLayer.tsx","../src/utils/mapTileUtils.ts","../src/layers/MapLayer.tsx","../src/layers/VideoLayer.tsx","../src/layers/TableLayer.tsx","../src/BlockRenderer.tsx","../src/SocialCaptionOverlay.tsx","../src/CaptionOverlay.tsx","../src/hooks/useAudioSync.ts","../src/hooks/useDocPlayback.ts","../src/hooks/useViewportOrientation.ts","../src/types.ts","../src/DocProgressBar.tsx","../src/DocControlsOverlay.tsx","../src/DocControlsSlideshow.tsx","../src/MarkdownRenderer.tsx","../src/LinearDocView.tsx","../src/DocPlayer.tsx","../src/styles/doc-animations.css","../src/standalone-entry.tsx"],"names":["slice","options","vnodeId","rerenderQueue","prevDebounce","defer","depthSort","CAPTURE_REGEX","eventClock","eventProxy","eventProxyCapture","i","EMPTY_OBJ","EMPTY_ARR","IS_NON_DIMENSIONAL","isArray","Array","assign","obj","props","removeNode","node","parentNode","removeChild","createElement","type","children","key","ref","normalizedProps","arguments","length","call","defaultProps","createVNode","original","vnode","__k","__","__b","__e","__c","constructor","__v","__i","__u","Fragment","BaseComponent","context","this","getDomSibling","childIndex","sibling","renderComponent","component","__P","__d","oldVNode","oldDom","commitQueue","refQueue","newVNode","diff","__n","namespaceURI","commitRoot","updateParentDomPointers","base","some","child","enqueueRender","c","push","process","__r","debounceRendering","l","sort","shift","diffChildren","parentDom","renderResult","newParentVNode","oldParentVNode","globalContext","namespace","excessDomChildren","isHydrating","childVNode","newDom","firstChildDom","result","shouldPlace","oldChildren","newChildrenLength","constructNewChildrenArray","applyRef","insert","nextSibling","skewedIndex","matchingIndex","oldChildrenLength","remainingOldChildren","skew","String","findMatchingIndex","unmount","parentVNode","insertBefore","nodeType","toChildArray","out","x","y","matched","shouldSearch","setStyle","style","value","setProperty","test","dom","name","oldValue","useCapture","lowerCaseName","o","cssText","replace","toLowerCase","_attached","addEventListener","removeEventListener","e","removeAttribute","setAttribute","createEventProxy","eventHandler","_dispatched","event","tmp","isNew","oldProps","oldState","snapshot","clearProcessingException","newProps","isClassComponent","provider","componentContext","renderHook","count","newType","outer","prototype","render","contextType","__E","doRender","sub","state","__h","_sb","__s","getDerivedStateFromProps","componentWillMount","componentDidMount","componentWillReceiveProps","shouldComponentUpdate","apply","componentWillUpdate","componentDidUpdate","getChildContext","getSnapshotBeforeUpdate","cloneNode","then","MODE_HYDRATE","indexOf","markAsForce","diffElementNodes","diffed","root","cb","map","newHtml","oldHtml","newChildren","inputValue","checked","localName","document","createTextNode","createElementNS","is","__m","data","childNodes","attributes","__html","innerHTML","content","undefined","hasRefUnmount","current","skipRemove","r","componentWillUnmount","replaceNode","documentElement","firstChild","createContext","defaultValue","Context","subs","ctx","Set","_props","forEach","add","old","delete","Provider","__l","Consumer","contextValue","error","errorInfo","ctor","handled","getDerivedStateFromError","setState","componentDidCatch","update","callback","s","forceUpdate","Promise","bind","resolve","setTimeout","a","b","currentIndex","currentComponent","previousComponent","prevRaf","currentHook","afterPaintEffects","_options","oldBeforeDiff","oldBeforeRender","oldAfterDiff","oldCommit","oldBeforeUnmount","oldRoot","getHookState","index","hooks","__H","useState","initialState","useReducer","invokeOrReturn","reducer","init","hookState","_reducer","action","currentValue","__N","nextValue","__f","updateHookState","p","stateHooks","filter","every","prevScu","shouldUpdate","hookItem","prevCWU","useEffect","args","argsChanged","_pendingArgs","useRef","initialValue","useMemo","factory","useCallback","useContext","flushAfterPaintEffects","invokeCleanup","invokeEffect","requestAnimationFrame","afterNextFrame","hasErrored","HAS_RAF","raf","done","clearTimeout","timeout","cancelAnimationFrame","hook","comp","cleanup","oldArgs","newArgs","arg","f","shallowDiffers","useLayoutEffect","PureComponent","Component","isPureReactComponent","oldDiffHook","oldCatchError","oldUnmount","detachedClone","detachedParent","effect","removeOriginal","originalParent","appendChild","Suspense","_suspenders","suspended","__a","SuspenseList","_next","_map","__z","__R","promise","suspendingVNode","suspendingComponent","resolved","onResolved","onSuspensionComplete","originalParentDom","suspendedVNode","__O","pop","detachedComponent","fallback","list","revealOrder","size","delegated","get","unsuspend","wrappedUnsuspend","Map","reverse","set","_this","REACT_ELEMENT_TYPE","Symbol","for","CAMEL_PROPS","ON_ANI","CAMEL_REPLACE","IS_DOM","onChangeInputType","parent","textContent","preactRender","isReactComponent","Object","defineProperty","configurable","v","writable","oldEventHook","persist","isPropagationStopped","cancelBubble","isDefaultPrevented","defaultPrevented","nativeEvent","classNameDescriptorNonEnumberable","class","oldVNodeHook","isNonDashedType","lowerCased","multiple","selected","className","$$typeof","oldDiffed","unmountComponentAtNode","container","createRoot","nn","pn","getBlockAtTime","blocks","time","block","getCaptionAtTime","captions","phrase","SYSTEM_SANS","SYSTEM_SERIF","SYSTEM_MONO","CLASSIC_COLOR_SCHEMES","standard","DEFAULT_THEME","VIEWPORT_PRESETS","REFERENCE_DIAGONAL","calculateFontScale","viewport","getViewportOrientation","ratio","LAYOUT_CONFIGS","getLayoutHints","orientation","scaledFontSize","basePx","isTitle","fontScale","layout","typeScale","getTwoColumnPositions","DEFAULT_DOC_FONT","isTemplateBlock","createTemplateContext","theme","blockIndex","totalBlocks","isPersistentLayerTemplate","layer","getChildren","extractPlainText","GRADIENT_PRESETS","expandSolidBackground","config","expandGradientBackground","expandImageBackground","layers","opacity","imageLayer","expandPatternBackground","expandTitleCaption","fontSize","hasSubtitle","isBottom","isLeft","pad","pillHeight","bgYPos","bgXPos","thumbW","thumbH","thumbPad","textX","textWidth","titleYPos","thumbX","thumbY","subtitleYPos","expandCornerBranding","xPos","yPos","expandProgressIndicator","color","expandPersistentLayer","expandPersistentLayers","acc","FALLBACK_COLOR_SCHEME","resolveColorScheme","schemes","keys","FALLBACK_BODY","FALLBACK_TITLE","FALLBACK_MONO","getThemeFont","role","typography","titleBlock","input","title","subtitle","backgroundColor","titleFontSize","scaledFontSize2","subtitleFontSize","sectionHeader","colorScheme","imageSrc","imageAlt","ambientMotion","colors","PERCENTAGE_RE","DEFAULT_LAYOUT","mapAmbientMotion","motion","duration","STRIP_SIZE","STRIP_SIZE_PCT","getAccentLayout","position","createAccentLayers","accent","slideId","src","alt","credit","license","createStripImage","createStripGradient","createBottomStripImage","createBottomStripGradient","createCornerInsetImage","createCornerVignette","side","gradientId","adjustY","originalY","yStr","match","yValue","TRAILING_PUNCT_RE","cleanCaption","text","createBackgroundLayer","id","fill","statHighlight","stat","description","detail","accentImage","accentLayout","statFontSize","descFontSize","detailFontSize","quoteBlock","quote","attribution","quoteFontSize","attrFontSize","decorativeQuoteFontSize","quoteY","factCard","fact","explanation","source","factFontSize","explainFontSize","sourceFontSize","twoColumn","left","right","header","leftColor","rightColor","leftColors","rightColors","positions","isStacked","columnWidth","headerFontSize","labelFontSize","sublabelFontSize","headerY","leftY","leftSublabelY","rightY","rightSublabelY","baseY","sublabelOffset","connectorFontSize","connectorY","connectorSymbol","MOOD_COLORS","dateEvent","date","footer","mood","dateFontSize","footerFontSize","imageWithCaption","rawCaption","_captionPosition","imageCredit","imageLicense","caption","captionFontSize","legacyKenBurns","imageAnimation","mapBlock","center","zoom","mapStyle","markers","staticSrc","mapAnimation","fullBleedQuote","textFontSize","listBlock","items","itemFontSize","startY","spacing","itemText","GAP","photoGrid","images","captionHeight","gridHeight","getGridPositions","altFontSize","img","pos","stacked","halfW","halfH","thirdH","leftW","rightW","definitionCard","term","definition","origin","termFontSize","defFontSize","originFontSize","comparisonBar","leftLabel","leftValue","rightLabel","rightValue","unit","valueFontSize","maxValue","maxBarWidth","leftBarWidth","rightBarWidth","barStartX","barHeight","topBarY","bottomBarY","formatValue","leftDisplay","rightDisplay","pullQuote","backgroundImage","decoFontSize","videoWithCaption","videoSrc","posterSrc","videoAlt","clipStart","clipEnd","sourceDuration","captionPosition","videoCredit","videoLicense","creditFontSize","captionY","videoPullQuote","backgroundVideo","dataTable","headers","rows","align","tableFontSize","coverBlock","heroSrc","heroAlt","heroCredit","heroLicense","startBlockToCoverInput","expandCoverBlock","templateRegistry","expandTemplateBlock","templateBlock","templateFn","err","expandDocBlocks","opts","persistentLayers","audioSegments","bottomLayers","topLayers","currentTime","expandedBlock","useBottom","useTop","blocksBySegment","segmentIndex","expandedBlocks","segmentBlocks","audioSegment","offsetTime","originalIndex","sectionHeaderBlocks","contentBlocks","item","fixedDuration","sum","contentBlockDuration","remainingDuration","scaleFactor","expandedInfos","hasAnySourceTiming","info","aIsHeader","bIsHeader","offsetWithinSegment","sourceStart","scaledDuration","segmentExpandedBlocks","next","currentEnd","MIN_TRANSITION_GAP","segmentEnd","lastBlock","prevBlock","onlyBlock","changed","prev","blockEnd","MAX_BLOCK_DURATION","numParts","partDuration","splitBlock","hasTemplate","getAnimationStyle","animation","_currentTime","getAnimationClassName","getAnimationCSSVars","direction","panDirection","vars","getTransitionClass","entering","flattenBlocks","getLayers","existingLayers","injectPersistentLayers","templateName","templateCtx","resolveValue","dimension","getAnchorOffset","anchor","width","height","MediaContext","R","useMediaProvider","useMediaUrl","relativePath","basePath","isAbsolute","T","needsProvider","url","setUrl","d","cancelled","isStaticChildren","__source","__self","ImageLayer","blockTime","offset","finalX","finalY","animStyle","preserveAspectRatio","getPreserveAspectRatio","isCover","isSpatialAnim","SPATIAL_ANIMATION_TYPES","kbAnim","remapToKenBurns","kbStyle","u","fit","anim","TextLayer","maxWidth","textAnchor","getTextAnchor","dominantBaseline","getDominantBaseline","rawLines","lines","line","wrapText","last","lineHeight","lineHeightPx","textStyles","filterId","getTextBoxWidth","avgCharWidth","charsPerLine","words","currentLine","word","testLine","remaining","ShapeLayer","rawX","rawY","anchorOffset","isCSSGradient","shapeProps","TILE_PROVIDERS","latLngToTile","lat","lng","n","latRad","getPixelOffset","tileSize","xTile","yTile","getTilesForViewport","centerLat","centerLng","viewportWidth","viewportHeight","centerTile","pixelOffset","tilesX","tilesY","startX","centerScreenX","centerScreenY","tiles","dy","dx","tileX","tileY","screenX","screenY","buildTileUrl","z","fetchTileImage","reject","composeMapImage","showAttribution","clampedZoom","canvas","tilePromises","tile","marker","drawMarker","drawAttribution","markerTile","centerOffset","markerOffset","icon","drawStar","cx","cy","spikes","outerRadius","innerRadius","rot","step","padding","MapLayer","mapImageUrl","setMapImageUrl","isLoading","setIsLoading","setError","dataUrl","VideoLayer","_blockTime","isPlaying","videoRef","A","hasStartedRef","resolvedPoster","video","playPromise","handleTimeUpdate","TableLayer","cellAlign","ci","borderRadius","row","ri","cell","VIEWPORT","BlockRenderer","isEntering","isExiting","transitionClass","transitionStyle","clipId","LayerRenderer","TARGET_CHUNK_SIZE","MIN_CHUNK_SIZE","MAX_CHUNK_SIZE","resolvePhraseTiming","w","rawWords","wordDuration","buildWordStream","allWords","chunkSize","numChunks","chunks","chunkWords","SocialCaptionOverlay","enabled","activeChunk","activeWordIndex","chunk","primaryColor","fontFamily","baseFontSize","isActive","CaptionOverlay","captionStyle","captionText","useAudioSync","audioRef","audioTrack","setCurrentTime","setIsPlaying","currentSegment","setCurrentSegment","isEnded","setIsEnded","isAudioReady","setIsAudioReady","totalDuration","setTotalDuration","segmentStarts","pendingSeekTime","shouldPlayAfterLoad","blobUrls","loadingPromises","fallbackMode","seg","start","preloadAudio","q","audioUrl","loadPromise","response","blob","blobUrl","segment","currentBlobUrls","audio","overallTime","handlePlay","handlePause","handleError","handleEnded","applyPendingSeek","segmentStart","segmentTime","currentSrc","cachedBlobUrl","handleCanPlay","play","pause","toggle","seekTo","clampedTime","segEnd","wasPlaying","skipToSegment","restart","lastTime","tick","now","dt","useDocPlayback","script","renderMode","transitionState","setTransitionState","flatBlocks","currentBlock","currentBlockIndex","blockProgress","docProgress","transitionDuration","timer","renderPrevBlockRef","oldPrev","renderTransitionDuration","renderIsEntering","renderIsExiting","goToBlock","targetBlock","nextBlock","getOrientationFromWindow","getViewportForOrientation","useViewportOrientation","windowSize","setWindowSize","handleResize","timeoutId","debouncedResize","formatTime","seconds","mins","secs","DocProgressBar","actions","blockMarkers","getBlockTitle","progressBarRef","hoverPosition","setHoverPosition","handleProgressHover","bar","rect","progress","handleProgressLeave","getBlockAtTimeLocal","blk","hoverTime","slideInfo","DocControlsOverlay","DocControlsSlideshow","slideNav","isFirst","isLast","renderInline","nodes","keyPrefix","k","renderBlock","Tag","renderBlocks","renderListItem","renderTable","isTask","headerRow","bodyRows","MarkdownRenderer","isAnnotatedBlock","annotation","countAll","BlockSection","renderContext","isAnnotated","visualBlock","headingText","bodyText","extractBodyPlainText","getTemplateDefaults","contents","extractListItems","extractTableData","table","LinearDocView","doc","activeViewport","activeTheme","bgColor","textColor","mutedColor","bodyFont","titleFont","lineHt","SMALL_WORDS","buildSegmentTitleMap","segIdx","titled","idx","DocPlayer","autoPlay","onEnded","onTimeUpdate","externalAudioProvider","showControls","showScrubber","muted","captionsEnabledProp","onCaptionsToggle","onPlaybackStateChange","onControlsReady","isFullscreen","onFullscreenToggle","onBlockMarkers","forceViewport","displayMode","isSlideshowMode","isLinearMode","containerRef","tapFeedback","setTapFeedback","tapFeedbackTimer","isDebugMode","internalAudio","isAvailable","unavailableMessage","_skipToSegment","currentTimeRef","totalDurationRef","expandedBlocksLenRef","handleContainerClick","previousBlock","startBlockConfig","coverForced","setCoverForced","coverGraceActive","setCoverGraceActive","coverGraceTimer","coverWasShowing","showCoverBlock","hasAutoPlayed","blockStartTime","elapsedMs","target","blockElapsed","videoSeekPromises","activeBlockEl","el","targetTime","titleMap","defaultMode","captionMode","setCaptionMode","captionsEnabled","activeCaptionStyle","setCaptionsEnabled","cycleCaptionMode","hasCaptions","segmentTitleMap","playbackState","playbackActions","slideNavActions","docBlock","firstLine","textLayer","prevSegment","isSectionStart","handleKeyDown","activeEl","debugPhrase","debugEnabled","doc_animations_default","cssInjected","injectCss","createInlineMediaProvider","inferMimeType","filename","ext","rewriteAudioUrls","audioMap","segments","roots","mount","element","mode","finalDoc","mediaProvider","_","mountStatic","version"],"mappings":"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","file":"squisq-player.global.js","sourcesContent":["/** Normal hydration that attaches to a DOM tree but does not diff it. */\nexport const MODE_HYDRATE = 1 << 5;\n/** Signifies this VNode suspended on the previous render */\nexport const MODE_SUSPENDED = 1 << 7;\n/** Indicates that this node needs to be inserted while patching children */\nexport const INSERT_VNODE = 1 << 2;\n/** Indicates a VNode has been matched with another VNode in the diff */\nexport const MATCHED = 1 << 1;\n\n/** Reset all mode flags */\nexport const RESET_MODE = ~(MODE_HYDRATE | MODE_SUSPENDED);\n\nexport const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\nexport const XHTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';\nexport const MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';\n\nexport const NULL = null;\nexport const UNDEFINED = undefined;\nexport const EMPTY_OBJ = /** @type {any} */ ({});\nexport const EMPTY_ARR = [];\nexport const IS_NON_DIMENSIONAL =\n\t/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;\n","import { EMPTY_ARR } from './constants';\n\nexport const isArray = Array.isArray;\n\n/**\n * Assign properties from `props` to `obj`\n * @template O, P The obj and props types\n * @param {O} obj The object to copy properties to\n * @param {P} props The object to copy properties from\n * @returns {O & P}\n */\nexport function assign(obj, props) {\n\t// @ts-expect-error We change the type of `obj` to be `O & P`\n\tfor (let i in props) obj[i] = props[i];\n\treturn /** @type {O & P} */ (obj);\n}\n\n/**\n * Remove a child node from its parent if attached. This is a workaround for\n * IE11 which doesn't support `Element.prototype.remove()`. Using this function\n * is smaller than including a dedicated polyfill.\n * @param {import('./index').ContainerNode} node The node to remove\n */\nexport function removeNode(node) {\n\tif (node && node.parentNode) node.parentNode.removeChild(node);\n}\n\nexport const slice = EMPTY_ARR.slice;\n","import { _catchError } from './diff/catch-error';\n\n/**\n * The `option` object can potentially contain callback functions\n * that are called during various stages of our renderer. This is the\n * foundation on which all our addons like `preact/debug`, `preact/compat`,\n * and `preact/hooks` are based on. See the `Options` type in `internal.d.ts`\n * for a full list of available option hooks (most editors/IDEs allow you to\n * ctrl+click or cmd+click on mac the type definition below).\n * @type {import('./internal').Options}\n */\nconst options = {\n\t_catchError\n};\n\nexport default options;\n","import { slice } from './util';\nimport options from './options';\nimport { NULL, UNDEFINED } from './constants';\n\nlet vnodeId = 0;\n\n/**\n * Create an virtual node (used for JSX)\n * @param {import('./internal').VNode[\"type\"]} type The node name or Component constructor for this\n * virtual node\n * @param {object | null | undefined} [props] The properties of the virtual node\n * @param {Array<import('.').ComponentChildren>} [children] The children of the\n * virtual node\n * @returns {import('./internal').VNode}\n */\nexport function createElement(type, props, children) {\n\tlet normalizedProps = {},\n\t\tkey,\n\t\tref,\n\t\ti;\n\tfor (i in props) {\n\t\tif (i == 'key') key = props[i];\n\t\telse if (i == 'ref') ref = props[i];\n\t\telse normalizedProps[i] = props[i];\n\t}\n\n\tif (arguments.length > 2) {\n\t\tnormalizedProps.children =\n\t\t\targuments.length > 3 ? slice.call(arguments, 2) : children;\n\t}\n\n\t// If a Component VNode, check for and apply defaultProps\n\t// Note: type may be undefined in development, must never error here.\n\tif (typeof type == 'function' && type.defaultProps != NULL) {\n\t\tfor (i in type.defaultProps) {\n\t\t\tif (normalizedProps[i] === UNDEFINED) {\n\t\t\t\tnormalizedProps[i] = type.defaultProps[i];\n\t\t\t}\n\t\t}\n\t}\n\n\treturn createVNode(type, normalizedProps, key, ref, NULL);\n}\n\n/**\n * Create a VNode (used internally by Preact)\n * @param {import('./internal').VNode[\"type\"]} type The node name or Component\n * Constructor for this virtual node\n * @param {object | string | number | null} props The properties of this virtual node.\n * If this virtual node represents a text node, this is the text of the node (string or number).\n * @param {string | number | null} key The key for this virtual node, used when\n * diffing it against its children\n * @param {import('./internal').VNode[\"ref\"]} ref The ref property that will\n * receive a reference to its created child\n * @returns {import('./internal').VNode}\n */\nexport function createVNode(type, props, key, ref, original) {\n\t// V8 seems to be better at detecting type shapes if the object is allocated from the same call site\n\t// Do not inline into createElement and coerceToVNode!\n\t/** @type {import('./internal').VNode} */\n\tconst vnode = {\n\t\ttype,\n\t\tprops,\n\t\tkey,\n\t\tref,\n\t\t_children: NULL,\n\t\t_parent: NULL,\n\t\t_depth: 0,\n\t\t_dom: NULL,\n\t\t_component: NULL,\n\t\tconstructor: UNDEFINED,\n\t\t_original: original == NULL ? ++vnodeId : original,\n\t\t_index: -1,\n\t\t_flags: 0\n\t};\n\n\t// Only invoke the vnode hook if this was *not* a direct copy:\n\tif (original == NULL && options.vnode != NULL) options.vnode(vnode);\n\n\treturn vnode;\n}\n\nexport function createRef() {\n\treturn { current: NULL };\n}\n\nexport function Fragment(props) {\n\treturn props.children;\n}\n\n/**\n * Check if a the argument is a valid Preact VNode.\n * @param {*} vnode\n * @returns {vnode is VNode}\n */\nexport const isValidElement = vnode =>\n\tvnode != NULL && vnode.constructor === UNDEFINED;\n","import { assign } from './util';\nimport { diff, commitRoot } from './diff/index';\nimport options from './options';\nimport { Fragment } from './create-element';\nimport { MODE_HYDRATE, NULL } from './constants';\n\n/**\n * Base Component class. Provides `setState()` and `forceUpdate()`, which\n * trigger rendering\n * @param {object} props The initial component props\n * @param {object} context The initial context from parent components'\n * getChildContext\n */\nexport function BaseComponent(props, context) {\n\tthis.props = props;\n\tthis.context = context;\n}\n\n/**\n * Update component state and schedule a re-render.\n * @this {import('./internal').Component}\n * @param {object | ((s: object, p: object) => object)} update A hash of state\n * properties to update with new values or a function that given the current\n * state and props returns a new partial state\n * @param {() => void} [callback] A function to be called once component state is\n * updated\n */\nBaseComponent.prototype.setState = function (update, callback) {\n\t// only clone state when copying to nextState the first time.\n\tlet s;\n\tif (this._nextState != NULL && this._nextState != this.state) {\n\t\ts = this._nextState;\n\t} else {\n\t\ts = this._nextState = assign({}, this.state);\n\t}\n\n\tif (typeof update == 'function') {\n\t\t// Some libraries like `immer` mark the current state as readonly,\n\t\t// preventing us from mutating it, so we need to clone it. See #2716\n\t\tupdate = update(assign({}, s), this.props);\n\t}\n\n\tif (update) {\n\t\tassign(s, update);\n\t}\n\n\t// Skip update if updater function returned null\n\tif (update == NULL) return;\n\n\tif (this._vnode) {\n\t\tif (callback) {\n\t\t\tthis._stateCallbacks.push(callback);\n\t\t}\n\t\tenqueueRender(this);\n\t}\n};\n\n/**\n * Immediately perform a synchronous re-render of the component\n * @this {import('./internal').Component}\n * @param {() => void} [callback] A function to be called after component is\n * re-rendered\n */\nBaseComponent.prototype.forceUpdate = function (callback) {\n\tif (this._vnode) {\n\t\t// Set render mode so that we can differentiate where the render request\n\t\t// is coming from. We need this because forceUpdate should never call\n\t\t// shouldComponentUpdate\n\t\tthis._force = true;\n\t\tif (callback) this._renderCallbacks.push(callback);\n\t\tenqueueRender(this);\n\t}\n};\n\n/**\n * Accepts `props` and `state`, and returns a new Virtual DOM tree to build.\n * Virtual DOM is generally constructed via [JSX](https://jasonformat.com/wtf-is-jsx).\n * @param {object} props Props (eg: JSX attributes) received from parent\n * element/component\n * @param {object} state The component's current state\n * @param {object} context Context object, as returned by the nearest\n * ancestor's `getChildContext()`\n * @returns {ComponentChildren | void}\n */\nBaseComponent.prototype.render = Fragment;\n\n/**\n * @param {import('./internal').VNode} vnode\n * @param {number | null} [childIndex]\n */\nexport function getDomSibling(vnode, childIndex) {\n\tif (childIndex == NULL) {\n\t\t// Use childIndex==null as a signal to resume the search from the vnode's sibling\n\t\treturn vnode._parent\n\t\t\t? getDomSibling(vnode._parent, vnode._index + 1)\n\t\t\t: NULL;\n\t}\n\n\tlet sibling;\n\tfor (; childIndex < vnode._children.length; childIndex++) {\n\t\tsibling = vnode._children[childIndex];\n\n\t\tif (sibling != NULL && sibling._dom != NULL) {\n\t\t\t// Since updateParentDomPointers keeps _dom pointer correct,\n\t\t\t// we can rely on _dom to tell us if this subtree contains a\n\t\t\t// rendered DOM node, and what the first rendered DOM node is\n\t\t\treturn sibling._dom;\n\t\t}\n\t}\n\n\t// If we get here, we have not found a DOM node in this vnode's children.\n\t// We must resume from this vnode's sibling (in it's parent _children array)\n\t// Only climb up and search the parent if we aren't searching through a DOM\n\t// VNode (meaning we reached the DOM parent of the original vnode that began\n\t// the search)\n\treturn typeof vnode.type == 'function' ? getDomSibling(vnode) : NULL;\n}\n\n/**\n * Trigger in-place re-rendering of a component.\n * @param {import('./internal').Component} component The component to rerender\n */\nfunction renderComponent(component) {\n\tif (component._parentDom && component._dirty) {\n\t\tlet oldVNode = component._vnode,\n\t\t\toldDom = oldVNode._dom,\n\t\t\tcommitQueue = [],\n\t\t\trefQueue = [],\n\t\t\tnewVNode = assign({}, oldVNode);\n\t\tnewVNode._original = oldVNode._original + 1;\n\t\tif (options.vnode) options.vnode(newVNode);\n\n\t\tdiff(\n\t\t\tcomponent._parentDom,\n\t\t\tnewVNode,\n\t\t\toldVNode,\n\t\t\tcomponent._globalContext,\n\t\t\tcomponent._parentDom.namespaceURI,\n\t\t\toldVNode._flags & MODE_HYDRATE ? [oldDom] : NULL,\n\t\t\tcommitQueue,\n\t\t\toldDom == NULL ? getDomSibling(oldVNode) : oldDom,\n\t\t\t!!(oldVNode._flags & MODE_HYDRATE),\n\t\t\trefQueue\n\t\t);\n\n\t\tnewVNode._original = oldVNode._original;\n\t\tnewVNode._parent._children[newVNode._index] = newVNode;\n\t\tcommitRoot(commitQueue, newVNode, refQueue);\n\t\toldVNode._dom = oldVNode._parent = null;\n\n\t\tif (newVNode._dom != oldDom) {\n\t\t\tupdateParentDomPointers(newVNode);\n\t\t}\n\t}\n}\n\n/**\n * @param {import('./internal').VNode} vnode\n */\nfunction updateParentDomPointers(vnode) {\n\tif ((vnode = vnode._parent) != NULL && vnode._component != NULL) {\n\t\tvnode._dom = vnode._component.base = NULL;\n\t\tvnode._children.some(child => {\n\t\t\tif (child != NULL && child._dom != NULL) {\n\t\t\t\treturn (vnode._dom = vnode._component.base = child._dom);\n\t\t\t}\n\t\t});\n\n\t\treturn updateParentDomPointers(vnode);\n\t}\n}\n\n/**\n * The render queue\n * @type {Array<import('./internal').Component>}\n */\nlet rerenderQueue = [];\n\n/*\n * The value of `Component.debounce` must asynchronously invoke the passed in callback. It is\n * important that contributors to Preact can consistently reason about what calls to `setState`, etc.\n * do, and when their effects will be applied. See the links below for some further reading on designing\n * asynchronous APIs.\n * * [Designing APIs for Asynchrony](https://blog.izs.me/2013/08/designing-apis-for-asynchrony)\n * * [Callbacks synchronous and asynchronous](https://blog.ometer.com/2011/07/24/callbacks-synchronous-and-asynchronous/)\n */\n\nlet prevDebounce;\n\nconst defer =\n\ttypeof Promise == 'function'\n\t\t? Promise.prototype.then.bind(Promise.resolve())\n\t\t: setTimeout;\n\n/**\n * Enqueue a rerender of a component\n * @param {import('./internal').Component} c The component to rerender\n */\nexport function enqueueRender(c) {\n\tif (\n\t\t(!c._dirty &&\n\t\t\t(c._dirty = true) &&\n\t\t\trerenderQueue.push(c) &&\n\t\t\t!process._rerenderCount++) ||\n\t\tprevDebounce != options.debounceRendering\n\t) {\n\t\tprevDebounce = options.debounceRendering;\n\t\t(prevDebounce || defer)(process);\n\t}\n}\n\n/**\n * @param {import('./internal').Component} a\n * @param {import('./internal').Component} b\n */\nconst depthSort = (a, b) => a._vnode._depth - b._vnode._depth;\n\n/** Flush the render queue by rerendering all queued components */\nfunction process() {\n\ttry {\n\t\tlet c,\n\t\t\tl = 1;\n\n\t\t// Don't update `renderCount` yet. Keep its value non-zero to prevent unnecessary\n\t\t// process() calls from getting scheduled while `queue` is still being consumed.\n\t\twhile (rerenderQueue.length) {\n\t\t\t// Keep the rerender queue sorted by (depth, insertion order). The queue\n\t\t\t// will initially be sorted on the first iteration only if it has more than 1 item.\n\t\t\t//\n\t\t\t// New items can be added to the queue e.g. when rerendering a provider, so we want to\n\t\t\t// keep the order from top to bottom with those new items so we can handle them in a\n\t\t\t// single pass\n\t\t\tif (rerenderQueue.length > l) {\n\t\t\t\trerenderQueue.sort(depthSort);\n\t\t\t}\n\n\t\t\tc = rerenderQueue.shift();\n\t\t\tl = rerenderQueue.length;\n\n\t\t\trenderComponent(c);\n\t\t}\n\t} finally {\n\t\trerenderQueue.length = process._rerenderCount = 0;\n\t}\n}\n\nprocess._rerenderCount = 0;\n","import { IS_NON_DIMENSIONAL, NULL, SVG_NAMESPACE } from '../constants';\nimport options from '../options';\n\nfunction setStyle(style, key, value) {\n\tif (key[0] == '-') {\n\t\tstyle.setProperty(key, value == NULL ? '' : value);\n\t} else if (value == NULL) {\n\t\tstyle[key] = '';\n\t} else if (typeof value != 'number' || IS_NON_DIMENSIONAL.test(key)) {\n\t\tstyle[key] = value;\n\t} else {\n\t\tstyle[key] = value + 'px';\n\t}\n}\n\nconst CAPTURE_REGEX = /(PointerCapture)$|Capture$/i;\n\n// A logical clock to solve issues like https://github.com/preactjs/preact/issues/3927.\n// When the DOM performs an event it leaves micro-ticks in between bubbling up which means that\n// an event can trigger on a newly reated DOM-node while the event bubbles up.\n//\n// Originally inspired by Vue\n// (https://github.com/vuejs/core/blob/caeb8a68811a1b0f79/packages/runtime-dom/src/modules/events.ts#L90-L101),\n// but modified to use a logical clock instead of Date.now() in case event handlers get attached\n// and events get dispatched during the same millisecond.\n//\n// The clock is incremented after each new event dispatch. This allows 1 000 000 new events\n// per second for over 280 years before the value reaches Number.MAX_SAFE_INTEGER (2**53 - 1).\nlet eventClock = 0;\n\n/**\n * Set a property value on a DOM node\n * @param {import('../internal').PreactElement} dom The DOM node to modify\n * @param {string} name The name of the property to set\n * @param {*} value The value to set the property to\n * @param {*} oldValue The old value the property had\n * @param {string} namespace Whether or not this DOM node is an SVG node or not\n */\nexport function setProperty(dom, name, value, oldValue, namespace) {\n\tlet useCapture;\n\n\to: if (name == 'style') {\n\t\tif (typeof value == 'string') {\n\t\t\tdom.style.cssText = value;\n\t\t} else {\n\t\t\tif (typeof oldValue == 'string') {\n\t\t\t\tdom.style.cssText = oldValue = '';\n\t\t\t}\n\n\t\t\tif (oldValue) {\n\t\t\t\tfor (name in oldValue) {\n\t\t\t\t\tif (!(value && name in value)) {\n\t\t\t\t\t\tsetStyle(dom.style, name, '');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (value) {\n\t\t\t\tfor (name in value) {\n\t\t\t\t\tif (!oldValue || value[name] != oldValue[name]) {\n\t\t\t\t\t\tsetStyle(dom.style, name, value[name]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t// Benchmark for comparison: https://esbench.com/bench/574c954bdb965b9a00965ac6\n\telse if (name[0] == 'o' && name[1] == 'n') {\n\t\tuseCapture = name != (name = name.replace(CAPTURE_REGEX, '$1'));\n\t\tconst lowerCaseName = name.toLowerCase();\n\n\t\t// Infer correct casing for DOM built-in events:\n\t\tif (lowerCaseName in dom || name == 'onFocusOut' || name == 'onFocusIn')\n\t\t\tname = lowerCaseName.slice(2);\n\t\telse name = name.slice(2);\n\n\t\tif (!dom._listeners) dom._listeners = {};\n\t\tdom._listeners[name + useCapture] = value;\n\n\t\tif (value) {\n\t\t\tif (!oldValue) {\n\t\t\t\tvalue._attached = eventClock;\n\t\t\t\tdom.addEventListener(\n\t\t\t\t\tname,\n\t\t\t\t\tuseCapture ? eventProxyCapture : eventProxy,\n\t\t\t\t\tuseCapture\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tvalue._attached = oldValue._attached;\n\t\t\t}\n\t\t} else {\n\t\t\tdom.removeEventListener(\n\t\t\t\tname,\n\t\t\t\tuseCapture ? eventProxyCapture : eventProxy,\n\t\t\t\tuseCapture\n\t\t\t);\n\t\t}\n\t} else {\n\t\tif (namespace == SVG_NAMESPACE) {\n\t\t\t// Normalize incorrect prop usage for SVG:\n\t\t\t// - xlink:href / xlinkHref --> href (xlink:href was removed from SVG and isn't needed)\n\t\t\t// - className --> class\n\t\t\tname = name.replace(/xlink(H|:h)/, 'h').replace(/sName$/, 's');\n\t\t} else if (\n\t\t\tname != 'width' &&\n\t\t\tname != 'height' &&\n\t\t\tname != 'href' &&\n\t\t\tname != 'list' &&\n\t\t\tname != 'form' &&\n\t\t\t// Default value in browsers is `-1` and an empty string is\n\t\t\t// cast to `0` instead\n\t\t\tname != 'tabIndex' &&\n\t\t\tname != 'download' &&\n\t\t\tname != 'rowSpan' &&\n\t\t\tname != 'colSpan' &&\n\t\t\tname != 'role' &&\n\t\t\tname != 'popover' &&\n\t\t\tname in dom\n\t\t) {\n\t\t\ttry {\n\t\t\t\tdom[name] = value == NULL ? '' : value;\n\t\t\t\t// labelled break is 1b smaller here than a return statement (sorry)\n\t\t\t\tbreak o;\n\t\t\t} catch (e) {}\n\t\t}\n\n\t\t// aria- and data- attributes have no boolean representation.\n\t\t// A `false` value is different from the attribute not being\n\t\t// present, so we can't remove it. For non-boolean aria\n\t\t// attributes we could treat false as a removal, but the\n\t\t// amount of exceptions would cost too many bytes. On top of\n\t\t// that other frameworks generally stringify `false`.\n\n\t\tif (typeof value == 'function') {\n\t\t\t// never serialize functions as attribute values\n\t\t} else if (value != NULL && (value !== false || name[4] == '-')) {\n\t\t\tdom.setAttribute(name, name == 'popover' && value == true ? '' : value);\n\t\t} else {\n\t\t\tdom.removeAttribute(name);\n\t\t}\n\t}\n}\n\n/**\n * Create an event proxy function.\n * @param {boolean} useCapture Is the event handler for the capture phase.\n * @private\n */\nfunction createEventProxy(useCapture) {\n\t/**\n\t * Proxy an event to hooked event handlers\n\t * @param {import('../internal').PreactEvent} e The event object from the browser\n\t * @private\n\t */\n\treturn function (e) {\n\t\tif (this._listeners) {\n\t\t\tconst eventHandler = this._listeners[e.type + useCapture];\n\t\t\tif (e._dispatched == NULL) {\n\t\t\t\te._dispatched = eventClock++;\n\n\t\t\t\t// When `e._dispatched` is smaller than the time when the targeted event\n\t\t\t\t// handler was attached we know we have bubbled up to an element that was added\n\t\t\t\t// during patching the DOM.\n\t\t\t} else if (e._dispatched < eventHandler._attached) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\treturn eventHandler(options.event ? options.event(e) : e);\n\t\t}\n\t};\n}\n\nconst eventProxy = createEventProxy(false);\nconst eventProxyCapture = createEventProxy(true);\n","import { enqueueRender } from './component';\nimport { NULL } from './constants';\n\nexport let i = 0;\n\nexport function createContext(defaultValue) {\n\tfunction Context(props) {\n\t\tif (!this.getChildContext) {\n\t\t\t/** @type {Set<import('./internal').Component> | null} */\n\t\t\tlet subs = new Set();\n\t\t\tlet ctx = {};\n\t\t\tctx[Context._id] = this;\n\n\t\t\tthis.getChildContext = () => ctx;\n\n\t\t\tthis.componentWillUnmount = () => {\n\t\t\t\tsubs = NULL;\n\t\t\t};\n\n\t\t\tthis.shouldComponentUpdate = function (_props) {\n\t\t\t\t// @ts-expect-error even\n\t\t\t\tif (this.props.value != _props.value) {\n\t\t\t\t\tsubs.forEach(c => {\n\t\t\t\t\t\tc._force = true;\n\t\t\t\t\t\tenqueueRender(c);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tthis.sub = c => {\n\t\t\t\tsubs.add(c);\n\t\t\t\tlet old = c.componentWillUnmount;\n\t\t\t\tc.componentWillUnmount = () => {\n\t\t\t\t\tif (subs) {\n\t\t\t\t\t\tsubs.delete(c);\n\t\t\t\t\t}\n\t\t\t\t\tif (old) old.call(c);\n\t\t\t\t};\n\t\t\t};\n\t\t}\n\n\t\treturn props.children;\n\t}\n\n\tContext._id = '__cC' + i++;\n\tContext._defaultValue = defaultValue;\n\n\t/** @type {import('./internal').FunctionComponent} */\n\tContext.Consumer = (props, contextValue) => {\n\t\treturn props.children(contextValue);\n\t};\n\n\t// we could also get rid of _contextRef entirely\n\tContext.Provider =\n\t\tContext._contextRef =\n\t\tContext.Consumer.contextType =\n\t\t\tContext;\n\n\treturn Context;\n}\n","import { diff, unmount, applyRef } from './index';\nimport { createVNode, Fragment } from '../create-element';\nimport {\n\tEMPTY_OBJ,\n\tEMPTY_ARR,\n\tINSERT_VNODE,\n\tMATCHED,\n\tUNDEFINED,\n\tNULL\n} from '../constants';\nimport { isArray } from '../util';\nimport { getDomSibling } from '../component';\n\n/**\n * @typedef {import('../internal').ComponentChildren} ComponentChildren\n * @typedef {import('../internal').Component} Component\n * @typedef {import('../internal').PreactElement} PreactElement\n * @typedef {import('../internal').VNode} VNode\n */\n\n/**\n * Diff the children of a virtual node\n * @param {PreactElement} parentDom The DOM element whose children are being\n * diffed\n * @param {ComponentChildren[]} renderResult\n * @param {VNode} newParentVNode The new virtual node whose children should be\n * diff'ed against oldParentVNode\n * @param {VNode} oldParentVNode The old virtual node whose children should be\n * diff'ed against newParentVNode\n * @param {object} globalContext The current context object - modified by\n * getChildContext\n * @param {string} namespace Current namespace of the DOM node (HTML, SVG, or MathML)\n * @param {Array<PreactElement>} excessDomChildren\n * @param {Array<Component>} commitQueue List of components which have callbacks\n * to invoke in commitRoot\n * @param {PreactElement} oldDom The current attached DOM element any new dom\n * elements should be placed around. Likely `null` on first render (except when\n * hydrating). Can be a sibling DOM element when diffing Fragments that have\n * siblings. In most cases, it starts out as `oldChildren[0]._dom`.\n * @param {boolean} isHydrating Whether or not we are in hydration\n * @param {any[]} refQueue an array of elements needed to invoke refs\n */\nexport function diffChildren(\n\tparentDom,\n\trenderResult,\n\tnewParentVNode,\n\toldParentVNode,\n\tglobalContext,\n\tnamespace,\n\texcessDomChildren,\n\tcommitQueue,\n\toldDom,\n\tisHydrating,\n\trefQueue\n) {\n\tlet i,\n\t\t/** @type {VNode} */\n\t\toldVNode,\n\t\t/** @type {VNode} */\n\t\tchildVNode,\n\t\t/** @type {PreactElement} */\n\t\tnewDom,\n\t\t/** @type {PreactElement} */\n\t\tfirstChildDom;\n\n\t// This is a compression of oldParentVNode!=null && oldParentVNode != EMPTY_OBJ && oldParentVNode._children || EMPTY_ARR\n\t// as EMPTY_OBJ._children should be `undefined`.\n\t/** @type {VNode[]} */\n\tlet oldChildren = (oldParentVNode && oldParentVNode._children) || EMPTY_ARR;\n\n\tlet newChildrenLength = renderResult.length;\n\n\toldDom = constructNewChildrenArray(\n\t\tnewParentVNode,\n\t\trenderResult,\n\t\toldChildren,\n\t\toldDom,\n\t\tnewChildrenLength\n\t);\n\n\tfor (i = 0; i < newChildrenLength; i++) {\n\t\tchildVNode = newParentVNode._children[i];\n\t\tif (childVNode == NULL) continue;\n\n\t\t// At this point, constructNewChildrenArray has assigned _index to be the\n\t\t// matchingIndex for this VNode's oldVNode (or -1 if there is no oldVNode).\n\t\toldVNode =\n\t\t\t(childVNode._index != -1 && oldChildren[childVNode._index]) || EMPTY_OBJ;\n\n\t\t// Update childVNode._index to its final index\n\t\tchildVNode._index = i;\n\n\t\t// Morph the old element into the new one, but don't append it to the dom yet\n\t\tlet result = diff(\n\t\t\tparentDom,\n\t\t\tchildVNode,\n\t\t\toldVNode,\n\t\t\tglobalContext,\n\t\t\tnamespace,\n\t\t\texcessDomChildren,\n\t\t\tcommitQueue,\n\t\t\toldDom,\n\t\t\tisHydrating,\n\t\t\trefQueue\n\t\t);\n\n\t\t// Adjust DOM nodes\n\t\tnewDom = childVNode._dom;\n\t\tif (childVNode.ref && oldVNode.ref != childVNode.ref) {\n\t\t\tif (oldVNode.ref) {\n\t\t\t\tapplyRef(oldVNode.ref, NULL, childVNode);\n\t\t\t}\n\t\t\trefQueue.push(\n\t\t\t\tchildVNode.ref,\n\t\t\t\tchildVNode._component || newDom,\n\t\t\t\tchildVNode\n\t\t\t);\n\t\t}\n\n\t\tif (firstChildDom == NULL && newDom != NULL) {\n\t\t\tfirstChildDom = newDom;\n\t\t}\n\n\t\tlet shouldPlace = !!(childVNode._flags & INSERT_VNODE);\n\t\tif (shouldPlace || oldVNode._children === childVNode._children) {\n\t\t\toldDom = insert(childVNode, oldDom, parentDom, shouldPlace);\n\t\t} else if (typeof childVNode.type == 'function' && result !== UNDEFINED) {\n\t\t\toldDom = result;\n\t\t} else if (newDom) {\n\t\t\toldDom = newDom.nextSibling;\n\t\t}\n\n\t\t// Unset diffing flags\n\t\tchildVNode._flags &= ~(INSERT_VNODE | MATCHED);\n\t}\n\n\tnewParentVNode._dom = firstChildDom;\n\n\treturn oldDom;\n}\n\n/**\n * @param {VNode} newParentVNode\n * @param {ComponentChildren[]} renderResult\n * @param {VNode[]} oldChildren\n */\nfunction constructNewChildrenArray(\n\tnewParentVNode,\n\trenderResult,\n\toldChildren,\n\toldDom,\n\tnewChildrenLength\n) {\n\t/** @type {number} */\n\tlet i;\n\t/** @type {VNode} */\n\tlet childVNode;\n\t/** @type {VNode} */\n\tlet oldVNode;\n\n\tlet oldChildrenLength = oldChildren.length,\n\t\tremainingOldChildren = oldChildrenLength;\n\n\tlet skew = 0;\n\n\tnewParentVNode._children = new Array(newChildrenLength);\n\tfor (i = 0; i < newChildrenLength; i++) {\n\t\t// @ts-expect-error We are reusing the childVNode variable to hold both the\n\t\t// pre and post normalized childVNode\n\t\tchildVNode = renderResult[i];\n\n\t\tif (\n\t\t\tchildVNode == NULL ||\n\t\t\ttypeof childVNode == 'boolean' ||\n\t\t\ttypeof childVNode == 'function'\n\t\t) {\n\t\t\tnewParentVNode._children[i] = NULL;\n\t\t\tcontinue;\n\t\t}\n\t\t// If this newVNode is being reused (e.g. <div>{reuse}{reuse}</div>) in the same diff,\n\t\t// or we are rendering a component (e.g. setState) copy the oldVNodes so it can have\n\t\t// it's own DOM & etc. pointers\n\t\telse if (\n\t\t\ttypeof childVNode == 'string' ||\n\t\t\ttypeof childVNode == 'number' ||\n\t\t\t// eslint-disable-next-line valid-typeof\n\t\t\ttypeof childVNode == 'bigint' ||\n\t\t\tchildVNode.constructor == String\n\t\t) {\n\t\t\tchildVNode = newParentVNode._children[i] = createVNode(\n\t\t\t\tNULL,\n\t\t\t\tchildVNode,\n\t\t\t\tNULL,\n\t\t\t\tNULL,\n\t\t\t\tNULL\n\t\t\t);\n\t\t} else if (isArray(childVNode)) {\n\t\t\tchildVNode = newParentVNode._children[i] = createVNode(\n\t\t\t\tFragment,\n\t\t\t\t{ children: childVNode },\n\t\t\t\tNULL,\n\t\t\t\tNULL,\n\t\t\t\tNULL\n\t\t\t);\n\t\t} else if (childVNode.constructor === UNDEFINED && childVNode._depth > 0) {\n\t\t\t// VNode is already in use, clone it. This can happen in the following\n\t\t\t// scenario:\n\t\t\t// const reuse = <div />\n\t\t\t// <div>{reuse}<span />{reuse}</div>\n\t\t\tchildVNode = newParentVNode._children[i] = createVNode(\n\t\t\t\tchildVNode.type,\n\t\t\t\tchildVNode.props,\n\t\t\t\tchildVNode.key,\n\t\t\t\tchildVNode.ref ? childVNode.ref : NULL,\n\t\t\t\tchildVNode._original\n\t\t\t);\n\t\t} else {\n\t\t\tnewParentVNode._children[i] = childVNode;\n\t\t}\n\n\t\tconst skewedIndex = i + skew;\n\t\tchildVNode._parent = newParentVNode;\n\t\tchildVNode._depth = newParentVNode._depth + 1;\n\n\t\t// Temporarily store the matchingIndex on the _index property so we can pull\n\t\t// out the oldVNode in diffChildren. We'll override this to the VNode's\n\t\t// final index after using this property to get the oldVNode\n\t\tconst matchingIndex = (childVNode._index = findMatchingIndex(\n\t\t\tchildVNode,\n\t\t\toldChildren,\n\t\t\tskewedIndex,\n\t\t\tremainingOldChildren\n\t\t));\n\n\t\toldVNode = NULL;\n\t\tif (matchingIndex != -1) {\n\t\t\toldVNode = oldChildren[matchingIndex];\n\t\t\tremainingOldChildren--;\n\t\t\tif (oldVNode) {\n\t\t\t\toldVNode._flags |= MATCHED;\n\t\t\t}\n\t\t}\n\n\t\t// Here, we define isMounting for the purposes of the skew diffing\n\t\t// algorithm. Nodes that are unsuspending are considered mounting and we detect\n\t\t// this by checking if oldVNode._original == null\n\t\tconst isMounting = oldVNode == NULL || oldVNode._original == NULL;\n\n\t\tif (isMounting) {\n\t\t\tif (matchingIndex == -1) {\n\t\t\t\t// When the array of children is growing we need to decrease the skew\n\t\t\t\t// as we are adding a new element to the array.\n\t\t\t\t// Example:\n\t\t\t\t// [1, 2, 3] --> [0, 1, 2, 3]\n\t\t\t\t// oldChildren newChildren\n\t\t\t\t//\n\t\t\t\t// The new element is at index 0, so our skew is 0,\n\t\t\t\t// we need to decrease the skew as we are adding a new element.\n\t\t\t\t// The decrease will cause us to compare the element at position 1\n\t\t\t\t// with value 1 with the element at position 0 with value 0.\n\t\t\t\t//\n\t\t\t\t// A linear concept is applied when the array is shrinking,\n\t\t\t\t// if the length is unchanged we can assume that no skew\n\t\t\t\t// changes are needed.\n\t\t\t\tif (newChildrenLength > oldChildrenLength) {\n\t\t\t\t\tskew--;\n\t\t\t\t} else if (newChildrenLength < oldChildrenLength) {\n\t\t\t\t\tskew++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If we are mounting a DOM VNode, mark it for insertion\n\t\t\tif (typeof childVNode.type != 'function') {\n\t\t\t\tchildVNode._flags |= INSERT_VNODE;\n\t\t\t}\n\t\t} else if (matchingIndex != skewedIndex) {\n\t\t\t// When we move elements around i.e. [0, 1, 2] --> [1, 0, 2]\n\t\t\t// --> we diff 1, we find it at position 1 while our skewed index is 0 and our skew is 0\n\t\t\t// we set the skew to 1 as we found an offset.\n\t\t\t// --> we diff 0, we find it at position 0 while our skewed index is at 2 and our skew is 1\n\t\t\t// this makes us increase the skew again.\n\t\t\t// --> we diff 2, we find it at position 2 while our skewed index is at 4 and our skew is 2\n\t\t\t//\n\t\t\t// this becomes an optimization question where currently we see a 1 element offset as an insertion\n\t\t\t// or deletion i.e. we optimize for [0, 1, 2] --> [9, 0, 1, 2]\n\t\t\t// while a more than 1 offset we see as a swap.\n\t\t\t// We could probably build heuristics for having an optimized course of action here as well, but\n\t\t\t// might go at the cost of some bytes.\n\t\t\t//\n\t\t\t// If we wanted to optimize for i.e. only swaps we'd just do the last two code-branches and have\n\t\t\t// only the first item be a re-scouting and all the others fall in their skewed counter-part.\n\t\t\t// We could also further optimize for swaps\n\t\t\tif (matchingIndex == skewedIndex - 1) {\n\t\t\t\tskew--;\n\t\t\t} else if (matchingIndex == skewedIndex + 1) {\n\t\t\t\tskew++;\n\t\t\t} else {\n\t\t\t\tif (matchingIndex > skewedIndex) {\n\t\t\t\t\tskew--;\n\t\t\t\t} else {\n\t\t\t\t\tskew++;\n\t\t\t\t}\n\n\t\t\t\t// Move this VNode's DOM if the original index (matchingIndex) doesn't\n\t\t\t\t// match the new skew index (i + new skew)\n\t\t\t\t// In the former two branches we know that it matches after skewing\n\t\t\t\tchildVNode._flags |= INSERT_VNODE;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Remove remaining oldChildren if there are any. Loop forwards so that as we\n\t// unmount DOM from the beginning of the oldChildren, we can adjust oldDom to\n\t// point to the next child, which needs to be the first DOM node that won't be\n\t// unmounted.\n\tif (remainingOldChildren) {\n\t\tfor (i = 0; i < oldChildrenLength; i++) {\n\t\t\toldVNode = oldChildren[i];\n\t\t\tif (oldVNode != NULL && (oldVNode._flags & MATCHED) == 0) {\n\t\t\t\tif (oldVNode._dom == oldDom) {\n\t\t\t\t\toldDom = getDomSibling(oldVNode);\n\t\t\t\t}\n\n\t\t\t\tunmount(oldVNode, oldVNode);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn oldDom;\n}\n\n/**\n * @param {VNode} parentVNode\n * @param {PreactElement} oldDom\n * @param {PreactElement} parentDom\n * @param {boolean} shouldPlace\n * @returns {PreactElement}\n */\nfunction insert(parentVNode, oldDom, parentDom, shouldPlace) {\n\t// Note: VNodes in nested suspended trees may be missing _children.\n\n\tif (typeof parentVNode.type == 'function') {\n\t\tlet children = parentVNode._children;\n\t\tfor (let i = 0; children && i < children.length; i++) {\n\t\t\tif (children[i]) {\n\t\t\t\t// If we enter this code path on sCU bailout, where we copy\n\t\t\t\t// oldVNode._children to newVNode._children, we need to update the old\n\t\t\t\t// children's _parent pointer to point to the newVNode (parentVNode\n\t\t\t\t// here).\n\t\t\t\tchildren[i]._parent = parentVNode;\n\t\t\t\toldDom = insert(children[i], oldDom, parentDom, shouldPlace);\n\t\t\t}\n\t\t}\n\n\t\treturn oldDom;\n\t} else if (parentVNode._dom != oldDom) {\n\t\tif (shouldPlace) {\n\t\t\tif (oldDom && parentVNode.type && !oldDom.parentNode) {\n\t\t\t\toldDom = getDomSibling(parentVNode);\n\t\t\t}\n\t\t\tparentDom.insertBefore(parentVNode._dom, oldDom || NULL);\n\t\t}\n\t\toldDom = parentVNode._dom;\n\t}\n\n\tdo {\n\t\toldDom = oldDom && oldDom.nextSibling;\n\t} while (oldDom != NULL && oldDom.nodeType == 8);\n\n\treturn oldDom;\n}\n\n/**\n * Flatten and loop through the children of a virtual node\n * @param {ComponentChildren} children The unflattened children of a virtual\n * node\n * @returns {VNode[]}\n */\nexport function toChildArray(children, out) {\n\tout = out || [];\n\tif (children == NULL || typeof children == 'boolean') {\n\t} else if (isArray(children)) {\n\t\tchildren.some(child => {\n\t\t\ttoChildArray(child, out);\n\t\t});\n\t} else {\n\t\tout.push(children);\n\t}\n\treturn out;\n}\n\n/**\n * @param {VNode} childVNode\n * @param {VNode[]} oldChildren\n * @param {number} skewedIndex\n * @param {number} remainingOldChildren\n * @returns {number}\n */\nfunction findMatchingIndex(\n\tchildVNode,\n\toldChildren,\n\tskewedIndex,\n\tremainingOldChildren\n) {\n\tconst key = childVNode.key;\n\tconst type = childVNode.type;\n\tlet oldVNode = oldChildren[skewedIndex];\n\tconst matched = oldVNode != NULL && (oldVNode._flags & MATCHED) == 0;\n\n\t// We only need to perform a search if there are more children\n\t// (remainingOldChildren) to search. However, if the oldVNode we just looked\n\t// at skewedIndex was not already used in this diff, then there must be at\n\t// least 1 other (so greater than 1) remainingOldChildren to attempt to match\n\t// against. So the following condition checks that ensuring\n\t// remainingOldChildren > 1 if the oldVNode is not already used/matched. Else\n\t// if the oldVNode was null or matched, then there could needs to be at least\n\t// 1 (aka `remainingOldChildren > 0`) children to find and compare against.\n\t//\n\t// If there is an unkeyed functional VNode, that isn't a built-in like our Fragment,\n\t// we should not search as we risk re-using state of an unrelated VNode. (reverted for now)\n\tlet shouldSearch =\n\t\t// (typeof type != 'function' || type === Fragment || key) &&\n\t\tremainingOldChildren > (matched ? 1 : 0);\n\n\tif (\n\t\t(oldVNode === NULL && key == null) ||\n\t\t(matched && key == oldVNode.key && type == oldVNode.type)\n\t) {\n\t\treturn skewedIndex;\n\t} else if (shouldSearch) {\n\t\tlet x = skewedIndex - 1;\n\t\tlet y = skewedIndex + 1;\n\t\twhile (x >= 0 || y < oldChildren.length) {\n\t\t\tconst childIndex = x >= 0 ? x-- : y++;\n\t\t\toldVNode = oldChildren[childIndex];\n\t\t\tif (\n\t\t\t\toldVNode != NULL &&\n\t\t\t\t(oldVNode._flags & MATCHED) == 0 &&\n\t\t\t\tkey == oldVNode.key &&\n\t\t\t\ttype == oldVNode.type\n\t\t\t) {\n\t\t\t\treturn childIndex;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn -1;\n}\n","import {\n\tEMPTY_ARR,\n\tEMPTY_OBJ,\n\tMATH_NAMESPACE,\n\tMODE_HYDRATE,\n\tMODE_SUSPENDED,\n\tNULL,\n\tRESET_MODE,\n\tSVG_NAMESPACE,\n\tUNDEFINED,\n\tXHTML_NAMESPACE\n} from '../constants';\nimport { BaseComponent, getDomSibling } from '../component';\nimport { Fragment } from '../create-element';\nimport { diffChildren } from './children';\nimport { setProperty } from './props';\nimport { assign, isArray, removeNode, slice } from '../util';\nimport options from '../options';\n\n/**\n * @typedef {import('../internal').ComponentChildren} ComponentChildren\n * @typedef {import('../internal').Component} Component\n * @typedef {import('../internal').PreactElement} PreactElement\n * @typedef {import('../internal').VNode} VNode\n */\n\n/**\n * @template {any} T\n * @typedef {import('../internal').Ref<T>} Ref<T>\n */\n\n/**\n * Diff two virtual nodes and apply proper changes to the DOM\n * @param {PreactElement} parentDom The parent of the DOM element\n * @param {VNode} newVNode The new virtual node\n * @param {VNode} oldVNode The old virtual node\n * @param {object} globalContext The current context object. Modified by\n * getChildContext\n * @param {string} namespace Current namespace of the DOM node (HTML, SVG, or MathML)\n * @param {Array<PreactElement>} excessDomChildren\n * @param {Array<Component>} commitQueue List of components which have callbacks\n * to invoke in commitRoot\n * @param {PreactElement} oldDom The current attached DOM element any new dom\n * elements should be placed around. Likely `null` on first render (except when\n * hydrating). Can be a sibling DOM element when diffing Fragments that have\n * siblings. In most cases, it starts out as `oldChildren[0]._dom`.\n * @param {boolean} isHydrating Whether or not we are in hydration\n * @param {any[]} refQueue an array of elements needed to invoke refs\n */\nexport function diff(\n\tparentDom,\n\tnewVNode,\n\toldVNode,\n\tglobalContext,\n\tnamespace,\n\texcessDomChildren,\n\tcommitQueue,\n\toldDom,\n\tisHydrating,\n\trefQueue\n) {\n\t/** @type {any} */\n\tlet tmp,\n\t\tnewType = newVNode.type;\n\n\t// When passing through createElement it assigns the object\n\t// constructor as undefined. This to prevent JSON-injection.\n\tif (newVNode.constructor !== UNDEFINED) return NULL;\n\n\t// If the previous diff bailed out, resume creating/hydrating.\n\tif (oldVNode._flags & MODE_SUSPENDED) {\n\t\tisHydrating = !!(oldVNode._flags & MODE_HYDRATE);\n\t\toldDom = newVNode._dom = oldVNode._dom;\n\t\texcessDomChildren = [oldDom];\n\t}\n\n\tif ((tmp = options._diff)) tmp(newVNode);\n\n\touter: if (typeof newType == 'function') {\n\t\ttry {\n\t\t\tlet c, isNew, oldProps, oldState, snapshot, clearProcessingException;\n\t\t\tlet newProps = newVNode.props;\n\t\t\tconst isClassComponent = newType.prototype && newType.prototype.render;\n\n\t\t\t// Necessary for createContext api. Setting this property will pass\n\t\t\t// the context value as `this.context` just for this component.\n\t\t\ttmp = newType.contextType;\n\t\t\tlet provider = tmp && globalContext[tmp._id];\n\t\t\tlet componentContext = tmp\n\t\t\t\t? provider\n\t\t\t\t\t? provider.props.value\n\t\t\t\t\t: tmp._defaultValue\n\t\t\t\t: globalContext;\n\n\t\t\t// Get component and set it to `c`\n\t\t\tif (oldVNode._component) {\n\t\t\t\tc = newVNode._component = oldVNode._component;\n\t\t\t\tclearProcessingException = c._processingException = c._pendingError;\n\t\t\t} else {\n\t\t\t\t// Instantiate the new component\n\t\t\t\tif (isClassComponent) {\n\t\t\t\t\t// @ts-expect-error The check above verifies that newType is suppose to be constructed\n\t\t\t\t\tnewVNode._component = c = new newType(newProps, componentContext); // eslint-disable-line new-cap\n\t\t\t\t} else {\n\t\t\t\t\t// @ts-expect-error Trust me, Component implements the interface we want\n\t\t\t\t\tnewVNode._component = c = new BaseComponent(\n\t\t\t\t\t\tnewProps,\n\t\t\t\t\t\tcomponentContext\n\t\t\t\t\t);\n\t\t\t\t\tc.constructor = newType;\n\t\t\t\t\tc.render = doRender;\n\t\t\t\t}\n\t\t\t\tif (provider) provider.sub(c);\n\n\t\t\t\tif (!c.state) c.state = {};\n\t\t\t\tc._globalContext = globalContext;\n\t\t\t\tisNew = c._dirty = true;\n\t\t\t\tc._renderCallbacks = [];\n\t\t\t\tc._stateCallbacks = [];\n\t\t\t}\n\n\t\t\t// Invoke getDerivedStateFromProps\n\t\t\tif (isClassComponent && c._nextState == NULL) {\n\t\t\t\tc._nextState = c.state;\n\t\t\t}\n\n\t\t\tif (isClassComponent && newType.getDerivedStateFromProps != NULL) {\n\t\t\t\tif (c._nextState == c.state) {\n\t\t\t\t\tc._nextState = assign({}, c._nextState);\n\t\t\t\t}\n\n\t\t\t\tassign(\n\t\t\t\t\tc._nextState,\n\t\t\t\t\tnewType.getDerivedStateFromProps(newProps, c._nextState)\n\t\t\t\t);\n\t\t\t}\n\n\t\t\toldProps = c.props;\n\t\t\toldState = c.state;\n\t\t\tc._vnode = newVNode;\n\n\t\t\t// Invoke pre-render lifecycle methods\n\t\t\tif (isNew) {\n\t\t\t\tif (\n\t\t\t\t\tisClassComponent &&\n\t\t\t\t\tnewType.getDerivedStateFromProps == NULL &&\n\t\t\t\t\tc.componentWillMount != NULL\n\t\t\t\t) {\n\t\t\t\t\tc.componentWillMount();\n\t\t\t\t}\n\n\t\t\t\tif (isClassComponent && c.componentDidMount != NULL) {\n\t\t\t\t\tc._renderCallbacks.push(c.componentDidMount);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (\n\t\t\t\t\tisClassComponent &&\n\t\t\t\t\tnewType.getDerivedStateFromProps == NULL &&\n\t\t\t\t\tnewProps !== oldProps &&\n\t\t\t\t\tc.componentWillReceiveProps != NULL\n\t\t\t\t) {\n\t\t\t\t\tc.componentWillReceiveProps(newProps, componentContext);\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\tnewVNode._original == oldVNode._original ||\n\t\t\t\t\t(!c._force &&\n\t\t\t\t\t\tc.shouldComponentUpdate != NULL &&\n\t\t\t\t\t\tc.shouldComponentUpdate(\n\t\t\t\t\t\t\tnewProps,\n\t\t\t\t\t\t\tc._nextState,\n\t\t\t\t\t\t\tcomponentContext\n\t\t\t\t\t\t) === false)\n\t\t\t\t) {\n\t\t\t\t\t// More info about this here: https://gist.github.com/JoviDeCroock/bec5f2ce93544d2e6070ef8e0036e4e8\n\t\t\t\t\tif (newVNode._original != oldVNode._original) {\n\t\t\t\t\t\t// When we are dealing with a bail because of sCU we have to update\n\t\t\t\t\t\t// the props, state and dirty-state.\n\t\t\t\t\t\t// when we are dealing with strict-equality we don't as the child could still\n\t\t\t\t\t\t// be dirtied see #3883\n\t\t\t\t\t\tc.props = newProps;\n\t\t\t\t\t\tc.state = c._nextState;\n\t\t\t\t\t\tc._dirty = false;\n\t\t\t\t\t}\n\n\t\t\t\t\tnewVNode._dom = oldVNode._dom;\n\t\t\t\t\tnewVNode._children = oldVNode._children;\n\t\t\t\t\tnewVNode._children.some(vnode => {\n\t\t\t\t\t\tif (vnode) vnode._parent = newVNode;\n\t\t\t\t\t});\n\n\t\t\t\t\tEMPTY_ARR.push.apply(c._renderCallbacks, c._stateCallbacks);\n\t\t\t\t\tc._stateCallbacks = [];\n\n\t\t\t\t\tif (c._renderCallbacks.length) {\n\t\t\t\t\t\tcommitQueue.push(c);\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak outer;\n\t\t\t\t}\n\n\t\t\t\tif (c.componentWillUpdate != NULL) {\n\t\t\t\t\tc.componentWillUpdate(newProps, c._nextState, componentContext);\n\t\t\t\t}\n\n\t\t\t\tif (isClassComponent && c.componentDidUpdate != NULL) {\n\t\t\t\t\tc._renderCallbacks.push(() => {\n\t\t\t\t\t\tc.componentDidUpdate(oldProps, oldState, snapshot);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tc.context = componentContext;\n\t\t\tc.props = newProps;\n\t\t\tc._parentDom = parentDom;\n\t\t\tc._force = false;\n\n\t\t\tlet renderHook = options._render,\n\t\t\t\tcount = 0;\n\t\t\tif (isClassComponent) {\n\t\t\t\tc.state = c._nextState;\n\t\t\t\tc._dirty = false;\n\n\t\t\t\tif (renderHook) renderHook(newVNode);\n\n\t\t\t\ttmp = c.render(c.props, c.state, c.context);\n\n\t\t\t\tEMPTY_ARR.push.apply(c._renderCallbacks, c._stateCallbacks);\n\t\t\t\tc._stateCallbacks = [];\n\t\t\t} else {\n\t\t\t\tdo {\n\t\t\t\t\tc._dirty = false;\n\t\t\t\t\tif (renderHook) renderHook(newVNode);\n\n\t\t\t\t\ttmp = c.render(c.props, c.state, c.context);\n\n\t\t\t\t\t// Handle setState called in render, see #2553\n\t\t\t\t\tc.state = c._nextState;\n\t\t\t\t} while (c._dirty && ++count < 25);\n\t\t\t}\n\n\t\t\t// Handle setState called in render, see #2553\n\t\t\tc.state = c._nextState;\n\n\t\t\tif (c.getChildContext != NULL) {\n\t\t\t\tglobalContext = assign(assign({}, globalContext), c.getChildContext());\n\t\t\t}\n\n\t\t\tif (isClassComponent && !isNew && c.getSnapshotBeforeUpdate != NULL) {\n\t\t\t\tsnapshot = c.getSnapshotBeforeUpdate(oldProps, oldState);\n\t\t\t}\n\n\t\t\tlet renderResult =\n\t\t\t\ttmp != NULL && tmp.type === Fragment && tmp.key == NULL\n\t\t\t\t\t? cloneNode(tmp.props.children)\n\t\t\t\t\t: tmp;\n\n\t\t\toldDom = diffChildren(\n\t\t\t\tparentDom,\n\t\t\t\tisArray(renderResult) ? renderResult : [renderResult],\n\t\t\t\tnewVNode,\n\t\t\t\toldVNode,\n\t\t\t\tglobalContext,\n\t\t\t\tnamespace,\n\t\t\t\texcessDomChildren,\n\t\t\t\tcommitQueue,\n\t\t\t\toldDom,\n\t\t\t\tisHydrating,\n\t\t\t\trefQueue\n\t\t\t);\n\n\t\t\tc.base = newVNode._dom;\n\n\t\t\t// We successfully rendered this VNode, unset any stored hydration/bailout state:\n\t\t\tnewVNode._flags &= RESET_MODE;\n\n\t\t\tif (c._renderCallbacks.length) {\n\t\t\t\tcommitQueue.push(c);\n\t\t\t}\n\n\t\t\tif (clearProcessingException) {\n\t\t\t\tc._pendingError = c._processingException = NULL;\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tnewVNode._original = NULL;\n\t\t\t// if hydrating or creating initial tree, bailout preserves DOM:\n\t\t\tif (isHydrating || excessDomChildren != NULL) {\n\t\t\t\tif (e.then) {\n\t\t\t\t\tnewVNode._flags |= isHydrating\n\t\t\t\t\t\t? MODE_HYDRATE | MODE_SUSPENDED\n\t\t\t\t\t\t: MODE_SUSPENDED;\n\n\t\t\t\t\twhile (oldDom && oldDom.nodeType == 8 && oldDom.nextSibling) {\n\t\t\t\t\t\toldDom = oldDom.nextSibling;\n\t\t\t\t\t}\n\n\t\t\t\t\texcessDomChildren[excessDomChildren.indexOf(oldDom)] = NULL;\n\t\t\t\t\tnewVNode._dom = oldDom;\n\t\t\t\t} else {\n\t\t\t\t\tfor (let i = excessDomChildren.length; i--; ) {\n\t\t\t\t\t\tremoveNode(excessDomChildren[i]);\n\t\t\t\t\t}\n\t\t\t\t\tmarkAsForce(newVNode);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tnewVNode._dom = oldVNode._dom;\n\t\t\t\tnewVNode._children = oldVNode._children;\n\t\t\t\tif (!e.then) markAsForce(newVNode);\n\t\t\t}\n\t\t\toptions._catchError(e, newVNode, oldVNode);\n\t\t}\n\t} else if (\n\t\texcessDomChildren == NULL &&\n\t\tnewVNode._original == oldVNode._original\n\t) {\n\t\tnewVNode._children = oldVNode._children;\n\t\tnewVNode._dom = oldVNode._dom;\n\t} else {\n\t\toldDom = newVNode._dom = diffElementNodes(\n\t\t\toldVNode._dom,\n\t\t\tnewVNode,\n\t\t\toldVNode,\n\t\t\tglobalContext,\n\t\t\tnamespace,\n\t\t\texcessDomChildren,\n\t\t\tcommitQueue,\n\t\t\tisHydrating,\n\t\t\trefQueue\n\t\t);\n\t}\n\n\tif ((tmp = options.diffed)) tmp(newVNode);\n\n\treturn newVNode._flags & MODE_SUSPENDED ? undefined : oldDom;\n}\n\nfunction markAsForce(vnode) {\n\tif (vnode) {\n\t\tif (vnode._component) vnode._component._force = true;\n\t\tif (vnode._children) vnode._children.some(markAsForce);\n\t}\n}\n\n/**\n * @param {Array<Component>} commitQueue List of components\n * which have callbacks to invoke in commitRoot\n * @param {VNode} root\n */\nexport function commitRoot(commitQueue, root, refQueue) {\n\tfor (let i = 0; i < refQueue.length; i++) {\n\t\tapplyRef(refQueue[i], refQueue[++i], refQueue[++i]);\n\t}\n\n\tif (options._commit) options._commit(root, commitQueue);\n\n\tcommitQueue.some(c => {\n\t\ttry {\n\t\t\t// @ts-expect-error Reuse the commitQueue variable here so the type changes\n\t\t\tcommitQueue = c._renderCallbacks;\n\t\t\tc._renderCallbacks = [];\n\t\t\tcommitQueue.some(cb => {\n\t\t\t\t// @ts-expect-error See above comment on commitQueue\n\t\t\t\tcb.call(c);\n\t\t\t});\n\t\t} catch (e) {\n\t\t\toptions._catchError(e, c._vnode);\n\t\t}\n\t});\n}\n\nfunction cloneNode(node) {\n\tif (typeof node != 'object' || node == NULL || node._depth > 0) {\n\t\treturn node;\n\t}\n\n\tif (isArray(node)) {\n\t\treturn node.map(cloneNode);\n\t}\n\n\treturn assign({}, node);\n}\n\n/**\n * Diff two virtual nodes representing DOM element\n * @param {PreactElement} dom The DOM element representing the virtual nodes\n * being diffed\n * @param {VNode} newVNode The new virtual node\n * @param {VNode} oldVNode The old virtual node\n * @param {object} globalContext The current context object\n * @param {string} namespace Current namespace of the DOM node (HTML, SVG, or MathML)\n * @param {Array<PreactElement>} excessDomChildren\n * @param {Array<Component>} commitQueue List of components which have callbacks\n * to invoke in commitRoot\n * @param {boolean} isHydrating Whether or not we are in hydration\n * @param {any[]} refQueue an array of elements needed to invoke refs\n * @returns {PreactElement}\n */\nfunction diffElementNodes(\n\tdom,\n\tnewVNode,\n\toldVNode,\n\tglobalContext,\n\tnamespace,\n\texcessDomChildren,\n\tcommitQueue,\n\tisHydrating,\n\trefQueue\n) {\n\tlet oldProps = oldVNode.props || EMPTY_OBJ;\n\tlet newProps = newVNode.props;\n\tlet nodeType = /** @type {string} */ (newVNode.type);\n\t/** @type {any} */\n\tlet i;\n\t/** @type {{ __html?: string }} */\n\tlet newHtml;\n\t/** @type {{ __html?: string }} */\n\tlet oldHtml;\n\t/** @type {ComponentChildren} */\n\tlet newChildren;\n\tlet value;\n\tlet inputValue;\n\tlet checked;\n\n\t// Tracks entering and exiting namespaces when descending through the tree.\n\tif (nodeType == 'svg') namespace = SVG_NAMESPACE;\n\telse if (nodeType == 'math') namespace = MATH_NAMESPACE;\n\telse if (!namespace) namespace = XHTML_NAMESPACE;\n\n\tif (excessDomChildren != NULL) {\n\t\tfor (i = 0; i < excessDomChildren.length; i++) {\n\t\t\tvalue = excessDomChildren[i];\n\n\t\t\t// if newVNode matches an element in excessDomChildren or the `dom`\n\t\t\t// argument matches an element in excessDomChildren, remove it from\n\t\t\t// excessDomChildren so it isn't later removed in diffChildren\n\t\t\tif (\n\t\t\t\tvalue &&\n\t\t\t\t'setAttribute' in value == !!nodeType &&\n\t\t\t\t(nodeType ? value.localName == nodeType : value.nodeType == 3)\n\t\t\t) {\n\t\t\t\tdom = value;\n\t\t\t\texcessDomChildren[i] = NULL;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (dom == NULL) {\n\t\tif (nodeType == NULL) {\n\t\t\treturn document.createTextNode(newProps);\n\t\t}\n\n\t\tdom = document.createElementNS(\n\t\t\tnamespace,\n\t\t\tnodeType,\n\t\t\tnewProps.is && newProps\n\t\t);\n\n\t\t// we are creating a new node, so we can assume this is a new subtree (in\n\t\t// case we are hydrating), this deopts the hydrate\n\t\tif (isHydrating) {\n\t\t\tif (options._hydrationMismatch)\n\t\t\t\toptions._hydrationMismatch(newVNode, excessDomChildren);\n\t\t\tisHydrating = false;\n\t\t}\n\t\t// we created a new parent, so none of the previously attached children can be reused:\n\t\texcessDomChildren = NULL;\n\t}\n\n\tif (nodeType == NULL) {\n\t\t// During hydration, we still have to split merged text from SSR'd HTML.\n\t\tif (oldProps !== newProps && (!isHydrating || dom.data != newProps)) {\n\t\t\tdom.data = newProps;\n\t\t}\n\t} else {\n\t\t// If excessDomChildren was not null, repopulate it with the current element's children:\n\t\texcessDomChildren = excessDomChildren && slice.call(dom.childNodes);\n\n\t\t// If we are in a situation where we are not hydrating but are using\n\t\t// existing DOM (e.g. replaceNode) we should read the existing DOM\n\t\t// attributes to diff them\n\t\tif (!isHydrating && excessDomChildren != NULL) {\n\t\t\toldProps = {};\n\t\t\tfor (i = 0; i < dom.attributes.length; i++) {\n\t\t\t\tvalue = dom.attributes[i];\n\t\t\t\toldProps[value.name] = value.value;\n\t\t\t}\n\t\t}\n\n\t\tfor (i in oldProps) {\n\t\t\tvalue = oldProps[i];\n\t\t\tif (i == 'dangerouslySetInnerHTML') {\n\t\t\t\toldHtml = value;\n\t\t\t} else if (\n\t\t\t\ti != 'children' &&\n\t\t\t\t!(i in newProps) &&\n\t\t\t\t!(i == 'value' && 'defaultValue' in newProps) &&\n\t\t\t\t!(i == 'checked' && 'defaultChecked' in newProps)\n\t\t\t) {\n\t\t\t\tsetProperty(dom, i, NULL, value, namespace);\n\t\t\t}\n\t\t}\n\n\t\t// During hydration, props are not diffed at all (including dangerouslySetInnerHTML)\n\t\t// @TODO we should warn in debug mode when props don't match here.\n\t\tfor (i in newProps) {\n\t\t\tvalue = newProps[i];\n\t\t\tif (i == 'children') {\n\t\t\t\tnewChildren = value;\n\t\t\t} else if (i == 'dangerouslySetInnerHTML') {\n\t\t\t\tnewHtml = value;\n\t\t\t} else if (i == 'value') {\n\t\t\t\tinputValue = value;\n\t\t\t} else if (i == 'checked') {\n\t\t\t\tchecked = value;\n\t\t\t} else if (\n\t\t\t\t(!isHydrating || typeof value == 'function') &&\n\t\t\t\toldProps[i] !== value\n\t\t\t) {\n\t\t\t\tsetProperty(dom, i, value, oldProps[i], namespace);\n\t\t\t}\n\t\t}\n\n\t\t// If the new vnode didn't have dangerouslySetInnerHTML, diff its children\n\t\tif (newHtml) {\n\t\t\t// Avoid re-applying the same '__html' if it did not changed between re-render\n\t\t\tif (\n\t\t\t\t!isHydrating &&\n\t\t\t\t(!oldHtml ||\n\t\t\t\t\t(newHtml.__html != oldHtml.__html && newHtml.__html != dom.innerHTML))\n\t\t\t) {\n\t\t\t\tdom.innerHTML = newHtml.__html;\n\t\t\t}\n\n\t\t\tnewVNode._children = [];\n\t\t} else {\n\t\t\tif (oldHtml) dom.innerHTML = '';\n\n\t\t\tdiffChildren(\n\t\t\t\t// @ts-expect-error\n\t\t\t\tnewVNode.type == 'template' ? dom.content : dom,\n\t\t\t\tisArray(newChildren) ? newChildren : [newChildren],\n\t\t\t\tnewVNode,\n\t\t\t\toldVNode,\n\t\t\t\tglobalContext,\n\t\t\t\tnodeType == 'foreignObject' ? XHTML_NAMESPACE : namespace,\n\t\t\t\texcessDomChildren,\n\t\t\t\tcommitQueue,\n\t\t\t\texcessDomChildren\n\t\t\t\t\t? excessDomChildren[0]\n\t\t\t\t\t: oldVNode._children && getDomSibling(oldVNode, 0),\n\t\t\t\tisHydrating,\n\t\t\t\trefQueue\n\t\t\t);\n\n\t\t\t// Remove children that are not part of any vnode.\n\t\t\tif (excessDomChildren != NULL) {\n\t\t\t\tfor (i = excessDomChildren.length; i--; ) {\n\t\t\t\t\tremoveNode(excessDomChildren[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// As above, don't diff props during hydration\n\t\tif (!isHydrating) {\n\t\t\ti = 'value';\n\t\t\tif (nodeType == 'progress' && inputValue == NULL) {\n\t\t\t\tdom.removeAttribute('value');\n\t\t\t} else if (\n\t\t\t\tinputValue != UNDEFINED &&\n\t\t\t\t// #2756 For the <progress>-element the initial value is 0,\n\t\t\t\t// despite the attribute not being present. When the attribute\n\t\t\t\t// is missing the progress bar is treated as indeterminate.\n\t\t\t\t// To fix that we'll always update it when it is 0 for progress elements\n\t\t\t\t(inputValue !== dom[i] ||\n\t\t\t\t\t(nodeType == 'progress' && !inputValue) ||\n\t\t\t\t\t// This is only for IE 11 to fix <select> value not being updated.\n\t\t\t\t\t// To avoid a stale select value we need to set the option.value\n\t\t\t\t\t// again, which triggers IE11 to re-evaluate the select value\n\t\t\t\t\t(nodeType == 'option' && inputValue != oldProps[i]))\n\t\t\t) {\n\t\t\t\tsetProperty(dom, i, inputValue, oldProps[i], namespace);\n\t\t\t}\n\n\t\t\ti = 'checked';\n\t\t\tif (checked != UNDEFINED && checked != dom[i]) {\n\t\t\t\tsetProperty(dom, i, checked, oldProps[i], namespace);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn dom;\n}\n\n/**\n * Invoke or update a ref, depending on whether it is a function or object ref.\n * @param {Ref<any> & { _unmount?: unknown }} ref\n * @param {any} value\n * @param {VNode} vnode\n */\nexport function applyRef(ref, value, vnode) {\n\ttry {\n\t\tif (typeof ref == 'function') {\n\t\t\tlet hasRefUnmount = typeof ref._unmount == 'function';\n\t\t\tif (hasRefUnmount) {\n\t\t\t\t// @ts-ignore TS doesn't like moving narrowing checks into variables\n\t\t\t\tref._unmount();\n\t\t\t}\n\n\t\t\tif (!hasRefUnmount || value != NULL) {\n\t\t\t\t// Store the cleanup function on the function\n\t\t\t\t// instance object itself to avoid shape\n\t\t\t\t// transitioning vnode\n\t\t\t\tref._unmount = ref(value);\n\t\t\t}\n\t\t} else ref.current = value;\n\t} catch (e) {\n\t\toptions._catchError(e, vnode);\n\t}\n}\n\n/**\n * Unmount a virtual node from the tree and apply DOM changes\n * @param {VNode} vnode The virtual node to unmount\n * @param {VNode} parentVNode The parent of the VNode that initiated the unmount\n * @param {boolean} [skipRemove] Flag that indicates that a parent node of the\n * current element is already detached from the DOM.\n */\nexport function unmount(vnode, parentVNode, skipRemove) {\n\tlet r;\n\tif (options.unmount) options.unmount(vnode);\n\n\tif ((r = vnode.ref)) {\n\t\tif (!r.current || r.current == vnode._dom) {\n\t\t\tapplyRef(r, NULL, parentVNode);\n\t\t}\n\t}\n\n\tif ((r = vnode._component) != NULL) {\n\t\tif (r.componentWillUnmount) {\n\t\t\ttry {\n\t\t\t\tr.componentWillUnmount();\n\t\t\t} catch (e) {\n\t\t\t\toptions._catchError(e, parentVNode);\n\t\t\t}\n\t\t}\n\n\t\tr.base = r._parentDom = NULL;\n\t}\n\n\tif ((r = vnode._children)) {\n\t\tfor (let i = 0; i < r.length; i++) {\n\t\t\tif (r[i]) {\n\t\t\t\tunmount(\n\t\t\t\t\tr[i],\n\t\t\t\t\tparentVNode,\n\t\t\t\t\tskipRemove || typeof vnode.type != 'function'\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!skipRemove) {\n\t\tremoveNode(vnode._dom);\n\t}\n\n\tvnode._component = vnode._parent = vnode._dom = UNDEFINED;\n}\n\n/** The `.render()` method for a PFC backing instance. */\nfunction doRender(props, state, context) {\n\treturn this.constructor(props, context);\n}\n","import { EMPTY_OBJ, NULL } from './constants';\nimport { commitRoot, diff } from './diff/index';\nimport { createElement, Fragment } from './create-element';\nimport options from './options';\nimport { slice } from './util';\n\n/**\n * Render a Preact virtual node into a DOM element\n * @param {import('./internal').ComponentChild} vnode The virtual node to render\n * @param {import('./internal').PreactElement} parentDom The DOM element to render into\n * @param {import('./internal').PreactElement | object} [replaceNode] Optional: Attempt to re-use an\n * existing DOM tree rooted at `replaceNode`\n */\nexport function render(vnode, parentDom, replaceNode) {\n\t// https://github.com/preactjs/preact/issues/3794\n\tif (parentDom == document) {\n\t\tparentDom = document.documentElement;\n\t}\n\n\tif (options._root) options._root(vnode, parentDom);\n\n\t// We abuse the `replaceNode` parameter in `hydrate()` to signal if we are in\n\t// hydration mode or not by passing the `hydrate` function instead of a DOM\n\t// element..\n\tlet isHydrating = typeof replaceNode == 'function';\n\n\t// To be able to support calling `render()` multiple times on the same\n\t// DOM node, we need to obtain a reference to the previous tree. We do\n\t// this by assigning a new `_children` property to DOM nodes which points\n\t// to the last rendered tree. By default this property is not present, which\n\t// means that we are mounting a new tree for the first time.\n\tlet oldVNode = isHydrating\n\t\t? NULL\n\t\t: (replaceNode && replaceNode._children) || parentDom._children;\n\n\tvnode = ((!isHydrating && replaceNode) || parentDom)._children =\n\t\tcreateElement(Fragment, NULL, [vnode]);\n\n\t// List of effects that need to be called after diffing.\n\tlet commitQueue = [],\n\t\trefQueue = [];\n\tdiff(\n\t\tparentDom,\n\t\t// Determine the new vnode tree and store it on the DOM element on\n\t\t// our custom `_children` property.\n\t\tvnode,\n\t\toldVNode || EMPTY_OBJ,\n\t\tEMPTY_OBJ,\n\t\tparentDom.namespaceURI,\n\t\t!isHydrating && replaceNode\n\t\t\t? [replaceNode]\n\t\t\t: oldVNode\n\t\t\t\t? NULL\n\t\t\t\t: parentDom.firstChild\n\t\t\t\t\t? slice.call(parentDom.childNodes)\n\t\t\t\t\t: NULL,\n\t\tcommitQueue,\n\t\t!isHydrating && replaceNode\n\t\t\t? replaceNode\n\t\t\t: oldVNode\n\t\t\t\t? oldVNode._dom\n\t\t\t\t: parentDom.firstChild,\n\t\tisHydrating,\n\t\trefQueue\n\t);\n\n\t// Flush all queued effects\n\tcommitRoot(commitQueue, vnode, refQueue);\n}\n\n/**\n * Update an existing DOM element with data from a Preact virtual node\n * @param {import('./internal').ComponentChild} vnode The virtual node to render\n * @param {import('./internal').PreactElement} parentDom The DOM element to update\n */\nexport function hydrate(vnode, parentDom) {\n\trender(vnode, parentDom, hydrate);\n}\n","import { NULL } from '../constants';\n\n/**\n * Find the closest error boundary to a thrown error and call it\n * @param {object} error The thrown value\n * @param {import('../internal').VNode} vnode The vnode that threw the error that was caught (except\n * for unmounting when this parameter is the highest parent that was being\n * unmounted)\n * @param {import('../internal').VNode} [oldVNode]\n * @param {import('../internal').ErrorInfo} [errorInfo]\n */\nexport function _catchError(error, vnode, oldVNode, errorInfo) {\n\t/** @type {import('../internal').Component} */\n\tlet component,\n\t\t/** @type {import('../internal').ComponentType} */\n\t\tctor,\n\t\t/** @type {boolean} */\n\t\thandled;\n\n\tfor (; (vnode = vnode._parent); ) {\n\t\tif ((component = vnode._component) && !component._processingException) {\n\t\t\ttry {\n\t\t\t\tctor = component.constructor;\n\n\t\t\t\tif (ctor && ctor.getDerivedStateFromError != NULL) {\n\t\t\t\t\tcomponent.setState(ctor.getDerivedStateFromError(error));\n\t\t\t\t\thandled = component._dirty;\n\t\t\t\t}\n\n\t\t\t\tif (component.componentDidCatch != NULL) {\n\t\t\t\t\tcomponent.componentDidCatch(error, errorInfo || {});\n\t\t\t\t\thandled = component._dirty;\n\t\t\t\t}\n\n\t\t\t\t// This is an error boundary. Mark it as having bailed out, and whether it was mid-hydration.\n\t\t\t\tif (handled) {\n\t\t\t\t\treturn (component._pendingError = component);\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\terror = e;\n\t\t\t}\n\t\t}\n\t}\n\n\tthrow error;\n}\n","import { options as _options } from 'preact';\n\n/** @type {number} */\nlet currentIndex;\n\n/** @type {import('./internal').Component} */\nlet currentComponent;\n\n/** @type {import('./internal').Component} */\nlet previousComponent;\n\n/** @type {number} */\nlet currentHook = 0;\n\n/** @type {Array<import('./internal').Component>} */\nlet afterPaintEffects = [];\n\n// Cast to use internal Options type\nconst options = /** @type {import('./internal').Options} */ (_options);\n\nlet oldBeforeDiff = options._diff;\nlet oldBeforeRender = options._render;\nlet oldAfterDiff = options.diffed;\nlet oldCommit = options._commit;\nlet oldBeforeUnmount = options.unmount;\nlet oldRoot = options._root;\n\n// We take the minimum timeout for requestAnimationFrame to ensure that\n// the callback is invoked after the next frame. 35ms is based on a 30hz\n// refresh rate, which is the minimum rate for a smooth user experience.\nconst RAF_TIMEOUT = 35;\nlet prevRaf;\n\n/** @type {(vnode: import('./internal').VNode) => void} */\noptions._diff = vnode => {\n\tcurrentComponent = null;\n\tif (oldBeforeDiff) oldBeforeDiff(vnode);\n};\n\noptions._root = (vnode, parentDom) => {\n\tif (vnode && parentDom._children && parentDom._children._mask) {\n\t\tvnode._mask = parentDom._children._mask;\n\t}\n\n\tif (oldRoot) oldRoot(vnode, parentDom);\n};\n\n/** @type {(vnode: import('./internal').VNode) => void} */\noptions._render = vnode => {\n\tif (oldBeforeRender) oldBeforeRender(vnode);\n\n\tcurrentComponent = vnode._component;\n\tcurrentIndex = 0;\n\n\tconst hooks = currentComponent.__hooks;\n\tif (hooks) {\n\t\tif (previousComponent === currentComponent) {\n\t\t\thooks._pendingEffects = [];\n\t\t\tcurrentComponent._renderCallbacks = [];\n\t\t\thooks._list.some(hookItem => {\n\t\t\t\tif (hookItem._nextValue) {\n\t\t\t\t\thookItem._value = hookItem._nextValue;\n\t\t\t\t}\n\t\t\t\thookItem._pendingArgs = hookItem._nextValue = undefined;\n\t\t\t});\n\t\t} else {\n\t\t\thooks._pendingEffects.some(invokeCleanup);\n\t\t\thooks._pendingEffects.some(invokeEffect);\n\t\t\thooks._pendingEffects = [];\n\t\t\tcurrentIndex = 0;\n\t\t}\n\t}\n\tpreviousComponent = currentComponent;\n};\n\n/** @type {(vnode: import('./internal').VNode) => void} */\noptions.diffed = vnode => {\n\tif (oldAfterDiff) oldAfterDiff(vnode);\n\n\tconst c = vnode._component;\n\tif (c && c.__hooks) {\n\t\tif (c.__hooks._pendingEffects.length) afterPaint(afterPaintEffects.push(c));\n\t\tc.__hooks._list.some(hookItem => {\n\t\t\tif (hookItem._pendingArgs) {\n\t\t\t\thookItem._args = hookItem._pendingArgs;\n\t\t\t}\n\t\t\thookItem._pendingArgs = undefined;\n\t\t});\n\t}\n\tpreviousComponent = currentComponent = null;\n};\n\n// TODO: Improve typing of commitQueue parameter\n/** @type {(vnode: import('./internal').VNode, commitQueue: any) => void} */\noptions._commit = (vnode, commitQueue) => {\n\tcommitQueue.some(component => {\n\t\ttry {\n\t\t\tcomponent._renderCallbacks.some(invokeCleanup);\n\t\t\tcomponent._renderCallbacks = component._renderCallbacks.filter(cb =>\n\t\t\t\tcb._value ? invokeEffect(cb) : true\n\t\t\t);\n\t\t} catch (e) {\n\t\t\tcommitQueue.some(c => {\n\t\t\t\tif (c._renderCallbacks) c._renderCallbacks = [];\n\t\t\t});\n\t\t\tcommitQueue = [];\n\t\t\toptions._catchError(e, component._vnode);\n\t\t}\n\t});\n\n\tif (oldCommit) oldCommit(vnode, commitQueue);\n};\n\n/** @type {(vnode: import('./internal').VNode) => void} */\noptions.unmount = vnode => {\n\tif (oldBeforeUnmount) oldBeforeUnmount(vnode);\n\n\tconst c = vnode._component;\n\tif (c && c.__hooks) {\n\t\tlet hasErrored;\n\t\tc.__hooks._list.some(s => {\n\t\t\ttry {\n\t\t\t\tinvokeCleanup(s);\n\t\t\t} catch (e) {\n\t\t\t\thasErrored = e;\n\t\t\t}\n\t\t});\n\t\tc.__hooks = undefined;\n\t\tif (hasErrored) options._catchError(hasErrored, c._vnode);\n\t}\n};\n\n/**\n * Get a hook's state from the currentComponent\n * @param {number} index The index of the hook to get\n * @param {number} type The index of the hook to get\n * @returns {any}\n */\nfunction getHookState(index, type) {\n\tif (options._hook) {\n\t\toptions._hook(currentComponent, index, currentHook || type);\n\t}\n\tcurrentHook = 0;\n\n\t// Largely inspired by:\n\t// * https://github.com/michael-klein/funcy.js/blob/f6be73468e6ec46b0ff5aa3cc4c9baf72a29025a/src/hooks/core_hooks.mjs\n\t// * https://github.com/michael-klein/funcy.js/blob/650beaa58c43c33a74820a3c98b3c7079cf2e333/src/renderer.mjs\n\t// Other implementations to look at:\n\t// * https://codesandbox.io/s/mnox05qp8\n\tconst hooks =\n\t\tcurrentComponent.__hooks ||\n\t\t(currentComponent.__hooks = {\n\t\t\t_list: [],\n\t\t\t_pendingEffects: []\n\t\t});\n\n\tif (index >= hooks._list.length) {\n\t\thooks._list.push({});\n\t}\n\n\treturn hooks._list[index];\n}\n\n/**\n * @template {unknown} S\n * @param {import('./index').Dispatch<import('./index').StateUpdater<S>>} [initialState]\n * @returns {[S, (state: S) => void]}\n */\nexport function useState(initialState) {\n\tcurrentHook = 1;\n\treturn useReducer(invokeOrReturn, initialState);\n}\n\n/**\n * @template {unknown} S\n * @template {unknown} A\n * @param {import('./index').Reducer<S, A>} reducer\n * @param {import('./index').Dispatch<import('./index').StateUpdater<S>>} initialState\n * @param {(initialState: any) => void} [init]\n * @returns {[ S, (state: S) => void ]}\n */\nexport function useReducer(reducer, initialState, init) {\n\t/** @type {import('./internal').ReducerHookState} */\n\tconst hookState = getHookState(currentIndex++, 2);\n\thookState._reducer = reducer;\n\tif (!hookState._component) {\n\t\thookState._value = [\n\t\t\t!init ? invokeOrReturn(undefined, initialState) : init(initialState),\n\n\t\t\taction => {\n\t\t\t\tconst currentValue = hookState._nextValue\n\t\t\t\t\t? hookState._nextValue[0]\n\t\t\t\t\t: hookState._value[0];\n\t\t\t\tconst nextValue = hookState._reducer(currentValue, action);\n\n\t\t\t\tif (currentValue !== nextValue) {\n\t\t\t\t\thookState._nextValue = [nextValue, hookState._value[1]];\n\t\t\t\t\thookState._component.setState({});\n\t\t\t\t}\n\t\t\t}\n\t\t];\n\n\t\thookState._component = currentComponent;\n\n\t\tif (!currentComponent._hasScuFromHooks) {\n\t\t\tcurrentComponent._hasScuFromHooks = true;\n\t\t\tlet prevScu = currentComponent.shouldComponentUpdate;\n\t\t\tconst prevCWU = currentComponent.componentWillUpdate;\n\n\t\t\t// If we're dealing with a forced update `shouldComponentUpdate` will\n\t\t\t// not be called. But we use that to update the hook values, so we\n\t\t\t// need to call it.\n\t\t\tcurrentComponent.componentWillUpdate = function (p, s, c) {\n\t\t\t\tif (this._force) {\n\t\t\t\t\tlet tmp = prevScu;\n\t\t\t\t\t// Clear to avoid other sCU hooks from being called\n\t\t\t\t\tprevScu = undefined;\n\t\t\t\t\tupdateHookState(p, s, c);\n\t\t\t\t\tprevScu = tmp;\n\t\t\t\t}\n\n\t\t\t\tif (prevCWU) prevCWU.call(this, p, s, c);\n\t\t\t};\n\n\t\t\t// This SCU has the purpose of bailing out after repeated updates\n\t\t\t// to stateful hooks.\n\t\t\t// we store the next value in _nextValue[0] and keep doing that for all\n\t\t\t// state setters, if we have next states and\n\t\t\t// all next states within a component end up being equal to their original state\n\t\t\t// we are safe to bail out for this specific component.\n\t\t\t/**\n\t\t\t *\n\t\t\t * @type {import('./internal').Component[\"shouldComponentUpdate\"]}\n\t\t\t */\n\t\t\t// @ts-ignore - We don't use TS to downtranspile\n\t\t\t// eslint-disable-next-line no-inner-declarations\n\t\t\tfunction updateHookState(p, s, c) {\n\t\t\t\tif (!hookState._component.__hooks) return true;\n\n\t\t\t\tconst stateHooks = hookState._component.__hooks._list.filter(\n\t\t\t\t\tx => x._component\n\t\t\t\t);\n\n\t\t\t\tconst allHooksEmpty = stateHooks.every(x => !x._nextValue);\n\t\t\t\t// When we have no updated hooks in the component we invoke the previous SCU or\n\t\t\t\t// traverse the VDOM tree further.\n\t\t\t\tif (allHooksEmpty) {\n\t\t\t\t\treturn prevScu ? prevScu.call(this, p, s, c) : true;\n\t\t\t\t}\n\n\t\t\t\t// We check whether we have components with a nextValue set that\n\t\t\t\t// have values that aren't equal to one another this pushes\n\t\t\t\t// us to update further down the tree\n\t\t\t\tlet shouldUpdate = hookState._component.props !== p;\n\t\t\t\tstateHooks.some(hookItem => {\n\t\t\t\t\tif (hookItem._nextValue) {\n\t\t\t\t\t\tconst currentValue = hookItem._value[0];\n\t\t\t\t\t\thookItem._value = hookItem._nextValue;\n\t\t\t\t\t\thookItem._nextValue = undefined;\n\t\t\t\t\t\tif (currentValue !== hookItem._value[0]) shouldUpdate = true;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\treturn prevScu\n\t\t\t\t\t? prevScu.call(this, p, s, c) || shouldUpdate\n\t\t\t\t\t: shouldUpdate;\n\t\t\t}\n\n\t\t\tcurrentComponent.shouldComponentUpdate = updateHookState;\n\t\t}\n\t}\n\n\treturn hookState._nextValue || hookState._value;\n}\n\n/**\n * @param {import('./internal').Effect} callback\n * @param {unknown[]} args\n * @returns {void}\n */\nexport function useEffect(callback, args) {\n\t/** @type {import('./internal').EffectHookState} */\n\tconst state = getHookState(currentIndex++, 3);\n\tif (!options._skipEffects && argsChanged(state._args, args)) {\n\t\tstate._value = callback;\n\t\tstate._pendingArgs = args;\n\n\t\tcurrentComponent.__hooks._pendingEffects.push(state);\n\t}\n}\n\n/**\n * @param {import('./internal').Effect} callback\n * @param {unknown[]} args\n * @returns {void}\n */\nexport function useLayoutEffect(callback, args) {\n\t/** @type {import('./internal').EffectHookState} */\n\tconst state = getHookState(currentIndex++, 4);\n\tif (!options._skipEffects && argsChanged(state._args, args)) {\n\t\tstate._value = callback;\n\t\tstate._pendingArgs = args;\n\n\t\tcurrentComponent._renderCallbacks.push(state);\n\t}\n}\n\n/** @type {(initialValue: unknown) => unknown} */\nexport function useRef(initialValue) {\n\tcurrentHook = 5;\n\treturn useMemo(() => ({ current: initialValue }), []);\n}\n\n/**\n * @param {object} ref\n * @param {() => object} createHandle\n * @param {unknown[]} args\n * @returns {void}\n */\nexport function useImperativeHandle(ref, createHandle, args) {\n\tcurrentHook = 6;\n\tuseLayoutEffect(\n\t\t() => {\n\t\t\tif (typeof ref == 'function') {\n\t\t\t\tconst result = ref(createHandle());\n\t\t\t\treturn () => {\n\t\t\t\t\tref(null);\n\t\t\t\t\tif (result && typeof result == 'function') result();\n\t\t\t\t};\n\t\t\t} else if (ref) {\n\t\t\t\tref.current = createHandle();\n\t\t\t\treturn () => (ref.current = null);\n\t\t\t}\n\t\t},\n\t\targs == null ? args : args.concat(ref)\n\t);\n}\n\n/**\n * @template {unknown} T\n * @param {() => T} factory\n * @param {unknown[]} args\n * @returns {T}\n */\nexport function useMemo(factory, args) {\n\t/** @type {import('./internal').MemoHookState<T>} */\n\tconst state = getHookState(currentIndex++, 7);\n\tif (argsChanged(state._args, args)) {\n\t\tstate._value = factory();\n\t\tstate._args = args;\n\t\tstate._factory = factory;\n\t}\n\n\treturn state._value;\n}\n\n/**\n * @param {() => void} callback\n * @param {unknown[]} args\n * @returns {() => void}\n */\nexport function useCallback(callback, args) {\n\tcurrentHook = 8;\n\treturn useMemo(() => callback, args);\n}\n\n/**\n * @param {import('./internal').PreactContext} context\n */\nexport function useContext(context) {\n\tconst provider = currentComponent.context[context._id];\n\t// We could skip this call here, but than we'd not call\n\t// `options._hook`. We need to do that in order to make\n\t// the devtools aware of this hook.\n\t/** @type {import('./internal').ContextHookState} */\n\tconst state = getHookState(currentIndex++, 9);\n\t// The devtools needs access to the context object to\n\t// be able to pull of the default value when no provider\n\t// is present in the tree.\n\tstate._context = context;\n\tif (!provider) return context._defaultValue;\n\t// This is probably not safe to convert to \"!\"\n\tif (state._value == null) {\n\t\tstate._value = true;\n\t\tprovider.sub(currentComponent);\n\t}\n\treturn provider.props.value;\n}\n\n/**\n * Display a custom label for a custom hook for the devtools panel\n * @type {<T>(value: T, cb?: (value: T) => string | number) => void}\n */\nexport function useDebugValue(value, formatter) {\n\tif (options.useDebugValue) {\n\t\toptions.useDebugValue(\n\t\t\tformatter ? formatter(value) : /** @type {any}*/ (value)\n\t\t);\n\t}\n}\n\n/**\n * @param {(error: unknown, errorInfo: import('preact').ErrorInfo) => void} cb\n * @returns {[unknown, () => void]}\n */\nexport function useErrorBoundary(cb) {\n\t/** @type {import('./internal').ErrorBoundaryHookState} */\n\tconst state = getHookState(currentIndex++, 10);\n\tconst errState = useState();\n\tstate._value = cb;\n\tif (!currentComponent.componentDidCatch) {\n\t\tcurrentComponent.componentDidCatch = (err, errorInfo) => {\n\t\t\tif (state._value) state._value(err, errorInfo);\n\t\t\terrState[1](err);\n\t\t};\n\t}\n\treturn [\n\t\terrState[0],\n\t\t() => {\n\t\t\terrState[1](undefined);\n\t\t}\n\t];\n}\n\n/** @type {() => string} */\nexport function useId() {\n\t/** @type {import('./internal').IdHookState} */\n\tconst state = getHookState(currentIndex++, 11);\n\tif (!state._value) {\n\t\t// Grab either the root node or the nearest async boundary node.\n\t\t/** @type {import('./internal').VNode} */\n\t\tlet root = currentComponent._vnode;\n\t\twhile (root !== null && !root._mask && root._parent !== null) {\n\t\t\troot = root._parent;\n\t\t}\n\n\t\tlet mask = root._mask || (root._mask = [0, 0]);\n\t\tstate._value = 'P' + mask[0] + '-' + mask[1]++;\n\t}\n\n\treturn state._value;\n}\n\n/**\n * After paint effects consumer.\n */\nfunction flushAfterPaintEffects() {\n\tlet component;\n\twhile ((component = afterPaintEffects.shift())) {\n\t\tconst hooks = component.__hooks;\n\t\tif (!component._parentDom || !hooks) continue;\n\t\ttry {\n\t\t\thooks._pendingEffects.some(invokeCleanup);\n\t\t\thooks._pendingEffects.some(invokeEffect);\n\t\t\thooks._pendingEffects = [];\n\t\t} catch (e) {\n\t\t\thooks._pendingEffects = [];\n\t\t\toptions._catchError(e, component._vnode);\n\t\t}\n\t}\n}\n\nlet HAS_RAF = typeof requestAnimationFrame == 'function';\n\n/**\n * Schedule a callback to be invoked after the browser has a chance to paint a new frame.\n * Do this by combining requestAnimationFrame (rAF) + setTimeout to invoke a callback after\n * the next browser frame.\n *\n * Also, schedule a timeout in parallel to the the rAF to ensure the callback is invoked\n * even if RAF doesn't fire (for example if the browser tab is not visible)\n *\n * @param {() => void} callback\n */\nfunction afterNextFrame(callback) {\n\tconst done = () => {\n\t\tclearTimeout(timeout);\n\t\tif (HAS_RAF) cancelAnimationFrame(raf);\n\t\tsetTimeout(callback);\n\t};\n\tconst timeout = setTimeout(done, RAF_TIMEOUT);\n\n\tlet raf;\n\tif (HAS_RAF) {\n\t\traf = requestAnimationFrame(done);\n\t}\n}\n\n// Note: if someone used options.debounceRendering = requestAnimationFrame,\n// then effects will ALWAYS run on the NEXT frame instead of the current one, incurring a ~16ms delay.\n// Perhaps this is not such a big deal.\n/**\n * Schedule afterPaintEffects flush after the browser paints\n * @param {number} newQueueLength\n * @returns {void}\n */\nfunction afterPaint(newQueueLength) {\n\tif (newQueueLength === 1 || prevRaf !== options.requestAnimationFrame) {\n\t\tprevRaf = options.requestAnimationFrame;\n\t\t(prevRaf || afterNextFrame)(flushAfterPaintEffects);\n\t}\n}\n\n/**\n * @param {import('./internal').HookState} hook\n * @returns {void}\n */\nfunction invokeCleanup(hook) {\n\t// A hook cleanup can introduce a call to render which creates a new root, this will call options.vnode\n\t// and move the currentComponent away.\n\tconst comp = currentComponent;\n\tlet cleanup = hook._cleanup;\n\tif (typeof cleanup == 'function') {\n\t\thook._cleanup = undefined;\n\t\tcleanup();\n\t}\n\n\tcurrentComponent = comp;\n}\n\n/**\n * Invoke a Hook's effect\n * @param {import('./internal').EffectHookState} hook\n * @returns {void}\n */\nfunction invokeEffect(hook) {\n\t// A hook call can introduce a call to render which creates a new root, this will call options.vnode\n\t// and move the currentComponent away.\n\tconst comp = currentComponent;\n\thook._cleanup = hook._value();\n\tcurrentComponent = comp;\n}\n\n/**\n * @param {unknown[]} oldArgs\n * @param {unknown[]} newArgs\n * @returns {boolean}\n */\nfunction argsChanged(oldArgs, newArgs) {\n\treturn (\n\t\t!oldArgs ||\n\t\toldArgs.length !== newArgs.length ||\n\t\tnewArgs.some((arg, index) => arg !== oldArgs[index])\n\t);\n}\n\n/**\n * @template Arg\n * @param {Arg} arg\n * @param {(arg: Arg) => any} f\n * @returns {any}\n */\nfunction invokeOrReturn(arg, f) {\n\treturn typeof f == 'function' ? f(arg) : f;\n}\n","/**\n * Assign properties from `props` to `obj`\n * @template O, P The obj and props types\n * @param {O} obj The object to copy properties to\n * @param {P} props The object to copy properties from\n * @returns {O & P}\n */\nexport function assign(obj, props) {\n\tfor (let i in props) obj[i] = props[i];\n\treturn /** @type {O & P} */ (obj);\n}\n\n/**\n * Check if two objects have a different shape\n * @param {object} a\n * @param {object} b\n * @returns {boolean}\n */\nexport function shallowDiffers(a, b) {\n\tfor (let i in a) if (i !== '__source' && !(i in b)) return true;\n\tfor (let i in b) if (i !== '__source' && a[i] !== b[i]) return true;\n\treturn false;\n}\n\n/**\n * Check if two values are the same value\n * @param {*} x\n * @param {*} y\n * @returns {boolean}\n */\nexport function is(x, y) {\n\treturn (x === y && (x !== 0 || 1 / x === 1 / y)) || (x !== x && y !== y);\n}\n","import { useState, useLayoutEffect, useEffect } from 'preact/hooks';\nimport { is } from './util';\n\n/**\n * This is taken from https://github.com/facebook/react/blob/main/packages/use-sync-external-store/src/useSyncExternalStoreShimClient.js#L84\n * on a high level this cuts out the warnings, ... and attempts a smaller implementation\n * @typedef {{ _value: any; _getSnapshot: () => any }} Store\n */\nexport function useSyncExternalStore(subscribe, getSnapshot) {\n\tconst value = getSnapshot();\n\n\t/**\n\t * @typedef {{ _instance: Store }} StoreRef\n\t * @type {[StoreRef, (store: StoreRef) => void]}\n\t */\n\tconst [{ _instance }, forceUpdate] = useState({\n\t\t_instance: { _value: value, _getSnapshot: getSnapshot }\n\t});\n\n\tuseLayoutEffect(() => {\n\t\t_instance._value = value;\n\t\t_instance._getSnapshot = getSnapshot;\n\n\t\tif (didSnapshotChange(_instance)) {\n\t\t\tforceUpdate({ _instance });\n\t\t}\n\t}, [subscribe, value, getSnapshot]);\n\n\tuseEffect(() => {\n\t\tif (didSnapshotChange(_instance)) {\n\t\t\tforceUpdate({ _instance });\n\t\t}\n\n\t\treturn subscribe(() => {\n\t\t\tif (didSnapshotChange(_instance)) {\n\t\t\t\tforceUpdate({ _instance });\n\t\t\t}\n\t\t});\n\t}, [subscribe]);\n\n\treturn value;\n}\n\n/** @type {(inst: Store) => boolean} */\nfunction didSnapshotChange(inst) {\n\ttry {\n\t\treturn !is(inst._value, inst._getSnapshot());\n\t} catch (error) {\n\t\treturn true;\n\t}\n}\n\nexport function startTransition(cb) {\n\tcb();\n}\n\nexport function useDeferredValue(val) {\n\treturn val;\n}\n\nexport function useTransition() {\n\treturn [false, startTransition];\n}\n\n// TODO: in theory this should be done after a VNode is diffed as we want to insert\n// styles/... before it attaches\nexport const useInsertionEffect = useLayoutEffect;\n","import { Component } from 'preact';\nimport { shallowDiffers } from './util';\n\n/**\n * Component class with a predefined `shouldComponentUpdate` implementation\n */\nexport function PureComponent(p, c) {\n\tthis.props = p;\n\tthis.context = c;\n}\nPureComponent.prototype = new Component();\n// Some third-party libraries check if this property is present\nPureComponent.prototype.isPureReactComponent = true;\nPureComponent.prototype.shouldComponentUpdate = function (props, state) {\n\treturn shallowDiffers(this.props, props) || shallowDiffers(this.state, state);\n};\n","import { options } from 'preact';\nimport { assign } from './util';\n\nlet oldDiffHook = options._diff;\noptions._diff = vnode => {\n\tif (vnode.type && vnode.type._forwarded && vnode.ref) {\n\t\tvnode.props.ref = vnode.ref;\n\t\tvnode.ref = null;\n\t}\n\tif (oldDiffHook) oldDiffHook(vnode);\n};\n\nexport const REACT_FORWARD_SYMBOL =\n\t(typeof Symbol != 'undefined' &&\n\t\tSymbol.for &&\n\t\tSymbol.for('react.forward_ref')) ||\n\t0xf47;\n\n/**\n * Pass ref down to a child. This is mainly used in libraries with HOCs that\n * wrap components. Using `forwardRef` there is an easy way to get a reference\n * of the wrapped component instead of one of the wrapper itself.\n * @param {import('./index').ForwardFn} fn\n * @returns {import('./internal').FunctionComponent}\n */\nexport function forwardRef(fn) {\n\tfunction Forwarded(props) {\n\t\tlet clone = assign({}, props);\n\t\tdelete clone.ref;\n\t\treturn fn(clone, props.ref || null);\n\t}\n\n\t// mobx-react checks for this being present\n\tForwarded.$$typeof = REACT_FORWARD_SYMBOL;\n\t// mobx-react heavily relies on implementation details.\n\t// It expects an object here with a `render` property,\n\t// and prototype.render will fail. Without this\n\t// mobx-react throws.\n\tForwarded.render = fn;\n\n\tForwarded.prototype.isReactComponent = Forwarded._forwarded = true;\n\tForwarded.displayName = 'ForwardRef(' + (fn.displayName || fn.name) + ')';\n\treturn Forwarded;\n}\n","import { toChildArray } from 'preact';\n\nconst mapFn = (children, fn) => {\n\tif (children == null) return null;\n\treturn toChildArray(toChildArray(children).map(fn));\n};\n\n// This API is completely unnecessary for Preact, so it's basically passthrough.\nexport const Children = {\n\tmap: mapFn,\n\tforEach: mapFn,\n\tcount(children) {\n\t\treturn children ? toChildArray(children).length : 0;\n\t},\n\tonly(children) {\n\t\tconst normalized = toChildArray(children);\n\t\tif (normalized.length !== 1) throw 'Children.only';\n\t\treturn normalized[0];\n\t},\n\ttoArray: toChildArray\n};\n","import { Component, createElement, options, Fragment } from 'preact';\nimport { MODE_HYDRATE } from '../../src/constants';\nimport { assign } from './util';\n\nconst oldCatchError = options._catchError;\noptions._catchError = function (error, newVNode, oldVNode, errorInfo) {\n\tif (error.then) {\n\t\t/** @type {import('./internal').Component} */\n\t\tlet component;\n\t\tlet vnode = newVNode;\n\n\t\tfor (; (vnode = vnode._parent); ) {\n\t\t\tif ((component = vnode._component) && component._childDidSuspend) {\n\t\t\t\tif (newVNode._dom == null) {\n\t\t\t\t\tnewVNode._dom = oldVNode._dom;\n\t\t\t\t\tnewVNode._children = oldVNode._children;\n\t\t\t\t}\n\t\t\t\t// Don't call oldCatchError if we found a Suspense\n\t\t\t\treturn component._childDidSuspend(error, newVNode);\n\t\t\t}\n\t\t}\n\t}\n\toldCatchError(error, newVNode, oldVNode, errorInfo);\n};\n\nconst oldUnmount = options.unmount;\noptions.unmount = function (vnode) {\n\t/** @type {import('./internal').Component} */\n\tconst component = vnode._component;\n\tif (component) component._unmounted = true;\n\tif (component && component._onResolve) {\n\t\tcomponent._onResolve();\n\t}\n\n\t// if the component is still hydrating\n\t// most likely it is because the component is suspended\n\t// we set the vnode.type as `null` so that it is not a typeof function\n\t// so the unmount will remove the vnode._dom\n\tif (component && vnode._flags & MODE_HYDRATE) {\n\t\tvnode.type = null;\n\t}\n\n\tif (oldUnmount) oldUnmount(vnode);\n};\n\nfunction detachedClone(vnode, detachedParent, parentDom) {\n\tif (vnode) {\n\t\tif (vnode._component && vnode._component.__hooks) {\n\t\t\tvnode._component.__hooks._list.forEach(effect => {\n\t\t\t\tif (typeof effect._cleanup == 'function') effect._cleanup();\n\t\t\t});\n\n\t\t\tvnode._component.__hooks = null;\n\t\t}\n\n\t\tvnode = assign({}, vnode);\n\t\tif (vnode._component != null) {\n\t\t\tif (vnode._component._parentDom === parentDom) {\n\t\t\t\tvnode._component._parentDom = detachedParent;\n\t\t\t}\n\n\t\t\tvnode._component._force = true;\n\n\t\t\tvnode._component = null;\n\t\t}\n\n\t\tvnode._children =\n\t\t\tvnode._children &&\n\t\t\tvnode._children.map(child =>\n\t\t\t\tdetachedClone(child, detachedParent, parentDom)\n\t\t\t);\n\t}\n\n\treturn vnode;\n}\n\nfunction removeOriginal(vnode, detachedParent, originalParent) {\n\tif (vnode && originalParent) {\n\t\tvnode._original = null;\n\t\tvnode._children =\n\t\t\tvnode._children &&\n\t\t\tvnode._children.map(child =>\n\t\t\t\tremoveOriginal(child, detachedParent, originalParent)\n\t\t\t);\n\n\t\tif (vnode._component) {\n\t\t\tif (vnode._component._parentDom === detachedParent) {\n\t\t\t\tif (vnode._dom) {\n\t\t\t\t\toriginalParent.appendChild(vnode._dom);\n\t\t\t\t}\n\t\t\t\tvnode._component._force = true;\n\t\t\t\tvnode._component._parentDom = originalParent;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn vnode;\n}\n\n// having custom inheritance instead of a class here saves a lot of bytes\nexport function Suspense() {\n\t// we do not call super here to golf some bytes...\n\tthis._pendingSuspensionCount = 0;\n\tthis._suspenders = null;\n\tthis._detachOnNextRender = null;\n}\n\n// Things we do here to save some bytes but are not proper JS inheritance:\n// - call `new Component()` as the prototype\n// - do not set `Suspense.prototype.constructor` to `Suspense`\nSuspense.prototype = new Component();\n\n/**\n * @this {import('./internal').SuspenseComponent}\n * @param {Promise} promise The thrown promise\n * @param {import('./internal').VNode<any, any>} suspendingVNode The suspending component\n */\nSuspense.prototype._childDidSuspend = function (promise, suspendingVNode) {\n\tconst suspendingComponent = suspendingVNode._component;\n\n\t/** @type {import('./internal').SuspenseComponent} */\n\tconst c = this;\n\n\tif (c._suspenders == null) {\n\t\tc._suspenders = [];\n\t}\n\tc._suspenders.push(suspendingComponent);\n\n\tconst resolve = suspended(c._vnode);\n\n\tlet resolved = false;\n\tconst onResolved = () => {\n\t\tif (resolved || c._unmounted) return;\n\n\t\tresolved = true;\n\t\tsuspendingComponent._onResolve = null;\n\n\t\tif (resolve) {\n\t\t\tresolve(onSuspensionComplete);\n\t\t} else {\n\t\t\tonSuspensionComplete();\n\t\t}\n\t};\n\n\tsuspendingComponent._onResolve = onResolved;\n\n\t// Store and null _parentDom to prevent setState/forceUpdate from\n\t// scheduling renders while suspended. Render would be a no-op anyway\n\t// since renderComponent checks _parentDom, but this avoids queue churn.\n\tconst originalParentDom = suspendingComponent._parentDom;\n\tsuspendingComponent._parentDom = null;\n\n\tconst onSuspensionComplete = () => {\n\t\tif (!--c._pendingSuspensionCount) {\n\t\t\t// If the suspension was during hydration we don't need to restore the\n\t\t\t// suspended children into the _children array\n\t\t\tif (c.state._suspended) {\n\t\t\t\tconst suspendedVNode = c.state._suspended;\n\t\t\t\tc._vnode._children[0] = removeOriginal(\n\t\t\t\t\tsuspendedVNode,\n\t\t\t\t\tsuspendedVNode._component._parentDom,\n\t\t\t\t\tsuspendedVNode._component._originalParentDom\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tc.setState({ _suspended: (c._detachOnNextRender = null) });\n\n\t\t\tlet suspended;\n\t\t\twhile ((suspended = c._suspenders.pop())) {\n\t\t\t\t// Restore _parentDom before forceUpdate so render can proceed\n\t\t\t\tsuspended._parentDom = originalParentDom;\n\t\t\t\tsuspended.forceUpdate();\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * We do not set `suspended: true` during hydration because we want the actual markup\n\t * to remain on screen and hydrate it when the suspense actually gets resolved.\n\t * While in non-hydration cases the usual fallback -> component flow would occour.\n\t */\n\tif (\n\t\t!c._pendingSuspensionCount++ &&\n\t\t!(suspendingVNode._flags & MODE_HYDRATE)\n\t) {\n\t\tc.setState({ _suspended: (c._detachOnNextRender = c._vnode._children[0]) });\n\t}\n\tpromise.then(onResolved, onResolved);\n};\n\nSuspense.prototype.componentWillUnmount = function () {\n\tthis._suspenders = [];\n};\n\n/**\n * @this {import('./internal').SuspenseComponent}\n * @param {import('./internal').SuspenseComponent[\"props\"]} props\n * @param {import('./internal').SuspenseState} state\n */\nSuspense.prototype.render = function (props, state) {\n\tif (this._detachOnNextRender) {\n\t\t// When the Suspense's _vnode was created by a call to createVNode\n\t\t// (i.e. due to a setState further up in the tree)\n\t\t// it's _children prop is null, in this case we \"forget\" about the parked vnodes to detach\n\t\tif (this._vnode._children) {\n\t\t\tconst detachedParent = document.createElement('div');\n\t\t\tconst detachedComponent = this._vnode._children[0]._component;\n\t\t\tthis._vnode._children[0] = detachedClone(\n\t\t\t\tthis._detachOnNextRender,\n\t\t\t\tdetachedParent,\n\t\t\t\t(detachedComponent._originalParentDom = detachedComponent._parentDom)\n\t\t\t);\n\t\t}\n\n\t\tthis._detachOnNextRender = null;\n\t}\n\n\t// Wrap fallback tree in a VNode that prevents itself from being marked as aborting mid-hydration:\n\t/** @type {import('./internal').VNode} */\n\tconst fallback =\n\t\tstate._suspended && createElement(Fragment, null, props.fallback);\n\tif (fallback) fallback._flags &= ~MODE_HYDRATE;\n\n\treturn [\n\t\tcreateElement(Fragment, null, state._suspended ? null : props.children),\n\t\tfallback\n\t];\n};\n\n/**\n * Checks and calls the parent component's _suspended method, passing in the\n * suspended vnode. This is a way for a parent (e.g. SuspenseList) to get notified\n * that one of its children/descendants suspended.\n *\n * The parent MAY return a callback. The callback will get called when the\n * suspension resolves, notifying the parent of the fact.\n * Moreover, the callback gets function `unsuspend` as a parameter. The resolved\n * child descendant will not actually get unsuspended until `unsuspend` gets called.\n * This is a way for the parent to delay unsuspending.\n *\n * If the parent does not return a callback then the resolved vnode\n * gets unsuspended immediately when it resolves.\n *\n * @param {import('./internal').VNode} vnode\n * @returns {((unsuspend: () => void) => void)?}\n */\nexport function suspended(vnode) {\n\tlet component = vnode._parent && vnode._parent._component;\n\treturn component && component._suspended && component._suspended(vnode);\n}\n\nexport function lazy(loader) {\n\tlet prom;\n\tlet component = null;\n\tlet error;\n\tlet resolved;\n\n\tfunction Lazy(props) {\n\t\tif (!prom) {\n\t\t\tprom = loader();\n\t\t\tprom.then(\n\t\t\t\texports => {\n\t\t\t\t\tif (exports) {\n\t\t\t\t\t\tcomponent = exports.default || exports;\n\t\t\t\t\t}\n\t\t\t\t\tresolved = true;\n\t\t\t\t},\n\t\t\t\te => {\n\t\t\t\t\terror = e;\n\t\t\t\t\tresolved = true;\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\n\t\tif (error) {\n\t\t\tthrow error;\n\t\t}\n\n\t\tif (!resolved) {\n\t\t\tthrow prom;\n\t\t}\n\n\t\treturn component ? createElement(component, props) : null;\n\t}\n\n\tLazy.displayName = 'Lazy';\n\tLazy._forwarded = true;\n\treturn Lazy;\n}\n","import { Component, toChildArray } from 'preact';\nimport { suspended } from './suspense.js';\n\n// Indexes to linked list nodes (nodes are stored as arrays to save bytes).\nconst SUSPENDED_COUNT = 0;\nconst RESOLVED_COUNT = 1;\nconst NEXT_NODE = 2;\n\n// Having custom inheritance instead of a class here saves a lot of bytes.\nexport function SuspenseList() {\n\tthis._next = null;\n\tthis._map = null;\n}\n\n// Mark one of child's earlier suspensions as resolved.\n// Some pending callbacks may become callable due to this\n// (e.g. the last suspended descendant gets resolved when\n// revealOrder === 'together'). Process those callbacks as well.\nconst resolve = (list, child, node) => {\n\tif (++node[RESOLVED_COUNT] === node[SUSPENDED_COUNT]) {\n\t\t// The number a child (or any of its descendants) has been suspended\n\t\t// matches the number of times it's been resolved. Therefore we\n\t\t// mark the child as completely resolved by deleting it from ._map.\n\t\t// This is used to figure out when *all* children have been completely\n\t\t// resolved when revealOrder is 'together'.\n\t\tlist._map.delete(child);\n\t}\n\n\t// If revealOrder is falsy then we can do an early exit, as the\n\t// callbacks won't get queued in the node anyway.\n\t// If revealOrder is 'together' then also do an early exit\n\t// if all suspended descendants have not yet been resolved.\n\tif (\n\t\t!list.props.revealOrder ||\n\t\t(list.props.revealOrder[0] === 't' && list._map.size)\n\t) {\n\t\treturn;\n\t}\n\n\t// Walk the currently suspended children in order, calling their\n\t// stored callbacks on the way. Stop if we encounter a child that\n\t// has not been completely resolved yet.\n\tnode = list._next;\n\twhile (node) {\n\t\twhile (node.length > 3) {\n\t\t\tnode.pop()();\n\t\t}\n\t\tif (node[RESOLVED_COUNT] < node[SUSPENDED_COUNT]) {\n\t\t\tbreak;\n\t\t}\n\t\tlist._next = node = node[NEXT_NODE];\n\t}\n};\n\n// Things we do here to save some bytes but are not proper JS inheritance:\n// - call `new Component()` as the prototype\n// - do not set `Suspense.prototype.constructor` to `Suspense`\nSuspenseList.prototype = new Component();\n\nSuspenseList.prototype._suspended = function (child) {\n\tconst list = this;\n\tconst delegated = suspended(list._vnode);\n\n\tlet node = list._map.get(child);\n\tnode[SUSPENDED_COUNT]++;\n\n\treturn unsuspend => {\n\t\tconst wrappedUnsuspend = () => {\n\t\t\tif (!list.props.revealOrder) {\n\t\t\t\t// Special case the undefined (falsy) revealOrder, as there\n\t\t\t\t// is no need to coordinate a specific order or unsuspends.\n\t\t\t\tunsuspend();\n\t\t\t} else {\n\t\t\t\tnode.push(unsuspend);\n\t\t\t\tresolve(list, child, node);\n\t\t\t}\n\t\t};\n\t\tif (delegated) {\n\t\t\tdelegated(wrappedUnsuspend);\n\t\t} else {\n\t\t\twrappedUnsuspend();\n\t\t}\n\t};\n};\n\nSuspenseList.prototype.render = function (props) {\n\tthis._next = null;\n\tthis._map = new Map();\n\n\tconst children = toChildArray(props.children);\n\tif (props.revealOrder && props.revealOrder[0] === 'b') {\n\t\t// If order === 'backwards' (or, well, anything starting with a 'b')\n\t\t// then flip the child list around so that the last child will be\n\t\t// the first in the linked list.\n\t\tchildren.reverse();\n\t}\n\t// Build the linked list. Iterate through the children in reverse order\n\t// so that `_next` points to the first linked list node to be resolved.\n\tfor (let i = children.length; i--; ) {\n\t\t// Create a new linked list node as an array of form:\n\t\t// \t[suspended_count, resolved_count, next_node]\n\t\t// where suspended_count and resolved_count are numeric counters for\n\t\t// keeping track how many times a node has been suspended and resolved.\n\t\t//\n\t\t// Note that suspended_count starts from 1 instead of 0, so we can block\n\t\t// processing callbacks until componentDidMount has been called. In a sense\n\t\t// node is suspended at least until componentDidMount gets called!\n\t\t//\n\t\t// Pending callbacks are added to the end of the node:\n\t\t// \t[suspended_count, resolved_count, next_node, callback_0, callback_1, ...]\n\t\tthis._map.set(children[i], (this._next = [1, 0, this._next]));\n\t}\n\treturn props.children;\n};\n\nSuspenseList.prototype.componentDidUpdate =\n\tSuspenseList.prototype.componentDidMount = function () {\n\t\t// Iterate through all children after mounting for two reasons:\n\t\t// 1. As each node[SUSPENDED_COUNT] starts from 1, this iteration increases\n\t\t// each node[RELEASED_COUNT] by 1, therefore balancing the counters.\n\t\t// The nodes can now be completely consumed from the linked list.\n\t\t// 2. Handle nodes that might have gotten resolved between render and\n\t\t// componentDidMount.\n\t\tthis._map.forEach((node, child) => {\n\t\t\tresolve(this, child, node);\n\t\t});\n\t};\n","import {\n\trender as preactRender,\n\thydrate as preactHydrate,\n\toptions,\n\ttoChildArray,\n\tComponent\n} from 'preact';\nimport {\n\tuseCallback,\n\tuseContext,\n\tuseDebugValue,\n\tuseEffect,\n\tuseId,\n\tuseImperativeHandle,\n\tuseLayoutEffect,\n\tuseMemo,\n\tuseReducer,\n\tuseRef,\n\tuseState\n} from 'preact/hooks';\nimport {\n\tuseDeferredValue,\n\tuseInsertionEffect,\n\tuseSyncExternalStore,\n\tuseTransition\n} from './index';\n\nexport const REACT_ELEMENT_TYPE =\n\t(typeof Symbol != 'undefined' && Symbol.for && Symbol.for('react.element')) ||\n\t0xeac7;\n\nconst CAMEL_PROPS =\n\t/^(?:accent|alignment|arabic|baseline|cap|clip(?!PathU)|color|dominant|fill|flood|font|glyph(?!R)|horiz|image(!S)|letter|lighting|marker(?!H|W|U)|overline|paint|pointer|shape|stop|strikethrough|stroke|text(?!L)|transform|underline|unicode|units|v|vector|vert|word|writing|x(?!C))[A-Z]/;\nconst ON_ANI = /^on(Ani|Tra|Tou|BeforeInp|Compo)/;\nconst CAMEL_REPLACE = /[A-Z0-9]/g;\nconst IS_DOM = typeof document !== 'undefined';\n\n// Input types for which onchange should not be converted to oninput.\n// type=\"file|checkbox|radio\", plus \"range\" in IE11.\n// (IE11 doesn't support Symbol, which we use here to turn `rad` into `ra` which matches \"range\")\nconst onChangeInputType = type =>\n\t(typeof Symbol != 'undefined' && typeof Symbol() == 'symbol'\n\t\t? /fil|che|rad/\n\t\t: /fil|che|ra/\n\t).test(type);\n\n// Some libraries like `react-virtualized` explicitly check for this.\nComponent.prototype.isReactComponent = true;\n\n// `UNSAFE_*` lifecycle hooks\n// Preact only ever invokes the unprefixed methods.\n// Here we provide a base \"fallback\" implementation that calls any defined UNSAFE_ prefixed method.\n// - If a component defines its own `componentDidMount()` (including via defineProperty), use that.\n// - If a component defines `UNSAFE_componentDidMount()`, `componentDidMount` is the alias getter/setter.\n// - If anything assigns to an `UNSAFE_*` property, the assignment is forwarded to the unprefixed property.\n// See https://github.com/preactjs/preact/issues/1941\n[\n\t'componentWillMount',\n\t'componentWillReceiveProps',\n\t'componentWillUpdate'\n].forEach(key => {\n\tObject.defineProperty(Component.prototype, key, {\n\t\tconfigurable: true,\n\t\tget() {\n\t\t\treturn this['UNSAFE_' + key];\n\t\t},\n\t\tset(v) {\n\t\t\tObject.defineProperty(this, key, {\n\t\t\t\tconfigurable: true,\n\t\t\t\twritable: true,\n\t\t\t\tvalue: v\n\t\t\t});\n\t\t}\n\t});\n});\n\n/**\n * Proxy render() since React returns a Component reference.\n * @param {import('./internal').VNode} vnode VNode tree to render\n * @param {import('./internal').PreactElement} parent DOM node to render vnode tree into\n * @param {() => void} [callback] Optional callback that will be called after rendering\n * @returns {import('./internal').Component | null} The root component reference or null\n */\nexport function render(vnode, parent, callback) {\n\t// React destroys any existing DOM nodes, see #1727\n\t// ...but only on the first render, see #1828\n\tif (parent._children == null) {\n\t\tparent.textContent = '';\n\t}\n\n\tpreactRender(vnode, parent);\n\tif (typeof callback == 'function') callback();\n\n\treturn vnode ? vnode._component : null;\n}\n\nexport function hydrate(vnode, parent, callback) {\n\tpreactHydrate(vnode, parent);\n\tif (typeof callback == 'function') callback();\n\n\treturn vnode ? vnode._component : null;\n}\n\nlet oldEventHook = options.event;\noptions.event = e => {\n\tif (oldEventHook) e = oldEventHook(e);\n\n\te.persist = () => {};\n\te.isPropagationStopped = function isPropagationStopped() {\n\t\treturn this.cancelBubble;\n\t};\n\te.isDefaultPrevented = function isDefaultPrevented() {\n\t\treturn this.defaultPrevented;\n\t};\n\treturn (e.nativeEvent = e);\n};\n\nconst classNameDescriptorNonEnumberable = {\n\tconfigurable: true,\n\tget() {\n\t\treturn this.class;\n\t}\n};\n\nfunction handleDomVNode(vnode) {\n\tlet props = vnode.props,\n\t\ttype = vnode.type,\n\t\tnormalizedProps = {},\n\t\tisNonDashedType = type.indexOf('-') == -1;\n\n\tfor (let i in props) {\n\t\tlet value = props[i];\n\n\t\tif (\n\t\t\t(i === 'value' && 'defaultValue' in props && value == null) ||\n\t\t\t// Emulate React's behavior of not rendering the contents of noscript tags on the client.\n\t\t\t(IS_DOM && i === 'children' && type === 'noscript') ||\n\t\t\ti === 'class' ||\n\t\t\ti === 'className'\n\t\t) {\n\t\t\t// Skip applying value if it is null/undefined and we already set\n\t\t\t// a default value\n\t\t\tcontinue;\n\t\t}\n\n\t\tlet lowerCased = i.toLowerCase();\n\t\tif (i === 'defaultValue' && 'value' in props && props.value == null) {\n\t\t\t// `defaultValue` is treated as a fallback `value` when a value prop is present but null/undefined.\n\t\t\t// `defaultValue` for Elements with no value prop is the same as the DOM defaultValue property.\n\t\t\ti = 'value';\n\t\t} else if (i === 'download' && value === true) {\n\t\t\t// Calling `setAttribute` with a truthy value will lead to it being\n\t\t\t// passed as a stringified value, e.g. `download=\"true\"`. React\n\t\t\t// converts it to an empty string instead, otherwise the attribute\n\t\t\t// value will be used as the file name and the file will be called\n\t\t\t// \"true\" upon downloading it.\n\t\t\tvalue = '';\n\t\t} else if (lowerCased === 'translate' && value === 'no') {\n\t\t\tvalue = false;\n\t\t} else if (lowerCased[0] === 'o' && lowerCased[1] === 'n') {\n\t\t\tif (lowerCased === 'ondoubleclick') {\n\t\t\t\ti = 'ondblclick';\n\t\t\t} else if (\n\t\t\t\tlowerCased === 'onchange' &&\n\t\t\t\t(type === 'input' || type === 'textarea') &&\n\t\t\t\t!onChangeInputType(props.type)\n\t\t\t) {\n\t\t\t\tlowerCased = i = 'oninput';\n\t\t\t} else if (lowerCased === 'onfocus') {\n\t\t\t\ti = 'onfocusin';\n\t\t\t} else if (lowerCased === 'onblur') {\n\t\t\t\ti = 'onfocusout';\n\t\t\t} else if (ON_ANI.test(i)) {\n\t\t\t\ti = lowerCased;\n\t\t\t}\n\t\t} else if (isNonDashedType && CAMEL_PROPS.test(i)) {\n\t\t\ti = i.replace(CAMEL_REPLACE, '-$&').toLowerCase();\n\t\t} else if (value === null) {\n\t\t\tvalue = undefined;\n\t\t}\n\n\t\t// Add support for onInput and onChange, see #3561\n\t\t// if we have an oninput prop already change it to oninputCapture\n\t\tif (lowerCased === 'oninput') {\n\t\t\ti = lowerCased;\n\t\t\tif (normalizedProps[i]) {\n\t\t\t\ti = 'oninputCapture';\n\t\t\t}\n\t\t}\n\n\t\tnormalizedProps[i] = value;\n\t}\n\n\tif (type == 'select') {\n\t\t// Add support for array select values: <select multiple value={[]} />\n\t\tif (normalizedProps.multiple && Array.isArray(normalizedProps.value)) {\n\t\t\t// forEach() always returns undefined, which we abuse here to unset the value prop.\n\t\t\tnormalizedProps.value = toChildArray(props.children).forEach(child => {\n\t\t\t\tchild.props.selected =\n\t\t\t\t\tnormalizedProps.value.indexOf(child.props.value) != -1;\n\t\t\t});\n\t\t}\n\n\t\t// Adding support for defaultValue in select tag\n\t\tif (normalizedProps.defaultValue != null) {\n\t\t\tnormalizedProps.value = toChildArray(props.children).forEach(child => {\n\t\t\t\tif (normalizedProps.multiple) {\n\t\t\t\t\tchild.props.selected =\n\t\t\t\t\t\tnormalizedProps.defaultValue.indexOf(child.props.value) != -1;\n\t\t\t\t} else {\n\t\t\t\t\tchild.props.selected =\n\t\t\t\t\t\tnormalizedProps.defaultValue == child.props.value;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tif (props.class && !props.className) {\n\t\tnormalizedProps.class = props.class;\n\t\tObject.defineProperty(\n\t\t\tnormalizedProps,\n\t\t\t'className',\n\t\t\tclassNameDescriptorNonEnumberable\n\t\t);\n\t} else if (props.className) {\n\t\tnormalizedProps.class = normalizedProps.className = props.className;\n\t}\n\n\tvnode.props = normalizedProps;\n}\n\nlet oldVNodeHook = options.vnode;\noptions.vnode = vnode => {\n\t// only normalize props on Element nodes\n\tif (typeof vnode.type === 'string') {\n\t\thandleDomVNode(vnode);\n\t}\n\n\tvnode.$$typeof = REACT_ELEMENT_TYPE;\n\n\tif (oldVNodeHook) oldVNodeHook(vnode);\n};\n\n// Only needed for react-relay\nlet currentComponent;\nconst oldBeforeRender = options._render;\noptions._render = function (vnode) {\n\tif (oldBeforeRender) {\n\t\toldBeforeRender(vnode);\n\t}\n\tcurrentComponent = vnode._component;\n};\n\nconst oldDiffed = options.diffed;\n/** @type {(vnode: import('./internal').VNode) => void} */\noptions.diffed = function (vnode) {\n\tif (oldDiffed) {\n\t\toldDiffed(vnode);\n\t}\n\n\tconst props = vnode.props;\n\tconst dom = vnode._dom;\n\n\tif (\n\t\tdom != null &&\n\t\tvnode.type === 'textarea' &&\n\t\t'value' in props &&\n\t\tprops.value !== dom.value\n\t) {\n\t\tdom.value = props.value == null ? '' : props.value;\n\t}\n\n\tcurrentComponent = null;\n};\n\n// This is a very very private internal function for React it\n// is used to sort-of do runtime dependency injection.\nexport const __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = {\n\tReactCurrentDispatcher: {\n\t\tcurrent: {\n\t\t\treadContext(context) {\n\t\t\t\treturn currentComponent._globalContext[context._id].props.value;\n\t\t\t},\n\t\t\tuseCallback,\n\t\t\tuseContext,\n\t\t\tuseDebugValue,\n\t\t\tuseDeferredValue,\n\t\t\tuseEffect,\n\t\t\tuseId,\n\t\t\tuseImperativeHandle,\n\t\t\tuseInsertionEffect,\n\t\t\tuseLayoutEffect,\n\t\t\tuseMemo,\n\t\t\t// useMutableSource, // experimental-only and replaced by uSES, likely not worth supporting\n\t\t\tuseReducer,\n\t\t\tuseRef,\n\t\t\tuseState,\n\t\t\tuseSyncExternalStore,\n\t\t\tuseTransition\n\t\t}\n\t}\n};\n","import {\n\tcreateElement,\n\trender as preactRender,\n\tcloneElement as preactCloneElement,\n\tcreateRef,\n\tComponent,\n\tcreateContext,\n\tFragment,\n\toptions\n} from 'preact';\nimport {\n\tuseState,\n\tuseId,\n\tuseReducer,\n\tuseEffect,\n\tuseLayoutEffect,\n\tuseRef,\n\tuseImperativeHandle,\n\tuseMemo,\n\tuseCallback,\n\tuseContext,\n\tuseDebugValue\n} from 'preact/hooks';\nimport {\n\tuseInsertionEffect,\n\tstartTransition,\n\tuseDeferredValue,\n\tuseSyncExternalStore,\n\tuseTransition\n} from './hooks';\nimport { PureComponent } from './PureComponent';\nimport { memo } from './memo';\nimport { forwardRef } from './forwardRef';\nimport { Children } from './Children';\nimport { Suspense, lazy } from './suspense';\nimport { SuspenseList } from './suspense-list';\nimport { createPortal } from './portals';\nimport {\n\thydrate,\n\trender,\n\tREACT_ELEMENT_TYPE,\n\t__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED\n} from './render';\n\nconst version = '18.3.1'; // trick libraries to think we are react\n\n/**\n * Legacy version of createElement.\n * @param {import('./internal').VNode[\"type\"]} type The node name or Component constructor\n */\nfunction createFactory(type) {\n\treturn createElement.bind(null, type);\n}\n\n/**\n * Check if the passed element is a valid (p)react node.\n * @param {*} element The element to check\n * @returns {boolean}\n */\nfunction isValidElement(element) {\n\treturn !!element && element.$$typeof === REACT_ELEMENT_TYPE;\n}\n\n/**\n * Check if the passed element is a Fragment node.\n * @param {*} element The element to check\n * @returns {boolean}\n */\nfunction isFragment(element) {\n\treturn isValidElement(element) && element.type === Fragment;\n}\n\n/**\n * Check if the passed element is a Memo node.\n * @param {*} element The element to check\n * @returns {boolean}\n */\nfunction isMemo(element) {\n\treturn (\n\t\t!!element &&\n\t\ttypeof element.displayName == 'string' &&\n\t\telement.displayName.indexOf('Memo(') == 0\n\t);\n}\n\n/**\n * Wrap `cloneElement` to abort if the passed element is not a valid element and apply\n * all vnode normalizations.\n * @param {import('./internal').VNode} element The vnode to clone\n * @param {object} props Props to add when cloning\n * @param {Array<import('./internal').ComponentChildren>} rest Optional component children\n */\nfunction cloneElement(element) {\n\tif (!isValidElement(element)) return element;\n\treturn preactCloneElement.apply(null, arguments);\n}\n\n/**\n * Remove a component tree from the DOM, including state and event handlers.\n * @param {import('./internal').PreactElement} container\n * @returns {boolean}\n */\nfunction unmountComponentAtNode(container) {\n\tif (container._children) {\n\t\tpreactRender(null, container);\n\t\treturn true;\n\t}\n\treturn false;\n}\n\n/**\n * Get the matching DOM node for a component\n * @param {import('./internal').Component} component\n * @returns {import('./internal').PreactElement | null}\n */\nfunction findDOMNode(component) {\n\treturn (\n\t\t(component &&\n\t\t\t(component.base || (component.nodeType === 1 && component))) ||\n\t\tnull\n\t);\n}\n\n/**\n * Deprecated way to control batched rendering inside the reconciler, but we\n * already schedule in batches inside our rendering code\n * @template Arg\n * @param {(arg: Arg) => void} callback function that triggers the updated\n * @param {Arg} [arg] Optional argument that can be passed to the callback\n */\n// eslint-disable-next-line camelcase\nconst unstable_batchedUpdates = (callback, arg) => callback(arg);\n\n/**\n * In React, `flushSync` flushes the entire tree and forces a rerender.\n * @template Arg\n * @template Result\n * @param {(arg: Arg) => Result} callback function that runs before the flush\n * @param {Arg} [arg] Optional argument that can be passed to the callback\n * @returns\n */\nconst flushSync = (callback, arg) => {\n\tconst prevDebounce = options.debounceRendering;\n\toptions.debounceRendering = cb => cb();\n\tconst res = callback(arg);\n\toptions.debounceRendering = prevDebounce;\n\treturn res;\n};\n\n// compat to react-is\nexport const isElement = isValidElement;\n\nexport * from 'preact/hooks';\nexport {\n\tversion,\n\tChildren,\n\trender,\n\thydrate,\n\tunmountComponentAtNode,\n\tcreatePortal,\n\tcreateElement,\n\tcreateContext,\n\tcreateFactory,\n\tcloneElement,\n\tcreateRef,\n\tFragment,\n\tisValidElement,\n\tisFragment,\n\tisMemo,\n\tfindDOMNode,\n\tComponent,\n\tPureComponent,\n\tmemo,\n\tforwardRef,\n\tflushSync,\n\tuseInsertionEffect,\n\tstartTransition,\n\tuseDeferredValue,\n\tuseSyncExternalStore,\n\tuseTransition,\n\t// eslint-disable-next-line camelcase\n\tunstable_batchedUpdates,\n\tFragment as StrictMode,\n\tSuspense,\n\tSuspenseList,\n\tlazy,\n\t__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED\n};\n\n// React copies the named exports to the default one.\nexport default {\n\tuseState,\n\tuseId,\n\tuseReducer,\n\tuseEffect,\n\tuseLayoutEffect,\n\tuseInsertionEffect,\n\tuseTransition,\n\tuseDeferredValue,\n\tuseSyncExternalStore,\n\tstartTransition,\n\tuseRef,\n\tuseImperativeHandle,\n\tuseMemo,\n\tuseCallback,\n\tuseContext,\n\tuseDebugValue,\n\tversion,\n\tChildren,\n\trender,\n\thydrate,\n\tunmountComponentAtNode,\n\tcreatePortal,\n\tcreateElement,\n\tcreateContext,\n\tcreateFactory,\n\tcloneElement,\n\tcreateRef,\n\tFragment,\n\tisValidElement,\n\tisElement,\n\tisFragment,\n\tisMemo,\n\tfindDOMNode,\n\tComponent,\n\tPureComponent,\n\tmemo,\n\tforwardRef,\n\tflushSync,\n\tunstable_batchedUpdates,\n\tStrictMode: Fragment,\n\tSuspense,\n\tSuspenseList,\n\tlazy,\n\t__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED\n};\n","import { render, hydrate, unmountComponentAtNode } from 'preact/compat';\n\nexport function createRoot(container) {\n\treturn {\n\t\t// eslint-disable-next-line\n\t\trender: function (children) {\n\t\t\trender(children, container);\n\t\t},\n\t\t// eslint-disable-next-line\n\t\tunmount: function () {\n\t\t\tunmountComponentAtNode(container);\n\t\t}\n\t};\n}\n\nexport function hydrateRoot(container, children) {\n\thydrate(children, container);\n\treturn createRoot(container);\n}\n\nexport default {\n\tcreateRoot,\n\thydrateRoot\n};\n","/**\n * Doc Schema\n *\n * Defines the JSON format for AI-scriptable visual docs that accompany\n * audio narration. A Doc describes a sequence of animated blocks\n * with text overlays, images, and transitions synchronized to audio.\n *\n * The format is designed to be:\n * 1. AI-generatable - Claude can create scripts from article content\n * 2. Browser-renderable - SVG + CSS animations (ES2015 compatible)\n * 3. Video-exportable - Frame-by-frame capture via Playwright\n *\n * Timing: Blocks are timed to match narration audio segments. Each article\n * has 3-6 MP3 files (intro + sections), and blocks are grouped by segment.\n */\n\n// ============================================\n// Core Types\n// ============================================\n\n/**\n * Configuration for the Start/resting block shown before playback begins.\n */\nexport interface StartBlockConfig {\n /** Hero image path (relative to article media) */\n heroSrc: string;\n /** Alt text for the hero image */\n heroAlt?: string;\n /** Title to display over the hero */\n title: string;\n /** Optional subtitle */\n subtitle?: string;\n /** Ambient motion for the hero image */\n ambientMotion?: 'zoomIn' | 'zoomOut' | 'panLeft' | 'panRight';\n /** Photo credit / artist name for the hero image */\n heroCredit?: string;\n /** License identifier for the hero image */\n heroLicense?: string;\n}\n\n/**\n * A complete visual doc for an article.\n */\nexport interface Doc {\n /** Article ID this doc belongs to */\n articleId: string;\n\n /** Total duration in seconds (sum of all audio segments) */\n duration: number;\n\n /** Ordered list of blocks */\n blocks: Block[];\n\n /** Audio track configuration */\n audio: AudioTrack;\n\n /** Caption track for closed captions (generated by postprocess-doc) */\n captions?: CaptionTrack;\n\n /**\n * Start/resting block shown before playback begins.\n * Displays hero image with title - acts as a \"poster\" for the doc.\n * The player shows this until the user starts playback.\n */\n startBlock?: StartBlockConfig;\n\n /**\n * Persistent layers rendered on every block (behind and/or on top of content).\n * Used for consistent branding overlays, background gradients, etc.\n */\n persistentLayers?: import('./BlockTemplates.js').PersistentLayerConfig;\n\n /**\n * Optional theme identifier. Resolved at render time via `resolveTheme()`.\n * When omitted, the renderer uses the default theme ('documentary').\n */\n themeId?: string;\n\n /** Optional metadata */\n meta?: {\n generatedAt?: string;\n generatedBy?: string;\n version?: number;\n };\n\n /**\n * YAML frontmatter from the source markdown.\n * Carries rendering hints like `document-render-as` and custom metadata.\n */\n frontmatter?: Record<string, unknown>;\n}\n\n/**\n * A single block in the doc.\n *\n * Blocks can be flat (audio-synced timeline) or nested (markdown-driven hierarchy).\n * When derived from markdown, a block corresponds to a heading section:\n * - `sourceHeading` references the original MarkdownHeading node\n * - `contents` holds the body markdown between this heading and the next\n * - `children` holds sub-heading blocks (e.g., H2s under an H1)\n */\nexport interface Block {\n /** Unique identifier for this block */\n id: string;\n\n /** When this block appears (seconds from start) */\n startTime: number;\n\n /** How long this block is visible (seconds) */\n duration: number;\n\n /** Which audio segment this block belongs to (0-indexed) */\n audioSegment: number;\n\n /**\n * Pre-computed visual layers, rendered back-to-front.\n *\n * Optional — template-derived blocks typically omit this and compute\n * layers on demand via `getLayers()` from `@bendyline/squisq/doc`.\n * Raw blocks (e.g., hand-crafted by AI) may provide layers directly.\n */\n layers?: Layer[];\n\n /** Entry transition from previous block */\n transition?: Transition;\n\n /** Template name that generated this block (for debugging) */\n template?: string;\n\n /**\n * Display title for template rendering.\n * Extracted from the sourceHeading when the block is created by markdownToDoc().\n * Templates like sectionHeader and titleBlock read this for their title layer.\n */\n title?: string;\n\n // ── Markdown-driven hierarchy (optional) ──\n\n /**\n * Nested sub-blocks (heading hierarchy).\n * When a doc is derived from markdown, sub-headings within this\n * heading's section become child blocks. For example, H2 blocks\n * under an H1 block appear here.\n */\n children?: Block[];\n\n /**\n * Markdown body content for this block's section.\n * Contains the block-level markdown nodes (paragraphs, lists, code,\n * blockquotes, etc.) that appear between this heading and the next\n * heading or sub-heading. Empty for pure structural blocks.\n */\n contents?: import('../markdown/types.js').MarkdownBlockNode[];\n\n /**\n * Reference to the MarkdownHeading node that created this block.\n * Present when the block was derived from markdown via markdownToDoc().\n * Enables round-tripping back to markdown and provides heading depth.\n * Absent for the preamble block (content before the first heading).\n */\n sourceHeading?: import('../markdown/types.js').MarkdownHeading;\n\n /**\n * Template overrides extracted from markdown directives.\n * For example, `### Data Section {template=chart colorScheme=blue}`\n * would produce `{ template: 'chart', colorScheme: 'blue' }`.\n * Allows per-block customization of template selection and parameters.\n */\n templateOverrides?: Record<string, string>;\n}\n\n// ============================================\n// Layer Types\n// ============================================\n\n/**\n * A visual element within a block.\n * Layers are composited back-to-front (first layer is background).\n */\nexport type Layer = ImageLayer | TextLayer | ShapeLayer | MapLayer | VideoLayer | TableLayer;\n\ninterface BaseLayer {\n /** Unique identifier for this layer */\n id: string;\n\n /** Position and size */\n position: Position;\n\n /** Animation to apply */\n animation?: Animation;\n}\n\n/**\n * Image layer - displays an image with optional Ken Burns effect.\n */\nexport interface ImageLayer extends BaseLayer {\n type: 'image';\n content: {\n /** Path to image file (relative to article media dir) */\n src: string;\n /** Alt text for accessibility */\n alt: string;\n /** How to fit image in bounds */\n fit?: 'cover' | 'contain' | 'fill';\n /** Photo credit / artist name */\n credit?: string;\n /** License identifier (e.g., 'CC BY-SA 4.0') */\n license?: string;\n };\n}\n\n/**\n * Text layer - displays text with styling.\n */\nexport interface TextLayer extends BaseLayer {\n type: 'text';\n content: {\n /** Text to display (supports \\n for line breaks) */\n text: string;\n /** Text styling */\n style: TextStyle;\n };\n}\n\n/**\n * Shape layer - simple geometric shapes for visual accents.\n */\nexport interface ShapeLayer extends BaseLayer {\n type: 'shape';\n content: {\n /** Shape type */\n shape: 'rect' | 'circle' | 'line';\n /** Fill color (CSS color or 'none') */\n fill?: string;\n /** Stroke color */\n stroke?: string;\n /** Stroke width in pixels */\n strokeWidth?: number;\n /** Corner radius for rect */\n borderRadius?: number;\n };\n}\n\n/**\n * Map layer - displays a geographic map with optional markers.\n *\n * Maps are rendered as composite tile images from free tile providers.\n * Supported styles use open-source/free tiles requiring attribution.\n */\nexport interface MapLayer extends BaseLayer {\n type: 'map';\n content: {\n /** Center coordinates for the map */\n center: {\n lat: number;\n lng: number;\n };\n /** Zoom level (0-18, typically 8-14 for doc blocks) */\n zoom: number;\n /** Map tile style */\n style: MapTileStyle;\n /** Optional markers to display on the map */\n markers?: MapMarker[];\n /** Pre-rendered static image path (for video export reliability) */\n staticSrc?: string;\n /** Show attribution text (default: true) */\n showAttribution?: boolean;\n };\n}\n\n/**\n * Video layer - displays a short video clip, always muted (narration provides audio).\n *\n * Rendered via an HTML5 <video> element inside <foreignObject>, similar to how\n * ImageLayer uses <img> for Ken Burns effects. clipStart/clipEnd define the window\n * within the source video to play. During Playwright frame capture (seekTo mode),\n * the video is seeked programmatically rather than playing in real time.\n */\nexport interface VideoLayer extends BaseLayer {\n type: 'video';\n content: {\n /** Path to video file (relative to article media dir) */\n src: string;\n /** Path to poster frame (shown before video loads / during seek) */\n posterSrc?: string;\n /** Alt text for accessibility */\n alt: string;\n /** How to fit video in bounds */\n fit?: 'cover' | 'contain' | 'fill';\n /** Start time within the source video (seconds) */\n clipStart: number;\n /** End time within the source video (seconds) */\n clipEnd: number;\n /** Total source video duration (for validation) */\n sourceDuration?: number;\n /** Video credit / artist name */\n credit?: string;\n /** License identifier (e.g., 'CC BY-SA 4.0') */\n license?: string;\n };\n}\n\n/**\n * Table layer - renders a data table with themed styling.\n * Uses foreignObject inside SVG for HTML-based table layout.\n */\nexport interface TableLayer extends BaseLayer {\n type: 'table';\n content: {\n /** Header cell values */\n headers: string[];\n /** Data rows (array of cell value arrays) */\n rows: string[][];\n /** Per-column alignment */\n align?: (('left' | 'right' | 'center') | null)[];\n /** Visual styling */\n style: TableLayerStyle;\n };\n}\n\n/**\n * Styling options for a TableLayer.\n */\nexport interface TableLayerStyle {\n /** Header row background color */\n headerBackground: string;\n /** Header row text color */\n headerColor: string;\n /** Body cell background color */\n cellBackground: string;\n /** Body cell text color */\n cellColor: string;\n /** Border/divider color */\n borderColor: string;\n /** Font size in pixels */\n fontSize: number;\n /** Font family */\n fontFamily?: string;\n /** Header font family (falls back to fontFamily) */\n headerFontFamily?: string;\n /** Corner radius for the table container */\n borderRadius?: number;\n}\n\n/**\n * Available map tile styles from free/open-source providers.\n */\nexport type MapTileStyle =\n | 'terrain' // OpenTopoMap - topographic/terrain (default)\n | 'satellite' // ESRI World Imagery\n | 'road' // OpenStreetMap standard\n | 'toner' // Stadia Toner (high contrast B&W)\n | 'watercolor'; // Stadia Watercolor (artistic)\n\n/**\n * A marker to display on the map.\n */\nexport interface MapMarker {\n /** Marker latitude */\n lat: number;\n /** Marker longitude */\n lng: number;\n /** Optional label text */\n label?: string;\n /** Marker color (CSS color, default: #ef4444) */\n color?: string;\n /** Marker icon type */\n icon?: 'pin' | 'circle' | 'star';\n}\n\n// ============================================\n// Position & Styling\n// ============================================\n\n/**\n * Position and dimensions for a layer.\n * Values can be pixels (number) or percentages (string like \"50%\").\n */\nexport interface Position {\n /** X position (pixels or percentage) */\n x: number | string;\n /** Y position (pixels or percentage) */\n y: number | string;\n /** Width (pixels or percentage) */\n width?: number | string;\n /** Height (pixels or percentage) */\n height?: number | string;\n /** Anchor point for positioning */\n anchor?: 'center' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';\n}\n\n/**\n * Text styling options.\n */\nexport interface TextStyle {\n /** Font size in pixels */\n fontSize: number;\n /** Font family (defaults to system sans-serif) */\n fontFamily?: string;\n /** Font weight */\n fontWeight?: 'normal' | 'bold';\n /** Text color (CSS color) */\n color: string;\n /** Text alignment */\n textAlign?: 'left' | 'center' | 'right';\n /** Line height multiplier */\n lineHeight?: number;\n /** Add drop shadow for readability over images */\n shadow?: boolean;\n /** Background color for text box */\n background?: string;\n /** Padding around text (pixels) */\n padding?: number;\n /** Maximum number of lines before truncation (adds \"...\" to last line) */\n maxLines?: number;\n}\n\n// ============================================\n// Animation & Transitions\n// ============================================\n\n/**\n * Animation to apply to a layer.\n */\nexport interface Animation {\n /** Animation type */\n type: AnimationType;\n /** Duration in seconds (defaults to layer's block duration) */\n duration?: number;\n /** Delay before animation starts (seconds) */\n delay?: number;\n /** CSS easing function */\n easing?: string;\n /** For Ken Burns: zoom direction */\n direction?: 'in' | 'out';\n /** For pan animations: pan direction */\n panDirection?: 'left' | 'right' | 'up' | 'down';\n}\n\n/**\n * Available animation types.\n */\nexport type AnimationType =\n | 'none'\n | 'fadeIn'\n | 'fadeOut'\n | 'slowZoom' // Slow zoom with optional pan\n | 'zoomIn'\n | 'zoomOut'\n | 'panLeft'\n | 'panRight'\n | 'typewriter'; // Text appears letter by letter\n\n/**\n * Transition between blocks.\n */\nexport interface Transition {\n /** Transition type */\n type: TransitionType;\n /** Duration in seconds */\n duration: number;\n}\n\nexport type TransitionType =\n | 'cut' // Instant switch\n | 'fade' // Cross-fade\n | 'dissolve' // Soft dissolve\n | 'slideLeft' // New block enters from right\n | 'slideRight'; // New block enters from left\n\n// ============================================\n// Audio Configuration\n// ============================================\n\n/**\n * Audio track configuration.\n * Articles have multiple MP3 segments (intro + sections).\n */\nexport interface AudioTrack {\n /** Audio segments in playback order */\n segments: AudioSegment[];\n}\n\n// ============================================\n// Captions\n// ============================================\n\n/**\n * A single word with precise timing, used for word-level highlighting\n * in social-style captions. Populated from TTS timing data when available.\n */\nexport interface CaptionWord {\n /** The word text */\n text: string;\n /** Start time in seconds (relative to doc start) */\n startTime: number;\n /** End time in seconds */\n endTime: number;\n}\n\n/**\n * A single caption phrase to display during playback.\n */\nexport interface CaptionPhrase {\n /** The text to display */\n text: string;\n /** Start time in seconds (relative to doc start) */\n startTime: number;\n /** End time in seconds */\n endTime: number;\n /** Which audio segment this caption belongs to (0-indexed) */\n audioSegment: number;\n /**\n * Optional per-word timing from TTS timing data.\n * When present, enables precise word-level highlighting in social\n * caption style. When absent, word timing is interpolated evenly\n * across the phrase duration.\n */\n words?: CaptionWord[];\n}\n\n/**\n * Caption track for a doc.\n */\nexport interface CaptionTrack {\n /** Caption phrases in chronological order */\n phrases: CaptionPhrase[];\n /** When the captions were generated */\n generatedAt: string;\n /** Algorithm version for regeneration detection */\n version: number;\n}\n\n/**\n * A single audio segment (one MP3 file).\n */\nexport interface AudioSegment {\n /** Path to MP3 file (relative to article media dir) */\n src: string;\n /** Segment name (e.g., \"intro\", \"history\") */\n name: string;\n /** Duration in seconds */\n duration: number;\n /** Start time in overall timeline (calculated) */\n startTime: number;\n}\n\n// ============================================\n// Audio Timing Data (from TTS)\n// ============================================\n\n/**\n * A single word-level timing bookmark from TTS synthesis.\n * Used for precise audio-to-content mapping and word-level caption sync.\n */\nexport interface AudioBookmark {\n /** Unique identifier (e.g., \"word-0\", \"word-1\") */\n id: string;\n /** Timestamp in seconds from audio start */\n time: number;\n /** Character offset in the source text */\n charOffset: number;\n /** The word text at this position */\n textFragment?: string;\n}\n\n/**\n * Timing data for an audio segment, typically from a `.timing.json` file\n * generated alongside TTS audio. Contains the source text and per-word\n * timing bookmarks for precise content matching and caption sync.\n */\nexport interface AudioTimingData {\n /** The normalized plain text that was synthesized */\n sourceText: string;\n /** Word-level timing bookmarks */\n bookmarks: AudioBookmark[];\n /** Total audio duration in seconds */\n duration: number;\n}\n\n// ============================================\n// Helper Functions\n// ============================================\n\n/**\n * Calculate total duration from audio segments.\n */\nexport function calculateDuration(audio: AudioTrack): number {\n return audio.segments.reduce((sum, seg) => sum + seg.duration, 0);\n}\n\n/**\n * Find which audio segment is playing at a given time.\n */\nexport function getSegmentAtTime(audio: AudioTrack, time: number): number {\n let elapsed = 0;\n for (let i = 0; i < audio.segments.length; i++) {\n elapsed += audio.segments[i].duration;\n if (time < elapsed) return i;\n }\n return audio.segments.length - 1;\n}\n\n/**\n * Find which block should be visible at a given time.\n */\nexport function getBlockAtTime(blocks: Block[], time: number): Block | null {\n for (let i = blocks.length - 1; i >= 0; i--) {\n const block = blocks[i];\n if (time >= block.startTime && time < block.startTime + block.duration) {\n return block;\n }\n }\n return blocks[0] || null;\n}\n\n/**\n * Find the caption phrase that should be displayed at a given time.\n */\nexport function getCaptionAtTime(\n captions: CaptionTrack | undefined,\n time: number,\n): CaptionPhrase | null {\n if (!captions || !captions.phrases.length) return null;\n\n for (const phrase of captions.phrases) {\n if (time >= phrase.startTime && time < phrase.endTime) {\n return phrase;\n }\n }\n return null;\n}\n\n/**\n * Validate a Doc for completeness.\n */\nexport function validateDoc(script: Doc): string[] {\n const errors: string[] = [];\n\n if (!script.articleId) {\n errors.push('Missing articleId');\n }\n\n if (!script.blocks || script.blocks.length === 0) {\n errors.push('No blocks defined');\n }\n\n if (!script.audio || !script.audio.segments || script.audio.segments.length === 0) {\n errors.push('No audio segments defined');\n }\n\n // Check for gaps in block coverage\n const totalDuration = script.duration;\n let covered = 0;\n for (const block of script.blocks) {\n if (block.startTime > covered + 0.1) {\n errors.push(`Gap in blocks: ${covered}s to ${block.startTime}s`);\n }\n covered = Math.max(covered, block.startTime + block.duration);\n }\n\n if (covered < totalDuration - 0.1) {\n errors.push(`Blocks end at ${covered}s but audio is ${totalDuration}s`);\n }\n\n return errors;\n}\n","/**\n * Built-in Theme Library\n *\n * Ships 8 curated themes covering documentary, editorial, minimal, and\n * cinematic styles. Each theme is fully JSON-serializable.\n *\n * Usage:\n * ```ts\n * import { THEMES, resolveTheme } from '@bendyline/squisq/schemas';\n *\n * const theme = resolveTheme('minimalist'); // look up by id\n * const theme = THEMES.documentary; // direct access\n * ```\n */\n\nimport type { Theme, ThemeColorScheme } from './Theme.js';\n\n// ============================================\n// Shared constants\n// ============================================\n\n// ── Font stacks ──────────────────────────────────────────────────\n// Each stack lists the recommended Google Font first (works when the\n// wrapping site loads it), then degrades to safe system fonts.\n// Squisq itself does NOT load Google Fonts.\n\n/** System fonts only — no external dependencies. */\nconst SYSTEM_SANS = 'system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif';\nconst SYSTEM_SERIF = 'Georgia, \"Times New Roman\", serif';\nconst SYSTEM_MONO = 'Consolas, \"Courier New\", monospace';\n\n/** Theme-specific stacks with Google Font leads. */\nconst PLAYFAIR = '\"Playfair Display\", Georgia, serif';\nconst SOURCE_SERIF = '\"Source Serif 4\", \"PT Serif\", Georgia, serif';\nconst INTER = '\"Inter\", \"Segoe UI\", Roboto, sans-serif';\nconst OSWALD = '\"Oswald\", Impact, \"Arial Black\", sans-serif';\nconst ROBOTO = '\"Roboto\", \"Segoe UI\", Arial, sans-serif';\nconst MERRIWEATHER = '\"Merriweather\", Georgia, serif';\nconst LORA = '\"Lora\", \"Merriweather\", Georgia, serif';\nconst JETBRAINS_MONO = '\"JetBrains Mono\", \"Fira Code\", Consolas, monospace';\nconst IBM_PLEX_SANS = '\"IBM Plex Sans\", \"Segoe UI\", Roboto, sans-serif';\nconst DM_SERIF = '\"DM Serif Display\", Georgia, serif';\nconst DM_SANS = '\"DM Sans\", \"Segoe UI\", Roboto, sans-serif';\nconst CORMORANT = '\"Cormorant Garamond\", Garamond, Georgia, serif';\nconst CRIMSON = '\"Crimson Text\", Georgia, serif';\nconst PT_SERIF = '\"PT Serif\", Georgia, serif';\nconst HANKEN_GROTESK = '\"Hanken Grotesk\", system-ui, sans-serif';\n\n/** Standard 6-scheme set used by the documentary theme (migrated from old COLOR_SCHEMES). */\nconst CLASSIC_COLOR_SCHEMES: Record<string, ThemeColorScheme> = {\n blue: { bg: '#1a365d', text: '#63b3ed', accent: '#90cdf4' },\n green: { bg: '#22543d', text: '#9ae6b4', accent: '#68d391' },\n purple: { bg: '#44337a', text: '#d6bcfa', accent: '#b794f4' },\n red: { bg: '#742a2a', text: '#fc8181', accent: '#feb2b2' },\n orange: { bg: '#744210', text: '#fbd38d', accent: '#f6ad55' },\n teal: { bg: '#234e52', text: '#81e6d9', accent: '#4fd1c5' },\n};\n\n// ============================================\n// 1. Standard (default — safe system fonts, no external dependencies)\n// ============================================\n\nconst standard: Theme = {\n id: 'standard',\n name: 'Standard',\n description: 'Clean and safe. System fonts only — no external font dependencies.',\n colors: {\n primary: '#3182ce',\n secondary: '#4a5568',\n background: '#1a202c',\n backgroundLight: '#2d3748',\n text: '#f7fafc',\n textMuted: '#a0aec0',\n highlight: '#4299e1',\n warning: '#fc8181',\n },\n typography: {\n bodyFontFamily: SYSTEM_SANS,\n titleFontFamily: SYSTEM_SERIF,\n monoFontFamily: SYSTEM_MONO,\n titleWeight: 'bold',\n },\n style: {\n textShadow: true,\n overlayOpacity: 0.45,\n animationSpeed: 1.0,\n },\n renderStyle: {\n name: 'standard',\n defaultTextAnimation: 'fadeIn',\n defaultImageAnimation: 'slowZoom',\n ambientMotion: true,\n defaultTransition: { type: 'fade', duration: 0.7 },\n },\n colorSchemes: CLASSIC_COLOR_SCHEMES,\n persistentLayers: {\n bottomLayers: [\n {\n template: 'gradientBackground',\n config: { type: 'gradientBackground', preset: 'dark-vignette' },\n },\n ],\n },\n};\n\n// ============================================\n// 2. Documentary\n// ============================================\n\nconst documentary: Theme = {\n id: 'documentary',\n name: 'Documentary',\n description: 'Classic dark cinematic look with elegant serif typography.',\n colors: {\n primary: '#3d5a80',\n secondary: '#63b3ed',\n background: '#1a202c',\n backgroundLight: '#2d3748',\n text: '#ffffff',\n textMuted: '#a0aec0',\n highlight: '#63b3ed',\n warning: '#fc8181',\n },\n typography: {\n bodyFontFamily: SOURCE_SERIF,\n titleFontFamily: PLAYFAIR,\n titleWeight: 'bold',\n },\n style: {\n textShadow: true,\n overlayOpacity: 0.5,\n animationSpeed: 1.0,\n },\n renderStyle: {\n name: 'documentary',\n defaultTextAnimation: 'fadeIn',\n defaultImageAnimation: 'slowZoom',\n ambientMotion: true,\n defaultTransition: { type: 'fade', duration: 0.8 },\n },\n colorSchemes: CLASSIC_COLOR_SCHEMES,\n persistentLayers: {\n bottomLayers: [\n {\n template: 'gradientBackground',\n config: { type: 'gradientBackground', preset: 'dark-vignette' },\n },\n ],\n },\n};\n\n// ============================================\n// 2. Minimalist\n// ============================================\n\nconst minimalist: Theme = {\n id: 'minimalist',\n name: 'Minimalist',\n description: 'Clean near-white background with sans-serif type and minimal animation.',\n colors: {\n primary: '#2d3748',\n secondary: '#4a5568',\n background: '#f7fafc',\n backgroundLight: '#edf2f7',\n text: '#1a202c',\n textMuted: '#718096',\n highlight: '#3182ce',\n warning: '#e53e3e',\n },\n typography: {\n bodyFontFamily: INTER,\n titleFontFamily: INTER,\n titleWeight: 'bold',\n lineHeight: 1.6,\n },\n style: {\n textShadow: false,\n overlayOpacity: 0.3,\n animationSpeed: 1.2,\n borderRadius: 8,\n },\n renderStyle: {\n name: 'minimalist',\n defaultTextAnimation: 'fadeIn',\n ambientMotion: false,\n defaultTransition: { type: 'fade', duration: 0.6 },\n templateHints: {\n titleBlock: { showAccentLine: false },\n },\n },\n colorSchemes: {\n blue: { bg: '#ebf8ff', text: '#2b6cb0', accent: '#3182ce' },\n green: { bg: '#f0fff4', text: '#276749', accent: '#38a169' },\n purple: { bg: '#faf5ff', text: '#553c9a', accent: '#805ad5' },\n red: { bg: '#fff5f5', text: '#c53030', accent: '#e53e3e' },\n orange: { bg: '#fffaf0', text: '#c05621', accent: '#dd6b20' },\n teal: { bg: '#e6fffa', text: '#285e61', accent: '#319795' },\n },\n};\n\n// ============================================\n// 3. Bold\n// ============================================\n\nconst bold: Theme = {\n id: 'bold',\n name: 'Bold',\n description: 'High-contrast black with vivid accents and dramatic animations.',\n colors: {\n primary: '#e53e3e',\n secondary: '#ed8936',\n background: '#000000',\n backgroundLight: '#1a1a1a',\n text: '#ffffff',\n textMuted: '#cbd5e0',\n highlight: '#f6e05e',\n warning: '#fc8181',\n },\n typography: {\n bodyFontFamily: ROBOTO,\n titleFontFamily: OSWALD,\n titleWeight: 'bold',\n titleScale: 1.15,\n bodyScale: 1.0,\n titleLineHeight: 1.1,\n },\n style: {\n textShadow: true,\n overlayOpacity: 0.6,\n animationSpeed: 0.8,\n },\n renderStyle: {\n name: 'bold',\n defaultTextAnimation: 'zoomIn',\n defaultImageAnimation: 'slowZoom',\n ambientMotion: true,\n defaultTransition: { type: 'dissolve', duration: 0.5 },\n templateHints: {\n statHighlight: { entrance: 'dramatic' },\n fullBleedQuote: { entrance: 'dramatic' },\n },\n },\n colorSchemes: {\n blue: { bg: '#1a202c', text: '#63b3ed', accent: '#90cdf4' },\n green: { bg: '#1a202c', text: '#48bb78', accent: '#68d391' },\n purple: { bg: '#1a202c', text: '#b794f4', accent: '#d6bcfa' },\n red: { bg: '#1a202c', text: '#fc8181', accent: '#feb2b2' },\n orange: { bg: '#1a202c', text: '#f6ad55', accent: '#fbd38d' },\n teal: { bg: '#1a202c', text: '#4fd1c5', accent: '#81e6d9' },\n },\n};\n\n// ============================================\n// 4. Morning Light\n// ============================================\n\nconst morningLight: Theme = {\n id: 'morning-light',\n name: 'Morning Light',\n description: 'Warm light background with dark text and gentle serif typography.',\n colors: {\n primary: '#744210',\n secondary: '#975a16',\n background: '#faf8f5',\n backgroundLight: '#f5f0eb',\n text: '#2d3748',\n textMuted: '#718096',\n highlight: '#dd6b20',\n warning: '#c53030',\n },\n typography: {\n bodyFontFamily: LORA,\n titleFontFamily: MERRIWEATHER,\n titleWeight: 'bold',\n lineHeight: 1.7,\n },\n style: {\n textShadow: false,\n overlayOpacity: 0.35,\n animationSpeed: 1.1,\n borderRadius: 4,\n },\n renderStyle: {\n name: 'morning-light',\n defaultTextAnimation: 'fadeIn',\n ambientMotion: false,\n defaultTransition: { type: 'fade', duration: 1.0 },\n },\n colorSchemes: {\n blue: { bg: '#ebf8ff', text: '#2c5282', accent: '#4299e1' },\n green: { bg: '#f0fff4', text: '#22543d', accent: '#48bb78' },\n purple: { bg: '#faf5ff', text: '#44337a', accent: '#9f7aea' },\n red: { bg: '#fff5f5', text: '#9b2c2c', accent: '#fc8181' },\n orange: { bg: '#fffaf0', text: '#744210', accent: '#ed8936' },\n teal: { bg: '#e6fffa', text: '#234e52', accent: '#38b2ac' },\n },\n};\n\n// ============================================\n// 5. Tech Dark\n// ============================================\n\nconst techDark: Theme = {\n id: 'tech-dark',\n name: 'Tech Dark',\n description: 'True black with neon cyan/green accents and monospace titles.',\n colors: {\n primary: '#00e5ff',\n secondary: '#00e676',\n background: '#0a0a0a',\n backgroundLight: '#1a1a2e',\n text: '#e0e0e0',\n textMuted: '#9e9e9e',\n highlight: '#00e5ff',\n warning: '#ff5252',\n },\n typography: {\n bodyFontFamily: IBM_PLEX_SANS,\n titleFontFamily: JETBRAINS_MONO,\n monoFontFamily: JETBRAINS_MONO,\n titleWeight: 'bold',\n titleScale: 0.9,\n lineHeight: 1.5,\n },\n style: {\n textShadow: true,\n overlayOpacity: 0.55,\n animationSpeed: 0.9,\n borderRadius: 2,\n },\n renderStyle: {\n name: 'tech-dark',\n defaultTextAnimation: 'typewriter',\n defaultImageAnimation: 'slowZoom',\n ambientMotion: true,\n defaultTransition: { type: 'dissolve', duration: 0.4 },\n templateHints: {\n statHighlight: { entrance: 'dramatic' },\n },\n },\n colorSchemes: {\n blue: { bg: '#0d1b2a', text: '#00b0ff', accent: '#40c4ff' },\n green: { bg: '#0d1b0d', text: '#00e676', accent: '#69f0ae' },\n purple: { bg: '#1a0d2e', text: '#d500f9', accent: '#ea80fc' },\n red: { bg: '#2e0d0d', text: '#ff5252', accent: '#ff8a80' },\n orange: { bg: '#2e1a0d', text: '#ff9100', accent: '#ffab40' },\n teal: { bg: '#0d2e2e', text: '#1de9b6', accent: '#64ffda' },\n },\n};\n\n// ============================================\n// 6. Magazine\n// ============================================\n\nconst magazine: Theme = {\n id: 'magazine',\n name: 'Magazine',\n description: 'Rich editorial palette with mixed serif/sans typography and slide transitions.',\n colors: {\n primary: '#c53030',\n secondary: '#2b6cb0',\n background: '#1a202c',\n backgroundLight: '#2d3748',\n text: '#f7fafc',\n textMuted: '#cbd5e0',\n highlight: '#ed8936',\n warning: '#fc8181',\n },\n typography: {\n bodyFontFamily: DM_SANS,\n titleFontFamily: DM_SERIF,\n titleWeight: 'bold',\n titleScale: 1.05,\n lineHeight: 1.5,\n },\n style: {\n textShadow: true,\n overlayOpacity: 0.45,\n animationSpeed: 1.0,\n borderRadius: 6,\n },\n renderStyle: {\n name: 'magazine',\n defaultTextAnimation: 'fadeIn',\n defaultImageAnimation: 'slowZoom',\n ambientMotion: true,\n defaultTransition: { type: 'slideLeft', duration: 0.7 },\n },\n colorSchemes: {\n blue: { bg: '#1a365d', text: '#90cdf4', accent: '#63b3ed' },\n green: { bg: '#1c4532', text: '#9ae6b4', accent: '#68d391' },\n purple: { bg: '#322659', text: '#d6bcfa', accent: '#b794f4' },\n red: { bg: '#63171b', text: '#feb2b2', accent: '#fc8181' },\n orange: { bg: '#652b19', text: '#fbd38d', accent: '#f6ad55' },\n teal: { bg: '#1d4044', text: '#81e6d9', accent: '#4fd1c5' },\n },\n};\n\n// ============================================\n// 7. Cinematic\n// ============================================\n\nconst cinematic: Theme = {\n id: 'cinematic',\n name: 'Cinematic',\n description: 'Ultra-dark with moody gradients, gold accents, and slow dissolve transitions.',\n colors: {\n primary: '#d69e2e',\n secondary: '#b7791f',\n background: '#0a0f1a',\n backgroundLight: '#1a202c',\n text: '#f7fafc',\n textMuted: '#a0aec0',\n highlight: '#ecc94b',\n warning: '#fc8181',\n },\n typography: {\n bodyFontFamily: CRIMSON,\n titleFontFamily: CORMORANT,\n titleWeight: 'bold',\n lineHeight: 1.5,\n titleLineHeight: 1.2,\n },\n style: {\n textShadow: true,\n overlayOpacity: 0.55,\n animationSpeed: 1.2,\n },\n renderStyle: {\n name: 'cinematic',\n defaultTextAnimation: 'fadeIn',\n defaultImageAnimation: 'slowZoom',\n ambientMotion: true,\n defaultTransition: { type: 'dissolve', duration: 1.2 },\n templateHints: {\n titleBlock: { showAccentLine: true },\n },\n },\n colorSchemes: {\n blue: { bg: '#0d1b2a', text: '#90cdf4', accent: '#63b3ed' },\n green: { bg: '#0d1b14', text: '#9ae6b4', accent: '#68d391' },\n purple: { bg: '#1a0d2e', text: '#d6bcfa', accent: '#b794f4' },\n red: { bg: '#2a0d0d', text: '#fc8181', accent: '#feb2b2' },\n orange: { bg: '#2a1a0d', text: '#fbd38d', accent: '#f6ad55' },\n teal: { bg: '#0d2a2a', text: '#81e6d9', accent: '#4fd1c5' },\n },\n persistentLayers: {\n bottomLayers: [\n {\n template: 'gradientBackground',\n config: { type: 'gradientBackground', preset: 'radial-dark' },\n },\n ],\n },\n};\n\n// ============================================\n// 8. Warm Earth\n// ============================================\n\nconst warmEarth: Theme = {\n id: 'warm-earth',\n name: 'Warm Earth',\n description: 'Natural warm tones with earthy browns and terracotta accents.',\n colors: {\n primary: '#9c4221',\n secondary: '#c05621',\n background: '#1c1410',\n backgroundLight: '#2d241e',\n text: '#faf5f0',\n textMuted: '#c4a882',\n highlight: '#dd6b20',\n warning: '#e53e3e',\n },\n typography: {\n bodyFontFamily: HANKEN_GROTESK,\n titleFontFamily: PT_SERIF,\n titleWeight: 'bold',\n lineHeight: 1.6,\n },\n style: {\n textShadow: true,\n overlayOpacity: 0.5,\n animationSpeed: 1.1,\n },\n renderStyle: {\n name: 'warm-earth',\n defaultTextAnimation: 'fadeIn',\n defaultImageAnimation: 'panLeft',\n ambientMotion: true,\n defaultTransition: { type: 'fade', duration: 0.9 },\n },\n colorSchemes: {\n blue: { bg: '#2a1f14', text: '#90cdf4', accent: '#63b3ed' },\n green: { bg: '#1e2a14', text: '#9ae6b4', accent: '#68d391' },\n purple: { bg: '#2a142a', text: '#d6bcfa', accent: '#b794f4' },\n red: { bg: '#2a1414', text: '#fc8181', accent: '#feb2b2' },\n orange: { bg: '#2a1e0a', text: '#fbd38d', accent: '#f6ad55' },\n teal: { bg: '#142a28', text: '#81e6d9', accent: '#4fd1c5' },\n },\n persistentLayers: {\n bottomLayers: [\n {\n template: 'gradientBackground',\n config: { type: 'gradientBackground', preset: 'earth-tones' },\n },\n ],\n },\n};\n\n// ============================================\n// Theme Library\n// ============================================\n\n/**\n * All built-in themes, keyed by id.\n */\nexport const THEMES: Record<string, Theme> = {\n standard,\n documentary,\n minimalist,\n bold,\n 'morning-light': morningLight,\n 'tech-dark': techDark,\n magazine,\n cinematic,\n 'warm-earth': warmEarth,\n};\n\n/** The default theme id. */\nexport const DEFAULT_THEME_ID = 'standard';\n\n/** The default theme (standard — safe system fonts, no external dependencies). */\nexport const DEFAULT_THEME: Theme = standard;\n\n/**\n * Resolve a theme by id. Returns the default theme when `id` is\n * undefined or not found in the library.\n */\nexport function resolveTheme(id: string | undefined): Theme {\n if (id && id in THEMES) return THEMES[id];\n return DEFAULT_THEME;\n}\n\n/**\n * Get all available theme ids.\n */\nexport function getAvailableThemes(): string[] {\n return Object.keys(THEMES);\n}\n\n/**\n * Get a summary of all themes (id + name + description) for theme pickers.\n */\nexport function getThemeSummaries(): Array<{ id: string; name: string; description?: string }> {\n return Object.values(THEMES).map((t) => ({\n id: t.id,\n name: t.name,\n description: t.description,\n }));\n}\n","/**\n * Viewport Configuration\n *\n * Defines viewport dimensions for doc rendering across different aspect ratios.\n * Templates use this configuration to adapt their layouts appropriately.\n *\n * Supported aspect ratios:\n * - landscape (16:9) - Default, standard video/presentation format\n * - portrait (9:16) - Vertical video, mobile stories\n * - square (1:1) - Social media posts\n * - standard (4:3) - Legacy presentation format\n */\n\n/**\n * Viewport configuration for doc rendering.\n */\nexport interface ViewportConfig {\n /** Canonical width in virtual pixels */\n width: number;\n /** Canonical height in virtual pixels */\n height: number;\n /** Human-readable name for debugging/display */\n name: string;\n}\n\n/**\n * Standard viewport presets for common aspect ratios.\n */\nexport const VIEWPORT_PRESETS = {\n /** 16:9 landscape (default, 1080p) */\n landscape: { width: 1920, height: 1080, name: '16:9 Landscape' },\n /** 9:16 portrait (vertical video, stories) */\n portrait: { width: 1080, height: 1920, name: '9:16 Portrait' },\n /** 1:1 square (social media) */\n square: { width: 1080, height: 1080, name: '1:1 Square' },\n /** 4:3 standard (legacy) */\n standard: { width: 1440, height: 1080, name: '4:3 Standard' },\n} as const;\n\n/**\n * Viewport preset name.\n */\nexport type ViewportPreset = keyof typeof VIEWPORT_PRESETS;\n\n/**\n * Viewport orientation derived from aspect ratio.\n */\nexport type ViewportOrientation = 'landscape' | 'portrait' | 'square';\n\n/**\n * Get a viewport configuration from a preset name or return the config if already a ViewportConfig.\n */\nexport function getViewport(viewport: ViewportPreset | ViewportConfig): ViewportConfig {\n if (typeof viewport === 'string') {\n return VIEWPORT_PRESETS[viewport];\n }\n return viewport;\n}\n\n/**\n * Calculate font scale factor for a viewport.\n * Based on diagonal pixels relative to 1080p landscape reference.\n * This ensures text remains readable across different viewport sizes.\n */\nconst REFERENCE_DIAGONAL = Math.sqrt(1920 * 1920 + 1080 * 1080); // ~2203\n\nexport function calculateFontScale(viewport: ViewportConfig): number {\n const currentDiagonal = Math.sqrt(\n viewport.width * viewport.width + viewport.height * viewport.height,\n );\n return currentDiagonal / REFERENCE_DIAGONAL;\n}\n\n/**\n * Determine if viewport is landscape, portrait, or square.\n */\nexport function getViewportOrientation(viewport: ViewportConfig): ViewportOrientation {\n const ratio = viewport.width / viewport.height;\n // Allow small tolerance for \"square\" classification\n if (Math.abs(ratio - 1) < 0.05) return 'square';\n return ratio > 1 ? 'landscape' : 'portrait';\n}\n\n/**\n * Get aspect ratio as a string (e.g., \"16:9\", \"9:16\", \"1:1\").\n */\nexport function getAspectRatioString(viewport: ViewportConfig): string {\n const gcd = (a: number, b: number): number => (b === 0 ? a : gcd(b, a % b));\n const divisor = gcd(viewport.width, viewport.height);\n return `${viewport.width / divisor}:${viewport.height / divisor}`;\n}\n","/**\n * Layout Strategy\n *\n * Provides orientation-specific layout hints for slide templates.\n * Templates use these hints to position content appropriately for\n * different aspect ratios (landscape, portrait, square).\n *\n * Key adaptations by orientation:\n * - Portrait: Larger relative text, stacked layouts instead of side-by-side\n * - Square: Balanced layout with moderate adjustments\n * - Landscape: Default/reference layout\n */\n\nimport type { ViewportOrientation, ViewportConfig } from './Viewport.js';\nimport { calculateFontScale } from './Viewport.js';\n\n/**\n * Layout hints for template positioning based on orientation.\n */\nexport interface LayoutHints {\n /** Primary content Y position (percentage string, e.g., \"35%\") */\n primaryY: string;\n /** Secondary content Y position (percentage string) */\n secondaryY: string;\n /** Tertiary/detail Y position (percentage string) */\n tertiaryY: string;\n /** Title font size multiplier (relative to base) */\n titleScale: number;\n /** Body text font size multiplier (relative to base) */\n bodyScale: number;\n /** Two-column: left X position (percentage string) */\n columnLeftX: string;\n /** Two-column: right X position (percentage string) */\n columnRightX: string;\n /** Two-column in portrait: top Y position for stacked layout */\n columnTopY: string;\n /** Two-column in portrait: bottom Y position for stacked layout */\n columnBottomY: string;\n /** Whether two-column should stack vertically */\n stackColumns: boolean;\n /** Max text width (percentage string) for wrapping */\n maxTextWidth: string;\n /** Horizontal padding from edges (percentage string) */\n horizontalPadding: string;\n /** Caption position Y for imageWithCaption (percentage string) */\n captionY: string;\n /** Caption font size multiplier */\n captionScale: number;\n}\n\n/**\n * Layout configurations by orientation.\n */\nconst LAYOUT_CONFIGS: Record<ViewportOrientation, LayoutHints> = {\n landscape: {\n primaryY: '35%',\n secondaryY: '55%',\n tertiaryY: '75%',\n titleScale: 1.0,\n bodyScale: 1.0,\n columnLeftX: '25%',\n columnRightX: '75%',\n columnTopY: '35%',\n columnBottomY: '65%',\n stackColumns: false,\n maxTextWidth: '80%',\n horizontalPadding: '10%',\n captionY: '85%',\n captionScale: 1.0,\n },\n portrait: {\n // Content positioned higher for thumb-reach zone on mobile\n primaryY: '25%',\n secondaryY: '42%',\n tertiaryY: '58%',\n // Titles scale down for narrower width; body text scales up to fill vertical space\n titleScale: 0.7,\n bodyScale: 1.5,\n // Stacked columns instead of side-by-side\n columnLeftX: '50%',\n columnRightX: '50%',\n columnTopY: '30%',\n columnBottomY: '55%',\n stackColumns: true,\n // Wider relative to viewport to use available space\n maxTextWidth: '90%',\n horizontalPadding: '5%',\n captionY: '75%',\n captionScale: 0.85,\n },\n square: {\n primaryY: '30%',\n secondaryY: '50%',\n tertiaryY: '70%',\n titleScale: 0.85,\n bodyScale: 0.9,\n columnLeftX: '25%',\n columnRightX: '75%',\n columnTopY: '35%',\n columnBottomY: '65%',\n stackColumns: false,\n maxTextWidth: '85%',\n horizontalPadding: '7.5%',\n captionY: '82%',\n captionScale: 0.9,\n },\n};\n\n/**\n * Get layout hints for a given orientation.\n */\nexport function getLayoutHints(orientation: ViewportOrientation): LayoutHints {\n return LAYOUT_CONFIGS[orientation];\n}\n\n/**\n * Calculate a scaled font size based on viewport and layout hints.\n *\n * @param basePx - Base font size in pixels (designed for 1920x1080)\n * @param viewport - Target viewport configuration\n * @param orientation - Viewport orientation\n * @param isTitle - Whether this is title text (uses titleScale) or body (uses bodyScale)\n */\nexport function scaledFontSize(\n basePx: number,\n viewport: ViewportConfig,\n orientation: ViewportOrientation,\n isTitle: boolean = false,\n): number {\n const fontScale = calculateFontScale(viewport);\n const layout = getLayoutHints(orientation);\n const typeScale = isTitle ? layout.titleScale : layout.bodyScale;\n return Math.round(basePx * fontScale * typeScale);\n}\n\n/**\n * Get position for two-column layout based on orientation.\n * Returns { left: {x, y}, right: {x, y} } positions.\n */\nexport function getTwoColumnPositions(orientation: ViewportOrientation): {\n left: { x: string; y: string };\n right: { x: string; y: string };\n} {\n const layout = getLayoutHints(orientation);\n\n if (layout.stackColumns) {\n // Portrait: stack vertically\n return {\n left: { x: '50%', y: layout.columnTopY },\n right: { x: '50%', y: layout.columnBottomY },\n };\n }\n\n // Landscape/square: side by side\n return {\n left: { x: layout.columnLeftX, y: '50%' },\n right: { x: layout.columnRightX, y: '50%' },\n };\n}\n\n/**\n * Get safe text bounds for a given orientation.\n * Returns margins to keep text away from edges.\n */\nexport function getSafeTextBounds(orientation: ViewportOrientation): {\n left: string;\n right: string;\n top: string;\n bottom: string;\n} {\n const layout = getLayoutHints(orientation);\n return {\n left: layout.horizontalPadding,\n right: layout.horizontalPadding,\n top: '10%',\n bottom: '10%',\n };\n}\n","/**\n * Block Templates Schema\n *\n * Defines a template system for AI-generated doc blocks. Instead of\n * specifying low-level layers, positions, and animations, AI can use\n * high-level templates like \"titleBlock\" or \"statHighlight\" with simple\n * content parameters.\n *\n * Templates are expanded into full Block structures at render time,\n * ensuring consistent styling and reducing AI generation errors.\n *\n * Template Types:\n * - titleBlock: Doc intro with title + subtitle\n * - sectionHeader: Colored section divider\n * - statHighlight: Big number/stat with description\n * - quoteBlock: Large centered quote\n * - factCard: Key fact with explanation\n * - twoColumn: Side-by-side comparison\n * - dateEvent: Timeline-style date + description\n * - imageWithCaption: Image with text overlay\n */\n\nimport type { Layer, Block, Transition, MapTileStyle, MapMarker } from './Doc.js';\nimport type { ViewportConfig, ViewportOrientation } from './Viewport.js';\nimport type { LayoutHints } from './LayoutStrategy.js';\nimport type { Theme } from './Theme.js';\nimport { VIEWPORT_PRESETS, getViewportOrientation, calculateFontScale } from './Viewport.js';\nimport { getLayoutHints, scaledFontSize as scaleFontSize } from './LayoutStrategy.js';\n\n/**\n * Name of a color scheme defined in the active theme's `colorSchemes` map.\n * Templates reference schemes by name (e.g. 'blue', 'green') and the theme\n * resolves them to actual colors at render time via `resolveColorScheme()`.\n */\nexport type ColorScheme = string;\n\n/**\n * Default font family for doc text.\n * PT Serif provides a classic, readable appearance for documentary-style content.\n * Used as a fallback in TextLayer when no font is specified.\n */\nexport const DEFAULT_DOC_FONT = 'system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif';\n\n/**\n * Default font family for titles.\n */\nexport const DEFAULT_TITLE_FONT = 'Georgia, \"Times New Roman\", serif';\n\n// ============================================\n// Accent Image System\n// ============================================\n\n/**\n * Position options for accent images on text-based blocks.\n * Accents are tasteful image additions that complement rather than overwhelm text.\n */\nexport type AccentPosition =\n | 'left-strip' // Vertical strip on left (25-30% width), text shifts right\n | 'right-strip' // Vertical strip on right (25-30% width), text shifts left\n | 'bottom-strip' // Horizontal strip at bottom (25-30% height), text shifts up\n | 'corner-inset'; // Small inset image in corner with vignette edge\n\n/**\n * Accent image configuration for text-based blocks.\n * When present, the template adjusts layout to accommodate the image tastefully.\n */\nexport interface AccentImage {\n /** Path to image file (relative to article media dir) */\n src: string;\n /** Alt text for accessibility */\n alt: string;\n /** Where to position the accent image */\n position: AccentPosition;\n /** Ambient motion effect (subtle Ken Burns) */\n ambientMotion?: 'zoomIn' | 'zoomOut' | 'panLeft' | 'panRight';\n /** Photo credit / artist name */\n credit?: string;\n /** License identifier (e.g., 'CC BY-SA 4.0') */\n license?: string;\n}\n\n// ============================================\n// Template Input Types\n// ============================================\n\n/**\n * Base properties shared by all template blocks.\n */\ninterface BaseTemplateBlock {\n /** Unique block ID */\n id: string;\n /** Block duration in seconds */\n duration: number;\n /** Which audio segment this block belongs to */\n audioSegment: number;\n /** Entry transition */\n transition?: Transition;\n /** Show doc's bottom layers (default: true) */\n useBottomLayer?: boolean;\n /** Show doc's top layers (default: true) */\n useTopLayer?: boolean;\n /**\n * Start time within the audio segment when this content is spoken.\n * Used to sync the block appearance with the narration.\n * If not provided, blocks are distributed evenly across the segment.\n */\n sourceStartTime?: number;\n /**\n * Duration of the spoken content this block represents.\n * Used with sourceStartTime to precisely position the block.\n */\n sourceDuration?: number;\n}\n\n/**\n * Title block - doc intro with large title and subtitle.\n */\nexport interface TitleBlockInput extends BaseTemplateBlock {\n template: 'titleBlock';\n /** Main title text */\n title: string;\n /** Subtitle or tagline (supports \\n for line breaks) */\n subtitle?: string;\n /** Background color (defaults to theme primary) */\n backgroundColor?: string;\n}\n\n/**\n * Section header - section title card with optional background image.\n * Displays the section title prominently, optionally over an image.\n */\nexport interface SectionHeaderInput extends BaseTemplateBlock {\n template: 'sectionHeader';\n /** Section title */\n title: string;\n /** Color scheme for the section (used for fallback background) */\n colorScheme?: ColorScheme;\n /** Optional background image path */\n imageSrc?: string;\n /** Alt text for background image */\n imageAlt?: string;\n /** Ambient motion for background image */\n ambientMotion?: 'zoomIn' | 'zoomOut' | 'panLeft' | 'panRight';\n}\n\n/**\n * Stat highlight - big number with description and optional detail.\n */\nexport interface StatHighlightInput extends BaseTemplateBlock {\n template: 'statHighlight';\n /** The statistic (e.g., \"89%\", \"2x\", \"7 miles\") */\n stat: string;\n /** Description of what the stat means */\n description: string;\n /** Additional detail or context */\n detail?: string;\n /** Color scheme for the stat */\n colorScheme?: ColorScheme;\n /** Optional accent image to complement the text */\n accentImage?: AccentImage;\n}\n\n/**\n * Quote block - large centered quote text.\n */\nexport interface QuoteBlockInput extends BaseTemplateBlock {\n template: 'quoteBlock';\n /** The quote text (supports \\n for line breaks) */\n quote: string;\n /** Attribution (author, source) */\n attribution?: string;\n /** Optional accent image to complement the text */\n accentImage?: AccentImage;\n}\n\n/**\n * Fact card - key fact with explanation.\n */\nexport interface FactCardInput extends BaseTemplateBlock {\n template: 'factCard';\n /** The main fact or statement */\n fact: string;\n /** Explanation or context */\n explanation: string;\n /** Optional source citation */\n source?: string;\n /** Optional accent image to complement the text */\n accentImage?: AccentImage;\n}\n\n/**\n * Two column - side-by-side comparison.\n */\nexport interface TwoColumnInput extends BaseTemplateBlock {\n template: 'twoColumn';\n /** Left column content */\n left: {\n label: string;\n sublabel?: string;\n };\n /** Right column content */\n right: {\n label: string;\n sublabel?: string;\n };\n /** Optional header above columns */\n header?: string;\n /** Color schemes for left and right */\n leftColor?: ColorScheme;\n rightColor?: ColorScheme;\n}\n\n/**\n * Date event - timeline-style date with description.\n */\nexport interface DateEventInput extends BaseTemplateBlock {\n template: 'dateEvent';\n /** The date (e.g., \"July 14, 1974\") */\n date: string;\n /** Description of what happened (supports \\n) */\n description: string;\n /** Optional footer text */\n footer?: string;\n /** Mood: 'neutral', 'somber', 'celebratory' */\n mood?: 'neutral' | 'somber' | 'celebratory';\n /** Optional accent image to complement the text */\n accentImage?: AccentImage;\n}\n\n/**\n * Image with caption - background image with text overlay.\n */\nexport interface ImageWithCaptionInput extends BaseTemplateBlock {\n template: 'imageWithCaption';\n /** Path to image file */\n imageSrc: string;\n /** Alt text for accessibility */\n imageAlt: string;\n /** Caption text */\n caption?: string;\n /** Caption position */\n captionPosition?: 'bottom' | 'top' | 'center';\n /** Ambient motion effect: slow zoom or pan for visual interest */\n ambientMotion?: 'zoomIn' | 'zoomOut' | 'panLeft' | 'panRight';\n /** When true, style caption as a title (larger, centered, prominent) */\n isTitle?: boolean;\n /** Optional subtitle shown below the title (only when isTitle is true) */\n subtitle?: string;\n /** Photo credit / artist name */\n imageCredit?: string;\n /** License identifier (e.g., 'CC BY-SA 4.0') */\n imageLicense?: string;\n}\n\n/**\n * Map block - geographic map showing article location.\n *\n * Displays a map centered on given coordinates with optional title,\n * caption, and markers. Great for establishing geographic context.\n * See docs/MAP_TILES.md for available tile styles and attribution.\n */\nexport interface MapBlockInput extends BaseTemplateBlock {\n template: 'mapBlock';\n /** Map center coordinates */\n center: {\n lat: number;\n lng: number;\n };\n /** Zoom level (4-16, typically 8-12 for regional context) */\n zoom: number;\n /** Map tile style (default: 'terrain') */\n mapStyle?: MapTileStyle;\n /** Optional title overlay at top */\n title?: string;\n /** Optional caption at bottom */\n caption?: string;\n /** Optional markers to show on map */\n markers?: MapMarker[];\n /** Ambient motion effect: slow zoom or pan for visual interest */\n ambientMotion?: 'zoomIn' | 'zoomOut' | 'panLeft' | 'panRight';\n /** Pre-rendered static image path (set by prerender-maps command) */\n staticSrc?: string;\n}\n\n/**\n * Full-bleed quote - dramatic short text filling the viewport.\n * Like a movie title card. For short, punchy sentences < 60 chars.\n */\nexport interface FullBleedQuoteInput extends BaseTemplateBlock {\n template: 'fullBleedQuote';\n /** Short dramatic text (< 60 chars recommended) */\n text: string;\n /** Color scheme for text tint */\n colorScheme?: ColorScheme;\n}\n\n/**\n * List block - 3-5 items stacked vertically with subtle numbering.\n * Good for enumerations like \"things to see\" or \"key features\".\n */\nexport interface ListBlockInput extends BaseTemplateBlock {\n template: 'listBlock';\n /** List items (3-5 recommended) */\n items: string[];\n /** Optional header above the list */\n title?: string;\n /** Color scheme for numbering accents */\n colorScheme?: ColorScheme;\n /** Optional accent image */\n accentImage?: AccentImage;\n}\n\n/**\n * Photo grid - 2-4 images in a tiled layout.\n * Used when multiple images are available for visual variety.\n */\nexport interface PhotoGridInput extends BaseTemplateBlock {\n template: 'photoGrid';\n /** Images to display (2-4) */\n images: { src: string; alt: string; credit?: string; license?: string }[];\n /** Optional caption below the grid */\n caption?: string;\n /** Ambient motion effect for the largest image */\n ambientMotion?: 'zoomIn' | 'zoomOut' | 'panLeft' | 'panRight';\n}\n\n/**\n * Definition card - dictionary-style term with definition.\n * Large term at top, definition below, optional origin note.\n */\nexport interface DefinitionCardInput extends BaseTemplateBlock {\n template: 'definitionCard';\n /** The term being defined */\n term: string;\n /** The definition text */\n definition: string;\n /** Optional etymology or origin note */\n origin?: string;\n /** Color scheme for term accent */\n colorScheme?: ColorScheme;\n /** Optional accent image */\n accentImage?: AccentImage;\n}\n\n/**\n * Comparison bar - two horizontal bars showing relative numeric values.\n * Good for side-by-side numeric comparisons with visual weight.\n */\nexport interface ComparisonBarInput extends BaseTemplateBlock {\n template: 'comparisonBar';\n /** Left bar label */\n leftLabel: string;\n /** Left bar numeric value */\n leftValue: number;\n /** Right bar label */\n rightLabel: string;\n /** Right bar numeric value */\n rightValue: number;\n /** Unit label (e.g., \"km\", \"people\") */\n unit?: string;\n /** Color scheme */\n colorScheme?: ColorScheme;\n}\n\n/**\n * Pull quote - quote text over a full-bleed background image with dark overlay.\n * Cinematic alternative to quoteBlock when a high-quality image is available.\n */\nexport interface PullQuoteInput extends BaseTemplateBlock {\n template: 'pullQuote';\n /** Quote text */\n text: string;\n /** Optional attribution */\n attribution?: string;\n /** Background image (fills entire viewport) */\n backgroundImage: { src: string; alt: string; credit?: string; license?: string };\n /** Ambient motion for background image */\n ambientMotion?: 'zoomIn' | 'zoomOut' | 'panLeft' | 'panRight';\n}\n\n/**\n * Video with caption - background video clip with text overlay.\n * Plays a short clip from a source video, always muted (narration is the audio track).\n * Mirrors ImageWithCaptionInput but with video-specific fields.\n */\nexport interface VideoWithCaptionInput extends BaseTemplateBlock {\n template: 'videoWithCaption';\n /** Path to video file */\n videoSrc: string;\n /** Path to poster frame (shown before video loads) */\n posterSrc?: string;\n /** Alt text for accessibility */\n videoAlt: string;\n /** Start time within source video (seconds) */\n clipStart: number;\n /** End time within source video (seconds) */\n clipEnd: number;\n /** Source video total duration (for validation) */\n sourceDuration?: number;\n /** Caption text overlay */\n caption?: string;\n /** Caption position */\n captionPosition?: 'bottom' | 'top' | 'center';\n /** Video credit / artist name */\n videoCredit?: string;\n /** License identifier */\n videoLicense?: string;\n}\n\n/**\n * Video pull quote - quote text over a video clip background with dark overlay.\n * Cinematic alternative to pullQuote when a video clip is available.\n */\nexport interface VideoPullQuoteInput extends BaseTemplateBlock {\n template: 'videoPullQuote';\n /** Quote text */\n text: string;\n /** Optional attribution */\n attribution?: string;\n /** Background video clip */\n backgroundVideo: {\n src: string;\n posterSrc?: string;\n alt: string;\n clipStart: number;\n clipEnd: number;\n credit?: string;\n license?: string;\n };\n}\n\n/**\n * Data table - renders a themed table with headers and rows.\n * Ideal for structured data, comparisons, and reference information.\n */\nexport interface DataTableInput extends BaseTemplateBlock {\n template: 'dataTable';\n /** Optional title displayed above the table */\n title?: string;\n /** Header cell values */\n headers: string[];\n /** Data rows (array of cell value arrays) */\n rows: string[][];\n /** Per-column alignment */\n align?: (('left' | 'right' | 'center') | null)[];\n /** Color scheme for the table header */\n colorScheme?: ColorScheme;\n}\n\n/**\n * Union of all template block types.\n */\nexport type TemplateBlock =\n | TitleBlockInput\n | SectionHeaderInput\n | StatHighlightInput\n | QuoteBlockInput\n | FactCardInput\n | TwoColumnInput\n | DateEventInput\n | ImageWithCaptionInput\n | MapBlockInput\n | FullBleedQuoteInput\n | ListBlockInput\n | PhotoGridInput\n | DefinitionCardInput\n | ComparisonBarInput\n | PullQuoteInput\n | VideoWithCaptionInput\n | VideoPullQuoteInput\n | DataTableInput;\n\n/**\n * A block can be either a raw Block or a TemplateBlock.\n */\nexport type DocBlock = Block | TemplateBlock;\n\n/**\n * Check if a block is a template block.\n */\nexport function isTemplateBlock(block: DocBlock): block is TemplateBlock {\n return 'template' in block && typeof block.template === 'string';\n}\n\n// ============================================\n// Template Function Type\n// ============================================\n\n/**\n * Template context passed to template functions.\n * Includes viewport information for multi-aspect ratio support.\n */\nexport interface TemplateContext {\n /** Full theme (colors, typography, style, renderStyle, colorSchemes) */\n theme: Theme;\n /** Block index in the doc */\n blockIndex: number;\n /** Total number of blocks */\n totalBlocks: number;\n /** Target viewport configuration */\n viewport: ViewportConfig;\n /** Computed font scale factor for this viewport */\n fontScale: number;\n /** Viewport orientation (landscape, portrait, square) */\n orientation: ViewportOrientation;\n /** Layout hints for this orientation */\n layout: LayoutHints;\n}\n\n/**\n * Create a template context with viewport-derived values.\n */\nexport function createTemplateContext(\n theme: Theme,\n blockIndex: number,\n totalBlocks: number,\n viewport: ViewportConfig = VIEWPORT_PRESETS.landscape,\n): TemplateContext {\n const orientation = getViewportOrientation(viewport);\n return {\n theme,\n blockIndex,\n totalBlocks,\n viewport,\n fontScale: calculateFontScale(viewport),\n orientation,\n layout: getLayoutHints(orientation),\n };\n}\n\n/**\n * Calculate a scaled font size for the given context.\n * Use this in templates to ensure text scales appropriately.\n *\n * @param basePx - Base font size in pixels (designed for 1920x1080)\n * @param context - Template context with viewport info\n * @param isTitle - Whether this is title text (larger scale) or body text\n */\nexport function scaledFontSize(\n basePx: number,\n context: TemplateContext,\n isTitle: boolean = false,\n): number {\n return scaleFontSize(basePx, context.viewport, context.orientation, isTitle);\n}\n\n/**\n * Template function signature.\n * Takes template input and returns layers array.\n */\nexport type TemplateFunction<T extends TemplateBlock> = (\n input: T,\n context: TemplateContext,\n) => Layer[];\n\n/**\n * Registry of all template functions.\n */\nexport type TemplateRegistry = {\n [K in TemplateBlock['template']]: TemplateFunction<Extract<TemplateBlock, { template: K }>>;\n};\n\n// ============================================\n// Persistent Layer System\n// ============================================\n\n/**\n * Configuration for persistent doc-wide layers.\n * Bottom layers render behind all block content, top layers on top.\n */\nexport interface PersistentLayerConfig {\n /** Layers rendered behind all block content */\n bottomLayers?: PersistentLayer[];\n /** Layers rendered on top of all block content */\n topLayers?: PersistentLayer[];\n}\n\n/**\n * A persistent layer - either a template or raw Layer.\n */\nexport type PersistentLayer = PersistentLayerTemplate | Layer;\n\n/**\n * Check if a persistent layer is a template.\n */\nexport function isPersistentLayerTemplate(\n layer: PersistentLayer,\n): layer is PersistentLayerTemplate {\n return 'template' in layer && typeof layer.template === 'string';\n}\n\n/**\n * Template-based persistent layer for easy configuration.\n */\nexport interface PersistentLayerTemplate {\n template: PersistentLayerTemplateType;\n config: PersistentLayerTemplateConfig;\n}\n\n/**\n * Available persistent layer template types.\n */\nexport type PersistentLayerTemplateType =\n | 'solidBackground' // Solid color fill\n | 'gradientBackground' // CSS gradient or preset\n | 'imageBackground' // Blurred/faded hero image\n | 'patternBackground' // Subtle pattern (dots, grid)\n | 'titleCaption' // Article title in corner\n | 'cornerBranding' // Logo or text badge\n | 'progressIndicator'; // Bar/dots showing position\n\n/**\n * Union of all persistent layer template configs.\n */\nexport type PersistentLayerTemplateConfig =\n | SolidBackgroundConfig\n | GradientBackgroundConfig\n | ImageBackgroundConfig\n | PatternBackgroundConfig\n | TitleCaptionConfig\n | CornerBrandingConfig\n | ProgressIndicatorConfig;\n\n// ============================================\n// Background Layer Configs\n// ============================================\n\n/**\n * Solid color background.\n */\nexport interface SolidBackgroundConfig {\n type: 'solidBackground';\n /** CSS color value */\n color: string;\n}\n\n/**\n * Gradient background (CSS gradient or preset).\n */\nexport interface GradientBackgroundConfig {\n type: 'gradientBackground';\n /** Custom CSS gradient string */\n gradient?: string;\n /** Preset gradient name */\n preset?: 'dark-vignette' | 'radial-dark' | 'warm-sunset' | 'cool-blue' | 'earth-tones';\n}\n\n/**\n * Image background (blurred/faded hero image).\n */\nexport interface ImageBackgroundConfig {\n type: 'imageBackground';\n /** Path to image file */\n src: string;\n /** Blur radius in pixels (0-20) */\n blur?: number;\n /** Opacity (0-1) */\n opacity?: number;\n /** Ambient motion effect */\n ambientMotion?: 'zoomIn' | 'zoomOut' | 'panLeft' | 'panRight';\n}\n\n/**\n * Pattern background (subtle repeating pattern).\n */\nexport interface PatternBackgroundConfig {\n type: 'patternBackground';\n /** Pattern type */\n pattern: 'dots' | 'grid' | 'diagonal' | 'noise';\n /** Pattern color */\n color?: string;\n /** Pattern opacity (0-1) */\n opacity?: number;\n /** Pattern scale multiplier */\n scale?: number;\n}\n\n// ============================================\n// Overlay Layer Configs\n// ============================================\n\n/**\n * Title caption overlay (article title in corner).\n */\nexport interface TitleCaptionConfig {\n type: 'titleCaption';\n /** Title text */\n title: string;\n /** Subtitle text (e.g., short URL like \"qual..la/slug\") */\n subtitle?: string;\n /** Position on screen */\n position: 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right';\n /** Font size in pixels (default: 18) */\n fontSize?: number;\n /** Show thumbnail alongside title */\n showThumbnail?: boolean;\n /** Thumbnail image path */\n thumbnailSrc?: string;\n}\n\n/**\n * Corner branding overlay (logo or text badge).\n */\nexport interface CornerBrandingConfig {\n type: 'cornerBranding';\n /** Text content or image path */\n content: string;\n /** Position on screen */\n position: 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right';\n /** Whether content is an image path (vs text) */\n isImage?: boolean;\n}\n\n/**\n * Progress indicator overlay (bar or dots showing position).\n */\nexport interface ProgressIndicatorConfig {\n type: 'progressIndicator';\n /** Indicator style */\n style: 'bar' | 'dots' | 'fraction';\n /** Position on screen */\n position: 'bottom' | 'top';\n /** Indicator color */\n color?: string;\n}\n","/**\n * Markdown Tree Utilities\n *\n * Helper functions for traversing and querying the MarkdownDocument tree.\n * All functions are pure and operate on the JSON node interfaces.\n */\n\nimport type { MarkdownNode, MarkdownDocument } from './types.js';\n\n/**\n * Get the children of any markdown node, if it has children.\n * Returns an empty array for leaf nodes (text, code, break, etc.).\n *\n * This is useful for generic tree walking where you don't want to\n * check the specific node type.\n */\nexport function getChildren(node: MarkdownNode): MarkdownNode[] {\n if ('children' in node && Array.isArray(node.children)) {\n return node.children as MarkdownNode[];\n }\n return [];\n}\n\n/**\n * Walk the markdown tree depth-first, calling the visitor for each node.\n *\n * The visitor receives the current node and its parent. Return `true`\n * from the visitor to skip the node's children (prune).\n *\n * @param node - The root node to start walking from\n * @param visitor - Called for each node; return true to skip children\n * @param parent - (internal) Parent node\n */\nexport function walkMarkdownTree(\n node: MarkdownNode,\n visitor: (node: MarkdownNode, parent?: MarkdownNode) => void | boolean,\n parent?: MarkdownNode,\n): void {\n const skip = visitor(node, parent);\n if (skip === true) return;\n\n const children = getChildren(node);\n for (const child of children) {\n walkMarkdownTree(child, visitor, node);\n }\n}\n\n/**\n * Find all nodes of a specific type in the tree.\n *\n * @param root - The document or node to search within\n * @param type - The node type to find (e.g., 'heading', 'link', 'text')\n * @returns Array of matching nodes\n *\n * @example\n * ```ts\n * const headings = findNodesByType(doc, 'heading');\n * const links = findNodesByType(doc, 'link');\n * ```\n */\nexport function findNodesByType<T extends MarkdownNode>(root: MarkdownNode, type: T['type']): T[] {\n const results: T[] = [];\n walkMarkdownTree(root, (node) => {\n if (node.type === type) {\n results.push(node as T);\n }\n });\n return results;\n}\n\n/**\n * Extract all plain text content from a node and its descendants.\n * Concatenates text values, ignoring formatting, links, etc.\n *\n * @param node - The node to extract text from\n * @returns Plain text content\n *\n * @example\n * ```ts\n * const heading = doc.children[0]; // { type: 'heading', children: [{ type: 'text', value: 'Hello' }] }\n * extractPlainText(heading); // 'Hello'\n * ```\n */\nexport function extractPlainText(node: MarkdownNode): string {\n if ('value' in node && typeof node.value === 'string') {\n return node.value;\n }\n\n const children = getChildren(node);\n return children.map(extractPlainText).join('');\n}\n\n/**\n * Count the total number of nodes in the tree.\n *\n * @param node - The root node\n * @returns Total node count (including the root)\n */\nexport function countNodes(node: MarkdownNode): number {\n let count = 1;\n const children = getChildren(node);\n for (const child of children) {\n count += countNodes(child);\n }\n return count;\n}\n\n/**\n * Parse a YAML frontmatter string into a key-value record.\n *\n * Handles simple `key: value` pairs common in markdown frontmatter.\n * Values are trimmed; quoted strings have their quotes removed.\n * Returns `null` if parsing fails or the input is empty.\n *\n * @param yaml - The raw YAML string (without the `---` delimiters)\n * @returns A record of string keys to parsed values, or null\n */\nexport function parseFrontmatter(yaml: string): Record<string, unknown> | null {\n if (!yaml || !yaml.trim()) return null;\n\n const result: Record<string, unknown> = {};\n\n for (const line of yaml.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n\n const colonIdx = trimmed.indexOf(':');\n if (colonIdx < 1) continue;\n\n const key = trimmed.slice(0, colonIdx).trim();\n let value: string | boolean | number = trimmed.slice(colonIdx + 1).trim();\n\n // Remove surrounding quotes\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1);\n }\n\n // Parse booleans and numbers\n if (value === 'true') {\n result[key] = true;\n } else if (value === 'false') {\n result[key] = false;\n } else if (value !== '' && !isNaN(Number(value))) {\n result[key] = Number(value);\n } else {\n result[key] = value;\n }\n }\n\n return Object.keys(result).length > 0 ? result : null;\n}\n\n/**\n * Create a minimal MarkdownDocument from a list of block nodes.\n * Convenience function for programmatic document construction.\n */\nexport function createDocument(...children: MarkdownDocument['children']): MarkdownDocument {\n return {\n type: 'document',\n children,\n };\n}\n","/**\n * Persistent Layers Expansion\n *\n * Expands persistent layer templates (solid backgrounds, gradients, overlays)\n * into raw Layer arrays. These layers are injected into each block based on\n * per-block flags (useBottomLayer, useTopLayer).\n *\n * This is shared code used by both site and efb-app doc renderers.\n *\n * Related Files:\n * - schemas/BlockTemplates.ts - PersistentLayerConfig types\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type {\n PersistentLayer,\n PersistentLayerTemplate,\n PersistentLayerConfig,\n SolidBackgroundConfig,\n GradientBackgroundConfig,\n ImageBackgroundConfig,\n PatternBackgroundConfig,\n TitleCaptionConfig,\n CornerBrandingConfig,\n ProgressIndicatorConfig,\n} from '../../schemas/BlockTemplates.js';\nimport type { Theme } from '../../schemas/Theme.js';\nimport { isPersistentLayerTemplate } from '../../schemas/BlockTemplates.js';\n\n// ============================================\n// Gradient Presets\n// ============================================\n\nconst GRADIENT_PRESETS: Record<string, string> = {\n 'dark-vignette':\n 'radial-gradient(ellipse at center, rgba(26,32,44,0.8) 0%, rgba(0,0,0,0.95) 100%)',\n 'radial-dark': 'radial-gradient(ellipse at center, #1a202c 0%, #000000 100%)',\n 'warm-sunset': 'linear-gradient(135deg, rgba(124,58,48,0.9) 0%, rgba(26,32,44,0.95) 100%)',\n 'cool-blue': 'linear-gradient(135deg, rgba(26,54,93,0.9) 0%, rgba(26,32,44,0.95) 100%)',\n 'earth-tones': 'linear-gradient(135deg, rgba(68,51,34,0.9) 0%, rgba(26,32,44,0.95) 100%)',\n};\n\n// ============================================\n// Background Layer Expansion\n// ============================================\n\n/**\n * Expand a solid background config to a Layer.\n */\nfunction expandSolidBackground(config: SolidBackgroundConfig): Layer {\n return {\n type: 'shape',\n id: 'persistent-bg-solid',\n content: {\n shape: 'rect',\n fill: config.color,\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n };\n}\n\n/**\n * Expand a gradient background config to a Layer.\n */\nfunction expandGradientBackground(config: GradientBackgroundConfig): Layer {\n const gradient = config.gradient ?? GRADIENT_PRESETS[config.preset ?? 'dark-vignette'];\n\n return {\n type: 'shape',\n id: 'persistent-bg-gradient',\n content: {\n shape: 'rect',\n fill: gradient,\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n };\n}\n\n/**\n * Expand an image background config to Layers.\n * Returns multiple layers: base image + dark overlay for readability.\n */\nfunction expandImageBackground(config: ImageBackgroundConfig): Layer[] {\n const layers: Layer[] = [];\n const opacity = config.opacity ?? 0.4;\n\n // Base image layer\n const imageLayer: Layer = {\n type: 'image',\n id: 'persistent-bg-image',\n content: {\n src: config.src,\n alt: 'Background',\n fit: 'cover',\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n animation: config.ambientMotion\n ? {\n type: config.ambientMotion,\n duration: 30, // Long ambient motion\n }\n : undefined,\n };\n\n layers.push(imageLayer);\n\n // Add dark overlay for text readability\n layers.push({\n type: 'shape',\n id: 'persistent-bg-overlay',\n content: {\n shape: 'rect',\n fill: `rgba(0,0,0,${0.5 + (1 - opacity) * 0.3})`,\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n });\n\n return layers;\n}\n\n/**\n * Expand a pattern background config to a Layer.\n */\nfunction expandPatternBackground(config: PatternBackgroundConfig): Layer {\n const opacity = config.opacity ?? 0.1;\n const color = config.color ?? `rgba(255,255,255,${opacity})`;\n\n // Pattern as SVG data URI for rect patterns\n // For simplicity, use a solid subtle color with reduced opacity\n return {\n type: 'shape',\n id: 'persistent-bg-pattern',\n content: {\n shape: 'rect',\n fill: color,\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n };\n}\n\n// ============================================\n// Overlay Layer Expansion\n// ============================================\n\n/**\n * Expand a title caption config to Layers.\n */\nfunction expandTitleCaption(config: TitleCaptionConfig): Layer[] {\n const layers: Layer[] = [];\n const fontSize = config.fontSize ?? 18;\n const hasSubtitle = !!config.subtitle;\n\n // Position calculations\n const isBottom = config.position.includes('bottom');\n const isLeft = config.position.includes('left');\n\n // Even padding around the pill (3% from edges)\n const pad = 3; // percent\n\n // Pill dimensions — taller when subtitle present\n const pillHeight = hasSubtitle ? '15%' : '7%';\n // Position above player controls\n const bgYPos = isBottom ? (hasSubtitle ? '78%' : '84%') : '2%';\n const bgXPos = isLeft ? `${pad}%` : '68%';\n\n // Thumbnail sizing — use different width/height to appear square in 16:9 viewport\n // In 16:9, 6% of width ≈ 10.7% of height in pixels, so use ~6%w x 10%h for visual square\n const thumbW = hasSubtitle ? '6%' : '5%';\n const thumbH = hasSubtitle ? '10%' : '5%';\n const thumbPad = 1.5; // padding inside pill around thumbnail (percent)\n\n // Text X offset: after thumbnail + padding, or just pill padding\n const textX =\n config.showThumbnail && isLeft\n ? `${pad + thumbPad + 6 + thumbPad}%` // pill edge + thumb padding + thumb width + gap\n : `${pad + thumbPad}%`;\n // Text area width: pill width minus thumbnail area minus padding\n const textWidth = config.showThumbnail\n ? '19%' // narrower when thumbnail takes space\n : '24%';\n\n // Title Y: top of text area inside pill\n const titleYPos = isBottom ? (hasSubtitle ? '80%' : '86%') : '4%';\n\n // Background pill for readability\n layers.push({\n type: 'shape',\n id: 'persistent-caption-bg',\n content: {\n shape: 'rect',\n fill: 'rgba(0,0,0,0.6)',\n borderRadius: 8,\n },\n position: {\n x: bgXPos,\n y: bgYPos,\n width: config.showThumbnail ? '30%' : '28%',\n height: pillHeight,\n },\n });\n\n // Thumbnail if configured\n if (config.showThumbnail && config.thumbnailSrc) {\n const thumbX = isLeft ? `${pad + thumbPad}%` : '93%';\n // Center thumbnail vertically in pill\n const thumbY = isBottom ? (hasSubtitle ? `${78 + thumbPad}%` : '85%') : '3%';\n\n layers.push({\n type: 'image',\n id: 'persistent-caption-thumb',\n content: {\n src: config.thumbnailSrc,\n alt: 'Article thumbnail',\n fit: 'cover',\n },\n position: {\n x: thumbX,\n y: thumbY,\n width: thumbW,\n height: thumbH,\n },\n });\n }\n\n // Title text — single line, cropped with ellipsis\n layers.push({\n type: 'text',\n id: 'persistent-caption-title',\n content: {\n text: config.title,\n style: {\n fontSize,\n fontWeight: 'bold',\n color: 'rgba(255,255,255,0.9)',\n textAlign: isLeft ? 'left' : 'right',\n maxLines: 1,\n },\n },\n position: {\n x: textX,\n y: titleYPos,\n width: textWidth,\n },\n });\n\n // Subtitle text (e.g., short URL)\n if (hasSubtitle) {\n const subtitleYPos = isBottom ? '85.5%' : '8%';\n\n layers.push({\n type: 'text',\n id: 'persistent-caption-subtitle',\n content: {\n text: config.subtitle!,\n style: {\n fontSize: 18,\n fontWeight: 'normal',\n color: 'rgba(255,255,255,0.55)',\n textAlign: isLeft ? 'left' : 'right',\n },\n },\n position: {\n x: textX,\n y: subtitleYPos,\n width: textWidth,\n },\n });\n }\n\n return layers;\n}\n\n/**\n * Expand a corner branding config to a Layer.\n */\nfunction expandCornerBranding(config: CornerBrandingConfig): Layer {\n const isBottom = config.position.includes('bottom');\n const isLeft = config.position.includes('left');\n\n const xPos = isLeft ? '3%' : '90%';\n const yPos = isBottom ? '94%' : '3%';\n\n if (config.isImage) {\n return {\n type: 'image',\n id: 'persistent-branding',\n content: {\n src: config.content,\n alt: 'Branding',\n fit: 'contain',\n },\n position: {\n x: xPos,\n y: yPos,\n width: '8%',\n height: '4%',\n },\n };\n }\n\n return {\n type: 'text',\n id: 'persistent-branding',\n content: {\n text: config.content,\n style: {\n fontSize: 14,\n fontWeight: 'normal',\n color: 'rgba(255,255,255,0.6)',\n },\n },\n position: {\n x: xPos,\n y: yPos,\n },\n };\n}\n\n/**\n * Expand a progress indicator config to a Layer.\n * Note: Progress requires block context, returns placeholder bar.\n */\nfunction expandProgressIndicator(config: ProgressIndicatorConfig): Layer {\n const color = config.color ?? 'rgba(255,255,255,0.3)';\n const y = config.position === 'top' ? '1%' : '98%';\n\n // Simple bar style - actual progress would need to be set per-block\n return {\n type: 'shape',\n id: 'persistent-progress',\n content: {\n shape: 'rect',\n fill: color,\n borderRadius: 2,\n },\n position: {\n x: '5%',\n y,\n width: '90%',\n height: '0.5%',\n },\n };\n}\n\n// ============================================\n// Main Expansion Function\n// ============================================\n\n/**\n * Expand a single persistent layer (template or raw) to raw Layer(s).\n */\nexport function expandPersistentLayer(layer: PersistentLayer): Layer[] {\n // If already a raw Layer, return as-is\n if (!isPersistentLayerTemplate(layer)) {\n return [layer as Layer];\n }\n\n const template = layer as PersistentLayerTemplate;\n const config = template.config;\n\n switch (config.type) {\n case 'solidBackground':\n return [expandSolidBackground(config)];\n case 'gradientBackground':\n return [expandGradientBackground(config)];\n case 'imageBackground':\n return expandImageBackground(config);\n case 'patternBackground':\n return [expandPatternBackground(config)];\n case 'titleCaption':\n return expandTitleCaption(config);\n case 'cornerBranding':\n return [expandCornerBranding(config)];\n case 'progressIndicator':\n return [expandProgressIndicator(config)];\n default:\n console.warn('Unknown persistent layer template:', (config as Record<string, unknown>).type);\n return [];\n }\n}\n\n/**\n * Expand all persistent layers in a config to raw Layer arrays.\n */\nexport function expandPersistentLayers(layers: PersistentLayer[] | undefined): Layer[] {\n if (!layers || layers.length === 0) {\n return [];\n }\n\n // Use reduce+concat instead of flatMap for Coherent GT compatibility (ES2017)\n return layers.reduce<Layer[]>((acc, layer) => acc.concat(expandPersistentLayer(layer)), []);\n}\n\n// ============================================\n// Style Presets (legacy helper — prefer theme.persistentLayers)\n// ============================================\n\n/** Legacy style preset names. Prefer using `Theme.persistentLayers` directly. */\nexport type DocStylePreset = 'minimal' | 'documentary' | 'branded' | 'cinematic' | 'clean';\n\n/**\n * Get a PersistentLayerConfig from a style preset.\n *\n * @param preset - Style preset name\n * @param articleTitle - Article title for title caption\n * @param heroSrc - Optional hero image for cinematic style\n */\nexport function getDocStyleConfig(\n preset: DocStylePreset,\n articleTitle: string,\n heroSrc?: string,\n subtitle?: string,\n): PersistentLayerConfig {\n switch (preset) {\n case 'minimal':\n return {};\n\n case 'documentary':\n return {\n bottomLayers: [\n {\n template: 'gradientBackground',\n config: { type: 'gradientBackground', preset: 'dark-vignette' },\n },\n ],\n topLayers: [\n {\n template: 'titleCaption',\n config: {\n type: 'titleCaption',\n title: articleTitle,\n subtitle,\n position: 'bottom-left',\n fontSize: 24,\n showThumbnail: !!heroSrc,\n thumbnailSrc: heroSrc,\n },\n },\n ],\n };\n\n case 'branded':\n return {\n bottomLayers: [\n {\n template: 'gradientBackground',\n config: { type: 'gradientBackground', preset: 'cool-blue' },\n },\n ],\n topLayers: [\n {\n template: 'titleCaption',\n config: {\n type: 'titleCaption',\n title: articleTitle,\n subtitle,\n position: 'bottom-left',\n fontSize: 26,\n showThumbnail: !!heroSrc,\n thumbnailSrc: heroSrc,\n },\n },\n ],\n };\n\n case 'cinematic':\n return {\n bottomLayers: heroSrc\n ? [\n {\n template: 'imageBackground',\n config: {\n type: 'imageBackground',\n src: heroSrc,\n blur: 12,\n opacity: 0.3,\n ambientMotion: 'zoomIn',\n },\n },\n ]\n : [\n {\n template: 'gradientBackground',\n config: { type: 'gradientBackground', preset: 'radial-dark' },\n },\n ],\n topLayers: [\n {\n template: 'titleCaption',\n config: {\n type: 'titleCaption',\n title: articleTitle,\n subtitle,\n position: 'bottom-right',\n fontSize: 22,\n },\n },\n ],\n };\n\n case 'clean':\n return {\n bottomLayers: [\n {\n template: 'solidBackground',\n config: { type: 'solidBackground', color: '#1a202c' },\n },\n ],\n };\n\n default:\n return {};\n }\n}\n\n/**\n * Get persistent layers from a Theme. Returns the theme's baked-in\n * persistentLayers config, or an empty config when the theme has none.\n */\nexport function getPersistentLayersFromTheme(theme: Theme): PersistentLayerConfig {\n return theme.persistentLayers ?? {};\n}\n","/**\n * Theme Utilities\n *\n * Template-facing helpers that read from the Theme object on the\n * TemplateContext. Templates call these instead of hard-coding style\n * decisions, so the same template code adapts to any theme.\n */\n\nimport type { TemplateContext } from '../../schemas/BlockTemplates.js';\nimport type { ThemeColorScheme, RenderStyle } from '../../schemas/Theme.js';\nimport type { AnimationType } from '../../schemas/Doc.js';\n\n// ============================================\n// Color Scheme Resolution\n// ============================================\n\n/** Fallback color scheme when a name is not found in the theme. */\nconst FALLBACK_COLOR_SCHEME: ThemeColorScheme = {\n bg: '#1a365d',\n text: '#63b3ed',\n accent: '#90cdf4',\n};\n\n/**\n * Resolve a named color scheme from the theme, with a safe fallback.\n * Templates call this instead of `COLOR_SCHEMES[name]`.\n */\nexport function resolveColorScheme(\n context: TemplateContext,\n name: string | undefined,\n): ThemeColorScheme {\n const schemes = context.theme.colorSchemes;\n if (name && name in schemes) return schemes[name];\n // Fall back to first defined scheme, then hard fallback\n const keys = Object.keys(schemes);\n if (keys.length > 0) return schemes[keys[0]];\n return FALLBACK_COLOR_SCHEME;\n}\n\n// ============================================\n// Font Family Resolution\n// ============================================\n\n/** Safe system font fallbacks. */\nconst FALLBACK_BODY = 'system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif';\nconst FALLBACK_TITLE = 'Georgia, \"Times New Roman\", serif';\nconst FALLBACK_MONO = 'Consolas, \"Courier New\", monospace';\n\n/**\n * Get the theme font family for a given role.\n * Templates call this to set `fontFamily` on text layers.\n *\n * @param context Template context (includes theme with typography settings)\n * @param role 'title' for headings, 'body' for descriptions, 'mono' for code\n * @returns A CSS font-family string with the theme's font and safe fallbacks\n */\nexport function getThemeFont(context: TemplateContext, role: 'title' | 'body' | 'mono'): string {\n const { typography } = context.theme;\n switch (role) {\n case 'title':\n return typography.titleFontFamily || FALLBACK_TITLE;\n case 'body':\n return typography.bodyFontFamily || FALLBACK_BODY;\n case 'mono':\n return typography.monoFontFamily || FALLBACK_MONO;\n }\n}\n\n// ============================================\n// Font Sizing\n// ============================================\n\n/**\n * Calculate a theme-aware scaled font size.\n * Applies the theme's typography scale multipliers on top of the\n * viewport-based font scale from LayoutStrategy.\n *\n * @param basePx Base font size designed for 1920×1080\n * @param context Template context (includes fontScale, layout, theme)\n * @param isTitle Whether this is title text (uses titleScale) or body (bodyScale)\n */\nexport function themedFontSize(\n basePx: number,\n context: TemplateContext,\n isTitle: boolean = false,\n): number {\n const { fontScale, layout, theme } = context;\n\n // Base scale from viewport + orientation\n const layoutScale = isTitle ? layout.titleScale : layout.bodyScale;\n\n // Theme multiplier (defaults to 1.0 when not set)\n const themeScale = isTitle\n ? (theme.typography.titleScale ?? 1.0)\n : (theme.typography.bodyScale ?? 1.0);\n\n return Math.round(basePx * fontScale * layoutScale * themeScale);\n}\n\n// ============================================\n// Animation Helpers\n// ============================================\n\n/**\n * Scale an animation duration by the theme's animationSpeed multiplier.\n * A speed of 1.0 returns the base duration unchanged.\n */\nexport function scaleAnimationDuration(baseDuration: number, context: TemplateContext): number {\n const speed = context.theme.style.animationSpeed ?? 1.0;\n return baseDuration * speed;\n}\n\n/**\n * Get the theme's default animation type for a layer kind.\n * Returns `undefined` when the theme doesn't specify one (template picks its own).\n */\nexport function getDefaultAnimation(\n context: TemplateContext,\n layerType: 'text' | 'image',\n): AnimationType | undefined {\n const rs: RenderStyle = context.theme.renderStyle;\n return layerType === 'text' ? rs.defaultTextAnimation : rs.defaultImageAnimation;\n}\n\n// ============================================\n// Style Helpers\n// ============================================\n\n/**\n * Whether the theme defaults to text shadows.\n * Templates should consult this when choosing `shadow: true/false`.\n */\nexport function shouldUseShadow(context: TemplateContext): boolean {\n return context.theme.style.textShadow ?? true;\n}\n\n/**\n * Get the theme's overlay opacity for image-backed blocks.\n */\nexport function getOverlayOpacity(context: TemplateContext): number {\n return context.theme.style.overlayOpacity ?? 0.5;\n}\n\n// ============================================\n// Template Hint Access\n// ============================================\n\n/**\n * Read a per-template hint from the theme's renderStyle.\n * Returns `fallback` when the hint isn't defined.\n *\n * @example\n * ```ts\n * const entrance = getTemplateHint(context, 'statHighlight', 'entrance', 'subtle');\n * ```\n */\nexport function getTemplateHint<T extends string | number | boolean>(\n context: TemplateContext,\n templateName: string,\n key: string,\n fallback: T,\n): T {\n const hints = context.theme.renderStyle.templateHints;\n if (!hints) return fallback;\n const tplHints = hints[templateName];\n if (!tplHints || !(key in tplHints)) return fallback;\n return tplHints[key] as T;\n}\n","/**\n * Title Block Template\n *\n * Large title with optional subtitle for doc intros.\n * Centered text with fade-in animations.\n * Adapts font sizes and positioning for different viewports.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { TitleBlockInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { getThemeFont } from '../utils/themeUtils.js';\n\nexport function titleBlock(input: TitleBlockInput, context: TemplateContext): Layer[] {\n const { title, subtitle, backgroundColor } = input;\n const { theme, layout } = context;\n\n // Scale font sizes for viewport\n const titleFontSize = scaledFontSize(96, context, true);\n const subtitleFontSize = scaledFontSize(36, context, false);\n\n const baseBg = backgroundColor || theme.colors.primary;\n\n const layers: Layer[] = [\n // Background — radial gradient for depth instead of flat color\n {\n type: 'shape',\n id: 'bg',\n content: {\n shape: 'rect',\n fill: `radial-gradient(ellipse at 50% 40%, ${baseBg} 0%, ${theme.colors.background} 100%)`,\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n },\n // Subtle decorative line above title\n {\n type: 'shape',\n id: 'accent-line',\n content: {\n shape: 'rect',\n fill: 'rgba(255, 255, 255, 0.2)',\n },\n position: {\n x: '40%',\n y: subtitle ? '28%' : '38%',\n width: '20%',\n height: '2px',\n },\n },\n // Title\n {\n type: 'text',\n id: 'title',\n content: {\n text: title,\n style: {\n fontSize: titleFontSize,\n fontFamily: getThemeFont(context, 'title'),\n fontWeight: 'bold',\n color: theme.colors.text,\n textAlign: 'center',\n shadow: true,\n },\n },\n position: {\n x: '50%',\n y: subtitle ? layout.primaryY : '50%',\n anchor: 'center',\n width: layout.maxTextWidth,\n },\n animation: { type: 'fadeIn', duration: 2 },\n },\n ];\n\n // Add subtitle if provided\n if (subtitle) {\n layers.push({\n type: 'text',\n id: 'subtitle',\n content: {\n text: subtitle,\n style: {\n fontSize: subtitleFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.textMuted,\n textAlign: 'center',\n lineHeight: 1.5,\n },\n },\n position: {\n x: '50%',\n y: layout.secondaryY,\n anchor: 'center',\n width: layout.maxTextWidth,\n },\n animation: { type: 'fadeIn', duration: 1.5, delay: 1 },\n });\n }\n\n return layers;\n}\n","/**\n * Section Header Template\n *\n * Section title card with optional background image.\n * Used to introduce new sections of a story.\n * When an image is provided, displays like a title slide with the image as background.\n * Without an image, falls back to a colored background.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer, AnimationType } from '../../schemas/Doc.js';\nimport type { SectionHeaderInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { resolveColorScheme, getThemeFont } from '../utils/themeUtils.js';\n\nexport function sectionHeader(input: SectionHeaderInput, context: TemplateContext): Layer[] {\n const { title = '', colorScheme = 'blue', imageSrc, imageAlt, ambientMotion } = input;\n const { layout } = context;\n const colors = resolveColorScheme(context, colorScheme);\n\n // Scale font sizes for viewport\n const titleFontSize = scaledFontSize(72, context, true);\n\n const layers: Layer[] = [];\n\n // Background - either image or solid color\n if (imageSrc) {\n // Image background with Ken Burns effect\n layers.push({\n type: 'image',\n id: 'bg-image',\n content: {\n src: imageSrc,\n alt: imageAlt || title,\n fit: 'cover',\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n animation: ambientMotion\n ? { type: ambientMotion as AnimationType, duration: 8 }\n : { type: 'slowZoom', duration: 8, direction: 'in' },\n });\n\n // Dark overlay for text readability\n layers.push({\n type: 'shape',\n id: 'overlay',\n content: {\n shape: 'rect',\n fill: 'rgba(0, 0, 0, 0.5)',\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n });\n } else {\n // Solid color background\n layers.push({\n type: 'shape',\n id: 'bg',\n content: {\n shape: 'rect',\n fill: colors.bg,\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n });\n\n // Decorative lines above and below title\n layers.push({\n type: 'shape',\n id: 'line-top',\n content: { shape: 'rect', fill: `${colors.text}33` },\n position: { x: '50%', y: '40%', width: '20%', height: '2px', anchor: 'center' },\n });\n layers.push({\n type: 'shape',\n id: 'line-bottom',\n content: { shape: 'rect', fill: `${colors.text}33` },\n position: { x: '50%', y: '60%', width: '20%', height: '2px', anchor: 'center' },\n });\n }\n\n // Section title - white text with shadow for readability over images\n layers.push({\n type: 'text',\n id: 'title',\n content: {\n text: title,\n style: {\n fontSize: titleFontSize,\n fontFamily: getThemeFont(context, 'title'),\n fontWeight: 'bold',\n color: imageSrc ? '#ffffff' : colors.text,\n textAlign: 'center',\n shadow: true,\n },\n },\n position: {\n x: '50%',\n y: '50%',\n anchor: 'center',\n width: layout.maxTextWidth,\n },\n animation: { type: 'fadeIn', duration: 1.5 },\n });\n\n return layers;\n}\n","/**\n * Accent Image Utility\n *\n * Creates image layers and layout adjustments for accent images on text-based slides.\n * Accent images are tasteful additions that complement text without overwhelming it.\n *\n * Layout patterns:\n * - left-strip: 35% width vertical strip on left, text area shifted to right 65%\n * - right-strip: 35% width vertical strip on right, text area shifted to left 65%\n * - bottom-strip: 35% height horizontal strip at bottom, text area in upper 65%\n * - corner-inset: Small 25% corner image with gradient vignette\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer, ImageLayer, ShapeLayer, Animation } from '../../schemas/Doc.js';\nimport type { AccentImage, AccentPosition } from '../../schemas/BlockTemplates.js';\n\nconst PERCENTAGE_RE = /^(\\d+(?:\\.\\d+)?)\\s*%?$/;\n\n/**\n * Layout adjustments when an accent image is present.\n * Templates use these values to reposition their text content.\n */\nexport interface AccentLayout {\n /** X offset for text center (e.g., '64%' for left-strip) */\n textCenterX: string;\n /** Width available for text content */\n textWidth: string;\n /** Y offset adjustment for vertical positioning */\n textYAdjust: number;\n /** Whether to adjust Y positions (for bottom-strip) */\n adjustY: boolean;\n}\n\n/**\n * Default layout when no accent image is present.\n */\nexport const DEFAULT_LAYOUT: AccentLayout = {\n textCenterX: '50%',\n textWidth: '85%',\n textYAdjust: 0,\n adjustY: false,\n};\n\n/**\n * Map ambientMotion values to proper Ken Burns animations.\n * Uses slowZoom variants which provide smooth pan/zoom without opacity changes.\n * Supports both standard values ('zoomIn', 'panLeft', etc.) and legacy\n * aliases ('in', 'out', 'left', 'right') for backward compatibility.\n *\n * @param motion - The ambient motion value (e.g., 'zoomIn', 'panLeft')\n * @param duration - Optional animation duration in seconds\n */\nexport function mapAmbientMotion(\n motion: string | undefined,\n duration?: number,\n): Animation | undefined {\n if (!motion) return undefined;\n const base = duration !== undefined ? { duration } : {};\n switch (motion) {\n case 'zoomIn':\n case 'in':\n return { type: 'slowZoom', direction: 'in', ...base };\n case 'zoomOut':\n case 'out':\n return { type: 'slowZoom', direction: 'out', ...base };\n case 'panLeft':\n case 'left':\n return { type: 'slowZoom', panDirection: 'left', ...base };\n case 'panRight':\n case 'right':\n return { type: 'slowZoom', panDirection: 'right', ...base };\n default:\n return undefined;\n }\n}\n\n/**\n * Accent strip width/height as percentage.\n * 35% gives the image enough presence to complement the text without overwhelming it.\n */\nconst STRIP_SIZE = 35;\nconst STRIP_SIZE_PCT = `${STRIP_SIZE}%`;\n\n/**\n * Get layout adjustments based on accent position.\n */\nexport function getAccentLayout(position: AccentPosition): AccentLayout {\n switch (position) {\n case 'left-strip':\n return {\n textCenterX: `${50 + STRIP_SIZE / 2}%`, // Shift center right\n textWidth: `${100 - STRIP_SIZE - 8}%`, // Leave margin\n textYAdjust: 0,\n adjustY: false,\n };\n case 'right-strip':\n return {\n textCenterX: `${50 - STRIP_SIZE / 2}%`, // Shift center left\n textWidth: `${100 - STRIP_SIZE - 8}%`,\n textYAdjust: 0,\n adjustY: false,\n };\n case 'bottom-strip':\n return {\n textCenterX: '50%',\n textWidth: '85%',\n textYAdjust: -10, // Shift content up by 10%\n adjustY: true,\n };\n case 'corner-inset':\n return {\n textCenterX: '45%', // Slight shift to avoid corner\n textWidth: '70%',\n textYAdjust: 0,\n adjustY: false,\n };\n default:\n return DEFAULT_LAYOUT;\n }\n}\n\n/**\n * Create layers for an accent image.\n * Returns the image layer and any overlay/gradient layers needed.\n */\nexport function createAccentLayers(accent: AccentImage, slideId: string): Layer[] {\n const layers: Layer[] = [];\n const { src, alt, position, ambientMotion, credit, license } = accent;\n\n switch (position) {\n case 'left-strip':\n layers.push(createStripImage(src, alt, 'left', slideId, ambientMotion, credit, license));\n layers.push(createStripGradient('left', slideId));\n break;\n\n case 'right-strip':\n layers.push(createStripImage(src, alt, 'right', slideId, ambientMotion, credit, license));\n layers.push(createStripGradient('right', slideId));\n break;\n\n case 'bottom-strip':\n layers.push(createBottomStripImage(src, alt, slideId, ambientMotion, credit, license));\n layers.push(createBottomStripGradient(slideId));\n break;\n\n case 'corner-inset':\n layers.push(createCornerInsetImage(src, alt, slideId, ambientMotion, credit, license));\n layers.push(createCornerVignette(slideId));\n break;\n }\n\n return layers;\n}\n\n/**\n * Create a vertical strip image layer.\n */\nfunction createStripImage(\n src: string,\n alt: string,\n side: 'left' | 'right',\n slideId: string,\n ambientMotion?: AccentImage['ambientMotion'],\n credit?: string,\n license?: string,\n): ImageLayer {\n return {\n type: 'image',\n id: `${slideId}-accent-img`,\n content: {\n src,\n alt,\n fit: 'cover',\n credit,\n license,\n },\n position: {\n x: side === 'left' ? 0 : `${100 - STRIP_SIZE}%`,\n y: 0,\n width: STRIP_SIZE_PCT,\n height: '100%',\n },\n animation: mapAmbientMotion(ambientMotion, 15),\n };\n}\n\n/**\n * Create a gradient overlay for strip images (fades to background).\n */\nfunction createStripGradient(side: 'left' | 'right', slideId: string): ShapeLayer {\n // Gradient from transparent to background color at the edge\n const gradientId = side === 'left' ? 'accent-gradient-left' : 'accent-gradient-right';\n\n return {\n type: 'shape',\n id: `${slideId}-accent-fade`,\n content: {\n shape: 'rect',\n // SVG gradient will be handled by the renderer\n // Using a semi-transparent overlay as fallback\n fill: `url(#${gradientId})`,\n },\n position: {\n x: side === 'left' ? `${STRIP_SIZE - 8}%` : `${100 - STRIP_SIZE}%`,\n y: 0,\n width: '10%',\n height: '100%',\n },\n };\n}\n\n/**\n * Create a horizontal bottom strip image layer.\n */\nfunction createBottomStripImage(\n src: string,\n alt: string,\n slideId: string,\n ambientMotion?: AccentImage['ambientMotion'],\n credit?: string,\n license?: string,\n): ImageLayer {\n return {\n type: 'image',\n id: `${slideId}-accent-img`,\n content: {\n src,\n alt,\n fit: 'cover',\n credit,\n license,\n },\n position: {\n x: 0,\n y: `${100 - STRIP_SIZE}%`,\n width: '100%',\n height: STRIP_SIZE_PCT,\n },\n animation: mapAmbientMotion(ambientMotion, 15),\n };\n}\n\n/**\n * Create a gradient overlay for bottom strip (fades up to background).\n */\nfunction createBottomStripGradient(slideId: string): ShapeLayer {\n return {\n type: 'shape',\n id: `${slideId}-accent-fade`,\n content: {\n shape: 'rect',\n fill: 'url(#accent-gradient-bottom)',\n },\n position: {\n x: 0,\n y: `${100 - STRIP_SIZE - 8}%`,\n width: '100%',\n height: '12%',\n },\n };\n}\n\n/**\n * Create a corner inset image layer.\n */\nfunction createCornerInsetImage(\n src: string,\n alt: string,\n slideId: string,\n ambientMotion?: AccentImage['ambientMotion'],\n credit?: string,\n license?: string,\n): ImageLayer {\n return {\n type: 'image',\n id: `${slideId}-accent-img`,\n content: {\n src,\n alt,\n fit: 'cover',\n credit,\n license,\n },\n position: {\n x: '70%',\n y: '60%',\n width: '28%',\n height: '38%',\n anchor: 'top-left',\n },\n animation: mapAmbientMotion(ambientMotion, 15) ?? { type: 'fadeIn', duration: 2, delay: 0.5 },\n };\n}\n\n/**\n * Create a vignette overlay around corner inset.\n */\nfunction createCornerVignette(slideId: string): ShapeLayer {\n return {\n type: 'shape',\n id: `${slideId}-accent-vignette`,\n content: {\n shape: 'rect',\n fill: 'url(#accent-vignette-corner)',\n borderRadius: 8,\n },\n position: {\n x: '69%',\n y: '59%',\n width: '30%',\n height: '40%',\n },\n };\n}\n\n/**\n * Adjust a Y position value based on accent layout.\n * Used by templates to shift content when bottom-strip is present.\n */\nexport function adjustY(originalY: string | number, layout: AccentLayout): string {\n if (!layout.adjustY || layout.textYAdjust === 0) {\n return typeof originalY === 'number' ? `${originalY}%` : originalY;\n }\n\n // Parse percentage value\n const yStr = typeof originalY === 'number' ? `${originalY}` : originalY;\n const match = yStr.match(PERCENTAGE_RE);\n\n if (match) {\n const yValue = parseFloat(match[1]);\n const adjusted = Math.max(5, yValue + layout.textYAdjust);\n return `${adjusted}%`;\n }\n\n return yStr;\n}\n","/**\n * Template Utilities\n *\n * Shared helpers for doc block templates:\n * - Caption text cleaning\n * - Common layer construction patterns\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\n\nconst TRAILING_PUNCT_RE = /[.;:!?]+$/;\n\n/**\n * Strip trailing punctuation from a caption string.\n * Image captions on blocks look cleaner without terminal periods,\n * semicolons, or other sentence-ending punctuation.\n */\nexport function cleanCaption(text: string): string {\n return text.replace(TRAILING_PUNCT_RE, '').trim();\n}\n\n/**\n * Create a full-screen background shape layer.\n * Most text-based templates start with this as their first layer.\n */\nexport function createBackgroundLayer(id: string, fill: string): Layer {\n return {\n type: 'shape',\n id,\n content: { shape: 'rect', fill },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n };\n}\n","/**\n * Stat Highlight Template\n *\n * Large statistic/number with description and optional detail.\n * Great for emphasizing key data points.\n * Adapts font sizes and positioning for different viewports.\n *\n * Supports optional accent images that appear as tasteful side/bottom strips.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { StatHighlightInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { resolveColorScheme, getThemeFont } from '../utils/themeUtils.js';\nimport { createAccentLayers, getAccentLayout, adjustY, DEFAULT_LAYOUT } from './accentImage.js';\nimport { createBackgroundLayer } from './captionUtils.js';\n\nexport function statHighlight(input: StatHighlightInput, context: TemplateContext): Layer[] {\n const { stat, description, detail, colorScheme = 'blue', accentImage } = input;\n const { theme } = context;\n const colors = resolveColorScheme(context, colorScheme);\n\n // Get layout adjustments if accent image is present\n const accentLayout = accentImage ? getAccentLayout(accentImage.position) : DEFAULT_LAYOUT;\n\n // Scale font sizes — stat is dramatically large, description is understated\n const statFontSize = scaledFontSize(148, context, true);\n const descFontSize = scaledFontSize(32, context, false);\n const detailFontSize = scaledFontSize(26, context, false);\n\n const layers: Layer[] = [\n createBackgroundLayer(\n 'bg',\n `linear-gradient(180deg, ${theme.colors.background} 0%, #0f1520 100%)`,\n ),\n ];\n\n // Add accent image layers (behind text, after background)\n if (accentImage) {\n layers.push(...createAccentLayers(accentImage, input.id));\n }\n\n // Big stat — hero element, dominates the slide\n layers.push({\n type: 'text',\n id: 'stat',\n content: {\n text: stat,\n style: {\n fontSize: statFontSize,\n fontFamily: getThemeFont(context, 'title'),\n fontWeight: 'bold',\n color: colors.text,\n shadow: !!accentImage,\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY('32%', accentLayout),\n anchor: 'center',\n },\n animation: { type: 'zoomIn', duration: 0.6 },\n });\n\n // Description — smaller and understated beneath the stat\n layers.push({\n type: 'text',\n id: 'description',\n content: {\n text: description,\n style: {\n fontSize: descFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.textMuted,\n textAlign: 'center',\n lineHeight: 1.6,\n shadow: !!accentImage,\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY('58%', accentLayout),\n width: accentLayout.textWidth,\n anchor: 'center',\n },\n animation: { type: 'fadeIn', duration: 1, delay: 0.3 },\n });\n\n // Add detail if provided\n if (detail) {\n layers.push({\n type: 'text',\n id: 'detail',\n content: {\n text: detail,\n style: {\n fontSize: detailFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: colors.accent,\n textAlign: 'center',\n shadow: !!accentImage,\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY('75%', accentLayout),\n anchor: 'center',\n },\n animation: { type: 'fadeIn', duration: 1, delay: 1 },\n });\n }\n\n return layers;\n}\n","/**\n * Quote Block Template\n *\n * Large centered quote with optional attribution.\n * Good for impactful statements or descriptions.\n * Adapts font sizes and positioning for different viewports.\n *\n * Supports optional accent images that appear as tasteful side/bottom strips.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { QuoteBlockInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { getThemeFont } from '../utils/themeUtils.js';\nimport { createAccentLayers, getAccentLayout, adjustY, DEFAULT_LAYOUT } from './accentImage.js';\nimport { createBackgroundLayer } from './captionUtils.js';\n\nexport function quoteBlock(input: QuoteBlockInput, context: TemplateContext): Layer[] {\n const { quote, attribution, accentImage } = input;\n const { theme, layout } = context;\n\n // Get layout adjustments if accent image is present\n const accentLayout = accentImage ? getAccentLayout(accentImage.position) : DEFAULT_LAYOUT;\n\n // Scale font sizes for viewport\n const quoteFontSize = scaledFontSize(48, context, true);\n const attrFontSize = scaledFontSize(24, context, false);\n\n // Decorative quotation mark font size\n const decorativeQuoteFontSize = scaledFontSize(280, context, true);\n\n const layers: Layer[] = [\n createBackgroundLayer(\n 'bg',\n `linear-gradient(160deg, ${theme.colors.backgroundLight} 0%, #1e2636 100%)`,\n ),\n ];\n\n // Add accent image layers (behind text, after background)\n if (accentImage) {\n layers.push(...createAccentLayers(accentImage, input.id));\n }\n\n // Decorative opening quotation mark — oversized, low-opacity behind quote\n layers.push({\n type: 'text',\n id: 'deco-quote',\n content: {\n text: '\\u201C',\n style: {\n fontSize: decorativeQuoteFontSize,\n fontFamily: getThemeFont(context, 'title'),\n color: 'rgba(255, 255, 255, 0.06)',\n textAlign: 'center',\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY('18%', accentLayout),\n anchor: 'center',\n },\n });\n\n // Quote text - positioned based on accent layout\n const quoteY = attribution ? layout.primaryY : '50%';\n layers.push({\n type: 'text',\n id: 'quote',\n content: {\n text: quote,\n style: {\n fontSize: quoteFontSize,\n fontFamily: getThemeFont(context, 'title'),\n color: theme.colors.text,\n textAlign: 'center',\n lineHeight: 1.6,\n shadow: true,\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY(quoteY, accentLayout),\n anchor: 'center',\n width: accentLayout.textWidth,\n },\n animation: { type: 'fadeIn', duration: 2 },\n });\n\n // Add attribution if provided\n if (attribution) {\n layers.push({\n type: 'text',\n id: 'attribution',\n content: {\n text: `— ${attribution}`,\n style: {\n fontSize: attrFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.textMuted,\n textAlign: 'center',\n shadow: !!accentImage,\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY(layout.captionY, accentLayout),\n anchor: 'center',\n },\n animation: { type: 'fadeIn', duration: 1, delay: 1.5 },\n });\n }\n\n return layers;\n}\n","/**\n * Fact Card Template\n *\n * Key fact with explanation and optional source.\n * Useful for presenting important information clearly.\n * Adapts font sizes and positioning for different viewports.\n *\n * Supports optional accent images that appear as tasteful side/bottom strips.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { FactCardInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { getThemeFont } from '../utils/themeUtils.js';\nimport { createAccentLayers, getAccentLayout, adjustY, DEFAULT_LAYOUT } from './accentImage.js';\nimport { createBackgroundLayer } from './captionUtils.js';\n\nexport function factCard(input: FactCardInput, context: TemplateContext): Layer[] {\n const { fact, explanation, source, accentImage } = input;\n const { theme } = context;\n\n // Get layout adjustments if accent image is present\n const accentLayout = accentImage ? getAccentLayout(accentImage.position) : DEFAULT_LAYOUT;\n\n // Scale font sizes for viewport\n const factFontSize = scaledFontSize(56, context, true);\n const explainFontSize = scaledFontSize(32, context, false);\n const sourceFontSize = scaledFontSize(20, context, false);\n\n const layers: Layer[] = [\n createBackgroundLayer(\n 'bg',\n `linear-gradient(170deg, #1e2030 0%, ${theme.colors.background} 100%)`,\n ),\n ];\n\n // Add accent image layers (behind text, after background)\n if (accentImage) {\n layers.push(...createAccentLayers(accentImage, input.id));\n }\n\n // Fact (main statement)\n layers.push({\n type: 'text',\n id: 'fact',\n content: {\n text: fact,\n style: {\n fontSize: factFontSize,\n fontFamily: getThemeFont(context, 'title'),\n fontWeight: 'bold',\n color: theme.colors.text,\n textAlign: 'center',\n lineHeight: 1.4,\n shadow: true,\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY('35%', accentLayout),\n width: accentLayout.textWidth,\n anchor: 'center',\n },\n animation: { type: 'fadeIn', duration: 1.5 },\n });\n\n // Explanation\n layers.push({\n type: 'text',\n id: 'explanation',\n content: {\n text: explanation,\n style: {\n fontSize: explainFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.textMuted,\n textAlign: 'center',\n lineHeight: 1.5,\n shadow: !!accentImage,\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY('60%', accentLayout),\n width: accentLayout.textWidth,\n anchor: 'center',\n },\n animation: { type: 'fadeIn', duration: 1, delay: 0.8 },\n });\n\n // Add source if provided\n if (source) {\n layers.push({\n type: 'text',\n id: 'source',\n content: {\n text: source,\n style: {\n fontSize: sourceFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.textMuted,\n textAlign: 'center',\n shadow: !!accentImage,\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY('85%', accentLayout),\n anchor: 'center',\n },\n animation: { type: 'fadeIn', duration: 0.8, delay: 1.5 },\n });\n }\n\n return layers;\n}\n","/**\n * Two Column Template\n *\n * Side-by-side comparison of two items.\n * Each column has a label and optional sublabel.\n * Adapts font sizes and positioning for different viewports.\n *\n * Portrait mode: Stacks columns vertically (top/bottom) instead of side-by-side.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { TwoColumnInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { resolveColorScheme, getThemeFont } from '../utils/themeUtils.js';\nimport { getTwoColumnPositions } from '../../schemas/LayoutStrategy.js';\n\nexport function twoColumn(input: TwoColumnInput, context: TemplateContext): Layer[] {\n const { left, right, header, leftColor = 'green', rightColor = 'blue' } = input;\n\n // Guard: required fields may be absent when generated from sparse markdown\n if (!left?.label || !right?.label) return [];\n\n const { theme, layout, orientation } = context;\n const leftColors = resolveColorScheme(context, leftColor);\n const rightColors = resolveColorScheme(context, rightColor);\n\n // Get column positions based on orientation\n const positions = getTwoColumnPositions(orientation);\n const isStacked = layout.stackColumns;\n\n // Column width ~42% for side-by-side, ~85% for stacked\n const columnWidth = isStacked ? '85%' : '42%';\n\n // Calculate font sizes based on viewport\n const headerFontSize = scaledFontSize(32, context, false);\n const labelFontSize = scaledFontSize(44, context, true);\n const sublabelFontSize = scaledFontSize(22, context, false);\n\n const layers: Layer[] = [\n // Background — subtle gradient to add depth\n {\n type: 'shape',\n id: 'bg',\n content: {\n shape: 'rect',\n fill: `linear-gradient(135deg, ${theme.colors.background} 0%, #16202e 100%)`,\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n },\n ];\n\n if (!isStacked) {\n // Left column background panel\n layers.push({\n type: 'shape',\n id: 'left-panel',\n content: {\n shape: 'rect',\n fill: 'rgba(255, 255, 255, 0.04)',\n },\n position: { x: '3%', y: '15%', width: '44%', height: '70%' },\n });\n\n // Right column background panel\n layers.push({\n type: 'shape',\n id: 'right-panel',\n content: {\n shape: 'rect',\n fill: 'rgba(255, 255, 255, 0.04)',\n },\n position: { x: '53%', y: '15%', width: '44%', height: '70%' },\n });\n }\n\n // Header position adjusts based on layout\n const headerY = isStacked ? '12%' : '22%';\n\n // Add header if provided\n if (header) {\n layers.push({\n type: 'text',\n id: 'header',\n content: {\n text: header,\n style: {\n fontSize: headerFontSize,\n fontFamily: getThemeFont(context, 'title'),\n color: theme.colors.textMuted,\n textAlign: 'center',\n },\n },\n position: { x: '50%', y: headerY, anchor: 'center' },\n animation: { type: 'fadeIn', duration: 0.8 },\n });\n }\n\n // Calculate Y positions based on layout mode and header presence\n let leftY: string;\n let leftSublabelY: string;\n let rightY: string;\n let rightSublabelY: string;\n\n if (isStacked) {\n // Portrait: stacked vertically\n leftY = header ? '30%' : '25%';\n leftSublabelY = header ? '40%' : '35%';\n rightY = header ? '60%' : '55%';\n rightSublabelY = header ? '70%' : '65%';\n } else {\n // Landscape/square: side by side — vertically centered in panels (15%-85%)\n const baseY = header ? '47%' : '45%';\n const sublabelOffset = header ? '58%' : '56%';\n leftY = baseY;\n leftSublabelY = sublabelOffset;\n rightY = baseY;\n rightSublabelY = sublabelOffset;\n }\n\n // Left column (or top in portrait)\n layers.push({\n type: 'text',\n id: 'left-label',\n content: {\n text: left.label,\n style: {\n fontSize: labelFontSize,\n fontFamily: getThemeFont(context, 'body'),\n fontWeight: 'bold',\n color: leftColors.text,\n textAlign: 'center',\n lineHeight: 1.3,\n },\n },\n position: {\n x: positions.left.x,\n y: leftY,\n anchor: 'center',\n width: columnWidth,\n },\n animation: { type: 'fadeIn', duration: 1 },\n });\n\n if (left.sublabel) {\n layers.push({\n type: 'text',\n id: 'left-sublabel',\n content: {\n text: left.sublabel,\n style: {\n fontSize: sublabelFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.textMuted,\n textAlign: 'center',\n lineHeight: 1.4,\n },\n },\n position: {\n x: positions.left.x,\n y: leftSublabelY,\n anchor: 'center',\n width: columnWidth,\n },\n animation: { type: 'fadeIn', duration: 0.8, delay: 0.3 },\n });\n }\n\n // Visual connector between columns (bold arrow)\n const connectorFontSize = scaledFontSize(120, context, true);\n const connectorY = isStacked ? '48%' : '50%'; // Centered in viewport\n const connectorSymbol = isStacked ? '\\u2193' : '\\u2192'; // ↓ for stacked, → for side-by-side\n\n layers.push({\n type: 'text',\n id: 'connector',\n content: {\n text: connectorSymbol,\n style: {\n fontSize: connectorFontSize,\n fontFamily: getThemeFont(context, 'title'),\n fontWeight: 'bold',\n color: 'rgba(255, 255, 255, 0.6)',\n textAlign: 'center',\n },\n },\n position: {\n x: '50%',\n y: connectorY,\n anchor: 'center',\n },\n animation: { type: 'fadeIn', duration: 0.6, delay: 0.4 },\n });\n\n // Right column (or bottom in portrait)\n layers.push({\n type: 'text',\n id: 'right-label',\n content: {\n text: right.label,\n style: {\n fontSize: labelFontSize,\n fontFamily: getThemeFont(context, 'body'),\n fontWeight: 'bold',\n color: rightColors.text,\n textAlign: 'center',\n lineHeight: 1.3,\n },\n },\n position: {\n x: positions.right.x,\n y: rightY,\n anchor: 'center',\n width: columnWidth,\n },\n animation: { type: 'fadeIn', duration: 1, delay: 0.5 },\n });\n\n if (right.sublabel) {\n layers.push({\n type: 'text',\n id: 'right-sublabel',\n content: {\n text: right.sublabel,\n style: {\n fontSize: sublabelFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.textMuted,\n textAlign: 'center',\n lineHeight: 1.4,\n },\n },\n position: {\n x: positions.right.x,\n y: rightSublabelY,\n anchor: 'center',\n width: columnWidth,\n },\n animation: { type: 'fadeIn', duration: 0.8, delay: 0.8 },\n });\n }\n\n return layers;\n}\n","/**\n * Date Event Template\n *\n * Timeline-style slide with prominent date and description.\n * Supports different moods: neutral, somber, celebratory.\n * Adapts font sizes and positioning for different viewports.\n *\n * Supports optional accent images that appear as tasteful side/bottom strips.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { DateEventInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { getThemeFont } from '../utils/themeUtils.js';\nimport { createAccentLayers, getAccentLayout, adjustY, DEFAULT_LAYOUT } from './accentImage.js';\n\nconst MOOD_COLORS = {\n neutral: { bg: '#1a202c', date: '#63b3ed', text: '#ffffff' },\n somber: { bg: '#1a1a2e', date: '#e53e3e', text: '#a0aec0' },\n celebratory: { bg: '#1a365d', date: '#68d391', text: '#ffffff' },\n};\n\nexport function dateEvent(input: DateEventInput, context: TemplateContext): Layer[] {\n const { date, description, footer, mood = 'neutral', accentImage } = input;\n const { theme } = context;\n const colors = MOOD_COLORS[mood];\n\n // Get layout adjustments if accent image is present\n const accentLayout = accentImage ? getAccentLayout(accentImage.position) : DEFAULT_LAYOUT;\n\n // Scale font sizes — date is the hero element\n const dateFontSize = scaledFontSize(96, context, true);\n const descFontSize = scaledFontSize(30, context, false);\n const footerFontSize = scaledFontSize(26, context, false);\n\n const layers: Layer[] = [\n // Background — unique diagonal gradient to differentiate from other dark templates\n {\n type: 'shape',\n id: 'bg',\n content: {\n shape: 'rect',\n fill: `linear-gradient(135deg, ${colors.bg} 0%, #0d1117 100%)`,\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n },\n ];\n\n // Add accent image layers (behind text, after background)\n if (accentImage) {\n layers.push(...createAccentLayers(accentImage, input.id));\n }\n\n // Date — hero element, much larger\n layers.push({\n type: 'text',\n id: 'date',\n content: {\n text: date,\n style: {\n fontSize: dateFontSize,\n fontFamily: getThemeFont(context, 'title'),\n fontWeight: 'bold',\n color: colors.date,\n shadow: !!accentImage,\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY('35%', accentLayout),\n anchor: 'center',\n },\n animation: { type: 'fadeIn', duration: 1.5 },\n });\n\n // Description - constrained width for proper text wrapping\n layers.push({\n type: 'text',\n id: 'description',\n content: {\n text: description,\n style: {\n fontSize: descFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: colors.text,\n textAlign: 'center',\n lineHeight: 1.8,\n shadow: !!accentImage,\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY('58%', accentLayout),\n width: accentLayout.textWidth,\n anchor: 'center',\n },\n animation: { type: 'fadeIn', duration: 2, delay: 1 },\n });\n\n // Add footer if provided\n if (footer) {\n layers.push({\n type: 'text',\n id: 'footer',\n content: {\n text: footer,\n style: {\n fontSize: footerFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.textMuted,\n shadow: !!accentImage,\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY('82%', accentLayout),\n anchor: 'center',\n },\n animation: { type: 'fadeIn', duration: 1, delay: 3 },\n });\n }\n\n return layers;\n}\n","/**\n * Image With Caption Template\n *\n * Full-screen background image with text overlay.\n * Supports Ken Burns animation effects (zoom, pan).\n * Adapts caption positioning and font sizes for different viewports.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { ImageWithCaptionInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { getThemeFont } from '../utils/themeUtils.js';\nimport { cleanCaption } from './captionUtils.js';\nimport { mapAmbientMotion } from './accentImage.js';\n\nexport function imageWithCaption(input: ImageWithCaptionInput, context: TemplateContext): Layer[] {\n const {\n imageSrc,\n imageAlt,\n caption: rawCaption,\n captionPosition: _captionPosition = 'bottom',\n ambientMotion,\n isTitle,\n subtitle,\n imageCredit,\n imageLicense,\n } = input;\n const caption = rawCaption ? cleanCaption(rawCaption) : rawCaption;\n const { theme, layout } = context;\n\n // Scale font sizes for viewport\n const captionFontSize = scaledFontSize(36, context, false);\n const titleFontSize = scaledFontSize(96, context, true);\n const subtitleFontSize = scaledFontSize(36, context, false);\n\n // Determine animation based on ambientMotion setting\n // Support both new 'ambientMotion' and legacy 'kenBurns' property\n const legacyKenBurns = (input as unknown as Record<string, unknown>).kenBurns as\n | string\n | undefined;\n const motion: string | undefined = ambientMotion || legacyKenBurns;\n const imageAnimation = mapAmbientMotion(motion);\n\n const layers: Layer[] = [\n // Background image\n {\n type: 'image',\n id: 'bg-image',\n content: {\n src: imageSrc,\n alt: imageAlt,\n fit: 'cover',\n credit: imageCredit,\n license: imageLicense,\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n animation: imageAnimation,\n },\n ];\n\n // TITLE MODE: Large centered title over hero image (like cover slide)\n if (isTitle && caption) {\n // Full gradient overlay for title readability (similar to cover slide)\n layers.push({\n type: 'shape',\n id: 'title-gradient',\n content: {\n shape: 'rect',\n fill: 'linear-gradient(0deg, rgba(0,0,0,0.8) 0%, rgba(0,0,0,0.4) 40%, rgba(0,0,0,0.1) 70%, transparent 100%)',\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n });\n\n // Title text - large and centered in lower portion\n layers.push({\n type: 'text',\n id: 'title',\n content: {\n text: caption,\n style: {\n fontSize: titleFontSize,\n fontFamily: getThemeFont(context, 'title'),\n fontWeight: 'bold',\n color: theme.colors.text,\n textAlign: 'center',\n shadow: true,\n },\n },\n position: {\n x: '50%',\n y: subtitle ? '70%' : '75%',\n anchor: 'center',\n width: layout.maxTextWidth,\n },\n animation: { type: 'fadeIn', duration: 0.8 },\n });\n\n // Optional subtitle\n if (subtitle) {\n layers.push({\n type: 'text',\n id: 'subtitle',\n content: {\n text: subtitle,\n style: {\n fontSize: subtitleFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.textMuted,\n textAlign: 'center',\n lineHeight: 1.5,\n },\n },\n position: {\n x: '50%',\n y: '82%',\n anchor: 'center',\n width: layout.maxTextWidth,\n },\n animation: { type: 'fadeIn', duration: 0.8, delay: 0.2 },\n });\n }\n\n return layers;\n }\n\n // STANDARD MODE: Caption at bottom\n if (caption) {\n // Subtle gradient at bottom for caption readability (raised above media controls)\n layers.push({\n type: 'shape',\n id: 'caption-gradient',\n content: {\n shape: 'rect',\n fill: 'linear-gradient(0deg, rgba(0,0,0,0.7) 0%, rgba(0,0,0,0.3) 60%, transparent 100%)',\n },\n position: {\n x: 0,\n y: '65%',\n width: '100%',\n height: '35%',\n },\n });\n\n // Caption text - raised above media controls\n layers.push({\n type: 'text',\n id: 'caption',\n content: {\n text: caption,\n style: {\n fontSize: captionFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.text,\n textAlign: 'center',\n shadow: true,\n },\n },\n position: {\n x: '50%',\n y: '82%',\n anchor: 'center',\n width: layout.maxTextWidth,\n },\n animation: { type: 'fadeIn', duration: 1.5, delay: 0.5 },\n });\n }\n\n return layers;\n}\n","/**\n * Map Block Template\n *\n * Full-screen geographic map with optional title and caption overlays.\n * Great for establishing geographic context at the start of a doc\n * or when discussing location-specific content.\n * Adapts font sizes and positioning for different viewports.\n *\n * Map tiles are fetched from free/open-source providers.\n * See docs/MAP_TILES.md for available styles and attribution requirements.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { MapBlockInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { getThemeFont } from '../utils/themeUtils.js';\nimport { mapAmbientMotion } from './accentImage.js';\n\nexport function mapBlock(input: MapBlockInput, context: TemplateContext): Layer[] {\n const {\n center,\n zoom,\n mapStyle = 'terrain',\n title,\n caption,\n markers,\n ambientMotion,\n staticSrc,\n } = input;\n const { theme, layout } = context;\n\n // Scale font sizes for viewport\n const titleFontSize = scaledFontSize(64, context, true);\n const captionFontSize = scaledFontSize(32, context, false);\n\n // Determine animation based on ambientMotion setting\n const mapAnimation = mapAmbientMotion(ambientMotion);\n\n const layers: Layer[] = [\n // Map background\n {\n type: 'map',\n id: 'map-bg',\n content: {\n center,\n zoom,\n style: mapStyle,\n markers,\n showAttribution: true,\n staticSrc, // Use pre-rendered image if available\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n animation: mapAnimation,\n },\n ];\n\n // Add title overlay if provided\n if (title) {\n // Gradient overlay at top for title readability\n layers.push({\n type: 'shape',\n id: 'title-overlay',\n content: {\n shape: 'rect',\n fill: 'rgba(0,0,0,0.6)',\n },\n position: { x: 0, y: 0, width: '100%', height: '18%' },\n });\n\n // Title text - positioned at top of slide\n layers.push({\n type: 'text',\n id: 'title',\n content: {\n text: title,\n style: {\n fontSize: titleFontSize,\n fontFamily: getThemeFont(context, 'title'),\n fontWeight: 'bold',\n color: theme.colors.text,\n textAlign: 'center',\n shadow: true,\n },\n },\n position: {\n x: '50%',\n y: '9%',\n anchor: 'center',\n width: layout.maxTextWidth,\n },\n animation: { type: 'fadeIn', duration: 1, delay: 0.3 },\n });\n }\n\n // Add caption if provided\n if (caption) {\n // Gradient overlay at bottom for caption readability\n layers.push({\n type: 'shape',\n id: 'caption-overlay',\n content: {\n shape: 'rect',\n fill: 'rgba(0,0,0,0.6)',\n },\n position: { x: 0, y: '82%', width: '100%', height: '18%' },\n });\n\n // Caption text\n layers.push({\n type: 'text',\n id: 'caption',\n content: {\n text: caption,\n style: {\n fontSize: captionFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.text,\n textAlign: 'center',\n shadow: true,\n },\n },\n position: {\n x: '50%',\n y: layout.captionY,\n anchor: 'center',\n width: layout.maxTextWidth,\n },\n animation: { type: 'fadeIn', duration: 1, delay: 0.5 },\n });\n }\n\n return layers;\n}\n","/**\n * Full Bleed Quote Template\n *\n * Short dramatic text filling the viewport like a movie title card.\n * Designed for punchy text under 60 characters. Uses massive font\n * centered on a dark vignette background.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { FullBleedQuoteInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { resolveColorScheme, getThemeFont } from '../utils/themeUtils.js';\n\nexport function fullBleedQuote(input: FullBleedQuoteInput, context: TemplateContext): Layer[] {\n const { text, colorScheme = 'blue' } = input;\n const { theme } = context;\n const colors = resolveColorScheme(context, colorScheme);\n\n // Massive font for dramatic impact\n const textFontSize = scaledFontSize(120, context, true);\n\n return [\n // Background — dark radial vignette for cinematic feel\n {\n type: 'shape',\n id: 'bg',\n content: {\n shape: 'rect',\n fill: `radial-gradient(ellipse at 50% 50%, ${theme.colors.backgroundLight} 0%, #000000 100%)`,\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n },\n // The text — massive, centered\n {\n type: 'text',\n id: 'impact-text',\n content: {\n text,\n style: {\n fontSize: textFontSize,\n fontFamily: getThemeFont(context, 'title'),\n fontWeight: 'bold',\n color: colors.text,\n textAlign: 'center',\n lineHeight: 1.2,\n shadow: true,\n },\n },\n position: {\n x: '50%',\n y: '50%',\n anchor: 'center',\n width: '85%',\n },\n animation: { type: 'fadeIn', duration: 1.5 },\n },\n ];\n}\n","/**\n * List Block Template\n *\n * Displays 3-5 items in a numbered vertical list with staggered animations.\n * Good for enumerations like \"things to see\", \"key features\", or \"tips\".\n * Supports optional accent images.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { ListBlockInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { getThemeFont } from '../utils/themeUtils.js';\nimport { createAccentLayers, getAccentLayout, adjustY, DEFAULT_LAYOUT } from './accentImage.js';\n\nexport function listBlock(input: ListBlockInput, context: TemplateContext): Layer[] {\n const { items, title, accentImage } = input;\n const { theme } = context;\n\n // Get layout adjustments if accent image is present\n const accentLayout = accentImage ? getAccentLayout(accentImage.position) : DEFAULT_LAYOUT;\n\n const titleFontSize = scaledFontSize(44, context, true);\n const itemFontSize = scaledFontSize(34, context, false);\n\n const layers: Layer[] = [\n // Background — gradient\n {\n type: 'shape',\n id: 'bg',\n content: {\n shape: 'rect',\n fill: `linear-gradient(155deg, ${theme.colors.backgroundLight} 0%, ${theme.colors.background} 100%)`,\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n },\n ];\n\n // Add accent image layers\n if (accentImage) {\n layers.push(...createAccentLayers(accentImage, input.id));\n }\n\n // Title if provided\n const startY = title ? 30 : 22;\n if (title) {\n layers.push({\n type: 'text',\n id: 'list-title',\n content: {\n text: title,\n style: {\n fontSize: titleFontSize,\n fontFamily: getThemeFont(context, 'title'),\n fontWeight: 'bold',\n color: theme.colors.text,\n textAlign: 'center',\n shadow: !!accentImage,\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY('16%', accentLayout),\n anchor: 'center',\n },\n animation: { type: 'fadeIn', duration: 1 },\n });\n }\n\n // Calculate vertical spacing for items\n const endY = 80;\n const spacing = items.length > 1 ? (endY - startY) / (items.length - 1) : 0;\n\n // List items with staggered animation\n for (let i = 0; i < items.length; i++) {\n const y = startY + spacing * i;\n const itemText = `${i + 1}. ${items[i]}`;\n\n layers.push({\n type: 'text',\n id: `item-${i}`,\n content: {\n text: itemText,\n style: {\n fontSize: itemFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.text,\n lineHeight: 1.4,\n shadow: !!accentImage,\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY(`${y}%`, accentLayout),\n anchor: 'center',\n width: accentLayout.textWidth,\n },\n animation: { type: 'fadeIn', duration: 0.8, delay: 0.3 + 0.3 * i },\n });\n }\n\n return layers;\n}\n","/**\n * Photo Grid Template\n *\n * Displays 2-4 images in a tiled layout for visual variety.\n * Layout adapts based on image count and viewport orientation:\n *\n * Landscape:\n * - 2 images: side-by-side 50/50\n * - 3 images: one large left (60%) + two stacked right\n * - 4 images: 2x2 grid\n *\n * Portrait (9:16): images stack horizontally (top/bottom) instead of\n * side-by-side, giving each image full width on narrow screens.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { PhotoGridInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { getThemeFont } from '../utils/themeUtils.js';\nimport { cleanCaption } from './captionUtils.js';\n\n/** Gap between images as percentage */\nconst GAP = 0.5;\n\nexport function photoGrid(input: PhotoGridInput, context: TemplateContext): Layer[] {\n const { images, caption: rawCaption, ambientMotion } = input;\n\n // Guard: images array is required\n if (!images || images.length === 0) return [];\n\n const caption = rawCaption ? cleanCaption(rawCaption) : rawCaption;\n const { theme, layout } = context;\n\n const layers: Layer[] = [\n // Black background (visible in gaps between images)\n {\n type: 'shape',\n id: 'bg',\n content: { shape: 'rect', fill: '#000000' },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n },\n ];\n\n // Reserve bottom space for caption — more room in landscape for larger text\n const captionHeight = caption ? (layout.stackColumns ? 18 : 22) : 0;\n const gridHeight = 100 - captionHeight;\n\n // Generate image positions based on count; stack vertically in portrait\n const positions = getGridPositions(images.length, gridHeight, layout.stackColumns);\n\n const altFontSize = scaledFontSize(24, context, false);\n\n for (let i = 0; i < Math.min(images.length, 4); i++) {\n const img = images[i];\n const pos = positions[i];\n\n // Placeholder behind image (visible if image fails to load)\n layers.push({\n type: 'shape',\n id: `grid-placeholder-${i}`,\n content: { shape: 'rect', fill: theme.colors.background },\n position: { x: `${pos.x}%`, y: `${pos.y}%`, width: `${pos.w}%`, height: `${pos.h}%` },\n });\n\n // Alt-text label on placeholder\n if (img.alt) {\n layers.push({\n type: 'text',\n id: `grid-alt-${i}`,\n content: {\n text: img.alt,\n style: {\n fontSize: altFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.textMuted,\n textAlign: 'center' as const,\n },\n },\n position: { x: `${pos.x + pos.w / 2}%`, y: `${pos.y + pos.h / 2}%`, anchor: 'center' },\n });\n }\n\n // Image layer (covers placeholder when loaded)\n layers.push({\n type: 'image',\n id: `grid-img-${i}`,\n content: {\n src: img.src,\n alt: img.alt,\n fit: 'cover',\n credit: img.credit,\n license: img.license,\n },\n position: {\n x: `${pos.x}%`,\n y: `${pos.y}%`,\n width: `${pos.w}%`,\n height: `${pos.h}%`,\n },\n // Apply ambient motion to the first (largest) image only\n animation:\n i === 0 && ambientMotion\n ? { type: ambientMotion, duration: 15 }\n : { type: 'fadeIn', duration: 1, delay: 0.2 * i },\n });\n }\n\n // Caption with gradient overlay\n if (caption) {\n const captionFontSize = scaledFontSize(layout.stackColumns ? 28 : 40, context, false);\n\n layers.push({\n type: 'shape',\n id: 'caption-bg',\n content: {\n shape: 'rect',\n fill: 'linear-gradient(transparent, rgba(0,0,0,0.8))',\n },\n position: { x: 0, y: `${gridHeight - 4}%`, width: '100%', height: `${captionHeight + 4}%` },\n });\n\n layers.push({\n type: 'text',\n id: 'caption',\n content: {\n text: caption,\n style: {\n fontSize: captionFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.text,\n textAlign: 'center',\n shadow: true,\n },\n },\n position: {\n x: '50%',\n y: `${gridHeight + (layout.stackColumns ? captionHeight / 2 : captionHeight * 0.3)}%`,\n anchor: 'center',\n width: '90%',\n },\n animation: { type: 'fadeIn', duration: 1, delay: 0.5 },\n });\n }\n\n return layers;\n}\n\ninterface GridPos {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nfunction getGridPositions(count: number, gridHeight: number, stacked: boolean): GridPos[] {\n const halfW = 50 - GAP / 2;\n const halfH = gridHeight / 2 - GAP / 2;\n\n switch (count) {\n case 2:\n if (stacked) {\n // Portrait: stack top/bottom\n return [\n { x: 0, y: 0, w: 100, h: halfH },\n { x: 0, y: gridHeight / 2 + GAP / 2, w: 100, h: halfH },\n ];\n }\n return [\n { x: 0, y: 0, w: halfW, h: gridHeight },\n { x: 50 + GAP / 2, y: 0, w: halfW, h: gridHeight },\n ];\n case 3: {\n if (stacked) {\n // Portrait: stack all three vertically\n const thirdH = gridHeight / 3 - (GAP * 2) / 3;\n return [\n { x: 0, y: 0, w: 100, h: thirdH },\n { x: 0, y: gridHeight / 3 + GAP / 3, w: 100, h: thirdH },\n { x: 0, y: (gridHeight * 2) / 3 + (GAP * 2) / 3, w: 100, h: thirdH },\n ];\n }\n const leftW = 60 - GAP / 2;\n const rightW = 40 - GAP / 2;\n return [\n { x: 0, y: 0, w: leftW, h: gridHeight },\n { x: 60 + GAP / 2, y: 0, w: rightW, h: halfH },\n { x: 60 + GAP / 2, y: gridHeight / 2 + GAP / 2, w: rightW, h: halfH },\n ];\n }\n case 4:\n default:\n // 2x2 grid works well in both orientations\n return [\n { x: 0, y: 0, w: halfW, h: halfH },\n { x: 50 + GAP / 2, y: 0, w: halfW, h: halfH },\n { x: 0, y: gridHeight / 2 + GAP / 2, w: halfW, h: halfH },\n { x: 50 + GAP / 2, y: gridHeight / 2 + GAP / 2, w: halfW, h: halfH },\n ];\n }\n}\n","/**\n * Definition Card Template\n *\n * Dictionary-style slide with a large term and its definition.\n * Good for explaining local words, place names, or cultural concepts.\n * Supports optional accent images.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { DefinitionCardInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { resolveColorScheme, getThemeFont } from '../utils/themeUtils.js';\nimport { createAccentLayers, getAccentLayout, adjustY, DEFAULT_LAYOUT } from './accentImage.js';\nimport { createBackgroundLayer } from './captionUtils.js';\n\nexport function definitionCard(input: DefinitionCardInput, context: TemplateContext): Layer[] {\n const { term, definition, origin, colorScheme = 'blue', accentImage } = input;\n const { theme } = context;\n const colors = resolveColorScheme(context, colorScheme);\n\n // Get layout adjustments if accent image is present\n const accentLayout = accentImage ? getAccentLayout(accentImage.position) : DEFAULT_LAYOUT;\n\n const termFontSize = scaledFontSize(72, context, true);\n const defFontSize = scaledFontSize(32, context, false);\n const originFontSize = scaledFontSize(22, context, false);\n\n const layers: Layer[] = [\n createBackgroundLayer(\n 'bg',\n `linear-gradient(145deg, #1e2030 0%, ${theme.colors.background} 100%)`,\n ),\n ];\n\n // Add accent image layers\n if (accentImage) {\n layers.push(...createAccentLayers(accentImage, input.id));\n }\n\n // Term — large, accent-colored\n layers.push({\n type: 'text',\n id: 'term',\n content: {\n text: term,\n style: {\n fontSize: termFontSize,\n fontFamily: getThemeFont(context, 'title'),\n fontWeight: 'bold',\n color: colors.text,\n textAlign: 'center',\n shadow: !!accentImage,\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY('30%', accentLayout),\n anchor: 'center',\n },\n animation: { type: 'fadeIn', duration: 1.5 },\n });\n\n // Horizontal separator line\n layers.push({\n type: 'shape',\n id: 'separator',\n content: {\n shape: 'rect',\n fill: `${colors.text}33`, // accent color at 20% opacity\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY('42%', accentLayout),\n width: '30%',\n height: '2px',\n anchor: 'center',\n },\n });\n\n // Definition text\n layers.push({\n type: 'text',\n id: 'definition',\n content: {\n text: definition,\n style: {\n fontSize: defFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.text,\n textAlign: 'center',\n lineHeight: 1.6,\n maxLines: 4,\n shadow: !!accentImage,\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY('55%', accentLayout),\n width: accentLayout.textWidth,\n anchor: 'center',\n },\n animation: { type: 'fadeIn', duration: 1, delay: 0.8 },\n });\n\n // Origin if provided\n if (origin) {\n layers.push({\n type: 'text',\n id: 'origin',\n content: {\n text: origin,\n style: {\n fontSize: originFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.textMuted,\n textAlign: 'center',\n shadow: !!accentImage,\n },\n },\n position: {\n x: accentLayout.textCenterX,\n y: adjustY('78%', accentLayout),\n anchor: 'center',\n },\n animation: { type: 'fadeIn', duration: 0.8, delay: 1.5 },\n });\n }\n\n return layers;\n}\n","/**\n * Comparison Bar Template\n *\n * Two horizontal bars showing relative numeric values side by side.\n * Bar widths are proportional to the values for immediate visual comparison.\n * Good for population, distance, or measurement comparisons.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { ComparisonBarInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { resolveColorScheme, getThemeFont } from '../utils/themeUtils.js';\n\nexport function comparisonBar(input: ComparisonBarInput, context: TemplateContext): Layer[] {\n const { leftLabel, leftValue, rightLabel, rightValue, unit, colorScheme = 'blue' } = input;\n const { theme } = context;\n const colors = resolveColorScheme(context, colorScheme);\n\n const labelFontSize = scaledFontSize(28, context, false);\n const valueFontSize = scaledFontSize(48, context, true);\n\n // Calculate proportional bar widths (max bar = 65% of viewport width)\n const maxValue = Math.max(leftValue, rightValue, 1);\n const maxBarWidth = 65;\n const leftBarWidth = (leftValue / maxValue) * maxBarWidth;\n const rightBarWidth = (rightValue / maxValue) * maxBarWidth;\n\n // Bar positioning\n const barStartX = 15;\n const barHeight = 6; // % of viewport height\n const topBarY = 36;\n const bottomBarY = 58;\n\n // Format values for display\n const formatValue = (v: number): string => {\n if (v >= 1_000_000) return `${(v / 1_000_000).toFixed(1)}M`;\n if (v >= 1_000) return `${(v / 1_000).toFixed(v >= 10_000 ? 0 : 1)}K`;\n return v.toLocaleString();\n };\n\n const leftDisplay = unit ? `${formatValue(leftValue)} ${unit}` : formatValue(leftValue);\n const rightDisplay = unit ? `${formatValue(rightValue)} ${unit}` : formatValue(rightValue);\n\n return [\n // Background\n {\n type: 'shape',\n id: 'bg',\n content: {\n shape: 'rect',\n fill: `linear-gradient(180deg, ${theme.colors.background} 0%, #0f1520 100%)`,\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n },\n\n // Top bar label\n {\n type: 'text',\n id: 'left-label',\n content: {\n text: leftLabel,\n style: {\n fontSize: labelFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.textMuted,\n },\n },\n position: { x: `${barStartX}%`, y: `${topBarY - 8}%` },\n },\n\n // Top bar value\n {\n type: 'text',\n id: 'left-value',\n content: {\n text: leftDisplay,\n style: {\n fontSize: valueFontSize,\n fontFamily: getThemeFont(context, 'body'),\n fontWeight: 'bold',\n color: colors.text,\n },\n },\n position: { x: `${barStartX + leftBarWidth + 2}%`, y: `${topBarY - 1}%` },\n animation: { type: 'fadeIn', duration: 0.8, delay: 0.3 },\n },\n\n // Top bar\n {\n type: 'shape',\n id: 'left-bar',\n content: {\n shape: 'rect',\n fill: colors.text,\n borderRadius: 4,\n },\n position: {\n x: `${barStartX}%`,\n y: `${topBarY}%`,\n width: `${leftBarWidth}%`,\n height: `${barHeight}%`,\n },\n animation: { type: 'fadeIn', duration: 1 },\n },\n\n // Bottom bar label\n {\n type: 'text',\n id: 'right-label',\n content: {\n text: rightLabel,\n style: {\n fontSize: labelFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.textMuted,\n },\n },\n position: { x: `${barStartX}%`, y: `${bottomBarY - 8}%` },\n },\n\n // Bottom bar value\n {\n type: 'text',\n id: 'right-value',\n content: {\n text: rightDisplay,\n style: {\n fontSize: valueFontSize,\n fontFamily: getThemeFont(context, 'body'),\n fontWeight: 'bold',\n color: colors.accent,\n },\n },\n position: { x: `${barStartX + rightBarWidth + 2}%`, y: `${bottomBarY - 1}%` },\n animation: { type: 'fadeIn', duration: 0.8, delay: 0.6 },\n },\n\n // Bottom bar\n {\n type: 'shape',\n id: 'right-bar',\n content: {\n shape: 'rect',\n fill: colors.accent,\n borderRadius: 4,\n },\n position: {\n x: `${barStartX}%`,\n y: `${bottomBarY}%`,\n width: `${rightBarWidth}%`,\n height: `${barHeight}%`,\n },\n animation: { type: 'fadeIn', duration: 1, delay: 0.3 },\n },\n ];\n}\n","/**\n * Pull Quote Template\n *\n * Quote text over a full-bleed background image with dark overlay.\n * Cinematic alternative to quoteBlock when a high-quality image is available.\n * Combines the visual impact of imageWithCaption with the text focus of quoteBlock.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { PullQuoteInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { getThemeFont } from '../utils/themeUtils.js';\n\nexport function pullQuote(input: PullQuoteInput, context: TemplateContext): Layer[] {\n const { text, attribution, backgroundImage, ambientMotion } = input;\n\n // Guard: backgroundImage is required\n if (!backgroundImage?.src) return [];\n\n const quoteFontSize = scaledFontSize(52, context, true);\n const attrFontSize = scaledFontSize(24, context, false);\n const decoFontSize = scaledFontSize(200, context, true);\n\n const layers: Layer[] = [\n // Full-bleed background image\n {\n type: 'image',\n id: 'bg-image',\n content: {\n src: backgroundImage.src,\n alt: backgroundImage.alt,\n fit: 'cover',\n credit: backgroundImage.credit,\n license: backgroundImage.license,\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n animation: ambientMotion ? { type: ambientMotion, duration: 15 } : undefined,\n },\n\n // Dark overlay for text readability\n {\n type: 'shape',\n id: 'overlay',\n content: {\n shape: 'rect',\n fill: 'rgba(0, 0, 0, 0.55)',\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n },\n\n // Decorative quotation mark\n {\n type: 'text',\n id: 'deco-quote',\n content: {\n text: '\\u201C',\n style: {\n fontSize: decoFontSize,\n fontFamily: getThemeFont(context, 'title'),\n color: 'rgba(255, 255, 255, 0.08)',\n textAlign: 'center',\n },\n },\n position: {\n x: '50%',\n y: '20%',\n anchor: 'center',\n },\n },\n\n // Quote text\n {\n type: 'text',\n id: 'quote-text',\n content: {\n text,\n style: {\n fontSize: quoteFontSize,\n fontFamily: getThemeFont(context, 'title'),\n color: '#ffffff',\n textAlign: 'center',\n lineHeight: 1.5,\n shadow: true,\n },\n },\n position: {\n x: '50%',\n y: attribution ? '45%' : '50%',\n anchor: 'center',\n width: '80%',\n },\n animation: { type: 'fadeIn', duration: 2 },\n },\n ];\n\n // Attribution\n if (attribution) {\n layers.push({\n type: 'text',\n id: 'attribution',\n content: {\n text: `\\u2014 ${attribution}`,\n style: {\n fontSize: attrFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: 'rgba(255, 255, 255, 0.7)',\n textAlign: 'center',\n shadow: true,\n },\n },\n position: {\n x: '50%',\n y: '72%',\n anchor: 'center',\n },\n animation: { type: 'fadeIn', duration: 1, delay: 1.5 },\n });\n }\n\n return layers;\n}\n","/**\n * Video With Caption Template\n *\n * Full-screen background video clip with text overlay. Mirrors the structure of\n * imageWithCaption but uses a VideoLayer instead of an ImageLayer. The video\n * plays muted — narration audio is the only sound track.\n *\n * Adapts caption positioning and font sizes for different viewports.\n *\n * This is shared code used by both site and efb-app doc renderers.\n *\n * Related Files:\n * - shared/story/templates/imageWithCaption.ts — image equivalent\n * - schemas/StoryScript.ts — VideoLayer type\n * - site/src/components/story/layers/VideoLayer.tsx — rendering component\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { VideoWithCaptionInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { getThemeFont } from '../utils/themeUtils.js';\nimport { cleanCaption } from './captionUtils.js';\n\nexport function videoWithCaption(input: VideoWithCaptionInput, context: TemplateContext): Layer[] {\n const {\n videoSrc,\n posterSrc,\n videoAlt,\n clipStart,\n clipEnd,\n sourceDuration,\n caption: rawCaption,\n captionPosition = 'bottom',\n videoCredit,\n videoLicense,\n } = input;\n const caption = rawCaption ? cleanCaption(rawCaption) : rawCaption;\n const { theme, layout } = context;\n\n const captionFontSize = scaledFontSize(36, context, false);\n const creditFontSize = scaledFontSize(16, context, false);\n\n const layers: Layer[] = [\n // Background video clip\n {\n type: 'video',\n id: 'bg-video',\n content: {\n src: videoSrc,\n posterSrc,\n alt: videoAlt,\n fit: 'cover',\n clipStart,\n clipEnd,\n sourceDuration,\n credit: videoCredit,\n license: videoLicense,\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n },\n ];\n\n // Caption text at bottom with gradient for readability\n if (caption) {\n layers.push({\n type: 'shape',\n id: 'caption-gradient',\n content: {\n shape: 'rect',\n fill: 'linear-gradient(0deg, rgba(0,0,0,0.7) 0%, rgba(0,0,0,0.3) 60%, transparent 100%)',\n },\n position: {\n x: 0,\n y: captionPosition === 'top' ? 0 : '65%',\n width: '100%',\n height: '35%',\n },\n });\n\n const captionY =\n captionPosition === 'top' ? '15%' : captionPosition === 'center' ? '50%' : '82%';\n\n layers.push({\n type: 'text',\n id: 'caption',\n content: {\n text: caption,\n style: {\n fontSize: captionFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.text,\n textAlign: 'center',\n shadow: true,\n },\n },\n position: {\n x: '50%',\n y: captionY,\n anchor: 'center',\n width: layout.maxTextWidth,\n },\n animation: { type: 'fadeIn', duration: 1.5, delay: 0.5 },\n });\n }\n\n // Small credit text in bottom-right corner\n if (videoCredit) {\n layers.push({\n type: 'text',\n id: 'credit',\n content: {\n text: videoCredit,\n style: {\n fontSize: creditFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: 'rgba(255, 255, 255, 0.5)',\n textAlign: 'right',\n },\n },\n position: {\n x: '96%',\n y: '96%',\n anchor: 'bottom-right',\n },\n });\n }\n\n return layers;\n}\n","/**\n * Video Pull Quote Template\n *\n * Quote text over a video clip background with dark overlay.\n * Cinematic alternative to pullQuote when a video clip is available.\n * Combines the visual dynamism of live video with the text focus of quoteBlock.\n *\n * The video plays muted — narration audio is the only sound track.\n *\n * This is shared code used by both site and efb-app doc renderers.\n *\n * Related Files:\n * - shared/story/templates/pullQuote.ts — image-based equivalent\n * - schemas/StoryScript.ts — VideoLayer type\n * - site/src/components/story/layers/VideoLayer.tsx — rendering component\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { VideoPullQuoteInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { getThemeFont } from '../utils/themeUtils.js';\n\nexport function videoPullQuote(input: VideoPullQuoteInput, context: TemplateContext): Layer[] {\n const { text, attribution, backgroundVideo } = input;\n\n // Guard: backgroundVideo is required\n if (!backgroundVideo?.src) return [];\n\n const quoteFontSize = scaledFontSize(52, context, true);\n const attrFontSize = scaledFontSize(24, context, false);\n const decoFontSize = scaledFontSize(200, context, true);\n\n const layers: Layer[] = [\n // Full-bleed background video clip\n {\n type: 'video',\n id: 'bg-video',\n content: {\n src: backgroundVideo.src,\n posterSrc: backgroundVideo.posterSrc,\n alt: backgroundVideo.alt,\n fit: 'cover',\n clipStart: backgroundVideo.clipStart,\n clipEnd: backgroundVideo.clipEnd,\n credit: backgroundVideo.credit,\n license: backgroundVideo.license,\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n },\n\n // Dark overlay for text readability\n {\n type: 'shape',\n id: 'overlay',\n content: {\n shape: 'rect',\n fill: 'rgba(0, 0, 0, 0.55)',\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n },\n\n // Decorative quotation mark\n {\n type: 'text',\n id: 'deco-quote',\n content: {\n text: '\\u201C',\n style: {\n fontSize: decoFontSize,\n fontFamily: getThemeFont(context, 'title'),\n color: 'rgba(255, 255, 255, 0.08)',\n textAlign: 'center',\n },\n },\n position: {\n x: '50%',\n y: '20%',\n anchor: 'center',\n },\n },\n\n // Quote text\n {\n type: 'text',\n id: 'quote-text',\n content: {\n text,\n style: {\n fontSize: quoteFontSize,\n fontFamily: getThemeFont(context, 'title'),\n color: '#ffffff',\n textAlign: 'center',\n lineHeight: 1.5,\n shadow: true,\n },\n },\n position: {\n x: '50%',\n y: attribution ? '45%' : '50%',\n anchor: 'center',\n width: '80%',\n },\n animation: { type: 'fadeIn', duration: 2 },\n },\n ];\n\n // Attribution\n if (attribution) {\n layers.push({\n type: 'text',\n id: 'attribution',\n content: {\n text: `\\u2014 ${attribution}`,\n style: {\n fontSize: attrFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: 'rgba(255, 255, 255, 0.7)',\n textAlign: 'center',\n shadow: true,\n },\n },\n position: {\n x: '50%',\n y: '72%',\n anchor: 'center',\n },\n animation: { type: 'fadeIn', duration: 1, delay: 1.5 },\n });\n }\n\n return layers;\n}\n","/**\n * Data Table Template\n *\n * Renders a themed table with header row and data rows.\n * Uses a TableLayer (foreignObject-based HTML table inside SVG)\n * for proper table layout within the viewport.\n *\n * Adapts font sizes for different viewports and uses theme colors\n * for header background, text, borders, and body cells.\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { DataTableInput, TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport { getThemeFont, resolveColorScheme } from '../utils/themeUtils.js';\nimport { createBackgroundLayer } from './captionUtils.js';\n\nexport function dataTable(input: DataTableInput, context: TemplateContext): Layer[] {\n const { title, headers, rows, align, colorScheme } = input;\n const { theme } = context;\n\n const colors = resolveColorScheme(context, colorScheme);\n const titleFontSize = scaledFontSize(48, context, true);\n const tableFontSize = scaledFontSize(28, context, false);\n\n const layers: Layer[] = [\n createBackgroundLayer(\n 'bg',\n `linear-gradient(170deg, ${theme.colors.background} 0%, #0f1520 100%)`,\n ),\n ];\n\n // Optional title above the table\n if (title) {\n layers.push({\n type: 'text',\n id: 'title',\n content: {\n text: title,\n style: {\n fontSize: titleFontSize,\n fontFamily: getThemeFont(context, 'title'),\n fontWeight: 'bold',\n color: theme.colors.text,\n textAlign: 'center',\n shadow: true,\n },\n },\n position: { x: '50%', y: '10%', width: '80%', anchor: 'center' },\n animation: { type: 'fadeIn', duration: 0.8 },\n });\n }\n\n // Table layer\n layers.push({\n type: 'table',\n id: 'table',\n content: {\n headers,\n rows,\n align,\n style: {\n headerBackground: colors.accent,\n headerColor: colors.text,\n cellBackground: 'rgba(255,255,255,0.05)',\n cellColor: theme.colors.text,\n borderColor: 'rgba(255,255,255,0.12)',\n fontSize: tableFontSize,\n fontFamily: getThemeFont(context, 'body'),\n headerFontFamily: getThemeFont(context, 'title'),\n borderRadius: 8,\n },\n },\n position: {\n x: '10%',\n y: title ? '18%' : '8%',\n width: '80%',\n height: title ? '74%' : '84%',\n },\n animation: { type: 'fadeIn', duration: 1, delay: title ? 0.4 : 0 },\n });\n\n return layers;\n}\n","/**\n * Cover Block Template\n *\n * Full-screen hero image with title overlay, shown before playback starts.\n * This is the \"poster for the doc, displaying the\n * article's hero image with elegant title treatment.\n *\n * Features:\n * - Full-screen hero image with Ken Burns ambient motion\n * - Gradient overlay for text readability\n * - Large centered title with optional subtitle\n * - No animation delays (shown at rest, not during playback)\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Layer } from '../../schemas/Doc.js';\nimport type { TemplateContext } from '../../schemas/BlockTemplates.js';\nimport { scaledFontSize } from '../../schemas/BlockTemplates.js';\nimport type { StartBlockConfig } from '../../schemas/Doc.js';\nimport { getThemeFont } from '../utils/themeUtils.js';\nimport { mapAmbientMotion } from './accentImage.js';\n\n/**\n * Input for coverBlock template - matches StartBlockConfig\n */\nexport interface CoverBlockInput {\n /** Path to hero image */\n heroSrc: string;\n /** Alt text for the hero image */\n heroAlt?: string;\n /** Title to display over the hero */\n title: string;\n /** Optional subtitle */\n subtitle?: string;\n /** Ambient motion for the hero image */\n ambientMotion?: 'zoomIn' | 'zoomOut' | 'panLeft' | 'panRight';\n /** Photo credit / artist name */\n heroCredit?: string;\n /** License identifier */\n heroLicense?: string;\n}\n\n/**\n * Generate cover block layers from StartBlockConfig.\n */\nexport function coverBlock(input: CoverBlockInput, context: TemplateContext): Layer[] {\n const { heroSrc, heroAlt, title, subtitle, ambientMotion, heroCredit, heroLicense } = input;\n const { theme, layout } = context;\n\n // Scale font sizes for viewport - use larger sizes for the cover\n const titleFontSize = scaledFontSize(96, context, true);\n const subtitleFontSize = scaledFontSize(36, context, false);\n\n // Determine Ken Burns animation\n const imageAnimation = mapAmbientMotion(ambientMotion);\n\n const layers: Layer[] = [\n // Full-screen hero image\n {\n type: 'image',\n id: 'cover-hero',\n content: {\n src: heroSrc,\n alt: heroAlt || title,\n fit: 'cover',\n credit: heroCredit,\n license: heroLicense,\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n animation: imageAnimation,\n },\n // Gradient overlay for text readability - from bottom\n {\n type: 'shape',\n id: 'cover-gradient',\n content: {\n shape: 'rect',\n fill: 'linear-gradient(0deg, rgba(0,0,0,0.8) 0%, rgba(0,0,0,0.4) 40%, rgba(0,0,0,0.1) 70%, transparent 100%)',\n },\n position: { x: 0, y: 0, width: '100%', height: '100%' },\n },\n // Title - positioned lower in the frame to work with hero composition\n {\n type: 'text',\n id: 'cover-title',\n content: {\n text: title,\n style: {\n fontSize: titleFontSize,\n fontFamily: getThemeFont(context, 'title'),\n fontWeight: 'bold',\n color: theme.colors.text,\n textAlign: 'center',\n shadow: true,\n },\n },\n position: {\n x: '50%',\n y: subtitle ? '70%' : '75%',\n anchor: 'center',\n width: layout.maxTextWidth,\n },\n // No animation delay - shown immediately at rest\n animation: { type: 'fadeIn', duration: 0.8 },\n },\n ];\n\n // Add subtitle if provided\n if (subtitle) {\n layers.push({\n type: 'text',\n id: 'cover-subtitle',\n content: {\n text: subtitle,\n style: {\n fontSize: subtitleFontSize,\n fontFamily: getThemeFont(context, 'body'),\n color: theme.colors.textMuted,\n textAlign: 'center',\n lineHeight: 1.5,\n },\n },\n position: {\n x: '50%',\n y: '82%',\n anchor: 'center',\n width: layout.maxTextWidth,\n },\n animation: { type: 'fadeIn', duration: 0.8, delay: 0.2 },\n });\n }\n\n return layers;\n}\n\n/**\n * Convert StartBlockConfig to CoverBlockInput.\n */\nexport function startBlockToCoverInput(config: StartBlockConfig): CoverBlockInput {\n return {\n heroSrc: config.heroSrc,\n heroAlt: config.heroAlt,\n title: config.title,\n subtitle: config.subtitle,\n ambientMotion: config.ambientMotion,\n heroCredit: config.heroCredit,\n heroLicense: config.heroLicense,\n };\n}\n\n/**\n * Expand a StartBlockConfig into a renderable Block.\n * This is used by the player to render the cover block at rest.\n */\nexport function expandCoverBlock(config: StartBlockConfig, context: TemplateContext): Layer[] {\n const input = startBlockToCoverInput(config);\n return coverBlock(input, context);\n}\n","/**\n * Block Template Registry\n *\n * Central registry of all block templates. Provides functions to:\n * - Look up templates by name\n * - Expand template blocks into full Layer arrays\n * - Convert a template-based doc script into a renderable format\n *\n * Supports multiple viewport configurations for different aspect ratios.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Block, Layer } from '../../schemas/Doc.js';\nimport type {\n TemplateBlock,\n TemplateContext,\n TemplateRegistry,\n DocBlock,\n PersistentLayerConfig,\n} from '../../schemas/BlockTemplates.js';\nimport type { Theme } from '../../schemas/Theme.js';\nimport { isTemplateBlock, createTemplateContext } from '../../schemas/BlockTemplates.js';\nimport { DEFAULT_THEME as defaultTheme } from '../../schemas/themeLibrary.js';\nimport { expandPersistentLayers } from './persistentLayers.js';\nimport type { ViewportConfig } from '../../schemas/Viewport.js';\nimport { VIEWPORT_PRESETS } from '../../schemas/Viewport.js';\n\n// Import all template functions\nimport { titleBlock } from './titleBlock.js';\nimport { sectionHeader } from './sectionHeader.js';\nimport { statHighlight } from './statHighlight.js';\nimport { quoteBlock } from './quoteBlock.js';\nimport { factCard } from './factCard.js';\nimport { twoColumn } from './twoColumn.js';\nimport { dateEvent } from './dateEvent.js';\nimport { imageWithCaption } from './imageWithCaption.js';\nimport { mapBlock } from './mapBlock.js';\nimport { fullBleedQuote } from './fullBleedQuote.js';\nimport { listBlock } from './listBlock.js';\nimport { photoGrid } from './photoGrid.js';\nimport { definitionCard } from './definitionCard.js';\nimport { comparisonBar } from './comparisonBar.js';\nimport { pullQuote } from './pullQuote.js';\nimport { videoWithCaption } from './videoWithCaption.js';\nimport { videoPullQuote } from './videoPullQuote.js';\nimport { dataTable } from './dataTable.js';\n\n/**\n * Registry mapping template names to their implementation functions.\n * Note: coverBlock is not in the registry as it's used directly for start blocks,\n * not as a regular template in the block sequence.\n */\nexport const templateRegistry: TemplateRegistry = {\n titleBlock,\n sectionHeader,\n statHighlight,\n quoteBlock,\n factCard,\n twoColumn,\n dateEvent,\n imageWithCaption,\n mapBlock,\n fullBleedQuote,\n listBlock,\n photoGrid,\n definitionCard,\n comparisonBar,\n pullQuote,\n videoWithCaption,\n videoPullQuote,\n dataTable,\n};\n\n/**\n * Expand a template block into a full Block with layers.\n */\nexport function expandTemplateBlock(templateBlock: TemplateBlock, context: TemplateContext): Block {\n const templateFn = templateRegistry[templateBlock.template];\n\n if (!templateFn) {\n console.warn(`Unknown template: ${templateBlock.template}`);\n // Return block with no layers\n return {\n id: templateBlock.id,\n startTime: 0,\n duration: templateBlock.duration,\n audioSegment: templateBlock.audioSegment,\n transition: templateBlock.transition,\n template: templateBlock.template, // Preserve for debugging\n };\n }\n\n // Generate layers from template with error handling\n let layers: Layer[];\n try {\n // Each registry entry accepts its specific TemplateBlock variant; the\n // discriminated union guarantees the shapes match at runtime.\n layers = (templateFn as (input: TemplateBlock, ctx: TemplateContext) => Layer[])(\n templateBlock,\n context,\n );\n if (!Array.isArray(layers)) {\n console.error(\n `Template ${templateBlock.template} did not return an array, got:`,\n typeof layers,\n );\n layers = [];\n }\n } catch (err: unknown) {\n console.error(`Error expanding template ${templateBlock.template}:`, err);\n layers = [];\n }\n\n return {\n id: templateBlock.id,\n startTime: 0, // Will be calculated later\n duration: templateBlock.duration,\n audioSegment: templateBlock.audioSegment,\n ...(layers.length > 0 ? { layers } : {}),\n transition: templateBlock.transition,\n template: templateBlock.template, // Preserve for debugging\n };\n}\n\n/**\n * Audio segment timing info for aligning blocks with audio.\n */\nexport interface AudioSegmentTiming {\n /** Start time of this segment in the overall timeline */\n startTime: number;\n /** Duration of this segment */\n duration: number;\n}\n\n/**\n * Options for expanding doc blocks.\n */\nexport interface ExpandDocBlocksOptions {\n /** Theme for template rendering (defaults to DEFAULT_THEME) */\n theme?: Theme;\n /** Viewport configuration (defaults to 16:9 landscape) */\n viewport?: ViewportConfig;\n /** Persistent layers for visual consistency across blocks */\n persistentLayers?: PersistentLayerConfig;\n /**\n * Audio segment timing information.\n * When provided, blocks are timed relative to their audio segment's start time,\n * ensuring proper synchronization with audio playback.\n */\n audioSegments?: AudioSegmentTiming[];\n}\n\n/**\n * Expand all template blocks in a doc, calculating start times.\n * Injects persistent layers (bottom/top) based on per-block flags.\n *\n * When audioSegments is provided, blocks are timed relative to their audio segment's\n * start time, ensuring blocks appear when their audio is playing. Blocks within each\n * segment are distributed proportionally across the segment duration.\n *\n * @param blocks - Array of template or raw blocks\n * @param options - Expansion options including theme, viewport, and persistent layers\n */\nexport function expandDocBlocks(blocks: DocBlock[], options: ExpandDocBlocksOptions = {}): Block[] {\n const opts: ExpandDocBlocksOptions = options;\n\n const theme = opts.theme ?? defaultTheme;\n const viewport = opts.viewport ?? VIEWPORT_PRESETS.landscape;\n const { persistentLayers, audioSegments } = opts;\n const totalBlocks = blocks.length;\n\n // Pre-expand persistent layers once\n const bottomLayers = expandPersistentLayers(persistentLayers?.bottomLayers);\n const topLayers = expandPersistentLayers(persistentLayers?.topLayers);\n\n // If no audio segments provided, use simple cumulative timing\n if (!audioSegments || audioSegments.length === 0) {\n let currentTime = 0;\n return blocks.map((block, index) => {\n const context = createTemplateContext(theme, index, totalBlocks, viewport);\n const expandedBlock = isTemplateBlock(block)\n ? expandTemplateBlock(block, context)\n : (block as Block);\n\n // Inject persistent layers\n const templateBlock = block as TemplateBlock;\n const useBottom = templateBlock.useBottomLayer !== false;\n const useTop = templateBlock.useTopLayer !== false;\n if (bottomLayers.length > 0 || topLayers.length > 0) {\n expandedBlock.layers = [\n ...(useBottom ? bottomLayers : []),\n ...(expandedBlock.layers ?? []),\n ...(useTop ? topLayers : []),\n ];\n }\n\n expandedBlock.startTime = currentTime;\n currentTime += expandedBlock.duration;\n return expandedBlock;\n });\n }\n\n // Group blocks by their audioSegment index\n const blocksBySegment = new Map<number, { block: DocBlock; originalIndex: number }[]>();\n blocks.forEach((block, index) => {\n const segmentIndex = (block as TemplateBlock).audioSegment ?? 0;\n if (!blocksBySegment.has(segmentIndex)) {\n blocksBySegment.set(segmentIndex, []);\n }\n blocksBySegment.get(segmentIndex)!.push({ block, originalIndex: index });\n });\n\n // Expand blocks, timing them relative to their audio segment\n const expandedBlocks: Block[] = new Array(blocks.length);\n\n for (const [segmentIndex, segmentBlocks] of blocksBySegment) {\n const audioSegment = audioSegments[segmentIndex];\n if (!audioSegment) {\n // No audio segment info - use simple sequential timing within the segment\n let offsetTime = 0;\n for (const { block, originalIndex } of segmentBlocks) {\n const context = createTemplateContext(theme, originalIndex, totalBlocks, viewport);\n const expandedBlock = isTemplateBlock(block)\n ? expandTemplateBlock(block, context)\n : (block as Block);\n\n const templateBlock = block as TemplateBlock;\n const useBottom = templateBlock.useBottomLayer !== false;\n const useTop = templateBlock.useTopLayer !== false;\n if (bottomLayers.length > 0 || topLayers.length > 0) {\n expandedBlock.layers = [\n ...(useBottom ? bottomLayers : []),\n ...(expandedBlock.layers ?? []),\n ...(useTop ? topLayers : []),\n ];\n }\n\n expandedBlock.startTime = offsetTime;\n offsetTime += expandedBlock.duration;\n expandedBlocks[originalIndex] = expandedBlock;\n }\n continue;\n }\n\n // Section headers (sectionHeader template) get their original duration since\n // the title is spoken at the start of the segment. Other blocks are scaled\n // to fill the remaining time.\n const sectionHeaderBlocks: typeof segmentBlocks = [];\n const contentBlocks: typeof segmentBlocks = [];\n\n for (const item of segmentBlocks) {\n const templateBlock = item.block as TemplateBlock;\n if (templateBlock.template === 'sectionHeader') {\n sectionHeaderBlocks.push(item);\n } else {\n contentBlocks.push(item);\n }\n }\n\n // Calculate fixed duration (section headers) and scalable duration (content)\n const fixedDuration = sectionHeaderBlocks.reduce((sum, { block }) => {\n return sum + ((block as TemplateBlock).duration ?? 0);\n }, 0);\n\n const contentBlockDuration = contentBlocks.reduce((sum, { block }) => {\n return sum + ((block as TemplateBlock).duration ?? 0);\n }, 0);\n\n // Remaining time after section header(s) for content blocks\n const remainingDuration = audioSegment.duration - fixedDuration;\n\n // Scale factor only applies to content blocks\n const scaleFactor =\n contentBlockDuration > 0 && remainingDuration > 0\n ? remainingDuration / contentBlockDuration\n : 1;\n\n // First pass: expand all blocks and track which have source timing\n interface ExpandedSlideInfo {\n block: Block;\n originalIndex: number;\n templateBlock: TemplateBlock;\n hasSourceTiming: boolean;\n }\n const expandedInfos: ExpandedSlideInfo[] = [];\n\n for (const { block, originalIndex } of segmentBlocks) {\n const context = createTemplateContext(theme, originalIndex, totalBlocks, viewport);\n const expandedBlock = isTemplateBlock(block)\n ? expandTemplateBlock(block, context)\n : (block as Block);\n\n const templateBlock = block as TemplateBlock;\n const useBottom = templateBlock.useBottomLayer !== false;\n const useTop = templateBlock.useTopLayer !== false;\n if (bottomLayers.length > 0 || topLayers.length > 0) {\n expandedBlock.layers = [\n ...(useBottom ? bottomLayers : []),\n ...(expandedBlock.layers ?? []),\n ...(useTop ? topLayers : []),\n ];\n }\n\n expandedInfos.push({\n block: expandedBlock,\n originalIndex,\n templateBlock,\n hasSourceTiming: typeof templateBlock.sourceStartTime === 'number',\n });\n }\n\n // Sort blocks within this segment.\n // When ANY block has source timing (from audio analysis), section headers\n // are placed first since they are intro cards for the segment. When there\n // is no source timing (e.g., preview/synthetic mode), keep original\n // document order so the slideshow matches what the author wrote.\n const hasAnySourceTiming = expandedInfos.some((info) => info.hasSourceTiming);\n\n expandedInfos.sort((a, b) => {\n if (hasAnySourceTiming) {\n const aIsHeader = a.templateBlock.template === 'sectionHeader';\n const bIsHeader = b.templateBlock.template === 'sectionHeader';\n\n // Section headers come first when we have audio-based timing\n if (aIsHeader && !bIsHeader) return -1;\n if (!aIsHeader && bIsHeader) return 1;\n\n // Both have source timing - sort by time\n if (a.hasSourceTiming && b.hasSourceTiming) {\n return a.templateBlock.sourceStartTime! - b.templateBlock.sourceStartTime!;\n }\n\n // One has timing, one doesn't - timing comes first\n if (a.hasSourceTiming && !b.hasSourceTiming) return -1;\n if (!a.hasSourceTiming && b.hasSourceTiming) return 1;\n }\n\n // Keep original document order\n return a.originalIndex - b.originalIndex;\n });\n\n // Second pass: assign start times\n // Slides with sourceStartTime use that; others fill gaps\n let offsetWithinSegment = 0;\n for (let i = 0; i < expandedInfos.length; i++) {\n const info = expandedInfos[i];\n const { block: expandedBlock, templateBlock } = info;\n\n // Use source timing if available, otherwise use sequential offset\n if (info.hasSourceTiming) {\n // Use the source timing - this is when the content is spoken\n const sourceStart = templateBlock.sourceStartTime!;\n expandedBlock.startTime = audioSegment.startTime + sourceStart;\n // Use source duration if available, otherwise use block duration\n if (typeof templateBlock.sourceDuration === 'number') {\n expandedBlock.duration = Math.max(5, templateBlock.sourceDuration);\n }\n // Update offset for next block\n offsetWithinSegment = sourceStart + expandedBlock.duration;\n } else if (templateBlock.template === 'sectionHeader') {\n // Section headers start at the beginning of the segment\n expandedBlock.startTime = audioSegment.startTime + offsetWithinSegment;\n offsetWithinSegment += expandedBlock.duration;\n } else {\n // No source timing - place after previous block\n expandedBlock.startTime = audioSegment.startTime + offsetWithinSegment;\n // Scale content block duration to fit\n const scaledDuration = expandedBlock.duration * scaleFactor;\n expandedBlock.duration = scaledDuration;\n offsetWithinSegment += scaledDuration;\n }\n\n expandedBlocks[info.originalIndex] = expandedBlock;\n }\n\n // Third pass: fix overlaps and gaps by adjusting durations\n // Sort by startTime for overlap detection\n const segmentExpandedBlocks = expandedInfos\n .map((info) => expandedBlocks[info.originalIndex])\n .sort((a, b) => a.startTime - b.startTime);\n\n for (let i = 0; i < segmentExpandedBlocks.length - 1; i++) {\n const current = segmentExpandedBlocks[i];\n const next = segmentExpandedBlocks[i + 1];\n const currentEnd = current.startTime + current.duration;\n\n if (currentEnd > next.startTime) {\n // Overlap - shorten current block to end when next begins\n current.duration = next.startTime - current.startTime;\n } else if (currentEnd < next.startTime - 0.5) {\n // Gap > 0.5s - extend current block to fill (visual continuity)\n // Same formula as overlap: snap to next block start\n current.duration = Math.max(0.1, next.startTime - current.startTime);\n }\n }\n\n // Minimum gap between any two transitions (including section boundaries).\n // No block should be visible for less than this before a transition occurs.\n const MIN_TRANSITION_GAP = 5;\n const segmentEnd = audioSegment.startTime + audioSegment.duration;\n\n // Fourth pass: enforce minimum transition gap at section boundary.\n // Eliminate blocks from the end that would start within MIN_TRANSITION_GAP\n // of the section end (creating a jarring transition right before the next\n // section header). Loop to handle cascading eliminations.\n while (segmentExpandedBlocks.length > 1) {\n const lastBlock = segmentExpandedBlocks[segmentExpandedBlocks.length - 1];\n const timeFromLastToEnd = segmentEnd - lastBlock.startTime;\n\n if (timeFromLastToEnd < MIN_TRANSITION_GAP && lastBlock.template !== 'sectionHeader') {\n const prevBlock = segmentExpandedBlocks[segmentExpandedBlocks.length - 2];\n prevBlock.duration = segmentEnd - prevBlock.startTime;\n lastBlock.duration = 0;\n lastBlock.startTime = segmentEnd;\n segmentExpandedBlocks.pop();\n } else {\n // Extend last block to fill to segment end\n if (lastBlock.startTime + lastBlock.duration < segmentEnd) {\n lastBlock.duration = segmentEnd - lastBlock.startTime;\n }\n break;\n }\n }\n\n // Handle single-block segment\n if (segmentExpandedBlocks.length === 1) {\n const onlyBlock = segmentExpandedBlocks[0];\n if (onlyBlock.startTime + onlyBlock.duration < segmentEnd) {\n onlyBlock.duration = segmentEnd - onlyBlock.startTime;\n }\n }\n\n // Fifth pass: eliminate any remaining blocks shorter than MIN_TRANSITION_GAP.\n // Walk backwards and merge short blocks into their predecessor.\n // Skip index 0 (first block, typically section header) to preserve segment start.\n let changed = true;\n while (changed) {\n changed = false;\n for (let i = segmentExpandedBlocks.length - 1; i >= 1; i--) {\n const block = segmentExpandedBlocks[i];\n if (block.duration > 0 && block.duration < MIN_TRANSITION_GAP) {\n const prev = segmentExpandedBlocks[i - 1];\n const blockEnd = block.startTime + block.duration;\n prev.duration = blockEnd - prev.startTime;\n block.duration = 0;\n block.startTime = segmentEnd;\n segmentExpandedBlocks.splice(i, 1);\n changed = true;\n break; // Restart loop after modification\n }\n }\n }\n\n // Sixth pass: split blocks that are too long (>20s)\n // This ensures no single block lingers for too long\n const MAX_BLOCK_DURATION = 20;\n\n for (let i = 0; i < segmentExpandedBlocks.length; i++) {\n const block = segmentExpandedBlocks[i];\n\n if (block.duration > MAX_BLOCK_DURATION) {\n // Calculate how many parts we need\n const numParts = Math.ceil(block.duration / MAX_BLOCK_DURATION);\n const partDuration = block.duration / numParts;\n\n // Only split if each part would meet minimum transition gap\n if (partDuration >= MIN_TRANSITION_GAP) {\n // Shorten original block to first part\n block.duration = partDuration;\n\n // Create additional blocks for remaining parts\n for (let p = 1; p < numParts; p++) {\n const splitBlock: Block = {\n id: `${block.id}-split-${p}`,\n startTime: block.startTime + p * partDuration,\n duration: partDuration,\n audioSegment: block.audioSegment,\n layers: (block.layers ?? []).map((layer) => ({\n ...layer,\n id: `${layer.id}-split-${p}`,\n })),\n transition: { type: 'dissolve', duration: 1.0 },\n template: block.template,\n };\n // Insert into expanded blocks array\n expandedBlocks.push(splitBlock);\n }\n }\n }\n }\n }\n\n // Filter out zero-duration blocks (eliminated in earlier passes)\n return expandedBlocks.filter((block) => block && block.duration > 0);\n}\n\n/**\n * Get list of available template names.\n */\nexport function getAvailableTemplates(): string[] {\n return Object.keys(templateRegistry);\n}\n\n/**\n * Check if a template exists.\n */\nexport function hasTemplate(name: string): boolean {\n return name in templateRegistry;\n}\n\n// Re-export types and utilities from schemas\nexport {\n isTemplateBlock,\n createTemplateContext,\n scaledFontSize,\n} from '../../schemas/BlockTemplates.js';\nexport type {\n TemplateBlock,\n DocBlock,\n TemplateContext,\n PersistentLayerConfig,\n} from '../../schemas/BlockTemplates.js';\nexport {\n DEFAULT_THEME,\n resolveTheme,\n getAvailableThemes,\n getThemeSummaries,\n} from '../../schemas/themeLibrary.js';\nexport type {\n Theme,\n ThemeColorPalette,\n ThemeColorScheme,\n ThemeTypography,\n ThemeStyle,\n RenderStyle,\n} from '../../schemas/Theme.js';\nexport type { DocStylePreset } from './persistentLayers.js';\n// Re-export timing types (AudioSegmentTiming and ExpandDocBlocksOptions are already exported above)\nexport { VIEWPORT_PRESETS, getViewport, getViewportOrientation } from '../../schemas/Viewport.js';\nexport type {\n ViewportConfig,\n ViewportPreset,\n ViewportOrientation,\n} from '../../schemas/Viewport.js';\nexport { getLayoutHints, getTwoColumnPositions } from '../../schemas/LayoutStrategy.js';\nexport type { LayoutHints } from '../../schemas/LayoutStrategy.js';\nexport { expandPersistentLayers, getDocStyleConfig } from './persistentLayers.js';\n\n// Re-export individual templates for direct access\nexport { titleBlock } from './titleBlock.js';\nexport { sectionHeader } from './sectionHeader.js';\nexport { statHighlight } from './statHighlight.js';\nexport { quoteBlock } from './quoteBlock.js';\nexport { factCard } from './factCard.js';\nexport { twoColumn } from './twoColumn.js';\nexport { dateEvent } from './dateEvent.js';\nexport { imageWithCaption } from './imageWithCaption.js';\nexport { mapBlock } from './mapBlock.js';\nexport { coverBlock, expandCoverBlock } from './coverBlock.js';\nexport type { CoverBlockInput } from './coverBlock.js';\nexport { fullBleedQuote } from './fullBleedQuote.js';\nexport { listBlock } from './listBlock.js';\nexport { photoGrid } from './photoGrid.js';\nexport { definitionCard } from './definitionCard.js';\nexport { comparisonBar } from './comparisonBar.js';\nexport { pullQuote } from './pullQuote.js';\nexport { videoWithCaption } from './videoWithCaption.js';\nexport { videoPullQuote } from './videoPullQuote.js';\nexport { dataTable } from './dataTable.js';\n\n// Re-export accent image utilities\nexport { getAccentLayout, createAccentLayers, adjustY, DEFAULT_LAYOUT } from './accentImage.js';\nexport type { AccentLayout } from './accentImage.js';\n","/**\n * Animation Utilities\n *\n * Helper functions for mapping Doc animations to CSS classes and styles.\n * Generates the appropriate animation class names and CSS custom properties\n * for duration, delay, and easing.\n *\n * This is shared code used by both site and efb-app doc renderers.\n */\n\nimport type { Animation, AnimationType, TransitionType } from '../../schemas/Doc.js';\n\ninterface AnimationResult {\n /** CSS class name to apply */\n className: string;\n /** Inline styles for CSS custom properties */\n style: Record<string, string>;\n}\n\n/**\n * Get CSS class and styles for an animation.\n */\nexport function getAnimationStyle(\n animation: Animation | undefined,\n _currentTime: number = 0,\n): AnimationResult {\n if (!animation || animation.type === 'none') {\n return { className: '', style: {} };\n }\n\n const className = getAnimationClassName(animation);\n const style = getAnimationCSSVars(animation);\n\n return { className, style };\n}\n\n/**\n * Map animation type to CSS class name.\n */\nfunction getAnimationClassName(animation: Animation): string {\n const { type, direction, panDirection } = animation;\n\n switch (type) {\n case 'fadeIn':\n return 'anim-fadeIn';\n case 'fadeOut':\n return 'anim-fadeOut';\n case 'slowZoom':\n // Slow zoom (Ken Burns style) has variants based on direction and pan\n if (panDirection === 'left') return 'anim-slowZoom-panLeft';\n if (panDirection === 'right') return 'anim-slowZoom-panRight';\n if (direction === 'out') return 'anim-slowZoom-out';\n return 'anim-slowZoom-in';\n case 'zoomIn':\n return 'anim-zoomIn';\n case 'zoomOut':\n return 'anim-zoomOut';\n case 'panLeft':\n return 'anim-panLeft';\n case 'panRight':\n return 'anim-panRight';\n case 'typewriter':\n return 'anim-typewriter';\n default:\n return '';\n }\n}\n\n/**\n * Generate CSS custom properties for animation timing.\n */\nfunction getAnimationCSSVars(animation: Animation): Record<string, string> {\n const vars: Record<string, string> = {};\n\n if (animation.duration !== undefined) {\n vars['--anim-duration'] = `${animation.duration}s`;\n }\n\n if (animation.delay !== undefined) {\n vars['--anim-delay'] = `${animation.delay}s`;\n }\n\n if (animation.easing) {\n vars['--anim-easing'] = animation.easing;\n }\n\n return vars;\n}\n\n/**\n * Get default duration for an animation type.\n */\nexport function getDefaultAnimationDuration(type: AnimationType): number {\n switch (type) {\n case 'slowZoom':\n case 'panLeft':\n case 'panRight':\n return 8; // Long, slow animations\n case 'typewriter':\n return 3;\n case 'fadeIn':\n case 'fadeOut':\n return 1;\n case 'zoomIn':\n case 'zoomOut':\n return 0.5;\n default:\n return 1;\n }\n}\n\n/**\n * Get transition class for slide entry/exit.\n */\nexport function getTransitionClass(type: TransitionType, entering: boolean): string {\n const mode = entering ? 'enter' : 'exit';\n return `transition-${type}-${mode}`;\n}\n\n/**\n * Calculate animation progress (0-1) based on current time.\n */\nexport function getAnimationProgress(\n animation: Animation,\n currentTime: number,\n slideDuration: number,\n): number {\n const delay = animation.delay || 0;\n const duration = animation.duration || slideDuration;\n\n if (currentTime < delay) return 0;\n if (currentTime >= delay + duration) return 1;\n\n return (currentTime - delay) / duration;\n}\n","/**\n * Markdown → Doc Conversion\n *\n * Converts a MarkdownDocument into a hierarchical Doc whose Block tree\n * mirrors the heading structure of the markdown. Every heading (H1–H6)\n * becomes a Block; body content between headings populates `contents`;\n * sub-headings nest as `children`.\n *\n * This enables using BlockTemplates to supply alternate visualizations\n * for each section of a markdown document.\n *\n * @example\n * ```ts\n * import { parseMarkdown } from '@bendyline/squisq/markdown';\n * import { markdownToDoc } from '@bendyline/squisq/doc';\n *\n * const md = parseMarkdown('# Intro\\n\\nHello world\\n\\n## Details\\n\\nMore text');\n * const doc = markdownToDoc(md);\n * // doc.blocks[0].sourceHeading.depth === 1 (\"# Intro\")\n * // doc.blocks[0].contents → [paragraph(\"Hello world\")]\n * // doc.blocks[0].children[0].sourceHeading.depth === 2 (\"## Details\")\n * ```\n */\n\nimport type { Doc, Block, CaptionTrack, CaptionPhrase } from '../schemas/Doc.js';\nimport type { MarkdownDocument, MarkdownBlockNode, MarkdownHeading } from '../markdown/types.js';\nimport { extractPlainText } from '../markdown/utils.js';\nimport { estimateReadingTime } from '../timing/readingTime.js';\n\n// ============================================\n// Options\n// ============================================\n\n/**\n * Options for markdownToDoc().\n */\nexport interface MarkdownToDocOptions {\n /** Article ID for the generated Doc. Default: 'markdown-doc' */\n articleId?: string;\n\n /** Default template name for heading blocks. Default: 'sectionHeader' */\n defaultTemplate?: string;\n\n /** Default duration per block in seconds. Default: 5 */\n defaultDuration?: number;\n\n /** Custom ID generator. Receives the heading node and its index. */\n generateId?: (heading: MarkdownHeading, index: number) => string;\n}\n\n// ============================================\n// ID Generation\n// ============================================\n\n/**\n * Convert text to a URL-friendly slug.\n * \"Getting Started & More\" → \"getting-started-more\"\n */\nconst SLUG_NON_WORD_RE = /[^\\w\\s-]/g;\nconst SLUG_SPACES_RE = /[\\s_]+/g;\nconst SLUG_MULTI_HYPHEN_RE = /-+/g;\nconst SLUG_TRIM_HYPHEN_RE = /^-|-$/g;\n\nfunction slugify(text: string): string {\n return (\n text\n .toLowerCase()\n .replace(SLUG_NON_WORD_RE, '') // Remove non-word chars (except spaces and hyphens)\n .replace(SLUG_SPACES_RE, '-') // Replace spaces/underscores with hyphens\n .replace(SLUG_MULTI_HYPHEN_RE, '-') // Collapse multiple hyphens\n .replace(SLUG_TRIM_HYPHEN_RE, '') || // Trim leading/trailing hyphens\n 'block'\n ); // Fallback for empty result\n}\n\n/**\n * Creates an ID generator that produces unique slugified IDs.\n * Appends -2, -3, etc. for duplicate headings.\n */\nfunction createIdGenerator() {\n const used = new Map<string, number>();\n\n return (heading: MarkdownHeading, _index: number): string => {\n const text = extractPlainText(heading);\n const base = slugify(text);\n const count = used.get(base) ?? 0;\n used.set(base, count + 1);\n\n if (count === 0) return base;\n return `${base}-${count + 1}`;\n };\n}\n\n// ============================================\n// Core Conversion\n// ============================================\n\n/**\n * Convert a MarkdownDocument into a Doc with a heading-driven Block hierarchy.\n *\n * **Algorithm:**\n * 1. Walk the document's top-level children sequentially\n * 2. Each MarkdownHeading starts a new block at its depth level\n * 3. Non-heading nodes accumulate as `contents` on the current block\n * 4. Sub-headings (deeper depth) nest as `children` of the current block\n * 5. Same-level or shallower headings close the current block and start a sibling/ancestor\n * 6. Content before the first heading goes into a \"preamble\" block with no sourceHeading\n *\n * @param markdownDoc - A parsed MarkdownDocument\n * @param options - Conversion options\n * @returns A Doc whose blocks mirror the markdown heading structure\n */\nexport function markdownToDoc(markdownDoc: MarkdownDocument, options?: MarkdownToDocOptions): Doc {\n const articleId = options?.articleId ?? 'markdown-doc';\n const defaultTemplate = options?.defaultTemplate ?? 'sectionHeader';\n const defaultDuration = options?.defaultDuration ?? 5;\n const generateId = options?.generateId ?? createIdGenerator();\n\n const rootBlocks: Block[] = [];\n let headingIndex = 0;\n\n // Stack tracks the nesting context: each entry is a block and its heading depth.\n // We push when we go deeper, pop when we come back up.\n const stack: Array<{ block: Block; depth: number }> = [];\n\n // Accumulator for content nodes that appear before any heading (preamble)\n // or between the current heading and the next heading/sub-heading.\n let pendingContents: MarkdownBlockNode[] = [];\n let currentBlock: Block | null = null;\n\n function flushContents() {\n if (currentBlock && pendingContents.length > 0) {\n currentBlock.contents = (currentBlock.contents ?? []).concat(pendingContents);\n pendingContents = [];\n }\n }\n\n function makeBlock(heading: MarkdownHeading | null): Block {\n const id = heading ? generateId(heading, headingIndex++) : 'preamble';\n\n // Use template from annotation if present, otherwise fall back to default\n const annotation = heading?.templateAnnotation;\n const template = annotation?.template ?? (heading ? defaultTemplate : undefined);\n\n // Extract heading text so templates (e.g. sectionHeader) that expect a\n // `title` property receive it without having to reach into sourceHeading.\n const title = heading ? extractPlainText(heading) : undefined;\n\n const block: Block = {\n id,\n startTime: 0,\n duration: defaultDuration,\n audioSegment: 0,\n template,\n ...(heading ? { sourceHeading: heading } : {}),\n ...(title ? { title } : {}),\n };\n\n // Propagate key-value params from annotation to templateOverrides\n if (annotation?.params) {\n block.templateOverrides = annotation.params;\n }\n\n return block;\n }\n\n for (const node of markdownDoc.children) {\n if (node.type === 'heading') {\n const heading = node as MarkdownHeading;\n const depth = heading.depth;\n\n // Flush any accumulated content to the current block\n flushContents();\n\n // Create the new block for this heading\n const newBlock = makeBlock(heading);\n\n if (stack.length === 0) {\n // If there's a preamble block with no heading, push it first\n if (currentBlock && !currentBlock.sourceHeading) {\n rootBlocks.push(currentBlock);\n }\n\n // This is a root-level block (or the first heading)\n rootBlocks.push(newBlock);\n stack.push({ block: newBlock, depth });\n } else {\n // Find where this heading fits in the hierarchy\n // Pop blocks from the stack until we find a parent with lower depth\n while (stack.length > 0 && stack[stack.length - 1].depth >= depth) {\n stack.pop();\n }\n\n if (stack.length === 0) {\n // Same level as root or shallower — new root block\n rootBlocks.push(newBlock);\n stack.push({ block: newBlock, depth });\n } else {\n // Deeper — child of the current stack top\n const parent = stack[stack.length - 1].block;\n if (!parent.children) parent.children = [];\n parent.children.push(newBlock);\n stack.push({ block: newBlock, depth });\n }\n }\n\n currentBlock = newBlock;\n } else {\n // Non-heading block node — accumulate as content\n if (!currentBlock) {\n // Content before any heading → create preamble block\n currentBlock = makeBlock(null);\n }\n pendingContents.push(node);\n }\n }\n\n // Flush remaining content\n flushContents();\n\n // If we only had preamble content (no headings at all), push it\n if (currentBlock && !currentBlock.sourceHeading && !rootBlocks.includes(currentBlock)) {\n rootBlocks.push(currentBlock);\n }\n\n // Calculate reading-time-based durations and generate captions\n const allBlocks = flattenBlocks(rootBlocks);\n const minDuration = 3; // seconds — minimum for blocks with little/no text\n const phrases: CaptionPhrase[] = [];\n\n // First pass: compute duration from body-content reading time\n for (const block of allBlocks) {\n const bodyText = getBlockBodyText(block);\n if (bodyText.length > 0) {\n const estimate = estimateReadingTime(bodyText);\n block.duration = Math.max(minDuration, estimate.seconds);\n } else {\n block.duration = defaultDuration;\n }\n }\n\n // Second pass: assign start times sequentially and build caption phrases\n let currentTime = 0;\n for (const block of allBlocks) {\n block.startTime = currentTime;\n\n // Generate caption phrases from the block's body content\n const bodyText = getBlockBodyText(block);\n if (bodyText.length > 0) {\n const sentences = splitIntoSentences(bodyText);\n if (sentences.length > 0) {\n const timePerSentence = block.duration / sentences.length;\n for (let i = 0; i < sentences.length; i++) {\n phrases.push({\n text: sentences[i],\n startTime: currentTime + i * timePerSentence,\n endTime: currentTime + (i + 1) * timePerSentence,\n audioSegment: 0,\n });\n }\n }\n }\n\n currentTime += block.duration;\n }\n\n const captions: CaptionTrack | undefined =\n phrases.length > 0 ? { phrases, generatedAt: new Date().toISOString(), version: 1 } : undefined;\n\n return {\n articleId,\n duration: currentTime,\n blocks: rootBlocks,\n audio: {\n segments: [],\n },\n ...(captions ? { captions } : {}),\n ...(markdownDoc.frontmatter ? { frontmatter: markdownDoc.frontmatter } : {}),\n };\n}\n\n// ============================================\n// Utilities\n// ============================================\n\n/**\n * Flatten a nested block tree into a depth-first ordered array.\n * Useful for calculating sequential timing or iterating all blocks.\n */\nexport function flattenBlocks(blocks: Block[]): Block[] {\n const result: Block[] = [];\n for (const block of blocks) {\n result.push(block);\n if (block.children) {\n result.push(...flattenBlocks(block.children));\n }\n }\n return result;\n}\n\n/**\n * Count the total number of blocks in a nested tree (including children at all levels).\n */\nexport function countBlocks(blocks: Block[]): number {\n let count = 0;\n for (const block of blocks) {\n count += 1;\n if (block.children) {\n count += countBlocks(block.children);\n }\n }\n return count;\n}\n\n/**\n * Get the heading depth for a block. Returns 0 for preamble blocks (no heading).\n */\nexport function getBlockDepth(block: Block): number {\n return block.sourceHeading?.depth ?? 0;\n}\n\n// ============================================\n// Internal helpers\n// ============================================\n\n/**\n * Extract the plain text from a block's body contents (excluding heading text).\n */\nfunction getBlockBodyText(block: Block): string {\n if (!block.contents || block.contents.length === 0) return '';\n // Join with newlines to preserve paragraph/list-item boundaries.\n // splitIntoPhrases uses these newlines as natural split points.\n return block.contents\n .map((node) => extractPlainText(node))\n .join('\\n')\n .trim();\n}\n\n/** Maximum words per caption phrase. Long sentences get split at this point. */\nconst MAX_PHRASE_WORDS = 12;\n\n/**\n * Split text into caption-sized phrases.\n *\n * Splits on:\n * 1. Newlines (paragraph/list-item boundaries from markdown)\n * 2. Sentence endings (.!?) followed by whitespace\n * 3. Long fragments (> MAX_PHRASE_WORDS) at clause boundaries (commas, semicolons, dashes)\n *\n * Merges very short fragments (< 15 chars) with the previous phrase.\n */\nfunction splitIntoSentences(text: string): string[] {\n // First split on newlines (each paragraph/list item becomes separate)\n const lines = text\n .split(/\\n+/)\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n\n // Then split each line on sentence boundaries\n const sentenceRe = /(?<=[.!?])\\s+/;\n const fragments: string[] = [];\n for (const line of lines) {\n const sentences = line\n .split(sentenceRe)\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n fragments.push(...sentences);\n }\n\n if (fragments.length === 0) return [];\n\n // Split long fragments at clause boundaries\n const split: string[] = [];\n for (const frag of fragments) {\n const words = frag.split(/\\s+/);\n if (words.length > MAX_PHRASE_WORDS) {\n // Try to split at comma, semicolon, or dash near the midpoint\n const mid = Math.floor(frag.length / 2);\n const clauseRe = /[,;]\\s+|\\s+—\\s+|\\s+-\\s+/g;\n let bestSplit = -1;\n let bestDist = Infinity;\n let match;\n while ((match = clauseRe.exec(frag)) !== null) {\n const dist = Math.abs(match.index - mid);\n if (dist < bestDist) {\n bestDist = dist;\n bestSplit = match.index + match[0].length;\n }\n }\n if (bestSplit > 0 && bestSplit < frag.length - 5) {\n split.push(frag.slice(0, bestSplit).trim());\n split.push(frag.slice(bestSplit).trim());\n } else {\n split.push(frag);\n }\n } else {\n split.push(frag);\n }\n }\n\n // Merge very short fragments (< 15 chars) with the previous phrase\n const merged: string[] = [split[0]];\n for (let i = 1; i < split.length; i++) {\n if (split[i].length < 15 && merged.length > 0) {\n merged[merged.length - 1] += ' ' + split[i];\n } else {\n merged.push(split[i]);\n }\n }\n return merged;\n}\n","/**\n * getLayers — Compute visual layers for a block on demand.\n *\n * This is the preferred way to obtain renderable layers for a block.\n * Instead of storing pre-computed layers on the Block object, call\n * `getLayers(block, context)` to derive them from the block's template\n * name, content, and the current render context (theme, viewport, etc.).\n *\n * For raw blocks that already carry a `layers` array, those layers are\n * returned directly (with optional persistent layer injection).\n *\n * @example\n * ```ts\n * import { getLayers } from '@bendyline/squisq/doc';\n *\n * const layers = getLayers(block, {\n * theme: DEFAULT_THEME,\n * viewport: VIEWPORT_PRESETS.landscape,\n * blockIndex: 0,\n * totalBlocks: 10,\n * });\n * ```\n */\n\nimport type { Block, Layer } from '../schemas/Doc.js';\nimport type {\n TemplateBlock,\n TemplateContext,\n PersistentLayerConfig,\n DocBlock,\n} from '../schemas/BlockTemplates.js';\nimport type { Theme } from '../schemas/Theme.js';\nimport type { ViewportConfig } from '../schemas/Viewport.js';\nimport { VIEWPORT_PRESETS } from '../schemas/Viewport.js';\nimport { createTemplateContext, isTemplateBlock } from '../schemas/BlockTemplates.js';\nimport { DEFAULT_THEME } from '../schemas/themeLibrary.js';\nimport { templateRegistry } from './templates/index.js';\nimport { expandPersistentLayers } from './templates/persistentLayers.js';\n\n// ============================================\n// RenderContext\n// ============================================\n\n/**\n * Context needed to compute layers for a block.\n *\n * Captures the visual rendering parameters: theme colors, viewport\n * configuration, persistent layers, and the block's position within\n * the doc (for template functions that vary output by index).\n */\nexport interface RenderContext {\n /** Theme for template rendering. Defaults to DEFAULT_THEME (documentary). */\n theme?: Theme;\n\n /** Target viewport configuration. Defaults to 16:9 landscape. */\n viewport?: ViewportConfig;\n\n /** Persistent layers injected behind and/or on top of all block content. */\n persistentLayers?: PersistentLayerConfig;\n\n /** 0-based index of this block in the sequence. Defaults to 0. */\n blockIndex?: number;\n\n /** Total number of blocks in the doc. Defaults to 1. */\n totalBlocks?: number;\n}\n\n// ============================================\n// getLayers\n// ============================================\n\n/**\n * Compute the visual layers for a block.\n *\n * Resolution order:\n * 1. If the block already has a non-empty `layers` array, use it (raw block).\n * 2. If the block has a `template` name that exists in the registry,\n * call the template function to generate layers.\n * 3. Otherwise return an empty array.\n *\n * Persistent layers (bottom/top) from the render context are injected\n * around the result unless the block opts out via `useBottomLayer: false`\n * or `useTopLayer: false`.\n *\n * @param block A Block or TemplateBlock to render.\n * @param context Render context (theme, viewport, persistent layers, position).\n * @returns The computed Layer[] for the block, ready for BlockRenderer.\n */\nexport function getLayers(block: DocBlock, context: RenderContext = {}): Layer[] {\n const theme = context.theme ?? DEFAULT_THEME;\n const viewport = context.viewport ?? VIEWPORT_PRESETS.landscape;\n const blockIndex = context.blockIndex ?? 0;\n const totalBlocks = context.totalBlocks ?? 1;\n\n // 1. Raw block path: block already has pre-computed layers\n const existingLayers = (block as Block).layers;\n if (existingLayers && existingLayers.length > 0 && !isTemplateBlock(block)) {\n return injectPersistentLayers(existingLayers, block, context);\n }\n\n // 2. Template path: look up and call the template function\n if (isTemplateBlock(block) && block.template in templateRegistry) {\n const templateName = block.template as keyof typeof templateRegistry;\n const templateCtx = createTemplateContext(theme, blockIndex, totalBlocks, viewport);\n let layers: Layer[];\n try {\n // Each registry entry accepts its specific TemplateBlock variant; the\n // discriminated union guarantees the shapes match at runtime.\n const templateFn = templateRegistry[templateName] as (\n input: TemplateBlock,\n ctx: TemplateContext,\n ) => Layer[];\n layers = templateFn(block, templateCtx);\n if (!Array.isArray(layers)) {\n console.error(`Template ${templateName} did not return an array, got:`, typeof layers);\n layers = [];\n }\n } catch (err: unknown) {\n console.error(`Error expanding template ${templateName}:`, err);\n layers = [];\n }\n\n return injectPersistentLayers(layers, block, context);\n }\n\n // 3. Fallback: no layers and no known template\n return injectPersistentLayers([], block, context);\n}\n\n// ============================================\n// Internal helpers\n// ============================================\n\n/**\n * Inject persistent bottom/top layers around the block's own layers,\n * respecting per-block opt-out flags.\n */\nfunction injectPersistentLayers(layers: Layer[], block: DocBlock, context: RenderContext): Layer[] {\n const { persistentLayers } = context;\n if (!persistentLayers) return layers;\n\n const bottomLayers = expandPersistentLayers(persistentLayers.bottomLayers);\n const topLayers = expandPersistentLayers(persistentLayers.topLayers);\n\n if (bottomLayers.length === 0 && topLayers.length === 0) return layers;\n\n const templateBlock = block as TemplateBlock;\n const useBottom = templateBlock.useBottomLayer !== false;\n const useTop = templateBlock.useTopLayer !== false;\n\n return [...(useBottom ? bottomLayers : []), ...layers, ...(useTop ? topLayers : [])];\n}\n","/**\n * Shared utilities for layer components.\n *\n * Resolves position values and anchor offsets used by all layer types.\n */\n\n/**\n * Resolve a position value (number or percentage string) to pixels.\n */\nexport function resolveValue(value: number | string, dimension: number): number {\n if (typeof value === 'number') {\n return value;\n }\n if (value.endsWith('%')) {\n const percent = parseFloat(value);\n return (percent / 100) * dimension;\n }\n return parseFloat(value);\n}\n\n/**\n * Get offset based on anchor point.\n */\nexport function getAnchorOffset(\n anchor: string | undefined,\n width: number,\n height: number,\n): { x: number; y: number } {\n switch (anchor) {\n case 'center':\n return { x: -width / 2, y: -height / 2 };\n case 'top-right':\n return { x: -width, y: 0 };\n case 'bottom-left':\n return { x: 0, y: -height };\n case 'bottom-right':\n return { x: -width, y: -height };\n case 'top-left':\n default:\n return { x: 0, y: 0 };\n }\n}\n","/**\n * MediaContext — React context for providing a MediaProvider to layer components.\n *\n * When a MediaProvider is available in context, layer components (ImageLayer,\n * VideoLayer) will use it to resolve media URLs instead of the basePath prop.\n * This enables slot-based media storage where binary assets are served from\n * IndexedDB as blob URLs.\n *\n * Usage:\n * const provider = createSlotMediaProvider(slotId);\n * <MediaContext.Provider value={provider}>\n * <DocPlayer doc={doc} basePath=\"/\" />\n * </MediaContext.Provider>\n */\n\nimport { createContext, useContext, useState, useEffect, useMemo } from 'react';\nimport type { MediaProvider } from '@bendyline/squisq/schemas';\n\n/**\n * React context holding the current MediaProvider (or null if none provided).\n */\nexport const MediaContext = createContext<MediaProvider | null>(null);\n\n/**\n * Hook to access the current MediaProvider from context.\n * Returns null if no provider is set.\n */\nexport function useMediaProvider(): MediaProvider | null {\n return useContext(MediaContext);\n}\n\n/**\n * Hook to resolve a media URL via the MediaProvider (if available),\n * falling back to basePath-based resolution.\n *\n * Returns the resolved URL string. Updates when the provider or path changes.\n *\n * @param relativePath - Relative media path from the document (e.g., 'hero.jpg')\n * @param basePath - Fallback base path for URL construction\n */\nexport function useMediaUrl(relativePath: string, basePath: string): string {\n const provider = useMediaProvider();\n\n // For absolute/http URLs, skip resolution entirely\n const isAbsolute =\n relativePath.startsWith('http') ||\n relativePath.startsWith('/') ||\n relativePath.startsWith('data:') ||\n relativePath.startsWith('blob:');\n\n // Memoize fallback to avoid recalculating on every render\n const fallback = useMemo(\n () => (isAbsolute ? relativePath : `${basePath}/${relativePath}`),\n [isAbsolute, relativePath, basePath],\n );\n\n // Fast path: no provider or absolute URL — return synchronously, skip effect entirely\n const needsProvider = !isAbsolute && !!provider;\n\n const [url, setUrl] = useState(fallback);\n\n useEffect(() => {\n if (!needsProvider) {\n setUrl(fallback);\n return;\n }\n\n let cancelled = false;\n provider!.resolveUrl(relativePath).then((resolved) => {\n if (!cancelled) setUrl(resolved);\n });\n\n return () => {\n cancelled = true;\n };\n }, [needsProvider, provider, relativePath, fallback]);\n\n // When provider is not needed, return fallback directly to avoid\n // the one-frame delay from the initial useState → useEffect cycle\n return needsProvider ? url : fallback;\n}\n","import { options, Fragment } from 'preact';\nimport { encodeEntities } from './utils';\nimport { IS_NON_DIMENSIONAL } from '../../src/constants';\n\nlet vnodeId = 0;\n\nconst isArray = Array.isArray;\n\n/**\n * @fileoverview\n * This file exports various methods that implement Babel's \"automatic\" JSX runtime API:\n * - jsx(type, props, key)\n * - jsxs(type, props, key)\n * - jsxDEV(type, props, key, __source, __self)\n *\n * The implementation of createVNode here is optimized for performance.\n * Benchmarks: https://esbench.com/bench/5f6b54a0b4632100a7dcd2b3\n */\n\n/**\n * JSX.Element factory used by Babel's {runtime:\"automatic\"} JSX transform\n * @param {VNode['type']} type\n * @param {VNode['props']} props\n * @param {VNode['key']} [key]\n * @param {unknown} [isStaticChildren]\n * @param {unknown} [__source]\n * @param {unknown} [__self]\n */\nfunction createVNode(type, props, key, isStaticChildren, __source, __self) {\n\tif (!props) props = {};\n\t// We'll want to preserve `ref` in props to get rid of the need for\n\t// forwardRef components in the future, but that should happen via\n\t// a separate PR.\n\tlet normalizedProps = props,\n\t\tref,\n\t\ti;\n\n\tif ('ref' in normalizedProps) {\n\t\tnormalizedProps = {};\n\t\tfor (i in props) {\n\t\t\tif (i == 'ref') {\n\t\t\t\tref = props[i];\n\t\t\t} else {\n\t\t\t\tnormalizedProps[i] = props[i];\n\t\t\t}\n\t\t}\n\t}\n\n\t/** @type {VNode & { __source: any; __self: any }} */\n\tconst vnode = {\n\t\ttype,\n\t\tprops: normalizedProps,\n\t\tkey,\n\t\tref,\n\t\t_children: null,\n\t\t_parent: null,\n\t\t_depth: 0,\n\t\t_dom: null,\n\t\t_component: null,\n\t\tconstructor: undefined,\n\t\t_original: --vnodeId,\n\t\t_index: -1,\n\t\t_flags: 0,\n\t\t__source,\n\t\t__self\n\t};\n\n\t// If a Component VNode, check for and apply defaultProps.\n\t// Note: `type` is often a String, and can be `undefined` in development.\n\tif (typeof type === 'function' && (ref = type.defaultProps)) {\n\t\tfor (i in ref)\n\t\t\tif (normalizedProps[i] === undefined) {\n\t\t\t\tnormalizedProps[i] = ref[i];\n\t\t\t}\n\t}\n\n\tif (options.vnode) options.vnode(vnode);\n\treturn vnode;\n}\n\n/**\n * Create a template vnode. This function is not expected to be\n * used directly, but rather through a precompile JSX transform\n * @param {string[]} templates\n * @param {Array<string | null | VNode>} exprs\n * @returns {VNode}\n */\nfunction jsxTemplate(templates, ...exprs) {\n\tconst vnode = createVNode(Fragment, { tpl: templates, exprs });\n\t// Bypass render to string top level Fragment optimization\n\tvnode.key = vnode._vnode;\n\treturn vnode;\n}\n\nconst JS_TO_CSS = {};\nconst CSS_REGEX = /[A-Z]/g;\n\n/**\n * Unwrap potential signals.\n * @param {*} value\n * @returns {*}\n */\nfunction normalizeAttrValue(value) {\n\treturn value !== null &&\n\t\ttypeof value === 'object' &&\n\t\ttypeof value.valueOf === 'function'\n\t\t? value.valueOf()\n\t\t: value;\n}\n\n/**\n * Serialize an HTML attribute to a string. This function is not\n * expected to be used directly, but rather through a precompile\n * JSX transform\n * @param {string} name The attribute name\n * @param {*} value The attribute value\n * @returns {string}\n */\nfunction jsxAttr(name, value) {\n\tif (options.attr) {\n\t\tconst result = options.attr(name, value);\n\t\tif (typeof result === 'string') return result;\n\t}\n\n\tvalue = normalizeAttrValue(value);\n\n\tif (name === 'ref' || name === 'key') return '';\n\tif (name === 'style' && typeof value === 'object') {\n\t\tlet str = '';\n\t\tfor (let prop in value) {\n\t\t\tlet val = value[prop];\n\t\t\tif (val != null && val !== '') {\n\t\t\t\tconst name =\n\t\t\t\t\tprop[0] == '-'\n\t\t\t\t\t\t? prop\n\t\t\t\t\t\t: JS_TO_CSS[prop] ||\n\t\t\t\t\t\t\t(JS_TO_CSS[prop] = prop.replace(CSS_REGEX, '-$&').toLowerCase());\n\n\t\t\t\tlet suffix = ';';\n\t\t\t\tif (\n\t\t\t\t\ttypeof val === 'number' &&\n\t\t\t\t\t// Exclude custom-attributes\n\t\t\t\t\t!name.startsWith('--') &&\n\t\t\t\t\t!IS_NON_DIMENSIONAL.test(name)\n\t\t\t\t) {\n\t\t\t\t\tsuffix = 'px;';\n\t\t\t\t}\n\t\t\t\tstr = str + name + ':' + val + suffix;\n\t\t\t}\n\t\t}\n\t\treturn name + '=\"' + encodeEntities(str) + '\"';\n\t}\n\n\tif (\n\t\tvalue == null ||\n\t\tvalue === false ||\n\t\ttypeof value === 'function' ||\n\t\ttypeof value === 'object'\n\t) {\n\t\treturn '';\n\t} else if (value === true) return name;\n\n\treturn name + '=\"' + encodeEntities('' + value) + '\"';\n}\n\n/**\n * Escape a dynamic child passed to `jsxTemplate`. This function\n * is not expected to be used directly, but rather through a\n * precompile JSX transform\n * @param {*} value\n * @returns {string | null | VNode | Array<string | null | VNode>}\n */\nfunction jsxEscape(value) {\n\tif (\n\t\tvalue == null ||\n\t\ttypeof value === 'boolean' ||\n\t\ttypeof value === 'function'\n\t) {\n\t\treturn null;\n\t}\n\n\tif (typeof value === 'object') {\n\t\t// Check for VNode\n\t\tif (value.constructor === undefined) return value;\n\n\t\tif (isArray(value)) {\n\t\t\tfor (let i = 0; i < value.length; i++) {\n\t\t\t\tvalue[i] = jsxEscape(value[i]);\n\t\t\t}\n\t\t\treturn value;\n\t\t}\n\t}\n\n\treturn encodeEntities('' + value);\n}\n\nexport {\n\tcreateVNode as jsx,\n\tcreateVNode as jsxs,\n\tcreateVNode as jsxDEV,\n\tFragment,\n\t// precompiled JSX transform\n\tjsxTemplate,\n\tjsxAttr,\n\tjsxEscape\n};\n","/**\n * ImageLayer Component\n *\n * Renders an image layer within an SVG block. Supports Ken Burns and other\n * animations via CSS classes. Images are rendered using SVG <image> element\n * with proper aspect ratio handling.\n */\n\nimport type { ImageLayer as ImageLayerType, Animation } from '@bendyline/squisq/schemas';\nimport { getAnimationStyle } from '../utils/animationUtils';\nimport { resolveValue, getAnchorOffset } from '../utils/layerUtils';\nimport { useMediaUrl } from '../hooks/MediaContext';\n\ninterface ImageLayerProps {\n layer: ImageLayerType;\n /** Base path for resolving relative image URLs */\n basePath: string;\n /** Viewport dimensions for percentage calculations */\n viewport: { width: number; height: number };\n /** Current time relative to block start (for animation timing) */\n blockTime: number;\n}\n\nexport function ImageLayer({ layer, basePath, viewport, blockTime }: ImageLayerProps) {\n const { content, position, animation } = layer;\n\n // Resolve position values to pixels\n const x = resolveValue(position.x, viewport.width);\n const y = resolveValue(position.y, viewport.height);\n const width = position.width ? resolveValue(position.width, viewport.width) : viewport.width;\n const height = position.height ? resolveValue(position.height, viewport.height) : viewport.height;\n\n // Apply anchor offset\n const offset = getAnchorOffset(position.anchor, width, height);\n const finalX = x + offset.x;\n const finalY = y + offset.y;\n\n // Resolve image URL via MediaProvider (if available), falling back to basePath\n const src = useMediaUrl(content.src, basePath);\n\n // Get animation styles\n const animStyle = getAnimationStyle(animation, blockTime);\n\n // SVG preserveAspectRatio based on fit mode\n const preserveAspectRatio = getPreserveAspectRatio(content.fit);\n const isCover = content.fit === 'cover';\n\n // Detect spatial (transform-based) animations that need Ken Burns treatment.\n // These animations should move the image *content* within fixed bounds rather\n // than shifting the entire image container.\n const isSpatialAnim = animation && SPATIAL_ANIMATION_TYPES.has(animation.type);\n\n // Ken Burns mode: cover image with spatial animation.\n // Keep the container static, animate the inner <img> within clipped bounds.\n if (isCover && isSpatialAnim && animation) {\n const kbAnim = remapToKenBurns(animation);\n const kbStyle = getAnimationStyle(kbAnim, blockTime);\n\n return (\n <g className=\"block-layer block-layer--image\" data-layer-id={layer.id}>\n <foreignObject x={finalX} y={finalY} width={width} height={height}>\n <div\n style={{\n width: '100%',\n height: '100%',\n overflow: 'hidden',\n }}\n >\n <img\n src={src}\n alt={content.alt || ''}\n className={kbStyle.className}\n style={{\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n objectPosition: 'center',\n display: 'block',\n pointerEvents: 'none',\n transformOrigin: 'center center',\n ...kbStyle.style,\n }}\n />\n </div>\n </foreignObject>\n </g>\n );\n }\n\n // For cover mode, use foreignObject with CSS object-fit for more reliable coverage\n // SVG's preserveAspectRatio can be inconsistent across browsers\n if (isCover) {\n return (\n <g\n className={`block-layer block-layer--image ${animStyle.className}`}\n style={animStyle.style}\n data-layer-id={layer.id}\n >\n <foreignObject x={finalX} y={finalY} width={width} height={height}>\n <img\n src={src}\n alt={content.alt || ''}\n style={{\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n objectPosition: 'center',\n display: 'block',\n pointerEvents: 'none',\n }}\n />\n </foreignObject>\n </g>\n );\n }\n\n // For contain/fill modes, use SVG image element\n return (\n <g\n className={`block-layer block-layer--image ${animStyle.className}`}\n style={animStyle.style}\n data-layer-id={layer.id}\n >\n <image\n href={src}\n x={finalX}\n y={finalY}\n width={width}\n height={height}\n preserveAspectRatio={preserveAspectRatio}\n style={{ pointerEvents: 'none' }}\n />\n </g>\n );\n}\n\n/**\n * Map fit mode to SVG preserveAspectRatio.\n */\nfunction getPreserveAspectRatio(fit?: 'cover' | 'contain' | 'fill'): string {\n switch (fit) {\n case 'cover':\n return 'xMidYMid slice';\n case 'fill':\n return 'none';\n case 'contain':\n default:\n return 'xMidYMid meet';\n }\n}\n\n// ============================================\n// Ken Burns Helpers\n// ============================================\n\n/** Animation types that use CSS transforms (translate/scale). */\nconst SPATIAL_ANIMATION_TYPES = new Set(['panLeft', 'panRight', 'slowZoom', 'zoomIn', 'zoomOut']);\n\n/**\n * Remap animation for Ken Burns inner-image rendering.\n *\n * Pure pan animations (panLeft/panRight) get remapped to combined slowZoom+pan\n * to maintain minimum scale and avoid revealing gaps at image edges.\n * zoomIn/zoomOut get remapped to slowZoom variants (no opacity change, which\n * is inappropriate for sustained ambient motion).\n */\nfunction remapToKenBurns(anim: Animation): Animation {\n switch (anim.type) {\n case 'panLeft':\n return { ...anim, type: 'slowZoom', panDirection: 'left' };\n case 'panRight':\n return { ...anim, type: 'slowZoom', panDirection: 'right' };\n case 'zoomIn':\n return { ...anim, type: 'slowZoom', direction: 'in' };\n case 'zoomOut':\n return { ...anim, type: 'slowZoom', direction: 'out' };\n default:\n return anim; // slowZoom variants are already correct\n }\n}\n\nexport default ImageLayer;\n","/**\n * TextLayer Component\n *\n * Renders a text layer within an SVG block. Supports multi-line text,\n * styling options (font, color, shadow), and animations like fadeIn\n * and typewriter effects.\n *\n * Text is rendered using SVG <text> elements with <tspan> for line breaks.\n */\n\nimport type { TextLayer as TextLayerType } from '@bendyline/squisq/schemas';\nimport { DEFAULT_DOC_FONT } from '@bendyline/squisq/schemas';\nimport { getAnimationStyle } from '../utils/animationUtils';\nimport { resolveValue } from '../utils/layerUtils';\n\ninterface TextLayerProps {\n layer: TextLayerType;\n /** Viewport dimensions for percentage calculations */\n viewport: { width: number; height: number };\n /** Current time relative to block start */\n blockTime: number;\n}\n\nexport function TextLayer({ layer, viewport, blockTime }: TextLayerProps) {\n const { content, position, animation } = layer;\n const { text, style } = content;\n\n // Resolve position values to pixels\n const x = resolveValue(position.x, viewport.width);\n const y = resolveValue(position.y, viewport.height);\n const maxWidth = position.width ? resolveValue(position.width, viewport.width) : undefined;\n\n // Apply anchor offset for text alignment\n const textAnchor = getTextAnchor(style.textAlign, position.anchor);\n const dominantBaseline = getDominantBaseline(position.anchor);\n\n // Get animation styles\n const animStyle = getAnimationStyle(animation, blockTime);\n\n // Split text into lines, and wrap if maxWidth is specified\n const rawLines = (text ?? '').split('\\n');\n let lines = maxWidth\n ? rawLines.reduce<string[]>(\n (acc, line) => acc.concat(wrapText(line, style.fontSize, maxWidth)),\n [],\n )\n : rawLines;\n\n // Truncate to maxLines if specified\n if (style.maxLines && lines.length > style.maxLines) {\n lines = lines.slice(0, style.maxLines);\n // Add ellipsis to last visible line\n const last = lines[lines.length - 1];\n lines[lines.length - 1] = last.replace(/\\s*$/, '') + '...';\n }\n const lineHeight = style.lineHeight || 1.4;\n const lineHeightPx = style.fontSize * lineHeight;\n\n // Build text styles\n const textStyles: Record<string, string | number> = {\n fontSize: `${style.fontSize}px`,\n fontFamily: style.fontFamily || DEFAULT_DOC_FONT,\n fontWeight: style.fontWeight || 'normal',\n fill: style.color,\n ...animStyle.style,\n };\n\n // Add shadow filter if requested\n const filterId = style.shadow ? `shadow-${layer.id}` : undefined;\n\n return (\n <g className={`block-layer block-layer--text ${animStyle.className}`} data-layer-id={layer.id}>\n {/* Shadow filter definition */}\n {style.shadow && (\n <defs>\n <filter id={filterId} x=\"-20%\" y=\"-20%\" width=\"140%\" height=\"140%\">\n <feDropShadow dx=\"0\" dy=\"2\" stdDeviation=\"3\" floodColor=\"rgba(0,0,0,0.7)\" />\n </filter>\n </defs>\n )}\n\n {/* Background box if specified */}\n {style.background && (\n <rect\n x={x - (style.padding || 16)}\n y={y - style.fontSize - (style.padding || 16)}\n width={getTextBoxWidth(lines, style) + (style.padding || 16) * 2}\n height={lines.length * lineHeightPx + (style.padding || 16) * 2}\n fill={style.background}\n rx={4}\n ry={4}\n />\n )}\n\n {/* Text element with tspans for each line */}\n <text\n x={x}\n y={y}\n textAnchor={textAnchor as 'start' | 'middle' | 'end'}\n dominantBaseline={dominantBaseline as 'text-before-edge' | 'middle' | 'text-after-edge'}\n style={textStyles}\n filter={filterId ? `url(#${filterId})` : undefined}\n >\n {lines.map((line, i) => (\n <tspan key={i} x={x} dy={i === 0 ? 0 : lineHeightPx}>\n {line || '\\u00A0'} {/* Non-breaking space for empty lines */}\n </tspan>\n ))}\n </text>\n </g>\n );\n}\n\n/**\n * Map text alignment to SVG text-anchor.\n */\nfunction getTextAnchor(align?: 'left' | 'center' | 'right', anchor?: string): string {\n // Explicit alignment takes precedence\n if (align === 'center') return 'middle';\n if (align === 'right') return 'end';\n if (align === 'left') return 'start';\n\n // Otherwise infer from position anchor\n if (anchor?.includes('right')) return 'end';\n if (anchor === 'center') return 'middle';\n return 'start';\n}\n\n/**\n * Map position anchor to SVG dominant-baseline.\n */\nfunction getDominantBaseline(anchor?: string): string {\n if (anchor?.includes('bottom')) return 'text-after-edge';\n if (anchor === 'center') return 'middle';\n return 'text-before-edge';\n}\n\n/**\n * Estimate text box width based on content (rough approximation).\n */\nfunction getTextBoxWidth(lines: string[], style: { fontSize: number }): number {\n const maxLineLength = Math.max(...lines.map((l) => l.length));\n // Rough estimate: average character width is ~0.5 * fontSize\n return maxLineLength * style.fontSize * 0.55;\n}\n\n/**\n * Wrap text to fit within a maximum width.\n * Uses character-based estimation for line breaking.\n */\nfunction wrapText(text: string, fontSize: number, maxWidth: number): string[] {\n if (!text.trim()) return [''];\n\n // Estimate characters per line (average char width ~0.5 * fontSize for most fonts)\n const avgCharWidth = fontSize * 0.5;\n const charsPerLine = Math.floor(maxWidth / avgCharWidth);\n\n if (charsPerLine <= 0) return [text];\n\n const words = text.split(/\\s+/);\n const lines: string[] = [];\n let currentLine = '';\n\n for (const word of words) {\n const testLine = currentLine ? `${currentLine} ${word}` : word;\n\n if (testLine.length <= charsPerLine) {\n currentLine = testLine;\n } else {\n // Current line is full, start new line\n if (currentLine) {\n lines.push(currentLine);\n }\n // Handle words longer than a line\n if (word.length > charsPerLine) {\n // Break long word\n let remaining = word;\n while (remaining.length > charsPerLine) {\n lines.push(remaining.slice(0, charsPerLine));\n remaining = remaining.slice(charsPerLine);\n }\n currentLine = remaining;\n } else {\n currentLine = word;\n }\n }\n }\n\n // Add remaining text\n if (currentLine) {\n lines.push(currentLine);\n }\n\n return lines.length > 0 ? lines : [''];\n}\n\nexport default TextLayer;\n","/**\n * ShapeLayer Component\n *\n * Renders simple geometric shapes (rect, circle, line) within an SVG block.\n * Useful for visual accents, dividers, and background elements.\n */\n\nimport type { ShapeLayer as ShapeLayerType } from '@bendyline/squisq/schemas';\nimport { getAnimationStyle } from '../utils/animationUtils';\nimport { resolveValue, getAnchorOffset } from '../utils/layerUtils';\n\ninterface ShapeLayerProps {\n layer: ShapeLayerType;\n /** Viewport dimensions for percentage calculations */\n viewport: { width: number; height: number };\n /** Current time relative to block start */\n blockTime: number;\n}\n\nexport function ShapeLayer({ layer, viewport, blockTime }: ShapeLayerProps) {\n const { content, position, animation } = layer;\n\n // Resolve position values to pixels\n const rawX = resolveValue(position.x, viewport.width);\n const rawY = resolveValue(position.y, viewport.height);\n const width = position.width ? resolveValue(position.width, viewport.width) : 100;\n const height = position.height ? resolveValue(position.height, viewport.height) : 100;\n\n // Apply anchor offset (e.g., 'center' shifts x by -width/2 and y by -height/2)\n const anchorOffset = getAnchorOffset(position.anchor, width, height);\n const x = rawX + anchorOffset.x;\n const y = rawY + anchorOffset.y;\n\n // Get animation styles\n const animStyle = getAnimationStyle(animation, blockTime);\n\n // Check if fill is a CSS gradient (SVG rect doesn't support CSS gradients natively)\n const fill = content.fill || 'none';\n const isCSSGradient = typeof fill === 'string' && fill.includes('gradient(');\n\n // For CSS gradients on rect, use foreignObject with an HTML div\n if (content.shape === 'rect' && isCSSGradient) {\n return (\n <g\n className={`block-layer block-layer--shape ${animStyle.className}`}\n style={animStyle.style}\n data-layer-id={layer.id}\n >\n <foreignObject x={x} y={y} width={width} height={height}>\n <div\n style={{\n width: '100%',\n height: '100%',\n background: fill,\n borderRadius: content.borderRadius ? `${content.borderRadius}px` : undefined,\n pointerEvents: 'none',\n }}\n />\n </foreignObject>\n </g>\n );\n }\n\n // Common style props for native SVG shapes\n const shapeProps = {\n fill: fill,\n stroke: content.stroke,\n strokeWidth: content.strokeWidth,\n };\n\n return (\n <g\n className={`block-layer block-layer--shape ${animStyle.className}`}\n style={animStyle.style}\n data-layer-id={layer.id}\n >\n {content.shape === 'rect' && (\n <rect\n x={x}\n y={y}\n width={width}\n height={height}\n rx={content.borderRadius}\n ry={content.borderRadius}\n {...shapeProps}\n />\n )}\n\n {content.shape === 'circle' && (\n <circle\n cx={x + width / 2}\n cy={y + height / 2}\n r={Math.min(width, height) / 2}\n {...shapeProps}\n />\n )}\n\n {content.shape === 'line' && (\n <line\n x1={x}\n y1={y}\n x2={x + width}\n y2={y + height}\n stroke={content.stroke || '#ffffff'}\n strokeWidth={content.strokeWidth || 2}\n />\n )}\n </g>\n );\n}\n\nexport default ShapeLayer;\n","/**\n * Map Tile Utilities\n *\n * Functions for fetching and composing map tiles from free/open-source providers.\n * Converts lat/lng to tile coordinates and composites multiple tiles into a\n * single image for SVG embedding.\n *\n * Supported Providers (all free with attribution):\n * - terrain: OpenTopoMap (CC-BY-SA)\n * - road: OpenStreetMap (ODbL)\n * - satellite: ESRI World Imagery (free with attribution)\n * - toner: Stadia/Stamen Toner (free tier)\n * - watercolor: Stadia/Stamen Watercolor (free tier)\n *\n * See docs/MAP_TILES.md for full provider details and terms.\n */\n\nimport type { MapTileStyle, MapMarker } from '@bendyline/squisq/schemas';\n\n/**\n * Tile provider configuration.\n */\nexport interface TileProvider {\n /** URL template with {z}, {x}, {y} placeholders */\n url: string;\n /** Attribution text (required for display) */\n attribution: string;\n /** Maximum zoom level */\n maxZoom: number;\n /** Tile size in pixels (default: 256) */\n tileSize?: number;\n}\n\n/**\n * Free tile providers for each map style.\n * All require attribution to be displayed.\n */\nexport const TILE_PROVIDERS: Record<MapTileStyle, TileProvider> = {\n terrain: {\n url: 'https://tile.opentopomap.org/{z}/{x}/{y}.png',\n attribution: 'Map: OpenTopoMap (CC-BY-SA)',\n maxZoom: 17,\n },\n road: {\n url: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',\n attribution: '© OpenStreetMap contributors',\n maxZoom: 19,\n },\n satellite: {\n url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',\n attribution: 'Imagery: Esri, Maxar, Earthstar',\n maxZoom: 18,\n },\n toner: {\n url: 'https://tiles.stadiamaps.com/tiles/stamen_toner/{z}/{x}/{y}.png',\n attribution: 'Map: Stadia Maps, Stamen Design',\n maxZoom: 20,\n },\n watercolor: {\n url: 'https://tiles.stadiamaps.com/tiles/stamen_watercolor/{z}/{x}/{y}.jpg',\n attribution: 'Map: Stadia Maps, Stamen Design',\n maxZoom: 16,\n },\n};\n\n/**\n * Convert latitude/longitude to tile coordinates at a given zoom level.\n * Uses Web Mercator projection (EPSG:3857).\n */\nexport function latLngToTile(lat: number, lng: number, zoom: number): { x: number; y: number } {\n const n = Math.pow(2, zoom);\n const x = Math.floor(((lng + 180) / 360) * n);\n const latRad = (lat * Math.PI) / 180;\n const y = Math.floor(((1 - Math.log(Math.tan(latRad) + 1 / Math.cos(latRad)) / Math.PI) / 2) * n);\n return { x, y };\n}\n\n/**\n * Convert tile coordinates back to lat/lng (top-left corner of tile).\n */\nexport function tileToLatLng(x: number, y: number, zoom: number): { lat: number; lng: number } {\n const n = Math.pow(2, zoom);\n const lng = (x / n) * 360 - 180;\n const latRad = Math.atan(Math.sinh(Math.PI * (1 - (2 * y) / n)));\n const lat = (latRad * 180) / Math.PI;\n return { lat, lng };\n}\n\n/**\n * Get the pixel offset within a tile for a given lat/lng.\n */\nexport function getPixelOffset(\n lat: number,\n lng: number,\n zoom: number,\n tileSize: number = 256,\n): { x: number; y: number } {\n const n = Math.pow(2, zoom);\n const xTile = ((lng + 180) / 360) * n;\n const latRad = (lat * Math.PI) / 180;\n const yTile = ((1 - Math.log(Math.tan(latRad) + 1 / Math.cos(latRad)) / Math.PI) / 2) * n;\n\n return {\n x: (xTile - Math.floor(xTile)) * tileSize,\n y: (yTile - Math.floor(yTile)) * tileSize,\n };\n}\n\n/**\n * Calculate which tiles are needed to cover a viewport centered on lat/lng.\n */\nexport function getTilesForViewport(\n centerLat: number,\n centerLng: number,\n zoom: number,\n viewportWidth: number,\n viewportHeight: number,\n tileSize: number = 256,\n): Array<{ x: number; y: number; screenX: number; screenY: number }> {\n const centerTile = latLngToTile(centerLat, centerLng, zoom);\n const pixelOffset = getPixelOffset(centerLat, centerLng, zoom, tileSize);\n\n // How many tiles we need in each direction\n const tilesX = Math.ceil(viewportWidth / tileSize) + 1;\n const tilesY = Math.ceil(viewportHeight / tileSize) + 1;\n\n // Start tile offset\n const startX = centerTile.x - Math.floor(tilesX / 2);\n const startY = centerTile.y - Math.floor(tilesY / 2);\n\n // Screen position of the center tile\n const centerScreenX = viewportWidth / 2 - pixelOffset.x;\n const centerScreenY = viewportHeight / 2 - pixelOffset.y;\n\n const tiles: Array<{ x: number; y: number; screenX: number; screenY: number }> = [];\n\n for (let dy = 0; dy < tilesY; dy++) {\n for (let dx = 0; dx < tilesX; dx++) {\n const tileX = startX + dx;\n const tileY = startY + dy;\n const screenX = centerScreenX + (tileX - centerTile.x) * tileSize;\n const screenY = centerScreenY + (tileY - centerTile.y) * tileSize;\n\n tiles.push({ x: tileX, y: tileY, screenX, screenY });\n }\n }\n\n return tiles;\n}\n\n/**\n * Build a tile URL from the provider template.\n */\nexport function buildTileUrl(provider: TileProvider, x: number, y: number, z: number): string {\n return provider.url.replace('{z}', String(z)).replace('{x}', String(x)).replace('{y}', String(y));\n}\n\n/**\n * Fetch a single tile image as an HTMLImageElement.\n */\nasync function fetchTileImage(url: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.crossOrigin = 'anonymous';\n img.onload = () => resolve(img);\n img.onerror = () => reject(new Error(`Failed to load tile: ${url}`));\n img.src = url;\n });\n}\n\n/**\n * Options for composing a map image.\n */\nexport interface ComposeMapOptions {\n /** Center coordinates */\n center: { lat: number; lng: number };\n /** Zoom level */\n zoom: number;\n /** Map tile style */\n style: MapTileStyle;\n /** Output width in pixels */\n width: number;\n /** Output height in pixels */\n height: number;\n /** Optional markers to render */\n markers?: MapMarker[];\n /** Show attribution (default: true) */\n showAttribution?: boolean;\n}\n\n/**\n * Compose map tiles into a single data URL image.\n *\n * This is the main function for generating map images for blocks.\n * It fetches all needed tiles, composites them on a canvas, and\n * returns a data URL that can be used in an SVG <image> element.\n */\nexport async function composeMapImage(options: ComposeMapOptions): Promise<string> {\n const { center, zoom, style, width, height, markers = [], showAttribution = true } = options;\n\n const provider = TILE_PROVIDERS[style];\n const tileSize = provider.tileSize || 256;\n const clampedZoom = Math.min(zoom, provider.maxZoom);\n\n // Create canvas\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext('2d');\n if (!ctx) throw new Error('Failed to get canvas context');\n\n // Fill with a neutral background in case tiles fail to load\n ctx.fillStyle = style === 'toner' ? '#ffffff' : '#e5e7eb';\n ctx.fillRect(0, 0, width, height);\n\n // Get tiles needed\n const tiles = getTilesForViewport(center.lat, center.lng, clampedZoom, width, height, tileSize);\n\n // Fetch and draw tiles\n const tilePromises = tiles.map(async (tile) => {\n const url = buildTileUrl(provider, tile.x, tile.y, clampedZoom);\n try {\n const img = await fetchTileImage(url);\n ctx.drawImage(img, tile.screenX, tile.screenY, tileSize, tileSize);\n } catch (err: unknown) {\n // Tile failed to load - leave background color\n console.warn(`Tile load failed: ${url}`, err);\n }\n });\n\n await Promise.all(tilePromises);\n\n // Draw markers\n for (const marker of markers) {\n drawMarker(ctx, marker, center, clampedZoom, width, height, tileSize);\n }\n\n // Draw attribution\n if (showAttribution) {\n drawAttribution(ctx, provider.attribution, width, height);\n }\n\n return canvas.toDataURL('image/png');\n}\n\n/**\n * Draw a marker on the canvas.\n */\nfunction drawMarker(\n ctx: CanvasRenderingContext2D,\n marker: MapMarker,\n center: { lat: number; lng: number },\n zoom: number,\n width: number,\n height: number,\n tileSize: number,\n): void {\n // Calculate screen position of marker relative to center\n const centerTile = latLngToTile(center.lat, center.lng, zoom);\n const markerTile = latLngToTile(marker.lat, marker.lng, zoom);\n\n const centerOffset = getPixelOffset(center.lat, center.lng, zoom, tileSize);\n const markerOffset = getPixelOffset(marker.lat, marker.lng, zoom, tileSize);\n\n const dx = (markerTile.x - centerTile.x) * tileSize + (markerOffset.x - centerOffset.x);\n const dy = (markerTile.y - centerTile.y) * tileSize + (markerOffset.y - centerOffset.y);\n\n const screenX = width / 2 + dx;\n const screenY = height / 2 + dy;\n\n // Draw marker\n const color = marker.color || '#ef4444';\n const icon = marker.icon || 'pin';\n\n ctx.save();\n\n if (icon === 'pin') {\n // Draw pin shape\n ctx.fillStyle = color;\n ctx.beginPath();\n ctx.arc(screenX, screenY - 12, 8, Math.PI, 0, false);\n ctx.lineTo(screenX, screenY);\n ctx.closePath();\n ctx.fill();\n\n // White dot in center\n ctx.fillStyle = '#ffffff';\n ctx.beginPath();\n ctx.arc(screenX, screenY - 12, 3, 0, Math.PI * 2);\n ctx.fill();\n } else if (icon === 'circle') {\n ctx.fillStyle = color;\n ctx.beginPath();\n ctx.arc(screenX, screenY, 8, 0, Math.PI * 2);\n ctx.fill();\n ctx.strokeStyle = '#ffffff';\n ctx.lineWidth = 2;\n ctx.stroke();\n } else if (icon === 'star') {\n ctx.fillStyle = color;\n drawStar(ctx, screenX, screenY, 5, 10, 5);\n ctx.fill();\n }\n\n // Draw label if present\n if (marker.label) {\n ctx.fillStyle = '#1f2937';\n ctx.font = 'bold 12px system-ui, sans-serif';\n ctx.textAlign = 'center';\n ctx.fillText(marker.label, screenX, screenY + 20);\n }\n\n ctx.restore();\n}\n\n/**\n * Draw a star shape.\n */\nfunction drawStar(\n ctx: CanvasRenderingContext2D,\n cx: number,\n cy: number,\n spikes: number,\n outerRadius: number,\n innerRadius: number,\n): void {\n let rot = (Math.PI / 2) * 3;\n const step = Math.PI / spikes;\n\n ctx.beginPath();\n ctx.moveTo(cx, cy - outerRadius);\n\n for (let i = 0; i < spikes; i++) {\n ctx.lineTo(cx + Math.cos(rot) * outerRadius, cy + Math.sin(rot) * outerRadius);\n rot += step;\n ctx.lineTo(cx + Math.cos(rot) * innerRadius, cy + Math.sin(rot) * innerRadius);\n rot += step;\n }\n\n ctx.lineTo(cx, cy - outerRadius);\n ctx.closePath();\n}\n\n/**\n * Draw attribution text on the canvas.\n */\nfunction drawAttribution(\n ctx: CanvasRenderingContext2D,\n text: string,\n width: number,\n height: number,\n): void {\n ctx.save();\n\n // Semi-transparent background\n ctx.fillStyle = 'rgba(255, 255, 255, 0.8)';\n const padding = 4;\n ctx.font = '10px system-ui, sans-serif';\n const textWidth = ctx.measureText(text).width;\n ctx.fillRect(width - textWidth - padding * 2 - 4, height - 16, textWidth + padding * 2, 14);\n\n // Text\n ctx.fillStyle = '#374151';\n ctx.textAlign = 'right';\n ctx.fillText(text, width - padding - 4, height - 5);\n\n ctx.restore();\n}\n\n/**\n * Get attribution text for a map style.\n */\nexport function getAttribution(style: MapTileStyle): string {\n return TILE_PROVIDERS[style].attribution;\n}\n","/**\n * MapLayer Component\n *\n * Renders a geographic map layer within an SVG block. Maps are composed from\n * static tile images fetched from free/open-source providers.\n *\n * For video export reliability, maps can use pre-rendered static images via\n * the staticSrc property, avoiding tile loading race conditions during capture.\n *\n * Tile fetching: Tiles are loaded on mount and composited into a data URL\n * for SVG embedding. This ensures correct rendering in both browser and\n * Playwright screenshot contexts.\n */\n\nimport { useState, useEffect } from 'react';\nimport type { MapLayer as MapLayerType } from '@bendyline/squisq/schemas';\nimport { getAnimationStyle } from '../utils/animationUtils';\nimport { resolveValue, getAnchorOffset } from '../utils/layerUtils';\nimport { composeMapImage } from '../utils/mapTileUtils';\n\ninterface MapLayerProps {\n layer: MapLayerType;\n /** Base path for resolving relative image URLs */\n basePath: string;\n /** Viewport dimensions for percentage calculations */\n viewport: { width: number; height: number };\n /** Current time relative to block start (for animation timing) */\n blockTime: number;\n}\n\nexport function MapLayer({ layer, basePath, viewport, blockTime }: MapLayerProps) {\n const { content, position, animation } = layer;\n const [mapImageUrl, setMapImageUrl] = useState<string | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n // Resolve position values to pixels\n const x = resolveValue(position.x, viewport.width);\n const y = resolveValue(position.y, viewport.height);\n const width = position.width ? resolveValue(position.width, viewport.width) : viewport.width;\n const height = position.height ? resolveValue(position.height, viewport.height) : viewport.height;\n\n // Apply anchor offset\n const offset = getAnchorOffset(position.anchor, width, height);\n const finalX = x + offset.x;\n const finalY = y + offset.y;\n\n // Use static image if provided, otherwise fetch and compose tiles\n useEffect(() => {\n let cancelled = false;\n\n if (content.staticSrc) {\n // Use pre-rendered static image\n const src = content.staticSrc.startsWith('http')\n ? content.staticSrc\n : `${basePath}/${content.staticSrc}`;\n setMapImageUrl(src);\n setIsLoading(false);\n return;\n }\n\n // Compose map from tiles\n setIsLoading(true);\n setError(null);\n\n composeMapImage({\n center: content.center,\n zoom: content.zoom,\n style: content.style,\n width,\n height,\n markers: content.markers,\n showAttribution: content.showAttribution !== false,\n })\n .then((dataUrl) => {\n if (!cancelled) {\n setMapImageUrl(dataUrl);\n setIsLoading(false);\n }\n })\n .catch((err: unknown) => {\n if (!cancelled) {\n console.error('Failed to compose map:', err);\n setError(err instanceof Error ? err.message : String(err));\n setIsLoading(false);\n }\n });\n\n return () => {\n cancelled = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- content properties are destructured below; center/markers/showAttribution are stable per-render\n }, [\n content.center.lat,\n content.center.lng,\n content.zoom,\n content.style,\n content.staticSrc,\n width,\n height,\n basePath,\n ]);\n\n // Get animation styles\n const animStyle = getAnimationStyle(animation, blockTime);\n\n // Render loading state\n if (isLoading) {\n return (\n <g\n className={`block-layer block-layer--map ${animStyle.className}`}\n style={animStyle.style}\n data-layer-id={layer.id}\n >\n <rect x={finalX} y={finalY} width={width} height={height} fill=\"#e5e7eb\" />\n <text\n x={finalX + width / 2}\n y={finalY + height / 2}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n fill=\"#9ca3af\"\n fontSize=\"24\"\n fontFamily=\"system-ui, sans-serif\"\n >\n Loading map...\n </text>\n </g>\n );\n }\n\n // Render error state\n if (error || !mapImageUrl) {\n return (\n <g\n className={`block-layer block-layer--map ${animStyle.className}`}\n style={animStyle.style}\n data-layer-id={layer.id}\n >\n <rect x={finalX} y={finalY} width={width} height={height} fill=\"#fef2f2\" />\n <text\n x={finalX + width / 2}\n y={finalY + height / 2}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n fill=\"#dc2626\"\n fontSize=\"18\"\n fontFamily=\"system-ui, sans-serif\"\n >\n Map failed to load\n </text>\n </g>\n );\n }\n\n return (\n <g\n className={`block-layer block-layer--map ${animStyle.className}`}\n style={animStyle.style}\n data-layer-id={layer.id}\n >\n {/* Clip path for overflow handling */}\n <defs>\n <clipPath id={`clip-${layer.id}`}>\n <rect x={finalX} y={finalY} width={width} height={height} />\n </clipPath>\n </defs>\n\n {/* Map image */}\n <g clipPath={`url(#clip-${layer.id})`}>\n <image\n href={mapImageUrl}\n x={finalX}\n y={finalY}\n width={width}\n height={height}\n preserveAspectRatio=\"xMidYMid slice\"\n style={{ pointerEvents: 'none' }}\n />\n </g>\n </g>\n );\n}\n\nexport default MapLayer;\n","/**\n * VideoLayer Component\n *\n * Renders a video clip layer within an SVG block. Uses an HTML5 <video> element\n * inside a <foreignObject> (same pattern as ImageLayer for cover-mode images).\n * Videos are always muted — narration audio is the only sound track.\n *\n * Two modes of operation:\n * 1. Normal playback: Video auto-plays from clipStart to clipEnd on mount,\n * pausing when the clip ends or when the block is no longer active.\n * 2. Render/seekTo mode (Playwright frame capture): Video is paused and seeked\n * programmatically via data attributes read by DocPlayer's seekTo handler.\n *\n * The <video> element carries data-clip-start and data-clip-end attributes so\n * the seekTo handler can calculate the correct video time for any doc time.\n *\n * Related Files:\n * - schemas/Doc.ts — VideoLayer type definition\n * - shared/doc/templates/videoWithCaption.ts — template producing VideoLayers\n * - site/src/components/doc/DocPlayer.tsx — seekTo handler for video sync\n * - site/src/components/doc/layers/ImageLayer.tsx — similar foreignObject pattern\n */\n\nimport { useRef, useEffect } from 'react';\nimport type { VideoLayer as VideoLayerType } from '@bendyline/squisq/schemas';\nimport { useMediaUrl } from '../hooks/MediaContext';\nimport { resolveValue, getAnchorOffset } from '../utils/layerUtils';\n\ninterface VideoLayerProps {\n layer: VideoLayerType;\n /** Base path for resolving relative video URLs */\n basePath: string;\n /** Viewport dimensions for percentage calculations */\n viewport: { width: number; height: number };\n /** Current time relative to block start (for playback sync) */\n blockTime: number;\n /** Whether the doc is currently playing */\n isPlaying?: boolean;\n}\n\nexport function VideoLayer({\n layer,\n basePath,\n viewport,\n blockTime: _blockTime,\n isPlaying,\n}: VideoLayerProps) {\n const { content, position } = layer;\n const videoRef = useRef<HTMLVideoElement>(null);\n const hasStartedRef = useRef(false);\n\n // Resolve position values to pixels\n const x = resolveValue(position.x, viewport.width);\n const y = resolveValue(position.y, viewport.height);\n const width = position.width ? resolveValue(position.width, viewport.width) : viewport.width;\n const height = position.height ? resolveValue(position.height, viewport.height) : viewport.height;\n\n // Apply anchor offset\n const offset = getAnchorOffset(position.anchor, width, height);\n const finalX = x + offset.x;\n const finalY = y + offset.y;\n\n // Resolve video URL via MediaProvider (if available), falling back to basePath\n const src = useMediaUrl(content.src, basePath);\n\n // Always call the hook (Rules of Hooks), but pass empty string when no poster\n const resolvedPoster = useMediaUrl(content.posterSrc || '', basePath);\n const posterSrc = content.posterSrc ? resolvedPoster : undefined;\n\n // On mount: seek to clipStart and set up clipEnd boundary.\n // The video will be muted and play silently alongside the narration.\n useEffect(() => {\n const video = videoRef.current;\n if (!video) return;\n\n // Set initial time to clipStart\n video.currentTime = content.clipStart;\n hasStartedRef.current = true;\n\n // Start playing if doc is already playing\n if (isPlaying) {\n const playPromise = video.play();\n if (playPromise) {\n playPromise.catch(() => {\n // Autoplay blocked — fine for Playwright seekTo mode\n });\n }\n }\n\n // Monitor timeupdate to pause at clipEnd\n const handleTimeUpdate = () => {\n if (video.currentTime >= content.clipEnd) {\n video.pause();\n video.currentTime = content.clipEnd;\n }\n };\n\n video.addEventListener('timeupdate', handleTimeUpdate);\n return () => {\n video.removeEventListener('timeupdate', handleTimeUpdate);\n video.pause();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- isPlaying is handled by the separate sync effect below\n }, [content.src, content.clipStart, content.clipEnd]);\n\n // Sync video play/pause with doc playback state\n useEffect(() => {\n const video = videoRef.current;\n if (!video || !hasStartedRef.current) return;\n\n // Don't resume if clip has already reached its end\n if (video.currentTime >= content.clipEnd) return;\n\n if (isPlaying) {\n const playPromise = video.play();\n if (playPromise) {\n playPromise.catch(() => {});\n }\n } else {\n video.pause();\n }\n }, [isPlaying, content.clipEnd]);\n\n return (\n <g className=\"block-layer block-layer--video\" data-layer-id={layer.id}>\n <foreignObject x={finalX} y={finalY} width={width} height={height}>\n <video\n ref={videoRef}\n src={src}\n poster={posterSrc}\n muted\n playsInline\n preload=\"auto\"\n data-clip-start={content.clipStart}\n data-clip-end={content.clipEnd}\n style={{\n width: '100%',\n height: '100%',\n objectFit: content.fit || 'cover',\n objectPosition: 'center',\n display: 'block',\n pointerEvents: 'none',\n }}\n />\n </foreignObject>\n </g>\n );\n}\n\nexport default VideoLayer;\n","/**\n * TableLayer Component\n *\n * Renders a data table within an SVG block using a <foreignObject> to embed\n * an HTML table. This gives us native table layout inside SVG viewports.\n *\n * The table is styled inline using the TableLayerStyle properties, which are\n * typically derived from the active theme by the dataTable template.\n */\n\nimport type { TableLayer as TableLayerType } from '@bendyline/squisq/schemas';\nimport { resolveValue, getAnchorOffset } from '../utils/layerUtils';\nimport { getAnimationStyle } from '../utils/animationUtils';\n\ninterface TableLayerProps {\n layer: TableLayerType;\n /** Viewport dimensions for percentage calculations */\n viewport: { width: number; height: number };\n /** Current time relative to block start (for animation) */\n blockTime: number;\n}\n\nexport function TableLayer({ layer, viewport, blockTime }: TableLayerProps) {\n const { content, position, animation } = layer;\n const { headers, rows, align, style } = content;\n\n // Resolve position values to pixels\n const x = resolveValue(position.x, viewport.width);\n const y = resolveValue(position.y, viewport.height);\n const width = position.width ? resolveValue(position.width, viewport.width) : viewport.width;\n const height = position.height ? resolveValue(position.height, viewport.height) : viewport.height;\n\n // Apply anchor offset\n const offset = getAnchorOffset(position.anchor, width, height);\n const finalX = x + offset.x;\n const finalY = y + offset.y;\n\n // Build animation style\n const animStyle = animation ? getAnimationStyle(animation, blockTime) : {};\n\n const cellAlign = (ci: number): React.CSSProperties | undefined => {\n const a = align?.[ci];\n return a ? { textAlign: a } : undefined;\n };\n\n const borderRadius = style.borderRadius ?? 8;\n\n return (\n <foreignObject x={finalX} y={finalY} width={width} height={height} style={animStyle}>\n <div\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n {...({ xmlns: 'http://www.w3.org/1999/xhtml' } as any)}\n style={{\n width: '100%',\n height: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '16px',\n boxSizing: 'border-box',\n }}\n >\n <table\n style={{\n width: '100%',\n borderCollapse: 'separate',\n borderSpacing: 0,\n fontSize: `${style.fontSize}px`,\n fontFamily: style.fontFamily ?? 'system-ui, sans-serif',\n overflow: 'hidden',\n borderRadius: `${borderRadius}px`,\n border: `1px solid ${style.borderColor}`,\n }}\n >\n {headers.length > 0 && (\n <thead>\n <tr>\n {headers.map((header, ci) => (\n <th\n key={ci}\n style={{\n background: style.headerBackground,\n color: style.headerColor,\n fontFamily:\n style.headerFontFamily ?? style.fontFamily ?? 'system-ui, sans-serif',\n fontWeight: 600,\n padding: '12px 16px',\n borderBottom: `2px solid ${style.borderColor}`,\n borderRight:\n ci < headers.length - 1 ? `1px solid ${style.borderColor}` : undefined,\n ...cellAlign(ci),\n }}\n >\n {header}\n </th>\n ))}\n </tr>\n </thead>\n )}\n {rows.length > 0 && (\n <tbody>\n {rows.map((row, ri) => (\n <tr key={ri}>\n {row.map((cell, ci) => (\n <td\n key={ci}\n style={{\n background: style.cellBackground,\n color: style.cellColor,\n padding: '10px 16px',\n borderBottom:\n ri < rows.length - 1 ? `1px solid ${style.borderColor}` : undefined,\n borderRight:\n ci < row.length - 1 ? `1px solid ${style.borderColor}` : undefined,\n ...cellAlign(ci),\n }}\n >\n {cell}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n )}\n </table>\n </div>\n </foreignObject>\n );\n}\n","/**\n * BlockRenderer Component\n *\n * Renders a single block as an SVG element with all its layers.\n * Each layer is rendered back-to-front (first layer is background).\n * Handles positioning, animations, and transitions.\n */\n\nimport type { Block, Layer } from '@bendyline/squisq/schemas';\nimport { ImageLayer } from './layers/ImageLayer';\nimport { TextLayer } from './layers/TextLayer';\nimport { ShapeLayer } from './layers/ShapeLayer';\nimport { MapLayer } from './layers/MapLayer';\nimport { VideoLayer } from './layers/VideoLayer';\nimport { TableLayer } from './layers/TableLayer';\nimport { getTransitionClass } from './utils/animationUtils';\n\n/** Default viewport dimensions (1080p landscape) - for backwards compatibility */\n// eslint-disable-next-line react-refresh/only-export-components\nexport const VIEWPORT = {\n width: 1920,\n height: 1080,\n};\n\n/** Viewport configuration type */\nexport interface ViewportDimensions {\n width: number;\n height: number;\n}\n\ninterface BlockRendererProps {\n /** The block to render */\n block: Block;\n /** Current time relative to block start (seconds) */\n blockTime: number;\n /** Base path for resolving media URLs */\n basePath: string;\n /** Whether this block is entering (for transition) */\n isEntering?: boolean;\n /** Whether this block is exiting (for transition) */\n isExiting?: boolean;\n /** Viewport dimensions (defaults to 1920x1080 landscape) */\n viewport?: ViewportDimensions;\n /** Whether the doc is currently playing (controls video playback) */\n isPlaying?: boolean;\n}\n\nexport function BlockRenderer({\n block,\n blockTime,\n basePath,\n isEntering = false,\n isExiting = false,\n viewport = VIEWPORT,\n isPlaying,\n}: BlockRendererProps) {\n // Build transition class and inline style for dynamic duration\n let transitionClass = '';\n const transitionStyle: Record<string, string> = {};\n if (block.transition && isEntering) {\n transitionClass = getTransitionClass(block.transition.type, true);\n transitionStyle['--transition-duration'] = `${block.transition.duration}s`;\n } else if (block.transition && isExiting) {\n transitionClass = getTransitionClass(block.transition.type, false);\n transitionStyle['--transition-duration'] = `${block.transition.duration}s`;\n }\n\n // Unique clip path ID per block to avoid conflicts when multiple blocks render simultaneously\n const clipId = `vb-clip-${block.id}`;\n\n return (\n <svg\n className={`block-svg ${transitionClass}`}\n style={transitionStyle}\n viewBox={`0 0 ${viewport.width} ${viewport.height}`}\n preserveAspectRatio=\"xMidYMid meet\"\n overflow=\"hidden\"\n data-block-id={block.id}\n >\n {/* Clip path matching the viewBox -- prevents Ken Burns animations from\n bleeding outside the block area (foreignObject + transform: scale\n can escape SVG overflow=\"hidden\" in some browsers) */}\n <defs>\n <clipPath id={clipId}>\n <rect x=\"0\" y=\"0\" width={viewport.width} height={viewport.height} />\n </clipPath>\n </defs>\n\n {/* All layers clipped to viewBox bounds */}\n <g clipPath={`url(#${clipId})`}>\n {(block.layers ?? []).map((layer) => (\n <LayerRenderer\n key={layer.id}\n layer={layer}\n basePath={basePath}\n viewport={viewport}\n blockTime={blockTime}\n isPlaying={isPlaying}\n />\n ))}\n </g>\n </svg>\n );\n}\n\ninterface LayerRendererProps {\n layer: Layer;\n basePath: string;\n viewport: { width: number; height: number };\n blockTime: number;\n isPlaying?: boolean;\n}\n\n/**\n * Dispatch to the appropriate layer component based on type.\n */\nfunction LayerRenderer({ layer, basePath, viewport, blockTime, isPlaying }: LayerRendererProps) {\n switch (layer.type) {\n case 'image':\n return (\n <ImageLayer layer={layer} basePath={basePath} viewport={viewport} blockTime={blockTime} />\n );\n case 'text':\n return <TextLayer layer={layer} viewport={viewport} blockTime={blockTime} />;\n case 'shape':\n return <ShapeLayer layer={layer} viewport={viewport} blockTime={blockTime} />;\n case 'map':\n return (\n <MapLayer layer={layer} basePath={basePath} viewport={viewport} blockTime={blockTime} />\n );\n case 'video':\n return (\n <VideoLayer\n layer={layer}\n basePath={basePath}\n viewport={viewport}\n blockTime={blockTime}\n isPlaying={isPlaying}\n />\n );\n case 'table':\n return <TableLayer layer={layer} viewport={viewport} blockTime={blockTime} />;\n default:\n console.warn(`Unknown layer type: ${(layer as Layer).type}`);\n return null;\n }\n}\n\nexport default BlockRenderer;\n","/**\n * SocialCaptionOverlay Component\n *\n * Social media-style captions (Instagram/TikTok): large centered words\n * showing 3-5 words at a time with the currently-spoken word highlighted\n * in the theme's primary color. Font and colors are pulled from the\n * active theme.\n *\n * Words are gathered across all caption phrases into a continuous stream,\n * then chunked into uniform groups for smooth, consistent pacing.\n *\n * Supports two timing modes:\n * 1. Precise: uses per-word timestamps from CaptionPhrase.words\n * 2. Interpolated: distributes timing evenly within each phrase\n */\n\nimport { useMemo } from 'react';\nimport type { CaptionTrack, CaptionPhrase, ViewportConfig } from '@bendyline/squisq/schemas';\nimport type { Theme } from '@bendyline/squisq/schemas';\n\n/** Target words per visible chunk. */\nconst TARGET_CHUNK_SIZE = 4;\nconst MIN_CHUNK_SIZE = 2;\nconst MAX_CHUNK_SIZE = 6;\n\n/** A timed word derived from phrase data. */\ninterface TimedWord {\n text: string;\n startTime: number;\n endTime: number;\n}\n\n/** A chunk of words displayed together. */\ninterface WordChunk {\n words: TimedWord[];\n startTime: number;\n endTime: number;\n}\n\n/**\n * Resolve per-word timing for a single phrase.\n * Uses precise word timestamps when available, otherwise interpolates.\n */\nfunction resolvePhraseTiming(phrase: CaptionPhrase): TimedWord[] {\n // Use precise timing when available\n if (phrase.words && phrase.words.length > 0) {\n return phrase.words.map((w) => ({\n text: w.text,\n startTime: w.startTime,\n endTime: w.endTime,\n }));\n }\n\n // Interpolate: split text into words, distribute evenly\n const rawWords = phrase.text.split(/\\s+/).filter((w) => w.length > 0);\n if (rawWords.length === 0) return [];\n\n const duration = phrase.endTime - phrase.startTime;\n const wordDuration = duration / rawWords.length;\n\n return rawWords.map((text, i) => ({\n text,\n startTime: phrase.startTime + i * wordDuration,\n endTime: phrase.startTime + (i + 1) * wordDuration,\n }));\n}\n\n/**\n * Build a continuous stream of timed words from ALL caption phrases,\n * then group into uniform display chunks. This eliminates the \"pulsy\"\n * feeling caused by per-phrase chunking with variable phrase lengths.\n */\nfunction buildWordStream(captions: CaptionTrack): { words: TimedWord[]; chunks: WordChunk[] } {\n // Gather all words across all phrases\n const allWords: TimedWord[] = [];\n for (const phrase of captions.phrases) {\n allWords.push(...resolvePhraseTiming(phrase));\n }\n\n if (allWords.length === 0) return { words: [], chunks: [] };\n\n // Determine uniform chunk size\n let chunkSize = TARGET_CHUNK_SIZE;\n if (allWords.length > chunkSize) {\n const numChunks = Math.ceil(allWords.length / chunkSize);\n chunkSize = Math.ceil(allWords.length / numChunks);\n chunkSize = Math.min(MAX_CHUNK_SIZE, Math.max(MIN_CHUNK_SIZE, chunkSize));\n } else {\n chunkSize = Math.max(MIN_CHUNK_SIZE, allWords.length);\n }\n\n // Build chunks\n const chunks: WordChunk[] = [];\n for (let i = 0; i < allWords.length; i += chunkSize) {\n const chunkWords = allWords.slice(i, i + chunkSize);\n chunks.push({\n words: chunkWords,\n startTime: chunkWords[0].startTime,\n endTime: chunkWords[chunkWords.length - 1].endTime,\n });\n }\n\n return { words: allWords, chunks };\n}\n\ninterface SocialCaptionOverlayProps {\n captions: CaptionTrack | undefined;\n currentTime: number;\n enabled?: boolean;\n theme?: Theme;\n viewport?: ViewportConfig;\n}\n\nexport function SocialCaptionOverlay({\n captions,\n currentTime,\n enabled = true,\n theme,\n viewport,\n}: SocialCaptionOverlayProps) {\n // Build the word stream once when captions change (memoized)\n const { chunks } = useMemo(\n () => (captions ? buildWordStream(captions) : { words: [], chunks: [] }),\n [captions],\n );\n\n if (!enabled || chunks.length === 0) {\n return (\n <div\n className=\"social-caption-overlay\"\n style={{\n position: 'absolute',\n bottom: '18%',\n left: 0,\n right: 0,\n zIndex: 50,\n pointerEvents: 'none',\n opacity: 0,\n transition: 'opacity 0.15s ease-in-out',\n }}\n />\n );\n }\n\n // Find the active chunk and word using binary-style search\n let activeChunk: WordChunk | null = null;\n let activeWordIndex = -1;\n\n for (const chunk of chunks) {\n if (currentTime >= chunk.startTime && currentTime < chunk.endTime) {\n activeChunk = chunk;\n break;\n }\n }\n\n // If between chunks (gap), show the nearest chunk\n if (!activeChunk) {\n for (let i = 0; i < chunks.length - 1; i++) {\n if (currentTime >= chunks[i].endTime && currentTime < chunks[i + 1].startTime) {\n // In a gap — show the chunk we just left (feels more natural)\n activeChunk = chunks[i];\n activeWordIndex = activeChunk.words.length - 1;\n break;\n }\n }\n // Past all chunks\n if (!activeChunk && chunks.length > 0 && currentTime >= chunks[chunks.length - 1].startTime) {\n activeChunk = chunks[chunks.length - 1];\n activeWordIndex = activeChunk.words.length - 1;\n }\n }\n\n if (!activeChunk) return null;\n\n // Find active word within chunk (if not already set from gap handling)\n if (activeWordIndex === -1) {\n for (let i = 0; i < activeChunk.words.length; i++) {\n const word = activeChunk.words[i];\n if (currentTime >= word.startTime && currentTime < word.endTime) {\n activeWordIndex = i;\n break;\n }\n }\n // Fallback: last word before currentTime\n if (activeWordIndex === -1) {\n for (let i = activeChunk.words.length - 1; i >= 0; i--) {\n if (currentTime >= activeChunk.words[i].startTime) {\n activeWordIndex = i;\n break;\n }\n }\n }\n // Final fallback\n if (activeWordIndex === -1) activeWordIndex = 0;\n }\n\n // Theme-derived styling\n const primaryColor = theme?.colors?.primary ?? '#5b9bd5';\n const fontFamily = theme?.typography?.titleFontFamily\n ? `\"${theme.typography.titleFontFamily}\", system-ui, sans-serif`\n : '\"PT Serif\", Georgia, serif';\n\n // Scale font to viewport — aim for ~5.5% of viewport height\n const viewportHeight = viewport?.height ?? 720;\n const baseFontSize = Math.round(viewportHeight * 0.055);\n const fontSize = Math.max(24, Math.min(72, baseFontSize));\n\n return (\n <div\n className=\"social-caption-overlay\"\n style={{\n position: 'absolute',\n bottom: '18%',\n left: 0,\n right: 0,\n zIndex: 50,\n pointerEvents: 'none',\n textAlign: 'center',\n padding: '0 8%',\n boxSizing: 'border-box',\n opacity: 1,\n transition: 'opacity 0.15s ease-in-out',\n }}\n >\n <div\n style={{\n display: 'inline-block',\n lineHeight: 1.3,\n }}\n >\n {activeChunk.words.map((word, i) => {\n const isActive = i === activeWordIndex;\n return (\n <span\n key={`${word.startTime}-${i}`}\n style={{\n fontFamily,\n fontSize: `${fontSize}px`,\n fontWeight: isActive ? 800 : 600,\n color: isActive ? primaryColor : 'rgba(255, 255, 255, 0.9)',\n textShadow: '0 2px 8px rgba(0,0,0,0.7), 0 0 20px rgba(0,0,0,0.4)',\n marginRight: i < activeChunk!.words.length - 1 ? '0.3em' : undefined,\n transition: 'color 0.1s ease, font-weight 0.1s ease',\n textTransform: 'uppercase',\n }}\n >\n {word.text}\n </span>\n );\n })}\n </div>\n </div>\n );\n}\n","/**\n * CaptionOverlay Component\n *\n * Displays closed captions synchronized with audio playback.\n * Supports two styles:\n *\n * - `'standard'` (default): Traditional broadcast captions — small white text\n * on a semi-transparent black badge at the top of the player.\n * - `'social'`: Social media-style (Instagram/TikTok) — large centered words\n * with the active word highlighted in the theme's primary color.\n */\n\nimport type { CaptionTrack, ViewportConfig } from '@bendyline/squisq/schemas';\nimport { getCaptionAtTime } from '@bendyline/squisq/schemas';\nimport type { Theme } from '@bendyline/squisq/schemas';\nimport type { CaptionStyle } from './types';\nimport { SocialCaptionOverlay } from './SocialCaptionOverlay';\n\ninterface CaptionOverlayProps {\n /** Caption track with timestamped phrases */\n captions: CaptionTrack | undefined;\n /** Current playback time in seconds */\n currentTime: number;\n /** Whether captions are enabled */\n enabled?: boolean;\n /** Font size in pixels for standard style (default: 16) */\n fontSize?: number;\n /** Caption display style (default: 'standard') */\n captionStyle?: CaptionStyle;\n /** Theme for social-style caption colors and fonts */\n theme?: Theme;\n /** Viewport config for social-style font scaling */\n viewport?: ViewportConfig;\n}\n\nexport function CaptionOverlay({\n captions,\n currentTime,\n enabled = true,\n fontSize = 16,\n captionStyle = 'standard',\n theme,\n viewport,\n}: CaptionOverlayProps) {\n // Delegate to social overlay when that style is active\n if (captionStyle === 'social') {\n return (\n <SocialCaptionOverlay\n captions={captions}\n currentTime={currentTime}\n enabled={enabled}\n theme={theme}\n viewport={viewport}\n />\n );\n }\n\n // Standard caption rendering\n const phrase = enabled && captions ? getCaptionAtTime(captions, currentTime) : null;\n const captionText = phrase?.text ?? null;\n\n return (\n <div\n className=\"caption-overlay\"\n style={{\n position: 'absolute',\n top: '6px',\n left: '50%',\n transform: 'translateX(-50%)',\n zIndex: 50,\n pointerEvents: 'none',\n maxWidth: '100%',\n width: '100%',\n textAlign: 'center',\n opacity: captionText ? 1 : 0,\n transition: 'opacity 0.15s ease-in-out',\n padding: '0 4px',\n boxSizing: 'border-box',\n }}\n >\n {captionText && (\n <div\n style={{\n display: 'inline-block',\n padding: '3px 10px',\n background: 'rgba(0, 0, 0, 0.65)',\n borderRadius: '4px',\n backdropFilter: 'blur(4px)',\n }}\n >\n <span\n style={{\n color: '#ffffff',\n fontSize: `${fontSize}px`,\n fontFamily: \"'Hanken Grotesk', system-ui, sans-serif\",\n fontWeight: 500,\n lineHeight: 1.25,\n textShadow: '0 1px 3px rgba(0,0,0,0.5)',\n whiteSpace: 'pre-wrap',\n wordWrap: 'break-word',\n }}\n >\n {captionText}\n </span>\n </div>\n )}\n </div>\n );\n}\n\nexport default CaptionOverlay;\n","/**\n * useAudioSync Hook\n *\n * Synchronizes playback state with an audio element. Provides current\n * playback time, playing state, and methods to control audio playback.\n *\n * Handles multiple audio segments (MP3 files) by tracking which segment\n * is currently playing and calculating the overall timeline position.\n *\n * This is the HTML5 Audio implementation of the AudioProvider interface.\n * For EFB/MSFS environments, use useCompanionAudioSync instead.\n */\n\nimport { useState, useEffect, useRef, useCallback } from 'react';\nimport type { RefObject } from 'react';\nimport type { AudioTrack } from '@bendyline/squisq/schemas';\nimport type { AudioProvider } from './AudioProvider';\n\nexport function useAudioSync(\n audioRef: RefObject<HTMLAudioElement>,\n audioTrack: AudioTrack | undefined,\n basePath: string = '',\n): AudioProvider {\n const [currentTime, setCurrentTime] = useState(0);\n const [isPlaying, setIsPlaying] = useState(false);\n const [currentSegment, setCurrentSegment] = useState(0);\n const [isEnded, setIsEnded] = useState(false);\n const [isAudioReady, setIsAudioReady] = useState(false);\n const [totalDuration, setTotalDuration] = useState(0);\n\n // Calculate segment start times\n const segmentStarts = useRef<number[]>([]);\n\n // Pending seek time (used when switching segments)\n const pendingSeekTime = useRef<number | null>(null);\n const shouldPlayAfterLoad = useRef(false);\n\n // Preloaded audio blob URLs (for seeking without range request support)\n const blobUrls = useRef<Map<string, string>>(new Map());\n const loadingPromises = useRef<Map<string, Promise<string>>>(new Map());\n\n // Fallback timer: when audio.play() is blocked (e.g., autoplay policy),\n // advance currentTime synthetically so blocks still progress without audio.\n const fallbackMode = useRef(false);\n\n useEffect(() => {\n if (!audioTrack?.segments) {\n return;\n }\n\n let time = 0;\n segmentStarts.current = audioTrack.segments.map((seg) => {\n const start = time;\n time += seg.duration;\n return start;\n });\n setTotalDuration(time);\n }, [audioTrack]);\n\n // Preload audio file as blob (enables seeking without range request support)\n const preloadAudio = useCallback(\n async (src: string): Promise<string> => {\n const audioUrl = basePath ? `${basePath}/${src}` : src;\n\n // Return cached blob URL if available\n if (blobUrls.current.has(src)) {\n return blobUrls.current.get(src)!;\n }\n\n // Return existing loading promise if in progress\n if (loadingPromises.current.has(src)) {\n return loadingPromises.current.get(src)!;\n }\n\n // Start loading\n const loadPromise = (async () => {\n try {\n const response = await fetch(audioUrl);\n if (!response.ok) throw new Error(`HTTP ${response.status}`);\n const blob = await response.blob();\n const blobUrl = URL.createObjectURL(blob);\n blobUrls.current.set(src, blobUrl);\n return blobUrl;\n } catch {\n // Fall back to direct URL if blob loading fails\n return audioUrl;\n } finally {\n loadingPromises.current.delete(src);\n }\n })();\n\n loadingPromises.current.set(src, loadPromise);\n return loadPromise;\n },\n [basePath],\n );\n\n // Preload all audio segments on mount\n useEffect(() => {\n if (!audioTrack?.segments) return;\n\n // Preload all segments in parallel\n audioTrack.segments.forEach((segment) => {\n preloadAudio(segment.src);\n });\n\n // Cleanup blob URLs on unmount\n const currentBlobUrls = blobUrls.current;\n return () => {\n currentBlobUrls.forEach((url) => {\n URL.revokeObjectURL(url);\n });\n currentBlobUrls.clear();\n };\n }, [audioTrack, preloadAudio]);\n\n // Handle audio time updates\n useEffect(() => {\n const audio = audioRef.current;\n if (!audio) return;\n\n const handleTimeUpdate = () => {\n // Calculate overall timeline position\n const segmentStart = segmentStarts.current[currentSegment] || 0;\n const overallTime = segmentStart + audio.currentTime;\n setCurrentTime(overallTime);\n };\n\n const handlePlay = () => {\n fallbackMode.current = false;\n setIsPlaying(true);\n };\n const handlePause = () => setIsPlaying(false);\n const handleError = () => {\n // Audio source failed to load (e.g., 404 in CI or missing files).\n // Set ready so the UI can still render controls and progress.\n setIsAudioReady(true);\n };\n const handleEnded = () => {\n // Move to next segment or end\n if (audioTrack && currentSegment < audioTrack.segments.length - 1) {\n // Auto-advance to next segment\n // Set shouldPlayAfterLoad so the next segment auto-plays after loading\n shouldPlayAfterLoad.current = true;\n setCurrentSegment((prev) => prev + 1);\n } else {\n setIsEnded(true);\n setIsPlaying(false);\n }\n };\n\n audio.addEventListener('timeupdate', handleTimeUpdate);\n audio.addEventListener('play', handlePlay);\n audio.addEventListener('pause', handlePause);\n audio.addEventListener('ended', handleEnded);\n audio.addEventListener('error', handleError);\n\n return () => {\n audio.removeEventListener('timeupdate', handleTimeUpdate);\n audio.removeEventListener('play', handlePlay);\n audio.removeEventListener('pause', handlePause);\n audio.removeEventListener('ended', handleEnded);\n audio.removeEventListener('error', handleError);\n };\n }, [audioRef, currentSegment, audioTrack]);\n\n // Load new segment when currentSegment changes\n useEffect(() => {\n const audio = audioRef.current;\n if (!audio || !audioTrack?.segments) return;\n\n const segment = audioTrack.segments[currentSegment];\n if (!segment) return;\n\n // Apply pending seek and play state\n const applyPendingSeek = () => {\n if (pendingSeekTime.current !== null) {\n const segmentStart = segmentStarts.current[currentSegment] || 0;\n const segmentTime = pendingSeekTime.current - segmentStart;\n audio.currentTime = Math.max(0, segmentTime);\n setCurrentTime(pendingSeekTime.current);\n pendingSeekTime.current = null;\n }\n\n if (shouldPlayAfterLoad.current) {\n audio.play().catch(() => {});\n shouldPlayAfterLoad.current = false;\n }\n };\n\n // Check if we're already on this source (avoid unnecessary reload)\n // For blob URLs, check by segment src key\n const currentSrc = audio.src;\n const cachedBlobUrl = blobUrls.current.get(segment.src);\n const isSameSource =\n currentSrc && (currentSrc === cachedBlobUrl || currentSrc.endsWith(segment.src));\n\n if (!isSameSource) {\n // Need to load new source - use preloaded blob URL\n const loadAndPlay = async () => {\n const blobUrl = await preloadAudio(segment.src);\n\n const handleCanPlay = () => {\n setIsAudioReady(true);\n applyPendingSeek();\n audio.removeEventListener('canplay', handleCanPlay);\n };\n\n audio.addEventListener('canplay', handleCanPlay);\n audio.src = blobUrl;\n audio.load();\n\n // If audio is already ready (blob is instant), canplay might not fire\n // Check after a microtask to see if it's ready\n await Promise.resolve();\n if (audio.readyState >= 3) {\n audio.removeEventListener('canplay', handleCanPlay);\n setIsAudioReady(true);\n applyPendingSeek();\n }\n };\n\n loadAndPlay();\n } else {\n // Same source - apply seek directly\n applyPendingSeek();\n }\n }, [audioRef, currentSegment, audioTrack, preloadAudio]);\n\n const play = useCallback(() => {\n const audio = audioRef.current;\n if (audio) {\n if (isEnded) {\n // Restart from beginning\n setCurrentSegment(0);\n setIsEnded(false);\n }\n audio\n .play()\n .then(() => {\n fallbackMode.current = false;\n })\n .catch(() => {\n // Audio playback failed (e.g., autoplay policy or 404).\n // Enable fallback timer so blocks progress without audio.\n fallbackMode.current = true;\n setIsPlaying(true);\n });\n }\n }, [audioRef, isEnded]);\n\n const pause = useCallback(() => {\n const audio = audioRef.current;\n if (audio) {\n audio.pause();\n }\n // Also set state directly for cases where audio isn't loaded\n // (pause event won't fire if audio has no valid source)\n setIsPlaying(false);\n }, [audioRef]);\n\n const toggle = useCallback(() => {\n const audio = audioRef.current;\n if (!audio) return;\n\n // Use component state instead of audio.paused to handle cases where\n // audio source isn't loaded (audio.paused is always true without a source)\n if (!isPlaying) {\n play();\n } else {\n pause();\n }\n }, [audioRef, isPlaying, play, pause]);\n\n const seekTo = useCallback(\n (time: number) => {\n const audio = audioRef.current;\n if (!audio || !audioTrack?.segments) return;\n\n // Clamp time to valid range.\n // When totalDuration is 0 (no audio segments), don't clamp — allow\n // seeking by block timing alone (used in render mode / preview).\n const clampedTime =\n totalDuration > 0 ? Math.max(0, Math.min(time, totalDuration)) : Math.max(0, time);\n\n // Find which segment this time falls into\n let segmentIndex = 0;\n let segmentStart = 0;\n for (let i = 0; i < audioTrack.segments.length; i++) {\n const segEnd = segmentStart + audioTrack.segments[i].duration;\n if (clampedTime < segEnd) {\n segmentIndex = i;\n break;\n }\n segmentStart = segEnd;\n // Handle edge case: time exactly at end goes to last segment\n if (i === audioTrack.segments.length - 1) {\n segmentIndex = i;\n }\n }\n\n const wasPlaying = !audio.paused;\n setIsEnded(false);\n\n // Check if we need to switch segments\n if (segmentIndex !== currentSegment) {\n // Store pending seek time - will be applied after segment loads\n pendingSeekTime.current = clampedTime;\n shouldPlayAfterLoad.current = wasPlaying;\n setCurrentSegment(segmentIndex);\n } else {\n // Same segment - seek directly\n const segmentTime = clampedTime - segmentStart;\n audio.currentTime = Math.max(0, segmentTime);\n setCurrentTime(clampedTime);\n }\n },\n [audioRef, audioTrack, currentSegment, totalDuration],\n );\n\n const skipToSegment = useCallback(\n (index: number) => {\n if (!audioTrack?.segments || index < 0 || index >= audioTrack.segments.length) {\n return;\n }\n setCurrentSegment(index);\n setIsEnded(false);\n },\n [audioTrack],\n );\n\n // Restart from beginning\n const restart = useCallback(async () => {\n seekTo(0);\n // Small delay to ensure seek completes before playing\n await new Promise((resolve) => setTimeout(resolve, 50));\n play();\n }, [seekTo, play]);\n\n // Fallback timer: advance currentTime synthetically when audio.play() was blocked\n // (e.g., autoplay policy or missing audio). Blocks progress at real-time pace\n // without sound. Stops when audio actually starts playing or playback is paused.\n useEffect(() => {\n if (!isPlaying || !fallbackMode.current || !totalDuration) return;\n\n let lastTime = performance.now();\n let raf: number;\n\n const tick = (now: number) => {\n // Audio started playing for real — stop the fallback\n if (!fallbackMode.current) return;\n\n const dt = (now - lastTime) / 1000;\n lastTime = now;\n\n setCurrentTime((prev) => {\n const next = prev + dt;\n if (next >= totalDuration) {\n fallbackMode.current = false;\n setIsEnded(true);\n setIsPlaying(false);\n return totalDuration;\n }\n return next;\n });\n\n raf = requestAnimationFrame(tick);\n };\n\n raf = requestAnimationFrame(tick);\n return () => cancelAnimationFrame(raf);\n }, [isPlaying, totalDuration]);\n\n return {\n // State\n currentTime,\n isPlaying,\n currentSegment,\n totalDuration,\n isEnded,\n isReady: isAudioReady,\n isAvailable: true, // HTML5 audio is always available in browsers\n // Actions\n play: async () => play(),\n pause: async () => pause(),\n toggle: async () => toggle(),\n seekTo: async (time: number) => seekTo(time),\n skipToSegment: async (index: number) => skipToSegment(index),\n restart,\n };\n}\n\nexport default useAudioSync;\n","/**\n * useDocPlayback Hook\n *\n * Manages the playback state for a visual doc, including which block\n * is currently active, transition states, and synchronization with audio.\n *\n * This hook provides:\n * - Current block determination based on time\n * - Transition tracking (entering/exiting blocks)\n * - Manual navigation (next/prev block)\n * - Time-based seeking\n * - Automatic expansion of template blocks\n */\n\nimport { useState, useEffect, useMemo, useCallback, useRef } from 'react';\nimport type { Doc, Block, DocBlock } from '@bendyline/squisq/schemas';\nimport type { Theme } from '@bendyline/squisq/schemas';\nimport { getBlockAtTime } from '@bendyline/squisq/schemas';\nimport {\n expandDocBlocks,\n flattenBlocks,\n isTemplateBlock,\n VIEWPORT_PRESETS,\n type ViewportConfig,\n} from '@bendyline/squisq/doc';\n\ninterface PlaybackState {\n /** Currently visible block */\n currentBlock: Block | null;\n /** Index of current block */\n currentBlockIndex: number;\n /** Previous block (for transitions) */\n previousBlock: Block | null;\n /** Whether current block is entering */\n isEntering: boolean;\n /** Whether previous block is exiting */\n isExiting: boolean;\n /** Time relative to current block start */\n blockTime: number;\n /** Progress through current block (0-1) */\n blockProgress: number;\n /** Overall progress through doc (0-1) */\n docProgress: number;\n /** Expanded blocks (templates converted to full blocks with layers) */\n blocks: Block[];\n}\n\ninterface PlaybackActions {\n /** Go to next block */\n nextBlock: () => void;\n /** Go to previous block */\n prevBlock: () => void;\n /** Go to specific block by index */\n goToBlock: (index: number) => void;\n}\n\nexport function useDocPlayback(\n script: Doc | null,\n currentTime: number,\n viewport: ViewportConfig = VIEWPORT_PRESETS.landscape,\n renderMode: boolean = false,\n theme?: Theme,\n): PlaybackState & PlaybackActions {\n const [transitionState, setTransitionState] = useState<{\n entering: boolean;\n exiting: boolean;\n previousBlock: Block | null;\n }>({\n entering: false,\n exiting: false,\n previousBlock: null,\n });\n\n // Expand any template blocks into full blocks\n const blocks = useMemo(() => {\n if (!script?.blocks) {\n return [];\n }\n\n // Flatten nested block hierarchy (markdown-derived docs have children)\n const hasChildren = script.blocks.some((b) => b.children && b.children.length > 0);\n const flatBlocks = hasChildren ? flattenBlocks(script.blocks) : script.blocks;\n\n // Check if any blocks are templates\n const hasTemplates = flatBlocks.some(isTemplateBlock);\n\n if (hasTemplates) {\n // Extract audio segment timing for proper block synchronization\n const audioSegments = script.audio?.segments?.map((seg) => ({\n startTime: seg.startTime,\n duration: seg.duration,\n }));\n\n // Expand template blocks with audio segment timing, viewport, and persistent layers\n const expanded = expandDocBlocks(flatBlocks as DocBlock[], {\n audioSegments,\n viewport,\n persistentLayers: script.persistentLayers,\n theme,\n });\n return expanded;\n }\n\n // All raw blocks, use as-is\n return flatBlocks;\n }, [script?.blocks, script?.audio?.segments, script?.persistentLayers, viewport, theme]);\n\n // Find current block based on time\n const currentBlock = useMemo(() => getBlockAtTime(blocks, currentTime), [blocks, currentTime]);\n\n const currentBlockIndex = useMemo(\n () => (currentBlock ? blocks.indexOf(currentBlock) : -1),\n [blocks, currentBlock],\n );\n\n // Calculate block-relative time\n const blockTime = useMemo(() => {\n if (!currentBlock) return 0;\n return Math.max(0, currentTime - currentBlock.startTime);\n }, [currentBlock, currentTime]);\n\n // Calculate progress values\n const blockProgress = useMemo(() => {\n if (!currentBlock || currentBlock.duration === 0) return 0;\n return Math.min(1, blockTime / currentBlock.duration);\n }, [currentBlock, blockTime]);\n\n const docProgress = useMemo(() => {\n if (!script || script.duration === 0) return 0;\n return Math.min(1, currentTime / script.duration);\n }, [script, currentTime]);\n\n // Track block transitions.\n // In render mode, transitions are computed from blockTime so they stay\n // synchronized with the seekTo timeline. In normal mode, setTimeout drives\n // transitions at the browser's real-time clock speed.\n const _prevBlockRef = useMemo(\n () => currentBlock,\n // eslint-disable-next-line react-hooks/exhaustive-deps -- intentionally keyed on index, not block reference\n [currentBlockIndex],\n );\n\n useEffect(() => {\n if (!currentBlock || renderMode) return;\n\n // When block changes, trigger transition (real-time mode only)\n if (transitionState.previousBlock?.id !== currentBlock.id) {\n const transition = currentBlock.transition;\n const transitionDuration = transition?.duration || 0;\n\n if (transitionDuration > 0) {\n // Start transition\n setTransitionState({\n entering: true,\n exiting: true,\n previousBlock: transitionState.previousBlock,\n });\n\n // End transition after duration\n const timer = setTimeout(() => {\n setTransitionState({\n entering: false,\n exiting: false,\n previousBlock: currentBlock,\n });\n }, transitionDuration * 1000);\n\n return () => clearTimeout(timer);\n } else {\n // Instant cut\n setTransitionState({\n entering: false,\n exiting: false,\n previousBlock: currentBlock,\n });\n }\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps -- intentionally keyed on currentBlock?.id only; reading transitionState.previousBlock without dep to avoid infinite loop\n }, [currentBlock?.id, renderMode]);\n\n // Render mode: track previous block via ref and compute transition from time\n const renderPrevBlockRef = useRef<Block | null>(null);\n\n useEffect(() => {\n if (!renderMode || !currentBlock) return;\n\n if (transitionState.previousBlock?.id !== currentBlock.id) {\n // Block changed — remember the old block for crossfade\n const oldPrev = transitionState.previousBlock;\n renderPrevBlockRef.current = oldPrev;\n // Store current block as the \"last seen\" for next transition\n setTransitionState((prev) => ({\n ...prev,\n previousBlock: currentBlock,\n }));\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps -- same pattern: keyed on block identity change\n }, [currentBlock?.id, renderMode]);\n\n // In render mode, derive entering/exiting from blockTime\n const renderTransitionDuration = currentBlock?.transition?.duration || 0;\n const renderIsEntering =\n renderMode && renderTransitionDuration > 0 && blockTime < renderTransitionDuration;\n const renderIsExiting = renderIsEntering && renderPrevBlockRef.current !== null;\n\n // Manual navigation\n const goToBlock = useCallback(\n (index: number) => {\n if (!script || index < 0 || index >= blocks.length) return;\n // This would need to be coordinated with seekTo from audio sync\n // For now, just return the target block's start time\n const targetBlock = blocks[index];\n if (targetBlock) {\n // Caller should use this time with audio seekTo\n return targetBlock.startTime;\n }\n },\n [script, blocks],\n );\n\n const nextBlock = useCallback(() => {\n if (currentBlockIndex < blocks.length - 1) {\n return goToBlock(currentBlockIndex + 1);\n }\n }, [currentBlockIndex, blocks.length, goToBlock]);\n\n const prevBlock = useCallback(() => {\n if (currentBlockIndex > 0) {\n return goToBlock(currentBlockIndex - 1);\n }\n }, [currentBlockIndex, goToBlock]);\n\n return {\n currentBlock,\n currentBlockIndex,\n previousBlock: renderMode\n ? renderIsExiting\n ? renderPrevBlockRef.current\n : null\n : transitionState.exiting\n ? transitionState.previousBlock\n : null,\n isEntering: renderMode ? renderIsEntering : transitionState.entering,\n isExiting: renderMode ? renderIsExiting : transitionState.exiting,\n blockTime,\n blockProgress,\n docProgress,\n nextBlock,\n prevBlock,\n goToBlock,\n /** Expanded blocks (templates converted to full blocks with layers) */\n blocks,\n };\n}\n\nexport default useDocPlayback;\n","/**\n * useViewportOrientation Hook\n *\n * Detects the current viewport orientation and returns the appropriate\n * VIEWPORT_PRESET for rendering docs. Automatically updates when\n * the window is resized.\n *\n * Thresholds:\n * - Portrait: height > width * 1.2 (significantly taller than wide)\n * - Square: width and height within 20% of each other\n * - Landscape: width > height * 1.2 (significantly wider than tall)\n */\n\nimport { useState, useEffect, useMemo } from 'react';\nimport {\n VIEWPORT_PRESETS,\n type ViewportConfig,\n type ViewportOrientation,\n} from '@bendyline/squisq/doc';\n\ninterface UseViewportOrientationResult {\n /** Current viewport preset configuration */\n viewport: ViewportConfig;\n /** Current orientation name */\n orientation: ViewportOrientation;\n /** Current window dimensions */\n windowSize: { width: number; height: number };\n}\n\n/**\n * Determine viewport orientation from window dimensions.\n */\nfunction getOrientationFromWindow(width: number, height: number): ViewportOrientation {\n const ratio = width / height;\n\n // Use thresholds to determine orientation\n // - Ratio > 1.2 = landscape (wider than tall)\n // - Ratio < 0.83 (1/1.2) = portrait (taller than wide)\n // - Otherwise = square-ish, use landscape for better readability\n if (ratio > 1.2) {\n return 'landscape';\n } else if (ratio < 0.83) {\n return 'portrait';\n } else {\n // Near-square viewports: use landscape for better text readability\n // Could also use 'square' preset if available and desired\n return 'landscape';\n }\n}\n\n/**\n * Get the appropriate viewport preset for an orientation.\n */\nfunction getViewportForOrientation(orientation: ViewportOrientation): ViewportConfig {\n switch (orientation) {\n case 'portrait':\n return VIEWPORT_PRESETS.portrait;\n case 'square':\n return VIEWPORT_PRESETS.square;\n case 'landscape':\n default:\n return VIEWPORT_PRESETS.landscape;\n }\n}\n\n/**\n * Hook to detect viewport orientation and return appropriate preset.\n * Updates automatically when window is resized.\n */\nexport function useViewportOrientation(): UseViewportOrientationResult {\n const [windowSize, setWindowSize] = useState(() => ({\n width: typeof window !== 'undefined' ? window.innerWidth : 1920,\n height: typeof window !== 'undefined' ? window.innerHeight : 1080,\n }));\n\n // Listen for window resize\n useEffect(() => {\n if (typeof window === 'undefined') return;\n\n const handleResize = () => {\n setWindowSize({\n width: window.innerWidth,\n height: window.innerHeight,\n });\n };\n\n // Debounce resize handler to avoid excessive re-renders\n let timeoutId: ReturnType<typeof setTimeout>;\n const debouncedResize = () => {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(handleResize, 100);\n };\n\n window.addEventListener('resize', debouncedResize);\n return () => {\n window.removeEventListener('resize', debouncedResize);\n clearTimeout(timeoutId);\n };\n }, []);\n\n // Calculate orientation from window size\n const orientation = useMemo(\n () => getOrientationFromWindow(windowSize.width, windowSize.height),\n [windowSize.width, windowSize.height],\n );\n\n // Get appropriate viewport preset\n const viewport = useMemo(() => getViewportForOrientation(orientation), [orientation]);\n\n return {\n viewport,\n orientation,\n windowSize,\n };\n}\n\nexport default useViewportOrientation;\n","/**\n * Doc Player Control Types\n *\n * Shared type definitions for doc player controls across different\n * layout modes (overlay, sidebar, bottom). These interfaces allow\n * control components to be decoupled from the core DocPlayer.\n *\n * Related Files:\n * - DocPlayer.tsx — Core player component\n * - DocProgressBar.tsx — Extracted progress bar\n * - DocControlsOverlay.tsx — Overlay controls (default)\n * - DocControlsSidebar.tsx — Vertical sidebar controls\n * - DocControlsBottom.tsx — Horizontal bottom strip controls\n */\n\nimport type { Block } from '@bendyline/squisq/schemas';\n\n/** Layout mode for doc player controls */\nexport type ControlsLayout = 'overlay' | 'sidebar' | 'bottom';\n\n/**\n * Display mode for DocPlayer.\n *\n * - `'video'` — Traditional video-style playback with play/pause, scrub bar,\n * and time-based auto-advance. Default mode.\n * - `'slideshow'` — PowerPoint-style presentation with prev/next navigation.\n * Blocks are treated as static slides that only change on user click.\n * No auto-advance, no scrub bar.\n * - `'linear'` — Long-scrolling document view. Renders the full markdown as\n * readable HTML with template-annotated sections shown as inline SVG cards.\n * No audio, no timeline, no controls — just a scrollable page.\n */\nexport type DisplayMode = 'video' | 'slideshow' | 'linear';\n\n/**\n * Caption display style.\n *\n * - `'standard'` — Traditional broadcast-style captions: small white text\n * on a semi-transparent black badge at the top of the player.\n * - `'social'` — Social media-style (Instagram/TikTok): large centered words\n * showing 3-5 words at a time with the active word highlighted in the\n * theme's primary color. Font and colors pulled from the active theme.\n */\nexport type CaptionStyle = 'standard' | 'social';\n\n/**\n * Caption display mode — combines enable/disable with style selection.\n * The CC button cycles through: off → standard → social → off.\n */\nexport type CaptionMode = 'off' | 'standard' | 'social';\n\n/** Slide navigation actions for slideshow display mode */\nexport interface SlideNavActions {\n /** Navigate to the next slide */\n nextSlide: () => void;\n /** Navigate to the previous slide */\n prevSlide: () => void;\n /** Navigate to a specific slide by index (0-based) */\n goToSlide: (index: number) => void;\n}\n\n/** Playback state exposed to external control components */\nexport interface PlaybackState {\n isPlaying: boolean;\n currentTime: number;\n totalDuration: number;\n currentBlockIndex: number;\n totalBlocks: number;\n docProgress: number;\n hasCaptions: boolean;\n captionsEnabled: boolean;\n /** Current caption display mode (off, standard, social). */\n captionMode: CaptionMode;\n isFullscreen?: boolean;\n /** Current audio segment index (0-based) */\n currentSegmentIndex: number;\n /** Current audio segment name (e.g., 'intro', 'history') */\n currentSegmentName: string | null;\n /** Current block data (for extracting image info, etc.) */\n currentBlock: Block | null;\n}\n\n/** Playback actions exposed to external control components */\nexport interface PlaybackActions {\n toggle: () => void;\n restart: () => void;\n seekTo: (time: number) => void;\n setCaptionsEnabled: (enabled: boolean) => void;\n /** Cycle caption mode: off → standard → social → off */\n cycleCaptionMode: () => void;\n toggleFullscreen?: () => void;\n}\n\n/** Block marker data for the progress bar */\nexport interface BlockMarker {\n block: Block;\n index: number;\n position: number;\n title: string;\n /** True if this block is the first in a new audio segment (section boundary) */\n isSectionStart: boolean;\n}\n\n// ============================================\n// Render-mode API (exposed on window for Playwright / debug)\n// ============================================\n\n/** Block metadata returned by SquisqRenderAPI.getBlocks() */\nexport interface RenderBlockInfo {\n id: string;\n template: string;\n startTime: number;\n duration: number;\n}\n\n/** Audio segment info returned by SquisqRenderAPI.getAudioSegments() */\nexport interface RenderAudioSegmentInfo {\n src: string;\n name: string;\n duration: number;\n startTime: number;\n}\n\n/** Caption phrase info returned by SquisqRenderAPI.getCaptions() */\nexport interface RenderCaptionInfo {\n text: string;\n startTime: number;\n endTime: number;\n}\n\n/** Chapter marker returned by SquisqRenderAPI.getChapters() */\nexport interface RenderChapterInfo {\n title: string;\n startTime: number;\n duration: number;\n}\n\n/**\n * API surface exposed on `window` in render mode and debug mode.\n * Used by Playwright for video export and by ?debug=true for testing.\n *\n * @example\n * ```ts\n * // In Playwright:\n * const w = window as unknown as SquisqWindow;\n * await w.seekTo!(5.0);\n * const blocks = w.getBlocks!();\n * ```\n */\nexport interface SquisqRenderAPI {\n seekTo: (time: number) => Promise<void>;\n getDuration: () => number;\n getBlocks: () => RenderBlockInfo[];\n getAudioSegments: () => RenderAudioSegmentInfo[];\n getCaptions: () => RenderCaptionInfo[];\n getChapters: () => RenderChapterInfo[];\n showCover: () => Promise<void>;\n hideCover: () => Promise<void>;\n hasCoverBlock: () => boolean;\n}\n\n/**\n * Window augmented with optional SquisqRenderAPI properties.\n * Each property is optional because they're only present in render/debug mode.\n */\nexport type SquisqWindow = Window & typeof globalThis & Partial<SquisqRenderAPI>;\n\n/** Format time in seconds to MM:SS string */\nexport function formatTime(seconds: number): string {\n const mins = Math.floor(seconds / 60);\n const secs = Math.floor(seconds % 60);\n return `${mins}:${secs.toString().padStart(2, '0')}`;\n}\n","/**\n * DocProgressBar Component\n *\n * Interactive progress/scrubber bar for doc playback. Shows a track with\n * progress fill, block markers as clickable dots, hover tooltip with time\n * and block title, and a hover line indicator.\n *\n * Extracted from DocPlayer to enable reuse across different control layouts\n * (overlay, sidebar, bottom). When used in sidebar/bottom layouts, this\n * component renders at the bottom of the video while other controls are\n * externalized.\n *\n * Related Files:\n * - DocPlayer.tsx -- Parent component\n * - DocControlsOverlay.tsx -- Uses this within the overlay\n * - types.ts -- Shared type definitions\n */\n\nimport { useRef, useState, useCallback } from 'react';\nimport type { PlaybackState, PlaybackActions, BlockMarker } from './types';\nimport { formatTime } from './types';\nimport type { Block } from '@bendyline/squisq/schemas';\n\ninterface DocProgressBarProps {\n state: PlaybackState;\n actions: PlaybackActions;\n blockMarkers: BlockMarker[];\n /** All expanded blocks for hover lookup */\n expandedBlocks: Block[];\n /** Optional: get block title for hover tooltip */\n getBlockTitle?: (block: Block) => string;\n}\n\nexport function DocProgressBar({\n state,\n actions,\n blockMarkers,\n expandedBlocks,\n getBlockTitle,\n}: DocProgressBarProps) {\n const progressBarRef = useRef<HTMLDivElement>(null);\n const [hoverPosition, setHoverPosition] = useState<number | null>(null);\n\n const handleProgressHover = useCallback((e: React.MouseEvent) => {\n const bar = progressBarRef.current;\n if (!bar) return;\n const rect = bar.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const progress = Math.max(0, Math.min(1, x / rect.width));\n setHoverPosition(progress);\n }, []);\n\n const handleProgressLeave = useCallback(() => {\n setHoverPosition(null);\n }, []);\n\n const getBlockAtTimeLocal = useCallback(\n (time: number): { block: Block; index: number } | null => {\n for (let i = expandedBlocks.length - 1; i >= 0; i--) {\n const blk = expandedBlocks[i];\n if (time >= blk.startTime) {\n return { block: blk, index: i };\n }\n }\n return expandedBlocks.length > 0 ? { block: expandedBlocks[0], index: 0 } : null;\n },\n [expandedBlocks],\n );\n\n return (\n <div\n ref={progressBarRef}\n style={{\n flex: 1,\n height: '24px',\n cursor: 'pointer',\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n }}\n onClick={(e) => {\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();\n const x = e.clientX - rect.left;\n const progress = x / rect.width;\n actions.seekTo(progress * state.totalDuration);\n }}\n onMouseMove={handleProgressHover}\n onMouseLeave={handleProgressLeave}\n >\n {/* Track background */}\n <div\n style={{\n position: 'absolute',\n left: 0,\n right: 0,\n height: '6px',\n background: 'rgba(255,255,255,0.2)',\n borderRadius: '3px',\n }}\n />\n\n {/* Progress fill */}\n <div\n style={{\n position: 'absolute',\n left: 0,\n width: `${state.docProgress * 100}%`,\n height: '6px',\n background: '#5b9bd5',\n borderRadius: '3px',\n transition: 'width 0.1s',\n }}\n />\n\n {/* Block markers (dots) */}\n {blockMarkers.map((marker, i) => (\n <div\n key={`${marker.block.id}-${i}`}\n style={{\n position: 'absolute',\n left: `${marker.position}%`,\n transform: 'translateX(-50%)',\n width: '10px',\n height: '10px',\n borderRadius: '50%',\n background:\n marker.index === state.currentBlockIndex ? '#ffffff' : 'rgba(255,255,255,0.5)',\n border: '2px solid #5b9bd5',\n cursor: 'pointer',\n zIndex: 2,\n transition: 'transform 0.15s, background 0.15s',\n }}\n title={marker.title}\n onClick={(e) => {\n e.stopPropagation();\n actions.seekTo(marker.block.startTime);\n }}\n onMouseEnter={(e) => {\n (e.currentTarget as HTMLElement).style.transform = 'translateX(-50%) scale(1.3)';\n }}\n onMouseLeave={(e) => {\n (e.currentTarget as HTMLElement).style.transform = 'translateX(-50%)';\n }}\n />\n ))}\n\n {/* Hover tooltip */}\n {hoverPosition !== null && (\n <div\n style={{\n position: 'absolute',\n left: `${hoverPosition * 100}%`,\n bottom: '100%',\n transform: 'translateX(-50%)',\n marginBottom: '8px',\n padding: '6px 10px',\n background: 'rgba(0,0,0,0.9)',\n borderRadius: '4px',\n whiteSpace: 'nowrap',\n pointerEvents: 'none',\n zIndex: 10,\n }}\n >\n <div style={{ color: 'white', fontSize: '12px', fontFamily: 'monospace' }}>\n {formatTime(hoverPosition * state.totalDuration)}\n </div>\n {(() => {\n const hoverTime = hoverPosition * state.totalDuration;\n const slideInfo = getBlockAtTimeLocal(hoverTime);\n if (slideInfo && getBlockTitle) {\n return (\n <div style={{ color: 'rgba(255,255,255,0.7)', fontSize: '11px', marginTop: '2px' }}>\n {getBlockTitle(slideInfo.block)}\n </div>\n );\n }\n return null;\n })()}\n </div>\n )}\n\n {/* Hover line indicator */}\n {hoverPosition !== null && (\n <div\n style={{\n position: 'absolute',\n left: `${hoverPosition * 100}%`,\n top: '50%',\n transform: 'translate(-50%, -50%)',\n width: '2px',\n height: '16px',\n background: 'rgba(255,255,255,0.6)',\n pointerEvents: 'none',\n zIndex: 1,\n }}\n />\n )}\n </div>\n );\n}\n","/**\n * DocControlsOverlay Component\n *\n * The default overlay controls that render at the bottom of the doc player\n * video with a gradient background. Contains all playback controls: restart,\n * play/pause, time display, progress bar with block markers, segment indicator,\n * and caption toggle.\n *\n * This is the original control layout extracted from DocPlayer. It's used\n * for the 'overlay' controls layout mode (Flow mode, landscape default).\n *\n * Related Files:\n * - DocPlayer.tsx -- Parent component\n * - DocProgressBar.tsx -- Progress bar sub-component\n * - types.ts -- Shared type definitions\n */\n\nimport { DocProgressBar } from './DocProgressBar';\nimport type { PlaybackState, PlaybackActions, BlockMarker } from './types';\nimport { formatTime } from './types';\nimport type { Block } from '@bendyline/squisq/schemas';\n\ninterface DocControlsOverlayProps {\n state: PlaybackState;\n actions: PlaybackActions;\n blockMarkers: BlockMarker[];\n expandedBlocks: Block[];\n getBlockTitle?: (block: Block) => string;\n}\n\nexport function DocControlsOverlay({\n state,\n actions,\n blockMarkers,\n expandedBlocks,\n getBlockTitle,\n}: DocControlsOverlayProps) {\n return (\n <div\n className=\"doc-player__controls\"\n style={{\n position: 'absolute',\n bottom: 0,\n left: 0,\n right: 0,\n padding: '12px 16px',\n background: 'linear-gradient(transparent, rgba(0,0,0,0.8))',\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n zIndex: 100,\n }}\n >\n {/* Restart button */}\n <button\n onClick={actions.restart}\n style={{\n background: 'none',\n border: 'none',\n color: 'rgba(255,255,255,0.7)',\n cursor: 'pointer',\n padding: '8px',\n fontSize: '14px',\n display: 'flex',\n alignItems: 'center',\n }}\n title=\"Restart\"\n aria-label=\"Restart from beginning\"\n >\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" width=\"18\" height=\"18\">\n <path d=\"M12 5V1L7 6l5 5V7c3.31 0 6 2.69 6 6s-2.69 6-6 6-6-2.69-6-6H4c0 4.42 3.58 8 8 8s8-3.58 8-8-3.58-8-8-8z\" />\n </svg>\n </button>\n\n {/* Play/Pause button */}\n <button\n onClick={actions.toggle}\n style={{\n background: 'rgba(255,255,255,0.2)',\n border: 'none',\n borderRadius: '50%',\n color: 'white',\n cursor: 'pointer',\n padding: '10px',\n fontSize: '16px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '40px',\n height: '40px',\n }}\n aria-label={state.isPlaying ? 'Pause' : 'Play'}\n >\n {state.isPlaying ? (\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" width=\"20\" height=\"20\">\n <path d=\"M6 19h4V5H6v14zm8-14v14h4V5h-4z\" />\n </svg>\n ) : (\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" width=\"20\" height=\"20\">\n <path d=\"M8 5v14l11-7z\" />\n </svg>\n )}\n </button>\n\n {/* Time display */}\n <span style={{ color: 'white', fontSize: '12px', minWidth: '80px', fontFamily: 'monospace' }}>\n {formatTime(state.currentTime)} / {formatTime(state.totalDuration)}\n </span>\n\n {/* Progress bar */}\n <DocProgressBar\n state={state}\n actions={actions}\n blockMarkers={blockMarkers}\n expandedBlocks={expandedBlocks}\n getBlockTitle={getBlockTitle}\n />\n\n {/* Segment indicator */}\n <span style={{ color: 'rgba(255,255,255,0.5)', fontSize: '11px', whiteSpace: 'nowrap' }}>\n {state.currentBlockIndex + 1}/{state.totalBlocks}\n </span>\n\n {/* Caption mode cycle button: off → standard → social → off */}\n {state.hasCaptions && (\n <button\n onClick={() => actions.cycleCaptionMode()}\n style={{\n background: state.captionMode !== 'off' ? 'rgba(255,255,255,0.2)' : 'none',\n border: 'none',\n color: state.captionMode !== 'off' ? 'white' : 'rgba(255,255,255,0.5)',\n cursor: 'pointer',\n padding: '8px',\n fontSize: '12px',\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n borderRadius: '4px',\n }}\n title={\n state.captionMode === 'off'\n ? 'Captions: Off (click for Standard)'\n : state.captionMode === 'standard'\n ? 'Captions: Standard (click for Social)'\n : 'Captions: Social (click to turn off)'\n }\n aria-label=\"Cycle caption style\"\n >\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" width=\"18\" height=\"18\">\n <path d=\"M19 4H5a2 2 0 00-2 2v12a2 2 0 002 2h14a2 2 0 002-2V6a2 2 0 00-2-2zm-8 7H9.5v-.5h-2v3h2V13H11v1a1 1 0 01-1 1H7a1 1 0 01-1-1v-4a1 1 0 011-1h3a1 1 0 011 1v1zm7 0h-1.5v-.5h-2v3h2V13H18v1a1 1 0 01-1 1h-3a1 1 0 01-1-1v-4a1 1 0 011-1h3a1 1 0 011 1v1z\" />\n </svg>\n {state.captionMode !== 'off' && (\n <span style={{ fontSize: '10px', textTransform: 'uppercase', letterSpacing: '0.5px' }}>\n {state.captionMode === 'standard' ? 'CC' : 'SM'}\n </span>\n )}\n </button>\n )}\n\n {/* Fullscreen toggle button */}\n {actions.toggleFullscreen && (\n <button\n onClick={actions.toggleFullscreen}\n style={{\n background: state.isFullscreen ? 'rgba(255,255,255,0.2)' : 'none',\n border: 'none',\n color: state.isFullscreen ? 'white' : 'rgba(255,255,255,0.5)',\n cursor: 'pointer',\n padding: '8px',\n display: 'flex',\n alignItems: 'center',\n borderRadius: '4px',\n }}\n title={state.isFullscreen ? 'Exit fullscreen (F)' : 'Fullscreen (F)'}\n aria-label={state.isFullscreen ? 'Exit fullscreen' : 'Enter fullscreen'}\n >\n {state.isFullscreen ? (\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" width=\"18\" height=\"18\">\n <path d=\"M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z\" />\n </svg>\n ) : (\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" width=\"18\" height=\"18\">\n <path d=\"M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z\" />\n </svg>\n )}\n </button>\n )}\n </div>\n );\n}\n","/**\n * DocControlsSlideshow Component\n *\n * Compact slide navigation controls for the DocPlayer slideshow display mode.\n * Renders in the lower-right corner with previous / slide counter / next buttons,\n * similar to PowerPoint/Keynote presentation navigation.\n *\n * Related Files:\n * - DocPlayer.tsx — Parent component (renders this when displayMode='slideshow')\n * - DocControlsOverlay.tsx — Video-mode controls (overlay layout)\n * - types.ts — Shared type definitions\n */\n\nimport type { PlaybackState, SlideNavActions } from './types';\n\ninterface DocControlsSlideshowProps {\n state: PlaybackState;\n slideNav: SlideNavActions;\n}\n\nexport function DocControlsSlideshow({ state, slideNav }: DocControlsSlideshowProps) {\n const { currentBlockIndex, totalBlocks } = state;\n const isFirst = currentBlockIndex <= 0;\n const isLast = currentBlockIndex >= totalBlocks - 1;\n\n return (\n <div\n className=\"doc-controls-slideshow\"\n data-testid=\"slideshow-controls\"\n style={{\n position: 'absolute',\n bottom: '16px',\n right: '16px',\n display: 'flex',\n alignItems: 'center',\n gap: '2px',\n background: 'rgba(0, 0, 0, 0.65)',\n borderRadius: '8px',\n padding: '4px 6px',\n zIndex: 100,\n userSelect: 'none',\n backdropFilter: 'blur(8px)',\n WebkitBackdropFilter: 'blur(8px)',\n }}\n >\n {/* Previous button */}\n <button\n onClick={(e) => {\n e.stopPropagation();\n slideNav.prevSlide();\n }}\n disabled={isFirst}\n data-testid=\"slide-prev\"\n aria-label=\"Previous slide\"\n title=\"Previous slide\"\n style={{\n background: 'none',\n border: 'none',\n color: isFirst ? 'rgba(255,255,255,0.3)' : 'rgba(255,255,255,0.9)',\n cursor: isFirst ? 'default' : 'pointer',\n padding: '6px 8px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: '4px',\n transition: 'background 0.15s',\n }}\n onMouseEnter={(e) => {\n if (!isFirst) e.currentTarget.style.background = 'rgba(255,255,255,0.1)';\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.background = 'none';\n }}\n >\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" width=\"18\" height=\"18\">\n <path d=\"M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z\" />\n </svg>\n </button>\n\n {/* Slide counter */}\n <span\n data-testid=\"slide-counter\"\n style={{\n color: 'rgba(255,255,255,0.9)',\n fontSize: '13px',\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n fontVariantNumeric: 'tabular-nums',\n minWidth: '48px',\n textAlign: 'center',\n padding: '0 4px',\n letterSpacing: '0.02em',\n }}\n >\n {totalBlocks > 0 ? `${currentBlockIndex + 1} / ${totalBlocks}` : '—'}\n </span>\n\n {/* Next button */}\n <button\n onClick={(e) => {\n e.stopPropagation();\n slideNav.nextSlide();\n }}\n disabled={isLast}\n data-testid=\"slide-next\"\n aria-label=\"Next slide\"\n title=\"Next slide\"\n style={{\n background: 'none',\n border: 'none',\n color: isLast ? 'rgba(255,255,255,0.3)' : 'rgba(255,255,255,0.9)',\n cursor: isLast ? 'default' : 'pointer',\n padding: '6px 8px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: '4px',\n transition: 'background 0.15s',\n }}\n onMouseEnter={(e) => {\n if (!isLast) e.currentTarget.style.background = 'rgba(255,255,255,0.1)';\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.background = 'none';\n }}\n >\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" width=\"18\" height=\"18\">\n <path d=\"M8.59 16.59L10 18l6-6-6-6-1.41 1.41L13.17 12z\" />\n </svg>\n </button>\n </div>\n );\n}\n","/**\n * MarkdownRenderer Component\n *\n * Converts a MarkdownBlockNode[] AST into React elements for rendering\n * markdown content as readable HTML. Used by LinearDocView to display\n * non-annotated document sections as flowing text.\n *\n * Supports all block and inline node types from the markdown DOM:\n * - Block: paragraph, heading, blockquote, list, code, table,\n * thematicBreak, math, htmlBlock, definitionList, directives\n * - Inline: text, emphasis, strong, delete, inlineCode, link,\n * image, break, inlineMath, htmlInline, footnoteReference\n *\n * All elements use the `squisq-md-*` CSS class prefix for styling.\n */\n\nimport { Fragment } from 'react';\nimport type {\n MarkdownBlockNode,\n MarkdownInlineNode,\n MarkdownListItem,\n MarkdownTableRow,\n MarkdownTableCell,\n} from '@bendyline/squisq/markdown';\n\n// ── Props ──────────────────────────────────────────────────────────\n\nexport interface MarkdownRendererProps {\n /** Block-level AST nodes to render */\n nodes: MarkdownBlockNode[];\n /** Optional CSS class for the wrapper element */\n className?: string;\n}\n\n// ── Inline Renderer ────────────────────────────────────────────────\n\n/** Render an array of inline nodes into React elements. */\nfunction renderInline(nodes: MarkdownInlineNode[], keyPrefix = ''): React.ReactNode[] {\n return nodes.map((node, i) => {\n const key = `${keyPrefix}i${i}`;\n switch (node.type) {\n case 'text':\n return <Fragment key={key}>{node.value}</Fragment>;\n\n case 'emphasis':\n return (\n <em key={key} className=\"squisq-md-em\">\n {renderInline(node.children, key)}\n </em>\n );\n\n case 'strong':\n return (\n <strong key={key} className=\"squisq-md-strong\">\n {renderInline(node.children, key)}\n </strong>\n );\n\n case 'delete':\n return (\n <del key={key} className=\"squisq-md-del\">\n {renderInline(node.children, key)}\n </del>\n );\n\n case 'inlineCode':\n return (\n <code key={key} className=\"squisq-md-inline-code\">\n {node.value}\n </code>\n );\n\n case 'link':\n return (\n <a\n key={key}\n className=\"squisq-md-link\"\n href={node.url}\n title={node.title ?? undefined}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {renderInline(node.children, key)}\n </a>\n );\n\n case 'image':\n return (\n <img\n key={key}\n className=\"squisq-md-image\"\n src={node.url}\n alt={node.alt ?? ''}\n title={node.title ?? undefined}\n />\n );\n\n case 'break':\n return <br key={key} />;\n\n case 'inlineMath':\n return (\n <code key={key} className=\"squisq-md-inline-math\">\n {node.value}\n </code>\n );\n\n case 'htmlInline':\n return (\n <span\n key={key}\n className=\"squisq-md-html-inline\"\n dangerouslySetInnerHTML={{ __html: node.rawHtml }}\n />\n );\n\n case 'footnoteReference':\n return (\n <sup key={key} className=\"squisq-md-footnote-ref\">\n <a href={`#fn-${node.identifier}`}>[{node.label ?? node.identifier}]</a>\n </sup>\n );\n\n case 'linkReference':\n // Render as plain text (definition targets not available at render time)\n return (\n <span key={key} className=\"squisq-md-link-ref\">\n {renderInline(node.children, key)}\n </span>\n );\n\n case 'imageReference':\n return (\n <span key={key} className=\"squisq-md-image-ref\">\n [{node.alt ?? node.identifier}]\n </span>\n );\n\n case 'textDirective':\n return (\n <span key={key} className=\"squisq-md-text-directive\" data-directive={node.name}>\n {renderInline(node.children, key)}\n </span>\n );\n\n default:\n return null;\n }\n });\n}\n\n// ── Block Renderer ─────────────────────────────────────────────────\n\n/** Render a single block-level node into a React element. */\nfunction renderBlock(node: MarkdownBlockNode, key: string): React.ReactNode {\n switch (node.type) {\n case 'paragraph':\n return (\n <p key={key} className=\"squisq-md-p\">\n {renderInline(node.children, key)}\n </p>\n );\n\n case 'heading': {\n const Tag = `h${node.depth}` as 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';\n return (\n <Tag key={key} className={`squisq-md-heading squisq-md-h${node.depth}`}>\n {renderInline(node.children, key)}\n </Tag>\n );\n }\n\n case 'blockquote':\n return (\n <blockquote key={key} className=\"squisq-md-blockquote\">\n {renderBlocks(node.children, key)}\n </blockquote>\n );\n\n case 'list':\n if (node.ordered) {\n return (\n <ol key={key} className=\"squisq-md-list squisq-md-ol\" start={node.start ?? undefined}>\n {node.children.map((item, i) => renderListItem(item, `${key}li${i}`))}\n </ol>\n );\n }\n return (\n <ul key={key} className=\"squisq-md-list squisq-md-ul\">\n {node.children.map((item, i) => renderListItem(item, `${key}li${i}`))}\n </ul>\n );\n\n case 'code':\n return (\n <pre key={key} className=\"squisq-md-code-block\">\n <code className={node.lang ? `language-${node.lang}` : undefined}>{node.value}</code>\n </pre>\n );\n\n case 'thematicBreak':\n return <hr key={key} className=\"squisq-md-hr\" />;\n\n case 'table':\n return renderTable(node.children, node.align, key);\n\n case 'htmlBlock':\n return (\n <div\n key={key}\n className=\"squisq-md-html-block\"\n dangerouslySetInnerHTML={{ __html: node.rawHtml }}\n />\n );\n\n case 'math':\n return (\n <pre key={key} className=\"squisq-md-math-block\">\n <code>{node.value}</code>\n </pre>\n );\n\n case 'definition':\n // Link definitions aren't rendered visually\n return null;\n\n case 'footnoteDefinition':\n return (\n <div key={key} className=\"squisq-md-footnote-def\" id={`fn-${node.identifier}`}>\n <sup>{node.label ?? node.identifier}</sup>\n {renderBlocks(node.children, key)}\n </div>\n );\n\n case 'containerDirective':\n return (\n <div\n key={key}\n className={`squisq-md-directive squisq-md-directive-${node.name}`}\n data-directive={node.name}\n >\n {node.label && <div className=\"squisq-md-directive-label\">{node.label}</div>}\n {renderBlocks(node.children, key)}\n </div>\n );\n\n case 'leafDirective':\n return (\n <div\n key={key}\n className={`squisq-md-directive squisq-md-directive-${node.name}`}\n data-directive={node.name}\n >\n {renderInline(node.children, key)}\n </div>\n );\n\n case 'definitionList':\n return (\n <dl key={key} className=\"squisq-md-dl\">\n {node.children.map((child, i) => {\n if (child.type === 'definitionTerm') {\n return (\n <dt key={`${key}dt${i}`} className=\"squisq-md-dt\">\n {renderInline(child.children, `${key}dt${i}`)}\n </dt>\n );\n }\n return (\n <dd key={`${key}dd${i}`} className=\"squisq-md-dd\">\n {renderBlocks(child.children, `${key}dd${i}`)}\n </dd>\n );\n })}\n </dl>\n );\n\n default:\n return null;\n }\n}\n\n/** Render a list item, including task-list checkbox support. */\nfunction renderListItem(item: MarkdownListItem, key: string): React.ReactNode {\n const isTask = item.checked !== null && item.checked !== undefined;\n return (\n <li key={key} className={`squisq-md-li${isTask ? ' squisq-md-task' : ''}`}>\n {isTask && (\n <input type=\"checkbox\" checked={!!item.checked} readOnly className=\"squisq-md-checkbox\" />\n )}\n {renderBlocks(item.children, key)}\n </li>\n );\n}\n\n/** Render a table from rows and alignment data. */\nfunction renderTable(\n rows: MarkdownTableRow[],\n align: (('left' | 'right' | 'center') | null)[] | undefined,\n key: string,\n): React.ReactNode {\n const [headerRow, ...bodyRows] = rows;\n return (\n <table key={key} className=\"squisq-md-table\">\n {headerRow && (\n <thead>\n <tr>\n {headerRow.children.map((cell: MarkdownTableCell, ci: number) => (\n <th\n key={`${key}th${ci}`}\n className=\"squisq-md-th\"\n style={align?.[ci] ? { textAlign: align[ci]! } : undefined}\n >\n {renderInline(cell.children, `${key}th${ci}`)}\n </th>\n ))}\n </tr>\n </thead>\n )}\n {bodyRows.length > 0 && (\n <tbody>\n {bodyRows.map((row, ri) => (\n <tr key={`${key}tr${ri}`}>\n {row.children.map((cell: MarkdownTableCell, ci: number) => (\n <td\n key={`${key}td${ri}-${ci}`}\n className=\"squisq-md-td\"\n style={align?.[ci] ? { textAlign: align[ci]! } : undefined}\n >\n {renderInline(cell.children, `${key}td${ri}-${ci}`)}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n )}\n </table>\n );\n}\n\n/** Render an array of block-level nodes. */\nfunction renderBlocks(nodes: MarkdownBlockNode[], keyPrefix = ''): React.ReactNode[] {\n return nodes.map((node, i) => renderBlock(node, `${keyPrefix}b${i}`));\n}\n\n// ── Main Component ─────────────────────────────────────────────────\n\n/**\n * Renders MarkdownBlockNode[] AST as React HTML elements.\n *\n * @example\n * ```tsx\n * <MarkdownRenderer nodes={block.contents} />\n * ```\n */\nexport function MarkdownRenderer({ nodes, className }: MarkdownRendererProps) {\n if (!nodes || nodes.length === 0) return null;\n\n return <div className={`squisq-md ${className || ''}`}>{renderBlocks(nodes)}</div>;\n}\n","/**\n * LinearDocView Component\n *\n * Renders a Doc as a long-scrolling document view. Each block is displayed\n * as a readable section: non-annotated blocks render their markdown content\n * as HTML, while template-annotated blocks render as inline SVG visual cards\n * via BlockRenderer.\n *\n * This is the view used when `displayMode === 'linear'` in DocPlayer.\n *\n * Layout:\n * - Scrollable container with max-width for readability\n * - Headings from the block hierarchy rendered as HTML headings\n * - Body content rendered via MarkdownRenderer\n * - Template-annotated sections show an SVG card (BlockRenderer)\n * using `getLayers()` for on-demand layer computation\n * - Blocks are rendered recursively to preserve the heading hierarchy\n */\n\nimport { useMemo } from 'react';\nimport type { Doc, Block, DocBlock } from '@bendyline/squisq/schemas';\nimport type { ViewportConfig } from '@bendyline/squisq/schemas';\nimport type { Theme } from '@bendyline/squisq/schemas';\nimport { VIEWPORT_PRESETS } from '@bendyline/squisq/schemas';\nimport { getLayers, hasTemplate, DEFAULT_THEME } from '@bendyline/squisq/doc';\nimport type { RenderContext } from '@bendyline/squisq/doc';\nimport { extractPlainText } from '@bendyline/squisq/markdown';\nimport type { MarkdownBlockNode, MarkdownList, MarkdownTable } from '@bendyline/squisq/markdown';\nimport { BlockRenderer } from './BlockRenderer';\nimport { MarkdownRenderer } from './MarkdownRenderer';\n\n// ── Props ──────────────────────────────────────────────────────────\n\nexport interface LinearDocViewProps {\n /** The Doc to render */\n doc: Doc;\n /** Base path for resolving media URLs (images, etc.) */\n basePath?: string;\n /** Viewport config for SVG card rendering (default: landscape) */\n viewport?: ViewportConfig;\n /** Optional CSS class for the outer container */\n className?: string;\n /** Theme to use for rendering (default: DEFAULT_THEME from the theme library) */\n theme?: Theme;\n}\n\n// ── Helpers ────────────────────────────────────────────────────────\n\n/**\n * Determine whether a block has a template annotation that should be\n * rendered as a visual SVG card. A block is \"annotated\" when:\n * 1. Its sourceHeading has a templateAnnotation, AND\n * 2. The annotated template exists in the registry\n */\nfunction isAnnotatedBlock(block: Block): boolean {\n const annotation = block.sourceHeading?.templateAnnotation;\n if (!annotation) return false;\n return !!annotation.template && hasTemplate(annotation.template);\n}\n\n/**\n * Count total blocks in a hierarchy (for RenderContext.totalBlocks).\n */\nfunction countAll(blocks: Block[]): number {\n let count = 0;\n for (const b of blocks) {\n count++;\n if (b.children) count += countAll(b.children);\n }\n return count;\n}\n\n// ── Block Section Renderer ─────────────────────────────────────────\n\ninterface BlockSectionProps {\n block: Block;\n basePath: string;\n viewport: ViewportConfig;\n renderContext: RenderContext;\n blockIndex: number;\n}\n\n/**\n * Render a single block section: heading + body content or SVG card.\n * Recurses into children to render the full heading tree.\n */\nfunction BlockSection({ block, basePath, viewport, renderContext, blockIndex }: BlockSectionProps) {\n const isAnnotated = isAnnotatedBlock(block);\n\n // For annotated blocks, compute layers and build a Block with them\n const visualBlock = useMemo(() => {\n if (!isAnnotated) return null;\n\n const annotation = block.sourceHeading!.templateAnnotation!;\n const headingText = extractPlainText(block.sourceHeading!);\n const bodyText = extractBodyPlainText(block.contents);\n\n // Build a TemplateBlock-compatible object\n const templateBlock: Record<string, unknown> = {\n id: block.id,\n template: annotation.template,\n startTime: 0,\n duration: 1,\n audioSegment: 0,\n title: headingText,\n ...getTemplateDefaults(\n annotation.template ?? 'sectionHeader',\n headingText,\n bodyText,\n block.contents,\n ),\n ...annotation.params,\n ...block.templateOverrides,\n };\n\n // Compute layers via getLayers\n const ctx: RenderContext = {\n ...renderContext,\n blockIndex,\n };\n const layers = getLayers(templateBlock as unknown as DocBlock, ctx);\n\n return {\n ...block,\n layers,\n template: annotation.template,\n } as Block;\n }, [block, isAnnotated, renderContext, blockIndex]);\n\n return (\n <div\n className=\"squisq-linear-section\"\n data-block-id={block.id}\n data-template={isAnnotated ? block.sourceHeading?.templateAnnotation?.template : undefined}\n >\n {/* Render the heading (if present — preamble has no sourceHeading) */}\n {block.sourceHeading && !isAnnotated && <MarkdownRenderer nodes={[block.sourceHeading]} />}\n\n {/* Annotated block: render SVG card */}\n {isAnnotated && visualBlock && (\n <div className=\"squisq-linear-card\">\n {/* Optional heading label above the card */}\n {block.sourceHeading && (\n <div className=\"squisq-linear-card-label squisq-md\">\n <MarkdownRenderer nodes={[block.sourceHeading]} />\n </div>\n )}\n <div\n className=\"squisq-linear-card-svg\"\n style={{\n width: '100%',\n aspectRatio: `${viewport.width} / ${viewport.height}`,\n overflow: 'hidden',\n borderRadius: '8px',\n boxShadow: '0 2px 8px rgba(0, 0, 0, 0.12)',\n marginBottom: '1em',\n }}\n >\n <BlockRenderer\n block={visualBlock}\n blockTime={0}\n basePath={basePath}\n viewport={viewport}\n />\n </div>\n </div>\n )}\n\n {/* Body content (always render for non-annotated blocks, skipped for annotated) */}\n {!isAnnotated && block.contents && block.contents.length > 0 && (\n <MarkdownRenderer nodes={block.contents} />\n )}\n\n {/* Recurse into children */}\n {block.children && block.children.length > 0 && (\n <div className=\"squisq-linear-children\">\n {block.children.map((child, i) => (\n <BlockSection\n key={child.id}\n block={child}\n basePath={basePath}\n viewport={viewport}\n renderContext={renderContext}\n blockIndex={blockIndex + i + 1}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n\n// ── Template Defaults (mirrored from PreviewPanel) ─────────────────\n\n/** Extract plain text from block contents. */\nfunction extractBodyPlainText(contents?: MarkdownBlockNode[]): string {\n if (!contents || contents.length === 0) return '';\n return contents\n .map((n) => extractPlainText(n))\n .join('\\n')\n .trim();\n}\n\n/** Extract list items as plain text. */\nfunction extractListItems(contents?: MarkdownBlockNode[]): string[] {\n if (!contents) return [];\n const items: string[] = [];\n for (const node of contents) {\n if (node.type === 'list') {\n for (const item of (node as MarkdownList).children) {\n const text = extractPlainText(item).trim();\n if (text) items.push(text);\n }\n }\n }\n return items;\n}\n\n/** Extract table data (headers, rows, alignment) from block contents. */\nfunction extractTableData(contents?: MarkdownBlockNode[]): {\n headers: string[];\n rows: string[][];\n align?: (('left' | 'right' | 'center') | null)[];\n} | null {\n if (!contents) return null;\n for (const node of contents) {\n if (node.type === 'table') {\n const table = node as MarkdownTable;\n const [headerRow, ...bodyRows] = table.children;\n if (!headerRow) return null;\n const headers = headerRow.children.map((cell) => extractPlainText(cell).trim());\n const rows = bodyRows.map((row) => row.children.map((cell) => extractPlainText(cell).trim()));\n return { headers, rows, align: table.align };\n }\n }\n return null;\n}\n\n/**\n * Provide sensible default fields for templates that require more than\n * just a `title`. Prevents crashes from undefined required fields.\n */\nfunction getTemplateDefaults(\n templateName: string,\n headingText: string,\n bodyText: string,\n contents?: MarkdownBlockNode[],\n): Record<string, unknown> {\n switch (templateName) {\n case 'statHighlight':\n return { stat: headingText, description: bodyText || headingText };\n case 'quoteBlock':\n case 'fullBleedQuote':\n case 'pullQuote':\n return { quote: bodyText || headingText };\n case 'factCard':\n return { fact: headingText, explanation: bodyText || headingText };\n case 'comparisonBar':\n return { leftLabel: 'A', leftValue: 60, rightLabel: 'B', rightValue: 40 };\n case 'listBlock':\n return { items: extractListItems(contents) || ['Item 1', 'Item 2', 'Item 3'] };\n case 'definitionCard':\n return { term: headingText, definition: bodyText || headingText };\n case 'dateEvent':\n return { date: headingText, description: bodyText || headingText };\n case 'dataTable': {\n const tableData = extractTableData(contents);\n return tableData ?? { headers: ['Column'], rows: [['Data']] };\n }\n default:\n return {};\n }\n}\n\n// ── Main Component ─────────────────────────────────────────────────\n\n/**\n * Renders a Doc as a long-scrolling, readable document.\n *\n * Non-annotated blocks are rendered as HTML text (headings, paragraphs,\n * lists, etc.) via MarkdownRenderer. Template-annotated blocks are\n * rendered as inline SVG visual cards via BlockRenderer.\n *\n * @example\n * ```tsx\n * <LinearDocView doc={doc} basePath=\"/media/\" />\n * ```\n */\nexport function LinearDocView({\n doc,\n basePath = '/',\n viewport,\n className,\n theme,\n}: LinearDocViewProps) {\n const activeViewport = viewport ?? VIEWPORT_PRESETS.landscape;\n const totalBlocks = useMemo(() => countAll(doc.blocks), [doc.blocks]);\n\n const renderContext: RenderContext = useMemo(\n () => ({\n theme: theme ?? DEFAULT_THEME,\n viewport: activeViewport,\n totalBlocks,\n }),\n [activeViewport, totalBlocks, theme],\n );\n\n const activeTheme = renderContext.theme!;\n const bgColor = activeTheme.colors.background;\n const textColor = activeTheme.colors.text;\n const mutedColor = activeTheme.colors.textMuted;\n const primaryColor = activeTheme.colors.primary;\n const bodyFont = activeTheme.typography.bodyFontFamily;\n const titleFont = activeTheme.typography.titleFontFamily;\n const lineHt = activeTheme.typography.lineHeight ?? 1.7;\n\n return (\n <div\n className={`squisq-linear ${className || ''}`}\n style={{\n width: '100%',\n height: '100%',\n overflowY: 'auto',\n overflowX: 'hidden',\n background: bgColor,\n }}\n >\n <div\n className=\"squisq-linear-content squisq-md\"\n style={\n {\n maxWidth: '720px',\n margin: '0 auto',\n padding: '24px 16px',\n lineHeight: lineHt,\n fontSize: '16px',\n fontFamily: bodyFont,\n color: textColor,\n // CSS custom properties for MarkdownRenderer / nested elements\n '--squisq-linear-title-font': titleFont,\n '--squisq-linear-body-font': bodyFont,\n '--squisq-linear-text': textColor,\n '--squisq-linear-muted': mutedColor,\n '--squisq-linear-primary': primaryColor,\n '--squisq-linear-bg': bgColor,\n } as React.CSSProperties\n }\n >\n {/* Theme-aware typography and layout for document mode */}\n <style>{`\n .squisq-linear-content h1,\n .squisq-linear-content h2,\n .squisq-linear-content h3,\n .squisq-linear-content h4,\n .squisq-linear-content h5,\n .squisq-linear-content h6 {\n font-family: var(--squisq-linear-title-font);\n color: var(--squisq-linear-text);\n margin-top: 1.2em;\n margin-bottom: 0.4em;\n }\n .squisq-linear-content h1 { font-size: 2em; }\n .squisq-linear-content h2 { font-size: 1.5em; }\n .squisq-linear-content h3 { font-size: 1.25em; }\n .squisq-linear-content p {\n margin-bottom: 0.75em;\n }\n .squisq-linear-content ul,\n .squisq-linear-content ol {\n padding-left: 2em;\n margin-bottom: 0.75em;\n }\n .squisq-linear-content li {\n margin-bottom: 0.3em;\n }\n .squisq-linear-content a {\n color: var(--squisq-linear-primary);\n }\n .squisq-linear-content code {\n color: var(--squisq-linear-primary);\n font-size: 0.9em;\n padding: 0.15em 0.3em;\n border-radius: 3px;\n background: rgba(128, 128, 128, 0.15);\n }\n .squisq-linear-content pre {\n padding: 1em;\n border-radius: 6px;\n background: rgba(0, 0, 0, 0.2);\n overflow-x: auto;\n margin-bottom: 0.75em;\n }\n .squisq-linear-content pre code {\n padding: 0;\n background: none;\n }\n .squisq-linear-content blockquote {\n border-left: 3px solid var(--squisq-linear-muted);\n color: var(--squisq-linear-muted);\n padding-left: 1em;\n margin-left: 0;\n margin-bottom: 0.75em;\n }\n .squisq-linear-content hr {\n border: none;\n border-top: 1px solid var(--squisq-linear-muted);\n margin: 1.5em 0;\n }\n .squisq-linear-content strong {\n font-weight: 700;\n }\n .squisq-linear-content em {\n font-style: italic;\n }\n .squisq-linear-content table {\n width: 100%;\n border-collapse: collapse;\n margin: 1em 0;\n font-size: 0.95em;\n }\n .squisq-linear-content thead th {\n background: var(--squisq-linear-primary);\n color: var(--squisq-linear-bg);\n font-family: var(--squisq-linear-title-font);\n font-weight: 600;\n padding: 10px 14px;\n text-align: left;\n }\n .squisq-linear-content tbody td {\n padding: 8px 14px;\n border-bottom: 1px solid color-mix(in srgb, var(--squisq-linear-muted) 30%, transparent);\n }\n .squisq-linear-content tbody tr:hover {\n background: color-mix(in srgb, var(--squisq-linear-primary) 8%, transparent);\n }\n `}</style>\n {doc.blocks.map((block, i) => (\n <BlockSection\n key={block.id}\n block={block}\n basePath={basePath}\n viewport={activeViewport}\n renderContext={renderContext}\n blockIndex={i}\n />\n ))}\n </div>\n </div>\n );\n}\n","/**\n * DocPlayer Component\n *\n * Main component for playing visual stories. Combines audio playback\n * with synchronized SVG block animations. Supports both interactive\n * browser playback and headless rendering for video export.\n *\n * Features:\n * - Audio synchronization with multiple MP3 segments\n * - Block transitions (fade, dissolve, slide)\n * - Playback controls (play/pause, seek, next/prev)\n * - Progress display\n * - Render mode for video capture (via window.seekTo)\n * - Pluggable audio provider for different environments (browser, EFB)\n * - Multiple control layouts: overlay (default), sidebar, bottom\n *\n * Related Files:\n * - DocControlsOverlay.tsx -- Default overlay controls\n * - DocProgressBar.tsx -- Extracted progress bar\n * - DocControlsSidebar.tsx -- Vertical sidebar controls\n * - DocPlayerWithSidebar.tsx -- Wrapper for sidebar layout\n * - types.ts -- Shared control types\n */\n\nimport { Fragment, useRef, useState, useEffect, useCallback, useMemo } from 'react';\nimport type { Doc, Block, TextLayer, StartBlockConfig, DocBlock } from '@bendyline/squisq/schemas';\nimport { isTemplateBlock, getCaptionAtTime } from '@bendyline/squisq/schemas';\nimport type { Theme } from '@bendyline/squisq/schemas';\nimport { BlockRenderer } from './BlockRenderer';\nimport { CaptionOverlay } from './CaptionOverlay';\nimport { useAudioSync } from './hooks/useAudioSync';\nimport { useDocPlayback } from './hooks/useDocPlayback';\nimport { useViewportOrientation } from './hooks/useViewportOrientation';\nimport type { AudioProvider } from './hooks/AudioProvider';\nimport {\n expandCoverBlock,\n createTemplateContext,\n DEFAULT_THEME,\n VIEWPORT_PRESETS,\n type ViewportConfig,\n} from '@bendyline/squisq/doc';\nimport { DocControlsOverlay } from './DocControlsOverlay';\nimport { DocControlsSlideshow } from './DocControlsSlideshow';\nimport { DocProgressBar } from './DocProgressBar';\nimport { LinearDocView } from './LinearDocView';\nimport type {\n PlaybackState,\n PlaybackActions,\n BlockMarker,\n DisplayMode,\n CaptionStyle,\n CaptionMode,\n SlideNavActions,\n SquisqWindow,\n} from './types';\n\nconst SMALL_WORDS = new Set([\n 'a',\n 'an',\n 'the',\n 'and',\n 'but',\n 'or',\n 'for',\n 'nor',\n 'on',\n 'at',\n 'to',\n 'in',\n 'of',\n 'by',\n 'is',\n]);\n\n/**\n * Build a map of audio segment index -> display-friendly title.\n * Uses sectionHeader blocks to find real titles, with fallbacks\n * for \"intro\" and slug-based names.\n */\nfunction buildSegmentTitleMap(script: Doc): Map<number, string> {\n const map = new Map<number, string>();\n\n // Scan blocks for sectionHeader templates which carry the real title\n for (const block of script.blocks as DocBlock[]) {\n if (isTemplateBlock(block) && block.template === 'sectionHeader' && 'title' in block) {\n const segIdx = block.audioSegment;\n if (!map.has(segIdx)) {\n map.set(segIdx, (block as { title: string }).title);\n }\n }\n }\n\n // Fill in any segments that weren't covered by sectionHeader blocks\n for (let i = 0; i < script.audio.segments.length; i++) {\n if (!map.has(i)) {\n const name = script.audio.segments[i].name;\n if (name === 'intro' || name.includes('intro')) {\n map.set(i, 'Introduction');\n } else if (name === 'flight-context' || name.includes('flight-context')) {\n map.set(i, 'Flight Context');\n } else {\n // Title-case the slug: \"hands-on-history\" -> \"Hands on History\"\n const words = name.split('-');\n const titled = words\n .map((w, idx) =>\n idx === 0 || !SMALL_WORDS.has(w) ? w.charAt(0).toUpperCase() + w.slice(1) : w,\n )\n .join(' ');\n map.set(i, titled);\n }\n }\n }\n\n return map;\n}\n\ninterface DocPlayerProps {\n /** Doc script to play */\n script: Doc;\n /** Base path for resolving media URLs */\n basePath: string;\n /** Render mode for video capture (hides controls, exposes seekTo) */\n renderMode?: boolean;\n /** Auto-play when loaded */\n autoPlay?: boolean;\n /** Callback when playback ends */\n onEnded?: () => void;\n /** Callback for time updates */\n onTimeUpdate?: (time: number) => void;\n /** Optional audio provider (if not provided, uses default HTML5 audio) */\n audioProvider?: AudioProvider;\n /** Show built-in controls (default: true). Set to false for custom controls. */\n showControls?: boolean;\n /** Show only the progress bar/scrubber at bottom (no other controls).\n * Only takes effect when showControls is false. Allows external controls\n * while keeping the scrubber in-video. */\n showScrubber?: boolean;\n /** Mute audio (default: false) */\n muted?: boolean;\n /** Enable captions (default: true) */\n captionsEnabled?: boolean;\n /** Callback when captions enabled state is toggled */\n onCaptionsToggle?: (enabled: boolean) => void;\n /** Callback for playback state changes (for external controls) */\n onPlaybackStateChange?: (state: PlaybackState) => void;\n /** Callback when playback controls are ready (for external controls) */\n onControlsReady?: (\n controls: PlaybackActions & {\n play: () => void;\n pause: () => void;\n },\n ) => void;\n /** Whether the player is currently in fullscreen mode */\n isFullscreen?: boolean;\n /** Callback to toggle fullscreen mode */\n onFullscreenToggle?: () => void;\n /** Callback when block markers are computed (for external progress bars) */\n onBlockMarkers?: (markers: BlockMarker[]) => void;\n /** Force a specific viewport preset, bypassing window-based orientation detection.\n * Used when the player is rendered in a constrained container (e.g., map overlay panel)\n * whose shape differs from the window's. */\n forceViewport?: ViewportConfig;\n /** Theme to use for rendering (default: DEFAULT_THEME from the theme library) */\n theme?: Theme;\n /**\n * Display mode for the player.\n * - `'video'` (default) — Traditional video playback with play/pause, scrub bar, auto-advance.\n * - `'slideshow'` — PowerPoint-style with prev/next buttons. Blocks are static slides\n * that only change on user click. No auto-advance, no scrub bar.\n * - `'linear'` — Long-scrolling document view. Renders markdown as readable HTML with\n * template-annotated sections as inline SVG cards. No audio, no timeline.\n */\n displayMode?: DisplayMode;\n /** Caption display style (default: 'standard').\n * 'social' shows large centered words with the active word highlighted. */\n captionStyle?: CaptionStyle;\n}\n\nexport function DocPlayer({\n script,\n basePath,\n renderMode = false,\n autoPlay = false,\n onEnded,\n onTimeUpdate,\n audioProvider: externalAudioProvider,\n showControls = true,\n showScrubber = false,\n muted = false,\n captionsEnabled: captionsEnabledProp,\n onCaptionsToggle,\n onPlaybackStateChange,\n onControlsReady,\n isFullscreen = false,\n onFullscreenToggle,\n onBlockMarkers,\n forceViewport,\n displayMode = 'video',\n theme,\n captionStyle = 'standard',\n}: DocPlayerProps) {\n const isSlideshowMode = displayMode === 'slideshow';\n const isLinearMode = displayMode === 'linear';\n const audioRef = useRef<HTMLAudioElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n\n // Tap-to-toggle play/pause feedback animation\n const [tapFeedback, setTapFeedback] = useState<'play' | 'pause' | null>(null);\n const tapFeedbackTimer = useRef<ReturnType<typeof setTimeout>>();\n\n // Detect viewport orientation for responsive docs\n // forceViewport takes precedence (used by render mode with explicit viewport and constrained panels)\n // In render mode without forceViewport, default to landscape for backward compatibility\n const { viewport, orientation } = useViewportOrientation();\n const activeViewport = forceViewport || (renderMode ? VIEWPORT_PRESETS.landscape : viewport);\n\n // Check for debug mode via URL parameter\n const isDebugMode = useMemo(() => {\n if (typeof window === 'undefined') return false;\n const params = new URLSearchParams(window.location.search);\n return params.get('debug') === 'true';\n }, []);\n\n // Use internal HTML5 audio sync if no external provider is given\n const internalAudio = useAudioSync(audioRef, script.audio, basePath);\n\n // Use external provider if provided, otherwise fall back to internal\n const audio = externalAudioProvider || internalAudio;\n\n // Destructure for convenience\n const {\n currentTime,\n isPlaying,\n currentSegment,\n totalDuration,\n isEnded,\n isReady: isAudioReady,\n isAvailable,\n unavailableMessage,\n play,\n pause,\n toggle,\n seekTo,\n skipToSegment: _skipToSegment,\n restart,\n } = audio;\n\n // Refs for frequently-changing values used in the keyboard handler,\n // so the handler callback doesn't need to be recreated every frame.\n const currentTimeRef = useRef(currentTime);\n currentTimeRef.current = currentTime;\n const totalDurationRef = useRef(totalDuration);\n totalDurationRef.current = totalDuration;\n const expandedBlocksLenRef = useRef(0);\n\n // Tap the player surface to toggle play/pause (disabled in slideshow and linear mode)\n const handleContainerClick = useCallback(\n (e: React.MouseEvent) => {\n if (renderMode || isSlideshowMode || isLinearMode) return;\n const target = e.target as HTMLElement;\n // Don't toggle if user clicked a control element\n if (\n target.closest(\n 'button, a, input, .doc-player__controls, .doc-player__scrubber, .doc-controls-sidebar, .doc-controls-slideshow',\n )\n )\n return;\n toggle();\n // Show visual feedback (show the state we're transitioning TO)\n const nextState = isPlaying ? 'play' : 'pause';\n setTapFeedback(nextState);\n clearTimeout(tapFeedbackTimer.current);\n tapFeedbackTimer.current = setTimeout(() => setTapFeedback(null), 600);\n },\n [renderMode, toggle, isPlaying, isSlideshowMode, isLinearMode],\n );\n\n // Doc playback hook - pass viewport for responsive template expansion\n const {\n currentBlock,\n currentBlockIndex,\n previousBlock,\n isEntering,\n isExiting,\n blockTime,\n blockProgress: _blockProgress,\n docProgress,\n nextBlock: _nextBlock,\n prevBlock: _prevBlock,\n blocks: expandedBlocks,\n } = useDocPlayback(script, currentTime, activeViewport, renderMode, theme);\n\n // Expand cover block (startBlock) if present - uses active viewport\n const coverBlock = useMemo((): Block | null => {\n const startBlockConfig = script.startBlock as StartBlockConfig | undefined;\n if (!startBlockConfig) return null;\n\n const context = createTemplateContext(theme ?? DEFAULT_THEME, 0, 1, activeViewport);\n const layers = expandCoverBlock(startBlockConfig, context);\n\n return {\n id: 'cover-block',\n startTime: -1, // Not part of timeline\n duration: 0, // Static\n audioSegment: -1,\n layers,\n };\n }, [script.startBlock, activeViewport, theme]);\n\n // Render-mode cover block control: allows Playwright to force-show the cover block\n const [coverForced, setCoverForced] = useState(false);\n\n // Grace period: keep cover block visible for 3s after first play press\n const [coverGraceActive, setCoverGraceActive] = useState(false);\n const coverGraceTimer = useRef<ReturnType<typeof setTimeout>>();\n const coverWasShowing = useRef(false);\n\n // Track when cover is showing at rest (before play)\n const atRest = !!(coverBlock && !isPlaying && currentTime === 0 && !renderMode && !autoPlay);\n if (atRest) coverWasShowing.current = true;\n\n useEffect(() => {\n if (isPlaying && coverWasShowing.current && coverBlock && !renderMode) {\n coverWasShowing.current = false;\n setCoverGraceActive(true);\n coverGraceTimer.current = setTimeout(() => setCoverGraceActive(false), 3000);\n return () => clearTimeout(coverGraceTimer.current);\n }\n }, [isPlaying, coverBlock, renderMode]);\n\n // Determine if we should show the cover block\n // Show cover when: has cover block, not playing, at time 0, not in render mode\n // OR during the grace period after first play, OR when coverForced (render mode)\n // Cover block is suppressed in slideshow and linear mode — start directly on content\n const showCoverBlock =\n !isSlideshowMode &&\n !isLinearMode &&\n coverBlock &&\n (coverForced ||\n coverGraceActive ||\n (!isPlaying && currentTime === 0 && !renderMode && !autoPlay));\n\n // Auto-play if enabled (wait for audio to be ready)\n // Use a ref to track if we've already auto-played to avoid repeating on every render\n const hasAutoPlayed = useRef(false);\n useEffect(() => {\n if (isAudioReady && autoPlay && !hasAutoPlayed.current) {\n hasAutoPlayed.current = true;\n play();\n }\n }, [isAudioReady, autoPlay, play]);\n\n // Callback for time updates\n useEffect(() => {\n onTimeUpdate?.(currentTime);\n }, [currentTime, onTimeUpdate]);\n\n // Callback for ended\n useEffect(() => {\n if (isEnded) {\n onEnded?.();\n }\n }, [isEnded, onEnded]);\n\n // Expose seekTo globally for render mode (Playwright) and debug mode (testing)\n useEffect(() => {\n if ((renderMode || isDebugMode) && typeof window !== 'undefined') {\n const w = window as SquisqWindow;\n w.seekTo = (time: number) => {\n seekTo(time);\n // After React renders the correct block, advance CSS animations\n // (Ken Burns, transitions) to match the doc timeline position.\n // Without this, animations restart from zero on each seekTo because\n // they run on the browser's real clock, not doc time.\n return new Promise<void>((resolve) => {\n requestAnimationFrame(() => {\n // Find the current block's start time\n let blockStartTime = 0;\n for (let i = expandedBlocks.length - 1; i >= 0; i--) {\n if (time >= expandedBlocks[i].startTime) {\n blockStartTime = expandedBlocks[i].startTime;\n break;\n }\n }\n const elapsedMs = (time - blockStartTime) * 1000;\n\n // Set all CSS animations to the correct timeline position\n document.getAnimations().forEach((anim) => {\n const target = (anim.effect as KeyframeEffect)?.target as Element | null;\n if (!target) return;\n\n // Animations on the active block: use current block elapsed time\n if (target.closest('.doc-player__block--active')) {\n anim.currentTime = Math.max(0, elapsedMs);\n }\n // Animations on the exiting block (during crossfade): use current\n // block elapsed for transition animations, keep Ken Burns at their\n // natural position based on when that block started\n // eslint-disable-next-line sonarjs/no-duplicated-branches\n else if (target.closest('.doc-player__block--previous')) {\n anim.currentTime = Math.max(0, elapsedMs);\n }\n });\n\n // Seek <video> elements in the active block to the correct clip position.\n // Each <video> carries data-clip-start/data-clip-end attributes set by\n // VideoLayer.tsx; we calculate targetTime = clipStart + blockElapsed.\n const blockElapsed = time - blockStartTime;\n const videoSeekPromises: Promise<void>[] = [];\n const activeBlockEl = document.querySelector('.doc-player__block--active');\n if (activeBlockEl) {\n const videos = activeBlockEl.querySelectorAll('video[data-clip-start]');\n videos.forEach((el) => {\n const video = el as HTMLVideoElement;\n const clipStart = parseFloat(video.dataset.clipStart || '0');\n const clipEnd = parseFloat(video.dataset.clipEnd || '0');\n const targetTime = Math.min(clipStart + Math.max(0, blockElapsed), clipEnd);\n\n video.pause();\n video.currentTime = targetTime;\n\n videoSeekPromises.push(\n new Promise<void>((r) => {\n if (Math.abs(video.currentTime - targetTime) < 0.1) {\n r();\n } else {\n video.addEventListener('seeked', () => r(), { once: true });\n setTimeout(r, 200); // Fallback if seeked never fires\n }\n }),\n );\n });\n }\n\n // Wait for video seeks + one more frame for the browser to render\n Promise.all(videoSeekPromises).then(() => {\n requestAnimationFrame(() => resolve());\n });\n });\n });\n };\n w.getDuration = () => {\n // When audio is present totalDuration comes from audio segments.\n // For audio-less docs, compute from block timings instead.\n if (totalDuration > 0) return totalDuration;\n if (expandedBlocks.length > 0) {\n const last = expandedBlocks[expandedBlocks.length - 1];\n return last.startTime + last.duration;\n }\n return 0;\n };\n // Expose block metadata for testing -- allows tests to find specific templates\n w.getBlocks = () =>\n expandedBlocks.map((s: Block) => ({\n id: s.id,\n template: (s as DocBlock).template ?? 'raw',\n startTime: s.startTime,\n duration: s.duration,\n }));\n // Audio segment info for video production -- returns the actual files in composition order\n w.getAudioSegments = () =>\n script.audio.segments.map((seg) => ({\n src: seg.src,\n name: seg.name,\n duration: seg.duration,\n startTime: seg.startTime,\n }));\n // Caption phrases for SRT/subtitle export\n w.getCaptions = () =>\n script.captions?.phrases?.map((p) => ({\n text: p.text,\n startTime: p.startTime,\n endTime: p.endTime,\n })) || [];\n // Chapter markers for YouTube timestamps -- uses segment titles from sectionHeader blocks\n w.getChapters = () => {\n const titleMap = buildSegmentTitleMap(script);\n return script.audio.segments.map((seg, i) => ({\n title: titleMap.get(i) || seg.name,\n startTime: seg.startTime,\n duration: seg.duration,\n }));\n };\n // Cover block control for video pre-roll -- force-show or hide the cover block\n w.showCover = () => {\n setCoverForced(true);\n return new Promise<void>((resolve) => requestAnimationFrame(() => resolve()));\n };\n w.hideCover = () => {\n setCoverForced(false);\n return new Promise<void>((resolve) => requestAnimationFrame(() => resolve()));\n };\n w.hasCoverBlock = () => !!coverBlock;\n }\n return () => {\n if (typeof window !== 'undefined') {\n const w = window as SquisqWindow;\n delete w.seekTo;\n delete w.getDuration;\n delete w.getBlocks;\n delete w.getAudioSegments;\n delete w.getCaptions;\n delete w.getChapters;\n delete w.showCover;\n delete w.hideCover;\n delete w.hasCoverBlock;\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- script is a stable prop; re-registering on every script change is unnecessary\n }, [renderMode, isDebugMode, seekTo, totalDuration, expandedBlocks, coverBlock]);\n\n // Caption mode state: cycles through off → standard → social → off\n // The captionStyle prop sets the default active style; captionsEnabledProp\n // can override the initial on/off state.\n const defaultMode: CaptionMode =\n captionsEnabledProp === false ? 'off' : captionStyle || 'standard';\n const [captionMode, setCaptionMode] = useState<CaptionMode>(defaultMode);\n\n // Derive captionsEnabled and active style from the mode\n const captionsEnabled = captionMode !== 'off';\n const activeCaptionStyle: CaptionStyle = captionMode === 'social' ? 'social' : 'standard';\n\n const setCaptionsEnabled = useCallback(\n (enabled: boolean) => {\n // When re-enabling, restore the prop-specified style rather than\n // always defaulting to 'standard'\n setCaptionMode(enabled ? captionStyle || 'standard' : 'off');\n onCaptionsToggle?.(enabled);\n },\n [onCaptionsToggle, captionStyle],\n );\n\n const cycleCaptionMode = useCallback(() => {\n setCaptionMode((prev) => {\n const next: CaptionMode =\n prev === 'off' ? 'standard' : prev === 'standard' ? 'social' : 'off';\n onCaptionsToggle?.(next !== 'off');\n return next;\n });\n }, [onCaptionsToggle]);\n\n const hasCaptions = script.captions && script.captions.phrases.length > 0;\n\n // Map segment indices to human-readable titles (from sectionHeader blocks)\n const segmentTitleMap = useMemo(() => buildSegmentTitleMap(script), [script]);\n\n // Build shared playback state for extracted controls\n const playbackState: PlaybackState = useMemo(\n () => ({\n isPlaying,\n currentTime,\n totalDuration,\n currentBlockIndex,\n totalBlocks: expandedBlocks.length,\n docProgress,\n hasCaptions: !!hasCaptions,\n captionsEnabled,\n captionMode,\n isFullscreen,\n currentSegmentIndex: currentSegment,\n currentSegmentName:\n segmentTitleMap.get(currentSegment) ?? script.audio.segments[currentSegment]?.name ?? null,\n currentBlock: currentBlock ?? null,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps -- script.audio.segments is stable within a given script\n [\n isPlaying,\n currentTime,\n totalDuration,\n currentBlockIndex,\n expandedBlocks.length,\n docProgress,\n hasCaptions,\n captionsEnabled,\n captionMode,\n isFullscreen,\n currentSegment,\n segmentTitleMap,\n currentBlock,\n ],\n );\n\n // Build shared playback actions for extracted controls\n const playbackActions: PlaybackActions = useMemo(\n () => ({\n toggle,\n restart,\n seekTo,\n setCaptionsEnabled,\n cycleCaptionMode,\n toggleFullscreen: onFullscreenToggle,\n }),\n [toggle, restart, seekTo, setCaptionsEnabled, cycleCaptionMode, onFullscreenToggle],\n );\n\n // Slide navigation actions for slideshow mode\n // These seek to the target block's startTime and keep the player paused.\n const slideNavActions: SlideNavActions = useMemo(\n () => ({\n nextSlide: () => {\n if (currentBlockIndex < expandedBlocks.length - 1) {\n const target = expandedBlocks[currentBlockIndex + 1];\n if (target) {\n seekTo(target.startTime);\n pause();\n }\n }\n },\n prevSlide: () => {\n if (currentBlockIndex > 0) {\n const target = expandedBlocks[currentBlockIndex - 1];\n if (target) {\n seekTo(target.startTime);\n pause();\n }\n }\n },\n goToSlide: (index: number) => {\n if (index >= 0 && index < expandedBlocks.length) {\n const target = expandedBlocks[index];\n if (target) {\n seekTo(target.startTime);\n pause();\n }\n }\n },\n }),\n [currentBlockIndex, expandedBlocks, seekTo, pause],\n );\n\n // Callback for playback state changes (for external controls)\n useEffect(() => {\n onPlaybackStateChange?.(playbackState);\n }, [playbackState, onPlaybackStateChange]);\n\n // Callback when controls are ready (for external controls)\n // Fires every time playbackActions change so the external sidebar always holds\n // fresh function references (toggle closes over isPlaying, so it changes often).\n useEffect(() => {\n onControlsReady?.({ play, pause, ...playbackActions });\n }, [play, pause, playbackActions, onControlsReady]);\n\n // Extract display title from a block (handles both template and expanded blocks)\n const getBlockTitle = useCallback((block: Block): string => {\n // For template blocks, extract title from template-specific properties first\n const docBlock = block as DocBlock;\n if (isTemplateBlock(docBlock)) {\n const props = docBlock as unknown as Record<string, unknown>;\n if (typeof props.title === 'string') return props.title;\n if (typeof props.stat === 'string') return props.stat;\n if (typeof props.quote === 'string') {\n const firstLine = props.quote.split('\\n')[0];\n if (firstLine.length <= 30) return firstLine;\n return firstLine.slice(0, 27) + '...';\n }\n if (typeof props.date === 'string') return props.date;\n if (typeof props.fact === 'string') return props.fact;\n }\n\n // For expanded blocks with layers, try to find text content\n if (block.layers && Array.isArray(block.layers)) {\n const textLayer = block.layers.find((l): l is TextLayer => l.type === 'text');\n if (textLayer?.content?.text) {\n // Get first line of text, truncate if too long\n const firstLine = textLayer.content.text.split('\\n')[0];\n if (firstLine.length <= 30) return firstLine;\n return firstLine.slice(0, 27) + '...';\n }\n }\n\n // Fallback to formatted id\n return block.id.replace(/-/g, ' ').replace(/\\b\\w/g, (c) => c.toUpperCase());\n }, []);\n\n // Compute block markers for progress bar (using expanded blocks)\n const blockMarkers = useMemo(() => {\n if (!totalDuration || !expandedBlocks.length) return [];\n let prevSegment = -1;\n return expandedBlocks.map((block, index) => {\n const isSectionStart = block.audioSegment !== prevSegment;\n prevSegment = block.audioSegment;\n return {\n block,\n index,\n position: (block.startTime / totalDuration) * 100,\n title: getBlockTitle(block),\n isSectionStart,\n };\n });\n }, [expandedBlocks, totalDuration, getBlockTitle]);\n\n // Notify parent when block markers are computed\n useEffect(() => {\n if (blockMarkers.length > 0) {\n onBlockMarkers?.(blockMarkers);\n }\n }, [blockMarkers, onBlockMarkers]);\n\n // Keep expandedBlocks length in a ref so keyboard handler stays stable\n expandedBlocksLenRef.current = expandedBlocks.length;\n\n // Handle keyboard controls — uses refs for frequently-changing values\n // (currentTime, totalDuration, expandedBlocks.length) to avoid\n // re-registering the event listener on every animation frame.\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n // Don't capture keyboard events when focus is on an input/textarea\n const activeEl = document.activeElement;\n if (\n activeEl &&\n (activeEl.tagName === 'INPUT' ||\n activeEl.tagName === 'TEXTAREA' ||\n activeEl.tagName === 'SELECT')\n ) {\n return;\n }\n\n // Linear mode: no keyboard shortcuts (native scrolling handles it)\n if (isLinearMode) return;\n\n if (isSlideshowMode) {\n // Slideshow mode: arrow keys navigate slides\n switch (e.key) {\n case 'ArrowRight':\n case 'ArrowDown':\n case ' ':\n e.preventDefault();\n slideNavActions.nextSlide();\n break;\n case 'ArrowLeft':\n case 'ArrowUp':\n e.preventDefault();\n slideNavActions.prevSlide();\n break;\n case 'Home':\n e.preventDefault();\n slideNavActions.goToSlide(0);\n break;\n case 'End':\n e.preventDefault();\n slideNavActions.goToSlide(expandedBlocksLenRef.current - 1);\n break;\n }\n } else {\n // Video mode: standard playback controls\n switch (e.key) {\n case ' ':\n e.preventDefault();\n toggle();\n break;\n case 'ArrowRight':\n seekTo(Math.min(currentTimeRef.current + 10, totalDurationRef.current));\n break;\n case 'ArrowLeft':\n seekTo(Math.max(currentTimeRef.current - 10, 0));\n break;\n }\n }\n },\n [isSlideshowMode, isLinearMode, toggle, seekTo, slideNavActions],\n );\n\n useEffect(() => {\n if (renderMode) return; // No keyboard in render mode\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [handleKeyDown, renderMode]);\n\n // ── Linear mode: render as scrollable document ──────────────────\n if (isLinearMode) {\n return (\n <div\n ref={containerRef}\n className=\"doc-player doc-player--linear\"\n style={{\n position: 'relative',\n width: '100%',\n height: '100%',\n overflow: 'hidden',\n }}\n >\n <LinearDocView doc={script} basePath={basePath} viewport={activeViewport} />\n </div>\n );\n }\n\n return (\n <div\n ref={containerRef}\n className=\"doc-player\"\n onClick={handleContainerClick}\n style={{\n position: 'relative',\n width: '100%',\n aspectRatio: `${activeViewport.width} / ${activeViewport.height}`,\n margin: '0 auto',\n overflow: 'hidden',\n cursor: renderMode ? undefined : 'pointer',\n }}\n >\n {/* Hidden audio element */}\n <audio ref={audioRef} preload=\"auto\" muted={muted} />\n\n {/* Block viewport */}\n <div className=\"doc-player__viewport\">\n {/* Cover block (shown at rest before playback) */}\n {showCoverBlock && coverBlock && (\n <div className=\"doc-player__block doc-player__block--cover\">\n <BlockRenderer\n block={coverBlock}\n blockTime={0}\n basePath={basePath}\n isEntering={false}\n viewport={activeViewport}\n />\n </div>\n )}\n\n {/* Previous block (during transition) */}\n {!showCoverBlock && previousBlock && isExiting && (\n <div className=\"doc-player__block doc-player__block--previous\">\n <BlockRenderer\n block={previousBlock}\n blockTime={blockTime}\n basePath={basePath}\n isExiting={true}\n viewport={activeViewport}\n />\n </div>\n )}\n\n {/* Current block */}\n {!showCoverBlock && currentBlock && (\n <div className=\"doc-player__block doc-player__block--active\">\n <BlockRenderer\n block={currentBlock}\n blockTime={blockTime}\n basePath={basePath}\n isEntering={isEntering}\n viewport={activeViewport}\n isPlaying={isPlaying}\n />\n </div>\n )}\n\n {/* Caption overlay -- shown during playback and in render mode when captions are enabled */}\n {hasCaptions && (renderMode ? captionsEnabled : true) && (\n <CaptionOverlay\n captions={script.captions}\n currentTime={currentTime}\n enabled={captionsEnabled && (renderMode || isPlaying || currentTime > 0)}\n fontSize={16}\n captionStyle={activeCaptionStyle}\n theme={theme}\n viewport={activeViewport}\n />\n )}\n\n {/* Debug overlay (when ?debug=true) */}\n {isDebugMode && (\n <div\n className=\"doc-player__debug\"\n style={{\n position: 'absolute',\n top: '8px',\n right: '8px',\n padding: '8px 12px',\n background: 'rgba(0, 0, 0, 0.85)',\n borderRadius: '6px',\n color: '#00ff00',\n fontFamily: 'monospace',\n fontSize: '11px',\n lineHeight: '1.5',\n zIndex: 200,\n maxWidth: '280px',\n pointerEvents: 'none',\n textAlign: 'left',\n }}\n >\n <div style={{ color: '#ffcc00', fontWeight: 'bold', marginBottom: '4px' }}>\n DEBUG MODE\n </div>\n <div>\n <span style={{ color: '#888' }}>template:</span>{' '}\n <span style={{ color: '#ff6b6b' }}>\n {(currentBlock as DocBlock | null)?.template ?? 'raw'}\n </span>\n </div>\n <div>\n <span style={{ color: '#888' }}>block:</span> {currentBlockIndex + 1}/\n {expandedBlocks.length}{' '}\n <span style={{ color: '#666' }}>({currentBlock?.id || 'none'})</span>\n </div>\n <div>\n <span style={{ color: '#888' }}>time:</span> {currentTime.toFixed(2)}s /{' '}\n {totalDuration.toFixed(1)}s{' '}\n <span style={{ color: '#666' }}>\n (progress: {(docProgress * 100).toFixed(1)}%, scriptDur:{' '}\n {script.duration.toFixed(1)})\n </span>\n </div>\n <div>\n <span style={{ color: '#888' }}>blockTime:</span> {blockTime.toFixed(2)}s /{' '}\n {(currentBlock?.duration || 0).toFixed(1)}s\n </div>\n <div>\n <span style={{ color: '#888' }}>segment:</span> {currentSegment}/\n {script.audio.segments.length - 1}{' '}\n <span style={{ color: '#666' }}>\n ({script.audio.segments[currentSegment]?.name || 'none'})\n </span>\n </div>\n <div>\n <span style={{ color: '#888' }}>viewport:</span>{' '}\n {activeViewport.name || `${activeViewport.width}x${activeViewport.height}`}{' '}\n <span style={{ color: '#666' }}>({orientation})</span>\n </div>\n <div>\n <span style={{ color: '#888' }}>playing:</span>{' '}\n <span style={{ color: isPlaying ? '#4ade80' : '#f87171' }}>\n {isPlaying ? 'yes' : 'no'}\n </span>\n {showCoverBlock && <span style={{ color: '#60a5fa' }}> (cover)</span>}\n </div>\n {hasCaptions &&\n (() => {\n const debugPhrase = getCaptionAtTime(script.captions!, currentTime);\n const debugEnabled = captionsEnabled && (isPlaying || currentTime > 0);\n return (\n <Fragment>\n <div>\n <span style={{ color: '#888' }}>captions:</span>{' '}\n {script.captions?.phrases.length || 0} phrases{' '}\n <span style={{ color: captionsEnabled ? '#4ade80' : '#666' }}>\n ({captionsEnabled ? 'on' : 'off'})\n </span>\n </div>\n <div>\n <span style={{ color: '#888' }}>cc.enabled:</span>{' '}\n <span style={{ color: debugEnabled ? '#4ade80' : '#f87171' }}>\n {String(debugEnabled)}\n </span>{' '}\n <span style={{ color: '#666' }}>\n (playing={String(isPlaying)} t&gt;0={String(currentTime > 0)})\n </span>\n </div>\n <div>\n <span style={{ color: '#888' }}>cc.phrase:</span>{' '}\n <span style={{ color: debugPhrase ? '#4ade80' : '#f87171' }}>\n {debugPhrase ? `\"${debugPhrase.text.slice(0, 30)}...\"` : 'null'}\n </span>\n </div>\n {debugPhrase && (\n <div>\n <span style={{ color: '#888' }}>cc.range:</span>{' '}\n <span style={{ color: '#60a5fa' }}>\n {debugPhrase.startTime.toFixed(2)}-{debugPhrase.endTime.toFixed(2)}\n </span>\n </div>\n )}\n </Fragment>\n );\n })()}\n </div>\n )}\n </div>\n\n {/* Audio unavailable overlay */}\n {!isAvailable && unavailableMessage && (\n <div\n className=\"doc-player__unavailable\"\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexDirection: 'column',\n gap: '16px',\n background: 'rgba(0, 0, 0, 0.7)',\n color: 'rgba(255, 255, 255, 0.9)',\n fontSize: '14px',\n zIndex: 50,\n }}\n >\n <span style={{ fontSize: '32px' }}>&#x1F50A;</span>\n <span>{unavailableMessage}</span>\n </div>\n )}\n\n {/* Full overlay controls (default video layout) */}\n {!renderMode && !isSlideshowMode && showControls && (\n <DocControlsOverlay\n state={playbackState}\n actions={playbackActions}\n blockMarkers={blockMarkers}\n expandedBlocks={expandedBlocks}\n getBlockTitle={getBlockTitle}\n />\n )}\n\n {/* Scrubber-only mode (for sidebar/bottom layouts where other controls are external) */}\n {!renderMode && !isSlideshowMode && !showControls && showScrubber && (\n <div\n className=\"doc-player__scrubber\"\n style={{\n position: 'absolute',\n bottom: 0,\n left: 0,\n right: 0,\n padding: '12px 16px 8px',\n background: 'linear-gradient(transparent, rgba(0,0,0,0.6))',\n display: 'flex',\n alignItems: 'center',\n zIndex: 100,\n }}\n >\n <DocProgressBar\n state={playbackState}\n actions={playbackActions}\n blockMarkers={blockMarkers}\n expandedBlocks={expandedBlocks}\n getBlockTitle={getBlockTitle}\n />\n </div>\n )}\n\n {/* Slideshow controls (prev / counter / next) */}\n {!renderMode && isSlideshowMode && (\n <DocControlsSlideshow state={playbackState} slideNav={slideNavActions} />\n )}\n\n {/* Tap feedback animation -- shows play/pause icon briefly on tap (video mode only) */}\n {!isSlideshowMode && tapFeedback && (\n <div className=\"doc-player__tap-feedback\" key={Date.now()}>\n <svg viewBox=\"0 0 24 24\" fill=\"white\" width=\"48\" height=\"48\">\n {tapFeedback === 'pause' ? (\n <path d=\"M6 19h4V5H6v14zm8-14v14h4V5h-4z\" />\n ) : (\n <path d=\"M8 5v14l11-7z\" />\n )}\n </svg>\n </div>\n )}\n </div>\n );\n}\n\nexport default DocPlayer;\n","/**\n * Doc Animations\n *\n * CSS keyframe animations for the visual doc system.\n * Designed to be ES2015/Chrome 49 compatible for Coherent GT (MSFS).\n *\n * Animation classes are applied dynamically based on Doc.\n * Each animation has variants for common durations.\n */\n\n/* ============================================\n Slow Zoom Effect\n Slow zoom with optional pan for cinematic feel\n ============================================ */\n\n@keyframes slowZoomIn {\n from {\n transform: scale(1);\n }\n to {\n transform: scale(1.15);\n }\n}\n\n@keyframes slowZoomOut {\n from {\n transform: scale(1.15);\n }\n to {\n transform: scale(1);\n }\n}\n\n@keyframes slowZoomPanLeft {\n from {\n transform: translateX(0) scale(1.1);\n }\n to {\n transform: translateX(-8%) scale(1.1);\n }\n}\n\n@keyframes slowZoomPanRight {\n from {\n transform: translateX(-8%) scale(1.1);\n }\n to {\n transform: translateX(0) scale(1.1);\n }\n}\n\n@keyframes slowZoomPanUp {\n from {\n transform: translateY(0) scale(1.1);\n }\n to {\n transform: translateY(-8%) scale(1.1);\n }\n}\n\n@keyframes slowZoomPanDown {\n from {\n transform: translateY(-8%) scale(1.1);\n }\n to {\n transform: translateY(0) scale(1.1);\n }\n}\n\n/* Slow zoom combined zoom + pan */\n@keyframes slowZoomCombinedPanLeft {\n from {\n transform: translateX(0) scale(1);\n }\n to {\n transform: translateX(-5%) scale(1.12);\n }\n}\n\n@keyframes slowZoomCombinedPanRight {\n from {\n transform: translateX(-5%) scale(1.12);\n }\n to {\n transform: translateX(0) scale(1);\n }\n}\n\n/* ============================================\n Fade Animations\n ============================================ */\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n@keyframes fadeOut {\n from {\n opacity: 1;\n }\n to {\n opacity: 0;\n }\n}\n\n@keyframes fadeInUp {\n from {\n opacity: 0;\n transform: translateY(20px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes fadeInDown {\n from {\n opacity: 0;\n transform: translateY(-20px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n/* ============================================\n Zoom Animations\n ============================================ */\n\n@keyframes zoomIn {\n from {\n transform: scale(0.9);\n opacity: 0;\n }\n to {\n transform: scale(1);\n opacity: 1;\n }\n}\n\n@keyframes zoomOut {\n from {\n transform: scale(1);\n opacity: 1;\n }\n to {\n transform: scale(0.9);\n opacity: 0;\n }\n}\n\n/* ============================================\n Pan/Slide Animations\n ============================================ */\n\n@keyframes panLeft {\n from {\n transform: translateX(0);\n }\n to {\n transform: translateX(-10%);\n }\n}\n\n@keyframes panRight {\n from {\n transform: translateX(-10%);\n }\n to {\n transform: translateX(0);\n }\n}\n\n@keyframes slideInLeft {\n from {\n transform: translateX(-100%);\n }\n to {\n transform: translateX(0);\n }\n}\n\n@keyframes slideInRight {\n from {\n transform: translateX(100%);\n }\n to {\n transform: translateX(0);\n }\n}\n\n@keyframes slideOutLeft {\n from {\n transform: translateX(0);\n }\n to {\n transform: translateX(-100%);\n }\n}\n\n@keyframes slideOutRight {\n from {\n transform: translateX(0);\n }\n to {\n transform: translateX(100%);\n }\n}\n\n/* ============================================\n Text Animations\n ============================================ */\n\n@keyframes typewriter {\n from {\n clip-path: inset(0 100% 0 0);\n }\n to {\n clip-path: inset(0 0 0 0);\n }\n}\n\n/* Fallback for browsers without clip-path */\n@keyframes typewriterFallback {\n from {\n width: 0;\n overflow: hidden;\n }\n to {\n width: 100%;\n overflow: hidden;\n }\n}\n\n/* ============================================\n Block Transitions\n Applied to entire block containers\n ============================================ */\n\n.transition-fade-enter {\n animation: fadeIn var(--transition-duration, 1.5s) ease-out forwards;\n}\n\n.transition-fade-exit {\n animation: fadeOut var(--transition-duration, 1.5s) ease-out forwards;\n}\n\n.transition-dissolve-enter {\n animation: fadeIn var(--transition-duration, 2s) ease-in-out forwards;\n}\n\n.transition-dissolve-exit {\n animation: fadeOut var(--transition-duration, 2s) ease-in-out forwards;\n}\n\n.transition-slideLeft-enter {\n animation: slideInRight var(--transition-duration, 0.8s) ease-out forwards;\n}\n\n.transition-slideLeft-exit {\n animation: slideOutLeft var(--transition-duration, 0.8s) ease-out forwards;\n}\n\n.transition-slideRight-enter {\n animation: slideInLeft var(--transition-duration, 0.8s) ease-out forwards;\n}\n\n.transition-slideRight-exit {\n animation: slideOutRight var(--transition-duration, 0.8s) ease-out forwards;\n}\n\n/* ============================================\n Animation Utility Classes\n Applied dynamically based on layer.animation\n ============================================ */\n\n.anim-none {\n animation: none;\n}\n\n.anim-fadeIn {\n animation: fadeIn var(--anim-duration, 1s) var(--anim-easing, ease-out) var(--anim-delay, 0s)\n forwards;\n}\n\n.anim-fadeOut {\n animation: fadeOut var(--anim-duration, 1s) var(--anim-easing, ease-out) var(--anim-delay, 0s)\n forwards;\n}\n\n.anim-fadeInUp {\n animation: fadeInUp var(--anim-duration, 0.6s) var(--anim-easing, ease-out) var(--anim-delay, 0s)\n forwards;\n}\n\n.anim-slowZoom-in {\n animation: slowZoomIn var(--anim-duration, 8s) var(--anim-easing, linear) var(--anim-delay, 0s)\n forwards;\n}\n\n.anim-slowZoom-out {\n animation: slowZoomOut var(--anim-duration, 8s) var(--anim-easing, linear) var(--anim-delay, 0s)\n forwards;\n}\n\n.anim-slowZoom-panLeft {\n animation: slowZoomCombinedPanLeft var(--anim-duration, 8s) var(--anim-easing, linear)\n var(--anim-delay, 0s) forwards;\n}\n\n.anim-slowZoom-panRight {\n animation: slowZoomCombinedPanRight var(--anim-duration, 8s) var(--anim-easing, linear)\n var(--anim-delay, 0s) forwards;\n}\n\n.anim-zoomIn {\n animation: zoomIn var(--anim-duration, 0.5s) var(--anim-easing, ease-out) var(--anim-delay, 0s)\n forwards;\n}\n\n.anim-zoomOut {\n animation: zoomOut var(--anim-duration, 0.5s) var(--anim-easing, ease-out) var(--anim-delay, 0s)\n forwards;\n}\n\n.anim-panLeft {\n animation: panLeft var(--anim-duration, 8s) var(--anim-easing, linear) var(--anim-delay, 0s)\n forwards;\n}\n\n.anim-panRight {\n animation: panRight var(--anim-duration, 8s) var(--anim-easing, linear) var(--anim-delay, 0s)\n forwards;\n}\n\n.anim-typewriter {\n animation: typewriter var(--anim-duration, 2s) var(--anim-easing, steps(40, end))\n var(--anim-delay, 0s) forwards;\n}\n\n/* ============================================\n Doc Player Container Styles\n ============================================ */\n\n.doc-player {\n position: relative;\n overflow: hidden;\n /* clip-path provides a hard pixel clip that catches SVG foreignObject bleed\n which can escape overflow:hidden in some browsers */\n clip-path: inset(0);\n background: #000;\n /* Ensure max dimensions work with aspect-ratio */\n max-width: 100%;\n max-height: 100%;\n}\n\n.doc-player__viewport {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n}\n\n.doc-player__block {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n}\n\n.doc-player__block--active {\n z-index: 2;\n}\n\n.doc-player__block--previous {\n z-index: 1;\n}\n\n/* Tap-to-toggle play/pause feedback */\n.doc-player__tap-feedback {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n z-index: 150;\n pointer-events: none;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 72px;\n height: 72px;\n border-radius: 50%;\n background: rgba(0, 0, 0, 0.45);\n animation: tap-feedback-fade 0.6s ease-out forwards;\n}\n\n@keyframes tap-feedback-fade {\n 0% {\n opacity: 1;\n transform: translate(-50%, -50%) scale(1);\n }\n 100% {\n opacity: 0;\n transform: translate(-50%, -50%) scale(1.3);\n }\n}\n\n/* SVG block container */\n.block-svg {\n width: 100%;\n height: 100%;\n display: block;\n}\n\n/* Layer containers within SVG */\n.block-layer {\n overflow: hidden;\n}\n\n.block-layer--image {\n /* Images need overflow visible for Ken Burns */\n overflow: visible;\n}\n\n/* ============================================\n Text Styling Helpers\n ============================================ */\n\n.text-shadow {\n text-shadow:\n 0 2px 4px rgba(0, 0, 0, 0.8),\n 0 4px 8px rgba(0, 0, 0, 0.4);\n}\n\n.text-shadow-light {\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n\n/* Text background box */\n.text-box {\n background: rgba(0, 0, 0, 0.6);\n padding: 16px 24px;\n border-radius: 4px;\n}\n\n.text-box--light {\n background: rgba(255, 255, 255, 0.9);\n color: #1a1a1a;\n}\n","/**\n * Standalone Entry Point — IIFE bundle for self-contained HTML rendering.\n *\n * This file is the entry point for the standalone `squisq-player.iife.js` bundle.\n * It bundles Preact (via preact/compat), squisq core, and all rendering components\n * into a single self-contained script that can be loaded in any HTML page.\n *\n * The bundle exposes a global `SquisqPlayer` object with methods to mount\n * interactive or static document views into any DOM element.\n *\n * Usage (in HTML):\n * <script src=\"squisq-player.iife.js\"></script>\n * <div id=\"root\"></div>\n * <script>\n * SquisqPlayer.mount(document.getElementById('root'), docJson, {\n * mode: 'slideshow',\n * images: { 'hero.jpg': 'data:image/jpeg;base64,...' }\n * });\n * </script>\n */\n\nimport { createElement } from 'react';\nimport { createRoot, type Root } from 'react-dom/client';\nimport type { Doc, MediaProvider } from '@bendyline/squisq/schemas';\nimport type { Theme } from '@bendyline/squisq/schemas';\nimport { DocPlayer } from './DocPlayer';\nimport { LinearDocView } from './LinearDocView';\nimport { MediaContext } from './hooks/MediaContext';\n\n// CSS is loaded as text via esbuild's text loader (configured in tsup.standalone.config.ts)\n// @ts-expect-error — .css import returns a string when esbuild uses 'text' loader (standalone build only)\nimport animationCss from './styles/doc-animations.css';\n\n// ── Types ──────────────────────────────────────────────────────────\n\nexport interface MountOptions {\n /** Rendering mode: 'slideshow' (interactive, default) or 'static' (scrollable) */\n mode?: 'slideshow' | 'static';\n /** Base path for resolving relative media URLs */\n basePath?: string;\n /**\n * Map of relative image paths to data URIs or blob URLs.\n * Used in single-HTML exports where images are inlined as base64.\n * Example: { 'hero.jpg': 'data:image/jpeg;base64,...' }\n */\n images?: Record<string, string>;\n /**\n * Map of audio segment names/paths to URLs (data URIs, blob URLs, or relative paths).\n * Used in ZIP exports where audio files are included alongside the HTML.\n */\n audio?: Record<string, string>;\n /** Optional theme override */\n theme?: Theme;\n /** Auto-play on mount (only for slideshow mode, default: false) */\n autoPlay?: boolean;\n /**\n * Enable render mode for headless frame capture.\n * Exposes window.seekTo(), getDuration(), getCaptions(), etc.\n * Disables controls and auto-play. Used by Playwright video export.\n */\n renderMode?: boolean;\n /** Caption style: 'standard' or 'social'. Omit or set to undefined for no captions. */\n captionStyle?: 'standard' | 'social';\n}\n\n// ── CSS Injection ──────────────────────────────────────────────────\n\nlet cssInjected = false;\n\nfunction injectCss(): void {\n if (cssInjected || typeof document === 'undefined') return;\n const style = document.createElement('style');\n style.setAttribute('data-squisq-player', 'animations');\n style.textContent = animationCss;\n document.head.appendChild(style);\n cssInjected = true;\n}\n\n// ── Inline Media Provider ──────────────────────────────────────────\n\n/**\n * Creates a MediaProvider that resolves URLs from an inline image map.\n * Falls back to basePath-based resolution for unknown paths.\n */\nfunction createInlineMediaProvider(\n images: Record<string, string>,\n basePath: string,\n): MediaProvider {\n return {\n async resolveUrl(relativePath: string): Promise<string> {\n if (relativePath in images) return images[relativePath];\n // Fallback to basePath\n if (\n relativePath.startsWith('http') ||\n relativePath.startsWith('data:') ||\n relativePath.startsWith('blob:')\n ) {\n return relativePath;\n }\n return `${basePath}/${relativePath}`;\n },\n async listMedia() {\n return Object.keys(images).map((name) => ({\n name,\n mimeType: inferMimeType(name),\n size: 0,\n }));\n },\n async addMedia() {\n throw new Error('Standalone player is read-only');\n },\n async removeMedia() {\n throw new Error('Standalone player is read-only');\n },\n dispose() {\n // no-op\n },\n };\n}\n\nfunction inferMimeType(filename: string): string {\n const ext = filename.split('.').pop()?.toLowerCase() ?? '';\n const map: Record<string, string> = {\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n png: 'image/png',\n gif: 'image/gif',\n webp: 'image/webp',\n svg: 'image/svg+xml',\n mp3: 'audio/mpeg',\n mp4: 'video/mp4',\n webm: 'video/webm',\n };\n return map[ext] ?? 'application/octet-stream';\n}\n\n// ── Audio Rewriting ────────────────────────────────────────────────\n\n/**\n * Rewrite audio segment URLs in a Doc if an audio map is provided.\n * Returns a shallow-modified copy — does not mutate the original.\n */\nfunction rewriteAudioUrls(doc: Doc, audioMap: Record<string, string>): Doc {\n if (!doc.audio?.segments?.length) return doc;\n\n const segments = doc.audio.segments.map((seg) => {\n const resolved = audioMap[seg.name] ?? audioMap[seg.src] ?? seg.src;\n return { ...seg, src: resolved };\n });\n\n return { ...doc, audio: { ...doc.audio, segments } };\n}\n\n// ── Root Tracking ──────────────────────────────────────────────────\n\nconst roots = new WeakMap<Element, Root>();\n\n// ── Public API ─────────────────────────────────────────────────────\n\n/**\n * Mount a SquisqPlayer into a DOM element.\n *\n * @param element - The DOM element to render into\n * @param doc - A Doc object (parsed JSON)\n * @param options - Rendering options\n */\nexport function mount(element: Element, doc: Doc, options: MountOptions = {}): void {\n injectCss();\n\n const {\n mode = 'slideshow',\n basePath = '.',\n images,\n audio,\n autoPlay = false,\n theme,\n renderMode = false,\n captionStyle,\n } = options;\n\n // Rewrite audio URLs if map provided\n const finalDoc = audio ? rewriteAudioUrls(doc, audio) : doc;\n\n // Build the media provider if images are provided\n const mediaProvider = images ? createInlineMediaProvider(images, basePath) : null;\n\n let content: ReturnType<typeof createElement>;\n\n if (mode === 'static') {\n content = createElement(LinearDocView, {\n doc: finalDoc,\n basePath,\n theme,\n });\n } else {\n content = createElement(DocPlayer, {\n script: finalDoc,\n basePath,\n displayMode: 'slideshow',\n autoPlay: renderMode ? false : autoPlay,\n showControls: !renderMode,\n renderMode,\n theme,\n captionsEnabled: !!captionStyle,\n captionStyle: captionStyle ?? 'standard',\n });\n }\n\n // Wrap in MediaContext if provider is available\n if (mediaProvider) {\n content = createElement(MediaContext.Provider, { value: mediaProvider }, content);\n }\n\n // Create or reuse React root\n let root = roots.get(element);\n if (!root) {\n root = createRoot(element);\n roots.set(element, root);\n }\n root.render(content);\n}\n\n/**\n * Mount a static scrollable document view (alias for mount with mode='static').\n */\nexport function mountStatic(\n element: Element,\n doc: Doc,\n options: Omit<MountOptions, 'mode'> = {},\n): void {\n mount(element, doc, { ...options, mode: 'static' });\n}\n\n/**\n * Unmount a previously mounted SquisqPlayer from an element.\n */\nexport function unmount(element: Element): void {\n const root = roots.get(element);\n if (root) {\n root.unmount();\n roots.delete(element);\n }\n}\n\n/** Package version — injected at build time via esbuild define */\ndeclare const __SQUISQ_VERSION__: string;\nexport const version: string =\n typeof __SQUISQ_VERSION__ !== 'undefined' ? __SQUISQ_VERSION__ : '0.0.0';\n"]}