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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/ubuntu24-new/Dev/stormcloud-vp/lib/ui/StormcloudVideoPlayer.cjs","../../src/ui/StormcloudVideoPlayer.tsx","../../src/player/StormcloudVideoPlayer.ts","../../src/sdk/prebid.ts","../../src/sdk/vastParser.ts","../../src/sdk/prebidAdLayer.ts","../../src/utils/tracking.ts","../../src/utils/polyfills.ts","../../src/utils/browserCompat.ts"],"names":["__create","Object","create","__defProp","__copyProps","defineProperty","__getOwnPropDesc","getOwnPropertyDescriptor","__getOwnPropNames","getOwnPropertyNames","__getProtoOf","getPrototypeOf","__hasOwnProp","prototype","hasOwnProperty","__export","target","all","name","get","enumerable","to","from","except","desc","call","key","__toESM","mod","isNodeMode","value","__toCommonJS","StormcloudVideoPlayer_exports","StormcloudVideoPlayerComponent","module","exports","import_react","require","import_hls","DEFAULT_TIMEOUT_MS","AUCTION_URL","createPrebidManager","options","initialized","debug","log","args","console","warn","parseResponse","data","bids","seatbids","seatbid","currency","cur","seat","bidArray","bid","cacheUrl","ext","prebid","cache","vastXml","url","adm","bidResponse","bidder","cpm","price","width","w","height","h","adId","id","impId","impid","creativeId","crid","vastUrl","adomain","push","sort","a","b","initialize","requestBids","timeout","controller","timeoutId","fetchOptions","response","body","error","Error","AbortController","setTimeout","abort","method","signal","fetch","clearTimeout","ok","text","catch","status","slice","json","responsetimemillis","errors","length","toFixed","REQUEST_BIDS_MAX_RETRIES","REQUEST_BIDS_BACKOFF_MS","requestBidsUntilResponse","lastError","attempt","err","delay","Promise","resolve","destroy","isInitialized","isHlsType","type","includes","isMp4Type","parseVastXml","xmlString","filter","logPrefix","xmlDoc","parser","DOMParser","parseFromString","parserError","querySelector","textContent","adElement","getAttribute","title","isNoAdAvailable","toLowerCase","durationText","durationParts","split","duration","parseInt","Math","round","parseFloat","mediaFileElements","querySelectorAll","mediaFiles","forEach","mf","index","trim","substring","isHls","isMp4","accepted","bitrateAttr","bitrateValue","bitrate","aIsMp4","bIsMp4","trackingUrls","impression","start","firstQuartile","midpoint","thirdQuartile","complete","mute","unmute","pause","resume","fullscreen","exitFullscreen","skip","eventKey","el","event","clickThrough","vastTagUrl","mode","credentials","headers","Accept","referrerPolicy","statusText","createEmptyTrackingState","fireTrackingPixels","urls","sessionId","trackingUrl","img","Image","onerror","src","LOG","resolveBidToVastAd","winner","ad","fetchAndParseVastAd","createPrebidAdLayer","contentVideo","adPlaying","originalMutedState","originalVolume","max","min","volume","listeners","Map","mainHlsInstance","continueLiveStreamDuringAds","adVideoElement","adHls","adContainerEl","currentAd","destroyed","tornDown","trackingFired","emit","payload","set","Array","fn","generateSessionId","Date","now","random","toString","substr","getMainStreamQuality","levels","currentLevel","autoLevel","loadLevel","level","firstFile","widthDiff","scoredFiles","isHlsMediaFile","selectBestMediaFile","mainQuality","map","file","abs","heightDiff","resolutionDiff","fileBitrate","bitrateDiff","score","createAdVideoElement","video","document","createElement","style","position","left","top","objectFit","backgroundColor","playsInline","setupAdEventListeners","muted","addEventListener","progress","currentTime","handleAdComplete","e","ended","setAdPlayingFlag","isPlaying","dataset","stormcloudAdPlaying","display","pointerEvents","visibility","opacity","play","teardownCurrentPlayback","removeAttribute","load","mediaFile","startHlsPlayback","Hls","isSupported","enableWorker","lowLatencyMode","loadSource","attachMedia","on","Events","MANIFEST_PARSED","handleAdError","ERROR","_event","fatal","canPlayType","startPlayback","startNativePlayback","playAd","container","contentVolume","adVolume","reject","right","bottom","alignItems","zIndex","parentElement","appendChild","updateOptions","opts","paused","stop","remove","removeChild","clear","isAdPlaying","resize","listener","has","Set","add","off","delete","updateOriginalMutedState","nextVolume","Number","isNaN","getOriginalMutedState","getOriginalVolume","setAdVolume","getAdVolume","showPlaceholder","justifyContent","hidePlaceholder","cachedBrowserId","getClientInfo","screen","window","navigator","ua","userAgent","platform","vendor","maxTouchPoints","memory","deviceMemory","hardwareConcurrency","screenInfo","availWidth","availHeight","orientation","pixelDepth","deviceType","brand","os","model","isSmartTV","isAndroid","isWebView","isWebApp","webosMatch","match","tizenMatch","tvMatch","test","androidModelMatch","outerHeight","outerWidth","matchMedia","matches","standalone","angle","domain","location","hostname","origin","path","pathname","language","languages","join","cookieEnabled","doNotTrack","referrer","visibilityState","getBrowserID","clientInfo","fingerprintString","encodedData","utf8","buffer","i","hashBuffer","hashArray","hashHex","hash","char","fallbackHash","timestamp","JSON","stringify","crypto","subtle","digest","Uint8Array","TextEncoder","encode","unescape","encodeURIComponent","charCodeAt","padStart","padEnd","sendTrackRequest","licenseKey","TRACK_URL","sendInitialTracking","browserId","trackingData","adDetectInfo","sendAdLoadedTracking","adLoadedInfo","sendAdImpressionTracking","adImpressionInfo","sendHeartbeat","heartbeatData","toISOString","polyfillURLSearchParams","URLSearchParams","URLSearchParamsPolyfill","init","params","parseQueryString","append","query","cleanQuery","startsWith","param","decodedKey","safeDecodeURIComponent","decodedValue","str","decodeURIComponent","replace","values","String","getAll","callback","parts","polyfillTextEncoder","TextEncoderPolyfill","encoding","charcode","polyfillPromiseFinally","finally","constructor","then","reason","polyfillObjectAssign","assign","sources","TypeError","nextSource","nextKey","polyfillArrayFrom","items","arrayLike","len","result","mapFn","thisArg","polyfillStringStartsWith","search","pos","polyfillStringEndsWith","endsWith","polyfillStringIncludes","indexOf","initializePolyfills","webOSVersion","getChromeVersion","getWebKitVersion","getPlatform","userAgentData","version","detectBrowser","majorVersion","supportsIMA","supportsModernJS","recommendedAdPlayer","tizenVersion","chromeVersionNum","chromeVersion","webkitVersion","isLegacyTV","supportsGoogleIMA","browser","logBrowserInfo","imaSupport","getBrowserConfigOverrides","overrides","allowNativeHls","StormcloudVideoPlayer","config","pendingNextAdBids","continuousFetchLoopPromise","attached","inAdBreak","ptsDriftEmaMs","adPodQueue","lastHeartbeatTime","currentAdIndex","totalAdsInBreak","showAds","isLiveStream","nativeHlsMode","videoSrcProtection","bufferedSegmentsCount","shouldAutoplayAfterBuffering","hasInitialBufferCompleted","activeAdRequestToken","adRequestWatchdogToken","adFailsafeToken","continuousFetchingActive","maxPlaceholderDurationMs","isShowingPlaceholder","totalAdRequestsInBreak","maxTotalAdRequestsPerBreak","pendingAdBreak","savedMutedStateBeforeScte","consecutiveFailures","maxConsecutiveFailures","lastAdRequestTime","minAdRequestIntervalMs","backoffBaseMs","maxBackoffMs","adTransitionGapMs","browserOverrides","videoElement","debugAdTiming","prebidManager","adLayer","adRequest","attach","shouldUseNativeHls","isLive","adBehavior","autoplay","hls","import_hls2","backBufferLength","liveDurationInfinity","maxBufferLength","maxLiveSyncPlaybackRate","liveSyncDuration","maxMaxBufferLength","maxBufferSize","maxBufferHole","highBufferWatchdogPeriod","nudgeOffset","nudgeMaxRetry","startPosition","MEDIA_ATTACHED","_","minSegments","some","details","live","shouldContinueLiveStreamDuringAds","LEVEL_LOADED","_evt","fragments","fragmentsToScan","isArray","tagList","entry","tag","minSegmentsBeforePlay","idx","attrs","parseAttributeList","hasScteOut","durationSeconds","parseCueOutDuration","marker","raw","earlyDetection","startAdPrefetch","frag","sn","FRAG_BUFFERED","FRAG_PARSING_METADATA","id3Tags","samples","s","ptsSeconds","pts","onId3Tag","FRAG_CHANGED","prog","elapsed","onScte35Marker","hasScteIn","klass","toNumber","ErrorTypes","NETWORK_ERROR","startLoad","MEDIA_ERROR","recoverMediaError","getAdSource","attachAdLayerEventListeners","source","adIndex","errorPayload","errorMessage","errorCode","code","vastErrorCode","message","cause","innerError","causeMessage","handleAdFailure","clearAdFailsafeTimer","clearAdRequestWatchdog","expectedAdBreakDurationMs","adStopTimerId","scheduleAdStopCountdown","getRemainingAdMs","hidePlaceholderLayer","remaining","restoredMuted","restoredVolume","showPlaceholderLayer","handleAdPodComplete","ensurePlaceholderContainer","placeholderContainer","transition","wasHidden","offsetHeight","requestAnimationFrame","timeUpdateHandler","onTimeUpdate","emptiedHandler","wasPaused","streamType","getStreamType","canNative","updatePtsDrift","parseScte35FromId3","decodeId3ValueToText","cueOutMatch","arg","dur","id3","cueOutContMatch","cont","parseCueOutCont","cueInMatch","daterangeMatch","bin","parseScte35Binary","decoder","TextDecoder","out","fromCharCode","hasPendingAdBreak","durationMs","currentAdBreakStartWallClockMs","detectedAtFragmentSn","sendAdDetectTracking","isManifestMarker","isManifestBasedMarker","forceImmediate","immediateManifestAds","hasPts","clearAdStartTimer","handleAdStart","tol","driftToleranceMs","nowMs","estCurrentPtsMs","deltaMs","floor","markerPtsMs","tolerance","scheduleAdStartIn","elapsedMs","remainingMs","hasQueuedAds","activeAdRequest","clearAdStopTimer","num","dStr","d","res","elapsedMatch","durationMatch","slashMatch","regex","exec","rawVal","val","n","splice_command_type","BitReader","buf","bytePos","bitPos","numBits","readBits","remainingInByte","toRead","currentByte","shift","mask","bits","skipBits","r","tableId","sectionLength","ptsAdjHigh","ptsAdjLow","spliceCommandLength","spliceCommandType","cancel","outOfNetwork","programSpliceFlag","durationFlag","spliceImmediateFlag","timeSpecifiedFlag","componentCount","high","low","durationTicks","initializeTracking","heartbeatInterval","setInterval","sendHeartbeatIfNeeded","getCurrentAdIndex","getTotalAdsInBreak","isShowingAds","startContinuousFetchLoop","runContinuousFetchLoop","backoffMs","mult","pow","_marker","adBreakDurationMs","state","clearPendingAdBreak","showPlaceholderAndWaitForAds","stopContinuousFetching","tryNextAvailableAdWithRateLimit","backoffMultiplier","backoffDelay","effectiveMinInterval","timeSinceLastRequest","waitTime","tryNextAvailableAd","_retryCount","checkInterval","maxChecks","_currentTimeSec","ms","ensureAdStoppedByTimer","adBreakCheckIntervalMs","maxAdBreakExtensionMs","maxExtensionMsConfig","expectedDurationMs","shouldExtendAdBreak","pendingAds","overrunMs","maxExtensionMs","delayMs","adStartTimerId","ptsSecondsSample","sampleMs","alpha","isTizen","startAdRequestWatchdog","token","adFailsafeTimeoutMs","adRequestWatchdogId","logAdState","timeoutMs","startAdFailsafeTimer","failsafeMs","adFailsafeTimerId","videoPaused","imaAdPlaying","extra","MAX_SAFE_INTEGER","toggleMute","currentPerceptualState","isMuted","newMutedState","toggleFullscreen","fullscreenElement","requestFullscreen","setMuted","setVolume","clampedVolume","getVolume","isFullscreen","clientWidth","clientHeight","removeEventListener","clearInterval","import_fa","import_jsx_runtime","CRITICAL_PROPS","React","memo","props"],"mappings":"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","sourcesContent":["\"use strict\";\nvar __create = Object.create;\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __getProtoOf = Object.getPrototypeOf;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(\n // If the importer is in node compatibility mode or this is not an ESM\n // file that has been converted to a CommonJS file using a Babel-\n // compatible transform (i.e. \"__esModule\" has not been set), then set\n // \"default\" to the CommonJS \"module.exports\" for node compatibility.\n isNodeMode || !mod || !mod.__esModule ? __defProp(target, \"default\", { value: mod, enumerable: true }) : target,\n mod\n));\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\n\n// src/ui/StormcloudVideoPlayer.tsx\nvar StormcloudVideoPlayer_exports = {};\n__export(StormcloudVideoPlayer_exports, {\n StormcloudVideoPlayerComponent: () => StormcloudVideoPlayerComponent\n});\nmodule.exports = __toCommonJS(StormcloudVideoPlayer_exports);\nvar import_react = __toESM(require(\"react\"), 1);\n\n// src/player/StormcloudVideoPlayer.ts\nvar import_hls2 = __toESM(require(\"hls.js\"), 1);\n\n// src/sdk/prebid.ts\nvar DEFAULT_TIMEOUT_MS = 3e3;\nvar AUCTION_URL = \"https://sspproxy.adstorm.co/openrtb2/auction/adstorm\";\nfunction createPrebidManager(options = {}) {\n let initialized = false;\n const debug = options.debug ?? false;\n function log(...args) {\n if (debug) {\n console.log(\"[Prebid]\", ...args);\n }\n }\n function warn(...args) {\n console.warn(\"[Prebid]\", ...args);\n }\n function parseResponse(data) {\n const bids = [];\n const seatbids = data?.seatbid || [];\n const currency = data?.cur || \"USD\";\n for (const seatbid of seatbids) {\n const seat = seatbid.seat || \"unknown\";\n const bidArray = seatbid.bid || [];\n for (const bid of bidArray) {\n const cacheUrl = bid.ext?.prebid?.cache?.vastXml?.url;\n const vastXml = bid.adm || void 0;\n const bidResponse = {\n bidder: seat,\n cpm: bid.price || 0,\n width: bid.w || 0,\n height: bid.h || 0,\n adId: bid.id || \"\",\n impId: bid.impid || \"\",\n creativeId: bid.crid || \"\",\n currency\n };\n if (cacheUrl) bidResponse.vastUrl = cacheUrl;\n if (vastXml) bidResponse.vastXml = vastXml;\n if (bid.adomain) bidResponse.adomain = bid.adomain;\n bids.push(bidResponse);\n }\n }\n bids.sort((a, b) => b.cpm - a.cpm);\n return bids;\n }\n async function initialize() {\n if (initialized) return;\n initialized = true;\n log(\"Initialized, auction URL:\", AUCTION_URL);\n }\n async function requestBids() {\n if (!initialized) {\n throw new Error(\"Prebid not initialized. Call initialize() first.\");\n }\n const timeout = DEFAULT_TIMEOUT_MS;\n log(\"Fetching auction response from:\", AUCTION_URL);\n const controller = typeof AbortController !== \"undefined\" ? new AbortController() : null;\n const timeoutId = setTimeout(() => {\n controller?.abort();\n }, timeout + 2e3);\n try {\n const fetchOptions = {\n method: \"POST\"\n };\n if (controller) {\n fetchOptions.signal = controller.signal;\n }\n const response = await fetch(AUCTION_URL, fetchOptions);\n clearTimeout(timeoutId);\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new Error(\n `Prebid Server returned HTTP ${response.status}: ${body.slice(0, 200)}`\n );\n }\n const data = await response.json();\n if (debug && data?.ext?.responsetimemillis) {\n log(\"Bidder response times:\", data.ext.responsetimemillis);\n }\n if (debug && data?.ext?.errors) {\n warn(\"Auction errors:\", data.ext.errors);\n }\n const bids = parseResponse(data);\n log(`Received ${bids.length} bid(s)`);\n if (debug) {\n for (const b of bids) {\n log(\n ` ${b.bidder}: $${b.cpm.toFixed(2)} ${b.currency} ${b.width}x${b.height}` + (b.vastUrl ? \" [cached VAST]\" : \"\") + (b.vastXml && !b.vastUrl ? \" [VAST XML]\" : \"\")\n );\n }\n }\n return bids;\n } catch (error) {\n clearTimeout(timeoutId);\n if (error?.name === \"AbortError\") {\n warn(`Auction request timed out after ${timeout + 2e3}ms`);\n return [];\n }\n throw error;\n }\n }\n const REQUEST_BIDS_MAX_RETRIES = 3;\n const REQUEST_BIDS_BACKOFF_MS = 1500;\n async function requestBidsUntilResponse() {\n if (!initialized) {\n throw new Error(\"Prebid not initialized. Call initialize() first.\");\n }\n let lastError;\n for (let attempt = 1; attempt <= REQUEST_BIDS_MAX_RETRIES; attempt++) {\n try {\n const bids = await requestBids();\n if (bids.length > 0) {\n log(`requestBidsUntilResponse: got ${bids.length} bid(s) on attempt ${attempt}`);\n return bids;\n }\n log(`requestBidsUntilResponse: no bids on attempt ${attempt}/${REQUEST_BIDS_MAX_RETRIES}`);\n } catch (err) {\n lastError = err;\n warn(`requestBidsUntilResponse: attempt ${attempt}/${REQUEST_BIDS_MAX_RETRIES} failed:`, err);\n }\n if (attempt < REQUEST_BIDS_MAX_RETRIES) {\n const delay = REQUEST_BIDS_BACKOFF_MS * attempt;\n log(`requestBidsUntilResponse: waiting ${delay}ms before retry`);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n if (lastError instanceof Error) {\n throw lastError;\n }\n return [];\n }\n function destroy() {\n initialized = false;\n log(\"Destroyed\");\n }\n return {\n initialize,\n requestBids,\n requestBidsUntilResponse,\n destroy,\n get isInitialized() {\n return initialized;\n }\n };\n}\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\n// src/utils/tracking.ts\nvar cachedBrowserId = null;\nfunction getClientInfo() {\n const ua = navigator.userAgent;\n const platform = navigator.platform;\n const vendor = navigator.vendor || \"\";\n const maxTouchPoints = navigator.maxTouchPoints || 0;\n const memory = navigator.deviceMemory || null;\n const hardwareConcurrency = navigator.hardwareConcurrency || 1;\n const screenInfo = {\n width: screen?.width,\n height: screen?.height,\n availWidth: screen?.availWidth,\n availHeight: screen?.availHeight,\n orientation: screen?.orientation?.type || \"\",\n pixelDepth: screen?.pixelDepth\n };\n let deviceType = \"desktop\";\n let brand = \"Unknown\";\n let os = \"Unknown\";\n let model = \"\";\n let isSmartTV = false;\n let isAndroid = false;\n let isWebView = false;\n let isWebApp = false;\n if (ua.includes(\"Web0S\")) {\n brand = \"LG\";\n os = \"webOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n const webosMatch = ua.match(/Web0S\\/([^\\s]+)/);\n model = webosMatch ? `webOS ${webosMatch[1]}` : \"webOS TV\";\n } else if (ua.includes(\"Tizen\")) {\n brand = \"Samsung\";\n os = \"Tizen\";\n isSmartTV = true;\n deviceType = \"tv\";\n const tizenMatch = ua.match(/Tizen\\/([^\\s]+)/);\n const tvMatch = ua.match(/(?:Smart-TV|SMART-TV|TV)/i) ? \"Smart TV\" : \"\";\n model = tizenMatch ? `Tizen ${tizenMatch[1]} ${tvMatch}`.trim() : \"Tizen TV\";\n } else if (ua.includes(\"Philips\")) {\n brand = \"Philips\";\n os = \"Saphi\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Sharp\") || ua.includes(\"AQUOS\")) {\n brand = \"Sharp\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Android\") && (ua.includes(\"Sony\") || vendor.includes(\"Sony\"))) {\n brand = \"Sony\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Android\") && (ua.includes(\"NetCast\") || ua.includes(\"LG\"))) {\n brand = \"LG\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\" Roku\") || ua.includes(\"Roku/\")) {\n brand = \"Roku\";\n os = \"Roku OS\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"AppleTV\")) {\n brand = \"Apple\";\n os = \"tvOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n }\n if (ua.includes(\"Android\")) {\n isAndroid = true;\n os = \"Android\";\n deviceType = /Mobile/.test(ua) ? \"mobile\" : \"tablet\";\n if (ua.includes(\"Android\") && (maxTouchPoints === 0 || ua.includes(\"Google TV\") || ua.includes(\"XiaoMi\"))) {\n deviceType = \"tv\";\n isSmartTV = true;\n brand = brand === \"Unknown\" ? \"Android TV\" : brand;\n }\n const androidModelMatch = ua.match(/\\(([^)]*Android[^)]*)\\)/);\n if (androidModelMatch && androidModelMatch[1]) {\n model = androidModelMatch[1];\n }\n }\n if (/iPad|iPhone|iPod/.test(ua)) {\n os = \"iOS\";\n deviceType = \"mobile\";\n brand = \"Apple\";\n if (navigator.maxTouchPoints > 1 && /iPad/.test(ua)) {\n deviceType = \"tablet\";\n }\n }\n if (!isAndroid && !isSmartTV && !/Mobile/.test(ua)) {\n if (ua.includes(\"Windows\")) {\n os = \"Windows\";\n deviceType = \"desktop\";\n } else if (ua.includes(\"Mac\") && !/iPhone/.test(ua)) {\n os = \"macOS\";\n deviceType = \"desktop\";\n if (maxTouchPoints > 1) deviceType = \"tablet\";\n } else if (ua.includes(\"Linux\")) {\n os = \"Linux\";\n deviceType = \"desktop\";\n }\n }\n if (brand === \"Unknown\") {\n if (vendor.includes(\"Google\") || ua.includes(\"Chrome\")) brand = \"Google\";\n if (vendor.includes(\"Apple\")) brand = \"Apple\";\n if (vendor.includes(\"Samsung\") || ua.includes(\"SM-\")) brand = \"Samsung\";\n }\n isWebView = /wv|WebView|Linux; U;/.test(ua);\n if (window?.outerHeight === 0 && window?.outerWidth === 0) {\n isWebView = true;\n }\n isWebApp = window.matchMedia(\"(display-mode: standalone)\").matches || window.navigator.standalone === true || window.screen?.orientation?.angle !== void 0;\n return {\n brand,\n os,\n model: model || ua.substring(0, 50) + \"...\",\n deviceType,\n isSmartTV,\n isAndroid,\n isWebView,\n isWebApp,\n domain: window.location.hostname,\n origin: window.location.origin,\n path: window.location.pathname,\n userAgent: ua,\n vendor,\n platform,\n screen: screenInfo,\n hardwareConcurrency,\n deviceMemory: memory,\n maxTouchPoints,\n language: navigator.language,\n languages: navigator.languages?.join(\",\") || \"\",\n cookieEnabled: navigator.cookieEnabled,\n doNotTrack: navigator.doNotTrack || \"\",\n referrer: document.referrer,\n visibilityState: document.visibilityState\n };\n}\nasync function getBrowserID(clientInfo) {\n if (cachedBrowserId) {\n return cachedBrowserId;\n }\n const fingerprintString = JSON.stringify(clientInfo);\n if (typeof crypto !== \"undefined\" && crypto.subtle && crypto.subtle.digest) {\n try {\n await crypto.subtle.digest(\"SHA-256\", new Uint8Array([1, 2, 3]));\n let encodedData;\n if (typeof TextEncoder !== \"undefined\") {\n encodedData = new TextEncoder().encode(fingerprintString);\n } else {\n const utf8 = unescape(encodeURIComponent(fingerprintString));\n const buffer = new Uint8Array(utf8.length);\n for (let i = 0; i < utf8.length; i++) {\n buffer[i] = utf8.charCodeAt(i);\n }\n encodedData = buffer;\n }\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", encodedData);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n const hashHex = hashArray.map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n cachedBrowserId = hashHex;\n return hashHex;\n } catch (error) {\n console.warn(\n \"[StormcloudVideoPlayer] crypto.subtle.digest not supported, using fallback hash\"\n );\n }\n }\n let hash = 0;\n for (let i = 0; i < fingerprintString.length; i++) {\n const char = fingerprintString.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n const fallbackHash = Math.abs(hash).toString(16).padStart(8, \"0\");\n const timestamp = Date.now().toString(16).padStart(12, \"0\");\n const random = Math.random().toString(16).substring(2, 14).padStart(12, \"0\");\n cachedBrowserId = (fallbackHash + timestamp + random).padEnd(64, \"0\");\n return cachedBrowserId;\n}\nvar TRACK_URL = \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track\";\nasync function sendTrackRequest(licenseKey, body) {\n const headers = {\n \"Content-Type\": \"application/json\"\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n const response = await fetch(TRACK_URL, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body)\n });\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n await response.json();\n}\nasync function sendInitialTracking(licenseKey) {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData = {\n browserId,\n ...clientInfo\n };\n const headers = {\n \"Content-Type\": \"application/json\"\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n const response = await fetch(TRACK_URL, {\n method: \"POST\",\n headers,\n body: JSON.stringify(trackingData)\n });\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n await response.json();\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending initial tracking data:\",\n error\n );\n }\n}\nasync function sendAdDetectTracking(licenseKey, adDetectInfo) {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData = { browserId, ...clientInfo };\n await sendTrackRequest(licenseKey, {\n ...trackingData,\n licenseKey,\n adDetectInfo\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad detect tracking:\",\n error\n );\n }\n}\nasync function sendAdLoadedTracking(licenseKey, adLoadedInfo) {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData = { browserId, ...clientInfo };\n await sendTrackRequest(licenseKey, {\n ...trackingData,\n licenseKey,\n adLoadedInfo\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad loaded tracking:\",\n error\n );\n }\n}\nasync function sendAdImpressionTracking(licenseKey, adImpressionInfo) {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData = { browserId, ...clientInfo };\n await sendTrackRequest(licenseKey, {\n ...trackingData,\n licenseKey,\n adImpressionInfo\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad impression tracking:\",\n error\n );\n }\n}\nasync function sendHeartbeat(licenseKey) {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const heartbeatData = {\n browserId,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n };\n const headers = {\n \"Content-Type\": \"application/json\"\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n const response = await fetch(\n \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/heartbeat\",\n {\n method: \"POST\",\n headers,\n body: JSON.stringify(heartbeatData)\n }\n );\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n await response.json();\n } catch (error) {\n console.error(\"[StormcloudVideoPlayer] Error sending heartbeat:\", error);\n }\n}\n\n// src/utils/polyfills.ts\nfunction polyfillURLSearchParams() {\n if (typeof URLSearchParams !== \"undefined\") {\n return;\n }\n class URLSearchParamsPolyfill {\n constructor(init) {\n this.params = /* @__PURE__ */ new Map();\n if (typeof init === \"string\") {\n this.parseQueryString(init);\n } else if (init instanceof URLSearchParamsPolyfill) {\n init.forEach((value, key) => {\n this.append(key, value);\n });\n }\n }\n parseQueryString(query) {\n const cleanQuery = query.startsWith(\"?\") ? query.slice(1) : query;\n if (!cleanQuery) return;\n cleanQuery.split(\"&\").forEach((param) => {\n const [key, value] = param.split(\"=\");\n if (key) {\n const decodedKey = this.safeDecodeURIComponent(key);\n const decodedValue = value ? this.safeDecodeURIComponent(value) : \"\";\n this.append(decodedKey, decodedValue);\n }\n });\n }\n safeDecodeURIComponent(str) {\n try {\n return decodeURIComponent(str.replace(/\\+/g, \" \"));\n } catch (e) {\n return str;\n }\n }\n append(name, value) {\n const values = this.params.get(name) || [];\n values.push(String(value));\n this.params.set(name, values);\n }\n delete(name) {\n this.params.delete(name);\n }\n get(name) {\n const values = this.params.get(name);\n return values && values.length > 0 && values[0] !== void 0 ? values[0] : null;\n }\n getAll(name) {\n return this.params.get(name) || [];\n }\n has(name) {\n return this.params.has(name);\n }\n set(name, value) {\n this.params.set(name, [String(value)]);\n }\n forEach(callback) {\n this.params.forEach((values, key) => {\n values.forEach((value) => {\n callback(value, key, this);\n });\n });\n }\n toString() {\n const parts = [];\n this.params.forEach((values, key) => {\n values.forEach((value) => {\n parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);\n });\n });\n return parts.join(\"&\");\n }\n }\n window.URLSearchParams = URLSearchParamsPolyfill;\n}\nfunction polyfillTextEncoder() {\n if (typeof TextEncoder !== \"undefined\") {\n return;\n }\n class TextEncoderPolyfill {\n constructor() {\n this.encoding = \"utf-8\";\n }\n encode(str) {\n const utf8 = [];\n for (let i = 0; i < str.length; i++) {\n let charcode = str.charCodeAt(i);\n if (charcode < 128) {\n utf8.push(charcode);\n } else if (charcode < 2048) {\n utf8.push(192 | charcode >> 6, 128 | charcode & 63);\n } else if (charcode < 55296 || charcode >= 57344) {\n utf8.push(\n 224 | charcode >> 12,\n 128 | charcode >> 6 & 63,\n 128 | charcode & 63\n );\n } else {\n i++;\n charcode = 65536 + ((charcode & 1023) << 10 | str.charCodeAt(i) & 1023);\n utf8.push(\n 240 | charcode >> 18,\n 128 | charcode >> 12 & 63,\n 128 | charcode >> 6 & 63,\n 128 | charcode & 63\n );\n }\n }\n return new Uint8Array(utf8);\n }\n }\n window.TextEncoder = TextEncoderPolyfill;\n}\nfunction polyfillPromiseFinally() {\n if (typeof Promise !== \"undefined\" && !Promise.prototype.finally) {\n Promise.prototype.finally = function(callback) {\n const constructor = this.constructor;\n return this.then(\n (value) => constructor.resolve(callback()).then(() => value),\n (reason) => constructor.resolve(callback()).then(() => {\n throw reason;\n })\n );\n };\n }\n}\nfunction polyfillObjectAssign() {\n if (typeof Object.assign !== \"function\") {\n Object.assign = function(target, ...sources) {\n if (target == null) {\n throw new TypeError(\"Cannot convert undefined or null to object\");\n }\n const to = Object(target);\n for (let i = 0; i < sources.length; i++) {\n const nextSource = sources[i];\n if (nextSource != null) {\n for (const nextKey in nextSource) {\n if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {\n to[nextKey] = nextSource[nextKey];\n }\n }\n }\n }\n return to;\n };\n }\n}\nfunction polyfillArrayFrom() {\n if (!Array.from) {\n Array.from = function(arrayLike, mapFn, thisArg) {\n const items = Object(arrayLike);\n if (arrayLike == null) {\n throw new TypeError(\"Array.from requires an array-like object\");\n }\n const len = items.length >>> 0;\n const result = new Array(len);\n for (let i = 0; i < len; i++) {\n if (mapFn) {\n result[i] = mapFn.call(thisArg, items[i], i);\n } else {\n result[i] = items[i];\n }\n }\n return result;\n };\n }\n}\nfunction polyfillStringStartsWith() {\n if (!String.prototype.startsWith) {\n String.prototype.startsWith = function(search, pos) {\n pos = !pos || pos < 0 ? 0 : +pos;\n return this.substring(pos, pos + search.length) === search;\n };\n }\n}\nfunction polyfillStringEndsWith() {\n if (!String.prototype.endsWith) {\n String.prototype.endsWith = function(search, length) {\n if (length === void 0 || length > this.length) {\n length = this.length;\n }\n return this.substring(length - search.length, length) === search;\n };\n }\n}\nfunction polyfillStringIncludes() {\n if (!String.prototype.includes) {\n String.prototype.includes = function(search, start) {\n if (typeof start !== \"number\") {\n start = 0;\n }\n if (start + search.length > this.length) {\n return false;\n }\n return this.indexOf(search, start) !== -1;\n };\n }\n}\nfunction initializePolyfills() {\n polyfillObjectAssign();\n polyfillArrayFrom();\n polyfillStringStartsWith();\n polyfillStringEndsWith();\n polyfillStringIncludes();\n polyfillURLSearchParams();\n polyfillTextEncoder();\n polyfillPromiseFinally();\n}\n\n// src/utils/browserCompat.ts\nfunction getChromeVersion(ua) {\n const match = ua.match(/Chrome\\/(\\d+)/);\n return match && match[1] ? parseInt(match[1], 10) : 0;\n}\nfunction getWebKitVersion(ua) {\n const match = ua.match(/AppleWebKit\\/(\\d+)/);\n return match && match[1] ? parseInt(match[1], 10) : 0;\n}\nfunction getPlatform() {\n if (\"userAgentData\" in navigator && navigator.userAgentData?.platform) {\n return navigator.userAgentData.platform;\n }\n const ua = navigator.userAgent;\n if (/Mac|iPhone|iPad|iPod/i.test(ua)) {\n return /iPhone|iPad|iPod/i.test(ua) ? \"iPhone\" : \"MacIntel\";\n }\n if (/Win/i.test(ua)) {\n return \"Win32\";\n }\n if (/Linux/i.test(ua)) {\n return /Android/i.test(ua) ? \"Linux armv8l\" : \"Linux x86_64\";\n }\n if (/CrOS/i.test(ua)) {\n return \"CrOS\";\n }\n return navigator.platform || \"Unknown\";\n}\nfunction detectBrowser() {\n const ua = navigator.userAgent;\n const platform = getPlatform();\n let name = \"Unknown\";\n let version = \"0\";\n let majorVersion = 0;\n let isSmartTV = false;\n let isLegacyTV = false;\n let supportsIMA = true;\n let supportsModernJS = true;\n let recommendedAdPlayer = \"ima\";\n let webOSVersion;\n let tizenVersion;\n let chromeVersionNum;\n const chromeVersion = getChromeVersion(ua);\n const webkitVersion = getWebKitVersion(ua);\n chromeVersionNum = chromeVersion > 0 ? chromeVersion : void 0;\n if (/Web0S|webOS|LG Browser|LGSTB/i.test(ua)) {\n name = \"LG WebOS\";\n isSmartTV = true;\n let match = ua.match(/Web0S[/\\s]*([\\d.]+)/i) || ua.match(/webOS[/\\s]*([\\d.]+)/i);\n if (!match || !match[1]) {\n match = ua.match(/webOSTV[/\\s-]*([\\d.]+)/i) || ua.match(/webOS\\.TV[/\\s-]*([\\d.]+)/i);\n }\n if (match && match[1]) {\n version = match[1];\n const parts = version.split(\".\");\n majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;\n webOSVersion = majorVersion;\n } else if (chromeVersion > 0) {\n if (chromeVersion >= 79) {\n webOSVersion = 6;\n version = \"6.0\";\n majorVersion = 6;\n } else if (chromeVersion >= 68) {\n webOSVersion = 5;\n version = \"5.0\";\n majorVersion = 5;\n } else if (chromeVersion >= 53) {\n webOSVersion = 4;\n version = \"4.0\";\n majorVersion = 4;\n } else if (chromeVersion >= 38) {\n webOSVersion = 3;\n version = \"3.0\";\n majorVersion = 3;\n } else {\n webOSVersion = 2;\n version = \"2.0\";\n majorVersion = 2;\n }\n } else {\n version = \"Unknown\";\n webOSVersion = void 0;\n }\n if (webOSVersion !== void 0 && webOSVersion >= 4) {\n supportsIMA = true;\n recommendedAdPlayer = \"ima\";\n isLegacyTV = false;\n } else if (webOSVersion !== void 0 && webOSVersion >= 3) {\n if (chromeVersion >= 53) {\n supportsIMA = true;\n recommendedAdPlayer = \"ima\";\n isLegacyTV = false;\n } else {\n supportsIMA = false;\n recommendedAdPlayer = \"hls\";\n isLegacyTV = true;\n }\n } else if (chromeVersion >= 53) {\n supportsIMA = true;\n recommendedAdPlayer = \"ima\";\n isLegacyTV = false;\n } else {\n supportsIMA = false;\n recommendedAdPlayer = \"hls\";\n isLegacyTV = true;\n }\n } else if (/Tizen/i.test(ua)) {\n name = \"Samsung Tizen\";\n isSmartTV = true;\n const match = ua.match(/Tizen[/\\s]*([\\d.]+)/i);\n version = match && match[1] ? match[1] : \"Unknown\";\n if (version !== \"Unknown\") {\n const parts = version.split(\".\");\n majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;\n tizenVersion = majorVersion;\n }\n if (tizenVersion !== void 0 && tizenVersion >= 4) {\n supportsIMA = true;\n recommendedAdPlayer = \"ima\";\n isLegacyTV = false;\n } else if (tizenVersion !== void 0 && tizenVersion >= 3 && chromeVersion >= 47) {\n supportsIMA = true;\n recommendedAdPlayer = \"ima\";\n isLegacyTV = false;\n } else if (chromeVersion >= 53) {\n supportsIMA = true;\n recommendedAdPlayer = \"ima\";\n isLegacyTV = false;\n } else {\n supportsIMA = false;\n recommendedAdPlayer = \"hls\";\n isLegacyTV = true;\n }\n } else if (/SMART-TV|SmartTV/i.test(ua)) {\n name = \"Smart TV\";\n isSmartTV = true;\n if (chromeVersion >= 53) {\n supportsIMA = true;\n recommendedAdPlayer = \"ima\";\n } else {\n supportsIMA = false;\n recommendedAdPlayer = \"hls\";\n isLegacyTV = true;\n }\n } else if (/NetCast/i.test(ua)) {\n name = \"LG NetCast\";\n isSmartTV = true;\n isLegacyTV = true;\n supportsIMA = false;\n recommendedAdPlayer = \"hls\";\n } else if (/BRAVIA/i.test(ua)) {\n name = \"Sony BRAVIA\";\n isSmartTV = true;\n if (chromeVersion >= 53) {\n supportsIMA = true;\n recommendedAdPlayer = \"ima\";\n } else {\n supportsIMA = false;\n recommendedAdPlayer = \"hls\";\n isLegacyTV = true;\n }\n } else {\n if (chromeVersion > 0) {\n name = \"Chrome\";\n version = chromeVersion.toString();\n majorVersion = chromeVersion;\n if (chromeVersion < 50) {\n supportsIMA = false;\n supportsModernJS = false;\n recommendedAdPlayer = \"hls\";\n }\n }\n if (webkitVersion > 0 && webkitVersion < 600) {\n supportsModernJS = false;\n if (chromeVersion < 50) {\n supportsIMA = false;\n recommendedAdPlayer = \"hls\";\n }\n }\n }\n if (typeof Promise === \"undefined\" || typeof Map === \"undefined\" || typeof Set === \"undefined\") {\n supportsModernJS = false;\n supportsIMA = false;\n recommendedAdPlayer = \"hls\";\n }\n if (typeof URLSearchParams === \"undefined\") {\n supportsModernJS = false;\n }\n return {\n name,\n version,\n majorVersion,\n isSmartTV,\n isLegacyTV,\n platform,\n supportsIMA,\n supportsModernJS,\n recommendedAdPlayer,\n webOSVersion,\n tizenVersion,\n chromeVersion: chromeVersionNum\n };\n}\nfunction supportsGoogleIMA() {\n const browser = detectBrowser();\n if (browser.isLegacyTV) {\n return false;\n }\n if (typeof document === \"undefined\" || typeof document.createElement !== \"function\") {\n return false;\n }\n try {\n const video = document.createElement(\"video\");\n if (!video) {\n return false;\n }\n } catch (e) {\n return false;\n }\n if (typeof Promise === \"undefined\") {\n return false;\n }\n return browser.supportsIMA;\n}\nfunction logBrowserInfo(debug = false) {\n if (!debug) return;\n const browser = detectBrowser();\n const imaSupport = supportsGoogleIMA();\n console.log(\"[StormcloudVideoPlayer] Browser Compatibility Info:\", {\n browser: `${browser.name} ${browser.version}`,\n platform: browser.platform,\n isSmartTV: browser.isSmartTV,\n isLegacyTV: browser.isLegacyTV,\n supportsIMA: imaSupport,\n supportsModernJS: browser.supportsModernJS,\n recommendedAdPlayer: browser.recommendedAdPlayer,\n ...browser.webOSVersion !== void 0 ? { webOSVersion: browser.webOSVersion } : {},\n ...browser.tizenVersion !== void 0 ? { tizenVersion: browser.tizenVersion } : {},\n ...browser.chromeVersion !== void 0 ? { chromeVersion: browser.chromeVersion } : {},\n userAgent: navigator.userAgent\n });\n}\nfunction getBrowserConfigOverrides() {\n const browser = detectBrowser();\n const overrides = {};\n if (browser.isSmartTV) {\n overrides.allowNativeHls = true;\n }\n return overrides;\n}\n\n// src/player/StormcloudVideoPlayer.ts\nvar StormcloudVideoPlayer = class {\n constructor(config) {\n this.pendingNextAdBids = null;\n this.continuousFetchLoopPromise = null;\n this.attached = false;\n this.inAdBreak = false;\n this.ptsDriftEmaMs = 0;\n this.adPodQueue = [];\n this.lastHeartbeatTime = 0;\n this.currentAdIndex = 0;\n this.totalAdsInBreak = 0;\n this.showAds = false;\n this.isLiveStream = false;\n this.nativeHlsMode = false;\n this.videoSrcProtection = null;\n this.bufferedSegmentsCount = 0;\n this.shouldAutoplayAfterBuffering = false;\n this.hasInitialBufferCompleted = false;\n this.activeAdRequestToken = null;\n this.adRequestWatchdogToken = null;\n this.adFailsafeToken = null;\n this.continuousFetchingActive = false;\n this.maxPlaceholderDurationMs = 5e3;\n this.isShowingPlaceholder = false;\n this.totalAdRequestsInBreak = 0;\n this.maxTotalAdRequestsPerBreak = 20;\n this.pendingAdBreak = null;\n this.savedMutedStateBeforeScte = null;\n this.consecutiveFailures = 0;\n this.maxConsecutiveFailures = 5;\n this.lastAdRequestTime = 0;\n this.minAdRequestIntervalMs = 2500;\n this.backoffBaseMs = 1e3;\n this.maxBackoffMs = 15e3;\n this.adTransitionGapMs = 1500;\n initializePolyfills();\n const browserOverrides = getBrowserConfigOverrides();\n this.config = { ...browserOverrides, ...config };\n this.video = config.videoElement;\n logBrowserInfo(config.debugAdTiming);\n this.prebidManager = createPrebidManager(\n config.debugAdTiming !== void 0 ? { debug: !!config.debugAdTiming } : {}\n );\n this.adLayer = createPrebidAdLayer(this.video, {\n continueLiveStreamDuringAds: false,\n debug: !!config.debugAdTiming\n });\n }\n async adRequest() {\n await this.prebidManager.initialize();\n return this.prebidManager.requestBidsUntilResponse();\n }\n async load() {\n if (!this.attached) {\n this.attach();\n }\n this.initializeTracking();\n if (this.shouldUseNativeHls()) {\n this.nativeHlsMode = true;\n this.videoSrcProtection = this.config.src;\n this.video.src = this.config.src;\n this.isLiveStream = this.config.lowLatencyMode ?? false;\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Using native HLS playback - VOD mode:\",\n {\n isLive: this.isLiveStream,\n allowNativeHls: this.config.allowNativeHls,\n adBehavior: \"vod (main video pauses during ads)\"\n }\n );\n }\n this.adLayer.updateOptions({ continueLiveStreamDuringAds: false, mainHlsInstance: null });\n if (this.config.autoplay) {\n await this.video.play()?.catch(() => {\n });\n }\n return;\n }\n this.hls = new import_hls2.default({\n enableWorker: true,\n backBufferLength: 30,\n liveDurationInfinity: true,\n lowLatencyMode: !!this.config.lowLatencyMode,\n maxLiveSyncPlaybackRate: this.config.lowLatencyMode ? 1.5 : 1,\n ...this.config.lowLatencyMode ? { liveSyncDuration: 2 } : {},\n maxBufferLength: 30,\n maxMaxBufferLength: 600,\n maxBufferSize: 60 * 1e3 * 1e3,\n maxBufferHole: 0.5,\n highBufferWatchdogPeriod: 2,\n nudgeOffset: 0.1,\n nudgeMaxRetry: 3,\n startPosition: -1\n });\n this.hls.on(import_hls2.default.Events.MEDIA_ATTACHED, () => {\n this.hls?.loadSource(this.config.src);\n });\n this.hls.on(import_hls2.default.Events.MANIFEST_PARSED, async (_, data) => {\n if (this.config.allowNativeHls === false) {\n this.isLiveStream = true;\n } else {\n this.isLiveStream = this.hls?.levels?.some(\n (level) => level?.details?.live === true || level?.details?.type === \"LIVE\"\n ) ?? false;\n }\n if (this.config.debugAdTiming) {\n const adBehavior = this.shouldContinueLiveStreamDuringAds() ? \"live (main video continues muted during ads)\" : \"vod (main video pauses during ads)\";\n console.log(\"[StormcloudVideoPlayer] Stream type detected:\", {\n isLive: this.isLiveStream,\n allowNativeHls: this.config.allowNativeHls,\n adBehavior\n });\n }\n this.adLayer.updateOptions({\n continueLiveStreamDuringAds: this.shouldContinueLiveStreamDuringAds(),\n mainHlsInstance: this.hls ?? null\n });\n this.bufferedSegmentsCount = 0;\n this.hasInitialBufferCompleted = false;\n this.shouldAutoplayAfterBuffering = !!this.config.autoplay;\n const minSegments = this.config.minSegmentsBeforePlay ?? 2;\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Waiting for\",\n minSegments,\n \"segments to buffer before playback\"\n );\n }\n if (minSegments === 0 || !this.config.autoplay) {\n this.hasInitialBufferCompleted = true;\n if (this.config.autoplay) {\n await this.video.play()?.catch(() => {\n });\n }\n }\n });\n this.hls.on(import_hls2.default.Events.LEVEL_LOADED, (_evt, data) => {\n if (this.inAdBreak || this.pendingAdBreak) {\n return;\n }\n const details = data?.details;\n if (!details || !details.fragments || details.fragments.length === 0) {\n return;\n }\n const fragmentsToScan = Math.min(5, details.fragments.length);\n for (let i = 0; i < fragmentsToScan; i++) {\n const frag = details.fragments[i];\n const tagList = frag?.tagList;\n if (!Array.isArray(tagList)) continue;\n for (const entry of tagList) {\n let tag = \"\";\n let value = \"\";\n if (Array.isArray(entry)) {\n tag = String(entry[0] ?? \"\");\n value = String(entry[1] ?? \"\");\n } else if (typeof entry === \"string\") {\n const idx = entry.indexOf(\":\");\n if (idx >= 0) {\n tag = entry.substring(0, idx);\n value = entry.substring(idx + 1);\n } else {\n tag = entry;\n }\n }\n if (!tag) continue;\n if (tag.includes(\"EXT-X-CUE-OUT\") || tag.includes(\"EXT-X-DATERANGE\")) {\n const attrs = tag.includes(\"EXT-X-DATERANGE\") ? this.parseAttributeList(value) : {};\n const hasScteOut = tag.includes(\"EXT-X-CUE-OUT\") || \"SCTE35-OUT\" in attrs || attrs[\"SCTE35-OUT\"] !== void 0;\n if (hasScteOut) {\n const durationSeconds = this.parseCueOutDuration(value);\n const marker = {\n type: \"start\",\n ...durationSeconds !== void 0 ? { durationSeconds } : {},\n raw: { tag, value, earlyDetection: true }\n };\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] \\u{1F3AF} EARLY SCTE-35 DETECTION: Ad break marker found in fragment\", i, \"- starting pre-fetch (NOT playing yet)\");\n }\n this.startAdPrefetch(marker, frag?.sn);\n return;\n }\n }\n }\n }\n });\n this.hls.on(import_hls2.default.Events.FRAG_BUFFERED, async (_evt, data) => {\n if (this.hasInitialBufferCompleted) {\n return;\n }\n this.bufferedSegmentsCount++;\n const minSegments = this.config.minSegmentsBeforePlay ?? 2;\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Buffered segment ${this.bufferedSegmentsCount}/${minSegments}`\n );\n }\n if (this.bufferedSegmentsCount >= minSegments) {\n this.hasInitialBufferCompleted = true;\n if (this.shouldAutoplayAfterBuffering) {\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Initial buffer complete (${this.bufferedSegmentsCount} segments). Starting playback.`\n );\n }\n await this.video.play()?.catch((err) => {\n if (this.config.debugAdTiming) {\n console.warn(\"[StormcloudVideoPlayer] Autoplay failed:\", err);\n }\n });\n }\n }\n });\n this.hls.on(import_hls2.default.Events.FRAG_PARSING_METADATA, (_evt, data) => {\n const id3Tags = (data?.samples || []).map((s) => ({\n key: \"ID3\",\n value: s?.data,\n ptsSeconds: s?.pts\n }));\n id3Tags.forEach((tag) => this.onId3Tag(tag));\n });\n this.hls.on(import_hls2.default.Events.FRAG_CHANGED, (_evt, data) => {\n const frag = data?.frag;\n const tagList = frag?.tagList;\n if (!Array.isArray(tagList)) return;\n for (const entry of tagList) {\n let tag = \"\";\n let value = \"\";\n if (Array.isArray(entry)) {\n tag = String(entry[0] ?? \"\");\n value = String(entry[1] ?? \"\");\n } else if (typeof entry === \"string\") {\n const idx = entry.indexOf(\":\");\n if (idx >= 0) {\n tag = entry.substring(0, idx);\n value = entry.substring(idx + 1);\n } else {\n tag = entry;\n value = \"\";\n }\n }\n if (!tag) continue;\n if (tag.includes(\"EXT-X-CUE-OUT-CONT\")) {\n const prog = this.parseCueOutCont(value);\n const marker = {\n type: \"progress\",\n ...prog?.duration !== void 0 ? { durationSeconds: prog.duration } : {},\n ...prog?.elapsed !== void 0 ? { ptsSeconds: prog.elapsed } : {},\n raw: { tag, value }\n };\n this.onScte35Marker(marker);\n } else if (tag.includes(\"EXT-X-CUE-OUT\")) {\n const durationSeconds = this.parseCueOutDuration(value);\n const marker = {\n type: \"start\",\n ...durationSeconds !== void 0 ? { durationSeconds } : {},\n raw: { tag, value }\n };\n this.onScte35Marker(marker);\n } else if (tag.includes(\"EXT-X-CUE-IN\")) {\n this.onScte35Marker({ type: \"end\", raw: { tag, value } });\n } else if (tag.includes(\"EXT-X-DATERANGE\")) {\n const attrs = this.parseAttributeList(value);\n const hasScteOut = \"SCTE35-OUT\" in attrs || attrs[\"SCTE35-OUT\"] !== void 0;\n const hasScteIn = \"SCTE35-IN\" in attrs || attrs[\"SCTE35-IN\"] !== void 0;\n const klass = String(attrs[\"CLASS\"] ?? \"\");\n const duration = this.toNumber(attrs[\"DURATION\"]);\n if (hasScteOut || /com\\.apple\\.hls\\.cue/i.test(klass)) {\n const marker = {\n type: \"start\",\n ...duration !== void 0 ? { durationSeconds: duration } : {},\n raw: { tag, value, attrs }\n };\n this.onScte35Marker(marker);\n }\n if (hasScteIn) {\n this.onScte35Marker({ type: \"end\", raw: { tag, value, attrs } });\n }\n }\n }\n });\n this.hls.on(import_hls2.default.Events.ERROR, (_evt, data) => {\n if (data?.fatal) {\n switch (data.type) {\n case import_hls2.default.ErrorTypes.NETWORK_ERROR:\n this.hls?.startLoad();\n break;\n case import_hls2.default.ErrorTypes.MEDIA_ERROR:\n this.hls?.recoverMediaError();\n break;\n default:\n this.destroy();\n break;\n }\n }\n });\n this.hls.attachMedia(this.video);\n }\n getAdSource() {\n return \"prebid\";\n }\n attachAdLayerEventListeners() {\n this.adLayer.on(\"ad_impression\", () => {\n if (this.config.licenseKey) {\n sendAdImpressionTracking(this.config.licenseKey, {\n source: this.getAdSource(),\n adIndex: this.currentAdIndex,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n });\n }\n });\n this.adLayer.on(\"ad_error\", (errorPayload) => {\n let errorMessage = \"Ad playback failed\";\n if (errorPayload) {\n const errorCode = errorPayload.code || errorPayload.errorCode || \"unknown\";\n const vastErrorCode = errorPayload.vastErrorCode;\n const message = errorPayload.message || errorPayload.errorMessage || \"Unknown error\";\n const cause = errorPayload.cause || errorPayload.innerError || errorPayload.error;\n errorMessage = `Ad error: AdError ${errorCode}: ${message}`;\n if (vastErrorCode && vastErrorCode !== \"N/A\" && vastErrorCode !== errorCode) {\n errorMessage += ` (VAST Error Code: ${vastErrorCode})`;\n }\n if (cause) {\n const causeMessage = typeof cause === \"string\" ? cause : cause.message || String(cause);\n errorMessage += `. Caused by: ${causeMessage}`;\n }\n }\n console.error(\"[AD-ERROR]\", errorMessage, errorPayload || \"\");\n this.adLayer.stop().catch(() => {\n });\n this.handleAdFailure();\n });\n this.adLayer.on(\"content_pause\", () => {\n this.clearAdFailsafeTimer();\n this.clearAdRequestWatchdog();\n this.activeAdRequestToken = null;\n this.showAds = true;\n if (this.inAdBreak && this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {\n this.scheduleAdStopCountdown(this.getRemainingAdMs());\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Starting ad break timer on content_pause (first ad starting)\");\n }\n }\n this.adLayer.setAdVolume(\n this.adLayer.getOriginalMutedState() ? 0 : this.adLayer.getOriginalVolume()\n );\n if (this.isShowingPlaceholder) {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Hiding placeholder - new ads starting\");\n }\n this.hidePlaceholderLayer();\n this.adLayer.hidePlaceholder();\n this.isShowingPlaceholder = false;\n }\n });\n this.adLayer.on(\"content_resume\", () => {\n const remaining = this.getRemainingAdMs();\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] content_resume received, inAdBreak=%s, remaining=%s, pendingNext=%s\",\n this.inAdBreak,\n remaining,\n !!this.pendingNextAdBids\n );\n }\n this.clearAdFailsafeTimer();\n this.clearAdRequestWatchdog();\n this.activeAdRequestToken = null;\n this.showAds = false;\n if (!this.inAdBreak) {\n const restoredMuted = this.adLayer.getOriginalMutedState();\n const restoredVolume = this.adLayer.getOriginalVolume();\n if (this.video.muted !== restoredMuted) this.video.muted = restoredMuted;\n if (Math.abs(this.video.volume - restoredVolume) > 0.01) this.video.volume = restoredVolume;\n return;\n }\n this.consecutiveFailures = 0;\n if (this.pendingNextAdBids && this.pendingNextAdBids.length > 0) {\n const bids = [...this.pendingNextAdBids];\n this.pendingNextAdBids = null;\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n }\n this.showPlaceholderLayer();\n this.adLayer.showPlaceholder();\n setTimeout(() => {\n if (!this.inAdBreak || bids.length === 0) return;\n this.currentAdIndex++;\n this.adLayer.playAd(bids).catch((err) => {\n if (this.config.debugAdTiming) console.warn(\"[StormcloudVideoPlayer] playAd(pending) failed:\", err);\n this.handleAdFailure();\n });\n }, this.adTransitionGapMs);\n return;\n }\n if (remaining <= 500 && this.expectedAdBreakDurationMs != null) {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] content_resume: remaining time low and duration known, ending ad pod\");\n }\n this.handleAdPodComplete();\n } else {\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n }\n }\n });\n }\n ensurePlaceholderContainer() {\n if (this.placeholderContainer) {\n return;\n }\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 = \"5\";\n container.style.backgroundColor = \"#000\";\n container.style.transition = \"opacity 0.3s ease-in-out\";\n container.style.opacity = \"0\";\n if (!this.video.parentElement) {\n if (this.config.debugAdTiming) {\n console.warn(\"[StormcloudVideoPlayer] Video element has no parent for placeholder container\");\n }\n return;\n }\n this.video.parentElement.appendChild(container);\n this.placeholderContainer = container;\n }\n showPlaceholderLayer() {\n this.ensurePlaceholderContainer();\n if (!this.placeholderContainer) {\n return;\n }\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Muted video when showing placeholder\");\n }\n }\n const wasHidden = this.placeholderContainer.style.display === \"none\" || this.placeholderContainer.style.opacity === \"0\";\n if (wasHidden) {\n this.placeholderContainer.style.transition = \"none\";\n } else {\n this.placeholderContainer.style.transition = \"opacity 0.3s ease-in-out\";\n }\n this.placeholderContainer.style.backgroundColor = \"#000\";\n this.placeholderContainer.style.display = \"flex\";\n this.placeholderContainer.offsetHeight;\n this.placeholderContainer.style.opacity = \"1\";\n this.placeholderContainer.style.pointerEvents = \"auto\";\n if (wasHidden) {\n requestAnimationFrame(() => {\n if (this.placeholderContainer) {\n this.placeholderContainer.style.transition = \"opacity 0.3s ease-in-out\";\n }\n });\n }\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Showing placeholder layer\");\n }\n }\n hidePlaceholderLayer() {\n if (!this.placeholderContainer) {\n return;\n }\n this.placeholderContainer.style.opacity = \"0\";\n setTimeout(() => {\n if (this.placeholderContainer) {\n this.placeholderContainer.style.display = \"none\";\n this.placeholderContainer.style.pointerEvents = \"none\";\n this.placeholderContainer.style.backgroundColor = \"#000\";\n }\n }, 300);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Hiding placeholder layer\");\n }\n }\n attach() {\n if (this.attached) return;\n this.attached = true;\n this.video.autoplay = !!this.config.autoplay;\n this.video.muted = !!this.config.muted;\n this.adLayer.initialize();\n this.adLayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n this.attachAdLayerEventListeners();\n this.timeUpdateHandler = () => {\n this.onTimeUpdate(this.video.currentTime);\n };\n this.video.addEventListener(\"timeupdate\", this.timeUpdateHandler);\n this.emptiedHandler = () => {\n if (this.nativeHlsMode && this.videoSrcProtection && !this.adLayer.isAdPlaying()) {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Video src was cleared, restoring:\",\n this.videoSrcProtection\n );\n }\n const currentTime = this.video.currentTime;\n const wasPaused = this.video.paused;\n this.video.src = this.videoSrcProtection;\n this.video.currentTime = currentTime;\n if (!wasPaused) {\n this.video.play().catch(() => {\n });\n }\n }\n };\n this.video.addEventListener(\"emptied\", this.emptiedHandler);\n }\n shouldUseNativeHls() {\n const streamType = this.getStreamType();\n if (streamType === \"other\") {\n return true;\n }\n const canNative = this.video.canPlayType(\"application/vnd.apple.mpegurl\");\n return !!(this.config.allowNativeHls && canNative);\n }\n onId3Tag(tag) {\n if (typeof tag.ptsSeconds === \"number\") {\n this.updatePtsDrift(tag.ptsSeconds);\n }\n const marker = this.parseScte35FromId3(tag);\n if (marker) {\n this.onScte35Marker(marker);\n }\n }\n parseScte35FromId3(tag) {\n const text = this.decodeId3ValueToText(tag.value);\n if (!text) return void 0;\n const cueOutMatch = text.match(/EXT-X-CUE-OUT(?::([^\\r\\n]*))?/i) || text.match(/CUE-OUT(?::([^\\r\\n]*))?/i);\n if (cueOutMatch) {\n const arg = (cueOutMatch[1] ?? \"\").trim();\n const dur = this.parseCueOutDuration(arg);\n const marker = {\n type: \"start\",\n ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n ...dur !== void 0 ? { durationSeconds: dur } : {},\n raw: { id3: text }\n };\n return marker;\n }\n const cueOutContMatch = text.match(/EXT-X-CUE-OUT-CONT:([^\\r\\n]*)/i);\n if (cueOutContMatch) {\n const arg = (cueOutContMatch[1] ?? \"\").trim();\n const cont = this.parseCueOutCont(arg);\n const marker = {\n type: \"progress\",\n ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n ...cont?.duration !== void 0 ? { durationSeconds: cont.duration } : {},\n raw: { id3: text }\n };\n return marker;\n }\n const cueInMatch = text.match(/EXT-X-CUE-IN\\b/i) || text.match(/CUE-IN\\b/i);\n if (cueInMatch) {\n const marker = {\n type: \"end\",\n ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n raw: { id3: text }\n };\n return marker;\n }\n const daterangeMatch = text.match(/EXT-X-DATERANGE:([^\\r\\n]*)/i);\n if (daterangeMatch) {\n const attrs = this.parseAttributeList(daterangeMatch[1] ?? \"\");\n const hasScteOut = \"SCTE35-OUT\" in attrs || attrs[\"SCTE35-OUT\"] !== void 0;\n const hasScteIn = \"SCTE35-IN\" in attrs || attrs[\"SCTE35-IN\"] !== void 0;\n const klass = String(attrs[\"CLASS\"] ?? \"\");\n const duration = this.toNumber(attrs[\"DURATION\"]);\n if (hasScteOut || /com\\.apple\\.hls\\.cue/i.test(klass)) {\n const marker = {\n type: \"start\",\n ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n ...duration !== void 0 ? { durationSeconds: duration } : {},\n raw: { id3: text, attrs }\n };\n return marker;\n }\n if (hasScteIn) {\n const marker = {\n type: \"end\",\n ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n raw: { id3: text, attrs }\n };\n return marker;\n }\n }\n if (/SCTE35-OUT/i.test(text)) {\n const marker = {\n type: \"start\",\n ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n raw: { id3: text }\n };\n return marker;\n }\n if (/SCTE35-IN/i.test(text)) {\n const marker = {\n type: \"end\",\n ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n raw: { id3: text }\n };\n return marker;\n }\n if (tag.value instanceof Uint8Array) {\n const bin = this.parseScte35Binary(tag.value);\n if (bin) return bin;\n }\n return void 0;\n }\n decodeId3ValueToText(value) {\n try {\n if (typeof value === \"string\") return value;\n const decoder = new TextDecoder(\"utf-8\", { fatal: false });\n const text = decoder.decode(value);\n if (text && /[\\x20-\\x7E]/.test(text)) return text;\n let out = \"\";\n for (let i = 0; i < value.length; i++)\n out += String.fromCharCode(value[i]);\n return out;\n } catch {\n return void 0;\n }\n }\n onScte35Marker(marker) {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] SCTE-35 marker detected:\", {\n type: marker.type,\n ptsSeconds: marker.ptsSeconds,\n durationSeconds: marker.durationSeconds,\n currentTime: this.video.currentTime,\n raw: marker.raw,\n hasPendingAdBreak: !!this.pendingAdBreak\n });\n }\n if (marker.type === \"start\") {\n this.savedMutedStateBeforeScte = {\n muted: this.video.muted,\n volume: this.video.volume\n };\n this.adLayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Muted video on SCTE start marker\");\n }\n }\n if (this.inAdBreak) {\n if (this.expectedAdBreakDurationMs == null && marker.durationSeconds != null) {\n this.expectedAdBreakDurationMs = marker.durationSeconds * 1e3;\n if (this.config.debugAdTiming) {\n console.log(`[StormcloudVideoPlayer] Updated ad break duration from subsequent marker: ${this.expectedAdBreakDurationMs}ms`);\n }\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n return;\n }\n this.inAdBreak = true;\n const durationMs = marker.durationSeconds != null ? marker.durationSeconds * 1e3 : this.pendingAdBreak?.marker.durationSeconds != null ? this.pendingAdBreak.marker.durationSeconds * 1e3 : void 0;\n this.expectedAdBreakDurationMs = durationMs;\n this.currentAdBreakStartWallClockMs = Date.now();\n if (this.config.licenseKey) {\n const adDetectInfo = {\n source: \"scte35\",\n timestamp: (/* @__PURE__ */ new Date()).toISOString(),\n ...marker.durationSeconds != null && { durationSeconds: marker.durationSeconds },\n ...marker.ptsSeconds != null && { ptsSeconds: marker.ptsSeconds },\n ...this.pendingAdBreak?.detectedAtFragmentSn != null && {\n detectedAtFragmentSn: this.pendingAdBreak.detectedAtFragmentSn\n }\n };\n sendAdDetectTracking(this.config.licenseKey, adDetectInfo);\n }\n const isManifestMarker = this.isManifestBasedMarker(marker);\n const forceImmediate = this.config.immediateManifestAds ?? true;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Ad start decision:\", {\n isManifestMarker,\n forceImmediate,\n hasPts: typeof marker.ptsSeconds === \"number\"\n });\n }\n if (isManifestMarker && forceImmediate) {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Starting ad immediately (manifest-based)\"\n );\n }\n this.clearAdStartTimer();\n this.handleAdStart(marker);\n } else if (typeof marker.ptsSeconds === \"number\") {\n const tol = this.config.driftToleranceMs ?? 1e3;\n const nowMs = this.video.currentTime * 1e3;\n const estCurrentPtsMs = nowMs - this.ptsDriftEmaMs;\n const deltaMs = Math.floor(marker.ptsSeconds * 1e3 - estCurrentPtsMs);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] PTS-based timing calculation:\", {\n nowMs,\n estCurrentPtsMs,\n markerPtsMs: marker.ptsSeconds * 1e3,\n deltaMs,\n tolerance: tol\n });\n }\n if (deltaMs > tol) {\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Scheduling ad start in ${deltaMs}ms`\n );\n }\n this.scheduleAdStartIn(deltaMs);\n } else {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Starting ad immediately (within tolerance)\"\n );\n }\n this.clearAdStartTimer();\n this.handleAdStart(marker);\n }\n } else {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Starting ad immediately (fallback)\"\n );\n }\n this.clearAdStartTimer();\n this.handleAdStart(marker);\n }\n if (this.expectedAdBreakDurationMs != null) {\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n return;\n }\n if (marker.type === \"progress\" && this.inAdBreak) {\n if (marker.durationSeconds != null) {\n this.expectedAdBreakDurationMs = marker.durationSeconds * 1e3;\n }\n if (this.expectedAdBreakDurationMs != null && this.currentAdBreakStartWallClockMs != null) {\n const elapsedMs = Date.now() - this.currentAdBreakStartWallClockMs;\n const remainingMs = Math.max(\n 0,\n this.expectedAdBreakDurationMs - elapsedMs\n );\n this.scheduleAdStopCountdown(remainingMs);\n }\n if (!this.adLayer.isAdPlaying() && this.pendingNextAdBids != null && this.pendingNextAdBids.length > 0) {\n const bids = this.pendingNextAdBids;\n this.pendingNextAdBids = null;\n this.currentAdIndex++;\n this.adLayer.playAd(bids).catch(() => this.handleAdFailure());\n }\n return;\n }\n if (marker.type === \"end\") {\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Muted video on SCTE end marker\");\n }\n }\n const remaining = this.getRemainingAdMs();\n const adPlaying = this.adLayer.isAdPlaying();\n const hasQueuedAds = this.pendingNextAdBids != null && this.pendingNextAdBids.length > 0;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] SCTE-35 end marker received:\", {\n remaining,\n adPlaying,\n hasQueuedAds,\n activeAdRequest: this.activeAdRequestToken !== null\n });\n }\n if (adPlaying || remaining > 500) {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Ignoring premature SCTE-35 end marker - ads still active or time remaining\");\n }\n return;\n }\n this.inAdBreak = false;\n this.expectedAdBreakDurationMs = void 0;\n this.currentAdBreakStartWallClockMs = void 0;\n this.clearAdStartTimer();\n this.clearAdStopTimer();\n if (adPlaying) {\n this.adLayer.stop().catch(() => {\n });\n }\n this.handleAdPodComplete();\n return;\n }\n }\n parseCueOutDuration(value) {\n const num = parseFloat(value.trim());\n if (!Number.isNaN(num)) return num;\n const match = value.match(/(?:^|[,\\s])DURATION\\s*=\\s*([0-9.]+)/i) || value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n if (match && match[1] != null) {\n const dStr = match[1];\n const d = parseFloat(dStr);\n return Number.isNaN(d) ? void 0 : d;\n }\n return void 0;\n }\n parseCueOutCont(value) {\n const res = {};\n const elapsedMatch = value.match(/Elapsed\\s*=\\s*([0-9.]+)/i);\n const durationMatch = value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n if (elapsedMatch && elapsedMatch[1] != null) {\n const e = parseFloat(elapsedMatch[1]);\n if (!Number.isNaN(e)) res.elapsed = e;\n }\n if (durationMatch && durationMatch[1] != null) {\n const d = parseFloat(durationMatch[1]);\n if (!Number.isNaN(d)) res.duration = d;\n }\n if (!(\"elapsed\" in res) || !(\"duration\" in res)) {\n const slashMatch = value.match(/([0-9.]+)\\s*\\/\\s*([0-9.]+)/);\n if (slashMatch && slashMatch[1] && slashMatch[2]) {\n const elapsed = parseFloat(slashMatch[1]);\n const duration = parseFloat(slashMatch[2]);\n if (!Number.isNaN(elapsed) && !(\"elapsed\" in res)) res.elapsed = elapsed;\n if (!Number.isNaN(duration) && !(\"duration\" in res)) res.duration = duration;\n }\n }\n if (\"elapsed\" in res || \"duration\" in res) return res;\n return void 0;\n }\n parseAttributeList(value) {\n const attrs = {};\n const regex = /([A-Z0-9-]+)=((\"[^\"]*\")|([^\",]*))(?:,|$)/gi;\n let match;\n while ((match = regex.exec(value)) !== null) {\n const key = match[1] ?? \"\";\n let rawVal = match[3] ?? match[4] ?? \"\";\n if (rawVal.startsWith('\"') && rawVal.endsWith('\"')) {\n rawVal = rawVal.slice(1, -1);\n }\n if (key) {\n attrs[key] = rawVal;\n }\n }\n return attrs;\n }\n toNumber(val) {\n if (val == null) return void 0;\n const n = typeof val === \"string\" ? parseFloat(val) : Number(val);\n return Number.isNaN(n) ? void 0 : n;\n }\n isManifestBasedMarker(marker) {\n const raw = marker.raw;\n if (!raw) return false;\n if (raw.tag) {\n const tag = String(raw.tag);\n return tag.includes(\"EXT-X-CUE-OUT\") || tag.includes(\"EXT-X-CUE-IN\") || tag.includes(\"EXT-X-DATERANGE\");\n }\n if (raw.id3) return false;\n if (raw.splice_command_type) return false;\n return false;\n }\n parseScte35Binary(data) {\n class BitReader {\n constructor(buf) {\n this.buf = buf;\n this.bytePos = 0;\n this.bitPos = 0;\n }\n readBits(numBits) {\n let result = 0;\n while (numBits > 0) {\n if (this.bytePos >= this.buf.length) return result;\n const remainingInByte = 8 - this.bitPos;\n const toRead = Math.min(numBits, remainingInByte);\n const currentByte = this.buf[this.bytePos];\n const shift = remainingInByte - toRead;\n const mask = (1 << toRead) - 1 & 255;\n const bits = currentByte >> shift & mask;\n result = result << toRead | bits;\n this.bitPos += toRead;\n if (this.bitPos >= 8) {\n this.bitPos = 0;\n this.bytePos += 1;\n }\n numBits -= toRead;\n }\n return result >>> 0;\n }\n skipBits(n) {\n this.readBits(n);\n }\n }\n const r = new BitReader(data);\n const tableId = r.readBits(8);\n if (tableId !== 252) return void 0;\n r.readBits(1);\n r.readBits(1);\n r.readBits(2);\n const sectionLength = r.readBits(12);\n r.readBits(8);\n r.readBits(1);\n r.readBits(6);\n const ptsAdjHigh = r.readBits(1);\n const ptsAdjLow = r.readBits(32);\n void ptsAdjHigh;\n void ptsAdjLow;\n r.readBits(8);\n r.readBits(12);\n const spliceCommandLength = r.readBits(12);\n const spliceCommandType = r.readBits(8);\n if (spliceCommandType !== 5) {\n return void 0;\n }\n r.readBits(32);\n const cancel = r.readBits(1) === 1;\n r.readBits(7);\n if (cancel) return void 0;\n const outOfNetwork = r.readBits(1) === 1;\n const programSpliceFlag = r.readBits(1) === 1;\n const durationFlag = r.readBits(1) === 1;\n const spliceImmediateFlag = r.readBits(1) === 1;\n r.readBits(4);\n if (programSpliceFlag && !spliceImmediateFlag) {\n const timeSpecifiedFlag = r.readBits(1) === 1;\n if (timeSpecifiedFlag) {\n r.readBits(6);\n r.readBits(33);\n } else {\n r.readBits(7);\n }\n } else if (!programSpliceFlag) {\n const componentCount = r.readBits(8);\n for (let i = 0; i < componentCount; i++) {\n r.readBits(8);\n if (!spliceImmediateFlag) {\n const timeSpecifiedFlag = r.readBits(1) === 1;\n if (timeSpecifiedFlag) {\n r.readBits(6);\n r.readBits(33);\n } else {\n r.readBits(7);\n }\n }\n }\n }\n let durationSeconds = void 0;\n if (durationFlag) {\n r.readBits(6);\n r.readBits(1);\n const high = r.readBits(1);\n const low = r.readBits(32);\n const durationTicks = high * 4294967296 + low;\n durationSeconds = durationTicks / 9e4;\n }\n r.readBits(16);\n r.readBits(8);\n r.readBits(8);\n if (outOfNetwork) {\n const marker = {\n type: \"start\",\n ...durationSeconds !== void 0 ? { durationSeconds } : {},\n raw: { splice_command_type: 5 }\n };\n return marker;\n }\n return void 0;\n }\n initializeTracking() {\n sendInitialTracking(this.config.licenseKey).then(() => {\n this.heartbeatInterval = window.setInterval(() => {\n this.sendHeartbeatIfNeeded();\n }, 5e3);\n }).catch((error) => {\n if (this.config.debugAdTiming) {\n console.warn(\n \"[StormcloudVideoPlayer] Failed to send initial tracking:\",\n error\n );\n }\n this.heartbeatInterval = window.setInterval(() => {\n this.sendHeartbeatIfNeeded();\n }, 5e3);\n });\n }\n sendHeartbeatIfNeeded() {\n const now = Date.now();\n if (!this.lastHeartbeatTime || now - this.lastHeartbeatTime > 3e4) {\n this.lastHeartbeatTime = now;\n sendHeartbeat(this.config.licenseKey).catch((error) => {\n if (this.config.debugAdTiming) {\n console.warn(\n \"[StormcloudVideoPlayer] Failed to send heartbeat:\",\n error\n );\n }\n });\n }\n }\n getCurrentAdIndex() {\n return this.currentAdIndex;\n }\n getTotalAdsInBreak() {\n return this.totalAdsInBreak;\n }\n isAdPlaying() {\n return this.inAdBreak && this.adLayer.isAdPlaying();\n }\n isShowingAds() {\n return this.showAds;\n }\n getStreamType() {\n const url = this.config.src.toLowerCase();\n if (url.includes(\".m3u8\") || url.includes(\"/hls/\") || url.includes(\"application/vnd.apple.mpegurl\")) {\n return \"hls\";\n }\n return \"other\";\n }\n shouldShowNativeControls() {\n const streamType = this.getStreamType();\n if (streamType === \"other\") {\n return !(this.config.showCustomControls ?? false);\n }\n return !!(this.config.allowNativeHls && !(this.config.showCustomControls ?? false));\n }\n shouldContinueLiveStreamDuringAds() {\n if (this.config.allowNativeHls) {\n return false;\n }\n if (!this.isLiveStream) {\n return false;\n }\n return true;\n }\n startAdPrefetch(marker, fragmentSn) {\n if (this.pendingAdBreak || this.inAdBreak) {\n return;\n }\n this.pendingAdBreak = {\n marker,\n ...fragmentSn !== void 0 ? { detectedAtFragmentSn: fragmentSn } : {},\n isFetching: false,\n fetchStartTime: Date.now()\n };\n void this.adRequest().then(() => {\n }).catch(() => {\n if (this.config.debugAdTiming) {\n console.log(\"[PREFETCH] Prebid auction prefetch failed, will request at playback time\");\n }\n });\n if (this.config.debugAdTiming) {\n console.log(\"[PREFETCH] Ad break marker registered, auction prefetch started\");\n }\n }\n clearPendingAdBreak() {\n if (this.prefetchTimerId != null) {\n clearTimeout(this.prefetchTimerId);\n this.prefetchTimerId = void 0;\n }\n this.pendingAdBreak = null;\n }\n startContinuousFetchLoop() {\n if (this.continuousFetchLoopPromise != null) return;\n this.continuousFetchLoopPromise = this.runContinuousFetchLoop();\n }\n async runContinuousFetchLoop() {\n const backoffMs = () => {\n const mult = Math.pow(2, this.consecutiveFailures);\n return Math.min(this.backoffBaseMs * mult, this.maxBackoffMs);\n };\n while (this.inAdBreak && this.continuousFetchingActive) {\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) break;\n if (this.totalAdRequestsInBreak >= this.maxTotalAdRequestsPerBreak) break;\n const delay = this.lastAdRequestTime ? this.minAdRequestIntervalMs + (this.consecutiveFailures > 0 ? backoffMs() : 0) : 0;\n const elapsed = Date.now() - this.lastAdRequestTime;\n if (elapsed < delay && this.lastAdRequestTime > 0) {\n await new Promise((r) => setTimeout(r, delay - elapsed));\n }\n if (!this.inAdBreak || !this.continuousFetchingActive) break;\n try {\n const bids = await this.adRequest();\n this.lastAdRequestTime = Date.now();\n if (!this.inAdBreak) break;\n if (bids.length > 0) {\n this.consecutiveFailures = 0;\n if (this.adLayer.isAdPlaying()) {\n this.pendingNextAdBids = bids;\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] Next ad response stored (ad currently playing)\");\n }\n } else {\n this.currentAdIndex++;\n if (this.config.licenseKey) {\n sendAdLoadedTracking(this.config.licenseKey, {\n source: this.getAdSource(),\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n });\n }\n await this.adLayer.playAd(bids);\n if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {\n this.scheduleAdStopCountdown(this.getRemainingAdMs());\n }\n this.adLayer.setAdVolume(\n this.adLayer.getOriginalMutedState() ? 0 : this.adLayer.getOriginalVolume()\n );\n }\n } else {\n this.consecutiveFailures++;\n }\n } catch (err) {\n this.consecutiveFailures++;\n if (this.config.debugAdTiming) {\n console.warn(\"[CONTINUOUS-FETCH] adRequest failed:\", err);\n }\n }\n await new Promise((r) => setTimeout(r, backoffMs()));\n }\n this.continuousFetchLoopPromise = null;\n }\n async handleAdStart(_marker) {\n const adBreakDurationMs = _marker.durationSeconds != null ? _marker.durationSeconds * 1e3 : void 0;\n if (this.config.debugAdTiming) {\n const mode = this.isLiveStream ? \"LIVE\" : \"VOD\";\n console.log(\n `[CONTINUOUS-FETCH] \\u{1F4FA} ${mode} MODE: Target duration=${adBreakDurationMs}ms`\n );\n }\n this.consecutiveFailures = 0;\n this.continuousFetchingActive = true;\n this.continuousFetchLoopPromise = null;\n this.pendingNextAdBids = null;\n this.isShowingPlaceholder = false;\n this.totalAdRequestsInBreak = 0;\n const state = this.savedMutedStateBeforeScte ?? {\n muted: this.video.muted,\n volume: this.video.volume\n };\n this.adLayer.updateOriginalMutedState(state.muted, state.volume);\n this.savedMutedStateBeforeScte = null;\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Muted video in handleAdStart\");\n }\n }\n this.inAdBreak = true;\n this.currentAdBreakStartWallClockMs = Date.now();\n this.currentAdIndex = 0;\n this.totalAdsInBreak = 1;\n this.adPodQueue = [];\n this.showAds = true;\n this.showPlaceholderLayer();\n this.adLayer.showPlaceholder();\n if (this.expectedAdBreakDurationMs == null && adBreakDurationMs != null) {\n this.expectedAdBreakDurationMs = adBreakDurationMs;\n }\n this.clearPendingAdBreak();\n try {\n this.lastAdRequestTime = Date.now();\n const bids = await this.adRequest();\n if (!this.inAdBreak) return;\n if (bids.length > 0) {\n this.consecutiveFailures = 0;\n if (this.config.licenseKey) {\n sendAdLoadedTracking(this.config.licenseKey, {\n source: this.getAdSource(),\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n });\n }\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u2705 First ad request successful, starting playback\");\n }\n this.currentAdIndex++;\n await this.adLayer.playAd(bids);\n if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {\n this.scheduleAdStopCountdown(this.getRemainingAdMs());\n }\n const adVolume = state.muted ? 0 : state.volume;\n this.adLayer.setAdVolume(adVolume);\n } else {\n this.consecutiveFailures++;\n await this.showPlaceholderAndWaitForAds();\n }\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\"[CONTINUOUS-FETCH] \\u26A0\\uFE0F First ad request failed:\", error);\n }\n this.consecutiveFailures++;\n await this.showPlaceholderAndWaitForAds();\n }\n this.startContinuousFetchLoop();\n }\n stopContinuousFetching() {\n this.continuousFetchingActive = false;\n this.hidePlaceholderLayer();\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u{1F6D1} Stopping continuous ad fetching\");\n }\n }\n async tryNextAvailableAdWithRateLimit() {\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] \\u{1F6D1} Too many consecutive failures (${this.consecutiveFailures}), ending ad break gracefully`);\n }\n this.handleAdPodComplete();\n return;\n }\n const backoffMultiplier = Math.pow(2, this.consecutiveFailures);\n const backoffDelay = Math.min(this.backoffBaseMs * backoffMultiplier, this.maxBackoffMs);\n const effectiveMinInterval = this.minAdRequestIntervalMs + (this.consecutiveFailures > 0 ? backoffDelay : 0);\n const timeSinceLastRequest = Date.now() - this.lastAdRequestTime;\n if (timeSinceLastRequest < effectiveMinInterval) {\n const waitTime = effectiveMinInterval - timeSinceLastRequest;\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] \\u23F3 Rate limiting: waiting ${waitTime}ms before next request (backoff: ${this.consecutiveFailures} failures)`);\n }\n await new Promise((resolve) => setTimeout(resolve, waitTime));\n }\n return this.tryNextAvailableAd(0);\n }\n async tryNextAvailableAd(_retryCount = 0) {\n if (this.totalAdRequestsInBreak >= this.maxTotalAdRequestsPerBreak) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] \\u{1F6D1} Max ad requests per break (${this.maxTotalAdRequestsPerBreak}) reached`);\n }\n this.handleAdPodComplete();\n return;\n }\n const remaining = this.getRemainingAdMs();\n if (remaining <= 500 && this.expectedAdBreakDurationMs != null) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u23F9\\uFE0F No time remaining, ending ad break\");\n }\n this.handleAdPodComplete();\n return;\n }\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] \\u{1F6D1} Too many consecutive failures (${this.consecutiveFailures}), ending ad break`);\n }\n this.handleAdPodComplete();\n return;\n }\n try {\n this.lastAdRequestTime = Date.now();\n const bids = await this.adRequest();\n if (!this.inAdBreak) return;\n if (bids.length > 0) {\n this.consecutiveFailures = 0;\n this.currentAdIndex++;\n this.totalAdRequestsInBreak++;\n if (this.adLayer.isAdPlaying()) {\n this.pendingNextAdBids = bids;\n } else {\n if (this.config.licenseKey) {\n sendAdLoadedTracking(this.config.licenseKey, {\n source: this.getAdSource(),\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n });\n }\n await this.adLayer.playAd(bids);\n if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {\n this.scheduleAdStopCountdown(this.getRemainingAdMs());\n }\n this.adLayer.setAdVolume(\n this.adLayer.getOriginalMutedState() ? 0 : this.adLayer.getOriginalVolume()\n );\n }\n } else {\n this.consecutiveFailures++;\n await this.showPlaceholderAndWaitForAds();\n }\n } catch (error) {\n this.consecutiveFailures++;\n if (this.config.debugAdTiming) {\n console.warn(\"[CONTINUOUS-FETCH] tryNextAvailableAd request failed:\", error);\n }\n await this.showPlaceholderAndWaitForAds();\n }\n }\n async showPlaceholderAndWaitForAds() {\n const remaining = this.getRemainingAdMs();\n const waitTime = Math.min(this.maxPlaceholderDurationMs, remaining);\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u{1F6D1} Skipping placeholder - too many consecutive failures\");\n }\n this.handleAdPodComplete();\n return;\n }\n if (waitTime < 1e3) {\n this.handleAdPodComplete();\n return;\n }\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] \\u2B1B Showing placeholder for ${waitTime}ms while waiting for ad response`);\n }\n this.isShowingPlaceholder = true;\n this.adLayer.showPlaceholder();\n const checkInterval = 300;\n const maxChecks = Math.floor(waitTime / checkInterval);\n for (let i = 0; i < maxChecks; i++) {\n await new Promise((resolve) => setTimeout(resolve, checkInterval));\n if (!this.inAdBreak) return;\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u{1F6D1} Too many failures during placeholder wait\");\n }\n break;\n }\n if (this.pendingNextAdBids != null && this.pendingNextAdBids.length > 0) {\n const bids = this.pendingNextAdBids;\n this.pendingNextAdBids = null;\n this.isShowingPlaceholder = false;\n this.adLayer.hidePlaceholder();\n this.currentAdIndex++;\n try {\n await this.adLayer.playAd(bids);\n this.consecutiveFailures = 0;\n } catch {\n this.consecutiveFailures++;\n await this.tryNextAvailableAdWithRateLimit();\n }\n return;\n }\n if (this.adLayer.isAdPlaying()) {\n this.isShowingPlaceholder = false;\n this.adLayer.hidePlaceholder();\n return;\n }\n }\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u23F0 Placeholder timeout, ending ad break\");\n }\n this.isShowingPlaceholder = false;\n this.adLayer.hidePlaceholder();\n this.handleAdPodComplete();\n }\n onTimeUpdate(_currentTimeSec) {\n if (this.adLayer.isAdPlaying()) return;\n }\n scheduleAdStopCountdown(remainingMs) {\n this.clearAdStopTimer();\n const ms = Math.max(0, Math.floor(remainingMs));\n if (ms === 0) {\n this.ensureAdStoppedByTimer();\n return;\n }\n this.adStopTimerId = window.setTimeout(() => {\n this.ensureAdStoppedByTimer();\n }, ms);\n }\n clearAdStopTimer() {\n if (this.adStopTimerId != null) {\n clearTimeout(this.adStopTimerId);\n this.adStopTimerId = void 0;\n }\n }\n ensureAdStoppedByTimer() {\n if (!this.inAdBreak) return;\n this.adStopTimerId = void 0;\n const adPlaying = this.adLayer.isAdPlaying();\n const pendingAds = this.adPodQueue.length > 0;\n const checkIntervalMs = Math.max(\n 250,\n Math.floor(this.config.adBreakCheckIntervalMs ?? 1e3)\n );\n const maxExtensionMsConfig = this.config.maxAdBreakExtensionMs;\n const maxExtensionMs = typeof maxExtensionMsConfig === \"number\" && maxExtensionMsConfig > 0 ? maxExtensionMsConfig : 6e4;\n let elapsedSinceStartMs = 0;\n if (this.currentAdBreakStartWallClockMs != null) {\n elapsedSinceStartMs = Date.now() - this.currentAdBreakStartWallClockMs;\n }\n const expectedDurationMs = this.expectedAdBreakDurationMs ?? 0;\n const overrunMs = Math.max(0, elapsedSinceStartMs - expectedDurationMs);\n const shouldExtendAdBreak = (adPlaying || pendingAds || this.showAds) && overrunMs < maxExtensionMs;\n if (shouldExtendAdBreak) {\n this.scheduleAdStopCountdown(checkIntervalMs);\n return;\n }\n if (adPlaying) {\n this.adLayer.stop().catch(() => {\n });\n }\n this.handleAdPodComplete();\n }\n scheduleAdStartIn(delayMs) {\n this.clearAdStartTimer();\n const ms = Math.max(0, Math.floor(delayMs));\n if (ms === 0) {\n this.handleAdStart({ type: \"start\" }).catch(() => {\n });\n return;\n }\n this.adStartTimerId = window.setTimeout(() => {\n this.handleAdStart({ type: \"start\" }).catch(() => {\n });\n }, ms);\n }\n clearAdStartTimer() {\n if (this.adStartTimerId != null) {\n clearTimeout(this.adStartTimerId);\n this.adStartTimerId = void 0;\n }\n }\n updatePtsDrift(ptsSecondsSample) {\n const sampleMs = (this.video.currentTime - ptsSecondsSample) * 1e3;\n if (!Number.isFinite(sampleMs) || Math.abs(sampleMs) > 6e4) return;\n const alpha = 0.1;\n this.ptsDriftEmaMs = this.ptsDriftEmaMs * (1 - alpha) + sampleMs * alpha;\n }\n handleAdPodComplete() {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] \\u{1F3C1} Ad pod complete - cleaning up\");\n }\n this.clearAdRequestWatchdog();\n this.clearAdFailsafeTimer();\n this.activeAdRequestToken = null;\n this.stopContinuousFetching();\n this.clearPendingAdBreak();\n this.pendingNextAdBids = null;\n if (this.isShowingPlaceholder) {\n this.adLayer.hidePlaceholder();\n this.isShowingPlaceholder = false;\n }\n this.inAdBreak = false;\n this.expectedAdBreakDurationMs = void 0;\n this.currentAdBreakStartWallClockMs = void 0;\n this.clearAdStartTimer();\n this.clearAdStopTimer();\n this.adPodQueue = [];\n this.showAds = false;\n this.currentAdIndex = 0;\n this.totalAdsInBreak = 0;\n this.totalAdRequestsInBreak = 0;\n this.consecutiveFailures = 0;\n this.adLayer.stop().catch(() => {\n });\n const restoredMuted = this.adLayer.getOriginalMutedState();\n const restoredVolume = this.adLayer.getOriginalVolume();\n if (this.video.muted !== restoredMuted) {\n this.video.muted = restoredMuted;\n }\n if (Math.abs(this.video.volume - restoredVolume) > 0.01) {\n this.video.volume = restoredVolume;\n }\n const isTizen = detectBrowser().tizenVersion !== void 0;\n if (isTizen && this.hls) {\n this.hls.attachMedia(this.video);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Tizen: re-attached HLS to video element after ad break to restore audio\");\n }\n }\n if (this.shouldContinueLiveStreamDuringAds()) {\n if (this.config.debugAdTiming) {\n if (this.video.paused) {\n console.log(\"[StormcloudVideoPlayer] Content video paused in live mode after ads, resuming playback\");\n } else {\n console.log(\"[StormcloudVideoPlayer] Content video already playing in live mode after ads\");\n }\n }\n this.video.play()?.catch(() => {\n });\n } else if (this.video.paused) {\n this.video.play()?.catch(() => {\n });\n }\n if (isTizen && !restoredMuted) {\n requestAnimationFrame(() => {\n this.video.muted = false;\n this.video.volume = restoredVolume;\n });\n }\n }\n handleAdFailure() {\n this.consecutiveFailures++;\n if (this.config.debugAdTiming) {\n console.log(\n `[CONTINUOUS-FETCH] Ad failure: consecutiveFailures=${this.consecutiveFailures}`\n );\n }\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] \\u{1F6D1} Max consecutive failures reached (${this.consecutiveFailures}), ending ad break gracefully`);\n }\n this.handleAdPodComplete();\n }\n }\n startAdRequestWatchdog(token) {\n this.clearAdRequestWatchdog();\n const timeoutMs = this.config.adFailsafeTimeoutMs ?? 1e4;\n this.adRequestWatchdogToken = token;\n this.adRequestWatchdogId = window.setTimeout(() => {\n if (this.adRequestWatchdogToken !== token) {\n return;\n }\n this.adRequestWatchdogId = void 0;\n this.adRequestWatchdogToken = null;\n if (this.activeAdRequestToken === token) {\n this.activeAdRequestToken = null;\n }\n this.logAdState(\"ad_request_timeout\", { token, timeoutMs });\n this.handleAdFailure();\n }, timeoutMs);\n this.logAdState(\"ad_request_watchdog_started\", { token, timeoutMs });\n }\n clearAdRequestWatchdog() {\n if (this.adRequestWatchdogId != null) {\n clearTimeout(this.adRequestWatchdogId);\n this.adRequestWatchdogId = void 0;\n }\n if (this.adRequestWatchdogToken != null) {\n this.logAdState(\"ad_request_watchdog_cleared\", {\n token: this.adRequestWatchdogToken\n });\n this.adRequestWatchdogToken = null;\n }\n }\n startAdFailsafeTimer(token) {\n this.clearAdFailsafeTimer();\n const failsafeMs = this.config.adFailsafeTimeoutMs ?? 1e4;\n this.adFailsafeToken = token;\n this.adFailsafeTimerId = window.setTimeout(() => {\n if (this.adFailsafeToken !== token) {\n return;\n }\n this.adFailsafeTimerId = void 0;\n this.adFailsafeToken = null;\n if (this.activeAdRequestToken === token) {\n this.activeAdRequestToken = null;\n }\n this.logAdState(\"ad_failsafe_triggered\", {\n token,\n failsafeMs,\n videoPaused: this.video.paused,\n imaAdPlaying: this.adLayer.isAdPlaying()\n });\n this.handleAdFailure();\n }, failsafeMs);\n this.logAdState(\"ad_failsafe_started\", { token, failsafeMs });\n }\n clearAdFailsafeTimer() {\n if (this.adFailsafeTimerId != null) {\n clearTimeout(this.adFailsafeTimerId);\n this.logAdState(\"ad_failsafe_cleared\", { token: this.adFailsafeToken });\n this.adFailsafeTimerId = void 0;\n }\n this.adFailsafeToken = null;\n }\n logAdState(event, extra = {}) {\n if (!this.config.debugAdTiming) {\n return;\n }\n console.log(\"[StormcloudVideoPlayer][AdState]\", {\n event,\n timestamp: (/* @__PURE__ */ new Date()).toISOString(),\n showAds: this.showAds,\n adPlaying: this.adLayer.isAdPlaying(),\n inAdBreak: this.inAdBreak,\n activeAdRequestToken: this.activeAdRequestToken,\n ...extra\n });\n }\n getRemainingAdMs() {\n if (this.currentAdBreakStartWallClockMs == null) return 0;\n if (this.expectedAdBreakDurationMs == null) return Number.MAX_SAFE_INTEGER;\n const elapsed = Date.now() - this.currentAdBreakStartWallClockMs;\n return Math.max(0, this.expectedAdBreakDurationMs - elapsed);\n }\n toggleMute() {\n if (this.adLayer.isAdPlaying()) {\n const currentPerceptualState = this.isMuted();\n const newMutedState = !currentPerceptualState;\n this.adLayer.updateOriginalMutedState(newMutedState, this.video.volume);\n this.adLayer.setAdVolume(newMutedState ? 0 : this.adLayer.getOriginalVolume());\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Mute toggle during ad - immediately applied:\",\n newMutedState\n );\n }\n } else {\n this.video.muted = !this.video.muted;\n this.adLayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Muted:\", this.video.muted);\n }\n }\n }\n toggleFullscreen() {\n return new Promise((resolve, reject) => {\n if (!document.fullscreenElement) {\n const container = this.video.parentElement;\n if (!container) {\n reject(new Error(\"No parent container found for fullscreen\"));\n return;\n }\n container.requestFullscreen().then(() => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Entered fullscreen\");\n }\n resolve();\n }).catch((err) => {\n if (this.config.debugAdTiming) {\n console.error(\"[StormcloudVideoPlayer] Fullscreen error:\", err);\n }\n reject(err);\n });\n } else {\n document.exitFullscreen().then(() => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Exited fullscreen\");\n }\n resolve();\n }).catch((err) => {\n if (this.config.debugAdTiming) {\n console.error(\n \"[StormcloudVideoPlayer] Exit fullscreen error:\",\n err\n );\n }\n reject(err);\n });\n }\n });\n }\n isMuted() {\n if (this.adLayer.isAdPlaying()) {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] isMuted() override during ad playback -> false\"\n );\n }\n return false;\n }\n return this.video.muted;\n }\n setMuted(muted) {\n const adPlaying = this.adLayer.isAdPlaying();\n if (adPlaying && muted === this.video.muted) {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] setMuted reflective update during ad ignored\",\n { muted }\n );\n }\n return;\n }\n this.video.muted = muted;\n if (adPlaying) {\n this.adLayer.updateOriginalMutedState(muted, this.video.volume);\n this.adLayer.setAdVolume(muted ? 0 : this.adLayer.getOriginalVolume());\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] setMuted applied during ad\", {\n muted\n });\n }\n return;\n }\n this.adLayer.updateOriginalMutedState(muted, this.video.volume);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] setMuted called:\", muted);\n }\n }\n setVolume(volume) {\n const clampedVolume = Math.max(0, Math.min(1, volume));\n const adPlaying = this.adLayer.isAdPlaying();\n if (adPlaying) {\n this.adLayer.setAdVolume(clampedVolume);\n this.adLayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] setVolume applied during ad\", {\n volume: clampedVolume\n });\n }\n } else {\n this.video.volume = clampedVolume;\n this.video.muted = clampedVolume === 0;\n this.adLayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] setVolume called:\", clampedVolume);\n }\n }\n }\n getVolume() {\n const adPlaying = this.adLayer.isAdPlaying();\n if (adPlaying) {\n return this.adLayer.getAdVolume();\n }\n return this.video.volume;\n }\n isFullscreen() {\n return !!document.fullscreenElement;\n }\n isLive() {\n return this.isLiveStream;\n }\n get videoElement() {\n return this.video;\n }\n resize() {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Resizing player\");\n }\n if (this.adLayer && this.adLayer.isAdPlaying()) {\n const width = this.video.clientWidth || 640;\n const height = this.video.clientHeight || 480;\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Resizing ads manager to ${width}x${height}`\n );\n }\n this.adLayer.resize(width, height);\n }\n }\n destroy() {\n this.stopContinuousFetching();\n this.clearAdStartTimer();\n this.clearAdStopTimer();\n this.clearAdFailsafeTimer();\n this.clearAdRequestWatchdog();\n this.clearPendingAdBreak();\n if (this.placeholderContainer) {\n if (this.placeholderContainer.parentElement) {\n this.placeholderContainer.parentElement.removeChild(this.placeholderContainer);\n }\n this.placeholderContainer = void 0;\n }\n if (this.timeUpdateHandler) {\n this.video.removeEventListener(\"timeupdate\", this.timeUpdateHandler);\n delete this.timeUpdateHandler;\n }\n if (this.emptiedHandler) {\n this.video.removeEventListener(\"emptied\", this.emptiedHandler);\n delete this.emptiedHandler;\n }\n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval);\n this.heartbeatInterval = void 0;\n }\n this.hls?.destroy();\n this.adLayer?.destroy();\n this.consecutiveFailures = 0;\n }\n};\n\n// src/ui/StormcloudVideoPlayer.tsx\nvar import_fa = require(\"react-icons/fa\");\nvar import_jsx_runtime = require(\"react/jsx-runtime\");\nvar CRITICAL_PROPS = [\n \"src\",\n \"allowNativeHls\",\n \"licenseKey\",\n \"lowLatencyMode\",\n \"driftToleranceMs\"\n];\nvar StormcloudVideoPlayerComponent = import_react.default.memo(\n (props) => {\n const {\n src,\n autoplay,\n muted,\n lowLatencyMode,\n allowNativeHls,\n driftToleranceMs,\n immediateManifestAds,\n debugAdTiming,\n showCustomControls,\n hideLoadingIndicator,\n onVolumeToggle,\n onFullscreenToggle,\n onControlClick,\n onReady,\n wrapperClassName,\n wrapperStyle,\n className,\n style,\n controls,\n playsInline,\n preload,\n poster,\n children,\n licenseKey,\n minSegmentsBeforePlay,\n ...restVideoAttrs\n } = props;\n const videoRef = (0, import_react.useRef)(null);\n const playerRef = (0, import_react.useRef)(null);\n const bufferingTimeoutRef = (0, import_react.useRef)(null);\n const [adStatus, setAdStatus] = import_react.default.useState({ showAds: false, currentIndex: 0, totalAds: 0 });\n const [shouldShowNativeControls, setShouldShowNativeControls] = import_react.default.useState(true);\n const [isMuted, setIsMuted] = import_react.default.useState(false);\n const [isFullscreen, setIsFullscreen] = import_react.default.useState(false);\n const [isPlaying, setIsPlaying] = import_react.default.useState(false);\n const [currentTime, setCurrentTime] = import_react.default.useState(0);\n const [duration, setDuration] = import_react.default.useState(0);\n const [volume, setVolume] = import_react.default.useState(1);\n const [playbackRate, setPlaybackRate] = import_react.default.useState(1);\n const [showVolumeSlider, setShowVolumeSlider] = import_react.default.useState(false);\n const [showSpeedMenu, setShowSpeedMenu] = import_react.default.useState(false);\n const [isLoading, setIsLoading] = import_react.default.useState(true);\n const [isBuffering, setIsBuffering] = import_react.default.useState(false);\n const [showCenterPlay, setShowCenterPlay] = import_react.default.useState(false);\n const [showLicenseWarning, setShowLicenseWarning] = import_react.default.useState(false);\n const [viewportWidth, setViewportWidth] = import_react.default.useState(\n typeof window !== \"undefined\" ? window.innerWidth : 1920\n );\n const [isPortrait, setIsPortrait] = import_react.default.useState(\n typeof window !== \"undefined\" ? window.innerHeight > window.innerWidth : false\n );\n const getResponsiveScale = () => {\n if (viewportWidth < 480) return 0.7;\n if (viewportWidth < 768) return 0.8;\n if (viewportWidth < 1024) return 0.9;\n return 1;\n };\n const responsiveScale = getResponsiveScale();\n const formatTime = (seconds) => {\n if (!isFinite(seconds)) return \"0:00:00\";\n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor(seconds % 3600 / 60);\n const remainingSeconds = Math.floor(seconds % 60);\n return `${hours}:${minutes.toString().padStart(2, \"0\")}:${remainingSeconds.toString().padStart(2, \"0\")}`;\n };\n const handlePlayPause = () => {\n if (videoRef.current) {\n if (videoRef.current.paused) {\n const hasValidSource = videoRef.current.src || videoRef.current.currentSrc && videoRef.current.currentSrc !== \"\" || videoRef.current.readyState >= 1;\n if (hasValidSource) {\n videoRef.current.play()?.catch((error) => {\n console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n });\n setShowCenterPlay(false);\n } else {\n console.warn(\n \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n );\n }\n } else {\n videoRef.current.pause();\n setShowCenterPlay(true);\n }\n }\n };\n const handleCenterPlayClick = () => {\n if (videoRef.current && videoRef.current.paused) {\n const hasValidSource = videoRef.current.src || videoRef.current.currentSrc && videoRef.current.currentSrc !== \"\" || videoRef.current.readyState >= 1;\n if (hasValidSource) {\n videoRef.current.play()?.catch((error) => {\n console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n });\n setShowCenterPlay(false);\n } else {\n console.warn(\n \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n );\n }\n }\n };\n const handleTimelineSeek = (e) => {\n if (videoRef.current && duration > 0 && isFinite(duration)) {\n const rect = e.currentTarget.getBoundingClientRect();\n const clickX = e.clientX - rect.left;\n const progress = Math.max(0, Math.min(1, clickX / rect.width));\n const newTime = progress * duration;\n if (isFinite(newTime) && newTime >= 0 && newTime <= duration) {\n videoRef.current.currentTime = newTime;\n }\n }\n };\n const handleVolumeChange = (newVolume) => {\n if (playerRef.current && isFinite(newVolume)) {\n const clampedVolume = Math.max(0, Math.min(1, newVolume));\n playerRef.current.setVolume(clampedVolume);\n }\n };\n const handlePlaybackRateChange = (rate) => {\n if (videoRef.current && isFinite(rate) && rate > 0) {\n videoRef.current.playbackRate = rate;\n }\n setShowSpeedMenu(false);\n };\n const isHlsStream = src?.toLowerCase().includes(\".m3u8\") || src?.toLowerCase().includes(\"/hls/\");\n const shouldShowEnhancedControls = showCustomControls && (isHlsStream ? allowNativeHls : true);\n const criticalPropsKey = (0, import_react.useMemo)(() => {\n return CRITICAL_PROPS.map((prop) => `${prop}:${props[prop]}`).join(\"|\");\n }, [\n src,\n allowNativeHls,\n licenseKey,\n lowLatencyMode,\n driftToleranceMs\n ]);\n (0, import_react.useEffect)(() => {\n if (typeof window === \"undefined\") return;\n const el = videoRef.current;\n if (!el || !src) return;\n if (!licenseKey) {\n setShowLicenseWarning(true);\n setIsLoading(false);\n console.warn(\n \"StormcloudVideoPlayer: License key is required but not provided. Please set the licenseKey prop to use the player.\"\n );\n return;\n }\n setShowLicenseWarning(false);\n if (debugAdTiming) {\n console.log(\"[StormcloudUI] Initializing player, isLoading=true\");\n }\n if (playerRef.current) {\n try {\n playerRef.current.destroy();\n } catch {\n }\n playerRef.current = null;\n }\n const cfg = {\n src,\n videoElement: el\n };\n if (autoplay !== void 0) cfg.autoplay = autoplay;\n if (muted !== void 0) cfg.muted = muted;\n if (lowLatencyMode !== void 0) cfg.lowLatencyMode = lowLatencyMode;\n if (allowNativeHls !== void 0) cfg.allowNativeHls = allowNativeHls;\n if (driftToleranceMs !== void 0)\n cfg.driftToleranceMs = driftToleranceMs;\n if (immediateManifestAds !== void 0)\n cfg.immediateManifestAds = immediateManifestAds;\n if (debugAdTiming !== void 0) cfg.debugAdTiming = debugAdTiming;\n if (showCustomControls !== void 0)\n cfg.showCustomControls = showCustomControls;\n if (onVolumeToggle !== void 0) cfg.onVolumeToggle = onVolumeToggle;\n if (onFullscreenToggle !== void 0)\n cfg.onFullscreenToggle = onFullscreenToggle;\n if (onControlClick !== void 0) cfg.onControlClick = onControlClick;\n if (licenseKey !== void 0) cfg.licenseKey = licenseKey;\n if (minSegmentsBeforePlay !== void 0)\n cfg.minSegmentsBeforePlay = minSegmentsBeforePlay;\n const player = new StormcloudVideoPlayer(cfg);\n playerRef.current = player;\n player.load().then(() => {\n const showNative = player.shouldShowNativeControls();\n setShouldShowNativeControls(showNative);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Player loaded successfully, waiting for video ready\"\n );\n }\n onReady?.(player);\n }).catch((error) => {\n console.error(\n \"StormcloudVideoPlayer: Failed to load player:\",\n error\n );\n setIsLoading(false);\n onReady?.(player);\n });\n return () => {\n try {\n player.destroy();\n } catch {\n }\n playerRef.current = null;\n };\n }, [criticalPropsKey]);\n (0, import_react.useEffect)(() => {\n if (!playerRef.current) return;\n try {\n if (autoplay !== void 0 && playerRef.current.videoElement) {\n playerRef.current.videoElement.autoplay = autoplay;\n }\n if (muted !== void 0 && !playerRef.current.isShowingAds()) {\n playerRef.current.setMuted(muted);\n }\n } catch (error) {\n console.warn(\"Failed to update player properties:\", error);\n }\n }, [autoplay, muted]);\n (0, import_react.useEffect)(() => {\n if (!playerRef.current) return;\n const checkAdStatus = () => {\n if (playerRef.current) {\n const showAdsFromMethod = playerRef.current.isShowingAds();\n const showAdsFromAttribute = videoRef.current?.dataset?.stormcloudAdPlaying === \"true\";\n const showAds = showAdsFromMethod || showAdsFromAttribute;\n const currentIndex = playerRef.current.getCurrentAdIndex();\n const totalAds = playerRef.current.getTotalAdsInBreak();\n setAdStatus((prev) => {\n if (prev.showAds !== showAds || prev.currentIndex !== currentIndex || prev.totalAds !== totalAds) {\n if (showAds && !prev.showAds) {\n setShowCenterPlay(false);\n }\n return { showAds, currentIndex, totalAds };\n }\n return prev;\n });\n }\n };\n const interval = setInterval(checkAdStatus, 50);\n return () => clearInterval(interval);\n }, []);\n (0, import_react.useEffect)(() => {\n if (typeof window === \"undefined\" || !playerRef.current) return;\n const handleResize = () => {\n if (playerRef.current && videoRef.current) {\n if (typeof playerRef.current.resize === \"function\") {\n playerRef.current.resize();\n }\n }\n setViewportWidth(window.innerWidth);\n setIsPortrait(window.innerHeight > window.innerWidth);\n };\n window.addEventListener(\"resize\", handleResize);\n return () => window.removeEventListener(\"resize\", handleResize);\n }, []);\n (0, import_react.useEffect)(() => {\n if (!playerRef.current || !videoRef.current) return;\n const updateStates = () => {\n if (playerRef.current && videoRef.current) {\n setIsMuted(playerRef.current.isMuted());\n setIsPlaying(!videoRef.current.paused);\n const currentTimeValue = videoRef.current.currentTime;\n setCurrentTime(isFinite(currentTimeValue) ? currentTimeValue : 0);\n const durationValue = videoRef.current.duration;\n setDuration(isFinite(durationValue) ? durationValue : 0);\n const volumeValue = playerRef.current.getVolume();\n setVolume(\n isFinite(volumeValue) ? Math.max(0, Math.min(1, volumeValue)) : 1\n );\n const rateValue = videoRef.current.playbackRate;\n setPlaybackRate(\n isFinite(rateValue) && rateValue > 0 ? rateValue : 1\n );\n }\n setIsFullscreen(\n document.fullscreenElement === videoRef.current?.parentElement\n );\n };\n const interval = setInterval(updateStates, 200);\n const handleFullscreenChange = () => {\n setIsFullscreen(\n document.fullscreenElement === videoRef.current?.parentElement\n );\n };\n document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n return () => {\n clearInterval(interval);\n document.removeEventListener(\n \"fullscreenchange\",\n handleFullscreenChange\n );\n };\n }, []);\n (0, import_react.useEffect)(() => {\n if (!videoRef.current) return;\n const handleLoadedMetadata = () => {\n if (videoRef.current) {\n const video2 = videoRef.current;\n void video2.offsetHeight;\n }\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadedmetadata, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n const handleLoadedData = () => {\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadeddata, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n const handleLoadStart = () => {\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadstart, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n const handleCanPlay = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: canplay, readyState:\",\n videoRef.current?.readyState,\n \"- clearing loading state, isLoading=false\"\n );\n }\n };\n const handleCanPlayThrough = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: canplaythrough, readyState:\",\n videoRef.current?.readyState,\n \"- clearing loading state, isLoading=false\"\n );\n }\n };\n const handleWaiting = () => {\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n }\n bufferingTimeoutRef.current = window.setTimeout(() => {\n setIsBuffering(true);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video buffering detected (after 300ms delay), readyState:\",\n videoRef.current?.readyState,\n \"- showing spinner, isBuffering=true\"\n );\n }\n }, 300);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: waiting, readyState:\",\n videoRef.current?.readyState,\n \"- buffering delay started (300ms)\"\n );\n }\n };\n const handlePlaying = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n setShowCenterPlay(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: playing, readyState:\",\n videoRef.current?.readyState,\n \"- playback started, isLoading=false, isBuffering=false\"\n );\n }\n };\n const handlePause = () => {\n const isAdActive = playerRef.current?.isShowingAds() || videoRef.current?.dataset?.stormcloudAdPlaying === \"true\";\n if (playerRef.current && !isAdActive) {\n setShowCenterPlay(true);\n } else {\n setShowCenterPlay(false);\n }\n };\n const handleEnded = () => {\n setShowCenterPlay(true);\n };\n const video = videoRef.current;\n video.addEventListener(\"loadstart\", handleLoadStart);\n video.addEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.addEventListener(\"loadeddata\", handleLoadedData);\n video.addEventListener(\"canplay\", handleCanPlay);\n video.addEventListener(\"canplaythrough\", handleCanPlayThrough);\n video.addEventListener(\"waiting\", handleWaiting);\n video.addEventListener(\"playing\", handlePlaying);\n video.addEventListener(\"pause\", handlePause);\n video.addEventListener(\"ended\", handleEnded);\n if (video.paused) {\n setShowCenterPlay(true);\n }\n return () => {\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n video.removeEventListener(\"loadstart\", handleLoadStart);\n video.removeEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.removeEventListener(\"loadeddata\", handleLoadedData);\n video.removeEventListener(\"canplay\", handleCanPlay);\n video.removeEventListener(\"canplaythrough\", handleCanPlayThrough);\n video.removeEventListener(\"waiting\", handleWaiting);\n video.removeEventListener(\"playing\", handlePlaying);\n video.removeEventListener(\"pause\", handlePause);\n video.removeEventListener(\"ended\", handleEnded);\n };\n }, [debugAdTiming]);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"style\", { children: `\n @keyframes spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n }\n \n .stormcloud-loading-hidden .stormcloud-loading-indicator {\n display: none !important;\n }\n \n .stormcloud-video-wrapper:fullscreen {\n border-radius: 0 !important;\n box-shadow: none !important;\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n \n .stormcloud-video-wrapper:has(*:fullscreen) {\n border-radius: 0 !important;\n box-shadow: none !important;\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n \n *:fullscreen {\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n }\n ` }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n className: `stormcloud-video-wrapper ${wrapperClassName || \"\"}`,\n style: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n position: isFullscreen ? \"fixed\" : \"relative\",\n top: isFullscreen ? 0 : void 0,\n left: isFullscreen ? 0 : void 0,\n overflow: \"hidden\",\n width: isFullscreen ? \"100vw\" : \"100%\",\n height: isFullscreen ? \"100vh\" : \"auto\",\n minHeight: isFullscreen ? \"100vh\" : \"auto\",\n maxWidth: isFullscreen ? \"100vw\" : \"100%\",\n maxHeight: isFullscreen ? \"100vh\" : \"none\",\n zIndex: isFullscreen ? 999999 : void 0,\n backgroundColor: isFullscreen ? \"#000\" : void 0,\n borderRadius: isFullscreen ? 0 : void 0,\n boxShadow: isFullscreen ? \"none\" : void 0,\n ...wrapperStyle\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"video\",\n {\n ref: videoRef,\n className,\n style: {\n display: \"block\",\n width: \"100%\",\n height: isFullscreen ? \"100%\" : \"auto\",\n maxWidth: \"100%\",\n maxHeight: isFullscreen ? \"100%\" : \"none\",\n objectFit: isFullscreen ? \"cover\" : \"contain\",\n backgroundColor: \"#000\",\n aspectRatio: isFullscreen ? \"unset\" : void 0,\n ...style\n },\n controls: shouldShowNativeControls && controls && !showCustomControls,\n playsInline,\n preload,\n poster,\n ...restVideoAttrs,\n children\n }\n ),\n (isLoading || isBuffering) && !hideLoadingIndicator && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaSpinner,\n {\n className: \"stormcloud-loading-indicator\",\n size: 42,\n color: \"white\",\n style: {\n position: \"absolute\",\n top: \"calc(50% - 21px)\",\n left: \"calc(50% - 21px)\",\n zIndex: 20,\n animation: \"spin 1s linear infinite\",\n filter: \"drop-shadow(0 3px 6px rgba(0, 0, 0, 0.8))\"\n }\n }\n ),\n showLicenseWarning && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n zIndex: 25,\n background: \"linear-gradient(135deg, rgba(220, 38, 38, 0.95) 0%, rgba(185, 28, 28, 0.9) 100%)\",\n color: \"white\",\n padding: \"24px 32px\",\n borderRadius: \"16px\",\n backdropFilter: \"blur(20px)\",\n border: \"2px solid rgba(255, 255, 255, 0.2)\",\n boxShadow: \"0 20px 60px rgba(0, 0, 0, 0.6), inset 0 2px 0 rgba(255, 255, 255, 0.2)\",\n textAlign: \"center\",\n maxWidth: \"400px\",\n margin: \"0 16px\"\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n fontSize: \"20px\",\n fontWeight: \"bold\",\n marginBottom: \"12px\",\n color: \"#ffffff\",\n textShadow: \"0 2px 4px rgba(0, 0, 0, 0.5)\"\n },\n children: \"License Key Required\"\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n fontSize: \"14px\",\n lineHeight: \"1.5\",\n color: \"rgba(255, 255, 255, 0.9)\",\n textShadow: \"0 1px 2px rgba(0, 0, 0, 0.3)\"\n },\n children: [\n \"Please provide a valid license key to use the Stormcloud Video Player.\",\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"br\", {}),\n \"Contact your administrator for licensing information.\"\n ]\n }\n )\n ]\n }\n ),\n showCenterPlay && !isLoading && !isBuffering && !showLicenseWarning && !adStatus.showAds && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n onClick: handleCenterPlayClick,\n style: {\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n zIndex: 15,\n cursor: \"pointer\",\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.8) 100%)\",\n borderRadius: \"50%\",\n width: \"100px\",\n height: \"100px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n border: \"3px solid rgba(255, 255, 255, 0.8)\",\n boxShadow: \"0 12px 40px rgba(0, 0, 0, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\"\n },\n onMouseEnter: (e) => {\n const target = e.currentTarget;\n target.style.transform = \"translate(-50%, -50%)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.95) 0%, rgba(40, 40, 40, 0.9) 100%)\";\n target.style.boxShadow = \"0 16px 48px rgba(0, 0, 0, 0.9), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.borderColor = \"rgba(255, 255, 255, 0.9)\";\n },\n onMouseLeave: (e) => {\n const target = e.currentTarget;\n target.style.transform = \"translate(-50%, -50%)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.8) 100%)\";\n target.style.boxShadow = \"0 12px 40px rgba(0, 0, 0, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.3)\";\n target.style.borderColor = \"rgba(255, 255, 255, 0.8)\";\n },\n title: \"Play\",\n children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaPlay,\n {\n size: 36,\n color: \"white\",\n style: {\n marginLeft: \"6px\",\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\"\n }\n }\n )\n }\n ),\n shouldShowEnhancedControls && !showLicenseWarning ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: 0,\n left: 0,\n right: 0,\n background: \"linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.8) 100%)\",\n padding: \"20px 16px 16px\",\n zIndex: 10\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n width: \"100%\",\n height: \"8px\",\n background: \"linear-gradient(90deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0.1) 100%)\",\n borderRadius: \"8px\",\n marginBottom: \"16px\",\n cursor: \"pointer\",\n position: \"relative\",\n backdropFilter: \"blur(5px)\",\n border: \"1px solid rgba(255, 255, 255, 0.1)\",\n boxShadow: \"inset 0 2px 4px rgba(0, 0, 0, 0.2)\"\n },\n onClick: handleTimelineSeek,\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n height: \"100%\",\n background: \"linear-gradient(90deg, rgba(139, 92, 246, 0.9) 0%, rgba(59, 130, 246, 0.8) 50%, rgba(34, 197, 94, 0.9) 100%)\",\n borderRadius: \"8px\",\n width: `${duration > 0 ? currentTime / duration * 100 : 0}%`,\n transition: \"width 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 2px 8px rgba(139, 92, 246, 0.4)\"\n }\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n top: \"-6px\",\n right: `${duration > 0 ? 100 - currentTime / duration * 100 : 100}%`,\n width: \"20px\",\n height: \"20px\",\n background: \"linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(240, 240, 240, 0.9) 100%)\",\n borderRadius: \"50%\",\n border: \"3px solid rgba(139, 92, 246, 0.8)\",\n boxShadow: \"0 4px 16px rgba(139, 92, 246, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.8)\",\n transform: \"translateX(50%)\",\n transition: \"all 0.2s cubic-bezier(0.4, 0, 0.2, 1)\"\n }\n }\n )\n ]\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n color: \"white\",\n flexWrap: viewportWidth < 768 ? \"wrap\" : \"nowrap\",\n gap: `${8 * responsiveScale}px`\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n display: \"flex\",\n alignItems: \"center\",\n gap: `${12 * responsiveScale}px`,\n flexWrap: viewportWidth < 480 ? \"wrap\" : \"nowrap\"\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"button\",\n {\n onClick: handlePlayPause,\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n backdropFilter: \"blur(12px)\",\n border: `${2 * responsiveScale}px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${10 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 8px 32px rgba(0, 0, 0, 0.4), 0 4px 16px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n minWidth: `${48 * responsiveScale}px`,\n minHeight: `${48 * responsiveScale}px`\n },\n onMouseEnter: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n target.style.boxShadow = \"0 12px 48px rgba(0, 0, 0, 0.6), 0 6px 24px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n },\n onMouseLeave: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n target.style.boxShadow = \"0 8px 32px rgba(0, 0, 0, 0.4), 0 4px 16px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n },\n title: isPlaying ? \"Pause\" : \"Play\",\n children: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaPause,\n {\n size: Math.max(16, 20 * responsiveScale),\n style: { filter: \"drop-shadow(0 0 0 transparent)\" }\n }\n ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaPlay,\n {\n size: Math.max(16, 20 * responsiveScale),\n style: { filter: \"drop-shadow(0 0 0 transparent)\" }\n }\n )\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n padding: \"8px\",\n margin: \"-8px\"\n },\n onMouseEnter: () => setShowVolumeSlider(true),\n onMouseLeave: () => setShowVolumeSlider(false),\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"button\",\n {\n onClick: () => {\n if (playerRef.current) {\n playerRef.current.toggleMute();\n }\n if (onVolumeToggle) {\n onVolumeToggle();\n }\n },\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${2 * responsiveScale}px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${44 * responsiveScale}px`,\n minHeight: `${44 * responsiveScale}px`\n },\n onMouseEnter: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow = \"0 10px 36px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n },\n onMouseLeave: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow = \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n },\n title: isMuted ? \"Unmute\" : \"Mute\",\n children: isMuted || volume === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaVolumeMute,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 0 0 transparent)\"\n }\n }\n ) : volume < 0.5 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaVolumeDown,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 0 0 transparent)\"\n }\n }\n ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaVolumeUp,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 0 0 transparent)\"\n }\n }\n )\n }\n ),\n showVolumeSlider && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"60px\",\n height: \"20px\",\n marginBottom: \"-16px\",\n zIndex: 9\n },\n onMouseEnter: () => setShowVolumeSlider(true),\n onMouseLeave: () => setShowVolumeSlider(false)\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: \"4px\",\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.88) 0%, rgba(20, 20, 20, 0.92) 100%)\",\n backdropFilter: \"blur(15px)\",\n padding: \"10px 14px\",\n borderRadius: \"14px\",\n border: \"1px solid rgba(255, 255, 255, 0.15)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"128px\",\n boxShadow: \"0 12px 40px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15)\",\n zIndex: 10,\n transition: \"transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, border-color 0.2s ease-in-out\"\n },\n onMouseEnter: (e) => {\n setShowVolumeSlider(true);\n e.currentTarget.style.boxShadow = \"0 16px 48px rgba(0, 0, 0, 0.6), 0 6px 16px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 0 24px rgba(59, 130, 246, 0.3)\";\n e.currentTarget.style.borderColor = \"rgba(59, 130, 246, 0.4)\";\n },\n onMouseLeave: (e) => {\n setShowVolumeSlider(false);\n e.currentTarget.style.boxShadow = \"0 12px 40px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15)\";\n e.currentTarget.style.borderColor = \"rgba(255, 255, 255, 0.15)\";\n },\n children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"relative\",\n width: \"8px\",\n height: \"104px\",\n cursor: \"pointer\",\n transition: \"transform 0.2s ease-in-out\"\n },\n onMouseEnter: (e) => {\n },\n onMouseLeave: (e) => {\n },\n onMouseDown: (e) => {\n e.preventDefault();\n const sliderElement = e.currentTarget;\n const handleMouseMove = (moveEvent) => {\n if (!sliderElement) return;\n const rect2 = sliderElement.getBoundingClientRect();\n const y2 = moveEvent.clientY - rect2.top;\n const percentage2 = 1 - Math.max(0, Math.min(1, y2 / rect2.height));\n handleVolumeChange(percentage2);\n };\n const handleMouseUp = () => {\n document.removeEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.removeEventListener(\n \"mouseup\",\n handleMouseUp\n );\n };\n document.addEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.addEventListener(\n \"mouseup\",\n handleMouseUp\n );\n const rect = sliderElement.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage = 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n },\n onClick: (e) => {\n e.stopPropagation();\n const rect = e.currentTarget.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage = 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: \"100%\",\n background: \"linear-gradient(180deg, rgba(255, 255, 255, 0.4) 0%, rgba(255, 255, 255, 0.15) 100%)\",\n borderRadius: \"4px\",\n boxShadow: \"inset 0 1px 3px rgba(0, 0, 0, 0.2)\"\n }\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: `${(isMuted ? 0 : volume) * 100}%`,\n background: \"linear-gradient(180deg, rgba(96, 165, 250, 1) 0%, rgba(59, 130, 246, 0.95) 50%, rgba(37, 99, 235, 0.9) 100%)\",\n borderRadius: \"4px\",\n transition: \"height 0.15s ease-out, box-shadow 0.2s ease-in-out\",\n boxShadow: \"0 0 8px rgba(59, 130, 246, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.3)\"\n }\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: `calc(${(isMuted ? 0 : volume) * 100}% - 7px)`,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"14px\",\n height: \"14px\",\n background: \"linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)\",\n borderRadius: \"50%\",\n boxShadow: \"0 2px 6px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(59, 130, 246, 0.3), 0 0 12px rgba(59, 130, 246, 0.4)\",\n transition: \"bottom 0.15s ease-out, transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, width 0.2s ease-in-out, height 0.2s ease-in-out\",\n cursor: \"grab\"\n },\n onMouseEnter: (e) => {\n e.currentTarget.style.boxShadow = \"0 3px 10px rgba(0, 0, 0, 0.4), 0 0 0 3px rgba(59, 130, 246, 0.5), 0 0 20px rgba(59, 130, 246, 0.6)\";\n e.currentTarget.style.cursor = \"grab\";\n },\n onMouseLeave: (e) => {\n e.currentTarget.style.boxShadow = \"0 2px 6px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(59, 130, 246, 0.3), 0 0 12px rgba(59, 130, 246, 0.4)\";\n },\n onMouseDown: (e) => {\n e.currentTarget.style.cursor = \"grabbing\";\n },\n onMouseUp: (e) => {\n e.currentTarget.style.cursor = \"grab\";\n }\n }\n )\n ]\n }\n )\n }\n )\n ] })\n ]\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n fontSize: `${14 * responsiveScale}px`,\n fontFamily: \"monospace\",\n color: \"rgba(255, 255, 255, 0.9)\",\n display: viewportWidth < 480 ? \"none\" : \"block\"\n },\n children: [\n formatTime(currentTime),\n \" / \",\n formatTime(duration)\n ]\n }\n )\n ]\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n display: \"flex\",\n alignItems: \"center\",\n gap: `${12 * responsiveScale}px`\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"relative\",\n display: viewportWidth < 600 ? \"none\" : \"block\"\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"button\",\n {\n onClick: () => setShowSpeedMenu(!showSpeedMenu),\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${2 * responsiveScale}px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px ${14 * responsiveScale}px`,\n borderRadius: `${14 * responsiveScale}px`,\n fontSize: `${14 * responsiveScale}px`,\n fontFamily: \"monospace\",\n fontWeight: \"700\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 6px 24px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${56 * responsiveScale}px`,\n minHeight: `${40 * responsiveScale}px`\n },\n onMouseEnter: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow = \"0 10px 32px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n },\n onMouseLeave: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow = \"0 6px 24px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n },\n title: \"Playback Speed\",\n children: [\n playbackRate,\n \"x\"\n ]\n }\n ),\n showSpeedMenu && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"100%\",\n right: 0,\n marginBottom: \"12px\",\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.95) 100%)\",\n backdropFilter: \"blur(20px)\",\n borderRadius: \"12px\",\n border: \"1px solid rgba(255, 255, 255, 0.1)\",\n overflow: \"hidden\",\n minWidth: \"90px\",\n boxShadow: \"0 16px 48px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.1)\"\n },\n children: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2].map(\n (speed) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"button\",\n {\n onClick: () => handlePlaybackRateChange(speed),\n style: {\n display: \"block\",\n width: \"100%\",\n padding: \"10px 16px\",\n background: playbackRate === speed ? \"linear-gradient(135deg, rgba(99, 102, 241, 0.8) 0%, rgba(139, 92, 246, 0.6) 100%)\" : \"transparent\",\n border: \"none\",\n color: \"white\",\n cursor: \"pointer\",\n fontSize: \"13px\",\n fontFamily: \"monospace\",\n fontWeight: \"600\",\n textAlign: \"center\",\n transition: \"all 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n borderBottom: speed !== 2 ? \"1px solid rgba(255, 255, 255, 0.05)\" : \"none\"\n },\n onMouseEnter: (e) => {\n if (playbackRate !== speed) {\n e.target.style.background = \"linear-gradient(135deg, rgba(255, 255, 255, 0.15) 0%, rgba(255, 255, 255, 0.05) 100%)\";\n }\n },\n onMouseLeave: (e) => {\n if (playbackRate !== speed) {\n e.target.style.background = \"transparent\";\n }\n },\n children: [\n speed,\n \"x\"\n ]\n },\n speed\n )\n )\n }\n )\n ]\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"button\",\n {\n onClick: () => {\n if (onFullscreenToggle) {\n onFullscreenToggle();\n } else if (playerRef.current) {\n playerRef.current.toggleFullscreen().catch((err) => {\n console.error(\"Fullscreen error:\", err);\n });\n }\n },\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${2 * responsiveScale}px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${44 * responsiveScale}px`,\n minHeight: `${44 * responsiveScale}px`\n },\n onMouseEnter: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow = \"0 10px 36px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n },\n onMouseLeave: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow = \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n },\n title: isFullscreen ? \"Exit Fullscreen\" : \"Enter Fullscreen\",\n children: isFullscreen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaCompress,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: { filter: \"drop-shadow(0 0 0 transparent)\" }\n }\n ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaExpand,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: { filter: \"drop-shadow(0 0 0 transparent)\" }\n }\n )\n }\n )\n ]\n }\n )\n ]\n }\n )\n ]\n }\n ) }) : showCustomControls && !showLicenseWarning && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: `${10 * responsiveScale}px`,\n right: `${10 * responsiveScale}px`,\n transform: \"none\",\n display: \"flex\",\n flexDirection: isPortrait ? \"column\" : \"row\",\n gap: `${10 * responsiveScale}px`,\n zIndex: 10\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n padding: \"8px\",\n margin: \"-8px\"\n },\n onMouseEnter: () => setShowVolumeSlider(true),\n onMouseLeave: () => setShowVolumeSlider(false),\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"button\",\n {\n onClick: () => {\n if (playerRef.current) {\n playerRef.current.toggleMute();\n }\n if (onVolumeToggle) {\n onVolumeToggle();\n }\n },\n onMouseEnter: (e) => {\n const target = e.currentTarget;\n target.style.boxShadow = \"0 14px 48px rgba(0, 0, 0, 0.7), 0 0 0 3px rgba(255, 255, 255, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n },\n onMouseLeave: (e) => {\n const target = e.currentTarget;\n target.style.boxShadow = \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n },\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n color: \"#ffffff\",\n border: \"none\",\n borderRadius: `${18 * responsiveScale}px`,\n padding: `${8 * responsiveScale}px`,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n boxShadow: \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.4s cubic-bezier(0.4, 0, 0.2, 1)\",\n minWidth: `${46 * responsiveScale}px`,\n minHeight: `${46 * responsiveScale}px`\n },\n title: isMuted ? \"Unmute\" : \"Mute\",\n children: isMuted || volume === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaVolumeMute,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\"\n }\n }\n ) : volume < 0.5 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaVolumeDown,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\"\n }\n }\n ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaVolumeUp,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\"\n }\n }\n )\n }\n ),\n showVolumeSlider && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"60px\",\n height: \"20px\",\n marginBottom: \"-16px\",\n zIndex: 9\n },\n onMouseEnter: () => setShowVolumeSlider(true),\n onMouseLeave: () => setShowVolumeSlider(false)\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: \"4px\",\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.96) 0%, rgba(20, 20, 20, 0.92) 100%)\",\n backdropFilter: \"blur(20px)\",\n padding: \"10px 14px\",\n borderRadius: \"14px\",\n border: \"2px solid rgba(255, 255, 255, 0.7)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"128px\",\n boxShadow: \"0 12px 40px rgba(0, 0, 0, 0.85), 0 4px 12px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.35)\",\n zIndex: 10,\n transition: \"transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, border-color 0.2s ease-in-out\"\n },\n onMouseEnter: (e) => {\n setShowVolumeSlider(true);\n e.currentTarget.style.boxShadow = \"0 16px 48px rgba(0, 0, 0, 0.9), 0 6px 16px rgba(0, 0, 0, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 0 24px rgba(96, 165, 250, 0.4)\";\n e.currentTarget.style.borderColor = \"rgba(96, 165, 250, 0.8)\";\n },\n onMouseLeave: (e) => {\n setShowVolumeSlider(false);\n e.currentTarget.style.boxShadow = \"0 12px 40px rgba(0, 0, 0, 0.85), 0 4px 12px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.35)\";\n e.currentTarget.style.borderColor = \"rgba(255, 255, 255, 0.7)\";\n },\n children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"relative\",\n width: \"8px\",\n height: \"104px\",\n cursor: \"pointer\",\n transition: \"transform 0.2s ease-in-out\"\n },\n onMouseDown: (e) => {\n e.preventDefault();\n const sliderElement = e.currentTarget;\n const handleMouseMove = (moveEvent) => {\n if (!sliderElement) return;\n const rect2 = sliderElement.getBoundingClientRect();\n const y2 = moveEvent.clientY - rect2.top;\n const percentage2 = 1 - Math.max(0, Math.min(1, y2 / rect2.height));\n handleVolumeChange(percentage2);\n };\n const handleMouseUp = () => {\n document.removeEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.removeEventListener(\n \"mouseup\",\n handleMouseUp\n );\n };\n document.addEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.addEventListener(\n \"mouseup\",\n handleMouseUp\n );\n const rect = sliderElement.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage = 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n },\n onClick: (e) => {\n e.stopPropagation();\n const rect = e.currentTarget.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage = 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: \"100%\",\n background: \"linear-gradient(180deg, rgba(255, 255, 255, 0.85) 0%, rgba(255, 255, 255, 0.5) 100%)\",\n borderRadius: \"4px\",\n border: \"1px solid rgba(255, 255, 255, 0.4)\",\n boxShadow: \"inset 0 1px 3px rgba(0, 0, 0, 0.3)\"\n }\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: `${(isMuted ? 0 : volume) * 100}%`,\n background: \"linear-gradient(180deg, rgba(125, 211, 252, 1) 0%, rgba(96, 165, 250, 0.98) 50%, rgba(59, 130, 246, 0.95) 100%)\",\n borderRadius: \"4px\",\n transition: \"height 0.15s ease-out, box-shadow 0.2s ease-in-out\",\n boxShadow: \"0 0 12px rgba(96, 165, 250, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.4)\"\n }\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: `calc(${(isMuted ? 0 : volume) * 100}% - 8px)`,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"16px\",\n height: \"16px\",\n background: \"linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)\",\n borderRadius: \"50%\",\n border: \"2px solid rgba(96, 165, 250, 0.9)\",\n boxShadow: \"0 3px 8px rgba(0, 0, 0, 0.5), 0 0 0 2px rgba(96, 165, 250, 0.4), 0 0 16px rgba(96, 165, 250, 0.5)\",\n transition: \"bottom 0.15s ease-out, transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, width 0.2s ease-in-out, height 0.2s ease-in-out\",\n cursor: \"grab\"\n },\n onMouseEnter: (e) => {\n e.currentTarget.style.boxShadow = \"0 4px 12px rgba(0, 0, 0, 0.6), 0 0 0 3px rgba(96, 165, 250, 0.6), 0 0 24px rgba(96, 165, 250, 0.7)\";\n e.currentTarget.style.cursor = \"grab\";\n },\n onMouseLeave: (e) => {\n e.currentTarget.style.boxShadow = \"0 3px 8px rgba(0, 0, 0, 0.5), 0 0 0 2px rgba(96, 165, 250, 0.4), 0 0 16px rgba(96, 165, 250, 0.5)\";\n },\n onMouseDown: (e) => {\n e.currentTarget.style.cursor = \"grabbing\";\n },\n onMouseUp: (e) => {\n e.currentTarget.style.cursor = \"grab\";\n }\n }\n )\n ]\n }\n )\n }\n )\n ] })\n ]\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"button\",\n {\n onClick: () => {\n if (onFullscreenToggle) {\n onFullscreenToggle();\n } else if (playerRef.current) {\n playerRef.current.toggleFullscreen().catch((err) => {\n console.error(\"Fullscreen error:\", err);\n });\n }\n },\n onMouseEnter: (e) => {\n const target = e.currentTarget;\n target.style.boxShadow = \"0 14px 48px rgba(0, 0, 0, 0.7), 0 0 0 3px rgba(255, 255, 255, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n },\n onMouseLeave: (e) => {\n const target = e.currentTarget;\n target.style.boxShadow = \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n },\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n color: \"#ffffff\",\n border: \"none\",\n borderRadius: `${18 * responsiveScale}px`,\n padding: `${8 * responsiveScale}px`,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n boxShadow: \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.4s cubic-bezier(0.4, 0, 0.2, 1)\",\n minWidth: `${46 * responsiveScale}px`,\n minHeight: `${46 * responsiveScale}px`\n },\n title: isFullscreen ? \"Exit Fullscreen\" : \"Enter Fullscreen\",\n children: isFullscreen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaCompress,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\"\n }\n }\n ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaExpand,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\"\n }\n }\n )\n }\n )\n ]\n }\n ),\n onControlClick && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n onClick: onControlClick,\n style: {\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 1,\n cursor: \"pointer\"\n }\n }\n )\n ]\n }\n )\n ] });\n },\n (prevProps, nextProps) => {\n for (const prop of CRITICAL_PROPS) {\n if (prevProps[prop] !== nextProps[prop]) {\n return false;\n }\n }\n const uiProps = [\n \"autoplay\",\n \"muted\",\n \"controls\",\n \"showCustomControls\",\n \"className\",\n \"style\",\n \"wrapperClassName\",\n \"wrapperStyle\",\n \"playsInline\",\n \"preload\",\n \"poster\",\n \"children\"\n ];\n for (const prop of uiProps) {\n if (prevProps[prop] !== nextProps[prop]) {\n return false;\n }\n }\n const callbackProps = [\n \"onReady\",\n \"onVolumeToggle\",\n \"onFullscreenToggle\",\n \"onControlClick\"\n ];\n for (const prop of callbackProps) {\n if (prevProps[prop] !== nextProps[prop]) {\n return false;\n }\n }\n return true;\n }\n);\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n StormcloudVideoPlayerComponent\n});\n","import React, { useEffect, useRef, useMemo } from \"react\";\nimport { StormcloudVideoPlayer } from \"../player/StormcloudVideoPlayer\";\nimport type { StormcloudVideoPlayerConfig } from \"../types\";\nimport {\n FaPlay,\n FaPause,\n FaVolumeUp,\n FaVolumeMute,\n FaVolumeDown,\n FaExpand,\n FaCompress,\n FaSpinner,\n} from \"react-icons/fa\";\n\nexport type StormcloudVideoPlayerProps = Omit<\n StormcloudVideoPlayerConfig,\n \"videoElement\"\n> &\n React.VideoHTMLAttributes<HTMLVideoElement> & {\n onReady?: (player: StormcloudVideoPlayer) => void;\n wrapperClassName?: string;\n wrapperStyle?: React.CSSProperties;\n licenseKey?: string;\n };\n\nconst CRITICAL_PROPS = [\n \"src\",\n \"allowNativeHls\",\n \"licenseKey\",\n \"lowLatencyMode\",\n \"driftToleranceMs\",\n] as const;\n\nexport const StormcloudVideoPlayerComponent: React.FC<StormcloudVideoPlayerProps> =\n React.memo(\n (props) => {\n const {\n src,\n autoplay,\n muted,\n lowLatencyMode,\n allowNativeHls,\n driftToleranceMs,\n immediateManifestAds,\n debugAdTiming,\n showCustomControls,\n hideLoadingIndicator,\n onVolumeToggle,\n onFullscreenToggle,\n onControlClick,\n onReady,\n wrapperClassName,\n wrapperStyle,\n className,\n style,\n controls,\n playsInline,\n preload,\n poster,\n children,\n licenseKey,\n minSegmentsBeforePlay,\n ...restVideoAttrs\n } = props;\n\n const videoRef = useRef<HTMLVideoElement | null>(null);\n const playerRef = useRef<StormcloudVideoPlayer | null>(null);\n const bufferingTimeoutRef = useRef<number | null>(null);\n const [adStatus, setAdStatus] = React.useState<{\n showAds: boolean;\n currentIndex: number;\n totalAds: number;\n }>({ showAds: false, currentIndex: 0, totalAds: 0 });\n\n const [shouldShowNativeControls, setShouldShowNativeControls] =\n React.useState(true);\n\n const [isMuted, setIsMuted] = React.useState(false);\n const [isFullscreen, setIsFullscreen] = React.useState(false);\n const [isPlaying, setIsPlaying] = React.useState(false);\n const [currentTime, setCurrentTime] = React.useState(0);\n const [duration, setDuration] = React.useState(0);\n const [volume, setVolume] = React.useState(1);\n const [playbackRate, setPlaybackRate] = React.useState(1);\n const [showVolumeSlider, setShowVolumeSlider] = React.useState(false);\n const [showSpeedMenu, setShowSpeedMenu] = React.useState(false);\n const [isLoading, setIsLoading] = React.useState(true);\n const [isBuffering, setIsBuffering] = React.useState(false);\n const [showCenterPlay, setShowCenterPlay] = React.useState(false);\n const [showLicenseWarning, setShowLicenseWarning] = React.useState(false);\n const [viewportWidth, setViewportWidth] = React.useState(\n typeof window !== \"undefined\" ? window.innerWidth : 1920\n );\n const [isPortrait, setIsPortrait] = React.useState(\n typeof window !== \"undefined\"\n ? window.innerHeight > window.innerWidth\n : false\n );\n\n const getResponsiveScale = () => {\n if (viewportWidth < 480) return 0.7;\n if (viewportWidth < 768) return 0.8;\n if (viewportWidth < 1024) return 0.9;\n return 1;\n };\n\n const responsiveScale = getResponsiveScale();\n\n const formatTime = (seconds: number): string => {\n if (!isFinite(seconds)) return \"0:00:00\";\n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n const remainingSeconds = Math.floor(seconds % 60);\n return `${hours}:${minutes\n .toString()\n .padStart(2, \"0\")}:${remainingSeconds.toString().padStart(2, \"0\")}`;\n };\n\n const handlePlayPause = () => {\n if (videoRef.current) {\n if (videoRef.current.paused) {\n const hasValidSource =\n videoRef.current.src ||\n (videoRef.current.currentSrc &&\n videoRef.current.currentSrc !== \"\") ||\n videoRef.current.readyState >= 1;\n\n if (hasValidSource) {\n videoRef.current.play()?.catch((error) => {\n console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n });\n setShowCenterPlay(false);\n } else {\n console.warn(\n \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n );\n }\n } else {\n videoRef.current.pause();\n setShowCenterPlay(true);\n }\n }\n };\n\n const handleCenterPlayClick = () => {\n if (videoRef.current && videoRef.current.paused) {\n const hasValidSource =\n videoRef.current.src ||\n (videoRef.current.currentSrc &&\n videoRef.current.currentSrc !== \"\") ||\n videoRef.current.readyState >= 1;\n\n if (hasValidSource) {\n videoRef.current.play()?.catch((error) => {\n console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n });\n setShowCenterPlay(false);\n } else {\n console.warn(\n \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n );\n }\n }\n };\n\n const handleTimelineSeek = (e: React.MouseEvent<HTMLDivElement>) => {\n if (videoRef.current && duration > 0 && isFinite(duration)) {\n const rect = e.currentTarget.getBoundingClientRect();\n const clickX = e.clientX - rect.left;\n const progress = Math.max(0, Math.min(1, clickX / rect.width));\n const newTime = progress * duration;\n\n if (isFinite(newTime) && newTime >= 0 && newTime <= duration) {\n videoRef.current.currentTime = newTime;\n }\n }\n };\n\n const handleVolumeChange = (newVolume: number) => {\n if (playerRef.current && isFinite(newVolume)) {\n const clampedVolume = Math.max(0, Math.min(1, newVolume));\n playerRef.current.setVolume(clampedVolume);\n }\n };\n\n const handlePlaybackRateChange = (rate: number) => {\n if (videoRef.current && isFinite(rate) && rate > 0) {\n videoRef.current.playbackRate = rate;\n }\n setShowSpeedMenu(false);\n };\n\n const isHlsStream =\n src?.toLowerCase().includes(\".m3u8\") ||\n src?.toLowerCase().includes(\"/hls/\");\n const shouldShowEnhancedControls =\n showCustomControls && (isHlsStream ? allowNativeHls : true);\n\n const criticalPropsKey = useMemo(() => {\n return CRITICAL_PROPS.map((prop) => `${prop}:${props[prop]}`).join(\"|\");\n }, [\n src,\n allowNativeHls,\n licenseKey,\n lowLatencyMode,\n driftToleranceMs,\n ]);\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const el = videoRef.current;\n if (!el || !src) return;\n\n if (!licenseKey) {\n setShowLicenseWarning(true);\n setIsLoading(false);\n console.warn(\n \"StormcloudVideoPlayer: License key is required but not provided. Please set the licenseKey prop to use the player.\"\n );\n return;\n }\n\n setShowLicenseWarning(false);\n\n if (debugAdTiming) {\n console.log(\"[StormcloudUI] Initializing player, isLoading=true\");\n }\n\n if (playerRef.current) {\n try {\n playerRef.current.destroy();\n } catch {}\n playerRef.current = null;\n }\n\n const cfg: StormcloudVideoPlayerConfig = {\n src,\n videoElement: el,\n } as StormcloudVideoPlayerConfig;\n if (autoplay !== undefined) cfg.autoplay = autoplay;\n if (muted !== undefined) cfg.muted = muted;\n if (lowLatencyMode !== undefined) cfg.lowLatencyMode = lowLatencyMode;\n if (allowNativeHls !== undefined) cfg.allowNativeHls = allowNativeHls;\n if (driftToleranceMs !== undefined)\n cfg.driftToleranceMs = driftToleranceMs;\n if (immediateManifestAds !== undefined)\n cfg.immediateManifestAds = immediateManifestAds;\n if (debugAdTiming !== undefined) cfg.debugAdTiming = debugAdTiming;\n if (showCustomControls !== undefined)\n cfg.showCustomControls = showCustomControls;\n if (onVolumeToggle !== undefined) cfg.onVolumeToggle = onVolumeToggle;\n if (onFullscreenToggle !== undefined)\n cfg.onFullscreenToggle = onFullscreenToggle;\n if (onControlClick !== undefined) cfg.onControlClick = onControlClick;\n if (licenseKey !== undefined) cfg.licenseKey = licenseKey;\n if (minSegmentsBeforePlay !== undefined)\n cfg.minSegmentsBeforePlay = minSegmentsBeforePlay;\n\n const player = new StormcloudVideoPlayer(cfg);\n playerRef.current = player;\n player\n .load()\n .then(() => {\n const showNative = player.shouldShowNativeControls();\n setShouldShowNativeControls(showNative);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Player loaded successfully, waiting for video ready\"\n );\n }\n onReady?.(player);\n })\n .catch((error) => {\n console.error(\n \"StormcloudVideoPlayer: Failed to load player:\",\n error\n );\n setIsLoading(false);\n onReady?.(player);\n });\n\n return () => {\n try {\n player.destroy();\n } catch {}\n playerRef.current = null;\n };\n }, [criticalPropsKey]);\n\n useEffect(() => {\n if (!playerRef.current) return;\n\n try {\n if (autoplay !== undefined && playerRef.current.videoElement) {\n playerRef.current.videoElement.autoplay = autoplay;\n }\n if (muted !== undefined && !playerRef.current.isShowingAds()) {\n playerRef.current.setMuted(muted);\n }\n } catch (error) {\n console.warn(\"Failed to update player properties:\", error);\n }\n }, [autoplay, muted]);\n\n useEffect(() => {\n if (!playerRef.current) return;\n\n const checkAdStatus = () => {\n if (playerRef.current) {\n const showAdsFromMethod = playerRef.current.isShowingAds();\n const showAdsFromAttribute = videoRef.current?.dataset?.stormcloudAdPlaying === \"true\";\n const showAds = showAdsFromMethod || showAdsFromAttribute;\n const currentIndex = playerRef.current.getCurrentAdIndex();\n const totalAds = playerRef.current.getTotalAdsInBreak();\n\n setAdStatus((prev) => {\n if (\n prev.showAds !== showAds ||\n prev.currentIndex !== currentIndex ||\n prev.totalAds !== totalAds\n ) {\n if (showAds && !prev.showAds) {\n setShowCenterPlay(false);\n }\n return { showAds, currentIndex, totalAds };\n }\n return prev;\n });\n }\n };\n\n const interval = setInterval(checkAdStatus, 50);\n return () => clearInterval(interval);\n }, []);\n\n useEffect(() => {\n if (typeof window === \"undefined\" || !playerRef.current) return;\n\n const handleResize = () => {\n if (playerRef.current && videoRef.current) {\n if (typeof playerRef.current.resize === \"function\") {\n playerRef.current.resize();\n }\n }\n setViewportWidth(window.innerWidth);\n setIsPortrait(window.innerHeight > window.innerWidth);\n };\n\n window.addEventListener(\"resize\", handleResize);\n return () => window.removeEventListener(\"resize\", handleResize);\n }, []);\n\n useEffect(() => {\n if (!playerRef.current || !videoRef.current) return;\n\n const updateStates = () => {\n if (playerRef.current && videoRef.current) {\n setIsMuted(playerRef.current.isMuted());\n setIsPlaying(!videoRef.current.paused);\n\n const currentTimeValue = videoRef.current.currentTime;\n setCurrentTime(isFinite(currentTimeValue) ? currentTimeValue : 0);\n\n const durationValue = videoRef.current.duration;\n setDuration(isFinite(durationValue) ? durationValue : 0);\n\n const volumeValue = playerRef.current.getVolume();\n setVolume(\n isFinite(volumeValue) ? Math.max(0, Math.min(1, volumeValue)) : 1\n );\n\n const rateValue = videoRef.current.playbackRate;\n setPlaybackRate(\n isFinite(rateValue) && rateValue > 0 ? rateValue : 1\n );\n }\n setIsFullscreen(\n document.fullscreenElement === videoRef.current?.parentElement\n );\n };\n\n const interval = setInterval(updateStates, 200);\n\n const handleFullscreenChange = () => {\n setIsFullscreen(\n document.fullscreenElement === videoRef.current?.parentElement\n );\n };\n\n document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n\n return () => {\n clearInterval(interval);\n document.removeEventListener(\n \"fullscreenchange\",\n handleFullscreenChange\n );\n };\n }, []);\n\n useEffect(() => {\n if (!videoRef.current) return;\n\n const handleLoadedMetadata = () => {\n if (videoRef.current) {\n const video = videoRef.current;\n void video.offsetHeight;\n }\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadedmetadata, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n\n const handleLoadedData = () => {\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadeddata, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n\n const handleLoadStart = () => {\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadstart, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n\n const handleCanPlay = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: canplay, readyState:\",\n videoRef.current?.readyState,\n \"- clearing loading state, isLoading=false\"\n );\n }\n };\n\n const handleCanPlayThrough = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: canplaythrough, readyState:\",\n videoRef.current?.readyState,\n \"- clearing loading state, isLoading=false\"\n );\n }\n };\n\n const handleWaiting = () => {\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n }\n\n bufferingTimeoutRef.current = window.setTimeout(() => {\n setIsBuffering(true);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video buffering detected (after 300ms delay), readyState:\",\n videoRef.current?.readyState,\n \"- showing spinner, isBuffering=true\"\n );\n }\n }, 300);\n\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: waiting, readyState:\",\n videoRef.current?.readyState,\n \"- buffering delay started (300ms)\"\n );\n }\n };\n\n const handlePlaying = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n setShowCenterPlay(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: playing, readyState:\",\n videoRef.current?.readyState,\n \"- playback started, isLoading=false, isBuffering=false\"\n );\n }\n };\n\n const handlePause = () => {\n const isAdActive = playerRef.current?.isShowingAds() || \n videoRef.current?.dataset?.stormcloudAdPlaying === \"true\";\n \n if (playerRef.current && !isAdActive) {\n setShowCenterPlay(true);\n } else {\n setShowCenterPlay(false);\n }\n };\n\n const handleEnded = () => {\n setShowCenterPlay(true);\n };\n\n const video = videoRef.current;\n video.addEventListener(\"loadstart\", handleLoadStart);\n video.addEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.addEventListener(\"loadeddata\", handleLoadedData);\n video.addEventListener(\"canplay\", handleCanPlay);\n video.addEventListener(\"canplaythrough\", handleCanPlayThrough);\n video.addEventListener(\"waiting\", handleWaiting);\n video.addEventListener(\"playing\", handlePlaying);\n video.addEventListener(\"pause\", handlePause);\n video.addEventListener(\"ended\", handleEnded);\n\n if (video.paused) {\n setShowCenterPlay(true);\n }\n\n return () => {\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n\n video.removeEventListener(\"loadstart\", handleLoadStart);\n video.removeEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.removeEventListener(\"loadeddata\", handleLoadedData);\n video.removeEventListener(\"canplay\", handleCanPlay);\n video.removeEventListener(\"canplaythrough\", handleCanPlayThrough);\n video.removeEventListener(\"waiting\", handleWaiting);\n video.removeEventListener(\"playing\", handlePlaying);\n video.removeEventListener(\"pause\", handlePause);\n video.removeEventListener(\"ended\", handleEnded);\n };\n }, [debugAdTiming]);\n\n return (\n <>\n <style>\n {`\n @keyframes spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n }\n \n .stormcloud-loading-hidden .stormcloud-loading-indicator {\n display: none !important;\n }\n \n .stormcloud-video-wrapper:fullscreen {\n border-radius: 0 !important;\n box-shadow: none !important;\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n \n .stormcloud-video-wrapper:has(*:fullscreen) {\n border-radius: 0 !important;\n box-shadow: none !important;\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n \n *:fullscreen {\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n }\n `}\n </style>\n <div\n className={`stormcloud-video-wrapper ${wrapperClassName || \"\"}`}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n position: isFullscreen ? \"fixed\" : \"relative\",\n top: isFullscreen ? 0 : undefined,\n left: isFullscreen ? 0 : undefined,\n overflow: \"hidden\",\n width: isFullscreen ? \"100vw\" : \"100%\",\n height: isFullscreen ? \"100vh\" : \"auto\",\n minHeight: isFullscreen ? \"100vh\" : \"auto\",\n maxWidth: isFullscreen ? \"100vw\" : \"100%\",\n maxHeight: isFullscreen ? \"100vh\" : \"none\",\n zIndex: isFullscreen ? 999999 : undefined,\n backgroundColor: isFullscreen ? \"#000\" : undefined,\n borderRadius: isFullscreen ? 0 : undefined,\n boxShadow: isFullscreen ? \"none\" : undefined,\n ...wrapperStyle,\n }}\n >\n <video\n ref={videoRef}\n className={className}\n style={{\n display: \"block\",\n width: \"100%\",\n height: isFullscreen ? \"100%\" : \"auto\",\n maxWidth: \"100%\",\n maxHeight: isFullscreen ? \"100%\" : \"none\",\n objectFit: isFullscreen ? \"cover\" : \"contain\",\n backgroundColor: \"#000\",\n aspectRatio: isFullscreen ? \"unset\" : undefined,\n ...style,\n }}\n controls={\n shouldShowNativeControls && controls && !showCustomControls\n }\n playsInline={playsInline}\n preload={preload}\n poster={poster}\n {...restVideoAttrs}\n >\n {children}\n </video>\n\n {(isLoading || isBuffering) && !hideLoadingIndicator && (\n <FaSpinner\n className=\"stormcloud-loading-indicator\"\n size={42}\n color=\"white\"\n style={{\n position: \"absolute\",\n top: \"calc(50% - 21px)\",\n left: \"calc(50% - 21px)\",\n zIndex: 20,\n animation: \"spin 1s linear infinite\",\n filter: \"drop-shadow(0 3px 6px rgba(0, 0, 0, 0.8))\",\n }}\n />\n )}\n\n {showLicenseWarning && (\n <div\n style={{\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n zIndex: 25,\n background:\n \"linear-gradient(135deg, rgba(220, 38, 38, 0.95) 0%, rgba(185, 28, 28, 0.9) 100%)\",\n color: \"white\",\n padding: \"24px 32px\",\n borderRadius: \"16px\",\n backdropFilter: \"blur(20px)\",\n border: \"2px solid rgba(255, 255, 255, 0.2)\",\n boxShadow:\n \"0 20px 60px rgba(0, 0, 0, 0.6), inset 0 2px 0 rgba(255, 255, 255, 0.2)\",\n textAlign: \"center\",\n maxWidth: \"400px\",\n margin: \"0 16px\",\n }}\n >\n <div\n style={{\n fontSize: \"20px\",\n fontWeight: \"bold\",\n marginBottom: \"12px\",\n color: \"#ffffff\",\n textShadow: \"0 2px 4px rgba(0, 0, 0, 0.5)\",\n }}\n >\n License Key Required\n </div>\n <div\n style={{\n fontSize: \"14px\",\n lineHeight: \"1.5\",\n color: \"rgba(255, 255, 255, 0.9)\",\n textShadow: \"0 1px 2px rgba(0, 0, 0, 0.3)\",\n }}\n >\n Please provide a valid license key to use the Stormcloud Video\n Player.\n <br />\n Contact your administrator for licensing information.\n </div>\n </div>\n )}\n\n {showCenterPlay &&\n !isLoading &&\n !isBuffering &&\n !showLicenseWarning &&\n !adStatus.showAds && (\n <div\n onClick={handleCenterPlayClick}\n style={{\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n zIndex: 15,\n cursor: \"pointer\",\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.8) 100%)\",\n borderRadius: \"50%\",\n width: \"100px\",\n height: \"100px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n border: \"3px solid rgba(255, 255, 255, 0.8)\",\n boxShadow:\n \"0 12px 40px rgba(0, 0, 0, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n }}\n onMouseEnter={(e) => {\n const target = e.currentTarget as HTMLElement;\n target.style.transform = \"translate(-50%, -50%)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.95) 0%, rgba(40, 40, 40, 0.9) 100%)\";\n target.style.boxShadow =\n \"0 16px 48px rgba(0, 0, 0, 0.9), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.borderColor = \"rgba(255, 255, 255, 0.9)\";\n }}\n onMouseLeave={(e) => {\n const target = e.currentTarget as HTMLElement;\n target.style.transform = \"translate(-50%, -50%)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.8) 100%)\";\n target.style.boxShadow =\n \"0 12px 40px rgba(0, 0, 0, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.3)\";\n target.style.borderColor = \"rgba(255, 255, 255, 0.8)\";\n }}\n title=\"Play\"\n >\n <FaPlay\n size={36}\n color=\"white\"\n style={{\n marginLeft: \"6px\",\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n }}\n />\n </div>\n )}\n\n {shouldShowEnhancedControls && !showLicenseWarning ? (\n <>\n <div\n style={{\n position: \"absolute\",\n bottom: 0,\n left: 0,\n right: 0,\n background:\n \"linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.8) 100%)\",\n padding: \"20px 16px 16px\",\n zIndex: 10,\n }}\n >\n <div\n style={{\n width: \"100%\",\n height: \"8px\",\n background:\n \"linear-gradient(90deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0.1) 100%)\",\n borderRadius: \"8px\",\n marginBottom: \"16px\",\n cursor: \"pointer\",\n position: \"relative\",\n backdropFilter: \"blur(5px)\",\n border: \"1px solid rgba(255, 255, 255, 0.1)\",\n boxShadow: \"inset 0 2px 4px rgba(0, 0, 0, 0.2)\",\n }}\n onClick={handleTimelineSeek}\n >\n <div\n style={{\n height: \"100%\",\n background:\n \"linear-gradient(90deg, rgba(139, 92, 246, 0.9) 0%, rgba(59, 130, 246, 0.8) 50%, rgba(34, 197, 94, 0.9) 100%)\",\n borderRadius: \"8px\",\n width: `${\n duration > 0 ? (currentTime / duration) * 100 : 0\n }%`,\n transition: \"width 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 2px 8px rgba(139, 92, 246, 0.4)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n top: \"-6px\",\n right: `${\n duration > 0\n ? 100 - (currentTime / duration) * 100\n : 100\n }%`,\n width: \"20px\",\n height: \"20px\",\n background:\n \"linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(240, 240, 240, 0.9) 100%)\",\n borderRadius: \"50%\",\n border: \"3px solid rgba(139, 92, 246, 0.8)\",\n boxShadow:\n \"0 4px 16px rgba(139, 92, 246, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.8)\",\n transform: \"translateX(50%)\",\n transition: \"all 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n }}\n />\n </div>\n\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n color: \"white\",\n flexWrap: viewportWidth < 768 ? \"wrap\" : \"nowrap\",\n gap: `${8 * responsiveScale}px`,\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: `${12 * responsiveScale}px`,\n flexWrap: viewportWidth < 480 ? \"wrap\" : \"nowrap\",\n }}\n >\n <button\n onClick={handlePlayPause}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n backdropFilter: \"blur(12px)\",\n border: `${\n 2 * responsiveScale\n }px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${10 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow:\n \"0 8px 32px rgba(0, 0, 0, 0.4), 0 4px 16px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n minWidth: `${48 * responsiveScale}px`,\n minHeight: `${48 * responsiveScale}px`,\n }}\n onMouseEnter={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n target.style.boxShadow =\n \"0 12px 48px rgba(0, 0, 0, 0.6), 0 6px 24px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n }}\n onMouseLeave={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n target.style.boxShadow =\n \"0 8px 32px rgba(0, 0, 0, 0.4), 0 4px 16px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n }}\n title={isPlaying ? \"Pause\" : \"Play\"}\n >\n {isPlaying ? (\n <FaPause\n size={Math.max(16, 20 * responsiveScale)}\n style={{ filter: \"drop-shadow(0 0 0 transparent)\" }}\n />\n ) : (\n <FaPlay\n size={Math.max(16, 20 * responsiveScale)}\n style={{ filter: \"drop-shadow(0 0 0 transparent)\" }}\n />\n )}\n </button>\n\n <div\n style={{\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n padding: \"8px\",\n margin: \"-8px\",\n }}\n onMouseEnter={() => setShowVolumeSlider(true)}\n onMouseLeave={() => setShowVolumeSlider(false)}\n >\n <button\n onClick={() => {\n if (playerRef.current) {\n playerRef.current.toggleMute();\n }\n if (onVolumeToggle) {\n onVolumeToggle();\n }\n }}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${\n 2 * responsiveScale\n }px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow:\n \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${44 * responsiveScale}px`,\n minHeight: `${44 * responsiveScale}px`,\n }}\n onMouseEnter={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow =\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n }}\n onMouseLeave={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow =\n \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n }}\n title={isMuted ? \"Unmute\" : \"Mute\"}\n >\n {isMuted || volume === 0 ? (\n <FaVolumeMute\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 0 0 transparent)\",\n }}\n />\n ) : volume < 0.5 ? (\n <FaVolumeDown\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 0 0 transparent)\",\n }}\n />\n ) : (\n <FaVolumeUp\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 0 0 transparent)\",\n }}\n />\n )}\n </button>\n\n {showVolumeSlider && (\n <>\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"60px\",\n height: \"20px\",\n marginBottom: \"-16px\",\n zIndex: 9,\n }}\n onMouseEnter={() => setShowVolumeSlider(true)}\n onMouseLeave={() => setShowVolumeSlider(false)}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: \"4px\",\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.88) 0%, rgba(20, 20, 20, 0.92) 100%)\",\n backdropFilter: \"blur(15px)\",\n padding: \"10px 14px\",\n borderRadius: \"14px\",\n border: \"1px solid rgba(255, 255, 255, 0.15)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"128px\",\n boxShadow:\n \"0 12px 40px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15)\",\n zIndex: 10,\n transition:\n \"transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, border-color 0.2s ease-in-out\",\n }}\n onMouseEnter={(e) => {\n setShowVolumeSlider(true);\n e.currentTarget.style.boxShadow =\n \"0 16px 48px rgba(0, 0, 0, 0.6), 0 6px 16px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 0 24px rgba(59, 130, 246, 0.3)\";\n e.currentTarget.style.borderColor =\n \"rgba(59, 130, 246, 0.4)\";\n }}\n onMouseLeave={(e) => {\n setShowVolumeSlider(false);\n e.currentTarget.style.boxShadow =\n \"0 12px 40px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15)\";\n e.currentTarget.style.borderColor =\n \"rgba(255, 255, 255, 0.15)\";\n }}\n >\n <div\n style={{\n position: \"relative\",\n width: \"8px\",\n height: \"104px\",\n cursor: \"pointer\",\n transition: \"transform 0.2s ease-in-out\",\n }}\n onMouseEnter={(e) => {\n // Hover effect removed\n }}\n onMouseLeave={(e) => {\n // Hover effect removed\n }}\n onMouseDown={(e) => {\n e.preventDefault();\n const sliderElement = e.currentTarget;\n\n const handleMouseMove = (\n moveEvent: MouseEvent\n ) => {\n if (!sliderElement) return;\n const rect =\n sliderElement.getBoundingClientRect();\n const y = moveEvent.clientY - rect.top;\n const percentage =\n 1 -\n Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n };\n\n const handleMouseUp = () => {\n document.removeEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.removeEventListener(\n \"mouseup\",\n handleMouseUp\n );\n };\n\n document.addEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.addEventListener(\n \"mouseup\",\n handleMouseUp\n );\n\n const rect =\n sliderElement.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage =\n 1 -\n Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n }}\n onClick={(e) => {\n e.stopPropagation();\n const rect =\n e.currentTarget.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage =\n 1 -\n Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n }}\n >\n <div\n style={{\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: \"100%\",\n background:\n \"linear-gradient(180deg, rgba(255, 255, 255, 0.4) 0%, rgba(255, 255, 255, 0.15) 100%)\",\n borderRadius: \"4px\",\n boxShadow:\n \"inset 0 1px 3px rgba(0, 0, 0, 0.2)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: `${(isMuted ? 0 : volume) * 100}%`,\n background:\n \"linear-gradient(180deg, rgba(96, 165, 250, 1) 0%, rgba(59, 130, 246, 0.95) 50%, rgba(37, 99, 235, 0.9) 100%)\",\n borderRadius: \"4px\",\n transition:\n \"height 0.15s ease-out, box-shadow 0.2s ease-in-out\",\n boxShadow:\n \"0 0 8px rgba(59, 130, 246, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: `calc(${\n (isMuted ? 0 : volume) * 100\n }% - 7px)`,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"14px\",\n height: \"14px\",\n background:\n \"linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)\",\n borderRadius: \"50%\",\n boxShadow:\n \"0 2px 6px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(59, 130, 246, 0.3), 0 0 12px rgba(59, 130, 246, 0.4)\",\n transition:\n \"bottom 0.15s ease-out, transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, width 0.2s ease-in-out, height 0.2s ease-in-out\",\n cursor: \"grab\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.boxShadow =\n \"0 3px 10px rgba(0, 0, 0, 0.4), 0 0 0 3px rgba(59, 130, 246, 0.5), 0 0 20px rgba(59, 130, 246, 0.6)\";\n e.currentTarget.style.cursor = \"grab\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.boxShadow =\n \"0 2px 6px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(59, 130, 246, 0.3), 0 0 12px rgba(59, 130, 246, 0.4)\";\n }}\n onMouseDown={(e) => {\n e.currentTarget.style.cursor = \"grabbing\";\n }}\n onMouseUp={(e) => {\n e.currentTarget.style.cursor = \"grab\";\n }}\n />\n </div>\n </div>\n </>\n )}\n </div>\n\n <div\n style={{\n fontSize: `${14 * responsiveScale}px`,\n fontFamily: \"monospace\",\n color: \"rgba(255, 255, 255, 0.9)\",\n display: viewportWidth < 480 ? \"none\" : \"block\",\n }}\n >\n {formatTime(currentTime)} / {formatTime(duration)}\n </div>\n </div>\n\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: `${12 * responsiveScale}px`,\n }}\n >\n <div\n style={{\n position: \"relative\",\n display: viewportWidth < 600 ? \"none\" : \"block\",\n }}\n >\n <button\n onClick={() => setShowSpeedMenu(!showSpeedMenu)}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${\n 2 * responsiveScale\n }px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px ${\n 14 * responsiveScale\n }px`,\n borderRadius: `${14 * responsiveScale}px`,\n fontSize: `${14 * responsiveScale}px`,\n fontFamily: \"monospace\",\n fontWeight: \"700\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow:\n \"0 6px 24px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${56 * responsiveScale}px`,\n minHeight: `${40 * responsiveScale}px`,\n }}\n onMouseEnter={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow =\n \"0 10px 32px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n }}\n onMouseLeave={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow =\n \"0 6px 24px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n }}\n title=\"Playback Speed\"\n >\n {playbackRate}x\n </button>\n\n {showSpeedMenu && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n right: 0,\n marginBottom: \"12px\",\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.95) 100%)\",\n backdropFilter: \"blur(20px)\",\n borderRadius: \"12px\",\n border: \"1px solid rgba(255, 255, 255, 0.1)\",\n overflow: \"hidden\",\n minWidth: \"90px\",\n boxShadow:\n \"0 16px 48px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.1)\",\n }}\n >\n {[0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2].map(\n (speed) => (\n <button\n key={speed}\n onClick={() =>\n handlePlaybackRateChange(speed)\n }\n style={{\n display: \"block\",\n width: \"100%\",\n padding: \"10px 16px\",\n background:\n playbackRate === speed\n ? \"linear-gradient(135deg, rgba(99, 102, 241, 0.8) 0%, rgba(139, 92, 246, 0.6) 100%)\"\n : \"transparent\",\n border: \"none\",\n color: \"white\",\n cursor: \"pointer\",\n fontSize: \"13px\",\n fontFamily: \"monospace\",\n fontWeight: \"600\",\n textAlign: \"center\",\n transition:\n \"all 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n borderBottom:\n speed !== 2\n ? \"1px solid rgba(255, 255, 255, 0.05)\"\n : \"none\",\n }}\n onMouseEnter={(e) => {\n if (playbackRate !== speed) {\n (\n e.target as HTMLElement\n ).style.background =\n \"linear-gradient(135deg, rgba(255, 255, 255, 0.15) 0%, rgba(255, 255, 255, 0.05) 100%)\";\n }\n }}\n onMouseLeave={(e) => {\n if (playbackRate !== speed) {\n (\n e.target as HTMLElement\n ).style.background = \"transparent\";\n }\n }}\n >\n {speed}x\n </button>\n )\n )}\n </div>\n )}\n </div>\n\n <button\n onClick={() => {\n if (onFullscreenToggle) {\n onFullscreenToggle();\n } else if (playerRef.current) {\n playerRef.current\n .toggleFullscreen()\n .catch((err) => {\n console.error(\"Fullscreen error:\", err);\n });\n }\n }}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${\n 2 * responsiveScale\n }px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow:\n \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${44 * responsiveScale}px`,\n minHeight: `${44 * responsiveScale}px`,\n }}\n onMouseEnter={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow =\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n }}\n onMouseLeave={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow =\n \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n }}\n title={\n isFullscreen ? \"Exit Fullscreen\" : \"Enter Fullscreen\"\n }\n >\n {isFullscreen ? (\n <FaCompress\n size={Math.max(14, 16 * responsiveScale)}\n style={{ filter: \"drop-shadow(0 0 0 transparent)\" }}\n />\n ) : (\n <FaExpand\n size={Math.max(14, 16 * responsiveScale)}\n style={{ filter: \"drop-shadow(0 0 0 transparent)\" }}\n />\n )}\n </button>\n </div>\n </div>\n </div>\n </>\n ) : (\n showCustomControls &&\n !showLicenseWarning && (\n <div\n style={{\n position: \"absolute\",\n bottom: `${10 * responsiveScale}px`,\n right: `${10 * responsiveScale}px`,\n transform: \"none\",\n display: \"flex\",\n flexDirection: isPortrait ? \"column\" : \"row\",\n gap: `${10 * responsiveScale}px`,\n zIndex: 10,\n }}\n >\n <div\n style={{\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n padding: \"8px\",\n margin: \"-8px\",\n }}\n onMouseEnter={() => setShowVolumeSlider(true)}\n onMouseLeave={() => setShowVolumeSlider(false)}\n >\n <button\n onClick={() => {\n if (playerRef.current) {\n playerRef.current.toggleMute();\n }\n if (onVolumeToggle) {\n onVolumeToggle();\n }\n }}\n onMouseEnter={(e) => {\n const target = e.currentTarget as HTMLButtonElement;\n target.style.boxShadow =\n \"0 14px 48px rgba(0, 0, 0, 0.7), 0 0 0 3px rgba(255, 255, 255, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n }}\n onMouseLeave={(e) => {\n const target = e.currentTarget as HTMLButtonElement;\n target.style.boxShadow =\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n }}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n color: \"#ffffff\",\n border: \"none\",\n borderRadius: `${18 * responsiveScale}px`,\n padding: `${8 * responsiveScale}px`,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n boxShadow:\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.4s cubic-bezier(0.4, 0, 0.2, 1)\",\n minWidth: `${46 * responsiveScale}px`,\n minHeight: `${46 * responsiveScale}px`,\n }}\n title={isMuted ? \"Unmute\" : \"Mute\"}\n >\n {isMuted || volume === 0 ? (\n <FaVolumeMute\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\",\n }}\n />\n ) : volume < 0.5 ? (\n <FaVolumeDown\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\",\n }}\n />\n ) : (\n <FaVolumeUp\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\",\n }}\n />\n )}\n </button>\n\n {showVolumeSlider && (\n <>\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"60px\",\n height: \"20px\",\n marginBottom: \"-16px\",\n zIndex: 9,\n }}\n onMouseEnter={() => setShowVolumeSlider(true)}\n onMouseLeave={() => setShowVolumeSlider(false)}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: \"4px\",\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.96) 0%, rgba(20, 20, 20, 0.92) 100%)\",\n backdropFilter: \"blur(20px)\",\n padding: \"10px 14px\",\n borderRadius: \"14px\",\n border: \"2px solid rgba(255, 255, 255, 0.7)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"128px\",\n boxShadow:\n \"0 12px 40px rgba(0, 0, 0, 0.85), 0 4px 12px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.35)\",\n zIndex: 10,\n transition:\n \"transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, border-color 0.2s ease-in-out\",\n }}\n onMouseEnter={(e) => {\n setShowVolumeSlider(true);\n e.currentTarget.style.boxShadow =\n \"0 16px 48px rgba(0, 0, 0, 0.9), 0 6px 16px rgba(0, 0, 0, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 0 24px rgba(96, 165, 250, 0.4)\";\n e.currentTarget.style.borderColor =\n \"rgba(96, 165, 250, 0.8)\";\n }}\n onMouseLeave={(e) => {\n setShowVolumeSlider(false);\n e.currentTarget.style.boxShadow =\n \"0 12px 40px rgba(0, 0, 0, 0.85), 0 4px 12px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.35)\";\n e.currentTarget.style.borderColor =\n \"rgba(255, 255, 255, 0.7)\";\n }}\n >\n <div\n style={{\n position: \"relative\",\n width: \"8px\",\n height: \"104px\",\n cursor: \"pointer\",\n transition: \"transform 0.2s ease-in-out\",\n }}\n onMouseDown={(e) => {\n e.preventDefault();\n const sliderElement = e.currentTarget;\n\n const handleMouseMove = (\n moveEvent: MouseEvent\n ) => {\n if (!sliderElement) return;\n const rect =\n sliderElement.getBoundingClientRect();\n const y = moveEvent.clientY - rect.top;\n const percentage =\n 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n };\n\n const handleMouseUp = () => {\n document.removeEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.removeEventListener(\n \"mouseup\",\n handleMouseUp\n );\n };\n\n document.addEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.addEventListener(\n \"mouseup\",\n handleMouseUp\n );\n\n const rect =\n sliderElement.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage =\n 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n }}\n onClick={(e) => {\n e.stopPropagation();\n const rect =\n e.currentTarget.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage =\n 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n }}\n >\n <div\n style={{\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: \"100%\",\n background:\n \"linear-gradient(180deg, rgba(255, 255, 255, 0.85) 0%, rgba(255, 255, 255, 0.5) 100%)\",\n borderRadius: \"4px\",\n border: \"1px solid rgba(255, 255, 255, 0.4)\",\n boxShadow: \"inset 0 1px 3px rgba(0, 0, 0, 0.3)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: `${(isMuted ? 0 : volume) * 100}%`,\n background:\n \"linear-gradient(180deg, rgba(125, 211, 252, 1) 0%, rgba(96, 165, 250, 0.98) 50%, rgba(59, 130, 246, 0.95) 100%)\",\n borderRadius: \"4px\",\n transition:\n \"height 0.15s ease-out, box-shadow 0.2s ease-in-out\",\n boxShadow:\n \"0 0 12px rgba(96, 165, 250, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.4)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: `calc(${\n (isMuted ? 0 : volume) * 100\n }% - 8px)`,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"16px\",\n height: \"16px\",\n background:\n \"linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)\",\n borderRadius: \"50%\",\n border: \"2px solid rgba(96, 165, 250, 0.9)\",\n boxShadow:\n \"0 3px 8px rgba(0, 0, 0, 0.5), 0 0 0 2px rgba(96, 165, 250, 0.4), 0 0 16px rgba(96, 165, 250, 0.5)\",\n transition:\n \"bottom 0.15s ease-out, transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, width 0.2s ease-in-out, height 0.2s ease-in-out\",\n cursor: \"grab\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.boxShadow =\n \"0 4px 12px rgba(0, 0, 0, 0.6), 0 0 0 3px rgba(96, 165, 250, 0.6), 0 0 24px rgba(96, 165, 250, 0.7)\";\n e.currentTarget.style.cursor = \"grab\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.boxShadow =\n \"0 3px 8px rgba(0, 0, 0, 0.5), 0 0 0 2px rgba(96, 165, 250, 0.4), 0 0 16px rgba(96, 165, 250, 0.5)\";\n }}\n onMouseDown={(e) => {\n e.currentTarget.style.cursor = \"grabbing\";\n }}\n onMouseUp={(e) => {\n e.currentTarget.style.cursor = \"grab\";\n }}\n />\n </div>\n </div>\n </>\n )}\n </div>\n\n <button\n onClick={() => {\n if (onFullscreenToggle) {\n onFullscreenToggle();\n } else if (playerRef.current) {\n playerRef.current.toggleFullscreen().catch((err) => {\n console.error(\"Fullscreen error:\", err);\n });\n }\n }}\n onMouseEnter={(e) => {\n const target = e.currentTarget as HTMLButtonElement;\n target.style.boxShadow =\n \"0 14px 48px rgba(0, 0, 0, 0.7), 0 0 0 3px rgba(255, 255, 255, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n }}\n onMouseLeave={(e) => {\n const target = e.currentTarget as HTMLButtonElement;\n target.style.boxShadow =\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n }}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n color: \"#ffffff\",\n border: \"none\",\n borderRadius: `${18 * responsiveScale}px`,\n padding: `${8 * responsiveScale}px`,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n boxShadow:\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.4s cubic-bezier(0.4, 0, 0.2, 1)\",\n minWidth: `${46 * responsiveScale}px`,\n minHeight: `${46 * responsiveScale}px`,\n }}\n title={\n isFullscreen ? \"Exit Fullscreen\" : \"Enter Fullscreen\"\n }\n >\n {isFullscreen ? (\n <FaCompress\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\",\n }}\n />\n ) : (\n <FaExpand\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\",\n }}\n />\n )}\n </button>\n </div>\n )\n )}\n\n {onControlClick && (\n <div\n onClick={onControlClick}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 1,\n cursor: \"pointer\",\n }}\n />\n )}\n </div>\n </>\n );\n },\n (prevProps, nextProps) => {\n for (const prop of CRITICAL_PROPS) {\n if ((prevProps as any)[prop] !== (nextProps as any)[prop]) {\n return false;\n }\n }\n\n const uiProps = [\n \"autoplay\",\n \"muted\",\n \"controls\",\n \"showCustomControls\",\n \"className\",\n \"style\",\n \"wrapperClassName\",\n \"wrapperStyle\",\n \"playsInline\",\n \"preload\",\n \"poster\",\n \"children\",\n ] as const;\n\n for (const prop of uiProps) {\n if ((prevProps as any)[prop] !== (nextProps as any)[prop]) {\n return false;\n }\n }\n\n const callbackProps = [\n \"onReady\",\n \"onVolumeToggle\",\n \"onFullscreenToggle\",\n \"onControlClick\",\n ] as const;\n for (const prop of callbackProps) {\n if ((prevProps as any)[prop] !== (nextProps as any)[prop]) {\n return false;\n }\n }\n\n return true;\n }\n );\n","import Hls from \"hls.js\";\nimport type {\n StormcloudVideoPlayerConfig,\n Scte35Marker,\n Id3TagInfo,\n} from \"../types\";\nimport type { PrebidBidResponse } from \"../types\";\nimport { createPrebidManager } from \"../sdk/prebid\";\nimport { createPrebidAdLayer } from \"../sdk/prebidAdLayer\";\nimport type { PrebidAdLayer } from \"../sdk/prebidAdLayer\";\nimport {\n sendInitialTracking,\n sendHeartbeat,\n sendAdDetectTracking,\n sendAdLoadedTracking,\n sendAdImpressionTracking,\n} from \"../utils/tracking\";\nimport { initializePolyfills } from \"../utils/polyfills\";\nimport { logBrowserInfo, getBrowserConfigOverrides, detectBrowser } from \"../utils/browserCompat\";\n\nexport class StormcloudVideoPlayer {\n private readonly video: HTMLVideoElement;\n private readonly config: StormcloudVideoPlayerConfig;\n private hls?: Hls;\n private prebidManager: ReturnType<typeof createPrebidManager>;\n private adLayer: PrebidAdLayer;\n private pendingNextAdBids: PrebidBidResponse[] | null = null;\n private continuousFetchLoopPromise: Promise<void> | null = null;\n private attached = false;\n private inAdBreak = false;\n private currentAdBreakStartWallClockMs: number | undefined;\n private expectedAdBreakDurationMs: number | undefined;\n private adStopTimerId: number | undefined;\n private adStartTimerId: number | undefined;\n private adFailsafeTimerId: number | undefined;\n private ptsDriftEmaMs = 0;\n private adPodQueue: string[] = [];\n private lastHeartbeatTime: number = 0;\n private heartbeatInterval: number | undefined;\n private currentAdIndex: number = 0;\n private totalAdsInBreak: number = 0;\n private showAds: boolean = false;\n private isLiveStream: boolean = false;\n private nativeHlsMode: boolean = false;\n private videoSrcProtection: string | null = null;\n private bufferedSegmentsCount: number = 0;\n private shouldAutoplayAfterBuffering: boolean = false;\n private hasInitialBufferCompleted: boolean = false;\n private activeAdRequestToken: number | null = null;\n private adRequestWatchdogId: number | undefined;\n private adRequestWatchdogToken: number | null = null;\n private adFailsafeToken: number | null = null;\n private continuousFetchingActive: boolean = false;\n private maxPlaceholderDurationMs: number = 5000;\n private isShowingPlaceholder: boolean = false;\n private timeUpdateHandler?: (event: Event) => void;\n private emptiedHandler?: (event: Event) => void;\n \n private totalAdRequestsInBreak: number = 0;\n private readonly maxTotalAdRequestsPerBreak: number = 20;\n \n private pendingAdBreak: {\n marker: Scte35Marker;\n detectedAtFragmentSn?: number;\n isFetching: boolean;\n fetchStartTime?: number;\n } | null = null;\n private prefetchTimerId: number | undefined;\n private savedMutedStateBeforeScte: { muted: boolean; volume: number } | null = null;\n\n private consecutiveFailures: number = 0;\n private readonly maxConsecutiveFailures: number = 5;\n private lastAdRequestTime: number = 0;\n private readonly minAdRequestIntervalMs: number = 2500;\n private readonly backoffBaseMs: number = 1000;\n private readonly maxBackoffMs: number = 15000;\n private readonly adTransitionGapMs: number = 1500;\n private placeholderContainer: HTMLDivElement | undefined;\n\n constructor(config: StormcloudVideoPlayerConfig) {\n initializePolyfills();\n\n const browserOverrides = getBrowserConfigOverrides();\n \n this.config = { ...browserOverrides, ...config };\n this.video = config.videoElement;\n\n logBrowserInfo(config.debugAdTiming);\n\n this.prebidManager = createPrebidManager(\n config.debugAdTiming !== undefined ? { debug: !!config.debugAdTiming } : {}\n );\n this.adLayer = createPrebidAdLayer(this.video, {\n continueLiveStreamDuringAds: false,\n debug: !!config.debugAdTiming,\n });\n }\n\n private async adRequest(): Promise<PrebidBidResponse[]> {\n await this.prebidManager.initialize();\n return this.prebidManager.requestBidsUntilResponse();\n }\n\n async load(): Promise<void> {\n if (!this.attached) {\n this.attach();\n }\n\n this.initializeTracking();\n\n if (this.shouldUseNativeHls()) {\n this.nativeHlsMode = true;\n this.videoSrcProtection = this.config.src;\n this.video.src = this.config.src;\n\n this.isLiveStream = this.config.lowLatencyMode ?? false;\n\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Using native HLS playback - VOD mode:\",\n {\n isLive: this.isLiveStream,\n allowNativeHls: this.config.allowNativeHls,\n adBehavior: \"vod (main video pauses during ads)\",\n }\n );\n }\n\n this.adLayer.updateOptions({ continueLiveStreamDuringAds: false, mainHlsInstance: null });\n\n if (this.config.autoplay) {\n await this.video.play()?.catch(() => {});\n }\n return;\n }\n\n this.hls = new Hls({\n enableWorker: true,\n backBufferLength: 30,\n liveDurationInfinity: true,\n lowLatencyMode: !!this.config.lowLatencyMode,\n maxLiveSyncPlaybackRate: this.config.lowLatencyMode ? 1.5 : 1.0,\n ...(this.config.lowLatencyMode ? { liveSyncDuration: 2 } : {}),\n maxBufferLength: 30,\n maxMaxBufferLength: 600,\n maxBufferSize: 60 * 1000 * 1000,\n maxBufferHole: 0.5,\n highBufferWatchdogPeriod: 2,\n nudgeOffset: 0.1,\n nudgeMaxRetry: 3,\n startPosition: -1,\n });\n\n this.hls.on(Hls.Events.MEDIA_ATTACHED, () => {\n this.hls?.loadSource(this.config.src);\n });\n\n this.hls.on(Hls.Events.MANIFEST_PARSED, async (_, data: any) => {\n if (this.config.allowNativeHls === false) {\n this.isLiveStream = true;\n } else {\n this.isLiveStream =\n this.hls?.levels?.some(\n (level) =>\n level?.details?.live === true || level?.details?.type === \"LIVE\"\n ) ?? false;\n }\n\n if (this.config.debugAdTiming) {\n const adBehavior = this.shouldContinueLiveStreamDuringAds()\n ? \"live (main video continues muted during ads)\"\n : \"vod (main video pauses during ads)\";\n console.log(\"[StormcloudVideoPlayer] Stream type detected:\", {\n isLive: this.isLiveStream,\n allowNativeHls: this.config.allowNativeHls,\n adBehavior,\n });\n }\n\n this.adLayer.updateOptions({\n continueLiveStreamDuringAds: this.shouldContinueLiveStreamDuringAds(),\n mainHlsInstance: this.hls ?? null,\n });\n\n this.bufferedSegmentsCount = 0;\n this.hasInitialBufferCompleted = false;\n this.shouldAutoplayAfterBuffering = !!this.config.autoplay;\n\n const minSegments = this.config.minSegmentsBeforePlay ?? 2;\n\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Waiting for\",\n minSegments,\n \"segments to buffer before playback\"\n );\n }\n\n if (minSegments === 0 || !this.config.autoplay) {\n this.hasInitialBufferCompleted = true;\n if (this.config.autoplay) {\n await this.video.play()?.catch(() => {});\n }\n }\n });\n\n this.hls.on(Hls.Events.LEVEL_LOADED, (_evt, data: any) => {\n if (this.inAdBreak || this.pendingAdBreak) {\n return;\n }\n\n const details = data?.details;\n if (!details || !details.fragments || details.fragments.length === 0) {\n return;\n }\n\n const fragmentsToScan = Math.min(5, details.fragments.length);\n \n for (let i = 0; i < fragmentsToScan; i++) {\n const frag = details.fragments[i];\n const tagList: any[] | undefined = frag?.tagList;\n \n if (!Array.isArray(tagList)) continue;\n\n for (const entry of tagList) {\n let tag = \"\";\n let value = \"\";\n \n if (Array.isArray(entry)) {\n tag = String(entry[0] ?? \"\");\n value = String(entry[1] ?? \"\");\n } else if (typeof entry === \"string\") {\n const idx = entry.indexOf(\":\");\n if (idx >= 0) {\n tag = entry.substring(0, idx);\n value = entry.substring(idx + 1);\n } else {\n tag = entry;\n }\n }\n\n if (!tag) continue;\n\n if (tag.includes(\"EXT-X-CUE-OUT\") || tag.includes(\"EXT-X-DATERANGE\")) {\n const attrs = tag.includes(\"EXT-X-DATERANGE\") \n ? this.parseAttributeList(value)\n : {};\n const hasScteOut = tag.includes(\"EXT-X-CUE-OUT\") || \n \"SCTE35-OUT\" in attrs || \n attrs[\"SCTE35-OUT\"] !== undefined;\n\n if (hasScteOut) {\n const durationSeconds = this.parseCueOutDuration(value);\n const marker: Scte35Marker = {\n type: \"start\",\n ...(durationSeconds !== undefined ? { durationSeconds } : {}),\n raw: { tag, value, earlyDetection: true },\n } as Scte35Marker;\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] 🎯 EARLY SCTE-35 DETECTION: Ad break marker found in fragment\", i, \"- starting pre-fetch (NOT playing yet)\");\n }\n\n this.startAdPrefetch(marker, frag?.sn);\n return;\n }\n }\n }\n }\n });\n\n this.hls.on(Hls.Events.FRAG_BUFFERED, async (_evt, data: any) => {\n if (this.hasInitialBufferCompleted) {\n return;\n }\n\n this.bufferedSegmentsCount++;\n const minSegments = this.config.minSegmentsBeforePlay ?? 2;\n\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Buffered segment ${this.bufferedSegmentsCount}/${minSegments}`\n );\n }\n\n if (this.bufferedSegmentsCount >= minSegments) {\n this.hasInitialBufferCompleted = true;\n\n if (this.shouldAutoplayAfterBuffering) {\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Initial buffer complete (${this.bufferedSegmentsCount} segments). Starting playback.`\n );\n }\n await this.video.play()?.catch((err) => {\n if (this.config.debugAdTiming) {\n console.warn(\"[StormcloudVideoPlayer] Autoplay failed:\", err);\n }\n });\n }\n }\n });\n\n this.hls.on(Hls.Events.FRAG_PARSING_METADATA, (_evt, data: any) => {\n const id3Tags: Id3TagInfo[] = (data?.samples || []).map((s: any) => ({\n key: \"ID3\",\n value: s?.data,\n ptsSeconds: s?.pts,\n }));\n id3Tags.forEach((tag) => this.onId3Tag(tag));\n });\n\n this.hls.on(Hls.Events.FRAG_CHANGED, (_evt, data: any) => {\n const frag = data?.frag;\n const tagList: any[] | undefined = frag?.tagList;\n if (!Array.isArray(tagList)) return;\n\n for (const entry of tagList) {\n let tag = \"\";\n let value = \"\";\n if (Array.isArray(entry)) {\n tag = String(entry[0] ?? \"\");\n value = String(entry[1] ?? \"\");\n } else if (typeof entry === \"string\") {\n const idx = entry.indexOf(\":\");\n if (idx >= 0) {\n tag = entry.substring(0, idx);\n value = entry.substring(idx + 1);\n } else {\n tag = entry;\n value = \"\";\n }\n }\n\n if (!tag) continue;\n if (tag.includes(\"EXT-X-CUE-OUT-CONT\")) {\n const prog = this.parseCueOutCont(value);\n const marker: Scte35Marker = {\n type: \"progress\",\n ...(prog?.duration !== undefined\n ? { durationSeconds: prog.duration }\n : {}),\n ...(prog?.elapsed !== undefined\n ? { ptsSeconds: prog.elapsed }\n : {}),\n raw: { tag, value },\n } as Scte35Marker;\n this.onScte35Marker(marker);\n } else if (tag.includes(\"EXT-X-CUE-OUT\")) {\n const durationSeconds = this.parseCueOutDuration(value);\n const marker: Scte35Marker = {\n type: \"start\",\n ...(durationSeconds !== undefined ? { durationSeconds } : {}),\n raw: { tag, value },\n } as Scte35Marker;\n this.onScte35Marker(marker);\n } else if (tag.includes(\"EXT-X-CUE-IN\")) {\n this.onScte35Marker({ type: \"end\", raw: { tag, value } });\n } else if (tag.includes(\"EXT-X-DATERANGE\")) {\n const attrs = this.parseAttributeList(value);\n const hasScteOut =\n \"SCTE35-OUT\" in attrs || attrs[\"SCTE35-OUT\"] !== undefined;\n const hasScteIn =\n \"SCTE35-IN\" in attrs || attrs[\"SCTE35-IN\"] !== undefined;\n const klass = String(attrs[\"CLASS\"] ?? \"\");\n const duration = this.toNumber(attrs[\"DURATION\"]);\n\n if (hasScteOut || /com\\.apple\\.hls\\.cue/i.test(klass)) {\n const marker: Scte35Marker = {\n type: \"start\",\n ...(duration !== undefined ? { durationSeconds: duration } : {}),\n raw: { tag, value, attrs },\n } as Scte35Marker;\n this.onScte35Marker(marker);\n }\n if (hasScteIn) {\n this.onScte35Marker({ type: \"end\", raw: { tag, value, attrs } });\n }\n }\n }\n });\n\n this.hls.on(Hls.Events.ERROR, (_evt, data) => {\n if (data?.fatal) {\n switch (data.type) {\n case Hls.ErrorTypes.NETWORK_ERROR:\n this.hls?.startLoad();\n break;\n case Hls.ErrorTypes.MEDIA_ERROR:\n this.hls?.recoverMediaError();\n break;\n default:\n this.destroy();\n break;\n }\n }\n });\n\n this.hls.attachMedia(this.video);\n }\n\n private getAdSource(): \"prebid\" {\n return \"prebid\";\n }\n\n private attachAdLayerEventListeners(): void {\n this.adLayer.on(\"ad_impression\", () => {\n if (this.config.licenseKey) {\n sendAdImpressionTracking(this.config.licenseKey, {\n source: this.getAdSource(),\n adIndex: this.currentAdIndex,\n timestamp: new Date().toISOString(),\n });\n }\n });\n this.adLayer.on(\"ad_error\", (errorPayload?: any) => {\n let errorMessage = \"Ad playback failed\";\n \n if (errorPayload) {\n const errorCode = errorPayload.code || errorPayload.errorCode || \"unknown\";\n const vastErrorCode = errorPayload.vastErrorCode;\n const message = errorPayload.message || errorPayload.errorMessage || \"Unknown error\";\n const cause = errorPayload.cause || errorPayload.innerError || errorPayload.error;\n \n errorMessage = `Ad error: AdError ${errorCode}: ${message}`;\n \n if (vastErrorCode && vastErrorCode !== \"N/A\" && vastErrorCode !== errorCode) {\n errorMessage += ` (VAST Error Code: ${vastErrorCode})`;\n }\n \n if (cause) {\n const causeMessage = typeof cause === \"string\" ? cause : (cause.message || String(cause));\n errorMessage += `. Caused by: ${causeMessage}`;\n }\n }\n \n console.error(\"[AD-ERROR]\", errorMessage, errorPayload || \"\");\n this.adLayer.stop().catch(() => {});\n this.handleAdFailure();\n });\n this.adLayer.on(\"content_pause\", () => {\n this.clearAdFailsafeTimer();\n this.clearAdRequestWatchdog();\n this.activeAdRequestToken = null;\n this.showAds = true;\n \n if (this.inAdBreak && this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {\n this.scheduleAdStopCountdown(this.getRemainingAdMs());\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Starting ad break timer on content_pause (first ad starting)\");\n }\n }\n\n this.adLayer.setAdVolume(\n this.adLayer.getOriginalMutedState() ? 0 : this.adLayer.getOriginalVolume()\n );\n\n if (this.isShowingPlaceholder) {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Hiding placeholder - new ads starting\");\n }\n this.hidePlaceholderLayer();\n this.adLayer.hidePlaceholder();\n this.isShowingPlaceholder = false;\n }\n });\n this.adLayer.on(\"content_resume\", () => {\n const remaining = this.getRemainingAdMs();\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] content_resume received, inAdBreak=%s, remaining=%s, pendingNext=%s\",\n this.inAdBreak,\n remaining,\n !!this.pendingNextAdBids\n );\n }\n\n this.clearAdFailsafeTimer();\n this.clearAdRequestWatchdog();\n this.activeAdRequestToken = null;\n this.showAds = false;\n\n if (!this.inAdBreak) {\n const restoredMuted = this.adLayer.getOriginalMutedState();\n const restoredVolume = this.adLayer.getOriginalVolume();\n if (this.video.muted !== restoredMuted) this.video.muted = restoredMuted;\n if (Math.abs(this.video.volume - restoredVolume) > 0.01) this.video.volume = restoredVolume;\n return;\n }\n\n this.consecutiveFailures = 0;\n\n if (this.pendingNextAdBids && this.pendingNextAdBids.length > 0) {\n const bids = [...this.pendingNextAdBids];\n this.pendingNextAdBids = null;\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n }\n this.showPlaceholderLayer();\n this.adLayer.showPlaceholder();\n setTimeout(() => {\n if (!this.inAdBreak || bids.length === 0) return;\n this.currentAdIndex++;\n this.adLayer.playAd(bids).catch((err) => {\n if (this.config.debugAdTiming) console.warn(\"[StormcloudVideoPlayer] playAd(pending) failed:\", err);\n this.handleAdFailure();\n });\n }, this.adTransitionGapMs);\n return;\n }\n\n if (remaining <= 500 && this.expectedAdBreakDurationMs != null) {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] content_resume: remaining time low and duration known, ending ad pod\");\n }\n this.handleAdPodComplete();\n } else {\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n }\n }\n });\n }\n\n private ensurePlaceholderContainer(): void {\n if (this.placeholderContainer) {\n return;\n }\n\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 = \"5\";\n container.style.backgroundColor = \"#000\";\n container.style.transition = \"opacity 0.3s ease-in-out\";\n container.style.opacity = \"0\";\n\n if (!this.video.parentElement) {\n if (this.config.debugAdTiming) {\n console.warn(\"[StormcloudVideoPlayer] Video element has no parent for placeholder container\");\n }\n return;\n }\n\n this.video.parentElement.appendChild(container);\n this.placeholderContainer = container;\n }\n\n private showPlaceholderLayer(): void {\n this.ensurePlaceholderContainer();\n \n if (!this.placeholderContainer) {\n return;\n }\n\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Muted video when showing placeholder\");\n }\n }\n\n const wasHidden = this.placeholderContainer.style.display === \"none\" || this.placeholderContainer.style.opacity === \"0\";\n if (wasHidden) {\n this.placeholderContainer.style.transition = \"none\";\n } else {\n this.placeholderContainer.style.transition = \"opacity 0.3s ease-in-out\";\n }\n \n this.placeholderContainer.style.backgroundColor = \"#000\";\n this.placeholderContainer.style.display = \"flex\";\n this.placeholderContainer.offsetHeight;\n this.placeholderContainer.style.opacity = \"1\";\n this.placeholderContainer.style.pointerEvents = \"auto\";\n \n if (wasHidden) {\n requestAnimationFrame(() => {\n if (this.placeholderContainer) {\n this.placeholderContainer.style.transition = \"opacity 0.3s ease-in-out\";\n }\n });\n }\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Showing placeholder layer\");\n }\n }\n\n private hidePlaceholderLayer(): void {\n if (!this.placeholderContainer) {\n return;\n }\n\n this.placeholderContainer.style.opacity = \"0\";\n setTimeout(() => {\n if (this.placeholderContainer) {\n this.placeholderContainer.style.display = \"none\";\n this.placeholderContainer.style.pointerEvents = \"none\";\n this.placeholderContainer.style.backgroundColor = \"#000\";\n }\n }, 300);\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Hiding placeholder layer\");\n }\n }\n\n private attach(): void {\n if (this.attached) return;\n this.attached = true;\n this.video.autoplay = !!this.config.autoplay;\n this.video.muted = !!this.config.muted;\n\n this.adLayer.initialize();\n this.adLayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n this.attachAdLayerEventListeners();\n\n this.timeUpdateHandler = () => {\n this.onTimeUpdate(this.video.currentTime);\n };\n this.video.addEventListener(\"timeupdate\", this.timeUpdateHandler);\n\n this.emptiedHandler = () => {\n if (\n this.nativeHlsMode &&\n this.videoSrcProtection &&\n !this.adLayer.isAdPlaying()\n ) {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Video src was cleared, restoring:\",\n this.videoSrcProtection\n );\n }\n const currentTime = this.video.currentTime;\n const wasPaused = this.video.paused;\n this.video.src = this.videoSrcProtection;\n this.video.currentTime = currentTime;\n if (!wasPaused) {\n this.video.play().catch(() => {});\n }\n }\n };\n this.video.addEventListener(\"emptied\", this.emptiedHandler);\n }\n\n private shouldUseNativeHls(): boolean {\n const streamType = this.getStreamType();\n\n if (streamType === \"other\") {\n return true;\n }\n\n const canNative = this.video.canPlayType(\"application/vnd.apple.mpegurl\");\n return !!(this.config.allowNativeHls && canNative);\n }\n\n private onId3Tag(tag: Id3TagInfo): void {\n if (typeof tag.ptsSeconds === \"number\") {\n this.updatePtsDrift(tag.ptsSeconds);\n }\n const marker = this.parseScte35FromId3(tag);\n if (marker) {\n this.onScte35Marker(marker);\n }\n }\n\n private parseScte35FromId3(tag: Id3TagInfo): Scte35Marker | undefined {\n const text = this.decodeId3ValueToText(tag.value);\n if (!text) return undefined;\n\n const cueOutMatch =\n text.match(/EXT-X-CUE-OUT(?::([^\\r\\n]*))?/i) ||\n text.match(/CUE-OUT(?::([^\\r\\n]*))?/i);\n if (cueOutMatch) {\n const arg = (cueOutMatch[1] ?? \"\").trim();\n const dur = this.parseCueOutDuration(arg);\n const marker: Scte35Marker = {\n type: \"start\",\n ...(tag.ptsSeconds !== undefined ? { ptsSeconds: tag.ptsSeconds } : {}),\n ...(dur !== undefined ? { durationSeconds: dur } : {}),\n raw: { id3: text },\n } as Scte35Marker;\n return marker;\n }\n\n const cueOutContMatch = text.match(/EXT-X-CUE-OUT-CONT:([^\\r\\n]*)/i);\n if (cueOutContMatch) {\n const arg = (cueOutContMatch[1] ?? \"\").trim();\n const cont = this.parseCueOutCont(arg);\n const marker: Scte35Marker = {\n type: \"progress\",\n ...(tag.ptsSeconds !== undefined ? { ptsSeconds: tag.ptsSeconds } : {}),\n ...(cont?.duration !== undefined\n ? { durationSeconds: cont.duration }\n : {}),\n raw: { id3: text },\n } as Scte35Marker;\n return marker;\n }\n\n const cueInMatch = text.match(/EXT-X-CUE-IN\\b/i) || text.match(/CUE-IN\\b/i);\n if (cueInMatch) {\n const marker: Scte35Marker = {\n type: \"end\",\n ...(tag.ptsSeconds !== undefined ? { ptsSeconds: tag.ptsSeconds } : {}),\n raw: { id3: text },\n } as Scte35Marker;\n return marker;\n }\n\n const daterangeMatch = text.match(/EXT-X-DATERANGE:([^\\r\\n]*)/i);\n if (daterangeMatch) {\n const attrs = this.parseAttributeList(daterangeMatch[1] ?? \"\");\n const hasScteOut =\n \"SCTE35-OUT\" in attrs || attrs[\"SCTE35-OUT\"] !== undefined;\n const hasScteIn =\n \"SCTE35-IN\" in attrs || attrs[\"SCTE35-IN\"] !== undefined;\n const klass = String(attrs[\"CLASS\"] ?? \"\");\n const duration = this.toNumber(attrs[\"DURATION\"]);\n if (hasScteOut || /com\\.apple\\.hls\\.cue/i.test(klass)) {\n const marker: Scte35Marker = {\n type: \"start\",\n ...(tag.ptsSeconds !== undefined\n ? { ptsSeconds: tag.ptsSeconds }\n : {}),\n ...(duration !== undefined ? { durationSeconds: duration } : {}),\n raw: { id3: text, attrs },\n } as Scte35Marker;\n return marker;\n }\n if (hasScteIn) {\n const marker: Scte35Marker = {\n type: \"end\",\n ...(tag.ptsSeconds !== undefined\n ? { ptsSeconds: tag.ptsSeconds }\n : {}),\n raw: { id3: text, attrs },\n } as Scte35Marker;\n return marker;\n }\n }\n\n if (/SCTE35-OUT/i.test(text)) {\n const marker: Scte35Marker = {\n type: \"start\",\n ...(tag.ptsSeconds !== undefined ? { ptsSeconds: tag.ptsSeconds } : {}),\n raw: { id3: text },\n } as Scte35Marker;\n return marker;\n }\n if (/SCTE35-IN/i.test(text)) {\n const marker: Scte35Marker = {\n type: \"end\",\n ...(tag.ptsSeconds !== undefined ? { ptsSeconds: tag.ptsSeconds } : {}),\n raw: { id3: text },\n } as Scte35Marker;\n return marker;\n }\n\n if (tag.value instanceof Uint8Array) {\n const bin = this.parseScte35Binary(tag.value);\n if (bin) return bin;\n }\n\n return undefined;\n }\n\n private decodeId3ValueToText(value: string | Uint8Array): string | undefined {\n try {\n if (typeof value === \"string\") return value;\n const decoder = new TextDecoder(\"utf-8\", { fatal: false });\n const text = decoder.decode(value);\n if (text && /[\\x20-\\x7E]/.test(text)) return text;\n let out = \"\";\n for (let i = 0; i < value.length; i++)\n out += String.fromCharCode(value[i]!);\n return out;\n } catch {\n return undefined;\n }\n }\n\n private onScte35Marker(marker: Scte35Marker): void {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] SCTE-35 marker detected:\", {\n type: marker.type,\n ptsSeconds: marker.ptsSeconds,\n durationSeconds: marker.durationSeconds,\n currentTime: this.video.currentTime,\n raw: marker.raw,\n hasPendingAdBreak: !!this.pendingAdBreak,\n });\n }\n\n if (marker.type === \"start\") {\n this.savedMutedStateBeforeScte = {\n muted: this.video.muted,\n volume: this.video.volume,\n };\n this.adLayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Muted video on SCTE start marker\");\n }\n }\n\n if (this.inAdBreak) {\n if (this.expectedAdBreakDurationMs == null && marker.durationSeconds != null) {\n this.expectedAdBreakDurationMs = marker.durationSeconds * 1000;\n if (this.config.debugAdTiming) {\n console.log(`[StormcloudVideoPlayer] Updated ad break duration from subsequent marker: ${this.expectedAdBreakDurationMs}ms`);\n }\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n return;\n }\n\n this.inAdBreak = true;\n const durationMs =\n marker.durationSeconds != null\n ? marker.durationSeconds * 1000\n : (this.pendingAdBreak?.marker.durationSeconds != null \n ? this.pendingAdBreak.marker.durationSeconds * 1000 \n : undefined);\n this.expectedAdBreakDurationMs = durationMs;\n this.currentAdBreakStartWallClockMs = Date.now();\n\n if (this.config.licenseKey) {\n const adDetectInfo = {\n source: \"scte35\" as const,\n timestamp: new Date().toISOString(),\n ...(marker.durationSeconds != null && { durationSeconds: marker.durationSeconds }),\n ...(marker.ptsSeconds != null && { ptsSeconds: marker.ptsSeconds }),\n ...(this.pendingAdBreak?.detectedAtFragmentSn != null && {\n detectedAtFragmentSn: this.pendingAdBreak.detectedAtFragmentSn,\n }),\n };\n sendAdDetectTracking(this.config.licenseKey, adDetectInfo);\n }\n\n const isManifestMarker = this.isManifestBasedMarker(marker);\n const forceImmediate = this.config.immediateManifestAds ?? true;\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Ad start decision:\", {\n isManifestMarker,\n forceImmediate,\n hasPts: typeof marker.ptsSeconds === \"number\",\n });\n }\n\n if (isManifestMarker && forceImmediate) {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Starting ad immediately (manifest-based)\"\n );\n }\n this.clearAdStartTimer();\n this.handleAdStart(marker);\n } else if (typeof marker.ptsSeconds === \"number\") {\n const tol = this.config.driftToleranceMs ?? 1000;\n const nowMs = this.video.currentTime * 1000;\n const estCurrentPtsMs = nowMs - this.ptsDriftEmaMs;\n const deltaMs = Math.floor(marker.ptsSeconds * 1000 - estCurrentPtsMs);\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] PTS-based timing calculation:\", {\n nowMs,\n estCurrentPtsMs,\n markerPtsMs: marker.ptsSeconds * 1000,\n deltaMs,\n tolerance: tol,\n });\n }\n\n if (deltaMs > tol) {\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Scheduling ad start in ${deltaMs}ms`\n );\n }\n this.scheduleAdStartIn(deltaMs);\n } else {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Starting ad immediately (within tolerance)\"\n );\n }\n this.clearAdStartTimer();\n this.handleAdStart(marker);\n }\n } else {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Starting ad immediately (fallback)\"\n );\n }\n this.clearAdStartTimer();\n this.handleAdStart(marker);\n }\n if (this.expectedAdBreakDurationMs != null) {\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n return;\n }\n if (marker.type === \"progress\" && this.inAdBreak) {\n if (marker.durationSeconds != null) {\n this.expectedAdBreakDurationMs = marker.durationSeconds * 1000;\n }\n if (\n this.expectedAdBreakDurationMs != null &&\n this.currentAdBreakStartWallClockMs != null\n ) {\n const elapsedMs = Date.now() - this.currentAdBreakStartWallClockMs;\n const remainingMs = Math.max(\n 0,\n this.expectedAdBreakDurationMs - elapsedMs\n );\n this.scheduleAdStopCountdown(remainingMs);\n }\n \n if (!this.adLayer.isAdPlaying() && this.pendingNextAdBids != null && this.pendingNextAdBids.length > 0) {\n const bids = this.pendingNextAdBids;\n this.pendingNextAdBids = null;\n this.currentAdIndex++;\n this.adLayer.playAd(bids).catch(() => this.handleAdFailure());\n }\n return;\n }\n if (marker.type === \"end\") {\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Muted video on SCTE end marker\");\n }\n }\n\n const remaining = this.getRemainingAdMs();\n const adPlaying = this.adLayer.isAdPlaying();\n const hasQueuedAds = this.pendingNextAdBids != null && this.pendingNextAdBids.length > 0;\n \n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] SCTE-35 end marker received:\", {\n remaining,\n adPlaying,\n hasQueuedAds,\n activeAdRequest: this.activeAdRequestToken !== null,\n });\n }\n \n if (adPlaying || remaining > 500) {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Ignoring premature SCTE-35 end marker - ads still active or time remaining\");\n }\n return;\n }\n \n this.inAdBreak = false;\n this.expectedAdBreakDurationMs = undefined;\n this.currentAdBreakStartWallClockMs = undefined;\n this.clearAdStartTimer();\n this.clearAdStopTimer();\n \n if (adPlaying) {\n this.adLayer.stop().catch(() => {});\n }\n \n this.handleAdPodComplete();\n return;\n }\n }\n\n private parseCueOutDuration(value: string): number | undefined {\n const num = parseFloat(value.trim());\n if (!Number.isNaN(num)) return num;\n const match =\n value.match(/(?:^|[,\\s])DURATION\\s*=\\s*([0-9.]+)/i) ||\n value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n if (match && match[1] != null) {\n const dStr = match[1];\n const d = parseFloat(dStr);\n return Number.isNaN(d) ? undefined : d;\n }\n return undefined;\n }\n\n private parseCueOutCont(\n value: string\n ): { elapsed?: number; duration?: number } | undefined {\n const res: { elapsed?: number; duration?: number } = {};\n \n const elapsedMatch = value.match(/Elapsed\\s*=\\s*([0-9.]+)/i);\n const durationMatch = value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n if (elapsedMatch && elapsedMatch[1] != null) {\n const e = parseFloat(elapsedMatch[1]);\n if (!Number.isNaN(e)) res.elapsed = e;\n }\n if (durationMatch && durationMatch[1] != null) {\n const d = parseFloat(durationMatch[1]);\n if (!Number.isNaN(d)) res.duration = d;\n }\n \n if (!(\"elapsed\" in res) || !(\"duration\" in res)) {\n const slashMatch = value.match(/([0-9.]+)\\s*\\/\\s*([0-9.]+)/);\n if (slashMatch && slashMatch[1] && slashMatch[2]) {\n const elapsed = parseFloat(slashMatch[1]);\n const duration = parseFloat(slashMatch[2]);\n if (!Number.isNaN(elapsed) && !(\"elapsed\" in res)) res.elapsed = elapsed;\n if (!Number.isNaN(duration) && !(\"duration\" in res)) res.duration = duration;\n }\n }\n \n if (\"elapsed\" in res || \"duration\" in res) return res;\n return undefined;\n }\n\n private parseAttributeList(value: string): Record<string, string> {\n const attrs: Record<string, string> = {};\n const regex = /([A-Z0-9-]+)=((\"[^\"]*\")|([^\",]*))(?:,|$)/gi;\n let match: RegExpExecArray | null;\n while ((match = regex.exec(value)) !== null) {\n const key: string = (match[1] ?? \"\") as string;\n let rawVal: string = (match[3] ?? match[4] ?? \"\") as string;\n if (rawVal.startsWith('\"') && rawVal.endsWith('\"')) {\n rawVal = rawVal.slice(1, -1);\n }\n if (key) {\n attrs[key] = rawVal;\n }\n }\n return attrs;\n }\n\n private toNumber(val: unknown): number | undefined {\n if (val == null) return undefined;\n const n = typeof val === \"string\" ? parseFloat(val) : Number(val);\n return Number.isNaN(n) ? undefined : n;\n }\n\n private isManifestBasedMarker(marker: Scte35Marker): boolean {\n const raw = marker.raw as any;\n if (!raw) return false;\n\n if (raw.tag) {\n const tag = String(raw.tag);\n return (\n tag.includes(\"EXT-X-CUE-OUT\") ||\n tag.includes(\"EXT-X-CUE-IN\") ||\n tag.includes(\"EXT-X-DATERANGE\")\n );\n }\n\n if (raw.id3) return false;\n\n if (raw.splice_command_type) return false;\n\n return false;\n }\n\n private parseScte35Binary(data: Uint8Array): Scte35Marker | undefined {\n class BitReader {\n private bytePos = 0;\n private bitPos = 0;\n constructor(private readonly buf: Uint8Array) {}\n readBits(numBits: number): number {\n let result = 0;\n while (numBits > 0) {\n if (this.bytePos >= this.buf.length) return result;\n const remainingInByte = 8 - this.bitPos;\n const toRead = Math.min(numBits, remainingInByte);\n const currentByte = this.buf[this.bytePos]!;\n const shift = remainingInByte - toRead;\n const mask = ((1 << toRead) - 1) & 0xff;\n const bits = (currentByte >> shift) & mask;\n result = (result << toRead) | bits;\n this.bitPos += toRead;\n if (this.bitPos >= 8) {\n this.bitPos = 0;\n this.bytePos += 1;\n }\n numBits -= toRead;\n }\n return result >>> 0;\n }\n skipBits(n: number): void {\n this.readBits(n);\n }\n }\n\n const r = new BitReader(data);\n const tableId = r.readBits(8);\n if (tableId !== 0xfc) return undefined;\n r.readBits(1);\n r.readBits(1);\n r.readBits(2);\n const sectionLength = r.readBits(12);\n r.readBits(8);\n r.readBits(1);\n r.readBits(6);\n const ptsAdjHigh = r.readBits(1);\n const ptsAdjLow = r.readBits(32);\n void ptsAdjHigh;\n void ptsAdjLow;\n r.readBits(8);\n r.readBits(12);\n const spliceCommandLength = r.readBits(12);\n const spliceCommandType = r.readBits(8);\n if (spliceCommandType !== 5) {\n return undefined;\n }\n r.readBits(32);\n const cancel = r.readBits(1) === 1;\n r.readBits(7);\n if (cancel) return undefined;\n const outOfNetwork = r.readBits(1) === 1;\n const programSpliceFlag = r.readBits(1) === 1;\n const durationFlag = r.readBits(1) === 1;\n const spliceImmediateFlag = r.readBits(1) === 1;\n r.readBits(4);\n if (programSpliceFlag && !spliceImmediateFlag) {\n const timeSpecifiedFlag = r.readBits(1) === 1;\n if (timeSpecifiedFlag) {\n r.readBits(6);\n r.readBits(33);\n } else {\n r.readBits(7);\n }\n } else if (!programSpliceFlag) {\n const componentCount = r.readBits(8);\n for (let i = 0; i < componentCount; i++) {\n r.readBits(8);\n if (!spliceImmediateFlag) {\n const timeSpecifiedFlag = r.readBits(1) === 1;\n if (timeSpecifiedFlag) {\n r.readBits(6);\n r.readBits(33);\n } else {\n r.readBits(7);\n }\n }\n }\n }\n let durationSeconds: number | undefined = undefined;\n if (durationFlag) {\n r.readBits(6);\n r.readBits(1);\n const high = r.readBits(1);\n const low = r.readBits(32);\n const durationTicks = high * 0x100000000 + low;\n durationSeconds = durationTicks / 90000;\n }\n r.readBits(16);\n r.readBits(8);\n r.readBits(8);\n\n if (outOfNetwork) {\n const marker: Scte35Marker = {\n type: \"start\",\n ...(durationSeconds !== undefined ? { durationSeconds } : {}),\n raw: { splice_command_type: 5 },\n } as Scte35Marker;\n return marker;\n }\n return undefined;\n }\n\n private initializeTracking(): void {\n sendInitialTracking(this.config.licenseKey)\n .then(() => {\n this.heartbeatInterval = window.setInterval(() => {\n this.sendHeartbeatIfNeeded();\n }, 5000);\n })\n .catch((error) => {\n if (this.config.debugAdTiming) {\n console.warn(\n \"[StormcloudVideoPlayer] Failed to send initial tracking:\",\n error\n );\n }\n this.heartbeatInterval = window.setInterval(() => {\n this.sendHeartbeatIfNeeded();\n }, 5000);\n });\n }\n\n private sendHeartbeatIfNeeded(): void {\n const now = Date.now();\n if (!this.lastHeartbeatTime || now - this.lastHeartbeatTime > 30000) {\n this.lastHeartbeatTime = now;\n sendHeartbeat(this.config.licenseKey).catch((error) => {\n if (this.config.debugAdTiming) {\n console.warn(\n \"[StormcloudVideoPlayer] Failed to send heartbeat:\",\n error\n );\n }\n });\n }\n }\n\n getCurrentAdIndex(): number {\n return this.currentAdIndex;\n }\n\n getTotalAdsInBreak(): number {\n return this.totalAdsInBreak;\n }\n\n isAdPlaying(): boolean {\n return this.inAdBreak && this.adLayer.isAdPlaying();\n }\n\n isShowingAds(): boolean {\n return this.showAds;\n }\n\n getStreamType(): \"hls\" | \"other\" {\n const url = this.config.src.toLowerCase();\n if (\n url.includes(\".m3u8\") ||\n url.includes(\"/hls/\") ||\n url.includes(\"application/vnd.apple.mpegurl\")\n ) {\n return \"hls\";\n }\n return \"other\";\n }\n\n shouldShowNativeControls(): boolean {\n const streamType = this.getStreamType();\n if (streamType === \"other\") {\n return !(this.config.showCustomControls ?? false);\n }\n return !!(\n this.config.allowNativeHls && !(this.config.showCustomControls ?? false)\n );\n }\n\n private shouldContinueLiveStreamDuringAds(): boolean {\n if (this.config.allowNativeHls) {\n return false;\n }\n\n if (!this.isLiveStream) {\n return false;\n }\n\n return true;\n }\n\n private startAdPrefetch(marker: Scte35Marker, fragmentSn?: number): void {\n if (this.pendingAdBreak || this.inAdBreak) {\n return;\n }\n\n this.pendingAdBreak = {\n marker,\n ...(fragmentSn !== undefined ? { detectedAtFragmentSn: fragmentSn } : {}),\n isFetching: false,\n fetchStartTime: Date.now(),\n };\n\n void this.adRequest().then(() => {}).catch(() => {\n if (this.config.debugAdTiming) {\n console.log(\"[PREFETCH] Prebid auction prefetch failed, will request at playback time\");\n }\n });\n\n if (this.config.debugAdTiming) {\n console.log(\"[PREFETCH] Ad break marker registered, auction prefetch started\");\n }\n }\n\n private clearPendingAdBreak(): void {\n if (this.prefetchTimerId != null) {\n clearTimeout(this.prefetchTimerId);\n this.prefetchTimerId = undefined;\n }\n this.pendingAdBreak = null;\n }\n\n private startContinuousFetchLoop(): void {\n if (this.continuousFetchLoopPromise != null) return;\n this.continuousFetchLoopPromise = this.runContinuousFetchLoop();\n }\n\n private async runContinuousFetchLoop(): Promise<void> {\n const backoffMs = () => {\n const mult = Math.pow(2, this.consecutiveFailures);\n return Math.min(this.backoffBaseMs * mult, this.maxBackoffMs);\n };\n while (this.inAdBreak && this.continuousFetchingActive) {\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) break;\n if (this.totalAdRequestsInBreak >= this.maxTotalAdRequestsPerBreak) break;\n const delay = this.lastAdRequestTime ? this.minAdRequestIntervalMs + (this.consecutiveFailures > 0 ? backoffMs() : 0) : 0;\n const elapsed = Date.now() - this.lastAdRequestTime;\n if (elapsed < delay && this.lastAdRequestTime > 0) {\n await new Promise((r) => setTimeout(r, delay - elapsed));\n }\n if (!this.inAdBreak || !this.continuousFetchingActive) break;\n try {\n const bids = await this.adRequest();\n this.lastAdRequestTime = Date.now();\n if (!this.inAdBreak) break;\n if (bids.length > 0) {\n this.consecutiveFailures = 0;\n if (this.adLayer.isAdPlaying()) {\n this.pendingNextAdBids = bids;\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] Next ad response stored (ad currently playing)\");\n }\n } else {\n this.currentAdIndex++;\n if (this.config.licenseKey) {\n sendAdLoadedTracking(this.config.licenseKey, {\n source: this.getAdSource(),\n timestamp: new Date().toISOString(),\n });\n }\n await this.adLayer.playAd(bids);\n if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {\n this.scheduleAdStopCountdown(this.getRemainingAdMs());\n }\n this.adLayer.setAdVolume(\n this.adLayer.getOriginalMutedState() ? 0 : this.adLayer.getOriginalVolume()\n );\n }\n } else {\n this.consecutiveFailures++;\n }\n } catch (err) {\n this.consecutiveFailures++;\n if (this.config.debugAdTiming) {\n console.warn(\"[CONTINUOUS-FETCH] adRequest failed:\", err);\n }\n }\n await new Promise((r) => setTimeout(r, backoffMs()));\n }\n this.continuousFetchLoopPromise = null;\n }\n\n private async handleAdStart(_marker: Scte35Marker): Promise<void> {\n const adBreakDurationMs =\n _marker.durationSeconds != null\n ? _marker.durationSeconds * 1000\n : undefined;\n\n if (this.config.debugAdTiming) {\n const mode = this.isLiveStream ? \"LIVE\" : \"VOD\";\n console.log(\n `[CONTINUOUS-FETCH] 📺 ${mode} MODE: Target duration=${adBreakDurationMs}ms`\n );\n }\n\n this.consecutiveFailures = 0;\n this.continuousFetchingActive = true;\n this.continuousFetchLoopPromise = null;\n this.pendingNextAdBids = null;\n this.isShowingPlaceholder = false;\n this.totalAdRequestsInBreak = 0;\n\n const state = this.savedMutedStateBeforeScte ?? {\n muted: this.video.muted,\n volume: this.video.volume,\n };\n this.adLayer.updateOriginalMutedState(state.muted, state.volume);\n this.savedMutedStateBeforeScte = null;\n\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Muted video in handleAdStart\");\n }\n }\n\n this.inAdBreak = true;\n this.currentAdBreakStartWallClockMs = Date.now();\n this.currentAdIndex = 0;\n this.totalAdsInBreak = 1;\n this.adPodQueue = [];\n\n this.showAds = true;\n\n this.showPlaceholderLayer();\n this.adLayer.showPlaceholder();\n\n if (\n this.expectedAdBreakDurationMs == null &&\n adBreakDurationMs != null\n ) {\n this.expectedAdBreakDurationMs = adBreakDurationMs;\n }\n\n this.clearPendingAdBreak();\n\n try {\n this.lastAdRequestTime = Date.now();\n const bids = await this.adRequest();\n if (!this.inAdBreak) return;\n if (bids.length > 0) {\n this.consecutiveFailures = 0;\n if (this.config.licenseKey) {\n sendAdLoadedTracking(this.config.licenseKey, {\n source: this.getAdSource(),\n timestamp: new Date().toISOString(),\n });\n }\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] ✅ First ad request successful, starting playback\");\n }\n this.currentAdIndex++;\n await this.adLayer.playAd(bids);\n if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {\n this.scheduleAdStopCountdown(this.getRemainingAdMs());\n }\n const adVolume = state.muted ? 0 : state.volume;\n this.adLayer.setAdVolume(adVolume);\n } else {\n this.consecutiveFailures++;\n await this.showPlaceholderAndWaitForAds();\n }\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\"[CONTINUOUS-FETCH] ⚠️ First ad request failed:\", error);\n }\n this.consecutiveFailures++;\n await this.showPlaceholderAndWaitForAds();\n }\n\n this.startContinuousFetchLoop();\n }\n\n private stopContinuousFetching(): void {\n this.continuousFetchingActive = false;\n \n this.hidePlaceholderLayer();\n \n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] 🛑 Stopping continuous ad fetching\");\n }\n }\n\n private async tryNextAvailableAdWithRateLimit(): Promise<void> {\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] 🛑 Too many consecutive failures (${this.consecutiveFailures}), ending ad break gracefully`);\n }\n this.handleAdPodComplete();\n return;\n }\n\n const backoffMultiplier = Math.pow(2, this.consecutiveFailures);\n const backoffDelay = Math.min(this.backoffBaseMs * backoffMultiplier, this.maxBackoffMs);\n const effectiveMinInterval = this.minAdRequestIntervalMs + (this.consecutiveFailures > 0 ? backoffDelay : 0);\n \n const timeSinceLastRequest = Date.now() - this.lastAdRequestTime;\n if (timeSinceLastRequest < effectiveMinInterval) {\n const waitTime = effectiveMinInterval - timeSinceLastRequest;\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] ⏳ Rate limiting: waiting ${waitTime}ms before next request (backoff: ${this.consecutiveFailures} failures)`);\n }\n await new Promise(resolve => setTimeout(resolve, waitTime));\n }\n\n return this.tryNextAvailableAd(0);\n }\n\n private async tryNextAvailableAd(_retryCount: number = 0): Promise<void> {\n if (this.totalAdRequestsInBreak >= this.maxTotalAdRequestsPerBreak) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] 🛑 Max ad requests per break (${this.maxTotalAdRequestsPerBreak}) reached`);\n }\n this.handleAdPodComplete();\n return;\n }\n const remaining = this.getRemainingAdMs();\n if (remaining <= 500 && this.expectedAdBreakDurationMs != null) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] ⏹️ No time remaining, ending ad break\");\n }\n this.handleAdPodComplete();\n return;\n }\n\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] 🛑 Too many consecutive failures (${this.consecutiveFailures}), ending ad break`);\n }\n this.handleAdPodComplete();\n return;\n }\n\n try {\n this.lastAdRequestTime = Date.now();\n const bids = await this.adRequest();\n if (!this.inAdBreak) return;\n if (bids.length > 0) {\n this.consecutiveFailures = 0;\n this.currentAdIndex++;\n this.totalAdRequestsInBreak++;\n if (this.adLayer.isAdPlaying()) {\n this.pendingNextAdBids = bids;\n } else {\n if (this.config.licenseKey) {\n sendAdLoadedTracking(this.config.licenseKey, {\n source: this.getAdSource(),\n timestamp: new Date().toISOString(),\n });\n }\n await this.adLayer.playAd(bids);\n if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {\n this.scheduleAdStopCountdown(this.getRemainingAdMs());\n }\n this.adLayer.setAdVolume(\n this.adLayer.getOriginalMutedState() ? 0 : this.adLayer.getOriginalVolume()\n );\n }\n } else {\n this.consecutiveFailures++;\n await this.showPlaceholderAndWaitForAds();\n }\n } catch (error) {\n this.consecutiveFailures++;\n if (this.config.debugAdTiming) {\n console.warn(\"[CONTINUOUS-FETCH] tryNextAvailableAd request failed:\", error);\n }\n await this.showPlaceholderAndWaitForAds();\n }\n }\n\n private async showPlaceholderAndWaitForAds(): Promise<void> {\n const remaining = this.getRemainingAdMs();\n const waitTime = Math.min(this.maxPlaceholderDurationMs, remaining);\n\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] 🛑 Skipping placeholder - too many consecutive failures\");\n }\n this.handleAdPodComplete();\n return;\n }\n\n if (waitTime < 1000) {\n this.handleAdPodComplete();\n return;\n }\n\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] ⬛ Showing placeholder for ${waitTime}ms while waiting for ad response`);\n }\n\n this.isShowingPlaceholder = true;\n this.adLayer.showPlaceholder();\n\n const checkInterval = 300;\n const maxChecks = Math.floor(waitTime / checkInterval);\n\n for (let i = 0; i < maxChecks; i++) {\n await new Promise((resolve) => setTimeout(resolve, checkInterval));\n\n if (!this.inAdBreak) return;\n\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] 🛑 Too many failures during placeholder wait\");\n }\n break;\n }\n\n if (this.pendingNextAdBids != null && this.pendingNextAdBids.length > 0) {\n const bids = this.pendingNextAdBids;\n this.pendingNextAdBids = null;\n this.isShowingPlaceholder = false;\n this.adLayer.hidePlaceholder();\n this.currentAdIndex++;\n try {\n await this.adLayer.playAd(bids);\n this.consecutiveFailures = 0;\n } catch {\n this.consecutiveFailures++;\n await this.tryNextAvailableAdWithRateLimit();\n }\n return;\n }\n\n if (this.adLayer.isAdPlaying()) {\n this.isShowingPlaceholder = false;\n this.adLayer.hidePlaceholder();\n return;\n }\n }\n\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] ⏰ Placeholder timeout, ending ad break\");\n }\n\n this.isShowingPlaceholder = false;\n this.adLayer.hidePlaceholder();\n this.handleAdPodComplete();\n }\n\n private onTimeUpdate(_currentTimeSec: number): void {\n if (this.adLayer.isAdPlaying()) return;\n }\n\n private scheduleAdStopCountdown(remainingMs: number): void {\n this.clearAdStopTimer();\n const ms = Math.max(0, Math.floor(remainingMs));\n if (ms === 0) {\n this.ensureAdStoppedByTimer();\n return;\n }\n this.adStopTimerId = window.setTimeout(() => {\n this.ensureAdStoppedByTimer();\n }, ms) as unknown as number;\n }\n\n private clearAdStopTimer(): void {\n if (this.adStopTimerId != null) {\n clearTimeout(this.adStopTimerId);\n this.adStopTimerId = undefined;\n }\n }\n\n private ensureAdStoppedByTimer(): void {\n if (!this.inAdBreak) return;\n\n this.adStopTimerId = undefined;\n\n const adPlaying = this.adLayer.isAdPlaying();\n const pendingAds = this.adPodQueue.length > 0;\n const checkIntervalMs = Math.max(\n 250,\n Math.floor(this.config.adBreakCheckIntervalMs ?? 1000)\n );\n const maxExtensionMsConfig = this.config.maxAdBreakExtensionMs;\n const maxExtensionMs =\n typeof maxExtensionMsConfig === \"number\" && maxExtensionMsConfig > 0\n ? maxExtensionMsConfig\n : 60000;\n\n let elapsedSinceStartMs = 0;\n if (this.currentAdBreakStartWallClockMs != null) {\n elapsedSinceStartMs = Date.now() - this.currentAdBreakStartWallClockMs;\n }\n const expectedDurationMs = this.expectedAdBreakDurationMs ?? 0;\n const overrunMs = Math.max(0, elapsedSinceStartMs - expectedDurationMs);\n\n const shouldExtendAdBreak =\n (adPlaying || pendingAds || this.showAds) && overrunMs < maxExtensionMs;\n\n if (shouldExtendAdBreak) {\n this.scheduleAdStopCountdown(checkIntervalMs);\n return;\n }\n\n if (adPlaying) {\n this.adLayer.stop().catch(() => {});\n }\n\n this.handleAdPodComplete();\n }\n\n private scheduleAdStartIn(delayMs: number): void {\n this.clearAdStartTimer();\n const ms = Math.max(0, Math.floor(delayMs));\n if (ms === 0) {\n this.handleAdStart({ type: \"start\" } as Scte35Marker).catch(() => {});\n return;\n }\n this.adStartTimerId = window.setTimeout(() => {\n this.handleAdStart({ type: \"start\" } as Scte35Marker).catch(() => {});\n }, ms) as unknown as number;\n }\n\n private clearAdStartTimer(): void {\n if (this.adStartTimerId != null) {\n clearTimeout(this.adStartTimerId);\n this.adStartTimerId = undefined;\n }\n }\n\n private updatePtsDrift(ptsSecondsSample: number): void {\n const sampleMs = (this.video.currentTime - ptsSecondsSample) * 1000;\n if (!Number.isFinite(sampleMs) || Math.abs(sampleMs) > 60000) return;\n const alpha = 0.1;\n this.ptsDriftEmaMs = this.ptsDriftEmaMs * (1 - alpha) + sampleMs * alpha;\n }\n\n private handleAdPodComplete(): void {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] 🏁 Ad pod complete - cleaning up\");\n }\n\n this.clearAdRequestWatchdog();\n this.clearAdFailsafeTimer();\n this.activeAdRequestToken = null;\n\n this.stopContinuousFetching();\n this.clearPendingAdBreak();\n this.pendingNextAdBids = null;\n\n if (this.isShowingPlaceholder) {\n this.adLayer.hidePlaceholder();\n this.isShowingPlaceholder = false;\n }\n\n this.inAdBreak = false;\n this.expectedAdBreakDurationMs = undefined;\n this.currentAdBreakStartWallClockMs = undefined;\n this.clearAdStartTimer();\n this.clearAdStopTimer();\n this.adPodQueue = [];\n this.showAds = false;\n this.currentAdIndex = 0;\n this.totalAdsInBreak = 0;\n this.totalAdRequestsInBreak = 0;\n this.consecutiveFailures = 0;\n\n this.adLayer.stop().catch(() => {});\n\n const restoredMuted = this.adLayer.getOriginalMutedState();\n const restoredVolume = this.adLayer.getOriginalVolume();\n\n if (this.video.muted !== restoredMuted) {\n this.video.muted = restoredMuted;\n }\n if (Math.abs(this.video.volume - restoredVolume) > 0.01) {\n this.video.volume = restoredVolume;\n }\n\n const isTizen = detectBrowser().tizenVersion !== undefined;\n if (isTizen && this.hls) {\n this.hls.attachMedia(this.video);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Tizen: re-attached HLS to video element after ad break to restore audio\");\n }\n }\n\n if (this.shouldContinueLiveStreamDuringAds()) {\n if (this.config.debugAdTiming) {\n if (this.video.paused) {\n console.log(\"[StormcloudVideoPlayer] Content video paused in live mode after ads, resuming playback\");\n } else {\n console.log(\"[StormcloudVideoPlayer] Content video already playing in live mode after ads\");\n }\n }\n this.video.play()?.catch(() => {});\n } else if (this.video.paused) {\n this.video.play()?.catch(() => {});\n }\n\n if (isTizen && !restoredMuted) {\n requestAnimationFrame(() => {\n this.video.muted = false;\n this.video.volume = restoredVolume;\n });\n }\n }\n\n private handleAdFailure(): void {\n this.consecutiveFailures++;\n if (this.config.debugAdTiming) {\n console.log(\n `[CONTINUOUS-FETCH] Ad failure: consecutiveFailures=${this.consecutiveFailures}`\n );\n }\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] 🛑 Max consecutive failures reached (${this.consecutiveFailures}), ending ad break gracefully`);\n }\n this.handleAdPodComplete();\n }\n }\n\n private startAdRequestWatchdog(token: number): void {\n this.clearAdRequestWatchdog();\n\n const timeoutMs = this.config.adFailsafeTimeoutMs ?? 10000;\n this.adRequestWatchdogToken = token;\n this.adRequestWatchdogId = window.setTimeout(() => {\n if (this.adRequestWatchdogToken !== token) {\n return;\n }\n\n this.adRequestWatchdogId = undefined;\n this.adRequestWatchdogToken = null;\n if (this.activeAdRequestToken === token) {\n this.activeAdRequestToken = null;\n }\n\n this.logAdState(\"ad_request_timeout\", { token, timeoutMs });\n this.handleAdFailure();\n }, timeoutMs) as unknown as number;\n\n this.logAdState(\"ad_request_watchdog_started\", { token, timeoutMs });\n }\n\n private clearAdRequestWatchdog(): void {\n if (this.adRequestWatchdogId != null) {\n clearTimeout(this.adRequestWatchdogId);\n this.adRequestWatchdogId = undefined;\n }\n\n if (this.adRequestWatchdogToken != null) {\n this.logAdState(\"ad_request_watchdog_cleared\", {\n token: this.adRequestWatchdogToken,\n });\n this.adRequestWatchdogToken = null;\n }\n }\n\n private startAdFailsafeTimer(token: number): void {\n this.clearAdFailsafeTimer();\n\n const failsafeMs = this.config.adFailsafeTimeoutMs ?? 10000;\n this.adFailsafeToken = token;\n\n this.adFailsafeTimerId = window.setTimeout(() => {\n if (this.adFailsafeToken !== token) {\n return;\n }\n\n this.adFailsafeTimerId = undefined;\n this.adFailsafeToken = null;\n\n if (this.activeAdRequestToken === token) {\n this.activeAdRequestToken = null;\n }\n\n this.logAdState(\"ad_failsafe_triggered\", {\n token,\n failsafeMs,\n videoPaused: this.video.paused,\n imaAdPlaying: this.adLayer.isAdPlaying(),\n });\n\n this.handleAdFailure();\n }, failsafeMs) as unknown as number;\n\n this.logAdState(\"ad_failsafe_started\", { token, failsafeMs });\n }\n\n private clearAdFailsafeTimer(): void {\n if (this.adFailsafeTimerId != null) {\n clearTimeout(this.adFailsafeTimerId);\n this.logAdState(\"ad_failsafe_cleared\", { token: this.adFailsafeToken });\n this.adFailsafeTimerId = undefined;\n }\n\n this.adFailsafeToken = null;\n }\n\n private logAdState(event: string, extra: Record<string, unknown> = {}): void {\n if (!this.config.debugAdTiming) {\n return;\n }\n\n console.log(\"[StormcloudVideoPlayer][AdState]\", {\n event,\n timestamp: new Date().toISOString(),\n showAds: this.showAds,\n adPlaying: this.adLayer.isAdPlaying(),\n inAdBreak: this.inAdBreak,\n activeAdRequestToken: this.activeAdRequestToken,\n ...extra,\n });\n }\n\n private getRemainingAdMs(): number {\n if (this.currentAdBreakStartWallClockMs == null) return 0;\n if (this.expectedAdBreakDurationMs == null) return Number.MAX_SAFE_INTEGER;\n const elapsed = Date.now() - this.currentAdBreakStartWallClockMs;\n return Math.max(0, this.expectedAdBreakDurationMs - elapsed);\n }\n\n toggleMute(): void {\n if (this.adLayer.isAdPlaying()) {\n const currentPerceptualState = this.isMuted();\n const newMutedState = !currentPerceptualState;\n\n this.adLayer.updateOriginalMutedState(newMutedState, this.video.volume);\n this.adLayer.setAdVolume(newMutedState ? 0 : this.adLayer.getOriginalVolume());\n\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Mute toggle during ad - immediately applied:\",\n newMutedState\n );\n }\n } else {\n this.video.muted = !this.video.muted;\n this.adLayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Muted:\", this.video.muted);\n }\n }\n }\n\n toggleFullscreen(): Promise<void> {\n return new Promise((resolve, reject) => {\n if (!document.fullscreenElement) {\n const container = this.video.parentElement;\n if (!container) {\n reject(new Error(\"No parent container found for fullscreen\"));\n return;\n }\n container\n .requestFullscreen()\n .then(() => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Entered fullscreen\");\n }\n resolve();\n })\n .catch((err) => {\n if (this.config.debugAdTiming) {\n console.error(\"[StormcloudVideoPlayer] Fullscreen error:\", err);\n }\n reject(err);\n });\n } else {\n document\n .exitFullscreen()\n .then(() => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Exited fullscreen\");\n }\n resolve();\n })\n .catch((err) => {\n if (this.config.debugAdTiming) {\n console.error(\n \"[StormcloudVideoPlayer] Exit fullscreen error:\",\n err\n );\n }\n reject(err);\n });\n }\n });\n }\n\n isMuted(): boolean {\n if (this.adLayer.isAdPlaying()) {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] isMuted() override during ad playback -> false\"\n );\n }\n return false;\n }\n return this.video.muted;\n }\n\n setMuted(muted: boolean): void {\n const adPlaying = this.adLayer.isAdPlaying();\n\n if (adPlaying && muted === this.video.muted) {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] setMuted reflective update during ad ignored\",\n { muted }\n );\n }\n return;\n }\n\n this.video.muted = muted;\n\n if (adPlaying) {\n this.adLayer.updateOriginalMutedState(muted, this.video.volume);\n this.adLayer.setAdVolume(muted ? 0 : this.adLayer.getOriginalVolume());\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] setMuted applied during ad\", {\n muted,\n });\n }\n return;\n }\n\n this.adLayer.updateOriginalMutedState(muted, this.video.volume);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] setMuted called:\", muted);\n }\n }\n\n setVolume(volume: number): void {\n const clampedVolume = Math.max(0, Math.min(1, volume));\n const adPlaying = this.adLayer.isAdPlaying();\n\n if (adPlaying) {\n this.adLayer.setAdVolume(clampedVolume);\n this.adLayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] setVolume applied during ad\", {\n volume: clampedVolume,\n });\n }\n } else {\n this.video.volume = clampedVolume;\n this.video.muted = clampedVolume === 0;\n this.adLayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] setVolume called:\", clampedVolume);\n }\n }\n }\n\n getVolume(): number {\n const adPlaying = this.adLayer.isAdPlaying();\n if (adPlaying) {\n return this.adLayer.getAdVolume();\n }\n return this.video.volume;\n }\n\n isFullscreen(): boolean {\n return !!document.fullscreenElement;\n }\n\n isLive(): boolean {\n return this.isLiveStream;\n }\n\n get videoElement(): HTMLVideoElement {\n return this.video;\n }\n\n resize(): void {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Resizing player\");\n }\n\n if (this.adLayer && this.adLayer.isAdPlaying()) {\n const width = this.video.clientWidth || 640;\n const height = this.video.clientHeight || 480;\n\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Resizing ads manager to ${width}x${height}`\n );\n }\n\n this.adLayer.resize(width, height);\n }\n }\n\n destroy(): void {\n this.stopContinuousFetching();\n this.clearAdStartTimer();\n this.clearAdStopTimer();\n this.clearAdFailsafeTimer();\n this.clearAdRequestWatchdog();\n this.clearPendingAdBreak();\n \n if (this.placeholderContainer) {\n if (this.placeholderContainer.parentElement) {\n this.placeholderContainer.parentElement.removeChild(this.placeholderContainer);\n }\n this.placeholderContainer = undefined;\n }\n \n if (this.timeUpdateHandler) {\n this.video.removeEventListener(\"timeupdate\", this.timeUpdateHandler);\n delete this.timeUpdateHandler;\n }\n if (this.emptiedHandler) {\n this.video.removeEventListener(\"emptied\", this.emptiedHandler);\n delete this.emptiedHandler;\n }\n \n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval);\n this.heartbeatInterval = undefined;\n }\n this.hls?.destroy();\n this.adLayer?.destroy();\n this.consecutiveFailures = 0;\n }\n}\n","import type { PrebidBidResponse, PrebidManager } from \"../types\";\n\nconst DEFAULT_TIMEOUT_MS = 3000;\nconst AUCTION_URL = \"https://sspproxy.adstorm.co/openrtb2/auction/adstorm\";\n\nexport interface PrebidManagerOptions {\n debug?: boolean;\n}\n\nexport function createPrebidManager(\n options: PrebidManagerOptions = {}\n): PrebidManager {\n let initialized = false;\n const debug = options.debug ?? false;\n\n function log(...args: any[]): void {\n if (debug) {\n console.log(\"[Prebid]\", ...args);\n }\n }\n\n function warn(...args: any[]): void {\n console.warn(\"[Prebid]\", ...args);\n }\n\n function parseResponse(data: any): PrebidBidResponse[] {\n const bids: PrebidBidResponse[] = [];\n const seatbids: any[] = data?.seatbid || [];\n const currency: string = data?.cur || \"USD\";\n\n for (const seatbid of seatbids) {\n const seat: string = seatbid.seat || \"unknown\";\n const bidArray: any[] = seatbid.bid || [];\n\n for (const bid of bidArray) {\n const cacheUrl: string | undefined =\n bid.ext?.prebid?.cache?.vastXml?.url;\n const vastXml: string | undefined = bid.adm || undefined;\n\n const bidResponse: PrebidBidResponse = {\n bidder: seat,\n cpm: bid.price || 0,\n width: bid.w || 0,\n height: bid.h || 0,\n adId: bid.id || \"\",\n impId: bid.impid || \"\",\n creativeId: bid.crid || \"\",\n currency,\n };\n if (cacheUrl) bidResponse.vastUrl = cacheUrl;\n if (vastXml) bidResponse.vastXml = vastXml;\n if (bid.adomain) bidResponse.adomain = bid.adomain;\n\n bids.push(bidResponse);\n }\n }\n\n bids.sort((a, b) => b.cpm - a.cpm);\n return bids;\n }\n\n async function initialize(): Promise<void> {\n if (initialized) return;\n initialized = true;\n log(\"Initialized, auction URL:\", AUCTION_URL);\n }\n\n async function requestBids(): Promise<PrebidBidResponse[]> {\n if (!initialized) {\n throw new Error(\"Prebid not initialized. Call initialize() first.\");\n }\n\n const timeout = DEFAULT_TIMEOUT_MS;\n\n log(\"Fetching auction response from:\", AUCTION_URL);\n\n const controller =\n typeof AbortController !== \"undefined\"\n ? new AbortController()\n : null;\n const timeoutId = setTimeout(() => {\n controller?.abort();\n }, timeout + 2000);\n\n try {\n const fetchOptions: RequestInit = {\n method: \"POST\",\n };\n if (controller) {\n fetchOptions.signal = controller.signal;\n }\n\n const response = await fetch(AUCTION_URL, fetchOptions);\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new Error(\n `Prebid Server returned HTTP ${response.status}: ${body.slice(0, 200)}`\n );\n }\n\n const data = await response.json();\n\n if (debug && data?.ext?.responsetimemillis) {\n log(\"Bidder response times:\", data.ext.responsetimemillis);\n }\n if (debug && data?.ext?.errors) {\n warn(\"Auction errors:\", data.ext.errors);\n }\n\n const bids = parseResponse(data);\n log(`Received ${bids.length} bid(s)`);\n\n if (debug) {\n for (const b of bids) {\n log(\n ` ${b.bidder}: $${b.cpm.toFixed(2)} ${b.currency}` +\n ` ${b.width}x${b.height}` +\n (b.vastUrl ? \" [cached VAST]\" : \"\") +\n (b.vastXml && !b.vastUrl ? \" [VAST XML]\" : \"\")\n );\n }\n }\n\n return bids;\n } catch (error: any) {\n clearTimeout(timeoutId);\n\n if (error?.name === \"AbortError\") {\n warn(`Auction request timed out after ${timeout + 2000}ms`);\n return [];\n }\n\n throw error;\n }\n }\n\n const REQUEST_BIDS_MAX_RETRIES = 3;\n const REQUEST_BIDS_BACKOFF_MS = 1500;\n\n async function requestBidsUntilResponse(): Promise<PrebidBidResponse[]> {\n if (!initialized) {\n throw new Error(\"Prebid not initialized. Call initialize() first.\");\n }\n let lastError: unknown;\n for (let attempt = 1; attempt <= REQUEST_BIDS_MAX_RETRIES; attempt++) {\n try {\n const bids = await requestBids();\n if (bids.length > 0) {\n log(`requestBidsUntilResponse: got ${bids.length} bid(s) on attempt ${attempt}`);\n return bids;\n }\n log(`requestBidsUntilResponse: no bids on attempt ${attempt}/${REQUEST_BIDS_MAX_RETRIES}`);\n } catch (err) {\n lastError = err;\n warn(`requestBidsUntilResponse: attempt ${attempt}/${REQUEST_BIDS_MAX_RETRIES} failed:`, err);\n }\n if (attempt < REQUEST_BIDS_MAX_RETRIES) {\n const delay = REQUEST_BIDS_BACKOFF_MS * attempt;\n log(`requestBidsUntilResponse: waiting ${delay}ms before retry`);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n if (lastError instanceof Error) {\n throw lastError;\n }\n return [];\n }\n\n function destroy(): void {\n initialized = false;\n log(\"Destroyed\");\n }\n\n return {\n initialize,\n requestBids,\n requestBidsUntilResponse,\n destroy,\n get isInitialized() {\n return initialized;\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","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","import type {\n ClientInfo,\n TrackingData,\n HeartbeatData,\n AdDetectInfo,\n AdLoadedInfo,\n AdImpressionInfo,\n} from \"../types\";\n\nlet cachedBrowserId: string | null = null;\n\nexport function getClientInfo(): ClientInfo {\n const ua = navigator.userAgent;\n const platform = navigator.platform;\n const vendor = navigator.vendor || \"\";\n const maxTouchPoints = navigator.maxTouchPoints || 0;\n const memory = (navigator as any).deviceMemory || null;\n const hardwareConcurrency = navigator.hardwareConcurrency || 1;\n\n const screenInfo = {\n width: screen?.width,\n height: screen?.height,\n availWidth: screen?.availWidth,\n availHeight: screen?.availHeight,\n orientation: (screen?.orientation as any)?.type || \"\",\n pixelDepth: screen?.pixelDepth,\n };\n\n let deviceType: \"tv\" | \"mobile\" | \"tablet\" | \"desktop\" = \"desktop\";\n let brand = \"Unknown\";\n let os = \"Unknown\";\n let model = \"\";\n let isSmartTV = false;\n let isAndroid = false;\n let isWebView = false;\n let isWebApp = false;\n\n if (ua.includes(\"Web0S\")) {\n brand = \"LG\";\n os = \"webOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n const webosMatch = ua.match(/Web0S\\/([^\\s]+)/);\n model = webosMatch ? `webOS ${webosMatch[1]}` : \"webOS TV\";\n } else if (ua.includes(\"Tizen\")) {\n brand = \"Samsung\";\n os = \"Tizen\";\n isSmartTV = true;\n deviceType = \"tv\";\n const tizenMatch = ua.match(/Tizen\\/([^\\s]+)/);\n const tvMatch = ua.match(/(?:Smart-TV|SMART-TV|TV)/i) ? \"Smart TV\" : \"\";\n model = tizenMatch\n ? `Tizen ${tizenMatch[1]} ${tvMatch}`.trim()\n : \"Tizen TV\";\n } else if (ua.includes(\"Philips\")) {\n brand = \"Philips\";\n os = \"Saphi\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Sharp\") || ua.includes(\"AQUOS\")) {\n brand = \"Sharp\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (\n ua.includes(\"Android\") &&\n (ua.includes(\"Sony\") || vendor.includes(\"Sony\"))\n ) {\n brand = \"Sony\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (\n ua.includes(\"Android\") &&\n (ua.includes(\"NetCast\") || ua.includes(\"LG\"))\n ) {\n brand = \"LG\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\" Roku\") || ua.includes(\"Roku/\")) {\n brand = \"Roku\";\n os = \"Roku OS\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"AppleTV\")) {\n brand = \"Apple\";\n os = \"tvOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n }\n\n if (ua.includes(\"Android\")) {\n isAndroid = true;\n os = \"Android\";\n deviceType = /Mobile/.test(ua) ? \"mobile\" : \"tablet\";\n\n if (\n ua.includes(\"Android\") &&\n (maxTouchPoints === 0 ||\n ua.includes(\"Google TV\") ||\n ua.includes(\"XiaoMi\"))\n ) {\n deviceType = \"tv\";\n isSmartTV = true;\n brand = brand === \"Unknown\" ? \"Android TV\" : brand;\n }\n\n const androidModelMatch = ua.match(/\\(([^)]*Android[^)]*)\\)/);\n if (androidModelMatch && androidModelMatch[1]) {\n model = androidModelMatch[1];\n }\n }\n\n if (/iPad|iPhone|iPod/.test(ua)) {\n os = \"iOS\";\n deviceType = \"mobile\";\n brand = \"Apple\";\n if (navigator.maxTouchPoints > 1 && /iPad/.test(ua)) {\n deviceType = \"tablet\";\n }\n }\n\n if (!isAndroid && !isSmartTV && !/Mobile/.test(ua)) {\n if (ua.includes(\"Windows\")) {\n os = \"Windows\";\n deviceType = \"desktop\";\n } else if (ua.includes(\"Mac\") && !/iPhone/.test(ua)) {\n os = \"macOS\";\n deviceType = \"desktop\";\n if (maxTouchPoints > 1) deviceType = \"tablet\";\n } else if (ua.includes(\"Linux\")) {\n os = \"Linux\";\n deviceType = \"desktop\";\n }\n }\n\n if (brand === \"Unknown\") {\n if (vendor.includes(\"Google\") || ua.includes(\"Chrome\")) brand = \"Google\";\n if (vendor.includes(\"Apple\")) brand = \"Apple\";\n if (vendor.includes(\"Samsung\") || ua.includes(\"SM-\")) brand = \"Samsung\";\n }\n\n isWebView = /wv|WebView|Linux; U;/.test(ua);\n\n if (window?.outerHeight === 0 && window?.outerWidth === 0) {\n isWebView = true;\n }\n\n isWebApp =\n window.matchMedia(\"(display-mode: standalone)\").matches ||\n (window.navigator as any).standalone === true ||\n window.screen?.orientation?.angle !== undefined;\n\n return {\n brand,\n os,\n model: model || ua.substring(0, 50) + \"...\",\n deviceType,\n isSmartTV,\n isAndroid,\n isWebView,\n isWebApp,\n domain: window.location.hostname,\n origin: window.location.origin,\n path: window.location.pathname,\n userAgent: ua,\n vendor,\n platform,\n screen: screenInfo,\n hardwareConcurrency,\n deviceMemory: memory,\n maxTouchPoints,\n language: navigator.language,\n languages: navigator.languages?.join(\",\") || \"\",\n cookieEnabled: navigator.cookieEnabled,\n doNotTrack: navigator.doNotTrack || \"\",\n referrer: document.referrer,\n visibilityState: document.visibilityState,\n };\n}\n\nexport async function getBrowserID(clientInfo: ClientInfo): Promise<string> {\n if (cachedBrowserId) {\n return cachedBrowserId;\n }\n\n const fingerprintString = JSON.stringify(clientInfo);\n\n if (typeof crypto !== \"undefined\" && crypto.subtle && crypto.subtle.digest) {\n try {\n await crypto.subtle.digest(\"SHA-256\", new Uint8Array([1, 2, 3]));\n\n let encodedData: BufferSource;\n if (typeof TextEncoder !== \"undefined\") {\n encodedData = new TextEncoder().encode(fingerprintString);\n } else {\n const utf8 = unescape(encodeURIComponent(fingerprintString));\n const buffer = new Uint8Array(utf8.length);\n for (let i = 0; i < utf8.length; i++) {\n buffer[i] = utf8.charCodeAt(i);\n }\n encodedData = buffer;\n }\n\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", encodedData);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n const hashHex = hashArray\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n cachedBrowserId = hashHex;\n return hashHex;\n } catch (error) {\n console.warn(\n \"[StormcloudVideoPlayer] crypto.subtle.digest not supported, using fallback hash\"\n );\n }\n }\n\n let hash = 0;\n for (let i = 0; i < fingerprintString.length; i++) {\n const char = fingerprintString.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n\n const fallbackHash = Math.abs(hash).toString(16).padStart(8, \"0\");\n const timestamp = Date.now().toString(16).padStart(12, \"0\");\n const random = Math.random().toString(16).substring(2, 14).padStart(12, \"0\");\n\n cachedBrowserId = (fallbackHash + timestamp + random).padEnd(64, \"0\");\n return cachedBrowserId;\n}\n\nconst TRACK_URL =\n \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track\";\n\nasync function sendTrackRequest(\n licenseKey: string | undefined,\n body: Record<string, unknown>\n): Promise<void> {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n const response = await fetch(TRACK_URL, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n });\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n await response.json();\n}\n\nexport async function sendInitialTracking(licenseKey?: string): Promise<void> {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n\n const trackingData: TrackingData = {\n browserId,\n ...clientInfo,\n };\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n\n const response = await fetch(TRACK_URL, {\n method: \"POST\",\n headers,\n body: JSON.stringify(trackingData),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n await response.json();\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending initial tracking data:\",\n error\n );\n }\n}\n\nexport async function sendAdDetectTracking(\n licenseKey: string | undefined,\n adDetectInfo: AdDetectInfo\n): Promise<void> {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData: TrackingData = { browserId, ...clientInfo };\n await sendTrackRequest(licenseKey, {\n ...trackingData,\n licenseKey,\n adDetectInfo,\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad detect tracking:\",\n error\n );\n }\n}\n\nexport async function sendAdLoadedTracking(\n licenseKey: string | undefined,\n adLoadedInfo: AdLoadedInfo\n): Promise<void> {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData: TrackingData = { browserId, ...clientInfo };\n await sendTrackRequest(licenseKey, {\n ...trackingData,\n licenseKey,\n adLoadedInfo,\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad loaded tracking:\",\n error\n );\n }\n}\n\nexport async function sendAdImpressionTracking(\n licenseKey: string | undefined,\n adImpressionInfo: AdImpressionInfo\n): Promise<void> {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData: TrackingData = { browserId, ...clientInfo };\n await sendTrackRequest(licenseKey, {\n ...trackingData,\n licenseKey,\n adImpressionInfo,\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad impression tracking:\",\n error\n );\n }\n}\n\nexport async function sendHeartbeat(licenseKey?: string): Promise<void> {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n\n const heartbeatData: HeartbeatData = {\n browserId,\n timestamp: new Date().toISOString(),\n };\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n\n const response = await fetch(\n \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/heartbeat\",\n {\n method: \"POST\",\n headers,\n body: JSON.stringify(heartbeatData),\n }\n );\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n await response.json();\n } catch (error) {\n console.error(\"[StormcloudVideoPlayer] Error sending heartbeat:\", error);\n }\n}\n","export function polyfillURLSearchParams(): void {\n if (typeof URLSearchParams !== 'undefined') {\n return;\n }\n\n class URLSearchParamsPolyfill {\n private params: Map<string, string[]>;\n\n constructor(init?: string | URLSearchParamsPolyfill) {\n this.params = new Map();\n\n if (typeof init === 'string') {\n this.parseQueryString(init);\n } else if (init instanceof URLSearchParamsPolyfill) {\n init.forEach((value, key) => {\n this.append(key, value);\n });\n }\n }\n\n private parseQueryString(query: string): void {\n const cleanQuery = query.startsWith('?') ? query.slice(1) : query;\n if (!cleanQuery) return;\n\n cleanQuery.split('&').forEach((param) => {\n const [key, value] = param.split('=');\n if (key) {\n const decodedKey = this.safeDecodeURIComponent(key);\n const decodedValue = value ? this.safeDecodeURIComponent(value) : '';\n this.append(decodedKey, decodedValue);\n }\n });\n }\n\n private safeDecodeURIComponent(str: string): string {\n try {\n return decodeURIComponent(str.replace(/\\+/g, ' '));\n } catch (e) {\n return str;\n }\n }\n\n append(name: string, value: string): void {\n const values = this.params.get(name) || [];\n values.push(String(value));\n this.params.set(name, values);\n }\n\n delete(name: string): void {\n this.params.delete(name);\n }\n\n get(name: string): string | null {\n const values = this.params.get(name);\n return values && values.length > 0 && values[0] !== undefined ? values[0] : null;\n }\n\n getAll(name: string): string[] {\n return this.params.get(name) || [];\n }\n\n has(name: string): boolean {\n return this.params.has(name);\n }\n\n set(name: string, value: string): void {\n this.params.set(name, [String(value)]);\n }\n\n forEach(callback: (value: string, key: string, parent: URLSearchParamsPolyfill) => void): void {\n this.params.forEach((values, key) => {\n values.forEach((value) => {\n callback(value, key, this);\n });\n });\n }\n\n toString(): string {\n const parts: string[] = [];\n this.params.forEach((values, key) => {\n values.forEach((value) => {\n parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);\n });\n });\n return parts.join('&');\n }\n }\n\n // @ts-ignore\n window.URLSearchParams = URLSearchParamsPolyfill;\n}\n\nexport function polyfillTextEncoder(): void {\n if (typeof TextEncoder !== 'undefined') {\n return;\n }\n\n class TextEncoderPolyfill {\n encoding = 'utf-8';\n\n encode(str: string): Uint8Array {\n const utf8: number[] = [];\n for (let i = 0; i < str.length; i++) {\n let charcode = str.charCodeAt(i);\n if (charcode < 0x80) {\n utf8.push(charcode);\n } else if (charcode < 0x800) {\n utf8.push(0xc0 | (charcode >> 6), 0x80 | (charcode & 0x3f));\n } else if (charcode < 0xd800 || charcode >= 0xe000) {\n utf8.push(\n 0xe0 | (charcode >> 12),\n 0x80 | ((charcode >> 6) & 0x3f),\n 0x80 | (charcode & 0x3f)\n );\n } else {\n i++;\n charcode = 0x10000 + (((charcode & 0x3ff) << 10) | (str.charCodeAt(i) & 0x3ff));\n utf8.push(\n 0xf0 | (charcode >> 18),\n 0x80 | ((charcode >> 12) & 0x3f),\n 0x80 | ((charcode >> 6) & 0x3f),\n 0x80 | (charcode & 0x3f)\n );\n }\n }\n return new Uint8Array(utf8);\n }\n }\n\n // @ts-ignore\n window.TextEncoder = TextEncoderPolyfill;\n}\n\nexport function polyfillPromiseFinally(): void {\n if (typeof Promise !== 'undefined' && !Promise.prototype.finally) {\n Promise.prototype.finally = function (callback: () => void) {\n const constructor = this.constructor as PromiseConstructor;\n return this.then(\n (value) => constructor.resolve(callback()).then(() => value),\n (reason) =>\n constructor.resolve(callback()).then(() => {\n throw reason;\n })\n );\n };\n }\n}\n\nexport function polyfillObjectAssign(): void {\n if (typeof Object.assign !== 'function') {\n Object.assign = function (target: any, ...sources: any[]) {\n if (target == null) {\n throw new TypeError('Cannot convert undefined or null to object');\n }\n\n const to = Object(target);\n\n for (let i = 0; i < sources.length; i++) {\n const nextSource = sources[i];\n\n if (nextSource != null) {\n for (const nextKey in nextSource) {\n if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {\n to[nextKey] = nextSource[nextKey];\n }\n }\n }\n }\n\n return to;\n };\n }\n}\n\nexport function polyfillArrayFrom(): void {\n if (!Array.from) {\n Array.from = function (arrayLike: any, mapFn?: any, thisArg?: any) {\n const items = Object(arrayLike);\n if (arrayLike == null) {\n throw new TypeError('Array.from requires an array-like object');\n }\n\n const len = items.length >>> 0;\n const result = new Array(len);\n\n for (let i = 0; i < len; i++) {\n if (mapFn) {\n result[i] = mapFn.call(thisArg, items[i], i);\n } else {\n result[i] = items[i];\n }\n }\n\n return result;\n };\n }\n}\n\nexport function polyfillStringStartsWith(): void {\n if (!String.prototype.startsWith) {\n String.prototype.startsWith = function (search: string, pos?: number) {\n pos = !pos || pos < 0 ? 0 : +pos;\n return this.substring(pos, pos + search.length) === search;\n };\n }\n}\n\nexport function polyfillStringEndsWith(): void {\n if (!String.prototype.endsWith) {\n String.prototype.endsWith = function (search: string, length?: number) {\n if (length === undefined || length > this.length) {\n length = this.length;\n }\n return this.substring(length - search.length, length) === search;\n };\n }\n}\n\nexport function polyfillStringIncludes(): void {\n if (!String.prototype.includes) {\n String.prototype.includes = function (search: string, start?: number) {\n if (typeof start !== 'number') {\n start = 0;\n }\n if (start + search.length > this.length) {\n return false;\n }\n return this.indexOf(search, start) !== -1;\n };\n }\n}\n\nexport function initializePolyfills(): void {\n polyfillObjectAssign();\n polyfillArrayFrom();\n polyfillStringStartsWith();\n polyfillStringEndsWith();\n polyfillStringIncludes();\n polyfillURLSearchParams();\n polyfillTextEncoder();\n polyfillPromiseFinally();\n}\n\n","interface NavigatorUAData {\n platform?: string;\n brands?: Array<{ brand: string; version: string }>;\n mobile?: boolean;\n}\n\ndeclare global {\n interface Navigator {\n userAgentData?: NavigatorUAData;\n }\n}\n\nexport interface BrowserInfo {\n name: string;\n version: string;\n majorVersion: number;\n isSmartTV: boolean;\n isLegacyTV: boolean;\n platform: string;\n supportsIMA: boolean;\n supportsModernJS: boolean;\n recommendedAdPlayer: 'ima' | 'hls';\n webOSVersion?: number | undefined;\n tizenVersion?: number | undefined;\n chromeVersion?: number | undefined;\n}\n\nfunction getChromeVersion(ua: string): number {\n const match = ua.match(/Chrome\\/(\\d+)/);\n return match && match[1] ? parseInt(match[1], 10) : 0;\n}\n\nfunction getWebKitVersion(ua: string): number {\n const match = ua.match(/AppleWebKit\\/(\\d+)/);\n return match && match[1] ? parseInt(match[1], 10) : 0;\n}\n\nfunction getPlatform(): string {\n if ('userAgentData' in navigator && navigator.userAgentData?.platform) {\n return navigator.userAgentData.platform;\n }\n\n const ua = navigator.userAgent;\n if (/Mac|iPhone|iPad|iPod/i.test(ua)) {\n return /iPhone|iPad|iPod/i.test(ua) ? 'iPhone' : 'MacIntel';\n }\n if (/Win/i.test(ua)) {\n return 'Win32';\n }\n if (/Linux/i.test(ua)) {\n return /Android/i.test(ua) ? 'Linux armv8l' : 'Linux x86_64';\n }\n if (/CrOS/i.test(ua)) {\n return 'CrOS';\n }\n\n // eslint-disable-next-line deprecation/deprecation\n return (navigator as any).platform || 'Unknown';\n}\n\nexport function detectBrowser(): BrowserInfo {\n const ua = navigator.userAgent;\n const platform = getPlatform();\n\n let name = 'Unknown';\n let version = '0';\n let majorVersion = 0;\n let isSmartTV = false;\n let isLegacyTV = false;\n let supportsIMA = true;\n let supportsModernJS = true;\n let recommendedAdPlayer: 'ima' | 'hls' = 'ima';\n let webOSVersion: number | undefined;\n let tizenVersion: number | undefined;\n let chromeVersionNum: number | undefined;\n\n const chromeVersion = getChromeVersion(ua);\n const webkitVersion = getWebKitVersion(ua);\n chromeVersionNum = chromeVersion > 0 ? chromeVersion : undefined;\n\n if (/Web0S|webOS|LG Browser|LGSTB/i.test(ua)) {\n name = 'LG WebOS';\n isSmartTV = true;\n \n let match = ua.match(/Web0S[/\\s]*([\\d.]+)/i) || ua.match(/webOS[/\\s]*([\\d.]+)/i);\n \n if (!match || !match[1]) {\n match = ua.match(/webOSTV[/\\s-]*([\\d.]+)/i) || ua.match(/webOS\\.TV[/\\s-]*([\\d.]+)/i);\n }\n \n if (match && match[1]) {\n version = match[1];\n const parts = version.split('.');\n majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;\n webOSVersion = majorVersion;\n } else if (chromeVersion > 0) {\n if (chromeVersion >= 79) {\n webOSVersion = 6;\n version = '6.0';\n majorVersion = 6;\n } else if (chromeVersion >= 68) {\n webOSVersion = 5;\n version = '5.0';\n majorVersion = 5;\n } else if (chromeVersion >= 53) {\n webOSVersion = 4;\n version = '4.0';\n majorVersion = 4;\n } else if (chromeVersion >= 38) {\n webOSVersion = 3;\n version = '3.0';\n majorVersion = 3;\n } else {\n webOSVersion = 2;\n version = '2.0';\n majorVersion = 2;\n }\n } else {\n version = 'Unknown';\n webOSVersion = undefined;\n }\n\n if (webOSVersion !== undefined && webOSVersion >= 4) {\n supportsIMA = true;\n recommendedAdPlayer = 'ima';\n isLegacyTV = false;\n } else if (webOSVersion !== undefined && webOSVersion >= 3) {\n if (chromeVersion >= 53) {\n supportsIMA = true;\n recommendedAdPlayer = 'ima';\n isLegacyTV = false;\n } else {\n supportsIMA = false;\n recommendedAdPlayer = 'hls';\n isLegacyTV = true;\n }\n } else if (chromeVersion >= 53) {\n supportsIMA = true;\n recommendedAdPlayer = 'ima';\n isLegacyTV = false;\n } else {\n supportsIMA = false;\n recommendedAdPlayer = 'hls';\n isLegacyTV = true;\n }\n } else if (/Tizen/i.test(ua)) {\n name = 'Samsung Tizen';\n isSmartTV = true;\n const match = ua.match(/Tizen[/\\s]*([\\d.]+)/i);\n version = match && match[1] ? match[1] : 'Unknown';\n if (version !== 'Unknown') {\n const parts = version.split('.');\n majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;\n tizenVersion = majorVersion;\n }\n \n if (tizenVersion !== undefined && tizenVersion >= 4) {\n supportsIMA = true;\n recommendedAdPlayer = 'ima';\n isLegacyTV = false;\n } else if (tizenVersion !== undefined && tizenVersion >= 3 && chromeVersion >= 47) {\n supportsIMA = true;\n recommendedAdPlayer = 'ima';\n isLegacyTV = false;\n } else if (chromeVersion >= 53) {\n supportsIMA = true;\n recommendedAdPlayer = 'ima';\n isLegacyTV = false;\n } else {\n supportsIMA = false;\n recommendedAdPlayer = 'hls';\n isLegacyTV = true;\n }\n } else if (/SMART-TV|SmartTV/i.test(ua)) {\n name = 'Smart TV';\n isSmartTV = true;\n if (chromeVersion >= 53) {\n supportsIMA = true;\n recommendedAdPlayer = 'ima';\n } else {\n supportsIMA = false;\n recommendedAdPlayer = 'hls';\n isLegacyTV = true;\n }\n } else if (/NetCast/i.test(ua)) {\n name = 'LG NetCast';\n isSmartTV = true;\n isLegacyTV = true;\n supportsIMA = false;\n recommendedAdPlayer = 'hls';\n } else if (/BRAVIA/i.test(ua)) {\n name = 'Sony BRAVIA';\n isSmartTV = true;\n if (chromeVersion >= 53) {\n supportsIMA = true;\n recommendedAdPlayer = 'ima';\n } else {\n supportsIMA = false;\n recommendedAdPlayer = 'hls';\n isLegacyTV = true;\n }\n } else {\n if (chromeVersion > 0) {\n name = 'Chrome';\n version = chromeVersion.toString();\n majorVersion = chromeVersion;\n\n if (chromeVersion < 50) {\n supportsIMA = false;\n supportsModernJS = false;\n recommendedAdPlayer = 'hls';\n }\n }\n\n if (webkitVersion > 0 && webkitVersion < 600) {\n supportsModernJS = false;\n if (chromeVersion < 50) {\n supportsIMA = false;\n recommendedAdPlayer = 'hls';\n }\n }\n }\n\n if (typeof Promise === 'undefined' ||\n typeof Map === 'undefined' ||\n typeof Set === 'undefined') {\n supportsModernJS = false;\n supportsIMA = false;\n recommendedAdPlayer = 'hls';\n }\n\n if (typeof URLSearchParams === 'undefined') {\n supportsModernJS = false;\n }\n\n return {\n name,\n version,\n majorVersion,\n isSmartTV,\n isLegacyTV,\n platform,\n supportsIMA,\n supportsModernJS,\n recommendedAdPlayer,\n webOSVersion,\n tizenVersion,\n chromeVersion: chromeVersionNum,\n };\n}\n\nexport function supportsGoogleIMA(): boolean {\n const browser = detectBrowser();\n\n if (browser.isLegacyTV) {\n return false;\n }\n\n if (typeof document === 'undefined' ||\n typeof document.createElement !== 'function') {\n return false;\n }\n\n try {\n const video = document.createElement('video');\n if (!video) {\n return false;\n }\n } catch (e) {\n return false;\n }\n\n if (typeof Promise === 'undefined') {\n return false;\n }\n\n return browser.supportsIMA;\n}\n\nexport function getRecommendedAdPlayer(): 'ima' | 'hls' {\n const browser = detectBrowser();\n return browser.recommendedAdPlayer;\n}\n\nexport function supportsModernJS(): boolean {\n try {\n return (\n typeof Promise !== 'undefined' &&\n typeof Map !== 'undefined' &&\n typeof Set !== 'undefined' &&\n typeof Array.from !== 'undefined' &&\n typeof Object.assign !== 'undefined' &&\n typeof Array.prototype.forEach !== 'undefined' &&\n typeof String.prototype.includes !== 'undefined'\n );\n } catch (e) {\n return false;\n }\n}\n\nexport function logBrowserInfo(debug: boolean = false): void {\n if (!debug) return;\n\n const browser = detectBrowser();\n const imaSupport = supportsGoogleIMA();\n\n console.log('[StormcloudVideoPlayer] Browser Compatibility Info:', {\n browser: `${browser.name} ${browser.version}`,\n platform: browser.platform,\n isSmartTV: browser.isSmartTV,\n isLegacyTV: browser.isLegacyTV,\n supportsIMA: imaSupport,\n supportsModernJS: browser.supportsModernJS,\n recommendedAdPlayer: browser.recommendedAdPlayer,\n ...(browser.webOSVersion !== undefined ? { webOSVersion: browser.webOSVersion } : {}),\n ...(browser.tizenVersion !== undefined ? { tizenVersion: browser.tizenVersion } : {}),\n ...(browser.chromeVersion !== undefined ? { chromeVersion: browser.chromeVersion } : {}),\n userAgent: navigator.userAgent,\n });\n}\n\nexport function getBrowserConfigOverrides(): {\n allowNativeHls?: boolean;\n} {\n const browser = detectBrowser();\n const overrides: { allowNativeHls?: boolean } = {};\n\n if (browser.isSmartTV) {\n overrides.allowNativeHls = true;\n }\n\n return overrides;\n}\n\nexport function supportsFeature(feature: string): boolean {\n switch (feature) {\n case 'ima':\n return supportsGoogleIMA();\n case 'urlsearchparams':\n return typeof URLSearchParams !== 'undefined';\n case 'textencoder':\n return typeof TextEncoder !== 'undefined';\n case 'promises':\n return typeof Promise !== 'undefined';\n case 'fetch':\n return typeof fetch !== 'undefined';\n case 'crypto':\n return typeof crypto !== 'undefined' && typeof crypto.subtle !== 'undefined';\n default:\n return false;\n }\n}\n\n"]}
|
|
1
|
+
{"version":3,"sources":["/home/ubuntu24-new/Dev/stormcloud-vp/lib/ui/StormcloudVideoPlayer.cjs","../../src/ui/StormcloudVideoPlayer.tsx","../../src/player/StormcloudVideoPlayer.ts","../../src/sdk/prebid.ts","../../src/sdk/vastParser.ts","../../src/sdk/prebidAdLayer.ts","../../src/utils/tracking.ts","../../src/utils/polyfills.ts","../../src/utils/browserCompat.ts"],"names":["__create","Object","create","__defProp","__copyProps","defineProperty","__getOwnPropDesc","getOwnPropertyDescriptor","__getOwnPropNames","getOwnPropertyNames","__getProtoOf","getPrototypeOf","__hasOwnProp","prototype","hasOwnProperty","__export","target","all","name","get","enumerable","to","from","except","desc","call","key","__toESM","mod","isNodeMode","value","__toCommonJS","StormcloudVideoPlayer_exports","StormcloudVideoPlayerComponent","module","exports","import_react","require","import_hls","DEFAULT_TIMEOUT_MS","AUCTION_URL","createPrebidManager","options","initialized","debug","log","args","console","warn","parseResponse","data","bids","seatbids","seatbid","currency","cur","seat","bidArray","bid","cacheUrl","ext","prebid","cache","vastXml","url","adm","bidResponse","bidder","cpm","price","width","w","height","h","adId","id","impId","impid","creativeId","crid","vastUrl","adomain","push","sort","a","b","initialize","requestBids","timeout","controller","timeoutId","fetchOptions","response","body","error","Error","AbortController","setTimeout","abort","method","signal","fetch","clearTimeout","ok","text","catch","status","slice","json","responsetimemillis","errors","length","toFixed","REQUEST_BIDS_MAX_RETRIES","REQUEST_BIDS_BACKOFF_MS","requestBidsUntilResponse","lastError","attempt","err","delay","Promise","resolve","destroy","isInitialized","isHlsType","type","includes","isMp4Type","parseVastXml","xmlString","filter","logPrefix","xmlDoc","parser","DOMParser","parseFromString","parserError","querySelector","textContent","adElement","getAttribute","title","isNoAdAvailable","toLowerCase","durationText","durationParts","split","duration","parseInt","Math","round","parseFloat","mediaFileElements","querySelectorAll","mediaFiles","forEach","mf","index","trim","substring","isHls","isMp4","accepted","bitrateAttr","bitrateValue","bitrate","aIsMp4","bIsMp4","trackingUrls","impression","start","firstQuartile","midpoint","thirdQuartile","complete","mute","unmute","pause","resume","fullscreen","exitFullscreen","skip","el","event","eventKey","clickThrough","vastTagUrl","mode","credentials","headers","Accept","referrerPolicy","statusText","createEmptyTrackingState","fireTrackingPixels","urls","sessionId","trackingUrl","img","Image","onerror","src","LOG","resolveBidToVastAd","winner","ad","fetchAndParseVastAd","createPrebidAdLayer","contentVideo","adPlaying","originalMutedState","originalVolume","max","min","volume","listeners","Map","mainHlsInstance","continueLiveStreamDuringAds","adVideoElement","adHls","adContainerEl","currentAd","destroyed","tornDown","trackingFired","emit","payload","set","Array","fn","generateSessionId","Date","now","random","toString","substr","getMainStreamQuality","levels","currentLevel","autoLevel","loadLevel","level","firstFile","scoredFiles","widthDiff","fileBitrate","file","isHlsMediaFile","selectBestMediaFile","mainQuality","map","abs","heightDiff","resolutionDiff","bitrateDiff","score","createAdVideoElement","video","document","createElement","style","position","left","top","objectFit","backgroundColor","playsInline","setupAdEventListeners","muted","addEventListener","progress","currentTime","handleAdComplete","e","ended","setAdPlayingFlag","isPlaying","dataset","stormcloudAdPlaying","display","pointerEvents","visibility","opacity","teardownCurrentPlayback","removeAttribute","load","mediaFile","play","startHlsPlayback","Hls","isSupported","enableWorker","lowLatencyMode","loadSource","attachMedia","on","Events","MANIFEST_PARSED","handleAdError","ERROR","_event","fatal","canPlayType","startPlayback","startNativePlayback","playAd","container","contentVolume","adVolume","reject","right","bottom","alignItems","zIndex","parentElement","appendChild","updateOptions","opts","paused","stop","remove","removeChild","clear","isAdPlaying","resize","listener","has","Set","add","off","delete","updateOriginalMutedState","nextVolume","Number","isNaN","getOriginalMutedState","getOriginalVolume","setAdVolume","getAdVolume","showPlaceholder","justifyContent","hidePlaceholder","cachedBrowserId","getClientInfo","screen","window","navigator","ua","userAgent","platform","vendor","maxTouchPoints","memory","deviceMemory","hardwareConcurrency","screenInfo","availWidth","availHeight","orientation","pixelDepth","deviceType","brand","os","model","isSmartTV","isAndroid","isWebView","isWebApp","webosMatch","match","tizenMatch","tvMatch","test","androidModelMatch","outerHeight","outerWidth","matchMedia","matches","standalone","angle","domain","location","hostname","origin","path","pathname","language","languages","join","cookieEnabled","doNotTrack","referrer","visibilityState","getBrowserID","clientInfo","fingerprintString","encodedData","utf8","buffer","i","hashBuffer","hashArray","hashHex","hash","char","fallbackHash","timestamp","JSON","stringify","crypto","subtle","digest","Uint8Array","TextEncoder","encode","unescape","encodeURIComponent","charCodeAt","padStart","padEnd","sendTrackRequest","licenseKey","TRACK_URL","sendInitialTracking","browserId","trackingData","adDetectInfo","sendAdLoadedTracking","adLoadedInfo","sendAdImpressionTracking","adImpressionInfo","sendHeartbeat","heartbeatData","toISOString","polyfillURLSearchParams","URLSearchParams","URLSearchParamsPolyfill","init","params","parseQueryString","append","query","cleanQuery","startsWith","param","decodedKey","safeDecodeURIComponent","decodedValue","str","decodeURIComponent","replace","values","String","getAll","callback","parts","polyfillTextEncoder","TextEncoderPolyfill","encoding","charcode","polyfillPromiseFinally","finally","constructor","then","reason","polyfillObjectAssign","assign","sources","TypeError","nextSource","nextKey","polyfillArrayFrom","items","arrayLike","len","result","mapFn","thisArg","polyfillStringStartsWith","search","pos","polyfillStringEndsWith","endsWith","polyfillStringIncludes","indexOf","initializePolyfills","webOSVersion","getChromeVersion","getWebKitVersion","getPlatform","userAgentData","version","detectBrowser","majorVersion","supportsIMA","supportsModernJS","recommendedAdPlayer","tizenVersion","chromeVersionNum","chromeVersion","webkitVersion","isLegacyTV","supportsGoogleIMA","browser","logBrowserInfo","imaSupport","getBrowserConfigOverrides","overrides","allowNativeHls","StormcloudVideoPlayer","config","pendingNextAdBids","continuousFetchLoopPromise","attached","inAdBreak","ptsDriftEmaMs","adPodQueue","lastHeartbeatTime","currentAdIndex","totalAdsInBreak","showAds","isLiveStream","nativeHlsMode","videoSrcProtection","bufferedSegmentsCount","shouldAutoplayAfterBuffering","hasInitialBufferCompleted","activeAdRequestToken","adRequestWatchdogToken","adFailsafeToken","continuousFetchingActive","maxPlaceholderDurationMs","isShowingPlaceholder","totalAdRequestsInBreak","maxTotalAdRequestsPerBreak","pendingAdBreak","savedMutedStateBeforeScte","consecutiveFailures","maxConsecutiveFailures","lastAdRequestTime","minAdRequestIntervalMs","backoffBaseMs","maxBackoffMs","adTransitionGapMs","browserOverrides","videoElement","debugAdTiming","prebidManager","adLayer","adRequest","attach","shouldUseNativeHls","isLive","adBehavior","autoplay","hls","import_hls2","backBufferLength","liveDurationInfinity","maxBufferLength","maxLiveSyncPlaybackRate","liveSyncDuration","maxMaxBufferLength","maxBufferSize","maxBufferHole","highBufferWatchdogPeriod","nudgeOffset","nudgeMaxRetry","startPosition","MEDIA_ATTACHED","_","minSegments","some","details","live","shouldContinueLiveStreamDuringAds","LEVEL_LOADED","_evt","fragments","fragmentsToScan","isArray","tagList","entry","tag","minSegmentsBeforePlay","idx","attrs","parseAttributeList","hasScteOut","durationSeconds","parseCueOutDuration","marker","raw","earlyDetection","startAdPrefetch","frag","sn","FRAG_BUFFERED","FRAG_PARSING_METADATA","id3Tags","samples","s","ptsSeconds","pts","onId3Tag","FRAG_CHANGED","prog","elapsed","onScte35Marker","hasScteIn","klass","toNumber","ErrorTypes","NETWORK_ERROR","startLoad","MEDIA_ERROR","recoverMediaError","getAdSource","attachAdLayerEventListeners","source","adIndex","errorPayload","errorMessage","errorCode","code","vastErrorCode","message","cause","innerError","causeMessage","handleAdFailure","clearAdFailsafeTimer","clearAdRequestWatchdog","expectedAdBreakDurationMs","adStopTimerId","scheduleAdStopCountdown","getRemainingAdMs","hidePlaceholderLayer","remaining","restoredMuted","restoredVolume","showPlaceholderLayer","handleAdPodComplete","ensurePlaceholderContainer","placeholderContainer","transition","wasHidden","offsetHeight","requestAnimationFrame","timeUpdateHandler","onTimeUpdate","emptiedHandler","wasPaused","streamType","getStreamType","canNative","updatePtsDrift","parseScte35FromId3","decodeId3ValueToText","cueOutMatch","arg","dur","id3","cueOutContMatch","cont","parseCueOutCont","cueInMatch","daterangeMatch","bin","parseScte35Binary","decoder","TextDecoder","decode","out","fromCharCode","hasPendingAdBreak","durationMs","currentAdBreakStartWallClockMs","detectedAtFragmentSn","sendAdDetectTracking","isManifestBasedMarker","forceImmediate","isManifestMarker","immediateManifestAds","hasPts","clearAdStartTimer","handleAdStart","tol","driftToleranceMs","nowMs","estCurrentPtsMs","deltaMs","floor","markerPtsMs","tolerance","scheduleAdStartIn","elapsedMs","remainingMs","hasQueuedAds","activeAdRequest","clearAdStopTimer","num","dStr","d","res","elapsedMatch","durationMatch","slashMatch","regex","exec","rawVal","val","n","splice_command_type","BitReader","buf","bytePos","bitPos","readBits","numBits","remainingInByte","toRead","currentByte","shift","mask","bits","skipBits","r","tableId","sectionLength","ptsAdjHigh","ptsAdjLow","spliceCommandLength","spliceCommandType","cancel","outOfNetwork","programSpliceFlag","durationFlag","spliceImmediateFlag","timeSpecifiedFlag","componentCount","high","low","durationTicks","initializeTracking","heartbeatInterval","setInterval","sendHeartbeatIfNeeded","getCurrentAdIndex","getTotalAdsInBreak","isShowingAds","shouldShowNativeControls","runContinuousFetchLoop","backoffMs","mult","pow","_marker","adBreakDurationMs","state","clearPendingAdBreak","showPlaceholderAndWaitForAds","startContinuousFetchLoop","stopContinuousFetching","tryNextAvailableAdWithRateLimit","backoffDelay","effectiveMinInterval","timeSinceLastRequest","waitTime","backoffMultiplier","tryNextAvailableAd","_retryCount","checkInterval","maxChecks","_currentTimeSec","ensureAdStoppedByTimer","ms","adBreakCheckIntervalMs","maxAdBreakExtensionMs","maxExtensionMsConfig","elapsedSinceStartMs","expectedDurationMs","pendingAds","overrunMs","maxExtensionMs","checkIntervalMs","delayMs","adStartTimerId","ptsSecondsSample","isFinite","sampleMs","alpha","isTizen","startAdRequestWatchdog","token","adFailsafeTimeoutMs","adRequestWatchdogId","logAdState","timeoutMs","startAdFailsafeTimer","failsafeMs","adFailsafeTimerId","videoPaused","imaAdPlaying","extra","MAX_SAFE_INTEGER","toggleMute","currentPerceptualState","isMuted","newMutedState","toggleFullscreen","fullscreenElement","requestFullscreen","setMuted","setVolume","clampedVolume","getVolume","isFullscreen","clientWidth","clientHeight","removeEventListener","clearInterval","import_fa","import_jsx_runtime","CRITICAL_PROPS","React","memo","props"],"mappings":"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","sourcesContent":["\"use strict\";\nvar __create = Object.create;\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __getProtoOf = Object.getPrototypeOf;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(\n // If the importer is in node compatibility mode or this is not an ESM\n // file that has been converted to a CommonJS file using a Babel-\n // compatible transform (i.e. \"__esModule\" has not been set), then set\n // \"default\" to the CommonJS \"module.exports\" for node compatibility.\n isNodeMode || !mod || !mod.__esModule ? __defProp(target, \"default\", { value: mod, enumerable: true }) : target,\n mod\n));\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\n\n// src/ui/StormcloudVideoPlayer.tsx\nvar StormcloudVideoPlayer_exports = {};\n__export(StormcloudVideoPlayer_exports, {\n StormcloudVideoPlayerComponent: () => StormcloudVideoPlayerComponent\n});\nmodule.exports = __toCommonJS(StormcloudVideoPlayer_exports);\nvar import_react = __toESM(require(\"react\"), 1);\n\n// src/player/StormcloudVideoPlayer.ts\nvar import_hls2 = __toESM(require(\"hls.js\"), 1);\n\n// src/sdk/prebid.ts\nvar DEFAULT_TIMEOUT_MS = 3e3;\nvar AUCTION_URL = \"https://sspproxy.adstorm.co/openrtb2/auction/adstorm\";\nfunction createPrebidManager(options = {}) {\n let initialized = false;\n const debug = options.debug ?? false;\n function log(...args) {\n if (debug) {\n console.log(\"[Prebid]\", ...args);\n }\n }\n function warn(...args) {\n console.warn(\"[Prebid]\", ...args);\n }\n function parseResponse(data) {\n const bids = [];\n const seatbids = data?.seatbid || [];\n const currency = data?.cur || \"USD\";\n for (const seatbid of seatbids) {\n const seat = seatbid.seat || \"unknown\";\n const bidArray = seatbid.bid || [];\n for (const bid of bidArray) {\n const cacheUrl = bid.ext?.prebid?.cache?.vastXml?.url;\n const vastXml = bid.adm || void 0;\n const bidResponse = {\n bidder: seat,\n cpm: bid.price || 0,\n width: bid.w || 0,\n height: bid.h || 0,\n adId: bid.id || \"\",\n impId: bid.impid || \"\",\n creativeId: bid.crid || \"\",\n currency\n };\n if (cacheUrl) bidResponse.vastUrl = cacheUrl;\n if (vastXml) bidResponse.vastXml = vastXml;\n if (bid.adomain) bidResponse.adomain = bid.adomain;\n bids.push(bidResponse);\n }\n }\n bids.sort((a, b) => b.cpm - a.cpm);\n return bids;\n }\n async function initialize() {\n if (initialized) return;\n initialized = true;\n log(\"Initialized, auction URL:\", AUCTION_URL);\n }\n async function requestBids() {\n if (!initialized) {\n throw new Error(\"Prebid not initialized. Call initialize() first.\");\n }\n const timeout = DEFAULT_TIMEOUT_MS;\n log(\"Fetching auction response from:\", AUCTION_URL);\n const controller = typeof AbortController !== \"undefined\" ? new AbortController() : null;\n const timeoutId = setTimeout(() => {\n controller?.abort();\n }, timeout + 2e3);\n try {\n const fetchOptions = {\n method: \"POST\"\n };\n if (controller) {\n fetchOptions.signal = controller.signal;\n }\n const response = await fetch(AUCTION_URL, fetchOptions);\n clearTimeout(timeoutId);\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new Error(\n `Prebid Server returned HTTP ${response.status}: ${body.slice(0, 200)}`\n );\n }\n const data = await response.json();\n if (debug && data?.ext?.responsetimemillis) {\n log(\"Bidder response times:\", data.ext.responsetimemillis);\n }\n if (debug && data?.ext?.errors) {\n warn(\"Auction errors:\", data.ext.errors);\n }\n const bids = parseResponse(data);\n log(`Received ${bids.length} bid(s)`);\n if (debug) {\n for (const b of bids) {\n log(\n ` ${b.bidder}: $${b.cpm.toFixed(2)} ${b.currency} ${b.width}x${b.height}` + (b.vastUrl ? \" [cached VAST]\" : \"\") + (b.vastXml && !b.vastUrl ? \" [VAST XML]\" : \"\")\n );\n }\n }\n return bids;\n } catch (error) {\n clearTimeout(timeoutId);\n if (error?.name === \"AbortError\") {\n warn(`Auction request timed out after ${timeout + 2e3}ms`);\n return [];\n }\n throw error;\n }\n }\n const REQUEST_BIDS_MAX_RETRIES = 3;\n const REQUEST_BIDS_BACKOFF_MS = 1500;\n async function requestBidsUntilResponse() {\n if (!initialized) {\n throw new Error(\"Prebid not initialized. Call initialize() first.\");\n }\n let lastError;\n for (let attempt = 1; attempt <= REQUEST_BIDS_MAX_RETRIES; attempt++) {\n try {\n const bids = await requestBids();\n if (bids.length > 0) {\n log(`requestBidsUntilResponse: got ${bids.length} bid(s) on attempt ${attempt}`);\n return bids;\n }\n log(`requestBidsUntilResponse: no bids on attempt ${attempt}/${REQUEST_BIDS_MAX_RETRIES}`);\n } catch (err) {\n lastError = err;\n warn(`requestBidsUntilResponse: attempt ${attempt}/${REQUEST_BIDS_MAX_RETRIES} failed:`, err);\n }\n if (attempt < REQUEST_BIDS_MAX_RETRIES) {\n const delay = REQUEST_BIDS_BACKOFF_MS * attempt;\n log(`requestBidsUntilResponse: waiting ${delay}ms before retry`);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n if (lastError instanceof Error) {\n throw lastError;\n }\n return [];\n }\n function destroy() {\n initialized = false;\n log(\"Destroyed\");\n }\n return {\n initialize,\n requestBids,\n requestBidsUntilResponse,\n destroy,\n get isInitialized() {\n return initialized;\n }\n };\n}\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\n// src/utils/tracking.ts\nvar cachedBrowserId = null;\nfunction getClientInfo() {\n const ua = navigator.userAgent;\n const platform = navigator.platform;\n const vendor = navigator.vendor || \"\";\n const maxTouchPoints = navigator.maxTouchPoints || 0;\n const memory = navigator.deviceMemory || null;\n const hardwareConcurrency = navigator.hardwareConcurrency || 1;\n const screenInfo = {\n width: screen?.width,\n height: screen?.height,\n availWidth: screen?.availWidth,\n availHeight: screen?.availHeight,\n orientation: screen?.orientation?.type || \"\",\n pixelDepth: screen?.pixelDepth\n };\n let deviceType = \"desktop\";\n let brand = \"Unknown\";\n let os = \"Unknown\";\n let model = \"\";\n let isSmartTV = false;\n let isAndroid = false;\n let isWebView = false;\n let isWebApp = false;\n if (ua.includes(\"Web0S\")) {\n brand = \"LG\";\n os = \"webOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n const webosMatch = ua.match(/Web0S\\/([^\\s]+)/);\n model = webosMatch ? `webOS ${webosMatch[1]}` : \"webOS TV\";\n } else if (ua.includes(\"Tizen\")) {\n brand = \"Samsung\";\n os = \"Tizen\";\n isSmartTV = true;\n deviceType = \"tv\";\n const tizenMatch = ua.match(/Tizen\\/([^\\s]+)/);\n const tvMatch = ua.match(/(?:Smart-TV|SMART-TV|TV)/i) ? \"Smart TV\" : \"\";\n model = tizenMatch ? `Tizen ${tizenMatch[1]} ${tvMatch}`.trim() : \"Tizen TV\";\n } else if (ua.includes(\"Philips\")) {\n brand = \"Philips\";\n os = \"Saphi\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Sharp\") || ua.includes(\"AQUOS\")) {\n brand = \"Sharp\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Android\") && (ua.includes(\"Sony\") || vendor.includes(\"Sony\"))) {\n brand = \"Sony\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Android\") && (ua.includes(\"NetCast\") || ua.includes(\"LG\"))) {\n brand = \"LG\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\" Roku\") || ua.includes(\"Roku/\")) {\n brand = \"Roku\";\n os = \"Roku OS\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"AppleTV\")) {\n brand = \"Apple\";\n os = \"tvOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n }\n if (ua.includes(\"Android\")) {\n isAndroid = true;\n os = \"Android\";\n deviceType = /Mobile/.test(ua) ? \"mobile\" : \"tablet\";\n if (ua.includes(\"Android\") && (maxTouchPoints === 0 || ua.includes(\"Google TV\") || ua.includes(\"XiaoMi\"))) {\n deviceType = \"tv\";\n isSmartTV = true;\n brand = brand === \"Unknown\" ? \"Android TV\" : brand;\n }\n const androidModelMatch = ua.match(/\\(([^)]*Android[^)]*)\\)/);\n if (androidModelMatch && androidModelMatch[1]) {\n model = androidModelMatch[1];\n }\n }\n if (/iPad|iPhone|iPod/.test(ua)) {\n os = \"iOS\";\n deviceType = \"mobile\";\n brand = \"Apple\";\n if (navigator.maxTouchPoints > 1 && /iPad/.test(ua)) {\n deviceType = \"tablet\";\n }\n }\n if (!isAndroid && !isSmartTV && !/Mobile/.test(ua)) {\n if (ua.includes(\"Windows\")) {\n os = \"Windows\";\n deviceType = \"desktop\";\n } else if (ua.includes(\"Mac\") && !/iPhone/.test(ua)) {\n os = \"macOS\";\n deviceType = \"desktop\";\n if (maxTouchPoints > 1) deviceType = \"tablet\";\n } else if (ua.includes(\"Linux\")) {\n os = \"Linux\";\n deviceType = \"desktop\";\n }\n }\n if (brand === \"Unknown\") {\n if (vendor.includes(\"Google\") || ua.includes(\"Chrome\")) brand = \"Google\";\n if (vendor.includes(\"Apple\")) brand = \"Apple\";\n if (vendor.includes(\"Samsung\") || ua.includes(\"SM-\")) brand = \"Samsung\";\n }\n isWebView = /wv|WebView|Linux; U;/.test(ua);\n if (window?.outerHeight === 0 && window?.outerWidth === 0) {\n isWebView = true;\n }\n isWebApp = window.matchMedia(\"(display-mode: standalone)\").matches || window.navigator.standalone === true || window.screen?.orientation?.angle !== void 0;\n return {\n brand,\n os,\n model: model || ua.substring(0, 50) + \"...\",\n deviceType,\n isSmartTV,\n isAndroid,\n isWebView,\n isWebApp,\n domain: window.location.hostname,\n origin: window.location.origin,\n path: window.location.pathname,\n userAgent: ua,\n vendor,\n platform,\n screen: screenInfo,\n hardwareConcurrency,\n deviceMemory: memory,\n maxTouchPoints,\n language: navigator.language,\n languages: navigator.languages?.join(\",\") || \"\",\n cookieEnabled: navigator.cookieEnabled,\n doNotTrack: navigator.doNotTrack || \"\",\n referrer: document.referrer,\n visibilityState: document.visibilityState\n };\n}\nasync function getBrowserID(clientInfo) {\n if (cachedBrowserId) {\n return cachedBrowserId;\n }\n const fingerprintString = JSON.stringify(clientInfo);\n if (typeof crypto !== \"undefined\" && crypto.subtle && crypto.subtle.digest) {\n try {\n await crypto.subtle.digest(\"SHA-256\", new Uint8Array([1, 2, 3]));\n let encodedData;\n if (typeof TextEncoder !== \"undefined\") {\n encodedData = new TextEncoder().encode(fingerprintString);\n } else {\n const utf8 = unescape(encodeURIComponent(fingerprintString));\n const buffer = new Uint8Array(utf8.length);\n for (let i = 0; i < utf8.length; i++) {\n buffer[i] = utf8.charCodeAt(i);\n }\n encodedData = buffer;\n }\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", encodedData);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n const hashHex = hashArray.map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n cachedBrowserId = hashHex;\n return hashHex;\n } catch (error) {\n console.warn(\n \"[StormcloudVideoPlayer] crypto.subtle.digest not supported, using fallback hash\"\n );\n }\n }\n let hash = 0;\n for (let i = 0; i < fingerprintString.length; i++) {\n const char = fingerprintString.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n const fallbackHash = Math.abs(hash).toString(16).padStart(8, \"0\");\n const timestamp = Date.now().toString(16).padStart(12, \"0\");\n const random = Math.random().toString(16).substring(2, 14).padStart(12, \"0\");\n cachedBrowserId = (fallbackHash + timestamp + random).padEnd(64, \"0\");\n return cachedBrowserId;\n}\nvar TRACK_URL = \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track\";\nasync function sendTrackRequest(licenseKey, body) {\n const headers = {\n \"Content-Type\": \"application/json\"\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n const response = await fetch(TRACK_URL, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body)\n });\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n await response.json();\n}\nasync function sendInitialTracking(licenseKey) {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData = {\n browserId,\n ...clientInfo\n };\n const headers = {\n \"Content-Type\": \"application/json\"\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n const response = await fetch(TRACK_URL, {\n method: \"POST\",\n headers,\n body: JSON.stringify(trackingData)\n });\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n await response.json();\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending initial tracking data:\",\n error\n );\n }\n}\nasync function sendAdDetectTracking(licenseKey, adDetectInfo) {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData = { browserId, ...clientInfo };\n await sendTrackRequest(licenseKey, {\n ...trackingData,\n licenseKey,\n adDetectInfo\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad detect tracking:\",\n error\n );\n }\n}\nasync function sendAdLoadedTracking(licenseKey, adLoadedInfo) {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData = { browserId, ...clientInfo };\n await sendTrackRequest(licenseKey, {\n ...trackingData,\n licenseKey,\n adLoadedInfo\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad loaded tracking:\",\n error\n );\n }\n}\nasync function sendAdImpressionTracking(licenseKey, adImpressionInfo) {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData = { browserId, ...clientInfo };\n await sendTrackRequest(licenseKey, {\n ...trackingData,\n licenseKey,\n adImpressionInfo\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad impression tracking:\",\n error\n );\n }\n}\nasync function sendHeartbeat(licenseKey) {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const heartbeatData = {\n browserId,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n };\n const headers = {\n \"Content-Type\": \"application/json\"\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n const response = await fetch(\n \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/heartbeat\",\n {\n method: \"POST\",\n headers,\n body: JSON.stringify(heartbeatData)\n }\n );\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n await response.json();\n } catch (error) {\n console.error(\"[StormcloudVideoPlayer] Error sending heartbeat:\", error);\n }\n}\n\n// src/utils/polyfills.ts\nfunction polyfillURLSearchParams() {\n if (typeof URLSearchParams !== \"undefined\") {\n return;\n }\n class URLSearchParamsPolyfill {\n constructor(init) {\n this.params = /* @__PURE__ */ new Map();\n if (typeof init === \"string\") {\n this.parseQueryString(init);\n } else if (init instanceof URLSearchParamsPolyfill) {\n init.forEach((value, key) => {\n this.append(key, value);\n });\n }\n }\n parseQueryString(query) {\n const cleanQuery = query.startsWith(\"?\") ? query.slice(1) : query;\n if (!cleanQuery) return;\n cleanQuery.split(\"&\").forEach((param) => {\n const [key, value] = param.split(\"=\");\n if (key) {\n const decodedKey = this.safeDecodeURIComponent(key);\n const decodedValue = value ? this.safeDecodeURIComponent(value) : \"\";\n this.append(decodedKey, decodedValue);\n }\n });\n }\n safeDecodeURIComponent(str) {\n try {\n return decodeURIComponent(str.replace(/\\+/g, \" \"));\n } catch (e) {\n return str;\n }\n }\n append(name, value) {\n const values = this.params.get(name) || [];\n values.push(String(value));\n this.params.set(name, values);\n }\n delete(name) {\n this.params.delete(name);\n }\n get(name) {\n const values = this.params.get(name);\n return values && values.length > 0 && values[0] !== void 0 ? values[0] : null;\n }\n getAll(name) {\n return this.params.get(name) || [];\n }\n has(name) {\n return this.params.has(name);\n }\n set(name, value) {\n this.params.set(name, [String(value)]);\n }\n forEach(callback) {\n this.params.forEach((values, key) => {\n values.forEach((value) => {\n callback(value, key, this);\n });\n });\n }\n toString() {\n const parts = [];\n this.params.forEach((values, key) => {\n values.forEach((value) => {\n parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);\n });\n });\n return parts.join(\"&\");\n }\n }\n window.URLSearchParams = URLSearchParamsPolyfill;\n}\nfunction polyfillTextEncoder() {\n if (typeof TextEncoder !== \"undefined\") {\n return;\n }\n class TextEncoderPolyfill {\n constructor() {\n this.encoding = \"utf-8\";\n }\n encode(str) {\n const utf8 = [];\n for (let i = 0; i < str.length; i++) {\n let charcode = str.charCodeAt(i);\n if (charcode < 128) {\n utf8.push(charcode);\n } else if (charcode < 2048) {\n utf8.push(192 | charcode >> 6, 128 | charcode & 63);\n } else if (charcode < 55296 || charcode >= 57344) {\n utf8.push(\n 224 | charcode >> 12,\n 128 | charcode >> 6 & 63,\n 128 | charcode & 63\n );\n } else {\n i++;\n charcode = 65536 + ((charcode & 1023) << 10 | str.charCodeAt(i) & 1023);\n utf8.push(\n 240 | charcode >> 18,\n 128 | charcode >> 12 & 63,\n 128 | charcode >> 6 & 63,\n 128 | charcode & 63\n );\n }\n }\n return new Uint8Array(utf8);\n }\n }\n window.TextEncoder = TextEncoderPolyfill;\n}\nfunction polyfillPromiseFinally() {\n if (typeof Promise !== \"undefined\" && !Promise.prototype.finally) {\n Promise.prototype.finally = function(callback) {\n const constructor = this.constructor;\n return this.then(\n (value) => constructor.resolve(callback()).then(() => value),\n (reason) => constructor.resolve(callback()).then(() => {\n throw reason;\n })\n );\n };\n }\n}\nfunction polyfillObjectAssign() {\n if (typeof Object.assign !== \"function\") {\n Object.assign = function(target, ...sources) {\n if (target == null) {\n throw new TypeError(\"Cannot convert undefined or null to object\");\n }\n const to = Object(target);\n for (let i = 0; i < sources.length; i++) {\n const nextSource = sources[i];\n if (nextSource != null) {\n for (const nextKey in nextSource) {\n if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {\n to[nextKey] = nextSource[nextKey];\n }\n }\n }\n }\n return to;\n };\n }\n}\nfunction polyfillArrayFrom() {\n if (!Array.from) {\n Array.from = function(arrayLike, mapFn, thisArg) {\n const items = Object(arrayLike);\n if (arrayLike == null) {\n throw new TypeError(\"Array.from requires an array-like object\");\n }\n const len = items.length >>> 0;\n const result = new Array(len);\n for (let i = 0; i < len; i++) {\n if (mapFn) {\n result[i] = mapFn.call(thisArg, items[i], i);\n } else {\n result[i] = items[i];\n }\n }\n return result;\n };\n }\n}\nfunction polyfillStringStartsWith() {\n if (!String.prototype.startsWith) {\n String.prototype.startsWith = function(search, pos) {\n pos = !pos || pos < 0 ? 0 : +pos;\n return this.substring(pos, pos + search.length) === search;\n };\n }\n}\nfunction polyfillStringEndsWith() {\n if (!String.prototype.endsWith) {\n String.prototype.endsWith = function(search, length) {\n if (length === void 0 || length > this.length) {\n length = this.length;\n }\n return this.substring(length - search.length, length) === search;\n };\n }\n}\nfunction polyfillStringIncludes() {\n if (!String.prototype.includes) {\n String.prototype.includes = function(search, start) {\n if (typeof start !== \"number\") {\n start = 0;\n }\n if (start + search.length > this.length) {\n return false;\n }\n return this.indexOf(search, start) !== -1;\n };\n }\n}\nfunction initializePolyfills() {\n polyfillObjectAssign();\n polyfillArrayFrom();\n polyfillStringStartsWith();\n polyfillStringEndsWith();\n polyfillStringIncludes();\n polyfillURLSearchParams();\n polyfillTextEncoder();\n polyfillPromiseFinally();\n}\n\n// src/utils/browserCompat.ts\nfunction getChromeVersion(ua) {\n const match = ua.match(/Chrome\\/(\\d+)/);\n return match && match[1] ? parseInt(match[1], 10) : 0;\n}\nfunction getWebKitVersion(ua) {\n const match = ua.match(/AppleWebKit\\/(\\d+)/);\n return match && match[1] ? parseInt(match[1], 10) : 0;\n}\nfunction getPlatform() {\n if (\"userAgentData\" in navigator && navigator.userAgentData?.platform) {\n return navigator.userAgentData.platform;\n }\n const ua = navigator.userAgent;\n if (/Mac|iPhone|iPad|iPod/i.test(ua)) {\n return /iPhone|iPad|iPod/i.test(ua) ? \"iPhone\" : \"MacIntel\";\n }\n if (/Win/i.test(ua)) {\n return \"Win32\";\n }\n if (/Linux/i.test(ua)) {\n return /Android/i.test(ua) ? \"Linux armv8l\" : \"Linux x86_64\";\n }\n if (/CrOS/i.test(ua)) {\n return \"CrOS\";\n }\n return navigator.platform || \"Unknown\";\n}\nfunction detectBrowser() {\n const ua = navigator.userAgent;\n const platform = getPlatform();\n let name = \"Unknown\";\n let version = \"0\";\n let majorVersion = 0;\n let isSmartTV = false;\n let isLegacyTV = false;\n let supportsIMA = true;\n let supportsModernJS = true;\n let recommendedAdPlayer = \"ima\";\n let webOSVersion;\n let tizenVersion;\n let chromeVersionNum;\n const chromeVersion = getChromeVersion(ua);\n const webkitVersion = getWebKitVersion(ua);\n chromeVersionNum = chromeVersion > 0 ? chromeVersion : void 0;\n if (/Web0S|webOS|LG Browser|LGSTB/i.test(ua)) {\n name = \"LG WebOS\";\n isSmartTV = true;\n let match = ua.match(/Web0S[/\\s]*([\\d.]+)/i) || ua.match(/webOS[/\\s]*([\\d.]+)/i);\n if (!match || !match[1]) {\n match = ua.match(/webOSTV[/\\s-]*([\\d.]+)/i) || ua.match(/webOS\\.TV[/\\s-]*([\\d.]+)/i);\n }\n if (match && match[1]) {\n version = match[1];\n const parts = version.split(\".\");\n majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;\n webOSVersion = majorVersion;\n } else if (chromeVersion > 0) {\n if (chromeVersion >= 79) {\n webOSVersion = 6;\n version = \"6.0\";\n majorVersion = 6;\n } else if (chromeVersion >= 68) {\n webOSVersion = 5;\n version = \"5.0\";\n majorVersion = 5;\n } else if (chromeVersion >= 53) {\n webOSVersion = 4;\n version = \"4.0\";\n majorVersion = 4;\n } else if (chromeVersion >= 38) {\n webOSVersion = 3;\n version = \"3.0\";\n majorVersion = 3;\n } else {\n webOSVersion = 2;\n version = \"2.0\";\n majorVersion = 2;\n }\n } else {\n version = \"Unknown\";\n webOSVersion = void 0;\n }\n if (webOSVersion !== void 0 && webOSVersion >= 4) {\n supportsIMA = true;\n recommendedAdPlayer = \"ima\";\n isLegacyTV = false;\n } else if (webOSVersion !== void 0 && webOSVersion >= 3) {\n if (chromeVersion >= 53) {\n supportsIMA = true;\n recommendedAdPlayer = \"ima\";\n isLegacyTV = false;\n } else {\n supportsIMA = false;\n recommendedAdPlayer = \"hls\";\n isLegacyTV = true;\n }\n } else if (chromeVersion >= 53) {\n supportsIMA = true;\n recommendedAdPlayer = \"ima\";\n isLegacyTV = false;\n } else {\n supportsIMA = false;\n recommendedAdPlayer = \"hls\";\n isLegacyTV = true;\n }\n } else if (/Tizen/i.test(ua)) {\n name = \"Samsung Tizen\";\n isSmartTV = true;\n const match = ua.match(/Tizen[/\\s]*([\\d.]+)/i);\n version = match && match[1] ? match[1] : \"Unknown\";\n if (version !== \"Unknown\") {\n const parts = version.split(\".\");\n majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;\n tizenVersion = majorVersion;\n }\n if (tizenVersion !== void 0 && tizenVersion >= 4) {\n supportsIMA = true;\n recommendedAdPlayer = \"ima\";\n isLegacyTV = false;\n } else if (tizenVersion !== void 0 && tizenVersion >= 3 && chromeVersion >= 47) {\n supportsIMA = true;\n recommendedAdPlayer = \"ima\";\n isLegacyTV = false;\n } else if (chromeVersion >= 53) {\n supportsIMA = true;\n recommendedAdPlayer = \"ima\";\n isLegacyTV = false;\n } else {\n supportsIMA = false;\n recommendedAdPlayer = \"hls\";\n isLegacyTV = true;\n }\n } else if (/SMART-TV|SmartTV/i.test(ua)) {\n name = \"Smart TV\";\n isSmartTV = true;\n if (chromeVersion >= 53) {\n supportsIMA = true;\n recommendedAdPlayer = \"ima\";\n } else {\n supportsIMA = false;\n recommendedAdPlayer = \"hls\";\n isLegacyTV = true;\n }\n } else if (/NetCast/i.test(ua)) {\n name = \"LG NetCast\";\n isSmartTV = true;\n isLegacyTV = true;\n supportsIMA = false;\n recommendedAdPlayer = \"hls\";\n } else if (/BRAVIA/i.test(ua)) {\n name = \"Sony BRAVIA\";\n isSmartTV = true;\n if (chromeVersion >= 53) {\n supportsIMA = true;\n recommendedAdPlayer = \"ima\";\n } else {\n supportsIMA = false;\n recommendedAdPlayer = \"hls\";\n isLegacyTV = true;\n }\n } else {\n if (chromeVersion > 0) {\n name = \"Chrome\";\n version = chromeVersion.toString();\n majorVersion = chromeVersion;\n if (chromeVersion < 50) {\n supportsIMA = false;\n supportsModernJS = false;\n recommendedAdPlayer = \"hls\";\n }\n }\n if (webkitVersion > 0 && webkitVersion < 600) {\n supportsModernJS = false;\n if (chromeVersion < 50) {\n supportsIMA = false;\n recommendedAdPlayer = \"hls\";\n }\n }\n }\n if (typeof Promise === \"undefined\" || typeof Map === \"undefined\" || typeof Set === \"undefined\") {\n supportsModernJS = false;\n supportsIMA = false;\n recommendedAdPlayer = \"hls\";\n }\n if (typeof URLSearchParams === \"undefined\") {\n supportsModernJS = false;\n }\n return {\n name,\n version,\n majorVersion,\n isSmartTV,\n isLegacyTV,\n platform,\n supportsIMA,\n supportsModernJS,\n recommendedAdPlayer,\n webOSVersion,\n tizenVersion,\n chromeVersion: chromeVersionNum\n };\n}\nfunction supportsGoogleIMA() {\n const browser = detectBrowser();\n if (browser.isLegacyTV) {\n return false;\n }\n if (typeof document === \"undefined\" || typeof document.createElement !== \"function\") {\n return false;\n }\n try {\n const video = document.createElement(\"video\");\n if (!video) {\n return false;\n }\n } catch (e) {\n return false;\n }\n if (typeof Promise === \"undefined\") {\n return false;\n }\n return browser.supportsIMA;\n}\nfunction logBrowserInfo(debug = false) {\n if (!debug) return;\n const browser = detectBrowser();\n const imaSupport = supportsGoogleIMA();\n console.log(\"[StormcloudVideoPlayer] Browser Compatibility Info:\", {\n browser: `${browser.name} ${browser.version}`,\n platform: browser.platform,\n isSmartTV: browser.isSmartTV,\n isLegacyTV: browser.isLegacyTV,\n supportsIMA: imaSupport,\n supportsModernJS: browser.supportsModernJS,\n recommendedAdPlayer: browser.recommendedAdPlayer,\n ...browser.webOSVersion !== void 0 ? { webOSVersion: browser.webOSVersion } : {},\n ...browser.tizenVersion !== void 0 ? { tizenVersion: browser.tizenVersion } : {},\n ...browser.chromeVersion !== void 0 ? { chromeVersion: browser.chromeVersion } : {},\n userAgent: navigator.userAgent\n });\n}\nfunction getBrowserConfigOverrides() {\n const browser = detectBrowser();\n const overrides = {};\n if (browser.isSmartTV) {\n overrides.allowNativeHls = true;\n }\n return overrides;\n}\n\n// src/player/StormcloudVideoPlayer.ts\nvar StormcloudVideoPlayer = class {\n constructor(config) {\n this.pendingNextAdBids = null;\n this.continuousFetchLoopPromise = null;\n this.attached = false;\n this.inAdBreak = false;\n this.ptsDriftEmaMs = 0;\n this.adPodQueue = [];\n this.lastHeartbeatTime = 0;\n this.currentAdIndex = 0;\n this.totalAdsInBreak = 0;\n this.showAds = false;\n this.isLiveStream = false;\n this.nativeHlsMode = false;\n this.videoSrcProtection = null;\n this.bufferedSegmentsCount = 0;\n this.shouldAutoplayAfterBuffering = false;\n this.hasInitialBufferCompleted = false;\n this.activeAdRequestToken = null;\n this.adRequestWatchdogToken = null;\n this.adFailsafeToken = null;\n this.continuousFetchingActive = false;\n this.maxPlaceholderDurationMs = 5e3;\n this.isShowingPlaceholder = false;\n this.totalAdRequestsInBreak = 0;\n this.maxTotalAdRequestsPerBreak = 20;\n this.pendingAdBreak = null;\n this.savedMutedStateBeforeScte = null;\n this.consecutiveFailures = 0;\n this.maxConsecutiveFailures = 5;\n this.lastAdRequestTime = 0;\n this.minAdRequestIntervalMs = 2500;\n this.backoffBaseMs = 1e3;\n this.maxBackoffMs = 15e3;\n this.adTransitionGapMs = 1500;\n initializePolyfills();\n const browserOverrides = getBrowserConfigOverrides();\n this.config = { ...browserOverrides, ...config };\n this.video = config.videoElement;\n logBrowserInfo(config.debugAdTiming);\n this.prebidManager = createPrebidManager(\n config.debugAdTiming !== void 0 ? { debug: !!config.debugAdTiming } : {}\n );\n this.adLayer = createPrebidAdLayer(this.video, {\n continueLiveStreamDuringAds: false,\n debug: !!config.debugAdTiming\n });\n }\n async adRequest() {\n await this.prebidManager.initialize();\n return this.prebidManager.requestBidsUntilResponse();\n }\n async load() {\n if (!this.attached) {\n this.attach();\n }\n this.initializeTracking();\n if (this.shouldUseNativeHls()) {\n this.nativeHlsMode = true;\n this.videoSrcProtection = this.config.src;\n this.video.src = this.config.src;\n this.isLiveStream = this.config.lowLatencyMode ?? false;\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Using native HLS playback - VOD mode:\",\n {\n isLive: this.isLiveStream,\n allowNativeHls: this.config.allowNativeHls,\n adBehavior: \"vod (main video pauses during ads)\"\n }\n );\n }\n this.adLayer.updateOptions({ continueLiveStreamDuringAds: false, mainHlsInstance: null });\n if (this.config.autoplay) {\n await this.video.play()?.catch(() => {\n });\n }\n return;\n }\n this.hls = new import_hls2.default({\n enableWorker: true,\n backBufferLength: 30,\n liveDurationInfinity: true,\n lowLatencyMode: !!this.config.lowLatencyMode,\n maxLiveSyncPlaybackRate: this.config.lowLatencyMode ? 1.5 : 1,\n ...this.config.lowLatencyMode ? { liveSyncDuration: 2 } : {},\n maxBufferLength: 30,\n maxMaxBufferLength: 600,\n maxBufferSize: 60 * 1e3 * 1e3,\n maxBufferHole: 0.5,\n highBufferWatchdogPeriod: 2,\n nudgeOffset: 0.1,\n nudgeMaxRetry: 3,\n startPosition: -1\n });\n this.hls.on(import_hls2.default.Events.MEDIA_ATTACHED, () => {\n this.hls?.loadSource(this.config.src);\n });\n this.hls.on(import_hls2.default.Events.MANIFEST_PARSED, async (_, data) => {\n if (this.config.allowNativeHls === false) {\n this.isLiveStream = true;\n } else {\n this.isLiveStream = this.hls?.levels?.some(\n (level) => level?.details?.live === true || level?.details?.type === \"LIVE\"\n ) ?? false;\n }\n if (this.config.debugAdTiming) {\n const adBehavior = this.shouldContinueLiveStreamDuringAds() ? \"live (main video continues muted during ads)\" : \"vod (main video pauses during ads)\";\n console.log(\"[StormcloudVideoPlayer] Stream type detected:\", {\n isLive: this.isLiveStream,\n allowNativeHls: this.config.allowNativeHls,\n adBehavior\n });\n }\n this.adLayer.updateOptions({\n continueLiveStreamDuringAds: this.shouldContinueLiveStreamDuringAds(),\n mainHlsInstance: this.hls ?? null\n });\n this.bufferedSegmentsCount = 0;\n this.hasInitialBufferCompleted = false;\n this.shouldAutoplayAfterBuffering = !!this.config.autoplay;\n const minSegments = this.config.minSegmentsBeforePlay ?? 2;\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Waiting for\",\n minSegments,\n \"segments to buffer before playback\"\n );\n }\n if (minSegments === 0 || !this.config.autoplay) {\n this.hasInitialBufferCompleted = true;\n if (this.config.autoplay) {\n await this.video.play()?.catch(() => {\n });\n }\n }\n });\n this.hls.on(import_hls2.default.Events.LEVEL_LOADED, (_evt, data) => {\n if (this.inAdBreak || this.pendingAdBreak) {\n return;\n }\n const details = data?.details;\n if (!details || !details.fragments || details.fragments.length === 0) {\n return;\n }\n const fragmentsToScan = Math.min(5, details.fragments.length);\n for (let i = 0; i < fragmentsToScan; i++) {\n const frag = details.fragments[i];\n const tagList = frag?.tagList;\n if (!Array.isArray(tagList)) continue;\n for (const entry of tagList) {\n let tag = \"\";\n let value = \"\";\n if (Array.isArray(entry)) {\n tag = String(entry[0] ?? \"\");\n value = String(entry[1] ?? \"\");\n } else if (typeof entry === \"string\") {\n const idx = entry.indexOf(\":\");\n if (idx >= 0) {\n tag = entry.substring(0, idx);\n value = entry.substring(idx + 1);\n } else {\n tag = entry;\n }\n }\n if (!tag) continue;\n if (tag.includes(\"EXT-X-CUE-OUT\") || tag.includes(\"EXT-X-DATERANGE\")) {\n const attrs = tag.includes(\"EXT-X-DATERANGE\") ? this.parseAttributeList(value) : {};\n const hasScteOut = tag.includes(\"EXT-X-CUE-OUT\") || \"SCTE35-OUT\" in attrs || attrs[\"SCTE35-OUT\"] !== void 0;\n if (hasScteOut) {\n const durationSeconds = this.parseCueOutDuration(value);\n const marker = {\n type: \"start\",\n ...durationSeconds !== void 0 ? { durationSeconds } : {},\n raw: { tag, value, earlyDetection: true }\n };\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] \\u{1F3AF} EARLY SCTE-35 DETECTION: Ad break marker found in fragment\", i, \"- starting pre-fetch (NOT playing yet)\");\n }\n this.startAdPrefetch(marker, frag?.sn);\n return;\n }\n }\n }\n }\n });\n this.hls.on(import_hls2.default.Events.FRAG_BUFFERED, async (_evt, data) => {\n if (this.hasInitialBufferCompleted) {\n return;\n }\n this.bufferedSegmentsCount++;\n const minSegments = this.config.minSegmentsBeforePlay ?? 2;\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Buffered segment ${this.bufferedSegmentsCount}/${minSegments}`\n );\n }\n if (this.bufferedSegmentsCount >= minSegments) {\n this.hasInitialBufferCompleted = true;\n if (this.shouldAutoplayAfterBuffering) {\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Initial buffer complete (${this.bufferedSegmentsCount} segments). Starting playback.`\n );\n }\n await this.video.play()?.catch((err) => {\n if (this.config.debugAdTiming) {\n console.warn(\"[StormcloudVideoPlayer] Autoplay failed:\", err);\n }\n });\n }\n }\n });\n this.hls.on(import_hls2.default.Events.FRAG_PARSING_METADATA, (_evt, data) => {\n const id3Tags = (data?.samples || []).map((s) => ({\n key: \"ID3\",\n value: s?.data,\n ptsSeconds: s?.pts\n }));\n id3Tags.forEach((tag) => this.onId3Tag(tag));\n });\n this.hls.on(import_hls2.default.Events.FRAG_CHANGED, (_evt, data) => {\n const frag = data?.frag;\n const tagList = frag?.tagList;\n if (!Array.isArray(tagList)) return;\n for (const entry of tagList) {\n let tag = \"\";\n let value = \"\";\n if (Array.isArray(entry)) {\n tag = String(entry[0] ?? \"\");\n value = String(entry[1] ?? \"\");\n } else if (typeof entry === \"string\") {\n const idx = entry.indexOf(\":\");\n if (idx >= 0) {\n tag = entry.substring(0, idx);\n value = entry.substring(idx + 1);\n } else {\n tag = entry;\n value = \"\";\n }\n }\n if (!tag) continue;\n if (tag.includes(\"EXT-X-CUE-OUT-CONT\")) {\n const prog = this.parseCueOutCont(value);\n const marker = {\n type: \"progress\",\n ...prog?.duration !== void 0 ? { durationSeconds: prog.duration } : {},\n ...prog?.elapsed !== void 0 ? { ptsSeconds: prog.elapsed } : {},\n raw: { tag, value }\n };\n this.onScte35Marker(marker);\n } else if (tag.includes(\"EXT-X-CUE-OUT\")) {\n const durationSeconds = this.parseCueOutDuration(value);\n const marker = {\n type: \"start\",\n ...durationSeconds !== void 0 ? { durationSeconds } : {},\n raw: { tag, value }\n };\n this.onScte35Marker(marker);\n } else if (tag.includes(\"EXT-X-CUE-IN\")) {\n this.onScte35Marker({ type: \"end\", raw: { tag, value } });\n } else if (tag.includes(\"EXT-X-DATERANGE\")) {\n const attrs = this.parseAttributeList(value);\n const hasScteOut = \"SCTE35-OUT\" in attrs || attrs[\"SCTE35-OUT\"] !== void 0;\n const hasScteIn = \"SCTE35-IN\" in attrs || attrs[\"SCTE35-IN\"] !== void 0;\n const klass = String(attrs[\"CLASS\"] ?? \"\");\n const duration = this.toNumber(attrs[\"DURATION\"]);\n if (hasScteOut || /com\\.apple\\.hls\\.cue/i.test(klass)) {\n const marker = {\n type: \"start\",\n ...duration !== void 0 ? { durationSeconds: duration } : {},\n raw: { tag, value, attrs }\n };\n this.onScte35Marker(marker);\n }\n if (hasScteIn) {\n this.onScte35Marker({ type: \"end\", raw: { tag, value, attrs } });\n }\n }\n }\n });\n this.hls.on(import_hls2.default.Events.ERROR, (_evt, data) => {\n if (data?.fatal) {\n switch (data.type) {\n case import_hls2.default.ErrorTypes.NETWORK_ERROR:\n this.hls?.startLoad();\n break;\n case import_hls2.default.ErrorTypes.MEDIA_ERROR:\n this.hls?.recoverMediaError();\n break;\n default:\n this.destroy();\n break;\n }\n }\n });\n this.hls.attachMedia(this.video);\n }\n getAdSource() {\n return \"prebid\";\n }\n attachAdLayerEventListeners() {\n this.adLayer.on(\"ad_impression\", () => {\n if (this.config.licenseKey) {\n sendAdImpressionTracking(this.config.licenseKey, {\n source: this.getAdSource(),\n adIndex: this.currentAdIndex,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n });\n }\n });\n this.adLayer.on(\"ad_error\", (errorPayload) => {\n let errorMessage = \"Ad playback failed\";\n if (errorPayload) {\n const errorCode = errorPayload.code || errorPayload.errorCode || \"unknown\";\n const vastErrorCode = errorPayload.vastErrorCode;\n const message = errorPayload.message || errorPayload.errorMessage || \"Unknown error\";\n const cause = errorPayload.cause || errorPayload.innerError || errorPayload.error;\n errorMessage = `Ad error: AdError ${errorCode}: ${message}`;\n if (vastErrorCode && vastErrorCode !== \"N/A\" && vastErrorCode !== errorCode) {\n errorMessage += ` (VAST Error Code: ${vastErrorCode})`;\n }\n if (cause) {\n const causeMessage = typeof cause === \"string\" ? cause : cause.message || String(cause);\n errorMessage += `. Caused by: ${causeMessage}`;\n }\n }\n console.error(\"[AD-ERROR]\", errorMessage, errorPayload || \"\");\n this.adLayer.stop().catch(() => {\n });\n this.handleAdFailure();\n });\n this.adLayer.on(\"content_pause\", () => {\n this.clearAdFailsafeTimer();\n this.clearAdRequestWatchdog();\n this.activeAdRequestToken = null;\n this.showAds = true;\n if (this.inAdBreak && this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {\n this.scheduleAdStopCountdown(this.getRemainingAdMs());\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Starting ad break timer on content_pause (first ad starting)\");\n }\n }\n this.adLayer.setAdVolume(\n this.adLayer.getOriginalMutedState() ? 1 : this.adLayer.getOriginalVolume()\n );\n if (this.isShowingPlaceholder) {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Hiding placeholder - new ads starting\");\n }\n this.hidePlaceholderLayer();\n this.adLayer.hidePlaceholder();\n this.isShowingPlaceholder = false;\n }\n });\n this.adLayer.on(\"content_resume\", () => {\n const remaining = this.getRemainingAdMs();\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] content_resume received, inAdBreak=%s, remaining=%s, pendingNext=%s\",\n this.inAdBreak,\n remaining,\n !!this.pendingNextAdBids\n );\n }\n this.clearAdFailsafeTimer();\n this.clearAdRequestWatchdog();\n this.activeAdRequestToken = null;\n this.showAds = false;\n if (!this.inAdBreak) {\n const restoredMuted = this.adLayer.getOriginalMutedState();\n const restoredVolume = this.adLayer.getOriginalVolume();\n if (this.video.muted !== restoredMuted) this.video.muted = restoredMuted;\n if (Math.abs(this.video.volume - restoredVolume) > 0.01) this.video.volume = restoredVolume;\n return;\n }\n this.consecutiveFailures = 0;\n if (this.pendingNextAdBids && this.pendingNextAdBids.length > 0) {\n const bids = [...this.pendingNextAdBids];\n this.pendingNextAdBids = null;\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n }\n this.showPlaceholderLayer();\n this.adLayer.showPlaceholder();\n setTimeout(() => {\n if (!this.inAdBreak || bids.length === 0) return;\n this.currentAdIndex++;\n this.adLayer.playAd(bids).catch((err) => {\n if (this.config.debugAdTiming) console.warn(\"[StormcloudVideoPlayer] playAd(pending) failed:\", err);\n this.handleAdFailure();\n });\n }, this.adTransitionGapMs);\n return;\n }\n if (remaining <= 500 && this.expectedAdBreakDurationMs != null) {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] content_resume: remaining time low and duration known, ending ad pod\");\n }\n this.handleAdPodComplete();\n } else {\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n }\n }\n });\n }\n ensurePlaceholderContainer() {\n if (this.placeholderContainer) {\n return;\n }\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 = \"5\";\n container.style.backgroundColor = \"#000\";\n container.style.transition = \"opacity 0.3s ease-in-out\";\n container.style.opacity = \"0\";\n if (!this.video.parentElement) {\n if (this.config.debugAdTiming) {\n console.warn(\"[StormcloudVideoPlayer] Video element has no parent for placeholder container\");\n }\n return;\n }\n this.video.parentElement.appendChild(container);\n this.placeholderContainer = container;\n }\n showPlaceholderLayer() {\n this.ensurePlaceholderContainer();\n if (!this.placeholderContainer) {\n return;\n }\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Muted video when showing placeholder\");\n }\n }\n const wasHidden = this.placeholderContainer.style.display === \"none\" || this.placeholderContainer.style.opacity === \"0\";\n if (wasHidden) {\n this.placeholderContainer.style.transition = \"none\";\n } else {\n this.placeholderContainer.style.transition = \"opacity 0.3s ease-in-out\";\n }\n this.placeholderContainer.style.backgroundColor = \"#000\";\n this.placeholderContainer.style.display = \"flex\";\n this.placeholderContainer.offsetHeight;\n this.placeholderContainer.style.opacity = \"1\";\n this.placeholderContainer.style.pointerEvents = \"auto\";\n if (wasHidden) {\n requestAnimationFrame(() => {\n if (this.placeholderContainer) {\n this.placeholderContainer.style.transition = \"opacity 0.3s ease-in-out\";\n }\n });\n }\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Showing placeholder layer\");\n }\n }\n hidePlaceholderLayer() {\n if (!this.placeholderContainer) {\n return;\n }\n this.placeholderContainer.style.opacity = \"0\";\n setTimeout(() => {\n if (this.placeholderContainer) {\n this.placeholderContainer.style.display = \"none\";\n this.placeholderContainer.style.pointerEvents = \"none\";\n this.placeholderContainer.style.backgroundColor = \"#000\";\n }\n }, 300);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Hiding placeholder layer\");\n }\n }\n attach() {\n if (this.attached) return;\n this.attached = true;\n this.video.autoplay = !!this.config.autoplay;\n this.video.muted = !!this.config.muted;\n this.adLayer.initialize();\n this.adLayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n this.attachAdLayerEventListeners();\n this.timeUpdateHandler = () => {\n this.onTimeUpdate(this.video.currentTime);\n };\n this.video.addEventListener(\"timeupdate\", this.timeUpdateHandler);\n this.emptiedHandler = () => {\n if (this.nativeHlsMode && this.videoSrcProtection && !this.adLayer.isAdPlaying()) {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Video src was cleared, restoring:\",\n this.videoSrcProtection\n );\n }\n const currentTime = this.video.currentTime;\n const wasPaused = this.video.paused;\n this.video.src = this.videoSrcProtection;\n this.video.currentTime = currentTime;\n if (!wasPaused) {\n this.video.play().catch(() => {\n });\n }\n }\n };\n this.video.addEventListener(\"emptied\", this.emptiedHandler);\n }\n shouldUseNativeHls() {\n const streamType = this.getStreamType();\n if (streamType === \"other\") {\n return true;\n }\n const canNative = this.video.canPlayType(\"application/vnd.apple.mpegurl\");\n return !!(this.config.allowNativeHls && canNative);\n }\n onId3Tag(tag) {\n if (typeof tag.ptsSeconds === \"number\") {\n this.updatePtsDrift(tag.ptsSeconds);\n }\n const marker = this.parseScte35FromId3(tag);\n if (marker) {\n this.onScte35Marker(marker);\n }\n }\n parseScte35FromId3(tag) {\n const text = this.decodeId3ValueToText(tag.value);\n if (!text) return void 0;\n const cueOutMatch = text.match(/EXT-X-CUE-OUT(?::([^\\r\\n]*))?/i) || text.match(/CUE-OUT(?::([^\\r\\n]*))?/i);\n if (cueOutMatch) {\n const arg = (cueOutMatch[1] ?? \"\").trim();\n const dur = this.parseCueOutDuration(arg);\n const marker = {\n type: \"start\",\n ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n ...dur !== void 0 ? { durationSeconds: dur } : {},\n raw: { id3: text }\n };\n return marker;\n }\n const cueOutContMatch = text.match(/EXT-X-CUE-OUT-CONT:([^\\r\\n]*)/i);\n if (cueOutContMatch) {\n const arg = (cueOutContMatch[1] ?? \"\").trim();\n const cont = this.parseCueOutCont(arg);\n const marker = {\n type: \"progress\",\n ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n ...cont?.duration !== void 0 ? { durationSeconds: cont.duration } : {},\n raw: { id3: text }\n };\n return marker;\n }\n const cueInMatch = text.match(/EXT-X-CUE-IN\\b/i) || text.match(/CUE-IN\\b/i);\n if (cueInMatch) {\n const marker = {\n type: \"end\",\n ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n raw: { id3: text }\n };\n return marker;\n }\n const daterangeMatch = text.match(/EXT-X-DATERANGE:([^\\r\\n]*)/i);\n if (daterangeMatch) {\n const attrs = this.parseAttributeList(daterangeMatch[1] ?? \"\");\n const hasScteOut = \"SCTE35-OUT\" in attrs || attrs[\"SCTE35-OUT\"] !== void 0;\n const hasScteIn = \"SCTE35-IN\" in attrs || attrs[\"SCTE35-IN\"] !== void 0;\n const klass = String(attrs[\"CLASS\"] ?? \"\");\n const duration = this.toNumber(attrs[\"DURATION\"]);\n if (hasScteOut || /com\\.apple\\.hls\\.cue/i.test(klass)) {\n const marker = {\n type: \"start\",\n ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n ...duration !== void 0 ? { durationSeconds: duration } : {},\n raw: { id3: text, attrs }\n };\n return marker;\n }\n if (hasScteIn) {\n const marker = {\n type: \"end\",\n ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n raw: { id3: text, attrs }\n };\n return marker;\n }\n }\n if (/SCTE35-OUT/i.test(text)) {\n const marker = {\n type: \"start\",\n ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n raw: { id3: text }\n };\n return marker;\n }\n if (/SCTE35-IN/i.test(text)) {\n const marker = {\n type: \"end\",\n ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n raw: { id3: text }\n };\n return marker;\n }\n if (tag.value instanceof Uint8Array) {\n const bin = this.parseScte35Binary(tag.value);\n if (bin) return bin;\n }\n return void 0;\n }\n decodeId3ValueToText(value) {\n try {\n if (typeof value === \"string\") return value;\n const decoder = new TextDecoder(\"utf-8\", { fatal: false });\n const text = decoder.decode(value);\n if (text && /[\\x20-\\x7E]/.test(text)) return text;\n let out = \"\";\n for (let i = 0; i < value.length; i++)\n out += String.fromCharCode(value[i]);\n return out;\n } catch {\n return void 0;\n }\n }\n onScte35Marker(marker) {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] SCTE-35 marker detected:\", {\n type: marker.type,\n ptsSeconds: marker.ptsSeconds,\n durationSeconds: marker.durationSeconds,\n currentTime: this.video.currentTime,\n raw: marker.raw,\n hasPendingAdBreak: !!this.pendingAdBreak\n });\n }\n if (marker.type === \"start\") {\n this.savedMutedStateBeforeScte = {\n muted: this.video.muted,\n volume: this.video.volume\n };\n this.adLayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Muted video on SCTE start marker\");\n }\n }\n if (this.inAdBreak) {\n if (this.expectedAdBreakDurationMs == null && marker.durationSeconds != null) {\n this.expectedAdBreakDurationMs = marker.durationSeconds * 1e3;\n if (this.config.debugAdTiming) {\n console.log(`[StormcloudVideoPlayer] Updated ad break duration from subsequent marker: ${this.expectedAdBreakDurationMs}ms`);\n }\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n return;\n }\n this.inAdBreak = true;\n const durationMs = marker.durationSeconds != null ? marker.durationSeconds * 1e3 : this.pendingAdBreak?.marker.durationSeconds != null ? this.pendingAdBreak.marker.durationSeconds * 1e3 : void 0;\n this.expectedAdBreakDurationMs = durationMs;\n this.currentAdBreakStartWallClockMs = Date.now();\n if (this.config.licenseKey) {\n const adDetectInfo = {\n source: \"scte35\",\n timestamp: (/* @__PURE__ */ new Date()).toISOString(),\n ...marker.durationSeconds != null && { durationSeconds: marker.durationSeconds },\n ...marker.ptsSeconds != null && { ptsSeconds: marker.ptsSeconds },\n ...this.pendingAdBreak?.detectedAtFragmentSn != null && {\n detectedAtFragmentSn: this.pendingAdBreak.detectedAtFragmentSn\n }\n };\n sendAdDetectTracking(this.config.licenseKey, adDetectInfo);\n }\n const isManifestMarker = this.isManifestBasedMarker(marker);\n const forceImmediate = this.config.immediateManifestAds ?? true;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Ad start decision:\", {\n isManifestMarker,\n forceImmediate,\n hasPts: typeof marker.ptsSeconds === \"number\"\n });\n }\n if (isManifestMarker && forceImmediate) {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Starting ad immediately (manifest-based)\"\n );\n }\n this.clearAdStartTimer();\n this.handleAdStart(marker);\n } else if (typeof marker.ptsSeconds === \"number\") {\n const tol = this.config.driftToleranceMs ?? 1e3;\n const nowMs = this.video.currentTime * 1e3;\n const estCurrentPtsMs = nowMs - this.ptsDriftEmaMs;\n const deltaMs = Math.floor(marker.ptsSeconds * 1e3 - estCurrentPtsMs);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] PTS-based timing calculation:\", {\n nowMs,\n estCurrentPtsMs,\n markerPtsMs: marker.ptsSeconds * 1e3,\n deltaMs,\n tolerance: tol\n });\n }\n if (deltaMs > tol) {\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Scheduling ad start in ${deltaMs}ms`\n );\n }\n this.scheduleAdStartIn(deltaMs);\n } else {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Starting ad immediately (within tolerance)\"\n );\n }\n this.clearAdStartTimer();\n this.handleAdStart(marker);\n }\n } else {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Starting ad immediately (fallback)\"\n );\n }\n this.clearAdStartTimer();\n this.handleAdStart(marker);\n }\n if (this.expectedAdBreakDurationMs != null) {\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n return;\n }\n if (marker.type === \"progress\" && this.inAdBreak) {\n if (marker.durationSeconds != null) {\n this.expectedAdBreakDurationMs = marker.durationSeconds * 1e3;\n }\n if (this.expectedAdBreakDurationMs != null && this.currentAdBreakStartWallClockMs != null) {\n const elapsedMs = Date.now() - this.currentAdBreakStartWallClockMs;\n const remainingMs = Math.max(\n 0,\n this.expectedAdBreakDurationMs - elapsedMs\n );\n this.scheduleAdStopCountdown(remainingMs);\n }\n if (!this.adLayer.isAdPlaying() && this.pendingNextAdBids != null && this.pendingNextAdBids.length > 0) {\n const bids = this.pendingNextAdBids;\n this.pendingNextAdBids = null;\n this.currentAdIndex++;\n this.adLayer.playAd(bids).catch(() => this.handleAdFailure());\n }\n return;\n }\n if (marker.type === \"end\") {\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Muted video on SCTE end marker\");\n }\n }\n const remaining = this.getRemainingAdMs();\n const adPlaying = this.adLayer.isAdPlaying();\n const hasQueuedAds = this.pendingNextAdBids != null && this.pendingNextAdBids.length > 0;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] SCTE-35 end marker received:\", {\n remaining,\n adPlaying,\n hasQueuedAds,\n activeAdRequest: this.activeAdRequestToken !== null\n });\n }\n if (adPlaying || remaining > 500) {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Ignoring premature SCTE-35 end marker - ads still active or time remaining\");\n }\n return;\n }\n this.inAdBreak = false;\n this.expectedAdBreakDurationMs = void 0;\n this.currentAdBreakStartWallClockMs = void 0;\n this.clearAdStartTimer();\n this.clearAdStopTimer();\n if (adPlaying) {\n this.adLayer.stop().catch(() => {\n });\n }\n this.handleAdPodComplete();\n return;\n }\n }\n parseCueOutDuration(value) {\n const num = parseFloat(value.trim());\n if (!Number.isNaN(num)) return num;\n const match = value.match(/(?:^|[,\\s])DURATION\\s*=\\s*([0-9.]+)/i) || value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n if (match && match[1] != null) {\n const dStr = match[1];\n const d = parseFloat(dStr);\n return Number.isNaN(d) ? void 0 : d;\n }\n return void 0;\n }\n parseCueOutCont(value) {\n const res = {};\n const elapsedMatch = value.match(/Elapsed\\s*=\\s*([0-9.]+)/i);\n const durationMatch = value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n if (elapsedMatch && elapsedMatch[1] != null) {\n const e = parseFloat(elapsedMatch[1]);\n if (!Number.isNaN(e)) res.elapsed = e;\n }\n if (durationMatch && durationMatch[1] != null) {\n const d = parseFloat(durationMatch[1]);\n if (!Number.isNaN(d)) res.duration = d;\n }\n if (!(\"elapsed\" in res) || !(\"duration\" in res)) {\n const slashMatch = value.match(/([0-9.]+)\\s*\\/\\s*([0-9.]+)/);\n if (slashMatch && slashMatch[1] && slashMatch[2]) {\n const elapsed = parseFloat(slashMatch[1]);\n const duration = parseFloat(slashMatch[2]);\n if (!Number.isNaN(elapsed) && !(\"elapsed\" in res)) res.elapsed = elapsed;\n if (!Number.isNaN(duration) && !(\"duration\" in res)) res.duration = duration;\n }\n }\n if (\"elapsed\" in res || \"duration\" in res) return res;\n return void 0;\n }\n parseAttributeList(value) {\n const attrs = {};\n const regex = /([A-Z0-9-]+)=((\"[^\"]*\")|([^\",]*))(?:,|$)/gi;\n let match;\n while ((match = regex.exec(value)) !== null) {\n const key = match[1] ?? \"\";\n let rawVal = match[3] ?? match[4] ?? \"\";\n if (rawVal.startsWith('\"') && rawVal.endsWith('\"')) {\n rawVal = rawVal.slice(1, -1);\n }\n if (key) {\n attrs[key] = rawVal;\n }\n }\n return attrs;\n }\n toNumber(val) {\n if (val == null) return void 0;\n const n = typeof val === \"string\" ? parseFloat(val) : Number(val);\n return Number.isNaN(n) ? void 0 : n;\n }\n isManifestBasedMarker(marker) {\n const raw = marker.raw;\n if (!raw) return false;\n if (raw.tag) {\n const tag = String(raw.tag);\n return tag.includes(\"EXT-X-CUE-OUT\") || tag.includes(\"EXT-X-CUE-IN\") || tag.includes(\"EXT-X-DATERANGE\");\n }\n if (raw.id3) return false;\n if (raw.splice_command_type) return false;\n return false;\n }\n parseScte35Binary(data) {\n class BitReader {\n constructor(buf) {\n this.buf = buf;\n this.bytePos = 0;\n this.bitPos = 0;\n }\n readBits(numBits) {\n let result = 0;\n while (numBits > 0) {\n if (this.bytePos >= this.buf.length) return result;\n const remainingInByte = 8 - this.bitPos;\n const toRead = Math.min(numBits, remainingInByte);\n const currentByte = this.buf[this.bytePos];\n const shift = remainingInByte - toRead;\n const mask = (1 << toRead) - 1 & 255;\n const bits = currentByte >> shift & mask;\n result = result << toRead | bits;\n this.bitPos += toRead;\n if (this.bitPos >= 8) {\n this.bitPos = 0;\n this.bytePos += 1;\n }\n numBits -= toRead;\n }\n return result >>> 0;\n }\n skipBits(n) {\n this.readBits(n);\n }\n }\n const r = new BitReader(data);\n const tableId = r.readBits(8);\n if (tableId !== 252) return void 0;\n r.readBits(1);\n r.readBits(1);\n r.readBits(2);\n const sectionLength = r.readBits(12);\n r.readBits(8);\n r.readBits(1);\n r.readBits(6);\n const ptsAdjHigh = r.readBits(1);\n const ptsAdjLow = r.readBits(32);\n void ptsAdjHigh;\n void ptsAdjLow;\n r.readBits(8);\n r.readBits(12);\n const spliceCommandLength = r.readBits(12);\n const spliceCommandType = r.readBits(8);\n if (spliceCommandType !== 5) {\n return void 0;\n }\n r.readBits(32);\n const cancel = r.readBits(1) === 1;\n r.readBits(7);\n if (cancel) return void 0;\n const outOfNetwork = r.readBits(1) === 1;\n const programSpliceFlag = r.readBits(1) === 1;\n const durationFlag = r.readBits(1) === 1;\n const spliceImmediateFlag = r.readBits(1) === 1;\n r.readBits(4);\n if (programSpliceFlag && !spliceImmediateFlag) {\n const timeSpecifiedFlag = r.readBits(1) === 1;\n if (timeSpecifiedFlag) {\n r.readBits(6);\n r.readBits(33);\n } else {\n r.readBits(7);\n }\n } else if (!programSpliceFlag) {\n const componentCount = r.readBits(8);\n for (let i = 0; i < componentCount; i++) {\n r.readBits(8);\n if (!spliceImmediateFlag) {\n const timeSpecifiedFlag = r.readBits(1) === 1;\n if (timeSpecifiedFlag) {\n r.readBits(6);\n r.readBits(33);\n } else {\n r.readBits(7);\n }\n }\n }\n }\n let durationSeconds = void 0;\n if (durationFlag) {\n r.readBits(6);\n r.readBits(1);\n const high = r.readBits(1);\n const low = r.readBits(32);\n const durationTicks = high * 4294967296 + low;\n durationSeconds = durationTicks / 9e4;\n }\n r.readBits(16);\n r.readBits(8);\n r.readBits(8);\n if (outOfNetwork) {\n const marker = {\n type: \"start\",\n ...durationSeconds !== void 0 ? { durationSeconds } : {},\n raw: { splice_command_type: 5 }\n };\n return marker;\n }\n return void 0;\n }\n initializeTracking() {\n sendInitialTracking(this.config.licenseKey).then(() => {\n this.heartbeatInterval = window.setInterval(() => {\n this.sendHeartbeatIfNeeded();\n }, 5e3);\n }).catch((error) => {\n if (this.config.debugAdTiming) {\n console.warn(\n \"[StormcloudVideoPlayer] Failed to send initial tracking:\",\n error\n );\n }\n this.heartbeatInterval = window.setInterval(() => {\n this.sendHeartbeatIfNeeded();\n }, 5e3);\n });\n }\n sendHeartbeatIfNeeded() {\n const now = Date.now();\n if (!this.lastHeartbeatTime || now - this.lastHeartbeatTime > 3e4) {\n this.lastHeartbeatTime = now;\n sendHeartbeat(this.config.licenseKey).catch((error) => {\n if (this.config.debugAdTiming) {\n console.warn(\n \"[StormcloudVideoPlayer] Failed to send heartbeat:\",\n error\n );\n }\n });\n }\n }\n getCurrentAdIndex() {\n return this.currentAdIndex;\n }\n getTotalAdsInBreak() {\n return this.totalAdsInBreak;\n }\n isAdPlaying() {\n return this.inAdBreak && this.adLayer.isAdPlaying();\n }\n isShowingAds() {\n return this.showAds;\n }\n getStreamType() {\n const url = this.config.src.toLowerCase();\n if (url.includes(\".m3u8\") || url.includes(\"/hls/\") || url.includes(\"application/vnd.apple.mpegurl\")) {\n return \"hls\";\n }\n return \"other\";\n }\n shouldShowNativeControls() {\n const streamType = this.getStreamType();\n if (streamType === \"other\") {\n return !(this.config.showCustomControls ?? false);\n }\n return !!(this.config.allowNativeHls && !(this.config.showCustomControls ?? false));\n }\n shouldContinueLiveStreamDuringAds() {\n if (this.config.allowNativeHls) {\n return false;\n }\n if (!this.isLiveStream) {\n return false;\n }\n return true;\n }\n startAdPrefetch(marker, fragmentSn) {\n if (this.pendingAdBreak || this.inAdBreak) {\n return;\n }\n this.pendingAdBreak = {\n marker,\n ...fragmentSn !== void 0 ? { detectedAtFragmentSn: fragmentSn } : {},\n isFetching: false,\n fetchStartTime: Date.now()\n };\n void this.adRequest().then(() => {\n }).catch(() => {\n if (this.config.debugAdTiming) {\n console.log(\"[PREFETCH] Prebid auction prefetch failed, will request at playback time\");\n }\n });\n if (this.config.debugAdTiming) {\n console.log(\"[PREFETCH] Ad break marker registered, auction prefetch started\");\n }\n }\n clearPendingAdBreak() {\n if (this.prefetchTimerId != null) {\n clearTimeout(this.prefetchTimerId);\n this.prefetchTimerId = void 0;\n }\n this.pendingAdBreak = null;\n }\n startContinuousFetchLoop() {\n if (this.continuousFetchLoopPromise != null) return;\n this.continuousFetchLoopPromise = this.runContinuousFetchLoop();\n }\n async runContinuousFetchLoop() {\n const backoffMs = () => {\n const mult = Math.pow(2, this.consecutiveFailures);\n return Math.min(this.backoffBaseMs * mult, this.maxBackoffMs);\n };\n while (this.inAdBreak && this.continuousFetchingActive) {\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) break;\n if (this.totalAdRequestsInBreak >= this.maxTotalAdRequestsPerBreak) break;\n const delay = this.lastAdRequestTime ? this.minAdRequestIntervalMs + (this.consecutiveFailures > 0 ? backoffMs() : 0) : 0;\n const elapsed = Date.now() - this.lastAdRequestTime;\n if (elapsed < delay && this.lastAdRequestTime > 0) {\n await new Promise((r) => setTimeout(r, delay - elapsed));\n }\n if (!this.inAdBreak || !this.continuousFetchingActive) break;\n try {\n const bids = await this.adRequest();\n this.lastAdRequestTime = Date.now();\n if (!this.inAdBreak) break;\n if (bids.length > 0) {\n this.consecutiveFailures = 0;\n if (this.adLayer.isAdPlaying()) {\n this.pendingNextAdBids = bids;\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] Next ad response stored (ad currently playing)\");\n }\n } else {\n this.currentAdIndex++;\n if (this.config.licenseKey) {\n sendAdLoadedTracking(this.config.licenseKey, {\n source: this.getAdSource(),\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n });\n }\n await this.adLayer.playAd(bids);\n if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {\n this.scheduleAdStopCountdown(this.getRemainingAdMs());\n }\n this.adLayer.setAdVolume(\n this.adLayer.getOriginalMutedState() ? 1 : this.adLayer.getOriginalVolume()\n );\n }\n } else {\n this.consecutiveFailures++;\n }\n } catch (err) {\n this.consecutiveFailures++;\n if (this.config.debugAdTiming) {\n console.warn(\"[CONTINUOUS-FETCH] adRequest failed:\", err);\n }\n }\n await new Promise((r) => setTimeout(r, backoffMs()));\n }\n this.continuousFetchLoopPromise = null;\n }\n async handleAdStart(_marker) {\n const adBreakDurationMs = _marker.durationSeconds != null ? _marker.durationSeconds * 1e3 : void 0;\n if (this.config.debugAdTiming) {\n const mode = this.isLiveStream ? \"LIVE\" : \"VOD\";\n console.log(\n `[CONTINUOUS-FETCH] \\u{1F4FA} ${mode} MODE: Target duration=${adBreakDurationMs}ms`\n );\n }\n this.consecutiveFailures = 0;\n this.continuousFetchingActive = true;\n this.continuousFetchLoopPromise = null;\n this.pendingNextAdBids = null;\n this.isShowingPlaceholder = false;\n this.totalAdRequestsInBreak = 0;\n const state = this.savedMutedStateBeforeScte ?? {\n muted: this.video.muted,\n volume: this.video.volume\n };\n this.adLayer.updateOriginalMutedState(state.muted, state.volume);\n this.savedMutedStateBeforeScte = null;\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Muted video in handleAdStart\");\n }\n }\n this.inAdBreak = true;\n this.currentAdBreakStartWallClockMs = Date.now();\n this.currentAdIndex = 0;\n this.totalAdsInBreak = 1;\n this.adPodQueue = [];\n this.showAds = true;\n this.showPlaceholderLayer();\n this.adLayer.showPlaceholder();\n if (this.expectedAdBreakDurationMs == null && adBreakDurationMs != null) {\n this.expectedAdBreakDurationMs = adBreakDurationMs;\n }\n this.clearPendingAdBreak();\n try {\n this.lastAdRequestTime = Date.now();\n const bids = await this.adRequest();\n if (!this.inAdBreak) return;\n if (bids.length > 0) {\n this.consecutiveFailures = 0;\n if (this.config.licenseKey) {\n sendAdLoadedTracking(this.config.licenseKey, {\n source: this.getAdSource(),\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n });\n }\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u2705 First ad request successful, starting playback\");\n }\n this.currentAdIndex++;\n await this.adLayer.playAd(bids);\n if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {\n this.scheduleAdStopCountdown(this.getRemainingAdMs());\n }\n const adVolume = state.muted ? 1 : state.volume;\n this.adLayer.setAdVolume(adVolume);\n } else {\n this.consecutiveFailures++;\n await this.showPlaceholderAndWaitForAds();\n }\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\"[CONTINUOUS-FETCH] \\u26A0\\uFE0F First ad request failed:\", error);\n }\n this.consecutiveFailures++;\n await this.showPlaceholderAndWaitForAds();\n }\n this.startContinuousFetchLoop();\n }\n stopContinuousFetching() {\n this.continuousFetchingActive = false;\n this.hidePlaceholderLayer();\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u{1F6D1} Stopping continuous ad fetching\");\n }\n }\n async tryNextAvailableAdWithRateLimit() {\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] \\u{1F6D1} Too many consecutive failures (${this.consecutiveFailures}), ending ad break gracefully`);\n }\n this.handleAdPodComplete();\n return;\n }\n const backoffMultiplier = Math.pow(2, this.consecutiveFailures);\n const backoffDelay = Math.min(this.backoffBaseMs * backoffMultiplier, this.maxBackoffMs);\n const effectiveMinInterval = this.minAdRequestIntervalMs + (this.consecutiveFailures > 0 ? backoffDelay : 0);\n const timeSinceLastRequest = Date.now() - this.lastAdRequestTime;\n if (timeSinceLastRequest < effectiveMinInterval) {\n const waitTime = effectiveMinInterval - timeSinceLastRequest;\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] \\u23F3 Rate limiting: waiting ${waitTime}ms before next request (backoff: ${this.consecutiveFailures} failures)`);\n }\n await new Promise((resolve) => setTimeout(resolve, waitTime));\n }\n return this.tryNextAvailableAd(0);\n }\n async tryNextAvailableAd(_retryCount = 0) {\n if (this.totalAdRequestsInBreak >= this.maxTotalAdRequestsPerBreak) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] \\u{1F6D1} Max ad requests per break (${this.maxTotalAdRequestsPerBreak}) reached`);\n }\n this.handleAdPodComplete();\n return;\n }\n const remaining = this.getRemainingAdMs();\n if (remaining <= 500 && this.expectedAdBreakDurationMs != null) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u23F9\\uFE0F No time remaining, ending ad break\");\n }\n this.handleAdPodComplete();\n return;\n }\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] \\u{1F6D1} Too many consecutive failures (${this.consecutiveFailures}), ending ad break`);\n }\n this.handleAdPodComplete();\n return;\n }\n try {\n this.lastAdRequestTime = Date.now();\n const bids = await this.adRequest();\n if (!this.inAdBreak) return;\n if (bids.length > 0) {\n this.consecutiveFailures = 0;\n this.currentAdIndex++;\n this.totalAdRequestsInBreak++;\n if (this.adLayer.isAdPlaying()) {\n this.pendingNextAdBids = bids;\n } else {\n if (this.config.licenseKey) {\n sendAdLoadedTracking(this.config.licenseKey, {\n source: this.getAdSource(),\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n });\n }\n await this.adLayer.playAd(bids);\n if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {\n this.scheduleAdStopCountdown(this.getRemainingAdMs());\n }\n this.adLayer.setAdVolume(\n this.adLayer.getOriginalMutedState() ? 1 : this.adLayer.getOriginalVolume()\n );\n }\n } else {\n this.consecutiveFailures++;\n await this.showPlaceholderAndWaitForAds();\n }\n } catch (error) {\n this.consecutiveFailures++;\n if (this.config.debugAdTiming) {\n console.warn(\"[CONTINUOUS-FETCH] tryNextAvailableAd request failed:\", error);\n }\n await this.showPlaceholderAndWaitForAds();\n }\n }\n async showPlaceholderAndWaitForAds() {\n const remaining = this.getRemainingAdMs();\n const waitTime = Math.min(this.maxPlaceholderDurationMs, remaining);\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u{1F6D1} Skipping placeholder - too many consecutive failures\");\n }\n this.handleAdPodComplete();\n return;\n }\n if (waitTime < 1e3) {\n this.handleAdPodComplete();\n return;\n }\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] \\u2B1B Showing placeholder for ${waitTime}ms while waiting for ad response`);\n }\n this.isShowingPlaceholder = true;\n this.adLayer.showPlaceholder();\n const checkInterval = 300;\n const maxChecks = Math.floor(waitTime / checkInterval);\n for (let i = 0; i < maxChecks; i++) {\n await new Promise((resolve) => setTimeout(resolve, checkInterval));\n if (!this.inAdBreak) return;\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u{1F6D1} Too many failures during placeholder wait\");\n }\n break;\n }\n if (this.pendingNextAdBids != null && this.pendingNextAdBids.length > 0) {\n const bids = this.pendingNextAdBids;\n this.pendingNextAdBids = null;\n this.isShowingPlaceholder = false;\n this.adLayer.hidePlaceholder();\n this.currentAdIndex++;\n try {\n await this.adLayer.playAd(bids);\n this.consecutiveFailures = 0;\n } catch {\n this.consecutiveFailures++;\n await this.tryNextAvailableAdWithRateLimit();\n }\n return;\n }\n if (this.adLayer.isAdPlaying()) {\n this.isShowingPlaceholder = false;\n this.adLayer.hidePlaceholder();\n return;\n }\n }\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u23F0 Placeholder timeout, ending ad break\");\n }\n this.isShowingPlaceholder = false;\n this.adLayer.hidePlaceholder();\n this.handleAdPodComplete();\n }\n onTimeUpdate(_currentTimeSec) {\n if (this.adLayer.isAdPlaying()) return;\n }\n scheduleAdStopCountdown(remainingMs) {\n this.clearAdStopTimer();\n const ms = Math.max(0, Math.floor(remainingMs));\n if (ms === 0) {\n this.ensureAdStoppedByTimer();\n return;\n }\n this.adStopTimerId = window.setTimeout(() => {\n this.ensureAdStoppedByTimer();\n }, ms);\n }\n clearAdStopTimer() {\n if (this.adStopTimerId != null) {\n clearTimeout(this.adStopTimerId);\n this.adStopTimerId = void 0;\n }\n }\n ensureAdStoppedByTimer() {\n if (!this.inAdBreak) return;\n this.adStopTimerId = void 0;\n const adPlaying = this.adLayer.isAdPlaying();\n const pendingAds = this.adPodQueue.length > 0;\n const checkIntervalMs = Math.max(\n 250,\n Math.floor(this.config.adBreakCheckIntervalMs ?? 1e3)\n );\n const maxExtensionMsConfig = this.config.maxAdBreakExtensionMs;\n const maxExtensionMs = typeof maxExtensionMsConfig === \"number\" && maxExtensionMsConfig > 0 ? maxExtensionMsConfig : 6e4;\n let elapsedSinceStartMs = 0;\n if (this.currentAdBreakStartWallClockMs != null) {\n elapsedSinceStartMs = Date.now() - this.currentAdBreakStartWallClockMs;\n }\n const expectedDurationMs = this.expectedAdBreakDurationMs ?? 0;\n const overrunMs = Math.max(0, elapsedSinceStartMs - expectedDurationMs);\n const shouldExtendAdBreak = (adPlaying || pendingAds || this.showAds) && overrunMs < maxExtensionMs;\n if (shouldExtendAdBreak) {\n this.scheduleAdStopCountdown(checkIntervalMs);\n return;\n }\n if (adPlaying) {\n this.adLayer.stop().catch(() => {\n });\n }\n this.handleAdPodComplete();\n }\n scheduleAdStartIn(delayMs) {\n this.clearAdStartTimer();\n const ms = Math.max(0, Math.floor(delayMs));\n if (ms === 0) {\n this.handleAdStart({ type: \"start\" }).catch(() => {\n });\n return;\n }\n this.adStartTimerId = window.setTimeout(() => {\n this.handleAdStart({ type: \"start\" }).catch(() => {\n });\n }, ms);\n }\n clearAdStartTimer() {\n if (this.adStartTimerId != null) {\n clearTimeout(this.adStartTimerId);\n this.adStartTimerId = void 0;\n }\n }\n updatePtsDrift(ptsSecondsSample) {\n const sampleMs = (this.video.currentTime - ptsSecondsSample) * 1e3;\n if (!Number.isFinite(sampleMs) || Math.abs(sampleMs) > 6e4) return;\n const alpha = 0.1;\n this.ptsDriftEmaMs = this.ptsDriftEmaMs * (1 - alpha) + sampleMs * alpha;\n }\n handleAdPodComplete() {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] \\u{1F3C1} Ad pod complete - cleaning up\");\n }\n this.clearAdRequestWatchdog();\n this.clearAdFailsafeTimer();\n this.activeAdRequestToken = null;\n this.stopContinuousFetching();\n this.clearPendingAdBreak();\n this.pendingNextAdBids = null;\n if (this.isShowingPlaceholder) {\n this.adLayer.hidePlaceholder();\n this.isShowingPlaceholder = false;\n }\n this.inAdBreak = false;\n this.expectedAdBreakDurationMs = void 0;\n this.currentAdBreakStartWallClockMs = void 0;\n this.clearAdStartTimer();\n this.clearAdStopTimer();\n this.adPodQueue = [];\n this.showAds = false;\n this.currentAdIndex = 0;\n this.totalAdsInBreak = 0;\n this.totalAdRequestsInBreak = 0;\n this.consecutiveFailures = 0;\n this.adLayer.stop().catch(() => {\n });\n const restoredMuted = this.adLayer.getOriginalMutedState();\n const restoredVolume = this.adLayer.getOriginalVolume();\n if (this.video.muted !== restoredMuted) {\n this.video.muted = restoredMuted;\n }\n if (Math.abs(this.video.volume - restoredVolume) > 0.01) {\n this.video.volume = restoredVolume;\n }\n const isTizen = detectBrowser().tizenVersion !== void 0;\n if (isTizen && this.hls) {\n this.hls.attachMedia(this.video);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Tizen: re-attached HLS to video element after ad break to restore audio\");\n }\n }\n if (this.shouldContinueLiveStreamDuringAds()) {\n if (this.config.debugAdTiming) {\n if (this.video.paused) {\n console.log(\"[StormcloudVideoPlayer] Content video paused in live mode after ads, resuming playback\");\n } else {\n console.log(\"[StormcloudVideoPlayer] Content video already playing in live mode after ads\");\n }\n }\n this.video.play()?.catch(() => {\n });\n } else if (this.video.paused) {\n this.video.play()?.catch(() => {\n });\n }\n if (!restoredMuted) {\n requestAnimationFrame(() => {\n this.video.muted = false;\n this.video.volume = restoredVolume;\n });\n setTimeout(() => {\n this.video.muted = false;\n this.video.volume = restoredVolume;\n }, 0);\n setTimeout(() => {\n this.video.muted = false;\n this.video.volume = restoredVolume;\n }, 50);\n }\n }\n handleAdFailure() {\n this.consecutiveFailures++;\n if (this.config.debugAdTiming) {\n console.log(\n `[CONTINUOUS-FETCH] Ad failure: consecutiveFailures=${this.consecutiveFailures}`\n );\n }\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] \\u{1F6D1} Max consecutive failures reached (${this.consecutiveFailures}), ending ad break gracefully`);\n }\n this.handleAdPodComplete();\n }\n }\n startAdRequestWatchdog(token) {\n this.clearAdRequestWatchdog();\n const timeoutMs = this.config.adFailsafeTimeoutMs ?? 1e4;\n this.adRequestWatchdogToken = token;\n this.adRequestWatchdogId = window.setTimeout(() => {\n if (this.adRequestWatchdogToken !== token) {\n return;\n }\n this.adRequestWatchdogId = void 0;\n this.adRequestWatchdogToken = null;\n if (this.activeAdRequestToken === token) {\n this.activeAdRequestToken = null;\n }\n this.logAdState(\"ad_request_timeout\", { token, timeoutMs });\n this.handleAdFailure();\n }, timeoutMs);\n this.logAdState(\"ad_request_watchdog_started\", { token, timeoutMs });\n }\n clearAdRequestWatchdog() {\n if (this.adRequestWatchdogId != null) {\n clearTimeout(this.adRequestWatchdogId);\n this.adRequestWatchdogId = void 0;\n }\n if (this.adRequestWatchdogToken != null) {\n this.logAdState(\"ad_request_watchdog_cleared\", {\n token: this.adRequestWatchdogToken\n });\n this.adRequestWatchdogToken = null;\n }\n }\n startAdFailsafeTimer(token) {\n this.clearAdFailsafeTimer();\n const failsafeMs = this.config.adFailsafeTimeoutMs ?? 1e4;\n this.adFailsafeToken = token;\n this.adFailsafeTimerId = window.setTimeout(() => {\n if (this.adFailsafeToken !== token) {\n return;\n }\n this.adFailsafeTimerId = void 0;\n this.adFailsafeToken = null;\n if (this.activeAdRequestToken === token) {\n this.activeAdRequestToken = null;\n }\n this.logAdState(\"ad_failsafe_triggered\", {\n token,\n failsafeMs,\n videoPaused: this.video.paused,\n imaAdPlaying: this.adLayer.isAdPlaying()\n });\n this.handleAdFailure();\n }, failsafeMs);\n this.logAdState(\"ad_failsafe_started\", { token, failsafeMs });\n }\n clearAdFailsafeTimer() {\n if (this.adFailsafeTimerId != null) {\n clearTimeout(this.adFailsafeTimerId);\n this.logAdState(\"ad_failsafe_cleared\", { token: this.adFailsafeToken });\n this.adFailsafeTimerId = void 0;\n }\n this.adFailsafeToken = null;\n }\n logAdState(event, extra = {}) {\n if (!this.config.debugAdTiming) {\n return;\n }\n console.log(\"[StormcloudVideoPlayer][AdState]\", {\n event,\n timestamp: (/* @__PURE__ */ new Date()).toISOString(),\n showAds: this.showAds,\n adPlaying: this.adLayer.isAdPlaying(),\n inAdBreak: this.inAdBreak,\n activeAdRequestToken: this.activeAdRequestToken,\n ...extra\n });\n }\n getRemainingAdMs() {\n if (this.currentAdBreakStartWallClockMs == null) return 0;\n if (this.expectedAdBreakDurationMs == null) return Number.MAX_SAFE_INTEGER;\n const elapsed = Date.now() - this.currentAdBreakStartWallClockMs;\n return Math.max(0, this.expectedAdBreakDurationMs - elapsed);\n }\n toggleMute() {\n if (this.adLayer.isAdPlaying()) {\n const currentPerceptualState = this.isMuted();\n const newMutedState = !currentPerceptualState;\n this.adLayer.updateOriginalMutedState(newMutedState, this.video.volume);\n this.adLayer.setAdVolume(newMutedState ? 0 : this.adLayer.getOriginalVolume());\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Mute toggle during ad - immediately applied:\",\n newMutedState\n );\n }\n } else {\n this.video.muted = !this.video.muted;\n this.adLayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Muted:\", this.video.muted);\n }\n }\n }\n toggleFullscreen() {\n return new Promise((resolve, reject) => {\n if (!document.fullscreenElement) {\n const container = this.video.parentElement;\n if (!container) {\n reject(new Error(\"No parent container found for fullscreen\"));\n return;\n }\n container.requestFullscreen().then(() => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Entered fullscreen\");\n }\n resolve();\n }).catch((err) => {\n if (this.config.debugAdTiming) {\n console.error(\"[StormcloudVideoPlayer] Fullscreen error:\", err);\n }\n reject(err);\n });\n } else {\n document.exitFullscreen().then(() => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Exited fullscreen\");\n }\n resolve();\n }).catch((err) => {\n if (this.config.debugAdTiming) {\n console.error(\n \"[StormcloudVideoPlayer] Exit fullscreen error:\",\n err\n );\n }\n reject(err);\n });\n }\n });\n }\n isMuted() {\n if (this.adLayer.isAdPlaying()) {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] isMuted() override during ad playback -> false\"\n );\n }\n return false;\n }\n return this.video.muted;\n }\n setMuted(muted) {\n const adPlaying = this.adLayer.isAdPlaying();\n if (adPlaying && muted === this.video.muted) {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] setMuted reflective update during ad ignored\",\n { muted }\n );\n }\n return;\n }\n this.video.muted = muted;\n if (adPlaying) {\n this.adLayer.updateOriginalMutedState(muted, this.video.volume);\n this.adLayer.setAdVolume(muted ? 0 : this.adLayer.getOriginalVolume());\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] setMuted applied during ad\", {\n muted\n });\n }\n return;\n }\n this.adLayer.updateOriginalMutedState(muted, this.video.volume);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] setMuted called:\", muted);\n }\n }\n setVolume(volume) {\n const clampedVolume = Math.max(0, Math.min(1, volume));\n const adPlaying = this.adLayer.isAdPlaying();\n if (adPlaying) {\n this.adLayer.setAdVolume(clampedVolume);\n this.adLayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] setVolume applied during ad\", {\n volume: clampedVolume\n });\n }\n } else {\n this.video.volume = clampedVolume;\n this.video.muted = clampedVolume === 0;\n this.adLayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] setVolume called:\", clampedVolume);\n }\n }\n }\n getVolume() {\n const adPlaying = this.adLayer.isAdPlaying();\n if (adPlaying) {\n return this.adLayer.getAdVolume();\n }\n return this.video.volume;\n }\n isFullscreen() {\n return !!document.fullscreenElement;\n }\n isLive() {\n return this.isLiveStream;\n }\n get videoElement() {\n return this.video;\n }\n resize() {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Resizing player\");\n }\n if (this.adLayer && this.adLayer.isAdPlaying()) {\n const width = this.video.clientWidth || 640;\n const height = this.video.clientHeight || 480;\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Resizing ads manager to ${width}x${height}`\n );\n }\n this.adLayer.resize(width, height);\n }\n }\n destroy() {\n this.stopContinuousFetching();\n this.clearAdStartTimer();\n this.clearAdStopTimer();\n this.clearAdFailsafeTimer();\n this.clearAdRequestWatchdog();\n this.clearPendingAdBreak();\n if (this.placeholderContainer) {\n if (this.placeholderContainer.parentElement) {\n this.placeholderContainer.parentElement.removeChild(this.placeholderContainer);\n }\n this.placeholderContainer = void 0;\n }\n if (this.timeUpdateHandler) {\n this.video.removeEventListener(\"timeupdate\", this.timeUpdateHandler);\n delete this.timeUpdateHandler;\n }\n if (this.emptiedHandler) {\n this.video.removeEventListener(\"emptied\", this.emptiedHandler);\n delete this.emptiedHandler;\n }\n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval);\n this.heartbeatInterval = void 0;\n }\n this.hls?.destroy();\n this.adLayer?.destroy();\n this.consecutiveFailures = 0;\n }\n};\n\n// src/ui/StormcloudVideoPlayer.tsx\nvar import_fa = require(\"react-icons/fa\");\nvar import_jsx_runtime = require(\"react/jsx-runtime\");\nvar CRITICAL_PROPS = [\n \"src\",\n \"allowNativeHls\",\n \"licenseKey\",\n \"lowLatencyMode\",\n \"driftToleranceMs\"\n];\nvar StormcloudVideoPlayerComponent = import_react.default.memo(\n (props) => {\n const {\n src,\n autoplay,\n muted,\n lowLatencyMode,\n allowNativeHls,\n driftToleranceMs,\n immediateManifestAds,\n debugAdTiming,\n showCustomControls,\n hideLoadingIndicator,\n onVolumeToggle,\n onFullscreenToggle,\n onControlClick,\n onReady,\n wrapperClassName,\n wrapperStyle,\n className,\n style,\n controls,\n playsInline,\n preload,\n poster,\n children,\n licenseKey,\n minSegmentsBeforePlay,\n ...restVideoAttrs\n } = props;\n const videoRef = (0, import_react.useRef)(null);\n const playerRef = (0, import_react.useRef)(null);\n const bufferingTimeoutRef = (0, import_react.useRef)(null);\n const [adStatus, setAdStatus] = import_react.default.useState({ showAds: false, currentIndex: 0, totalAds: 0 });\n const [shouldShowNativeControls, setShouldShowNativeControls] = import_react.default.useState(true);\n const [isMuted, setIsMuted] = import_react.default.useState(false);\n const [isFullscreen, setIsFullscreen] = import_react.default.useState(false);\n const [isPlaying, setIsPlaying] = import_react.default.useState(false);\n const [currentTime, setCurrentTime] = import_react.default.useState(0);\n const [duration, setDuration] = import_react.default.useState(0);\n const [volume, setVolume] = import_react.default.useState(1);\n const [playbackRate, setPlaybackRate] = import_react.default.useState(1);\n const [showVolumeSlider, setShowVolumeSlider] = import_react.default.useState(false);\n const [showSpeedMenu, setShowSpeedMenu] = import_react.default.useState(false);\n const [isLoading, setIsLoading] = import_react.default.useState(true);\n const [isBuffering, setIsBuffering] = import_react.default.useState(false);\n const [showCenterPlay, setShowCenterPlay] = import_react.default.useState(false);\n const [showLicenseWarning, setShowLicenseWarning] = import_react.default.useState(false);\n const [viewportWidth, setViewportWidth] = import_react.default.useState(\n typeof window !== \"undefined\" ? window.innerWidth : 1920\n );\n const [isPortrait, setIsPortrait] = import_react.default.useState(\n typeof window !== \"undefined\" ? window.innerHeight > window.innerWidth : false\n );\n const getResponsiveScale = () => {\n if (viewportWidth < 480) return 0.7;\n if (viewportWidth < 768) return 0.8;\n if (viewportWidth < 1024) return 0.9;\n return 1;\n };\n const responsiveScale = getResponsiveScale();\n const formatTime = (seconds) => {\n if (!isFinite(seconds)) return \"0:00:00\";\n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor(seconds % 3600 / 60);\n const remainingSeconds = Math.floor(seconds % 60);\n return `${hours}:${minutes.toString().padStart(2, \"0\")}:${remainingSeconds.toString().padStart(2, \"0\")}`;\n };\n const handlePlayPause = () => {\n if (videoRef.current) {\n if (videoRef.current.paused) {\n const hasValidSource = videoRef.current.src || videoRef.current.currentSrc && videoRef.current.currentSrc !== \"\" || videoRef.current.readyState >= 1;\n if (hasValidSource) {\n videoRef.current.play()?.catch((error) => {\n console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n });\n setShowCenterPlay(false);\n } else {\n console.warn(\n \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n );\n }\n } else {\n videoRef.current.pause();\n setShowCenterPlay(true);\n }\n }\n };\n const handleCenterPlayClick = () => {\n if (videoRef.current && videoRef.current.paused) {\n const hasValidSource = videoRef.current.src || videoRef.current.currentSrc && videoRef.current.currentSrc !== \"\" || videoRef.current.readyState >= 1;\n if (hasValidSource) {\n videoRef.current.play()?.catch((error) => {\n console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n });\n setShowCenterPlay(false);\n } else {\n console.warn(\n \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n );\n }\n }\n };\n const handleTimelineSeek = (e) => {\n if (videoRef.current && duration > 0 && isFinite(duration)) {\n const rect = e.currentTarget.getBoundingClientRect();\n const clickX = e.clientX - rect.left;\n const progress = Math.max(0, Math.min(1, clickX / rect.width));\n const newTime = progress * duration;\n if (isFinite(newTime) && newTime >= 0 && newTime <= duration) {\n videoRef.current.currentTime = newTime;\n }\n }\n };\n const handleVolumeChange = (newVolume) => {\n if (playerRef.current && isFinite(newVolume)) {\n const clampedVolume = Math.max(0, Math.min(1, newVolume));\n playerRef.current.setVolume(clampedVolume);\n }\n };\n const handlePlaybackRateChange = (rate) => {\n if (videoRef.current && isFinite(rate) && rate > 0) {\n videoRef.current.playbackRate = rate;\n }\n setShowSpeedMenu(false);\n };\n const isHlsStream = src?.toLowerCase().includes(\".m3u8\") || src?.toLowerCase().includes(\"/hls/\");\n const shouldShowEnhancedControls = showCustomControls && (isHlsStream ? allowNativeHls : true);\n const criticalPropsKey = (0, import_react.useMemo)(() => {\n return CRITICAL_PROPS.map((prop) => `${prop}:${props[prop]}`).join(\"|\");\n }, [\n src,\n allowNativeHls,\n licenseKey,\n lowLatencyMode,\n driftToleranceMs\n ]);\n (0, import_react.useEffect)(() => {\n if (typeof window === \"undefined\") return;\n const el = videoRef.current;\n if (!el || !src) return;\n if (!licenseKey) {\n setShowLicenseWarning(true);\n setIsLoading(false);\n console.warn(\n \"StormcloudVideoPlayer: License key is required but not provided. Please set the licenseKey prop to use the player.\"\n );\n return;\n }\n setShowLicenseWarning(false);\n if (debugAdTiming) {\n console.log(\"[StormcloudUI] Initializing player, isLoading=true\");\n }\n if (playerRef.current) {\n try {\n playerRef.current.destroy();\n } catch {\n }\n playerRef.current = null;\n }\n const cfg = {\n src,\n videoElement: el\n };\n if (autoplay !== void 0) cfg.autoplay = autoplay;\n if (muted !== void 0) cfg.muted = muted;\n if (lowLatencyMode !== void 0) cfg.lowLatencyMode = lowLatencyMode;\n if (allowNativeHls !== void 0) cfg.allowNativeHls = allowNativeHls;\n if (driftToleranceMs !== void 0)\n cfg.driftToleranceMs = driftToleranceMs;\n if (immediateManifestAds !== void 0)\n cfg.immediateManifestAds = immediateManifestAds;\n if (debugAdTiming !== void 0) cfg.debugAdTiming = debugAdTiming;\n if (showCustomControls !== void 0)\n cfg.showCustomControls = showCustomControls;\n if (onVolumeToggle !== void 0) cfg.onVolumeToggle = onVolumeToggle;\n if (onFullscreenToggle !== void 0)\n cfg.onFullscreenToggle = onFullscreenToggle;\n if (onControlClick !== void 0) cfg.onControlClick = onControlClick;\n if (licenseKey !== void 0) cfg.licenseKey = licenseKey;\n if (minSegmentsBeforePlay !== void 0)\n cfg.minSegmentsBeforePlay = minSegmentsBeforePlay;\n const player = new StormcloudVideoPlayer(cfg);\n playerRef.current = player;\n player.load().then(() => {\n const showNative = player.shouldShowNativeControls();\n setShouldShowNativeControls(showNative);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Player loaded successfully, waiting for video ready\"\n );\n }\n onReady?.(player);\n }).catch((error) => {\n console.error(\n \"StormcloudVideoPlayer: Failed to load player:\",\n error\n );\n setIsLoading(false);\n onReady?.(player);\n });\n return () => {\n try {\n player.destroy();\n } catch {\n }\n playerRef.current = null;\n };\n }, [criticalPropsKey]);\n (0, import_react.useEffect)(() => {\n if (!playerRef.current) return;\n try {\n if (autoplay !== void 0 && playerRef.current.videoElement) {\n playerRef.current.videoElement.autoplay = autoplay;\n }\n if (muted !== void 0 && !playerRef.current.isShowingAds()) {\n playerRef.current.setMuted(muted);\n }\n } catch (error) {\n console.warn(\"Failed to update player properties:\", error);\n }\n }, [autoplay, muted]);\n (0, import_react.useEffect)(() => {\n if (!playerRef.current) return;\n const checkAdStatus = () => {\n if (playerRef.current) {\n const showAdsFromMethod = playerRef.current.isShowingAds();\n const showAdsFromAttribute = videoRef.current?.dataset?.stormcloudAdPlaying === \"true\";\n const showAds = showAdsFromMethod || showAdsFromAttribute;\n const currentIndex = playerRef.current.getCurrentAdIndex();\n const totalAds = playerRef.current.getTotalAdsInBreak();\n setAdStatus((prev) => {\n if (prev.showAds !== showAds || prev.currentIndex !== currentIndex || prev.totalAds !== totalAds) {\n if (showAds && !prev.showAds) {\n setShowCenterPlay(false);\n }\n return { showAds, currentIndex, totalAds };\n }\n return prev;\n });\n }\n };\n const interval = setInterval(checkAdStatus, 50);\n return () => clearInterval(interval);\n }, []);\n (0, import_react.useEffect)(() => {\n if (typeof window === \"undefined\" || !playerRef.current) return;\n const handleResize = () => {\n if (playerRef.current && videoRef.current) {\n if (typeof playerRef.current.resize === \"function\") {\n playerRef.current.resize();\n }\n }\n setViewportWidth(window.innerWidth);\n setIsPortrait(window.innerHeight > window.innerWidth);\n };\n window.addEventListener(\"resize\", handleResize);\n return () => window.removeEventListener(\"resize\", handleResize);\n }, []);\n (0, import_react.useEffect)(() => {\n if (!playerRef.current || !videoRef.current) return;\n const updateStates = () => {\n if (playerRef.current && videoRef.current) {\n setIsMuted(playerRef.current.isMuted());\n setIsPlaying(!videoRef.current.paused);\n const currentTimeValue = videoRef.current.currentTime;\n setCurrentTime(isFinite(currentTimeValue) ? currentTimeValue : 0);\n const durationValue = videoRef.current.duration;\n setDuration(isFinite(durationValue) ? durationValue : 0);\n const volumeValue = playerRef.current.getVolume();\n setVolume(\n isFinite(volumeValue) ? Math.max(0, Math.min(1, volumeValue)) : 1\n );\n const rateValue = videoRef.current.playbackRate;\n setPlaybackRate(\n isFinite(rateValue) && rateValue > 0 ? rateValue : 1\n );\n }\n setIsFullscreen(\n document.fullscreenElement === videoRef.current?.parentElement\n );\n };\n const interval = setInterval(updateStates, 200);\n const handleFullscreenChange = () => {\n setIsFullscreen(\n document.fullscreenElement === videoRef.current?.parentElement\n );\n };\n document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n return () => {\n clearInterval(interval);\n document.removeEventListener(\n \"fullscreenchange\",\n handleFullscreenChange\n );\n };\n }, []);\n (0, import_react.useEffect)(() => {\n if (!videoRef.current) return;\n const handleLoadedMetadata = () => {\n if (videoRef.current) {\n const video2 = videoRef.current;\n void video2.offsetHeight;\n }\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadedmetadata, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n const handleLoadedData = () => {\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadeddata, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n const handleLoadStart = () => {\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadstart, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n const handleCanPlay = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: canplay, readyState:\",\n videoRef.current?.readyState,\n \"- clearing loading state, isLoading=false\"\n );\n }\n };\n const handleCanPlayThrough = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: canplaythrough, readyState:\",\n videoRef.current?.readyState,\n \"- clearing loading state, isLoading=false\"\n );\n }\n };\n const handleWaiting = () => {\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n }\n bufferingTimeoutRef.current = window.setTimeout(() => {\n setIsBuffering(true);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video buffering detected (after 300ms delay), readyState:\",\n videoRef.current?.readyState,\n \"- showing spinner, isBuffering=true\"\n );\n }\n }, 300);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: waiting, readyState:\",\n videoRef.current?.readyState,\n \"- buffering delay started (300ms)\"\n );\n }\n };\n const handlePlaying = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n setShowCenterPlay(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: playing, readyState:\",\n videoRef.current?.readyState,\n \"- playback started, isLoading=false, isBuffering=false\"\n );\n }\n };\n const handlePause = () => {\n const isAdActive = playerRef.current?.isShowingAds() || videoRef.current?.dataset?.stormcloudAdPlaying === \"true\";\n if (playerRef.current && !isAdActive) {\n setShowCenterPlay(true);\n } else {\n setShowCenterPlay(false);\n }\n };\n const handleEnded = () => {\n setShowCenterPlay(true);\n };\n const video = videoRef.current;\n video.addEventListener(\"loadstart\", handleLoadStart);\n video.addEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.addEventListener(\"loadeddata\", handleLoadedData);\n video.addEventListener(\"canplay\", handleCanPlay);\n video.addEventListener(\"canplaythrough\", handleCanPlayThrough);\n video.addEventListener(\"waiting\", handleWaiting);\n video.addEventListener(\"playing\", handlePlaying);\n video.addEventListener(\"pause\", handlePause);\n video.addEventListener(\"ended\", handleEnded);\n if (video.paused) {\n setShowCenterPlay(true);\n }\n return () => {\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n video.removeEventListener(\"loadstart\", handleLoadStart);\n video.removeEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.removeEventListener(\"loadeddata\", handleLoadedData);\n video.removeEventListener(\"canplay\", handleCanPlay);\n video.removeEventListener(\"canplaythrough\", handleCanPlayThrough);\n video.removeEventListener(\"waiting\", handleWaiting);\n video.removeEventListener(\"playing\", handlePlaying);\n video.removeEventListener(\"pause\", handlePause);\n video.removeEventListener(\"ended\", handleEnded);\n };\n }, [debugAdTiming]);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"style\", { children: `\n @keyframes spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n }\n \n .stormcloud-loading-hidden .stormcloud-loading-indicator {\n display: none !important;\n }\n \n .stormcloud-video-wrapper:fullscreen {\n border-radius: 0 !important;\n box-shadow: none !important;\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n \n .stormcloud-video-wrapper:has(*:fullscreen) {\n border-radius: 0 !important;\n box-shadow: none !important;\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n \n *:fullscreen {\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n }\n ` }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n className: `stormcloud-video-wrapper ${wrapperClassName || \"\"}`,\n style: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n position: isFullscreen ? \"fixed\" : \"relative\",\n top: isFullscreen ? 0 : void 0,\n left: isFullscreen ? 0 : void 0,\n overflow: \"hidden\",\n width: isFullscreen ? \"100vw\" : \"100%\",\n height: isFullscreen ? \"100vh\" : \"auto\",\n minHeight: isFullscreen ? \"100vh\" : \"auto\",\n maxWidth: isFullscreen ? \"100vw\" : \"100%\",\n maxHeight: isFullscreen ? \"100vh\" : \"none\",\n zIndex: isFullscreen ? 999999 : void 0,\n backgroundColor: isFullscreen ? \"#000\" : void 0,\n borderRadius: isFullscreen ? 0 : void 0,\n boxShadow: isFullscreen ? \"none\" : void 0,\n ...wrapperStyle\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"video\",\n {\n ref: videoRef,\n className,\n style: {\n display: \"block\",\n width: \"100%\",\n height: isFullscreen ? \"100%\" : \"auto\",\n maxWidth: \"100%\",\n maxHeight: isFullscreen ? \"100%\" : \"none\",\n objectFit: isFullscreen ? \"cover\" : \"contain\",\n backgroundColor: \"#000\",\n aspectRatio: isFullscreen ? \"unset\" : void 0,\n ...style\n },\n controls: shouldShowNativeControls && controls && !showCustomControls,\n playsInline,\n preload,\n poster,\n ...restVideoAttrs,\n children\n }\n ),\n (isLoading || isBuffering) && !hideLoadingIndicator && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaSpinner,\n {\n className: \"stormcloud-loading-indicator\",\n size: 42,\n color: \"white\",\n style: {\n position: \"absolute\",\n top: \"calc(50% - 21px)\",\n left: \"calc(50% - 21px)\",\n zIndex: 20,\n animation: \"spin 1s linear infinite\",\n filter: \"drop-shadow(0 3px 6px rgba(0, 0, 0, 0.8))\"\n }\n }\n ),\n showLicenseWarning && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n zIndex: 25,\n background: \"linear-gradient(135deg, rgba(220, 38, 38, 0.95) 0%, rgba(185, 28, 28, 0.9) 100%)\",\n color: \"white\",\n padding: \"24px 32px\",\n borderRadius: \"16px\",\n backdropFilter: \"blur(20px)\",\n border: \"2px solid rgba(255, 255, 255, 0.2)\",\n boxShadow: \"0 20px 60px rgba(0, 0, 0, 0.6), inset 0 2px 0 rgba(255, 255, 255, 0.2)\",\n textAlign: \"center\",\n maxWidth: \"400px\",\n margin: \"0 16px\"\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n fontSize: \"20px\",\n fontWeight: \"bold\",\n marginBottom: \"12px\",\n color: \"#ffffff\",\n textShadow: \"0 2px 4px rgba(0, 0, 0, 0.5)\"\n },\n children: \"License Key Required\"\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n fontSize: \"14px\",\n lineHeight: \"1.5\",\n color: \"rgba(255, 255, 255, 0.9)\",\n textShadow: \"0 1px 2px rgba(0, 0, 0, 0.3)\"\n },\n children: [\n \"Please provide a valid license key to use the Stormcloud Video Player.\",\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"br\", {}),\n \"Contact your administrator for licensing information.\"\n ]\n }\n )\n ]\n }\n ),\n showCenterPlay && !isLoading && !isBuffering && !showLicenseWarning && !adStatus.showAds && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n onClick: handleCenterPlayClick,\n style: {\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n zIndex: 15,\n cursor: \"pointer\",\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.8) 100%)\",\n borderRadius: \"50%\",\n width: \"100px\",\n height: \"100px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n border: \"3px solid rgba(255, 255, 255, 0.8)\",\n boxShadow: \"0 12px 40px rgba(0, 0, 0, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\"\n },\n onMouseEnter: (e) => {\n const target = e.currentTarget;\n target.style.transform = \"translate(-50%, -50%)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.95) 0%, rgba(40, 40, 40, 0.9) 100%)\";\n target.style.boxShadow = \"0 16px 48px rgba(0, 0, 0, 0.9), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.borderColor = \"rgba(255, 255, 255, 0.9)\";\n },\n onMouseLeave: (e) => {\n const target = e.currentTarget;\n target.style.transform = \"translate(-50%, -50%)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.8) 100%)\";\n target.style.boxShadow = \"0 12px 40px rgba(0, 0, 0, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.3)\";\n target.style.borderColor = \"rgba(255, 255, 255, 0.8)\";\n },\n title: \"Play\",\n children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaPlay,\n {\n size: 36,\n color: \"white\",\n style: {\n marginLeft: \"6px\",\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\"\n }\n }\n )\n }\n ),\n shouldShowEnhancedControls && !showLicenseWarning ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: 0,\n left: 0,\n right: 0,\n background: \"linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.8) 100%)\",\n padding: \"20px 16px 16px\",\n zIndex: 10\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n width: \"100%\",\n height: \"8px\",\n background: \"linear-gradient(90deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0.1) 100%)\",\n borderRadius: \"8px\",\n marginBottom: \"16px\",\n cursor: \"pointer\",\n position: \"relative\",\n backdropFilter: \"blur(5px)\",\n border: \"1px solid rgba(255, 255, 255, 0.1)\",\n boxShadow: \"inset 0 2px 4px rgba(0, 0, 0, 0.2)\"\n },\n onClick: handleTimelineSeek,\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n height: \"100%\",\n background: \"linear-gradient(90deg, rgba(139, 92, 246, 0.9) 0%, rgba(59, 130, 246, 0.8) 50%, rgba(34, 197, 94, 0.9) 100%)\",\n borderRadius: \"8px\",\n width: `${duration > 0 ? currentTime / duration * 100 : 0}%`,\n transition: \"width 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 2px 8px rgba(139, 92, 246, 0.4)\"\n }\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n top: \"-6px\",\n right: `${duration > 0 ? 100 - currentTime / duration * 100 : 100}%`,\n width: \"20px\",\n height: \"20px\",\n background: \"linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(240, 240, 240, 0.9) 100%)\",\n borderRadius: \"50%\",\n border: \"3px solid rgba(139, 92, 246, 0.8)\",\n boxShadow: \"0 4px 16px rgba(139, 92, 246, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.8)\",\n transform: \"translateX(50%)\",\n transition: \"all 0.2s cubic-bezier(0.4, 0, 0.2, 1)\"\n }\n }\n )\n ]\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n color: \"white\",\n flexWrap: viewportWidth < 768 ? \"wrap\" : \"nowrap\",\n gap: `${8 * responsiveScale}px`\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n display: \"flex\",\n alignItems: \"center\",\n gap: `${12 * responsiveScale}px`,\n flexWrap: viewportWidth < 480 ? \"wrap\" : \"nowrap\"\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"button\",\n {\n onClick: handlePlayPause,\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n backdropFilter: \"blur(12px)\",\n border: `${2 * responsiveScale}px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${10 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 8px 32px rgba(0, 0, 0, 0.4), 0 4px 16px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n minWidth: `${48 * responsiveScale}px`,\n minHeight: `${48 * responsiveScale}px`\n },\n onMouseEnter: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n target.style.boxShadow = \"0 12px 48px rgba(0, 0, 0, 0.6), 0 6px 24px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n },\n onMouseLeave: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n target.style.boxShadow = \"0 8px 32px rgba(0, 0, 0, 0.4), 0 4px 16px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n },\n title: isPlaying ? \"Pause\" : \"Play\",\n children: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaPause,\n {\n size: Math.max(16, 20 * responsiveScale),\n style: { filter: \"drop-shadow(0 0 0 transparent)\" }\n }\n ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaPlay,\n {\n size: Math.max(16, 20 * responsiveScale),\n style: { filter: \"drop-shadow(0 0 0 transparent)\" }\n }\n )\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n padding: \"8px\",\n margin: \"-8px\"\n },\n onMouseEnter: () => setShowVolumeSlider(true),\n onMouseLeave: () => setShowVolumeSlider(false),\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"button\",\n {\n onClick: () => {\n if (playerRef.current) {\n playerRef.current.toggleMute();\n }\n if (onVolumeToggle) {\n onVolumeToggle();\n }\n },\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${2 * responsiveScale}px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${44 * responsiveScale}px`,\n minHeight: `${44 * responsiveScale}px`\n },\n onMouseEnter: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow = \"0 10px 36px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n },\n onMouseLeave: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow = \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n },\n title: isMuted ? \"Unmute\" : \"Mute\",\n children: isMuted || volume === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaVolumeMute,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 0 0 transparent)\"\n }\n }\n ) : volume < 0.5 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaVolumeDown,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 0 0 transparent)\"\n }\n }\n ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaVolumeUp,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 0 0 transparent)\"\n }\n }\n )\n }\n ),\n showVolumeSlider && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"60px\",\n height: \"20px\",\n marginBottom: \"-16px\",\n zIndex: 9\n },\n onMouseEnter: () => setShowVolumeSlider(true),\n onMouseLeave: () => setShowVolumeSlider(false)\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: \"4px\",\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.88) 0%, rgba(20, 20, 20, 0.92) 100%)\",\n backdropFilter: \"blur(15px)\",\n padding: \"10px 14px\",\n borderRadius: \"14px\",\n border: \"1px solid rgba(255, 255, 255, 0.15)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"128px\",\n boxShadow: \"0 12px 40px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15)\",\n zIndex: 10,\n transition: \"transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, border-color 0.2s ease-in-out\"\n },\n onMouseEnter: (e) => {\n setShowVolumeSlider(true);\n e.currentTarget.style.boxShadow = \"0 16px 48px rgba(0, 0, 0, 0.6), 0 6px 16px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 0 24px rgba(59, 130, 246, 0.3)\";\n e.currentTarget.style.borderColor = \"rgba(59, 130, 246, 0.4)\";\n },\n onMouseLeave: (e) => {\n setShowVolumeSlider(false);\n e.currentTarget.style.boxShadow = \"0 12px 40px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15)\";\n e.currentTarget.style.borderColor = \"rgba(255, 255, 255, 0.15)\";\n },\n children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"relative\",\n width: \"8px\",\n height: \"104px\",\n cursor: \"pointer\",\n transition: \"transform 0.2s ease-in-out\"\n },\n onMouseEnter: (e) => {\n },\n onMouseLeave: (e) => {\n },\n onMouseDown: (e) => {\n e.preventDefault();\n const sliderElement = e.currentTarget;\n const handleMouseMove = (moveEvent) => {\n if (!sliderElement) return;\n const rect2 = sliderElement.getBoundingClientRect();\n const y2 = moveEvent.clientY - rect2.top;\n const percentage2 = 1 - Math.max(0, Math.min(1, y2 / rect2.height));\n handleVolumeChange(percentage2);\n };\n const handleMouseUp = () => {\n document.removeEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.removeEventListener(\n \"mouseup\",\n handleMouseUp\n );\n };\n document.addEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.addEventListener(\n \"mouseup\",\n handleMouseUp\n );\n const rect = sliderElement.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage = 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n },\n onClick: (e) => {\n e.stopPropagation();\n const rect = e.currentTarget.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage = 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: \"100%\",\n background: \"linear-gradient(180deg, rgba(255, 255, 255, 0.4) 0%, rgba(255, 255, 255, 0.15) 100%)\",\n borderRadius: \"4px\",\n boxShadow: \"inset 0 1px 3px rgba(0, 0, 0, 0.2)\"\n }\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: `${(isMuted ? 0 : volume) * 100}%`,\n background: \"linear-gradient(180deg, rgba(96, 165, 250, 1) 0%, rgba(59, 130, 246, 0.95) 50%, rgba(37, 99, 235, 0.9) 100%)\",\n borderRadius: \"4px\",\n transition: \"height 0.15s ease-out, box-shadow 0.2s ease-in-out\",\n boxShadow: \"0 0 8px rgba(59, 130, 246, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.3)\"\n }\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: `calc(${(isMuted ? 0 : volume) * 100}% - 7px)`,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"14px\",\n height: \"14px\",\n background: \"linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)\",\n borderRadius: \"50%\",\n boxShadow: \"0 2px 6px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(59, 130, 246, 0.3), 0 0 12px rgba(59, 130, 246, 0.4)\",\n transition: \"bottom 0.15s ease-out, transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, width 0.2s ease-in-out, height 0.2s ease-in-out\",\n cursor: \"grab\"\n },\n onMouseEnter: (e) => {\n e.currentTarget.style.boxShadow = \"0 3px 10px rgba(0, 0, 0, 0.4), 0 0 0 3px rgba(59, 130, 246, 0.5), 0 0 20px rgba(59, 130, 246, 0.6)\";\n e.currentTarget.style.cursor = \"grab\";\n },\n onMouseLeave: (e) => {\n e.currentTarget.style.boxShadow = \"0 2px 6px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(59, 130, 246, 0.3), 0 0 12px rgba(59, 130, 246, 0.4)\";\n },\n onMouseDown: (e) => {\n e.currentTarget.style.cursor = \"grabbing\";\n },\n onMouseUp: (e) => {\n e.currentTarget.style.cursor = \"grab\";\n }\n }\n )\n ]\n }\n )\n }\n )\n ] })\n ]\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n fontSize: `${14 * responsiveScale}px`,\n fontFamily: \"monospace\",\n color: \"rgba(255, 255, 255, 0.9)\",\n display: viewportWidth < 480 ? \"none\" : \"block\"\n },\n children: [\n formatTime(currentTime),\n \" / \",\n formatTime(duration)\n ]\n }\n )\n ]\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n display: \"flex\",\n alignItems: \"center\",\n gap: `${12 * responsiveScale}px`\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"relative\",\n display: viewportWidth < 600 ? \"none\" : \"block\"\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"button\",\n {\n onClick: () => setShowSpeedMenu(!showSpeedMenu),\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${2 * responsiveScale}px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px ${14 * responsiveScale}px`,\n borderRadius: `${14 * responsiveScale}px`,\n fontSize: `${14 * responsiveScale}px`,\n fontFamily: \"monospace\",\n fontWeight: \"700\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 6px 24px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${56 * responsiveScale}px`,\n minHeight: `${40 * responsiveScale}px`\n },\n onMouseEnter: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow = \"0 10px 32px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n },\n onMouseLeave: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow = \"0 6px 24px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n },\n title: \"Playback Speed\",\n children: [\n playbackRate,\n \"x\"\n ]\n }\n ),\n showSpeedMenu && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"100%\",\n right: 0,\n marginBottom: \"12px\",\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.95) 100%)\",\n backdropFilter: \"blur(20px)\",\n borderRadius: \"12px\",\n border: \"1px solid rgba(255, 255, 255, 0.1)\",\n overflow: \"hidden\",\n minWidth: \"90px\",\n boxShadow: \"0 16px 48px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.1)\"\n },\n children: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2].map(\n (speed) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"button\",\n {\n onClick: () => handlePlaybackRateChange(speed),\n style: {\n display: \"block\",\n width: \"100%\",\n padding: \"10px 16px\",\n background: playbackRate === speed ? \"linear-gradient(135deg, rgba(99, 102, 241, 0.8) 0%, rgba(139, 92, 246, 0.6) 100%)\" : \"transparent\",\n border: \"none\",\n color: \"white\",\n cursor: \"pointer\",\n fontSize: \"13px\",\n fontFamily: \"monospace\",\n fontWeight: \"600\",\n textAlign: \"center\",\n transition: \"all 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n borderBottom: speed !== 2 ? \"1px solid rgba(255, 255, 255, 0.05)\" : \"none\"\n },\n onMouseEnter: (e) => {\n if (playbackRate !== speed) {\n e.target.style.background = \"linear-gradient(135deg, rgba(255, 255, 255, 0.15) 0%, rgba(255, 255, 255, 0.05) 100%)\";\n }\n },\n onMouseLeave: (e) => {\n if (playbackRate !== speed) {\n e.target.style.background = \"transparent\";\n }\n },\n children: [\n speed,\n \"x\"\n ]\n },\n speed\n )\n )\n }\n )\n ]\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"button\",\n {\n onClick: () => {\n if (onFullscreenToggle) {\n onFullscreenToggle();\n } else if (playerRef.current) {\n playerRef.current.toggleFullscreen().catch((err) => {\n console.error(\"Fullscreen error:\", err);\n });\n }\n },\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${2 * responsiveScale}px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${44 * responsiveScale}px`,\n minHeight: `${44 * responsiveScale}px`\n },\n onMouseEnter: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow = \"0 10px 36px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n },\n onMouseLeave: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow = \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n },\n title: isFullscreen ? \"Exit Fullscreen\" : \"Enter Fullscreen\",\n children: isFullscreen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaCompress,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: { filter: \"drop-shadow(0 0 0 transparent)\" }\n }\n ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaExpand,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: { filter: \"drop-shadow(0 0 0 transparent)\" }\n }\n )\n }\n )\n ]\n }\n )\n ]\n }\n )\n ]\n }\n ) }) : showCustomControls && !showLicenseWarning && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: `${10 * responsiveScale}px`,\n right: `${10 * responsiveScale}px`,\n transform: \"none\",\n display: \"flex\",\n flexDirection: isPortrait ? \"column\" : \"row\",\n gap: `${10 * responsiveScale}px`,\n zIndex: 10\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n padding: \"8px\",\n margin: \"-8px\"\n },\n onMouseEnter: () => setShowVolumeSlider(true),\n onMouseLeave: () => setShowVolumeSlider(false),\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"button\",\n {\n onClick: () => {\n if (playerRef.current) {\n playerRef.current.toggleMute();\n }\n if (onVolumeToggle) {\n onVolumeToggle();\n }\n },\n onMouseEnter: (e) => {\n const target = e.currentTarget;\n target.style.boxShadow = \"0 14px 48px rgba(0, 0, 0, 0.7), 0 0 0 3px rgba(255, 255, 255, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n },\n onMouseLeave: (e) => {\n const target = e.currentTarget;\n target.style.boxShadow = \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n },\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n color: \"#ffffff\",\n border: \"none\",\n borderRadius: `${18 * responsiveScale}px`,\n padding: `${8 * responsiveScale}px`,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n boxShadow: \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.4s cubic-bezier(0.4, 0, 0.2, 1)\",\n minWidth: `${46 * responsiveScale}px`,\n minHeight: `${46 * responsiveScale}px`\n },\n title: isMuted ? \"Unmute\" : \"Mute\",\n children: isMuted || volume === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaVolumeMute,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\"\n }\n }\n ) : volume < 0.5 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaVolumeDown,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\"\n }\n }\n ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaVolumeUp,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\"\n }\n }\n )\n }\n ),\n showVolumeSlider && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"60px\",\n height: \"20px\",\n marginBottom: \"-16px\",\n zIndex: 9\n },\n onMouseEnter: () => setShowVolumeSlider(true),\n onMouseLeave: () => setShowVolumeSlider(false)\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: \"4px\",\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.96) 0%, rgba(20, 20, 20, 0.92) 100%)\",\n backdropFilter: \"blur(20px)\",\n padding: \"10px 14px\",\n borderRadius: \"14px\",\n border: \"2px solid rgba(255, 255, 255, 0.7)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"128px\",\n boxShadow: \"0 12px 40px rgba(0, 0, 0, 0.85), 0 4px 12px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.35)\",\n zIndex: 10,\n transition: \"transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, border-color 0.2s ease-in-out\"\n },\n onMouseEnter: (e) => {\n setShowVolumeSlider(true);\n e.currentTarget.style.boxShadow = \"0 16px 48px rgba(0, 0, 0, 0.9), 0 6px 16px rgba(0, 0, 0, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 0 24px rgba(96, 165, 250, 0.4)\";\n e.currentTarget.style.borderColor = \"rgba(96, 165, 250, 0.8)\";\n },\n onMouseLeave: (e) => {\n setShowVolumeSlider(false);\n e.currentTarget.style.boxShadow = \"0 12px 40px rgba(0, 0, 0, 0.85), 0 4px 12px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.35)\";\n e.currentTarget.style.borderColor = \"rgba(255, 255, 255, 0.7)\";\n },\n children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"relative\",\n width: \"8px\",\n height: \"104px\",\n cursor: \"pointer\",\n transition: \"transform 0.2s ease-in-out\"\n },\n onMouseDown: (e) => {\n e.preventDefault();\n const sliderElement = e.currentTarget;\n const handleMouseMove = (moveEvent) => {\n if (!sliderElement) return;\n const rect2 = sliderElement.getBoundingClientRect();\n const y2 = moveEvent.clientY - rect2.top;\n const percentage2 = 1 - Math.max(0, Math.min(1, y2 / rect2.height));\n handleVolumeChange(percentage2);\n };\n const handleMouseUp = () => {\n document.removeEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.removeEventListener(\n \"mouseup\",\n handleMouseUp\n );\n };\n document.addEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.addEventListener(\n \"mouseup\",\n handleMouseUp\n );\n const rect = sliderElement.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage = 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n },\n onClick: (e) => {\n e.stopPropagation();\n const rect = e.currentTarget.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage = 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: \"100%\",\n background: \"linear-gradient(180deg, rgba(255, 255, 255, 0.85) 0%, rgba(255, 255, 255, 0.5) 100%)\",\n borderRadius: \"4px\",\n border: \"1px solid rgba(255, 255, 255, 0.4)\",\n boxShadow: \"inset 0 1px 3px rgba(0, 0, 0, 0.3)\"\n }\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: `${(isMuted ? 0 : volume) * 100}%`,\n background: \"linear-gradient(180deg, rgba(125, 211, 252, 1) 0%, rgba(96, 165, 250, 0.98) 50%, rgba(59, 130, 246, 0.95) 100%)\",\n borderRadius: \"4px\",\n transition: \"height 0.15s ease-out, box-shadow 0.2s ease-in-out\",\n boxShadow: \"0 0 12px rgba(96, 165, 250, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.4)\"\n }\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: `calc(${(isMuted ? 0 : volume) * 100}% - 8px)`,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"16px\",\n height: \"16px\",\n background: \"linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)\",\n borderRadius: \"50%\",\n border: \"2px solid rgba(96, 165, 250, 0.9)\",\n boxShadow: \"0 3px 8px rgba(0, 0, 0, 0.5), 0 0 0 2px rgba(96, 165, 250, 0.4), 0 0 16px rgba(96, 165, 250, 0.5)\",\n transition: \"bottom 0.15s ease-out, transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, width 0.2s ease-in-out, height 0.2s ease-in-out\",\n cursor: \"grab\"\n },\n onMouseEnter: (e) => {\n e.currentTarget.style.boxShadow = \"0 4px 12px rgba(0, 0, 0, 0.6), 0 0 0 3px rgba(96, 165, 250, 0.6), 0 0 24px rgba(96, 165, 250, 0.7)\";\n e.currentTarget.style.cursor = \"grab\";\n },\n onMouseLeave: (e) => {\n e.currentTarget.style.boxShadow = \"0 3px 8px rgba(0, 0, 0, 0.5), 0 0 0 2px rgba(96, 165, 250, 0.4), 0 0 16px rgba(96, 165, 250, 0.5)\";\n },\n onMouseDown: (e) => {\n e.currentTarget.style.cursor = \"grabbing\";\n },\n onMouseUp: (e) => {\n e.currentTarget.style.cursor = \"grab\";\n }\n }\n )\n ]\n }\n )\n }\n )\n ] })\n ]\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"button\",\n {\n onClick: () => {\n if (onFullscreenToggle) {\n onFullscreenToggle();\n } else if (playerRef.current) {\n playerRef.current.toggleFullscreen().catch((err) => {\n console.error(\"Fullscreen error:\", err);\n });\n }\n },\n onMouseEnter: (e) => {\n const target = e.currentTarget;\n target.style.boxShadow = \"0 14px 48px rgba(0, 0, 0, 0.7), 0 0 0 3px rgba(255, 255, 255, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n },\n onMouseLeave: (e) => {\n const target = e.currentTarget;\n target.style.boxShadow = \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n },\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n color: \"#ffffff\",\n border: \"none\",\n borderRadius: `${18 * responsiveScale}px`,\n padding: `${8 * responsiveScale}px`,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n boxShadow: \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.4s cubic-bezier(0.4, 0, 0.2, 1)\",\n minWidth: `${46 * responsiveScale}px`,\n minHeight: `${46 * responsiveScale}px`\n },\n title: isFullscreen ? \"Exit Fullscreen\" : \"Enter Fullscreen\",\n children: isFullscreen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaCompress,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\"\n }\n }\n ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaExpand,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\"\n }\n }\n )\n }\n )\n ]\n }\n ),\n onControlClick && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n onClick: onControlClick,\n style: {\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 1,\n cursor: \"pointer\"\n }\n }\n )\n ]\n }\n )\n ] });\n },\n (prevProps, nextProps) => {\n for (const prop of CRITICAL_PROPS) {\n if (prevProps[prop] !== nextProps[prop]) {\n return false;\n }\n }\n const uiProps = [\n \"autoplay\",\n \"muted\",\n \"controls\",\n \"showCustomControls\",\n \"className\",\n \"style\",\n \"wrapperClassName\",\n \"wrapperStyle\",\n \"playsInline\",\n \"preload\",\n \"poster\",\n \"children\"\n ];\n for (const prop of uiProps) {\n if (prevProps[prop] !== nextProps[prop]) {\n return false;\n }\n }\n const callbackProps = [\n \"onReady\",\n \"onVolumeToggle\",\n \"onFullscreenToggle\",\n \"onControlClick\"\n ];\n for (const prop of callbackProps) {\n if (prevProps[prop] !== nextProps[prop]) {\n return false;\n }\n }\n return true;\n }\n);\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n StormcloudVideoPlayerComponent\n});\n","import React, { useEffect, useRef, useMemo } from \"react\";\nimport { StormcloudVideoPlayer } from \"../player/StormcloudVideoPlayer\";\nimport type { StormcloudVideoPlayerConfig } from \"../types\";\nimport {\n FaPlay,\n FaPause,\n FaVolumeUp,\n FaVolumeMute,\n FaVolumeDown,\n FaExpand,\n FaCompress,\n FaSpinner,\n} from \"react-icons/fa\";\n\nexport type StormcloudVideoPlayerProps = Omit<\n StormcloudVideoPlayerConfig,\n \"videoElement\"\n> &\n React.VideoHTMLAttributes<HTMLVideoElement> & {\n onReady?: (player: StormcloudVideoPlayer) => void;\n wrapperClassName?: string;\n wrapperStyle?: React.CSSProperties;\n licenseKey?: string;\n };\n\nconst CRITICAL_PROPS = [\n \"src\",\n \"allowNativeHls\",\n \"licenseKey\",\n \"lowLatencyMode\",\n \"driftToleranceMs\",\n] as const;\n\nexport const StormcloudVideoPlayerComponent: React.FC<StormcloudVideoPlayerProps> =\n React.memo(\n (props) => {\n const {\n src,\n autoplay,\n muted,\n lowLatencyMode,\n allowNativeHls,\n driftToleranceMs,\n immediateManifestAds,\n debugAdTiming,\n showCustomControls,\n hideLoadingIndicator,\n onVolumeToggle,\n onFullscreenToggle,\n onControlClick,\n onReady,\n wrapperClassName,\n wrapperStyle,\n className,\n style,\n controls,\n playsInline,\n preload,\n poster,\n children,\n licenseKey,\n minSegmentsBeforePlay,\n ...restVideoAttrs\n } = props;\n\n const videoRef = useRef<HTMLVideoElement | null>(null);\n const playerRef = useRef<StormcloudVideoPlayer | null>(null);\n const bufferingTimeoutRef = useRef<number | null>(null);\n const [adStatus, setAdStatus] = React.useState<{\n showAds: boolean;\n currentIndex: number;\n totalAds: number;\n }>({ showAds: false, currentIndex: 0, totalAds: 0 });\n\n const [shouldShowNativeControls, setShouldShowNativeControls] =\n React.useState(true);\n\n const [isMuted, setIsMuted] = React.useState(false);\n const [isFullscreen, setIsFullscreen] = React.useState(false);\n const [isPlaying, setIsPlaying] = React.useState(false);\n const [currentTime, setCurrentTime] = React.useState(0);\n const [duration, setDuration] = React.useState(0);\n const [volume, setVolume] = React.useState(1);\n const [playbackRate, setPlaybackRate] = React.useState(1);\n const [showVolumeSlider, setShowVolumeSlider] = React.useState(false);\n const [showSpeedMenu, setShowSpeedMenu] = React.useState(false);\n const [isLoading, setIsLoading] = React.useState(true);\n const [isBuffering, setIsBuffering] = React.useState(false);\n const [showCenterPlay, setShowCenterPlay] = React.useState(false);\n const [showLicenseWarning, setShowLicenseWarning] = React.useState(false);\n const [viewportWidth, setViewportWidth] = React.useState(\n typeof window !== \"undefined\" ? window.innerWidth : 1920\n );\n const [isPortrait, setIsPortrait] = React.useState(\n typeof window !== \"undefined\"\n ? window.innerHeight > window.innerWidth\n : false\n );\n\n const getResponsiveScale = () => {\n if (viewportWidth < 480) return 0.7;\n if (viewportWidth < 768) return 0.8;\n if (viewportWidth < 1024) return 0.9;\n return 1;\n };\n\n const responsiveScale = getResponsiveScale();\n\n const formatTime = (seconds: number): string => {\n if (!isFinite(seconds)) return \"0:00:00\";\n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n const remainingSeconds = Math.floor(seconds % 60);\n return `${hours}:${minutes\n .toString()\n .padStart(2, \"0\")}:${remainingSeconds.toString().padStart(2, \"0\")}`;\n };\n\n const handlePlayPause = () => {\n if (videoRef.current) {\n if (videoRef.current.paused) {\n const hasValidSource =\n videoRef.current.src ||\n (videoRef.current.currentSrc &&\n videoRef.current.currentSrc !== \"\") ||\n videoRef.current.readyState >= 1;\n\n if (hasValidSource) {\n videoRef.current.play()?.catch((error) => {\n console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n });\n setShowCenterPlay(false);\n } else {\n console.warn(\n \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n );\n }\n } else {\n videoRef.current.pause();\n setShowCenterPlay(true);\n }\n }\n };\n\n const handleCenterPlayClick = () => {\n if (videoRef.current && videoRef.current.paused) {\n const hasValidSource =\n videoRef.current.src ||\n (videoRef.current.currentSrc &&\n videoRef.current.currentSrc !== \"\") ||\n videoRef.current.readyState >= 1;\n\n if (hasValidSource) {\n videoRef.current.play()?.catch((error) => {\n console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n });\n setShowCenterPlay(false);\n } else {\n console.warn(\n \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n );\n }\n }\n };\n\n const handleTimelineSeek = (e: React.MouseEvent<HTMLDivElement>) => {\n if (videoRef.current && duration > 0 && isFinite(duration)) {\n const rect = e.currentTarget.getBoundingClientRect();\n const clickX = e.clientX - rect.left;\n const progress = Math.max(0, Math.min(1, clickX / rect.width));\n const newTime = progress * duration;\n\n if (isFinite(newTime) && newTime >= 0 && newTime <= duration) {\n videoRef.current.currentTime = newTime;\n }\n }\n };\n\n const handleVolumeChange = (newVolume: number) => {\n if (playerRef.current && isFinite(newVolume)) {\n const clampedVolume = Math.max(0, Math.min(1, newVolume));\n playerRef.current.setVolume(clampedVolume);\n }\n };\n\n const handlePlaybackRateChange = (rate: number) => {\n if (videoRef.current && isFinite(rate) && rate > 0) {\n videoRef.current.playbackRate = rate;\n }\n setShowSpeedMenu(false);\n };\n\n const isHlsStream =\n src?.toLowerCase().includes(\".m3u8\") ||\n src?.toLowerCase().includes(\"/hls/\");\n const shouldShowEnhancedControls =\n showCustomControls && (isHlsStream ? allowNativeHls : true);\n\n const criticalPropsKey = useMemo(() => {\n return CRITICAL_PROPS.map((prop) => `${prop}:${props[prop]}`).join(\"|\");\n }, [\n src,\n allowNativeHls,\n licenseKey,\n lowLatencyMode,\n driftToleranceMs,\n ]);\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const el = videoRef.current;\n if (!el || !src) return;\n\n if (!licenseKey) {\n setShowLicenseWarning(true);\n setIsLoading(false);\n console.warn(\n \"StormcloudVideoPlayer: License key is required but not provided. Please set the licenseKey prop to use the player.\"\n );\n return;\n }\n\n setShowLicenseWarning(false);\n\n if (debugAdTiming) {\n console.log(\"[StormcloudUI] Initializing player, isLoading=true\");\n }\n\n if (playerRef.current) {\n try {\n playerRef.current.destroy();\n } catch {}\n playerRef.current = null;\n }\n\n const cfg: StormcloudVideoPlayerConfig = {\n src,\n videoElement: el,\n } as StormcloudVideoPlayerConfig;\n if (autoplay !== undefined) cfg.autoplay = autoplay;\n if (muted !== undefined) cfg.muted = muted;\n if (lowLatencyMode !== undefined) cfg.lowLatencyMode = lowLatencyMode;\n if (allowNativeHls !== undefined) cfg.allowNativeHls = allowNativeHls;\n if (driftToleranceMs !== undefined)\n cfg.driftToleranceMs = driftToleranceMs;\n if (immediateManifestAds !== undefined)\n cfg.immediateManifestAds = immediateManifestAds;\n if (debugAdTiming !== undefined) cfg.debugAdTiming = debugAdTiming;\n if (showCustomControls !== undefined)\n cfg.showCustomControls = showCustomControls;\n if (onVolumeToggle !== undefined) cfg.onVolumeToggle = onVolumeToggle;\n if (onFullscreenToggle !== undefined)\n cfg.onFullscreenToggle = onFullscreenToggle;\n if (onControlClick !== undefined) cfg.onControlClick = onControlClick;\n if (licenseKey !== undefined) cfg.licenseKey = licenseKey;\n if (minSegmentsBeforePlay !== undefined)\n cfg.minSegmentsBeforePlay = minSegmentsBeforePlay;\n\n const player = new StormcloudVideoPlayer(cfg);\n playerRef.current = player;\n player\n .load()\n .then(() => {\n const showNative = player.shouldShowNativeControls();\n setShouldShowNativeControls(showNative);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Player loaded successfully, waiting for video ready\"\n );\n }\n onReady?.(player);\n })\n .catch((error) => {\n console.error(\n \"StormcloudVideoPlayer: Failed to load player:\",\n error\n );\n setIsLoading(false);\n onReady?.(player);\n });\n\n return () => {\n try {\n player.destroy();\n } catch {}\n playerRef.current = null;\n };\n }, [criticalPropsKey]);\n\n useEffect(() => {\n if (!playerRef.current) return;\n\n try {\n if (autoplay !== undefined && playerRef.current.videoElement) {\n playerRef.current.videoElement.autoplay = autoplay;\n }\n if (muted !== undefined && !playerRef.current.isShowingAds()) {\n playerRef.current.setMuted(muted);\n }\n } catch (error) {\n console.warn(\"Failed to update player properties:\", error);\n }\n }, [autoplay, muted]);\n\n useEffect(() => {\n if (!playerRef.current) return;\n\n const checkAdStatus = () => {\n if (playerRef.current) {\n const showAdsFromMethod = playerRef.current.isShowingAds();\n const showAdsFromAttribute = videoRef.current?.dataset?.stormcloudAdPlaying === \"true\";\n const showAds = showAdsFromMethod || showAdsFromAttribute;\n const currentIndex = playerRef.current.getCurrentAdIndex();\n const totalAds = playerRef.current.getTotalAdsInBreak();\n\n setAdStatus((prev) => {\n if (\n prev.showAds !== showAds ||\n prev.currentIndex !== currentIndex ||\n prev.totalAds !== totalAds\n ) {\n if (showAds && !prev.showAds) {\n setShowCenterPlay(false);\n }\n return { showAds, currentIndex, totalAds };\n }\n return prev;\n });\n }\n };\n\n const interval = setInterval(checkAdStatus, 50);\n return () => clearInterval(interval);\n }, []);\n\n useEffect(() => {\n if (typeof window === \"undefined\" || !playerRef.current) return;\n\n const handleResize = () => {\n if (playerRef.current && videoRef.current) {\n if (typeof playerRef.current.resize === \"function\") {\n playerRef.current.resize();\n }\n }\n setViewportWidth(window.innerWidth);\n setIsPortrait(window.innerHeight > window.innerWidth);\n };\n\n window.addEventListener(\"resize\", handleResize);\n return () => window.removeEventListener(\"resize\", handleResize);\n }, []);\n\n useEffect(() => {\n if (!playerRef.current || !videoRef.current) return;\n\n const updateStates = () => {\n if (playerRef.current && videoRef.current) {\n setIsMuted(playerRef.current.isMuted());\n setIsPlaying(!videoRef.current.paused);\n\n const currentTimeValue = videoRef.current.currentTime;\n setCurrentTime(isFinite(currentTimeValue) ? currentTimeValue : 0);\n\n const durationValue = videoRef.current.duration;\n setDuration(isFinite(durationValue) ? durationValue : 0);\n\n const volumeValue = playerRef.current.getVolume();\n setVolume(\n isFinite(volumeValue) ? Math.max(0, Math.min(1, volumeValue)) : 1\n );\n\n const rateValue = videoRef.current.playbackRate;\n setPlaybackRate(\n isFinite(rateValue) && rateValue > 0 ? rateValue : 1\n );\n }\n setIsFullscreen(\n document.fullscreenElement === videoRef.current?.parentElement\n );\n };\n\n const interval = setInterval(updateStates, 200);\n\n const handleFullscreenChange = () => {\n setIsFullscreen(\n document.fullscreenElement === videoRef.current?.parentElement\n );\n };\n\n document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n\n return () => {\n clearInterval(interval);\n document.removeEventListener(\n \"fullscreenchange\",\n handleFullscreenChange\n );\n };\n }, []);\n\n useEffect(() => {\n if (!videoRef.current) return;\n\n const handleLoadedMetadata = () => {\n if (videoRef.current) {\n const video = videoRef.current;\n void video.offsetHeight;\n }\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadedmetadata, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n\n const handleLoadedData = () => {\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadeddata, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n\n const handleLoadStart = () => {\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadstart, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n\n const handleCanPlay = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: canplay, readyState:\",\n videoRef.current?.readyState,\n \"- clearing loading state, isLoading=false\"\n );\n }\n };\n\n const handleCanPlayThrough = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: canplaythrough, readyState:\",\n videoRef.current?.readyState,\n \"- clearing loading state, isLoading=false\"\n );\n }\n };\n\n const handleWaiting = () => {\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n }\n\n bufferingTimeoutRef.current = window.setTimeout(() => {\n setIsBuffering(true);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video buffering detected (after 300ms delay), readyState:\",\n videoRef.current?.readyState,\n \"- showing spinner, isBuffering=true\"\n );\n }\n }, 300);\n\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: waiting, readyState:\",\n videoRef.current?.readyState,\n \"- buffering delay started (300ms)\"\n );\n }\n };\n\n const handlePlaying = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n setShowCenterPlay(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: playing, readyState:\",\n videoRef.current?.readyState,\n \"- playback started, isLoading=false, isBuffering=false\"\n );\n }\n };\n\n const handlePause = () => {\n const isAdActive = playerRef.current?.isShowingAds() || \n videoRef.current?.dataset?.stormcloudAdPlaying === \"true\";\n \n if (playerRef.current && !isAdActive) {\n setShowCenterPlay(true);\n } else {\n setShowCenterPlay(false);\n }\n };\n\n const handleEnded = () => {\n setShowCenterPlay(true);\n };\n\n const video = videoRef.current;\n video.addEventListener(\"loadstart\", handleLoadStart);\n video.addEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.addEventListener(\"loadeddata\", handleLoadedData);\n video.addEventListener(\"canplay\", handleCanPlay);\n video.addEventListener(\"canplaythrough\", handleCanPlayThrough);\n video.addEventListener(\"waiting\", handleWaiting);\n video.addEventListener(\"playing\", handlePlaying);\n video.addEventListener(\"pause\", handlePause);\n video.addEventListener(\"ended\", handleEnded);\n\n if (video.paused) {\n setShowCenterPlay(true);\n }\n\n return () => {\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n\n video.removeEventListener(\"loadstart\", handleLoadStart);\n video.removeEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.removeEventListener(\"loadeddata\", handleLoadedData);\n video.removeEventListener(\"canplay\", handleCanPlay);\n video.removeEventListener(\"canplaythrough\", handleCanPlayThrough);\n video.removeEventListener(\"waiting\", handleWaiting);\n video.removeEventListener(\"playing\", handlePlaying);\n video.removeEventListener(\"pause\", handlePause);\n video.removeEventListener(\"ended\", handleEnded);\n };\n }, [debugAdTiming]);\n\n return (\n <>\n <style>\n {`\n @keyframes spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n }\n \n .stormcloud-loading-hidden .stormcloud-loading-indicator {\n display: none !important;\n }\n \n .stormcloud-video-wrapper:fullscreen {\n border-radius: 0 !important;\n box-shadow: none !important;\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n \n .stormcloud-video-wrapper:has(*:fullscreen) {\n border-radius: 0 !important;\n box-shadow: none !important;\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n \n *:fullscreen {\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n }\n `}\n </style>\n <div\n className={`stormcloud-video-wrapper ${wrapperClassName || \"\"}`}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n position: isFullscreen ? \"fixed\" : \"relative\",\n top: isFullscreen ? 0 : undefined,\n left: isFullscreen ? 0 : undefined,\n overflow: \"hidden\",\n width: isFullscreen ? \"100vw\" : \"100%\",\n height: isFullscreen ? \"100vh\" : \"auto\",\n minHeight: isFullscreen ? \"100vh\" : \"auto\",\n maxWidth: isFullscreen ? \"100vw\" : \"100%\",\n maxHeight: isFullscreen ? \"100vh\" : \"none\",\n zIndex: isFullscreen ? 999999 : undefined,\n backgroundColor: isFullscreen ? \"#000\" : undefined,\n borderRadius: isFullscreen ? 0 : undefined,\n boxShadow: isFullscreen ? \"none\" : undefined,\n ...wrapperStyle,\n }}\n >\n <video\n ref={videoRef}\n className={className}\n style={{\n display: \"block\",\n width: \"100%\",\n height: isFullscreen ? \"100%\" : \"auto\",\n maxWidth: \"100%\",\n maxHeight: isFullscreen ? \"100%\" : \"none\",\n objectFit: isFullscreen ? \"cover\" : \"contain\",\n backgroundColor: \"#000\",\n aspectRatio: isFullscreen ? \"unset\" : undefined,\n ...style,\n }}\n controls={\n shouldShowNativeControls && controls && !showCustomControls\n }\n playsInline={playsInline}\n preload={preload}\n poster={poster}\n {...restVideoAttrs}\n >\n {children}\n </video>\n\n {(isLoading || isBuffering) && !hideLoadingIndicator && (\n <FaSpinner\n className=\"stormcloud-loading-indicator\"\n size={42}\n color=\"white\"\n style={{\n position: \"absolute\",\n top: \"calc(50% - 21px)\",\n left: \"calc(50% - 21px)\",\n zIndex: 20,\n animation: \"spin 1s linear infinite\",\n filter: \"drop-shadow(0 3px 6px rgba(0, 0, 0, 0.8))\",\n }}\n />\n )}\n\n {showLicenseWarning && (\n <div\n style={{\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n zIndex: 25,\n background:\n \"linear-gradient(135deg, rgba(220, 38, 38, 0.95) 0%, rgba(185, 28, 28, 0.9) 100%)\",\n color: \"white\",\n padding: \"24px 32px\",\n borderRadius: \"16px\",\n backdropFilter: \"blur(20px)\",\n border: \"2px solid rgba(255, 255, 255, 0.2)\",\n boxShadow:\n \"0 20px 60px rgba(0, 0, 0, 0.6), inset 0 2px 0 rgba(255, 255, 255, 0.2)\",\n textAlign: \"center\",\n maxWidth: \"400px\",\n margin: \"0 16px\",\n }}\n >\n <div\n style={{\n fontSize: \"20px\",\n fontWeight: \"bold\",\n marginBottom: \"12px\",\n color: \"#ffffff\",\n textShadow: \"0 2px 4px rgba(0, 0, 0, 0.5)\",\n }}\n >\n License Key Required\n </div>\n <div\n style={{\n fontSize: \"14px\",\n lineHeight: \"1.5\",\n color: \"rgba(255, 255, 255, 0.9)\",\n textShadow: \"0 1px 2px rgba(0, 0, 0, 0.3)\",\n }}\n >\n Please provide a valid license key to use the Stormcloud Video\n Player.\n <br />\n Contact your administrator for licensing information.\n </div>\n </div>\n )}\n\n {showCenterPlay &&\n !isLoading &&\n !isBuffering &&\n !showLicenseWarning &&\n !adStatus.showAds && (\n <div\n onClick={handleCenterPlayClick}\n style={{\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n zIndex: 15,\n cursor: \"pointer\",\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.8) 100%)\",\n borderRadius: \"50%\",\n width: \"100px\",\n height: \"100px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n border: \"3px solid rgba(255, 255, 255, 0.8)\",\n boxShadow:\n \"0 12px 40px rgba(0, 0, 0, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n }}\n onMouseEnter={(e) => {\n const target = e.currentTarget as HTMLElement;\n target.style.transform = \"translate(-50%, -50%)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.95) 0%, rgba(40, 40, 40, 0.9) 100%)\";\n target.style.boxShadow =\n \"0 16px 48px rgba(0, 0, 0, 0.9), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.borderColor = \"rgba(255, 255, 255, 0.9)\";\n }}\n onMouseLeave={(e) => {\n const target = e.currentTarget as HTMLElement;\n target.style.transform = \"translate(-50%, -50%)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.8) 100%)\";\n target.style.boxShadow =\n \"0 12px 40px rgba(0, 0, 0, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.3)\";\n target.style.borderColor = \"rgba(255, 255, 255, 0.8)\";\n }}\n title=\"Play\"\n >\n <FaPlay\n size={36}\n color=\"white\"\n style={{\n marginLeft: \"6px\",\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n }}\n />\n </div>\n )}\n\n {shouldShowEnhancedControls && !showLicenseWarning ? (\n <>\n <div\n style={{\n position: \"absolute\",\n bottom: 0,\n left: 0,\n right: 0,\n background:\n \"linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.8) 100%)\",\n padding: \"20px 16px 16px\",\n zIndex: 10,\n }}\n >\n <div\n style={{\n width: \"100%\",\n height: \"8px\",\n background:\n \"linear-gradient(90deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0.1) 100%)\",\n borderRadius: \"8px\",\n marginBottom: \"16px\",\n cursor: \"pointer\",\n position: \"relative\",\n backdropFilter: \"blur(5px)\",\n border: \"1px solid rgba(255, 255, 255, 0.1)\",\n boxShadow: \"inset 0 2px 4px rgba(0, 0, 0, 0.2)\",\n }}\n onClick={handleTimelineSeek}\n >\n <div\n style={{\n height: \"100%\",\n background:\n \"linear-gradient(90deg, rgba(139, 92, 246, 0.9) 0%, rgba(59, 130, 246, 0.8) 50%, rgba(34, 197, 94, 0.9) 100%)\",\n borderRadius: \"8px\",\n width: `${\n duration > 0 ? (currentTime / duration) * 100 : 0\n }%`,\n transition: \"width 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 2px 8px rgba(139, 92, 246, 0.4)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n top: \"-6px\",\n right: `${\n duration > 0\n ? 100 - (currentTime / duration) * 100\n : 100\n }%`,\n width: \"20px\",\n height: \"20px\",\n background:\n \"linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(240, 240, 240, 0.9) 100%)\",\n borderRadius: \"50%\",\n border: \"3px solid rgba(139, 92, 246, 0.8)\",\n boxShadow:\n \"0 4px 16px rgba(139, 92, 246, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.8)\",\n transform: \"translateX(50%)\",\n transition: \"all 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n }}\n />\n </div>\n\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n color: \"white\",\n flexWrap: viewportWidth < 768 ? \"wrap\" : \"nowrap\",\n gap: `${8 * responsiveScale}px`,\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: `${12 * responsiveScale}px`,\n flexWrap: viewportWidth < 480 ? \"wrap\" : \"nowrap\",\n }}\n >\n <button\n onClick={handlePlayPause}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n backdropFilter: \"blur(12px)\",\n border: `${\n 2 * responsiveScale\n }px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${10 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow:\n \"0 8px 32px rgba(0, 0, 0, 0.4), 0 4px 16px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n minWidth: `${48 * responsiveScale}px`,\n minHeight: `${48 * responsiveScale}px`,\n }}\n onMouseEnter={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n target.style.boxShadow =\n \"0 12px 48px rgba(0, 0, 0, 0.6), 0 6px 24px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n }}\n onMouseLeave={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n target.style.boxShadow =\n \"0 8px 32px rgba(0, 0, 0, 0.4), 0 4px 16px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n }}\n title={isPlaying ? \"Pause\" : \"Play\"}\n >\n {isPlaying ? (\n <FaPause\n size={Math.max(16, 20 * responsiveScale)}\n style={{ filter: \"drop-shadow(0 0 0 transparent)\" }}\n />\n ) : (\n <FaPlay\n size={Math.max(16, 20 * responsiveScale)}\n style={{ filter: \"drop-shadow(0 0 0 transparent)\" }}\n />\n )}\n </button>\n\n <div\n style={{\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n padding: \"8px\",\n margin: \"-8px\",\n }}\n onMouseEnter={() => setShowVolumeSlider(true)}\n onMouseLeave={() => setShowVolumeSlider(false)}\n >\n <button\n onClick={() => {\n if (playerRef.current) {\n playerRef.current.toggleMute();\n }\n if (onVolumeToggle) {\n onVolumeToggle();\n }\n }}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${\n 2 * responsiveScale\n }px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow:\n \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${44 * responsiveScale}px`,\n minHeight: `${44 * responsiveScale}px`,\n }}\n onMouseEnter={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow =\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n }}\n onMouseLeave={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow =\n \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n }}\n title={isMuted ? \"Unmute\" : \"Mute\"}\n >\n {isMuted || volume === 0 ? (\n <FaVolumeMute\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 0 0 transparent)\",\n }}\n />\n ) : volume < 0.5 ? (\n <FaVolumeDown\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 0 0 transparent)\",\n }}\n />\n ) : (\n <FaVolumeUp\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 0 0 transparent)\",\n }}\n />\n )}\n </button>\n\n {showVolumeSlider && (\n <>\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"60px\",\n height: \"20px\",\n marginBottom: \"-16px\",\n zIndex: 9,\n }}\n onMouseEnter={() => setShowVolumeSlider(true)}\n onMouseLeave={() => setShowVolumeSlider(false)}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: \"4px\",\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.88) 0%, rgba(20, 20, 20, 0.92) 100%)\",\n backdropFilter: \"blur(15px)\",\n padding: \"10px 14px\",\n borderRadius: \"14px\",\n border: \"1px solid rgba(255, 255, 255, 0.15)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"128px\",\n boxShadow:\n \"0 12px 40px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15)\",\n zIndex: 10,\n transition:\n \"transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, border-color 0.2s ease-in-out\",\n }}\n onMouseEnter={(e) => {\n setShowVolumeSlider(true);\n e.currentTarget.style.boxShadow =\n \"0 16px 48px rgba(0, 0, 0, 0.6), 0 6px 16px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 0 24px rgba(59, 130, 246, 0.3)\";\n e.currentTarget.style.borderColor =\n \"rgba(59, 130, 246, 0.4)\";\n }}\n onMouseLeave={(e) => {\n setShowVolumeSlider(false);\n e.currentTarget.style.boxShadow =\n \"0 12px 40px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15)\";\n e.currentTarget.style.borderColor =\n \"rgba(255, 255, 255, 0.15)\";\n }}\n >\n <div\n style={{\n position: \"relative\",\n width: \"8px\",\n height: \"104px\",\n cursor: \"pointer\",\n transition: \"transform 0.2s ease-in-out\",\n }}\n onMouseEnter={(e) => {\n // Hover effect removed\n }}\n onMouseLeave={(e) => {\n // Hover effect removed\n }}\n onMouseDown={(e) => {\n e.preventDefault();\n const sliderElement = e.currentTarget;\n\n const handleMouseMove = (\n moveEvent: MouseEvent\n ) => {\n if (!sliderElement) return;\n const rect =\n sliderElement.getBoundingClientRect();\n const y = moveEvent.clientY - rect.top;\n const percentage =\n 1 -\n Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n };\n\n const handleMouseUp = () => {\n document.removeEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.removeEventListener(\n \"mouseup\",\n handleMouseUp\n );\n };\n\n document.addEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.addEventListener(\n \"mouseup\",\n handleMouseUp\n );\n\n const rect =\n sliderElement.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage =\n 1 -\n Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n }}\n onClick={(e) => {\n e.stopPropagation();\n const rect =\n e.currentTarget.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage =\n 1 -\n Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n }}\n >\n <div\n style={{\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: \"100%\",\n background:\n \"linear-gradient(180deg, rgba(255, 255, 255, 0.4) 0%, rgba(255, 255, 255, 0.15) 100%)\",\n borderRadius: \"4px\",\n boxShadow:\n \"inset 0 1px 3px rgba(0, 0, 0, 0.2)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: `${(isMuted ? 0 : volume) * 100}%`,\n background:\n \"linear-gradient(180deg, rgba(96, 165, 250, 1) 0%, rgba(59, 130, 246, 0.95) 50%, rgba(37, 99, 235, 0.9) 100%)\",\n borderRadius: \"4px\",\n transition:\n \"height 0.15s ease-out, box-shadow 0.2s ease-in-out\",\n boxShadow:\n \"0 0 8px rgba(59, 130, 246, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: `calc(${\n (isMuted ? 0 : volume) * 100\n }% - 7px)`,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"14px\",\n height: \"14px\",\n background:\n \"linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)\",\n borderRadius: \"50%\",\n boxShadow:\n \"0 2px 6px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(59, 130, 246, 0.3), 0 0 12px rgba(59, 130, 246, 0.4)\",\n transition:\n \"bottom 0.15s ease-out, transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, width 0.2s ease-in-out, height 0.2s ease-in-out\",\n cursor: \"grab\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.boxShadow =\n \"0 3px 10px rgba(0, 0, 0, 0.4), 0 0 0 3px rgba(59, 130, 246, 0.5), 0 0 20px rgba(59, 130, 246, 0.6)\";\n e.currentTarget.style.cursor = \"grab\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.boxShadow =\n \"0 2px 6px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(59, 130, 246, 0.3), 0 0 12px rgba(59, 130, 246, 0.4)\";\n }}\n onMouseDown={(e) => {\n e.currentTarget.style.cursor = \"grabbing\";\n }}\n onMouseUp={(e) => {\n e.currentTarget.style.cursor = \"grab\";\n }}\n />\n </div>\n </div>\n </>\n )}\n </div>\n\n <div\n style={{\n fontSize: `${14 * responsiveScale}px`,\n fontFamily: \"monospace\",\n color: \"rgba(255, 255, 255, 0.9)\",\n display: viewportWidth < 480 ? \"none\" : \"block\",\n }}\n >\n {formatTime(currentTime)} / {formatTime(duration)}\n </div>\n </div>\n\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: `${12 * responsiveScale}px`,\n }}\n >\n <div\n style={{\n position: \"relative\",\n display: viewportWidth < 600 ? \"none\" : \"block\",\n }}\n >\n <button\n onClick={() => setShowSpeedMenu(!showSpeedMenu)}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${\n 2 * responsiveScale\n }px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px ${\n 14 * responsiveScale\n }px`,\n borderRadius: `${14 * responsiveScale}px`,\n fontSize: `${14 * responsiveScale}px`,\n fontFamily: \"monospace\",\n fontWeight: \"700\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow:\n \"0 6px 24px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${56 * responsiveScale}px`,\n minHeight: `${40 * responsiveScale}px`,\n }}\n onMouseEnter={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow =\n \"0 10px 32px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n }}\n onMouseLeave={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow =\n \"0 6px 24px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n }}\n title=\"Playback Speed\"\n >\n {playbackRate}x\n </button>\n\n {showSpeedMenu && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n right: 0,\n marginBottom: \"12px\",\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.95) 100%)\",\n backdropFilter: \"blur(20px)\",\n borderRadius: \"12px\",\n border: \"1px solid rgba(255, 255, 255, 0.1)\",\n overflow: \"hidden\",\n minWidth: \"90px\",\n boxShadow:\n \"0 16px 48px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.1)\",\n }}\n >\n {[0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2].map(\n (speed) => (\n <button\n key={speed}\n onClick={() =>\n handlePlaybackRateChange(speed)\n }\n style={{\n display: \"block\",\n width: \"100%\",\n padding: \"10px 16px\",\n background:\n playbackRate === speed\n ? \"linear-gradient(135deg, rgba(99, 102, 241, 0.8) 0%, rgba(139, 92, 246, 0.6) 100%)\"\n : \"transparent\",\n border: \"none\",\n color: \"white\",\n cursor: \"pointer\",\n fontSize: \"13px\",\n fontFamily: \"monospace\",\n fontWeight: \"600\",\n textAlign: \"center\",\n transition:\n \"all 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n borderBottom:\n speed !== 2\n ? \"1px solid rgba(255, 255, 255, 0.05)\"\n : \"none\",\n }}\n onMouseEnter={(e) => {\n if (playbackRate !== speed) {\n (\n e.target as HTMLElement\n ).style.background =\n \"linear-gradient(135deg, rgba(255, 255, 255, 0.15) 0%, rgba(255, 255, 255, 0.05) 100%)\";\n }\n }}\n onMouseLeave={(e) => {\n if (playbackRate !== speed) {\n (\n e.target as HTMLElement\n ).style.background = \"transparent\";\n }\n }}\n >\n {speed}x\n </button>\n )\n )}\n </div>\n )}\n </div>\n\n <button\n onClick={() => {\n if (onFullscreenToggle) {\n onFullscreenToggle();\n } else if (playerRef.current) {\n playerRef.current\n .toggleFullscreen()\n .catch((err) => {\n console.error(\"Fullscreen error:\", err);\n });\n }\n }}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${\n 2 * responsiveScale\n }px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow:\n \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${44 * responsiveScale}px`,\n minHeight: `${44 * responsiveScale}px`,\n }}\n onMouseEnter={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow =\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n }}\n onMouseLeave={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow =\n \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n }}\n title={\n isFullscreen ? \"Exit Fullscreen\" : \"Enter Fullscreen\"\n }\n >\n {isFullscreen ? (\n <FaCompress\n size={Math.max(14, 16 * responsiveScale)}\n style={{ filter: \"drop-shadow(0 0 0 transparent)\" }}\n />\n ) : (\n <FaExpand\n size={Math.max(14, 16 * responsiveScale)}\n style={{ filter: \"drop-shadow(0 0 0 transparent)\" }}\n />\n )}\n </button>\n </div>\n </div>\n </div>\n </>\n ) : (\n showCustomControls &&\n !showLicenseWarning && (\n <div\n style={{\n position: \"absolute\",\n bottom: `${10 * responsiveScale}px`,\n right: `${10 * responsiveScale}px`,\n transform: \"none\",\n display: \"flex\",\n flexDirection: isPortrait ? \"column\" : \"row\",\n gap: `${10 * responsiveScale}px`,\n zIndex: 10,\n }}\n >\n <div\n style={{\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n padding: \"8px\",\n margin: \"-8px\",\n }}\n onMouseEnter={() => setShowVolumeSlider(true)}\n onMouseLeave={() => setShowVolumeSlider(false)}\n >\n <button\n onClick={() => {\n if (playerRef.current) {\n playerRef.current.toggleMute();\n }\n if (onVolumeToggle) {\n onVolumeToggle();\n }\n }}\n onMouseEnter={(e) => {\n const target = e.currentTarget as HTMLButtonElement;\n target.style.boxShadow =\n \"0 14px 48px rgba(0, 0, 0, 0.7), 0 0 0 3px rgba(255, 255, 255, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n }}\n onMouseLeave={(e) => {\n const target = e.currentTarget as HTMLButtonElement;\n target.style.boxShadow =\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n }}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n color: \"#ffffff\",\n border: \"none\",\n borderRadius: `${18 * responsiveScale}px`,\n padding: `${8 * responsiveScale}px`,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n boxShadow:\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.4s cubic-bezier(0.4, 0, 0.2, 1)\",\n minWidth: `${46 * responsiveScale}px`,\n minHeight: `${46 * responsiveScale}px`,\n }}\n title={isMuted ? \"Unmute\" : \"Mute\"}\n >\n {isMuted || volume === 0 ? (\n <FaVolumeMute\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\",\n }}\n />\n ) : volume < 0.5 ? (\n <FaVolumeDown\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\",\n }}\n />\n ) : (\n <FaVolumeUp\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\",\n }}\n />\n )}\n </button>\n\n {showVolumeSlider && (\n <>\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"60px\",\n height: \"20px\",\n marginBottom: \"-16px\",\n zIndex: 9,\n }}\n onMouseEnter={() => setShowVolumeSlider(true)}\n onMouseLeave={() => setShowVolumeSlider(false)}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: \"4px\",\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.96) 0%, rgba(20, 20, 20, 0.92) 100%)\",\n backdropFilter: \"blur(20px)\",\n padding: \"10px 14px\",\n borderRadius: \"14px\",\n border: \"2px solid rgba(255, 255, 255, 0.7)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"128px\",\n boxShadow:\n \"0 12px 40px rgba(0, 0, 0, 0.85), 0 4px 12px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.35)\",\n zIndex: 10,\n transition:\n \"transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, border-color 0.2s ease-in-out\",\n }}\n onMouseEnter={(e) => {\n setShowVolumeSlider(true);\n e.currentTarget.style.boxShadow =\n \"0 16px 48px rgba(0, 0, 0, 0.9), 0 6px 16px rgba(0, 0, 0, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 0 24px rgba(96, 165, 250, 0.4)\";\n e.currentTarget.style.borderColor =\n \"rgba(96, 165, 250, 0.8)\";\n }}\n onMouseLeave={(e) => {\n setShowVolumeSlider(false);\n e.currentTarget.style.boxShadow =\n \"0 12px 40px rgba(0, 0, 0, 0.85), 0 4px 12px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.35)\";\n e.currentTarget.style.borderColor =\n \"rgba(255, 255, 255, 0.7)\";\n }}\n >\n <div\n style={{\n position: \"relative\",\n width: \"8px\",\n height: \"104px\",\n cursor: \"pointer\",\n transition: \"transform 0.2s ease-in-out\",\n }}\n onMouseDown={(e) => {\n e.preventDefault();\n const sliderElement = e.currentTarget;\n\n const handleMouseMove = (\n moveEvent: MouseEvent\n ) => {\n if (!sliderElement) return;\n const rect =\n sliderElement.getBoundingClientRect();\n const y = moveEvent.clientY - rect.top;\n const percentage =\n 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n };\n\n const handleMouseUp = () => {\n document.removeEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.removeEventListener(\n \"mouseup\",\n handleMouseUp\n );\n };\n\n document.addEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.addEventListener(\n \"mouseup\",\n handleMouseUp\n );\n\n const rect =\n sliderElement.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage =\n 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n }}\n onClick={(e) => {\n e.stopPropagation();\n const rect =\n e.currentTarget.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage =\n 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n }}\n >\n <div\n style={{\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: \"100%\",\n background:\n \"linear-gradient(180deg, rgba(255, 255, 255, 0.85) 0%, rgba(255, 255, 255, 0.5) 100%)\",\n borderRadius: \"4px\",\n border: \"1px solid rgba(255, 255, 255, 0.4)\",\n boxShadow: \"inset 0 1px 3px rgba(0, 0, 0, 0.3)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: `${(isMuted ? 0 : volume) * 100}%`,\n background:\n \"linear-gradient(180deg, rgba(125, 211, 252, 1) 0%, rgba(96, 165, 250, 0.98) 50%, rgba(59, 130, 246, 0.95) 100%)\",\n borderRadius: \"4px\",\n transition:\n \"height 0.15s ease-out, box-shadow 0.2s ease-in-out\",\n boxShadow:\n \"0 0 12px rgba(96, 165, 250, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.4)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: `calc(${\n (isMuted ? 0 : volume) * 100\n }% - 8px)`,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"16px\",\n height: \"16px\",\n background:\n \"linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)\",\n borderRadius: \"50%\",\n border: \"2px solid rgba(96, 165, 250, 0.9)\",\n boxShadow:\n \"0 3px 8px rgba(0, 0, 0, 0.5), 0 0 0 2px rgba(96, 165, 250, 0.4), 0 0 16px rgba(96, 165, 250, 0.5)\",\n transition:\n \"bottom 0.15s ease-out, transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, width 0.2s ease-in-out, height 0.2s ease-in-out\",\n cursor: \"grab\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.boxShadow =\n \"0 4px 12px rgba(0, 0, 0, 0.6), 0 0 0 3px rgba(96, 165, 250, 0.6), 0 0 24px rgba(96, 165, 250, 0.7)\";\n e.currentTarget.style.cursor = \"grab\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.boxShadow =\n \"0 3px 8px rgba(0, 0, 0, 0.5), 0 0 0 2px rgba(96, 165, 250, 0.4), 0 0 16px rgba(96, 165, 250, 0.5)\";\n }}\n onMouseDown={(e) => {\n e.currentTarget.style.cursor = \"grabbing\";\n }}\n onMouseUp={(e) => {\n e.currentTarget.style.cursor = \"grab\";\n }}\n />\n </div>\n </div>\n </>\n )}\n </div>\n\n <button\n onClick={() => {\n if (onFullscreenToggle) {\n onFullscreenToggle();\n } else if (playerRef.current) {\n playerRef.current.toggleFullscreen().catch((err) => {\n console.error(\"Fullscreen error:\", err);\n });\n }\n }}\n onMouseEnter={(e) => {\n const target = e.currentTarget as HTMLButtonElement;\n target.style.boxShadow =\n \"0 14px 48px rgba(0, 0, 0, 0.7), 0 0 0 3px rgba(255, 255, 255, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n }}\n onMouseLeave={(e) => {\n const target = e.currentTarget as HTMLButtonElement;\n target.style.boxShadow =\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n }}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n color: \"#ffffff\",\n border: \"none\",\n borderRadius: `${18 * responsiveScale}px`,\n padding: `${8 * responsiveScale}px`,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n boxShadow:\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.4s cubic-bezier(0.4, 0, 0.2, 1)\",\n minWidth: `${46 * responsiveScale}px`,\n minHeight: `${46 * responsiveScale}px`,\n }}\n title={\n isFullscreen ? \"Exit Fullscreen\" : \"Enter Fullscreen\"\n }\n >\n {isFullscreen ? (\n <FaCompress\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\",\n }}\n />\n ) : (\n <FaExpand\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\",\n }}\n />\n )}\n </button>\n </div>\n )\n )}\n\n {onControlClick && (\n <div\n onClick={onControlClick}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 1,\n cursor: \"pointer\",\n }}\n />\n )}\n </div>\n </>\n );\n },\n (prevProps, nextProps) => {\n for (const prop of CRITICAL_PROPS) {\n if ((prevProps as any)[prop] !== (nextProps as any)[prop]) {\n return false;\n }\n }\n\n const uiProps = [\n \"autoplay\",\n \"muted\",\n \"controls\",\n \"showCustomControls\",\n \"className\",\n \"style\",\n \"wrapperClassName\",\n \"wrapperStyle\",\n \"playsInline\",\n \"preload\",\n \"poster\",\n \"children\",\n ] as const;\n\n for (const prop of uiProps) {\n if ((prevProps as any)[prop] !== (nextProps as any)[prop]) {\n return false;\n }\n }\n\n const callbackProps = [\n \"onReady\",\n \"onVolumeToggle\",\n \"onFullscreenToggle\",\n \"onControlClick\",\n ] as const;\n for (const prop of callbackProps) {\n if ((prevProps as any)[prop] !== (nextProps as any)[prop]) {\n return false;\n }\n }\n\n return true;\n }\n );\n","import Hls from \"hls.js\";\nimport type {\n StormcloudVideoPlayerConfig,\n Scte35Marker,\n Id3TagInfo,\n} from \"../types\";\nimport type { PrebidBidResponse } from \"../types\";\nimport { createPrebidManager } from \"../sdk/prebid\";\nimport { createPrebidAdLayer } from \"../sdk/prebidAdLayer\";\nimport type { PrebidAdLayer } from \"../sdk/prebidAdLayer\";\nimport {\n sendInitialTracking,\n sendHeartbeat,\n sendAdDetectTracking,\n sendAdLoadedTracking,\n sendAdImpressionTracking,\n} from \"../utils/tracking\";\nimport { initializePolyfills } from \"../utils/polyfills\";\nimport { logBrowserInfo, getBrowserConfigOverrides, detectBrowser } from \"../utils/browserCompat\";\n\nexport class StormcloudVideoPlayer {\n private readonly video: HTMLVideoElement;\n private readonly config: StormcloudVideoPlayerConfig;\n private hls?: Hls;\n private prebidManager: ReturnType<typeof createPrebidManager>;\n private adLayer: PrebidAdLayer;\n private pendingNextAdBids: PrebidBidResponse[] | null = null;\n private continuousFetchLoopPromise: Promise<void> | null = null;\n private attached = false;\n private inAdBreak = false;\n private currentAdBreakStartWallClockMs: number | undefined;\n private expectedAdBreakDurationMs: number | undefined;\n private adStopTimerId: number | undefined;\n private adStartTimerId: number | undefined;\n private adFailsafeTimerId: number | undefined;\n private ptsDriftEmaMs = 0;\n private adPodQueue: string[] = [];\n private lastHeartbeatTime: number = 0;\n private heartbeatInterval: number | undefined;\n private currentAdIndex: number = 0;\n private totalAdsInBreak: number = 0;\n private showAds: boolean = false;\n private isLiveStream: boolean = false;\n private nativeHlsMode: boolean = false;\n private videoSrcProtection: string | null = null;\n private bufferedSegmentsCount: number = 0;\n private shouldAutoplayAfterBuffering: boolean = false;\n private hasInitialBufferCompleted: boolean = false;\n private activeAdRequestToken: number | null = null;\n private adRequestWatchdogId: number | undefined;\n private adRequestWatchdogToken: number | null = null;\n private adFailsafeToken: number | null = null;\n private continuousFetchingActive: boolean = false;\n private maxPlaceholderDurationMs: number = 5000;\n private isShowingPlaceholder: boolean = false;\n private timeUpdateHandler?: (event: Event) => void;\n private emptiedHandler?: (event: Event) => void;\n \n private totalAdRequestsInBreak: number = 0;\n private readonly maxTotalAdRequestsPerBreak: number = 20;\n \n private pendingAdBreak: {\n marker: Scte35Marker;\n detectedAtFragmentSn?: number;\n isFetching: boolean;\n fetchStartTime?: number;\n } | null = null;\n private prefetchTimerId: number | undefined;\n private savedMutedStateBeforeScte: { muted: boolean; volume: number } | null = null;\n\n private consecutiveFailures: number = 0;\n private readonly maxConsecutiveFailures: number = 5;\n private lastAdRequestTime: number = 0;\n private readonly minAdRequestIntervalMs: number = 2500;\n private readonly backoffBaseMs: number = 1000;\n private readonly maxBackoffMs: number = 15000;\n private readonly adTransitionGapMs: number = 1500;\n private placeholderContainer: HTMLDivElement | undefined;\n\n constructor(config: StormcloudVideoPlayerConfig) {\n initializePolyfills();\n\n const browserOverrides = getBrowserConfigOverrides();\n \n this.config = { ...browserOverrides, ...config };\n this.video = config.videoElement;\n\n logBrowserInfo(config.debugAdTiming);\n\n this.prebidManager = createPrebidManager(\n config.debugAdTiming !== undefined ? { debug: !!config.debugAdTiming } : {}\n );\n this.adLayer = createPrebidAdLayer(this.video, {\n continueLiveStreamDuringAds: false,\n debug: !!config.debugAdTiming,\n });\n }\n\n private async adRequest(): Promise<PrebidBidResponse[]> {\n await this.prebidManager.initialize();\n return this.prebidManager.requestBidsUntilResponse();\n }\n\n async load(): Promise<void> {\n if (!this.attached) {\n this.attach();\n }\n\n this.initializeTracking();\n\n if (this.shouldUseNativeHls()) {\n this.nativeHlsMode = true;\n this.videoSrcProtection = this.config.src;\n this.video.src = this.config.src;\n\n this.isLiveStream = this.config.lowLatencyMode ?? false;\n\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Using native HLS playback - VOD mode:\",\n {\n isLive: this.isLiveStream,\n allowNativeHls: this.config.allowNativeHls,\n adBehavior: \"vod (main video pauses during ads)\",\n }\n );\n }\n\n this.adLayer.updateOptions({ continueLiveStreamDuringAds: false, mainHlsInstance: null });\n\n if (this.config.autoplay) {\n await this.video.play()?.catch(() => {});\n }\n return;\n }\n\n this.hls = new Hls({\n enableWorker: true,\n backBufferLength: 30,\n liveDurationInfinity: true,\n lowLatencyMode: !!this.config.lowLatencyMode,\n maxLiveSyncPlaybackRate: this.config.lowLatencyMode ? 1.5 : 1.0,\n ...(this.config.lowLatencyMode ? { liveSyncDuration: 2 } : {}),\n maxBufferLength: 30,\n maxMaxBufferLength: 600,\n maxBufferSize: 60 * 1000 * 1000,\n maxBufferHole: 0.5,\n highBufferWatchdogPeriod: 2,\n nudgeOffset: 0.1,\n nudgeMaxRetry: 3,\n startPosition: -1,\n });\n\n this.hls.on(Hls.Events.MEDIA_ATTACHED, () => {\n this.hls?.loadSource(this.config.src);\n });\n\n this.hls.on(Hls.Events.MANIFEST_PARSED, async (_, data: any) => {\n if (this.config.allowNativeHls === false) {\n this.isLiveStream = true;\n } else {\n this.isLiveStream =\n this.hls?.levels?.some(\n (level) =>\n level?.details?.live === true || level?.details?.type === \"LIVE\"\n ) ?? false;\n }\n\n if (this.config.debugAdTiming) {\n const adBehavior = this.shouldContinueLiveStreamDuringAds()\n ? \"live (main video continues muted during ads)\"\n : \"vod (main video pauses during ads)\";\n console.log(\"[StormcloudVideoPlayer] Stream type detected:\", {\n isLive: this.isLiveStream,\n allowNativeHls: this.config.allowNativeHls,\n adBehavior,\n });\n }\n\n this.adLayer.updateOptions({\n continueLiveStreamDuringAds: this.shouldContinueLiveStreamDuringAds(),\n mainHlsInstance: this.hls ?? null,\n });\n\n this.bufferedSegmentsCount = 0;\n this.hasInitialBufferCompleted = false;\n this.shouldAutoplayAfterBuffering = !!this.config.autoplay;\n\n const minSegments = this.config.minSegmentsBeforePlay ?? 2;\n\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Waiting for\",\n minSegments,\n \"segments to buffer before playback\"\n );\n }\n\n if (minSegments === 0 || !this.config.autoplay) {\n this.hasInitialBufferCompleted = true;\n if (this.config.autoplay) {\n await this.video.play()?.catch(() => {});\n }\n }\n });\n\n this.hls.on(Hls.Events.LEVEL_LOADED, (_evt, data: any) => {\n if (this.inAdBreak || this.pendingAdBreak) {\n return;\n }\n\n const details = data?.details;\n if (!details || !details.fragments || details.fragments.length === 0) {\n return;\n }\n\n const fragmentsToScan = Math.min(5, details.fragments.length);\n \n for (let i = 0; i < fragmentsToScan; i++) {\n const frag = details.fragments[i];\n const tagList: any[] | undefined = frag?.tagList;\n \n if (!Array.isArray(tagList)) continue;\n\n for (const entry of tagList) {\n let tag = \"\";\n let value = \"\";\n \n if (Array.isArray(entry)) {\n tag = String(entry[0] ?? \"\");\n value = String(entry[1] ?? \"\");\n } else if (typeof entry === \"string\") {\n const idx = entry.indexOf(\":\");\n if (idx >= 0) {\n tag = entry.substring(0, idx);\n value = entry.substring(idx + 1);\n } else {\n tag = entry;\n }\n }\n\n if (!tag) continue;\n\n if (tag.includes(\"EXT-X-CUE-OUT\") || tag.includes(\"EXT-X-DATERANGE\")) {\n const attrs = tag.includes(\"EXT-X-DATERANGE\") \n ? this.parseAttributeList(value)\n : {};\n const hasScteOut = tag.includes(\"EXT-X-CUE-OUT\") || \n \"SCTE35-OUT\" in attrs || \n attrs[\"SCTE35-OUT\"] !== undefined;\n\n if (hasScteOut) {\n const durationSeconds = this.parseCueOutDuration(value);\n const marker: Scte35Marker = {\n type: \"start\",\n ...(durationSeconds !== undefined ? { durationSeconds } : {}),\n raw: { tag, value, earlyDetection: true },\n } as Scte35Marker;\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] 🎯 EARLY SCTE-35 DETECTION: Ad break marker found in fragment\", i, \"- starting pre-fetch (NOT playing yet)\");\n }\n\n this.startAdPrefetch(marker, frag?.sn);\n return;\n }\n }\n }\n }\n });\n\n this.hls.on(Hls.Events.FRAG_BUFFERED, async (_evt, data: any) => {\n if (this.hasInitialBufferCompleted) {\n return;\n }\n\n this.bufferedSegmentsCount++;\n const minSegments = this.config.minSegmentsBeforePlay ?? 2;\n\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Buffered segment ${this.bufferedSegmentsCount}/${minSegments}`\n );\n }\n\n if (this.bufferedSegmentsCount >= minSegments) {\n this.hasInitialBufferCompleted = true;\n\n if (this.shouldAutoplayAfterBuffering) {\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Initial buffer complete (${this.bufferedSegmentsCount} segments). Starting playback.`\n );\n }\n await this.video.play()?.catch((err) => {\n if (this.config.debugAdTiming) {\n console.warn(\"[StormcloudVideoPlayer] Autoplay failed:\", err);\n }\n });\n }\n }\n });\n\n this.hls.on(Hls.Events.FRAG_PARSING_METADATA, (_evt, data: any) => {\n const id3Tags: Id3TagInfo[] = (data?.samples || []).map((s: any) => ({\n key: \"ID3\",\n value: s?.data,\n ptsSeconds: s?.pts,\n }));\n id3Tags.forEach((tag) => this.onId3Tag(tag));\n });\n\n this.hls.on(Hls.Events.FRAG_CHANGED, (_evt, data: any) => {\n const frag = data?.frag;\n const tagList: any[] | undefined = frag?.tagList;\n if (!Array.isArray(tagList)) return;\n\n for (const entry of tagList) {\n let tag = \"\";\n let value = \"\";\n if (Array.isArray(entry)) {\n tag = String(entry[0] ?? \"\");\n value = String(entry[1] ?? \"\");\n } else if (typeof entry === \"string\") {\n const idx = entry.indexOf(\":\");\n if (idx >= 0) {\n tag = entry.substring(0, idx);\n value = entry.substring(idx + 1);\n } else {\n tag = entry;\n value = \"\";\n }\n }\n\n if (!tag) continue;\n if (tag.includes(\"EXT-X-CUE-OUT-CONT\")) {\n const prog = this.parseCueOutCont(value);\n const marker: Scte35Marker = {\n type: \"progress\",\n ...(prog?.duration !== undefined\n ? { durationSeconds: prog.duration }\n : {}),\n ...(prog?.elapsed !== undefined\n ? { ptsSeconds: prog.elapsed }\n : {}),\n raw: { tag, value },\n } as Scte35Marker;\n this.onScte35Marker(marker);\n } else if (tag.includes(\"EXT-X-CUE-OUT\")) {\n const durationSeconds = this.parseCueOutDuration(value);\n const marker: Scte35Marker = {\n type: \"start\",\n ...(durationSeconds !== undefined ? { durationSeconds } : {}),\n raw: { tag, value },\n } as Scte35Marker;\n this.onScte35Marker(marker);\n } else if (tag.includes(\"EXT-X-CUE-IN\")) {\n this.onScte35Marker({ type: \"end\", raw: { tag, value } });\n } else if (tag.includes(\"EXT-X-DATERANGE\")) {\n const attrs = this.parseAttributeList(value);\n const hasScteOut =\n \"SCTE35-OUT\" in attrs || attrs[\"SCTE35-OUT\"] !== undefined;\n const hasScteIn =\n \"SCTE35-IN\" in attrs || attrs[\"SCTE35-IN\"] !== undefined;\n const klass = String(attrs[\"CLASS\"] ?? \"\");\n const duration = this.toNumber(attrs[\"DURATION\"]);\n\n if (hasScteOut || /com\\.apple\\.hls\\.cue/i.test(klass)) {\n const marker: Scte35Marker = {\n type: \"start\",\n ...(duration !== undefined ? { durationSeconds: duration } : {}),\n raw: { tag, value, attrs },\n } as Scte35Marker;\n this.onScte35Marker(marker);\n }\n if (hasScteIn) {\n this.onScte35Marker({ type: \"end\", raw: { tag, value, attrs } });\n }\n }\n }\n });\n\n this.hls.on(Hls.Events.ERROR, (_evt, data) => {\n if (data?.fatal) {\n switch (data.type) {\n case Hls.ErrorTypes.NETWORK_ERROR:\n this.hls?.startLoad();\n break;\n case Hls.ErrorTypes.MEDIA_ERROR:\n this.hls?.recoverMediaError();\n break;\n default:\n this.destroy();\n break;\n }\n }\n });\n\n this.hls.attachMedia(this.video);\n }\n\n private getAdSource(): \"prebid\" {\n return \"prebid\";\n }\n\n private attachAdLayerEventListeners(): void {\n this.adLayer.on(\"ad_impression\", () => {\n if (this.config.licenseKey) {\n sendAdImpressionTracking(this.config.licenseKey, {\n source: this.getAdSource(),\n adIndex: this.currentAdIndex,\n timestamp: new Date().toISOString(),\n });\n }\n });\n this.adLayer.on(\"ad_error\", (errorPayload?: any) => {\n let errorMessage = \"Ad playback failed\";\n \n if (errorPayload) {\n const errorCode = errorPayload.code || errorPayload.errorCode || \"unknown\";\n const vastErrorCode = errorPayload.vastErrorCode;\n const message = errorPayload.message || errorPayload.errorMessage || \"Unknown error\";\n const cause = errorPayload.cause || errorPayload.innerError || errorPayload.error;\n \n errorMessage = `Ad error: AdError ${errorCode}: ${message}`;\n \n if (vastErrorCode && vastErrorCode !== \"N/A\" && vastErrorCode !== errorCode) {\n errorMessage += ` (VAST Error Code: ${vastErrorCode})`;\n }\n \n if (cause) {\n const causeMessage = typeof cause === \"string\" ? cause : (cause.message || String(cause));\n errorMessage += `. Caused by: ${causeMessage}`;\n }\n }\n \n console.error(\"[AD-ERROR]\", errorMessage, errorPayload || \"\");\n this.adLayer.stop().catch(() => {});\n this.handleAdFailure();\n });\n this.adLayer.on(\"content_pause\", () => {\n this.clearAdFailsafeTimer();\n this.clearAdRequestWatchdog();\n this.activeAdRequestToken = null;\n this.showAds = true;\n \n if (this.inAdBreak && this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {\n this.scheduleAdStopCountdown(this.getRemainingAdMs());\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Starting ad break timer on content_pause (first ad starting)\");\n }\n }\n\n this.adLayer.setAdVolume(\n this.adLayer.getOriginalMutedState() ? 1 : this.adLayer.getOriginalVolume()\n );\n\n if (this.isShowingPlaceholder) {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Hiding placeholder - new ads starting\");\n }\n this.hidePlaceholderLayer();\n this.adLayer.hidePlaceholder();\n this.isShowingPlaceholder = false;\n }\n });\n this.adLayer.on(\"content_resume\", () => {\n const remaining = this.getRemainingAdMs();\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] content_resume received, inAdBreak=%s, remaining=%s, pendingNext=%s\",\n this.inAdBreak,\n remaining,\n !!this.pendingNextAdBids\n );\n }\n\n this.clearAdFailsafeTimer();\n this.clearAdRequestWatchdog();\n this.activeAdRequestToken = null;\n this.showAds = false;\n\n if (!this.inAdBreak) {\n const restoredMuted = this.adLayer.getOriginalMutedState();\n const restoredVolume = this.adLayer.getOriginalVolume();\n if (this.video.muted !== restoredMuted) this.video.muted = restoredMuted;\n if (Math.abs(this.video.volume - restoredVolume) > 0.01) this.video.volume = restoredVolume;\n return;\n }\n\n this.consecutiveFailures = 0;\n\n if (this.pendingNextAdBids && this.pendingNextAdBids.length > 0) {\n const bids = [...this.pendingNextAdBids];\n this.pendingNextAdBids = null;\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n }\n this.showPlaceholderLayer();\n this.adLayer.showPlaceholder();\n setTimeout(() => {\n if (!this.inAdBreak || bids.length === 0) return;\n this.currentAdIndex++;\n this.adLayer.playAd(bids).catch((err) => {\n if (this.config.debugAdTiming) console.warn(\"[StormcloudVideoPlayer] playAd(pending) failed:\", err);\n this.handleAdFailure();\n });\n }, this.adTransitionGapMs);\n return;\n }\n\n if (remaining <= 500 && this.expectedAdBreakDurationMs != null) {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] content_resume: remaining time low and duration known, ending ad pod\");\n }\n this.handleAdPodComplete();\n } else {\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n }\n }\n });\n }\n\n private ensurePlaceholderContainer(): void {\n if (this.placeholderContainer) {\n return;\n }\n\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 = \"5\";\n container.style.backgroundColor = \"#000\";\n container.style.transition = \"opacity 0.3s ease-in-out\";\n container.style.opacity = \"0\";\n\n if (!this.video.parentElement) {\n if (this.config.debugAdTiming) {\n console.warn(\"[StormcloudVideoPlayer] Video element has no parent for placeholder container\");\n }\n return;\n }\n\n this.video.parentElement.appendChild(container);\n this.placeholderContainer = container;\n }\n\n private showPlaceholderLayer(): void {\n this.ensurePlaceholderContainer();\n \n if (!this.placeholderContainer) {\n return;\n }\n\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Muted video when showing placeholder\");\n }\n }\n\n const wasHidden = this.placeholderContainer.style.display === \"none\" || this.placeholderContainer.style.opacity === \"0\";\n if (wasHidden) {\n this.placeholderContainer.style.transition = \"none\";\n } else {\n this.placeholderContainer.style.transition = \"opacity 0.3s ease-in-out\";\n }\n \n this.placeholderContainer.style.backgroundColor = \"#000\";\n this.placeholderContainer.style.display = \"flex\";\n this.placeholderContainer.offsetHeight;\n this.placeholderContainer.style.opacity = \"1\";\n this.placeholderContainer.style.pointerEvents = \"auto\";\n \n if (wasHidden) {\n requestAnimationFrame(() => {\n if (this.placeholderContainer) {\n this.placeholderContainer.style.transition = \"opacity 0.3s ease-in-out\";\n }\n });\n }\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Showing placeholder layer\");\n }\n }\n\n private hidePlaceholderLayer(): void {\n if (!this.placeholderContainer) {\n return;\n }\n\n this.placeholderContainer.style.opacity = \"0\";\n setTimeout(() => {\n if (this.placeholderContainer) {\n this.placeholderContainer.style.display = \"none\";\n this.placeholderContainer.style.pointerEvents = \"none\";\n this.placeholderContainer.style.backgroundColor = \"#000\";\n }\n }, 300);\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Hiding placeholder layer\");\n }\n }\n\n private attach(): void {\n if (this.attached) return;\n this.attached = true;\n this.video.autoplay = !!this.config.autoplay;\n this.video.muted = !!this.config.muted;\n\n this.adLayer.initialize();\n this.adLayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n this.attachAdLayerEventListeners();\n\n this.timeUpdateHandler = () => {\n this.onTimeUpdate(this.video.currentTime);\n };\n this.video.addEventListener(\"timeupdate\", this.timeUpdateHandler);\n\n this.emptiedHandler = () => {\n if (\n this.nativeHlsMode &&\n this.videoSrcProtection &&\n !this.adLayer.isAdPlaying()\n ) {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Video src was cleared, restoring:\",\n this.videoSrcProtection\n );\n }\n const currentTime = this.video.currentTime;\n const wasPaused = this.video.paused;\n this.video.src = this.videoSrcProtection;\n this.video.currentTime = currentTime;\n if (!wasPaused) {\n this.video.play().catch(() => {});\n }\n }\n };\n this.video.addEventListener(\"emptied\", this.emptiedHandler);\n }\n\n private shouldUseNativeHls(): boolean {\n const streamType = this.getStreamType();\n\n if (streamType === \"other\") {\n return true;\n }\n\n const canNative = this.video.canPlayType(\"application/vnd.apple.mpegurl\");\n return !!(this.config.allowNativeHls && canNative);\n }\n\n private onId3Tag(tag: Id3TagInfo): void {\n if (typeof tag.ptsSeconds === \"number\") {\n this.updatePtsDrift(tag.ptsSeconds);\n }\n const marker = this.parseScte35FromId3(tag);\n if (marker) {\n this.onScte35Marker(marker);\n }\n }\n\n private parseScte35FromId3(tag: Id3TagInfo): Scte35Marker | undefined {\n const text = this.decodeId3ValueToText(tag.value);\n if (!text) return undefined;\n\n const cueOutMatch =\n text.match(/EXT-X-CUE-OUT(?::([^\\r\\n]*))?/i) ||\n text.match(/CUE-OUT(?::([^\\r\\n]*))?/i);\n if (cueOutMatch) {\n const arg = (cueOutMatch[1] ?? \"\").trim();\n const dur = this.parseCueOutDuration(arg);\n const marker: Scte35Marker = {\n type: \"start\",\n ...(tag.ptsSeconds !== undefined ? { ptsSeconds: tag.ptsSeconds } : {}),\n ...(dur !== undefined ? { durationSeconds: dur } : {}),\n raw: { id3: text },\n } as Scte35Marker;\n return marker;\n }\n\n const cueOutContMatch = text.match(/EXT-X-CUE-OUT-CONT:([^\\r\\n]*)/i);\n if (cueOutContMatch) {\n const arg = (cueOutContMatch[1] ?? \"\").trim();\n const cont = this.parseCueOutCont(arg);\n const marker: Scte35Marker = {\n type: \"progress\",\n ...(tag.ptsSeconds !== undefined ? { ptsSeconds: tag.ptsSeconds } : {}),\n ...(cont?.duration !== undefined\n ? { durationSeconds: cont.duration }\n : {}),\n raw: { id3: text },\n } as Scte35Marker;\n return marker;\n }\n\n const cueInMatch = text.match(/EXT-X-CUE-IN\\b/i) || text.match(/CUE-IN\\b/i);\n if (cueInMatch) {\n const marker: Scte35Marker = {\n type: \"end\",\n ...(tag.ptsSeconds !== undefined ? { ptsSeconds: tag.ptsSeconds } : {}),\n raw: { id3: text },\n } as Scte35Marker;\n return marker;\n }\n\n const daterangeMatch = text.match(/EXT-X-DATERANGE:([^\\r\\n]*)/i);\n if (daterangeMatch) {\n const attrs = this.parseAttributeList(daterangeMatch[1] ?? \"\");\n const hasScteOut =\n \"SCTE35-OUT\" in attrs || attrs[\"SCTE35-OUT\"] !== undefined;\n const hasScteIn =\n \"SCTE35-IN\" in attrs || attrs[\"SCTE35-IN\"] !== undefined;\n const klass = String(attrs[\"CLASS\"] ?? \"\");\n const duration = this.toNumber(attrs[\"DURATION\"]);\n if (hasScteOut || /com\\.apple\\.hls\\.cue/i.test(klass)) {\n const marker: Scte35Marker = {\n type: \"start\",\n ...(tag.ptsSeconds !== undefined\n ? { ptsSeconds: tag.ptsSeconds }\n : {}),\n ...(duration !== undefined ? { durationSeconds: duration } : {}),\n raw: { id3: text, attrs },\n } as Scte35Marker;\n return marker;\n }\n if (hasScteIn) {\n const marker: Scte35Marker = {\n type: \"end\",\n ...(tag.ptsSeconds !== undefined\n ? { ptsSeconds: tag.ptsSeconds }\n : {}),\n raw: { id3: text, attrs },\n } as Scte35Marker;\n return marker;\n }\n }\n\n if (/SCTE35-OUT/i.test(text)) {\n const marker: Scte35Marker = {\n type: \"start\",\n ...(tag.ptsSeconds !== undefined ? { ptsSeconds: tag.ptsSeconds } : {}),\n raw: { id3: text },\n } as Scte35Marker;\n return marker;\n }\n if (/SCTE35-IN/i.test(text)) {\n const marker: Scte35Marker = {\n type: \"end\",\n ...(tag.ptsSeconds !== undefined ? { ptsSeconds: tag.ptsSeconds } : {}),\n raw: { id3: text },\n } as Scte35Marker;\n return marker;\n }\n\n if (tag.value instanceof Uint8Array) {\n const bin = this.parseScte35Binary(tag.value);\n if (bin) return bin;\n }\n\n return undefined;\n }\n\n private decodeId3ValueToText(value: string | Uint8Array): string | undefined {\n try {\n if (typeof value === \"string\") return value;\n const decoder = new TextDecoder(\"utf-8\", { fatal: false });\n const text = decoder.decode(value);\n if (text && /[\\x20-\\x7E]/.test(text)) return text;\n let out = \"\";\n for (let i = 0; i < value.length; i++)\n out += String.fromCharCode(value[i]!);\n return out;\n } catch {\n return undefined;\n }\n }\n\n private onScte35Marker(marker: Scte35Marker): void {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] SCTE-35 marker detected:\", {\n type: marker.type,\n ptsSeconds: marker.ptsSeconds,\n durationSeconds: marker.durationSeconds,\n currentTime: this.video.currentTime,\n raw: marker.raw,\n hasPendingAdBreak: !!this.pendingAdBreak,\n });\n }\n\n if (marker.type === \"start\") {\n this.savedMutedStateBeforeScte = {\n muted: this.video.muted,\n volume: this.video.volume,\n };\n this.adLayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Muted video on SCTE start marker\");\n }\n }\n\n if (this.inAdBreak) {\n if (this.expectedAdBreakDurationMs == null && marker.durationSeconds != null) {\n this.expectedAdBreakDurationMs = marker.durationSeconds * 1000;\n if (this.config.debugAdTiming) {\n console.log(`[StormcloudVideoPlayer] Updated ad break duration from subsequent marker: ${this.expectedAdBreakDurationMs}ms`);\n }\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n return;\n }\n\n this.inAdBreak = true;\n const durationMs =\n marker.durationSeconds != null\n ? marker.durationSeconds * 1000\n : (this.pendingAdBreak?.marker.durationSeconds != null \n ? this.pendingAdBreak.marker.durationSeconds * 1000 \n : undefined);\n this.expectedAdBreakDurationMs = durationMs;\n this.currentAdBreakStartWallClockMs = Date.now();\n\n if (this.config.licenseKey) {\n const adDetectInfo = {\n source: \"scte35\" as const,\n timestamp: new Date().toISOString(),\n ...(marker.durationSeconds != null && { durationSeconds: marker.durationSeconds }),\n ...(marker.ptsSeconds != null && { ptsSeconds: marker.ptsSeconds }),\n ...(this.pendingAdBreak?.detectedAtFragmentSn != null && {\n detectedAtFragmentSn: this.pendingAdBreak.detectedAtFragmentSn,\n }),\n };\n sendAdDetectTracking(this.config.licenseKey, adDetectInfo);\n }\n\n const isManifestMarker = this.isManifestBasedMarker(marker);\n const forceImmediate = this.config.immediateManifestAds ?? true;\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Ad start decision:\", {\n isManifestMarker,\n forceImmediate,\n hasPts: typeof marker.ptsSeconds === \"number\",\n });\n }\n\n if (isManifestMarker && forceImmediate) {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Starting ad immediately (manifest-based)\"\n );\n }\n this.clearAdStartTimer();\n this.handleAdStart(marker);\n } else if (typeof marker.ptsSeconds === \"number\") {\n const tol = this.config.driftToleranceMs ?? 1000;\n const nowMs = this.video.currentTime * 1000;\n const estCurrentPtsMs = nowMs - this.ptsDriftEmaMs;\n const deltaMs = Math.floor(marker.ptsSeconds * 1000 - estCurrentPtsMs);\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] PTS-based timing calculation:\", {\n nowMs,\n estCurrentPtsMs,\n markerPtsMs: marker.ptsSeconds * 1000,\n deltaMs,\n tolerance: tol,\n });\n }\n\n if (deltaMs > tol) {\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Scheduling ad start in ${deltaMs}ms`\n );\n }\n this.scheduleAdStartIn(deltaMs);\n } else {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Starting ad immediately (within tolerance)\"\n );\n }\n this.clearAdStartTimer();\n this.handleAdStart(marker);\n }\n } else {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Starting ad immediately (fallback)\"\n );\n }\n this.clearAdStartTimer();\n this.handleAdStart(marker);\n }\n if (this.expectedAdBreakDurationMs != null) {\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n return;\n }\n if (marker.type === \"progress\" && this.inAdBreak) {\n if (marker.durationSeconds != null) {\n this.expectedAdBreakDurationMs = marker.durationSeconds * 1000;\n }\n if (\n this.expectedAdBreakDurationMs != null &&\n this.currentAdBreakStartWallClockMs != null\n ) {\n const elapsedMs = Date.now() - this.currentAdBreakStartWallClockMs;\n const remainingMs = Math.max(\n 0,\n this.expectedAdBreakDurationMs - elapsedMs\n );\n this.scheduleAdStopCountdown(remainingMs);\n }\n \n if (!this.adLayer.isAdPlaying() && this.pendingNextAdBids != null && this.pendingNextAdBids.length > 0) {\n const bids = this.pendingNextAdBids;\n this.pendingNextAdBids = null;\n this.currentAdIndex++;\n this.adLayer.playAd(bids).catch(() => this.handleAdFailure());\n }\n return;\n }\n if (marker.type === \"end\") {\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Muted video on SCTE end marker\");\n }\n }\n\n const remaining = this.getRemainingAdMs();\n const adPlaying = this.adLayer.isAdPlaying();\n const hasQueuedAds = this.pendingNextAdBids != null && this.pendingNextAdBids.length > 0;\n \n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] SCTE-35 end marker received:\", {\n remaining,\n adPlaying,\n hasQueuedAds,\n activeAdRequest: this.activeAdRequestToken !== null,\n });\n }\n \n if (adPlaying || remaining > 500) {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Ignoring premature SCTE-35 end marker - ads still active or time remaining\");\n }\n return;\n }\n \n this.inAdBreak = false;\n this.expectedAdBreakDurationMs = undefined;\n this.currentAdBreakStartWallClockMs = undefined;\n this.clearAdStartTimer();\n this.clearAdStopTimer();\n \n if (adPlaying) {\n this.adLayer.stop().catch(() => {});\n }\n \n this.handleAdPodComplete();\n return;\n }\n }\n\n private parseCueOutDuration(value: string): number | undefined {\n const num = parseFloat(value.trim());\n if (!Number.isNaN(num)) return num;\n const match =\n value.match(/(?:^|[,\\s])DURATION\\s*=\\s*([0-9.]+)/i) ||\n value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n if (match && match[1] != null) {\n const dStr = match[1];\n const d = parseFloat(dStr);\n return Number.isNaN(d) ? undefined : d;\n }\n return undefined;\n }\n\n private parseCueOutCont(\n value: string\n ): { elapsed?: number; duration?: number } | undefined {\n const res: { elapsed?: number; duration?: number } = {};\n \n const elapsedMatch = value.match(/Elapsed\\s*=\\s*([0-9.]+)/i);\n const durationMatch = value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n if (elapsedMatch && elapsedMatch[1] != null) {\n const e = parseFloat(elapsedMatch[1]);\n if (!Number.isNaN(e)) res.elapsed = e;\n }\n if (durationMatch && durationMatch[1] != null) {\n const d = parseFloat(durationMatch[1]);\n if (!Number.isNaN(d)) res.duration = d;\n }\n \n if (!(\"elapsed\" in res) || !(\"duration\" in res)) {\n const slashMatch = value.match(/([0-9.]+)\\s*\\/\\s*([0-9.]+)/);\n if (slashMatch && slashMatch[1] && slashMatch[2]) {\n const elapsed = parseFloat(slashMatch[1]);\n const duration = parseFloat(slashMatch[2]);\n if (!Number.isNaN(elapsed) && !(\"elapsed\" in res)) res.elapsed = elapsed;\n if (!Number.isNaN(duration) && !(\"duration\" in res)) res.duration = duration;\n }\n }\n \n if (\"elapsed\" in res || \"duration\" in res) return res;\n return undefined;\n }\n\n private parseAttributeList(value: string): Record<string, string> {\n const attrs: Record<string, string> = {};\n const regex = /([A-Z0-9-]+)=((\"[^\"]*\")|([^\",]*))(?:,|$)/gi;\n let match: RegExpExecArray | null;\n while ((match = regex.exec(value)) !== null) {\n const key: string = (match[1] ?? \"\") as string;\n let rawVal: string = (match[3] ?? match[4] ?? \"\") as string;\n if (rawVal.startsWith('\"') && rawVal.endsWith('\"')) {\n rawVal = rawVal.slice(1, -1);\n }\n if (key) {\n attrs[key] = rawVal;\n }\n }\n return attrs;\n }\n\n private toNumber(val: unknown): number | undefined {\n if (val == null) return undefined;\n const n = typeof val === \"string\" ? parseFloat(val) : Number(val);\n return Number.isNaN(n) ? undefined : n;\n }\n\n private isManifestBasedMarker(marker: Scte35Marker): boolean {\n const raw = marker.raw as any;\n if (!raw) return false;\n\n if (raw.tag) {\n const tag = String(raw.tag);\n return (\n tag.includes(\"EXT-X-CUE-OUT\") ||\n tag.includes(\"EXT-X-CUE-IN\") ||\n tag.includes(\"EXT-X-DATERANGE\")\n );\n }\n\n if (raw.id3) return false;\n\n if (raw.splice_command_type) return false;\n\n return false;\n }\n\n private parseScte35Binary(data: Uint8Array): Scte35Marker | undefined {\n class BitReader {\n private bytePos = 0;\n private bitPos = 0;\n constructor(private readonly buf: Uint8Array) {}\n readBits(numBits: number): number {\n let result = 0;\n while (numBits > 0) {\n if (this.bytePos >= this.buf.length) return result;\n const remainingInByte = 8 - this.bitPos;\n const toRead = Math.min(numBits, remainingInByte);\n const currentByte = this.buf[this.bytePos]!;\n const shift = remainingInByte - toRead;\n const mask = ((1 << toRead) - 1) & 0xff;\n const bits = (currentByte >> shift) & mask;\n result = (result << toRead) | bits;\n this.bitPos += toRead;\n if (this.bitPos >= 8) {\n this.bitPos = 0;\n this.bytePos += 1;\n }\n numBits -= toRead;\n }\n return result >>> 0;\n }\n skipBits(n: number): void {\n this.readBits(n);\n }\n }\n\n const r = new BitReader(data);\n const tableId = r.readBits(8);\n if (tableId !== 0xfc) return undefined;\n r.readBits(1);\n r.readBits(1);\n r.readBits(2);\n const sectionLength = r.readBits(12);\n r.readBits(8);\n r.readBits(1);\n r.readBits(6);\n const ptsAdjHigh = r.readBits(1);\n const ptsAdjLow = r.readBits(32);\n void ptsAdjHigh;\n void ptsAdjLow;\n r.readBits(8);\n r.readBits(12);\n const spliceCommandLength = r.readBits(12);\n const spliceCommandType = r.readBits(8);\n if (spliceCommandType !== 5) {\n return undefined;\n }\n r.readBits(32);\n const cancel = r.readBits(1) === 1;\n r.readBits(7);\n if (cancel) return undefined;\n const outOfNetwork = r.readBits(1) === 1;\n const programSpliceFlag = r.readBits(1) === 1;\n const durationFlag = r.readBits(1) === 1;\n const spliceImmediateFlag = r.readBits(1) === 1;\n r.readBits(4);\n if (programSpliceFlag && !spliceImmediateFlag) {\n const timeSpecifiedFlag = r.readBits(1) === 1;\n if (timeSpecifiedFlag) {\n r.readBits(6);\n r.readBits(33);\n } else {\n r.readBits(7);\n }\n } else if (!programSpliceFlag) {\n const componentCount = r.readBits(8);\n for (let i = 0; i < componentCount; i++) {\n r.readBits(8);\n if (!spliceImmediateFlag) {\n const timeSpecifiedFlag = r.readBits(1) === 1;\n if (timeSpecifiedFlag) {\n r.readBits(6);\n r.readBits(33);\n } else {\n r.readBits(7);\n }\n }\n }\n }\n let durationSeconds: number | undefined = undefined;\n if (durationFlag) {\n r.readBits(6);\n r.readBits(1);\n const high = r.readBits(1);\n const low = r.readBits(32);\n const durationTicks = high * 0x100000000 + low;\n durationSeconds = durationTicks / 90000;\n }\n r.readBits(16);\n r.readBits(8);\n r.readBits(8);\n\n if (outOfNetwork) {\n const marker: Scte35Marker = {\n type: \"start\",\n ...(durationSeconds !== undefined ? { durationSeconds } : {}),\n raw: { splice_command_type: 5 },\n } as Scte35Marker;\n return marker;\n }\n return undefined;\n }\n\n private initializeTracking(): void {\n sendInitialTracking(this.config.licenseKey)\n .then(() => {\n this.heartbeatInterval = window.setInterval(() => {\n this.sendHeartbeatIfNeeded();\n }, 5000);\n })\n .catch((error) => {\n if (this.config.debugAdTiming) {\n console.warn(\n \"[StormcloudVideoPlayer] Failed to send initial tracking:\",\n error\n );\n }\n this.heartbeatInterval = window.setInterval(() => {\n this.sendHeartbeatIfNeeded();\n }, 5000);\n });\n }\n\n private sendHeartbeatIfNeeded(): void {\n const now = Date.now();\n if (!this.lastHeartbeatTime || now - this.lastHeartbeatTime > 30000) {\n this.lastHeartbeatTime = now;\n sendHeartbeat(this.config.licenseKey).catch((error) => {\n if (this.config.debugAdTiming) {\n console.warn(\n \"[StormcloudVideoPlayer] Failed to send heartbeat:\",\n error\n );\n }\n });\n }\n }\n\n getCurrentAdIndex(): number {\n return this.currentAdIndex;\n }\n\n getTotalAdsInBreak(): number {\n return this.totalAdsInBreak;\n }\n\n isAdPlaying(): boolean {\n return this.inAdBreak && this.adLayer.isAdPlaying();\n }\n\n isShowingAds(): boolean {\n return this.showAds;\n }\n\n getStreamType(): \"hls\" | \"other\" {\n const url = this.config.src.toLowerCase();\n if (\n url.includes(\".m3u8\") ||\n url.includes(\"/hls/\") ||\n url.includes(\"application/vnd.apple.mpegurl\")\n ) {\n return \"hls\";\n }\n return \"other\";\n }\n\n shouldShowNativeControls(): boolean {\n const streamType = this.getStreamType();\n if (streamType === \"other\") {\n return !(this.config.showCustomControls ?? false);\n }\n return !!(\n this.config.allowNativeHls && !(this.config.showCustomControls ?? false)\n );\n }\n\n private shouldContinueLiveStreamDuringAds(): boolean {\n if (this.config.allowNativeHls) {\n return false;\n }\n\n if (!this.isLiveStream) {\n return false;\n }\n\n return true;\n }\n\n private startAdPrefetch(marker: Scte35Marker, fragmentSn?: number): void {\n if (this.pendingAdBreak || this.inAdBreak) {\n return;\n }\n\n this.pendingAdBreak = {\n marker,\n ...(fragmentSn !== undefined ? { detectedAtFragmentSn: fragmentSn } : {}),\n isFetching: false,\n fetchStartTime: Date.now(),\n };\n\n void this.adRequest().then(() => {}).catch(() => {\n if (this.config.debugAdTiming) {\n console.log(\"[PREFETCH] Prebid auction prefetch failed, will request at playback time\");\n }\n });\n\n if (this.config.debugAdTiming) {\n console.log(\"[PREFETCH] Ad break marker registered, auction prefetch started\");\n }\n }\n\n private clearPendingAdBreak(): void {\n if (this.prefetchTimerId != null) {\n clearTimeout(this.prefetchTimerId);\n this.prefetchTimerId = undefined;\n }\n this.pendingAdBreak = null;\n }\n\n private startContinuousFetchLoop(): void {\n if (this.continuousFetchLoopPromise != null) return;\n this.continuousFetchLoopPromise = this.runContinuousFetchLoop();\n }\n\n private async runContinuousFetchLoop(): Promise<void> {\n const backoffMs = () => {\n const mult = Math.pow(2, this.consecutiveFailures);\n return Math.min(this.backoffBaseMs * mult, this.maxBackoffMs);\n };\n while (this.inAdBreak && this.continuousFetchingActive) {\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) break;\n if (this.totalAdRequestsInBreak >= this.maxTotalAdRequestsPerBreak) break;\n const delay = this.lastAdRequestTime ? this.minAdRequestIntervalMs + (this.consecutiveFailures > 0 ? backoffMs() : 0) : 0;\n const elapsed = Date.now() - this.lastAdRequestTime;\n if (elapsed < delay && this.lastAdRequestTime > 0) {\n await new Promise((r) => setTimeout(r, delay - elapsed));\n }\n if (!this.inAdBreak || !this.continuousFetchingActive) break;\n try {\n const bids = await this.adRequest();\n this.lastAdRequestTime = Date.now();\n if (!this.inAdBreak) break;\n if (bids.length > 0) {\n this.consecutiveFailures = 0;\n if (this.adLayer.isAdPlaying()) {\n this.pendingNextAdBids = bids;\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] Next ad response stored (ad currently playing)\");\n }\n } else {\n this.currentAdIndex++;\n if (this.config.licenseKey) {\n sendAdLoadedTracking(this.config.licenseKey, {\n source: this.getAdSource(),\n timestamp: new Date().toISOString(),\n });\n }\n await this.adLayer.playAd(bids);\n if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {\n this.scheduleAdStopCountdown(this.getRemainingAdMs());\n }\n this.adLayer.setAdVolume(\n this.adLayer.getOriginalMutedState() ? 1 : this.adLayer.getOriginalVolume()\n );\n }\n } else {\n this.consecutiveFailures++;\n }\n } catch (err) {\n this.consecutiveFailures++;\n if (this.config.debugAdTiming) {\n console.warn(\"[CONTINUOUS-FETCH] adRequest failed:\", err);\n }\n }\n await new Promise((r) => setTimeout(r, backoffMs()));\n }\n this.continuousFetchLoopPromise = null;\n }\n\n private async handleAdStart(_marker: Scte35Marker): Promise<void> {\n const adBreakDurationMs =\n _marker.durationSeconds != null\n ? _marker.durationSeconds * 1000\n : undefined;\n\n if (this.config.debugAdTiming) {\n const mode = this.isLiveStream ? \"LIVE\" : \"VOD\";\n console.log(\n `[CONTINUOUS-FETCH] 📺 ${mode} MODE: Target duration=${adBreakDurationMs}ms`\n );\n }\n\n this.consecutiveFailures = 0;\n this.continuousFetchingActive = true;\n this.continuousFetchLoopPromise = null;\n this.pendingNextAdBids = null;\n this.isShowingPlaceholder = false;\n this.totalAdRequestsInBreak = 0;\n\n const state = this.savedMutedStateBeforeScte ?? {\n muted: this.video.muted,\n volume: this.video.volume,\n };\n this.adLayer.updateOriginalMutedState(state.muted, state.volume);\n this.savedMutedStateBeforeScte = null;\n\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Muted video in handleAdStart\");\n }\n }\n\n this.inAdBreak = true;\n this.currentAdBreakStartWallClockMs = Date.now();\n this.currentAdIndex = 0;\n this.totalAdsInBreak = 1;\n this.adPodQueue = [];\n\n this.showAds = true;\n\n this.showPlaceholderLayer();\n this.adLayer.showPlaceholder();\n\n if (\n this.expectedAdBreakDurationMs == null &&\n adBreakDurationMs != null\n ) {\n this.expectedAdBreakDurationMs = adBreakDurationMs;\n }\n\n this.clearPendingAdBreak();\n\n try {\n this.lastAdRequestTime = Date.now();\n const bids = await this.adRequest();\n if (!this.inAdBreak) return;\n if (bids.length > 0) {\n this.consecutiveFailures = 0;\n if (this.config.licenseKey) {\n sendAdLoadedTracking(this.config.licenseKey, {\n source: this.getAdSource(),\n timestamp: new Date().toISOString(),\n });\n }\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] ✅ First ad request successful, starting playback\");\n }\n this.currentAdIndex++;\n await this.adLayer.playAd(bids);\n if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {\n this.scheduleAdStopCountdown(this.getRemainingAdMs());\n }\n const adVolume = state.muted ? 1 : state.volume;\n this.adLayer.setAdVolume(adVolume);\n } else {\n this.consecutiveFailures++;\n await this.showPlaceholderAndWaitForAds();\n }\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\"[CONTINUOUS-FETCH] ⚠️ First ad request failed:\", error);\n }\n this.consecutiveFailures++;\n await this.showPlaceholderAndWaitForAds();\n }\n\n this.startContinuousFetchLoop();\n }\n\n private stopContinuousFetching(): void {\n this.continuousFetchingActive = false;\n \n this.hidePlaceholderLayer();\n \n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] 🛑 Stopping continuous ad fetching\");\n }\n }\n\n private async tryNextAvailableAdWithRateLimit(): Promise<void> {\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] 🛑 Too many consecutive failures (${this.consecutiveFailures}), ending ad break gracefully`);\n }\n this.handleAdPodComplete();\n return;\n }\n\n const backoffMultiplier = Math.pow(2, this.consecutiveFailures);\n const backoffDelay = Math.min(this.backoffBaseMs * backoffMultiplier, this.maxBackoffMs);\n const effectiveMinInterval = this.minAdRequestIntervalMs + (this.consecutiveFailures > 0 ? backoffDelay : 0);\n \n const timeSinceLastRequest = Date.now() - this.lastAdRequestTime;\n if (timeSinceLastRequest < effectiveMinInterval) {\n const waitTime = effectiveMinInterval - timeSinceLastRequest;\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] ⏳ Rate limiting: waiting ${waitTime}ms before next request (backoff: ${this.consecutiveFailures} failures)`);\n }\n await new Promise(resolve => setTimeout(resolve, waitTime));\n }\n\n return this.tryNextAvailableAd(0);\n }\n\n private async tryNextAvailableAd(_retryCount: number = 0): Promise<void> {\n if (this.totalAdRequestsInBreak >= this.maxTotalAdRequestsPerBreak) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] 🛑 Max ad requests per break (${this.maxTotalAdRequestsPerBreak}) reached`);\n }\n this.handleAdPodComplete();\n return;\n }\n const remaining = this.getRemainingAdMs();\n if (remaining <= 500 && this.expectedAdBreakDurationMs != null) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] ⏹️ No time remaining, ending ad break\");\n }\n this.handleAdPodComplete();\n return;\n }\n\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] 🛑 Too many consecutive failures (${this.consecutiveFailures}), ending ad break`);\n }\n this.handleAdPodComplete();\n return;\n }\n\n try {\n this.lastAdRequestTime = Date.now();\n const bids = await this.adRequest();\n if (!this.inAdBreak) return;\n if (bids.length > 0) {\n this.consecutiveFailures = 0;\n this.currentAdIndex++;\n this.totalAdRequestsInBreak++;\n if (this.adLayer.isAdPlaying()) {\n this.pendingNextAdBids = bids;\n } else {\n if (this.config.licenseKey) {\n sendAdLoadedTracking(this.config.licenseKey, {\n source: this.getAdSource(),\n timestamp: new Date().toISOString(),\n });\n }\n await this.adLayer.playAd(bids);\n if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {\n this.scheduleAdStopCountdown(this.getRemainingAdMs());\n }\n this.adLayer.setAdVolume(\n this.adLayer.getOriginalMutedState() ? 1 : this.adLayer.getOriginalVolume()\n );\n }\n } else {\n this.consecutiveFailures++;\n await this.showPlaceholderAndWaitForAds();\n }\n } catch (error) {\n this.consecutiveFailures++;\n if (this.config.debugAdTiming) {\n console.warn(\"[CONTINUOUS-FETCH] tryNextAvailableAd request failed:\", error);\n }\n await this.showPlaceholderAndWaitForAds();\n }\n }\n\n private async showPlaceholderAndWaitForAds(): Promise<void> {\n const remaining = this.getRemainingAdMs();\n const waitTime = Math.min(this.maxPlaceholderDurationMs, remaining);\n\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] 🛑 Skipping placeholder - too many consecutive failures\");\n }\n this.handleAdPodComplete();\n return;\n }\n\n if (waitTime < 1000) {\n this.handleAdPodComplete();\n return;\n }\n\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] ⬛ Showing placeholder for ${waitTime}ms while waiting for ad response`);\n }\n\n this.isShowingPlaceholder = true;\n this.adLayer.showPlaceholder();\n\n const checkInterval = 300;\n const maxChecks = Math.floor(waitTime / checkInterval);\n\n for (let i = 0; i < maxChecks; i++) {\n await new Promise((resolve) => setTimeout(resolve, checkInterval));\n\n if (!this.inAdBreak) return;\n\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] 🛑 Too many failures during placeholder wait\");\n }\n break;\n }\n\n if (this.pendingNextAdBids != null && this.pendingNextAdBids.length > 0) {\n const bids = this.pendingNextAdBids;\n this.pendingNextAdBids = null;\n this.isShowingPlaceholder = false;\n this.adLayer.hidePlaceholder();\n this.currentAdIndex++;\n try {\n await this.adLayer.playAd(bids);\n this.consecutiveFailures = 0;\n } catch {\n this.consecutiveFailures++;\n await this.tryNextAvailableAdWithRateLimit();\n }\n return;\n }\n\n if (this.adLayer.isAdPlaying()) {\n this.isShowingPlaceholder = false;\n this.adLayer.hidePlaceholder();\n return;\n }\n }\n\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] ⏰ Placeholder timeout, ending ad break\");\n }\n\n this.isShowingPlaceholder = false;\n this.adLayer.hidePlaceholder();\n this.handleAdPodComplete();\n }\n\n private onTimeUpdate(_currentTimeSec: number): void {\n if (this.adLayer.isAdPlaying()) return;\n }\n\n private scheduleAdStopCountdown(remainingMs: number): void {\n this.clearAdStopTimer();\n const ms = Math.max(0, Math.floor(remainingMs));\n if (ms === 0) {\n this.ensureAdStoppedByTimer();\n return;\n }\n this.adStopTimerId = window.setTimeout(() => {\n this.ensureAdStoppedByTimer();\n }, ms) as unknown as number;\n }\n\n private clearAdStopTimer(): void {\n if (this.adStopTimerId != null) {\n clearTimeout(this.adStopTimerId);\n this.adStopTimerId = undefined;\n }\n }\n\n private ensureAdStoppedByTimer(): void {\n if (!this.inAdBreak) return;\n\n this.adStopTimerId = undefined;\n\n const adPlaying = this.adLayer.isAdPlaying();\n const pendingAds = this.adPodQueue.length > 0;\n const checkIntervalMs = Math.max(\n 250,\n Math.floor(this.config.adBreakCheckIntervalMs ?? 1000)\n );\n const maxExtensionMsConfig = this.config.maxAdBreakExtensionMs;\n const maxExtensionMs =\n typeof maxExtensionMsConfig === \"number\" && maxExtensionMsConfig > 0\n ? maxExtensionMsConfig\n : 60000;\n\n let elapsedSinceStartMs = 0;\n if (this.currentAdBreakStartWallClockMs != null) {\n elapsedSinceStartMs = Date.now() - this.currentAdBreakStartWallClockMs;\n }\n const expectedDurationMs = this.expectedAdBreakDurationMs ?? 0;\n const overrunMs = Math.max(0, elapsedSinceStartMs - expectedDurationMs);\n\n const shouldExtendAdBreak =\n (adPlaying || pendingAds || this.showAds) && overrunMs < maxExtensionMs;\n\n if (shouldExtendAdBreak) {\n this.scheduleAdStopCountdown(checkIntervalMs);\n return;\n }\n\n if (adPlaying) {\n this.adLayer.stop().catch(() => {});\n }\n\n this.handleAdPodComplete();\n }\n\n private scheduleAdStartIn(delayMs: number): void {\n this.clearAdStartTimer();\n const ms = Math.max(0, Math.floor(delayMs));\n if (ms === 0) {\n this.handleAdStart({ type: \"start\" } as Scte35Marker).catch(() => {});\n return;\n }\n this.adStartTimerId = window.setTimeout(() => {\n this.handleAdStart({ type: \"start\" } as Scte35Marker).catch(() => {});\n }, ms) as unknown as number;\n }\n\n private clearAdStartTimer(): void {\n if (this.adStartTimerId != null) {\n clearTimeout(this.adStartTimerId);\n this.adStartTimerId = undefined;\n }\n }\n\n private updatePtsDrift(ptsSecondsSample: number): void {\n const sampleMs = (this.video.currentTime - ptsSecondsSample) * 1000;\n if (!Number.isFinite(sampleMs) || Math.abs(sampleMs) > 60000) return;\n const alpha = 0.1;\n this.ptsDriftEmaMs = this.ptsDriftEmaMs * (1 - alpha) + sampleMs * alpha;\n }\n\n private handleAdPodComplete(): void {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] 🏁 Ad pod complete - cleaning up\");\n }\n\n this.clearAdRequestWatchdog();\n this.clearAdFailsafeTimer();\n this.activeAdRequestToken = null;\n\n this.stopContinuousFetching();\n this.clearPendingAdBreak();\n this.pendingNextAdBids = null;\n\n if (this.isShowingPlaceholder) {\n this.adLayer.hidePlaceholder();\n this.isShowingPlaceholder = false;\n }\n\n this.inAdBreak = false;\n this.expectedAdBreakDurationMs = undefined;\n this.currentAdBreakStartWallClockMs = undefined;\n this.clearAdStartTimer();\n this.clearAdStopTimer();\n this.adPodQueue = [];\n this.showAds = false;\n this.currentAdIndex = 0;\n this.totalAdsInBreak = 0;\n this.totalAdRequestsInBreak = 0;\n this.consecutiveFailures = 0;\n\n this.adLayer.stop().catch(() => {});\n\n const restoredMuted = this.adLayer.getOriginalMutedState();\n const restoredVolume = this.adLayer.getOriginalVolume();\n\n if (this.video.muted !== restoredMuted) {\n this.video.muted = restoredMuted;\n }\n if (Math.abs(this.video.volume - restoredVolume) > 0.01) {\n this.video.volume = restoredVolume;\n }\n\n const isTizen = detectBrowser().tizenVersion !== undefined;\n if (isTizen && this.hls) {\n this.hls.attachMedia(this.video);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Tizen: re-attached HLS to video element after ad break to restore audio\");\n }\n }\n\n if (this.shouldContinueLiveStreamDuringAds()) {\n if (this.config.debugAdTiming) {\n if (this.video.paused) {\n console.log(\"[StormcloudVideoPlayer] Content video paused in live mode after ads, resuming playback\");\n } else {\n console.log(\"[StormcloudVideoPlayer] Content video already playing in live mode after ads\");\n }\n }\n this.video.play()?.catch(() => {});\n } else if (this.video.paused) {\n this.video.play()?.catch(() => {});\n }\n\n if (!restoredMuted) {\n requestAnimationFrame(() => {\n this.video.muted = false;\n this.video.volume = restoredVolume;\n });\n setTimeout(() => {\n this.video.muted = false;\n this.video.volume = restoredVolume;\n }, 0);\n setTimeout(() => {\n this.video.muted = false;\n this.video.volume = restoredVolume;\n }, 50);\n }\n }\n\n private handleAdFailure(): void {\n this.consecutiveFailures++;\n if (this.config.debugAdTiming) {\n console.log(\n `[CONTINUOUS-FETCH] Ad failure: consecutiveFailures=${this.consecutiveFailures}`\n );\n }\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] 🛑 Max consecutive failures reached (${this.consecutiveFailures}), ending ad break gracefully`);\n }\n this.handleAdPodComplete();\n }\n }\n\n private startAdRequestWatchdog(token: number): void {\n this.clearAdRequestWatchdog();\n\n const timeoutMs = this.config.adFailsafeTimeoutMs ?? 10000;\n this.adRequestWatchdogToken = token;\n this.adRequestWatchdogId = window.setTimeout(() => {\n if (this.adRequestWatchdogToken !== token) {\n return;\n }\n\n this.adRequestWatchdogId = undefined;\n this.adRequestWatchdogToken = null;\n if (this.activeAdRequestToken === token) {\n this.activeAdRequestToken = null;\n }\n\n this.logAdState(\"ad_request_timeout\", { token, timeoutMs });\n this.handleAdFailure();\n }, timeoutMs) as unknown as number;\n\n this.logAdState(\"ad_request_watchdog_started\", { token, timeoutMs });\n }\n\n private clearAdRequestWatchdog(): void {\n if (this.adRequestWatchdogId != null) {\n clearTimeout(this.adRequestWatchdogId);\n this.adRequestWatchdogId = undefined;\n }\n\n if (this.adRequestWatchdogToken != null) {\n this.logAdState(\"ad_request_watchdog_cleared\", {\n token: this.adRequestWatchdogToken,\n });\n this.adRequestWatchdogToken = null;\n }\n }\n\n private startAdFailsafeTimer(token: number): void {\n this.clearAdFailsafeTimer();\n\n const failsafeMs = this.config.adFailsafeTimeoutMs ?? 10000;\n this.adFailsafeToken = token;\n\n this.adFailsafeTimerId = window.setTimeout(() => {\n if (this.adFailsafeToken !== token) {\n return;\n }\n\n this.adFailsafeTimerId = undefined;\n this.adFailsafeToken = null;\n\n if (this.activeAdRequestToken === token) {\n this.activeAdRequestToken = null;\n }\n\n this.logAdState(\"ad_failsafe_triggered\", {\n token,\n failsafeMs,\n videoPaused: this.video.paused,\n imaAdPlaying: this.adLayer.isAdPlaying(),\n });\n\n this.handleAdFailure();\n }, failsafeMs) as unknown as number;\n\n this.logAdState(\"ad_failsafe_started\", { token, failsafeMs });\n }\n\n private clearAdFailsafeTimer(): void {\n if (this.adFailsafeTimerId != null) {\n clearTimeout(this.adFailsafeTimerId);\n this.logAdState(\"ad_failsafe_cleared\", { token: this.adFailsafeToken });\n this.adFailsafeTimerId = undefined;\n }\n\n this.adFailsafeToken = null;\n }\n\n private logAdState(event: string, extra: Record<string, unknown> = {}): void {\n if (!this.config.debugAdTiming) {\n return;\n }\n\n console.log(\"[StormcloudVideoPlayer][AdState]\", {\n event,\n timestamp: new Date().toISOString(),\n showAds: this.showAds,\n adPlaying: this.adLayer.isAdPlaying(),\n inAdBreak: this.inAdBreak,\n activeAdRequestToken: this.activeAdRequestToken,\n ...extra,\n });\n }\n\n private getRemainingAdMs(): number {\n if (this.currentAdBreakStartWallClockMs == null) return 0;\n if (this.expectedAdBreakDurationMs == null) return Number.MAX_SAFE_INTEGER;\n const elapsed = Date.now() - this.currentAdBreakStartWallClockMs;\n return Math.max(0, this.expectedAdBreakDurationMs - elapsed);\n }\n\n toggleMute(): void {\n if (this.adLayer.isAdPlaying()) {\n const currentPerceptualState = this.isMuted();\n const newMutedState = !currentPerceptualState;\n\n this.adLayer.updateOriginalMutedState(newMutedState, this.video.volume);\n this.adLayer.setAdVolume(newMutedState ? 0 : this.adLayer.getOriginalVolume());\n\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Mute toggle during ad - immediately applied:\",\n newMutedState\n );\n }\n } else {\n this.video.muted = !this.video.muted;\n this.adLayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Muted:\", this.video.muted);\n }\n }\n }\n\n toggleFullscreen(): Promise<void> {\n return new Promise((resolve, reject) => {\n if (!document.fullscreenElement) {\n const container = this.video.parentElement;\n if (!container) {\n reject(new Error(\"No parent container found for fullscreen\"));\n return;\n }\n container\n .requestFullscreen()\n .then(() => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Entered fullscreen\");\n }\n resolve();\n })\n .catch((err) => {\n if (this.config.debugAdTiming) {\n console.error(\"[StormcloudVideoPlayer] Fullscreen error:\", err);\n }\n reject(err);\n });\n } else {\n document\n .exitFullscreen()\n .then(() => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Exited fullscreen\");\n }\n resolve();\n })\n .catch((err) => {\n if (this.config.debugAdTiming) {\n console.error(\n \"[StormcloudVideoPlayer] Exit fullscreen error:\",\n err\n );\n }\n reject(err);\n });\n }\n });\n }\n\n isMuted(): boolean {\n if (this.adLayer.isAdPlaying()) {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] isMuted() override during ad playback -> false\"\n );\n }\n return false;\n }\n return this.video.muted;\n }\n\n setMuted(muted: boolean): void {\n const adPlaying = this.adLayer.isAdPlaying();\n\n if (adPlaying && muted === this.video.muted) {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] setMuted reflective update during ad ignored\",\n { muted }\n );\n }\n return;\n }\n\n this.video.muted = muted;\n\n if (adPlaying) {\n this.adLayer.updateOriginalMutedState(muted, this.video.volume);\n this.adLayer.setAdVolume(muted ? 0 : this.adLayer.getOriginalVolume());\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] setMuted applied during ad\", {\n muted,\n });\n }\n return;\n }\n\n this.adLayer.updateOriginalMutedState(muted, this.video.volume);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] setMuted called:\", muted);\n }\n }\n\n setVolume(volume: number): void {\n const clampedVolume = Math.max(0, Math.min(1, volume));\n const adPlaying = this.adLayer.isAdPlaying();\n\n if (adPlaying) {\n this.adLayer.setAdVolume(clampedVolume);\n this.adLayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] setVolume applied during ad\", {\n volume: clampedVolume,\n });\n }\n } else {\n this.video.volume = clampedVolume;\n this.video.muted = clampedVolume === 0;\n this.adLayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] setVolume called:\", clampedVolume);\n }\n }\n }\n\n getVolume(): number {\n const adPlaying = this.adLayer.isAdPlaying();\n if (adPlaying) {\n return this.adLayer.getAdVolume();\n }\n return this.video.volume;\n }\n\n isFullscreen(): boolean {\n return !!document.fullscreenElement;\n }\n\n isLive(): boolean {\n return this.isLiveStream;\n }\n\n get videoElement(): HTMLVideoElement {\n return this.video;\n }\n\n resize(): void {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Resizing player\");\n }\n\n if (this.adLayer && this.adLayer.isAdPlaying()) {\n const width = this.video.clientWidth || 640;\n const height = this.video.clientHeight || 480;\n\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Resizing ads manager to ${width}x${height}`\n );\n }\n\n this.adLayer.resize(width, height);\n }\n }\n\n destroy(): void {\n this.stopContinuousFetching();\n this.clearAdStartTimer();\n this.clearAdStopTimer();\n this.clearAdFailsafeTimer();\n this.clearAdRequestWatchdog();\n this.clearPendingAdBreak();\n \n if (this.placeholderContainer) {\n if (this.placeholderContainer.parentElement) {\n this.placeholderContainer.parentElement.removeChild(this.placeholderContainer);\n }\n this.placeholderContainer = undefined;\n }\n \n if (this.timeUpdateHandler) {\n this.video.removeEventListener(\"timeupdate\", this.timeUpdateHandler);\n delete this.timeUpdateHandler;\n }\n if (this.emptiedHandler) {\n this.video.removeEventListener(\"emptied\", this.emptiedHandler);\n delete this.emptiedHandler;\n }\n \n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval);\n this.heartbeatInterval = undefined;\n }\n this.hls?.destroy();\n this.adLayer?.destroy();\n this.consecutiveFailures = 0;\n }\n}\n","import type { PrebidBidResponse, PrebidManager } from \"../types\";\n\nconst DEFAULT_TIMEOUT_MS = 3000;\nconst AUCTION_URL = \"https://sspproxy.adstorm.co/openrtb2/auction/adstorm\";\n\nexport interface PrebidManagerOptions {\n debug?: boolean;\n}\n\nexport function createPrebidManager(\n options: PrebidManagerOptions = {}\n): PrebidManager {\n let initialized = false;\n const debug = options.debug ?? false;\n\n function log(...args: any[]): void {\n if (debug) {\n console.log(\"[Prebid]\", ...args);\n }\n }\n\n function warn(...args: any[]): void {\n console.warn(\"[Prebid]\", ...args);\n }\n\n function parseResponse(data: any): PrebidBidResponse[] {\n const bids: PrebidBidResponse[] = [];\n const seatbids: any[] = data?.seatbid || [];\n const currency: string = data?.cur || \"USD\";\n\n for (const seatbid of seatbids) {\n const seat: string = seatbid.seat || \"unknown\";\n const bidArray: any[] = seatbid.bid || [];\n\n for (const bid of bidArray) {\n const cacheUrl: string | undefined =\n bid.ext?.prebid?.cache?.vastXml?.url;\n const vastXml: string | undefined = bid.adm || undefined;\n\n const bidResponse: PrebidBidResponse = {\n bidder: seat,\n cpm: bid.price || 0,\n width: bid.w || 0,\n height: bid.h || 0,\n adId: bid.id || \"\",\n impId: bid.impid || \"\",\n creativeId: bid.crid || \"\",\n currency,\n };\n if (cacheUrl) bidResponse.vastUrl = cacheUrl;\n if (vastXml) bidResponse.vastXml = vastXml;\n if (bid.adomain) bidResponse.adomain = bid.adomain;\n\n bids.push(bidResponse);\n }\n }\n\n bids.sort((a, b) => b.cpm - a.cpm);\n return bids;\n }\n\n async function initialize(): Promise<void> {\n if (initialized) return;\n initialized = true;\n log(\"Initialized, auction URL:\", AUCTION_URL);\n }\n\n async function requestBids(): Promise<PrebidBidResponse[]> {\n if (!initialized) {\n throw new Error(\"Prebid not initialized. Call initialize() first.\");\n }\n\n const timeout = DEFAULT_TIMEOUT_MS;\n\n log(\"Fetching auction response from:\", AUCTION_URL);\n\n const controller =\n typeof AbortController !== \"undefined\"\n ? new AbortController()\n : null;\n const timeoutId = setTimeout(() => {\n controller?.abort();\n }, timeout + 2000);\n\n try {\n const fetchOptions: RequestInit = {\n method: \"POST\",\n };\n if (controller) {\n fetchOptions.signal = controller.signal;\n }\n\n const response = await fetch(AUCTION_URL, fetchOptions);\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new Error(\n `Prebid Server returned HTTP ${response.status}: ${body.slice(0, 200)}`\n );\n }\n\n const data = await response.json();\n\n if (debug && data?.ext?.responsetimemillis) {\n log(\"Bidder response times:\", data.ext.responsetimemillis);\n }\n if (debug && data?.ext?.errors) {\n warn(\"Auction errors:\", data.ext.errors);\n }\n\n const bids = parseResponse(data);\n log(`Received ${bids.length} bid(s)`);\n\n if (debug) {\n for (const b of bids) {\n log(\n ` ${b.bidder}: $${b.cpm.toFixed(2)} ${b.currency}` +\n ` ${b.width}x${b.height}` +\n (b.vastUrl ? \" [cached VAST]\" : \"\") +\n (b.vastXml && !b.vastUrl ? \" [VAST XML]\" : \"\")\n );\n }\n }\n\n return bids;\n } catch (error: any) {\n clearTimeout(timeoutId);\n\n if (error?.name === \"AbortError\") {\n warn(`Auction request timed out after ${timeout + 2000}ms`);\n return [];\n }\n\n throw error;\n }\n }\n\n const REQUEST_BIDS_MAX_RETRIES = 3;\n const REQUEST_BIDS_BACKOFF_MS = 1500;\n\n async function requestBidsUntilResponse(): Promise<PrebidBidResponse[]> {\n if (!initialized) {\n throw new Error(\"Prebid not initialized. Call initialize() first.\");\n }\n let lastError: unknown;\n for (let attempt = 1; attempt <= REQUEST_BIDS_MAX_RETRIES; attempt++) {\n try {\n const bids = await requestBids();\n if (bids.length > 0) {\n log(`requestBidsUntilResponse: got ${bids.length} bid(s) on attempt ${attempt}`);\n return bids;\n }\n log(`requestBidsUntilResponse: no bids on attempt ${attempt}/${REQUEST_BIDS_MAX_RETRIES}`);\n } catch (err) {\n lastError = err;\n warn(`requestBidsUntilResponse: attempt ${attempt}/${REQUEST_BIDS_MAX_RETRIES} failed:`, err);\n }\n if (attempt < REQUEST_BIDS_MAX_RETRIES) {\n const delay = REQUEST_BIDS_BACKOFF_MS * attempt;\n log(`requestBidsUntilResponse: waiting ${delay}ms before retry`);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n if (lastError instanceof Error) {\n throw lastError;\n }\n return [];\n }\n\n function destroy(): void {\n initialized = false;\n log(\"Destroyed\");\n }\n\n return {\n initialize,\n requestBids,\n requestBidsUntilResponse,\n destroy,\n get isInitialized() {\n return initialized;\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","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","import type {\n ClientInfo,\n TrackingData,\n HeartbeatData,\n AdDetectInfo,\n AdLoadedInfo,\n AdImpressionInfo,\n} from \"../types\";\n\nlet cachedBrowserId: string | null = null;\n\nexport function getClientInfo(): ClientInfo {\n const ua = navigator.userAgent;\n const platform = navigator.platform;\n const vendor = navigator.vendor || \"\";\n const maxTouchPoints = navigator.maxTouchPoints || 0;\n const memory = (navigator as any).deviceMemory || null;\n const hardwareConcurrency = navigator.hardwareConcurrency || 1;\n\n const screenInfo = {\n width: screen?.width,\n height: screen?.height,\n availWidth: screen?.availWidth,\n availHeight: screen?.availHeight,\n orientation: (screen?.orientation as any)?.type || \"\",\n pixelDepth: screen?.pixelDepth,\n };\n\n let deviceType: \"tv\" | \"mobile\" | \"tablet\" | \"desktop\" = \"desktop\";\n let brand = \"Unknown\";\n let os = \"Unknown\";\n let model = \"\";\n let isSmartTV = false;\n let isAndroid = false;\n let isWebView = false;\n let isWebApp = false;\n\n if (ua.includes(\"Web0S\")) {\n brand = \"LG\";\n os = \"webOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n const webosMatch = ua.match(/Web0S\\/([^\\s]+)/);\n model = webosMatch ? `webOS ${webosMatch[1]}` : \"webOS TV\";\n } else if (ua.includes(\"Tizen\")) {\n brand = \"Samsung\";\n os = \"Tizen\";\n isSmartTV = true;\n deviceType = \"tv\";\n const tizenMatch = ua.match(/Tizen\\/([^\\s]+)/);\n const tvMatch = ua.match(/(?:Smart-TV|SMART-TV|TV)/i) ? \"Smart TV\" : \"\";\n model = tizenMatch\n ? `Tizen ${tizenMatch[1]} ${tvMatch}`.trim()\n : \"Tizen TV\";\n } else if (ua.includes(\"Philips\")) {\n brand = \"Philips\";\n os = \"Saphi\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Sharp\") || ua.includes(\"AQUOS\")) {\n brand = \"Sharp\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (\n ua.includes(\"Android\") &&\n (ua.includes(\"Sony\") || vendor.includes(\"Sony\"))\n ) {\n brand = \"Sony\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (\n ua.includes(\"Android\") &&\n (ua.includes(\"NetCast\") || ua.includes(\"LG\"))\n ) {\n brand = \"LG\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\" Roku\") || ua.includes(\"Roku/\")) {\n brand = \"Roku\";\n os = \"Roku OS\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"AppleTV\")) {\n brand = \"Apple\";\n os = \"tvOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n }\n\n if (ua.includes(\"Android\")) {\n isAndroid = true;\n os = \"Android\";\n deviceType = /Mobile/.test(ua) ? \"mobile\" : \"tablet\";\n\n if (\n ua.includes(\"Android\") &&\n (maxTouchPoints === 0 ||\n ua.includes(\"Google TV\") ||\n ua.includes(\"XiaoMi\"))\n ) {\n deviceType = \"tv\";\n isSmartTV = true;\n brand = brand === \"Unknown\" ? \"Android TV\" : brand;\n }\n\n const androidModelMatch = ua.match(/\\(([^)]*Android[^)]*)\\)/);\n if (androidModelMatch && androidModelMatch[1]) {\n model = androidModelMatch[1];\n }\n }\n\n if (/iPad|iPhone|iPod/.test(ua)) {\n os = \"iOS\";\n deviceType = \"mobile\";\n brand = \"Apple\";\n if (navigator.maxTouchPoints > 1 && /iPad/.test(ua)) {\n deviceType = \"tablet\";\n }\n }\n\n if (!isAndroid && !isSmartTV && !/Mobile/.test(ua)) {\n if (ua.includes(\"Windows\")) {\n os = \"Windows\";\n deviceType = \"desktop\";\n } else if (ua.includes(\"Mac\") && !/iPhone/.test(ua)) {\n os = \"macOS\";\n deviceType = \"desktop\";\n if (maxTouchPoints > 1) deviceType = \"tablet\";\n } else if (ua.includes(\"Linux\")) {\n os = \"Linux\";\n deviceType = \"desktop\";\n }\n }\n\n if (brand === \"Unknown\") {\n if (vendor.includes(\"Google\") || ua.includes(\"Chrome\")) brand = \"Google\";\n if (vendor.includes(\"Apple\")) brand = \"Apple\";\n if (vendor.includes(\"Samsung\") || ua.includes(\"SM-\")) brand = \"Samsung\";\n }\n\n isWebView = /wv|WebView|Linux; U;/.test(ua);\n\n if (window?.outerHeight === 0 && window?.outerWidth === 0) {\n isWebView = true;\n }\n\n isWebApp =\n window.matchMedia(\"(display-mode: standalone)\").matches ||\n (window.navigator as any).standalone === true ||\n window.screen?.orientation?.angle !== undefined;\n\n return {\n brand,\n os,\n model: model || ua.substring(0, 50) + \"...\",\n deviceType,\n isSmartTV,\n isAndroid,\n isWebView,\n isWebApp,\n domain: window.location.hostname,\n origin: window.location.origin,\n path: window.location.pathname,\n userAgent: ua,\n vendor,\n platform,\n screen: screenInfo,\n hardwareConcurrency,\n deviceMemory: memory,\n maxTouchPoints,\n language: navigator.language,\n languages: navigator.languages?.join(\",\") || \"\",\n cookieEnabled: navigator.cookieEnabled,\n doNotTrack: navigator.doNotTrack || \"\",\n referrer: document.referrer,\n visibilityState: document.visibilityState,\n };\n}\n\nexport async function getBrowserID(clientInfo: ClientInfo): Promise<string> {\n if (cachedBrowserId) {\n return cachedBrowserId;\n }\n\n const fingerprintString = JSON.stringify(clientInfo);\n\n if (typeof crypto !== \"undefined\" && crypto.subtle && crypto.subtle.digest) {\n try {\n await crypto.subtle.digest(\"SHA-256\", new Uint8Array([1, 2, 3]));\n\n let encodedData: BufferSource;\n if (typeof TextEncoder !== \"undefined\") {\n encodedData = new TextEncoder().encode(fingerprintString);\n } else {\n const utf8 = unescape(encodeURIComponent(fingerprintString));\n const buffer = new Uint8Array(utf8.length);\n for (let i = 0; i < utf8.length; i++) {\n buffer[i] = utf8.charCodeAt(i);\n }\n encodedData = buffer;\n }\n\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", encodedData);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n const hashHex = hashArray\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n cachedBrowserId = hashHex;\n return hashHex;\n } catch (error) {\n console.warn(\n \"[StormcloudVideoPlayer] crypto.subtle.digest not supported, using fallback hash\"\n );\n }\n }\n\n let hash = 0;\n for (let i = 0; i < fingerprintString.length; i++) {\n const char = fingerprintString.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n\n const fallbackHash = Math.abs(hash).toString(16).padStart(8, \"0\");\n const timestamp = Date.now().toString(16).padStart(12, \"0\");\n const random = Math.random().toString(16).substring(2, 14).padStart(12, \"0\");\n\n cachedBrowserId = (fallbackHash + timestamp + random).padEnd(64, \"0\");\n return cachedBrowserId;\n}\n\nconst TRACK_URL =\n \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track\";\n\nasync function sendTrackRequest(\n licenseKey: string | undefined,\n body: Record<string, unknown>\n): Promise<void> {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n const response = await fetch(TRACK_URL, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n });\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n await response.json();\n}\n\nexport async function sendInitialTracking(licenseKey?: string): Promise<void> {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n\n const trackingData: TrackingData = {\n browserId,\n ...clientInfo,\n };\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n\n const response = await fetch(TRACK_URL, {\n method: \"POST\",\n headers,\n body: JSON.stringify(trackingData),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n await response.json();\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending initial tracking data:\",\n error\n );\n }\n}\n\nexport async function sendAdDetectTracking(\n licenseKey: string | undefined,\n adDetectInfo: AdDetectInfo\n): Promise<void> {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData: TrackingData = { browserId, ...clientInfo };\n await sendTrackRequest(licenseKey, {\n ...trackingData,\n licenseKey,\n adDetectInfo,\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad detect tracking:\",\n error\n );\n }\n}\n\nexport async function sendAdLoadedTracking(\n licenseKey: string | undefined,\n adLoadedInfo: AdLoadedInfo\n): Promise<void> {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData: TrackingData = { browserId, ...clientInfo };\n await sendTrackRequest(licenseKey, {\n ...trackingData,\n licenseKey,\n adLoadedInfo,\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad loaded tracking:\",\n error\n );\n }\n}\n\nexport async function sendAdImpressionTracking(\n licenseKey: string | undefined,\n adImpressionInfo: AdImpressionInfo\n): Promise<void> {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData: TrackingData = { browserId, ...clientInfo };\n await sendTrackRequest(licenseKey, {\n ...trackingData,\n licenseKey,\n adImpressionInfo,\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad impression tracking:\",\n error\n );\n }\n}\n\nexport async function sendHeartbeat(licenseKey?: string): Promise<void> {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n\n const heartbeatData: HeartbeatData = {\n browserId,\n timestamp: new Date().toISOString(),\n };\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n\n const response = await fetch(\n \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/heartbeat\",\n {\n method: \"POST\",\n headers,\n body: JSON.stringify(heartbeatData),\n }\n );\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n await response.json();\n } catch (error) {\n console.error(\"[StormcloudVideoPlayer] Error sending heartbeat:\", error);\n }\n}\n","export function polyfillURLSearchParams(): void {\n if (typeof URLSearchParams !== 'undefined') {\n return;\n }\n\n class URLSearchParamsPolyfill {\n private params: Map<string, string[]>;\n\n constructor(init?: string | URLSearchParamsPolyfill) {\n this.params = new Map();\n\n if (typeof init === 'string') {\n this.parseQueryString(init);\n } else if (init instanceof URLSearchParamsPolyfill) {\n init.forEach((value, key) => {\n this.append(key, value);\n });\n }\n }\n\n private parseQueryString(query: string): void {\n const cleanQuery = query.startsWith('?') ? query.slice(1) : query;\n if (!cleanQuery) return;\n\n cleanQuery.split('&').forEach((param) => {\n const [key, value] = param.split('=');\n if (key) {\n const decodedKey = this.safeDecodeURIComponent(key);\n const decodedValue = value ? this.safeDecodeURIComponent(value) : '';\n this.append(decodedKey, decodedValue);\n }\n });\n }\n\n private safeDecodeURIComponent(str: string): string {\n try {\n return decodeURIComponent(str.replace(/\\+/g, ' '));\n } catch (e) {\n return str;\n }\n }\n\n append(name: string, value: string): void {\n const values = this.params.get(name) || [];\n values.push(String(value));\n this.params.set(name, values);\n }\n\n delete(name: string): void {\n this.params.delete(name);\n }\n\n get(name: string): string | null {\n const values = this.params.get(name);\n return values && values.length > 0 && values[0] !== undefined ? values[0] : null;\n }\n\n getAll(name: string): string[] {\n return this.params.get(name) || [];\n }\n\n has(name: string): boolean {\n return this.params.has(name);\n }\n\n set(name: string, value: string): void {\n this.params.set(name, [String(value)]);\n }\n\n forEach(callback: (value: string, key: string, parent: URLSearchParamsPolyfill) => void): void {\n this.params.forEach((values, key) => {\n values.forEach((value) => {\n callback(value, key, this);\n });\n });\n }\n\n toString(): string {\n const parts: string[] = [];\n this.params.forEach((values, key) => {\n values.forEach((value) => {\n parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);\n });\n });\n return parts.join('&');\n }\n }\n\n // @ts-ignore\n window.URLSearchParams = URLSearchParamsPolyfill;\n}\n\nexport function polyfillTextEncoder(): void {\n if (typeof TextEncoder !== 'undefined') {\n return;\n }\n\n class TextEncoderPolyfill {\n encoding = 'utf-8';\n\n encode(str: string): Uint8Array {\n const utf8: number[] = [];\n for (let i = 0; i < str.length; i++) {\n let charcode = str.charCodeAt(i);\n if (charcode < 0x80) {\n utf8.push(charcode);\n } else if (charcode < 0x800) {\n utf8.push(0xc0 | (charcode >> 6), 0x80 | (charcode & 0x3f));\n } else if (charcode < 0xd800 || charcode >= 0xe000) {\n utf8.push(\n 0xe0 | (charcode >> 12),\n 0x80 | ((charcode >> 6) & 0x3f),\n 0x80 | (charcode & 0x3f)\n );\n } else {\n i++;\n charcode = 0x10000 + (((charcode & 0x3ff) << 10) | (str.charCodeAt(i) & 0x3ff));\n utf8.push(\n 0xf0 | (charcode >> 18),\n 0x80 | ((charcode >> 12) & 0x3f),\n 0x80 | ((charcode >> 6) & 0x3f),\n 0x80 | (charcode & 0x3f)\n );\n }\n }\n return new Uint8Array(utf8);\n }\n }\n\n // @ts-ignore\n window.TextEncoder = TextEncoderPolyfill;\n}\n\nexport function polyfillPromiseFinally(): void {\n if (typeof Promise !== 'undefined' && !Promise.prototype.finally) {\n Promise.prototype.finally = function (callback: () => void) {\n const constructor = this.constructor as PromiseConstructor;\n return this.then(\n (value) => constructor.resolve(callback()).then(() => value),\n (reason) =>\n constructor.resolve(callback()).then(() => {\n throw reason;\n })\n );\n };\n }\n}\n\nexport function polyfillObjectAssign(): void {\n if (typeof Object.assign !== 'function') {\n Object.assign = function (target: any, ...sources: any[]) {\n if (target == null) {\n throw new TypeError('Cannot convert undefined or null to object');\n }\n\n const to = Object(target);\n\n for (let i = 0; i < sources.length; i++) {\n const nextSource = sources[i];\n\n if (nextSource != null) {\n for (const nextKey in nextSource) {\n if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {\n to[nextKey] = nextSource[nextKey];\n }\n }\n }\n }\n\n return to;\n };\n }\n}\n\nexport function polyfillArrayFrom(): void {\n if (!Array.from) {\n Array.from = function (arrayLike: any, mapFn?: any, thisArg?: any) {\n const items = Object(arrayLike);\n if (arrayLike == null) {\n throw new TypeError('Array.from requires an array-like object');\n }\n\n const len = items.length >>> 0;\n const result = new Array(len);\n\n for (let i = 0; i < len; i++) {\n if (mapFn) {\n result[i] = mapFn.call(thisArg, items[i], i);\n } else {\n result[i] = items[i];\n }\n }\n\n return result;\n };\n }\n}\n\nexport function polyfillStringStartsWith(): void {\n if (!String.prototype.startsWith) {\n String.prototype.startsWith = function (search: string, pos?: number) {\n pos = !pos || pos < 0 ? 0 : +pos;\n return this.substring(pos, pos + search.length) === search;\n };\n }\n}\n\nexport function polyfillStringEndsWith(): void {\n if (!String.prototype.endsWith) {\n String.prototype.endsWith = function (search: string, length?: number) {\n if (length === undefined || length > this.length) {\n length = this.length;\n }\n return this.substring(length - search.length, length) === search;\n };\n }\n}\n\nexport function polyfillStringIncludes(): void {\n if (!String.prototype.includes) {\n String.prototype.includes = function (search: string, start?: number) {\n if (typeof start !== 'number') {\n start = 0;\n }\n if (start + search.length > this.length) {\n return false;\n }\n return this.indexOf(search, start) !== -1;\n };\n }\n}\n\nexport function initializePolyfills(): void {\n polyfillObjectAssign();\n polyfillArrayFrom();\n polyfillStringStartsWith();\n polyfillStringEndsWith();\n polyfillStringIncludes();\n polyfillURLSearchParams();\n polyfillTextEncoder();\n polyfillPromiseFinally();\n}\n\n","interface NavigatorUAData {\n platform?: string;\n brands?: Array<{ brand: string; version: string }>;\n mobile?: boolean;\n}\n\ndeclare global {\n interface Navigator {\n userAgentData?: NavigatorUAData;\n }\n}\n\nexport interface BrowserInfo {\n name: string;\n version: string;\n majorVersion: number;\n isSmartTV: boolean;\n isLegacyTV: boolean;\n platform: string;\n supportsIMA: boolean;\n supportsModernJS: boolean;\n recommendedAdPlayer: 'ima' | 'hls';\n webOSVersion?: number | undefined;\n tizenVersion?: number | undefined;\n chromeVersion?: number | undefined;\n}\n\nfunction getChromeVersion(ua: string): number {\n const match = ua.match(/Chrome\\/(\\d+)/);\n return match && match[1] ? parseInt(match[1], 10) : 0;\n}\n\nfunction getWebKitVersion(ua: string): number {\n const match = ua.match(/AppleWebKit\\/(\\d+)/);\n return match && match[1] ? parseInt(match[1], 10) : 0;\n}\n\nfunction getPlatform(): string {\n if ('userAgentData' in navigator && navigator.userAgentData?.platform) {\n return navigator.userAgentData.platform;\n }\n\n const ua = navigator.userAgent;\n if (/Mac|iPhone|iPad|iPod/i.test(ua)) {\n return /iPhone|iPad|iPod/i.test(ua) ? 'iPhone' : 'MacIntel';\n }\n if (/Win/i.test(ua)) {\n return 'Win32';\n }\n if (/Linux/i.test(ua)) {\n return /Android/i.test(ua) ? 'Linux armv8l' : 'Linux x86_64';\n }\n if (/CrOS/i.test(ua)) {\n return 'CrOS';\n }\n\n // eslint-disable-next-line deprecation/deprecation\n return (navigator as any).platform || 'Unknown';\n}\n\nexport function detectBrowser(): BrowserInfo {\n const ua = navigator.userAgent;\n const platform = getPlatform();\n\n let name = 'Unknown';\n let version = '0';\n let majorVersion = 0;\n let isSmartTV = false;\n let isLegacyTV = false;\n let supportsIMA = true;\n let supportsModernJS = true;\n let recommendedAdPlayer: 'ima' | 'hls' = 'ima';\n let webOSVersion: number | undefined;\n let tizenVersion: number | undefined;\n let chromeVersionNum: number | undefined;\n\n const chromeVersion = getChromeVersion(ua);\n const webkitVersion = getWebKitVersion(ua);\n chromeVersionNum = chromeVersion > 0 ? chromeVersion : undefined;\n\n if (/Web0S|webOS|LG Browser|LGSTB/i.test(ua)) {\n name = 'LG WebOS';\n isSmartTV = true;\n \n let match = ua.match(/Web0S[/\\s]*([\\d.]+)/i) || ua.match(/webOS[/\\s]*([\\d.]+)/i);\n \n if (!match || !match[1]) {\n match = ua.match(/webOSTV[/\\s-]*([\\d.]+)/i) || ua.match(/webOS\\.TV[/\\s-]*([\\d.]+)/i);\n }\n \n if (match && match[1]) {\n version = match[1];\n const parts = version.split('.');\n majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;\n webOSVersion = majorVersion;\n } else if (chromeVersion > 0) {\n if (chromeVersion >= 79) {\n webOSVersion = 6;\n version = '6.0';\n majorVersion = 6;\n } else if (chromeVersion >= 68) {\n webOSVersion = 5;\n version = '5.0';\n majorVersion = 5;\n } else if (chromeVersion >= 53) {\n webOSVersion = 4;\n version = '4.0';\n majorVersion = 4;\n } else if (chromeVersion >= 38) {\n webOSVersion = 3;\n version = '3.0';\n majorVersion = 3;\n } else {\n webOSVersion = 2;\n version = '2.0';\n majorVersion = 2;\n }\n } else {\n version = 'Unknown';\n webOSVersion = undefined;\n }\n\n if (webOSVersion !== undefined && webOSVersion >= 4) {\n supportsIMA = true;\n recommendedAdPlayer = 'ima';\n isLegacyTV = false;\n } else if (webOSVersion !== undefined && webOSVersion >= 3) {\n if (chromeVersion >= 53) {\n supportsIMA = true;\n recommendedAdPlayer = 'ima';\n isLegacyTV = false;\n } else {\n supportsIMA = false;\n recommendedAdPlayer = 'hls';\n isLegacyTV = true;\n }\n } else if (chromeVersion >= 53) {\n supportsIMA = true;\n recommendedAdPlayer = 'ima';\n isLegacyTV = false;\n } else {\n supportsIMA = false;\n recommendedAdPlayer = 'hls';\n isLegacyTV = true;\n }\n } else if (/Tizen/i.test(ua)) {\n name = 'Samsung Tizen';\n isSmartTV = true;\n const match = ua.match(/Tizen[/\\s]*([\\d.]+)/i);\n version = match && match[1] ? match[1] : 'Unknown';\n if (version !== 'Unknown') {\n const parts = version.split('.');\n majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;\n tizenVersion = majorVersion;\n }\n \n if (tizenVersion !== undefined && tizenVersion >= 4) {\n supportsIMA = true;\n recommendedAdPlayer = 'ima';\n isLegacyTV = false;\n } else if (tizenVersion !== undefined && tizenVersion >= 3 && chromeVersion >= 47) {\n supportsIMA = true;\n recommendedAdPlayer = 'ima';\n isLegacyTV = false;\n } else if (chromeVersion >= 53) {\n supportsIMA = true;\n recommendedAdPlayer = 'ima';\n isLegacyTV = false;\n } else {\n supportsIMA = false;\n recommendedAdPlayer = 'hls';\n isLegacyTV = true;\n }\n } else if (/SMART-TV|SmartTV/i.test(ua)) {\n name = 'Smart TV';\n isSmartTV = true;\n if (chromeVersion >= 53) {\n supportsIMA = true;\n recommendedAdPlayer = 'ima';\n } else {\n supportsIMA = false;\n recommendedAdPlayer = 'hls';\n isLegacyTV = true;\n }\n } else if (/NetCast/i.test(ua)) {\n name = 'LG NetCast';\n isSmartTV = true;\n isLegacyTV = true;\n supportsIMA = false;\n recommendedAdPlayer = 'hls';\n } else if (/BRAVIA/i.test(ua)) {\n name = 'Sony BRAVIA';\n isSmartTV = true;\n if (chromeVersion >= 53) {\n supportsIMA = true;\n recommendedAdPlayer = 'ima';\n } else {\n supportsIMA = false;\n recommendedAdPlayer = 'hls';\n isLegacyTV = true;\n }\n } else {\n if (chromeVersion > 0) {\n name = 'Chrome';\n version = chromeVersion.toString();\n majorVersion = chromeVersion;\n\n if (chromeVersion < 50) {\n supportsIMA = false;\n supportsModernJS = false;\n recommendedAdPlayer = 'hls';\n }\n }\n\n if (webkitVersion > 0 && webkitVersion < 600) {\n supportsModernJS = false;\n if (chromeVersion < 50) {\n supportsIMA = false;\n recommendedAdPlayer = 'hls';\n }\n }\n }\n\n if (typeof Promise === 'undefined' ||\n typeof Map === 'undefined' ||\n typeof Set === 'undefined') {\n supportsModernJS = false;\n supportsIMA = false;\n recommendedAdPlayer = 'hls';\n }\n\n if (typeof URLSearchParams === 'undefined') {\n supportsModernJS = false;\n }\n\n return {\n name,\n version,\n majorVersion,\n isSmartTV,\n isLegacyTV,\n platform,\n supportsIMA,\n supportsModernJS,\n recommendedAdPlayer,\n webOSVersion,\n tizenVersion,\n chromeVersion: chromeVersionNum,\n };\n}\n\nexport function supportsGoogleIMA(): boolean {\n const browser = detectBrowser();\n\n if (browser.isLegacyTV) {\n return false;\n }\n\n if (typeof document === 'undefined' ||\n typeof document.createElement !== 'function') {\n return false;\n }\n\n try {\n const video = document.createElement('video');\n if (!video) {\n return false;\n }\n } catch (e) {\n return false;\n }\n\n if (typeof Promise === 'undefined') {\n return false;\n }\n\n return browser.supportsIMA;\n}\n\nexport function getRecommendedAdPlayer(): 'ima' | 'hls' {\n const browser = detectBrowser();\n return browser.recommendedAdPlayer;\n}\n\nexport function supportsModernJS(): boolean {\n try {\n return (\n typeof Promise !== 'undefined' &&\n typeof Map !== 'undefined' &&\n typeof Set !== 'undefined' &&\n typeof Array.from !== 'undefined' &&\n typeof Object.assign !== 'undefined' &&\n typeof Array.prototype.forEach !== 'undefined' &&\n typeof String.prototype.includes !== 'undefined'\n );\n } catch (e) {\n return false;\n }\n}\n\nexport function logBrowserInfo(debug: boolean = false): void {\n if (!debug) return;\n\n const browser = detectBrowser();\n const imaSupport = supportsGoogleIMA();\n\n console.log('[StormcloudVideoPlayer] Browser Compatibility Info:', {\n browser: `${browser.name} ${browser.version}`,\n platform: browser.platform,\n isSmartTV: browser.isSmartTV,\n isLegacyTV: browser.isLegacyTV,\n supportsIMA: imaSupport,\n supportsModernJS: browser.supportsModernJS,\n recommendedAdPlayer: browser.recommendedAdPlayer,\n ...(browser.webOSVersion !== undefined ? { webOSVersion: browser.webOSVersion } : {}),\n ...(browser.tizenVersion !== undefined ? { tizenVersion: browser.tizenVersion } : {}),\n ...(browser.chromeVersion !== undefined ? { chromeVersion: browser.chromeVersion } : {}),\n userAgent: navigator.userAgent,\n });\n}\n\nexport function getBrowserConfigOverrides(): {\n allowNativeHls?: boolean;\n} {\n const browser = detectBrowser();\n const overrides: { allowNativeHls?: boolean } = {};\n\n if (browser.isSmartTV) {\n overrides.allowNativeHls = true;\n }\n\n return overrides;\n}\n\nexport function supportsFeature(feature: string): boolean {\n switch (feature) {\n case 'ima':\n return supportsGoogleIMA();\n case 'urlsearchparams':\n return typeof URLSearchParams !== 'undefined';\n case 'textencoder':\n return typeof TextEncoder !== 'undefined';\n case 'promises':\n return typeof Promise !== 'undefined';\n case 'fetch':\n return typeof fetch !== 'undefined';\n case 'crypto':\n return typeof crypto !== 'undefined' && typeof crypto.subtle !== 'undefined';\n default:\n return false;\n }\n}\n\n"]}
|