stormcloud-video-player 0.5.13 → 0.5.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/stormcloud-vp.min.js +1 -1
- package/lib/index.cjs +14 -6
- package/lib/index.cjs.map +1 -1
- package/lib/index.js +14 -6
- package/lib/index.js.map +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +14 -6
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/players/HlsPlayer.cjs +14 -6
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/index.cjs +14 -6
- package/lib/players/index.cjs.map +1 -1
- package/lib/sdk/prebidAdLayer.cjs +1 -1
- package/lib/sdk/prebidAdLayer.cjs.map +1 -1
- package/lib/ui/StormcloudVideoPlayer.cjs +14 -6
- package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
- package/package.json +1 -1
|
@@ -789,7 +789,7 @@ function createPrebidAdLayer(contentVideo, options) {
|
|
|
789
789
|
contentVideo.volume = 0;
|
|
790
790
|
adPlaying = true;
|
|
791
791
|
setAdPlayingFlag(true);
|
|
792
|
-
adVolume = originalMutedState ?
|
|
792
|
+
adVolume = originalMutedState ? 1 : originalVolume;
|
|
793
793
|
adVideoElement.volume = Math.max(0, Math.min(1, adVolume));
|
|
794
794
|
adVideoElement.muted = false;
|
|
795
795
|
if (adContainerEl) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/ubuntu24-new/Dev/stormcloud-vp/lib/sdk/prebidAdLayer.cjs","../../src/sdk/prebidAdLayer.ts","../../src/sdk/vastParser.ts"],"names":["__create","Object","create","__defProp","defineProperty","__getOwnPropDesc","getOwnPropertyDescriptor","__getOwnPropNames","getOwnPropertyNames","__getProtoOf","getPrototypeOf","__hasOwnProp","prototype","hasOwnProperty","__export","target","all","name","get","enumerable","__copyProps","to","from","except","desc","key","call","__toESM","mod","isNodeMode","__esModule","value","__toCommonJS","prebidAdLayer_exports","createPrebidAdLayer","module","exports","isHlsType","type","includes","isMp4Type","parseVastXml","xmlString","filter","logPrefix","xmlDoc","parser","DOMParser","parseFromString","parserError","querySelector","console","error","textContent","adElement","warn","adId","getAttribute","title","isNoAdAvailable","toLowerCase","durationText","durationParts","split","duration","parseInt","Math","round","parseFloat","mediaFileElements","querySelectorAll","mediaFiles","log","length","forEach","mf","index","url","trim","width","height","substring","isHls","isMp4","accepted","bitrateAttr","bitrateValue","push","bitrate","sort","a","b","aIsMp4","bIsMp4","trackingUrls","impression","start","firstQuartile","midpoint","thirdQuartile","complete","mute","unmute","pause","resume","fullscreen","exitFullscreen","skip","el","event","eventKey","clickThrough","id","fetchAndParseVastAd","vastTagUrl","response","vastXml","fetch","mode","credentials","headers","Accept","referrerPolicy","ok","Error","statusText","text","createEmptyTrackingState","fireTrackingPixels","urls","sessionId","trackingUrl","img","Image","onerror","src","import_hls","require","LOG","resolveBidToVastAd","winner","ad","Promise","resolve","vastUrl","contentVideo","options","adPlaying","originalMutedState","originalVolume","max","min","volume","listeners","Map","mainHlsInstance","continueLiveStreamDuringAds","debug","adVideoElement","adHls","adContainerEl","currentAd","destroyed","tornDown","trackingFired","emit","payload","set","Array","fn","generateSessionId","Date","now","random","toString","substr","autoLevel","heightDiff","scoredFiles","video","document","playsInline","getMainStreamQuality","levels","currentLevel","loadLevel","level","selectBestMediaFile","firstFile","mainQuality","map","file","widthDiff","abs","resolutionDiff","fileBitrate","bitrateDiff","score","isHlsMediaFile","createAdVideoElement","createElement","style","position","left","top","objectFit","backgroundColor","muted","setupAdEventListeners","addEventListener","progress","currentTime","handleAdComplete","e","handleAdError","ended","setAdPlayingFlag","isPlaying","dataset","stormcloudAdPlaying","display","pointerEvents","visibility","opacity","play","catch","teardownCurrentPlayback","destroy","removeAttribute","load","startNativePlayback","mediaFile","startHlsPlayback","Hls","isSupported","enableWorker","lowLatencyMode","loadSource","attachMedia","on","Events","MANIFEST_PARSED","ERROR","_event","data","fatal","canPlayType","startPlayback"],"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/sdk/prebidAdLayer.ts\nvar prebidAdLayer_exports = {};\n__export(prebidAdLayer_exports, {\n createPrebidAdLayer: () => createPrebidAdLayer\n});\nmodule.exports = __toCommonJS(prebidAdLayer_exports);\n\n// src/sdk/vastParser.ts\nfunction isHlsType(type) {\n return type === \"application/x-mpegURL\" || type.includes(\"m3u8\");\n}\nfunction isMp4Type(type) {\n return type === \"video/mp4\" || type.includes(\"mp4\");\n}\nfunction parseVastXml(xmlString, filter = \"all\", logPrefix = \"[VastParser]\") {\n try {\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlString, \"text/xml\");\n const parserError = xmlDoc.querySelector(\"parsererror\");\n if (parserError) {\n console.error(\n `${logPrefix} XML parsing error (malformed VAST XML):`,\n parserError.textContent\n );\n return null;\n }\n const adElement = xmlDoc.querySelector(\"Ad\");\n if (!adElement) {\n console.warn(`${logPrefix} No Ad element found in VAST XML`);\n return null;\n }\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n const isNoAdAvailable = adId === \"empty\" || title.toLowerCase().includes(\"no ad available\") || title.toLowerCase() === \"no ad available\";\n const durationText = xmlDoc.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n const durationParts = durationText.split(\":\");\n const duration = parseInt(durationParts[0] || \"0\", 10) * 3600 + parseInt(durationParts[1] || \"0\", 10) * 60 + Math.round(parseFloat(durationParts[2] || \"0\"));\n const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n const mediaFiles = [];\n console.log(\n `${logPrefix} Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`\n );\n mediaFileElements.forEach((mf, index) => {\n const type = mf.getAttribute(\"type\") || \"\";\n const url = mf.textContent?.trim() || \"\";\n const width = mf.getAttribute(\"width\") || \"\";\n const height = mf.getAttribute(\"height\") || \"\";\n console.log(\n `${logPrefix} MediaFile ${index}: type=\"${type}\", url=\"${url.substring(0, 80)}...\", width=\"${width}\", height=\"${height}\"`\n );\n if (!url) {\n console.warn(`${logPrefix} MediaFile ${index} has empty URL`);\n return;\n }\n const isHls = isHlsType(type);\n const isMp4 = isMp4Type(type);\n let accepted = false;\n if (filter === \"hls-only\") {\n accepted = isHls;\n } else if (filter === \"mp4-first\") {\n accepted = isMp4 || isHls;\n } else {\n accepted = true;\n }\n if (!accepted) {\n console.log(\n `${logPrefix} MediaFile ${index} ignored (type=\"${type}\" not accepted by filter \"${filter}\")`\n );\n return;\n }\n const bitrateAttr = mf.getAttribute(\"bitrate\");\n const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;\n mediaFiles.push({\n url,\n type,\n width: parseInt(width || \"1920\", 10),\n height: parseInt(height || \"1080\", 10),\n bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : void 0\n });\n console.log(`${logPrefix} Added MediaFile: type=\"${type}\" url=\"${url.substring(0, 80)}...\"`);\n });\n if (filter === \"mp4-first\" && mediaFiles.length > 1) {\n mediaFiles.sort((a, b) => {\n const aIsMp4 = isMp4Type(a.type) ? 0 : 1;\n const bIsMp4 = isMp4Type(b.type) ? 0 : 1;\n return aIsMp4 - bIsMp4;\n });\n }\n if (mediaFiles.length === 0) {\n if (isNoAdAvailable) {\n console.warn(\n `${logPrefix} No ads available (VAST response indicates no ads)`\n );\n } else {\n console.warn(`${logPrefix} No compatible media files found in VAST XML`);\n }\n return null;\n }\n const trackingUrls = {\n impression: [],\n start: [],\n firstQuartile: [],\n midpoint: [],\n thirdQuartile: [],\n complete: [],\n mute: [],\n unmute: [],\n pause: [],\n resume: [],\n fullscreen: [],\n exitFullscreen: [],\n skip: [],\n error: []\n };\n xmlDoc.querySelectorAll(\"Impression\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.impression.push(url);\n });\n xmlDoc.querySelectorAll(\"Tracking\").forEach((el) => {\n const event = el.getAttribute(\"event\");\n const url = el.textContent?.trim();\n if (event && url) {\n const eventKey = event;\n if (trackingUrls[eventKey]) {\n trackingUrls[eventKey].push(url);\n }\n }\n });\n const clickThrough = xmlDoc.querySelector(\"ClickThrough\")?.textContent?.trim();\n return {\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls,\n clickThrough\n };\n } catch (error) {\n console.error(`${logPrefix} Error parsing VAST XML:`, error);\n return null;\n }\n}\nasync function fetchAndParseVastAd(vastTagUrl, filter = \"all\", logPrefix = \"[VastParser]\") {\n const response = await fetch(vastTagUrl, {\n mode: \"cors\",\n credentials: \"include\",\n headers: {\n Accept: \"application/xml, text/xml, */*\"\n },\n referrerPolicy: \"no-referrer-when-downgrade\"\n });\n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.statusText}`);\n }\n const vastXml = await response.text();\n console.log(`${logPrefix} VAST XML received`);\n console.log(\n `${logPrefix} VAST XML content (first 2000 chars):`,\n vastXml.substring(0, 2e3)\n );\n return parseVastXml(vastXml, filter, logPrefix);\n}\nfunction createEmptyTrackingState() {\n return {\n impression: false,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false\n };\n}\nfunction fireTrackingPixels(urls, sessionId, logPrefix = \"[VastParser]\") {\n if (!urls || urls.length === 0) return;\n urls.forEach((url) => {\n try {\n let trackingUrl = url;\n if (sessionId) {\n trackingUrl = `${trackingUrl}${trackingUrl.includes(\"?\") ? \"&\" : \"?\"}session_id=${sessionId}`;\n }\n const img = new Image(1, 1);\n img.onerror = () => {\n };\n img.src = trackingUrl;\n console.log(`${logPrefix} Fired tracking pixel: ${trackingUrl}`);\n } catch (error) {\n console.warn(`${logPrefix} Error firing tracking pixel:`, error);\n }\n });\n}\n\n// src/sdk/prebidAdLayer.ts\nvar import_hls = __toESM(require(\"hls.js\"), 1);\nvar LOG = \"[PrebidAdLayer]\";\nfunction resolveBidToVastAd(winner, logPrefix) {\n if (winner.vastXml) {\n const ad = parseVastXml(winner.vastXml, \"mp4-first\", logPrefix);\n return Promise.resolve(ad);\n }\n if (winner.vastUrl) {\n return fetchAndParseVastAd(winner.vastUrl, \"mp4-first\", logPrefix);\n }\n return Promise.resolve(null);\n}\nfunction createPrebidAdLayer(contentVideo, options) {\n let adPlaying = false;\n let originalMutedState = false;\n let originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));\n const listeners = /* @__PURE__ */ new Map();\n let mainHlsInstance = options?.mainHlsInstance;\n let continueLiveStreamDuringAds = options?.continueLiveStreamDuringAds ?? false;\n const debug = options?.debug ?? false;\n let adVideoElement;\n let adHls;\n let adContainerEl;\n let currentAd;\n let sessionId;\n let destroyed = false;\n let tornDown = false;\n let trackingFired = createEmptyTrackingState();\n function emit(event, payload) {\n const set = listeners.get(event);\n if (!set) return;\n for (const fn of Array.from(set)) {\n try {\n fn(payload);\n } catch (error) {\n console.warn(`${LOG} Error in event listener for ${event}:`, error);\n }\n }\n }\n function generateSessionId() {\n return `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }\n function fireTrackingPixels2(urls) {\n fireTrackingPixels(urls, sessionId, LOG);\n }\n function getMainStreamQuality() {\n if (!mainHlsInstance?.levels) return null;\n const currentLevel = mainHlsInstance.currentLevel;\n if (currentLevel === -1 || !mainHlsInstance.levels[currentLevel]) {\n const autoLevel = mainHlsInstance.loadLevel;\n if (autoLevel !== -1 && mainHlsInstance.levels[autoLevel]) {\n const level2 = mainHlsInstance.levels[autoLevel];\n return {\n width: level2.width || 1920,\n height: level2.height || 1080,\n bitrate: level2.bitrate || 5e6\n };\n }\n return null;\n }\n const level = mainHlsInstance.levels[currentLevel];\n return {\n width: level.width || 1920,\n height: level.height || 1080,\n bitrate: level.bitrate || 5e6\n };\n }\n function selectBestMediaFile(mediaFiles) {\n if (mediaFiles.length === 0) throw new Error(\"No media files available\");\n const firstFile = mediaFiles[0];\n if (mediaFiles.length === 1) return firstFile;\n const mainQuality = getMainStreamQuality();\n if (!mainQuality) {\n if (debug) console.log(`${LOG} No main stream quality info, using first media file`);\n return firstFile;\n }\n const scoredFiles = mediaFiles.map((file) => {\n const widthDiff = Math.abs(file.width - mainQuality.width);\n const heightDiff = Math.abs(file.height - mainQuality.height);\n const resolutionDiff = widthDiff + heightDiff;\n const fileBitrate = (file.bitrate || 5e3) * 1e3;\n const bitrateDiff = Math.abs(fileBitrate - mainQuality.bitrate);\n const score = resolutionDiff * 2 + bitrateDiff / 1e3;\n return { file, score };\n });\n scoredFiles.sort((a, b) => a.score - b.score);\n return scoredFiles[0]?.file ?? firstFile;\n }\n function isHlsMediaFile(file) {\n return file.type === \"application/x-mpegURL\" || file.type.includes(\"m3u8\");\n }\n function createAdVideoElement() {\n const video = document.createElement(\"video\");\n video.style.position = \"absolute\";\n video.style.left = \"0\";\n video.style.top = \"0\";\n video.style.width = \"100%\";\n video.style.height = \"100%\";\n video.style.objectFit = \"contain\";\n video.style.backgroundColor = \"#000\";\n video.playsInline = true;\n video.muted = false;\n video.volume = 1;\n return video;\n }\n function setupAdEventListeners() {\n if (!adVideoElement) return;\n adVideoElement.addEventListener(\"timeupdate\", () => {\n const ad = currentAd;\n if (!ad || !adVideoElement) return;\n const progress = adVideoElement.currentTime / ad.duration;\n if (progress >= 0.25 && !trackingFired.firstQuartile) {\n trackingFired.firstQuartile = true;\n fireTrackingPixels2(ad.trackingUrls.firstQuartile);\n }\n if (progress >= 0.5 && !trackingFired.midpoint) {\n trackingFired.midpoint = true;\n fireTrackingPixels2(ad.trackingUrls.midpoint);\n }\n if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n trackingFired.thirdQuartile = true;\n fireTrackingPixels2(ad.trackingUrls.thirdQuartile);\n }\n });\n adVideoElement.addEventListener(\"playing\", () => {\n const ad = currentAd;\n if (!ad || trackingFired.start) return;\n trackingFired.start = true;\n fireTrackingPixels2(ad.trackingUrls.start);\n if (debug) console.log(`${LOG} Ad started playing`);\n });\n adVideoElement.addEventListener(\"ended\", () => {\n if (tornDown || !currentAd || trackingFired.complete) return;\n trackingFired.complete = true;\n fireTrackingPixels2(currentAd.trackingUrls.complete);\n if (debug) console.log(`${LOG} Ad completed`);\n handleAdComplete();\n });\n adVideoElement.addEventListener(\"error\", (e) => {\n if (tornDown) return;\n console.error(`${LOG} Ad video error:`, e);\n if (currentAd) fireTrackingPixels2(currentAd.trackingUrls.error);\n handleAdError();\n });\n adVideoElement.addEventListener(\"volumechange\", () => {\n if (!currentAd || !adVideoElement) return;\n if (adVideoElement.muted) {\n fireTrackingPixels2(currentAd.trackingUrls.mute);\n } else {\n fireTrackingPixels2(currentAd.trackingUrls.unmute);\n }\n });\n adVideoElement.addEventListener(\"pause\", () => {\n if (currentAd && adVideoElement && !adVideoElement.ended) {\n fireTrackingPixels2(currentAd.trackingUrls.pause);\n }\n });\n adVideoElement.addEventListener(\"play\", () => {\n if (currentAd && adVideoElement && adVideoElement.currentTime > 0) {\n fireTrackingPixels2(currentAd.trackingUrls.resume);\n }\n });\n }\n function setAdPlayingFlag(isPlaying) {\n if (isPlaying) {\n contentVideo.dataset.stormcloudAdPlaying = \"true\";\n } else {\n delete contentVideo.dataset.stormcloudAdPlaying;\n }\n }\n function handleAdComplete() {\n if (tornDown) return;\n if (debug) console.log(`${LOG} Handling ad completion`);\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = true;\n contentVideo.volume = 0;\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n if (continueLiveStreamDuringAds) {\n contentVideo.play().catch(() => {\n });\n }\n emit(\"ad_impression\");\n emit(\"content_resume\");\n }\n function handleAdError() {\n if (tornDown) return;\n if (debug) console.log(`${LOG} Handling ad error`);\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = true;\n contentVideo.volume = 0;\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n emit(\"ad_error\");\n }\n function teardownCurrentPlayback() {\n if (adHls) {\n adHls.destroy();\n adHls = void 0;\n }\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.removeAttribute(\"src\");\n adVideoElement.load();\n }\n }\n function startNativePlayback(mediaFile) {\n if (!adVideoElement) return;\n if (debug) console.log(`${LOG} Starting native MP4 playback: ${mediaFile.url}`);\n adVideoElement.src = mediaFile.url;\n adVideoElement.load();\n adVideoElement.play().catch((error) => {\n console.error(`${LOG} Error starting native ad playback:`, error);\n handleAdError();\n });\n }\n function startHlsPlayback(mediaFile) {\n if (!adVideoElement) return;\n if (debug) console.log(`${LOG} Starting HLS playback: ${mediaFile.url}`);\n if (import_hls.default.isSupported()) {\n if (adHls) {\n adHls.destroy();\n adHls = void 0;\n }\n adHls = new import_hls.default({ enableWorker: true, lowLatencyMode: false });\n adHls.loadSource(mediaFile.url);\n adHls.attachMedia(adVideoElement);\n adHls.on(import_hls.default.Events.MANIFEST_PARSED, () => {\n adVideoElement.play().catch((error) => {\n console.error(`${LOG} Error starting HLS ad playback:`, error);\n handleAdError();\n });\n });\n adHls.on(import_hls.default.Events.ERROR, (_event, data) => {\n if (data.fatal) handleAdError();\n });\n } else if (adVideoElement.canPlayType(\"application/vnd.apple.mpegurl\")) {\n adVideoElement.src = mediaFile.url;\n adVideoElement.play().catch((error) => {\n console.error(`${LOG} Error starting native HLS ad playback:`, error);\n handleAdError();\n });\n } else {\n console.error(`${LOG} HLS not supported on this platform`);\n handleAdError();\n }\n }\n function startPlayback(mediaFile) {\n if (!adVideoElement) return;\n if (isHlsMediaFile(mediaFile)) {\n startHlsPlayback(mediaFile);\n } else {\n startNativePlayback(mediaFile);\n }\n }\n async function playAd(bids) {\n if (destroyed) {\n return Promise.reject(new Error(\"Layer has been destroyed\"));\n }\n if (bids.length === 0) {\n return Promise.reject(new Error(\"No bids provided\"));\n }\n const winner = bids[0];\n if (debug) {\n console.log(`${LOG} Winning bid: ${winner.bidder} $${winner.cpm.toFixed(2)} ${winner.currency}`);\n }\n const ad = await resolveBidToVastAd(winner, LOG);\n if (!ad) {\n if (debug) console.warn(`${LOG} Winning bid has no VAST URL or XML`);\n emit(\"ad_error\");\n return Promise.reject(new Error(\"No VAST from bid\"));\n }\n if (debug) {\n console.log(`${LOG} Ad parsed: ${ad.title}, duration: ${ad.duration}s, mediaFiles: ${ad.mediaFiles.length}`);\n }\n sessionId = generateSessionId();\n currentAd = ad;\n trackingFired = { ...createEmptyTrackingState() };\n fireTrackingPixels2(ad.trackingUrls.impression);\n trackingFired.impression = true;\n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl.appendChild(adVideoElement);\n setupAdEventListeners();\n } else {\n teardownCurrentPlayback();\n }\n const contentVolume = contentVideo.volume;\n originalVolume = Math.max(0, Math.min(1, contentVolume || originalVolume));\n if (!continueLiveStreamDuringAds) {\n contentVideo.pause();\n }\n contentVideo.muted = true;\n contentVideo.volume = 0;\n adPlaying = true;\n setAdPlayingFlag(true);\n const adVolume = originalMutedState ? 0 : originalVolume;\n adVideoElement.volume = Math.max(0, Math.min(1, adVolume));\n adVideoElement.muted = false;\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n emit(\"content_pause\");\n const mediaFile = selectBestMediaFile(ad.mediaFiles);\n if (debug) console.log(`${LOG} Loading ad from: ${mediaFile.url}`);\n startPlayback(mediaFile);\n }\n return {\n initialize() {\n if (debug) console.log(`${LOG} Initializing`);\n },\n updateOptions(opts) {\n if (opts.continueLiveStreamDuringAds !== void 0) {\n continueLiveStreamDuringAds = opts.continueLiveStreamDuringAds;\n }\n if (opts.mainHlsInstance !== void 0) {\n mainHlsInstance = opts.mainHlsInstance ?? void 0;\n }\n },\n playAd,\n pause() {\n if (!adPlaying || !adVideoElement) return;\n try {\n if (!adVideoElement.paused) adVideoElement.pause();\n } catch (error) {\n if (debug) console.warn(`${LOG} Error pausing ad:`, error);\n }\n },\n resume() {\n if (!adPlaying || !adVideoElement) return;\n try {\n if (adVideoElement.paused) adVideoElement.play().catch(() => {\n });\n } catch (error) {\n if (debug) console.warn(`${LOG} Error resuming ad:`, error);\n }\n },\n async stop() {\n tornDown = true;\n if (debug) console.log(`${LOG} Stopping ad`);\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalMutedState ? 0 : originalVolume;\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n if (continueLiveStreamDuringAds) {\n contentVideo.play().catch(() => {\n });\n }\n teardownCurrentPlayback();\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.removeAttribute(\"src\");\n adVideoElement.load();\n }\n currentAd = void 0;\n tornDown = false;\n },\n destroy() {\n tornDown = true;\n if (debug) console.log(`${LOG} Destroying`);\n destroyed = true;\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n teardownCurrentPlayback();\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.removeAttribute(\"src\");\n adVideoElement.remove();\n adVideoElement = void 0;\n }\n if (adContainerEl?.parentElement) {\n adContainerEl.parentElement.removeChild(adContainerEl);\n }\n adContainerEl = void 0;\n currentAd = void 0;\n listeners.clear();\n },\n isAdPlaying() {\n return adPlaying;\n },\n resize(width, height) {\n if (adContainerEl) {\n adContainerEl.style.width = `${width}px`;\n adContainerEl.style.height = `${height}px`;\n }\n if (adVideoElement) {\n adVideoElement.style.width = `${width}px`;\n adVideoElement.style.height = `${height}px`;\n }\n },\n on(event, listener) {\n if (!listeners.has(event)) listeners.set(event, /* @__PURE__ */ new Set());\n listeners.get(event).add(listener);\n },\n off(event, listener) {\n listeners.get(event)?.delete(listener);\n },\n updateOriginalMutedState(muted, volume) {\n const nextVolume = typeof volume === \"number\" && !Number.isNaN(volume) ? Math.max(0, Math.min(1, volume)) : originalVolume;\n originalMutedState = muted;\n originalVolume = nextVolume;\n },\n getOriginalMutedState() {\n return originalMutedState;\n },\n getOriginalVolume() {\n return originalVolume;\n },\n setAdVolume(volume) {\n if (adVideoElement && adPlaying) {\n adVideoElement.volume = Math.max(0, Math.min(1, volume));\n }\n },\n getAdVolume() {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\n showPlaceholder() {\n contentVideo.style.opacity = \"0\";\n contentVideo.style.visibility = \"hidden\";\n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n },\n hidePlaceholder() {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n if (!adPlaying) {\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n }\n }\n };\n}\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n createPrebidAdLayer\n});\n","import type { PrebidBidResponse } from \"../types\";\nimport type { VastAd, VastMediaFile } from \"./vastParser\";\nimport {\n parseVastXml,\n fetchAndParseVastAd,\n fireTrackingPixels as fireTrackingPixelsShared,\n createEmptyTrackingState,\n} from \"./vastParser\";\nimport Hls from \"hls.js\";\n\nconst LOG = \"[PrebidAdLayer]\";\n\nexport interface PrebidAdLayerOptions {\n continueLiveStreamDuringAds?: boolean;\n mainHlsInstance?: Hls;\n debug?: boolean;\n}\n\nexport interface PrebidAdLayerOptionsUpdate {\n continueLiveStreamDuringAds?: boolean;\n mainHlsInstance?: Hls | null;\n}\n\nexport interface PrebidAdLayer {\n initialize: () => void;\n updateOptions: (opts: PrebidAdLayerOptionsUpdate) => void;\n playAd: (bids: PrebidBidResponse[]) => Promise<void>;\n pause: () => void;\n resume: () => void;\n stop: () => Promise<void>;\n destroy: () => void;\n isAdPlaying: () => boolean;\n resize: (width: number, height: number) => void;\n on: (event: string, listener: (payload?: any) => void) => void;\n off: (event: string, listener: (payload?: any) => void) => void;\n updateOriginalMutedState: (muted: boolean, volume?: number) => void;\n getOriginalMutedState: () => boolean;\n getOriginalVolume: () => number;\n setAdVolume: (volume: number) => void;\n getAdVolume: () => number;\n showPlaceholder: () => void;\n hidePlaceholder: () => void;\n}\n\nfunction resolveBidToVastAd(winner: PrebidBidResponse, logPrefix: string): Promise<VastAd | null> {\n if (winner.vastXml) {\n const ad = parseVastXml(winner.vastXml, \"mp4-first\", logPrefix);\n return Promise.resolve(ad);\n }\n if (winner.vastUrl) {\n return fetchAndParseVastAd(winner.vastUrl, \"mp4-first\", logPrefix);\n }\n return Promise.resolve(null);\n}\n\nexport function createPrebidAdLayer(\n contentVideo: HTMLVideoElement,\n options?: PrebidAdLayerOptions\n): PrebidAdLayer {\n let adPlaying = false;\n let originalMutedState = false;\n let originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));\n const listeners = new Map<string, Set<(payload?: any) => void>>();\n let mainHlsInstance: Hls | undefined = options?.mainHlsInstance;\n let continueLiveStreamDuringAds = options?.continueLiveStreamDuringAds ?? false;\n const debug = options?.debug ?? false;\n\n let adVideoElement: HTMLVideoElement | undefined;\n let adHls: Hls | undefined;\n let adContainerEl: HTMLDivElement | undefined;\n let currentAd: VastAd | undefined;\n let sessionId: string | undefined;\n let destroyed = false;\n let tornDown = false;\n let trackingFired = createEmptyTrackingState();\n\n function emit(event: string, payload?: any): void {\n const set = listeners.get(event);\n if (!set) return;\n for (const fn of Array.from(set)) {\n try {\n fn(payload);\n } catch (error) {\n console.warn(`${LOG} Error in event listener for ${event}:`, error);\n }\n }\n }\n\n function generateSessionId(): string {\n return `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }\n\n function fireTrackingPixels(urls: string[]): void {\n fireTrackingPixelsShared(urls, sessionId, LOG);\n }\n\n function getMainStreamQuality(): { width: number; height: number; bitrate: number } | null {\n if (!mainHlsInstance?.levels) return null;\n const currentLevel = mainHlsInstance.currentLevel;\n if (currentLevel === -1 || !mainHlsInstance.levels[currentLevel]) {\n const autoLevel = mainHlsInstance.loadLevel;\n if (autoLevel !== -1 && mainHlsInstance.levels[autoLevel]) {\n const level = mainHlsInstance.levels[autoLevel];\n return {\n width: level.width || 1920,\n height: level.height || 1080,\n bitrate: level.bitrate || 5000000,\n };\n }\n return null;\n }\n const level = mainHlsInstance.levels[currentLevel];\n return {\n width: level.width || 1920,\n height: level.height || 1080,\n bitrate: level.bitrate || 5000000,\n };\n }\n\n function selectBestMediaFile(mediaFiles: VastMediaFile[]): VastMediaFile {\n if (mediaFiles.length === 0) throw new Error(\"No media files available\");\n const firstFile = mediaFiles[0]!;\n if (mediaFiles.length === 1) return firstFile;\n\n const mainQuality = getMainStreamQuality();\n if (!mainQuality) {\n if (debug) console.log(`${LOG} No main stream quality info, using first media file`);\n return firstFile;\n }\n\n const scoredFiles = mediaFiles.map((file) => {\n const widthDiff = Math.abs(file.width - mainQuality.width);\n const heightDiff = Math.abs(file.height - mainQuality.height);\n const resolutionDiff = widthDiff + heightDiff;\n const fileBitrate = (file.bitrate || 5000) * 1000;\n const bitrateDiff = Math.abs(fileBitrate - mainQuality.bitrate);\n const score = resolutionDiff * 2 + bitrateDiff / 1000;\n return { file, score };\n });\n scoredFiles.sort((a, b) => a.score - b.score);\n return scoredFiles[0]?.file ?? firstFile;\n }\n\n function isHlsMediaFile(file: VastMediaFile): boolean {\n return file.type === \"application/x-mpegURL\" || file.type.includes(\"m3u8\");\n }\n\n function createAdVideoElement(): HTMLVideoElement {\n const video = document.createElement(\"video\");\n video.style.position = \"absolute\";\n video.style.left = \"0\";\n video.style.top = \"0\";\n video.style.width = \"100%\";\n video.style.height = \"100%\";\n video.style.objectFit = \"contain\";\n video.style.backgroundColor = \"#000\";\n video.playsInline = true;\n video.muted = false;\n video.volume = 1.0;\n return video;\n }\n\n function setupAdEventListeners(): void {\n if (!adVideoElement) return;\n\n adVideoElement.addEventListener(\"timeupdate\", () => {\n const ad = currentAd;\n if (!ad || !adVideoElement) return;\n const progress = adVideoElement.currentTime / ad.duration;\n if (progress >= 0.25 && !trackingFired.firstQuartile) {\n trackingFired.firstQuartile = true;\n fireTrackingPixels(ad.trackingUrls.firstQuartile);\n }\n if (progress >= 0.5 && !trackingFired.midpoint) {\n trackingFired.midpoint = true;\n fireTrackingPixels(ad.trackingUrls.midpoint);\n }\n if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n trackingFired.thirdQuartile = true;\n fireTrackingPixels(ad.trackingUrls.thirdQuartile);\n }\n });\n\n adVideoElement.addEventListener(\"playing\", () => {\n const ad = currentAd;\n if (!ad || trackingFired.start) return;\n trackingFired.start = true;\n fireTrackingPixels(ad.trackingUrls.start);\n if (debug) console.log(`${LOG} Ad started playing`);\n });\n\n adVideoElement.addEventListener(\"ended\", () => {\n if (tornDown || !currentAd || trackingFired.complete) return;\n trackingFired.complete = true;\n fireTrackingPixels(currentAd.trackingUrls.complete);\n if (debug) console.log(`${LOG} Ad completed`);\n handleAdComplete();\n });\n\n adVideoElement.addEventListener(\"error\", (e) => {\n if (tornDown) return;\n console.error(`${LOG} Ad video error:`, e);\n if (currentAd) fireTrackingPixels(currentAd.trackingUrls.error);\n handleAdError();\n });\n\n adVideoElement.addEventListener(\"volumechange\", () => {\n if (!currentAd || !adVideoElement) return;\n if (adVideoElement.muted) {\n fireTrackingPixels(currentAd.trackingUrls.mute);\n } else {\n fireTrackingPixels(currentAd.trackingUrls.unmute);\n }\n });\n\n adVideoElement.addEventListener(\"pause\", () => {\n if (currentAd && adVideoElement && !adVideoElement.ended) {\n fireTrackingPixels(currentAd.trackingUrls.pause);\n }\n });\n\n adVideoElement.addEventListener(\"play\", () => {\n if (currentAd && adVideoElement && adVideoElement.currentTime > 0) {\n fireTrackingPixels(currentAd.trackingUrls.resume);\n }\n });\n }\n\n function setAdPlayingFlag(isPlaying: boolean): void {\n if (isPlaying) {\n contentVideo.dataset.stormcloudAdPlaying = \"true\";\n } else {\n delete contentVideo.dataset.stormcloudAdPlaying;\n }\n }\n\n function handleAdComplete(): void {\n if (tornDown) return;\n if (debug) console.log(`${LOG} Handling ad completion`);\n adPlaying = false;\n setAdPlayingFlag(false);\n\n contentVideo.muted = true;\n contentVideo.volume = 0;\n\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n\n if (continueLiveStreamDuringAds) {\n contentVideo.play().catch(() => {});\n }\n\n emit(\"ad_impression\");\n emit(\"content_resume\");\n }\n\n function handleAdError(): void {\n if (tornDown) return;\n if (debug) console.log(`${LOG} Handling ad error`);\n adPlaying = false;\n setAdPlayingFlag(false);\n\n contentVideo.muted = true;\n contentVideo.volume = 0;\n\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n\n emit(\"ad_error\");\n }\n\n function teardownCurrentPlayback(): void {\n if (adHls) {\n adHls.destroy();\n adHls = undefined;\n }\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.removeAttribute(\"src\");\n adVideoElement.load();\n }\n }\n\n function startNativePlayback(mediaFile: VastMediaFile): void {\n if (!adVideoElement) return;\n if (debug) console.log(`${LOG} Starting native MP4 playback: ${mediaFile.url}`);\n adVideoElement.src = mediaFile.url;\n adVideoElement.load();\n adVideoElement.play().catch((error) => {\n console.error(`${LOG} Error starting native ad playback:`, error);\n handleAdError();\n });\n }\n\n function startHlsPlayback(mediaFile: VastMediaFile): void {\n if (!adVideoElement) return;\n if (debug) console.log(`${LOG} Starting HLS playback: ${mediaFile.url}`);\n\n if (Hls.isSupported()) {\n if (adHls) {\n adHls.destroy();\n adHls = undefined;\n }\n adHls = new Hls({ enableWorker: true, lowLatencyMode: false });\n adHls.loadSource(mediaFile.url);\n adHls.attachMedia(adVideoElement);\n\n adHls.on(Hls.Events.MANIFEST_PARSED, () => {\n adVideoElement!.play().catch((error) => {\n console.error(`${LOG} Error starting HLS ad playback:`, error);\n handleAdError();\n });\n });\n\n adHls.on(Hls.Events.ERROR, (_event, data) => {\n if (data.fatal) handleAdError();\n });\n } else if (adVideoElement.canPlayType(\"application/vnd.apple.mpegurl\")) {\n adVideoElement.src = mediaFile.url;\n adVideoElement.play().catch((error) => {\n console.error(`${LOG} Error starting native HLS ad playback:`, error);\n handleAdError();\n });\n } else {\n console.error(`${LOG} HLS not supported on this platform`);\n handleAdError();\n }\n }\n\n function startPlayback(mediaFile: VastMediaFile): void {\n if (!adVideoElement) return;\n if (isHlsMediaFile(mediaFile)) {\n startHlsPlayback(mediaFile);\n } else {\n startNativePlayback(mediaFile);\n }\n }\n\n async function playAd(bids: PrebidBidResponse[]): Promise<void> {\n if (destroyed) {\n return Promise.reject(new Error(\"Layer has been destroyed\"));\n }\n if (bids.length === 0) {\n return Promise.reject(new Error(\"No bids provided\"));\n }\n\n const winner = bids[0]!;\n if (debug) {\n console.log(`${LOG} Winning bid: ${winner.bidder} $${winner.cpm.toFixed(2)} ${winner.currency}`);\n }\n\n const ad = await resolveBidToVastAd(winner, LOG);\n if (!ad) {\n if (debug) console.warn(`${LOG} Winning bid has no VAST URL or XML`);\n emit(\"ad_error\");\n return Promise.reject(new Error(\"No VAST from bid\"));\n }\n\n if (debug) {\n console.log(`${LOG} Ad parsed: ${ad.title}, duration: ${ad.duration}s, mediaFiles: ${ad.mediaFiles.length}`);\n }\n\n sessionId = generateSessionId();\n currentAd = ad;\n trackingFired = { ...createEmptyTrackingState() };\n fireTrackingPixels(ad.trackingUrls.impression);\n trackingFired.impression = true;\n\n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl.appendChild(adVideoElement);\n setupAdEventListeners();\n } else {\n teardownCurrentPlayback();\n }\n\n const contentVolume = contentVideo.volume;\n originalVolume = Math.max(0, Math.min(1, contentVolume || originalVolume));\n\n if (!continueLiveStreamDuringAds) {\n contentVideo.pause();\n }\n\n contentVideo.muted = true;\n contentVideo.volume = 0;\n adPlaying = true;\n setAdPlayingFlag(true);\n\n const adVolume = originalMutedState ? 0 : originalVolume;\n adVideoElement.volume = Math.max(0, Math.min(1, adVolume));\n adVideoElement.muted = false;\n\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n\n emit(\"content_pause\");\n\n const mediaFile = selectBestMediaFile(ad.mediaFiles);\n if (debug) console.log(`${LOG} Loading ad from: ${mediaFile.url}`);\n startPlayback(mediaFile);\n }\n\n return {\n initialize() {\n if (debug) console.log(`${LOG} Initializing`);\n },\n\n updateOptions(opts: PrebidAdLayerOptionsUpdate) {\n if (opts.continueLiveStreamDuringAds !== undefined) {\n continueLiveStreamDuringAds = opts.continueLiveStreamDuringAds;\n }\n if (opts.mainHlsInstance !== undefined) {\n mainHlsInstance = opts.mainHlsInstance ?? undefined;\n }\n },\n\n playAd,\n\n pause() {\n if (!adPlaying || !adVideoElement) return;\n try {\n if (!adVideoElement.paused) adVideoElement.pause();\n } catch (error) {\n if (debug) console.warn(`${LOG} Error pausing ad:`, error);\n }\n },\n\n resume() {\n if (!adPlaying || !adVideoElement) return;\n try {\n if (adVideoElement.paused) adVideoElement.play().catch(() => {});\n } catch (error) {\n if (debug) console.warn(`${LOG} Error resuming ad:`, error);\n }\n },\n\n async stop() {\n tornDown = true;\n if (debug) console.log(`${LOG} Stopping ad`);\n adPlaying = false;\n setAdPlayingFlag(false);\n\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalMutedState ? 0 : originalVolume;\n\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n\n if (continueLiveStreamDuringAds) {\n contentVideo.play().catch(() => {});\n }\n\n teardownCurrentPlayback();\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.removeAttribute(\"src\");\n adVideoElement.load();\n }\n currentAd = undefined;\n tornDown = false;\n },\n\n destroy() {\n tornDown = true;\n if (debug) console.log(`${LOG} Destroying`);\n destroyed = true;\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n\n teardownCurrentPlayback();\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.removeAttribute(\"src\");\n adVideoElement.remove();\n adVideoElement = undefined;\n }\n if (adContainerEl?.parentElement) {\n adContainerEl.parentElement.removeChild(adContainerEl);\n }\n adContainerEl = undefined;\n currentAd = undefined;\n listeners.clear();\n },\n\n isAdPlaying() {\n return adPlaying;\n },\n\n resize(width: number, height: number) {\n if (adContainerEl) {\n adContainerEl.style.width = `${width}px`;\n adContainerEl.style.height = `${height}px`;\n }\n if (adVideoElement) {\n adVideoElement.style.width = `${width}px`;\n adVideoElement.style.height = `${height}px`;\n }\n },\n\n on(event: string, listener: (payload?: any) => void) {\n if (!listeners.has(event)) listeners.set(event, new Set());\n listeners.get(event)!.add(listener);\n },\n\n off(event: string, listener: (payload?: any) => void) {\n listeners.get(event)?.delete(listener);\n },\n\n updateOriginalMutedState(muted: boolean, volume?: number) {\n const nextVolume =\n typeof volume === \"number\" && !Number.isNaN(volume)\n ? Math.max(0, Math.min(1, volume))\n : originalVolume;\n originalMutedState = muted;\n originalVolume = nextVolume;\n },\n\n getOriginalMutedState() {\n return originalMutedState;\n },\n\n getOriginalVolume() {\n return originalVolume;\n },\n\n setAdVolume(volume: number) {\n if (adVideoElement && adPlaying) {\n adVideoElement.volume = Math.max(0, Math.min(1, volume));\n }\n },\n\n getAdVolume(): number {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\n\n showPlaceholder() {\n contentVideo.style.opacity = \"0\";\n contentVideo.style.visibility = \"hidden\";\n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n },\n\n hidePlaceholder() {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n if (!adPlaying) {\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n }\n },\n };\n}\n","export interface VastMediaFile {\n url: string;\n type: string;\n width: number;\n height: number;\n bitrate?: number | undefined;\n}\n\nexport interface VastTrackingUrls {\n impression: string[];\n start: string[];\n firstQuartile: string[];\n midpoint: string[];\n thirdQuartile: string[];\n complete: string[];\n mute: string[];\n unmute: string[];\n pause: string[];\n resume: string[];\n fullscreen: string[];\n exitFullscreen: string[];\n skip: string[];\n error: string[];\n}\n\nexport interface VastAd {\n id: string;\n title: string;\n duration: number;\n mediaFiles: VastMediaFile[];\n trackingUrls: VastTrackingUrls;\n clickThrough?: string | undefined;\n}\n\nexport type MediaFileFilter = \"hls-only\" | \"mp4-first\" | \"all\";\n\nfunction isHlsType(type: string): boolean {\n return type === \"application/x-mpegURL\" || type.includes(\"m3u8\");\n}\n\nfunction isMp4Type(type: string): boolean {\n return type === \"video/mp4\" || type.includes(\"mp4\");\n}\n\nexport function parseVastXml(\n xmlString: string,\n filter: MediaFileFilter = \"all\",\n logPrefix = \"[VastParser]\"\n): VastAd | null {\n try {\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlString, \"text/xml\");\n\n const parserError = xmlDoc.querySelector(\"parsererror\");\n if (parserError) {\n console.error(\n `${logPrefix} XML parsing error (malformed VAST XML):`,\n parserError.textContent\n );\n return null;\n }\n\n const adElement = xmlDoc.querySelector(\"Ad\");\n if (!adElement) {\n console.warn(`${logPrefix} No Ad element found in VAST XML`);\n return null;\n }\n\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n\n const isNoAdAvailable =\n adId === \"empty\" ||\n title.toLowerCase().includes(\"no ad available\") ||\n title.toLowerCase() === \"no ad available\";\n\n const durationText =\n xmlDoc.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n const durationParts = durationText.split(\":\");\n const duration =\n parseInt(durationParts[0] || \"0\", 10) * 3600 +\n parseInt(durationParts[1] || \"0\", 10) * 60 +\n Math.round(parseFloat(durationParts[2] || \"0\"));\n\n const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n const mediaFiles: VastMediaFile[] = [];\n\n console.log(\n `${logPrefix} Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`\n );\n\n mediaFileElements.forEach((mf, index) => {\n const type = mf.getAttribute(\"type\") || \"\";\n const url = mf.textContent?.trim() || \"\";\n const width = mf.getAttribute(\"width\") || \"\";\n const height = mf.getAttribute(\"height\") || \"\";\n\n console.log(\n `${logPrefix} MediaFile ${index}: type=\"${type}\", url=\"${url.substring(0, 80)}...\", width=\"${width}\", height=\"${height}\"`\n );\n\n if (!url) {\n console.warn(`${logPrefix} MediaFile ${index} has empty URL`);\n return;\n }\n\n const isHls = isHlsType(type);\n const isMp4 = isMp4Type(type);\n\n let accepted = false;\n if (filter === \"hls-only\") {\n accepted = isHls;\n } else if (filter === \"mp4-first\") {\n accepted = isMp4 || isHls;\n } else {\n accepted = true;\n }\n\n if (!accepted) {\n console.log(\n `${logPrefix} MediaFile ${index} ignored (type=\"${type}\" not accepted by filter \"${filter}\")`\n );\n return;\n }\n\n const bitrateAttr = mf.getAttribute(\"bitrate\");\n const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : undefined;\n\n mediaFiles.push({\n url,\n type,\n width: parseInt(width || \"1920\", 10),\n height: parseInt(height || \"1080\", 10),\n bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : undefined,\n });\n\n console.log(`${logPrefix} Added MediaFile: type=\"${type}\" url=\"${url.substring(0, 80)}...\"`);\n });\n\n if (filter === \"mp4-first\" && mediaFiles.length > 1) {\n mediaFiles.sort((a, b) => {\n const aIsMp4 = isMp4Type(a.type) ? 0 : 1;\n const bIsMp4 = isMp4Type(b.type) ? 0 : 1;\n return aIsMp4 - bIsMp4;\n });\n }\n\n if (mediaFiles.length === 0) {\n if (isNoAdAvailable) {\n console.warn(\n `${logPrefix} No ads available (VAST response indicates no ads)`\n );\n } else {\n console.warn(`${logPrefix} No compatible media files found in VAST XML`);\n }\n return null;\n }\n\n const trackingUrls: VastTrackingUrls = {\n impression: [],\n start: [],\n firstQuartile: [],\n midpoint: [],\n thirdQuartile: [],\n complete: [],\n mute: [],\n unmute: [],\n pause: [],\n resume: [],\n fullscreen: [],\n exitFullscreen: [],\n skip: [],\n error: [],\n };\n\n xmlDoc.querySelectorAll(\"Impression\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.impression.push(url);\n });\n\n xmlDoc.querySelectorAll(\"Tracking\").forEach((el) => {\n const event = el.getAttribute(\"event\");\n const url = el.textContent?.trim();\n if (event && url) {\n const eventKey = event as keyof VastTrackingUrls;\n if (trackingUrls[eventKey]) {\n trackingUrls[eventKey].push(url);\n }\n }\n });\n\n const clickThrough = xmlDoc\n .querySelector(\"ClickThrough\")\n ?.textContent?.trim();\n\n return {\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls,\n clickThrough,\n };\n } catch (error) {\n console.error(`${logPrefix} Error parsing VAST XML:`, error);\n return null;\n }\n}\n\nexport async function fetchAndParseVastAd(\n vastTagUrl: string,\n filter: MediaFileFilter = \"all\",\n logPrefix = \"[VastParser]\"\n): Promise<VastAd | null> {\n const response = await fetch(vastTagUrl, {\n mode: \"cors\",\n credentials: \"include\",\n headers: {\n Accept: \"application/xml, text/xml, */*\",\n },\n referrerPolicy: \"no-referrer-when-downgrade\",\n });\n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.statusText}`);\n }\n\n const vastXml = await response.text();\n console.log(`${logPrefix} VAST XML received`);\n console.log(\n `${logPrefix} VAST XML content (first 2000 chars):`,\n vastXml.substring(0, 2000)\n );\n\n return parseVastXml(vastXml, filter, logPrefix);\n}\n\nexport function createEmptyTrackingState() {\n return {\n impression: false,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false,\n };\n}\n\nexport function fireTrackingPixels(\n urls: string[],\n sessionId?: string,\n logPrefix = \"[VastParser]\"\n): void {\n if (!urls || urls.length === 0) return;\n\n urls.forEach((url) => {\n try {\n let trackingUrl = url;\n\n if (sessionId) {\n trackingUrl = `${trackingUrl}${\n trackingUrl.includes(\"?\") ? \"&\" : \"?\"\n }session_id=${sessionId}`;\n }\n\n const img = new Image(1, 1);\n img.onerror = () => {\n // 502 or other network errors are fire-and-forget; do not affect playback\n };\n img.src = trackingUrl;\n console.log(`${logPrefix} Fired tracking pixel: ${trackingUrl}`);\n } catch (error) {\n console.warn(`${logPrefix} Error firing tracking pixel:`, error);\n }\n });\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["/home/ubuntu24-new/Dev/stormcloud-vp/lib/sdk/prebidAdLayer.cjs","../../src/sdk/prebidAdLayer.ts","../../src/sdk/vastParser.ts"],"names":["__create","Object","create","__defProp","defineProperty","__getOwnPropDesc","getOwnPropertyDescriptor","__getOwnPropNames","getOwnPropertyNames","__getProtoOf","getPrototypeOf","__hasOwnProp","prototype","hasOwnProperty","__export","target","all","name","get","enumerable","__copyProps","to","from","except","desc","key","call","__toESM","mod","isNodeMode","__esModule","value","__toCommonJS","prebidAdLayer_exports","createPrebidAdLayer","module","exports","isHlsType","type","includes","isMp4Type","parseVastXml","xmlString","filter","logPrefix","xmlDoc","parser","DOMParser","parseFromString","parserError","querySelector","console","error","textContent","adElement","warn","adId","getAttribute","title","isNoAdAvailable","toLowerCase","durationText","durationParts","split","duration","parseInt","Math","round","parseFloat","mediaFileElements","querySelectorAll","mediaFiles","log","length","forEach","mf","index","url","trim","width","height","substring","isHls","isMp4","accepted","bitrateAttr","bitrateValue","push","bitrate","sort","a","b","aIsMp4","bIsMp4","trackingUrls","impression","start","firstQuartile","midpoint","thirdQuartile","complete","mute","unmute","pause","resume","fullscreen","exitFullscreen","skip","el","event","eventKey","clickThrough","id","fetchAndParseVastAd","vastTagUrl","response","vastXml","fetch","mode","credentials","headers","Accept","referrerPolicy","ok","Error","statusText","text","createEmptyTrackingState","fireTrackingPixels","urls","sessionId","trackingUrl","img","Image","onerror","src","import_hls","require","LOG","resolveBidToVastAd","winner","ad","Promise","resolve","vastUrl","contentVideo","options","adPlaying","originalMutedState","originalVolume","max","min","volume","listeners","Map","mainHlsInstance","continueLiveStreamDuringAds","debug","adVideoElement","adHls","adContainerEl","currentAd","destroyed","tornDown","trackingFired","emit","payload","set","Array","fn","generateSessionId","Date","now","random","toString","substr","autoLevel","heightDiff","scoredFiles","video","document","playsInline","getMainStreamQuality","levels","currentLevel","loadLevel","level","selectBestMediaFile","firstFile","mainQuality","map","file","widthDiff","abs","resolutionDiff","fileBitrate","bitrateDiff","score","isHlsMediaFile","createAdVideoElement","createElement","style","position","left","top","objectFit","backgroundColor","muted","setupAdEventListeners","addEventListener","progress","currentTime","handleAdComplete","e","handleAdError","ended","setAdPlayingFlag","isPlaying","dataset","stormcloudAdPlaying","display","pointerEvents","visibility","opacity","play","catch","teardownCurrentPlayback","destroy","removeAttribute","load","startNativePlayback","mediaFile","startHlsPlayback","Hls","isSupported","enableWorker","lowLatencyMode","loadSource","attachMedia","on","Events","MANIFEST_PARSED","ERROR","_event","data","fatal","canPlayType","startPlayback"],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YACIA,UAAAA,SAAWC,OAAOC,MAAM;YACxBC,YAAAA,UAAYF,OAAOG,cAAc;YACjCC,cAAAA,iBAAmBJ,OAAOK,wBAAwB;YAClDC,cAAAA,kBAAoBN,OAAOO,mBAAmB;QAC9CC,eAAeR,OAAOS,cAAc;IACxC,EAAIC,OAAAA,OAAAA,CAAeV,OAAOW,SAAS,CAACC,cAAc;QAC9CC,QAAAA,GAAW,EAAA,CAAA,GAAA,OAAA,WAAA,EAACC,QAAQC,mBAAAA;QACtB,IAAK,GAAA,CAAIC,QAAQD,IACfb,UAAUY,QAAQE,MAAM;UAAEC,KAAKF,GAAG,CAACC,KAAK;QAAEE,YAAY;IAAK,KAAA,oBAAA,UAAA;QAAA,SAAA,iEAAA,OAAA,YAAA,iEAAA;;YAC/D;;;;oBAAA;;wBAAA,MAAA,YAAA;4BACIC,MAAAA,QAAc,qBAACC,IAAIC,MAAMC,QAAQC;4BACnC,IAAIF,QAAQ,CAAA,OAAOA,qCAAP,SAAOA,KAAG,MAAM,YAAY,OAAOA,SAAS,YAAY;oCAC7D,CAAA,iCAAA,2BAAA;;;wCAAA,IAAIG,MAAJ;sCACH,IAAI,CAACd,aAAae,IAAI,CAACL,IAAII,QAAQA,QAAQF,QACzCpB,UAAUkB,IAAII,KAAK;;;oBAL3B,WAAA;sCAK6BP,KAAK,SAALA;kDAAWI,IAAI,CAACG,IAAI,MAAA,OAAA,SAAA,UAAA;;;;wBAAEN,QAAY,CAAEK,CAAAA,GAAAA,IAAOnB,iBAAiBiB,MAAMG,IAAG,KAAMD,KAAKL,UAAU;;;gCAApEA;iCAAqE,EAAA,OAAA,WAAA;mCAFpH,GAAK,SAAL,GAAgBZ,GAAhB,eAAkCe,0BAA7B,SAAA,6BAAA,QAAA,yBAAA;;;2BAAA,UAAA,SAAA,QAAA;;;;;;;uBAAA,6BAAA;wBAAA;;;wBAAA;8BAAA;;;;IAGP,KAAA,mBAAA,IAAA,EAAA,SAAA;QAAA,YAAA,iEAAA;MACA,EAAA,CAAA,IAAOD,IAAAA,KAAAA,MAAAA,KAAAA,GAAAA;IACT,KAAA,OAAA,CAAA,SAAA;QACIM,IAAAA,MAAU,iBAACC,KAAKC,YAAYd;iBAAYA,SAASa,IAAAA,GAAO,OAAO5B,SAASS,aAAamB,QAAQ,CAAC,GAAGR,YACnG,sEAAsE;YACtE,IAAA,WAAA,gDAAiE;gBACjE,cAAA,GAAA,OAAA,aAAsE,OAAtE,YAAA,QAAA,CAAA,OAAA,MAAA,CAAsE,IAAA,eAAA,OAAA;YACtE,mEAAqE;YACrES,IAAAA,MAAc,CAACD,GAAAA,IAAO,CAACA,CAAAA,GAAIE,UAAU,GAAG3B,UAAUY,QAAQ,WAAW;cAAEgB,EAAAA,KAAOH,EAAAA,GAAAA,cAAKT,YAAY;YAAK,GAAKJ,CAAAA,GAAAA,GAAAA,CACzGa;;QAEEI,EAAAA,OAAAA,MAAe,CAAA,qBAACJ;iBAAQR,GAAAA,IAAAA,CAAAA,GAAYjB,OAAZiB,CAAYjB,UAAAA,CAAU,CAAC,GAAG,cAAc,eAAA;YAAE4B,OAAO;MAAK,IAAIH;;AC3BtF,IAAAK,uBAAAA,CAAA,CAAA;AAAAnB,IAAAA,KAAAmB,QAAAA,QAAAA,OAAA,CAAA,WAAA;IAAAC,MAAAA,eAAA,SAAAA;eAAAA,aAAAA,MAAAA,EAAAA,SAAAA;;QAAA,IAAA,KAAA,aAAA,OAAA,OAAA,EAAA,aAAA;QAAAC,GAAAC,IAAAA,GAAA,GAAAJ,EAAAA,OAAAA,CAAAA,GAAAC;IDoCA,sBAAwB;IEAxB,IAAA,GAASI,IAAAA,MAAUC,CAAAA,EAAAA,CAAA;QACjB,OAAOA,SAAS,WAAA,OAAA,OAAA,EAA2BA,KAAKC,QAAA,CAAS;IAC3D;IAEA,OAASC,QAAAA,EAAUF,IAAA,CAAA,CAAA;IACjB,OAAOA,SAAS,eAAeA,KAAKC,QAAA,CAAS;AAC/C,SAAA,oBAAA,YAAA,EAAA,OAAA;;IAEO,IAAA,GAASE,SAAAA,IACdC,SAAA;UACAC,SAAAA,UAAAA,uDAA0B,OAC1BC,YAAAA,iEAAY;MAEZ,EAAA,EAAI,eAAA,KAAA,GAAA,CAAA,GAAA,KAAA,GAAA,CAAA,GAAA,aAAA,MAAA,IAAA;YAoBYC,QAAAA,aAAAA,EAQZA,CAAAA,IAAAA,mBAkHmBA,mCAAAA;UA7IrB,IAAMC,SAAS,GAAA,oBAAA,8BAAA,CAAIC,OAAAA,eAAAA;UACnB,IAAMF,SAASC,OAAOE,gBAAAA,oBAAAA,8BAAAA,OAAA,CAAgBN,UAAW,iBAAA,uCAAA;QAEjD,IAAMO,aAAAA,oBAAAA,8BAAAA,QAAAA,CAAcJ,IAAAA,GAAOK,sCAAAA,YAAA,CAAc;UACzC,IAAID,aAAa;cACfE,QAAQC,KAAA,CACN,GAAY,OAATR,WAAS,6CACZK,YAAYI,WAAA;cAEd,OAAO;UACT;UAEA,IAAMC,YAAYT,OAAOK,aAAA,CAAc;UACvC,IAAI,CAACI,KAAAA,MAAW;cACdH,KAAAA,GAAQI,IAAA,CAAK,GAAY,OAATX,WAAS;cACzB,OAAO,GAAA;UACT,GAAA,KAAA,KAAA,EAAA,OAAA;YAEA,EAAMY,IAAAA,GAAOF,OAAAA,GAAUG,CAAAA,WAAA,CAAa,SAAS;YAC7C,CAAA,GAAMC,EAAAA,MAAQb,EAAAA,wBAAAA,OAAOK,aAAA,CAAc,wBAArBL,4CAAAA,sBAAiCQ,WAAA,KAAe;YAE9D,kCAAA,2BAAA;;gBAAA,IAAA,YAAMM,MAAAA,GACJH,CAAAA,CAAAA,yBADF,SAAA,6BAAA,QAAA,yBAAA,iCACEA,CAAS,WACTE,MAAME,WAAA,GAAcrB,QAAA,CAAS,sBAC7BmB,MAAME,WAAA,OAAkB;gBAH1B,IAAMD,KAAN;kBAKA,EAAA,EAAME,eACJhB,EAAAA,yBAAAA,OAAOK,aAAA,CAAc,yBAArBL,6CAAAA,uBAAkCQ,WAAA,KAAe;oBACnD,GAAA,CAAMS,gBAAgBD,aAAaE,KAAA,CAAM;kBACzC,IAAMC,GAAAA,OAAAA,CACJC,SAASH,aAAA,CAAc,EAAC,IAAK,KAAK,MAAM,OACxCG,SAASH,aAAA,CAAc,EAAC,IAAK,KAAK,MAAM,KACxCI,KAAKC,KAAA,CAAMC,WAAWN,aAAA,CAAc,EAAC,IAAK;oBAE5C,IAAMO,IAAAA,IAAAA,CAAAA,GAA4C,OAA5CA,KAAAA,IAAoBxB,OAAOyB,gBAAA,CAAiB,KAAA,OAAA,OAAA,MAAA;kBAClD,IAAMC,aAA8B,EAAC;gBAErCpB,QAAQqB,GAAA,CACN,GAAsBH,OAAnBzB,WAAS,WAAkC,OAAxByB,kBAAkBI,MAAM,EAAA;;YAjBhD;YAAA;;;qBAAA,6BAAA;oBAAA;;;oBAAA;0BAAA,GAAMd;;;;UAoBNU,kBAAkBK,OAAA,CAAQ,SAACC,IAAIC;kBAEjBD;eADZ,IAAMrC,OAAUmB,EAAA,CAAa,IAAvBnB,CAAOqC,GAAGlB,CAAAA,GAAAA,IAAAA,KAAwB,OAAxBA,KAAa,MAAA,GAAW,QAAA,CAAA,IAAA,MAAA,CAAA,GAAA;cACxC,IAAMoB,MAAMF,EAAAA,kBAAAA,GAAGtB,WAAA,cAAHsB,sCAAAA,gBAAgBG,IAAA,OAAU;cACtC,IAAMC,QAAQJ,GAAGlB,IAAAA,IAAAA,IAAA,CAAa,YAAY;gBAC1C,IAAMuB,OAAAA,EAASL,GAAGlB,CAAAA,WAAA,CAAa,aAAa;cAE5CN,QAAQqB,GAAA,CACN,GAA0BI,OAAvBhC,WAAS,eAA8BN,OAAhBsC,OAAK,YAA0BC,OAAfvC,MAAI,YAA+CyC,OAApCF,IAAII,SAAA,CAAU,GAAG,KAAG,iBAAmCD,OAAnBD,OAAK,eAAoB,OAANC,QAAM;cAGxH,IAAI,CAACH,KAAK;uFACR1B,QAAQI,CAAAA,EAAA,CAAK,GAA0BqB,GAAAA,KAAvBhC,EAAAA,SAAS,eAAmB,OAALgC,OAAK;kBAC5C,SAAA,gBAAA,YAAA;gBACF,aAAA,CAAA,KAAA,CAAA,gBAAA,MAAA,CAAA,aAAA,EAAA;gBAEA,IAAMM,QAAQ7C,UAAUC,MAAAA,SAAAA;kBACxB,IAAM6C,QAAQ3C,CAAAA,KAAAA,IAAUF,YAAAA,MAAAA,CAAAA,UAAAA,EAAAA;oBAExB,EAAI8C,OAAAA,IAAW,YAAA,MAAA,CAAA,UAAA;oBACf,GAAA,CAAIzC,WAAW,YAAY;0BACzByC,CAAAA,OAAAA,GAAWF,EAAAA,IAAAA;sBACb,MAAA,CAAA,IAAWvC,EAAAA,MAAAA,GAAW,CAAA,YAAa;0BACjCyC,GAAAA,OAAAA,CAAWD,MAAAA,GAASD,CAAAA;oBACtB,OAAO;sBACLE,WAAW;kBACb,CAAA;gBAEA,IAAI,CAACA,UAAU;kBACbjC,EAAAA,MAAQqB,GAAA,CACN,GAA0BI,GAAAA,IAAvBhC,EAAAA,CAAAA,QAAS,KAAA,UAAsCN,OAAxBsC,OAAK,oBAAoDjC,OAAjCL,MAAI,8BAAmC,OAANK,QAAM;oBAE3F;kBACF,CAAA,MAAA,KAAA,IAAA;kBAEA,EAAA,EAAM0C,IAAAA,MAAAA,IAAcV,GAAGlB,YAAA,CAAa;kBACpC,GAAA,CAAM6B,KAAAA,OAAAA,GAAeD,CAAAA,aAAcpB,SAASoB,aAAa,MAAM,KAAA;gBAE/Dd,WAAWgB,IAAA,CAAK;kBACdV,KAAAA;kBACAvC,MAAAA,SAAAA,UAAAA;;aAwBF;oBAvBEyC,GAAAA,IAAOd,EAAAA,KAAAA,EAASc,CAAAA,MAAAA,EAAS,EAAA,MAAQ;kBACjCC,MAAAA,EAAQf,QAAAA,CAASe,EAAAA,QAAU,QAAQ;oBACnCQ,GAAAA,MAASF,KAAAA,GAAAA,OAAAA,CAAgBA,eAAe,IAAIA,eAAe,KAAA;cAC7D,YAAA;gBAEAnC,QAAQqB,EAAAA,CAAA,CAAI,GAAuClC,OAApCM,WAAS,4BAAyCiC,OAAdvC,MAAI,WAA8B,OAApBuC,IAAII,SAAA,CAAU,GAAG,KAAG;cACvF,EAAA,OAAA,QAAA,GAAA,CAAA,GAAA,OAAA,KAAA;cAEA,IAAItC,CAAAA,UAAW,eAAe4B,WAAWE,MAAA,GAAS,GAAG;gBACnDF,WAAWkB,IAAA,CAAK,SAACC,GAAGC;kBAClB,IAAMC,IAAAA,KAASpD,MAAAA,GAAAA,CAAUkD,SAAAA,CAAEpD,IAAI,IAAI,IAAI;oBACvC,IAAMuD,IAAAA,KAASrD,GAAAA,CAAAA,KAAAA,CAAUmD,EAAErD,EAAAA,EAAI,CAAA,GAAI,IAAI,KAAA,KAAA;oBACvC,OAAOsD,EAAAA,KAAAA,EAASC,CAAAA,CAAAA,KAAAA,MAAAA,GAAAA,YAAAA,MAAAA;gBAClB,iBAAA,YAAA;cACF,EAAA,cAAA,CAAA,KAAA,OAAA,IAAA,GAAA,IAAA;cAEA,EAAItB,WAAWE,GAAAA,GAAA,EAAA,GAAW,CAAA,EAAG,YAAA,YAAA,OAAA;gBAC3B,IAAId,IAAAA,aAAiB,IAAA,IAAA,cAAA;;uBACnBR;gBAAAA,OAAAA,GAAQI;YAAAA,CAAA,CACN,GAAY,OAATX,WAAS;gBAEhB,OAAO;oBACLO,IAAAA,CAAAA,SAAAA,EAAQI,CAAAA,GAAA,CAAK;mBAAA,CAAY,CAAA,KAAA,CAATX,EAAAA,EAAAA,KAAAA,EAAS;;mDAC3B,CAAA,EAAA,gEAAA,IAAA,uCAAA;cACA,OAAO;UACT,GAAA,eAAA,IAAA;YAEA,GAAA,CAAMkD,IAAAA,IAAAA,KAAAA,EAAiC,yBAAA,KAAA,IAAA,CAAA,QAAA,CAAA;cACrCC,YAAY,EAAC;cACbC,OAAO,EAAC;cACRC,MAAAA,SAAe,EAAC,WAAA,CAAA;gBAChBC,GAAAA,CAAAA,MAAU,EAAC,GAAA;gBACXC,GAAAA,CAAAA,IAAAA,GAAAA,IAAe,EAAC;gBAChBC,GAAAA,CAAAA,GAAAA,GAAU,EAAC;gBACXC,GAAAA,CAAAA,EAAM,EAAC,CAAA,GAAA;gBACPC,GAAAA,CAAAA,IAAQ,EAAC,GAAA;gBACTC,GAAAA,CAAAA,GAAO,EAAC,IAAA,GAAA;gBACRC,GAAAA,CAAAA,IAAQ,EAAC,SAAA,GAAA;gBACTC,SAAAA,GAAY,EAAC;gBACbC,GAAAA,GAAAA,UAAgB,EAAC;gBACjBC,IAAAA,EAAM,CAAA,CAAC;gBACPvD,OAAO,EAAC;UACV;UAEAP,GAAAA,IAAOyB,gBAAA,CAAiB,cAAcI,OAAA,CAAQ,SAACkC;oBACjCA,SAAAA;gBAAZ,IAAM/B,GAAAA,IAAM+B,YAAAA,CAAAA,KAAAA,GAAGvD,MAAAA,KAAA,cAAHuD,sCAAAA,gBAAgB9B,IAAA;gBAC5B,IAAID,CAAAA,IAAKiB,aAAaC,UAAA,CAAWR,IAAA,CAAKV;cACxC,EAAA,CAAA,MAAA,CAAA,gBAAA;cAEAhC,EAAAA,GAAOyB,QAAAA,QAAA,CAAiB,MAAA,MAAYI,KAAAA,EAAA,CAAQ,GAAA,MAACkC,EAAAA;sBAE/BA,MAAAA,QAAAA,CAAAA,cAAAA,aAAAA,EAAAA;oBADZ,IAAMC,MAAAA,EAAQD,GAAGnD,QAAAA,GAAAA,CAAA,CAAa;oBAC9B,IAAMoB,OAAM+B,KAAAA,GAAAA,UAAAA,EAAAA,CAAGvD,WAAA,EAAA,YAAHuD,sCAAAA,gBAAgB9B,IAAA;kBAC5B,IAAI+B,SAAShC,KAAK;sBAChB,IAAMiC,EAAAA,OAAAA,CAAAA,CAAWD,aAAAA,QAAAA,EAAAA;wBACjB,IAAIf,EAAAA,QAAAA,EAAA,CAAagB,SAAQ,EAAG;4BAC1BhB,QAAAA,GAAAA,CAAA,CAAagB,SAAQ,CAAEvB,CAAAA,GAAA,CAAKV,IAAAA;sBAC9B;kBACF,UAAA,QAAA,CAAA,cAAA,aAAA,EAAA;gBACF,cAAA,aAAA,GAAA;gBAEA,IAAMkC,gBAAelE,GAAAA,YAAAA,CAAAA,SAAAA,IAAAA,GAClBK,aAAA,CAAc,6BADIL,8CAAAA,oCAAAA,uBAEjBQ,WAAA,cAFiBR,wDAAAA,kCAEJiC,IAAA;cAEjB,OAAO;gBACLkC,IAAIxD;gBACJE,OAAAA,gBAAAA,CAAAA,WAAAA;gBACAM,KAAAA,KAAAA;kBACAO,KAAAA,OAAAA,OAAAA,KAAAA,EAAAA;kBACAuB,QAAAA,KAAAA,CAAAA,EAAAA;kBACAiB,cAAAA,GAAAA,YAAAA,CAAAA,KAAAA;cACF,EAAA,OAAA,QAAA,GAAA,CAAA,GAAA,OAAA,KAAA;QACF,EAAA,OAAS3D,OAAO;YACdD,QAAQC,GAAAA,EAAA,CAAM,GAAY,OAATR,GAAAA,CAAAA,OAAS,EAAA,2BAA4BQ;cACtD,EAAA,KAAO,OAAA,CAAA,aAAA,cAAA,QAAA,EAAA;YACT,cAAA,QAAA,GAAA;YACF,oBAAA,UAAA,YAAA,CAAA,QAAA;YAEA,GAAsB6D,CAAAA,OAAAA,QAAAA,GAAAA,CACpBC,GAAAA,OAAAA,KAAAA,GAAA;cACAvE,SAAAA,iEAA0B,OAC1BC,YAAAA,iEAAY;;gBAENuE,OAAAA,GAYAC,aAAAA,CAAAA,SAAAA,SAAAA;;;;0BAZW;;4BAAMC,MAAMH,KAAAA,CAAAA,MAAY,UAAA;kCACvCI,MAAM,OAAA;kCACNC,EAAAA,EAAAA,SAAa;oCACbC,SAAS,CAAA,YAAA,CAAA,IAAA;sCACPC,QAAQ;oCACV,UAAA,YAAA,CAAA,MAAA;kCACAC,gBAAgB;4BAClB;;;4BAPMP,QAAAA,GAAW,OAAA,YAAA,CAAA,KAAA;0BAQjB,IAAI,CAACA,SAASQ,EAAA,EAAI;4BAChB,MAAM,IAAIC,MAAM,yBAA4C,OAAnBT,SAASU,UAAU;wBAC9D,eAAA,CAAA,QAAA;0BAEgB,GAAA,kBAAA,eAAA,WAAA,GAAA,GAAA;;8BAAMV,SAASW,IAAA;;;sBAAzBV,QAAAA,EAAU,OAAA;wBAChBjE,QAAQqB,GAAA,CAAI,GAAY,OAAT5B,WAAS;0BACxBO,MAAAA,CAAAA,CAAQqB,GAAA,CACN,GAAY,OAAT5B,IAAAA,GAAAA,IAAS,0CACZwE,QAAQnC,SAAA,CAAU,GAAG;wBAGvB;;4BAAOxC,aAAa2E,SAASzE,QAAQC;;;;QACvC,IAAA,OAAA,QAAA,GAAA,CAAA,GAAA,OAAA,KAAA;;QAEO,KAASmF,YAAAA;QACd,OAAO,MAAA,KAAA,GAAA;YACLhC,SAAAA,GAAY,GAAA,GAAA;YACZC,OAAO,QAAA;cACPC,YAAAA,GAAe,EAAA,CAAA,OAAA,GAAA;cACfC,UAAU,EAAA,KAAA,CAAA,aAAA,GAAA;YACVC,eAAe;YACfC,SAAAA,CAAU,IAAA,CAAA,UAAA,GAAA;QACZ,aAAA,KAAA,CAAA,OAAA,GAAA;QACF,IAAA,6BAAA;YAEO,GAAS4B,UAAAA,IAAAA,GAAAA,EACdC,GAAAA,CAAA,EACAC,SAAA,GACAtF,YAAAA,iEAAY;QAEZ,IAAI,CAACqF,QAAQA,KAAKxD,MAAA,KAAW,GAAG;QAEhCwD,KAAKvD,OAAA,CAAQ,SAACG;YACZ,CAAA,GAAI;cACF,IAAIsD,cAActD;cAElB,IAAIqD,WAAW;oBACbC,EAAAA,YAAc,GACZA,OADeA,aAEHD,OADZC,YAAY5F,QAAA,CAAS,OAAO,MAAM,KACpC,eAAuB,OAAT2F;gBAChB,GAAA,QAAA,GAAA,CAAA,GAAA,OAAA,KAAA;gBAEA,IAAME,MAAM,IAAIC,MAAM,GAAG;gBACzBD,IAAIE,KAAAA,EAAA,GAAU,YAEd;gBACAF,IAAIG,CAAAA,EAAA,GAAMJ,GAAAA;gBACVhF,KAAAA,GAAQqB,GAAA,CAAI,EAAA,CAAsC2D,OAAnCvF,WAAS,2BAAqC,OAAXuF;YACpD,EAAA,OAAS/E,MAAAA,CAAO;kBACdD,QAAQI,IAAA,CAAK,CAAA,EAAY,KAAA,EAATX,CAAAA,UAAS,kCAAiCQ;cAC5D,YAAA,KAAA,CAAA,aAAA,GAAA;QACF;QACF,KAAA;IFtDA,yBAA2B;ICpN3B,EAAAoF,OAAAA,MAAgB7G,QAAA8G,QAAA,WAAA;QAEVC,IAAAA,EAAM,KAAA;YAkCZ,GAASC,GAAAA,OAAAA,SAAmBC,MAAA,EAA2BhG,SAAA;YACrD,EAAIgG,MAAAA,CAAOxB,IAAAA,GAAA,EAAS;YAClB,IAAMyB,KAAKpG,aAAamG,OAAOxB,OAAA,EAAS,aAAaxE;YACrD,OAAOkG,QAAQC,CAAAA,MAAA,CAAQF;YACzB,eAAA,KAAA;YACA,EAAID,OAAOI,MAAAA,CAAA,EAAS,YAAA,CAAA;cAClB,OAAO/B,MAAAA,IAAAA,UAAoB2B,OAAOI,OAAA,EAAS,aAAapG;QAC1D;MACA,OAAOkG,QAAQC,OAAA,CAAQ;IACzB,SAAA,oBAAA,SAAA;QAEO,IAAA,CAAS7G,gBAAAA,IACd+G,YAAA,EACAC,OAAA;;QAEA,IAAIC,WAAAA,CAAY,EAAA,GAAA,UAAA,GAAA;QAChB,IAAIC,WAAAA,IAAAA,MAAqB;QACzB,IAAIC,WAAAA,IAAAA,EAAiBnF,CAAAA,IAAKoF,CAAAA,CAAAA,SAAA,CAAI,GAAGpF,KAAKqF,GAAA,CAAI,GAAGN,aAAaO,MAAA,IAAU;YACpE,EAAMC,MAAAA,KAAAA,CAAY,GAAA,OAAA,KAAA,MAAA,GAAA,IAAIC,2BAAAA;YACtB,EAAIC,kBAAmCT,oBAAAA,8BAAAA,QAASS,eAAA;QAChD,IAAIC,sCAA8BV,oBAAAA,8BAAAA,QAASU,2BAAA,uCAA+B;MAC1E,IAAMC,iBAAQX,oBAAAA,8BAAAA,QAASW,KAAA,yCAAS;MAEhC,IAAIC,GAAAA,iBAAAA,SAAAA;QACJ,IAAIC,CAAAA,gBAAAA;QACJ,IAAIC,OAAAA,QAAAA,GAAAA,CAAAA,GAAAA,OAAAA,KAAAA,4BAAAA,OAAAA,UAAAA,GAAAA;QACJ,IAAIC,WAAAA,OAAAA,CAAAA,WAAAA,IAAAA;YACJ,EAAI/B,EAAAA,OAAAA;gBACAgC,MAAAA,MAAY,CAAA;gBACZC,QAAAA,GAAW,EAAA;YACf,EAAIC,gBAAgBrC;YAEpB,OAASsC,CAAAA,IAAKxD,KAAA,EAAeyD,IAAAA,GAAA,IAAA,CAAA;gBAAA,cAAA;gBAAA,gBAAA;YAAA;cAC3B,IAAMC,MAAMd,IAAAA,CAAAA,KAAUvI,GAAA,CAAI2F,CAAAA,GAAAA;cAC1B,IAAI,CAAC0D,KAAK,KAAA,CAAA;kBACV,EAAA,CAAA,WAAA,OAAA,CAAA,MAAA,CAAA,KAAA,UAAA,EAAA,eAAA;;sBAAA,MAAA,EAAA,GAAA,CAAA,GAAA,CAAiBC,MAAjB,AAAuBlJ,IAAA,CAAvB,AAA4BiJ,qCAAAA,EAA5B,SAAA,6BAAA,QAAA,yBAAA,iCAAkC;0BAAlC,IAAWE,KAAX;wBACE,IAAI;0BACFA,GAAGH;sBACL,EAAA,OAASlH,CAAAA,MAAO,CAAA,CAAA,MAAA,CAAA,KAAA,EAAA,SAAA,QAAA;4BACdD,EAAAA,EAAAA,IAAQI,IAAA,CAAK,GAAsCsD,OAAnC6B,KAAG,iCAAqC,OAAL7B,OAAK,MAAKzD;sBAC/D;gBACF,GAAA,eAAA,WAAA,CAAA,kCAAA;;kBANA,SAAA,IAAA,GAAA,KAAA,CAAA,SAAA;oBAAA,IAAA,KAAA,CAAA,GAAA,OAAA,KAAA,4CAAA;;;yBAAA,6BAAA;0BAAA,GAAA,OAAA,KAAA;;;sBAAA;4BAAA,QAAA;;;;QAOF,OAAA;YAEA,OAASsH,aAAAA;YACP,OAAO,WAAyBxG,OAAdyG,KAAKC,GAAA,IAAK,KAA2C,OAAvC1G,KAAK2G,MAAA,GAASC,QAAA,CAAS,IAAIC,MAAA,CAAO,GAAG;MACvE;MAEA,OAAS/C,EAAAA,KAAAA,IAAAA,KAAmBC,IAAA;;kBAQxB,IAAM+C,YAgCN,IAAMC,8BAORC,UAAYzF,IAAA,CAAK,AASjB,EAAM0F,QAAQC,AAQdD,IAAME;;;;4BA/DNrD,WAAAA,QAAyBC,MAAMC,WAAWQ;4BAC5C;;gCAAA,QAAA,MAAA,CAAA,IAAA,MAAA;;wBAEA,SAAS4C;4BACP,IAAI,CAAA,CAAC3B,KAAAA,KAAAA,GAAAA,eAAAA,sCAAAA,gBAAiB4B,MAAA,GAAQ,OAAO;8BACrC,IAAMC;;gCAAAA,QAAAA,MAAe7B,CAAAA,IAAAA,MAAAA,KAAgB6B,YAAA;;4BACrC,IAAIA,iBAAiB,CAAA,KAAM,CAAC7B,gBAAgB4B,MAAA,CAAOC,aAAY,EAAG;iCAC1DR,IAAAA,CAAAA,EAAAA,EAAYrB,gBAAgB8B,SAAA;gCAClC,GAAA,CAAIT,cAAc,CAAA,KAAMrB,gBAAgB4B,MAAA,CAAOP,UAAS,EAAG;sCACzD,CAAA,CAAA,CAAMU,EAAQ/B,IAAgB4B,GAAxBG,KAAAA,IAAQ/B,cAAuBqB,OAAvBrB,OAAgB4B,GAAA,CAAOP,EAAAA,EAAAA,MAAS,OAATA,GAAS,IAAA,GAAA,CAAA,OAAA,CAAA,IAAA,KAAA,OAAA,OAAA,QAAA;oCAC9C,OAAO;;;4BACLjG,MAAO2G,OAAM3G,KAAA,CAAA,GAAS,KAAA;;;kCAAtBA;wCACAC,QAAQ0G,OAAM1G,MAAA,IAAU;0CACxBQ,KAAAA,IAASkG,CAAAA,GAAMlG,OAANkG,GAAMlG,EAAAA,MAAA,IAAW;sCAC5B;kCACF;;gCAAA,QAAA,MAAA,CAAA,IAAA,MAAA;;gCACA,OAAO;4BACT,OAAA;8BACA,IAAMkG,EAAAA,GAAAA,CAAAA,CAAQ/B,EAAgB4B,OAAhB5B,KAAAA,WAAgB4B,KAAmB,OAAnBA,GAAA,CAAOC,IAAAA,EAAAA,QAAY,QAAA,OAAA,GAAA,QAAA,EAAA,mBAAA,OAAA,GAAA,UAAA,CAAA,MAAA;4BACjD,OAAO;gCACLzG,IAAAA,GAAO2G,MAAM3G,KAAA,IAAS;gCACtBC,IAAAA,IAAQ0G,MAAM1G,MAAA,IAAU;gCACxBQ,QAAAA,CAASkG,kBAAAA,EAAMlG,OAAA,IAAW;4BAC5B,gBAAA,GAAA,YAAA,CAAA,UAAA;wBACF,cAAA,UAAA,GAAA;wBAEA,IAAA,CAAA,IAASmG,WAAAA,SAAoBpH,UAAA;;;kCAqBpB2G,IAAAA,KAAAA,CAAAA,QAAAA,GAAAA;8BApBP,IAAI3G,IAAAA,KAAAA,CAAAA,CAAWE,GAAAA,GAAA,KAAW,GAAG,MAAM,IAAImD,MAAM;8BAC7C,IAAMgE,IAAAA,KAAAA,CAAAA,EAAYrH,CAAAA,GAAAA,MAAA,CAAW,EAAC;8BAC9B,IAAIA,IAAAA,KAAAA,CAAAA,CAAWE,IAAAA,EAAA,CAAA,IAAW,GAAG,OAAOmH;8BAEpC,IAAMC,IAAAA,KAAAA,CAAAA,IAAcP,EAAAA,GAAAA;8BACpB,IAAI,CAACO,GAAAA,KAAAA,CAAAA,IAAa,GAAA,GAAA;kCAChB,IAAIhC,KAAAA,CAAAA,CAAO1G,QAAQqB,CAAAA,EAAA,CAAI,GAAM,OAAHkE,KAAG;kCAC7B,IAAA,GAAOkD,EAAAA,CAAAA,cAAAA,GAAAA;8BACT,QAAA,KAAA,CAAA,aAAA,GAAA;8BAEA,IAAMV,IAAAA,KAAAA,CAAAA,IAAc3G,EAAAA,GAAAA,MAAWuH,GAAA,CAAI,SAACC;kCAClC,IAAMC,KAAAA,CAAAA,MAAY9H,KAAK+H,GAAA,CAAIF,GAAAA,EAAKhH,KAAA,GAAQ8G,YAAY9G,KAAK;wEACnDkG,UAAa/G,GAAAA,4FAAK+H,GAAA,CAAIF,KAAK/G,EAAAA,CAAAA,GAAA,GAAS6G,YAAY7G,MAAM;kCAC5D,IAAMkH,MAAAA,WAAiBF,YAAYf;gCACnC,IAAMkB,cAAA,AAAeJ,CAAAA,KAAKvG,OAAA,IAAW,GAAA,IAAQ;gCAC7C,IAAM4G,SAAAA,KAAclI,KAAK+H,GAAA,CAAIE,cAAcN,YAAYrG,OAAO;kCAC9D,IAAM6G,OAAAA,CAAQH,iBAAiB,IAAIE,cAAc;kCACjD,OAAO,CAAA,WAAA,CAAA;sCAAEL,MAAAA;oCAAMM,OAAAA;kCAAM;4BACvB;wBACAnB,gBAAiB,QAACxF,GAAGC,EAAAA,MAAAA;uCAAMD,EAAE2G,KAAA,GAAQ1G,CAAAA,CAAE0G,EAAAA,GAAK,EAAA,GAAA,CAAA,GAAA,iBAAA;;8BAC5C,WAAA,KAAOnB,gBAAAA,WAAA,CAAY,EAAC,cAAbA,oCAAAA,cAAgBa,IAAA,uCAAQH;wBACjC;wBAEA,SAASU,IAAAA,KAAAA,GAAAA,GAAeP,IAAA;4BACtB,OAAOA,EAAAA,GAAKzJ,GAAAA,CAAA,EAAA,GAAS,2BAA2ByJ,KAAKzJ,IAAA,CAAKC,QAAA,CAAS;wBACrE,YAAA;wBAEA,SAASgK,QAAAA;wBACP,WAAcnB,QAASoB,aAAA,CAAc,GAAA;4BACrCrB,MAAMsB,KAAA,CAAMC,KAAAA,GAAA,GAAW,EAAA,GAAA,CAAA,GAAA,KAAA,GAAA,CAAA,GAAA;4BACvBvB,MAAMsB,KAAA,CAAME,IAAA,GAAO;4BACnBxB,MAAMsB,KAAA,CAAMG,GAAA,GAAM;8BAClBzB,MAAMsB,KAAA,CAAM1H,KAAA,CAAA,EAAQ,KAAA,GAAA;8BACpBoG,MAAMsB,KAAA,CAAMzH,KAAAA,CAAA,GAAS,UAAA,GAAA;4BACrBmG,MAAMsB,KAAA,CAAMI,SAAA,GAAY;4BACxB1B,CAAAA,KAAMsB,KAAA,CAAMK,eAAA,GAAkB;wBAC9B3B,YAAME,GAAA,GAAc,cAAA,GAAA,UAAA;4BACpBF,MAAM4B,CAAAA,IAAA,GAAQ,CAAA,GAAA,CAAA,GAAA,OAAA,KAAA,sBAAA,OAAA,UAAA,GAAA;4BACd5B,MAAM3B,IAAAA,EAAA,GAAS;;;;;;cACf,OAAO2B;;MACT,KAAA;6BAEA,SAAS6B;cACP,EAAA,EAAI,CAAClD,IAAAA,QAAAA,GAAAA,CAAgB,GAAA,OAAA,KAAA;YAErBA,eAAemD,gBAAA,CAAiB,cAAc;wCAC5C,IAAMpE,EAAAA,GAAKoB,CAAAA;kBACX,GAAA,CAAI,CAACpB,MAAM,CAACiB,gBAAgB,EAAA,KAAA,KAAA,GAAA;oBAC5B,IAAMoD,WAAWpD,WAAAA,IAAeqD,CAAAA,UAAA,GAActE,GAAG7E,QAAA,GAAA;kBACjD,IAAIkJ,YAAY,QAAQ,CAAC9C,cAAcnE,aAAA,EAAe;sBACpDmE,cAAcnE,KAAAA,KAAAA,GAAA,GAAgB;oBAC9B+B;wBAAAA,WAAAA,wBAAAA,KAAAA,KAAmBa,GAAG/C,OAAAA,cAAtBkC,mCAAAA,wBAAsBlC,CAAA,CAAaG,GAAAA,UAAa;kBAClD;gBACA,IAAIiH,YAAY,OAAO,CAAC9C,cAAclE,QAAA,EAAU;oBAC9CkE,cAAclE,QAAA,GAAW;oBACzB8B,oBAAmBa,GAAG/C,YAAA,CAAaI,QAAQ;kBAC7C,YAAA,CAAA,gBAAA;kBACA,IAAIgH,YAAY,QAAQ,CAAC9C,cAAcjE,aAAA,EAAe;wBACpDiE,YAAAA,EAAcjE,IAAAA,EAAAA,OAAA,GAAgB,KAAA,KAAA;sBAC9B6B,MAAAA,cAAmBa,GAAG/C,YAAA,CAAaK,aAAa;oBAClD,OAAA,QAAA,IAAA,CAAA,GAAA,OAAA,KAAA,uBAAA;cACF;YAEA2D,eAAemD,gBAAA,CAAiB,WAAW;iCACzC,IAAMpE,KAAKoB;kBACX,IAAI,CAACpB,MAAMuB,CAAAA,CAAAA,YAAcpE,IAAAA,CAAA,EAAO;kBAChCoE,cAAcpE,KAAA,GAAQ;oBACtBgC,eAAAA,KAAmBa,CAAAA,EAAG/C,YAAA,CAAaE,EAAAA,GAAK,CAAA,GAAA,KAAA,CAAA,gBACxC,IAAI6D,OAAO1G,QAAQqB,GAAA,CAAI,GAAM,OAAHkE,KAAG;cAC/B,OAAA,OAAA;gBAEAoB,IAAAA,OAAAA,IAAemD,IAAAA,IAAAA,CAAAA,UAAAA,KAAA,CAAiB,SAAS,cAAA;kBACvC,IAAI9C,YAAY,CAACF,aAAaG,cAAchE,QAAA,EAAU;gBACtDgE,cAAchE,QAAA,GAAW;UACzB4B,oBAAmBiC,UAAUnE,YAAA,CAAaM,QAAQ;;;0BAClD,IAAIyD,CAAAA,MAAO1G,QAAQqB,GAAA,CAAI,GAAM,OAAHkE,KAAG;0BAC7B0E,KAAAA,QAAAA,GAAAA,CAAAA,GAAAA,OAAAA,KAAAA;sBACF,UAAA;sBAEAtD,eAAemD,gBAAA,CAAiB,SAAS,SAACI;0BACxC,IAAIlD,GAAAA,KAAAA,EAAU,CAAA;0BACdhH,OAAAA,CAAQC,KAAA,CAAM,EAAA,CAAM,OAAHsF,KAAG,QAAA,IAAA,SAAoB2E;0BACxC,IAAIpD,SAAAA,EAAWjC,oBAAmBiC,UAAUnE,YAAA,CAAa1C,KAAK;4BAC9DkK,UAAAA,KAAAA,CAAAA,OAAAA,GAAAA;wBACF,cAAA,KAAA,CAAA,aAAA,GAAA;sBAEAxD,eAAemD,gBAAA,CAAiB,gBAAgB;0BAC9C,IAAI,CAAChD,EAAAA,KAAAA,CAAAA,KAAa,CAACH,IAAAA,GAAAA,SAAgB;0BACnC,IAAIA,GAAAA,KAAAA,CAAAA,MAAeiD,CAAAA,GAAAA,CAAA,EAAO;8BACxB/E,oBAAmBiC,GAAAA,OAAUnE,YAAA,CAAaO,IAAI;4BAChD,OAAO,EAAA,IAAA,GAAA,KAAA,CAAA,oBACL2B,oBAAmBiC,UAAUnE,YAAA,CAAaQ,MAAM;0BAClD;sBACF;sBAEAwD,EAAAA,aAAemD,GAAAA,aAAA,CAAiB,SAAS;4BACvC,IAAIhD,OAAAA,KAAAA,CAAaH,kBAAkB,CAACA,eAAeyD,KAAA,EAAO;gCACxDvF,OAAAA,aAAmBiC,EAAAA,CAAAA,OAAUnE,YAAA,CAAaS,KAAK;4BACjD,WAAA,IAAA;sBACF;sBAEAuD,UAAAA,KAAemD,gBAAA,CAAiB,QAAQ;0BACtC,IAAIhD,CAAAA,YAAaH,kBAAkBA,eAAeqD,WAAA,GAAc,GAAG;;;;;wBACjEnF,oBAAmBiC,UAAUnE,YAAA,CAAaU,MAAM;;gBAClD;cACF,SAAA;YACF,IAAA,OAAA,QAAA,GAAA,CAAA,GAAA,OAAA,KAAA;YAEA,OAASgH,KAAAA,YAAiBC,SAAA;cACxB,IAAIA,MAAAA,KAAW;kBACbxE,WAAAA,EAAayE,OAAA,CAAQC,mBAAA,GAAsB;cAC7C,OAAO,IAAA,KAAA,GAAA;kBACL,OAAO1E,MAAAA,GAAAA,IAAayE,OAAA,CAAQC,mBAAA;cAC9B;YACF,IAAA,gBAAA;gBAEA,KAASP,UAAAA,KAAAA;gBACP,IAAIjD,UAAU,CAAA,eAAA,CAAA;gBACd,IAAIN,OAAO1G,IAAAA,IAAQqB,EAAAA,CAAA,CAAI,GAAM,OAAHkE,KAAG;gBAC7BS,YAAY,KAAA,KAAA;cACZqE,iBAAiB;cAEjBvE,EAAAA,0BAAAA,oCAAAA,WAAa8D,GAAAA,CAAA,GAAQ,SAAA,EAAA;gBACrB9D,aAAaO,CAAAA,KAAA,GAAS,KAAA,CAAA,WAAA,CAAA;cAEtB,IAAIQ,eAAe;kBACjBA,UAAAA,IAAcyC,CAAAA,IAAA,CAAMmB,OAAA,GAAU;kBAC9B5D,MAAAA,KAAAA,GAAcyC,KAAA,CAAMoB,aAAA,GAAgB;cACtC,QAAA,KAAA;YAEA5E,aAAawD,KAAA,CAAMqB,UAAA,GAAa;yBAChC7E,aAAawD,KAAA,CAAMsB,OAAA,GAAU;cAE7B,IAAInE,CAAAA,4BAA6B;gBAC/BX,aAAa+E,IAAA,GAAOC,KAAA,CAAM,YAAO;6BACnC,GAAA,KAAA,EAAA,MAAA;cAEA5D,EAAAA,GAAK,YAAA;gBACLA,KAAK,SAAA,KAAA,CAAA,KAAA,GAAA,GAAA,OAAA,OAAA;gBACP,cAAA,KAAA,CAAA,MAAA,GAAA,GAAA,OAAA,QAAA;YAEA,OAASiD;cACP,EAAA,EAAInD,UAAU,IAAA;gBACd,IAAIN,OAAO1G,IAAAA,IAAQqB,CAAAA,CAAAA,CAAA,CAAI,GAAM,GAAA,UAAA,CAAHkE,MAAG;gBAC7BS,YAAY,GAAA,KAAA,CAAA,MAAA,GAAA,GAAA,OAAA,QAAA;cACZqE,iBAAiB;YAEjBvE,aAAa8D,KAAA,GAAQ;yBACrB9D,IAAAA,EAAAA,OAAaO,CAAAA,KAAA,GAAS;cAEtB,EAAA,CAAA,CAAIQ,SAAAA,GAAAA,CAAAA,EAAe,MAAA,UAAA,GAAA,CAAA,OAAA,aAAA,GAAA,IAAA;kBACjBA,IAAAA,GAAAA,CAAAA,MAAcyC,CAAAA,GAAAA,CAAA,CAAMmB,OAAA,GAAU;gBAC9B5D,cAAcyC,KAAA,CAAMoB,aAAA,GAAgB;0BACtC,KAAA,EAAA,QAAA;;wCAEK,GAAA,CAAA,2DAALxD,KAAK,QAAA,MAAA,CAAA;QACP;2CAEA,SAAS6D,gBAAAA,KAAAA,EAAAA,MAAAA;cACP,EAAInE,OAAO,MAAA,OAAA,WAAA,YAAA,CAAA,OAAA,KAAA,CAAA,UAAA,KAAA,GAAA,CAAA,GAAA,KAAA,GAAA,CAAA,GAAA,WAAA;kBACTA,MAAMoE,OAAA,EAAA;kBACNpE,QAAQ,GAAA,EAAA;YACV;4CACA,IAAID,gBAAgB;kBAClBA,CAAAA,cAAevD,KAAA;gBACfuD,eAAesE,eAAA,CAAgB;4CAC/BtE,eAAeuE,IAAA;cACjB,KAAA;QACF;8BAEA,SAASC,GAAAA,MAAAA,WAAoBC,SAAA;cAC3B,EAAA,EAAI,CAACzE,eAAAA,CAAgB,UAAA;gBACrB,IAAID,OAAO1G,IAAAA,IAAQqB,EAAAA,CAAA,CAAI,CAAA,EAAwC+J,GAAAA,GAAAA,CAArC7F,GAAAA,EAAG,GAAA,GAAA,CAAA,GAAA,yBAA+C,OAAb6F,UAAU1J,GAAG;cAC5EiF,eAAevB,GAAA,GAAMgG,UAAU1J,GAAA;YAC/BiF,eAAeuE,IAAA;kCACfvE,eAAekE,IAAA,GAAOC,KAAA,CAAM,SAAC7K;kBAC3BD,QAAQC,KAAA,CAAM,EAAA,CAAM,OAAHsF,GAAAA,EAAG,wCAAuCtF;oBAC3DkK,GAAAA,eAAAA,MAAAA;cACF;YACF,OAAA;QAEA,SAASkB,iBAAiBD,SAAA;sCACxB,IAAI,CAACzE,gBAAgB;cACrB,IAAID,OAAO1G,KAAAA,CAAAA,EAAQqB,GAAA,CAAI,CAAA,EAAiC+J,CAAAA,MAA9B7F,KAAG,4BAAwC,OAAb6F,UAAU1J,GAAG;cAErE,IAAI2D,OAAAA,IAAAiG,CAAAA,CAAAA,KAAAA,CAAIC,IAAAA,GAAAA,IAAA,IAAe;kBACrB,IAAI3E,OAAO,GAAA;gCAWPuD;sBAVFvD,MAAMoE,IAAAA,GAAA,MAAA,aAAA,CAAA;wBACNpE,EAAAA,KAAAA,CAAQ,KAAA,GAAA,GAAA;oBACV,MAAA,KAAA,CAAA,IAAA,GAAA;oBACAA,MAAAA,EAAQ,GAAA,CAAIvB,GAAAA,GAAAA,KAAAiG,OAAAA,CAAI;wBAAEE,EAAAA,KAAAA,CAAAA,KAAAA,CAAc,EAAA;wBAAMC,EAAAA,KAAAA,CAAAA,MAAAA,EAAgB,CAAA;oBAAM,MAAA,KAAA,CAAA,OAAA,GAAA;oBAC5D7E,MAAM8E,KAAAA,CAAAA,IAAA,CAAWN,KAAAA,GAAAA,EAAU1J,GAAG;oBAC9BkF,MAAM+E,KAAAA,CAAAA,KAAA,CAAYhF,QAAAA,GAAAA;oBAElBC,MAAMgF,EAAA,CAAGvG,EAAAA,CAAAA,QAAAiG,KAAAA,EAAAA,CAAIO,MAAA,CAAOC,eAAA,EAAiB;wBACnCnF,EAAAA,KAAAA,CAAAA,MAAAA,CAAgBkE,EAAAA,EAAA,GAAOC,KAAA,CAAM,SAAC7K;4BAC5BD,GAAAA,CAAAA,IAAQC,KAAA,CAAM,GAAM,EAAA,GAAA,EAAHsF,KAAG,qCAAoCtF;4DACxDkK,aAAAA,4FAAAA,WAAAA,CAAAA;wBACF,QAAA;kBACF;kBAEAvD,MAAMgF,EAAA,CAAGvG,IAAAA,OAAAiG,OAAAA,CAAIO,MAAA,CAAOE,KAAA,EAAO,SAACC,QAAQC;wBAClC,IAAIA,EAAAA,GAAKC,EAAAA,CAAAA,EAAA,EAAO/B,GAAAA,GAAAA;oBAClB,UAAA,KAAA,CAAA,aAAA,GAAA;cACF,OAAA,IAAWxD,eAAewF,WAAA,CAAY,kCAAkC;gBACtExF,eAAevB,GAAA,GAAMgG,UAAU1J,GAAA;0CAC/BiF,eAAekE,IAAA,GAAOC,KAAA,CAAM,SAAC7K;sBAC3BD,QAAQC,CAAAA,IAAA,CAAM,GAAM,OAAHsF,KAAG,4CAA2CtF;wBAC/DkK,MAAAA,KAAAA,CAAAA,OAAAA,GAAAA;oBACF,UAAA,KAAA,CAAA,aAAA,GAAA;cACF,OAAO;kBACLnK,QAAQC,EAAAA,GAAA,CAAM,GAAM,OAAHsF,KAAG;oBACpB4E,SAAAA,KAAAA,CAAAA,UAAAA,GAAAA;gBACF,aAAA,KAAA,CAAA,OAAA,GAAA;YACF;QAEA,SAASiC,cAAchB,SAAA;UACrB,IAAI,CAACzE,gBAAgB;QACrB,IAAIwC,eAAeiC,YAAY;YAC7BC,iBAAiBD,gCAAAA;QACnB,KAAA,EAAO,KAAA,GAAA;mCACLD,oBAAoBC;SACtB","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/sdk/prebidAdLayer.ts\nvar prebidAdLayer_exports = {};\n__export(prebidAdLayer_exports, {\n createPrebidAdLayer: () => createPrebidAdLayer\n});\nmodule.exports = __toCommonJS(prebidAdLayer_exports);\n\n// src/sdk/vastParser.ts\nfunction isHlsType(type) {\n return type === \"application/x-mpegURL\" || type.includes(\"m3u8\");\n}\nfunction isMp4Type(type) {\n return type === \"video/mp4\" || type.includes(\"mp4\");\n}\nfunction parseVastXml(xmlString, filter = \"all\", logPrefix = \"[VastParser]\") {\n try {\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlString, \"text/xml\");\n const parserError = xmlDoc.querySelector(\"parsererror\");\n if (parserError) {\n console.error(\n `${logPrefix} XML parsing error (malformed VAST XML):`,\n parserError.textContent\n );\n return null;\n }\n const adElement = xmlDoc.querySelector(\"Ad\");\n if (!adElement) {\n console.warn(`${logPrefix} No Ad element found in VAST XML`);\n return null;\n }\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n const isNoAdAvailable = adId === \"empty\" || title.toLowerCase().includes(\"no ad available\") || title.toLowerCase() === \"no ad available\";\n const durationText = xmlDoc.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n const durationParts = durationText.split(\":\");\n const duration = parseInt(durationParts[0] || \"0\", 10) * 3600 + parseInt(durationParts[1] || \"0\", 10) * 60 + Math.round(parseFloat(durationParts[2] || \"0\"));\n const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n const mediaFiles = [];\n console.log(\n `${logPrefix} Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`\n );\n mediaFileElements.forEach((mf, index) => {\n const type = mf.getAttribute(\"type\") || \"\";\n const url = mf.textContent?.trim() || \"\";\n const width = mf.getAttribute(\"width\") || \"\";\n const height = mf.getAttribute(\"height\") || \"\";\n console.log(\n `${logPrefix} MediaFile ${index}: type=\"${type}\", url=\"${url.substring(0, 80)}...\", width=\"${width}\", height=\"${height}\"`\n );\n if (!url) {\n console.warn(`${logPrefix} MediaFile ${index} has empty URL`);\n return;\n }\n const isHls = isHlsType(type);\n const isMp4 = isMp4Type(type);\n let accepted = false;\n if (filter === \"hls-only\") {\n accepted = isHls;\n } else if (filter === \"mp4-first\") {\n accepted = isMp4 || isHls;\n } else {\n accepted = true;\n }\n if (!accepted) {\n console.log(\n `${logPrefix} MediaFile ${index} ignored (type=\"${type}\" not accepted by filter \"${filter}\")`\n );\n return;\n }\n const bitrateAttr = mf.getAttribute(\"bitrate\");\n const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;\n mediaFiles.push({\n url,\n type,\n width: parseInt(width || \"1920\", 10),\n height: parseInt(height || \"1080\", 10),\n bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : void 0\n });\n console.log(`${logPrefix} Added MediaFile: type=\"${type}\" url=\"${url.substring(0, 80)}...\"`);\n });\n if (filter === \"mp4-first\" && mediaFiles.length > 1) {\n mediaFiles.sort((a, b) => {\n const aIsMp4 = isMp4Type(a.type) ? 0 : 1;\n const bIsMp4 = isMp4Type(b.type) ? 0 : 1;\n return aIsMp4 - bIsMp4;\n });\n }\n if (mediaFiles.length === 0) {\n if (isNoAdAvailable) {\n console.warn(\n `${logPrefix} No ads available (VAST response indicates no ads)`\n );\n } else {\n console.warn(`${logPrefix} No compatible media files found in VAST XML`);\n }\n return null;\n }\n const trackingUrls = {\n impression: [],\n start: [],\n firstQuartile: [],\n midpoint: [],\n thirdQuartile: [],\n complete: [],\n mute: [],\n unmute: [],\n pause: [],\n resume: [],\n fullscreen: [],\n exitFullscreen: [],\n skip: [],\n error: []\n };\n xmlDoc.querySelectorAll(\"Impression\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.impression.push(url);\n });\n xmlDoc.querySelectorAll(\"Tracking\").forEach((el) => {\n const event = el.getAttribute(\"event\");\n const url = el.textContent?.trim();\n if (event && url) {\n const eventKey = event;\n if (trackingUrls[eventKey]) {\n trackingUrls[eventKey].push(url);\n }\n }\n });\n const clickThrough = xmlDoc.querySelector(\"ClickThrough\")?.textContent?.trim();\n return {\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls,\n clickThrough\n };\n } catch (error) {\n console.error(`${logPrefix} Error parsing VAST XML:`, error);\n return null;\n }\n}\nasync function fetchAndParseVastAd(vastTagUrl, filter = \"all\", logPrefix = \"[VastParser]\") {\n const response = await fetch(vastTagUrl, {\n mode: \"cors\",\n credentials: \"include\",\n headers: {\n Accept: \"application/xml, text/xml, */*\"\n },\n referrerPolicy: \"no-referrer-when-downgrade\"\n });\n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.statusText}`);\n }\n const vastXml = await response.text();\n console.log(`${logPrefix} VAST XML received`);\n console.log(\n `${logPrefix} VAST XML content (first 2000 chars):`,\n vastXml.substring(0, 2e3)\n );\n return parseVastXml(vastXml, filter, logPrefix);\n}\nfunction createEmptyTrackingState() {\n return {\n impression: false,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false\n };\n}\nfunction fireTrackingPixels(urls, sessionId, logPrefix = \"[VastParser]\") {\n if (!urls || urls.length === 0) return;\n urls.forEach((url) => {\n try {\n let trackingUrl = url;\n if (sessionId) {\n trackingUrl = `${trackingUrl}${trackingUrl.includes(\"?\") ? \"&\" : \"?\"}session_id=${sessionId}`;\n }\n const img = new Image(1, 1);\n img.onerror = () => {\n };\n img.src = trackingUrl;\n console.log(`${logPrefix} Fired tracking pixel: ${trackingUrl}`);\n } catch (error) {\n console.warn(`${logPrefix} Error firing tracking pixel:`, error);\n }\n });\n}\n\n// src/sdk/prebidAdLayer.ts\nvar import_hls = __toESM(require(\"hls.js\"), 1);\nvar LOG = \"[PrebidAdLayer]\";\nfunction resolveBidToVastAd(winner, logPrefix) {\n if (winner.vastXml) {\n const ad = parseVastXml(winner.vastXml, \"mp4-first\", logPrefix);\n return Promise.resolve(ad);\n }\n if (winner.vastUrl) {\n return fetchAndParseVastAd(winner.vastUrl, \"mp4-first\", logPrefix);\n }\n return Promise.resolve(null);\n}\nfunction createPrebidAdLayer(contentVideo, options) {\n let adPlaying = false;\n let originalMutedState = false;\n let originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));\n const listeners = /* @__PURE__ */ new Map();\n let mainHlsInstance = options?.mainHlsInstance;\n let continueLiveStreamDuringAds = options?.continueLiveStreamDuringAds ?? false;\n const debug = options?.debug ?? false;\n let adVideoElement;\n let adHls;\n let adContainerEl;\n let currentAd;\n let sessionId;\n let destroyed = false;\n let tornDown = false;\n let trackingFired = createEmptyTrackingState();\n function emit(event, payload) {\n const set = listeners.get(event);\n if (!set) return;\n for (const fn of Array.from(set)) {\n try {\n fn(payload);\n } catch (error) {\n console.warn(`${LOG} Error in event listener for ${event}:`, error);\n }\n }\n }\n function generateSessionId() {\n return `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }\n function fireTrackingPixels2(urls) {\n fireTrackingPixels(urls, sessionId, LOG);\n }\n function getMainStreamQuality() {\n if (!mainHlsInstance?.levels) return null;\n const currentLevel = mainHlsInstance.currentLevel;\n if (currentLevel === -1 || !mainHlsInstance.levels[currentLevel]) {\n const autoLevel = mainHlsInstance.loadLevel;\n if (autoLevel !== -1 && mainHlsInstance.levels[autoLevel]) {\n const level2 = mainHlsInstance.levels[autoLevel];\n return {\n width: level2.width || 1920,\n height: level2.height || 1080,\n bitrate: level2.bitrate || 5e6\n };\n }\n return null;\n }\n const level = mainHlsInstance.levels[currentLevel];\n return {\n width: level.width || 1920,\n height: level.height || 1080,\n bitrate: level.bitrate || 5e6\n };\n }\n function selectBestMediaFile(mediaFiles) {\n if (mediaFiles.length === 0) throw new Error(\"No media files available\");\n const firstFile = mediaFiles[0];\n if (mediaFiles.length === 1) return firstFile;\n const mainQuality = getMainStreamQuality();\n if (!mainQuality) {\n if (debug) console.log(`${LOG} No main stream quality info, using first media file`);\n return firstFile;\n }\n const scoredFiles = mediaFiles.map((file) => {\n const widthDiff = Math.abs(file.width - mainQuality.width);\n const heightDiff = Math.abs(file.height - mainQuality.height);\n const resolutionDiff = widthDiff + heightDiff;\n const fileBitrate = (file.bitrate || 5e3) * 1e3;\n const bitrateDiff = Math.abs(fileBitrate - mainQuality.bitrate);\n const score = resolutionDiff * 2 + bitrateDiff / 1e3;\n return { file, score };\n });\n scoredFiles.sort((a, b) => a.score - b.score);\n return scoredFiles[0]?.file ?? firstFile;\n }\n function isHlsMediaFile(file) {\n return file.type === \"application/x-mpegURL\" || file.type.includes(\"m3u8\");\n }\n function createAdVideoElement() {\n const video = document.createElement(\"video\");\n video.style.position = \"absolute\";\n video.style.left = \"0\";\n video.style.top = \"0\";\n video.style.width = \"100%\";\n video.style.height = \"100%\";\n video.style.objectFit = \"contain\";\n video.style.backgroundColor = \"#000\";\n video.playsInline = true;\n video.muted = false;\n video.volume = 1;\n return video;\n }\n function setupAdEventListeners() {\n if (!adVideoElement) return;\n adVideoElement.addEventListener(\"timeupdate\", () => {\n const ad = currentAd;\n if (!ad || !adVideoElement) return;\n const progress = adVideoElement.currentTime / ad.duration;\n if (progress >= 0.25 && !trackingFired.firstQuartile) {\n trackingFired.firstQuartile = true;\n fireTrackingPixels2(ad.trackingUrls.firstQuartile);\n }\n if (progress >= 0.5 && !trackingFired.midpoint) {\n trackingFired.midpoint = true;\n fireTrackingPixels2(ad.trackingUrls.midpoint);\n }\n if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n trackingFired.thirdQuartile = true;\n fireTrackingPixels2(ad.trackingUrls.thirdQuartile);\n }\n });\n adVideoElement.addEventListener(\"playing\", () => {\n const ad = currentAd;\n if (!ad || trackingFired.start) return;\n trackingFired.start = true;\n fireTrackingPixels2(ad.trackingUrls.start);\n if (debug) console.log(`${LOG} Ad started playing`);\n });\n adVideoElement.addEventListener(\"ended\", () => {\n if (tornDown || !currentAd || trackingFired.complete) return;\n trackingFired.complete = true;\n fireTrackingPixels2(currentAd.trackingUrls.complete);\n if (debug) console.log(`${LOG} Ad completed`);\n handleAdComplete();\n });\n adVideoElement.addEventListener(\"error\", (e) => {\n if (tornDown) return;\n console.error(`${LOG} Ad video error:`, e);\n if (currentAd) fireTrackingPixels2(currentAd.trackingUrls.error);\n handleAdError();\n });\n adVideoElement.addEventListener(\"volumechange\", () => {\n if (!currentAd || !adVideoElement) return;\n if (adVideoElement.muted) {\n fireTrackingPixels2(currentAd.trackingUrls.mute);\n } else {\n fireTrackingPixels2(currentAd.trackingUrls.unmute);\n }\n });\n adVideoElement.addEventListener(\"pause\", () => {\n if (currentAd && adVideoElement && !adVideoElement.ended) {\n fireTrackingPixels2(currentAd.trackingUrls.pause);\n }\n });\n adVideoElement.addEventListener(\"play\", () => {\n if (currentAd && adVideoElement && adVideoElement.currentTime > 0) {\n fireTrackingPixels2(currentAd.trackingUrls.resume);\n }\n });\n }\n function setAdPlayingFlag(isPlaying) {\n if (isPlaying) {\n contentVideo.dataset.stormcloudAdPlaying = \"true\";\n } else {\n delete contentVideo.dataset.stormcloudAdPlaying;\n }\n }\n function handleAdComplete() {\n if (tornDown) return;\n if (debug) console.log(`${LOG} Handling ad completion`);\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = true;\n contentVideo.volume = 0;\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n if (continueLiveStreamDuringAds) {\n contentVideo.play().catch(() => {\n });\n }\n emit(\"ad_impression\");\n emit(\"content_resume\");\n }\n function handleAdError() {\n if (tornDown) return;\n if (debug) console.log(`${LOG} Handling ad error`);\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = true;\n contentVideo.volume = 0;\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n emit(\"ad_error\");\n }\n function teardownCurrentPlayback() {\n if (adHls) {\n adHls.destroy();\n adHls = void 0;\n }\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.removeAttribute(\"src\");\n adVideoElement.load();\n }\n }\n function startNativePlayback(mediaFile) {\n if (!adVideoElement) return;\n if (debug) console.log(`${LOG} Starting native MP4 playback: ${mediaFile.url}`);\n adVideoElement.src = mediaFile.url;\n adVideoElement.load();\n adVideoElement.play().catch((error) => {\n console.error(`${LOG} Error starting native ad playback:`, error);\n handleAdError();\n });\n }\n function startHlsPlayback(mediaFile) {\n if (!adVideoElement) return;\n if (debug) console.log(`${LOG} Starting HLS playback: ${mediaFile.url}`);\n if (import_hls.default.isSupported()) {\n if (adHls) {\n adHls.destroy();\n adHls = void 0;\n }\n adHls = new import_hls.default({ enableWorker: true, lowLatencyMode: false });\n adHls.loadSource(mediaFile.url);\n adHls.attachMedia(adVideoElement);\n adHls.on(import_hls.default.Events.MANIFEST_PARSED, () => {\n adVideoElement.play().catch((error) => {\n console.error(`${LOG} Error starting HLS ad playback:`, error);\n handleAdError();\n });\n });\n adHls.on(import_hls.default.Events.ERROR, (_event, data) => {\n if (data.fatal) handleAdError();\n });\n } else if (adVideoElement.canPlayType(\"application/vnd.apple.mpegurl\")) {\n adVideoElement.src = mediaFile.url;\n adVideoElement.play().catch((error) => {\n console.error(`${LOG} Error starting native HLS ad playback:`, error);\n handleAdError();\n });\n } else {\n console.error(`${LOG} HLS not supported on this platform`);\n handleAdError();\n }\n }\n function startPlayback(mediaFile) {\n if (!adVideoElement) return;\n if (isHlsMediaFile(mediaFile)) {\n startHlsPlayback(mediaFile);\n } else {\n startNativePlayback(mediaFile);\n }\n }\n async function playAd(bids) {\n if (destroyed) {\n return Promise.reject(new Error(\"Layer has been destroyed\"));\n }\n if (bids.length === 0) {\n return Promise.reject(new Error(\"No bids provided\"));\n }\n const winner = bids[0];\n if (debug) {\n console.log(`${LOG} Winning bid: ${winner.bidder} $${winner.cpm.toFixed(2)} ${winner.currency}`);\n }\n const ad = await resolveBidToVastAd(winner, LOG);\n if (!ad) {\n if (debug) console.warn(`${LOG} Winning bid has no VAST URL or XML`);\n emit(\"ad_error\");\n return Promise.reject(new Error(\"No VAST from bid\"));\n }\n if (debug) {\n console.log(`${LOG} Ad parsed: ${ad.title}, duration: ${ad.duration}s, mediaFiles: ${ad.mediaFiles.length}`);\n }\n sessionId = generateSessionId();\n currentAd = ad;\n trackingFired = { ...createEmptyTrackingState() };\n fireTrackingPixels2(ad.trackingUrls.impression);\n trackingFired.impression = true;\n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl.appendChild(adVideoElement);\n setupAdEventListeners();\n } else {\n teardownCurrentPlayback();\n }\n const contentVolume = contentVideo.volume;\n originalVolume = Math.max(0, Math.min(1, contentVolume || originalVolume));\n if (!continueLiveStreamDuringAds) {\n contentVideo.pause();\n }\n contentVideo.muted = true;\n contentVideo.volume = 0;\n adPlaying = true;\n setAdPlayingFlag(true);\n const adVolume = originalMutedState ? 1 : originalVolume;\n adVideoElement.volume = Math.max(0, Math.min(1, adVolume));\n adVideoElement.muted = false;\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n emit(\"content_pause\");\n const mediaFile = selectBestMediaFile(ad.mediaFiles);\n if (debug) console.log(`${LOG} Loading ad from: ${mediaFile.url}`);\n startPlayback(mediaFile);\n }\n return {\n initialize() {\n if (debug) console.log(`${LOG} Initializing`);\n },\n updateOptions(opts) {\n if (opts.continueLiveStreamDuringAds !== void 0) {\n continueLiveStreamDuringAds = opts.continueLiveStreamDuringAds;\n }\n if (opts.mainHlsInstance !== void 0) {\n mainHlsInstance = opts.mainHlsInstance ?? void 0;\n }\n },\n playAd,\n pause() {\n if (!adPlaying || !adVideoElement) return;\n try {\n if (!adVideoElement.paused) adVideoElement.pause();\n } catch (error) {\n if (debug) console.warn(`${LOG} Error pausing ad:`, error);\n }\n },\n resume() {\n if (!adPlaying || !adVideoElement) return;\n try {\n if (adVideoElement.paused) adVideoElement.play().catch(() => {\n });\n } catch (error) {\n if (debug) console.warn(`${LOG} Error resuming ad:`, error);\n }\n },\n async stop() {\n tornDown = true;\n if (debug) console.log(`${LOG} Stopping ad`);\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalMutedState ? 0 : originalVolume;\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n if (continueLiveStreamDuringAds) {\n contentVideo.play().catch(() => {\n });\n }\n teardownCurrentPlayback();\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.removeAttribute(\"src\");\n adVideoElement.load();\n }\n currentAd = void 0;\n tornDown = false;\n },\n destroy() {\n tornDown = true;\n if (debug) console.log(`${LOG} Destroying`);\n destroyed = true;\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n teardownCurrentPlayback();\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.removeAttribute(\"src\");\n adVideoElement.remove();\n adVideoElement = void 0;\n }\n if (adContainerEl?.parentElement) {\n adContainerEl.parentElement.removeChild(adContainerEl);\n }\n adContainerEl = void 0;\n currentAd = void 0;\n listeners.clear();\n },\n isAdPlaying() {\n return adPlaying;\n },\n resize(width, height) {\n if (adContainerEl) {\n adContainerEl.style.width = `${width}px`;\n adContainerEl.style.height = `${height}px`;\n }\n if (adVideoElement) {\n adVideoElement.style.width = `${width}px`;\n adVideoElement.style.height = `${height}px`;\n }\n },\n on(event, listener) {\n if (!listeners.has(event)) listeners.set(event, /* @__PURE__ */ new Set());\n listeners.get(event).add(listener);\n },\n off(event, listener) {\n listeners.get(event)?.delete(listener);\n },\n updateOriginalMutedState(muted, volume) {\n const nextVolume = typeof volume === \"number\" && !Number.isNaN(volume) ? Math.max(0, Math.min(1, volume)) : originalVolume;\n originalMutedState = muted;\n originalVolume = nextVolume;\n },\n getOriginalMutedState() {\n return originalMutedState;\n },\n getOriginalVolume() {\n return originalVolume;\n },\n setAdVolume(volume) {\n if (adVideoElement && adPlaying) {\n adVideoElement.volume = Math.max(0, Math.min(1, volume));\n }\n },\n getAdVolume() {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\n showPlaceholder() {\n contentVideo.style.opacity = \"0\";\n contentVideo.style.visibility = \"hidden\";\n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n },\n hidePlaceholder() {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n if (!adPlaying) {\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n }\n }\n };\n}\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n createPrebidAdLayer\n});\n","import type { PrebidBidResponse } from \"../types\";\nimport type { VastAd, VastMediaFile } from \"./vastParser\";\nimport {\n parseVastXml,\n fetchAndParseVastAd,\n fireTrackingPixels as fireTrackingPixelsShared,\n createEmptyTrackingState,\n} from \"./vastParser\";\nimport Hls from \"hls.js\";\n\nconst LOG = \"[PrebidAdLayer]\";\n\nexport interface PrebidAdLayerOptions {\n continueLiveStreamDuringAds?: boolean;\n mainHlsInstance?: Hls;\n debug?: boolean;\n}\n\nexport interface PrebidAdLayerOptionsUpdate {\n continueLiveStreamDuringAds?: boolean;\n mainHlsInstance?: Hls | null;\n}\n\nexport interface PrebidAdLayer {\n initialize: () => void;\n updateOptions: (opts: PrebidAdLayerOptionsUpdate) => void;\n playAd: (bids: PrebidBidResponse[]) => Promise<void>;\n pause: () => void;\n resume: () => void;\n stop: () => Promise<void>;\n destroy: () => void;\n isAdPlaying: () => boolean;\n resize: (width: number, height: number) => void;\n on: (event: string, listener: (payload?: any) => void) => void;\n off: (event: string, listener: (payload?: any) => void) => void;\n updateOriginalMutedState: (muted: boolean, volume?: number) => void;\n getOriginalMutedState: () => boolean;\n getOriginalVolume: () => number;\n setAdVolume: (volume: number) => void;\n getAdVolume: () => number;\n showPlaceholder: () => void;\n hidePlaceholder: () => void;\n}\n\nfunction resolveBidToVastAd(winner: PrebidBidResponse, logPrefix: string): Promise<VastAd | null> {\n if (winner.vastXml) {\n const ad = parseVastXml(winner.vastXml, \"mp4-first\", logPrefix);\n return Promise.resolve(ad);\n }\n if (winner.vastUrl) {\n return fetchAndParseVastAd(winner.vastUrl, \"mp4-first\", logPrefix);\n }\n return Promise.resolve(null);\n}\n\nexport function createPrebidAdLayer(\n contentVideo: HTMLVideoElement,\n options?: PrebidAdLayerOptions\n): PrebidAdLayer {\n let adPlaying = false;\n let originalMutedState = false;\n let originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));\n const listeners = new Map<string, Set<(payload?: any) => void>>();\n let mainHlsInstance: Hls | undefined = options?.mainHlsInstance;\n let continueLiveStreamDuringAds = options?.continueLiveStreamDuringAds ?? false;\n const debug = options?.debug ?? false;\n\n let adVideoElement: HTMLVideoElement | undefined;\n let adHls: Hls | undefined;\n let adContainerEl: HTMLDivElement | undefined;\n let currentAd: VastAd | undefined;\n let sessionId: string | undefined;\n let destroyed = false;\n let tornDown = false;\n let trackingFired = createEmptyTrackingState();\n\n function emit(event: string, payload?: any): void {\n const set = listeners.get(event);\n if (!set) return;\n for (const fn of Array.from(set)) {\n try {\n fn(payload);\n } catch (error) {\n console.warn(`${LOG} Error in event listener for ${event}:`, error);\n }\n }\n }\n\n function generateSessionId(): string {\n return `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }\n\n function fireTrackingPixels(urls: string[]): void {\n fireTrackingPixelsShared(urls, sessionId, LOG);\n }\n\n function getMainStreamQuality(): { width: number; height: number; bitrate: number } | null {\n if (!mainHlsInstance?.levels) return null;\n const currentLevel = mainHlsInstance.currentLevel;\n if (currentLevel === -1 || !mainHlsInstance.levels[currentLevel]) {\n const autoLevel = mainHlsInstance.loadLevel;\n if (autoLevel !== -1 && mainHlsInstance.levels[autoLevel]) {\n const level = mainHlsInstance.levels[autoLevel];\n return {\n width: level.width || 1920,\n height: level.height || 1080,\n bitrate: level.bitrate || 5000000,\n };\n }\n return null;\n }\n const level = mainHlsInstance.levels[currentLevel];\n return {\n width: level.width || 1920,\n height: level.height || 1080,\n bitrate: level.bitrate || 5000000,\n };\n }\n\n function selectBestMediaFile(mediaFiles: VastMediaFile[]): VastMediaFile {\n if (mediaFiles.length === 0) throw new Error(\"No media files available\");\n const firstFile = mediaFiles[0]!;\n if (mediaFiles.length === 1) return firstFile;\n\n const mainQuality = getMainStreamQuality();\n if (!mainQuality) {\n if (debug) console.log(`${LOG} No main stream quality info, using first media file`);\n return firstFile;\n }\n\n const scoredFiles = mediaFiles.map((file) => {\n const widthDiff = Math.abs(file.width - mainQuality.width);\n const heightDiff = Math.abs(file.height - mainQuality.height);\n const resolutionDiff = widthDiff + heightDiff;\n const fileBitrate = (file.bitrate || 5000) * 1000;\n const bitrateDiff = Math.abs(fileBitrate - mainQuality.bitrate);\n const score = resolutionDiff * 2 + bitrateDiff / 1000;\n return { file, score };\n });\n scoredFiles.sort((a, b) => a.score - b.score);\n return scoredFiles[0]?.file ?? firstFile;\n }\n\n function isHlsMediaFile(file: VastMediaFile): boolean {\n return file.type === \"application/x-mpegURL\" || file.type.includes(\"m3u8\");\n }\n\n function createAdVideoElement(): HTMLVideoElement {\n const video = document.createElement(\"video\");\n video.style.position = \"absolute\";\n video.style.left = \"0\";\n video.style.top = \"0\";\n video.style.width = \"100%\";\n video.style.height = \"100%\";\n video.style.objectFit = \"contain\";\n video.style.backgroundColor = \"#000\";\n video.playsInline = true;\n video.muted = false;\n video.volume = 1.0;\n return video;\n }\n\n function setupAdEventListeners(): void {\n if (!adVideoElement) return;\n\n adVideoElement.addEventListener(\"timeupdate\", () => {\n const ad = currentAd;\n if (!ad || !adVideoElement) return;\n const progress = adVideoElement.currentTime / ad.duration;\n if (progress >= 0.25 && !trackingFired.firstQuartile) {\n trackingFired.firstQuartile = true;\n fireTrackingPixels(ad.trackingUrls.firstQuartile);\n }\n if (progress >= 0.5 && !trackingFired.midpoint) {\n trackingFired.midpoint = true;\n fireTrackingPixels(ad.trackingUrls.midpoint);\n }\n if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n trackingFired.thirdQuartile = true;\n fireTrackingPixels(ad.trackingUrls.thirdQuartile);\n }\n });\n\n adVideoElement.addEventListener(\"playing\", () => {\n const ad = currentAd;\n if (!ad || trackingFired.start) return;\n trackingFired.start = true;\n fireTrackingPixels(ad.trackingUrls.start);\n if (debug) console.log(`${LOG} Ad started playing`);\n });\n\n adVideoElement.addEventListener(\"ended\", () => {\n if (tornDown || !currentAd || trackingFired.complete) return;\n trackingFired.complete = true;\n fireTrackingPixels(currentAd.trackingUrls.complete);\n if (debug) console.log(`${LOG} Ad completed`);\n handleAdComplete();\n });\n\n adVideoElement.addEventListener(\"error\", (e) => {\n if (tornDown) return;\n console.error(`${LOG} Ad video error:`, e);\n if (currentAd) fireTrackingPixels(currentAd.trackingUrls.error);\n handleAdError();\n });\n\n adVideoElement.addEventListener(\"volumechange\", () => {\n if (!currentAd || !adVideoElement) return;\n if (adVideoElement.muted) {\n fireTrackingPixels(currentAd.trackingUrls.mute);\n } else {\n fireTrackingPixels(currentAd.trackingUrls.unmute);\n }\n });\n\n adVideoElement.addEventListener(\"pause\", () => {\n if (currentAd && adVideoElement && !adVideoElement.ended) {\n fireTrackingPixels(currentAd.trackingUrls.pause);\n }\n });\n\n adVideoElement.addEventListener(\"play\", () => {\n if (currentAd && adVideoElement && adVideoElement.currentTime > 0) {\n fireTrackingPixels(currentAd.trackingUrls.resume);\n }\n });\n }\n\n function setAdPlayingFlag(isPlaying: boolean): void {\n if (isPlaying) {\n contentVideo.dataset.stormcloudAdPlaying = \"true\";\n } else {\n delete contentVideo.dataset.stormcloudAdPlaying;\n }\n }\n\n function handleAdComplete(): void {\n if (tornDown) return;\n if (debug) console.log(`${LOG} Handling ad completion`);\n adPlaying = false;\n setAdPlayingFlag(false);\n\n contentVideo.muted = true;\n contentVideo.volume = 0;\n\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n\n if (continueLiveStreamDuringAds) {\n contentVideo.play().catch(() => {});\n }\n\n emit(\"ad_impression\");\n emit(\"content_resume\");\n }\n\n function handleAdError(): void {\n if (tornDown) return;\n if (debug) console.log(`${LOG} Handling ad error`);\n adPlaying = false;\n setAdPlayingFlag(false);\n\n contentVideo.muted = true;\n contentVideo.volume = 0;\n\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n\n emit(\"ad_error\");\n }\n\n function teardownCurrentPlayback(): void {\n if (adHls) {\n adHls.destroy();\n adHls = undefined;\n }\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.removeAttribute(\"src\");\n adVideoElement.load();\n }\n }\n\n function startNativePlayback(mediaFile: VastMediaFile): void {\n if (!adVideoElement) return;\n if (debug) console.log(`${LOG} Starting native MP4 playback: ${mediaFile.url}`);\n adVideoElement.src = mediaFile.url;\n adVideoElement.load();\n adVideoElement.play().catch((error) => {\n console.error(`${LOG} Error starting native ad playback:`, error);\n handleAdError();\n });\n }\n\n function startHlsPlayback(mediaFile: VastMediaFile): void {\n if (!adVideoElement) return;\n if (debug) console.log(`${LOG} Starting HLS playback: ${mediaFile.url}`);\n\n if (Hls.isSupported()) {\n if (adHls) {\n adHls.destroy();\n adHls = undefined;\n }\n adHls = new Hls({ enableWorker: true, lowLatencyMode: false });\n adHls.loadSource(mediaFile.url);\n adHls.attachMedia(adVideoElement);\n\n adHls.on(Hls.Events.MANIFEST_PARSED, () => {\n adVideoElement!.play().catch((error) => {\n console.error(`${LOG} Error starting HLS ad playback:`, error);\n handleAdError();\n });\n });\n\n adHls.on(Hls.Events.ERROR, (_event, data) => {\n if (data.fatal) handleAdError();\n });\n } else if (adVideoElement.canPlayType(\"application/vnd.apple.mpegurl\")) {\n adVideoElement.src = mediaFile.url;\n adVideoElement.play().catch((error) => {\n console.error(`${LOG} Error starting native HLS ad playback:`, error);\n handleAdError();\n });\n } else {\n console.error(`${LOG} HLS not supported on this platform`);\n handleAdError();\n }\n }\n\n function startPlayback(mediaFile: VastMediaFile): void {\n if (!adVideoElement) return;\n if (isHlsMediaFile(mediaFile)) {\n startHlsPlayback(mediaFile);\n } else {\n startNativePlayback(mediaFile);\n }\n }\n\n async function playAd(bids: PrebidBidResponse[]): Promise<void> {\n if (destroyed) {\n return Promise.reject(new Error(\"Layer has been destroyed\"));\n }\n if (bids.length === 0) {\n return Promise.reject(new Error(\"No bids provided\"));\n }\n\n const winner = bids[0]!;\n if (debug) {\n console.log(`${LOG} Winning bid: ${winner.bidder} $${winner.cpm.toFixed(2)} ${winner.currency}`);\n }\n\n const ad = await resolveBidToVastAd(winner, LOG);\n if (!ad) {\n if (debug) console.warn(`${LOG} Winning bid has no VAST URL or XML`);\n emit(\"ad_error\");\n return Promise.reject(new Error(\"No VAST from bid\"));\n }\n\n if (debug) {\n console.log(`${LOG} Ad parsed: ${ad.title}, duration: ${ad.duration}s, mediaFiles: ${ad.mediaFiles.length}`);\n }\n\n sessionId = generateSessionId();\n currentAd = ad;\n trackingFired = { ...createEmptyTrackingState() };\n fireTrackingPixels(ad.trackingUrls.impression);\n trackingFired.impression = true;\n\n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl.appendChild(adVideoElement);\n setupAdEventListeners();\n } else {\n teardownCurrentPlayback();\n }\n\n const contentVolume = contentVideo.volume;\n originalVolume = Math.max(0, Math.min(1, contentVolume || originalVolume));\n\n if (!continueLiveStreamDuringAds) {\n contentVideo.pause();\n }\n\n contentVideo.muted = true;\n contentVideo.volume = 0;\n adPlaying = true;\n setAdPlayingFlag(true);\n\n const adVolume = originalMutedState ? 1 : originalVolume;\n adVideoElement.volume = Math.max(0, Math.min(1, adVolume));\n adVideoElement.muted = false;\n\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n\n emit(\"content_pause\");\n\n const mediaFile = selectBestMediaFile(ad.mediaFiles);\n if (debug) console.log(`${LOG} Loading ad from: ${mediaFile.url}`);\n startPlayback(mediaFile);\n }\n\n return {\n initialize() {\n if (debug) console.log(`${LOG} Initializing`);\n },\n\n updateOptions(opts: PrebidAdLayerOptionsUpdate) {\n if (opts.continueLiveStreamDuringAds !== undefined) {\n continueLiveStreamDuringAds = opts.continueLiveStreamDuringAds;\n }\n if (opts.mainHlsInstance !== undefined) {\n mainHlsInstance = opts.mainHlsInstance ?? undefined;\n }\n },\n\n playAd,\n\n pause() {\n if (!adPlaying || !adVideoElement) return;\n try {\n if (!adVideoElement.paused) adVideoElement.pause();\n } catch (error) {\n if (debug) console.warn(`${LOG} Error pausing ad:`, error);\n }\n },\n\n resume() {\n if (!adPlaying || !adVideoElement) return;\n try {\n if (adVideoElement.paused) adVideoElement.play().catch(() => {});\n } catch (error) {\n if (debug) console.warn(`${LOG} Error resuming ad:`, error);\n }\n },\n\n async stop() {\n tornDown = true;\n if (debug) console.log(`${LOG} Stopping ad`);\n adPlaying = false;\n setAdPlayingFlag(false);\n\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalMutedState ? 0 : originalVolume;\n\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n\n if (continueLiveStreamDuringAds) {\n contentVideo.play().catch(() => {});\n }\n\n teardownCurrentPlayback();\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.removeAttribute(\"src\");\n adVideoElement.load();\n }\n currentAd = undefined;\n tornDown = false;\n },\n\n destroy() {\n tornDown = true;\n if (debug) console.log(`${LOG} Destroying`);\n destroyed = true;\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n\n teardownCurrentPlayback();\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.removeAttribute(\"src\");\n adVideoElement.remove();\n adVideoElement = undefined;\n }\n if (adContainerEl?.parentElement) {\n adContainerEl.parentElement.removeChild(adContainerEl);\n }\n adContainerEl = undefined;\n currentAd = undefined;\n listeners.clear();\n },\n\n isAdPlaying() {\n return adPlaying;\n },\n\n resize(width: number, height: number) {\n if (adContainerEl) {\n adContainerEl.style.width = `${width}px`;\n adContainerEl.style.height = `${height}px`;\n }\n if (adVideoElement) {\n adVideoElement.style.width = `${width}px`;\n adVideoElement.style.height = `${height}px`;\n }\n },\n\n on(event: string, listener: (payload?: any) => void) {\n if (!listeners.has(event)) listeners.set(event, new Set());\n listeners.get(event)!.add(listener);\n },\n\n off(event: string, listener: (payload?: any) => void) {\n listeners.get(event)?.delete(listener);\n },\n\n updateOriginalMutedState(muted: boolean, volume?: number) {\n const nextVolume =\n typeof volume === \"number\" && !Number.isNaN(volume)\n ? Math.max(0, Math.min(1, volume))\n : originalVolume;\n originalMutedState = muted;\n originalVolume = nextVolume;\n },\n\n getOriginalMutedState() {\n return originalMutedState;\n },\n\n getOriginalVolume() {\n return originalVolume;\n },\n\n setAdVolume(volume: number) {\n if (adVideoElement && adPlaying) {\n adVideoElement.volume = Math.max(0, Math.min(1, volume));\n }\n },\n\n getAdVolume(): number {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\n\n showPlaceholder() {\n contentVideo.style.opacity = \"0\";\n contentVideo.style.visibility = \"hidden\";\n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n },\n\n hidePlaceholder() {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n if (!adPlaying) {\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n }\n },\n };\n}\n","export interface VastMediaFile {\n url: string;\n type: string;\n width: number;\n height: number;\n bitrate?: number | undefined;\n}\n\nexport interface VastTrackingUrls {\n impression: string[];\n start: string[];\n firstQuartile: string[];\n midpoint: string[];\n thirdQuartile: string[];\n complete: string[];\n mute: string[];\n unmute: string[];\n pause: string[];\n resume: string[];\n fullscreen: string[];\n exitFullscreen: string[];\n skip: string[];\n error: string[];\n}\n\nexport interface VastAd {\n id: string;\n title: string;\n duration: number;\n mediaFiles: VastMediaFile[];\n trackingUrls: VastTrackingUrls;\n clickThrough?: string | undefined;\n}\n\nexport type MediaFileFilter = \"hls-only\" | \"mp4-first\" | \"all\";\n\nfunction isHlsType(type: string): boolean {\n return type === \"application/x-mpegURL\" || type.includes(\"m3u8\");\n}\n\nfunction isMp4Type(type: string): boolean {\n return type === \"video/mp4\" || type.includes(\"mp4\");\n}\n\nexport function parseVastXml(\n xmlString: string,\n filter: MediaFileFilter = \"all\",\n logPrefix = \"[VastParser]\"\n): VastAd | null {\n try {\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlString, \"text/xml\");\n\n const parserError = xmlDoc.querySelector(\"parsererror\");\n if (parserError) {\n console.error(\n `${logPrefix} XML parsing error (malformed VAST XML):`,\n parserError.textContent\n );\n return null;\n }\n\n const adElement = xmlDoc.querySelector(\"Ad\");\n if (!adElement) {\n console.warn(`${logPrefix} No Ad element found in VAST XML`);\n return null;\n }\n\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n\n const isNoAdAvailable =\n adId === \"empty\" ||\n title.toLowerCase().includes(\"no ad available\") ||\n title.toLowerCase() === \"no ad available\";\n\n const durationText =\n xmlDoc.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n const durationParts = durationText.split(\":\");\n const duration =\n parseInt(durationParts[0] || \"0\", 10) * 3600 +\n parseInt(durationParts[1] || \"0\", 10) * 60 +\n Math.round(parseFloat(durationParts[2] || \"0\"));\n\n const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n const mediaFiles: VastMediaFile[] = [];\n\n console.log(\n `${logPrefix} Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`\n );\n\n mediaFileElements.forEach((mf, index) => {\n const type = mf.getAttribute(\"type\") || \"\";\n const url = mf.textContent?.trim() || \"\";\n const width = mf.getAttribute(\"width\") || \"\";\n const height = mf.getAttribute(\"height\") || \"\";\n\n console.log(\n `${logPrefix} MediaFile ${index}: type=\"${type}\", url=\"${url.substring(0, 80)}...\", width=\"${width}\", height=\"${height}\"`\n );\n\n if (!url) {\n console.warn(`${logPrefix} MediaFile ${index} has empty URL`);\n return;\n }\n\n const isHls = isHlsType(type);\n const isMp4 = isMp4Type(type);\n\n let accepted = false;\n if (filter === \"hls-only\") {\n accepted = isHls;\n } else if (filter === \"mp4-first\") {\n accepted = isMp4 || isHls;\n } else {\n accepted = true;\n }\n\n if (!accepted) {\n console.log(\n `${logPrefix} MediaFile ${index} ignored (type=\"${type}\" not accepted by filter \"${filter}\")`\n );\n return;\n }\n\n const bitrateAttr = mf.getAttribute(\"bitrate\");\n const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : undefined;\n\n mediaFiles.push({\n url,\n type,\n width: parseInt(width || \"1920\", 10),\n height: parseInt(height || \"1080\", 10),\n bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : undefined,\n });\n\n console.log(`${logPrefix} Added MediaFile: type=\"${type}\" url=\"${url.substring(0, 80)}...\"`);\n });\n\n if (filter === \"mp4-first\" && mediaFiles.length > 1) {\n mediaFiles.sort((a, b) => {\n const aIsMp4 = isMp4Type(a.type) ? 0 : 1;\n const bIsMp4 = isMp4Type(b.type) ? 0 : 1;\n return aIsMp4 - bIsMp4;\n });\n }\n\n if (mediaFiles.length === 0) {\n if (isNoAdAvailable) {\n console.warn(\n `${logPrefix} No ads available (VAST response indicates no ads)`\n );\n } else {\n console.warn(`${logPrefix} No compatible media files found in VAST XML`);\n }\n return null;\n }\n\n const trackingUrls: VastTrackingUrls = {\n impression: [],\n start: [],\n firstQuartile: [],\n midpoint: [],\n thirdQuartile: [],\n complete: [],\n mute: [],\n unmute: [],\n pause: [],\n resume: [],\n fullscreen: [],\n exitFullscreen: [],\n skip: [],\n error: [],\n };\n\n xmlDoc.querySelectorAll(\"Impression\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.impression.push(url);\n });\n\n xmlDoc.querySelectorAll(\"Tracking\").forEach((el) => {\n const event = el.getAttribute(\"event\");\n const url = el.textContent?.trim();\n if (event && url) {\n const eventKey = event as keyof VastTrackingUrls;\n if (trackingUrls[eventKey]) {\n trackingUrls[eventKey].push(url);\n }\n }\n });\n\n const clickThrough = xmlDoc\n .querySelector(\"ClickThrough\")\n ?.textContent?.trim();\n\n return {\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls,\n clickThrough,\n };\n } catch (error) {\n console.error(`${logPrefix} Error parsing VAST XML:`, error);\n return null;\n }\n}\n\nexport async function fetchAndParseVastAd(\n vastTagUrl: string,\n filter: MediaFileFilter = \"all\",\n logPrefix = \"[VastParser]\"\n): Promise<VastAd | null> {\n const response = await fetch(vastTagUrl, {\n mode: \"cors\",\n credentials: \"include\",\n headers: {\n Accept: \"application/xml, text/xml, */*\",\n },\n referrerPolicy: \"no-referrer-when-downgrade\",\n });\n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.statusText}`);\n }\n\n const vastXml = await response.text();\n console.log(`${logPrefix} VAST XML received`);\n console.log(\n `${logPrefix} VAST XML content (first 2000 chars):`,\n vastXml.substring(0, 2000)\n );\n\n return parseVastXml(vastXml, filter, logPrefix);\n}\n\nexport function createEmptyTrackingState() {\n return {\n impression: false,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false,\n };\n}\n\nexport function fireTrackingPixels(\n urls: string[],\n sessionId?: string,\n logPrefix = \"[VastParser]\"\n): void {\n if (!urls || urls.length === 0) return;\n\n urls.forEach((url) => {\n try {\n let trackingUrl = url;\n\n if (sessionId) {\n trackingUrl = `${trackingUrl}${\n trackingUrl.includes(\"?\") ? \"&\" : \"?\"\n }session_id=${sessionId}`;\n }\n\n const img = new Image(1, 1);\n img.onerror = () => {\n // 502 or other network errors are fire-and-forget; do not affect playback\n };\n img.src = trackingUrl;\n console.log(`${logPrefix} Fired tracking pixel: ${trackingUrl}`);\n } catch (error) {\n console.warn(`${logPrefix} Error firing tracking pixel:`, error);\n }\n });\n}\n"]}
|
|
@@ -1290,7 +1290,7 @@ function createPrebidAdLayer(contentVideo, options) {
|
|
|
1290
1290
|
contentVideo.volume = 0;
|
|
1291
1291
|
adPlaying = true;
|
|
1292
1292
|
setAdPlayingFlag(true);
|
|
1293
|
-
adVolume = originalMutedState ?
|
|
1293
|
+
adVolume = originalMutedState ? 1 : originalVolume;
|
|
1294
1294
|
adVideoElement.volume = Math.max(0, Math.min(1, adVolume));
|
|
1295
1295
|
adVideoElement.muted = false;
|
|
1296
1296
|
if (adContainerEl) {
|
|
@@ -3051,7 +3051,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
3051
3051
|
console.log("[StormcloudVideoPlayer] Starting ad break timer on content_pause (first ad starting)");
|
|
3052
3052
|
}
|
|
3053
3053
|
}
|
|
3054
|
-
_this.adLayer.setAdVolume(_this.adLayer.getOriginalMutedState() ?
|
|
3054
|
+
_this.adLayer.setAdVolume(_this.adLayer.getOriginalMutedState() ? 1 : _this.adLayer.getOriginalVolume());
|
|
3055
3055
|
if (_this.isShowingPlaceholder) {
|
|
3056
3056
|
if (_this.config.debugAdTiming) {
|
|
3057
3057
|
console.log("[StormcloudVideoPlayer] Hiding placeholder - new ads starting");
|
|
@@ -3995,7 +3995,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
3995
3995
|
if (_this.expectedAdBreakDurationMs != null && _this.adStopTimerId == null) {
|
|
3996
3996
|
_this.scheduleAdStopCountdown(_this.getRemainingAdMs());
|
|
3997
3997
|
}
|
|
3998
|
-
_this.adLayer.setAdVolume(_this.adLayer.getOriginalMutedState() ?
|
|
3998
|
+
_this.adLayer.setAdVolume(_this.adLayer.getOriginalMutedState() ? 1 : _this.adLayer.getOriginalVolume());
|
|
3999
3999
|
_state.label = 7;
|
|
4000
4000
|
case 7:
|
|
4001
4001
|
return [
|
|
@@ -4157,7 +4157,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
4157
4157
|
if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {
|
|
4158
4158
|
this.scheduleAdStopCountdown(this.getRemainingAdMs());
|
|
4159
4159
|
}
|
|
4160
|
-
adVolume = state.muted ?
|
|
4160
|
+
adVolume = state.muted ? 1 : state.volume;
|
|
4161
4161
|
this.adLayer.setAdVolume(adVolume);
|
|
4162
4162
|
return [
|
|
4163
4163
|
3,
|
|
@@ -4348,7 +4348,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
4348
4348
|
if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {
|
|
4349
4349
|
this.scheduleAdStopCountdown(this.getRemainingAdMs());
|
|
4350
4350
|
}
|
|
4351
|
-
this.adLayer.setAdVolume(this.adLayer.getOriginalMutedState() ?
|
|
4351
|
+
this.adLayer.setAdVolume(this.adLayer.getOriginalMutedState() ? 1 : this.adLayer.getOriginalVolume());
|
|
4352
4352
|
_state.label = 5;
|
|
4353
4353
|
case 5:
|
|
4354
4354
|
return [
|
|
@@ -4681,11 +4681,19 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
4681
4681
|
var _this_video_play1;
|
|
4682
4682
|
(_this_video_play1 = this.video.play()) === null || _this_video_play1 === void 0 ? void 0 : _this_video_play1.catch(function() {});
|
|
4683
4683
|
}
|
|
4684
|
-
if (
|
|
4684
|
+
if (!restoredMuted) {
|
|
4685
4685
|
requestAnimationFrame(function() {
|
|
4686
4686
|
_this.video.muted = false;
|
|
4687
4687
|
_this.video.volume = restoredVolume;
|
|
4688
4688
|
});
|
|
4689
|
+
setTimeout(function() {
|
|
4690
|
+
_this.video.muted = false;
|
|
4691
|
+
_this.video.volume = restoredVolume;
|
|
4692
|
+
}, 0);
|
|
4693
|
+
setTimeout(function() {
|
|
4694
|
+
_this.video.muted = false;
|
|
4695
|
+
_this.video.volume = restoredVolume;
|
|
4696
|
+
}, 50);
|
|
4689
4697
|
}
|
|
4690
4698
|
}
|
|
4691
4699
|
},
|