stormcloud-video-player 0.7.41 → 0.7.42

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":["/home/ubuntu24-new/Dev/stormcloud-vp/lib/ui/OverlayRenderer.cjs","../../src/ui/OverlayRenderer.tsx","../../src/utils/overlays.ts"],"names":["__hasOwnProp","name","__create","Object","create","prototype","hasOwnProperty","__export","target","all","__defProp","get","__copyProps","to","from","except","desc","key","call","enumerable","__getOwnPropDesc","__getOwnPropNames","__toESM","mod","isNodeMode","__getProtoOf","__esModule","value","__toCommonJS","OverlayRenderer_exports","OverlayRenderer","module","exports","import_react","require","OVERLAY_API_BASE","timeStringToSeconds","timeStr","parts","split","length","hours","parseInt","minutes","secStr","dotIdx","indexOf","seconds","substring","msFrag","ms","padEnd","num","parseFloat","isFinite","Math","max","isOverlayActive","overlay","currentTime","visible","startSec","start_time","durationSec","duration","SWIRL_HD_AUTHORING_WIDTH","SWIRL_HD_AUTHORING_HEIGHT","NAB_DEMO_NAME_PREFIX","overlayAuthoringDimensions","decodeWidth","decodeHeight","width","height","extR","x","extB","y","EPS","exceedsDecode","isNabDemo","startsWith","isSyntheticMarketsTicker","id","resolveImageUrl","apiBaseUrl","imageUrl","url","URL","import_jsx_runtime","computeVideoDimensions","video","nativeWidth","videoWidth","nativeHeight","videoHeight","displayWidth","offsetWidth","displayHeight","offsetHeight","videoAspect","displayAspect","renderWidth","renderHeight","offsetX","offsetY","image_url","jsx","content","display","alignItems","justifyContent","fontFamily","fontWeight","textAlign","boxSizing","wordBreak","pointerEvents","userSelect","lineHeight","text","xmlText","maxItems","replace","DOMParser","parser","parseFromString","stripped","Array","doc","querySelectorAll","map","item","querySelector","textContent","trim","i","Error","items","Map","cachedFetchRSSItems","rssUrl","expiresAt","now","cached","promise","fetchRSSItems","catch","err","RSS_CACHE_TTL_MS","encoded","origin","resp","data","encodeURIComponent","window","location","fetch","ok","includes","parseRSSXml","json","contents","ScrollerOverlay","cfg","scroller_config","uid","useId","useState","rssItems","setRssItems","rssLoading","setRssLoading","rssError","setRssError","rss_url","autoRefresh","updateInterval","max_items","auto_refresh","update_interval","useEffect","use_custom_text","custom_text","cancelled","then","finally","interval","setInterval","rssCache","delete","clearInterval","sep","separator_char","segments","show_description","description","push","show_timestamp","pubDate","Date","toLocaleDateString","show_author","author","show_category","category","join","scrollSpeed","scroll_speed","direction","fontSize","font_size","font_family","font_weight","textColor","text_color","bgColor","background_color","bgOpacity","background_opacity","borderRadius","border_radius","itemSpacing","item_spacing","pad","padding","label","labelLine2","label_line2","labelColor","label_color","labelTextColor","label_text_color","accentColor","accent_color","showAccentLine","show_accent_line","isEquitiesStrip","preset","isHorizontal","isReverse","fullText","animId","keyframes","jsxs","Fragment","children","style","flexDirection","overflow","backgroundColor","hexToRgb","color","background","flexShrink","flex","minHeight","gap","round","boxShadow","alignSelf","maxWidth","letterSpacing","textTransform","whiteSpace","opacity","position","minWidth","animation","willChange","copy","paddingRight","seg","React","margin","textShadow","paddingBottom","parseConfig","JSON","parse","ScoreBugOverlay","size","f","w","textOverflow","homeTeam","marginTop","homeScore","period","clock","awayTeam","awayScore","sponsorText","sponsorImageUrl","borderTop","src","alt","objectFit","LowerThirdOverlay","accentH","h"],"mappings":"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","sourcesContent":["\"use strict\";\nvar __create = Object.create;\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __getProtoOf = Object.getPrototypeOf;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(\n // If the importer is in node compatibility mode or this is not an ESM\n // file that has been converted to a CommonJS file using a Babel-\n // compatible transform (i.e. \"__esModule\" has not been set), then set\n // \"default\" to the CommonJS \"module.exports\" for node compatibility.\n isNodeMode || !mod || !mod.__esModule ? __defProp(target, \"default\", { value: mod, enumerable: true }) : target,\n mod\n));\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\n\n// src/ui/OverlayRenderer.tsx\nvar OverlayRenderer_exports = {};\n__export(OverlayRenderer_exports, {\n OverlayRenderer: () => OverlayRenderer\n});\nmodule.exports = __toCommonJS(OverlayRenderer_exports);\nvar import_react = __toESM(require(\"react\"), 1);\n\n// src/utils/overlays.ts\nvar OVERLAY_API_BASE = \"https://adstorm.co/api-adstorm-dev\";\nfunction timeStringToSeconds(timeStr) {\n if (!timeStr) return 0;\n const parts = timeStr.split(\":\");\n if (parts.length >= 3) {\n const hours = parseInt(parts[0] ?? \"0\", 10) || 0;\n const minutes = parseInt(parts[1] ?? \"0\", 10) || 0;\n const secStr = parts[2] ?? \"0\";\n const dotIdx = secStr.indexOf(\".\");\n const seconds = parseInt(dotIdx >= 0 ? secStr.substring(0, dotIdx) : secStr, 10) || 0;\n const msFrag = dotIdx >= 0 ? secStr.substring(dotIdx + 1) : \"\";\n const ms = msFrag ? parseInt(msFrag.padEnd(3, \"0\").substring(0, 3), 10) || 0 : 0;\n return hours * 3600 + minutes * 60 + seconds + ms / 1e3;\n }\n if (parts.length === 2) {\n const minutes = parseInt(parts[0] ?? \"0\", 10) || 0;\n const secStr = parts[1] ?? \"0\";\n const dotIdx = secStr.indexOf(\".\");\n const seconds = parseInt(dotIdx >= 0 ? secStr.substring(0, dotIdx) : secStr, 10) || 0;\n const msFrag = dotIdx >= 0 ? secStr.substring(dotIdx + 1) : \"\";\n const ms = msFrag ? parseInt(msFrag.padEnd(3, \"0\").substring(0, 3), 10) || 0 : 0;\n return minutes * 60 + seconds + ms / 1e3;\n }\n const num = parseFloat(timeStr);\n return isFinite(num) ? Math.max(0, num) : 0;\n}\nfunction isOverlayActive(overlay, currentTime) {\n if (!overlay.visible) return false;\n const startSec = timeStringToSeconds(overlay.start_time);\n const durationSec = timeStringToSeconds(overlay.duration);\n if (durationSec <= 0) return false;\n return currentTime >= startSec && currentTime < startSec + durationSec;\n}\nvar SWIRL_HD_AUTHORING_WIDTH = 1920;\nvar SWIRL_HD_AUTHORING_HEIGHT = 1080;\nvar NAB_DEMO_NAME_PREFIX = \"NAB Demo \\u2014 \";\nfunction overlayAuthoringDimensions(overlay, decodeWidth, decodeHeight) {\n if (!decodeWidth || !decodeHeight) {\n return {\n width: decodeWidth || SWIRL_HD_AUTHORING_WIDTH,\n height: decodeHeight || SWIRL_HD_AUTHORING_HEIGHT\n };\n }\n if (!overlay.visible) {\n return { width: decodeWidth, height: decodeHeight };\n }\n const extR = overlay.x + overlay.width;\n const extB = overlay.y + overlay.height;\n const EPS = 2;\n const exceedsDecode = extR > decodeWidth + EPS || extB > decodeHeight + EPS;\n const isNabDemo = overlay.name.startsWith(NAB_DEMO_NAME_PREFIX);\n const isSyntheticMarketsTicker = overlay.id === -9001 || overlay.name === \"Demo stock ticker\";\n if (exceedsDecode && (isNabDemo || isSyntheticMarketsTicker)) {\n return {\n width: SWIRL_HD_AUTHORING_WIDTH,\n height: SWIRL_HD_AUTHORING_HEIGHT\n };\n }\n return { width: decodeWidth, height: decodeHeight };\n}\nfunction resolveImageUrl(imageUrl, apiBaseUrl = OVERLAY_API_BASE) {\n if (!imageUrl) return \"\";\n if (imageUrl.startsWith(\"http://\") || imageUrl.startsWith(\"https://\")) {\n return imageUrl;\n }\n if (imageUrl.startsWith(\"/\")) {\n try {\n const url = new URL(apiBaseUrl);\n return `${url.origin}${imageUrl}`;\n } catch {\n return imageUrl;\n }\n }\n return `${apiBaseUrl}/${imageUrl}`;\n}\n\n// src/ui/OverlayRenderer.tsx\nvar import_jsx_runtime = require(\"react/jsx-runtime\");\nfunction computeVideoDimensions(video) {\n const nativeWidth = video.videoWidth;\n const nativeHeight = video.videoHeight;\n if (!nativeWidth || !nativeHeight) return null;\n const displayWidth = video.offsetWidth;\n const displayHeight = video.offsetHeight;\n if (!displayWidth || !displayHeight) return null;\n const videoAspect = nativeWidth / nativeHeight;\n const displayAspect = displayWidth / displayHeight;\n let renderWidth;\n let renderHeight;\n let offsetX;\n let offsetY;\n if (videoAspect > displayAspect) {\n renderWidth = displayWidth;\n renderHeight = displayWidth / videoAspect;\n offsetX = 0;\n offsetY = (displayHeight - renderHeight) / 2;\n } else {\n renderHeight = displayHeight;\n renderWidth = displayHeight * videoAspect;\n offsetX = (displayWidth - renderWidth) / 2;\n offsetY = 0;\n }\n return {\n nativeWidth,\n nativeHeight,\n displayWidth: renderWidth,\n displayHeight: renderHeight,\n offsetX,\n offsetY,\n scaleX: renderWidth / nativeWidth,\n scaleY: renderHeight / nativeHeight\n };\n}\nfunction ImageOverlay({ overlay }) {\n const src = resolveImageUrl(overlay.image_url || \"\");\n if (!src) return null;\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"img\",\n {\n src,\n alt: overlay.name,\n draggable: false,\n style: {\n width: \"100%\",\n height: \"100%\",\n objectFit: \"contain\",\n display: \"block\",\n pointerEvents: \"none\",\n userSelect: \"none\"\n }\n }\n );\n}\nfunction TextOverlay({ overlay }) {\n const text = overlay.content || \"\";\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: \"#ffffff\",\n fontSize: \"clamp(10px, 1.4vw, 20px)\",\n fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\",\n fontWeight: 600,\n textAlign: \"center\",\n padding: \"4px 8px\",\n boxSizing: \"border-box\",\n wordBreak: \"break-word\",\n textShadow: \"0 1px 4px rgba(0,0,0,0.7)\",\n pointerEvents: \"none\",\n userSelect: \"none\",\n lineHeight: 1.3\n },\n children: text\n }\n );\n}\nfunction parseRSSXml(xmlText, maxItems) {\n const stripped = xmlText.replace(/^<\\?xml[^?]*\\?>\\s*/, \"\");\n const parser = new DOMParser();\n const doc = parser.parseFromString(stripped, \"text/xml\");\n const items = Array.from(doc.querySelectorAll(\"item\")).map((item) => ({\n title: (item.querySelector(\"title\")?.textContent || \"\").replace(/<[^>]*>/g, \"\").trim(),\n description: (item.querySelector(\"description\")?.textContent || \"\").replace(/<[^>]*>/g, \"\").trim(),\n pubDate: item.querySelector(\"pubDate\")?.textContent || \"\",\n author: item.querySelector(\"author, dc\\\\:creator\")?.textContent || \"\",\n category: item.querySelector(\"category\")?.textContent || \"\"\n })).filter((i) => i.title).slice(0, maxItems);\n if (items.length === 0 && doc.querySelector(\"parsererror\")) {\n throw new Error(\"Invalid RSS XML\");\n }\n return items;\n}\nvar RSS_CACHE_TTL_MS = 6e4;\nvar rssCache = /* @__PURE__ */ new Map();\nfunction cachedFetchRSSItems(rssUrl, maxItems) {\n const now = Date.now();\n const cached = rssCache.get(rssUrl);\n if (cached && cached.expiresAt > now) return cached.promise;\n const promise = fetchRSSItems(rssUrl, maxItems).catch((err) => {\n rssCache.delete(rssUrl);\n throw err;\n });\n rssCache.set(rssUrl, { promise, expiresAt: now + RSS_CACHE_TTL_MS });\n return promise;\n}\nasync function fetchRSSItems(rssUrl, maxItems) {\n const encoded = encodeURIComponent(rssUrl);\n try {\n const origin = typeof window !== \"undefined\" ? window.location.origin : \"\";\n const resp = await fetch(`${origin}/api/rss-proxy?url=${encoded}`);\n if (resp.ok) {\n const text = await resp.text();\n if (text.includes(\"<item\")) return parseRSSXml(text, maxItems);\n }\n } catch {\n }\n try {\n const resp = await fetch(`https://api.allorigins.win/get?url=${encoded}`);\n if (resp.ok) {\n const data = await resp.json();\n if (data.contents) return parseRSSXml(data.contents, maxItems);\n }\n } catch {\n }\n try {\n const resp = await fetch(`https://corsproxy.io/?url=${encoded}`);\n if (resp.ok) {\n const text = await resp.text();\n if (text) return parseRSSXml(text, maxItems);\n }\n } catch {\n }\n throw new Error(\"All RSS proxies failed\");\n}\nfunction ScrollerOverlay({ overlay }) {\n const cfg = overlay.scroller_config;\n const uid = (0, import_react.useId)().replace(/:/g, \"\");\n const [rssItems, setRssItems] = (0, import_react.useState)([]);\n const [rssLoading, setRssLoading] = (0, import_react.useState)(true);\n const [rssError, setRssError] = (0, import_react.useState)(false);\n const rssUrl = cfg?.rss_url || \"\";\n const maxItems = cfg?.max_items ?? 10;\n const autoRefresh = cfg?.auto_refresh !== false;\n const updateInterval = cfg?.update_interval ?? 5;\n (0, import_react.useEffect)(() => {\n if (!rssUrl || cfg?.use_custom_text && cfg?.custom_text) {\n setRssLoading(false);\n return;\n }\n let cancelled = false;\n setRssLoading(true);\n setRssError(false);\n cachedFetchRSSItems(rssUrl, maxItems).then((items) => {\n if (!cancelled) {\n setRssItems(items);\n setRssError(false);\n }\n }).catch(() => {\n if (!cancelled) setRssError(true);\n }).finally(() => {\n if (!cancelled) setRssLoading(false);\n });\n return () => {\n cancelled = true;\n };\n }, [rssUrl, maxItems, cfg?.use_custom_text, cfg?.custom_text]);\n (0, import_react.useEffect)(() => {\n if (!rssUrl || !autoRefresh || cfg?.use_custom_text && cfg?.custom_text) return;\n const interval = setInterval(() => {\n rssCache.delete(rssUrl);\n cachedFetchRSSItems(rssUrl, maxItems).then((items) => {\n setRssItems(items);\n setRssError(false);\n }).catch(() => {\n });\n }, updateInterval * 60 * 1e3);\n return () => clearInterval(interval);\n }, [rssUrl, autoRefresh, updateInterval, maxItems, cfg?.use_custom_text, cfg?.custom_text]);\n const sep = cfg?.separator_char ?? \"\\u25C6\";\n let segments;\n if (cfg?.use_custom_text && cfg?.custom_text) {\n segments = [cfg.custom_text];\n } else if (rssItems.length > 0) {\n segments = rssItems.map((item) => {\n const parts = [];\n if (cfg?.show_title !== false && item.title) parts.push(item.title);\n if (cfg?.show_description && item.description) parts.push(item.description);\n if (cfg?.show_timestamp && item.pubDate) {\n try {\n parts.push(new Date(item.pubDate).toLocaleDateString());\n } catch {\n }\n }\n if (cfg?.show_author && item.author) parts.push(`\\u2014 ${item.author}`);\n if (cfg?.show_category && item.category) parts.push(`[${item.category}]`);\n return parts.join(\" \");\n });\n } else if (rssLoading) {\n segments = [\"Loading feed\\u2026\"];\n } else if (rssError) {\n segments = overlay.content ? [overlay.content] : [\"RSS feed unavailable\"];\n } else if (overlay.content) {\n segments = [overlay.content];\n } else {\n segments = rssUrl ? [\"Loading feed\\u2026\"] : [\"RSS Ticker\"];\n }\n const scrollSpeed = cfg?.scroll_speed ?? 40;\n const direction = cfg?.direction ?? \"left\";\n const fontSize = cfg?.font_size ?? 15;\n const fontFamily = cfg?.font_family || \"Roboto, 'Segoe UI', Arial, sans-serif\";\n const fontWeight = cfg?.font_weight || \"700\";\n const textColor = cfg?.text_color || \"#ffffff\";\n const bgColor = cfg?.background_color || \"#0d0d1a\";\n const bgOpacity = cfg?.background_opacity !== void 0 ? cfg.background_opacity / 100 : 0.95;\n const borderRadius = cfg?.border_radius ?? 0;\n const itemSpacing = cfg?.item_spacing ?? 60;\n const pad = cfg?.padding !== void 0 && cfg.padding >= 0 ? cfg.padding : 8;\n const label = cfg?.label ?? \"NEWS\";\n const labelLine2 = cfg?.label_line2 ?? \"\";\n const labelColor = cfg?.label_color ?? \"#f97316\";\n const labelTextColor = cfg?.label_text_color ?? \"#ffffff\";\n const accentColor = cfg?.accent_color ?? labelColor;\n const showAccentLine = cfg?.show_accent_line !== false;\n const isEquitiesStrip = cfg?.preset === \"equities_strip\";\n const isHorizontal = direction === \"left\" || direction === \"right\";\n const isReverse = direction === \"right\" || direction === \"down\";\n const fullText = segments.join(` ${sep} `);\n const durationSec = Math.max(6, fullText.length * 9 / scrollSpeed);\n const animId = `sc-ticker-${overlay.id}-${uid}`;\n const keyframes = isHorizontal ? `@keyframes ${animId} {\n ${isReverse ? \"0% { transform: translateX(-50%); } 100% { transform: translateX(0%); }\" : \"0% { transform: translateX(0); } 100% { transform: translateX(-50%); }\"}\n }` : `@keyframes ${animId} {\n ${isReverse ? \"0% { transform: translateY(-50%); } 100% { transform: translateY(0%); }\" : \"0% { transform: translateY(0); } 100% { transform: translateY(-50%); }\"}\n }`;\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"style\", { children: keyframes }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n overflow: \"hidden\",\n borderRadius: borderRadius > 0 ? `${borderRadius}px` : void 0,\n backgroundColor: `rgba(${hexToRgb(bgColor)}, ${bgOpacity})`,\n fontFamily,\n fontSize: `${fontSize}px`,\n fontWeight,\n color: textColor,\n pointerEvents: \"none\",\n userSelect: \"none\"\n },\n children: [\n showAccentLine && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n height: isEquitiesStrip ? 2 : 3,\n background: accentColor,\n flexShrink: 0,\n width: \"100%\"\n }\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n display: \"flex\",\n flex: 1,\n overflow: \"hidden\",\n minHeight: 0,\n alignItems: \"center\",\n padding: isEquitiesStrip ? `${Math.max(2, pad * 0.5)}px ${pad}px` : `${Math.max(4, pad * 0.75)}px ${pad}px`,\n gap: isEquitiesStrip ? Math.max(4, Math.round(pad * 0.75)) : Math.max(6, pad),\n boxSizing: \"border-box\"\n },\n children: [\n label && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n background: labelColor,\n color: labelTextColor,\n padding: isEquitiesStrip ? \"6px 12px\" : \"10px 14px\",\n display: \"flex\",\n flexDirection: isEquitiesStrip ? \"row\" : \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n textAlign: \"center\",\n gap: isEquitiesStrip ? 0 : 2,\n borderRadius: Math.max(2, borderRadius > 0 ? borderRadius : 6),\n boxShadow: isEquitiesStrip ? \"inset 0 1px 0 rgba(255,255,255,0.08)\" : \"0 2px 8px rgba(0,0,0,0.35)\",\n alignSelf: \"stretch\",\n maxWidth: isEquitiesStrip ? \"min(200px, 28%)\" : void 0\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"span\",\n {\n style: {\n fontWeight: isEquitiesStrip ? 700 : 800,\n fontSize: isEquitiesStrip ? \"0.82em\" : \"0.78em\",\n letterSpacing: isEquitiesStrip ? \"0.04em\" : \"0.08em\",\n lineHeight: 1.2,\n textTransform: isEquitiesStrip ? \"none\" : \"uppercase\",\n whiteSpace: isEquitiesStrip ? \"normal\" : \"nowrap\",\n textAlign: isEquitiesStrip ? \"left\" : \"center\"\n },\n children: label\n }\n ),\n labelLine2 && !isEquitiesStrip && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"span\",\n {\n style: {\n fontWeight: 600,\n fontSize: \"0.58em\",\n letterSpacing: \"0.06em\",\n lineHeight: 1.15,\n opacity: 0.92,\n whiteSpace: \"nowrap\"\n },\n children: labelLine2\n }\n )\n ]\n }\n ),\n label && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n width: isEquitiesStrip ? 1 : 2,\n alignSelf: \"stretch\",\n minHeight: isEquitiesStrip ? 20 : 24,\n background: accentColor,\n flexShrink: 0,\n borderRadius: 1,\n opacity: 0.85\n }\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n flex: 1,\n overflow: \"hidden\",\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n minWidth: 0\n },\n children: isHorizontal ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n display: \"inline-flex\",\n whiteSpace: \"nowrap\",\n animation: `${animId} ${durationSec}s linear infinite`,\n willChange: \"transform\"\n },\n children: [0, 1].map((copy) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"span\", { style: { paddingRight: `${itemSpacing}px` }, children: segments.map((seg, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react.default.Fragment, { children: [\n i > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"span\", { style: { opacity: 0.5, margin: \"0 8px\" }, children: sep }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"span\", { style: { textShadow: \"0 1px 3px rgba(0,0,0,0.6)\" }, children: seg })\n ] }, i)) }, copy))\n }\n ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n display: \"flex\",\n flexDirection: \"column\",\n whiteSpace: \"nowrap\",\n animation: `${animId} ${durationSec}s linear infinite`,\n willChange: \"transform\"\n },\n children: [0, 1].map(\n (copy) => segments.map((seg, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { paddingBottom: `${itemSpacing / 4}px` }, children: seg }, `${copy}-${i}`))\n )\n }\n )\n }\n )\n ]\n }\n )\n ]\n }\n )\n ] });\n}\nfunction parseConfig(content) {\n if (!content) return null;\n try {\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\nfunction ScoreBugOverlay({ overlay, size }) {\n const cfg = parseConfig(overlay.content);\n if (!cfg) return null;\n const f = Math.max(6, size.w * 0.052);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n width: \"100%\",\n height: \"100%\",\n borderRadius: Math.max(2, size.w * 0.028),\n display: \"flex\",\n flexDirection: \"column\",\n background: cfg.backgroundColor,\n color: cfg.textColor,\n fontFamily: \"'Inter', 'Roboto', 'Segoe UI', system-ui, sans-serif\",\n overflow: \"hidden\",\n pointerEvents: \"none\",\n userSelect: \"none\",\n fontSize: `${f}px`,\n boxShadow: \"0 8px 28px rgba(0,0,0,0.45)\"\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n flex: 1,\n display: \"flex\",\n alignItems: \"center\",\n padding: `${f * 0.42}px ${f * 0.85}px`,\n gap: f * 0.45,\n minHeight: 0\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { flex: 1, textAlign: \"center\", minWidth: 0, padding: `0 ${f * 0.15}px` }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n fontSize: \"1.05em\",\n fontWeight: 800,\n letterSpacing: \"0.02em\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\"\n },\n children: cfg.homeTeam\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1.75em\", fontWeight: 900, lineHeight: 1.05, marginTop: f * 0.08 }, children: cfg.homeScore })\n ] }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n fontSize: \"0.88em\",\n textAlign: \"center\",\n fontWeight: 600,\n opacity: 0.92,\n color: cfg.textColor,\n padding: `0 ${f * 0.5}px`,\n flexShrink: 0,\n lineHeight: 1.25,\n textTransform: \"uppercase\",\n letterSpacing: \"0.04em\"\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { children: cfg.period }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontWeight: 700, opacity: 1 }, children: cfg.clock })\n ]\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { flex: 1, textAlign: \"center\", minWidth: 0, padding: `0 ${f * 0.15}px` }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n fontSize: \"1.05em\",\n fontWeight: 800,\n letterSpacing: \"0.02em\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\"\n },\n children: cfg.awayTeam\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1.75em\", fontWeight: 900, lineHeight: 1.05, marginTop: f * 0.08 }, children: cfg.awayScore })\n ] })\n ]\n }\n ),\n (cfg.sponsorText || cfg.sponsorImageUrl) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n fontSize: \"0.72em\",\n textAlign: \"center\",\n fontWeight: 600,\n opacity: 0.88,\n padding: `${f * 0.34}px ${f * 0.55}px`,\n borderTop: `1px solid ${cfg.accentColor}55`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: f * 0.45,\n overflow: \"hidden\",\n letterSpacing: \"0.04em\",\n textTransform: \"uppercase\",\n background: `linear-gradient(180deg, rgba(0,0,0,0.12) 0%, rgba(0,0,0,0.22) 100%)`\n },\n children: [\n cfg.sponsorImageUrl && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"img\", { src: cfg.sponsorImageUrl, alt: \"sponsor\", style: { height: `${f * 1.35}px`, objectFit: \"contain\", flexShrink: 0 } }),\n cfg.sponsorText && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"span\", { style: { overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }, children: cfg.sponsorText })\n ]\n }\n )\n ]\n }\n );\n}\nfunction LowerThirdOverlay({ overlay, size }) {\n const cfg = parseConfig(overlay.content);\n if (!cfg) return null;\n const f = Math.max(6, size.w * 0.05);\n const accentH = Math.max(3, size.h * 0.038);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n width: \"100%\",\n height: \"100%\",\n borderRadius: Math.max(2, size.w * 0.018),\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"flex-end\",\n background: cfg.backgroundColor,\n color: cfg.textColor,\n fontFamily: \"'Inter', 'Roboto', 'Segoe UI', system-ui, sans-serif\",\n overflow: \"hidden\",\n pointerEvents: \"none\",\n userSelect: \"none\",\n fontSize: `${f}px`,\n boxShadow: \"0 10px 32px rgba(0,0,0,0.4)\"\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { width: \"100%\", height: accentH, backgroundColor: cfg.accentColor, flexShrink: 0 } }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n flex: 1,\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n padding: `${f * 0.62}px ${f * 1.05}px`,\n minHeight: 0,\n gap: f * 0.18\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n fontSize: \"1.28em\",\n fontWeight: 800,\n lineHeight: 1.22,\n letterSpacing: \"0.01em\",\n textShadow: \"0 2px 6px rgba(0,0,0,0.55)\"\n },\n children: cfg.headline\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n fontSize: \"0.94em\",\n fontWeight: 500,\n opacity: 0.92,\n lineHeight: 1.35,\n color: cfg.textColor\n },\n children: cfg.subtitle\n }\n )\n ]\n }\n ),\n (cfg.sponsorText || cfg.sponsorImageUrl) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n fontSize: \"0.68em\",\n fontWeight: 600,\n opacity: 0.72,\n padding: `${f * 0.28}px ${f * 1.05}px ${f * 0.48}px`,\n display: \"flex\",\n alignItems: \"center\",\n gap: f * 0.4,\n overflow: \"hidden\",\n letterSpacing: \"0.06em\",\n textTransform: \"uppercase\",\n borderTop: `1px solid rgba(255,255,255,0.08)`\n },\n children: [\n cfg.sponsorImageUrl && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"img\", { src: cfg.sponsorImageUrl, alt: \"sponsor\", style: { height: `${f * 1.25}px`, objectFit: \"contain\", flexShrink: 0 } }),\n cfg.sponsorText && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"span\", { style: { overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }, children: cfg.sponsorText })\n ]\n }\n )\n ]\n }\n );\n}\nfunction QrCodeOverlay({ overlay, size }) {\n const cfg = parseConfig(overlay.content);\n if (!cfg) return null;\n const qrSide = Math.max(32, Math.min(size.w, size.h) * 0.55);\n const qrUrl = `https://api.qrserver.com/v1/create-qr-code/?size=${Math.round(qrSide * 2)}x${Math.round(qrSide * 2)}&data=${encodeURIComponent(cfg.url || \"https://example.com\")}`;\n const f = Math.max(6, size.w * 0.06);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", flexDirection: \"column\", alignItems: \"center\", justifyContent: \"center\", gap: f * 0.4, background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", padding: f * 0.6, boxSizing: \"border-box\", pointerEvents: \"none\", userSelect: \"none\", overflow: \"hidden\" }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { flexShrink: 0, background: \"#fff\", borderRadius: Math.max(2, qrSide * 0.06), padding: Math.max(2, qrSide * 0.06), lineHeight: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"img\", { src: qrUrl, alt: \"QR Code\", style: { width: `${qrSide}px`, height: `${qrSide}px`, display: \"block\" } }) }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: `${f * 1.1}px`, fontWeight: 700, textAlign: \"center\", color: cfg.accentColor, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", width: \"100%\" }, children: cfg.ctaText }),\n cfg.description && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: `${f * 0.75}px`, opacity: 0.6, textAlign: \"center\", overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", width: \"100%\" }, children: cfg.description })\n ] });\n}\nfunction ComingUpNextOverlay({ overlay, size }) {\n const cfg = parseConfig(overlay.content);\n if (!cfg) return null;\n const f = Math.max(8, Math.min(size.h * 0.13, size.w * 0.048));\n const showSubtitle = size.h >= 60;\n const showThumbnail = false;\n const thumbW = 0;\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: {\n width: \"100%\",\n height: \"100%\",\n borderRadius: Math.max(2, size.w * 0.025),\n display: \"flex\",\n background: cfg.backgroundColor,\n color: cfg.textColor,\n fontFamily: \"'Arial', 'Helvetica Neue', Helvetica, sans-serif\",\n overflow: \"hidden\",\n pointerEvents: \"none\",\n userSelect: \"none\",\n fontSize: `${f}px`,\n WebkitFontSmoothing: \"antialiased\"\n }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { width: Math.max(3, size.w * 0.018), flexShrink: 0, backgroundColor: cfg.accentColor } }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: {\n flex: 1,\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n padding: `${f * 0.35}px ${f * 0.75}px`,\n minWidth: 0,\n gap: `${f * 0.08}px`\n }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: {\n fontSize: \"0.7em\",\n fontWeight: 700,\n textTransform: \"uppercase\",\n letterSpacing: \"0.09em\",\n color: cfg.accentColor,\n lineHeight: 1\n }, children: \"Coming Up Next\" }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: {\n fontSize: \"1.2em\",\n fontWeight: 700,\n lineHeight: 1.2,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\"\n }, children: cfg.title }),\n showSubtitle && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: {\n fontSize: \"0.82em\",\n opacity: 0.65,\n lineHeight: 1.1,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\"\n }, children: cfg.subtitle }),\n cfg.scheduledTime && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: {\n fontSize: \"0.9em\",\n fontWeight: 700,\n color: cfg.accentColor,\n lineHeight: 1\n }, children: cfg.scheduledTime })\n ] }),\n showThumbnail && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { flexShrink: 0, width: `${thumbW}px`, overflow: \"hidden\" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"img\",\n {\n src: cfg.thumbnailUrl,\n alt: \"\",\n style: { width: \"100%\", height: \"100%\", objectFit: \"cover\", display: \"block\" }\n }\n ) })\n ] });\n}\nfunction ContextualTriggerOverlay({ overlay, size }) {\n const cfg = parseConfig(overlay.content);\n if (!cfg) return null;\n const icons = { alert: \"\\u26A0\\uFE0F\", celebration: \"\\u{1F389}\", info: \"\\u2139\\uFE0F\", warning: \"\\u{1F514}\" };\n const f = Math.max(6, size.w * 0.05);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", alignItems: \"center\", gap: f * 0.8, padding: `0 ${f * 1.2}px`, background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", borderLeft: `${Math.max(2, size.w * 0.02)}px solid ${cfg.accentColor}`, boxSizing: \"border-box\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"span\", { style: { fontSize: \"2em\", flexShrink: 0 }, children: icons[cfg.iconType] || \"\\u26A1\" }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { flex: 1, minWidth: 0 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1.3em\", fontWeight: 700, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }, children: cfg.headline }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.9em\", opacity: 0.7, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }, children: cfg.message })\n ] })\n ] });\n}\nfunction OddsBettingOverlay({ overlay, size }) {\n const cfg = parseConfig(overlay.content);\n if (!cfg) return null;\n const f = Math.max(6, size.w * 0.052);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", flexDirection: \"column\", padding: f * 0.8, background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", boxSizing: \"border-box\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.9em\", fontWeight: 700, textTransform: \"uppercase\", letterSpacing: \"0.05em\", color: cfg.accentColor, marginBottom: f * 0.4 }, children: cfg.eventTitle }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { flex: 1, display: \"flex\", flexDirection: \"column\", gap: f * 0.2, justifyContent: \"center\" }, children: (cfg.options || []).slice(0, 5).map((opt, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { display: \"flex\", justifyContent: \"space-between\", alignItems: \"center\", padding: `${f * 0.2}px ${f * 0.6}px`, borderRadius: Math.max(2, f * 0.3), background: `${cfg.accentColor}15`, fontSize: \"1em\" }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"span\", { style: { overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", flex: 1 }, children: opt.label }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"span\", { style: { fontWeight: 700, marginLeft: f * 0.8, flexShrink: 0, color: cfg.accentColor }, children: opt.odds })\n ] }, i)) }),\n cfg.sponsorText && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.7em\", opacity: 0.4, textAlign: \"center\", marginTop: f * 0.4 }, children: cfg.sponsorText })\n ] });\n}\nfunction BreakingNewsOverlay({ overlay, size }) {\n const cfg = parseConfig(overlay.content);\n if (!cfg) return null;\n const urgencyColors = { breaking: \"#dc2626\", urgent: \"#ea580c\", normal: \"#2563eb\" };\n const labelBg = urgencyColors[cfg.urgency] || urgencyColors.normal;\n const label = cfg.urgency === \"breaking\" ? \"BREAKING\" : cfg.urgency === \"urgent\" ? \"URGENT\" : \"NEWS\";\n const f = Math.max(6, size.w * 0.05);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.02), display: \"flex\", alignItems: \"center\", background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", overflow: \"hidden\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { padding: `0 ${f * 0.8}px`, height: \"100%\", display: \"flex\", alignItems: \"center\", background: labelBg, color: \"#fff\", fontSize: \"1em\", fontWeight: 900, textTransform: \"uppercase\", letterSpacing: \"0.05em\", flexShrink: 0 }, children: label }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { flex: 1, padding: `0 ${f * 1}px`, minWidth: 0 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1.3em\", fontWeight: 700, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }, children: cfg.headline }),\n cfg.body && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.9em\", opacity: 0.7, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }, children: cfg.body })\n ] })\n ] });\n}\nfunction calcCountdownRemaining(targetTime) {\n const diff = Math.max(0, new Date(targetTime).getTime() - Date.now());\n return {\n d: Math.floor(diff / 864e5),\n h: Math.floor(diff % 864e5 / 36e5),\n m: Math.floor(diff % 36e5 / 6e4),\n s: Math.floor(diff % 6e4 / 1e3),\n expired: diff === 0\n };\n}\nfunction CountdownOverlay({ overlay, size }) {\n const cfg = parseConfig(overlay.content);\n const targetTime = cfg?.targetTime ?? \"\";\n const [remaining, setRemaining] = (0, import_react.useState)(\n () => targetTime ? calcCountdownRemaining(targetTime) : { d: 0, h: 0, m: 0, s: 0, expired: false }\n );\n (0, import_react.useEffect)(() => {\n if (!targetTime) return;\n setRemaining(calcCountdownRemaining(targetTime));\n const id = setInterval(() => setRemaining(calcCountdownRemaining(targetTime)), 1e3);\n return () => clearInterval(id);\n }, [targetTime]);\n if (!cfg) return null;\n const f = Math.max(6, size.w * 0.055);\n const pad = (n) => String(n).padStart(2, \"0\");\n const units = [\n { show: cfg.showDays, value: pad(remaining.d), label: \"DAYS\" },\n { show: cfg.showHours, value: pad(remaining.h), label: \"HRS\" },\n { show: cfg.showMinutes, value: pad(remaining.m), label: \"MIN\" },\n { show: cfg.showSeconds, value: pad(remaining.s), label: \"SEC\" }\n ];\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", flexDirection: \"column\", alignItems: \"center\", justifyContent: \"center\", padding: f * 0.8, background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", boxSizing: \"border-box\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.8em\", fontWeight: 600, textTransform: \"uppercase\", letterSpacing: \"0.05em\", color: cfg.accentColor, marginBottom: f * 0.4 }, children: cfg.eventName }),\n remaining.expired ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1em\", fontWeight: 700, opacity: 0.6 }, children: cfg.message || \"Event ended\" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { display: \"flex\", gap: f * 0.6, alignItems: \"center\" }, children: units.filter((u) => u.show).map((u, i, arr) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react.default.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { textAlign: \"center\" }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"2em\", fontWeight: 900, lineHeight: 1, borderRadius: Math.max(2, f * 0.4), padding: `${f * 0.2}px ${f * 0.4}px`, background: `${cfg.accentColor}20` }, children: u.value }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.5em\", opacity: 0.5, marginTop: f * 0.2 }, children: u.label })\n ] }),\n i < arr.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1.8em\", fontWeight: 700, opacity: 0.3 }, children: \":\" })\n ] }, u.label)) }),\n !remaining.expired && cfg.message && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.8em\", opacity: 0.6, marginTop: f * 0.4, textAlign: \"center\" }, children: cfg.message })\n ] });\n}\nfunction ShapeOverlay({ overlay, size }) {\n const f = Math.max(6, size.w * 0.05);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.03), background: \"rgba(99, 102, 241, 0.2)\", border: \"2px solid rgba(99, 102, 241, 0.4)\", display: \"flex\", alignItems: \"center\", justifyContent: \"center\", pointerEvents: \"none\", userSelect: \"none\" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: `${f}px`, fontWeight: 500, color: \"rgba(163, 163, 163, 0.8)\", textTransform: \"uppercase\" }, children: overlay.name }) });\n}\nfunction hexToRgb(hex) {\n if (!hex || !hex.startsWith(\"#\")) return \"0,0,0\";\n const clean = hex.slice(1);\n const num = parseInt(clean.length === 3 ? clean.replace(/./g, \"$&$&\") : clean, 16);\n return `${num >> 16 & 255},${num >> 8 & 255},${num & 255}`;\n}\nvar FADE_DURATION_MS = 1e3;\nvar SHOWCASE_CYCLE_MS_DEFAULT = 6e4;\nvar SHOWCASE_POP_IN_MS = 420;\nvar SHOWCASE_STEADY_END_MS = 46e3;\nvar SHOWCASE_POP_OUT_MS = 450;\nvar SHOWCASE_POP_OUT_END_MS = SHOWCASE_STEADY_END_MS + SHOWCASE_POP_OUT_MS;\nfunction easeOutCubic(t) {\n const u = 1 - t;\n return 1 - u * u * u;\n}\nfunction easeInCubic(t) {\n return t * t * t;\n}\nfunction easeOutBack(t) {\n const c1 = 1.70158;\n const c3 = c1 + 1;\n return 1 + c3 * (t - 1) ** 3 + c1 * (t - 1) ** 2;\n}\nfunction showcaseOpacity(phase) {\n if (phase < SHOWCASE_POP_IN_MS) return easeOutCubic(phase / SHOWCASE_POP_IN_MS);\n if (phase >= SHOWCASE_STEADY_END_MS && phase < SHOWCASE_POP_OUT_END_MS) {\n return 1 - easeInCubic((phase - SHOWCASE_STEADY_END_MS) / SHOWCASE_POP_OUT_MS);\n }\n return 1;\n}\nfunction showcaseScale(phase) {\n if (phase < SHOWCASE_POP_IN_MS) {\n return Math.min(\n 1,\n 0.78 + 0.22 * easeOutBack(phase / SHOWCASE_POP_IN_MS)\n );\n }\n if (phase >= SHOWCASE_STEADY_END_MS && phase < SHOWCASE_POP_OUT_END_MS) {\n return 1 - 0.14 * easeInCubic((phase - SHOWCASE_STEADY_END_MS) / SHOWCASE_POP_OUT_MS);\n }\n return 1;\n}\nfunction useShowcasePhase(enabled, cycleMs) {\n const [phase, setPhase] = (0, import_react.useState)(0);\n (0, import_react.useEffect)(() => {\n if (!enabled) return;\n setPhase(Date.now() % cycleMs);\n const id = window.setInterval(() => {\n setPhase(Date.now() % cycleMs);\n }, 48);\n return () => clearInterval(id);\n }, [enabled, cycleMs]);\n return phase;\n}\nvar OverlayRenderer = ({\n overlays,\n currentTime,\n videoRef,\n coordinateSpace,\n showcaseMode = false,\n showcaseCycleMs = SHOWCASE_CYCLE_MS_DEFAULT\n}) => {\n const [dims, setDims] = (0, import_react.useState)(null);\n const rafRef = (0, import_react.useRef)(null);\n const [fadeMap, setFadeMap] = (0, import_react.useState)(/* @__PURE__ */ new Map());\n const removeTimers = (0, import_react.useRef)(/* @__PURE__ */ new Map());\n const showcasePhase = useShowcasePhase(showcaseMode, showcaseCycleMs);\n const updateDims = (0, import_react.useCallback)(() => {\n const video = videoRef.current;\n if (video) {\n const computed = computeVideoDimensions(video);\n setDims((prev) => {\n if (!computed || prev && prev.nativeWidth === computed.nativeWidth && prev.nativeHeight === computed.nativeHeight && prev.displayWidth === computed.displayWidth && prev.displayHeight === computed.displayHeight && prev.offsetX === computed.offsetX && prev.offsetY === computed.offsetY) {\n return prev;\n }\n return computed;\n });\n }\n }, [videoRef]);\n (0, import_react.useEffect)(() => {\n updateDims();\n const interval = setInterval(updateDims, 500);\n const handleResize = () => {\n if (rafRef.current) cancelAnimationFrame(rafRef.current);\n rafRef.current = requestAnimationFrame(updateDims);\n };\n window.addEventListener(\"resize\", handleResize);\n return () => {\n clearInterval(interval);\n window.removeEventListener(\"resize\", handleResize);\n if (rafRef.current) cancelAnimationFrame(rafRef.current);\n };\n }, [updateDims]);\n const activeOverlays = (0, import_react.useMemo)(() => {\n if (showcaseMode) {\n return overlays.filter((o) => {\n if (!o.visible) return false;\n return showcasePhase < SHOWCASE_POP_OUT_END_MS;\n });\n }\n return overlays.filter((o) => isOverlayActive(o, currentTime));\n }, [overlays, currentTime, showcaseMode, showcasePhase]);\n const activeBeatIds = (0, import_react.useMemo)(\n () => new Set(activeOverlays.map((o) => o.id)),\n [activeOverlays]\n );\n (0, import_react.useLayoutEffect)(() => {\n const activeIds = new Set(activeOverlays.map((o) => o.id));\n setFadeMap((prev) => {\n const next = new Map(prev);\n for (const overlay of activeOverlays) {\n if (!next.has(overlay.id)) {\n next.set(overlay.id, { overlay, visible: false });\n } else {\n const existing = next.get(overlay.id);\n next.set(overlay.id, { ...existing, overlay });\n }\n }\n for (const [id, state] of next) {\n if (!activeIds.has(id) && state.visible) {\n next.set(id, { ...state, visible: false });\n if (!removeTimers.current.has(id)) {\n const timer = setTimeout(() => {\n setFadeMap((m) => {\n const updated = new Map(m);\n updated.delete(id);\n return updated;\n });\n removeTimers.current.delete(id);\n }, FADE_DURATION_MS);\n removeTimers.current.set(id, timer);\n }\n } else if (!activeIds.has(id) && !state.visible) {\n }\n }\n return next;\n });\n }, [activeOverlays]);\n (0, import_react.useEffect)(() => {\n const toFadeIn = [];\n for (const [id, state] of fadeMap) {\n if (!state.visible) {\n const isActive = activeOverlays.some((o) => o.id === id);\n if (isActive) toFadeIn.push(id);\n }\n }\n if (toFadeIn.length === 0) return;\n const raf = requestAnimationFrame(() => {\n setFadeMap((prev) => {\n const next = new Map(prev);\n for (const id of toFadeIn) {\n const state = next.get(id);\n if (state) next.set(id, { ...state, visible: true });\n }\n return next;\n });\n });\n return () => cancelAnimationFrame(raf);\n }, [fadeMap, activeOverlays]);\n (0, import_react.useEffect)(() => {\n return () => {\n for (const timer of removeTimers.current.values()) clearTimeout(timer);\n };\n }, []);\n if (!dims || fadeMap.size === 0) return null;\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n \"aria-hidden\": \"true\",\n style: {\n position: \"absolute\",\n left: `${dims.offsetX}px`,\n top: `${dims.offsetY}px`,\n width: `${dims.displayWidth}px`,\n height: `${dims.displayHeight}px`,\n pointerEvents: \"none\",\n overflow: \"hidden\",\n zIndex: 8\n },\n children: [...fadeMap.values()].map(({ overlay, visible }) => {\n const uniform = coordinateSpace && coordinateSpace.width > 0 && coordinateSpace.height > 0;\n const auth = uniform ? { width: coordinateSpace.width, height: coordinateSpace.height } : overlayAuthoringDimensions(\n overlay,\n dims.nativeWidth,\n dims.nativeHeight\n );\n const scaleX = dims.displayWidth / auth.width;\n const scaleY = dims.displayHeight / auth.height;\n const left = overlay.x * scaleX;\n const top = overlay.y * scaleY;\n const width = overlay.width * scaleX;\n const height = overlay.height * scaleY;\n const baseOpacity = Math.max(0, Math.min(100, overlay.opacity)) / 100;\n const inShowcaseBeat = showcaseMode && activeBeatIds.has(overlay.id);\n const useShowcasePop = inShowcaseBeat;\n const opacity = useShowcasePop ? baseOpacity * showcaseOpacity(showcasePhase) : visible ? baseOpacity : 0;\n const popScale = useShowcasePop ? showcaseScale(showcasePhase) : 1;\n const sz = { w: width, h: height };\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n left: `${left}px`,\n top: `${top}px`,\n width: `${width}px`,\n height: `${height}px`,\n opacity,\n transition: useShowcasePop ? \"none\" : `opacity ${FADE_DURATION_MS}ms ease`,\n transform: showcaseMode && useShowcasePop ? `scale(${popScale})` : void 0,\n transformOrigin: showcaseMode && useShowcasePop ? \"center center\" : void 0,\n zIndex: overlay.z_index,\n overflow: \"hidden\"\n },\n children: [\n overlay.type === \"image\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ImageOverlay, { overlay }),\n overlay.type === \"text\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TextOverlay, { overlay }),\n overlay.type === \"scroller\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScrollerOverlay, { overlay }),\n overlay.type === \"shape\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ShapeOverlay, { overlay, size: sz }),\n overlay.type === \"score_bug\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScoreBugOverlay, { overlay, size: sz }),\n overlay.type === \"lower_third\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LowerThirdOverlay, { overlay, size: sz }),\n overlay.type === \"qr_code\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(QrCodeOverlay, { overlay, size: sz }),\n overlay.type === \"coming_up_next\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ComingUpNextOverlay, { overlay, size: sz }),\n overlay.type === \"contextual_trigger\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContextualTriggerOverlay, { overlay, size: sz }),\n overlay.type === \"odds_betting\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(OddsBettingOverlay, { overlay, size: sz }),\n overlay.type === \"breaking_news\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BreakingNewsOverlay, { overlay, size: sz }),\n overlay.type === \"countdown\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CountdownOverlay, { overlay, size: sz })\n ]\n },\n overlay.id\n );\n })\n }\n );\n};\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n OverlayRenderer\n});\n","import React, {\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n useCallback,\n useMemo,\n useId,\n} from \"react\";\nimport {\n type SwirlOverlay,\n isOverlayActive,\n resolveImageUrl,\n overlayAuthoringDimensions,\n} from \"../utils/overlays\";\n\ninterface VideoDimensions {\n nativeWidth: number;\n nativeHeight: number;\n displayWidth: number;\n displayHeight: number;\n offsetX: number;\n offsetY: number;\n scaleX: number;\n scaleY: number;\n}\n\ninterface OverlayRendererProps {\n overlays: SwirlOverlay[];\n currentTime: number;\n videoRef: React.RefObject<HTMLVideoElement | null>;\n coordinateSpace?: { width: number; height: number } | null;\n showcaseMode?: boolean;\n showcaseCycleMs?: number;\n}\n\nfunction computeVideoDimensions(\n video: HTMLVideoElement\n): VideoDimensions | null {\n const nativeWidth = video.videoWidth;\n const nativeHeight = video.videoHeight;\n if (!nativeWidth || !nativeHeight) return null;\n\n const displayWidth = video.offsetWidth;\n const displayHeight = video.offsetHeight;\n if (!displayWidth || !displayHeight) return null;\n\n const videoAspect = nativeWidth / nativeHeight;\n const displayAspect = displayWidth / displayHeight;\n\n let renderWidth: number;\n let renderHeight: number;\n let offsetX: number;\n let offsetY: number;\n\n if (videoAspect > displayAspect) {\n renderWidth = displayWidth;\n renderHeight = displayWidth / videoAspect;\n offsetX = 0;\n offsetY = (displayHeight - renderHeight) / 2;\n } else {\n renderHeight = displayHeight;\n renderWidth = displayHeight * videoAspect;\n offsetX = (displayWidth - renderWidth) / 2;\n offsetY = 0;\n }\n\n return {\n nativeWidth,\n nativeHeight,\n displayWidth: renderWidth,\n displayHeight: renderHeight,\n offsetX,\n offsetY,\n scaleX: renderWidth / nativeWidth,\n scaleY: renderHeight / nativeHeight,\n };\n}\n\nfunction ImageOverlay({ overlay }: { overlay: SwirlOverlay }) {\n const src = resolveImageUrl(overlay.image_url || \"\");\n if (!src) return null;\n return (\n <img\n src={src}\n alt={overlay.name}\n draggable={false}\n style={{\n width: \"100%\",\n height: \"100%\",\n objectFit: \"contain\",\n display: \"block\",\n pointerEvents: \"none\",\n userSelect: \"none\",\n }}\n />\n );\n}\n\nfunction TextOverlay({ overlay }: { overlay: SwirlOverlay }) {\n const text = overlay.content || \"\";\n return (\n <div\n style={{\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: \"#ffffff\",\n fontSize: \"clamp(10px, 1.4vw, 20px)\",\n fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\",\n fontWeight: 600,\n textAlign: \"center\",\n padding: \"4px 8px\",\n boxSizing: \"border-box\",\n wordBreak: \"break-word\",\n textShadow: \"0 1px 4px rgba(0,0,0,0.7)\",\n pointerEvents: \"none\",\n userSelect: \"none\",\n lineHeight: 1.3,\n }}\n >\n {text}\n </div>\n );\n}\n\ninterface RSSItem {\n title: string;\n description: string;\n pubDate: string;\n author: string;\n category: string;\n}\n\nfunction parseRSSXml(xmlText: string, maxItems: number): RSSItem[] {\n const stripped = xmlText.replace(/^<\\?xml[^?]*\\?>\\s*/, \"\");\n const parser = new DOMParser();\n const doc = parser.parseFromString(stripped, \"text/xml\");\n const items = Array.from(doc.querySelectorAll(\"item\"))\n .map((item) => ({\n title: (item.querySelector(\"title\")?.textContent || \"\").replace(/<[^>]*>/g, \"\").trim(),\n description: (item.querySelector(\"description\")?.textContent || \"\").replace(/<[^>]*>/g, \"\").trim(),\n pubDate: item.querySelector(\"pubDate\")?.textContent || \"\",\n author: item.querySelector(\"author, dc\\\\:creator\")?.textContent || \"\",\n category: item.querySelector(\"category\")?.textContent || \"\",\n }))\n .filter((i) => i.title)\n .slice(0, maxItems);\n if (items.length === 0 && doc.querySelector(\"parsererror\")) {\n throw new Error(\"Invalid RSS XML\");\n }\n return items;\n}\n\nconst RSS_CACHE_TTL_MS = 60_000;\nconst rssCache = new Map<string, { promise: Promise<RSSItem[]>; expiresAt: number }>();\n\nfunction cachedFetchRSSItems(rssUrl: string, maxItems: number): Promise<RSSItem[]> {\n const now = Date.now();\n const cached = rssCache.get(rssUrl);\n if (cached && cached.expiresAt > now) return cached.promise;\n const promise = fetchRSSItems(rssUrl, maxItems).catch((err) => {\n rssCache.delete(rssUrl);\n throw err;\n });\n rssCache.set(rssUrl, { promise, expiresAt: now + RSS_CACHE_TTL_MS });\n return promise;\n}\n\nasync function fetchRSSItems(rssUrl: string, maxItems: number): Promise<RSSItem[]> {\n const encoded = encodeURIComponent(rssUrl);\n\n try {\n const origin = typeof window !== \"undefined\" ? window.location.origin : \"\";\n const resp = await fetch(`${origin}/api/rss-proxy?url=${encoded}`);\n if (resp.ok) {\n const text = await resp.text();\n if (text.includes(\"<item\")) return parseRSSXml(text, maxItems);\n }\n } catch { /* fall through */ }\n\n try {\n const resp = await fetch(`https://api.allorigins.win/get?url=${encoded}`);\n if (resp.ok) {\n const data = await resp.json();\n if (data.contents) return parseRSSXml(data.contents, maxItems);\n }\n } catch { /* fall through */ }\n\n try {\n const resp = await fetch(`https://corsproxy.io/?url=${encoded}`);\n if (resp.ok) {\n const text = await resp.text();\n if (text) return parseRSSXml(text, maxItems);\n }\n } catch { /* fall through */ }\n\n throw new Error(\"All RSS proxies failed\");\n}\n\nfunction ScrollerOverlay({ overlay }: { overlay: SwirlOverlay }) {\n const cfg = overlay.scroller_config;\n const uid = useId().replace(/:/g, \"\");\n\n const [rssItems, setRssItems] = useState<RSSItem[]>([]);\n const [rssLoading, setRssLoading] = useState(true);\n const [rssError, setRssError] = useState(false);\n\n const rssUrl = cfg?.rss_url || \"\";\n const maxItems = cfg?.max_items ?? 10;\n const autoRefresh = cfg?.auto_refresh !== false;\n const updateInterval = cfg?.update_interval ?? 5;\n\n useEffect(() => {\n if (!rssUrl || (cfg?.use_custom_text && cfg?.custom_text)) {\n setRssLoading(false);\n return;\n }\n let cancelled = false;\n setRssLoading(true);\n setRssError(false);\n cachedFetchRSSItems(rssUrl, maxItems)\n .then((items) => { if (!cancelled) { setRssItems(items); setRssError(false); } })\n .catch(() => { if (!cancelled) setRssError(true); })\n .finally(() => { if (!cancelled) setRssLoading(false); });\n return () => { cancelled = true; };\n }, [rssUrl, maxItems, cfg?.use_custom_text, cfg?.custom_text]);\n\n useEffect(() => {\n if (!rssUrl || !autoRefresh || (cfg?.use_custom_text && cfg?.custom_text)) return;\n const interval = setInterval(() => {\n rssCache.delete(rssUrl);\n cachedFetchRSSItems(rssUrl, maxItems)\n .then((items) => { setRssItems(items); setRssError(false); })\n .catch(() => { /* keep showing last good items */ });\n }, updateInterval * 60 * 1000);\n return () => clearInterval(interval);\n }, [rssUrl, autoRefresh, updateInterval, maxItems, cfg?.use_custom_text, cfg?.custom_text]);\n\n const sep = cfg?.separator_char ?? \"◆\";\n\n let segments: string[];\n if (cfg?.use_custom_text && cfg?.custom_text) {\n segments = [cfg.custom_text];\n } else if (rssItems.length > 0) {\n segments = rssItems.map((item) => {\n const parts: string[] = [];\n if (cfg?.show_title !== false && item.title) parts.push(item.title);\n if (cfg?.show_description && item.description) parts.push(item.description);\n if (cfg?.show_timestamp && item.pubDate) {\n try { parts.push(new Date(item.pubDate).toLocaleDateString()); } catch { /* ignore */ }\n }\n if (cfg?.show_author && item.author) parts.push(`— ${item.author}`);\n if (cfg?.show_category && item.category) parts.push(`[${item.category}]`);\n return parts.join(\" \");\n });\n } else if (rssLoading) {\n segments = [\"Loading feed…\"];\n } else if (rssError) {\n segments = overlay.content ? [overlay.content] : [\"RSS feed unavailable\"];\n } else if (overlay.content) {\n segments = [overlay.content];\n } else {\n segments = rssUrl ? [\"Loading feed…\"] : [\"RSS Ticker\"];\n }\n\n const scrollSpeed = cfg?.scroll_speed ?? 40;\n const direction = cfg?.direction ?? \"left\";\n const fontSize = cfg?.font_size ?? 15;\n const fontFamily = cfg?.font_family || \"Roboto, 'Segoe UI', Arial, sans-serif\";\n const fontWeight = cfg?.font_weight || \"700\";\n const textColor = cfg?.text_color || \"#ffffff\";\n const bgColor = cfg?.background_color || \"#0d0d1a\";\n const bgOpacity = cfg?.background_opacity !== undefined ? cfg.background_opacity / 100 : 0.95;\n const borderRadius = cfg?.border_radius ?? 0;\n const itemSpacing = cfg?.item_spacing ?? 60;\n const pad = cfg?.padding !== undefined && cfg.padding >= 0 ? cfg.padding : 8;\n\n const label = cfg?.label ?? \"NEWS\";\n const labelLine2 = cfg?.label_line2 ?? \"\";\n const labelColor = cfg?.label_color ?? \"#f97316\";\n const labelTextColor = cfg?.label_text_color ?? \"#ffffff\";\n const accentColor = cfg?.accent_color ?? labelColor;\n const showAccentLine = cfg?.show_accent_line !== false;\n const isEquitiesStrip = cfg?.preset === \"equities_strip\";\n\n const isHorizontal = direction === \"left\" || direction === \"right\";\n const isReverse = direction === \"right\" || direction === \"down\";\n\n const fullText = segments.join(` ${sep} `);\n const durationSec = Math.max(6, (fullText.length * 9) / scrollSpeed);\n\n const animId = `sc-ticker-${overlay.id}-${uid}`;\n const keyframes = isHorizontal\n ? `@keyframes ${animId} {\n ${isReverse\n ? \"0% { transform: translateX(-50%); } 100% { transform: translateX(0%); }\"\n : \"0% { transform: translateX(0); } 100% { transform: translateX(-50%); }\"}\n }`\n : `@keyframes ${animId} {\n ${isReverse\n ? \"0% { transform: translateY(-50%); } 100% { transform: translateY(0%); }\"\n : \"0% { transform: translateY(0); } 100% { transform: translateY(-50%); }\"}\n }`;\n\n return (\n <>\n <style>{keyframes}</style>\n <div\n style={{\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n overflow: \"hidden\",\n borderRadius: borderRadius > 0 ? `${borderRadius}px` : undefined,\n backgroundColor: `rgba(${hexToRgb(bgColor)}, ${bgOpacity})`,\n fontFamily,\n fontSize: `${fontSize}px`,\n fontWeight,\n color: textColor,\n pointerEvents: \"none\",\n userSelect: \"none\",\n }}\n >\n {showAccentLine && (\n <div\n style={{\n height: isEquitiesStrip ? 2 : 3,\n background: accentColor,\n flexShrink: 0,\n width: \"100%\",\n }}\n />\n )}\n\n <div\n style={{\n display: \"flex\",\n flex: 1,\n overflow: \"hidden\",\n minHeight: 0,\n alignItems: \"center\",\n padding: isEquitiesStrip\n ? `${Math.max(2, pad * 0.5)}px ${pad}px`\n : `${Math.max(4, pad * 0.75)}px ${pad}px`,\n gap: isEquitiesStrip ? Math.max(4, Math.round(pad * 0.75)) : Math.max(6, pad),\n boxSizing: \"border-box\",\n }}\n >\n {label && (\n <div\n style={{\n background: labelColor,\n color: labelTextColor,\n padding: isEquitiesStrip ? \"6px 12px\" : \"10px 14px\",\n display: \"flex\",\n flexDirection: isEquitiesStrip ? \"row\" : \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n textAlign: \"center\",\n gap: isEquitiesStrip ? 0 : 2,\n borderRadius: Math.max(2, borderRadius > 0 ? borderRadius : 6),\n boxShadow: isEquitiesStrip\n ? \"inset 0 1px 0 rgba(255,255,255,0.08)\"\n : \"0 2px 8px rgba(0,0,0,0.35)\",\n alignSelf: \"stretch\",\n maxWidth: isEquitiesStrip ? \"min(200px, 28%)\" : undefined,\n }}\n >\n <span\n style={{\n fontWeight: isEquitiesStrip ? 700 : 800,\n fontSize: isEquitiesStrip ? \"0.82em\" : \"0.78em\",\n letterSpacing: isEquitiesStrip ? \"0.04em\" : \"0.08em\",\n lineHeight: 1.2,\n textTransform: isEquitiesStrip ? \"none\" : \"uppercase\",\n whiteSpace: isEquitiesStrip ? \"normal\" : \"nowrap\",\n textAlign: isEquitiesStrip ? \"left\" : \"center\",\n }}\n >\n {label}\n </span>\n {labelLine2 && !isEquitiesStrip && (\n <span\n style={{\n fontWeight: 600,\n fontSize: \"0.58em\",\n letterSpacing: \"0.06em\",\n lineHeight: 1.15,\n opacity: 0.92,\n whiteSpace: \"nowrap\",\n }}\n >\n {labelLine2}\n </span>\n )}\n </div>\n )}\n\n {label && (\n <div\n style={{\n width: isEquitiesStrip ? 1 : 2,\n alignSelf: \"stretch\",\n minHeight: isEquitiesStrip ? 20 : 24,\n background: accentColor,\n flexShrink: 0,\n borderRadius: 1,\n opacity: 0.85,\n }}\n />\n )}\n\n <div\n style={{\n flex: 1,\n overflow: \"hidden\",\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n minWidth: 0,\n }}\n >\n {isHorizontal ? (\n <div\n style={{\n display: \"inline-flex\",\n whiteSpace: \"nowrap\",\n animation: `${animId} ${durationSec}s linear infinite`,\n willChange: \"transform\",\n }}\n >\n {[0, 1].map((copy) => (\n <span key={copy} style={{ paddingRight: `${itemSpacing}px` }}>\n {segments.map((seg, i) => (\n <React.Fragment key={i}>\n {i > 0 && (\n <span style={{ opacity: 0.5, margin: \"0 8px\" }}>{sep}</span>\n )}\n <span style={{ textShadow: \"0 1px 3px rgba(0,0,0,0.6)\" }}>{seg}</span>\n </React.Fragment>\n ))}\n </span>\n ))}\n </div>\n ) : (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n whiteSpace: \"nowrap\",\n animation: `${animId} ${durationSec}s linear infinite`,\n willChange: \"transform\",\n }}\n >\n {[0, 1].map((copy) =>\n segments.map((seg, i) => (\n <div key={`${copy}-${i}`} style={{ paddingBottom: `${itemSpacing / 4}px` }}>\n {seg}\n </div>\n ))\n )}\n </div>\n )}\n </div>\n </div>\n </div>\n </>\n );\n}\n\nfunction parseConfig<T>(content?: string): T | null {\n if (!content) return null;\n try { return JSON.parse(content) as T; } catch { return null; }\n}\n\ninterface OverlaySize { w: number; h: number; }\n\ninterface ScoreBugCfg { homeTeam: string; awayTeam: string; homeScore: number; awayScore: number; period: string; clock: string; sponsorText: string; sponsorImageUrl: string; backgroundColor: string; textColor: string; accentColor: string; }\ninterface LowerThirdCfg { headline: string; subtitle: string; sponsorText: string; sponsorImageUrl: string; backgroundColor: string; textColor: string; accentColor: string; style: string; }\ninterface QrCodeCfg { url: string; ctaText: string; description: string; size: number; backgroundColor: string; textColor: string; accentColor: string; }\ninterface ComingUpNextCfg { title: string; subtitle: string; scheduledTime: string; thumbnailUrl: string; backgroundColor: string; textColor: string; accentColor: string; }\ninterface ContextualTriggerCfg { triggerType: string; headline: string; message: string; iconType: string; backgroundColor: string; textColor: string; accentColor: string; animationStyle: string; }\ninterface OddsBettingCfg { eventTitle: string; options: Array<{ label: string; odds: string }>; sponsorText: string; backgroundColor: string; textColor: string; accentColor: string; oddsFormat: string; }\ninterface BreakingNewsCfg { headline: string; body: string; urgency: string; backgroundColor: string; textColor: string; accentColor: string; }\ninterface CountdownCfg { eventName: string; targetTime: string; message: string; showDays: boolean; showHours: boolean; showMinutes: boolean; showSeconds: boolean; backgroundColor: string; textColor: string; accentColor: string; }\n\nfunction ScoreBugOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const cfg = parseConfig<ScoreBugCfg>(overlay.content);\n if (!cfg) return null;\n const f = Math.max(6, size.w * 0.052);\n return (\n <div\n style={{\n width: \"100%\",\n height: \"100%\",\n borderRadius: Math.max(2, size.w * 0.028),\n display: \"flex\",\n flexDirection: \"column\",\n background: cfg.backgroundColor,\n color: cfg.textColor,\n fontFamily: \"'Inter', 'Roboto', 'Segoe UI', system-ui, sans-serif\",\n overflow: \"hidden\",\n pointerEvents: \"none\",\n userSelect: \"none\",\n fontSize: `${f}px`,\n boxShadow: \"0 8px 28px rgba(0,0,0,0.45)\",\n }}\n >\n <div\n style={{\n flex: 1,\n display: \"flex\",\n alignItems: \"center\",\n padding: `${f * 0.42}px ${f * 0.85}px`,\n gap: f * 0.45,\n minHeight: 0,\n }}\n >\n <div style={{ flex: 1, textAlign: \"center\", minWidth: 0, padding: `0 ${f * 0.15}px` }}>\n <div\n style={{\n fontSize: \"1.05em\",\n fontWeight: 800,\n letterSpacing: \"0.02em\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {cfg.homeTeam}\n </div>\n <div style={{ fontSize: \"1.75em\", fontWeight: 900, lineHeight: 1.05, marginTop: f * 0.08 }}>\n {cfg.homeScore}\n </div>\n </div>\n <div\n style={{\n fontSize: \"0.88em\",\n textAlign: \"center\",\n fontWeight: 600,\n opacity: 0.92,\n color: cfg.textColor,\n padding: `0 ${f * 0.5}px`,\n flexShrink: 0,\n lineHeight: 1.25,\n textTransform: \"uppercase\",\n letterSpacing: \"0.04em\",\n }}\n >\n <div>{cfg.period}</div>\n <div style={{ fontWeight: 700, opacity: 1 }}>{cfg.clock}</div>\n </div>\n <div style={{ flex: 1, textAlign: \"center\", minWidth: 0, padding: `0 ${f * 0.15}px` }}>\n <div\n style={{\n fontSize: \"1.05em\",\n fontWeight: 800,\n letterSpacing: \"0.02em\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {cfg.awayTeam}\n </div>\n <div style={{ fontSize: \"1.75em\", fontWeight: 900, lineHeight: 1.05, marginTop: f * 0.08 }}>\n {cfg.awayScore}\n </div>\n </div>\n </div>\n {(cfg.sponsorText || cfg.sponsorImageUrl) && (\n <div\n style={{\n fontSize: \"0.72em\",\n textAlign: \"center\",\n fontWeight: 600,\n opacity: 0.88,\n padding: `${f * 0.34}px ${f * 0.55}px`,\n borderTop: `1px solid ${cfg.accentColor}55`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: f * 0.45,\n overflow: \"hidden\",\n letterSpacing: \"0.04em\",\n textTransform: \"uppercase\",\n background: `linear-gradient(180deg, rgba(0,0,0,0.12) 0%, rgba(0,0,0,0.22) 100%)`,\n }}\n >\n {cfg.sponsorImageUrl && (\n <img src={cfg.sponsorImageUrl} alt=\"sponsor\" style={{ height: `${f * 1.35}px`, objectFit: \"contain\", flexShrink: 0 }} />\n )}\n {cfg.sponsorText && (\n <span style={{ overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>{cfg.sponsorText}</span>\n )}\n </div>\n )}\n </div>\n );\n}\n\nfunction LowerThirdOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const cfg = parseConfig<LowerThirdCfg>(overlay.content);\n if (!cfg) return null;\n const f = Math.max(6, size.w * 0.05);\n const accentH = Math.max(3, size.h * 0.038);\n return (\n <div\n style={{\n width: \"100%\",\n height: \"100%\",\n borderRadius: Math.max(2, size.w * 0.018),\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"flex-end\",\n background: cfg.backgroundColor,\n color: cfg.textColor,\n fontFamily: \"'Inter', 'Roboto', 'Segoe UI', system-ui, sans-serif\",\n overflow: \"hidden\",\n pointerEvents: \"none\",\n userSelect: \"none\",\n fontSize: `${f}px`,\n boxShadow: \"0 10px 32px rgba(0,0,0,0.4)\",\n }}\n >\n <div style={{ width: \"100%\", height: accentH, backgroundColor: cfg.accentColor, flexShrink: 0 }} />\n <div\n style={{\n flex: 1,\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n padding: `${f * 0.62}px ${f * 1.05}px`,\n minHeight: 0,\n gap: f * 0.18,\n }}\n >\n <div\n style={{\n fontSize: \"1.28em\",\n fontWeight: 800,\n lineHeight: 1.22,\n letterSpacing: \"0.01em\",\n textShadow: \"0 2px 6px rgba(0,0,0,0.55)\",\n }}\n >\n {cfg.headline}\n </div>\n <div\n style={{\n fontSize: \"0.94em\",\n fontWeight: 500,\n opacity: 0.92,\n lineHeight: 1.35,\n color: cfg.textColor,\n }}\n >\n {cfg.subtitle}\n </div>\n </div>\n {(cfg.sponsorText || cfg.sponsorImageUrl) && (\n <div\n style={{\n fontSize: \"0.68em\",\n fontWeight: 600,\n opacity: 0.72,\n padding: `${f * 0.28}px ${f * 1.05}px ${f * 0.48}px`,\n display: \"flex\",\n alignItems: \"center\",\n gap: f * 0.4,\n overflow: \"hidden\",\n letterSpacing: \"0.06em\",\n textTransform: \"uppercase\",\n borderTop: `1px solid rgba(255,255,255,0.08)`,\n }}\n >\n {cfg.sponsorImageUrl && (\n <img src={cfg.sponsorImageUrl} alt=\"sponsor\" style={{ height: `${f * 1.25}px`, objectFit: \"contain\", flexShrink: 0 }} />\n )}\n {cfg.sponsorText && (\n <span style={{ overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>{cfg.sponsorText}</span>\n )}\n </div>\n )}\n </div>\n );\n}\n\nfunction QrCodeOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const cfg = parseConfig<QrCodeCfg>(overlay.content);\n if (!cfg) return null;\n const qrSide = Math.max(32, Math.min(size.w, size.h) * 0.55);\n const qrUrl = `https://api.qrserver.com/v1/create-qr-code/?size=${Math.round(qrSide * 2)}x${Math.round(qrSide * 2)}&data=${encodeURIComponent(cfg.url || \"https://example.com\")}`;\n const f = Math.max(6, size.w * 0.06);\n return (\n <div style={{ width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", flexDirection: \"column\", alignItems: \"center\", justifyContent: \"center\", gap: f * 0.4, background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", padding: f * 0.6, boxSizing: \"border-box\", pointerEvents: \"none\", userSelect: \"none\", overflow: \"hidden\" }}>\n <div style={{ flexShrink: 0, background: \"#fff\", borderRadius: Math.max(2, qrSide * 0.06), padding: Math.max(2, qrSide * 0.06), lineHeight: 0 }}>\n <img src={qrUrl} alt=\"QR Code\" style={{ width: `${qrSide}px`, height: `${qrSide}px`, display: \"block\" }} />\n </div>\n <div style={{ fontSize: `${f * 1.1}px`, fontWeight: 700, textAlign: \"center\", color: cfg.accentColor, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", width: \"100%\" }}>{cfg.ctaText}</div>\n {cfg.description && <div style={{ fontSize: `${f * 0.75}px`, opacity: 0.6, textAlign: \"center\", overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", width: \"100%\" }}>{cfg.description}</div>}\n </div>\n );\n}\n\nfunction ComingUpNextOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const cfg = parseConfig<ComingUpNextCfg>(overlay.content);\n if (!cfg) return null;\n const f = Math.max(8, Math.min(size.h * 0.13, size.w * 0.048));\n const showSubtitle = size.h >= 60;\n const showThumbnail = false;\n const thumbW = 0;\n return (\n <div style={{\n width: \"100%\", height: \"100%\",\n borderRadius: Math.max(2, size.w * 0.025),\n display: \"flex\",\n background: cfg.backgroundColor,\n color: cfg.textColor,\n fontFamily: \"'Arial', 'Helvetica Neue', Helvetica, sans-serif\",\n overflow: \"hidden\",\n pointerEvents: \"none\", userSelect: \"none\",\n fontSize: `${f}px`,\n WebkitFontSmoothing: \"antialiased\",\n } as React.CSSProperties}>\n <div style={{ width: Math.max(3, size.w * 0.018), flexShrink: 0, backgroundColor: cfg.accentColor }} />\n <div style={{\n flex: 1, display: \"flex\", flexDirection: \"column\", justifyContent: \"center\",\n padding: `${f * 0.35}px ${f * 0.75}px`,\n minWidth: 0, gap: `${f * 0.08}px`,\n }}>\n <div style={{\n fontSize: \"0.7em\", fontWeight: 700,\n textTransform: \"uppercase\", letterSpacing: \"0.09em\",\n color: cfg.accentColor, lineHeight: 1,\n }}>\n Coming Up Next\n </div>\n <div style={{\n fontSize: \"1.2em\", fontWeight: 700, lineHeight: 1.2,\n overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\",\n }}>\n {cfg.title}\n </div>\n {showSubtitle && (\n <div style={{\n fontSize: \"0.82em\", opacity: 0.65, lineHeight: 1.1,\n overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\",\n }}>\n {cfg.subtitle}\n </div>\n )}\n {cfg.scheduledTime && (\n <div style={{\n fontSize: \"0.9em\", fontWeight: 700,\n color: cfg.accentColor, lineHeight: 1,\n }}>\n {cfg.scheduledTime}\n </div>\n )}\n </div>\n {showThumbnail && (\n <div style={{ flexShrink: 0, width: `${thumbW}px`, overflow: \"hidden\" }}>\n <img\n src={cfg.thumbnailUrl}\n alt=\"\"\n style={{ width: \"100%\", height: \"100%\", objectFit: \"cover\", display: \"block\" }}\n />\n </div>\n )}\n </div>\n );\n}\n\nfunction ContextualTriggerOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const cfg = parseConfig<ContextualTriggerCfg>(overlay.content);\n if (!cfg) return null;\n const icons: Record<string, string> = { alert: \"\\u26A0\\uFE0F\", celebration: \"\\uD83C\\uDF89\", info: \"\\u2139\\uFE0F\", warning: \"\\uD83D\\uDD14\" };\n const f = Math.max(6, size.w * 0.05);\n return (\n <div style={{ width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", alignItems: \"center\", gap: f * 0.8, padding: `0 ${f * 1.2}px`, background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", borderLeft: `${Math.max(2, size.w * 0.02)}px solid ${cfg.accentColor}`, boxSizing: \"border-box\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }}>\n <span style={{ fontSize: \"2em\", flexShrink: 0 }}>{icons[cfg.iconType] || \"\\u26A1\"}</span>\n <div style={{ flex: 1, minWidth: 0 }}>\n <div style={{ fontSize: \"1.3em\", fontWeight: 700, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>{cfg.headline}</div>\n <div style={{ fontSize: \"0.9em\", opacity: 0.7, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>{cfg.message}</div>\n </div>\n </div>\n );\n}\n\nfunction OddsBettingOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const cfg = parseConfig<OddsBettingCfg>(overlay.content);\n if (!cfg) return null;\n const f = Math.max(6, size.w * 0.052);\n return (\n <div style={{ width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", flexDirection: \"column\", padding: f * 0.8, background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", boxSizing: \"border-box\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }}>\n <div style={{ fontSize: \"0.9em\", fontWeight: 700, textTransform: \"uppercase\", letterSpacing: \"0.05em\", color: cfg.accentColor, marginBottom: f * 0.4 }}>{cfg.eventTitle}</div>\n <div style={{ flex: 1, display: \"flex\", flexDirection: \"column\", gap: f * 0.2, justifyContent: \"center\" }}>\n {(cfg.options || []).slice(0, 5).map((opt, i) => (\n <div key={i} style={{ display: \"flex\", justifyContent: \"space-between\", alignItems: \"center\", padding: `${f * 0.2}px ${f * 0.6}px`, borderRadius: Math.max(2, f * 0.3), background: `${cfg.accentColor}15`, fontSize: \"1em\" }}>\n <span style={{ overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", flex: 1 }}>{opt.label}</span>\n <span style={{ fontWeight: 700, marginLeft: f * 0.8, flexShrink: 0, color: cfg.accentColor }}>{opt.odds}</span>\n </div>\n ))}\n </div>\n {cfg.sponsorText && <div style={{ fontSize: \"0.7em\", opacity: 0.4, textAlign: \"center\", marginTop: f * 0.4 }}>{cfg.sponsorText}</div>}\n </div>\n );\n}\n\nfunction BreakingNewsOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const cfg = parseConfig<BreakingNewsCfg>(overlay.content);\n if (!cfg) return null;\n const urgencyColors: Record<string, string> = { breaking: \"#dc2626\", urgent: \"#ea580c\", normal: \"#2563eb\" };\n const labelBg = urgencyColors[cfg.urgency] || urgencyColors.normal;\n const label = cfg.urgency === \"breaking\" ? \"BREAKING\" : cfg.urgency === \"urgent\" ? \"URGENT\" : \"NEWS\";\n const f = Math.max(6, size.w * 0.05);\n return (\n <div style={{ width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.02), display: \"flex\", alignItems: \"center\", background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", overflow: \"hidden\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }}>\n <div style={{ padding: `0 ${f * 0.8}px`, height: \"100%\", display: \"flex\", alignItems: \"center\", background: labelBg, color: \"#fff\", fontSize: \"1em\", fontWeight: 900, textTransform: \"uppercase\", letterSpacing: \"0.05em\", flexShrink: 0 }}>{label}</div>\n <div style={{ flex: 1, padding: `0 ${f * 1.0}px`, minWidth: 0 }}>\n <div style={{ fontSize: \"1.3em\", fontWeight: 700, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>{cfg.headline}</div>\n {cfg.body && <div style={{ fontSize: \"0.9em\", opacity: 0.7, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>{cfg.body}</div>}\n </div>\n </div>\n );\n}\n\nfunction calcCountdownRemaining(targetTime: string) {\n const diff = Math.max(0, new Date(targetTime).getTime() - Date.now());\n return {\n d: Math.floor(diff / 86400000),\n h: Math.floor((diff % 86400000) / 3600000),\n m: Math.floor((diff % 3600000) / 60000),\n s: Math.floor((diff % 60000) / 1000),\n expired: diff === 0,\n };\n}\n\nfunction CountdownOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const cfg = parseConfig<CountdownCfg>(overlay.content);\n const targetTime = cfg?.targetTime ?? \"\";\n const [remaining, setRemaining] = useState(() =>\n targetTime ? calcCountdownRemaining(targetTime) : { d: 0, h: 0, m: 0, s: 0, expired: false }\n );\n\n useEffect(() => {\n if (!targetTime) return;\n setRemaining(calcCountdownRemaining(targetTime));\n const id = setInterval(() => setRemaining(calcCountdownRemaining(targetTime)), 1000);\n return () => clearInterval(id);\n }, [targetTime]);\n\n if (!cfg) return null;\n\n const f = Math.max(6, size.w * 0.055);\n const pad = (n: number) => String(n).padStart(2, \"0\");\n const units: Array<{ show: boolean; value: string; label: string }> = [\n { show: cfg.showDays, value: pad(remaining.d), label: \"DAYS\" },\n { show: cfg.showHours, value: pad(remaining.h), label: \"HRS\" },\n { show: cfg.showMinutes, value: pad(remaining.m), label: \"MIN\" },\n { show: cfg.showSeconds, value: pad(remaining.s), label: \"SEC\" },\n ];\n\n return (\n <div style={{ width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", flexDirection: \"column\", alignItems: \"center\", justifyContent: \"center\", padding: f * 0.8, background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", boxSizing: \"border-box\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }}>\n <div style={{ fontSize: \"0.8em\", fontWeight: 600, textTransform: \"uppercase\", letterSpacing: \"0.05em\", color: cfg.accentColor, marginBottom: f * 0.4 }}>{cfg.eventName}</div>\n {remaining.expired ? (\n <div style={{ fontSize: \"1em\", fontWeight: 700, opacity: 0.6 }}>{cfg.message || \"Event ended\"}</div>\n ) : (\n <div style={{ display: \"flex\", gap: f * 0.6, alignItems: \"center\" }}>\n {units.filter(u => u.show).map((u, i, arr) => (\n <React.Fragment key={u.label}>\n <div style={{ textAlign: \"center\" }}>\n <div style={{ fontSize: \"2em\", fontWeight: 900, lineHeight: 1, borderRadius: Math.max(2, f * 0.4), padding: `${f * 0.2}px ${f * 0.4}px`, background: `${cfg.accentColor}20` }}>{u.value}</div>\n <div style={{ fontSize: \"0.5em\", opacity: 0.5, marginTop: f * 0.2 }}>{u.label}</div>\n </div>\n {i < arr.length - 1 && <div style={{ fontSize: \"1.8em\", fontWeight: 700, opacity: 0.3 }}>:</div>}\n </React.Fragment>\n ))}\n </div>\n )}\n {!remaining.expired && cfg.message && <div style={{ fontSize: \"0.8em\", opacity: 0.6, marginTop: f * 0.4, textAlign: \"center\" }}>{cfg.message}</div>}\n </div>\n );\n}\n\nfunction ShapeOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const f = Math.max(6, size.w * 0.05);\n return (\n <div style={{ width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.03), background: \"rgba(99, 102, 241, 0.2)\", border: \"2px solid rgba(99, 102, 241, 0.4)\", display: \"flex\", alignItems: \"center\", justifyContent: \"center\", pointerEvents: \"none\", userSelect: \"none\" }}>\n <div style={{ fontSize: `${f}px`, fontWeight: 500, color: \"rgba(163, 163, 163, 0.8)\", textTransform: \"uppercase\" }}>{overlay.name}</div>\n </div>\n );\n}\n\nfunction hexToRgb(hex: string): string {\n if (!hex || !hex.startsWith(\"#\")) return \"0,0,0\";\n const clean = hex.slice(1);\n const num = parseInt(clean.length === 3 ? clean.replace(/./g, \"$&$&\") : clean, 16);\n return `${(num >> 16) & 255},${(num >> 8) & 255},${num & 255}`;\n}\n\ninterface OverlayFadeState {\n overlay: SwirlOverlay;\n visible: boolean;\n}\n\nconst FADE_DURATION_MS = 1000;\n\n/** One full cycle (~60s): pop in → hold → pop out → quiet until next cycle. */\nconst SHOWCASE_CYCLE_MS_DEFAULT = 60_000;\nconst SHOWCASE_POP_IN_MS = 420;\nconst SHOWCASE_STEADY_END_MS = 46_000;\nconst SHOWCASE_POP_OUT_MS = 450;\nconst SHOWCASE_POP_OUT_END_MS = SHOWCASE_STEADY_END_MS + SHOWCASE_POP_OUT_MS;\n\nfunction easeOutCubic(t: number): number {\n const u = 1 - t;\n return 1 - u * u * u;\n}\n\nfunction easeInCubic(t: number): number {\n return t * t * t;\n}\n\nfunction easeOutBack(t: number): number {\n const c1 = 1.70158;\n const c3 = c1 + 1;\n return 1 + c3 * (t - 1) ** 3 + c1 * (t - 1) ** 2;\n}\n\nfunction showcaseOpacity(phase: number): number {\n if (phase < SHOWCASE_POP_IN_MS) return easeOutCubic(phase / SHOWCASE_POP_IN_MS);\n if (phase >= SHOWCASE_STEADY_END_MS && phase < SHOWCASE_POP_OUT_END_MS) {\n return 1 - easeInCubic((phase - SHOWCASE_STEADY_END_MS) / SHOWCASE_POP_OUT_MS);\n }\n return 1;\n}\n\nfunction showcaseScale(phase: number): number {\n if (phase < SHOWCASE_POP_IN_MS) {\n return Math.min(\n 1,\n 0.78 + 0.22 * easeOutBack(phase / SHOWCASE_POP_IN_MS)\n );\n }\n if (phase >= SHOWCASE_STEADY_END_MS && phase < SHOWCASE_POP_OUT_END_MS) {\n return 1 - 0.14 * easeInCubic((phase - SHOWCASE_STEADY_END_MS) / SHOWCASE_POP_OUT_MS);\n }\n return 1;\n}\n\nfunction useShowcasePhase(enabled: boolean, cycleMs: number): number {\n const [phase, setPhase] = useState(0);\n useEffect(() => {\n if (!enabled) return;\n setPhase(Date.now() % cycleMs);\n const id = window.setInterval(() => {\n setPhase(Date.now() % cycleMs);\n }, 48);\n return () => clearInterval(id);\n }, [enabled, cycleMs]);\n return phase;\n}\n\nexport const OverlayRenderer: React.FC<OverlayRendererProps> = ({\n overlays,\n currentTime,\n videoRef,\n coordinateSpace,\n showcaseMode = false,\n showcaseCycleMs = SHOWCASE_CYCLE_MS_DEFAULT,\n}) => {\n const [dims, setDims] = useState<VideoDimensions | null>(null);\n const rafRef = useRef<number | null>(null);\n const [fadeMap, setFadeMap] = useState<Map<number, OverlayFadeState>>(new Map());\n const removeTimers = useRef<Map<number, ReturnType<typeof setTimeout>>>(new Map());\n\n const showcasePhase = useShowcasePhase(showcaseMode, showcaseCycleMs);\n\n const updateDims = useCallback(() => {\n const video = videoRef.current;\n if (video) {\n const computed = computeVideoDimensions(video);\n setDims((prev) => {\n if (\n !computed ||\n (prev &&\n prev.nativeWidth === computed.nativeWidth &&\n prev.nativeHeight === computed.nativeHeight &&\n prev.displayWidth === computed.displayWidth &&\n prev.displayHeight === computed.displayHeight &&\n prev.offsetX === computed.offsetX &&\n prev.offsetY === computed.offsetY)\n ) {\n return prev;\n }\n return computed;\n });\n }\n }, [videoRef]);\n\n useEffect(() => {\n updateDims();\n const interval = setInterval(updateDims, 500);\n\n const handleResize = () => {\n if (rafRef.current) cancelAnimationFrame(rafRef.current);\n rafRef.current = requestAnimationFrame(updateDims);\n };\n window.addEventListener(\"resize\", handleResize);\n\n return () => {\n clearInterval(interval);\n window.removeEventListener(\"resize\", handleResize);\n if (rafRef.current) cancelAnimationFrame(rafRef.current);\n };\n }, [updateDims]);\n\n const activeOverlays = useMemo(() => {\n if (showcaseMode) {\n return overlays.filter((o) => {\n if (!o.visible) return false;\n return showcasePhase < SHOWCASE_POP_OUT_END_MS;\n });\n }\n return overlays.filter((o) => isOverlayActive(o, currentTime));\n }, [overlays, currentTime, showcaseMode, showcasePhase]);\n\n const activeBeatIds = useMemo(\n () => new Set(activeOverlays.map((o) => o.id)),\n [activeOverlays]\n );\n\n useLayoutEffect(() => {\n const activeIds = new Set(activeOverlays.map((o) => o.id));\n\n setFadeMap((prev) => {\n const next = new Map(prev);\n\n for (const overlay of activeOverlays) {\n if (!next.has(overlay.id)) {\n next.set(overlay.id, { overlay, visible: false });\n } else {\n const existing = next.get(overlay.id)!;\n next.set(overlay.id, { ...existing, overlay });\n }\n }\n\n for (const [id, state] of next) {\n if (!activeIds.has(id) && state.visible) {\n next.set(id, { ...state, visible: false });\n if (!removeTimers.current.has(id)) {\n const timer = setTimeout(() => {\n setFadeMap((m) => {\n const updated = new Map(m);\n updated.delete(id);\n return updated;\n });\n removeTimers.current.delete(id);\n }, FADE_DURATION_MS);\n removeTimers.current.set(id, timer);\n }\n } else if (!activeIds.has(id) && !state.visible) {\n }\n }\n\n return next;\n });\n }, [activeOverlays]);\n\n useEffect(() => {\n const toFadeIn: number[] = [];\n for (const [id, state] of fadeMap) {\n if (!state.visible) {\n const isActive = activeOverlays.some((o) => o.id === id);\n if (isActive) toFadeIn.push(id);\n }\n }\n if (toFadeIn.length === 0) return;\n\n const raf = requestAnimationFrame(() => {\n setFadeMap((prev) => {\n const next = new Map(prev);\n for (const id of toFadeIn) {\n const state = next.get(id);\n if (state) next.set(id, { ...state, visible: true });\n }\n return next;\n });\n });\n return () => cancelAnimationFrame(raf);\n }, [fadeMap, activeOverlays]);\n\n useEffect(() => {\n return () => {\n for (const timer of removeTimers.current.values()) clearTimeout(timer);\n };\n }, []);\n\n if (!dims || fadeMap.size === 0) return null;\n\n return (\n <div\n aria-hidden=\"true\"\n style={{\n position: \"absolute\",\n left: `${dims.offsetX}px`,\n top: `${dims.offsetY}px`,\n width: `${dims.displayWidth}px`,\n height: `${dims.displayHeight}px`,\n pointerEvents: \"none\",\n overflow: \"hidden\",\n zIndex: 8,\n }}\n >\n {[...fadeMap.values()].map(({ overlay, visible }) => {\n const uniform =\n coordinateSpace &&\n coordinateSpace.width > 0 &&\n coordinateSpace.height > 0;\n const auth = uniform\n ? { width: coordinateSpace.width, height: coordinateSpace.height }\n : overlayAuthoringDimensions(\n overlay,\n dims.nativeWidth,\n dims.nativeHeight\n );\n const scaleX = dims.displayWidth / auth.width;\n const scaleY = dims.displayHeight / auth.height;\n const left = overlay.x * scaleX;\n const top = overlay.y * scaleY;\n const width = overlay.width * scaleX;\n const height = overlay.height * scaleY;\n const baseOpacity = Math.max(0, Math.min(100, overlay.opacity)) / 100;\n const inShowcaseBeat = showcaseMode && activeBeatIds.has(overlay.id);\n const useShowcasePop = inShowcaseBeat;\n const opacity = useShowcasePop\n ? baseOpacity * showcaseOpacity(showcasePhase)\n : visible\n ? baseOpacity\n : 0;\n const popScale = useShowcasePop ? showcaseScale(showcasePhase) : 1;\n const sz: OverlaySize = { w: width, h: height };\n\n return (\n <div\n key={overlay.id}\n style={{\n position: \"absolute\",\n left: `${left}px`,\n top: `${top}px`,\n width: `${width}px`,\n height: `${height}px`,\n opacity,\n transition: useShowcasePop\n ? \"none\"\n : `opacity ${FADE_DURATION_MS}ms ease`,\n transform: showcaseMode && useShowcasePop ? `scale(${popScale})` : undefined,\n transformOrigin: showcaseMode && useShowcasePop ? \"center center\" : undefined,\n zIndex: overlay.z_index,\n overflow: \"hidden\",\n }}\n >\n {overlay.type === \"image\" && <ImageOverlay overlay={overlay} />}\n {overlay.type === \"text\" && <TextOverlay overlay={overlay} />}\n {overlay.type === \"scroller\" && <ScrollerOverlay overlay={overlay} />}\n {overlay.type === \"shape\" && <ShapeOverlay overlay={overlay} size={sz} />}\n {overlay.type === \"score_bug\" && <ScoreBugOverlay overlay={overlay} size={sz} />}\n {overlay.type === \"lower_third\" && <LowerThirdOverlay overlay={overlay} size={sz} />}\n {overlay.type === \"qr_code\" && <QrCodeOverlay overlay={overlay} size={sz} />}\n {overlay.type === \"coming_up_next\" && <ComingUpNextOverlay overlay={overlay} size={sz} />}\n {overlay.type === \"contextual_trigger\" && <ContextualTriggerOverlay overlay={overlay} size={sz} />}\n {overlay.type === \"odds_betting\" && <OddsBettingOverlay overlay={overlay} size={sz} />}\n {overlay.type === \"breaking_news\" && <BreakingNewsOverlay overlay={overlay} size={sz} />}\n {overlay.type === \"countdown\" && <CountdownOverlay overlay={overlay} size={sz} />}\n </div>\n );\n })}\n </div>\n );\n};\n","export const OVERLAY_API_BASE = \"https://adstorm.co/api-adstorm-dev\";\n\nexport interface OverlayCoordinateSpace {\n width: number;\n height: number;\n}\n\nexport interface SwirlScrollerConfig {\n rss_url?: string;\n update_interval?: number;\n scroll_speed?: number;\n direction?: string;\n font_size?: number;\n font_family?: string;\n font_weight?: string;\n text_color?: string;\n background_color?: string;\n background_opacity?: number;\n border_color?: string;\n border_width?: number;\n border_radius?: number;\n padding?: number;\n margin?: number;\n show_title?: boolean;\n show_description?: boolean;\n show_timestamp?: boolean;\n show_author?: boolean;\n show_category?: boolean;\n max_items?: number;\n item_spacing?: number;\n fade_in_out?: boolean;\n fade_distance?: number;\n auto_refresh?: boolean;\n use_custom_text?: boolean;\n custom_text?: string;\n label?: string;\n label_line2?: string;\n label_color?: string;\n label_text_color?: string;\n accent_color?: string;\n show_accent_line?: boolean;\n separator_char?: string;\n preset?: string;\n}\n\nexport type SwirlOverlayType =\n | \"image\"\n | \"text\"\n | \"scroller\"\n | \"shape\"\n | \"score_bug\"\n | \"lower_third\"\n | \"qr_code\"\n | \"coming_up_next\"\n | \"contextual_trigger\"\n | \"odds_betting\"\n | \"breaking_news\"\n | \"countdown\";\n\nexport interface SwirlOverlay {\n id: number;\n project_id: number;\n name: string;\n type: SwirlOverlayType | string;\n visible: boolean;\n x: number;\n y: number;\n width: number;\n height: number;\n opacity: number;\n start_time: string;\n duration: string;\n content?: string;\n image_url?: string;\n scroller_config?: SwirlScrollerConfig;\n z_index: number;\n created_at?: string;\n updated_at?: string;\n}\n\nexport function timeStringToSeconds(timeStr: string): number {\n if (!timeStr) return 0;\n\n const parts = timeStr.split(\":\");\n\n if (parts.length >= 3) {\n const hours = parseInt(parts[0] ?? \"0\", 10) || 0;\n const minutes = parseInt(parts[1] ?? \"0\", 10) || 0;\n const secStr = parts[2] ?? \"0\";\n const dotIdx = secStr.indexOf(\".\");\n const seconds =\n parseInt(dotIdx >= 0 ? secStr.substring(0, dotIdx) : secStr, 10) || 0;\n const msFrag = dotIdx >= 0 ? secStr.substring(dotIdx + 1) : \"\";\n const ms = msFrag ? parseInt(msFrag.padEnd(3, \"0\").substring(0, 3), 10) || 0 : 0;\n return hours * 3600 + minutes * 60 + seconds + ms / 1000;\n }\n\n if (parts.length === 2) {\n const minutes = parseInt(parts[0] ?? \"0\", 10) || 0;\n const secStr = parts[1] ?? \"0\";\n const dotIdx = secStr.indexOf(\".\");\n const seconds =\n parseInt(dotIdx >= 0 ? secStr.substring(0, dotIdx) : secStr, 10) || 0;\n const msFrag = dotIdx >= 0 ? secStr.substring(dotIdx + 1) : \"\";\n const ms = msFrag ? parseInt(msFrag.padEnd(3, \"0\").substring(0, 3), 10) || 0 : 0;\n return minutes * 60 + seconds + ms / 1000;\n }\n\n const num = parseFloat(timeStr);\n return isFinite(num) ? Math.max(0, num) : 0;\n}\n\nexport function isOverlayActive(\n overlay: SwirlOverlay,\n currentTime: number\n): boolean {\n if (!overlay.visible) return false;\n const startSec = timeStringToSeconds(overlay.start_time);\n const durationSec = timeStringToSeconds(overlay.duration);\n if (durationSec <= 0) return false;\n return currentTime >= startSec && currentTime < startSec + durationSec;\n}\n\nexport const SWIRL_HD_AUTHORING_WIDTH = 1920;\nexport const SWIRL_HD_AUTHORING_HEIGHT = 1080;\n\nconst NAB_DEMO_NAME_PREFIX = \"NAB Demo — \";\n\nexport function overlayAuthoringDimensions(\n overlay: SwirlOverlay,\n decodeWidth: number,\n decodeHeight: number\n): { width: number; height: number } {\n if (!decodeWidth || !decodeHeight) {\n return {\n width: decodeWidth || SWIRL_HD_AUTHORING_WIDTH,\n height: decodeHeight || SWIRL_HD_AUTHORING_HEIGHT,\n };\n }\n if (!overlay.visible) {\n return { width: decodeWidth, height: decodeHeight };\n }\n const extR = overlay.x + overlay.width;\n const extB = overlay.y + overlay.height;\n const EPS = 2;\n const exceedsDecode =\n extR > decodeWidth + EPS || extB > decodeHeight + EPS;\n const isNabDemo = overlay.name.startsWith(NAB_DEMO_NAME_PREFIX);\n const isSyntheticMarketsTicker =\n overlay.id === -9001 || overlay.name === \"Demo stock ticker\";\n\n if (exceedsDecode && (isNabDemo || isSyntheticMarketsTicker)) {\n return {\n width: SWIRL_HD_AUTHORING_WIDTH,\n height: SWIRL_HD_AUTHORING_HEIGHT,\n };\n }\n return { width: decodeWidth, height: decodeHeight };\n}\n\nfunction overlayExtents(overlays: SwirlOverlay[]): { maxR: number; maxB: number } {\n let maxR = 0;\n let maxB = 0;\n for (const o of overlays) {\n if (!o.visible) continue;\n maxR = Math.max(maxR, o.x + o.width);\n maxB = Math.max(maxB, o.y + o.height);\n }\n return { maxR, maxB };\n}\n\nexport function swirlProjectHasNabDemoMixedWithOther(overlays: SwirlOverlay[]): boolean {\n let hasNab = false;\n let hasOther = false;\n for (const o of overlays) {\n if (!o.visible) continue;\n if (o.name.startsWith(NAB_DEMO_NAME_PREFIX)) hasNab = true;\n else hasOther = true;\n }\n return hasNab && hasOther;\n}\n\nexport function inferSwirlOverlayCoordinateSpace(\n overlays: SwirlOverlay[],\n videoWidth: number,\n videoHeight: number\n): OverlayCoordinateSpace {\n if (!videoWidth || !videoHeight) {\n return {\n width: videoWidth || SWIRL_HD_AUTHORING_WIDTH,\n height: videoHeight || SWIRL_HD_AUTHORING_HEIGHT,\n };\n }\n if (!overlays.length) {\n return { width: videoWidth, height: videoHeight };\n }\n\n const { maxR, maxB } = overlayExtents(overlays);\n const EPS = 1;\n const exceedsDecode = maxR > videoWidth + EPS || maxB > videoHeight + EPS;\n const fitsHdCanvas =\n maxR <= SWIRL_HD_AUTHORING_WIDTH + EPS &&\n maxB <= SWIRL_HD_AUTHORING_HEIGHT + EPS;\n const mixed = swirlProjectHasNabDemoMixedWithOther(overlays);\n const decodeLargerThanHd =\n videoWidth > SWIRL_HD_AUTHORING_WIDTH + EPS ||\n videoHeight > SWIRL_HD_AUTHORING_HEIGHT + EPS;\n\n if (fitsHdCanvas && (decodeLargerThanHd || (exceedsDecode && !mixed))) {\n return {\n width: SWIRL_HD_AUTHORING_WIDTH,\n height: SWIRL_HD_AUTHORING_HEIGHT,\n };\n }\n\n return { width: videoWidth, height: videoHeight };\n}\n\nexport function scrollerLooksLikeMarketsStock(o: SwirlOverlay): boolean {\n if (o.type !== \"scroller\") return false;\n const cfg = o.scroller_config;\n const blob = `${o.name} ${cfg?.label ?? \"\"} ${cfg?.label_line2 ?? \"\"} ${cfg?.custom_text ?? \"\"} ${cfg?.preset ?? \"\"}`;\n return /\\b(MARKETS?|NYSE|NASDAQ|DJIA|\\bS&P\\b|STOCK|AAPL|TSLA|NVDA|EQUITIES)\\b/i.test(blob);\n}\n\nexport type DemoStockTickerOptions = {\n coordinateWidth?: number;\n coordinateHeight?: number;\n};\n\nexport function createDemoStockTickerOverlay(\n projectId: number,\n opts?: DemoStockTickerOptions\n): SwirlOverlay {\n const cw =\n opts?.coordinateWidth && opts.coordinateWidth > 0\n ? opts.coordinateWidth\n : SWIRL_HD_AUTHORING_WIDTH;\n const ch =\n opts?.coordinateHeight && opts.coordinateHeight > 0\n ? opts.coordinateHeight\n : SWIRL_HD_AUTHORING_HEIGHT;\n const sx = cw / SWIRL_HD_AUTHORING_WIDTH;\n const sy = ch / SWIRL_HD_AUTHORING_HEIGHT;\n\n const x = 36 * sx;\n const y = 1002 * sy;\n const width = 1848 * sx;\n const height = 66 * sy;\n\n const fontSize = Math.max(8, Math.round(13 * sy));\n const scrollSpeed = Math.max(8, Math.round(36 * sx));\n const borderRadius = Math.max(1, Math.round(4 * sy));\n\n return {\n id: -9001,\n project_id: projectId,\n name: \"Demo stock ticker\",\n type: \"scroller\",\n visible: true,\n x,\n y,\n width,\n height,\n opacity: 100,\n start_time: \"00:00:00.000\",\n duration: \"24:00:00.000\",\n z_index: 120,\n scroller_config: {\n preset: \"equities_strip\",\n use_custom_text: true,\n custom_text:\n \"AAPL +0.84% • MSFT +0.31% • GOOGL −0.22% • AMZN +0.47% • NVDA +1.12% • META +0.19% • BRK.B +0.11% • JPM +0.55% • V +0.28% • UNH −0.17% • DJIA +0.41% • S&P 500 +0.29% • Nasdaq Composite +0.36% • Russell 2000 +0.52% • WTI crude $78.40 +0.6% • Gold $2,348/oz −0.2% • 10Y Treasury 4.28%\",\n direction: \"left\",\n scroll_speed: scrollSpeed,\n font_size: fontSize,\n font_weight: \"600\",\n text_color: \"#e2e8f0\",\n background_color: \"#0a0f18\",\n background_opacity: 92,\n border_radius: borderRadius,\n padding: Math.max(3, Math.round(6 * sy)),\n label: \"U.S. equities\",\n label_line2: \"\",\n label_color: \"#1e3a5f\",\n label_text_color: \"#f8fafc\",\n accent_color: \"#38bdf8\",\n show_accent_line: true,\n separator_char: \"•\",\n item_spacing: Math.max(28, Math.round(48 * sx)),\n },\n };\n}\n\nfunction normalizeScrollerConfig(\n raw: SwirlScrollerConfig | Record<string, unknown> | undefined\n): SwirlScrollerConfig | undefined {\n if (!raw || typeof raw !== \"object\") return undefined;\n const r = raw as Record<string, unknown>;\n const merged: SwirlScrollerConfig = { ...(raw as SwirlScrollerConfig) };\n if (merged.use_custom_text === undefined && typeof r.useCustomText === \"boolean\") {\n merged.use_custom_text = r.useCustomText;\n }\n if ((merged.custom_text === undefined || merged.custom_text === \"\") && typeof r.customText === \"string\") {\n merged.custom_text = r.customText;\n }\n if (!merged.rss_url && typeof r.rssUrl === \"string\") {\n merged.rss_url = r.rssUrl;\n }\n return merged;\n}\n\nexport function normalizeSwirlOverlay(raw: SwirlOverlay & Record<string, unknown>): SwirlOverlay {\n const o = { ...raw };\n if (o.type === \"scroller\") {\n const sc = raw.scroller_config ?? (raw as Record<string, unknown>).scrollerConfig;\n const normalized = normalizeScrollerConfig(sc as SwirlScrollerConfig);\n if (normalized) o.scroller_config = normalized;\n }\n return o;\n}\n\nexport async function fetchProjectOverlays(\n projectId: number,\n apiBaseUrl: string = OVERLAY_API_BASE\n): Promise<SwirlOverlay[]> {\n const base = apiBaseUrl.replace(/\\/$/, \"\");\n const response = await fetch(\n `${base}/adstorm/swirl/projects/${projectId}/overlays`\n );\n if (!response.ok) {\n throw new Error(\n `Failed to fetch overlays: ${response.status} ${response.statusText}`\n );\n }\n const data = await response.json();\n if (!Array.isArray(data)) return [];\n return data.map((row: SwirlOverlay & Record<string, unknown>) =>\n normalizeSwirlOverlay(row)\n );\n}\n\nexport function resolveImageUrl(\n imageUrl: string,\n apiBaseUrl: string = OVERLAY_API_BASE\n): string {\n if (!imageUrl) return \"\";\n if (imageUrl.startsWith(\"http://\") || imageUrl.startsWith(\"https://\")) {\n return imageUrl;\n }\n if (imageUrl.startsWith(\"/\")) {\n try {\n const url = new URL(apiBaseUrl);\n return `${url.origin}${imageUrl}`;\n } catch {\n return imageUrl;\n }\n }\n return `${apiBaseUrl}/${imageUrl}`;\n}\n"]}
1
+ {"version":3,"sources":["/home/ubuntu24-new/Dev/stormcloud-vp/lib/ui/OverlayRenderer.cjs","../../src/ui/OverlayRenderer.tsx","../../src/utils/overlays.ts"],"names":["__getProtoOf","__export","Object","getPrototypeOf","__hasOwnProp","prototype","hasOwnProperty","target","all","name","__defProp","__copyProps","to","from","except","desc","key","call","get","enumerable","__getOwnPropDesc","__getOwnPropNames","__toESM","mod","isNodeMode","__create","__esModule","value","__toCommonJS","OverlayRenderer_exports","OverlayRenderer","module","exports","import_react","require","OVERLAY_API_BASE","timeStringToSeconds","timeStr","parts","split","length","hours","parseInt","minutes","secStr","dotIdx","indexOf","seconds","substring","msFrag","ms","padEnd","num","parseFloat","isFinite","Math","max","isOverlayActive","overlay","currentTime","visible","startSec","start_time","durationSec","duration","SWIRL_HD_AUTHORING_WIDTH","SWIRL_HD_AUTHORING_HEIGHT","NAB_DEMO_NAME_PREFIX","overlayAuthoringDimensions","decodeWidth","decodeHeight","width","height","extR","x","extB","y","EPS","exceedsDecode","isNabDemo","startsWith","resolveImageUrl","apiBaseUrl","imageUrl","url","URL","import_jsx_runtime","computeVideoDimensions","video","nativeWidth","videoWidth","nativeHeight","videoHeight","displayWidth","offsetWidth","displayHeight","offsetHeight","videoAspect","displayAspect","renderWidth","renderHeight","offsetX","offsetY","image_url","jsx","content","display","alignItems","justifyContent","fontFamily","fontWeight","textAlign","boxSizing","wordBreak","pointerEvents","userSelect","lineHeight","text","xmlText","maxItems","replace","DOMParser","parser","parseFromString","stripped","Array","doc","querySelectorAll","map","item","querySelector","textContent","trim","i","Error","items","Map","cachedFetchRSSItems","rssUrl","expiresAt","now","cached","promise","fetchRSSItems","catch","err","RSS_CACHE_TTL_MS","encoded","origin","resp","data","encodeURIComponent","window","location","fetch","ok","includes","parseRSSXml","json","contents","ScrollerOverlay","cfg","scroller_config","uid","useId","useState","rssItems","setRssItems","rssLoading","setRssLoading","rssError","setRssError","rss_url","autoRefresh","updateInterval","max_items","auto_refresh","update_interval","useEffect","use_custom_text","custom_text","cancelled","then","finally","interval","setInterval","rssCache","delete","clearInterval","sep","separator_char","segments","show_description","description","push","show_timestamp","pubDate","Date","toLocaleDateString","show_author","author","show_category","category","join","scrollSpeed","scroll_speed","direction","fontSize","font_size","font_family","font_weight","textColor","text_color","bgColor","background_color","bgOpacity","background_opacity","borderRadius","border_radius","itemSpacing","item_spacing","pad","padding","label","labelLine2","label_line2","labelColor","label_color","labelTextColor","label_text_color","accentColor","accent_color","showAccentLine","show_accent_line","isEquitiesStrip","preset","isHorizontal","isReverse","fullText","animId","id","keyframes","jsxs","Fragment","children","style","flexDirection","overflow","backgroundColor","hexToRgb","color","background","flexShrink","flex","minHeight","gap","round","boxShadow","alignSelf","maxWidth","letterSpacing","textTransform","whiteSpace","opacity","position","minWidth","animation","willChange","copy","paddingRight","seg","React","margin","textShadow","paddingBottom","parseConfig","JSON","parse","ScoreBugOverlay","size","f","w","textOverflow","homeTeam","marginTop","homeScore","period","clock","awayTeam","awayScore","sponsorText","sponsorImageUrl","borderTop","src","alt","objectFit","LowerThirdOverlay","accentH","h"],"mappings":"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","sourcesContent":["\"use strict\";\nvar __create = Object.create;\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __getProtoOf = Object.getPrototypeOf;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(\n // If the importer is in node compatibility mode or this is not an ESM\n // file that has been converted to a CommonJS file using a Babel-\n // compatible transform (i.e. \"__esModule\" has not been set), then set\n // \"default\" to the CommonJS \"module.exports\" for node compatibility.\n isNodeMode || !mod || !mod.__esModule ? __defProp(target, \"default\", { value: mod, enumerable: true }) : target,\n mod\n));\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\n\n// src/ui/OverlayRenderer.tsx\nvar OverlayRenderer_exports = {};\n__export(OverlayRenderer_exports, {\n OverlayRenderer: () => OverlayRenderer\n});\nmodule.exports = __toCommonJS(OverlayRenderer_exports);\nvar import_react = __toESM(require(\"react\"), 1);\n\n// src/utils/overlays.ts\nvar OVERLAY_API_BASE = \"https://adstorm.co/api-adstorm-dev\";\nfunction timeStringToSeconds(timeStr) {\n if (!timeStr) return 0;\n const parts = timeStr.split(\":\");\n if (parts.length >= 3) {\n const hours = parseInt(parts[0] ?? \"0\", 10) || 0;\n const minutes = parseInt(parts[1] ?? \"0\", 10) || 0;\n const secStr = parts[2] ?? \"0\";\n const dotIdx = secStr.indexOf(\".\");\n const seconds = parseInt(dotIdx >= 0 ? secStr.substring(0, dotIdx) : secStr, 10) || 0;\n const msFrag = dotIdx >= 0 ? secStr.substring(dotIdx + 1) : \"\";\n const ms = msFrag ? parseInt(msFrag.padEnd(3, \"0\").substring(0, 3), 10) || 0 : 0;\n return hours * 3600 + minutes * 60 + seconds + ms / 1e3;\n }\n if (parts.length === 2) {\n const minutes = parseInt(parts[0] ?? \"0\", 10) || 0;\n const secStr = parts[1] ?? \"0\";\n const dotIdx = secStr.indexOf(\".\");\n const seconds = parseInt(dotIdx >= 0 ? secStr.substring(0, dotIdx) : secStr, 10) || 0;\n const msFrag = dotIdx >= 0 ? secStr.substring(dotIdx + 1) : \"\";\n const ms = msFrag ? parseInt(msFrag.padEnd(3, \"0\").substring(0, 3), 10) || 0 : 0;\n return minutes * 60 + seconds + ms / 1e3;\n }\n const num = parseFloat(timeStr);\n return isFinite(num) ? Math.max(0, num) : 0;\n}\nfunction isOverlayActive(overlay, currentTime) {\n if (!overlay.visible) return false;\n const startSec = timeStringToSeconds(overlay.start_time);\n const durationSec = timeStringToSeconds(overlay.duration);\n if (durationSec <= 0) return false;\n return currentTime >= startSec && currentTime < startSec + durationSec;\n}\nvar SWIRL_HD_AUTHORING_WIDTH = 1920;\nvar SWIRL_HD_AUTHORING_HEIGHT = 1080;\nvar NAB_DEMO_NAME_PREFIX = \"NAB Demo \\u2014 \";\nfunction overlayAuthoringDimensions(overlay, decodeWidth, decodeHeight) {\n if (!decodeWidth || !decodeHeight) {\n return {\n width: decodeWidth || SWIRL_HD_AUTHORING_WIDTH,\n height: decodeHeight || SWIRL_HD_AUTHORING_HEIGHT\n };\n }\n if (!overlay.visible) {\n return { width: decodeWidth, height: decodeHeight };\n }\n const extR = overlay.x + overlay.width;\n const extB = overlay.y + overlay.height;\n const EPS = 2;\n const exceedsDecode = extR > decodeWidth + EPS || extB > decodeHeight + EPS;\n const isNabDemo = overlay.name.startsWith(NAB_DEMO_NAME_PREFIX);\n if (exceedsDecode && isNabDemo) {\n return {\n width: SWIRL_HD_AUTHORING_WIDTH,\n height: SWIRL_HD_AUTHORING_HEIGHT\n };\n }\n return { width: decodeWidth, height: decodeHeight };\n}\nfunction resolveImageUrl(imageUrl, apiBaseUrl = OVERLAY_API_BASE) {\n if (!imageUrl) return \"\";\n if (imageUrl.startsWith(\"http://\") || imageUrl.startsWith(\"https://\")) {\n return imageUrl;\n }\n if (imageUrl.startsWith(\"/\")) {\n try {\n const url = new URL(apiBaseUrl);\n return `${url.origin}${imageUrl}`;\n } catch {\n return imageUrl;\n }\n }\n return `${apiBaseUrl}/${imageUrl}`;\n}\n\n// src/ui/OverlayRenderer.tsx\nvar import_jsx_runtime = require(\"react/jsx-runtime\");\nfunction computeVideoDimensions(video) {\n const nativeWidth = video.videoWidth;\n const nativeHeight = video.videoHeight;\n if (!nativeWidth || !nativeHeight) return null;\n const displayWidth = video.offsetWidth;\n const displayHeight = video.offsetHeight;\n if (!displayWidth || !displayHeight) return null;\n const videoAspect = nativeWidth / nativeHeight;\n const displayAspect = displayWidth / displayHeight;\n let renderWidth;\n let renderHeight;\n let offsetX;\n let offsetY;\n if (videoAspect > displayAspect) {\n renderWidth = displayWidth;\n renderHeight = displayWidth / videoAspect;\n offsetX = 0;\n offsetY = (displayHeight - renderHeight) / 2;\n } else {\n renderHeight = displayHeight;\n renderWidth = displayHeight * videoAspect;\n offsetX = (displayWidth - renderWidth) / 2;\n offsetY = 0;\n }\n return {\n nativeWidth,\n nativeHeight,\n displayWidth: renderWidth,\n displayHeight: renderHeight,\n offsetX,\n offsetY,\n scaleX: renderWidth / nativeWidth,\n scaleY: renderHeight / nativeHeight\n };\n}\nfunction ImageOverlay({ overlay }) {\n const src = resolveImageUrl(overlay.image_url || \"\");\n if (!src) return null;\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"img\",\n {\n src,\n alt: overlay.name,\n draggable: false,\n style: {\n width: \"100%\",\n height: \"100%\",\n objectFit: \"contain\",\n display: \"block\",\n pointerEvents: \"none\",\n userSelect: \"none\"\n }\n }\n );\n}\nfunction TextOverlay({ overlay }) {\n const text = overlay.content || \"\";\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: \"#ffffff\",\n fontSize: \"clamp(10px, 1.4vw, 20px)\",\n fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\",\n fontWeight: 600,\n textAlign: \"center\",\n padding: \"4px 8px\",\n boxSizing: \"border-box\",\n wordBreak: \"break-word\",\n textShadow: \"0 1px 4px rgba(0,0,0,0.7)\",\n pointerEvents: \"none\",\n userSelect: \"none\",\n lineHeight: 1.3\n },\n children: text\n }\n );\n}\nfunction parseRSSXml(xmlText, maxItems) {\n const stripped = xmlText.replace(/^<\\?xml[^?]*\\?>\\s*/, \"\");\n const parser = new DOMParser();\n const doc = parser.parseFromString(stripped, \"text/xml\");\n const items = Array.from(doc.querySelectorAll(\"item\")).map((item) => ({\n title: (item.querySelector(\"title\")?.textContent || \"\").replace(/<[^>]*>/g, \"\").trim(),\n description: (item.querySelector(\"description\")?.textContent || \"\").replace(/<[^>]*>/g, \"\").trim(),\n pubDate: item.querySelector(\"pubDate\")?.textContent || \"\",\n author: item.querySelector(\"author, dc\\\\:creator\")?.textContent || \"\",\n category: item.querySelector(\"category\")?.textContent || \"\"\n })).filter((i) => i.title).slice(0, maxItems);\n if (items.length === 0 && doc.querySelector(\"parsererror\")) {\n throw new Error(\"Invalid RSS XML\");\n }\n return items;\n}\nvar RSS_CACHE_TTL_MS = 6e4;\nvar rssCache = /* @__PURE__ */ new Map();\nfunction cachedFetchRSSItems(rssUrl, maxItems) {\n const now = Date.now();\n const cached = rssCache.get(rssUrl);\n if (cached && cached.expiresAt > now) return cached.promise;\n const promise = fetchRSSItems(rssUrl, maxItems).catch((err) => {\n rssCache.delete(rssUrl);\n throw err;\n });\n rssCache.set(rssUrl, { promise, expiresAt: now + RSS_CACHE_TTL_MS });\n return promise;\n}\nasync function fetchRSSItems(rssUrl, maxItems) {\n const encoded = encodeURIComponent(rssUrl);\n try {\n const origin = typeof window !== \"undefined\" ? window.location.origin : \"\";\n const resp = await fetch(`${origin}/api/rss-proxy?url=${encoded}`);\n if (resp.ok) {\n const text = await resp.text();\n if (text.includes(\"<item\")) return parseRSSXml(text, maxItems);\n }\n } catch {\n }\n try {\n const resp = await fetch(`https://api.allorigins.win/get?url=${encoded}`);\n if (resp.ok) {\n const data = await resp.json();\n if (data.contents) return parseRSSXml(data.contents, maxItems);\n }\n } catch {\n }\n try {\n const resp = await fetch(`https://corsproxy.io/?url=${encoded}`);\n if (resp.ok) {\n const text = await resp.text();\n if (text) return parseRSSXml(text, maxItems);\n }\n } catch {\n }\n throw new Error(\"All RSS proxies failed\");\n}\nfunction ScrollerOverlay({ overlay }) {\n const cfg = overlay.scroller_config;\n const uid = (0, import_react.useId)().replace(/:/g, \"\");\n const [rssItems, setRssItems] = (0, import_react.useState)([]);\n const [rssLoading, setRssLoading] = (0, import_react.useState)(true);\n const [rssError, setRssError] = (0, import_react.useState)(false);\n const rssUrl = cfg?.rss_url || \"\";\n const maxItems = cfg?.max_items ?? 10;\n const autoRefresh = cfg?.auto_refresh !== false;\n const updateInterval = cfg?.update_interval ?? 5;\n (0, import_react.useEffect)(() => {\n if (!rssUrl || cfg?.use_custom_text && cfg?.custom_text) {\n setRssLoading(false);\n return;\n }\n let cancelled = false;\n setRssLoading(true);\n setRssError(false);\n cachedFetchRSSItems(rssUrl, maxItems).then((items) => {\n if (!cancelled) {\n setRssItems(items);\n setRssError(false);\n }\n }).catch(() => {\n if (!cancelled) setRssError(true);\n }).finally(() => {\n if (!cancelled) setRssLoading(false);\n });\n return () => {\n cancelled = true;\n };\n }, [rssUrl, maxItems, cfg?.use_custom_text, cfg?.custom_text]);\n (0, import_react.useEffect)(() => {\n if (!rssUrl || !autoRefresh || cfg?.use_custom_text && cfg?.custom_text) return;\n const interval = setInterval(() => {\n rssCache.delete(rssUrl);\n cachedFetchRSSItems(rssUrl, maxItems).then((items) => {\n setRssItems(items);\n setRssError(false);\n }).catch(() => {\n });\n }, updateInterval * 60 * 1e3);\n return () => clearInterval(interval);\n }, [rssUrl, autoRefresh, updateInterval, maxItems, cfg?.use_custom_text, cfg?.custom_text]);\n const sep = cfg?.separator_char ?? \"\\u25C6\";\n let segments;\n if (cfg?.use_custom_text && cfg?.custom_text) {\n segments = [cfg.custom_text];\n } else if (rssItems.length > 0) {\n segments = rssItems.map((item) => {\n const parts = [];\n if (cfg?.show_title !== false && item.title) parts.push(item.title);\n if (cfg?.show_description && item.description) parts.push(item.description);\n if (cfg?.show_timestamp && item.pubDate) {\n try {\n parts.push(new Date(item.pubDate).toLocaleDateString());\n } catch {\n }\n }\n if (cfg?.show_author && item.author) parts.push(`\\u2014 ${item.author}`);\n if (cfg?.show_category && item.category) parts.push(`[${item.category}]`);\n return parts.join(\" \");\n });\n } else if (rssLoading) {\n segments = [\"Loading feed\\u2026\"];\n } else if (rssError) {\n segments = overlay.content ? [overlay.content] : [\"RSS feed unavailable\"];\n } else if (overlay.content) {\n segments = [overlay.content];\n } else {\n segments = rssUrl ? [\"Loading feed\\u2026\"] : [\"RSS Ticker\"];\n }\n const scrollSpeed = cfg?.scroll_speed ?? 40;\n const direction = cfg?.direction ?? \"left\";\n const fontSize = cfg?.font_size ?? 15;\n const fontFamily = cfg?.font_family || \"Roboto, 'Segoe UI', Arial, sans-serif\";\n const fontWeight = cfg?.font_weight || \"700\";\n const textColor = cfg?.text_color || \"#ffffff\";\n const bgColor = cfg?.background_color || \"#0d0d1a\";\n const bgOpacity = cfg?.background_opacity !== void 0 ? cfg.background_opacity / 100 : 0.95;\n const borderRadius = cfg?.border_radius ?? 0;\n const itemSpacing = cfg?.item_spacing ?? 60;\n const pad = cfg?.padding !== void 0 && cfg.padding >= 0 ? cfg.padding : 8;\n const label = cfg?.label ?? \"NEWS\";\n const labelLine2 = cfg?.label_line2 ?? \"\";\n const labelColor = cfg?.label_color ?? \"#f97316\";\n const labelTextColor = cfg?.label_text_color ?? \"#ffffff\";\n const accentColor = cfg?.accent_color ?? labelColor;\n const showAccentLine = cfg?.show_accent_line !== false;\n const isEquitiesStrip = cfg?.preset === \"equities_strip\";\n const isHorizontal = direction === \"left\" || direction === \"right\";\n const isReverse = direction === \"right\" || direction === \"down\";\n const fullText = segments.join(` ${sep} `);\n const durationSec = Math.max(6, fullText.length * 9 / scrollSpeed);\n const animId = `sc-ticker-${overlay.id}-${uid}`;\n const keyframes = isHorizontal ? `@keyframes ${animId} {\n ${isReverse ? \"0% { transform: translateX(-50%); } 100% { transform: translateX(0%); }\" : \"0% { transform: translateX(0); } 100% { transform: translateX(-50%); }\"}\n }` : `@keyframes ${animId} {\n ${isReverse ? \"0% { transform: translateY(-50%); } 100% { transform: translateY(0%); }\" : \"0% { transform: translateY(0); } 100% { transform: translateY(-50%); }\"}\n }`;\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"style\", { children: keyframes }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n overflow: \"hidden\",\n borderRadius: borderRadius > 0 ? `${borderRadius}px` : void 0,\n backgroundColor: `rgba(${hexToRgb(bgColor)}, ${bgOpacity})`,\n fontFamily,\n fontSize: `${fontSize}px`,\n fontWeight,\n color: textColor,\n pointerEvents: \"none\",\n userSelect: \"none\"\n },\n children: [\n showAccentLine && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n height: isEquitiesStrip ? 2 : 3,\n background: accentColor,\n flexShrink: 0,\n width: \"100%\"\n }\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n display: \"flex\",\n flex: 1,\n overflow: \"hidden\",\n minHeight: 0,\n alignItems: \"center\",\n padding: isEquitiesStrip ? `${Math.max(2, pad * 0.5)}px ${pad}px` : `${Math.max(4, pad * 0.75)}px ${pad}px`,\n gap: isEquitiesStrip ? Math.max(4, Math.round(pad * 0.75)) : Math.max(6, pad),\n boxSizing: \"border-box\"\n },\n children: [\n label && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n background: labelColor,\n color: labelTextColor,\n padding: isEquitiesStrip ? \"6px 12px\" : \"10px 14px\",\n display: \"flex\",\n flexDirection: isEquitiesStrip ? \"row\" : \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n textAlign: \"center\",\n gap: isEquitiesStrip ? 0 : 2,\n borderRadius: Math.max(2, borderRadius > 0 ? borderRadius : 6),\n boxShadow: isEquitiesStrip ? \"inset 0 1px 0 rgba(255,255,255,0.08)\" : \"0 2px 8px rgba(0,0,0,0.35)\",\n alignSelf: \"stretch\",\n maxWidth: isEquitiesStrip ? \"min(200px, 28%)\" : void 0\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"span\",\n {\n style: {\n fontWeight: isEquitiesStrip ? 700 : 800,\n fontSize: isEquitiesStrip ? \"0.82em\" : \"0.78em\",\n letterSpacing: isEquitiesStrip ? \"0.04em\" : \"0.08em\",\n lineHeight: 1.2,\n textTransform: isEquitiesStrip ? \"none\" : \"uppercase\",\n whiteSpace: isEquitiesStrip ? \"normal\" : \"nowrap\",\n textAlign: isEquitiesStrip ? \"left\" : \"center\"\n },\n children: label\n }\n ),\n labelLine2 && !isEquitiesStrip && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"span\",\n {\n style: {\n fontWeight: 600,\n fontSize: \"0.58em\",\n letterSpacing: \"0.06em\",\n lineHeight: 1.15,\n opacity: 0.92,\n whiteSpace: \"nowrap\"\n },\n children: labelLine2\n }\n )\n ]\n }\n ),\n label && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n width: isEquitiesStrip ? 1 : 2,\n alignSelf: \"stretch\",\n minHeight: isEquitiesStrip ? 20 : 24,\n background: accentColor,\n flexShrink: 0,\n borderRadius: 1,\n opacity: 0.85\n }\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n flex: 1,\n overflow: \"hidden\",\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n minWidth: 0\n },\n children: isHorizontal ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n display: \"inline-flex\",\n whiteSpace: \"nowrap\",\n animation: `${animId} ${durationSec}s linear infinite`,\n willChange: \"transform\"\n },\n children: [0, 1].map((copy) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"span\", { style: { paddingRight: `${itemSpacing}px` }, children: segments.map((seg, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react.default.Fragment, { children: [\n i > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"span\", { style: { opacity: 0.5, margin: \"0 8px\" }, children: sep }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"span\", { style: { textShadow: \"0 1px 3px rgba(0,0,0,0.6)\" }, children: seg })\n ] }, i)) }, copy))\n }\n ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n display: \"flex\",\n flexDirection: \"column\",\n whiteSpace: \"nowrap\",\n animation: `${animId} ${durationSec}s linear infinite`,\n willChange: \"transform\"\n },\n children: [0, 1].map(\n (copy) => segments.map((seg, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { paddingBottom: `${itemSpacing / 4}px` }, children: seg }, `${copy}-${i}`))\n )\n }\n )\n }\n )\n ]\n }\n )\n ]\n }\n )\n ] });\n}\nfunction parseConfig(content) {\n if (!content) return null;\n try {\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\nfunction ScoreBugOverlay({ overlay, size }) {\n const cfg = parseConfig(overlay.content);\n if (!cfg) return null;\n const f = Math.max(6, size.w * 0.052);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n width: \"100%\",\n height: \"100%\",\n borderRadius: Math.max(2, size.w * 0.028),\n display: \"flex\",\n flexDirection: \"column\",\n background: cfg.backgroundColor,\n color: cfg.textColor,\n fontFamily: \"'Inter', 'Roboto', 'Segoe UI', system-ui, sans-serif\",\n overflow: \"hidden\",\n pointerEvents: \"none\",\n userSelect: \"none\",\n fontSize: `${f}px`,\n boxShadow: \"0 8px 28px rgba(0,0,0,0.45)\"\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n flex: 1,\n display: \"flex\",\n alignItems: \"center\",\n padding: `${f * 0.42}px ${f * 0.85}px`,\n gap: f * 0.45,\n minHeight: 0\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { flex: 1, textAlign: \"center\", minWidth: 0, padding: `0 ${f * 0.15}px` }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n fontSize: \"1.05em\",\n fontWeight: 800,\n letterSpacing: \"0.02em\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\"\n },\n children: cfg.homeTeam\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1.75em\", fontWeight: 900, lineHeight: 1.05, marginTop: f * 0.08 }, children: cfg.homeScore })\n ] }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n fontSize: \"0.88em\",\n textAlign: \"center\",\n fontWeight: 600,\n opacity: 0.92,\n color: cfg.textColor,\n padding: `0 ${f * 0.5}px`,\n flexShrink: 0,\n lineHeight: 1.25,\n textTransform: \"uppercase\",\n letterSpacing: \"0.04em\"\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { children: cfg.period }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontWeight: 700, opacity: 1 }, children: cfg.clock })\n ]\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { flex: 1, textAlign: \"center\", minWidth: 0, padding: `0 ${f * 0.15}px` }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n fontSize: \"1.05em\",\n fontWeight: 800,\n letterSpacing: \"0.02em\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\"\n },\n children: cfg.awayTeam\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1.75em\", fontWeight: 900, lineHeight: 1.05, marginTop: f * 0.08 }, children: cfg.awayScore })\n ] })\n ]\n }\n ),\n (cfg.sponsorText || cfg.sponsorImageUrl) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n fontSize: \"0.72em\",\n textAlign: \"center\",\n fontWeight: 600,\n opacity: 0.88,\n padding: `${f * 0.34}px ${f * 0.55}px`,\n borderTop: `1px solid ${cfg.accentColor}55`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: f * 0.45,\n overflow: \"hidden\",\n letterSpacing: \"0.04em\",\n textTransform: \"uppercase\",\n background: `linear-gradient(180deg, rgba(0,0,0,0.12) 0%, rgba(0,0,0,0.22) 100%)`\n },\n children: [\n cfg.sponsorImageUrl && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"img\", { src: cfg.sponsorImageUrl, alt: \"sponsor\", style: { height: `${f * 1.35}px`, objectFit: \"contain\", flexShrink: 0 } }),\n cfg.sponsorText && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"span\", { style: { overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }, children: cfg.sponsorText })\n ]\n }\n )\n ]\n }\n );\n}\nfunction LowerThirdOverlay({ overlay, size }) {\n const cfg = parseConfig(overlay.content);\n if (!cfg) return null;\n const f = Math.max(6, size.w * 0.05);\n const accentH = Math.max(3, size.h * 0.038);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n width: \"100%\",\n height: \"100%\",\n borderRadius: Math.max(2, size.w * 0.018),\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"flex-end\",\n background: cfg.backgroundColor,\n color: cfg.textColor,\n fontFamily: \"'Inter', 'Roboto', 'Segoe UI', system-ui, sans-serif\",\n overflow: \"hidden\",\n pointerEvents: \"none\",\n userSelect: \"none\",\n fontSize: `${f}px`,\n boxShadow: \"0 10px 32px rgba(0,0,0,0.4)\"\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { width: \"100%\", height: accentH, backgroundColor: cfg.accentColor, flexShrink: 0 } }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n flex: 1,\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n padding: `${f * 0.62}px ${f * 1.05}px`,\n minHeight: 0,\n gap: f * 0.18\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n fontSize: \"1.28em\",\n fontWeight: 800,\n lineHeight: 1.22,\n letterSpacing: \"0.01em\",\n textShadow: \"0 2px 6px rgba(0,0,0,0.55)\"\n },\n children: cfg.headline\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n fontSize: \"0.94em\",\n fontWeight: 500,\n opacity: 0.92,\n lineHeight: 1.35,\n color: cfg.textColor\n },\n children: cfg.subtitle\n }\n )\n ]\n }\n ),\n (cfg.sponsorText || cfg.sponsorImageUrl) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n fontSize: \"0.68em\",\n fontWeight: 600,\n opacity: 0.72,\n padding: `${f * 0.28}px ${f * 1.05}px ${f * 0.48}px`,\n display: \"flex\",\n alignItems: \"center\",\n gap: f * 0.4,\n overflow: \"hidden\",\n letterSpacing: \"0.06em\",\n textTransform: \"uppercase\",\n borderTop: `1px solid rgba(255,255,255,0.08)`\n },\n children: [\n cfg.sponsorImageUrl && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"img\", { src: cfg.sponsorImageUrl, alt: \"sponsor\", style: { height: `${f * 1.25}px`, objectFit: \"contain\", flexShrink: 0 } }),\n cfg.sponsorText && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"span\", { style: { overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }, children: cfg.sponsorText })\n ]\n }\n )\n ]\n }\n );\n}\nfunction QrCodeOverlay({ overlay, size }) {\n const cfg = parseConfig(overlay.content);\n if (!cfg) return null;\n const qrSide = Math.max(32, Math.min(size.w, size.h) * 0.55);\n const qrUrl = `https://api.qrserver.com/v1/create-qr-code/?size=${Math.round(qrSide * 2)}x${Math.round(qrSide * 2)}&data=${encodeURIComponent(cfg.url || \"https://example.com\")}`;\n const f = Math.max(6, size.w * 0.06);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", flexDirection: \"column\", alignItems: \"center\", justifyContent: \"center\", gap: f * 0.4, background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", padding: f * 0.6, boxSizing: \"border-box\", pointerEvents: \"none\", userSelect: \"none\", overflow: \"hidden\" }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { flexShrink: 0, background: \"#fff\", borderRadius: Math.max(2, qrSide * 0.06), padding: Math.max(2, qrSide * 0.06), lineHeight: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"img\", { src: qrUrl, alt: \"QR Code\", style: { width: `${qrSide}px`, height: `${qrSide}px`, display: \"block\" } }) }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: `${f * 1.1}px`, fontWeight: 700, textAlign: \"center\", color: cfg.accentColor, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", width: \"100%\" }, children: cfg.ctaText }),\n cfg.description && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: `${f * 0.75}px`, opacity: 0.6, textAlign: \"center\", overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", width: \"100%\" }, children: cfg.description })\n ] });\n}\nfunction ComingUpNextOverlay({ overlay, size }) {\n const cfg = parseConfig(overlay.content);\n if (!cfg) return null;\n const f = Math.max(8, Math.min(size.h * 0.13, size.w * 0.048));\n const showSubtitle = size.h >= 60;\n const showThumbnail = false;\n const thumbW = 0;\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: {\n width: \"100%\",\n height: \"100%\",\n borderRadius: Math.max(2, size.w * 0.025),\n display: \"flex\",\n background: cfg.backgroundColor,\n color: cfg.textColor,\n fontFamily: \"'Arial', 'Helvetica Neue', Helvetica, sans-serif\",\n overflow: \"hidden\",\n pointerEvents: \"none\",\n userSelect: \"none\",\n fontSize: `${f}px`,\n WebkitFontSmoothing: \"antialiased\"\n }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { width: Math.max(3, size.w * 0.018), flexShrink: 0, backgroundColor: cfg.accentColor } }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: {\n flex: 1,\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n padding: `${f * 0.35}px ${f * 0.75}px`,\n minWidth: 0,\n gap: `${f * 0.08}px`\n }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: {\n fontSize: \"0.7em\",\n fontWeight: 700,\n textTransform: \"uppercase\",\n letterSpacing: \"0.09em\",\n color: cfg.accentColor,\n lineHeight: 1\n }, children: \"Coming Up Next\" }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: {\n fontSize: \"1.2em\",\n fontWeight: 700,\n lineHeight: 1.2,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\"\n }, children: cfg.title }),\n showSubtitle && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: {\n fontSize: \"0.82em\",\n opacity: 0.65,\n lineHeight: 1.1,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\"\n }, children: cfg.subtitle }),\n cfg.scheduledTime && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: {\n fontSize: \"0.9em\",\n fontWeight: 700,\n color: cfg.accentColor,\n lineHeight: 1\n }, children: cfg.scheduledTime })\n ] }),\n showThumbnail && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { flexShrink: 0, width: `${thumbW}px`, overflow: \"hidden\" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"img\",\n {\n src: cfg.thumbnailUrl,\n alt: \"\",\n style: { width: \"100%\", height: \"100%\", objectFit: \"cover\", display: \"block\" }\n }\n ) })\n ] });\n}\nfunction ContextualTriggerOverlay({ overlay, size }) {\n const cfg = parseConfig(overlay.content);\n if (!cfg) return null;\n const icons = { alert: \"\\u26A0\\uFE0F\", celebration: \"\\u{1F389}\", info: \"\\u2139\\uFE0F\", warning: \"\\u{1F514}\" };\n const f = Math.max(6, size.w * 0.05);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", alignItems: \"center\", gap: f * 0.8, padding: `0 ${f * 1.2}px`, background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", borderLeft: `${Math.max(2, size.w * 0.02)}px solid ${cfg.accentColor}`, boxSizing: \"border-box\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"span\", { style: { fontSize: \"2em\", flexShrink: 0 }, children: icons[cfg.iconType] || \"\\u26A1\" }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { flex: 1, minWidth: 0 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1.3em\", fontWeight: 700, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }, children: cfg.headline }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.9em\", opacity: 0.7, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }, children: cfg.message })\n ] })\n ] });\n}\nfunction OddsBettingOverlay({ overlay, size }) {\n const cfg = parseConfig(overlay.content);\n if (!cfg) return null;\n const f = Math.max(6, size.w * 0.052);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", flexDirection: \"column\", padding: f * 0.8, background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", boxSizing: \"border-box\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.9em\", fontWeight: 700, textTransform: \"uppercase\", letterSpacing: \"0.05em\", color: cfg.accentColor, marginBottom: f * 0.4 }, children: cfg.eventTitle }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { flex: 1, display: \"flex\", flexDirection: \"column\", gap: f * 0.2, justifyContent: \"center\" }, children: (cfg.options || []).slice(0, 5).map((opt, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { display: \"flex\", justifyContent: \"space-between\", alignItems: \"center\", padding: `${f * 0.2}px ${f * 0.6}px`, borderRadius: Math.max(2, f * 0.3), background: `${cfg.accentColor}15`, fontSize: \"1em\" }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"span\", { style: { overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", flex: 1 }, children: opt.label }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"span\", { style: { fontWeight: 700, marginLeft: f * 0.8, flexShrink: 0, color: cfg.accentColor }, children: opt.odds })\n ] }, i)) }),\n cfg.sponsorText && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.7em\", opacity: 0.4, textAlign: \"center\", marginTop: f * 0.4 }, children: cfg.sponsorText })\n ] });\n}\nfunction BreakingNewsOverlay({ overlay, size }) {\n const cfg = parseConfig(overlay.content);\n if (!cfg) return null;\n const urgencyColors = { breaking: \"#dc2626\", urgent: \"#ea580c\", normal: \"#2563eb\" };\n const labelBg = urgencyColors[cfg.urgency] || urgencyColors.normal;\n const label = cfg.urgency === \"breaking\" ? \"BREAKING\" : cfg.urgency === \"urgent\" ? \"URGENT\" : \"NEWS\";\n const f = Math.max(6, size.w * 0.05);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.02), display: \"flex\", alignItems: \"center\", background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", overflow: \"hidden\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { padding: `0 ${f * 0.8}px`, height: \"100%\", display: \"flex\", alignItems: \"center\", background: labelBg, color: \"#fff\", fontSize: \"1em\", fontWeight: 900, textTransform: \"uppercase\", letterSpacing: \"0.05em\", flexShrink: 0 }, children: label }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { flex: 1, padding: `0 ${f * 1}px`, minWidth: 0 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1.3em\", fontWeight: 700, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }, children: cfg.headline }),\n cfg.body && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.9em\", opacity: 0.7, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }, children: cfg.body })\n ] })\n ] });\n}\nfunction calcCountdownRemaining(targetTime) {\n const diff = Math.max(0, new Date(targetTime).getTime() - Date.now());\n return {\n d: Math.floor(diff / 864e5),\n h: Math.floor(diff % 864e5 / 36e5),\n m: Math.floor(diff % 36e5 / 6e4),\n s: Math.floor(diff % 6e4 / 1e3),\n expired: diff === 0\n };\n}\nfunction CountdownOverlay({ overlay, size }) {\n const cfg = parseConfig(overlay.content);\n const targetTime = cfg?.targetTime ?? \"\";\n const [remaining, setRemaining] = (0, import_react.useState)(\n () => targetTime ? calcCountdownRemaining(targetTime) : { d: 0, h: 0, m: 0, s: 0, expired: false }\n );\n (0, import_react.useEffect)(() => {\n if (!targetTime) return;\n setRemaining(calcCountdownRemaining(targetTime));\n const id = setInterval(() => setRemaining(calcCountdownRemaining(targetTime)), 1e3);\n return () => clearInterval(id);\n }, [targetTime]);\n if (!cfg) return null;\n const f = Math.max(6, size.w * 0.055);\n const pad = (n) => String(n).padStart(2, \"0\");\n const units = [\n { show: cfg.showDays, value: pad(remaining.d), label: \"DAYS\" },\n { show: cfg.showHours, value: pad(remaining.h), label: \"HRS\" },\n { show: cfg.showMinutes, value: pad(remaining.m), label: \"MIN\" },\n { show: cfg.showSeconds, value: pad(remaining.s), label: \"SEC\" }\n ];\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", flexDirection: \"column\", alignItems: \"center\", justifyContent: \"center\", padding: f * 0.8, background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", boxSizing: \"border-box\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.8em\", fontWeight: 600, textTransform: \"uppercase\", letterSpacing: \"0.05em\", color: cfg.accentColor, marginBottom: f * 0.4 }, children: cfg.eventName }),\n remaining.expired ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1em\", fontWeight: 700, opacity: 0.6 }, children: cfg.message || \"Event ended\" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { display: \"flex\", gap: f * 0.6, alignItems: \"center\" }, children: units.filter((u) => u.show).map((u, i, arr) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react.default.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { textAlign: \"center\" }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"2em\", fontWeight: 900, lineHeight: 1, borderRadius: Math.max(2, f * 0.4), padding: `${f * 0.2}px ${f * 0.4}px`, background: `${cfg.accentColor}20` }, children: u.value }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.5em\", opacity: 0.5, marginTop: f * 0.2 }, children: u.label })\n ] }),\n i < arr.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1.8em\", fontWeight: 700, opacity: 0.3 }, children: \":\" })\n ] }, u.label)) }),\n !remaining.expired && cfg.message && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.8em\", opacity: 0.6, marginTop: f * 0.4, textAlign: \"center\" }, children: cfg.message })\n ] });\n}\nfunction ShapeOverlay({ overlay, size }) {\n const f = Math.max(6, size.w * 0.05);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.03), background: \"rgba(99, 102, 241, 0.2)\", border: \"2px solid rgba(99, 102, 241, 0.4)\", display: \"flex\", alignItems: \"center\", justifyContent: \"center\", pointerEvents: \"none\", userSelect: \"none\" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: `${f}px`, fontWeight: 500, color: \"rgba(163, 163, 163, 0.8)\", textTransform: \"uppercase\" }, children: overlay.name }) });\n}\nfunction hexToRgb(hex) {\n if (!hex || !hex.startsWith(\"#\")) return \"0,0,0\";\n const clean = hex.slice(1);\n const num = parseInt(clean.length === 3 ? clean.replace(/./g, \"$&$&\") : clean, 16);\n return `${num >> 16 & 255},${num >> 8 & 255},${num & 255}`;\n}\nvar FADE_DURATION_MS = 1e3;\nvar SHOWCASE_CYCLE_MS_DEFAULT = 6e4;\nvar SHOWCASE_POP_IN_MS = 420;\nvar SHOWCASE_STEADY_END_MS = 46e3;\nvar SHOWCASE_POP_OUT_MS = 450;\nvar SHOWCASE_POP_OUT_END_MS = SHOWCASE_STEADY_END_MS + SHOWCASE_POP_OUT_MS;\nfunction easeOutCubic(t) {\n const u = 1 - t;\n return 1 - u * u * u;\n}\nfunction easeInCubic(t) {\n return t * t * t;\n}\nfunction easeOutBack(t) {\n const c1 = 1.70158;\n const c3 = c1 + 1;\n return 1 + c3 * (t - 1) ** 3 + c1 * (t - 1) ** 2;\n}\nfunction showcaseOpacity(phase) {\n if (phase < SHOWCASE_POP_IN_MS) return easeOutCubic(phase / SHOWCASE_POP_IN_MS);\n if (phase >= SHOWCASE_STEADY_END_MS && phase < SHOWCASE_POP_OUT_END_MS) {\n return 1 - easeInCubic((phase - SHOWCASE_STEADY_END_MS) / SHOWCASE_POP_OUT_MS);\n }\n return 1;\n}\nfunction showcaseScale(phase) {\n if (phase < SHOWCASE_POP_IN_MS) {\n return Math.min(\n 1,\n 0.78 + 0.22 * easeOutBack(phase / SHOWCASE_POP_IN_MS)\n );\n }\n if (phase >= SHOWCASE_STEADY_END_MS && phase < SHOWCASE_POP_OUT_END_MS) {\n return 1 - 0.14 * easeInCubic((phase - SHOWCASE_STEADY_END_MS) / SHOWCASE_POP_OUT_MS);\n }\n return 1;\n}\nfunction useShowcasePhase(enabled, cycleMs) {\n const [phase, setPhase] = (0, import_react.useState)(0);\n (0, import_react.useEffect)(() => {\n if (!enabled) return;\n setPhase(Date.now() % cycleMs);\n const id = window.setInterval(() => {\n setPhase(Date.now() % cycleMs);\n }, 48);\n return () => clearInterval(id);\n }, [enabled, cycleMs]);\n return phase;\n}\nvar OverlayRenderer = ({\n overlays,\n currentTime,\n videoRef,\n coordinateSpace,\n showcaseMode = false,\n showcaseCycleMs = SHOWCASE_CYCLE_MS_DEFAULT\n}) => {\n const [dims, setDims] = (0, import_react.useState)(null);\n const rafRef = (0, import_react.useRef)(null);\n const [fadeMap, setFadeMap] = (0, import_react.useState)(/* @__PURE__ */ new Map());\n const removeTimers = (0, import_react.useRef)(/* @__PURE__ */ new Map());\n const showcasePhase = useShowcasePhase(showcaseMode, showcaseCycleMs);\n const updateDims = (0, import_react.useCallback)(() => {\n const video = videoRef.current;\n if (video) {\n const computed = computeVideoDimensions(video);\n setDims((prev) => {\n if (!computed || prev && prev.nativeWidth === computed.nativeWidth && prev.nativeHeight === computed.nativeHeight && prev.displayWidth === computed.displayWidth && prev.displayHeight === computed.displayHeight && prev.offsetX === computed.offsetX && prev.offsetY === computed.offsetY) {\n return prev;\n }\n return computed;\n });\n }\n }, [videoRef]);\n (0, import_react.useEffect)(() => {\n updateDims();\n const interval = setInterval(updateDims, 500);\n const handleResize = () => {\n if (rafRef.current) cancelAnimationFrame(rafRef.current);\n rafRef.current = requestAnimationFrame(updateDims);\n };\n window.addEventListener(\"resize\", handleResize);\n return () => {\n clearInterval(interval);\n window.removeEventListener(\"resize\", handleResize);\n if (rafRef.current) cancelAnimationFrame(rafRef.current);\n };\n }, [updateDims]);\n const activeOverlays = (0, import_react.useMemo)(() => {\n if (showcaseMode) {\n return overlays.filter((o) => {\n if (!o.visible) return false;\n return showcasePhase < SHOWCASE_POP_OUT_END_MS;\n });\n }\n return overlays.filter((o) => isOverlayActive(o, currentTime));\n }, [overlays, currentTime, showcaseMode, showcasePhase]);\n const activeBeatIds = (0, import_react.useMemo)(\n () => new Set(activeOverlays.map((o) => o.id)),\n [activeOverlays]\n );\n (0, import_react.useLayoutEffect)(() => {\n const activeIds = new Set(activeOverlays.map((o) => o.id));\n setFadeMap((prev) => {\n const next = new Map(prev);\n for (const overlay of activeOverlays) {\n if (!next.has(overlay.id)) {\n next.set(overlay.id, { overlay, visible: false });\n } else {\n const existing = next.get(overlay.id);\n next.set(overlay.id, { ...existing, overlay });\n }\n }\n for (const [id, state] of next) {\n if (!activeIds.has(id) && state.visible) {\n next.set(id, { ...state, visible: false });\n if (!removeTimers.current.has(id)) {\n const timer = setTimeout(() => {\n setFadeMap((m) => {\n const updated = new Map(m);\n updated.delete(id);\n return updated;\n });\n removeTimers.current.delete(id);\n }, FADE_DURATION_MS);\n removeTimers.current.set(id, timer);\n }\n } else if (!activeIds.has(id) && !state.visible) {\n }\n }\n return next;\n });\n }, [activeOverlays]);\n (0, import_react.useEffect)(() => {\n const toFadeIn = [];\n for (const [id, state] of fadeMap) {\n if (!state.visible) {\n const isActive = activeOverlays.some((o) => o.id === id);\n if (isActive) toFadeIn.push(id);\n }\n }\n if (toFadeIn.length === 0) return;\n const raf = requestAnimationFrame(() => {\n setFadeMap((prev) => {\n const next = new Map(prev);\n for (const id of toFadeIn) {\n const state = next.get(id);\n if (state) next.set(id, { ...state, visible: true });\n }\n return next;\n });\n });\n return () => cancelAnimationFrame(raf);\n }, [fadeMap, activeOverlays]);\n (0, import_react.useEffect)(() => {\n return () => {\n for (const timer of removeTimers.current.values()) clearTimeout(timer);\n };\n }, []);\n if (!dims || fadeMap.size === 0) return null;\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n \"aria-hidden\": \"true\",\n style: {\n position: \"absolute\",\n left: `${dims.offsetX}px`,\n top: `${dims.offsetY}px`,\n width: `${dims.displayWidth}px`,\n height: `${dims.displayHeight}px`,\n pointerEvents: \"none\",\n overflow: \"hidden\",\n zIndex: 8\n },\n children: [...fadeMap.values()].map(({ overlay, visible }) => {\n const uniform = coordinateSpace && coordinateSpace.width > 0 && coordinateSpace.height > 0;\n const auth = uniform ? { width: coordinateSpace.width, height: coordinateSpace.height } : overlayAuthoringDimensions(\n overlay,\n dims.nativeWidth,\n dims.nativeHeight\n );\n const scaleX = dims.displayWidth / auth.width;\n const scaleY = dims.displayHeight / auth.height;\n const left = overlay.x * scaleX;\n const top = overlay.y * scaleY;\n const width = overlay.width * scaleX;\n const height = overlay.height * scaleY;\n const baseOpacity = Math.max(0, Math.min(100, overlay.opacity)) / 100;\n const inShowcaseBeat = showcaseMode && activeBeatIds.has(overlay.id);\n const useShowcasePop = inShowcaseBeat;\n const opacity = useShowcasePop ? baseOpacity * showcaseOpacity(showcasePhase) : visible ? baseOpacity : 0;\n const popScale = useShowcasePop ? showcaseScale(showcasePhase) : 1;\n const sz = { w: width, h: height };\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n left: `${left}px`,\n top: `${top}px`,\n width: `${width}px`,\n height: `${height}px`,\n opacity,\n transition: useShowcasePop ? \"none\" : `opacity ${FADE_DURATION_MS}ms ease`,\n transform: showcaseMode && useShowcasePop ? `scale(${popScale})` : void 0,\n transformOrigin: showcaseMode && useShowcasePop ? \"center center\" : void 0,\n zIndex: overlay.z_index,\n overflow: \"hidden\"\n },\n children: [\n overlay.type === \"image\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ImageOverlay, { overlay }),\n overlay.type === \"text\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TextOverlay, { overlay }),\n overlay.type === \"scroller\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScrollerOverlay, { overlay }),\n overlay.type === \"shape\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ShapeOverlay, { overlay, size: sz }),\n overlay.type === \"score_bug\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScoreBugOverlay, { overlay, size: sz }),\n overlay.type === \"lower_third\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LowerThirdOverlay, { overlay, size: sz }),\n overlay.type === \"qr_code\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(QrCodeOverlay, { overlay, size: sz }),\n overlay.type === \"coming_up_next\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ComingUpNextOverlay, { overlay, size: sz }),\n overlay.type === \"contextual_trigger\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContextualTriggerOverlay, { overlay, size: sz }),\n overlay.type === \"odds_betting\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(OddsBettingOverlay, { overlay, size: sz }),\n overlay.type === \"breaking_news\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BreakingNewsOverlay, { overlay, size: sz }),\n overlay.type === \"countdown\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CountdownOverlay, { overlay, size: sz })\n ]\n },\n overlay.id\n );\n })\n }\n );\n};\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n OverlayRenderer\n});\n","import React, {\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n useCallback,\n useMemo,\n useId,\n} from \"react\";\nimport {\n type SwirlOverlay,\n isOverlayActive,\n resolveImageUrl,\n overlayAuthoringDimensions,\n} from \"../utils/overlays\";\n\ninterface VideoDimensions {\n nativeWidth: number;\n nativeHeight: number;\n displayWidth: number;\n displayHeight: number;\n offsetX: number;\n offsetY: number;\n scaleX: number;\n scaleY: number;\n}\n\ninterface OverlayRendererProps {\n overlays: SwirlOverlay[];\n currentTime: number;\n videoRef: React.RefObject<HTMLVideoElement | null>;\n coordinateSpace?: { width: number; height: number } | null;\n showcaseMode?: boolean;\n showcaseCycleMs?: number;\n}\n\nfunction computeVideoDimensions(\n video: HTMLVideoElement\n): VideoDimensions | null {\n const nativeWidth = video.videoWidth;\n const nativeHeight = video.videoHeight;\n if (!nativeWidth || !nativeHeight) return null;\n\n const displayWidth = video.offsetWidth;\n const displayHeight = video.offsetHeight;\n if (!displayWidth || !displayHeight) return null;\n\n const videoAspect = nativeWidth / nativeHeight;\n const displayAspect = displayWidth / displayHeight;\n\n let renderWidth: number;\n let renderHeight: number;\n let offsetX: number;\n let offsetY: number;\n\n if (videoAspect > displayAspect) {\n renderWidth = displayWidth;\n renderHeight = displayWidth / videoAspect;\n offsetX = 0;\n offsetY = (displayHeight - renderHeight) / 2;\n } else {\n renderHeight = displayHeight;\n renderWidth = displayHeight * videoAspect;\n offsetX = (displayWidth - renderWidth) / 2;\n offsetY = 0;\n }\n\n return {\n nativeWidth,\n nativeHeight,\n displayWidth: renderWidth,\n displayHeight: renderHeight,\n offsetX,\n offsetY,\n scaleX: renderWidth / nativeWidth,\n scaleY: renderHeight / nativeHeight,\n };\n}\n\nfunction ImageOverlay({ overlay }: { overlay: SwirlOverlay }) {\n const src = resolveImageUrl(overlay.image_url || \"\");\n if (!src) return null;\n return (\n <img\n src={src}\n alt={overlay.name}\n draggable={false}\n style={{\n width: \"100%\",\n height: \"100%\",\n objectFit: \"contain\",\n display: \"block\",\n pointerEvents: \"none\",\n userSelect: \"none\",\n }}\n />\n );\n}\n\nfunction TextOverlay({ overlay }: { overlay: SwirlOverlay }) {\n const text = overlay.content || \"\";\n return (\n <div\n style={{\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: \"#ffffff\",\n fontSize: \"clamp(10px, 1.4vw, 20px)\",\n fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\",\n fontWeight: 600,\n textAlign: \"center\",\n padding: \"4px 8px\",\n boxSizing: \"border-box\",\n wordBreak: \"break-word\",\n textShadow: \"0 1px 4px rgba(0,0,0,0.7)\",\n pointerEvents: \"none\",\n userSelect: \"none\",\n lineHeight: 1.3,\n }}\n >\n {text}\n </div>\n );\n}\n\ninterface RSSItem {\n title: string;\n description: string;\n pubDate: string;\n author: string;\n category: string;\n}\n\nfunction parseRSSXml(xmlText: string, maxItems: number): RSSItem[] {\n const stripped = xmlText.replace(/^<\\?xml[^?]*\\?>\\s*/, \"\");\n const parser = new DOMParser();\n const doc = parser.parseFromString(stripped, \"text/xml\");\n const items = Array.from(doc.querySelectorAll(\"item\"))\n .map((item) => ({\n title: (item.querySelector(\"title\")?.textContent || \"\").replace(/<[^>]*>/g, \"\").trim(),\n description: (item.querySelector(\"description\")?.textContent || \"\").replace(/<[^>]*>/g, \"\").trim(),\n pubDate: item.querySelector(\"pubDate\")?.textContent || \"\",\n author: item.querySelector(\"author, dc\\\\:creator\")?.textContent || \"\",\n category: item.querySelector(\"category\")?.textContent || \"\",\n }))\n .filter((i) => i.title)\n .slice(0, maxItems);\n if (items.length === 0 && doc.querySelector(\"parsererror\")) {\n throw new Error(\"Invalid RSS XML\");\n }\n return items;\n}\n\nconst RSS_CACHE_TTL_MS = 60_000;\nconst rssCache = new Map<string, { promise: Promise<RSSItem[]>; expiresAt: number }>();\n\nfunction cachedFetchRSSItems(rssUrl: string, maxItems: number): Promise<RSSItem[]> {\n const now = Date.now();\n const cached = rssCache.get(rssUrl);\n if (cached && cached.expiresAt > now) return cached.promise;\n const promise = fetchRSSItems(rssUrl, maxItems).catch((err) => {\n rssCache.delete(rssUrl);\n throw err;\n });\n rssCache.set(rssUrl, { promise, expiresAt: now + RSS_CACHE_TTL_MS });\n return promise;\n}\n\nasync function fetchRSSItems(rssUrl: string, maxItems: number): Promise<RSSItem[]> {\n const encoded = encodeURIComponent(rssUrl);\n\n try {\n const origin = typeof window !== \"undefined\" ? window.location.origin : \"\";\n const resp = await fetch(`${origin}/api/rss-proxy?url=${encoded}`);\n if (resp.ok) {\n const text = await resp.text();\n if (text.includes(\"<item\")) return parseRSSXml(text, maxItems);\n }\n } catch { /* fall through */ }\n\n try {\n const resp = await fetch(`https://api.allorigins.win/get?url=${encoded}`);\n if (resp.ok) {\n const data = await resp.json();\n if (data.contents) return parseRSSXml(data.contents, maxItems);\n }\n } catch { /* fall through */ }\n\n try {\n const resp = await fetch(`https://corsproxy.io/?url=${encoded}`);\n if (resp.ok) {\n const text = await resp.text();\n if (text) return parseRSSXml(text, maxItems);\n }\n } catch { /* fall through */ }\n\n throw new Error(\"All RSS proxies failed\");\n}\n\nfunction ScrollerOverlay({ overlay }: { overlay: SwirlOverlay }) {\n const cfg = overlay.scroller_config;\n const uid = useId().replace(/:/g, \"\");\n\n const [rssItems, setRssItems] = useState<RSSItem[]>([]);\n const [rssLoading, setRssLoading] = useState(true);\n const [rssError, setRssError] = useState(false);\n\n const rssUrl = cfg?.rss_url || \"\";\n const maxItems = cfg?.max_items ?? 10;\n const autoRefresh = cfg?.auto_refresh !== false;\n const updateInterval = cfg?.update_interval ?? 5;\n\n useEffect(() => {\n if (!rssUrl || (cfg?.use_custom_text && cfg?.custom_text)) {\n setRssLoading(false);\n return;\n }\n let cancelled = false;\n setRssLoading(true);\n setRssError(false);\n cachedFetchRSSItems(rssUrl, maxItems)\n .then((items) => { if (!cancelled) { setRssItems(items); setRssError(false); } })\n .catch(() => { if (!cancelled) setRssError(true); })\n .finally(() => { if (!cancelled) setRssLoading(false); });\n return () => { cancelled = true; };\n }, [rssUrl, maxItems, cfg?.use_custom_text, cfg?.custom_text]);\n\n useEffect(() => {\n if (!rssUrl || !autoRefresh || (cfg?.use_custom_text && cfg?.custom_text)) return;\n const interval = setInterval(() => {\n rssCache.delete(rssUrl);\n cachedFetchRSSItems(rssUrl, maxItems)\n .then((items) => { setRssItems(items); setRssError(false); })\n .catch(() => { /* keep showing last good items */ });\n }, updateInterval * 60 * 1000);\n return () => clearInterval(interval);\n }, [rssUrl, autoRefresh, updateInterval, maxItems, cfg?.use_custom_text, cfg?.custom_text]);\n\n const sep = cfg?.separator_char ?? \"◆\";\n\n let segments: string[];\n if (cfg?.use_custom_text && cfg?.custom_text) {\n segments = [cfg.custom_text];\n } else if (rssItems.length > 0) {\n segments = rssItems.map((item) => {\n const parts: string[] = [];\n if (cfg?.show_title !== false && item.title) parts.push(item.title);\n if (cfg?.show_description && item.description) parts.push(item.description);\n if (cfg?.show_timestamp && item.pubDate) {\n try { parts.push(new Date(item.pubDate).toLocaleDateString()); } catch { /* ignore */ }\n }\n if (cfg?.show_author && item.author) parts.push(`— ${item.author}`);\n if (cfg?.show_category && item.category) parts.push(`[${item.category}]`);\n return parts.join(\" \");\n });\n } else if (rssLoading) {\n segments = [\"Loading feed…\"];\n } else if (rssError) {\n segments = overlay.content ? [overlay.content] : [\"RSS feed unavailable\"];\n } else if (overlay.content) {\n segments = [overlay.content];\n } else {\n segments = rssUrl ? [\"Loading feed…\"] : [\"RSS Ticker\"];\n }\n\n const scrollSpeed = cfg?.scroll_speed ?? 40;\n const direction = cfg?.direction ?? \"left\";\n const fontSize = cfg?.font_size ?? 15;\n const fontFamily = cfg?.font_family || \"Roboto, 'Segoe UI', Arial, sans-serif\";\n const fontWeight = cfg?.font_weight || \"700\";\n const textColor = cfg?.text_color || \"#ffffff\";\n const bgColor = cfg?.background_color || \"#0d0d1a\";\n const bgOpacity = cfg?.background_opacity !== undefined ? cfg.background_opacity / 100 : 0.95;\n const borderRadius = cfg?.border_radius ?? 0;\n const itemSpacing = cfg?.item_spacing ?? 60;\n const pad = cfg?.padding !== undefined && cfg.padding >= 0 ? cfg.padding : 8;\n\n const label = cfg?.label ?? \"NEWS\";\n const labelLine2 = cfg?.label_line2 ?? \"\";\n const labelColor = cfg?.label_color ?? \"#f97316\";\n const labelTextColor = cfg?.label_text_color ?? \"#ffffff\";\n const accentColor = cfg?.accent_color ?? labelColor;\n const showAccentLine = cfg?.show_accent_line !== false;\n const isEquitiesStrip = cfg?.preset === \"equities_strip\";\n\n const isHorizontal = direction === \"left\" || direction === \"right\";\n const isReverse = direction === \"right\" || direction === \"down\";\n\n const fullText = segments.join(` ${sep} `);\n const durationSec = Math.max(6, (fullText.length * 9) / scrollSpeed);\n\n const animId = `sc-ticker-${overlay.id}-${uid}`;\n const keyframes = isHorizontal\n ? `@keyframes ${animId} {\n ${isReverse\n ? \"0% { transform: translateX(-50%); } 100% { transform: translateX(0%); }\"\n : \"0% { transform: translateX(0); } 100% { transform: translateX(-50%); }\"}\n }`\n : `@keyframes ${animId} {\n ${isReverse\n ? \"0% { transform: translateY(-50%); } 100% { transform: translateY(0%); }\"\n : \"0% { transform: translateY(0); } 100% { transform: translateY(-50%); }\"}\n }`;\n\n return (\n <>\n <style>{keyframes}</style>\n <div\n style={{\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n overflow: \"hidden\",\n borderRadius: borderRadius > 0 ? `${borderRadius}px` : undefined,\n backgroundColor: `rgba(${hexToRgb(bgColor)}, ${bgOpacity})`,\n fontFamily,\n fontSize: `${fontSize}px`,\n fontWeight,\n color: textColor,\n pointerEvents: \"none\",\n userSelect: \"none\",\n }}\n >\n {showAccentLine && (\n <div\n style={{\n height: isEquitiesStrip ? 2 : 3,\n background: accentColor,\n flexShrink: 0,\n width: \"100%\",\n }}\n />\n )}\n\n <div\n style={{\n display: \"flex\",\n flex: 1,\n overflow: \"hidden\",\n minHeight: 0,\n alignItems: \"center\",\n padding: isEquitiesStrip\n ? `${Math.max(2, pad * 0.5)}px ${pad}px`\n : `${Math.max(4, pad * 0.75)}px ${pad}px`,\n gap: isEquitiesStrip ? Math.max(4, Math.round(pad * 0.75)) : Math.max(6, pad),\n boxSizing: \"border-box\",\n }}\n >\n {label && (\n <div\n style={{\n background: labelColor,\n color: labelTextColor,\n padding: isEquitiesStrip ? \"6px 12px\" : \"10px 14px\",\n display: \"flex\",\n flexDirection: isEquitiesStrip ? \"row\" : \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n textAlign: \"center\",\n gap: isEquitiesStrip ? 0 : 2,\n borderRadius: Math.max(2, borderRadius > 0 ? borderRadius : 6),\n boxShadow: isEquitiesStrip\n ? \"inset 0 1px 0 rgba(255,255,255,0.08)\"\n : \"0 2px 8px rgba(0,0,0,0.35)\",\n alignSelf: \"stretch\",\n maxWidth: isEquitiesStrip ? \"min(200px, 28%)\" : undefined,\n }}\n >\n <span\n style={{\n fontWeight: isEquitiesStrip ? 700 : 800,\n fontSize: isEquitiesStrip ? \"0.82em\" : \"0.78em\",\n letterSpacing: isEquitiesStrip ? \"0.04em\" : \"0.08em\",\n lineHeight: 1.2,\n textTransform: isEquitiesStrip ? \"none\" : \"uppercase\",\n whiteSpace: isEquitiesStrip ? \"normal\" : \"nowrap\",\n textAlign: isEquitiesStrip ? \"left\" : \"center\",\n }}\n >\n {label}\n </span>\n {labelLine2 && !isEquitiesStrip && (\n <span\n style={{\n fontWeight: 600,\n fontSize: \"0.58em\",\n letterSpacing: \"0.06em\",\n lineHeight: 1.15,\n opacity: 0.92,\n whiteSpace: \"nowrap\",\n }}\n >\n {labelLine2}\n </span>\n )}\n </div>\n )}\n\n {label && (\n <div\n style={{\n width: isEquitiesStrip ? 1 : 2,\n alignSelf: \"stretch\",\n minHeight: isEquitiesStrip ? 20 : 24,\n background: accentColor,\n flexShrink: 0,\n borderRadius: 1,\n opacity: 0.85,\n }}\n />\n )}\n\n <div\n style={{\n flex: 1,\n overflow: \"hidden\",\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n minWidth: 0,\n }}\n >\n {isHorizontal ? (\n <div\n style={{\n display: \"inline-flex\",\n whiteSpace: \"nowrap\",\n animation: `${animId} ${durationSec}s linear infinite`,\n willChange: \"transform\",\n }}\n >\n {[0, 1].map((copy) => (\n <span key={copy} style={{ paddingRight: `${itemSpacing}px` }}>\n {segments.map((seg, i) => (\n <React.Fragment key={i}>\n {i > 0 && (\n <span style={{ opacity: 0.5, margin: \"0 8px\" }}>{sep}</span>\n )}\n <span style={{ textShadow: \"0 1px 3px rgba(0,0,0,0.6)\" }}>{seg}</span>\n </React.Fragment>\n ))}\n </span>\n ))}\n </div>\n ) : (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n whiteSpace: \"nowrap\",\n animation: `${animId} ${durationSec}s linear infinite`,\n willChange: \"transform\",\n }}\n >\n {[0, 1].map((copy) =>\n segments.map((seg, i) => (\n <div key={`${copy}-${i}`} style={{ paddingBottom: `${itemSpacing / 4}px` }}>\n {seg}\n </div>\n ))\n )}\n </div>\n )}\n </div>\n </div>\n </div>\n </>\n );\n}\n\nfunction parseConfig<T>(content?: string): T | null {\n if (!content) return null;\n try { return JSON.parse(content) as T; } catch { return null; }\n}\n\ninterface OverlaySize { w: number; h: number; }\n\ninterface ScoreBugCfg { homeTeam: string; awayTeam: string; homeScore: number; awayScore: number; period: string; clock: string; sponsorText: string; sponsorImageUrl: string; backgroundColor: string; textColor: string; accentColor: string; }\ninterface LowerThirdCfg { headline: string; subtitle: string; sponsorText: string; sponsorImageUrl: string; backgroundColor: string; textColor: string; accentColor: string; style: string; }\ninterface QrCodeCfg { url: string; ctaText: string; description: string; size: number; backgroundColor: string; textColor: string; accentColor: string; }\ninterface ComingUpNextCfg { title: string; subtitle: string; scheduledTime: string; thumbnailUrl: string; backgroundColor: string; textColor: string; accentColor: string; }\ninterface ContextualTriggerCfg { triggerType: string; headline: string; message: string; iconType: string; backgroundColor: string; textColor: string; accentColor: string; animationStyle: string; }\ninterface OddsBettingCfg { eventTitle: string; options: Array<{ label: string; odds: string }>; sponsorText: string; backgroundColor: string; textColor: string; accentColor: string; oddsFormat: string; }\ninterface BreakingNewsCfg { headline: string; body: string; urgency: string; backgroundColor: string; textColor: string; accentColor: string; }\ninterface CountdownCfg { eventName: string; targetTime: string; message: string; showDays: boolean; showHours: boolean; showMinutes: boolean; showSeconds: boolean; backgroundColor: string; textColor: string; accentColor: string; }\n\nfunction ScoreBugOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const cfg = parseConfig<ScoreBugCfg>(overlay.content);\n if (!cfg) return null;\n const f = Math.max(6, size.w * 0.052);\n return (\n <div\n style={{\n width: \"100%\",\n height: \"100%\",\n borderRadius: Math.max(2, size.w * 0.028),\n display: \"flex\",\n flexDirection: \"column\",\n background: cfg.backgroundColor,\n color: cfg.textColor,\n fontFamily: \"'Inter', 'Roboto', 'Segoe UI', system-ui, sans-serif\",\n overflow: \"hidden\",\n pointerEvents: \"none\",\n userSelect: \"none\",\n fontSize: `${f}px`,\n boxShadow: \"0 8px 28px rgba(0,0,0,0.45)\",\n }}\n >\n <div\n style={{\n flex: 1,\n display: \"flex\",\n alignItems: \"center\",\n padding: `${f * 0.42}px ${f * 0.85}px`,\n gap: f * 0.45,\n minHeight: 0,\n }}\n >\n <div style={{ flex: 1, textAlign: \"center\", minWidth: 0, padding: `0 ${f * 0.15}px` }}>\n <div\n style={{\n fontSize: \"1.05em\",\n fontWeight: 800,\n letterSpacing: \"0.02em\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {cfg.homeTeam}\n </div>\n <div style={{ fontSize: \"1.75em\", fontWeight: 900, lineHeight: 1.05, marginTop: f * 0.08 }}>\n {cfg.homeScore}\n </div>\n </div>\n <div\n style={{\n fontSize: \"0.88em\",\n textAlign: \"center\",\n fontWeight: 600,\n opacity: 0.92,\n color: cfg.textColor,\n padding: `0 ${f * 0.5}px`,\n flexShrink: 0,\n lineHeight: 1.25,\n textTransform: \"uppercase\",\n letterSpacing: \"0.04em\",\n }}\n >\n <div>{cfg.period}</div>\n <div style={{ fontWeight: 700, opacity: 1 }}>{cfg.clock}</div>\n </div>\n <div style={{ flex: 1, textAlign: \"center\", minWidth: 0, padding: `0 ${f * 0.15}px` }}>\n <div\n style={{\n fontSize: \"1.05em\",\n fontWeight: 800,\n letterSpacing: \"0.02em\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {cfg.awayTeam}\n </div>\n <div style={{ fontSize: \"1.75em\", fontWeight: 900, lineHeight: 1.05, marginTop: f * 0.08 }}>\n {cfg.awayScore}\n </div>\n </div>\n </div>\n {(cfg.sponsorText || cfg.sponsorImageUrl) && (\n <div\n style={{\n fontSize: \"0.72em\",\n textAlign: \"center\",\n fontWeight: 600,\n opacity: 0.88,\n padding: `${f * 0.34}px ${f * 0.55}px`,\n borderTop: `1px solid ${cfg.accentColor}55`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: f * 0.45,\n overflow: \"hidden\",\n letterSpacing: \"0.04em\",\n textTransform: \"uppercase\",\n background: `linear-gradient(180deg, rgba(0,0,0,0.12) 0%, rgba(0,0,0,0.22) 100%)`,\n }}\n >\n {cfg.sponsorImageUrl && (\n <img src={cfg.sponsorImageUrl} alt=\"sponsor\" style={{ height: `${f * 1.35}px`, objectFit: \"contain\", flexShrink: 0 }} />\n )}\n {cfg.sponsorText && (\n <span style={{ overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>{cfg.sponsorText}</span>\n )}\n </div>\n )}\n </div>\n );\n}\n\nfunction LowerThirdOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const cfg = parseConfig<LowerThirdCfg>(overlay.content);\n if (!cfg) return null;\n const f = Math.max(6, size.w * 0.05);\n const accentH = Math.max(3, size.h * 0.038);\n return (\n <div\n style={{\n width: \"100%\",\n height: \"100%\",\n borderRadius: Math.max(2, size.w * 0.018),\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"flex-end\",\n background: cfg.backgroundColor,\n color: cfg.textColor,\n fontFamily: \"'Inter', 'Roboto', 'Segoe UI', system-ui, sans-serif\",\n overflow: \"hidden\",\n pointerEvents: \"none\",\n userSelect: \"none\",\n fontSize: `${f}px`,\n boxShadow: \"0 10px 32px rgba(0,0,0,0.4)\",\n }}\n >\n <div style={{ width: \"100%\", height: accentH, backgroundColor: cfg.accentColor, flexShrink: 0 }} />\n <div\n style={{\n flex: 1,\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n padding: `${f * 0.62}px ${f * 1.05}px`,\n minHeight: 0,\n gap: f * 0.18,\n }}\n >\n <div\n style={{\n fontSize: \"1.28em\",\n fontWeight: 800,\n lineHeight: 1.22,\n letterSpacing: \"0.01em\",\n textShadow: \"0 2px 6px rgba(0,0,0,0.55)\",\n }}\n >\n {cfg.headline}\n </div>\n <div\n style={{\n fontSize: \"0.94em\",\n fontWeight: 500,\n opacity: 0.92,\n lineHeight: 1.35,\n color: cfg.textColor,\n }}\n >\n {cfg.subtitle}\n </div>\n </div>\n {(cfg.sponsorText || cfg.sponsorImageUrl) && (\n <div\n style={{\n fontSize: \"0.68em\",\n fontWeight: 600,\n opacity: 0.72,\n padding: `${f * 0.28}px ${f * 1.05}px ${f * 0.48}px`,\n display: \"flex\",\n alignItems: \"center\",\n gap: f * 0.4,\n overflow: \"hidden\",\n letterSpacing: \"0.06em\",\n textTransform: \"uppercase\",\n borderTop: `1px solid rgba(255,255,255,0.08)`,\n }}\n >\n {cfg.sponsorImageUrl && (\n <img src={cfg.sponsorImageUrl} alt=\"sponsor\" style={{ height: `${f * 1.25}px`, objectFit: \"contain\", flexShrink: 0 }} />\n )}\n {cfg.sponsorText && (\n <span style={{ overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>{cfg.sponsorText}</span>\n )}\n </div>\n )}\n </div>\n );\n}\n\nfunction QrCodeOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const cfg = parseConfig<QrCodeCfg>(overlay.content);\n if (!cfg) return null;\n const qrSide = Math.max(32, Math.min(size.w, size.h) * 0.55);\n const qrUrl = `https://api.qrserver.com/v1/create-qr-code/?size=${Math.round(qrSide * 2)}x${Math.round(qrSide * 2)}&data=${encodeURIComponent(cfg.url || \"https://example.com\")}`;\n const f = Math.max(6, size.w * 0.06);\n return (\n <div style={{ width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", flexDirection: \"column\", alignItems: \"center\", justifyContent: \"center\", gap: f * 0.4, background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", padding: f * 0.6, boxSizing: \"border-box\", pointerEvents: \"none\", userSelect: \"none\", overflow: \"hidden\" }}>\n <div style={{ flexShrink: 0, background: \"#fff\", borderRadius: Math.max(2, qrSide * 0.06), padding: Math.max(2, qrSide * 0.06), lineHeight: 0 }}>\n <img src={qrUrl} alt=\"QR Code\" style={{ width: `${qrSide}px`, height: `${qrSide}px`, display: \"block\" }} />\n </div>\n <div style={{ fontSize: `${f * 1.1}px`, fontWeight: 700, textAlign: \"center\", color: cfg.accentColor, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", width: \"100%\" }}>{cfg.ctaText}</div>\n {cfg.description && <div style={{ fontSize: `${f * 0.75}px`, opacity: 0.6, textAlign: \"center\", overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", width: \"100%\" }}>{cfg.description}</div>}\n </div>\n );\n}\n\nfunction ComingUpNextOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const cfg = parseConfig<ComingUpNextCfg>(overlay.content);\n if (!cfg) return null;\n const f = Math.max(8, Math.min(size.h * 0.13, size.w * 0.048));\n const showSubtitle = size.h >= 60;\n const showThumbnail = false;\n const thumbW = 0;\n return (\n <div style={{\n width: \"100%\", height: \"100%\",\n borderRadius: Math.max(2, size.w * 0.025),\n display: \"flex\",\n background: cfg.backgroundColor,\n color: cfg.textColor,\n fontFamily: \"'Arial', 'Helvetica Neue', Helvetica, sans-serif\",\n overflow: \"hidden\",\n pointerEvents: \"none\", userSelect: \"none\",\n fontSize: `${f}px`,\n WebkitFontSmoothing: \"antialiased\",\n } as React.CSSProperties}>\n <div style={{ width: Math.max(3, size.w * 0.018), flexShrink: 0, backgroundColor: cfg.accentColor }} />\n <div style={{\n flex: 1, display: \"flex\", flexDirection: \"column\", justifyContent: \"center\",\n padding: `${f * 0.35}px ${f * 0.75}px`,\n minWidth: 0, gap: `${f * 0.08}px`,\n }}>\n <div style={{\n fontSize: \"0.7em\", fontWeight: 700,\n textTransform: \"uppercase\", letterSpacing: \"0.09em\",\n color: cfg.accentColor, lineHeight: 1,\n }}>\n Coming Up Next\n </div>\n <div style={{\n fontSize: \"1.2em\", fontWeight: 700, lineHeight: 1.2,\n overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\",\n }}>\n {cfg.title}\n </div>\n {showSubtitle && (\n <div style={{\n fontSize: \"0.82em\", opacity: 0.65, lineHeight: 1.1,\n overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\",\n }}>\n {cfg.subtitle}\n </div>\n )}\n {cfg.scheduledTime && (\n <div style={{\n fontSize: \"0.9em\", fontWeight: 700,\n color: cfg.accentColor, lineHeight: 1,\n }}>\n {cfg.scheduledTime}\n </div>\n )}\n </div>\n {showThumbnail && (\n <div style={{ flexShrink: 0, width: `${thumbW}px`, overflow: \"hidden\" }}>\n <img\n src={cfg.thumbnailUrl}\n alt=\"\"\n style={{ width: \"100%\", height: \"100%\", objectFit: \"cover\", display: \"block\" }}\n />\n </div>\n )}\n </div>\n );\n}\n\nfunction ContextualTriggerOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const cfg = parseConfig<ContextualTriggerCfg>(overlay.content);\n if (!cfg) return null;\n const icons: Record<string, string> = { alert: \"\\u26A0\\uFE0F\", celebration: \"\\uD83C\\uDF89\", info: \"\\u2139\\uFE0F\", warning: \"\\uD83D\\uDD14\" };\n const f = Math.max(6, size.w * 0.05);\n return (\n <div style={{ width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", alignItems: \"center\", gap: f * 0.8, padding: `0 ${f * 1.2}px`, background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", borderLeft: `${Math.max(2, size.w * 0.02)}px solid ${cfg.accentColor}`, boxSizing: \"border-box\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }}>\n <span style={{ fontSize: \"2em\", flexShrink: 0 }}>{icons[cfg.iconType] || \"\\u26A1\"}</span>\n <div style={{ flex: 1, minWidth: 0 }}>\n <div style={{ fontSize: \"1.3em\", fontWeight: 700, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>{cfg.headline}</div>\n <div style={{ fontSize: \"0.9em\", opacity: 0.7, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>{cfg.message}</div>\n </div>\n </div>\n );\n}\n\nfunction OddsBettingOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const cfg = parseConfig<OddsBettingCfg>(overlay.content);\n if (!cfg) return null;\n const f = Math.max(6, size.w * 0.052);\n return (\n <div style={{ width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", flexDirection: \"column\", padding: f * 0.8, background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", boxSizing: \"border-box\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }}>\n <div style={{ fontSize: \"0.9em\", fontWeight: 700, textTransform: \"uppercase\", letterSpacing: \"0.05em\", color: cfg.accentColor, marginBottom: f * 0.4 }}>{cfg.eventTitle}</div>\n <div style={{ flex: 1, display: \"flex\", flexDirection: \"column\", gap: f * 0.2, justifyContent: \"center\" }}>\n {(cfg.options || []).slice(0, 5).map((opt, i) => (\n <div key={i} style={{ display: \"flex\", justifyContent: \"space-between\", alignItems: \"center\", padding: `${f * 0.2}px ${f * 0.6}px`, borderRadius: Math.max(2, f * 0.3), background: `${cfg.accentColor}15`, fontSize: \"1em\" }}>\n <span style={{ overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", flex: 1 }}>{opt.label}</span>\n <span style={{ fontWeight: 700, marginLeft: f * 0.8, flexShrink: 0, color: cfg.accentColor }}>{opt.odds}</span>\n </div>\n ))}\n </div>\n {cfg.sponsorText && <div style={{ fontSize: \"0.7em\", opacity: 0.4, textAlign: \"center\", marginTop: f * 0.4 }}>{cfg.sponsorText}</div>}\n </div>\n );\n}\n\nfunction BreakingNewsOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const cfg = parseConfig<BreakingNewsCfg>(overlay.content);\n if (!cfg) return null;\n const urgencyColors: Record<string, string> = { breaking: \"#dc2626\", urgent: \"#ea580c\", normal: \"#2563eb\" };\n const labelBg = urgencyColors[cfg.urgency] || urgencyColors.normal;\n const label = cfg.urgency === \"breaking\" ? \"BREAKING\" : cfg.urgency === \"urgent\" ? \"URGENT\" : \"NEWS\";\n const f = Math.max(6, size.w * 0.05);\n return (\n <div style={{ width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.02), display: \"flex\", alignItems: \"center\", background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", overflow: \"hidden\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }}>\n <div style={{ padding: `0 ${f * 0.8}px`, height: \"100%\", display: \"flex\", alignItems: \"center\", background: labelBg, color: \"#fff\", fontSize: \"1em\", fontWeight: 900, textTransform: \"uppercase\", letterSpacing: \"0.05em\", flexShrink: 0 }}>{label}</div>\n <div style={{ flex: 1, padding: `0 ${f * 1.0}px`, minWidth: 0 }}>\n <div style={{ fontSize: \"1.3em\", fontWeight: 700, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>{cfg.headline}</div>\n {cfg.body && <div style={{ fontSize: \"0.9em\", opacity: 0.7, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>{cfg.body}</div>}\n </div>\n </div>\n );\n}\n\nfunction calcCountdownRemaining(targetTime: string) {\n const diff = Math.max(0, new Date(targetTime).getTime() - Date.now());\n return {\n d: Math.floor(diff / 86400000),\n h: Math.floor((diff % 86400000) / 3600000),\n m: Math.floor((diff % 3600000) / 60000),\n s: Math.floor((diff % 60000) / 1000),\n expired: diff === 0,\n };\n}\n\nfunction CountdownOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const cfg = parseConfig<CountdownCfg>(overlay.content);\n const targetTime = cfg?.targetTime ?? \"\";\n const [remaining, setRemaining] = useState(() =>\n targetTime ? calcCountdownRemaining(targetTime) : { d: 0, h: 0, m: 0, s: 0, expired: false }\n );\n\n useEffect(() => {\n if (!targetTime) return;\n setRemaining(calcCountdownRemaining(targetTime));\n const id = setInterval(() => setRemaining(calcCountdownRemaining(targetTime)), 1000);\n return () => clearInterval(id);\n }, [targetTime]);\n\n if (!cfg) return null;\n\n const f = Math.max(6, size.w * 0.055);\n const pad = (n: number) => String(n).padStart(2, \"0\");\n const units: Array<{ show: boolean; value: string; label: string }> = [\n { show: cfg.showDays, value: pad(remaining.d), label: \"DAYS\" },\n { show: cfg.showHours, value: pad(remaining.h), label: \"HRS\" },\n { show: cfg.showMinutes, value: pad(remaining.m), label: \"MIN\" },\n { show: cfg.showSeconds, value: pad(remaining.s), label: \"SEC\" },\n ];\n\n return (\n <div style={{ width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", flexDirection: \"column\", alignItems: \"center\", justifyContent: \"center\", padding: f * 0.8, background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", boxSizing: \"border-box\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }}>\n <div style={{ fontSize: \"0.8em\", fontWeight: 600, textTransform: \"uppercase\", letterSpacing: \"0.05em\", color: cfg.accentColor, marginBottom: f * 0.4 }}>{cfg.eventName}</div>\n {remaining.expired ? (\n <div style={{ fontSize: \"1em\", fontWeight: 700, opacity: 0.6 }}>{cfg.message || \"Event ended\"}</div>\n ) : (\n <div style={{ display: \"flex\", gap: f * 0.6, alignItems: \"center\" }}>\n {units.filter(u => u.show).map((u, i, arr) => (\n <React.Fragment key={u.label}>\n <div style={{ textAlign: \"center\" }}>\n <div style={{ fontSize: \"2em\", fontWeight: 900, lineHeight: 1, borderRadius: Math.max(2, f * 0.4), padding: `${f * 0.2}px ${f * 0.4}px`, background: `${cfg.accentColor}20` }}>{u.value}</div>\n <div style={{ fontSize: \"0.5em\", opacity: 0.5, marginTop: f * 0.2 }}>{u.label}</div>\n </div>\n {i < arr.length - 1 && <div style={{ fontSize: \"1.8em\", fontWeight: 700, opacity: 0.3 }}>:</div>}\n </React.Fragment>\n ))}\n </div>\n )}\n {!remaining.expired && cfg.message && <div style={{ fontSize: \"0.8em\", opacity: 0.6, marginTop: f * 0.4, textAlign: \"center\" }}>{cfg.message}</div>}\n </div>\n );\n}\n\nfunction ShapeOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const f = Math.max(6, size.w * 0.05);\n return (\n <div style={{ width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.03), background: \"rgba(99, 102, 241, 0.2)\", border: \"2px solid rgba(99, 102, 241, 0.4)\", display: \"flex\", alignItems: \"center\", justifyContent: \"center\", pointerEvents: \"none\", userSelect: \"none\" }}>\n <div style={{ fontSize: `${f}px`, fontWeight: 500, color: \"rgba(163, 163, 163, 0.8)\", textTransform: \"uppercase\" }}>{overlay.name}</div>\n </div>\n );\n}\n\nfunction hexToRgb(hex: string): string {\n if (!hex || !hex.startsWith(\"#\")) return \"0,0,0\";\n const clean = hex.slice(1);\n const num = parseInt(clean.length === 3 ? clean.replace(/./g, \"$&$&\") : clean, 16);\n return `${(num >> 16) & 255},${(num >> 8) & 255},${num & 255}`;\n}\n\ninterface OverlayFadeState {\n overlay: SwirlOverlay;\n visible: boolean;\n}\n\nconst FADE_DURATION_MS = 1000;\n\n/** One full cycle (~60s): pop in → hold → pop out → quiet until next cycle. */\nconst SHOWCASE_CYCLE_MS_DEFAULT = 60_000;\nconst SHOWCASE_POP_IN_MS = 420;\nconst SHOWCASE_STEADY_END_MS = 46_000;\nconst SHOWCASE_POP_OUT_MS = 450;\nconst SHOWCASE_POP_OUT_END_MS = SHOWCASE_STEADY_END_MS + SHOWCASE_POP_OUT_MS;\n\nfunction easeOutCubic(t: number): number {\n const u = 1 - t;\n return 1 - u * u * u;\n}\n\nfunction easeInCubic(t: number): number {\n return t * t * t;\n}\n\nfunction easeOutBack(t: number): number {\n const c1 = 1.70158;\n const c3 = c1 + 1;\n return 1 + c3 * (t - 1) ** 3 + c1 * (t - 1) ** 2;\n}\n\nfunction showcaseOpacity(phase: number): number {\n if (phase < SHOWCASE_POP_IN_MS) return easeOutCubic(phase / SHOWCASE_POP_IN_MS);\n if (phase >= SHOWCASE_STEADY_END_MS && phase < SHOWCASE_POP_OUT_END_MS) {\n return 1 - easeInCubic((phase - SHOWCASE_STEADY_END_MS) / SHOWCASE_POP_OUT_MS);\n }\n return 1;\n}\n\nfunction showcaseScale(phase: number): number {\n if (phase < SHOWCASE_POP_IN_MS) {\n return Math.min(\n 1,\n 0.78 + 0.22 * easeOutBack(phase / SHOWCASE_POP_IN_MS)\n );\n }\n if (phase >= SHOWCASE_STEADY_END_MS && phase < SHOWCASE_POP_OUT_END_MS) {\n return 1 - 0.14 * easeInCubic((phase - SHOWCASE_STEADY_END_MS) / SHOWCASE_POP_OUT_MS);\n }\n return 1;\n}\n\nfunction useShowcasePhase(enabled: boolean, cycleMs: number): number {\n const [phase, setPhase] = useState(0);\n useEffect(() => {\n if (!enabled) return;\n setPhase(Date.now() % cycleMs);\n const id = window.setInterval(() => {\n setPhase(Date.now() % cycleMs);\n }, 48);\n return () => clearInterval(id);\n }, [enabled, cycleMs]);\n return phase;\n}\n\nexport const OverlayRenderer: React.FC<OverlayRendererProps> = ({\n overlays,\n currentTime,\n videoRef,\n coordinateSpace,\n showcaseMode = false,\n showcaseCycleMs = SHOWCASE_CYCLE_MS_DEFAULT,\n}) => {\n const [dims, setDims] = useState<VideoDimensions | null>(null);\n const rafRef = useRef<number | null>(null);\n const [fadeMap, setFadeMap] = useState<Map<number, OverlayFadeState>>(new Map());\n const removeTimers = useRef<Map<number, ReturnType<typeof setTimeout>>>(new Map());\n\n const showcasePhase = useShowcasePhase(showcaseMode, showcaseCycleMs);\n\n const updateDims = useCallback(() => {\n const video = videoRef.current;\n if (video) {\n const computed = computeVideoDimensions(video);\n setDims((prev) => {\n if (\n !computed ||\n (prev &&\n prev.nativeWidth === computed.nativeWidth &&\n prev.nativeHeight === computed.nativeHeight &&\n prev.displayWidth === computed.displayWidth &&\n prev.displayHeight === computed.displayHeight &&\n prev.offsetX === computed.offsetX &&\n prev.offsetY === computed.offsetY)\n ) {\n return prev;\n }\n return computed;\n });\n }\n }, [videoRef]);\n\n useEffect(() => {\n updateDims();\n const interval = setInterval(updateDims, 500);\n\n const handleResize = () => {\n if (rafRef.current) cancelAnimationFrame(rafRef.current);\n rafRef.current = requestAnimationFrame(updateDims);\n };\n window.addEventListener(\"resize\", handleResize);\n\n return () => {\n clearInterval(interval);\n window.removeEventListener(\"resize\", handleResize);\n if (rafRef.current) cancelAnimationFrame(rafRef.current);\n };\n }, [updateDims]);\n\n const activeOverlays = useMemo(() => {\n if (showcaseMode) {\n return overlays.filter((o) => {\n if (!o.visible) return false;\n return showcasePhase < SHOWCASE_POP_OUT_END_MS;\n });\n }\n return overlays.filter((o) => isOverlayActive(o, currentTime));\n }, [overlays, currentTime, showcaseMode, showcasePhase]);\n\n const activeBeatIds = useMemo(\n () => new Set(activeOverlays.map((o) => o.id)),\n [activeOverlays]\n );\n\n useLayoutEffect(() => {\n const activeIds = new Set(activeOverlays.map((o) => o.id));\n\n setFadeMap((prev) => {\n const next = new Map(prev);\n\n for (const overlay of activeOverlays) {\n if (!next.has(overlay.id)) {\n next.set(overlay.id, { overlay, visible: false });\n } else {\n const existing = next.get(overlay.id)!;\n next.set(overlay.id, { ...existing, overlay });\n }\n }\n\n for (const [id, state] of next) {\n if (!activeIds.has(id) && state.visible) {\n next.set(id, { ...state, visible: false });\n if (!removeTimers.current.has(id)) {\n const timer = setTimeout(() => {\n setFadeMap((m) => {\n const updated = new Map(m);\n updated.delete(id);\n return updated;\n });\n removeTimers.current.delete(id);\n }, FADE_DURATION_MS);\n removeTimers.current.set(id, timer);\n }\n } else if (!activeIds.has(id) && !state.visible) {\n }\n }\n\n return next;\n });\n }, [activeOverlays]);\n\n useEffect(() => {\n const toFadeIn: number[] = [];\n for (const [id, state] of fadeMap) {\n if (!state.visible) {\n const isActive = activeOverlays.some((o) => o.id === id);\n if (isActive) toFadeIn.push(id);\n }\n }\n if (toFadeIn.length === 0) return;\n\n const raf = requestAnimationFrame(() => {\n setFadeMap((prev) => {\n const next = new Map(prev);\n for (const id of toFadeIn) {\n const state = next.get(id);\n if (state) next.set(id, { ...state, visible: true });\n }\n return next;\n });\n });\n return () => cancelAnimationFrame(raf);\n }, [fadeMap, activeOverlays]);\n\n useEffect(() => {\n return () => {\n for (const timer of removeTimers.current.values()) clearTimeout(timer);\n };\n }, []);\n\n if (!dims || fadeMap.size === 0) return null;\n\n return (\n <div\n aria-hidden=\"true\"\n style={{\n position: \"absolute\",\n left: `${dims.offsetX}px`,\n top: `${dims.offsetY}px`,\n width: `${dims.displayWidth}px`,\n height: `${dims.displayHeight}px`,\n pointerEvents: \"none\",\n overflow: \"hidden\",\n zIndex: 8,\n }}\n >\n {[...fadeMap.values()].map(({ overlay, visible }) => {\n const uniform =\n coordinateSpace &&\n coordinateSpace.width > 0 &&\n coordinateSpace.height > 0;\n const auth = uniform\n ? { width: coordinateSpace.width, height: coordinateSpace.height }\n : overlayAuthoringDimensions(\n overlay,\n dims.nativeWidth,\n dims.nativeHeight\n );\n const scaleX = dims.displayWidth / auth.width;\n const scaleY = dims.displayHeight / auth.height;\n const left = overlay.x * scaleX;\n const top = overlay.y * scaleY;\n const width = overlay.width * scaleX;\n const height = overlay.height * scaleY;\n const baseOpacity = Math.max(0, Math.min(100, overlay.opacity)) / 100;\n const inShowcaseBeat = showcaseMode && activeBeatIds.has(overlay.id);\n const useShowcasePop = inShowcaseBeat;\n const opacity = useShowcasePop\n ? baseOpacity * showcaseOpacity(showcasePhase)\n : visible\n ? baseOpacity\n : 0;\n const popScale = useShowcasePop ? showcaseScale(showcasePhase) : 1;\n const sz: OverlaySize = { w: width, h: height };\n\n return (\n <div\n key={overlay.id}\n style={{\n position: \"absolute\",\n left: `${left}px`,\n top: `${top}px`,\n width: `${width}px`,\n height: `${height}px`,\n opacity,\n transition: useShowcasePop\n ? \"none\"\n : `opacity ${FADE_DURATION_MS}ms ease`,\n transform: showcaseMode && useShowcasePop ? `scale(${popScale})` : undefined,\n transformOrigin: showcaseMode && useShowcasePop ? \"center center\" : undefined,\n zIndex: overlay.z_index,\n overflow: \"hidden\",\n }}\n >\n {overlay.type === \"image\" && <ImageOverlay overlay={overlay} />}\n {overlay.type === \"text\" && <TextOverlay overlay={overlay} />}\n {overlay.type === \"scroller\" && <ScrollerOverlay overlay={overlay} />}\n {overlay.type === \"shape\" && <ShapeOverlay overlay={overlay} size={sz} />}\n {overlay.type === \"score_bug\" && <ScoreBugOverlay overlay={overlay} size={sz} />}\n {overlay.type === \"lower_third\" && <LowerThirdOverlay overlay={overlay} size={sz} />}\n {overlay.type === \"qr_code\" && <QrCodeOverlay overlay={overlay} size={sz} />}\n {overlay.type === \"coming_up_next\" && <ComingUpNextOverlay overlay={overlay} size={sz} />}\n {overlay.type === \"contextual_trigger\" && <ContextualTriggerOverlay overlay={overlay} size={sz} />}\n {overlay.type === \"odds_betting\" && <OddsBettingOverlay overlay={overlay} size={sz} />}\n {overlay.type === \"breaking_news\" && <BreakingNewsOverlay overlay={overlay} size={sz} />}\n {overlay.type === \"countdown\" && <CountdownOverlay overlay={overlay} size={sz} />}\n </div>\n );\n })}\n </div>\n );\n};\n","export const OVERLAY_API_BASE = \"https://adstorm.co/api-adstorm-dev\";\n\nexport interface OverlayCoordinateSpace {\n width: number;\n height: number;\n}\n\nexport interface SwirlScrollerConfig {\n rss_url?: string;\n update_interval?: number;\n scroll_speed?: number;\n direction?: string;\n font_size?: number;\n font_family?: string;\n font_weight?: string;\n text_color?: string;\n background_color?: string;\n background_opacity?: number;\n border_color?: string;\n border_width?: number;\n border_radius?: number;\n padding?: number;\n margin?: number;\n show_title?: boolean;\n show_description?: boolean;\n show_timestamp?: boolean;\n show_author?: boolean;\n show_category?: boolean;\n max_items?: number;\n item_spacing?: number;\n fade_in_out?: boolean;\n fade_distance?: number;\n auto_refresh?: boolean;\n use_custom_text?: boolean;\n custom_text?: string;\n label?: string;\n label_line2?: string;\n label_color?: string;\n label_text_color?: string;\n accent_color?: string;\n show_accent_line?: boolean;\n separator_char?: string;\n preset?: string;\n}\n\nexport type SwirlOverlayType =\n | \"image\"\n | \"text\"\n | \"scroller\"\n | \"shape\"\n | \"score_bug\"\n | \"lower_third\"\n | \"qr_code\"\n | \"coming_up_next\"\n | \"contextual_trigger\"\n | \"odds_betting\"\n | \"breaking_news\"\n | \"countdown\";\n\nexport interface SwirlOverlay {\n id: number;\n project_id: number;\n name: string;\n type: SwirlOverlayType | string;\n visible: boolean;\n x: number;\n y: number;\n width: number;\n height: number;\n opacity: number;\n start_time: string;\n duration: string;\n content?: string;\n image_url?: string;\n scroller_config?: SwirlScrollerConfig;\n z_index: number;\n created_at?: string;\n updated_at?: string;\n}\n\nexport function timeStringToSeconds(timeStr: string): number {\n if (!timeStr) return 0;\n\n const parts = timeStr.split(\":\");\n\n if (parts.length >= 3) {\n const hours = parseInt(parts[0] ?? \"0\", 10) || 0;\n const minutes = parseInt(parts[1] ?? \"0\", 10) || 0;\n const secStr = parts[2] ?? \"0\";\n const dotIdx = secStr.indexOf(\".\");\n const seconds =\n parseInt(dotIdx >= 0 ? secStr.substring(0, dotIdx) : secStr, 10) || 0;\n const msFrag = dotIdx >= 0 ? secStr.substring(dotIdx + 1) : \"\";\n const ms = msFrag ? parseInt(msFrag.padEnd(3, \"0\").substring(0, 3), 10) || 0 : 0;\n return hours * 3600 + minutes * 60 + seconds + ms / 1000;\n }\n\n if (parts.length === 2) {\n const minutes = parseInt(parts[0] ?? \"0\", 10) || 0;\n const secStr = parts[1] ?? \"0\";\n const dotIdx = secStr.indexOf(\".\");\n const seconds =\n parseInt(dotIdx >= 0 ? secStr.substring(0, dotIdx) : secStr, 10) || 0;\n const msFrag = dotIdx >= 0 ? secStr.substring(dotIdx + 1) : \"\";\n const ms = msFrag ? parseInt(msFrag.padEnd(3, \"0\").substring(0, 3), 10) || 0 : 0;\n return minutes * 60 + seconds + ms / 1000;\n }\n\n const num = parseFloat(timeStr);\n return isFinite(num) ? Math.max(0, num) : 0;\n}\n\nexport function isOverlayActive(\n overlay: SwirlOverlay,\n currentTime: number\n): boolean {\n if (!overlay.visible) return false;\n const startSec = timeStringToSeconds(overlay.start_time);\n const durationSec = timeStringToSeconds(overlay.duration);\n if (durationSec <= 0) return false;\n return currentTime >= startSec && currentTime < startSec + durationSec;\n}\n\nexport const SWIRL_HD_AUTHORING_WIDTH = 1920;\nexport const SWIRL_HD_AUTHORING_HEIGHT = 1080;\n\nconst NAB_DEMO_NAME_PREFIX = \"NAB Demo — \";\n\nexport function overlayAuthoringDimensions(\n overlay: SwirlOverlay,\n decodeWidth: number,\n decodeHeight: number\n): { width: number; height: number } {\n if (!decodeWidth || !decodeHeight) {\n return {\n width: decodeWidth || SWIRL_HD_AUTHORING_WIDTH,\n height: decodeHeight || SWIRL_HD_AUTHORING_HEIGHT,\n };\n }\n if (!overlay.visible) {\n return { width: decodeWidth, height: decodeHeight };\n }\n const extR = overlay.x + overlay.width;\n const extB = overlay.y + overlay.height;\n const EPS = 2;\n const exceedsDecode =\n extR > decodeWidth + EPS || extB > decodeHeight + EPS;\n const isNabDemo = overlay.name.startsWith(NAB_DEMO_NAME_PREFIX);\n\n if (exceedsDecode && isNabDemo) {\n return {\n width: SWIRL_HD_AUTHORING_WIDTH,\n height: SWIRL_HD_AUTHORING_HEIGHT,\n };\n }\n return { width: decodeWidth, height: decodeHeight };\n}\n\nfunction overlayExtents(overlays: SwirlOverlay[]): { maxR: number; maxB: number } {\n let maxR = 0;\n let maxB = 0;\n for (const o of overlays) {\n if (!o.visible) continue;\n maxR = Math.max(maxR, o.x + o.width);\n maxB = Math.max(maxB, o.y + o.height);\n }\n return { maxR, maxB };\n}\n\nexport function swirlProjectHasNabDemoMixedWithOther(overlays: SwirlOverlay[]): boolean {\n let hasNab = false;\n let hasOther = false;\n for (const o of overlays) {\n if (!o.visible) continue;\n if (o.name.startsWith(NAB_DEMO_NAME_PREFIX)) hasNab = true;\n else hasOther = true;\n }\n return hasNab && hasOther;\n}\n\nexport function inferSwirlOverlayCoordinateSpace(\n overlays: SwirlOverlay[],\n videoWidth: number,\n videoHeight: number\n): OverlayCoordinateSpace {\n if (!videoWidth || !videoHeight) {\n return {\n width: videoWidth || SWIRL_HD_AUTHORING_WIDTH,\n height: videoHeight || SWIRL_HD_AUTHORING_HEIGHT,\n };\n }\n if (!overlays.length) {\n return { width: videoWidth, height: videoHeight };\n }\n\n const { maxR, maxB } = overlayExtents(overlays);\n const EPS = 1;\n const exceedsDecode = maxR > videoWidth + EPS || maxB > videoHeight + EPS;\n const fitsHdCanvas =\n maxR <= SWIRL_HD_AUTHORING_WIDTH + EPS &&\n maxB <= SWIRL_HD_AUTHORING_HEIGHT + EPS;\n const mixed = swirlProjectHasNabDemoMixedWithOther(overlays);\n const decodeLargerThanHd =\n videoWidth > SWIRL_HD_AUTHORING_WIDTH + EPS ||\n videoHeight > SWIRL_HD_AUTHORING_HEIGHT + EPS;\n\n if (fitsHdCanvas && (decodeLargerThanHd || (exceedsDecode && !mixed))) {\n return {\n width: SWIRL_HD_AUTHORING_WIDTH,\n height: SWIRL_HD_AUTHORING_HEIGHT,\n };\n }\n\n return { width: videoWidth, height: videoHeight };\n}\n\nfunction normalizeScrollerConfig(\n raw: SwirlScrollerConfig | Record<string, unknown> | undefined\n): SwirlScrollerConfig | undefined {\n if (!raw || typeof raw !== \"object\") return undefined;\n const r = raw as Record<string, unknown>;\n const merged: SwirlScrollerConfig = { ...(raw as SwirlScrollerConfig) };\n if (merged.use_custom_text === undefined && typeof r.useCustomText === \"boolean\") {\n merged.use_custom_text = r.useCustomText;\n }\n if ((merged.custom_text === undefined || merged.custom_text === \"\") && typeof r.customText === \"string\") {\n merged.custom_text = r.customText;\n }\n if (!merged.rss_url && typeof r.rssUrl === \"string\") {\n merged.rss_url = r.rssUrl;\n }\n return merged;\n}\n\nexport function normalizeSwirlOverlay(raw: SwirlOverlay & Record<string, unknown>): SwirlOverlay {\n const o = { ...raw };\n if (o.type === \"scroller\") {\n const sc = raw.scroller_config ?? (raw as Record<string, unknown>).scrollerConfig;\n const normalized = normalizeScrollerConfig(sc as SwirlScrollerConfig);\n if (normalized) o.scroller_config = normalized;\n }\n return o;\n}\n\nexport async function fetchProjectOverlays(\n projectId: number,\n apiBaseUrl: string = OVERLAY_API_BASE\n): Promise<SwirlOverlay[]> {\n const base = apiBaseUrl.replace(/\\/$/, \"\");\n const response = await fetch(\n `${base}/adstorm/swirl/projects/${projectId}/overlays`\n );\n if (!response.ok) {\n throw new Error(\n `Failed to fetch overlays: ${response.status} ${response.statusText}`\n );\n }\n const data = await response.json();\n if (!Array.isArray(data)) return [];\n return data.map((row: SwirlOverlay & Record<string, unknown>) =>\n normalizeSwirlOverlay(row)\n );\n}\n\nexport function resolveImageUrl(\n imageUrl: string,\n apiBaseUrl: string = OVERLAY_API_BASE\n): string {\n if (!imageUrl) return \"\";\n if (imageUrl.startsWith(\"http://\") || imageUrl.startsWith(\"https://\")) {\n return imageUrl;\n }\n if (imageUrl.startsWith(\"/\")) {\n try {\n const url = new URL(apiBaseUrl);\n return `${url.origin}${imageUrl}`;\n } catch {\n return imageUrl;\n }\n }\n return `${apiBaseUrl}/${imageUrl}`;\n}\n"]}