stormcloud-video-player 0.3.17 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/ubuntu24/Dev/stormcloud-vp/lib/ui/StormcloudVideoPlayer.cjs","../../src/ui/StormcloudVideoPlayer.tsx","../../src/player/StormcloudVideoPlayer.ts","../../src/utils/browserCompat.ts","../../src/sdk/ima.ts","../../src/sdk/hlsAdPlayer.ts","../../src/utils/tracking.ts","../../src/utils/polyfills.ts"],"names":["__create","Object","create","__defProp","defineProperty","__getOwnPropDesc","__getOwnPropNames","getOwnPropertyDescriptor","getOwnPropertyNames","__hasOwnProp","prototype","hasOwnProperty","__export","target","all","name","get","enumerable","__copyProps","to","from","except","desc","key","call","__toESM","mod","isNodeMode","__getProtoOf","__esModule","value","__toCommonJS","StormcloudVideoPlayer_exports","StormcloudVideoPlayerComponent","module","exports","import_react","require","import_hls","getChromeVersion","ua","match","parseInt","getWebKitVersion","getPlatform","navigator","userAgentData","platform","userAgent","test","detectBrowser","version","majorVersion","isSmartTV","isLegacyTV","supportsIMA","supportsModernJS","recommendedAdPlayer","parts","split","chromeVersion","webkitVersion","toString","browser","URLSearchParams","supportsGoogleIMA","document","createElement","video","e","Promise","logBrowserInfo","debug","imaSupport","console","log","getBrowserConfigOverrides","overrides","adPlayerType","allowNativeHls","createImaController","options","adPlaying","contentVideoHidden","originalMutedState","originalVolume","volume","Number","isNaN","Math","max","min","listeners","Map","preloadedVast","preloadingVast","adVideoElement","setAdPlayingFlag","isPlaying","dataset","stormcloudAdPlaying","hideContentVideo","style","transition","opacity","setTimeout","visibility","showContentVideo","offsetHeight","muted","createAdVideoElement","position","top","left","width","height","objectFit","backgroundColor","zIndex","playsInline","addEventListener","adVideo","event","payload","Array","set","fn","window","warn","reject","Error","frameEl","frameElement","sandboxAttr","getAttribute","tokens","Set","map","t","trim","filter","length","allowsScripts","has","error","google","ima","resolve","existing","querySelector","timeout","clearTimeout","script","src","async","defer","setAttribute","onload","onerror","head","appendChild","adsManager","adsLoader","adContainerEl","adDisplayContainer","lastAdTagUrl","retryAttempts","maxRetries","backoffBaseMs","adsLoadedPromise","adsLoadedResolve","adsLoadedReject","makeAdsRequest","vastTagUrl","adsRequest","AdsRequest","adTagUrl","videoWidth","offsetWidth","clientWidth","videoHeight","clientHeight","linearAdSlotWidth","linearAdSlotHeight","nonLinearAdSlotWidth","nonLinearAdSlotHeight","setAdWillAutoPlay","willAutoPlay","paused","autoplay","setAdWillPlayMuted","willPlayMuted","vastLoadTimeout","requestAds","ensurePlaceholderContainer","container","pointerEvents","right","bottom","display","alignItems","justifyContent","parentElement","fetchVastDocument","response","fetch","mode","ok","status","text","destroyAdsManager","destroy","initialize","ensureImaLoaded","then","AdDisplayContainer","catch","currentReject","adsLoaderCls","message","URL","AdsLoader","AdsManagerLoadedEvent","Type","ADS_MANAGER_LOADED","evt","adsRenderingSettings","AdsRenderingSettings","enablePreloading","getAdsManager","AdEvent","AdErrorEvent","AD_ERROR","errorEvent","getError","getMessage","delay","pow","emit","continueLiveStreamDuringAds","play","CONTENT_PAUSE_REQUESTED","pause","STARTED","CONTENT_RESUME_REQUESTED","ALL_ADS_COMPLETED","adErrorEvent","preloadAds","inflight","xml","delete","finally","preloadPromise","hasPreloadedAd","adVolume","init","ViewMode","NORMAL","setVolume","start","stop","removeChild","clear","isAdPlaying","resize","on","listener","add","off","updateOriginalMutedState","nextVolume","getOriginalMutedState","getOriginalVolume","setAdVolume","clampedVolume","getAdVolume","getVolume","showPlaceholder","hidePlaceholder","createHlsAdPlayer","contentVideo","destroyed","licenseKey","mainHlsInstance","adHls","currentAd","sessionId","preloadingAds","pendingTimeouts","trackingFired","impression","firstQuartile","midpoint","generateSessionId","Date","now","random","substr","fireTrackingPixels","urls","forEach","url","trackingUrl","includes","img","Image","getMainStreamQuality","resolutionDiff","levels","currentLevel","autoLevel","loadLevel","level","bitrate","selectBestMediaFile","mediaFiles","firstFile","mainQuality","scoredFiles","file","widthDiff","heightDiff","abs","fileBitrate","bitrateDiff","score","sort","a","b","bestMatch","resolution","parseVastXml","xmlString","xmlDoc","parser","DOMParser","parseFromString","parserError","textContent","adElement","adId","title","isNoAdAvailable","toLowerCase","durationText","durationParts","duration","mediaFileElements","querySelectorAll","mf","index","type","bitrateAttr","bitrateValue","push","trackingUrls","thirdQuartile","complete","mute","unmute","resume","fullscreen","exitFullscreen","skip","el","eventKey","clickThrough","id","fetchAndParseVastAd","vastXml","statusText","substring","progress","setupAdEventListeners","currentTime","handleAdComplete","handleAdError","ended","timeoutId","stillInPod","idx","indexOf","splice","previousMutedState","ad","preloadedAds","contentVolume","mediaFile","Hls","isSupported","enableWorker","lowLatencyMode","loadSource","attachMedia","Events","MANIFEST_PARSED","ERROR","data","fatal","canPlayType","remove","cachedBrowserId","getClientInfo","vendor","maxTouchPoints","memory","deviceMemory","hardwareConcurrency","screenInfo","screen","availWidth","availHeight","orientation","pixelDepth","deviceType","brand","os","model","isAndroid","isWebView","isWebApp","webosMatch","tizenMatch","tvMatch","androidModelMatch","outerHeight","outerWidth","matchMedia","matches","standalone","angle","location","domain","referrer","hostname","origin","path","pathname","language","languages","join","doNotTrack","visibilityState","getBrowserID","clientInfo","fingerprintString","JSON","stringify","crypto","subtle","digest","Uint8Array","TextEncoder","encodedData","encode","utf8","unescape","encodeURIComponent","i","buffer","charCodeAt","hashBuffer","hashArray","hashHex","padStart","hash","char","fallbackHash","timestamp","padEnd","sendInitialTracking","browserId","trackingData","headers","method","body","json","sendHeartbeat","heartbeatData","toISOString","polyfillURLSearchParams","URLSearchParamsPolyfill","params","parseQueryString","append","query","cleanQuery","startsWith","slice","param","decodedKey","safeDecodeURIComponent","decodedValue","str","values","String","getAll","callback","polyfillTextEncoder","TextEncoderPolyfill","encoding","charcode","polyfillPromiseFinally","constructor","reason","polyfillObjectAssign","assign","sources","TypeError","nextSource","nextKey","polyfillArrayFrom","arrayLike","mapFn","thisArg","items","len","result","polyfillStringStartsWith","search","pos","polyfillStringEndsWith","endsWith","polyfillStringIncludes","initializePolyfills","StormcloudVideoPlayer","config","attached","inAdBreak","ptsDriftEmaMs","adPodQueue","lastHeartbeatTime","currentAdIndex","totalAdsInBreak","showAds","isLiveStream","nativeHlsMode","videoSrcProtection","bufferedSegmentsCount","shouldAutoplayAfterBuffering","hasInitialBufferCompleted","adPodAllUrls","preloadingAdUrls","vastToMediaUrlMap","preloadedMediaUrls","preloadingMediaUrls","adRequestTokenCounter","activeAdRequestToken","adRequestWatchdogToken","adFailsafeToken","targetAdBreakDurationMs","isAdaptiveMode","failedVastUrls","continuousFetchingActive","adRequestQueue","successfulAdRequests","maxPlaceholderDurationMs","placeholderStartTimeMs","isShowingPlaceholder","browserOverrides","videoElement","debugAdTiming","createAdPlayer","vastMode","hls","load","attach","fetchAdConfiguration","initializeTracking","shouldUseNativeHls","isLive","adBehavior","import_hls2","liveDurationInfinity","maxLiveSyncPlaybackRate","liveSyncDuration","maxBufferLength","maxMaxBufferLength","maxBufferSize","highBufferWatchdogPeriod","nudgeOffset","nudgeMaxRetry","startPosition","MEDIA_ATTACHED","_","minSegments","some","details","live","shouldContinueLiveStreamDuringAds","minSegmentsBeforePlay","FRAG_BUFFERED","_evt","err","attrs","parseAttributeList","FRAG_PARSING_METADATA","s","ptsSeconds","pts","id3Tags","tag","onId3Tag","FRAG_CHANGED","frag","tagList","isArray","entry","durationSeconds","parseCueOutDuration","marker","raw","onScte35Marker","prog","parseCueOutCont","elapsed","hasScteOut","hasScteIn","klass","toNumber","ErrorTypes","NETWORK_ERROR","startLoad","MEDIA_ERROR","recoverMediaError","handleAdPodComplete","errorPayload","remaining","getRemainingAdMs","nextPreloaded","findNextPreloadedAd","playSingleAd","handleAdFailure","clearAdFailsafeTimer","clearAdRequestWatchdog","tryNextAvailableAd","streamType","timeUpdateHandler","onTimeUpdate","emptiedHandler","wasPaused","getStreamType","canNative","updatePtsDrift","parseScte35FromId3","decodeId3ValueToText","cueOutMatch","arg","dur","id3","cueOutContMatch","cont","cueInMatch","daterangeMatch","bin","parseScte35Binary","decoder","TextDecoder","decode","out","fromCharCode","durationMs","expectedAdBreakDurationMs","currentAdBreakStartWallClockMs","isManifestMarker","isManifestBasedMarker","forceImmediate","immediateManifestAds","hasPts","clearAdStartTimer","handleAdStart","tol","driftToleranceMs","nowMs","estCurrentPtsMs","deltaMs","floor","markerPtsMs","tolerance","scheduleAdStartIn","scheduleAdStopCountdown","elapsedMs","remainingMs","scheduled","findCurrentOrNextBreak","tags","selectVastTagsForBreak","apiVastTagUrl","first","rest","clearAdStopTimer","num","parseFloat","dStr","d","elapsedMatch","durationMatch","res","regex","exec","rawVal","val","n","splice_command_type","BitReader","buf","bitPos","readBits","numBits","bytePos","remainingInByte","toRead","currentByte","shift","mask","bits","skipBits","r","tableId","sectionLength","ptsAdjHigh","ptsAdjLow","spliceCommandLength","spliceCommandType","cancel","outOfNetwork","programSpliceFlag","durationFlag","timeSpecifiedFlag","spliceImmediateFlag","componentCount","high","low","durationTicks","heartbeatInterval","setInterval","sendHeartbeatIfNeeded","vastEndpoint","apiUrl","imaPayload","numberAds","vast","cue_tones","number_ads","apiNumberAds","getCurrentAdIndex","getTotalAdsInBreak","generateVastUrlsWithCorrelators","baseUrl","count","searchParams","uniqueCorrelator","isShowingAds","shouldShowNativeControls","showCustomControls","_marker","baseVastUrl","adBreakDurationMs","currentMuted","currentVolume","firstAdUrlArray","firstAdUrl","fetchedAdDurations","startContinuousFetching","continuousFetchLoop","maxQueueSize","newAdUrl","xmlText","stopContinuousFetching","retryCount","nextAdUrl","showPlaceholderAndWaitForAds","waitTime","checkInterval","maxChecks","schedule","candidate","currentTimeSec","breakToPlay","findBreakForTime","handleMidAdJoin","adBreak","endMs","startTimeMs","ms","ensureAdStoppedByTimer","adStopTimerId","adStartTimerId","ptsSecondsSample","sampleMs","isFinite","alpha","requestToken","playError","startAdRequestWatchdog","restoredMuted","restoredVolume","token","timeoutMs","adFailsafeTimeoutMs","adRequestWatchdogId","logAdState","startAdFailsafeTimer","failsafeMs","adFailsafeTimerId","videoPaused","imaAdPlaying","extra","fetchAndParseVastXml","extractMediaUrlsFromVast","lowerUrl","mediaUrls","fetchVastDuration","calculateAdditionalAdsNeeded","totalFetchedDurationMs","size","fetchedCount","queuedButNotFetched","averageDurationMs","estimatedQueuedDurationMs","estimatedTotalDurationMs","remainingTimeMs","additionalAds","addAdaptiveAdsToQueue","newUrls","preloadMediaFile","mediaUrl","Range","preloadAllAdsInBackground","processedUrls","nextUrl","preloadPromises","find","preloadSingleAd","primaryMediaUrl","hasImaPreload","hasMediaPreload","end","toggleMute","currentPerceptualState","isMuted","newMutedState","toggleFullscreen","fullscreenElement","requestFullscreen","setMuted","isFullscreen","removeEventListener","clearInterval"],"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/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 if (/Web0S|webOS/i.test(ua)) {\n name = \"LG WebOS\";\n isSmartTV = true;\n const match = ua.match(/Web0S[/\\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 }\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 }\n } else if (/SMART-TV|SmartTV/i.test(ua)) {\n name = \"Smart TV\";\n isSmartTV = true;\n } else if (/NetCast/i.test(ua)) {\n name = \"LG NetCast\";\n isSmartTV = true;\n isLegacyTV = true;\n } else if (/BRAVIA/i.test(ua)) {\n name = \"Sony BRAVIA\";\n isSmartTV = true;\n }\n const chromeVersion = getChromeVersion(ua);\n const webkitVersion = getWebKitVersion(ua);\n if (chromeVersion > 0) {\n if (!isSmartTV) {\n name = \"Chrome\";\n version = chromeVersion.toString();\n majorVersion = chromeVersion;\n }\n if (chromeVersion < 50) {\n supportsIMA = false;\n supportsModernJS = false;\n isLegacyTV = true;\n recommendedAdPlayer = \"hls\";\n }\n }\n if (webkitVersion > 0 && webkitVersion < 600) {\n supportsModernJS = false;\n if (isSmartTV) {\n isLegacyTV = true;\n supportsIMA = false;\n recommendedAdPlayer = \"hls\";\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 };\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 userAgent: navigator.userAgent\n });\n}\nfunction getBrowserConfigOverrides() {\n const browser = detectBrowser();\n const overrides = {};\n if (browser.isLegacyTV || !browser.supportsIMA) {\n overrides.adPlayerType = \"hls\";\n }\n if (browser.isSmartTV) {\n overrides.allowNativeHls = true;\n }\n return overrides;\n}\n\n// src/sdk/ima.ts\nfunction createImaController(video, options) {\n let adPlaying = false;\n let contentVideoHidden = false;\n let originalMutedState = false;\n let originalVolume = typeof video.volume === \"number\" && !Number.isNaN(video.volume) ? Math.max(0, Math.min(1, video.volume)) : 1;\n const listeners = /* @__PURE__ */ new Map();\n const preloadedVast = /* @__PURE__ */ new Map();\n const preloadingVast = /* @__PURE__ */ new Map();\n let adVideoElement;\n function setAdPlayingFlag(isPlaying) {\n if (isPlaying) {\n video.dataset.stormcloudAdPlaying = \"true\";\n } else {\n delete video.dataset.stormcloudAdPlaying;\n }\n }\n function hideContentVideo() {\n if (!contentVideoHidden) {\n video.style.transition = \"opacity 0.3s ease-in-out\";\n video.style.opacity = \"0\";\n setTimeout(() => {\n video.style.visibility = \"hidden\";\n }, 300);\n video.muted = true;\n video.volume = 0;\n contentVideoHidden = true;\n }\n }\n function showContentVideo() {\n if (contentVideoHidden) {\n video.style.visibility = \"visible\";\n video.style.transition = \"opacity 0.3s ease-in-out\";\n video.offsetHeight;\n video.style.opacity = \"1\";\n video.muted = originalMutedState;\n video.volume = originalVolume;\n contentVideoHidden = false;\n }\n }\n function createAdVideoElement() {\n const adVideo = document.createElement(\"video\");\n adVideo.style.position = \"absolute\";\n adVideo.style.top = \"0\";\n adVideo.style.left = \"0\";\n adVideo.style.width = \"100%\";\n adVideo.style.height = \"100%\";\n adVideo.style.objectFit = \"contain\";\n adVideo.style.backgroundColor = \"transparent\";\n adVideo.style.zIndex = \"15\";\n adVideo.playsInline = true;\n adVideo.muted = false;\n adVideo.volume = originalMutedState ? 0 : originalVolume;\n adVideo.style.opacity = \"0\";\n adVideo.addEventListener(\n \"canplay\",\n () => {\n adVideo.style.opacity = \"1\";\n },\n { once: true }\n );\n return adVideo;\n }\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 {\n }\n }\n }\n function ensureImaLoaded() {\n if (!supportsGoogleIMA()) {\n console.warn(\n \"[IMA] Google IMA SDK is not supported on this browser. Please use HLS ad player instead.\"\n );\n return Promise.reject(\n new Error(\"Google IMA SDK not supported on this browser\")\n );\n }\n try {\n const frameEl = window.frameElement;\n const sandboxAttr = frameEl?.getAttribute?.(\"sandbox\") || \"\";\n if (sandboxAttr) {\n const tokens = new Set(\n sandboxAttr.split(/\\s+/).map((t) => t.trim()).filter((t) => t.length > 0)\n );\n const allowsScripts = tokens.has(\"allow-scripts\");\n if (!allowsScripts) {\n console.error(\n \"StormcloudVideoPlayer: The host page is inside a sandboxed iframe without 'allow-scripts'. Google IMA cannot run ads within sandboxed frames. Remove the sandbox attribute or include 'allow-scripts allow-same-origin'.\"\n );\n }\n }\n } catch {\n }\n if (typeof window !== \"undefined\" && window.google?.ima)\n return Promise.resolve();\n const existing = document.querySelector(\n 'script[data-ima=\"true\"]'\n );\n if (existing) {\n if (window.google?.ima) {\n return Promise.resolve();\n }\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error(\"IMA SDK load timeout\"));\n }, 1e4);\n existing.addEventListener(\"load\", () => {\n clearTimeout(timeout);\n resolve();\n });\n existing.addEventListener(\"error\", () => {\n clearTimeout(timeout);\n reject(new Error(\"IMA SDK load failed\"));\n });\n });\n }\n return new Promise((resolve, reject) => {\n const script = document.createElement(\"script\");\n script.src = \"https://imasdk.googleapis.com/js/sdkloader/ima3.js\";\n script.async = true;\n script.defer = true;\n script.setAttribute(\"data-ima\", \"true\");\n script.onload = () => resolve();\n script.onerror = () => reject(new Error(\"IMA SDK load failed\"));\n document.head.appendChild(script);\n });\n }\n let adsManager;\n let adsLoader;\n let adDisplayContainer;\n let adContainerEl;\n let lastAdTagUrl;\n let retryAttempts = 0;\n const maxRetries = 2;\n const backoffBaseMs = 500;\n let adsLoadedPromise;\n let adsLoadedResolve;\n let adsLoadedReject;\n function makeAdsRequest(google, vastTagUrl) {\n const adsRequest = new google.ima.AdsRequest();\n console.log(\"[IMA] \\u{1F4E1} Requesting VAST from URL (letting IMA fetch fresh)\");\n adsRequest.adTagUrl = vastTagUrl;\n const videoWidth = video.offsetWidth || video.clientWidth || 640;\n const videoHeight = video.offsetHeight || video.clientHeight || 360;\n adsRequest.linearAdSlotWidth = videoWidth;\n adsRequest.linearAdSlotHeight = videoHeight;\n adsRequest.nonLinearAdSlotWidth = videoWidth;\n adsRequest.nonLinearAdSlotHeight = videoHeight;\n if (typeof adsRequest.setAdWillAutoPlay === \"function\") {\n try {\n const willAutoPlay = !video.paused || video.autoplay;\n adsRequest.setAdWillAutoPlay(willAutoPlay);\n } catch (error) {\n console.warn(\"[IMA] Failed to call setAdWillAutoPlay:\", error);\n }\n }\n if (typeof adsRequest.setAdWillPlayMuted === \"function\") {\n try {\n const willPlayMuted = video.muted || video.volume === 0;\n adsRequest.setAdWillPlayMuted(willPlayMuted);\n } catch (error) {\n console.warn(\"[IMA] Failed to call setAdWillPlayMuted:\", error);\n }\n }\n adsRequest.vastLoadTimeout = 1e4;\n adsLoader.requestAds(adsRequest);\n }\n function ensurePlaceholderContainer() {\n if (adContainerEl) {\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 = \"10\";\n container.style.backgroundColor = \"transparent\";\n container.style.transition = \"opacity 0.3s ease-in-out, background-color 0.3s ease-in-out\";\n container.style.opacity = \"0\";\n video.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n async function fetchVastDocument(vastTagUrl) {\n const response = await fetch(vastTagUrl, { mode: \"cors\" });\n if (!response.ok) {\n throw new Error(`Failed to preload VAST: ${response.status}`);\n }\n return response.text();\n }\n function destroyAdsManager() {\n if (adsManager) {\n try {\n adsManager.destroy();\n } catch {\n }\n adsManager = void 0;\n }\n if (adVideoElement) {\n adVideoElement.style.opacity = \"0\";\n }\n }\n return {\n initialize() {\n ensureImaLoaded().then(() => {\n const google = window.google;\n ensurePlaceholderContainer();\n if (!adDisplayContainer && adContainerEl) {\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl.appendChild(adVideoElement);\n }\n adDisplayContainer = new google.ima.AdDisplayContainer(\n adContainerEl,\n adVideoElement\n );\n try {\n adDisplayContainer.initialize?.();\n } catch {\n }\n }\n }).catch(() => {\n });\n },\n async requestAds(vastTagUrl) {\n if (!vastTagUrl || vastTagUrl.trim() === \"\") {\n const error = new Error(\"VAST tag URL is empty or undefined\");\n console.warn(\"[IMA] \\u274C\", error.message);\n return Promise.reject(error);\n }\n try {\n new URL(vastTagUrl);\n } catch (e) {\n const error = new Error(`Invalid VAST tag URL format: ${vastTagUrl}`);\n console.warn(\"[IMA] \\u274C\", error.message);\n return Promise.reject(error);\n }\n if (adPlaying) {\n console.warn(\n \"[IMA] \\u26A0\\uFE0F Cannot request new ads while an ad is playing. Call stop() first.\"\n );\n return Promise.reject(\n new Error(\"Ad already playing - cannot request new ads\")\n );\n }\n destroyAdsManager();\n adsLoadedReject = void 0;\n adsLoadedResolve = void 0;\n let currentReject;\n adsLoadedPromise = new Promise((resolve, reject) => {\n adsLoadedResolve = resolve;\n adsLoadedReject = reject;\n currentReject = reject;\n setTimeout(() => {\n if (adsLoadedReject) {\n adsLoadedReject(new Error(\"Ad request timeout\"));\n adsLoadedReject = void 0;\n adsLoadedResolve = void 0;\n }\n }, 1e4);\n });\n try {\n await ensureImaLoaded();\n const google = window.google;\n lastAdTagUrl = vastTagUrl;\n retryAttempts = 0;\n if (!adDisplayContainer) {\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 = \"transparent\";\n container.style.transition = \"opacity 0.3s ease-in-out, background-color 0.3s ease-in-out\";\n container.style.opacity = \"0\";\n if (!video.parentElement) {\n throw new Error(\"Video element has no parent for ad container\");\n }\n video.parentElement.appendChild(container);\n adContainerEl = container;\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl.appendChild(adVideoElement);\n }\n adDisplayContainer = new google.ima.AdDisplayContainer(\n container,\n adVideoElement\n );\n }\n const videoWidth = video.offsetWidth || video.clientWidth;\n const videoHeight = video.offsetHeight || video.clientHeight;\n if (!videoWidth || !videoHeight || videoWidth === 0 || videoHeight === 0) {\n const error = new Error(\n `Invalid video dimensions: ${videoWidth}x${videoHeight}. Cannot initialize ads.`\n );\n console.warn(\"[IMA]\", error.message);\n currentReject?.(error);\n adsLoadedReject = void 0;\n adsLoadedResolve = void 0;\n return Promise.reject(error);\n }\n if (!adsLoader) {\n const adsLoaderCls = new google.ima.AdsLoader(adDisplayContainer);\n adsLoader = adsLoaderCls;\n adsLoader.addEventListener(\n google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,\n (evt) => {\n try {\n const adsRenderingSettings = new google.ima.AdsRenderingSettings();\n adsRenderingSettings.enablePreloading = true;\n adsManager = evt.getAdsManager(video, adsRenderingSettings);\n const AdEvent = google.ima.AdEvent.Type;\n const AdErrorEvent = google.ima.AdErrorEvent.Type;\n adsManager.addEventListener(\n AdErrorEvent.AD_ERROR,\n (errorEvent) => {\n const error = errorEvent.getError();\n console.error(\"[DEBUG-ERROR] \\u274C AD_ERROR:\", error.getMessage?.());\n destroyAdsManager();\n adPlaying = false;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n adContainerEl.style.backgroundColor = \"transparent\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n }\n }, 300);\n }\n showContentVideo();\n if (adsLoadedReject) {\n adsLoadedReject(new Error(\"Ad playback error\"));\n adsLoadedReject = void 0;\n adsLoadedResolve = void 0;\n }\n if (lastAdTagUrl && retryAttempts < maxRetries) {\n const delay = backoffBaseMs * Math.pow(2, retryAttempts++);\n window.setTimeout(() => {\n try {\n makeAdsRequest(google, lastAdTagUrl);\n } catch {\n }\n }, delay);\n } else {\n emit(\"ad_error\");\n if (!options?.continueLiveStreamDuringAds) {\n if (video.paused) {\n video.play()?.catch(() => {\n });\n }\n }\n }\n }\n );\n adsManager.addEventListener(\n AdEvent.CONTENT_PAUSE_REQUESTED,\n () => {\n if (!options?.continueLiveStreamDuringAds) {\n video.pause();\n }\n adPlaying = true;\n setAdPlayingFlag(true);\n emit(\"content_pause\");\n }\n );\n adsManager.addEventListener(AdEvent.STARTED, () => {\n setAdPlayingFlag(true);\n hideContentVideo();\n if (adVideoElement) {\n adVideoElement.volume = originalMutedState ? 0 : originalVolume;\n adVideoElement.muted = originalMutedState;\n }\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"auto\";\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.backgroundColor = \"#000\";\n adContainerEl.offsetHeight;\n adContainerEl.style.opacity = \"1\";\n }\n });\n adsManager.addEventListener(\n AdEvent.CONTENT_RESUME_REQUESTED,\n () => {\n adPlaying = false;\n setAdPlayingFlag(false);\n emit(\"content_resume\");\n }\n );\n adsManager.addEventListener(AdEvent.ALL_ADS_COMPLETED, () => {\n adPlaying = false;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n adContainerEl.style.backgroundColor = \"transparent\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n }\n }, 300);\n }\n showContentVideo();\n if (!options?.continueLiveStreamDuringAds && video.paused) {\n video.play().catch(() => {\n });\n }\n emit(\"all_ads_completed\");\n });\n if (adsLoadedResolve) {\n adsLoadedResolve();\n adsLoadedResolve = void 0;\n adsLoadedReject = void 0;\n }\n } catch (e) {\n console.error(\"[IMA] Error setting up ads manager:\", e);\n adPlaying = false;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n adContainerEl.style.backgroundColor = \"transparent\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n }\n }, 300);\n }\n showContentVideo();\n if (!options?.continueLiveStreamDuringAds) {\n if (video.paused) {\n video.play().catch(() => {\n });\n }\n }\n if (adsLoadedReject) {\n adsLoadedReject(new Error(\"Failed to setup ads manager\"));\n adsLoadedReject = void 0;\n adsLoadedResolve = void 0;\n }\n emit(\"ad_error\");\n }\n },\n false\n );\n adsLoader.addEventListener(\n google.ima.AdErrorEvent.Type.AD_ERROR,\n (adErrorEvent) => {\n const error = adErrorEvent.getError();\n console.error(\"[DEBUG-ERROR] \\u274C ADS_LOADER ERROR:\", error.getMessage?.());\n adPlaying = false;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n adContainerEl.style.backgroundColor = \"transparent\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n }\n }, 300);\n }\n showContentVideo();\n if (!options?.continueLiveStreamDuringAds) {\n if (video.paused) {\n video.play().catch(() => {\n });\n }\n }\n if (adsLoadedReject) {\n adsLoadedReject(new Error(\"Ads loader error\"));\n adsLoadedReject = void 0;\n adsLoadedResolve = void 0;\n }\n emit(\"ad_error\");\n },\n false\n );\n }\n makeAdsRequest(google, vastTagUrl);\n return adsLoadedPromise;\n } catch (error) {\n console.error(\"[IMA] Failed to request ads:\", error);\n currentReject?.(error);\n adsLoadedReject = void 0;\n adsLoadedResolve = void 0;\n return Promise.reject(error);\n }\n },\n async preloadAds(vastTagUrl) {\n if (!vastTagUrl || vastTagUrl.trim() === \"\") {\n return Promise.resolve();\n }\n if (preloadedVast.has(vastTagUrl)) {\n return Promise.resolve();\n }\n const inflight = preloadingVast.get(vastTagUrl);\n if (inflight) {\n return inflight;\n }\n const preloadPromise = fetchVastDocument(vastTagUrl).then((xml) => {\n preloadedVast.set(vastTagUrl, xml);\n }).catch(() => {\n preloadedVast.delete(vastTagUrl);\n }).finally(() => {\n preloadingVast.delete(vastTagUrl);\n });\n preloadingVast.set(vastTagUrl, preloadPromise);\n return preloadPromise;\n },\n hasPreloadedAd(vastTagUrl) {\n return preloadedVast.has(vastTagUrl);\n },\n async play() {\n if (!window.google?.ima || !adDisplayContainer) {\n return Promise.reject(new Error(\"IMA SDK not available\"));\n }\n if (!adsManager) {\n return Promise.reject(new Error(\"No ads manager\"));\n }\n try {\n const width = video.clientWidth || 640;\n const height = video.clientHeight || 360;\n adsManager.init(width, height, window.google.ima.ViewMode.NORMAL);\n adPlaying = true;\n const adVolume = originalMutedState ? 0 : originalVolume;\n if (adVideoElement) {\n adVideoElement.volume = adVolume;\n adVideoElement.muted = originalMutedState;\n }\n try {\n adsManager.setVolume(adVolume);\n } catch {\n }\n adsManager.start();\n return Promise.resolve();\n } catch (error) {\n console.error(\"[IMA] \\u274C Error starting ad:\", error);\n adPlaying = false;\n setAdPlayingFlag(false);\n if (!options?.continueLiveStreamDuringAds) {\n video.play()?.catch(() => {\n });\n }\n return Promise.reject(error);\n }\n },\n async stop() {\n adPlaying = false;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n adContainerEl.style.backgroundColor = \"transparent\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n }\n }, 300);\n }\n showContentVideo();\n try {\n adsManager?.stop?.();\n } catch {\n }\n destroyAdsManager();\n },\n destroy() {\n destroyAdsManager();\n adPlaying = false;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n adContainerEl.style.backgroundColor = \"transparent\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n if (adContainerEl.parentElement) {\n adContainerEl.parentElement.removeChild(adContainerEl);\n }\n adContainerEl = void 0;\n adVideoElement = void 0;\n }\n }, 300);\n }\n showContentVideo();\n try {\n adsLoader?.destroy?.();\n } catch {\n }\n adDisplayContainer = void 0;\n adsLoader = void 0;\n contentVideoHidden = false;\n preloadedVast.clear();\n preloadingVast.clear();\n },\n isAdPlaying() {\n return adPlaying;\n },\n resize(width, height) {\n if (!adsManager || !window.google?.ima) {\n console.warn(\n \"[IMA] Cannot resize: No ads manager or IMA SDK available\"\n );\n return;\n }\n try {\n console.log(`[IMA] Resizing ads manager to ${width}x${height}`);\n adsManager.resize(width, height, window.google.ima.ViewMode.NORMAL);\n } catch (error) {\n console.warn(\"[IMA] Error resizing ads manager:\", error);\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 const clampedVolume = Math.max(0, Math.min(1, volume));\n if (adVideoElement && adPlaying) {\n adVideoElement.volume = clampedVolume;\n adVideoElement.muted = clampedVolume === 0;\n }\n if (adsManager && adPlaying) {\n try {\n adsManager.setVolume(clampedVolume);\n } catch {\n }\n }\n },\n getAdVolume() {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n if (adsManager && adPlaying) {\n try {\n return adsManager.getVolume();\n } catch (error) {\n console.warn(\"[IMA] Failed to get ad volume:\", error);\n return 1;\n }\n }\n return 1;\n },\n showPlaceholder() {\n ensurePlaceholderContainer();\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.backgroundColor = \"#000\";\n adContainerEl.offsetHeight;\n adContainerEl.style.opacity = \"1\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n },\n hidePlaceholder() {\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n adContainerEl.style.backgroundColor = \"transparent\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n }\n };\n}\n\n// src/sdk/hlsAdPlayer.ts\nvar import_hls = __toESM(require(\"hls.js\"), 1);\nfunction createHlsAdPlayer(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 const licenseKey = options?.licenseKey;\n const mainHlsInstance = options?.mainHlsInstance;\n let adVideoElement;\n let adHls;\n let adContainerEl;\n let currentAd;\n let sessionId;\n const preloadedAds = /* @__PURE__ */ new Map();\n const preloadingAds = /* @__PURE__ */ new Map();\n let destroyed = false;\n let pendingTimeouts = [];\n let trackingFired = {\n impression: false,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false\n };\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(\n `[HlsAdPlayer] Error in event listener for ${event}:`,\n error\n );\n }\n }\n }\n function generateSessionId() {\n return `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }\n function fireTrackingPixels(urls) {\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 if (licenseKey) {\n trackingUrl = `${trackingUrl}${trackingUrl.includes(\"?\") ? \"&\" : \"?\"}license_key=${licenseKey}`;\n }\n const img = new Image(1, 1);\n img.src = trackingUrl;\n console.log(`[HlsAdPlayer] Fired tracking pixel: ${trackingUrl}`);\n } catch (error) {\n console.warn(`[HlsAdPlayer] Error firing tracking pixel:`, error);\n }\n });\n }\n function getMainStreamQuality() {\n if (!mainHlsInstance || !mainHlsInstance.levels) {\n return null;\n }\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) {\n throw new Error(\"No media files available\");\n }\n const firstFile = mediaFiles[0];\n if (!firstFile) {\n throw new Error(\"No media files available\");\n }\n if (mediaFiles.length === 1) {\n return firstFile;\n }\n const mainQuality = getMainStreamQuality();\n if (!mainQuality) {\n console.log(\n \"[HlsAdPlayer] No main stream quality info, using first media file\"\n );\n return firstFile;\n }\n console.log(\"[HlsAdPlayer] Main stream quality:\", mainQuality);\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, resolutionDiff, bitrateDiff };\n });\n scoredFiles.sort((a, b) => a.score - b.score);\n const bestMatch = scoredFiles[0];\n if (!bestMatch) {\n console.log(\"[HlsAdPlayer] No best match found, using first media file\");\n return firstFile;\n }\n console.log(\"[HlsAdPlayer] Selected media file:\", {\n url: bestMatch.file.url,\n resolution: `${bestMatch.file.width}x${bestMatch.file.height}`,\n bitrate: bestMatch.file.bitrate,\n score: bestMatch.score,\n resolutionDiff: bestMatch.resolutionDiff,\n bitrateDiff: bestMatch.bitrateDiff\n });\n return bestMatch.file;\n }\n function parseVastXml(xmlString) {\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 \"[HlsAdPlayer] 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(\"[HlsAdPlayer] 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 + parseInt(durationParts[2] || \"0\", 10);\n const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n const mediaFiles = [];\n console.log(\n `[HlsAdPlayer] 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 `[HlsAdPlayer] MediaFile ${index}: type=\"${type}\", url=\"${url}\", width=\"${width}\", height=\"${height}\"`\n );\n if (type === \"application/x-mpegURL\" || type.includes(\"m3u8\")) {\n if (!url) {\n console.warn(\n `[HlsAdPlayer] MediaFile ${index} has HLS type but empty URL`\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(`[HlsAdPlayer] Added HLS MediaFile: ${url}`);\n } else {\n console.log(\n `[HlsAdPlayer] MediaFile ${index} ignored (type=\"${type}\" is not HLS)`\n );\n }\n });\n if (mediaFiles.length === 0) {\n if (isNoAdAvailable) {\n console.warn(\n \"[HlsAdPlayer] No ads available (VAST response indicates no ads)\"\n );\n } else {\n console.warn(\"[HlsAdPlayer] No HLS 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(\"[HlsAdPlayer] Error parsing VAST XML:\", error);\n return null;\n }\n }\n async function fetchAndParseVastAd(vastTagUrl) {\n const response = await fetch(vastTagUrl);\n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.statusText}`);\n }\n const vastXml = await response.text();\n console.log(\"[HlsAdPlayer] VAST XML received\");\n console.log(\n \"[HlsAdPlayer] VAST XML content (first 2000 chars):\",\n vastXml.substring(0, 2e3)\n );\n return parseVastXml(vastXml);\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 console.log(\n `[HlsAdPlayer] Created ad video element with volume ${video.volume}`\n );\n return video;\n }\n function setupAdEventListeners() {\n if (!adVideoElement || !currentAd) return;\n adVideoElement.addEventListener(\"timeupdate\", () => {\n if (!currentAd || !adVideoElement) return;\n const progress = adVideoElement.currentTime / currentAd.duration;\n if (progress >= 0.25 && !trackingFired.firstQuartile) {\n trackingFired.firstQuartile = true;\n fireTrackingPixels(currentAd.trackingUrls.firstQuartile);\n }\n if (progress >= 0.5 && !trackingFired.midpoint) {\n trackingFired.midpoint = true;\n fireTrackingPixels(currentAd.trackingUrls.midpoint);\n }\n if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n trackingFired.thirdQuartile = true;\n fireTrackingPixels(currentAd.trackingUrls.thirdQuartile);\n }\n });\n adVideoElement.addEventListener(\"playing\", () => {\n if (!currentAd || trackingFired.start) return;\n trackingFired.start = true;\n fireTrackingPixels(currentAd.trackingUrls.start);\n console.log(\"[HlsAdPlayer] Ad started playing\");\n });\n adVideoElement.addEventListener(\"ended\", () => {\n if (!currentAd || trackingFired.complete) return;\n trackingFired.complete = true;\n fireTrackingPixels(currentAd.trackingUrls.complete);\n console.log(\"[HlsAdPlayer] Ad completed\");\n handleAdComplete();\n });\n adVideoElement.addEventListener(\"error\", (e) => {\n console.error(\"[HlsAdPlayer] Ad video error:\", e);\n if (currentAd) {\n fireTrackingPixels(currentAd.trackingUrls.error);\n }\n handleAdError();\n });\n adVideoElement.addEventListener(\"volumechange\", () => {\n if (!currentAd) return;\n if (adVideoElement.muted) {\n fireTrackingPixels(currentAd.trackingUrls.mute);\n } else {\n fireTrackingPixels(currentAd.trackingUrls.unmute);\n }\n });\n adVideoElement.addEventListener(\"pause\", () => {\n if (currentAd && !adVideoElement.ended) {\n fireTrackingPixels(currentAd.trackingUrls.pause);\n }\n });\n adVideoElement.addEventListener(\"play\", () => {\n if (currentAd && adVideoElement.currentTime > 0) {\n fireTrackingPixels(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 console.log(\"[HlsAdPlayer] Handling ad completion\");\n adPlaying = false;\n setAdPlayingFlag(false);\n emit(\"content_resume\");\n const timeoutId = window.setTimeout(() => {\n if (destroyed) {\n console.log(\"[HlsAdPlayer] Player destroyed, skipping post-completion check\");\n return;\n }\n const stillInPod = contentVideo.dataset.stormcloudAdPlaying === \"true\";\n if (stillInPod) {\n console.log(\n \"[HlsAdPlayer] Still in ad pod - keeping ad container visible (black screen)\"\n );\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n }\n const idx = pendingTimeouts.indexOf(timeoutId);\n if (idx !== -1) {\n pendingTimeouts.splice(idx, 1);\n }\n }, 50);\n pendingTimeouts.push(timeoutId);\n }\n function handleAdError() {\n console.log(\"[HlsAdPlayer] Handling ad error\");\n adPlaying = false;\n setAdPlayingFlag(false);\n const previousMutedState = contentVideo.muted;\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalMutedState ? 0 : originalVolume;\n console.log(\n `[HlsAdPlayer] Restored mute state: ${previousMutedState} -> ${originalMutedState}`\n );\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n if (!options?.continueLiveStreamDuringAds) {\n if (contentVideo.paused) {\n contentVideo.play().catch(() => {\n });\n }\n }\n emit(\"ad_error\");\n }\n return {\n initialize() {\n console.log(\"[HlsAdPlayer] Initializing\");\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 async requestAds(vastTagUrl) {\n console.log(\"[HlsAdPlayer] Requesting ads:\", vastTagUrl);\n if (adPlaying) {\n console.warn(\n \"[HlsAdPlayer] Cannot request new ads while an ad is playing\"\n );\n return Promise.reject(new Error(\"Ad already playing\"));\n }\n try {\n sessionId = generateSessionId();\n let ad;\n if (preloadedAds.has(vastTagUrl)) {\n ad = preloadedAds.get(vastTagUrl);\n preloadedAds.delete(vastTagUrl);\n console.log(\n \"[HlsAdPlayer] Using preloaded VAST response:\",\n vastTagUrl\n );\n } else {\n ad = await fetchAndParseVastAd(vastTagUrl);\n }\n if (!ad) {\n console.warn(\"[HlsAdPlayer] No ads available from VAST response\");\n emit(\"ad_error\");\n return Promise.resolve();\n }\n currentAd = ad;\n console.log(\n `[HlsAdPlayer] Ad parsed: ${ad.title}, duration: ${ad.duration}s`\n );\n fireTrackingPixels(ad.trackingUrls.impression);\n trackingFired.impression = true;\n return Promise.resolve();\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error requesting ads:\", error);\n emit(\"ad_error\");\n return Promise.reject(error);\n }\n },\n async preloadAds(vastTagUrl) {\n if (!vastTagUrl || vastTagUrl.trim() === \"\") {\n return Promise.resolve();\n }\n if (preloadedAds.has(vastTagUrl)) {\n return Promise.resolve();\n }\n const inflight = preloadingAds.get(vastTagUrl);\n if (inflight) {\n return inflight;\n }\n const preloadPromise = fetchAndParseVastAd(vastTagUrl).then((ad) => {\n if (ad) {\n preloadedAds.set(vastTagUrl, ad);\n console.log(\n \"[HlsAdPlayer] Cached VAST response for preloading:\",\n vastTagUrl\n );\n }\n }).catch((error) => {\n console.warn(\"[HlsAdPlayer] Failed to preload VAST response:\", error);\n preloadedAds.delete(vastTagUrl);\n }).finally(() => {\n preloadingAds.delete(vastTagUrl);\n });\n preloadingAds.set(vastTagUrl, preloadPromise);\n return preloadPromise;\n },\n hasPreloadedAd(vastTagUrl) {\n return preloadedAds.has(vastTagUrl);\n },\n async play() {\n if (!currentAd) {\n console.warn(\n \"[HlsAdPlayer] Cannot play: No ad loaded (no ads available)\"\n );\n return Promise.reject(new Error(\"No ad loaded\"));\n }\n console.log(\"[HlsAdPlayer] Starting ad playback\");\n try {\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl?.appendChild(adVideoElement);\n setupAdEventListeners();\n }\n trackingFired = {\n impression: trackingFired.impression,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false\n };\n const contentVolume = contentVideo.volume;\n originalVolume = Math.max(\n 0,\n Math.min(1, contentVolume || originalVolume)\n );\n if (!options?.continueLiveStreamDuringAds) {\n contentVideo.pause();\n console.log(\"[HlsAdPlayer] Content paused (VOD mode)\");\n } else {\n console.log(\"[HlsAdPlayer] Content continues (Live mode)\");\n }\n console.log(\"[HlsAdPlayer] FORCE MUTING main video\");\n contentVideo.muted = true;\n contentVideo.volume = 0;\n adPlaying = true;\n setAdPlayingFlag(true);\n if (adVideoElement) {\n const adVolume = originalMutedState ? 0 : originalVolume;\n adVideoElement.volume = Math.max(0, Math.min(1, adVolume));\n adVideoElement.muted = false;\n console.log(\n `[HlsAdPlayer] Set ad video volume to ${adVideoElement.volume}, muted: ${adVideoElement.muted}, originalMutedState: ${originalMutedState}, contentVolume: ${contentVolume}`\n );\n }\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n emit(\"content_pause\");\n const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n if (!mediaFile) {\n throw new Error(\"No media file available for ad\");\n }\n console.log(`[HlsAdPlayer] Loading ad from: ${mediaFile.url}`);\n if (import_hls.default.isSupported()) {\n if (adHls) {\n adHls.destroy();\n }\n adHls = new import_hls.default({\n enableWorker: true,\n lowLatencyMode: false\n });\n adHls.loadSource(mediaFile.url);\n adHls.attachMedia(adVideoElement);\n adHls.on(import_hls.default.Events.MANIFEST_PARSED, () => {\n console.log(\"[HlsAdPlayer] HLS manifest parsed, starting playback\");\n adVideoElement.play().catch((error) => {\n console.error(\"[HlsAdPlayer] Error starting ad playback:\", error);\n handleAdError();\n });\n });\n adHls.on(import_hls.default.Events.ERROR, (event, data) => {\n console.error(\"[HlsAdPlayer] HLS error:\", data);\n if (data.fatal) {\n handleAdError();\n }\n });\n } else if (adVideoElement.canPlayType(\"application/vnd.apple.mpegurl\")) {\n adVideoElement.src = mediaFile.url;\n adVideoElement.play().catch((error) => {\n console.error(\"[HlsAdPlayer] Error starting ad playback:\", error);\n handleAdError();\n });\n } else {\n throw new Error(\"HLS not supported\");\n }\n return Promise.resolve();\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error playing ad:\", error);\n handleAdError();\n return Promise.reject(error);\n }\n },\n async stop() {\n console.log(\"[HlsAdPlayer] Stopping ad\");\n adPlaying = false;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n if (adHls) {\n adHls.destroy();\n adHls = void 0;\n }\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n }\n currentAd = void 0;\n },\n destroy() {\n console.log(\"[HlsAdPlayer] Destroying\");\n destroyed = true;\n for (const timeoutId of pendingTimeouts) {\n clearTimeout(timeoutId);\n }\n pendingTimeouts = [];\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalMutedState ? 0 : originalVolume;\n if (adHls) {\n adHls.destroy();\n adHls = void 0;\n }\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.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 preloadedAds.clear();\n preloadingAds.clear();\n },\n isAdPlaying() {\n return adPlaying;\n },\n resize(width, height) {\n console.log(`[HlsAdPlayer] Resizing to ${width}x${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 console.log(\n `[HlsAdPlayer] updateOriginalMutedState called: { muted: ${originalMutedState} -> ${muted}, volume: ${originalVolume} -> ${nextVolume} }`\n );\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 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 }\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}\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(\n \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track\",\n {\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 await response.json();\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending initial tracking data:\",\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/player/StormcloudVideoPlayer.ts\nvar StormcloudVideoPlayer = class {\n constructor(config) {\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.adPodAllUrls = [];\n this.preloadingAdUrls = /* @__PURE__ */ new Set();\n this.vastToMediaUrlMap = /* @__PURE__ */ new Map();\n this.preloadedMediaUrls = /* @__PURE__ */ new Set();\n this.preloadingMediaUrls = /* @__PURE__ */ new Set();\n this.adRequestTokenCounter = 0;\n this.activeAdRequestToken = null;\n this.adRequestWatchdogToken = null;\n this.adFailsafeToken = null;\n this.fetchedAdDurations = /* @__PURE__ */ new Map();\n this.targetAdBreakDurationMs = null;\n this.isAdaptiveMode = false;\n this.failedVastUrls = /* @__PURE__ */ new Set();\n this.continuousFetchingActive = false;\n this.adRequestQueue = [];\n this.successfulAdRequests = [];\n this.maxPlaceholderDurationMs = 5e3;\n this.placeholderStartTimeMs = null;\n this.isShowingPlaceholder = false;\n initializePolyfills();\n const browserOverrides = getBrowserConfigOverrides();\n this.config = { ...config, ...browserOverrides };\n this.video = config.videoElement;\n logBrowserInfo(config.debugAdTiming);\n this.ima = this.createAdPlayer(false);\n }\n createAdPlayer(continueLiveStreamDuringAds) {\n const vastMode = this.config.vastMode || \"default\";\n let adPlayerType = this.config.adPlayerType || (vastMode === \"adstorm\" ? \"hls\" : \"ima\");\n if (adPlayerType === \"ima\" && !supportsGoogleIMA()) {\n if (this.config.debugAdTiming) {\n console.warn(\n \"[StormcloudVideoPlayer] Google IMA SDK not supported on this browser, falling back to HLS ad player\"\n );\n }\n adPlayerType = \"hls\";\n }\n if (adPlayerType === \"hls\") {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Creating HLS ad player (AdStorm mode)\"\n );\n }\n return createHlsAdPlayer(this.video, {\n continueLiveStreamDuringAds,\n ...this.config.licenseKey ? { licenseKey: this.config.licenseKey } : {},\n ...this.hls ? { mainHlsInstance: this.hls } : {}\n });\n } else {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Creating Google IMA ad player (Default mode)\"\n );\n }\n return createImaController(this.video, {\n continueLiveStreamDuringAds\n });\n }\n }\n async load() {\n if (!this.attached) {\n this.attach();\n }\n try {\n await this.fetchAdConfiguration();\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\n \"[StormcloudVideoPlayer] Failed to fetch ad configuration:\",\n error\n );\n }\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.ima.destroy();\n this.ima = this.createAdPlayer(false);\n this.ima.initialize();\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 this.isLiveStream = this.hls?.levels?.some(\n (level) => level?.details?.live === true || level?.details?.type === \"LIVE\"\n ) ?? false;\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.ima.destroy();\n this.ima = this.createAdPlayer(this.shouldContinueLiveStreamDuringAds());\n this.ima.initialize();\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.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\")) {\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-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-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 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.ima.initialize();\n this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);\n this.ima.on(\"all_ads_completed\", () => {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] IMA all_ads_completed event received - ending ad break\"\n );\n }\n if (this.inAdBreak) {\n this.handleAdPodComplete();\n }\n });\n this.ima.on(\"ad_error\", (errorPayload) => {\n const remaining = this.getRemainingAdMs();\n console.error(\"[AD-ERROR] Ad playback failed\", errorPayload || \"\");\n if (this.inAdBreak) {\n if (remaining > 500 && this.adPodQueue.length > 0) {\n const nextPreloaded = this.findNextPreloadedAd();\n if (nextPreloaded) {\n this.currentAdIndex++;\n this.playSingleAd(nextPreloaded).catch(() => {\n this.handleAdFailure();\n });\n } else {\n this.handleAdFailure();\n }\n } else {\n this.handleAdFailure();\n }\n } else {\n this.handleAdFailure();\n }\n });\n this.ima.on(\"content_pause\", () => {\n this.clearAdFailsafeTimer();\n this.clearAdRequestWatchdog();\n this.activeAdRequestToken = null;\n this.showAds = true;\n });\n this.ima.on(\"content_resume\", () => {\n this.clearAdFailsafeTimer();\n this.clearAdRequestWatchdog();\n this.activeAdRequestToken = null;\n this.showAds = false;\n if (!this.inAdBreak) {\n return;\n }\n const remaining = this.getRemainingAdMs();\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] content_resume event: remaining=${remaining}ms, queued ads=${this.adRequestQueue.length}`);\n }\n if (remaining > 500) {\n this.tryNextAvailableAd();\n } else {\n this.handleAdPodComplete();\n }\n });\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.ima.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 });\n }\n if (marker.type === \"start\") {\n if (this.inAdBreak) {\n return;\n }\n this.inAdBreak = true;\n const durationMs = marker.durationSeconds != null ? marker.durationSeconds * 1e3 : void 0;\n this.expectedAdBreakDurationMs = durationMs;\n this.currentAdBreakStartWallClockMs = Date.now();\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.ima.isAdPlaying() && this.activeAdRequestToken === null) {\n const scheduled = this.findCurrentOrNextBreak(\n this.video.currentTime * 1e3\n );\n const tags = this.selectVastTagsForBreak(scheduled) || (this.apiVastTagUrl ? [this.apiVastTagUrl] : void 0);\n if (tags && tags.length > 0) {\n const first = tags[0];\n const rest = tags.slice(1);\n this.adPodQueue = rest;\n this.playSingleAd(first).catch(() => {\n });\n }\n }\n return;\n }\n if (marker.type === \"end\") {\n this.inAdBreak = false;\n this.expectedAdBreakDurationMs = void 0;\n this.currentAdBreakStartWallClockMs = void 0;\n this.clearAdStartTimer();\n this.clearAdStopTimer();\n if (this.ima.isAdPlaying()) {\n this.ima.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 elapsedMatch = value.match(/Elapsed\\s*=\\s*([0-9.]+)/i);\n const durationMatch = value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n const res = {};\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) 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 async fetchAdConfiguration() {\n const vastMode = this.config.vastMode || \"default\";\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] VAST mode:\", vastMode);\n }\n if (vastMode === \"adstorm\") {\n if (!this.config.licenseKey) {\n if (this.config.debugAdTiming) {\n console.warn(\n \"[StormcloudVideoPlayer] AdStorm mode requires a license key\"\n );\n }\n return;\n }\n const vastEndpoint = `https://adstorm.co/api-adstorm-dev/adstorm/vast/${this.config.licenseKey}`;\n this.apiVastTagUrl = vastEndpoint;\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Using AdStorm VAST endpoint (adstorm mode):\",\n vastEndpoint\n );\n }\n return;\n }\n if (this.config.vastTagUrl) {\n this.apiVastTagUrl = this.config.vastTagUrl;\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Using custom VAST tag URL:\",\n this.apiVastTagUrl\n );\n }\n return;\n }\n const apiUrl = \"https://adstorm.co/api-adstorm-dev/adstorm/ads/web\";\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Fetching ad configuration from:\",\n apiUrl\n );\n }\n const headers = {};\n if (this.config.licenseKey) {\n headers[\"Authorization\"] = `Bearer ${this.config.licenseKey}`;\n }\n const response = await fetch(apiUrl, { headers });\n if (!response.ok) {\n if (this.config.debugAdTiming) {\n console.warn(\n `[StormcloudVideoPlayer] Failed to fetch ad configuration: ${response.status}`\n );\n }\n return;\n }\n const data = await response.json();\n const imaPayload = data.response?.ima?.[\"publisherdesk.ima\"]?.payload;\n if (imaPayload) {\n this.apiVastTagUrl = decodeURIComponent(imaPayload);\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Extracted VAST tag URL from /ads/web:\",\n this.apiVastTagUrl\n );\n }\n } else {\n if (this.config.debugAdTiming) {\n console.warn(\n \"[StormcloudVideoPlayer] No VAST tag URL found in /ads/web response\"\n );\n }\n }\n const numberAds = data.response?.options?.vast?.cue_tones?.number_ads;\n if (numberAds != null && numberAds > 0) {\n this.apiNumberAds = numberAds;\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Number of ads per break from API:\",\n this.apiNumberAds\n );\n }\n }\n }\n getCurrentAdIndex() {\n return this.currentAdIndex;\n }\n getTotalAdsInBreak() {\n return this.totalAdsInBreak;\n }\n generateVastUrlsWithCorrelators(baseUrl, count) {\n const urls = [];\n for (let i = 0; i < count; i++) {\n try {\n const url = new URL(baseUrl);\n const timestamp = Date.now();\n const random = Math.floor(Math.random() * 1e6);\n const uniqueCorrelator = `${timestamp}${random}${i}`;\n url.searchParams.set(\"correlator\", uniqueCorrelator);\n urls.push(url.toString());\n } catch (error) {\n console.warn(\n \"[StormcloudVideoPlayer] Failed to parse VAST URL:\",\n baseUrl,\n error\n );\n urls.push(`${baseUrl}${baseUrl.includes(\"?\") ? \"&\" : \"?\"}correlator=${Date.now()}${i}`);\n }\n }\n return urls;\n }\n isAdPlaying() {\n return this.inAdBreak && this.ima.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 async handleAdStart(_marker) {\n const scheduled = this.findCurrentOrNextBreak(\n this.video.currentTime * 1e3\n );\n const tags = this.selectVastTagsForBreak(scheduled);\n let baseVastUrl;\n if (this.apiVastTagUrl) {\n baseVastUrl = this.apiVastTagUrl;\n } else if (tags && tags.length > 0 && tags[0]) {\n baseVastUrl = tags[0];\n } else {\n return;\n }\n const adBreakDurationMs = _marker.durationSeconds != null ? _marker.durationSeconds * 1e3 : scheduled?.durationMs;\n if (this.isLiveStream && adBreakDurationMs != null && adBreakDurationMs > 0) {\n this.isAdaptiveMode = true;\n this.targetAdBreakDurationMs = adBreakDurationMs;\n this.fetchedAdDurations.clear();\n if (this.config.debugAdTiming) {\n console.log(\n `[CONTINUOUS-FETCH] \\u{1F4FA} LIVE MODE: Target duration=${adBreakDurationMs}ms | Will continuously fetch ads during break`\n );\n }\n } else {\n this.isAdaptiveMode = false;\n this.targetAdBreakDurationMs = null;\n this.fetchedAdDurations.clear();\n if (this.config.debugAdTiming) {\n console.log(\n `[CONTINUOUS-FETCH] \\u{1F3AC} VOD MODE: Using fixed ad strategy`\n );\n }\n }\n this.adPodAllUrls = [];\n this.preloadingAdUrls.clear();\n this.vastToMediaUrlMap.clear();\n this.preloadedMediaUrls.clear();\n this.preloadingMediaUrls.clear();\n this.failedVastUrls.clear();\n this.adRequestQueue = [];\n this.successfulAdRequests = [];\n this.continuousFetchingActive = true;\n this.isShowingPlaceholder = false;\n this.placeholderStartTimeMs = null;\n const currentMuted = this.video.muted;\n const currentVolume = this.video.volume;\n this.ima.updateOriginalMutedState(currentMuted, currentVolume);\n this.inAdBreak = true;\n this.currentAdIndex = 0;\n this.totalAdsInBreak = 1;\n this.adPodQueue = [];\n if (this.expectedAdBreakDurationMs == null && adBreakDurationMs != null) {\n this.expectedAdBreakDurationMs = adBreakDurationMs;\n this.currentAdBreakStartWallClockMs = Date.now();\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u{1F680} Immediately requesting first ad...\");\n }\n const firstAdUrlArray = this.generateVastUrlsWithCorrelators(baseVastUrl, 1);\n const firstAdUrl = firstAdUrlArray[0];\n if (!firstAdUrl) {\n if (this.config.debugAdTiming) {\n console.warn(\"[CONTINUOUS-FETCH] \\u26A0\\uFE0F Failed to generate first ad URL\");\n }\n this.handleAdPodComplete();\n return;\n }\n try {\n await this.ima.requestAds(firstAdUrl);\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u2705 First ad request successful, starting playback\");\n }\n this.successfulAdRequests.push(firstAdUrl);\n this.currentAdIndex++;\n this.startContinuousFetching(baseVastUrl);\n await this.ima.play();\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\"[CONTINUOUS-FETCH] \\u26A0\\uFE0F First ad request failed:\", error);\n }\n this.failedVastUrls.add(firstAdUrl);\n this.startContinuousFetching(baseVastUrl);\n this.tryNextAvailableAd();\n }\n }\n startContinuousFetching(baseVastUrl) {\n if (!this.continuousFetchingActive) {\n return;\n }\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u{1F504} Starting continuous ad fetching loop\");\n }\n this.continuousFetchLoop(baseVastUrl);\n }\n async continuousFetchLoop(baseVastUrl) {\n while (this.continuousFetchingActive && this.inAdBreak) {\n const remaining = this.getRemainingAdMs();\n if (remaining <= 0) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u23F9\\uFE0F Ad break time expired, stopping fetch loop\");\n }\n break;\n }\n const maxQueueSize = 3;\n if (this.adRequestQueue.length >= maxQueueSize) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] \\u23F8\\uFE0F Queue full (${this.adRequestQueue.length}), pausing fetching...`);\n }\n await new Promise((resolve) => setTimeout(resolve, 2e3));\n continue;\n }\n const newAdUrl = this.generateVastUrlsWithCorrelators(baseVastUrl, 1)[0];\n if (!newAdUrl || this.failedVastUrls.has(newAdUrl)) {\n await new Promise((resolve) => setTimeout(resolve, 1e3));\n continue;\n }\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] \\u{1F4E1} Attempting to fetch ad (${this.successfulAdRequests.length + this.adRequestQueue.length + 1} total)...`);\n }\n try {\n const response = await fetch(newAdUrl, { mode: \"cors\" });\n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.status}`);\n }\n const xmlText = await response.text();\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlText, \"text/xml\");\n const mediaFiles = xmlDoc.querySelectorAll(\"MediaFile\");\n if (mediaFiles.length === 0) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u26A0\\uFE0F VAST response has no media files, skipping\");\n }\n this.failedVastUrls.add(newAdUrl);\n await new Promise((resolve) => setTimeout(resolve, 1e3));\n continue;\n }\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] \\u2705 Successfully fetched ad, adding to queue (queue size: ${this.adRequestQueue.length + 1})`);\n }\n this.adRequestQueue.push(newAdUrl);\n this.totalAdsInBreak++;\n await new Promise((resolve) => setTimeout(resolve, 500));\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u274C Ad fetch failed:\", error.message);\n }\n this.failedVastUrls.add(newAdUrl);\n await new Promise((resolve) => setTimeout(resolve, 2e3));\n }\n }\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u{1F6D1} Continuous fetch loop ended\");\n }\n }\n stopContinuousFetching() {\n this.continuousFetchingActive = false;\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u{1F6D1} Stopping continuous ad fetching\");\n }\n }\n async tryNextAvailableAd(retryCount = 0) {\n const remaining = this.getRemainingAdMs();\n if (remaining <= 500) {\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.adRequestQueue.length > 0) {\n const nextAdUrl = this.adRequestQueue.shift();\n if (nextAdUrl) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] \\u{1F3AC} Playing next queued ad (${this.currentAdIndex + 1}/${this.totalAdsInBreak}, ${this.adRequestQueue.length} remaining in queue)`);\n }\n const currentMuted = this.video.muted;\n const currentVolume = this.video.volume;\n this.ima.updateOriginalMutedState(currentMuted, currentVolume);\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] \\u{1F50A} Updated ad audio state: muted=${currentMuted}, volume=${currentVolume}`);\n }\n this.currentAdIndex++;\n this.successfulAdRequests.push(nextAdUrl);\n await this.playSingleAd(nextAdUrl).catch(() => {\n this.tryNextAvailableAd(0);\n });\n return;\n }\n }\n const maxRetries = 5;\n if (this.continuousFetchingActive && retryCount < maxRetries && remaining > 2e3) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] \\u23F3 Queue empty but fetching active, waiting... (retry ${retryCount + 1}/${maxRetries})`);\n }\n await new Promise((resolve) => setTimeout(resolve, 1e3));\n await this.tryNextAvailableAd(retryCount + 1);\n return;\n }\n if (!this.isShowingPlaceholder && remaining > 1e3) {\n this.showPlaceholderAndWaitForAds();\n } else {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u23F9\\uFE0F No more ads available, ending ad break\");\n }\n this.handleAdPodComplete();\n }\n }\n async showPlaceholderAndWaitForAds() {\n const remaining = this.getRemainingAdMs();\n const waitTime = Math.min(this.maxPlaceholderDurationMs, remaining);\n if (waitTime < 1e3) {\n this.handleAdPodComplete();\n return;\n }\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] \\u2B1B Showing black placeholder for ${waitTime}ms while waiting for ads`);\n }\n this.isShowingPlaceholder = true;\n this.placeholderStartTimeMs = Date.now();\n this.ima.showPlaceholder();\n const checkInterval = 500;\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) {\n return;\n }\n if (this.adRequestQueue.length > 0) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u2705 New ad became available during placeholder\");\n }\n this.isShowingPlaceholder = false;\n this.placeholderStartTimeMs = null;\n this.ima.hidePlaceholder();\n const currentMuted = this.video.muted;\n const currentVolume = this.video.volume;\n this.ima.updateOriginalMutedState(currentMuted, currentVolume);\n const nextAdUrl = this.adRequestQueue.shift();\n if (nextAdUrl) {\n this.currentAdIndex++;\n this.successfulAdRequests.push(nextAdUrl);\n await this.playSingleAd(nextAdUrl).catch(() => {\n this.tryNextAvailableAd();\n });\n }\n return;\n }\n }\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u23F0 Placeholder timeout reached, no ads fetched\");\n }\n this.isShowingPlaceholder = false;\n this.placeholderStartTimeMs = null;\n this.ima.hidePlaceholder();\n this.handleAdPodComplete();\n }\n findCurrentOrNextBreak(nowMs) {\n const schedule = [];\n let candidate;\n for (const b of schedule) {\n const tol = this.config.driftToleranceMs ?? 1e3;\n if (b.startTimeMs <= nowMs + tol && (candidate == null || b.startTimeMs > (candidate.startTimeMs || 0))) {\n candidate = b;\n }\n }\n return candidate;\n }\n onTimeUpdate(currentTimeSec) {\n if (this.ima.isAdPlaying()) return;\n const nowMs = currentTimeSec * 1e3;\n const breakToPlay = this.findBreakForTime(nowMs);\n if (breakToPlay) {\n this.handleMidAdJoin(breakToPlay, nowMs);\n }\n }\n async handleMidAdJoin(adBreak, nowMs) {\n const durationMs = adBreak.durationMs ?? 0;\n const endMs = adBreak.startTimeMs + durationMs;\n if (durationMs > 0 && nowMs > adBreak.startTimeMs && nowMs < endMs) {\n const remainingMs = endMs - nowMs;\n const tags = this.selectVastTagsForBreak(adBreak) || (this.apiVastTagUrl ? [this.apiVastTagUrl] : void 0);\n if (tags && tags.length > 0) {\n const first = tags[0];\n const rest = tags.slice(1);\n this.adPodQueue = rest;\n this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);\n await this.playSingleAd(first);\n this.inAdBreak = true;\n this.expectedAdBreakDurationMs = remainingMs;\n this.currentAdBreakStartWallClockMs = Date.now();\n this.scheduleAdStopCountdown(remainingMs);\n }\n }\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.ima.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.ima.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 async playSingleAd(vastTagUrl) {\n if (this.ima.isAdPlaying()) {\n return;\n }\n if (this.failedVastUrls.has(vastTagUrl)) {\n console.warn(\"[AD-ERROR] Skipping already-failed VAST URL:\", vastTagUrl.substring(0, 60));\n this.handleAdFailure();\n return;\n }\n const requestToken = ++this.adRequestTokenCounter;\n this.activeAdRequestToken = requestToken;\n this.startAdRequestWatchdog(requestToken);\n try {\n await this.ima.requestAds(vastTagUrl);\n this.clearAdRequestWatchdog();\n if (this.activeAdRequestToken !== requestToken) {\n return;\n }\n try {\n this.startAdFailsafeTimer(requestToken);\n await this.ima.play();\n } catch (playError) {\n console.error(\"[AD-ERROR] Failed to play ad:\", playError);\n this.failedVastUrls.add(vastTagUrl);\n this.clearAdFailsafeTimer();\n if (this.activeAdRequestToken === requestToken) {\n this.activeAdRequestToken = null;\n }\n this.handleAdFailure();\n return;\n }\n } catch (error) {\n console.error(\"[AD-ERROR] Ad request failed:\", error?.message);\n this.failedVastUrls.add(vastTagUrl);\n this.clearAdRequestWatchdog();\n this.clearAdFailsafeTimer();\n if (this.activeAdRequestToken === requestToken) {\n this.activeAdRequestToken = null;\n }\n this.handleAdFailure();\n }\n }\n handleAdPodComplete() {\n this.clearAdRequestWatchdog();\n this.clearAdFailsafeTimer();\n this.activeAdRequestToken = null;\n this.stopContinuousFetching();\n if (this.isShowingPlaceholder) {\n this.ima.hidePlaceholder();\n this.isShowingPlaceholder = false;\n this.placeholderStartTimeMs = null;\n }\n this.preloadingAdUrls.clear();\n this.vastToMediaUrlMap.clear();\n this.preloadedMediaUrls.clear();\n this.preloadingMediaUrls.clear();\n this.adRequestQueue = [];\n this.successfulAdRequests = [];\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.adPodAllUrls = [];\n this.showAds = false;\n this.currentAdIndex = 0;\n this.totalAdsInBreak = 0;\n this.ima.stop().catch(() => {\n });\n const restoredMuted = this.ima.getOriginalMutedState();\n const restoredVolume = this.ima.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 if (!this.shouldContinueLiveStreamDuringAds() && this.video.paused) {\n this.video.play()?.catch(() => {\n });\n }\n }\n handleAdFailure() {\n const remaining = this.getRemainingAdMs();\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] Ad failure: remaining=${remaining}ms, queued ads=${this.adRequestQueue.length}`);\n }\n if (remaining > 500) {\n this.tryNextAvailableAd();\n } else {\n console.error(\"[AD-ERROR] Ad failed and no time remaining. Failed URLs:\", this.failedVastUrls.size);\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.ima.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 selectVastTagsForBreak(b) {\n if (!b || !b.vastTagUrl) return void 0;\n if (b.vastTagUrl.includes(\",\")) {\n return b.vastTagUrl.split(\",\").map((s) => s.trim()).filter((s) => s.length > 0);\n }\n return [b.vastTagUrl];\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.ima.isAdPlaying(),\n inAdBreak: this.inAdBreak,\n activeAdRequestToken: this.activeAdRequestToken,\n ...extra\n });\n }\n async fetchAndParseVastXml(vastTagUrl) {\n try {\n const response = await fetch(vastTagUrl, { mode: \"cors\" });\n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.status}`);\n }\n const xmlText = await response.text();\n return this.extractMediaUrlsFromVast(xmlText);\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\n `[StormcloudVideoPlayer] Failed to fetch/parse VAST XML: ${vastTagUrl}`,\n error\n );\n }\n return [];\n }\n }\n extractMediaUrlsFromVast(xmlText) {\n const mediaUrls = [];\n try {\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlText, \"text/xml\");\n const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n for (const mediaFile of Array.from(mediaFileElements)) {\n const url = mediaFile.textContent?.trim();\n if (url) {\n const lowerUrl = url.toLowerCase();\n if (lowerUrl.endsWith(\".mp4\") || lowerUrl.endsWith(\".webm\") || lowerUrl.endsWith(\".mov\") || lowerUrl.endsWith(\".avi\") || lowerUrl.includes(\".mp4?\") || lowerUrl.includes(\".webm?\") || lowerUrl.includes(\"/mp4/\") || lowerUrl.includes(\"type=video\")) {\n mediaUrls.push(url);\n }\n }\n }\n if (this.config.debugAdTiming && mediaUrls.length > 0) {\n console.log(\n `[StormcloudVideoPlayer] Extracted ${mediaUrls.length} media URLs from VAST:`,\n mediaUrls\n );\n }\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\n \"[StormcloudVideoPlayer] Failed to parse VAST XML:\",\n error\n );\n }\n }\n return mediaUrls;\n }\n async fetchVastDuration(vastTagUrl) {\n try {\n const response = await fetch(vastTagUrl, { mode: \"cors\" });\n if (!response.ok) {\n if (this.config.debugAdTiming) {\n console.warn(\n `[ADAPTIVE-POD] Failed to fetch VAST: ${response.status}`\n );\n }\n return null;\n }\n const xmlText = await response.text();\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlText, \"text/xml\");\n const durationText = xmlDoc.querySelector(\"Duration\")?.textContent;\n if (!durationText) {\n if (this.config.debugAdTiming) {\n console.warn(\"[ADAPTIVE-POD] No Duration element found in VAST\");\n }\n return null;\n }\n const durationParts = durationText.split(\":\");\n const durationSeconds = parseInt(durationParts[0] || \"0\", 10) * 3600 + parseInt(durationParts[1] || \"0\", 10) * 60 + parseInt(durationParts[2] || \"0\", 10);\n return durationSeconds;\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\n `[ADAPTIVE-POD] Error fetching VAST duration from ${vastTagUrl}:`,\n error\n );\n }\n return null;\n }\n }\n calculateAdditionalAdsNeeded() {\n if (!this.isAdaptiveMode || this.targetAdBreakDurationMs === null) {\n return 0;\n }\n let totalFetchedDurationMs = 0;\n for (const duration of this.fetchedAdDurations.values()) {\n totalFetchedDurationMs += duration * 1e3;\n }\n const fetchedCount = this.fetchedAdDurations.size;\n const averageDurationMs = fetchedCount > 0 ? totalFetchedDurationMs / fetchedCount : 30 * 1e3;\n const queuedButNotFetched = this.adPodAllUrls.length - fetchedCount;\n const estimatedQueuedDurationMs = queuedButNotFetched * averageDurationMs;\n const estimatedTotalDurationMs = totalFetchedDurationMs + estimatedQueuedDurationMs;\n const remainingTimeMs = this.targetAdBreakDurationMs - estimatedTotalDurationMs;\n if (remainingTimeMs <= 0) {\n if (this.config.debugAdTiming) {\n console.log(\n `[ADAPTIVE-POD] \\u2705 Target duration met: Fetched=${totalFetchedDurationMs}ms + Queued(${queuedButNotFetched} ads)=${estimatedQueuedDurationMs}ms = ${estimatedTotalDurationMs}ms / Target=${this.targetAdBreakDurationMs}ms`\n );\n }\n return 0;\n }\n const additionalAds = Math.ceil(remainingTimeMs / averageDurationMs);\n if (this.config.debugAdTiming) {\n console.log(\n `[ADAPTIVE-POD] \\u{1F4CA} Need ${additionalAds} more ads | Fetched: ${totalFetchedDurationMs}ms (${fetchedCount} ads) | Queued: ${estimatedQueuedDurationMs}ms (${queuedButNotFetched} ads) | Target: ${this.targetAdBreakDurationMs}ms | Remaining: ${remainingTimeMs}ms | Avg duration: ${averageDurationMs}ms`\n );\n }\n return additionalAds;\n }\n async addAdaptiveAdsToQueue() {\n if (!this.isAdaptiveMode || !this.apiVastTagUrl) {\n return;\n }\n const additionalAds = this.calculateAdditionalAdsNeeded();\n if (additionalAds <= 0) {\n return;\n }\n const newUrls = this.generateVastUrlsWithCorrelators(\n this.apiVastTagUrl,\n additionalAds\n );\n if (this.config.debugAdTiming) {\n console.log(\n `[ADAPTIVE-POD] \\u{1F504} Adding ${newUrls.length} additional VAST URLs to queue (will be preloaded sequentially)`\n );\n }\n this.adPodAllUrls.push(...newUrls);\n this.adPodQueue.push(...newUrls);\n this.totalAdsInBreak += newUrls.length;\n }\n async preloadMediaFile(mediaUrl) {\n if (this.preloadedMediaUrls.has(mediaUrl)) {\n return;\n }\n if (this.preloadingMediaUrls.has(mediaUrl)) {\n return;\n }\n this.preloadingMediaUrls.add(mediaUrl);\n try {\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Preloading video file: ${mediaUrl}`\n );\n }\n const response = await fetch(mediaUrl, {\n mode: \"cors\",\n method: \"GET\",\n headers: {\n Range: \"bytes=0-1048576\"\n }\n });\n if (response.ok || response.status === 206) {\n this.preloadedMediaUrls.add(mediaUrl);\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Successfully preloaded video file: ${mediaUrl}`\n );\n }\n }\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\n `[StormcloudVideoPlayer] Failed to preload video file: ${mediaUrl}`,\n error\n );\n }\n } finally {\n this.preloadingMediaUrls.delete(mediaUrl);\n }\n }\n async preloadAllAdsInBackground() {\n if (this.adPodAllUrls.length === 0) {\n return;\n }\n if (this.isAdaptiveMode) {\n if (this.config.debugAdTiming) {\n console.log(\n `[ADAPTIVE-POD] \\u{1F504} Starting sequential preload of remaining ads`\n );\n }\n const processedUrls = /* @__PURE__ */ new Set();\n for (const url of this.adPodAllUrls) {\n if (this.ima.hasPreloadedAd?.(url) || this.fetchedAdDurations.has(url)) {\n processedUrls.add(url);\n }\n }\n if (this.config.debugAdTiming && processedUrls.size > 0) {\n console.log(\n `[ADAPTIVE-POD] \\u{1F4E6} Skipping ${processedUrls.size} already-preloaded ads`\n );\n }\n while (true) {\n const nextUrl = this.adPodAllUrls.find((url) => !processedUrls.has(url));\n if (!nextUrl) {\n if (this.config.debugAdTiming) {\n console.log(`[ADAPTIVE-POD] \\u2705 All queued ads processed (${processedUrls.size} total)`);\n }\n break;\n }\n processedUrls.add(nextUrl);\n if (this.config.debugAdTiming) {\n console.log(\n `[ADAPTIVE-POD] \\u{1F4E5} Preloading ad ${processedUrls.size}/${this.adPodAllUrls.length}...`\n );\n }\n try {\n await this.preloadSingleAd(nextUrl);\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\n `[ADAPTIVE-POD] \\u26A0\\uFE0F Preload failed for ad ${processedUrls.size}:`,\n error\n );\n }\n }\n if (this.calculateAdditionalAdsNeeded() === 0) {\n if (this.config.debugAdTiming) {\n console.log(\n `[ADAPTIVE-POD] \\u2705 Target duration reached (${processedUrls.size} ads preloaded), stopping`\n );\n }\n break;\n }\n }\n if (this.config.debugAdTiming) {\n console.log(\n `[ADAPTIVE-POD] \\u2705 Sequential preloading completed (${processedUrls.size} ads ready)`\n );\n }\n } else {\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Starting parallel preload of ${this.adPodAllUrls.length} ads`\n );\n }\n const preloadPromises = this.adPodAllUrls.map(\n (vastTagUrl) => this.preloadSingleAd(vastTagUrl).catch((error) => {\n if (this.config.debugAdTiming) {\n console.warn(\n `[StormcloudVideoPlayer] Preload failed for ${vastTagUrl}:`,\n error\n );\n }\n })\n );\n await Promise.all(preloadPromises);\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Background preloading completed for all ads`\n );\n }\n }\n }\n async preloadSingleAd(vastTagUrl) {\n if (!vastTagUrl) return;\n try {\n if (this.isAdaptiveMode && !this.fetchedAdDurations.has(vastTagUrl)) {\n const duration = await this.fetchVastDuration(vastTagUrl);\n if (duration !== null) {\n this.fetchedAdDurations.set(vastTagUrl, duration);\n if (this.config.debugAdTiming) {\n console.log(\n `[ADAPTIVE-POD] \\u2713 Fetched ad duration: ${duration}s (${this.fetchedAdDurations.size} ads fetched so far)`\n );\n }\n await this.addAdaptiveAdsToQueue();\n }\n }\n if (this.ima.preloadAds && !this.ima.hasPreloadedAd(vastTagUrl)) {\n if (!this.preloadingAdUrls.has(vastTagUrl)) {\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Preloading VAST: ${vastTagUrl}`\n );\n }\n this.preloadingAdUrls.add(vastTagUrl);\n await this.ima.preloadAds(vastTagUrl).then(() => {\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] IMA VAST preload complete: ${vastTagUrl}`\n );\n }\n }).catch((error) => {\n if (this.config.debugAdTiming) {\n console.warn(\n `[StormcloudVideoPlayer] IMA VAST preload failed: ${vastTagUrl}`,\n error\n );\n }\n }).finally(() => {\n this.preloadingAdUrls.delete(vastTagUrl);\n });\n }\n }\n let mediaUrls = this.vastToMediaUrlMap.get(vastTagUrl);\n if (!mediaUrls) {\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Fetching and parsing VAST to extract media URLs: ${vastTagUrl}`\n );\n }\n mediaUrls = await this.fetchAndParseVastXml(vastTagUrl);\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Extracted ${mediaUrls.length} media URLs:`,\n mediaUrls\n );\n }\n if (mediaUrls.length > 0) {\n this.vastToMediaUrlMap.set(vastTagUrl, mediaUrls);\n }\n }\n if (mediaUrls && mediaUrls.length > 0) {\n const primaryMediaUrl = mediaUrls[0];\n if (primaryMediaUrl && !this.preloadedMediaUrls.has(primaryMediaUrl)) {\n await this.preloadMediaFile(primaryMediaUrl);\n }\n }\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\n `[StormcloudVideoPlayer] Failed to preload ad: ${vastTagUrl}`,\n error\n );\n }\n }\n }\n findNextPreloadedAd() {\n for (let i = 0; i < this.adPodQueue.length; i++) {\n const vastTagUrl = this.adPodQueue[i];\n if (!vastTagUrl) continue;\n if (this.failedVastUrls.has(vastTagUrl)) {\n console.warn(\"[AD-ERROR] Skipping failed URL in queue\");\n continue;\n }\n const hasImaPreload = this.ima.hasPreloadedAd?.(vastTagUrl) ?? false;\n const mediaUrls = this.vastToMediaUrlMap.get(vastTagUrl);\n const hasMediaPreload = mediaUrls && mediaUrls.length > 0 ? this.preloadedMediaUrls.has(mediaUrls[0]) : false;\n if (hasImaPreload || hasMediaPreload) {\n this.adPodQueue.splice(0, i + 1);\n return vastTagUrl;\n }\n }\n return void 0;\n }\n getRemainingAdMs() {\n if (this.expectedAdBreakDurationMs == null || this.currentAdBreakStartWallClockMs == null)\n return 0;\n const elapsed = Date.now() - this.currentAdBreakStartWallClockMs;\n return Math.max(0, this.expectedAdBreakDurationMs - elapsed);\n }\n findBreakForTime(nowMs) {\n const schedule = [];\n for (const b of schedule) {\n const end = (b.startTimeMs || 0) + (b.durationMs || 0);\n if (nowMs >= (b.startTimeMs || 0) && (b.durationMs ? nowMs < end : true)) {\n return b;\n }\n }\n return void 0;\n }\n toggleMute() {\n if (this.ima.isAdPlaying()) {\n const currentPerceptualState = this.isMuted();\n const newMutedState = !currentPerceptualState;\n this.ima.updateOriginalMutedState(newMutedState, this.video.volume);\n this.ima.setAdVolume(newMutedState ? 0 : 1);\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.ima.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.ima.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.ima.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.ima.updateOriginalMutedState(muted, this.video.volume);\n this.ima.setAdVolume(muted ? 0 : 1);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] setMuted applied during ad\", {\n muted\n });\n }\n return;\n }\n this.ima.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.ima.isAdPlaying();\n if (adPlaying) {\n this.ima.setAdVolume(clampedVolume);\n this.ima.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.ima.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] setVolume called:\", clampedVolume);\n }\n }\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.ima && this.ima.isAdPlaying()) {\n const width = this.video.clientWidth || 640;\n const height = this.video.clientHeight || 360;\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Resizing ads manager to ${width}x${height}`\n );\n }\n this.ima.resize(width, height);\n }\n }\n destroy() {\n this.stopContinuousFetching();\n this.clearAdStartTimer();\n this.clearAdStopTimer();\n this.clearAdFailsafeTimer();\n this.clearAdRequestWatchdog();\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.ima?.destroy();\n this.preloadingAdUrls.clear();\n this.vastToMediaUrlMap.clear();\n this.preloadedMediaUrls.clear();\n this.preloadingMediaUrls.clear();\n this.adPodAllUrls = [];\n this.adRequestQueue = [];\n this.successfulAdRequests = [];\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 \"vastMode\"\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 vastMode,\n vastTagUrl,\n adPlayerType,\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 vastMode\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 (vastMode !== void 0) cfg.vastMode = vastMode;\n if (vastTagUrl !== void 0) cfg.vastTagUrl = vastTagUrl;\n if (adPlayerType !== void 0) cfg.adPlayerType = adPlayerType;\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 showAds = playerRef.current.isShowingAds();\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 return { showAds, currentIndex, totalAds };\n }\n return prev;\n });\n }\n };\n const interval = setInterval(checkAdStatus, 100);\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 = videoRef.current.volume;\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 if (playerRef.current && !playerRef.current.isShowingAds()) {\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 \"vastMode\",\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 vastMode,\n vastTagUrl,\n adPlayerType,\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 vastMode,\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 (vastMode !== undefined) cfg.vastMode = vastMode;\n if (vastTagUrl !== undefined) cfg.vastTagUrl = vastTagUrl;\n if (adPlayerType !== undefined) cfg.adPlayerType = adPlayerType;\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 // Only apply muted prop when NOT showing ads to prevent interference with ad audio\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 showAds = playerRef.current.isShowingAds();\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 return { showAds, currentIndex, totalAds };\n }\n return prev;\n });\n }\n };\n\n const interval = setInterval(checkAdStatus, 100);\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 = videoRef.current.volume;\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 if (playerRef.current && !playerRef.current.isShowingAds()) {\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 ImaController,\n AdBreak,\n StormcloudApiResponse,\n} from \"../types\";\nimport { createImaController } from \"../sdk/ima\";\nimport { createHlsAdPlayer } from \"../sdk/hlsAdPlayer\";\nimport { sendInitialTracking, sendHeartbeat } from \"../utils/tracking\";\nimport { initializePolyfills } from \"../utils/polyfills\";\nimport {\n supportsGoogleIMA,\n logBrowserInfo,\n getBrowserConfigOverrides,\n} from \"../utils/browserCompat\";\n\nexport class StormcloudVideoPlayer {\n private readonly video: HTMLVideoElement;\n private readonly config: StormcloudVideoPlayerConfig;\n private hls?: Hls;\n private ima: ImaController;\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 apiVastTagUrl: string | undefined;\n private apiNumberAds: number | undefined;\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 adPodAllUrls: string[] = [];\n private preloadingAdUrls: Set<string> = new Set();\n private vastToMediaUrlMap: Map<string, string[]> = new Map();\n private preloadedMediaUrls: Set<string> = new Set();\n private preloadingMediaUrls: Set<string> = new Set();\n private adRequestTokenCounter = 0;\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 fetchedAdDurations: Map<string, number> = new Map();\n private targetAdBreakDurationMs: number | null = null;\n private isAdaptiveMode: boolean = false;\n private failedVastUrls: Set<string> = new Set();\n private continuousFetchingActive: boolean = false;\n private adRequestQueue: string[] = [];\n private successfulAdRequests: string[] = [];\n private maxPlaceholderDurationMs: number = 5000;\n private placeholderStartTimeMs: number | null = null;\n private isShowingPlaceholder: boolean = false;\n private timeUpdateHandler?: (event: Event) => void;\n private emptiedHandler?: (event: Event) => void;\n\n constructor(config: StormcloudVideoPlayerConfig) {\n initializePolyfills();\n\n const browserOverrides = getBrowserConfigOverrides();\n this.config = { ...config, ...browserOverrides };\n this.video = config.videoElement;\n\n logBrowserInfo(config.debugAdTiming);\n\n this.ima = this.createAdPlayer(false);\n }\n\n private createAdPlayer(continueLiveStreamDuringAds: boolean): ImaController {\n const vastMode = this.config.vastMode || \"default\";\n let adPlayerType =\n this.config.adPlayerType || (vastMode === \"adstorm\" ? \"hls\" : \"ima\");\n\n if (adPlayerType === \"ima\" && !supportsGoogleIMA()) {\n if (this.config.debugAdTiming) {\n console.warn(\n \"[StormcloudVideoPlayer] Google IMA SDK not supported on this browser, falling back to HLS ad player\"\n );\n }\n adPlayerType = \"hls\";\n }\n\n if (adPlayerType === \"hls\") {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Creating HLS ad player (AdStorm mode)\"\n );\n }\n return createHlsAdPlayer(this.video, {\n continueLiveStreamDuringAds,\n ...(this.config.licenseKey\n ? { licenseKey: this.config.licenseKey }\n : {}),\n ...(this.hls ? { mainHlsInstance: this.hls } : {}),\n });\n } else {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Creating Google IMA ad player (Default mode)\"\n );\n }\n return createImaController(this.video, {\n continueLiveStreamDuringAds,\n });\n }\n }\n\n async load(): Promise<void> {\n if (!this.attached) {\n this.attach();\n }\n\n try {\n await this.fetchAdConfiguration();\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\n \"[StormcloudVideoPlayer] Failed to fetch ad configuration:\",\n error\n );\n }\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.ima.destroy();\n this.ima = this.createAdPlayer(false);\n this.ima.initialize();\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 this.isLiveStream =\n this.hls?.levels?.some(\n (level) =>\n level?.details?.live === true || level?.details?.type === \"LIVE\"\n ) ?? false;\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.ima.destroy();\n this.ima = this.createAdPlayer(this.shouldContinueLiveStreamDuringAds());\n this.ima.initialize();\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.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\")) {\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-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-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 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.ima.initialize();\n this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);\n this.ima.on(\"all_ads_completed\", () => {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] IMA all_ads_completed event received - ending ad break\"\n );\n }\n\n if (this.inAdBreak) {\n this.handleAdPodComplete();\n }\n });\n this.ima.on(\"ad_error\", (errorPayload?: any) => {\n const remaining = this.getRemainingAdMs();\n console.error(\"[AD-ERROR] Ad playback failed\", errorPayload || \"\");\n \n if (this.inAdBreak) {\n if (remaining > 500 && this.adPodQueue.length > 0) {\n const nextPreloaded = this.findNextPreloadedAd();\n if (nextPreloaded) {\n this.currentAdIndex++;\n this.playSingleAd(nextPreloaded).catch(() => {\n this.handleAdFailure();\n });\n } else {\n this.handleAdFailure();\n }\n } else {\n this.handleAdFailure();\n }\n } else {\n this.handleAdFailure();\n }\n });\n this.ima.on(\"content_pause\", () => {\n this.clearAdFailsafeTimer();\n this.clearAdRequestWatchdog();\n this.activeAdRequestToken = null;\n this.showAds = true;\n });\n this.ima.on(\"content_resume\", () => {\n this.clearAdFailsafeTimer();\n this.clearAdRequestWatchdog();\n this.activeAdRequestToken = null;\n this.showAds = false;\n\n if (!this.inAdBreak) {\n return;\n }\n\n const remaining = this.getRemainingAdMs();\n \n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] content_resume event: remaining=${remaining}ms, queued ads=${this.adRequestQueue.length}`);\n }\n\n if (remaining > 500) {\n this.tryNextAvailableAd();\n } else {\n this.handleAdPodComplete();\n }\n });\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.ima.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 });\n }\n\n if (marker.type === \"start\") {\n if (this.inAdBreak) {\n return;\n }\n\n this.inAdBreak = true;\n const durationMs =\n marker.durationSeconds != null\n ? marker.durationSeconds * 1000\n : undefined;\n this.expectedAdBreakDurationMs = durationMs;\n this.currentAdBreakStartWallClockMs = Date.now();\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.ima.isAdPlaying() && this.activeAdRequestToken === null) {\n const scheduled = this.findCurrentOrNextBreak(\n this.video.currentTime * 1000\n );\n const tags =\n this.selectVastTagsForBreak(scheduled) ||\n (this.apiVastTagUrl ? [this.apiVastTagUrl] : undefined);\n if (tags && tags.length > 0) {\n const first = tags[0] as string;\n const rest = tags.slice(1);\n this.adPodQueue = rest;\n \n this.playSingleAd(first).catch(() => {});\n }\n }\n return;\n }\n if (marker.type === \"end\") {\n this.inAdBreak = false;\n this.expectedAdBreakDurationMs = undefined;\n this.currentAdBreakStartWallClockMs = undefined;\n this.clearAdStartTimer();\n this.clearAdStopTimer();\n \n if (this.ima.isAdPlaying()) {\n this.ima.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 elapsedMatch = value.match(/Elapsed\\s*=\\s*([0-9.]+)/i);\n const durationMatch = value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n const res: { elapsed?: number; duration?: number } = {};\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) 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 private async fetchAdConfiguration(): Promise<void> {\n const vastMode = this.config.vastMode || \"default\";\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] VAST mode:\", vastMode);\n }\n\n if (vastMode === \"adstorm\") {\n if (!this.config.licenseKey) {\n if (this.config.debugAdTiming) {\n console.warn(\n \"[StormcloudVideoPlayer] AdStorm mode requires a license key\"\n );\n }\n return;\n }\n\n const vastEndpoint = `https://adstorm.co/api-adstorm-dev/adstorm/vast/${this.config.licenseKey}`;\n this.apiVastTagUrl = vastEndpoint;\n\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Using AdStorm VAST endpoint (adstorm mode):\",\n vastEndpoint\n );\n }\n return;\n }\n\n if (this.config.vastTagUrl) {\n this.apiVastTagUrl = this.config.vastTagUrl;\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Using custom VAST tag URL:\",\n this.apiVastTagUrl\n );\n }\n return;\n }\n\n const apiUrl = \"https://adstorm.co/api-adstorm-dev/adstorm/ads/web\";\n\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Fetching ad configuration from:\",\n apiUrl\n );\n }\n\n const headers: Record<string, string> = {};\n if (this.config.licenseKey) {\n headers[\"Authorization\"] = `Bearer ${this.config.licenseKey}`;\n }\n\n const response = await fetch(apiUrl, { headers });\n if (!response.ok) {\n if (this.config.debugAdTiming) {\n console.warn(\n `[StormcloudVideoPlayer] Failed to fetch ad configuration: ${response.status}`\n );\n }\n return;\n }\n\n const data: StormcloudApiResponse = await response.json();\n\n const imaPayload = data.response?.ima?.[\"publisherdesk.ima\"]?.payload;\n if (imaPayload) {\n this.apiVastTagUrl = decodeURIComponent(imaPayload);\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Extracted VAST tag URL from /ads/web:\",\n this.apiVastTagUrl\n );\n }\n } else {\n if (this.config.debugAdTiming) {\n console.warn(\n \"[StormcloudVideoPlayer] No VAST tag URL found in /ads/web response\"\n );\n }\n }\n\n const numberAds = data.response?.options?.vast?.cue_tones?.number_ads;\n if (numberAds != null && numberAds > 0) {\n this.apiNumberAds = numberAds;\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Number of ads per break from API:\",\n this.apiNumberAds\n );\n }\n }\n }\n\n getCurrentAdIndex(): number {\n return this.currentAdIndex;\n }\n\n getTotalAdsInBreak(): number {\n return this.totalAdsInBreak;\n }\n\n private generateVastUrlsWithCorrelators(\n baseUrl: string,\n count: number\n ): string[] {\n const urls: string[] = [];\n \n for (let i = 0; i < count; i++) {\n try {\n const url = new URL(baseUrl);\n const timestamp = Date.now();\n const random = Math.floor(Math.random() * 1000000);\n const uniqueCorrelator = `${timestamp}${random}${i}`;\n \n url.searchParams.set(\"correlator\", uniqueCorrelator);\n \n urls.push(url.toString());\n } catch (error) {\n console.warn(\n \"[StormcloudVideoPlayer] Failed to parse VAST URL:\",\n baseUrl,\n error\n );\n urls.push(`${baseUrl}${baseUrl.includes(\"?\") ? \"&\" : \"?\"}correlator=${Date.now()}${i}`);\n }\n }\n \n return urls;\n }\n\n isAdPlaying(): boolean {\n return this.inAdBreak && this.ima.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 async handleAdStart(_marker: Scte35Marker): Promise<void> {\n const scheduled = this.findCurrentOrNextBreak(\n this.video.currentTime * 1000\n );\n const tags = this.selectVastTagsForBreak(scheduled);\n\n let baseVastUrl: string;\n\n if (this.apiVastTagUrl) {\n baseVastUrl = this.apiVastTagUrl;\n } else if (tags && tags.length > 0 && tags[0]) {\n baseVastUrl = tags[0];\n } else {\n return;\n }\n\n const adBreakDurationMs = \n _marker.durationSeconds != null \n ? _marker.durationSeconds * 1000 \n : scheduled?.durationMs;\n\n if (this.isLiveStream && adBreakDurationMs != null && adBreakDurationMs > 0) {\n this.isAdaptiveMode = true;\n this.targetAdBreakDurationMs = adBreakDurationMs;\n this.fetchedAdDurations.clear();\n\n if (this.config.debugAdTiming) {\n console.log(\n `[CONTINUOUS-FETCH] 📺 LIVE MODE: Target duration=${adBreakDurationMs}ms | ` +\n `Will continuously fetch ads during break`\n );\n }\n } else {\n this.isAdaptiveMode = false;\n this.targetAdBreakDurationMs = null;\n this.fetchedAdDurations.clear();\n\n if (this.config.debugAdTiming) {\n console.log(\n `[CONTINUOUS-FETCH] 🎬 VOD MODE: Using fixed ad strategy`\n );\n }\n }\n\n this.adPodAllUrls = [];\n this.preloadingAdUrls.clear();\n this.vastToMediaUrlMap.clear();\n this.preloadedMediaUrls.clear();\n this.preloadingMediaUrls.clear();\n this.failedVastUrls.clear();\n this.adRequestQueue = [];\n this.successfulAdRequests = [];\n this.continuousFetchingActive = true;\n this.isShowingPlaceholder = false;\n this.placeholderStartTimeMs = null;\n\n const currentMuted = this.video.muted;\n const currentVolume = this.video.volume;\n this.ima.updateOriginalMutedState(currentMuted, currentVolume);\n\n this.inAdBreak = true;\n this.currentAdIndex = 0;\n this.totalAdsInBreak = 1;\n this.adPodQueue = [];\n\n if (\n this.expectedAdBreakDurationMs == null &&\n adBreakDurationMs != null\n ) {\n this.expectedAdBreakDurationMs = adBreakDurationMs;\n this.currentAdBreakStartWallClockMs = Date.now();\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] 🚀 Immediately requesting first ad...\");\n }\n\n const firstAdUrlArray = this.generateVastUrlsWithCorrelators(baseVastUrl, 1);\n const firstAdUrl = firstAdUrlArray[0];\n \n if (!firstAdUrl) {\n if (this.config.debugAdTiming) {\n console.warn(\"[CONTINUOUS-FETCH] ⚠️ Failed to generate first ad URL\");\n }\n this.handleAdPodComplete();\n return;\n }\n\n try {\n await this.ima.requestAds(firstAdUrl);\n \n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] ✅ First ad request successful, starting playback\");\n }\n\n this.successfulAdRequests.push(firstAdUrl);\n this.currentAdIndex++;\n \n this.startContinuousFetching(baseVastUrl);\n \n await this.ima.play();\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\"[CONTINUOUS-FETCH] ⚠️ First ad request failed:\", error);\n }\n this.failedVastUrls.add(firstAdUrl);\n \n this.startContinuousFetching(baseVastUrl);\n this.tryNextAvailableAd();\n }\n }\n\n private startContinuousFetching(baseVastUrl: string): void {\n if (!this.continuousFetchingActive) {\n return;\n }\n\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] 🔄 Starting continuous ad fetching loop\");\n }\n\n this.continuousFetchLoop(baseVastUrl);\n }\n\n private async continuousFetchLoop(baseVastUrl: string): Promise<void> {\n while (this.continuousFetchingActive && this.inAdBreak) {\n const remaining = this.getRemainingAdMs();\n \n if (remaining <= 0) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] ⏹️ Ad break time expired, stopping fetch loop\");\n }\n break;\n }\n\n const maxQueueSize = 3;\n if (this.adRequestQueue.length >= maxQueueSize) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] ⏸️ Queue full (${this.adRequestQueue.length}), pausing fetching...`);\n }\n await new Promise(resolve => setTimeout(resolve, 2000));\n continue;\n }\n\n const newAdUrl = this.generateVastUrlsWithCorrelators(baseVastUrl, 1)[0];\n \n if (!newAdUrl || this.failedVastUrls.has(newAdUrl)) {\n await new Promise(resolve => setTimeout(resolve, 1000));\n continue;\n }\n\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] 📡 Attempting to fetch ad (${this.successfulAdRequests.length + this.adRequestQueue.length + 1} total)...`);\n }\n\n try {\n const response = await fetch(newAdUrl, { mode: \"cors\" });\n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.status}`);\n }\n \n const xmlText = await response.text();\n \n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlText, \"text/xml\");\n const mediaFiles = xmlDoc.querySelectorAll(\"MediaFile\");\n \n if (mediaFiles.length === 0) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] ⚠️ VAST response has no media files, skipping\");\n }\n this.failedVastUrls.add(newAdUrl);\n await new Promise(resolve => setTimeout(resolve, 1000));\n continue;\n }\n\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] ✅ Successfully fetched ad, adding to queue (queue size: ${this.adRequestQueue.length + 1})`);\n }\n \n this.adRequestQueue.push(newAdUrl);\n this.totalAdsInBreak++;\n \n await new Promise(resolve => setTimeout(resolve, 500));\n \n } catch (error) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] ❌ Ad fetch failed:\", (error as Error).message);\n }\n this.failedVastUrls.add(newAdUrl);\n \n await new Promise(resolve => setTimeout(resolve, 2000));\n }\n }\n\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] 🛑 Continuous fetch loop ended\");\n }\n }\n\n private stopContinuousFetching(): void {\n this.continuousFetchingActive = false;\n \n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] 🛑 Stopping continuous ad fetching\");\n }\n }\n\n private async tryNextAvailableAd(retryCount: number = 0): Promise<void> {\n const remaining = this.getRemainingAdMs();\n \n if (remaining <= 500) {\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.adRequestQueue.length > 0) {\n const nextAdUrl = this.adRequestQueue.shift();\n if (nextAdUrl) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] 🎬 Playing next queued ad (${this.currentAdIndex + 1}/${this.totalAdsInBreak}, ${this.adRequestQueue.length} remaining in queue)`);\n }\n \n const currentMuted = this.video.muted;\n const currentVolume = this.video.volume;\n this.ima.updateOriginalMutedState(currentMuted, currentVolume);\n \n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] 🔊 Updated ad audio state: muted=${currentMuted}, volume=${currentVolume}`);\n }\n \n this.currentAdIndex++;\n this.successfulAdRequests.push(nextAdUrl);\n await this.playSingleAd(nextAdUrl).catch(() => {\n this.tryNextAvailableAd(0);\n });\n return;\n }\n }\n\n const maxRetries = 5;\n if (this.continuousFetchingActive && retryCount < maxRetries && remaining > 2000) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] ⏳ Queue empty but fetching active, waiting... (retry ${retryCount + 1}/${maxRetries})`);\n }\n \n await new Promise(resolve => setTimeout(resolve, 1000));\n \n await this.tryNextAvailableAd(retryCount + 1);\n return;\n }\n\n if (!this.isShowingPlaceholder && remaining > 1000) {\n this.showPlaceholderAndWaitForAds();\n } else {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] ⏹️ No more ads available, ending ad break\");\n }\n this.handleAdPodComplete();\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 (waitTime < 1000) {\n this.handleAdPodComplete();\n return;\n }\n\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] ⬛ Showing black placeholder for ${waitTime}ms while waiting for ads`);\n }\n\n this.isShowingPlaceholder = true;\n this.placeholderStartTimeMs = Date.now();\n \n this.ima.showPlaceholder();\n\n const checkInterval = 500;\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) {\n return;\n }\n\n if (this.adRequestQueue.length > 0) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] ✅ New ad became available during placeholder\");\n }\n \n this.isShowingPlaceholder = false;\n this.placeholderStartTimeMs = null;\n this.ima.hidePlaceholder();\n \n const currentMuted = this.video.muted;\n const currentVolume = this.video.volume;\n this.ima.updateOriginalMutedState(currentMuted, currentVolume);\n \n const nextAdUrl = this.adRequestQueue.shift();\n if (nextAdUrl) {\n this.currentAdIndex++;\n this.successfulAdRequests.push(nextAdUrl);\n await this.playSingleAd(nextAdUrl).catch(() => {\n this.tryNextAvailableAd();\n });\n }\n return;\n }\n }\n\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] ⏰ Placeholder timeout reached, no ads fetched\");\n }\n \n this.isShowingPlaceholder = false;\n this.placeholderStartTimeMs = null;\n this.ima.hidePlaceholder();\n this.handleAdPodComplete();\n }\n\n private findCurrentOrNextBreak(nowMs: number): AdBreak | undefined {\n const schedule: AdBreak[] = [];\n let candidate: AdBreak | undefined;\n for (const b of schedule) {\n const tol = this.config.driftToleranceMs ?? 1000;\n if (\n b.startTimeMs <= nowMs + tol &&\n (candidate == null || b.startTimeMs > (candidate.startTimeMs || 0))\n ) {\n candidate = b;\n }\n }\n return candidate;\n }\n\n private onTimeUpdate(currentTimeSec: number): void {\n if (this.ima.isAdPlaying()) return;\n const nowMs = currentTimeSec * 1000;\n const breakToPlay = this.findBreakForTime(nowMs);\n if (breakToPlay) {\n this.handleMidAdJoin(breakToPlay, nowMs);\n }\n }\n\n private async handleMidAdJoin(\n adBreak: AdBreak,\n nowMs: number\n ): Promise<void> {\n const durationMs = adBreak.durationMs ?? 0;\n const endMs = adBreak.startTimeMs + durationMs;\n if (durationMs > 0 && nowMs > adBreak.startTimeMs && nowMs < endMs) {\n const remainingMs = endMs - nowMs;\n const tags =\n this.selectVastTagsForBreak(adBreak) ||\n (this.apiVastTagUrl ? [this.apiVastTagUrl] : undefined);\n if (tags && tags.length > 0) {\n const first = tags[0] as string;\n const rest = tags.slice(1);\n this.adPodQueue = rest;\n \n this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);\n \n await this.playSingleAd(first);\n this.inAdBreak = true;\n this.expectedAdBreakDurationMs = remainingMs;\n this.currentAdBreakStartWallClockMs = Date.now();\n this.scheduleAdStopCountdown(remainingMs);\n }\n }\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.ima.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.ima.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 async playSingleAd(vastTagUrl: string): Promise<void> {\n if (this.ima.isAdPlaying()) {\n return;\n }\n\n if (this.failedVastUrls.has(vastTagUrl)) {\n console.warn(\"[AD-ERROR] Skipping already-failed VAST URL:\", vastTagUrl.substring(0, 60));\n this.handleAdFailure();\n return;\n }\n\n const requestToken = ++this.adRequestTokenCounter;\n this.activeAdRequestToken = requestToken;\n \n this.startAdRequestWatchdog(requestToken);\n\n try {\n await this.ima.requestAds(vastTagUrl);\n\n this.clearAdRequestWatchdog();\n\n if (this.activeAdRequestToken !== requestToken) {\n return;\n }\n\n try {\n this.startAdFailsafeTimer(requestToken);\n await this.ima.play();\n } catch (playError) {\n console.error(\"[AD-ERROR] Failed to play ad:\", playError);\n this.failedVastUrls.add(vastTagUrl);\n this.clearAdFailsafeTimer();\n if (this.activeAdRequestToken === requestToken) {\n this.activeAdRequestToken = null;\n }\n this.handleAdFailure();\n return;\n }\n } catch (error) {\n console.error(\"[AD-ERROR] Ad request failed:\", (error as Error)?.message);\n this.failedVastUrls.add(vastTagUrl);\n\n this.clearAdRequestWatchdog();\n this.clearAdFailsafeTimer();\n if (this.activeAdRequestToken === requestToken) {\n this.activeAdRequestToken = null;\n }\n\n this.handleAdFailure();\n }\n }\n\n private handleAdPodComplete(): void {\n this.clearAdRequestWatchdog();\n this.clearAdFailsafeTimer();\n this.activeAdRequestToken = null;\n\n this.stopContinuousFetching();\n \n if (this.isShowingPlaceholder) {\n this.ima.hidePlaceholder();\n this.isShowingPlaceholder = false;\n this.placeholderStartTimeMs = null;\n }\n\n this.preloadingAdUrls.clear();\n this.vastToMediaUrlMap.clear();\n this.preloadedMediaUrls.clear();\n this.preloadingMediaUrls.clear();\n this.adRequestQueue = [];\n this.successfulAdRequests = [];\n\n this.inAdBreak = false;\n this.expectedAdBreakDurationMs = undefined;\n this.currentAdBreakStartWallClockMs = undefined;\n this.clearAdStartTimer();\n this.clearAdStopTimer();\n this.adPodQueue = [];\n this.adPodAllUrls = [];\n this.showAds = false;\n this.currentAdIndex = 0;\n this.totalAdsInBreak = 0;\n\n this.ima.stop().catch(() => {});\n\n const restoredMuted = this.ima.getOriginalMutedState();\n const restoredVolume = this.ima.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 if (!this.shouldContinueLiveStreamDuringAds() && this.video.paused) {\n this.video.play()?.catch(() => {});\n }\n }\n\n private handleAdFailure(): void {\n const remaining = this.getRemainingAdMs();\n \n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] Ad failure: remaining=${remaining}ms, queued ads=${this.adRequestQueue.length}`);\n }\n \n if (remaining > 500) {\n this.tryNextAvailableAd();\n } else {\n console.error(\"[AD-ERROR] Ad failed and no time remaining. Failed URLs:\", this.failedVastUrls.size);\n this.handleAdPodComplete();\n }\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.ima.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 selectVastTagsForBreak(b?: AdBreak): string[] | undefined {\n if (!b || !b.vastTagUrl) return undefined;\n if (b.vastTagUrl.includes(\",\")) {\n return b.vastTagUrl\n .split(\",\")\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n }\n return [b.vastTagUrl];\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.ima.isAdPlaying(),\n inAdBreak: this.inAdBreak,\n activeAdRequestToken: this.activeAdRequestToken,\n ...extra,\n });\n }\n\n private async fetchAndParseVastXml(vastTagUrl: string): Promise<string[]> {\n try {\n const response = await fetch(vastTagUrl, { mode: \"cors\" });\n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.status}`);\n }\n const xmlText = await response.text();\n return this.extractMediaUrlsFromVast(xmlText);\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\n `[StormcloudVideoPlayer] Failed to fetch/parse VAST XML: ${vastTagUrl}`,\n error\n );\n }\n return [];\n }\n }\n\n private extractMediaUrlsFromVast(xmlText: string): string[] {\n const mediaUrls: string[] = [];\n \n try {\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlText, \"text/xml\");\n \n const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n \n for (const mediaFile of Array.from(mediaFileElements)) {\n const url = mediaFile.textContent?.trim();\n if (url) {\n const lowerUrl = url.toLowerCase();\n if (\n lowerUrl.endsWith(\".mp4\") ||\n lowerUrl.endsWith(\".webm\") ||\n lowerUrl.endsWith(\".mov\") ||\n lowerUrl.endsWith(\".avi\") ||\n lowerUrl.includes(\".mp4?\") ||\n lowerUrl.includes(\".webm?\") ||\n lowerUrl.includes(\"/mp4/\") ||\n lowerUrl.includes(\"type=video\")\n ) {\n mediaUrls.push(url);\n }\n }\n }\n \n if (this.config.debugAdTiming && mediaUrls.length > 0) {\n console.log(\n `[StormcloudVideoPlayer] Extracted ${mediaUrls.length} media URLs from VAST:`,\n mediaUrls\n );\n }\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\n \"[StormcloudVideoPlayer] Failed to parse VAST XML:\",\n error\n );\n }\n }\n \n return mediaUrls;\n }\n\n private async fetchVastDuration(vastTagUrl: string): Promise<number | null> {\n try {\n const response = await fetch(vastTagUrl, { mode: \"cors\" });\n if (!response.ok) {\n if (this.config.debugAdTiming) {\n console.warn(\n `[ADAPTIVE-POD] Failed to fetch VAST: ${response.status}`\n );\n }\n return null;\n }\n \n const xmlText = await response.text();\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlText, \"text/xml\");\n \n const durationText = xmlDoc.querySelector(\"Duration\")?.textContent;\n if (!durationText) {\n if (this.config.debugAdTiming) {\n console.warn(\"[ADAPTIVE-POD] No Duration element found in VAST\");\n }\n return null;\n }\n \n const durationParts = durationText.split(\":\");\n const durationSeconds =\n parseInt(durationParts[0] || \"0\", 10) * 3600 +\n parseInt(durationParts[1] || \"0\", 10) * 60 +\n parseInt(durationParts[2] || \"0\", 10);\n \n return durationSeconds;\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\n `[ADAPTIVE-POD] Error fetching VAST duration from ${vastTagUrl}:`,\n error\n );\n }\n return null;\n }\n }\n\n private calculateAdditionalAdsNeeded(): number {\n if (!this.isAdaptiveMode || this.targetAdBreakDurationMs === null) {\n return 0;\n }\n\n let totalFetchedDurationMs = 0;\n for (const duration of this.fetchedAdDurations.values()) {\n totalFetchedDurationMs += duration * 1000;\n }\n\n const fetchedCount = this.fetchedAdDurations.size;\n const averageDurationMs = fetchedCount > 0 \n ? totalFetchedDurationMs / fetchedCount \n : 30 * 1000;\n\n const queuedButNotFetched = this.adPodAllUrls.length - fetchedCount;\n \n const estimatedQueuedDurationMs = queuedButNotFetched * averageDurationMs;\n const estimatedTotalDurationMs = totalFetchedDurationMs + estimatedQueuedDurationMs;\n\n const remainingTimeMs = this.targetAdBreakDurationMs - estimatedTotalDurationMs;\n\n if (remainingTimeMs <= 0) {\n if (this.config.debugAdTiming) {\n console.log(\n `[ADAPTIVE-POD] ✅ Target duration met: Fetched=${totalFetchedDurationMs}ms + Queued(${queuedButNotFetched} ads)=${estimatedQueuedDurationMs}ms = ${estimatedTotalDurationMs}ms / Target=${this.targetAdBreakDurationMs}ms`\n );\n }\n return 0;\n }\n\n const additionalAds = Math.ceil(remainingTimeMs / averageDurationMs);\n\n if (this.config.debugAdTiming) {\n console.log(\n `[ADAPTIVE-POD] 📊 Need ${additionalAds} more ads | ` +\n `Fetched: ${totalFetchedDurationMs}ms (${fetchedCount} ads) | ` +\n `Queued: ${estimatedQueuedDurationMs}ms (${queuedButNotFetched} ads) | ` +\n `Target: ${this.targetAdBreakDurationMs}ms | ` +\n `Remaining: ${remainingTimeMs}ms | ` +\n `Avg duration: ${averageDurationMs}ms`\n );\n }\n\n return additionalAds;\n }\n\n private async addAdaptiveAdsToQueue(): Promise<void> {\n if (!this.isAdaptiveMode || !this.apiVastTagUrl) {\n return;\n }\n\n const additionalAds = this.calculateAdditionalAdsNeeded();\n if (additionalAds <= 0) {\n return;\n }\n\n const newUrls = this.generateVastUrlsWithCorrelators(\n this.apiVastTagUrl,\n additionalAds\n );\n\n if (this.config.debugAdTiming) {\n console.log(\n `[ADAPTIVE-POD] 🔄 Adding ${newUrls.length} additional VAST URLs to queue (will be preloaded sequentially)`\n );\n }\n\n this.adPodAllUrls.push(...newUrls);\n this.adPodQueue.push(...newUrls);\n this.totalAdsInBreak += newUrls.length;\n }\n\n private async preloadMediaFile(mediaUrl: string): Promise<void> {\n if (this.preloadedMediaUrls.has(mediaUrl)) {\n return;\n }\n\n if (this.preloadingMediaUrls.has(mediaUrl)) {\n return;\n }\n\n this.preloadingMediaUrls.add(mediaUrl);\n\n try {\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Preloading video file: ${mediaUrl}`\n );\n }\n\n const response = await fetch(mediaUrl, {\n mode: \"cors\",\n method: \"GET\",\n headers: {\n Range: \"bytes=0-1048576\",\n },\n });\n\n if (response.ok || response.status === 206) {\n this.preloadedMediaUrls.add(mediaUrl);\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Successfully preloaded video file: ${mediaUrl}`\n );\n }\n }\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\n `[StormcloudVideoPlayer] Failed to preload video file: ${mediaUrl}`,\n error\n );\n }\n } finally {\n this.preloadingMediaUrls.delete(mediaUrl);\n }\n }\n\n private async preloadAllAdsInBackground(): Promise<void> {\n if (this.adPodAllUrls.length === 0) {\n return;\n }\n\n if (this.isAdaptiveMode) {\n if (this.config.debugAdTiming) {\n console.log(\n `[ADAPTIVE-POD] 🔄 Starting sequential preload of remaining ads`\n );\n }\n\n const processedUrls = new Set<string>();\n \n for (const url of this.adPodAllUrls) {\n if (this.ima.hasPreloadedAd?.(url) || this.fetchedAdDurations.has(url)) {\n processedUrls.add(url);\n }\n }\n\n if (this.config.debugAdTiming && processedUrls.size > 0) {\n console.log(\n `[ADAPTIVE-POD] 📦 Skipping ${processedUrls.size} already-preloaded ads`\n );\n }\n\n while (true) {\n const nextUrl = this.adPodAllUrls.find(url => !processedUrls.has(url));\n \n if (!nextUrl) {\n if (this.config.debugAdTiming) {\n console.log(`[ADAPTIVE-POD] ✅ All queued ads processed (${processedUrls.size} total)`);\n }\n break;\n }\n\n processedUrls.add(nextUrl);\n\n if (this.config.debugAdTiming) {\n console.log(\n `[ADAPTIVE-POD] 📥 Preloading ad ${processedUrls.size}/${this.adPodAllUrls.length}...`\n );\n }\n\n try {\n await this.preloadSingleAd(nextUrl);\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\n `[ADAPTIVE-POD] ⚠️ Preload failed for ad ${processedUrls.size}:`,\n error\n );\n }\n }\n\n if (this.calculateAdditionalAdsNeeded() === 0) {\n if (this.config.debugAdTiming) {\n console.log(\n `[ADAPTIVE-POD] ✅ Target duration reached (${processedUrls.size} ads preloaded), stopping`\n );\n }\n break;\n }\n }\n\n if (this.config.debugAdTiming) {\n console.log(\n `[ADAPTIVE-POD] ✅ Sequential preloading completed (${processedUrls.size} ads ready)`\n );\n }\n } else {\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Starting parallel preload of ${this.adPodAllUrls.length} ads`\n );\n }\n\n const preloadPromises = this.adPodAllUrls.map((vastTagUrl) =>\n this.preloadSingleAd(vastTagUrl).catch((error) => {\n if (this.config.debugAdTiming) {\n console.warn(\n `[StormcloudVideoPlayer] Preload failed for ${vastTagUrl}:`,\n error\n );\n }\n })\n );\n\n await Promise.all(preloadPromises);\n\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Background preloading completed for all ads`\n );\n }\n }\n }\n\n private async preloadSingleAd(vastTagUrl: string): Promise<void> {\n if (!vastTagUrl) return;\n\n try {\n if (this.isAdaptiveMode && !this.fetchedAdDurations.has(vastTagUrl)) {\n const duration = await this.fetchVastDuration(vastTagUrl);\n if (duration !== null) {\n this.fetchedAdDurations.set(vastTagUrl, duration);\n \n if (this.config.debugAdTiming) {\n console.log(\n `[ADAPTIVE-POD] ✓ Fetched ad duration: ${duration}s (${this.fetchedAdDurations.size} ads fetched so far)`\n );\n }\n\n await this.addAdaptiveAdsToQueue();\n }\n }\n\n if (this.ima.preloadAds && !this.ima.hasPreloadedAd(vastTagUrl)) {\n if (!this.preloadingAdUrls.has(vastTagUrl)) {\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Preloading VAST: ${vastTagUrl}`\n );\n }\n\n this.preloadingAdUrls.add(vastTagUrl);\n\n await this.ima\n .preloadAds(vastTagUrl)\n .then(() => {\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] IMA VAST preload complete: ${vastTagUrl}`\n );\n }\n })\n .catch((error) => {\n if (this.config.debugAdTiming) {\n console.warn(\n `[StormcloudVideoPlayer] IMA VAST preload failed: ${vastTagUrl}`,\n error\n );\n }\n })\n .finally(() => {\n this.preloadingAdUrls.delete(vastTagUrl);\n });\n }\n }\n\n let mediaUrls = this.vastToMediaUrlMap.get(vastTagUrl);\n\n if (!mediaUrls) {\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Fetching and parsing VAST to extract media URLs: ${vastTagUrl}`\n );\n }\n\n mediaUrls = await this.fetchAndParseVastXml(vastTagUrl);\n\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Extracted ${mediaUrls.length} media URLs:`,\n mediaUrls\n );\n }\n\n if (mediaUrls.length > 0) {\n this.vastToMediaUrlMap.set(vastTagUrl, mediaUrls);\n }\n }\n\n if (mediaUrls && mediaUrls.length > 0) {\n const primaryMediaUrl = mediaUrls[0];\n if (primaryMediaUrl && !this.preloadedMediaUrls.has(primaryMediaUrl)) {\n await this.preloadMediaFile(primaryMediaUrl);\n }\n }\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\n `[StormcloudVideoPlayer] Failed to preload ad: ${vastTagUrl}`,\n error\n );\n }\n }\n }\n\n private findNextPreloadedAd(): string | undefined {\n for (let i = 0; i < this.adPodQueue.length; i++) {\n const vastTagUrl = this.adPodQueue[i];\n if (!vastTagUrl) continue;\n\n if (this.failedVastUrls.has(vastTagUrl)) {\n console.warn(\"[AD-ERROR] Skipping failed URL in queue\");\n continue;\n }\n\n const hasImaPreload = this.ima.hasPreloadedAd?.(vastTagUrl) ?? false;\n const mediaUrls = this.vastToMediaUrlMap.get(vastTagUrl);\n const hasMediaPreload =\n mediaUrls && mediaUrls.length > 0\n ? this.preloadedMediaUrls.has(mediaUrls[0]!)\n : false;\n\n if (hasImaPreload || hasMediaPreload) {\n this.adPodQueue.splice(0, i + 1);\n return vastTagUrl;\n }\n }\n\n return undefined;\n }\n\n private getRemainingAdMs(): number {\n if (\n this.expectedAdBreakDurationMs == null ||\n this.currentAdBreakStartWallClockMs == null\n )\n return 0;\n const elapsed = Date.now() - this.currentAdBreakStartWallClockMs;\n return Math.max(0, this.expectedAdBreakDurationMs - elapsed);\n }\n\n private findBreakForTime(nowMs: number): AdBreak | undefined {\n const schedule: AdBreak[] = [];\n for (const b of schedule) {\n const end = (b.startTimeMs || 0) + (b.durationMs || 0);\n if (\n nowMs >= (b.startTimeMs || 0) &&\n (b.durationMs ? nowMs < end : true)\n ) {\n return b;\n }\n }\n return undefined;\n }\n\n toggleMute(): void {\n if (this.ima.isAdPlaying()) {\n const currentPerceptualState = this.isMuted();\n const newMutedState = !currentPerceptualState;\n\n this.ima.updateOriginalMutedState(newMutedState, this.video.volume);\n this.ima.setAdVolume(newMutedState ? 0 : 1);\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.ima.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.ima.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.ima.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.ima.updateOriginalMutedState(muted, this.video.volume);\n this.ima.setAdVolume(muted ? 0 : 1);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] setMuted applied during ad\", {\n muted,\n });\n }\n return;\n }\n\n this.ima.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.ima.isAdPlaying();\n\n if (adPlaying) {\n this.ima.setAdVolume(clampedVolume);\n this.ima.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.ima.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] setVolume called:\", clampedVolume);\n }\n }\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.ima && this.ima.isAdPlaying()) {\n const width = this.video.clientWidth || 640;\n const height = this.video.clientHeight || 360;\n\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Resizing ads manager to ${width}x${height}`\n );\n }\n\n this.ima.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 \n // Remove event listeners to prevent race conditions\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.ima?.destroy();\n this.preloadingAdUrls.clear();\n this.vastToMediaUrlMap.clear();\n this.preloadedMediaUrls.clear();\n this.preloadingMediaUrls.clear();\n this.adPodAllUrls = [];\n this.adRequestQueue = [];\n this.successfulAdRequests = [];\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}\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\n if (/Web0S|webOS/i.test(ua)) {\n name = 'LG WebOS';\n isSmartTV = true;\n const match = ua.match(/Web0S[/\\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 }\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 }\n } else if (/SMART-TV|SmartTV/i.test(ua)) {\n name = 'Smart TV';\n isSmartTV = true;\n } else if (/NetCast/i.test(ua)) {\n name = 'LG NetCast';\n isSmartTV = true;\n isLegacyTV = true;\n } else if (/BRAVIA/i.test(ua)) {\n name = 'Sony BRAVIA';\n isSmartTV = true;\n }\n\n const chromeVersion = getChromeVersion(ua);\n const webkitVersion = getWebKitVersion(ua);\n\n if (chromeVersion > 0) {\n if (!isSmartTV) {\n name = 'Chrome';\n version = chromeVersion.toString();\n majorVersion = chromeVersion;\n }\n\n if (chromeVersion < 50) {\n supportsIMA = false;\n supportsModernJS = false;\n isLegacyTV = true;\n recommendedAdPlayer = 'hls';\n }\n }\n\n if (webkitVersion > 0 && webkitVersion < 600) {\n supportsModernJS = false;\n if (isSmartTV) {\n isLegacyTV = true;\n supportsIMA = false;\n recommendedAdPlayer = 'hls';\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 };\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 userAgent: navigator.userAgent,\n });\n}\n\nexport function getBrowserConfigOverrides(): {\n adPlayerType?: 'ima' | 'hls';\n allowNativeHls?: boolean;\n} {\n const browser = detectBrowser();\n const overrides: any = {};\n\n if (browser.isLegacyTV || !browser.supportsIMA) {\n overrides.adPlayerType = 'hls';\n }\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","import type { ImaController } from \"../types\";\nimport { supportsGoogleIMA } from \"../utils/browserCompat\";\n\ndeclare global {\n interface Window {\n google?: any;\n }\n}\n\nexport function createImaController(\n video: HTMLVideoElement,\n options?: { continueLiveStreamDuringAds?: boolean }\n): ImaController {\n let adPlaying = false;\n let contentVideoHidden = false;\n let originalMutedState = false;\n let originalVolume =\n typeof video.volume === \"number\" && !Number.isNaN(video.volume)\n ? Math.max(0, Math.min(1, video.volume))\n : 1;\n const listeners = new Map<string, Set<(payload?: any) => void>>();\n const preloadedVast = new Map<string, string>();\n const preloadingVast = new Map<string, Promise<void>>();\n let adVideoElement: HTMLVideoElement | undefined;\n\n function setAdPlayingFlag(isPlaying: boolean): void {\n if (isPlaying) {\n video.dataset.stormcloudAdPlaying = \"true\";\n } else {\n delete video.dataset.stormcloudAdPlaying;\n }\n }\n\n function hideContentVideo(): void {\n if (!contentVideoHidden) {\n video.style.transition = \"opacity 0.3s ease-in-out\";\n video.style.opacity = \"0\";\n setTimeout(() => {\n video.style.visibility = \"hidden\";\n }, 300);\n video.muted = true;\n video.volume = 0;\n contentVideoHidden = true;\n }\n }\n\n function showContentVideo(): void {\n if (contentVideoHidden) {\n video.style.visibility = \"visible\";\n video.style.transition = \"opacity 0.3s ease-in-out\";\n video.offsetHeight;\n video.style.opacity = \"1\";\n video.muted = originalMutedState;\n video.volume = originalVolume;\n contentVideoHidden = false;\n }\n }\n\n function createAdVideoElement(): HTMLVideoElement {\n const adVideo = document.createElement(\"video\");\n adVideo.style.position = \"absolute\";\n adVideo.style.top = \"0\";\n adVideo.style.left = \"0\";\n adVideo.style.width = \"100%\";\n adVideo.style.height = \"100%\";\n adVideo.style.objectFit = \"contain\";\n adVideo.style.backgroundColor = \"transparent\";\n adVideo.style.zIndex = \"15\";\n adVideo.playsInline = true;\n adVideo.muted = false;\n adVideo.volume = originalMutedState ? 0 : originalVolume;\n\n adVideo.style.opacity = \"0\";\n adVideo.addEventListener(\n \"canplay\",\n () => {\n adVideo.style.opacity = \"1\";\n },\n { once: true }\n );\n\n return adVideo;\n }\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 {}\n }\n }\n\n function ensureImaLoaded(): Promise<void> {\n if (!supportsGoogleIMA()) {\n console.warn(\n \"[IMA] Google IMA SDK is not supported on this browser. Please use HLS ad player instead.\"\n );\n return Promise.reject(\n new Error(\"Google IMA SDK not supported on this browser\")\n );\n }\n\n try {\n const frameEl = window.frameElement as HTMLIFrameElement | null;\n const sandboxAttr = frameEl?.getAttribute?.(\"sandbox\") || \"\";\n if (sandboxAttr) {\n const tokens = new Set(\n sandboxAttr\n .split(/\\s+/)\n .map((t) => t.trim())\n .filter((t) => t.length > 0)\n );\n const allowsScripts = tokens.has(\"allow-scripts\");\n if (!allowsScripts) {\n // eslint-disable-next-line no-console\n console.error(\n \"StormcloudVideoPlayer: The host page is inside a sandboxed iframe without 'allow-scripts'. Google IMA cannot run ads within sandboxed frames. Remove the sandbox attribute or include 'allow-scripts allow-same-origin'.\"\n );\n }\n }\n } catch {}\n\n if (typeof window !== \"undefined\" && window.google?.ima)\n return Promise.resolve();\n const existing = document.querySelector(\n 'script[data-ima=\"true\"]'\n ) as HTMLScriptElement | null;\n if (existing) {\n if (window.google?.ima) {\n return Promise.resolve();\n }\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error(\"IMA SDK load timeout\"));\n }, 10000);\n existing.addEventListener(\"load\", () => {\n clearTimeout(timeout);\n resolve();\n });\n existing.addEventListener(\"error\", () => {\n clearTimeout(timeout);\n reject(new Error(\"IMA SDK load failed\"));\n });\n });\n }\n return new Promise((resolve, reject) => {\n const script = document.createElement(\"script\");\n script.src = \"https://imasdk.googleapis.com/js/sdkloader/ima3.js\";\n script.async = true;\n script.defer = true;\n script.setAttribute(\"data-ima\", \"true\");\n script.onload = () => resolve();\n script.onerror = () => reject(new Error(\"IMA SDK load failed\"));\n document.head.appendChild(script);\n });\n }\n\n let adsManager: any | undefined;\n let adsLoader: any | undefined;\n let adDisplayContainer: any | undefined;\n let adContainerEl: HTMLDivElement | undefined;\n let lastAdTagUrl: string | undefined;\n let retryAttempts = 0;\n const maxRetries = 2;\n const backoffBaseMs = 500;\n let adsLoadedPromise: Promise<void> | undefined;\n let adsLoadedResolve: (() => void) | undefined;\n let adsLoadedReject: ((error: Error) => void) | undefined;\n\n function makeAdsRequest(google: any, vastTagUrl: string) {\n const adsRequest = new google.ima.AdsRequest();\n \n console.log(\"[IMA] 📡 Requesting VAST from URL (letting IMA fetch fresh)\");\n adsRequest.adTagUrl = vastTagUrl;\n\n const videoWidth = video.offsetWidth || video.clientWidth || 640;\n const videoHeight = video.offsetHeight || video.clientHeight || 360;\n\n adsRequest.linearAdSlotWidth = videoWidth;\n adsRequest.linearAdSlotHeight = videoHeight;\n adsRequest.nonLinearAdSlotWidth = videoWidth;\n adsRequest.nonLinearAdSlotHeight = videoHeight;\n\n if (typeof adsRequest.setAdWillAutoPlay === \"function\") {\n try {\n const willAutoPlay = !video.paused || video.autoplay;\n adsRequest.setAdWillAutoPlay(willAutoPlay);\n } catch (error) {\n console.warn(\"[IMA] Failed to call setAdWillAutoPlay:\", error);\n }\n }\n\n if (typeof adsRequest.setAdWillPlayMuted === \"function\") {\n try {\n const willPlayMuted = video.muted || video.volume === 0;\n adsRequest.setAdWillPlayMuted(willPlayMuted);\n } catch (error) {\n console.warn(\"[IMA] Failed to call setAdWillPlayMuted:\", error);\n }\n }\n\n adsRequest.vastLoadTimeout = 10000;\n\n adsLoader.requestAds(adsRequest);\n }\n\n function ensurePlaceholderContainer(): void {\n if (adContainerEl) {\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 = \"10\";\n container.style.backgroundColor = \"transparent\";\n container.style.transition =\n \"opacity 0.3s ease-in-out, background-color 0.3s ease-in-out\";\n container.style.opacity = \"0\";\n\n video.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n\n async function fetchVastDocument(vastTagUrl: string): Promise<string> {\n const response = await fetch(vastTagUrl, { mode: \"cors\" });\n if (!response.ok) {\n throw new Error(`Failed to preload VAST: ${response.status}`);\n }\n return response.text();\n }\n\n function destroyAdsManager() {\n if (adsManager) {\n try {\n adsManager.destroy();\n } catch {}\n adsManager = undefined;\n }\n\n if (adVideoElement) {\n adVideoElement.style.opacity = \"0\";\n }\n }\n\n return {\n initialize() {\n ensureImaLoaded()\n .then(() => {\n const google = window.google;\n ensurePlaceholderContainer();\n\n if (!adDisplayContainer && adContainerEl) {\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl.appendChild(adVideoElement);\n }\n\n adDisplayContainer = new google.ima.AdDisplayContainer(\n adContainerEl,\n adVideoElement\n );\n try {\n adDisplayContainer.initialize?.();\n } catch {}\n }\n })\n .catch(() => {});\n },\n async requestAds(vastTagUrl: string) {\n if (!vastTagUrl || vastTagUrl.trim() === \"\") {\n const error = new Error(\"VAST tag URL is empty or undefined\");\n console.warn(\"[IMA] ❌\", error.message);\n return Promise.reject(error);\n }\n\n try {\n new URL(vastTagUrl);\n } catch (e) {\n const error = new Error(`Invalid VAST tag URL format: ${vastTagUrl}`);\n console.warn(\"[IMA] ❌\", error.message);\n return Promise.reject(error);\n }\n\n if (adPlaying) {\n console.warn(\n \"[IMA] ⚠️ Cannot request new ads while an ad is playing. Call stop() first.\"\n );\n return Promise.reject(\n new Error(\"Ad already playing - cannot request new ads\")\n );\n }\n\n destroyAdsManager();\n\n adsLoadedReject = undefined;\n adsLoadedResolve = undefined;\n\n let currentReject: ((error: Error) => void) | undefined;\n adsLoadedPromise = new Promise<void>((resolve, reject) => {\n adsLoadedResolve = resolve;\n adsLoadedReject = reject;\n currentReject = reject;\n\n setTimeout(() => {\n if (adsLoadedReject) {\n adsLoadedReject(new Error(\"Ad request timeout\"));\n adsLoadedReject = undefined;\n adsLoadedResolve = undefined;\n }\n }, 10000);\n });\n\n try {\n await ensureImaLoaded();\n const google = window.google;\n lastAdTagUrl = vastTagUrl;\n retryAttempts = 0;\n\n if (!adDisplayContainer) {\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 = \"transparent\";\n container.style.transition =\n \"opacity 0.3s ease-in-out, background-color 0.3s ease-in-out\";\n container.style.opacity = \"0\";\n\n if (!video.parentElement) {\n throw new Error(\"Video element has no parent for ad container\");\n }\n\n video.parentElement.appendChild(container);\n adContainerEl = container;\n\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl.appendChild(adVideoElement);\n }\n\n adDisplayContainer = new google.ima.AdDisplayContainer(\n container,\n adVideoElement\n );\n\n }\n\n const videoWidth = video.offsetWidth || video.clientWidth;\n const videoHeight = video.offsetHeight || video.clientHeight;\n\n if (\n !videoWidth ||\n !videoHeight ||\n videoWidth === 0 ||\n videoHeight === 0\n ) {\n const error = new Error(\n `Invalid video dimensions: ${videoWidth}x${videoHeight}. Cannot initialize ads.`\n );\n console.warn(\"[IMA]\", error.message);\n currentReject?.(error);\n adsLoadedReject = undefined;\n adsLoadedResolve = undefined;\n return Promise.reject(error);\n }\n\n if (!adsLoader) {\n const adsLoaderCls = new google.ima.AdsLoader(adDisplayContainer);\n adsLoader = adsLoaderCls;\n\n adsLoader.addEventListener(\n google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,\n (evt: any) => {\n try {\n const adsRenderingSettings =\n new google.ima.AdsRenderingSettings();\n adsRenderingSettings.enablePreloading = true;\n adsManager = evt.getAdsManager(video, adsRenderingSettings);\n const AdEvent = google.ima.AdEvent.Type;\n const AdErrorEvent = google.ima.AdErrorEvent.Type;\n\n adsManager.addEventListener(\n AdErrorEvent.AD_ERROR,\n (errorEvent: any) => {\n const error = errorEvent.getError();\n console.error(\"[DEBUG-ERROR] ❌ AD_ERROR:\", error.getMessage?.());\n\n destroyAdsManager();\n\n adPlaying = false;\n setAdPlayingFlag(false);\n\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n adContainerEl.style.backgroundColor = \"transparent\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n }\n }, 300);\n }\n\n showContentVideo();\n\n if (adsLoadedReject) {\n adsLoadedReject(new Error(\"Ad playback error\"));\n adsLoadedReject = undefined;\n adsLoadedResolve = undefined;\n }\n\n if (lastAdTagUrl && retryAttempts < maxRetries) {\n const delay =\n backoffBaseMs * Math.pow(2, retryAttempts++);\n window.setTimeout(() => {\n try {\n makeAdsRequest(google, lastAdTagUrl!);\n } catch {}\n }, delay);\n } else {\n emit(\"ad_error\");\n\n if (!options?.continueLiveStreamDuringAds) {\n if (video.paused) {\n video.play()?.catch(() => {});\n }\n }\n }\n }\n );\n\n adsManager.addEventListener(\n AdEvent.CONTENT_PAUSE_REQUESTED,\n () => {\n if (!options?.continueLiveStreamDuringAds) {\n video.pause();\n }\n\n adPlaying = true;\n setAdPlayingFlag(true);\n \n emit(\"content_pause\");\n }\n );\n\n adsManager.addEventListener(AdEvent.STARTED, () => {\n setAdPlayingFlag(true);\n\n hideContentVideo();\n\n if (adVideoElement) {\n adVideoElement.volume = originalMutedState\n ? 0\n : originalVolume;\n adVideoElement.muted = originalMutedState;\n }\n\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"auto\";\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.backgroundColor = \"#000\";\n adContainerEl.offsetHeight;\n adContainerEl.style.opacity = \"1\";\n }\n });\n\n adsManager.addEventListener(\n AdEvent.CONTENT_RESUME_REQUESTED,\n () => {\n adPlaying = false;\n setAdPlayingFlag(false);\n \n emit(\"content_resume\");\n }\n );\n\n adsManager.addEventListener(AdEvent.ALL_ADS_COMPLETED, () => {\n adPlaying = false;\n setAdPlayingFlag(false);\n\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n adContainerEl.style.backgroundColor = \"transparent\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n }\n }, 300);\n }\n\n showContentVideo();\n\n if (!options?.continueLiveStreamDuringAds && video.paused) {\n video.play().catch(() => {});\n }\n\n emit(\"all_ads_completed\");\n });\n\n if (adsLoadedResolve) {\n adsLoadedResolve();\n adsLoadedResolve = undefined;\n adsLoadedReject = undefined;\n }\n } catch (e) {\n console.error(\"[IMA] Error setting up ads manager:\", e);\n adPlaying = false;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n adContainerEl.style.backgroundColor = \"transparent\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n }\n }, 300);\n }\n showContentVideo();\n\n if (!options?.continueLiveStreamDuringAds) {\n if (video.paused) {\n video.play().catch(() => {});\n }\n }\n\n if (adsLoadedReject) {\n adsLoadedReject(new Error(\"Failed to setup ads manager\"));\n adsLoadedReject = undefined;\n adsLoadedResolve = undefined;\n }\n emit(\"ad_error\");\n }\n },\n false\n );\n\n adsLoader.addEventListener(\n google.ima.AdErrorEvent.Type.AD_ERROR,\n (adErrorEvent: any) => {\n const error = adErrorEvent.getError();\n console.error(\"[DEBUG-ERROR] ❌ ADS_LOADER ERROR:\", error.getMessage?.());\n\n adPlaying = false;\n setAdPlayingFlag(false);\n\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n adContainerEl.style.backgroundColor = \"transparent\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n }\n }, 300);\n }\n\n showContentVideo();\n\n if (!options?.continueLiveStreamDuringAds) {\n if (video.paused) {\n video.play().catch(() => {});\n }\n }\n\n if (adsLoadedReject) {\n adsLoadedReject(new Error(\"Ads loader error\"));\n adsLoadedReject = undefined;\n adsLoadedResolve = undefined;\n }\n emit(\"ad_error\");\n },\n false\n );\n }\n\n makeAdsRequest(google, vastTagUrl);\n return adsLoadedPromise;\n } catch (error) {\n console.error(\"[IMA] Failed to request ads:\", error);\n\n currentReject?.(error as Error);\n adsLoadedReject = undefined;\n adsLoadedResolve = undefined;\n return Promise.reject(error);\n }\n },\n async preloadAds(vastTagUrl: string) {\n if (!vastTagUrl || vastTagUrl.trim() === \"\") {\n return Promise.resolve();\n }\n\n if (preloadedVast.has(vastTagUrl)) {\n return Promise.resolve();\n }\n\n const inflight = preloadingVast.get(vastTagUrl);\n if (inflight) {\n return inflight;\n }\n\n const preloadPromise = fetchVastDocument(vastTagUrl)\n .then((xml) => {\n preloadedVast.set(vastTagUrl, xml);\n })\n .catch(() => {\n preloadedVast.delete(vastTagUrl);\n })\n .finally(() => {\n preloadingVast.delete(vastTagUrl);\n });\n\n preloadingVast.set(vastTagUrl, preloadPromise);\n return preloadPromise;\n },\n hasPreloadedAd(vastTagUrl: string) {\n return preloadedVast.has(vastTagUrl);\n },\n async play() {\n if (!window.google?.ima || !adDisplayContainer) {\n return Promise.reject(new Error(\"IMA SDK not available\"));\n }\n\n if (!adsManager) {\n return Promise.reject(new Error(\"No ads manager\"));\n }\n\n try {\n const width = video.clientWidth || 640;\n const height = video.clientHeight || 360;\n\n adsManager.init(width, height, window.google.ima.ViewMode.NORMAL);\n\n adPlaying = true;\n\n const adVolume = originalMutedState ? 0 : originalVolume;\n if (adVideoElement) {\n adVideoElement.volume = adVolume;\n adVideoElement.muted = originalMutedState;\n }\n\n try {\n adsManager.setVolume(adVolume);\n } catch {}\n\n adsManager.start();\n\n return Promise.resolve();\n } catch (error) {\n console.error(\"[IMA] ❌ Error starting ad:\", error);\n adPlaying = false;\n setAdPlayingFlag(false);\n\n if (!options?.continueLiveStreamDuringAds) {\n video.play()?.catch(() => {});\n }\n return Promise.reject(error);\n }\n },\n async stop() {\n adPlaying = false;\n setAdPlayingFlag(false);\n\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n adContainerEl.style.backgroundColor = \"transparent\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n }\n }, 300);\n }\n\n showContentVideo();\n\n try {\n adsManager?.stop?.();\n } catch {}\n\n destroyAdsManager();\n },\n destroy() {\n destroyAdsManager();\n\n adPlaying = false;\n setAdPlayingFlag(false);\n\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n adContainerEl.style.backgroundColor = \"transparent\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n\n if (adContainerEl.parentElement) {\n adContainerEl.parentElement.removeChild(adContainerEl);\n }\n\n adContainerEl = undefined;\n adVideoElement = undefined;\n }\n }, 300);\n }\n\n showContentVideo();\n\n try {\n adsLoader?.destroy?.();\n } catch {}\n\n adDisplayContainer = undefined;\n adsLoader = undefined;\n contentVideoHidden = false;\n preloadedVast.clear();\n preloadingVast.clear();\n },\n isAdPlaying() {\n return adPlaying;\n },\n resize(width: number, height: number) {\n if (!adsManager || !window.google?.ima) {\n console.warn(\n \"[IMA] Cannot resize: No ads manager or IMA SDK available\"\n );\n return;\n }\n\n try {\n console.log(`[IMA] Resizing ads manager to ${width}x${height}`);\n adsManager.resize(width, height, window.google.ima.ViewMode.NORMAL);\n } catch (error) {\n console.warn(\"[IMA] Error resizing ads manager:\", error);\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 off(event: string, listener: (payload?: any) => void) {\n listeners.get(event)?.delete(listener);\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 getOriginalMutedState() {\n return originalMutedState;\n },\n getOriginalVolume() {\n return originalVolume;\n },\n setAdVolume(volume: number) {\n const clampedVolume = Math.max(0, Math.min(1, volume));\n\n if (adVideoElement && adPlaying) {\n adVideoElement.volume = clampedVolume;\n adVideoElement.muted = clampedVolume === 0;\n }\n\n if (adsManager && adPlaying) {\n try {\n adsManager.setVolume(clampedVolume);\n } catch {}\n }\n },\n getAdVolume(): number {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n\n if (adsManager && adPlaying) {\n try {\n return adsManager.getVolume();\n } catch (error) {\n console.warn(\"[IMA] Failed to get ad volume:\", error);\n return 1;\n }\n }\n return 1;\n },\n showPlaceholder() {\n ensurePlaceholderContainer();\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.backgroundColor = \"#000\";\n adContainerEl.offsetHeight;\n adContainerEl.style.opacity = \"1\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n },\n hidePlaceholder() {\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n adContainerEl.style.backgroundColor = \"transparent\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n },\n };\n}\n","import type { ImaController } from \"../types\";\nimport Hls from \"hls.js\";\n\ninterface VastMediaFile {\n url: string;\n type: string;\n width: number;\n height: number;\n bitrate?: number | undefined;\n}\n\ninterface 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\ninterface VastAd {\n id: string;\n title: string;\n duration: number;\n mediaFiles: VastMediaFile[];\n trackingUrls: VastTrackingUrls;\n clickThrough?: string | undefined;\n}\n\nexport function createHlsAdPlayer(\n contentVideo: HTMLVideoElement,\n options?: {\n continueLiveStreamDuringAds?: boolean;\n licenseKey?: string;\n mainHlsInstance?: Hls;\n }\n): ImaController {\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 const licenseKey = options?.licenseKey;\n const mainHlsInstance = options?.mainHlsInstance;\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 const preloadedAds = new Map<string, VastAd>();\n const preloadingAds = new Map<string, Promise<void>>();\n let destroyed = false;\n let pendingTimeouts: number[] = [];\n\n let trackingFired = {\n impression: false,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false,\n };\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(\n `[HlsAdPlayer] Error in event listener for ${event}:`,\n error\n );\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 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 if (licenseKey) {\n trackingUrl = `${trackingUrl}${\n trackingUrl.includes(\"?\") ? \"&\" : \"?\"\n }license_key=${licenseKey}`;\n }\n\n const img = new Image(1, 1);\n img.src = trackingUrl;\n console.log(`[HlsAdPlayer] Fired tracking pixel: ${trackingUrl}`);\n } catch (error) {\n console.warn(`[HlsAdPlayer] Error firing tracking pixel:`, error);\n }\n });\n }\n\n function getMainStreamQuality(): {\n width: number;\n height: number;\n bitrate: number;\n } | null {\n if (!mainHlsInstance || !mainHlsInstance.levels) {\n return null;\n }\n\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\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) {\n throw new Error(\"No media files available\");\n }\n\n const firstFile = mediaFiles[0];\n if (!firstFile) {\n throw new Error(\"No media files available\");\n }\n\n if (mediaFiles.length === 1) {\n return firstFile;\n }\n\n const mainQuality = getMainStreamQuality();\n if (!mainQuality) {\n console.log(\n \"[HlsAdPlayer] No main stream quality info, using first media file\"\n );\n return firstFile;\n }\n\n console.log(\"[HlsAdPlayer] Main stream quality:\", mainQuality);\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\n const fileBitrate = (file.bitrate || 5000) * 1000;\n const bitrateDiff = Math.abs(fileBitrate - mainQuality.bitrate);\n\n const score = resolutionDiff * 2 + bitrateDiff / 1000;\n\n return { file, score, resolutionDiff, bitrateDiff };\n });\n\n scoredFiles.sort((a, b) => a.score - b.score);\n\n const bestMatch = scoredFiles[0];\n if (!bestMatch) {\n console.log(\"[HlsAdPlayer] No best match found, using first media file\");\n return firstFile;\n }\n\n console.log(\"[HlsAdPlayer] Selected media file:\", {\n url: bestMatch.file.url,\n resolution: `${bestMatch.file.width}x${bestMatch.file.height}`,\n bitrate: bestMatch.file.bitrate,\n score: bestMatch.score,\n resolutionDiff: bestMatch.resolutionDiff,\n bitrateDiff: bestMatch.bitrateDiff,\n });\n\n return bestMatch.file;\n }\n\n function parseVastXml(xmlString: string): 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 \"[HlsAdPlayer] 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(\"[HlsAdPlayer] 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 parseInt(durationParts[2] || \"0\", 10);\n\n const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n const mediaFiles: VastMediaFile[] = [];\n\n console.log(\n `[HlsAdPlayer] 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 `[HlsAdPlayer] MediaFile ${index}: type=\"${type}\", url=\"${url}\", width=\"${width}\", height=\"${height}\"`\n );\n\n if (type === \"application/x-mpegURL\" || type.includes(\"m3u8\")) {\n if (!url) {\n console.warn(\n `[HlsAdPlayer] MediaFile ${index} has HLS type but empty URL`\n );\n return;\n }\n\n const bitrateAttr = mf.getAttribute(\"bitrate\");\n const bitrateValue = bitrateAttr\n ? parseInt(bitrateAttr, 10)\n : undefined;\n\n mediaFiles.push({\n url,\n type,\n width: parseInt(width || \"1920\", 10),\n height: parseInt(height || \"1080\", 10),\n bitrate:\n bitrateValue && bitrateValue > 0 ? bitrateValue : undefined,\n });\n\n console.log(`[HlsAdPlayer] Added HLS MediaFile: ${url}`);\n } else {\n console.log(\n `[HlsAdPlayer] MediaFile ${index} ignored (type=\"${type}\" is not HLS)`\n );\n }\n });\n\n if (mediaFiles.length === 0) {\n if (isNoAdAvailable) {\n console.warn(\n \"[HlsAdPlayer] No ads available (VAST response indicates no ads)\"\n );\n } else {\n console.warn(\"[HlsAdPlayer] No HLS 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(\"[HlsAdPlayer] Error parsing VAST XML:\", error);\n return null;\n }\n }\n\n async function fetchAndParseVastAd(\n vastTagUrl: string\n ): Promise<VastAd | null> {\n const response = await fetch(vastTagUrl);\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(\"[HlsAdPlayer] VAST XML received\");\n console.log(\n \"[HlsAdPlayer] VAST XML content (first 2000 chars):\",\n vastXml.substring(0, 2000)\n );\n\n return parseVastXml(vastXml);\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\n video.volume = 1.0;\n console.log(\n `[HlsAdPlayer] Created ad video element with volume ${video.volume}`\n );\n\n return video;\n }\n\n function setupAdEventListeners(): void {\n if (!adVideoElement || !currentAd) return;\n\n adVideoElement.addEventListener(\"timeupdate\", () => {\n if (!currentAd || !adVideoElement) return;\n\n const progress = adVideoElement.currentTime / currentAd.duration;\n\n if (progress >= 0.25 && !trackingFired.firstQuartile) {\n trackingFired.firstQuartile = true;\n fireTrackingPixels(currentAd.trackingUrls.firstQuartile);\n }\n\n if (progress >= 0.5 && !trackingFired.midpoint) {\n trackingFired.midpoint = true;\n fireTrackingPixels(currentAd.trackingUrls.midpoint);\n }\n\n if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n trackingFired.thirdQuartile = true;\n fireTrackingPixels(currentAd.trackingUrls.thirdQuartile);\n }\n });\n\n adVideoElement.addEventListener(\"playing\", () => {\n if (!currentAd || trackingFired.start) return;\n trackingFired.start = true;\n fireTrackingPixels(currentAd.trackingUrls.start);\n console.log(\"[HlsAdPlayer] Ad started playing\");\n });\n\n adVideoElement.addEventListener(\"ended\", () => {\n if (!currentAd || trackingFired.complete) return;\n trackingFired.complete = true;\n fireTrackingPixels(currentAd.trackingUrls.complete);\n console.log(\"[HlsAdPlayer] Ad completed\");\n\n handleAdComplete();\n });\n\n adVideoElement.addEventListener(\"error\", (e) => {\n console.error(\"[HlsAdPlayer] Ad video error:\", e);\n if (currentAd) {\n fireTrackingPixels(currentAd.trackingUrls.error);\n }\n handleAdError();\n });\n\n adVideoElement.addEventListener(\"volumechange\", () => {\n if (!currentAd) 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!.ended) {\n fireTrackingPixels(currentAd.trackingUrls.pause);\n }\n });\n\n adVideoElement.addEventListener(\"play\", () => {\n if (currentAd && 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 console.log(\"[HlsAdPlayer] Handling ad completion\");\n adPlaying = false;\n setAdPlayingFlag(false);\n\n emit(\"content_resume\");\n\n const timeoutId = window.setTimeout(() => {\n if (destroyed) {\n console.log(\"[HlsAdPlayer] Player destroyed, skipping post-completion check\");\n return;\n }\n \n const stillInPod = contentVideo.dataset.stormcloudAdPlaying === \"true\";\n if (stillInPod) {\n console.log(\n \"[HlsAdPlayer] Still in ad pod - keeping ad container visible (black screen)\"\n );\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n }\n \n const idx = pendingTimeouts.indexOf(timeoutId);\n if (idx !== -1) {\n pendingTimeouts.splice(idx, 1);\n }\n }, 50);\n \n pendingTimeouts.push(timeoutId);\n }\n\n function handleAdError(): void {\n console.log(\"[HlsAdPlayer] Handling ad error\");\n adPlaying = false;\n setAdPlayingFlag(false);\n\n const previousMutedState = contentVideo.muted;\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalMutedState ? 0 : originalVolume;\n console.log(\n `[HlsAdPlayer] Restored mute state: ${previousMutedState} -> ${originalMutedState}`\n );\n\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n\n if (!options?.continueLiveStreamDuringAds) {\n if (contentVideo.paused) {\n contentVideo.play().catch(() => {});\n }\n }\n\n emit(\"ad_error\");\n }\n\n return {\n initialize() {\n console.log(\"[HlsAdPlayer] Initializing\");\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\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n },\n\n async requestAds(vastTagUrl: string) {\n console.log(\"[HlsAdPlayer] Requesting ads:\", vastTagUrl);\n\n if (adPlaying) {\n console.warn(\n \"[HlsAdPlayer] Cannot request new ads while an ad is playing\"\n );\n return Promise.reject(new Error(\"Ad already playing\"));\n }\n\n try {\n sessionId = generateSessionId();\n let ad: VastAd | null | undefined;\n\n if (preloadedAds.has(vastTagUrl)) {\n ad = preloadedAds.get(vastTagUrl);\n preloadedAds.delete(vastTagUrl);\n console.log(\n \"[HlsAdPlayer] Using preloaded VAST response:\",\n vastTagUrl\n );\n } else {\n ad = await fetchAndParseVastAd(vastTagUrl);\n }\n\n if (!ad) {\n console.warn(\"[HlsAdPlayer] No ads available from VAST response\");\n emit(\"ad_error\");\n return Promise.resolve();\n }\n\n currentAd = ad;\n console.log(\n `[HlsAdPlayer] Ad parsed: ${ad.title}, duration: ${ad.duration}s`\n );\n\n fireTrackingPixels(ad.trackingUrls.impression);\n trackingFired.impression = true;\n\n return Promise.resolve();\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error requesting ads:\", error);\n emit(\"ad_error\");\n return Promise.reject(error);\n }\n },\n async preloadAds(vastTagUrl: string) {\n if (!vastTagUrl || vastTagUrl.trim() === \"\") {\n return Promise.resolve();\n }\n\n if (preloadedAds.has(vastTagUrl)) {\n return Promise.resolve();\n }\n\n const inflight = preloadingAds.get(vastTagUrl);\n if (inflight) {\n return inflight;\n }\n\n const preloadPromise = fetchAndParseVastAd(vastTagUrl)\n .then((ad) => {\n if (ad) {\n preloadedAds.set(vastTagUrl, ad);\n console.log(\n \"[HlsAdPlayer] Cached VAST response for preloading:\",\n vastTagUrl\n );\n }\n })\n .catch((error) => {\n console.warn(\"[HlsAdPlayer] Failed to preload VAST response:\", error);\n preloadedAds.delete(vastTagUrl);\n })\n .finally(() => {\n preloadingAds.delete(vastTagUrl);\n });\n\n preloadingAds.set(vastTagUrl, preloadPromise);\n return preloadPromise;\n },\n hasPreloadedAd(vastTagUrl: string) {\n return preloadedAds.has(vastTagUrl);\n },\n\n async play() {\n if (!currentAd) {\n console.warn(\n \"[HlsAdPlayer] Cannot play: No ad loaded (no ads available)\"\n );\n return Promise.reject(new Error(\"No ad loaded\"));\n }\n\n console.log(\"[HlsAdPlayer] Starting ad playback\");\n\n try {\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl?.appendChild(adVideoElement);\n setupAdEventListeners();\n }\n\n trackingFired = {\n impression: trackingFired.impression,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false,\n };\n\n // Capture content volume BEFORE muting\n const contentVolume = contentVideo.volume;\n originalVolume = Math.max(\n 0,\n Math.min(1, contentVolume || originalVolume)\n );\n\n if (!options?.continueLiveStreamDuringAds) {\n contentVideo.pause();\n console.log(\"[HlsAdPlayer] Content paused (VOD mode)\");\n } else {\n console.log(\"[HlsAdPlayer] Content continues (Live mode)\");\n }\n\n console.log(\"[HlsAdPlayer] FORCE MUTING main video\");\n contentVideo.muted = true;\n contentVideo.volume = 0;\n adPlaying = true;\n setAdPlayingFlag(true);\n\n if (adVideoElement) {\n const adVolume = originalMutedState ? 0 : originalVolume;\n adVideoElement.volume = Math.max(0, Math.min(1, adVolume));\n adVideoElement.muted = false;\n console.log(\n `[HlsAdPlayer] Set ad video volume to ${adVideoElement.volume}, muted: ${adVideoElement.muted}, originalMutedState: ${originalMutedState}, contentVolume: ${contentVolume}`\n );\n }\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(currentAd.mediaFiles);\n if (!mediaFile) {\n throw new Error(\"No media file available for ad\");\n }\n\n console.log(`[HlsAdPlayer] Loading ad from: ${mediaFile.url}`);\n\n if (Hls.isSupported()) {\n if (adHls) {\n adHls.destroy();\n }\n\n adHls = new Hls({\n enableWorker: true,\n lowLatencyMode: false,\n });\n\n adHls.loadSource(mediaFile.url);\n adHls.attachMedia(adVideoElement);\n\n adHls.on(Hls.Events.MANIFEST_PARSED, () => {\n console.log(\"[HlsAdPlayer] HLS manifest parsed, starting playback\");\n adVideoElement!.play().catch((error) => {\n console.error(\"[HlsAdPlayer] Error starting ad playback:\", error);\n handleAdError();\n });\n });\n\n adHls.on(Hls.Events.ERROR, (event, data) => {\n console.error(\"[HlsAdPlayer] HLS error:\", data);\n if (data.fatal) {\n handleAdError();\n }\n });\n } else if (\n adVideoElement.canPlayType(\"application/vnd.apple.mpegurl\")\n ) {\n adVideoElement.src = mediaFile.url;\n adVideoElement.play().catch((error) => {\n console.error(\"[HlsAdPlayer] Error starting ad playback:\", error);\n handleAdError();\n });\n } else {\n throw new Error(\"HLS not supported\");\n }\n\n return Promise.resolve();\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error playing ad:\", error);\n handleAdError();\n return Promise.reject(error);\n }\n },\n\n async stop() {\n console.log(\"[HlsAdPlayer] Stopping ad\");\n adPlaying = false;\n setAdPlayingFlag(false);\n\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n\n if (adHls) {\n adHls.destroy();\n adHls = undefined;\n }\n\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n }\n\n currentAd = undefined;\n },\n\n destroy() {\n console.log(\"[HlsAdPlayer] Destroying\");\n destroyed = true;\n \n // Clear all pending timeouts\n for (const timeoutId of pendingTimeouts) {\n clearTimeout(timeoutId);\n }\n pendingTimeouts = [];\n \n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalMutedState ? 0 : originalVolume;\n\n if (adHls) {\n adHls.destroy();\n adHls = undefined;\n }\n\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n adVideoElement.remove();\n adVideoElement = undefined;\n }\n\n if (adContainerEl?.parentElement) {\n adContainerEl.parentElement.removeChild(adContainerEl);\n }\n\n adContainerEl = undefined;\n currentAd = undefined;\n listeners.clear();\n preloadedAds.clear();\n preloadingAds.clear();\n },\n\n isAdPlaying() {\n return adPlaying;\n },\n\n resize(width: number, height: number) {\n console.log(`[HlsAdPlayer] Resizing to ${width}x${height}`);\n\n if (adContainerEl) {\n adContainerEl.style.width = `${width}px`;\n adContainerEl.style.height = `${height}px`;\n }\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 console.log(\n `[HlsAdPlayer] updateOriginalMutedState called: { muted: ${originalMutedState} -> ${muted}, volume: ${originalVolume} -> ${nextVolume} }`\n );\n originalMutedState = muted;\n originalVolume = nextVolume;\n },\n\n getOriginalMutedState() {\n return originalMutedState;\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 showPlaceholder() {\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\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\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 },\n };\n}\n","import type { ClientInfo, TrackingData, HeartbeatData } 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\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(\n \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track\",\n {\n method: \"POST\",\n headers,\n body: JSON.stringify(trackingData),\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(\n \"[StormcloudVideoPlayer] Error sending initial tracking data:\",\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"]}
1
+ {"version":3,"sources":["/home/ubuntu24/Dev/stormcloud-vp/lib/ui/StormcloudVideoPlayer.cjs","../../src/ui/StormcloudVideoPlayer.tsx","../../src/sdk/adstormPlayer.ts","../../src/player/StormcloudVideoPlayer.ts","../../src/utils/polyfills.ts","../../src/utils/browserCompat.ts"],"names":["__create","Object","create","__defProp","defineProperty","__getOwnPropDesc","getOwnPropertyDescriptor","__getOwnPropNames","getOwnPropertyNames","__getProtoOf","getPrototypeOf","__hasOwnProp","prototype","hasOwnProperty","__export","target","all","name","get","enumerable","__copyProps","to","from","except","desc","key","call","__toESM","mod","isNodeMode","__esModule","value","__toCommonJS","StormcloudVideoPlayer_exports","StormcloudVideoPlayerComponent","module","exports","import_react","require","import_hls","SUPPORTED_VIDEO_EXTENSIONS","UNSUPPORTED_VIDEO_EXTENSIONS","getFileExtension","url","pathname","URL","lastDot","lastIndexOf","slice","toLowerCase","ext","split","isUnsupportedFormat","indexOf","replace","isSupportedFormat","mimeType","includes","createAdStormPlayer","contentVideo","options","adPlaying","originalMutedState","originalVolume","Math","max","min","volume","listeners","Map","adVideoElement","adContainerEl","destroyed","allowNativeHls","trackingFired","impression","start","firstQuartile","midpoint","thirdQuartile","complete","log","args","debug","console","emit","event","payload","set","Array","fn","error","warn","fireTrackingPixels","urls","length","forEach","img","Image","src","buildVastUrl","durationSeconds","metadata","baseUrl","licenseKey","defaultMetadata","video","codec","width","videoWidth","height","videoHeight","fps","bitrate","profile","pix_fmt","has_b_frames","audio","sample_rate","finalMetadata","metadataStr","encodeURIComponent","JSON","stringify","ceil","parseVastXml","xmlString","ads","parser","DOMParser","xmlDoc","parseFromString","parserError","querySelector","textContent","adElements","querySelectorAll","adElement","adId","getAttribute","title","durationText","durationParts","duration","parseInt","parseFloat","mediaFileElements","mediaFiles","mf","type","trim","originalUrl","replaceFlvExtension","push","trackingUrls","el","eventKey","clickThrough","id","selectBestMediaFile","mp4Files","filter","candidates","targetWidth","targetHeight","sort","a","b","diffA","abs","diffB","createAdVideoElement","document","createElement","style","position","left","top","objectFit","backgroundColor","zIndex","playsInline","muted","setAdPlayingFlag","isPlaying","dataset","stormcloudAdPlaying","setupAdEventListeners","currentAd","ad","addEventListener","progress","currentTime","e","opacity","setTimeout","display","pointerEvents","visibility","handleAdError","fetchVast","vastUrl","response","xmlText","fetch","headers","ok","Error","status","statusText","text","initialize","container","right","bottom","alignItems","justifyContent","transition","parentElement","appendChild","requestAds","parsed","Promise","reject","isNaN","resolve","play","mediaFile","pause","offsetHeight","stop","destroy","remove","removeChild","resize","on","listener","has","Set","off","delete","setAdVolume","updateOriginalMutedState","nextVolume","Number","getOriginalMutedState","getOriginalVolume","showPlaceholder","hidePlaceholder","setAllowNativeHls","polyfillURLSearchParams","URLSearchParams","URLSearchParamsPolyfill","init","params","parseQueryString","append","query","cleanQuery","startsWith","param","decodedKey","safeDecodeURIComponent","decodedValue","str","decodeURIComponent","values","String","getAll","callback","toString","parts","join","window","polyfillTextEncoder","TextEncoder","TextEncoderPolyfill","encoding","encode","utf8","i","charcode","charCodeAt","Uint8Array","polyfillPromiseFinally","finally","constructor","then","reason","polyfillObjectAssign","assign","sources","TypeError","nextSource","nextKey","polyfillArrayFrom","arrayLike","mapFn","thisArg","items","len","result","polyfillStringStartsWith","search","pos","substring","endsWith","polyfillStringIncludes","polyfillStringEndsWith","initializePolyfills","getChromeVersion","ua","match","getWebKitVersion","getPlatform","navigator","userAgentData","platform","userAgent","test","detectBrowser","version","majorVersion","isSmartTV","isLegacyTV","supportsModernJS","chromeVersion","webkitVersion","logBrowserInfo","browser","getBrowserConfigOverrides","overrides","StormcloudVideoPlayer","config","attached","inAdBreak","ptsDriftEmaMs","isLiveStream","nativeHlsMode","videoSrcProtection","bufferedSegmentsCount","shouldAutoplayAfterBuffering","hasInitialBufferCompleted","browserOverrides","videoElement","debugAdTiming","adPlayer","load","attach","shouldUseNativeHls","lowLatencyMode","isLive","autoplay","catch","hls","Hls","enableWorker","backBufferLength","liveDurationInfinity","maxLiveSyncPlaybackRate","liveSyncDuration","maxBufferLength","maxMaxBufferLength","maxBufferSize","maxBufferHole","highBufferWatchdogPeriod","nudgeOffset","startPosition","Events","MEDIA_ATTACHED","level","details","live","nudgeMaxRetry","loadSource","MANIFEST_PARSED","minSegments","levels","some","minSegmentsBeforePlay","FRAG_BUFFERED","err","FRAG_PARSING_METADATA","_evt","data","id3Tags","samples","map","s","ptsSeconds","pts","tag","onId3Tag","FRAG_CHANGED","frag","tagList","isArray","entry","idx","parseCueOutDuration","onScte35Marker","raw","prog","parseCueOutCont","elapsed","attrs","parseAttributeList","hasScteOut","hasScteIn","klass","toNumber","ERROR","fatal","ErrorTypes","NETWORK_ERROR","startLoad","MEDIA_ERROR","recoverMediaError","attachMedia","handleAdPodComplete","timeUpdateHandler","emptiedHandler","isAdPlaying","wasPaused","paused","streamType","getStreamType","canNative","canPlayType","updatePtsDrift","marker","parseScte35FromId3","decodeId3ValueToText","cueOutMatch","arg","dur","id3","cueOutContMatch","cont","cueInMatch","decoder","TextDecoder","decode","out","fromCharCode","durationMs","handleAdStart","num","d","elapsedMatch","durationMatch","res","regex","rawVal","val","n","scheduleAdStopCountdown","remainingMs","clearAdStopTimer","ms","floor","adStopTimerId","clearTimeout","ptsSecondsSample","sampleMs","isFinite","alpha","expectedAdBreakDurationMs","restoredMuted","restoredVolume","isShowingAds","shouldShowNativeControls","showCustomControls","toggleMute","currentMuted","newMutedState","toggleFullscreen","fullscreenElement","requestFullscreen","exitFullscreen","isMuted","setMuted","setVolume","clampedVolume","isFullscreen","clientHeight","removeEventListener","getCurrentAdIndex","getTotalAdsInBreak","React","memo","props","driftToleranceMs","immediateManifestAds","hideLoadingIndicator","onVolumeToggle","onFullscreenToggle","onControlClick","onReady","wrapperClassName","wrapperStyle","className","controls","preload","poster","children","restVideoAttrs","useRef","useState","setAdStatus","setShouldShowNativeControls","setIsMuted","setIsFullscreen","setIsPlaying","setCurrentTime","setDuration","playbackRate","setPlaybackRate","showVolumeSlider","setShowVolumeSlider","showSpeedMenu","setShowSpeedMenu","isLoading","setIsLoading","isBuffering","setIsBuffering","showLicenseWarning","setShowLicenseWarning","innerWidth","innerHeight","viewportWidth","isPortrait","setViewportWidth","setIsPortrait","getResponsiveScale","seconds","minutes","padStart","remainingSeconds","videoRef","current","currentSrc","readyState","getBoundingClientRect","clickX","rect","newTime","newVolume","rate","useMemo","prop","cfg","player","showNative","criticalPropsKey","playerRef","currentIndex","prev","showAds","totalAds","setInterval","checkAdStatus","clearInterval","interval","useEffect","handleResize","currentTimeValue","durationValue","volumeValue","rateValue","updateStates","handleFullscreenChange","bufferingTimeoutRef","handleLoadStart","handleLoadedMetadata","handleLoadedData","handleCanPlay","handleCanPlayThrough","handleWaiting","handlePlaying","handlePause","handleEnded","import_jsx_runtime","jsxs","Fragment","jsx","overflow","minHeight","maxWidth","maxHeight","borderRadius","boxShadow","ref","aspectRatio","import_fa","FaSpinner","color","animation","transform","background","padding","backdropFilter","border","textAlign","margin","fontSize","fontWeight","marginBottom","textShadow","lineHeight","showCenterPlay","adStatus","onClick","handleCenterPlayClick","cursor","onMouseEnter","currentTarget","borderColor","onMouseLeave","FaPlay","size","marginLeft","shouldShowEnhancedControls","handleTimelineSeek","flexWrap","gap","responsiveScale","handlePlayPause","minWidth","FaPause","FaVolumeMute","FaVolumeDown","FaVolumeUp","flexDirection","onMouseDown","preventDefault","sliderElement","handleMouseMove","moveEvent","y","clientY","percentage","handleVolumeChange"],"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_hls = __toESM(require(\"hls.js\"), 1);\n\n// src/sdk/adstormPlayer.ts\nvar SUPPORTED_VIDEO_EXTENSIONS = [\".mp4\", \".webm\", \".ogg\", \".m3u8\", \".ts\"];\nvar UNSUPPORTED_VIDEO_EXTENSIONS = [\".flv\", \".f4v\", \".swf\", \".wmv\", \".avi\", \".mov\", \".mkv\"];\nfunction getFileExtension(url) {\n try {\n const pathname = new URL(url, \"http://dummy\").pathname;\n const lastDot = pathname.lastIndexOf(\".\");\n if (lastDot === -1) return \"\";\n return pathname.slice(lastDot).toLowerCase();\n } catch {\n const lastDot = url.lastIndexOf(\".\");\n if (lastDot === -1) return \"\";\n const ext = url.slice(lastDot).split(/[?#]/)[0];\n return (ext || \"\").toLowerCase();\n }\n}\nfunction isUnsupportedFormat(url) {\n const ext = getFileExtension(url);\n return UNSUPPORTED_VIDEO_EXTENSIONS.indexOf(ext) !== -1;\n}\nfunction replaceFlvExtension(url) {\n const ext = getFileExtension(url);\n if (ext === \".flv\") {\n return url.replace(/\\.flv(\\?|$)/i, \".mp4$1\");\n }\n return url;\n}\nfunction isSupportedFormat(url, mimeType) {\n if (isUnsupportedFormat(url)) {\n return false;\n }\n const ext = getFileExtension(url);\n if (SUPPORTED_VIDEO_EXTENSIONS.indexOf(ext) !== -1) {\n return true;\n }\n if (ext === \"\" || ext === \".\") {\n return mimeType.includes(\"video/mp4\") || mimeType.includes(\"video/webm\") || mimeType.includes(\"m3u8\") || mimeType.includes(\"application/x-mpegurl\");\n }\n return false;\n}\nfunction createAdStormPlayer(contentVideo, options) {\n const { licenseKey, debug = false } = 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 adVideoElement;\n let adContainerEl;\n let currentAd;\n let destroyed = false;\n let allowNativeHls = false;\n let trackingFired = {\n impression: false,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false\n };\n function log(...args) {\n if (debug) {\n console.log(\"[AdStormPlayer]\", ...args);\n }\n }\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(`[AdStormPlayer] Error in event listener for ${event}:`, error);\n }\n }\n }\n function fireTrackingPixels(urls) {\n if (!urls || urls.length === 0) return;\n urls.forEach((url) => {\n try {\n const img = new Image(1, 1);\n img.src = url;\n log(\"Fired tracking pixel:\", url);\n } catch (error) {\n console.warn(\"[AdStormPlayer] Error firing tracking pixel:\", error);\n }\n });\n }\n function buildVastUrl(durationSeconds, metadata) {\n const baseUrl = `https://adstorm.co/api-adstorm-dev/adstorm/vast/${licenseKey}/pod`;\n const defaultMetadata = {\n video: {\n codec: \"h264\",\n width: contentVideo.videoWidth || 1280,\n height: contentVideo.videoHeight || 720,\n fps: 29.97,\n bitrate: 5e3,\n profile: \"high\",\n pix_fmt: \"yuv420p\",\n has_b_frames: 0\n },\n audio: {\n codec: \"aac\",\n sample_rate: 48e3,\n bitrate: 128\n }\n };\n const finalMetadata = metadata || defaultMetadata;\n const metadataStr = encodeURIComponent(JSON.stringify(finalMetadata));\n return `${baseUrl}?duration=${Math.ceil(durationSeconds)}&metadata=${metadataStr}`;\n }\n function parseVastXml(xmlString) {\n const ads = [];\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(\"[AdStormPlayer] XML parsing error:\", parserError.textContent);\n return [];\n }\n const adElements = xmlDoc.querySelectorAll(\"Ad\");\n adElements.forEach((adElement) => {\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = adElement.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n const durationText = adElement.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 + parseFloat(durationParts[2] || \"0\");\n const mediaFileElements = adElement.querySelectorAll(\"MediaFile\");\n const mediaFiles = [];\n mediaFileElements.forEach((mf) => {\n const type = mf.getAttribute(\"type\") || \"\";\n let url = mf.textContent?.trim() || \"\";\n const width = parseInt(mf.getAttribute(\"width\") || \"1920\", 10);\n const height = parseInt(mf.getAttribute(\"height\") || \"1080\", 10);\n const bitrate = mf.getAttribute(\"bitrate\") ? parseInt(mf.getAttribute(\"bitrate\"), 10) : void 0;\n if (!url) {\n log(`Skipping empty MediaFile URL`);\n return;\n }\n const originalUrl = url;\n url = replaceFlvExtension(url);\n if (url !== originalUrl) {\n log(`Converted FLV to MP4: ${originalUrl} -> ${url}`);\n }\n if (isUnsupportedFormat(url)) {\n const ext = getFileExtension(url);\n log(`Skipping unsupported format: ${url} (extension: ${ext}, declared type: ${type})`);\n return;\n }\n if (isSupportedFormat(url, type)) {\n mediaFiles.push({ url, type, width, height, bitrate });\n log(`Found media file: ${url} (${type}, ${width}x${height})`);\n } else {\n log(`Skipping incompatible media file: ${url} (type: ${type})`);\n }\n });\n if (mediaFiles.length === 0) {\n log(\"No valid media files found in ad:\", adId);\n return;\n }\n const trackingUrls = {\n impression: [],\n start: [],\n firstQuartile: [],\n midpoint: [],\n thirdQuartile: [],\n complete: [],\n error: []\n };\n adElement.querySelectorAll(\"Impression\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.impression.push(url);\n });\n adElement.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 = adElement.querySelector(\"ClickThrough\")?.textContent?.trim();\n ads.push({\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls,\n clickThrough\n });\n log(`Parsed ad: ${title}, duration: ${duration}s, media files: ${mediaFiles.length}`);\n });\n } catch (error) {\n console.error(\"[AdStormPlayer] Error parsing VAST XML:\", error);\n }\n return ads;\n }\n function selectBestMediaFile(mediaFiles) {\n if (mediaFiles.length === 0) return null;\n if (mediaFiles.length === 1) return mediaFiles[0];\n const mp4Files = mediaFiles.filter((mf) => mf.type.includes(\"video/mp4\"));\n const candidates = mp4Files.length > 0 ? mp4Files : mediaFiles;\n const targetWidth = contentVideo.videoWidth || 1280;\n const targetHeight = contentVideo.videoHeight || 720;\n candidates.sort((a, b) => {\n const diffA = Math.abs(a.width - targetWidth) + Math.abs(a.height - targetHeight);\n const diffB = Math.abs(b.width - targetWidth) + Math.abs(b.height - targetHeight);\n return diffA - diffB;\n });\n return candidates[0] || null;\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.style.zIndex = \"15\";\n video.playsInline = true;\n video.muted = false;\n video.volume = originalMutedState ? 0 : originalVolume;\n return video;\n }\n function setAdPlayingFlag(isPlaying) {\n if (isPlaying) {\n contentVideo.dataset.stormcloudAdPlaying = \"true\";\n } else {\n delete contentVideo.dataset.stormcloudAdPlaying;\n }\n }\n function setupAdEventListeners() {\n if (!adVideoElement || !currentAd) return;\n const ad = currentAd;\n adVideoElement.addEventListener(\"timeupdate\", () => {\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 adVideoElement.addEventListener(\"playing\", () => {\n if (!ad || trackingFired.start) return;\n trackingFired.start = true;\n fireTrackingPixels(ad.trackingUrls.start);\n log(\"Ad started playing\");\n });\n adVideoElement.addEventListener(\"ended\", () => {\n if (!ad || trackingFired.complete) return;\n trackingFired.complete = true;\n fireTrackingPixels(ad.trackingUrls.complete);\n log(\"Ad completed\");\n handleAdComplete();\n });\n adVideoElement.addEventListener(\"error\", (e) => {\n console.error(\"[AdStormPlayer] Ad video error:\", e);\n if (ad) {\n fireTrackingPixels(ad.trackingUrls.error);\n }\n handleAdError();\n });\n }\n function handleAdComplete() {\n log(\"Handling ad completion\");\n adPlaying = false;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n emit(\"content_resume\");\n emit(\"all_ads_completed\");\n }\n function handleAdError() {\n log(\"Handling ad error\");\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n emit(\"ad_error\");\n }\n async function fetchVast(durationSeconds) {\n const vastUrl = buildVastUrl(durationSeconds);\n log(\"Fetching VAST from:\", vastUrl);\n const response = await fetch(vastUrl, {\n headers: {\n \"Accept\": \"application/xml\"\n }\n });\n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.status} ${response.statusText}`);\n }\n const xmlText = await response.text();\n log(\"VAST response received, length:\", xmlText.length);\n return parseVastXml(xmlText);\n }\n return {\n initialize() {\n log(\"Initializing\");\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 container.style.transition = \"opacity 0.3s ease-in-out\";\n container.style.opacity = \"0\";\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n },\n async requestAds(duration) {\n log(\"Requesting ads for duration:\", duration);\n if (adPlaying) {\n return Promise.reject(new Error(\"Ad already playing\"));\n }\n try {\n let durationSeconds = 30;\n const parsed = parseInt(duration, 10);\n if (!isNaN(parsed) && parsed > 0) {\n durationSeconds = parsed;\n }\n const ads = await fetchVast(durationSeconds);\n if (ads.length === 0) {\n log(\"No ads available from VAST response\");\n emit(\"ad_error\");\n return Promise.resolve();\n }\n currentAd = ads[0];\n log(`Ad loaded: ${currentAd.title}, duration: ${currentAd.duration}s`);\n fireTrackingPixels(currentAd.trackingUrls.impression);\n trackingFired.impression = true;\n return Promise.resolve();\n } catch (error) {\n console.error(\"[AdStormPlayer] Error requesting ads:\", error);\n emit(\"ad_error\");\n return Promise.reject(error);\n }\n },\n async play() {\n if (!currentAd) {\n return Promise.reject(new Error(\"No ad loaded\"));\n }\n log(\"Starting ad playback\");\n try {\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl?.appendChild(adVideoElement);\n setupAdEventListeners();\n }\n trackingFired = {\n impression: trackingFired.impression,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false\n };\n contentVideo.style.transition = \"opacity 0.3s ease-in-out\";\n contentVideo.style.opacity = \"0\";\n setTimeout(() => {\n contentVideo.style.visibility = \"hidden\";\n }, 300);\n contentVideo.muted = true;\n contentVideo.volume = 0;\n if (allowNativeHls) {\n contentVideo.pause();\n }\n adPlaying = true;\n setAdPlayingFlag(true);\n if (adVideoElement) {\n adVideoElement.volume = originalMutedState ? 0 : originalVolume;\n adVideoElement.muted = originalMutedState;\n }\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n adContainerEl.offsetHeight;\n adContainerEl.style.opacity = \"1\";\n }\n emit(\"content_pause\");\n const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n if (!mediaFile) {\n throw new Error(\"No media file available\");\n }\n log(\"Playing media file:\", mediaFile.url);\n adVideoElement.src = mediaFile.url;\n await adVideoElement.play();\n return Promise.resolve();\n } catch (error) {\n console.error(\"[AdStormPlayer] Error playing ad:\", error);\n handleAdError();\n return Promise.reject(error);\n }\n },\n async stop() {\n log(\"Stopping ad\");\n adPlaying = false;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n }\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n currentAd = void 0;\n },\n destroy() {\n log(\"Destroying\");\n destroyed = true;\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.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 log(`Resizing to ${width}x${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 log(`updateOriginalMutedState: muted=${muted}, volume=${nextVolume}`);\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 adVideoElement.muted = volume === 0;\n }\n },\n getAdVolume() {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\n showPlaceholder() {\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.opacity = \"1\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n },\n hidePlaceholder() {\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n },\n setAllowNativeHls(value) {\n allowNativeHls = value;\n log(`allowNativeHls set to: ${value}`);\n }\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 supportsModernJS = true;\n if (/Web0S|webOS/i.test(ua)) {\n name = \"LG WebOS\";\n isSmartTV = true;\n const match = ua.match(/Web0S[/\\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 }\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 }\n } else if (/SMART-TV|SmartTV/i.test(ua)) {\n name = \"Smart TV\";\n isSmartTV = true;\n } else if (/NetCast/i.test(ua)) {\n name = \"LG NetCast\";\n isSmartTV = true;\n isLegacyTV = true;\n } else if (/BRAVIA/i.test(ua)) {\n name = \"Sony BRAVIA\";\n isSmartTV = true;\n }\n const chromeVersion = getChromeVersion(ua);\n const webkitVersion = getWebKitVersion(ua);\n if (chromeVersion > 0) {\n if (!isSmartTV) {\n name = \"Chrome\";\n version = chromeVersion.toString();\n majorVersion = chromeVersion;\n }\n if (chromeVersion < 50) {\n supportsModernJS = false;\n isLegacyTV = true;\n }\n }\n if (webkitVersion > 0 && webkitVersion < 600) {\n supportsModernJS = false;\n if (isSmartTV) {\n isLegacyTV = true;\n }\n }\n if (typeof Promise === \"undefined\" || typeof Map === \"undefined\" || typeof Set === \"undefined\") {\n supportsModernJS = false;\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 supportsModernJS\n };\n}\nfunction logBrowserInfo(debug = false) {\n if (!debug) return;\n const browser = detectBrowser();\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 supportsModernJS: browser.supportsModernJS,\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.attached = false;\n this.inAdBreak = false;\n this.ptsDriftEmaMs = 0;\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 initializePolyfills();\n const browserOverrides = getBrowserConfigOverrides();\n this.config = { ...config, ...browserOverrides };\n this.video = config.videoElement;\n logBrowserInfo(config.debugAdTiming);\n if (!this.config.licenseKey) {\n console.warn(\"[StormcloudVideoPlayer] No license key provided - ads will not work\");\n }\n this.adPlayer = createAdStormPlayer(this.video, {\n licenseKey: this.config.licenseKey || \"\",\n debug: this.config.debugAdTiming ?? false\n });\n }\n async load() {\n if (!this.attached) {\n this.attach();\n }\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(\"[StormcloudVideoPlayer] Using native HLS playback:\", {\n isLive: this.isLiveStream,\n allowNativeHls: this.config.allowNativeHls\n });\n }\n this.adPlayer.initialize();\n this.adPlayer.setAllowNativeHls(!!this.config.allowNativeHls);\n if (this.config.autoplay) {\n await this.video.play()?.catch(() => {\n });\n }\n return;\n }\n this.hls = new import_hls.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_hls.default.Events.MEDIA_ATTACHED, () => {\n this.hls?.loadSource(this.config.src);\n });\n this.hls.on(import_hls.default.Events.MANIFEST_PARSED, async () => {\n this.isLiveStream = this.hls?.levels?.some(\n (level) => level?.details?.live === true || level?.details?.type === \"LIVE\"\n ) ?? false;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Stream type detected:\", {\n isLive: this.isLiveStream\n });\n }\n this.adPlayer.initialize();\n this.adPlayer.setAllowNativeHls(!!this.config.allowNativeHls);\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_hls.default.Events.FRAG_BUFFERED, async () => {\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. 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_hls.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_hls.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\")) {\n const durationSeconds = this.parseCueOutDuration(value);\n this.onScte35Marker({\n type: \"start\",\n ...durationSeconds !== void 0 ? { durationSeconds } : {},\n raw: { tag, value }\n });\n } else if (tag.includes(\"EXT-X-CUE-OUT-CONT\")) {\n const prog = this.parseCueOutCont(value);\n this.onScte35Marker({\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 } 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;\n const hasScteIn = \"SCTE35-IN\" in attrs;\n const klass = String(attrs[\"CLASS\"] ?? \"\");\n const duration = this.toNumber(attrs[\"DURATION\"]) ?? this.toNumber(attrs[\"PLANNED-DURATION\"]);\n if (hasScteOut || /com\\.apple\\.hls\\.cue/i.test(klass)) {\n this.onScte35Marker({\n type: \"start\",\n ...duration !== void 0 ? { durationSeconds: duration } : {},\n raw: { tag, value, attrs }\n });\n }\n if (hasScteIn) {\n this.onScte35Marker({ type: \"end\", raw: { tag, value, attrs } });\n }\n }\n }\n });\n this.hls.on(import_hls.default.Events.ERROR, (_evt, data) => {\n if (data?.fatal) {\n switch (data.type) {\n case import_hls.default.ErrorTypes.NETWORK_ERROR:\n this.hls?.startLoad();\n break;\n case import_hls.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 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.adPlayer.initialize();\n this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n this.adPlayer.on(\"all_ads_completed\", () => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Ad completed - ending ad break\");\n }\n if (this.inAdBreak) {\n this.handleAdPodComplete();\n }\n });\n this.adPlayer.on(\"ad_error\", () => {\n console.error(\"[StormcloudVideoPlayer] Ad error occurred\");\n if (this.inAdBreak) {\n this.handleAdPodComplete();\n }\n });\n this.adPlayer.on(\"content_pause\", () => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Content paused for ad\");\n }\n });\n this.adPlayer.on(\"content_resume\", () => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Content resuming after ad\");\n }\n });\n this.timeUpdateHandler = () => {\n };\n this.video.addEventListener(\"timeupdate\", this.timeUpdateHandler);\n this.emptiedHandler = () => {\n if (this.nativeHlsMode && this.videoSrcProtection && !this.adPlayer.isAdPlaying()) {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Video src was cleared, restoring\");\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 return {\n type: \"start\",\n ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n ...dur !== void 0 ? { durationSeconds: dur } : {},\n raw: { id3: text }\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 return {\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 }\n const cueInMatch = text.match(/EXT-X-CUE-IN\\b/i) || text.match(/CUE-IN\\b/i);\n if (cueInMatch) {\n return {\n type: \"end\",\n ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n raw: { id3: text }\n };\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 }\n return out;\n } catch {\n return void 0;\n }\n }\n async 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 });\n }\n if (marker.type === \"start\") {\n if (this.inAdBreak) {\n return;\n }\n this.inAdBreak = true;\n const durationMs = marker.durationSeconds != null ? marker.durationSeconds * 1e3 : 3e4;\n this.expectedAdBreakDurationMs = durationMs;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Starting ad break:\", {\n durationMs,\n durationSeconds: marker.durationSeconds\n });\n }\n this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n await this.handleAdStart(marker);\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 return;\n }\n if (marker.type === \"end\") {\n if (!this.inAdBreak) return;\n this.inAdBreak = false;\n this.expectedAdBreakDurationMs = void 0;\n this.clearAdStopTimer();\n if (this.adPlayer.isAdPlaying()) {\n await this.adPlayer.stop();\n }\n this.handleAdPodComplete();\n return;\n }\n }\n async handleAdStart(marker) {\n const durationSeconds = marker.durationSeconds ?? 30;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Requesting ads for duration:\", durationSeconds);\n }\n try {\n await this.adPlayer.requestAds(String(durationSeconds));\n await this.adPlayer.play();\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\"[StormcloudVideoPlayer] Ad request/play failed:\", error);\n }\n this.handleAdPodComplete();\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 d = parseFloat(match[1]);\n return Number.isNaN(d) ? void 0 : d;\n }\n return void 0;\n }\n parseCueOutCont(value) {\n const elapsedMatch = value.match(/Elapsed\\s*=\\s*([0-9.]+)/i);\n const durationMatch = value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n const res = {};\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) 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 scheduleAdStopCountdown(remainingMs) {\n this.clearAdStopTimer();\n const ms = Math.max(0, Math.floor(remainingMs));\n if (ms === 0) {\n this.handleAdPodComplete();\n return;\n }\n this.adStopTimerId = window.setTimeout(() => {\n this.handleAdPodComplete();\n }, ms);\n }\n clearAdStopTimer() {\n if (this.adStopTimerId != null) {\n clearTimeout(this.adStopTimerId);\n this.adStopTimerId = 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 this.clearAdStopTimer();\n this.inAdBreak = false;\n this.expectedAdBreakDurationMs = void 0;\n this.adPlayer.stop().catch(() => {\n });\n const restoredMuted = this.adPlayer.getOriginalMutedState();\n const restoredVolume = this.adPlayer.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 if (this.video.paused) {\n this.video.play()?.catch(() => {\n });\n }\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Ad break complete\");\n }\n }\n isAdPlaying() {\n return this.inAdBreak && this.adPlayer.isAdPlaying();\n }\n isShowingAds() {\n return this.adPlayer.isAdPlaying();\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 toggleMute() {\n if (this.adPlayer.isAdPlaying()) {\n const currentMuted = this.video.muted;\n const newMutedState = !currentMuted;\n this.adPlayer.updateOriginalMutedState(newMutedState, this.video.volume);\n this.adPlayer.setAdVolume(newMutedState ? 0 : 1);\n } else {\n this.video.muted = !this.video.muted;\n this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);\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(() => resolve()).catch(reject);\n } else {\n document.exitFullscreen().then(() => resolve()).catch(reject);\n }\n });\n }\n isMuted() {\n return this.video.muted;\n }\n setMuted(muted) {\n this.video.muted = muted;\n this.adPlayer.updateOriginalMutedState(muted, this.video.volume);\n if (this.adPlayer.isAdPlaying()) {\n this.adPlayer.setAdVolume(muted ? 0 : 1);\n }\n }\n setVolume(volume) {\n const clampedVolume = Math.max(0, Math.min(1, volume));\n if (this.adPlayer.isAdPlaying()) {\n this.adPlayer.setAdVolume(clampedVolume);\n this.adPlayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n } else {\n this.video.volume = clampedVolume;\n this.video.muted = clampedVolume === 0;\n this.adPlayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n }\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.adPlayer && this.adPlayer.isAdPlaying()) {\n const width = this.video.clientWidth || 640;\n const height = this.video.clientHeight || 360;\n this.adPlayer.resize(width, height);\n }\n }\n destroy() {\n this.clearAdStopTimer();\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 this.hls?.destroy();\n this.adPlayer?.destroy();\n }\n getCurrentAdIndex() {\n return 0;\n }\n getTotalAdsInBreak() {\n return 1;\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 showAds = playerRef.current.isShowingAds();\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 return { showAds, currentIndex, totalAds };\n }\n return prev;\n });\n }\n };\n const interval = setInterval(checkAdStatus, 100);\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 = videoRef.current.volume;\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 if (playerRef.current && !playerRef.current.isShowingAds()) {\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 showAds = playerRef.current.isShowingAds();\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 return { showAds, currentIndex, totalAds };\n }\n return prev;\n });\n }\n };\n\n const interval = setInterval(checkAdStatus, 100);\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 = videoRef.current.volume;\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 if (playerRef.current && !playerRef.current.isShowingAds()) {\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 type { AdController } from \"../types\";\n\ninterface VastMediaFile {\n url: string;\n type: string;\n width: number;\n height: number;\n bitrate?: number | undefined;\n}\n\nconst SUPPORTED_VIDEO_EXTENSIONS = ['.mp4', '.webm', '.ogg', '.m3u8', '.ts'];\nconst UNSUPPORTED_VIDEO_EXTENSIONS = ['.flv', '.f4v', '.swf', '.wmv', '.avi', '.mov', '.mkv'];\n\nfunction getFileExtension(url: string): string {\n try {\n const pathname = new URL(url, 'http://dummy').pathname;\n const lastDot = pathname.lastIndexOf('.');\n if (lastDot === -1) return '';\n return pathname.slice(lastDot).toLowerCase();\n } catch {\n const lastDot = url.lastIndexOf('.');\n if (lastDot === -1) return '';\n const ext = url.slice(lastDot).split(/[?#]/)[0];\n return (ext || '').toLowerCase();\n }\n}\n\nfunction isUnsupportedFormat(url: string): boolean {\n const ext = getFileExtension(url);\n return UNSUPPORTED_VIDEO_EXTENSIONS.indexOf(ext) !== -1;\n}\n\nfunction replaceFlvExtension(url: string): string {\n const ext = getFileExtension(url);\n if (ext === '.flv') {\n return url.replace(/\\.flv(\\?|$)/i, '.mp4$1');\n }\n return url;\n}\n\nfunction isSupportedFormat(url: string, mimeType: string): boolean {\n if (isUnsupportedFormat(url)) {\n return false;\n }\n \n const ext = getFileExtension(url);\n \n if (SUPPORTED_VIDEO_EXTENSIONS.indexOf(ext) !== -1) {\n return true;\n }\n \n if (ext === '' || ext === '.') {\n return mimeType.includes('video/mp4') || \n mimeType.includes('video/webm') || \n mimeType.includes('m3u8') ||\n mimeType.includes('application/x-mpegurl');\n }\n \n return false;\n}\n\ninterface VastTrackingUrls {\n impression: string[];\n start: string[];\n firstQuartile: string[];\n midpoint: string[];\n thirdQuartile: string[];\n complete: string[];\n error: string[];\n}\n\ninterface VastAd {\n id: string;\n title: string;\n duration: number;\n mediaFiles: VastMediaFile[];\n trackingUrls: VastTrackingUrls;\n clickThrough?: string | undefined;\n}\n\ninterface AdStormMetadata {\n video?: {\n codec?: string;\n width?: number;\n height?: number;\n fps?: number;\n bitrate?: number;\n profile?: string;\n pix_fmt?: string;\n has_b_frames?: number;\n };\n audio?: {\n codec?: string;\n sample_rate?: number;\n bitrate?: number;\n };\n}\n\nexport interface AdStormPlayerOptions {\n licenseKey: string;\n debug?: boolean;\n}\n\nexport function createAdStormPlayer(\n contentVideo: HTMLVideoElement,\n options: AdStormPlayerOptions\n): AdController {\n const { licenseKey, debug = false } = options;\n \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 \n let adVideoElement: HTMLVideoElement | undefined;\n let adContainerEl: HTMLDivElement | undefined;\n let currentAd: VastAd | undefined;\n let destroyed = false;\n let allowNativeHls = false;\n \n let trackingFired = {\n impression: false,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false,\n };\n\n function log(...args: any[]): void {\n if (debug) {\n console.log(\"[AdStormPlayer]\", ...args);\n }\n }\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(`[AdStormPlayer] Error in event listener for ${event}:`, error);\n }\n }\n }\n\n function fireTrackingPixels(urls: string[]): void {\n if (!urls || urls.length === 0) return;\n \n urls.forEach((url) => {\n try {\n const img = new Image(1, 1);\n img.src = url;\n log(\"Fired tracking pixel:\", url);\n } catch (error) {\n console.warn(\"[AdStormPlayer] Error firing tracking pixel:\", error);\n }\n });\n }\n\n function buildVastUrl(durationSeconds: number, metadata?: AdStormMetadata): string {\n const baseUrl = `https://adstorm.co/api-adstorm-dev/adstorm/vast/${licenseKey}/pod`;\n \n const defaultMetadata: AdStormMetadata = {\n video: {\n codec: \"h264\",\n width: contentVideo.videoWidth || 1280,\n height: contentVideo.videoHeight || 720,\n fps: 29.97,\n bitrate: 5000,\n profile: \"high\",\n pix_fmt: \"yuv420p\",\n has_b_frames: 0,\n },\n audio: {\n codec: \"aac\",\n sample_rate: 48000,\n bitrate: 128,\n },\n };\n \n const finalMetadata = metadata || defaultMetadata;\n const metadataStr = encodeURIComponent(JSON.stringify(finalMetadata));\n \n return `${baseUrl}?duration=${Math.ceil(durationSeconds)}&metadata=${metadataStr}`;\n }\n\n function parseVastXml(xmlString: string): VastAd[] {\n const ads: VastAd[] = [];\n \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(\"[AdStormPlayer] XML parsing error:\", parserError.textContent);\n return [];\n }\n \n const adElements = xmlDoc.querySelectorAll(\"Ad\");\n \n adElements.forEach((adElement) => {\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = adElement.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n \n const durationText = adElement.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 parseFloat(durationParts[2] || \"0\");\n \n const mediaFileElements = adElement.querySelectorAll(\"MediaFile\");\n const mediaFiles: VastMediaFile[] = [];\n \n mediaFileElements.forEach((mf) => {\n const type = mf.getAttribute(\"type\") || \"\";\n let url = mf.textContent?.trim() || \"\";\n const width = parseInt(mf.getAttribute(\"width\") || \"1920\", 10);\n const height = parseInt(mf.getAttribute(\"height\") || \"1080\", 10);\n const bitrate = mf.getAttribute(\"bitrate\") \n ? parseInt(mf.getAttribute(\"bitrate\")!, 10) \n : undefined;\n \n if (!url) {\n log(`Skipping empty MediaFile URL`);\n return;\n }\n \n const originalUrl = url;\n url = replaceFlvExtension(url);\n if (url !== originalUrl) {\n log(`Converted FLV to MP4: ${originalUrl} -> ${url}`);\n }\n \n if (isUnsupportedFormat(url)) {\n const ext = getFileExtension(url);\n log(`Skipping unsupported format: ${url} (extension: ${ext}, declared type: ${type})`);\n return;\n }\n \n if (isSupportedFormat(url, type)) {\n mediaFiles.push({ url, type, width, height, bitrate });\n log(`Found media file: ${url} (${type}, ${width}x${height})`);\n } else {\n log(`Skipping incompatible media file: ${url} (type: ${type})`);\n }\n });\n \n if (mediaFiles.length === 0) {\n log(\"No valid media files found in ad:\", adId);\n return;\n }\n \n const trackingUrls: VastTrackingUrls = {\n impression: [],\n start: [],\n firstQuartile: [],\n midpoint: [],\n thirdQuartile: [],\n complete: [],\n error: [],\n };\n \n adElement.querySelectorAll(\"Impression\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.impression.push(url);\n });\n \n adElement.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 = adElement.querySelector(\"ClickThrough\")?.textContent?.trim();\n \n ads.push({\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls,\n clickThrough,\n });\n \n log(`Parsed ad: ${title}, duration: ${duration}s, media files: ${mediaFiles.length}`);\n });\n \n } catch (error) {\n console.error(\"[AdStormPlayer] Error parsing VAST XML:\", error);\n }\n \n return ads;\n }\n\n function selectBestMediaFile(mediaFiles: VastMediaFile[]): VastMediaFile | null {\n if (mediaFiles.length === 0) return null;\n if (mediaFiles.length === 1) return mediaFiles[0]!;\n \n const mp4Files = mediaFiles.filter(mf => mf.type.includes(\"video/mp4\"));\n const candidates = mp4Files.length > 0 ? mp4Files : mediaFiles;\n \n const targetWidth = contentVideo.videoWidth || 1280;\n const targetHeight = contentVideo.videoHeight || 720;\n \n candidates.sort((a, b) => {\n const diffA = Math.abs(a.width - targetWidth) + Math.abs(a.height - targetHeight);\n const diffB = Math.abs(b.width - targetWidth) + Math.abs(b.height - targetHeight);\n return diffA - diffB;\n });\n \n return candidates[0] || null;\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.style.zIndex = \"15\";\n video.playsInline = true;\n video.muted = false;\n video.volume = originalMutedState ? 0 : originalVolume;\n \n return video;\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 setupAdEventListeners(): void {\n if (!adVideoElement || !currentAd) return;\n \n const ad = currentAd;\n \n adVideoElement.addEventListener(\"timeupdate\", () => {\n if (!ad || !adVideoElement) return;\n \n const progress = adVideoElement.currentTime / ad.duration;\n \n if (progress >= 0.25 && !trackingFired.firstQuartile) {\n trackingFired.firstQuartile = true;\n fireTrackingPixels(ad.trackingUrls.firstQuartile);\n }\n \n if (progress >= 0.5 && !trackingFired.midpoint) {\n trackingFired.midpoint = true;\n fireTrackingPixels(ad.trackingUrls.midpoint);\n }\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 if (!ad || trackingFired.start) return;\n trackingFired.start = true;\n fireTrackingPixels(ad.trackingUrls.start);\n log(\"Ad started playing\");\n });\n \n adVideoElement.addEventListener(\"ended\", () => {\n if (!ad || trackingFired.complete) return;\n trackingFired.complete = true;\n fireTrackingPixels(ad.trackingUrls.complete);\n log(\"Ad completed\");\n handleAdComplete();\n });\n \n adVideoElement.addEventListener(\"error\", (e) => {\n console.error(\"[AdStormPlayer] Ad video error:\", e);\n if (ad) {\n fireTrackingPixels(ad.trackingUrls.error);\n }\n handleAdError();\n });\n }\n\n function handleAdComplete(): void {\n log(\"Handling ad completion\");\n adPlaying = false;\n setAdPlayingFlag(false);\n \n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n \n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n \n emit(\"content_resume\");\n emit(\"all_ads_completed\");\n }\n\n function handleAdError(): void {\n log(\"Handling ad error\");\n adPlaying = false;\n setAdPlayingFlag(false);\n \n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n \n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n \n emit(\"ad_error\");\n }\n\n async function fetchVast(durationSeconds: number): Promise<VastAd[]> {\n const vastUrl = buildVastUrl(durationSeconds);\n log(\"Fetching VAST from:\", vastUrl);\n \n const response = await fetch(vastUrl, {\n headers: {\n \"Accept\": \"application/xml\",\n },\n });\n \n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.status} ${response.statusText}`);\n }\n \n const xmlText = await response.text();\n log(\"VAST response received, length:\", xmlText.length);\n \n return parseVastXml(xmlText);\n }\n\n return {\n initialize() {\n log(\"Initializing\");\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 container.style.transition = \"opacity 0.3s ease-in-out\";\n container.style.opacity = \"0\";\n \n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n },\n\n async requestAds(duration: string) {\n log(\"Requesting ads for duration:\", duration);\n \n if (adPlaying) {\n return Promise.reject(new Error(\"Ad already playing\"));\n }\n \n try {\n let durationSeconds = 30;\n const parsed = parseInt(duration, 10);\n if (!isNaN(parsed) && parsed > 0) {\n durationSeconds = parsed;\n }\n \n const ads = await fetchVast(durationSeconds);\n \n if (ads.length === 0) {\n log(\"No ads available from VAST response\");\n emit(\"ad_error\");\n return Promise.resolve();\n }\n \n currentAd = ads[0];\n log(`Ad loaded: ${currentAd!.title}, duration: ${currentAd!.duration}s`);\n \n fireTrackingPixels(currentAd!.trackingUrls.impression);\n trackingFired.impression = true;\n \n return Promise.resolve();\n } catch (error) {\n console.error(\"[AdStormPlayer] Error requesting ads:\", error);\n emit(\"ad_error\");\n return Promise.reject(error);\n }\n },\n\n async play() {\n if (!currentAd) {\n return Promise.reject(new Error(\"No ad loaded\"));\n }\n \n log(\"Starting ad playback\");\n \n try {\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl?.appendChild(adVideoElement);\n setupAdEventListeners();\n }\n \n trackingFired = {\n impression: trackingFired.impression,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false,\n };\n \n contentVideo.style.transition = \"opacity 0.3s ease-in-out\";\n contentVideo.style.opacity = \"0\";\n setTimeout(() => {\n contentVideo.style.visibility = \"hidden\";\n }, 300);\n contentVideo.muted = true;\n contentVideo.volume = 0;\n \n if (allowNativeHls) {\n contentVideo.pause();\n }\n \n adPlaying = true;\n setAdPlayingFlag(true);\n \n if (adVideoElement) {\n adVideoElement.volume = originalMutedState ? 0 : originalVolume;\n adVideoElement.muted = originalMutedState;\n }\n \n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n adContainerEl.offsetHeight;\n adContainerEl.style.opacity = \"1\";\n }\n \n emit(\"content_pause\");\n \n const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n if (!mediaFile) {\n throw new Error(\"No media file available\");\n }\n \n log(\"Playing media file:\", mediaFile.url);\n adVideoElement!.src = mediaFile.url;\n \n await adVideoElement!.play();\n \n return Promise.resolve();\n } catch (error) {\n console.error(\"[AdStormPlayer] Error playing ad:\", error);\n handleAdError();\n return Promise.reject(error);\n }\n },\n\n async stop() {\n log(\"Stopping ad\");\n adPlaying = false;\n setAdPlayingFlag(false);\n \n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n \n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n }\n \n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n \n currentAd = undefined;\n },\n\n destroy() {\n log(\"Destroying\");\n destroyed = true;\n adPlaying = false;\n setAdPlayingFlag(false);\n \n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n \n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n adVideoElement.remove();\n adVideoElement = undefined;\n }\n \n if (adContainerEl?.parentElement) {\n adContainerEl.parentElement.removeChild(adContainerEl);\n }\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 log(`Resizing to ${width}x${height}`);\n \n if (adContainerEl) {\n adContainerEl.style.width = `${width}px`;\n adContainerEl.style.height = `${height}px`;\n }\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 log(`updateOriginalMutedState: muted=${muted}, volume=${nextVolume}`);\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 adVideoElement.muted = volume === 0;\n }\n },\n\n getAdVolume(): number {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\n\n showPlaceholder() {\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 \n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n \n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.opacity = \"1\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n },\n\n hidePlaceholder() {\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n },\n\n setAllowNativeHls(value: boolean) {\n allowNativeHls = value;\n log(`allowNativeHls set to: ${value}`);\n },\n };\n}\n\n","import Hls from \"hls.js\";\nimport type {\n StormcloudVideoPlayerConfig,\n Scte35Marker,\n Id3TagInfo,\n AdController,\n} from \"../types\";\nimport { createAdStormPlayer } from \"../sdk/adstormPlayer\";\nimport { initializePolyfills } from \"../utils/polyfills\";\nimport { getBrowserConfigOverrides, logBrowserInfo } from \"../utils/browserCompat\";\n\nexport class StormcloudVideoPlayer {\n private readonly video: HTMLVideoElement;\n private readonly config: StormcloudVideoPlayerConfig;\n private hls?: Hls;\n private adPlayer: AdController;\n private attached = false;\n private inAdBreak = false;\n private expectedAdBreakDurationMs: number | undefined;\n private adStopTimerId: number | undefined;\n private ptsDriftEmaMs = 0;\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 timeUpdateHandler?: (event: Event) => void;\n private emptiedHandler?: (event: Event) => void;\n\n constructor(config: StormcloudVideoPlayerConfig) {\n initializePolyfills();\n\n const browserOverrides = getBrowserConfigOverrides();\n this.config = { ...config, ...browserOverrides };\n this.video = config.videoElement;\n\n logBrowserInfo(config.debugAdTiming);\n\n if (!this.config.licenseKey) {\n console.warn(\"[StormcloudVideoPlayer] No license key provided - ads will not work\");\n }\n\n this.adPlayer = createAdStormPlayer(this.video, {\n licenseKey: this.config.licenseKey || \"\",\n debug: this.config.debugAdTiming ?? false,\n });\n }\n\n async load(): Promise<void> {\n if (!this.attached) {\n this.attach();\n }\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(\"[StormcloudVideoPlayer] Using native HLS playback:\", {\n isLive: this.isLiveStream,\n allowNativeHls: this.config.allowNativeHls,\n });\n }\n\n this.adPlayer.initialize();\n this.adPlayer.setAllowNativeHls(!!this.config.allowNativeHls);\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 () => {\n this.isLiveStream =\n this.hls?.levels?.some(\n (level) =>\n level?.details?.live === true || level?.details?.type === \"LIVE\"\n ) ?? false;\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Stream type detected:\", {\n isLive: this.isLiveStream,\n });\n }\n\n this.adPlayer.initialize();\n this.adPlayer.setAllowNativeHls(!!this.config.allowNativeHls);\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.FRAG_BUFFERED, async () => {\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. 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 \n if (tag.includes(\"EXT-X-CUE-OUT\")) {\n const durationSeconds = this.parseCueOutDuration(value);\n this.onScte35Marker({\n type: \"start\",\n ...(durationSeconds !== undefined ? { durationSeconds } : {}),\n raw: { tag, value },\n });\n } else if (tag.includes(\"EXT-X-CUE-OUT-CONT\")) {\n const prog = this.parseCueOutCont(value);\n this.onScte35Marker({\n type: \"progress\",\n ...(prog?.duration !== undefined ? { durationSeconds: prog.duration } : {}),\n ...(prog?.elapsed !== undefined ? { ptsSeconds: prog.elapsed } : {}),\n raw: { tag, value },\n });\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;\n const hasScteIn = \"SCTE35-IN\" in attrs;\n const klass = String(attrs[\"CLASS\"] ?? \"\");\n const duration = this.toNumber(attrs[\"DURATION\"]) ?? this.toNumber(attrs[\"PLANNED-DURATION\"]);\n\n if (hasScteOut || /com\\.apple\\.hls\\.cue/i.test(klass)) {\n this.onScte35Marker({\n type: \"start\",\n ...(duration !== undefined ? { durationSeconds: duration } : {}),\n raw: { tag, value, attrs },\n });\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 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.adPlayer.initialize();\n this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n \n this.adPlayer.on(\"all_ads_completed\", () => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Ad completed - ending ad break\");\n }\n if (this.inAdBreak) {\n this.handleAdPodComplete();\n }\n });\n \n this.adPlayer.on(\"ad_error\", () => {\n console.error(\"[StormcloudVideoPlayer] Ad error occurred\");\n if (this.inAdBreak) {\n this.handleAdPodComplete();\n }\n });\n \n this.adPlayer.on(\"content_pause\", () => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Content paused for ad\");\n }\n });\n \n this.adPlayer.on(\"content_resume\", () => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Content resuming after ad\");\n }\n });\n\n this.timeUpdateHandler = () => {\n };\n this.video.addEventListener(\"timeupdate\", this.timeUpdateHandler);\n\n this.emptiedHandler = () => {\n if (this.nativeHlsMode && this.videoSrcProtection && !this.adPlayer.isAdPlaying()) {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Video src was cleared, restoring\");\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 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\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 return {\n type: \"start\",\n ...(tag.ptsSeconds !== undefined ? { ptsSeconds: tag.ptsSeconds } : {}),\n ...(dur !== undefined ? { durationSeconds: dur } : {}),\n raw: { id3: text },\n };\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 return {\n type: \"progress\",\n ...(tag.ptsSeconds !== undefined ? { ptsSeconds: tag.ptsSeconds } : {}),\n ...(cont?.duration !== undefined ? { durationSeconds: cont.duration } : {}),\n raw: { id3: text },\n };\n }\n\n const cueInMatch = text.match(/EXT-X-CUE-IN\\b/i) || text.match(/CUE-IN\\b/i);\n if (cueInMatch) {\n return {\n type: \"end\",\n ...(tag.ptsSeconds !== undefined ? { ptsSeconds: tag.ptsSeconds } : {}),\n raw: { id3: text },\n };\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 }\n return out;\n } catch {\n return undefined;\n }\n }\n\n private async onScte35Marker(marker: Scte35Marker): Promise<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 });\n }\n\n if (marker.type === \"start\") {\n if (this.inAdBreak) {\n return;\n }\n\n this.inAdBreak = true;\n const durationMs = marker.durationSeconds != null\n ? marker.durationSeconds * 1000\n : 30000;\n \n this.expectedAdBreakDurationMs = durationMs;\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Starting ad break:\", {\n durationMs,\n durationSeconds: marker.durationSeconds,\n });\n }\n\n this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n\n await this.handleAdStart(marker);\n\n if (this.expectedAdBreakDurationMs != null) {\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n return;\n }\n\n if (marker.type === \"progress\" && this.inAdBreak) {\n if (marker.durationSeconds != null) {\n this.expectedAdBreakDurationMs = marker.durationSeconds * 1000;\n }\n return;\n }\n\n if (marker.type === \"end\") {\n if (!this.inAdBreak) return;\n \n this.inAdBreak = false;\n this.expectedAdBreakDurationMs = undefined;\n this.clearAdStopTimer();\n\n if (this.adPlayer.isAdPlaying()) {\n await this.adPlayer.stop();\n }\n\n this.handleAdPodComplete();\n return;\n }\n }\n\n private async handleAdStart(marker: Scte35Marker): Promise<void> {\n const durationSeconds = marker.durationSeconds ?? 30;\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Requesting ads for duration:\", durationSeconds);\n }\n\n try {\n await this.adPlayer.requestAds(String(durationSeconds));\n \n await this.adPlayer.play();\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\"[StormcloudVideoPlayer] Ad request/play failed:\", error);\n }\n this.handleAdPodComplete();\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 d = parseFloat(match[1]);\n return Number.isNaN(d) ? undefined : d;\n }\n return undefined;\n }\n\n private parseCueOutCont(value: string): { elapsed?: number; duration?: number } | undefined {\n const elapsedMatch = value.match(/Elapsed\\s*=\\s*([0-9.]+)/i);\n const durationMatch = value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n const res: { elapsed?: number; duration?: number } = {};\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) 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 scheduleAdStopCountdown(remainingMs: number): void {\n this.clearAdStopTimer();\n const ms = Math.max(0, Math.floor(remainingMs));\n if (ms === 0) {\n this.handleAdPodComplete();\n return;\n }\n this.adStopTimerId = window.setTimeout(() => {\n this.handleAdPodComplete();\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 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 this.clearAdStopTimer();\n \n this.inAdBreak = false;\n this.expectedAdBreakDurationMs = undefined;\n\n this.adPlayer.stop().catch(() => {});\n\n const restoredMuted = this.adPlayer.getOriginalMutedState();\n const restoredVolume = this.adPlayer.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 if (this.video.paused) {\n this.video.play()?.catch(() => {});\n }\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Ad break complete\");\n }\n }\n\n isAdPlaying(): boolean {\n return this.inAdBreak && this.adPlayer.isAdPlaying();\n }\n\n isShowingAds(): boolean {\n return this.adPlayer.isAdPlaying();\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 toggleMute(): void {\n if (this.adPlayer.isAdPlaying()) {\n const currentMuted = this.video.muted;\n const newMutedState = !currentMuted;\n\n this.adPlayer.updateOriginalMutedState(newMutedState, this.video.volume);\n this.adPlayer.setAdVolume(newMutedState ? 0 : 1);\n } else {\n this.video.muted = !this.video.muted;\n this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);\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(() => resolve())\n .catch(reject);\n } else {\n document.exitFullscreen().then(() => resolve()).catch(reject);\n }\n });\n }\n\n isMuted(): boolean {\n return this.video.muted;\n }\n\n setMuted(muted: boolean): void {\n this.video.muted = muted;\n this.adPlayer.updateOriginalMutedState(muted, this.video.volume);\n\n if (this.adPlayer.isAdPlaying()) {\n this.adPlayer.setAdVolume(muted ? 0 : 1);\n }\n }\n\n setVolume(volume: number): void {\n const clampedVolume = Math.max(0, Math.min(1, volume));\n\n if (this.adPlayer.isAdPlaying()) {\n this.adPlayer.setAdVolume(clampedVolume);\n this.adPlayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n } else {\n this.video.volume = clampedVolume;\n this.video.muted = clampedVolume === 0;\n this.adPlayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n }\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.adPlayer && this.adPlayer.isAdPlaying()) {\n const width = this.video.clientWidth || 640;\n const height = this.video.clientHeight || 360;\n this.adPlayer.resize(width, height);\n }\n }\n\n destroy(): void {\n this.clearAdStopTimer();\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 this.hls?.destroy();\n this.adPlayer?.destroy();\n }\n\n getCurrentAdIndex(): number {\n return 0;\n }\n\n getTotalAdsInBreak(): number {\n return 1;\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 supportsModernJS: boolean;\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 supportsModernJS = true;\n\n if (/Web0S|webOS/i.test(ua)) {\n name = 'LG WebOS';\n isSmartTV = true;\n const match = ua.match(/Web0S[/\\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 }\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 }\n } else if (/SMART-TV|SmartTV/i.test(ua)) {\n name = 'Smart TV';\n isSmartTV = true;\n } else if (/NetCast/i.test(ua)) {\n name = 'LG NetCast';\n isSmartTV = true;\n isLegacyTV = true;\n } else if (/BRAVIA/i.test(ua)) {\n name = 'Sony BRAVIA';\n isSmartTV = true;\n }\n\n const chromeVersion = getChromeVersion(ua);\n const webkitVersion = getWebKitVersion(ua);\n\n if (chromeVersion > 0) {\n if (!isSmartTV) {\n name = 'Chrome';\n version = chromeVersion.toString();\n majorVersion = chromeVersion;\n }\n\n if (chromeVersion < 50) {\n supportsModernJS = false;\n isLegacyTV = true;\n }\n }\n\n if (webkitVersion > 0 && webkitVersion < 600) {\n supportsModernJS = false;\n if (isSmartTV) {\n isLegacyTV = true;\n }\n }\n\n if (typeof Promise === 'undefined' ||\n typeof Map === 'undefined' ||\n typeof Set === 'undefined') {\n supportsModernJS = false;\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 supportsModernJS,\n };\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\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 supportsModernJS: browser.supportsModernJS,\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 '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"]}